Replay assistant reasoning as a content part for DeepSeek thinking mode
Forward each assistant reasoning part to /alpha/generate as
{type:"reasoning", text, signature?} instead of dropping it. DeepSeek
thinking mode rejects any request carrying tools whose prior assistant
turns omit their reasoning, so multi-turn tool-call conversations 400'd.
Only real (non-empty) reasoning is forwarded; no fabricated injection.
Update README and AGENTS.md accordingly.
This commit is contained in:
parent
0b1f933ead
commit
ab760fb876
@ -102,9 +102,14 @@ These are load-bearing. Breaking one causes silent failures in opencode.
|
||||
7. **`supportedUrls` is `{}` and stays empty.** CommandsCode URLs are not fetched by the SDK.
|
||||
8. **Redact before surfacing errors.** Any upstream error text passed to the client must go through
|
||||
`redact()`.
|
||||
9. **`file://` npm specs bypass install.** opencode imports `dist/index.js` directly, so the repo
|
||||
9. **Replay assistant reasoning as a `{type:"reasoning"}` content part.** DeepSeek thinking mode
|
||||
rejects any request carrying `tools` whose prior assistant turns omit their reasoning. In
|
||||
`transform.ts`, forward each assistant `reasoning` part as `{type:"reasoning", text, signature?}`;
|
||||
do not drop it and do not fabricate empty reasoning. `server.py` predates this requirement and is
|
||||
not the guide here.
|
||||
10. **`file://` npm specs bypass install.** opencode imports `dist/index.js` directly, so the repo
|
||||
must be rebuilt for opencode to see source changes.
|
||||
10. **`/models` is config-driven, not provider-driven.** opencode builds the model list from
|
||||
11. **`/models` is config-driven, not provider-driven.** opencode builds the model list from
|
||||
`provider.commandcode.models` in `opencode.json` and never asks a custom `file://` provider to
|
||||
discover models (only internal providers can register `discoverModels`). Refresh the map with
|
||||
`npm run sync-models`; do not expect a discovery hook in `src/` to populate it.
|
||||
|
||||
@ -171,6 +171,7 @@ useful for diagnosing model selection, retry, tool-call, and finish-reason issue
|
||||
| Non-streaming (`doGenerate`) | Yes — buffers the stream internally |
|
||||
| Text deltas | Yes |
|
||||
| Reasoning deltas | Yes — emitted as `reasoning-start` / `reasoning-delta` / `reasoning-end` |
|
||||
| Reasoning replay | Yes — assistant `reasoning` parts are sent back as `{type:"reasoning"}` content parts (required by DeepSeek thinking mode when tools are present); `signature` is forwarded when present |
|
||||
| Tool calls | Yes — `tool-input-start` / `tool-input-delta` / `tool-input-end` / `tool-call` |
|
||||
| Tool results | Yes — paired results are replayed; unpaired ids are dropped |
|
||||
| Multiple images (vision) | Yes — `data:` URIs, raw base64, `Uint8Array`, and remote URLs |
|
||||
|
||||
@ -193,6 +193,15 @@ export function transform(options: LanguageModelV3CallOptions, modelId: string):
|
||||
for (const part of message.content) {
|
||||
if (part.type === "text" && part.text) {
|
||||
parts.push({ type: "text", text: part.text });
|
||||
} else if (part.type === "reasoning") {
|
||||
// DeepSeek thinking mode requires prior assistant reasoning to be passed
|
||||
// back when `tools` are present; CommandCode reads it as a content part.
|
||||
const reasoning = part as { text?: string; signature?: string };
|
||||
if (reasoning.text) {
|
||||
const item: ContentPart = { type: "reasoning", text: reasoning.text };
|
||||
if (reasoning.signature) item["signature"] = reasoning.signature;
|
||||
parts.push(item);
|
||||
}
|
||||
} else if (part.type === "tool-call") {
|
||||
if (!paired.has(part.toolCallId)) continue;
|
||||
parts.push({
|
||||
@ -202,7 +211,6 @@ export function transform(options: LanguageModelV3CallOptions, modelId: string):
|
||||
input: (part as { input?: unknown }).input ?? {},
|
||||
});
|
||||
}
|
||||
// reasoning parts are not replayed upstream
|
||||
}
|
||||
if (parts.length) messages.push({ role: "assistant", content: parts });
|
||||
continue;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user