Custom Endpoint Models (Messages API) Never Send `thinking` Parameter
@vritant24 is already working on this.
Since May 29, 2026.
Assessment
This issue has not been assessed yet.
Description
Custom Endpoint Models (Messages API) Never Send thinking Parameter
Environment
- VS Code: 1.122.0-insider (build
4459d58b54) - Copilot Extension: v0.50.2026052902 (GitHub Copilot Chat)
- OS: Windows 11 (23H2)
- Extensions: Issue reproduces with all non-Copilot extensions disabled
- Custom Endpoint: Anthropic Messages API via proxy (
/v1/messages) - Dev Tools Console: No errors related to this issue (requests succeed with 200 OK, but response lacks thinking content)
Bug Summary
When using a custom endpoint model configured with apiType: "messages", the thinking parameter is never included in the request body sent to the upstream API - even when the model is configured with "thinking": true and "adaptiveThinking": true in chatLanguageModels.json. The model responds as if extended thinking is not enabled because the parameter is absent from the wire request.
In contrast, the built-in GitHub-hosted Claude models (e.g. claude-opus-4.6 via panel/editAgent) correctly send thinking: {type: "adaptive", display: "summarized"} and receive thinking blocks in responses.
Reproduction Steps
- Configure a custom endpoint model in VS Code settings with Messages API:
{
"github.copilot.chat.models": [
{
"name": "my-anthropic-proxy",
"vendor": "customendpoint",
"apiKey": "...",
"apiType": "messages",
"models": [
{
"id": "claude-opus-4-6",
"name": "Claude Opus 4.6",
"url": "https://my-proxy.example.com/v1/messages",
"toolCalling": true,
"vision": true,
"thinking": true,
"adaptiveThinking": true,
"maxInputTokens": 200000,
"maxOutputTokens": 128000,
"supportsReasoningEffort": ["low", "medium", "high"]
}
]
}
]
}
- Start a chat using the custom endpoint model.
- Inspect the HTTP request body sent to the proxy (e.g. via proxy logs).
Expected: Request body includes "thinking": {"type": "adaptive"} (or "adaptive" with display: "summarized").
Actual: Request body has no thinking field. The model responds without extended thinking.
Root Cause Analysis
Note: The following analysis is based on observing the request body at the proxy and inspecting the bundled
extension.jsto understand the code paths involved. Variable names are from the minified bundle.
The issue is caused by two gaps in the code path for custom endpoint models:
Issue 1: copilotLanguageModelWrapper does not pass enableThinking
When a custom endpoint model is invoked via the VS Code Language Model API (extensions calling lm.sendRequest()), the request flows through copilotLanguageModelWrapper. This wrapper constructs a modelCapabilities object that is passed to the internal request pipeline:
// In copilotLanguageModelWrapper (approx. offset 13807981 in extension.js)
modelCapabilities: {
reasoningEffort: typeof o.modelConfiguration?.reasoningEffort == "string"
? o.modelConfiguration.reasoningEffort
: void 0
}
Notice that enableThinking is not included in modelCapabilities. This is the first gate that prevents thinking.
Issue 2: LSn (Messages API body builder) requires enableThinking to set thinking
The function that constructs the Anthropic Messages API request body (minified as LSn, approx. offset 13555239) contains:
if (e.modelCapabilities?.enableThinking) {
if (r.supportsAdaptiveThinking)
m = { type: "adaptive", display: "summarized" };
else if (r.maxThinkingBudget && r.minThinkingBudget) {
let O = e.postOptions.max_tokens ?? 1024;
let Q = r.minThinkingBudget ?? 1024;
let F = 16e3 < Q ? Q : 16e3;
let B = r.maxThinkingBudget ?? 32e3;
let M = Math.min(B, O - 1, F);
M && (m = { type: "enabled", budget_tokens: M });
}
// No else clause — m stays undefined if neither condition matches
}
Since enableThinking is never set (Issue 1), this entire block is skipped and m (the thinking config) remains undefined. Even if enableThinking were passed, the function has no fallback: if supportsAdaptiveThinking is falsy and maxThinkingBudget/minThinkingBudget are not set, m still stays undefined.
Contrast with built-in agent path
The built-in agent (panel/editAgent) uses a separate code path that constructs the request body directly:
// panel/editAgent path (approx. offset 13825471)
thinking: Q ? { type: "adaptive" } : P ? { type: "enabled", budget_tokens: P } : void 0
Here Q is derived from _knownModels (populated for GitHub-hosted models). For custom endpoints, _knownModels is void 0, so this also falls through to void 0.
Data Flow Summary
Custom Endpoint Model Request Flow:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
copilotLanguageModelWrapper
→ modelCapabilities: { reasoningEffort: "high" } ← missing enableThinking!
→ makeChatRequest2()
→ chatMLFetcher.fetchOne()
→ endpoint.createRequestBody(e)
→ LSn(n, e, model, endpoint)
→ if (e.modelCapabilities?.enableThinking) ← FALSE, skipped
→ thinking: m ← m is undefined
→ Request body: { model, messages, ..., thinking: undefined }
Built-in GitHub Model Request Flow:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
panel/editAgent
→ Reads _knownModels for model capabilities
→ Q = supportsAdaptiveThinking from _knownModels
→ thinking: Q ? {type:"adaptive"} : P ? {type:"enabled",...} : void 0
→ Request body: { ..., thinking: {type:"adaptive", display:"summarized"} }
Proposed Fix
Fix 1: Pass enableThinking from model configuration
In copilotLanguageModelWrapper, include the model's thinking capability:
modelCapabilities: {
reasoningEffort: typeof o.modelConfiguration?.reasoningEffort == "string"
? o.modelConfiguration.reasoningEffort
: void 0,
enableThinking: !!endpoint.supportsThinking || !!endpoint.supportsAdaptiveThinking
}
Fix 2: Add fallback in LSn for models that declare thinking: true but lack budget metadata
if (e.modelCapabilities?.enableThinking) {
if (r.supportsAdaptiveThinking)
m = { type: "adaptive", display: "summarized" };
else if (r.maxThinkingBudget && r.minThinkingBudget) {
// ... existing budget logic ...
} else {
// Fallback: if model declares thinking support but has no
// adaptive/budget metadata, default to adaptive
m = { type: "adaptive" };
}
}
Fix 3 (panel/editAgent path): Respect user config thinking: true
The ternary that gates thinking on _knownModels should also check the endpoint's declared capabilities:
thinking: Q ? { type: "adaptive" }
: P ? { type: "enabled", budget_tokens: P }
: endpoint.supportsAdaptiveThinking ? { type: "adaptive" }
: void 0
Impact
This affects all users of custom endpoint models (BYOK/enterprise proxy setups) who configure Anthropic-compatible endpoints with extended thinking. The model config correctly declares thinking: true and adaptiveThinking: true, but these values are never used in the request body construction for the copilotLanguageModelWrapper code path.
Workaround
Manually patching the minified extension.js to (1) add enableThinking: true to the wrapper's modelCapabilities and (2) add an else m = {type: "adaptive"} fallback in the Messages API body builder restores thinking for custom endpoints. This must be reapplied after every VS Code update.
Related
- Custom endpoint model configuration:
apiType: "messages"withthinking: true - The
supportsAdaptiveThinkingproperty IS correctly resolved from user config →vD()→capabilities.supports.adaptive_thinking→ endpoint property. The gap is only that it's never consulted by the wrapper/request builder.
Checklist
- Searched existing issues — no matching issue found for custom endpoint + thinking
- Reproduced with all non-Copilot extensions disabled
- Minimal config provided to reproduce
- Filed against
microsoft/vscode(Copilot extension is bundled in VS Code;vscode-copilot-releaseis archived)
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.9k
- PR merge metrics
- PR metrics pending
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from microsoft/vscode
-
testplan-item
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
new release
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
testplan-item
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
testplan-item
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
All issues in microsoft/vscode
Similar issues
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 76/100
-
code-quality refactoring
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
github/gh-aw-firewall#8816 ·
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
langchain-ai/deepagents#6450 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
vercel/react-tweet#225 ·