Bug Description
When using the Custom Endpoint BYOK feature with DeepSeek reasoning models (or similar providers like Moonshot/Minimax that emit reasoning_content without an explicit ID), the first LLM turn succeeds, but any subsequent turn (after a tool call) fails with:
400 {"error":{"message":"The `reasoning_content` in the thinking mode must be passed back to the API.","type":"invalid_request_error",...}}
The Copilot extension already contains logic in OpenAIEndpoint.createRequestBody() to echo back reasoning_content on assistant messages, but this logic is gated on data.id being present. DeepSeek does not send an id alongside reasoning_content, so the echo-back is silently skipped, and DeepSeek rejects the second turn.
This makes Agent mode (multi-turn tool calling) unusable with DeepSeek reasoning models via BYOK.
Version
- VS Code: 1.122 (latest main)
- GitHub Copilot Chat extension: bundled
- OS: all (reproducible on Windows, macOS, Linux)
Steps to Reproduce
- Configure a Custom Endpoint with DeepSeek:
{
"name": "DeepSeek",
"vendor": "customendpoint",
"apiKey": "sk-...",
"apiType": "chat-completions",
"url": "https://api.deepseek.com/chat/completions",
"models": [{
"id": "deepseek-v4-flash",
"toolCalling": true,
"thinking": true,
"maxInputTokens": 128000,
"maxOutputTokens": 8192
}]
}
- Open Chat, select the DeepSeek model
- Send a prompt that triggers tool calling (e.g. "Create a file named
test.txt with some content")
- Observe: first turn succeeds, model returns
reasoning_content + tool call
- After tool executes, second turn is sent
- Observe: HTTP 400 from DeepSeek
Expected Behavior
The reasoning_content from the first turn should be echoed back in the assistant message of the second turn, so DeepSeek accepts the request.
Actual Behavior
The reasoning_content is silently dropped because it has no id, and the second turn fails with HTTP 400.
Logs
2026-05-29 07:10:17.012 [info] message 0 returned. finish reason: [tool_calls]
2026-05-29 07:10:17.019 [info] ccreq:d3c749f5.copilotmd | success | deepseek-v4-flash | 1336ms
2026-05-29 07:10:17.392 [info] Request ID for failed request: 1d4d4316-...
2026-05-29 07:10:17.396 [error] Server error: 400 {"error":{"message":"The `reasoning_content` in the thinking mode must be passed back to the API.","type":"invalid_request_error","param":null,"code":"invalid_request_error"}}
2026-05-29 07:10:17.399 [info] ccreq:0a452385.copilotmd | failed | deepseek-v4-flash | 225ms
Affected Providers
- DeepSeek (V4, V3 reasoning mode)
Any OpenAI-compatible provider that sends reasoning_content without an accompanying id field will hit this issue.
Bug Description
When using the Custom Endpoint BYOK feature with DeepSeek reasoning models (or similar providers like Moonshot/Minimax that emit
reasoning_contentwithout an explicit ID), the first LLM turn succeeds, but any subsequent turn (after a tool call) fails with:The Copilot extension already contains logic in
OpenAIEndpoint.createRequestBody()to echo backreasoning_contenton assistant messages, but this logic is gated ondata.idbeing present. DeepSeek does not send anidalongsidereasoning_content, so the echo-back is silently skipped, and DeepSeek rejects the second turn.This makes Agent mode (multi-turn tool calling) unusable with DeepSeek reasoning models via BYOK.
Version
Steps to Reproduce
{ "name": "DeepSeek", "vendor": "customendpoint", "apiKey": "sk-...", "apiType": "chat-completions", "url": "https://api.deepseek.com/chat/completions", "models": [{ "id": "deepseek-v4-flash", "toolCalling": true, "thinking": true, "maxInputTokens": 128000, "maxOutputTokens": 8192 }] }test.txtwith some content")reasoning_content+ tool callExpected Behavior
The
reasoning_contentfrom the first turn should be echoed back in the assistant message of the second turn, so DeepSeek accepts the request.Actual Behavior
The
reasoning_contentis silently dropped because it has noid, and the second turn fails with HTTP 400.Logs
Affected Providers
Any OpenAI-compatible provider that sends
reasoning_contentwithout an accompanyingidfield will hit this issue.