Add Command Code GOAT provider - #4943
Conversation
Command Code (commandcode.ai) exposes every plan model through an OpenAI-compatible provider API at https://api.commandcode.ai/provider/v1 auth'd with a bearer API key from Studio. GOAT and above include API access; models list is served at /provider/v1/models, which this entry uses as its discovery path once a key is saved. Command Code is not on models.dev, so the shipped GOAT catalog from commandcode.ai/models is the offline baseline. The runtime adapter is the standard openai-compatible 'provider' profile (chat-completions wire), same shape as zenmux/opencode; no per-model overrides or migration impact — stored connections are unaffected. Generated-by: Maka
Bilingual (zh-CN/zh-TW/en) catalog card for the new Command Code provider. The compile-time Record<ProviderType, ...> in provider-display-copy.ts requires an entry for every registered provider, so this ships with the registry change. Generated-by: Maka
Generated-by: Codex
Generated-by: Codex
jackwener
left a comment
There was a problem hiding this comment.
Reviewed against the vendor's Provider API documentation at exact head ff34b297.
| authKind: 'api_key', | ||
| fallbackModels: [], | ||
| status: 'ready', | ||
| runtimeAdapter: { kind: 'openai-compatible', name: 'provider' }, |
There was a problem hiding this comment.
[P2] With discovery as the only source of models, the picker will offer Claude, and every Claude request from this adapter is documented to fail.
Three settings on this entry combine into a reachable failure:
runtimeAdapter: { kind: 'openai-compatible', name: 'provider' }— all traffic goes to/chat/completions;modelDiscovery: { kind: 'protocol' }withfallbackModels: []— the picker is populated entirely from the remote catalog, with nothing shipped to shield it;status: 'ready'.
The vendor's own Provider API documentation is explicit on both halves. It exposes /chat/completions, /messages and /models; it advertises the catalog as "The best open & closed models on one API: Claude, GPT, Gemini, & top open-models"; and it names this exact mistake as a 400: "Wrong endpoint for the model (Claude on /chat/completions or non-Anthropic on /messages)".
So a user who saves a valid plan credential gets a model list that includes Claude, and selecting one produces a hard failure on every request. That is ordinary use, not an edge case — Claude is the first name in the vendor's own list of what the plan buys. This PR's own verification already observed it: "Claude on Chat Completions returned HTTP 400."
I am raising it even though the Remaining-work section discloses it and #4948 tracks it. The disclosure is accurate and the draft state is honest, and I am not asking for the per-model routing work to happen here. What the tracker does not do is make the state safe if this entry ships as it stands: a tracked follow-up is a plan, not a guard. Two shapes would close the gap without waiting for #4948 — filter Anthropic ids out of the discovered list so the picker only offers what this adapter can actually send, or hold status below ready until routing exists. Either keeps a user from choosing a model that cannot work.
简体中文
[P2] 当模型来源只有远端发现时,选择器会提供 Claude,而这个适配器发出的每一次 Claude 请求,按厂商文档都必然失败。
这个条目上的三项设置合起来构成一条可达的失败路径:
runtimeAdapter: { kind: 'openai-compatible', name: 'provider' }—— 所有流量都走/chat/completions;modelDiscovery: { kind: 'protocol' }且fallbackModels: []—— 选择器完全由远端目录填充,没有任何随包内容为它兜底;status: 'ready'。
厂商自己的 Provider API 文档对这两半都写得很直接。 它暴露 /chat/completions、/messages 与 /models;把目录宣传为 "The best open & closed models on one API: Claude, GPT, Gemini, & top open-models";并且把这个错误原样列为 400:"Wrong endpoint for the model (Claude on /chat/completions or non-Anthropic on /messages)"。
于是:一个保存了有效套餐凭据的用户,会拿到一份包含 Claude 的模型列表,而选中其中任意一个,都会让每一次请求硬失败。 这是普通使用,不是边缘情形 —— Claude 正是厂商自己列举「这个套餐买到什么」时的第一个名字。本 PR 自己的验证其实已经观察到了:"Claude on Chat Completions returned HTTP 400."
我仍然提出它,尽管 Remaining work 已披露、且 #4948 在跟踪。 那份披露是准确的,draft 状态也是诚实的,我也不要求把按模型路由的工作放到这一单来做。 但 tracker 做不到的一件事是:如果这个条目就以现状发布,它并不会因此变安全 —— 一个被跟踪的后续是一份计划,不是一道守卫。 有两种形状可以在不等 #4948 的前提下补上:把 Anthropic 的 id 从发现结果中过滤掉,使选择器只提供这个适配器真能发送的模型;或者在路由能力存在之前,不要把 status 置为 ready。两者都能防止用户选到一个根本无法工作的模型。
Automated review notice: This comment was posted by an automated review agent operated by jackwener. It is not an independent human review and does not replace one.
Generated-by: Codex
|
I closed this PR because #4957 already merged the Command Code provider registration, dynamic model discovery, catalog copy, and generic Cpu icon from this PR, together with the per-model protocol routing needed for Claude support. The Command Code / GOAT integration is now on main; it has not been dropped. No separate merge of this PR is needed. Sorry for not explaining the closure here sooner. |
Superseded by #4957, merged as
2dd98419aba3cefc9ffa935c341ed354137610fc. That PR includes this provider registration, catalog copy and generic Cpu mark together with per-model protocol routing. This draft is closed without a separate merge.Summary
Adds a Command Code connection using its Provider API. Models are fetched from the service when connecting; no Command Code model list is shipped. The catalog copy explains plan credits and automatic model discovery.
Providers without a dedicated brand mark reuse the existing Lucide Cpu icon. The custom fallback SVG is removed, with no new dependency or third-party brand asset. The generic mark is owned by the connection-settings feature and exposed through its public entry point, keeping the legacy brand mapping within the renderer dependency rules.
Refs #4948.
Remaining work
Verification
492ff80f0f4abf3a917ce8f2c41b32fa9e3fc60c, all 101 checker tests, renderer build, and ASF source headers passed after the ownership fix.AI use
Tool(s) and scope: Maka authored the initial provider registration. Codex removed the static model list, revised the catalog copy, reused the Cpu icon, and verified the changes. Preserve all Generated-by trailers when squashing.
Checklist
Does this PR entail a change in behavior?