## Summary Fixes #47540 - Anthropic Claude models not appearing in GitHub Copilot Chat model picker. ## Problem Users reported that Anthropic Claude models (Claude Sonnet 4, Claude Opus 4, etc.) were not appearing in the model picker when using GitHub Copilot Chat, even though: - The GitHub Copilot API returns these models - The models have `model_picker_enabled: true` - Users have valid Copilot subscriptions with access to these models ## Root Cause The issue was in the `ModelSupportedEndpoint` enum deserialization. The enum only defined two variants: ```rust pub enum ModelSupportedEndpoint { #[serde(rename = "/chat/completions")] ChatCompletions, #[serde(rename = "/responses")] Responses, } ``` Anthropic Claude models use the `/v1/messages` endpoint, which wasn't defined. When deserializing the API response, serde failed with: ``` Error("unknown variant `/v1/messages`, expected `/chat/completions` or `/responses`") ``` Because the crate uses resilient deserialization via `deserialize_models_skip_errors()`, the entire Claude model was silently skipped rather than causing a hard failure. This meant users saw no error - the models simply didn't appear. ## Solution ### 1. Added `/v1/messages` endpoint variant ```rust pub enum ModelSupportedEndpoint { #[serde(rename = "/chat/completions")] ChatCompletions, #[serde(rename = "/responses")] Responses, #[serde(rename = "/v1/messages")] Messages, // NEW: Anthropic models use this endpoint #[serde(other)] Unknown, // NEW: Future-proofing for unknown endpoints } ``` ### 2. Removed incorrect `dedup_by()` call The previous code deduplicated models by family: ```rust .dedup_by(|a, b| a.capabilities.family == b.capabilities.family) ``` This incorrectly filtered out model variants that share the same family (e.g., `claude-sonnet-4` and `claude-sonnet-4-thinking`). Removed this call to preserve all model variants. ### 3. Removed unused import Removed `use itertools::Itertools;` which was only used for the now-removed `dedup_by()`. ## Changes | File | Change | |------|--------| | `crates/copilot_chat/src/copilot_chat.rs` | Added `Messages` and `Unknown` variants to `ModelSupportedEndpoint` enum | | `crates/copilot_chat/src/copilot_chat.rs` | Removed `.dedup_by()` call that incorrectly filtered models | | `crates/copilot_chat/src/copilot_chat.rs` | Removed unused `itertools::Itertools` import | | `crates/copilot_chat/src/copilot_chat.rs` | Added 8 new unit tests | ## Test Coverage Added 8 new unit tests to ensure the fix works and prevent regression: | Test | Purpose | |------|---------| | `test_models_with_pending_policy_deserialize` | Verifies models with non-"enabled" policy states deserialize correctly (they're filtered later) | | `test_multiple_anthropic_models_preserved` | Verifies multiple Claude models are not incorrectly deduplicated | | `test_models_with_same_family_both_preserved` | Verifies models sharing the same family (e.g., thinking variants) are both preserved | | `test_mixed_vendor_models_all_preserved` | Verifies models from different vendors (OpenAI, Anthropic, Google) are all preserved | | `test_model_with_messages_endpoint_deserializes` | **Critical test**: Verifies `/v1/messages` endpoint deserializes correctly | | `test_model_with_unknown_endpoint_deserializes` | Verifies unknown future endpoints deserialize to `Unknown` variant | | `test_model_with_multiple_endpoints` | Verifies models with multiple endpoints deserialize correctly | | `test_supports_response_method` | Verifies the `supports_response()` method logic for endpoint routing | ### Test Results ``` running 10 tests test tests::test_model_with_messages_endpoint_deserializes ... ok test tests::test_model_with_multiple_endpoints ... ok test tests::test_model_with_unknown_endpoint_deserializes ... ok test tests::test_models_with_pending_policy_deserialize ... ok test tests::test_models_with_same_family_both_preserved ... ok test tests::test_mixed_vendor_models_all_preserved ... ok test tests::test_multiple_anthropic_models_preserved ... ok test tests::test_resilient_model_schema_deserialize ... ok test tests::test_supports_response_method ... ok test tests::test_unknown_vendor_resilience ... ok test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ``` ## How to Test Manually 1. Sign in to GitHub Copilot in Zed 2. Open the model picker (Agent panel → model selector dropdown) 3. Verify that Anthropic Claude models appear in the list: - Claude Sonnet 4 - Claude Opus 4 - Other Claude variants (if enabled in your GitHub Copilot settings) ## Checklist - [x] Code compiles without errors - [x] `./script/clippy --package copilot_chat` passes with no warnings - [x] All unit tests pass - [x] Change is focused on a single bug fix - [x] No unrelated refactoring or feature additions <img width="320" height="400" alt="Screenshot 2026-01-24 at 11 57 21 PM" src="https://github.com/user-attachments/assets/d5e17e1b-da80-4f4d-a218-d50d35114a21" /> Release Notes: - Fixed Anthropic models not appearing in the Copilot Chat model picker --------- Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
41 lines
774 B
TOML
41 lines
774 B
TOML
[package]
|
|
name = "copilot_chat"
|
|
version = "0.1.0"
|
|
edition.workspace = true
|
|
publish.workspace = true
|
|
license = "GPL-3.0-or-later"
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[lib]
|
|
path = "src/copilot_chat.rs"
|
|
doctest = false
|
|
|
|
[features]
|
|
default = []
|
|
test-support = [
|
|
"collections/test-support",
|
|
"gpui/test-support",
|
|
"settings/test-support",
|
|
]
|
|
|
|
[dependencies]
|
|
anyhow.workspace = true
|
|
chrono.workspace = true
|
|
collections.workspace = true
|
|
dirs.workspace = true
|
|
fs.workspace = true
|
|
futures.workspace = true
|
|
gpui.workspace = true
|
|
http_client.workspace = true
|
|
log.workspace = true
|
|
paths.workspace = true
|
|
serde.workspace = true
|
|
serde_json.workspace = true
|
|
settings.workspace = true
|
|
|
|
[dev-dependencies]
|
|
gpui = { workspace = true, features = ["test-support"] }
|
|
serde_json.workspace = true
|