fix(provider): correctly parse GitHub Copilot models response#3671
Merged
Conversation
The GitHub Copilot /models endpoint uses a different schema than the standard OpenAI models response: capabilities, token limits and access policy are nested objects. Parsing it with the generic OpenAI ListModelResponse dropped capability metadata and listed models the account cannot actually use (policy-disabled models and embeddings), which fail with model_not_supported when selected. Add a Copilot-specific DTO that: - Deserializes the Copilot models schema (capabilities/limits/policy) - Filters out policy-disabled models, non-chat models and models without token limit or tool call metadata - Maps context window, tool call, reasoning and vision capabilities to the domain model Co-Authored-By: ForgeCode <noreply@forgecode.dev>
1302860 to
2840761
Compare
The Copilot API has no 'auto' model id; official clients implement 'Auto' by omitting the model field so the service selects one server-side. On free/student plans 'Auto' is the included option while specific premium models consume a limited premium-request quota. - Add a synthetic 'auto' entry at the top of the Copilot model list - When 'auto' is selected, omit the model field from chat requests - Verified against the live API: requests without a model field return 200 for plain chat, streaming and tool calls Co-Authored-By: ForgeCode <noreply@forgecode.dev>
When the synthetic 'auto' model is selected the served model is chosen server-side and is unknown at request time. Sending reasoning tuning (reasoning, reasoning_effort, thinking) fails with invalid_reasoning_effort when the service selects a non-reasoning model such as gpt-4o-mini. Extract request preparation into prepare_copilot_auto_request which omits the model field along with all model-specific reasoning tuning. Co-Authored-By: ForgeCode <noreply@forgecode.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Users report that the GitHub Copilot provider lists models that fail with
model_not_supportedwhen selected (e.g. on the GitHub Student / free plan), and that model capability metadata (context length, tools, reasoning, vision) is missing for all Copilot models.Root cause: the Copilot
/modelsendpoint does not use the standard OpenAI models schema. It nests metadata undercapabilities,limits, andpolicyobjects. Forge parsed it with the generic OpenAIListModelResponse, which:policy.state == "disabled"for the account's subscription appear in:modelsbut return400 model_not_supportedwhen used.text-embedding-3-smallcannot chat at all.Solution
Add a Copilot-specific DTO (
CopilotListModelResponse/CopilotModel) that mirrors the real schema, and use it inOpenAIProvider::inner_models()when the provider isgithub_copilot:capabilities,limits,policy,supported_endpoints)The filtering rules match what opencode applies in its
github-copilotplugin.Verification
gpt-5.5,claude-opus-4.8, embeddings) are removedgpt-5-mini,claude-sonnet-4.6,gpt-4o,gpt-4.1) and fail (400) for filtered-out ones (gpt-5.5)cargo check,cargo clippy, and allforge_app+forge_repotests pass (999 tests)Co-Authored-By: ForgeCode noreply@forgecode.dev