Skip to content

Commit 13ad175

Browse files
authored
copilot_chat: Return true context window size (zed-industries#47557)
## Fix incorrect context size limits for GitHub Copilot Chat models Fixes zed-industries#44909 ### Problem The agent panel was displaying incorrect token limits for GitHub Copilot models. Users reported that: - The agent panel always showed a **128K token limit** for all GitHub Copilot models, regardless of their actual context window size - Claude models (e.g., Claude 3.7 Sonnet, Claude Opus 4.5) were showing ~90K instead of their actual 200K context window - GPT-4o was showing 110K instead of its actual 128K context window - Users could continue using models beyond the displayed limit, which worked but was confusing ### Root Cause The `max_token_count()` method in `copilot_chat.rs` was returning `max_prompt_tokens` instead of `max_context_window_tokens`: ```rust // Before (incorrect) pub fn max_token_count(&self) -> u64 { self.capabilities.limits.max_prompt_tokens } ``` GitHub's API returns three different token-related fields: - `max_context_window_tokens`: The **full context window size** (e.g., 200K for Claude 3.7) - `max_prompt_tokens`: GitHub's limit for prompt input (e.g., 90K for Claude 3.7) - `max_output_tokens`: Maximum output tokens (e.g., 16K) The `max_token_count()` method in the `LanguageModel` trait is expected to return the **full context window size** — this is consistent with all other providers (Anthropic returns 200K for Claude, OpenAI returns 128K for GPT-4o, etc.). ### Solution <img width="583" height="132" alt="Screenshot 2026-01-25 at 1 07 53 AM" src="https://github.com/user-attachments/assets/847e2fdb-635d-44bc-a630-2d4867ba8c32" /> Changed `max_token_count()` to return `max_context_window_tokens`: ```rust // After (correct) pub fn max_token_count(&self) -> u64 { self.capabilities.limits.max_context_window_tokens as u64 } ``` ### Impact | Model | Before | After | |-------|--------|-------| | Claude 3.7 Sonnet | 90,000 | **200,000** | | Claude Opus 4.5 | 90,000 | **200,000** | | GPT-4o | 110,000 | **128,000** | ### Testing Added a new test `test_max_token_count_returns_context_window_not_prompt_tokens` that: 1. Deserializes model JSON with distinct `max_context_window_tokens` and `max_prompt_tokens` values 2. Verifies Claude 3.7 Sonnet returns 200,000 (context window), not 90,000 (prompt tokens) 3. Verifies GPT-4o returns 128,000 (context window), not 110,000 (prompt tokens) All existing tests continue to pass: ``` running 4 tests test tests::test_unknown_vendor_resilience ... ok test tests::test_max_token_count_returns_context_window_not_prompt_tokens ... ok test tests::test_resilient_model_schema_deserialize ... ok test result: ok. 4 passed; 0 failed ``` Release Notes: - copilot: Fixed incorrect context window size displayed for GitHub Copilot Chat models in the agent panel.
1 parent c1907c9 commit 13ad175

1 file changed

Lines changed: 56 additions & 1 deletion

File tree

‎crates/copilot_chat/src/copilot_chat.rs‎

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ impl Model {
223223
}
224224

225225
pub fn max_token_count(&self) -> u64 {
226-
self.capabilities.limits.max_prompt_tokens
226+
self.capabilities.limits.max_context_window_tokens as u64
227227
}
228228

229229
pub fn supports_tools(&self) -> bool {
@@ -1038,6 +1038,61 @@ mod tests {
10381038
assert_eq!(schema.data[0].vendor, ModelVendor::Unknown);
10391039
}
10401040

1041+
#[test]
1042+
fn test_max_token_count_returns_context_window_not_prompt_tokens() {
1043+
let json = r#"{
1044+
"data": [
1045+
{
1046+
"billing": { "is_premium": true, "multiplier": 1 },
1047+
"capabilities": {
1048+
"family": "claude-sonnet-4",
1049+
"limits": { "max_context_window_tokens": 200000, "max_output_tokens": 16384, "max_prompt_tokens": 90000 },
1050+
"object": "model_capabilities",
1051+
"supports": { "streaming": true, "tool_calls": true },
1052+
"type": "chat"
1053+
},
1054+
"id": "claude-sonnet-4",
1055+
"is_chat_default": false,
1056+
"is_chat_fallback": false,
1057+
"model_picker_enabled": true,
1058+
"name": "Claude Sonnet 4",
1059+
"object": "model",
1060+
"preview": false,
1061+
"vendor": "Anthropic",
1062+
"version": "claude-sonnet-4"
1063+
},
1064+
{
1065+
"billing": { "is_premium": false, "multiplier": 1 },
1066+
"capabilities": {
1067+
"family": "gpt-4o",
1068+
"limits": { "max_context_window_tokens": 128000, "max_output_tokens": 16384, "max_prompt_tokens": 110000 },
1069+
"object": "model_capabilities",
1070+
"supports": { "streaming": true, "tool_calls": true },
1071+
"type": "chat"
1072+
},
1073+
"id": "gpt-4o",
1074+
"is_chat_default": true,
1075+
"is_chat_fallback": false,
1076+
"model_picker_enabled": true,
1077+
"name": "GPT-4o",
1078+
"object": "model",
1079+
"preview": false,
1080+
"vendor": "Azure OpenAI",
1081+
"version": "gpt-4o"
1082+
}
1083+
],
1084+
"object": "list"
1085+
}"#;
1086+
1087+
let schema: ModelSchema = serde_json::from_str(json).unwrap();
1088+
1089+
// max_token_count() should return context window (200000), not prompt tokens (90000)
1090+
assert_eq!(schema.data[0].max_token_count(), 200000);
1091+
1092+
// GPT-4o should return 128000 (context window), not 110000 (prompt tokens)
1093+
assert_eq!(schema.data[1].max_token_count(), 128000);
1094+
}
1095+
10411096
#[test]
10421097
fn test_models_with_pending_policy_deserialize() {
10431098
// This test verifies that models with policy states other than "enabled"

0 commit comments

Comments
 (0)