Add Together AI platform + bare-array listing tolerance (provider 9)

The 12th registry row: id "together", TOGETHER_API_KEY > auth.json
"together" scope, https://api.together.xyz/v1 with KIGI_TOGETHER_BASE_URL
override, Bearer, ChatCompletions + Passthrough, enrichment-backed
metadata (models_dev_id togetherai) with the tool-calling listing
restriction (Together's listing mixes chat/embedding/rerank/image types).

Together's GET /v1/models returns a BARE JSON ARRAY, not the OpenAI
{object:list,data:[]} envelope. New shared parser parse_openai_listing
tolerates both shapes (sniffs the top-level [ vs { for accurate
diagnostics); every OpenAI-listing provider now routes through it, with
byte-equivalent envelope behavior (verified: Groq/Google/OpenRouter
unchanged) and non-silent errors. Together's org/Model ids match the
togetherai snapshot keys exactly (verified), so restrict_to_enriched keeps
the ~27 tool-calling models without the id-shape trap.

Review: ship-ready, shared-parser change proven strictly-additive and safe,
registry/e2e/dialect all correct. Backlog logged: kigi ignores the wire
per-model  field, so a live Together chat model absent from
models.dev is dropped until indexed — a future wire- filter would
unlock the fresh full catalog.
This commit is contained in:
2026-07-21 13:16:20 -04:00
parent e7dbb98207
commit 0a147bd8a5
4 changed files with 190 additions and 10 deletions
@@ -603,7 +603,8 @@ mod tests {
"mistral",
"fireworks",
"google",
"openrouter"
"openrouter",
"together"
]
);
assert_eq!(default_id(&built), Some(XAI_API_KEY_METHOD_ID));
@@ -637,7 +638,8 @@ mod tests {
"mistral",
"fireworks",
"google",
"openrouter"
"openrouter",
"together"
]
);
assert_eq!(default_id(&built), Some(CACHED_TOKEN_AUTH_METHOD_ID));
@@ -664,7 +666,8 @@ mod tests {
"mistral",
"fireworks",
"google",
"openrouter"
"openrouter",
"together"
]
);
assert_eq!(default_id(&built), Some(CACHED_TOKEN_AUTH_METHOD_ID));
@@ -694,7 +697,8 @@ mod tests {
"mistral",
"fireworks",
"google",
"openrouter"
"openrouter",
"together"
]
);
assert_eq!(default_id(&built), None);