mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 03:40:42 +00:00
fix(deepseek): backfill v4 assistant reasoning replay
This commit is contained in:
@@ -2,6 +2,7 @@ import type { StreamFn } from "@mariozechner/pi-agent-core";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
buildCopilotDynamicHeaders,
|
||||
createDeepSeekV4OpenAICompatibleThinkingWrapper,
|
||||
createHtmlEntityToolCallArgumentDecodingWrapper,
|
||||
createAnthropicThinkingPrefillPayloadWrapper,
|
||||
createPayloadPatchStreamWrapper,
|
||||
@@ -104,6 +105,37 @@ describe("isOpenAICompatibleThinkingEnabled", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("createDeepSeekV4OpenAICompatibleThinkingWrapper", () => {
|
||||
it("backfills reasoning_content on every replayed assistant message when thinking is enabled", () => {
|
||||
const payload = {
|
||||
messages: [
|
||||
{ role: "user", content: "read file" },
|
||||
{ role: "assistant", tool_calls: [{ id: "call_1", name: "read" }] },
|
||||
{ role: "tool", content: "ok" },
|
||||
{ role: "assistant", content: "done" },
|
||||
{ role: "assistant", content: "kept", reasoning_content: "native reasoning" },
|
||||
],
|
||||
};
|
||||
const baseStreamFn: StreamFn = (_model, _context, options) => {
|
||||
options?.onPayload?.(payload as never, _model as never);
|
||||
return {} as ReturnType<StreamFn>;
|
||||
};
|
||||
|
||||
const wrapped = createDeepSeekV4OpenAICompatibleThinkingWrapper({
|
||||
baseStreamFn,
|
||||
thinkingLevel: "high",
|
||||
shouldPatchModel: () => true,
|
||||
});
|
||||
void wrapped?.({} as never, {} as never, {});
|
||||
|
||||
expect(payload.messages[0]).not.toHaveProperty("reasoning_content");
|
||||
expect(payload.messages[1]).toHaveProperty("reasoning_content", "");
|
||||
expect(payload.messages[2]).not.toHaveProperty("reasoning_content");
|
||||
expect(payload.messages[3]).toHaveProperty("reasoning_content", "");
|
||||
expect(payload.messages[4]).toHaveProperty("reasoning_content", "native reasoning");
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildCopilotDynamicHeaders", () => {
|
||||
it("matches Copilot IDE-style request headers without the legacy Openai-Intent", () => {
|
||||
expect(
|
||||
|
||||
@@ -259,7 +259,7 @@ function stripDeepSeekV4ReasoningContent(payload: Record<string, unknown>): void
|
||||
}
|
||||
}
|
||||
|
||||
function ensureDeepSeekV4ToolCallReasoningContent(payload: Record<string, unknown>): void {
|
||||
function ensureDeepSeekV4AssistantReasoningContent(payload: Record<string, unknown>): void {
|
||||
if (!Array.isArray(payload.messages)) {
|
||||
return;
|
||||
}
|
||||
@@ -268,7 +268,7 @@ function ensureDeepSeekV4ToolCallReasoningContent(payload: Record<string, unknow
|
||||
continue;
|
||||
}
|
||||
const record = message as Record<string, unknown>;
|
||||
if (record.role !== "assistant" || !Array.isArray(record.tool_calls)) {
|
||||
if (record.role !== "assistant") {
|
||||
continue;
|
||||
}
|
||||
if (!("reasoning_content" in record)) {
|
||||
@@ -302,7 +302,7 @@ export function createDeepSeekV4OpenAICompatibleThinkingWrapper(params: {
|
||||
|
||||
payload.thinking = { type: "enabled" };
|
||||
payload.reasoning_effort = resolveDeepSeekV4ReasoningEffort(params.thinkingLevel);
|
||||
ensureDeepSeekV4ToolCallReasoningContent(payload);
|
||||
ensureDeepSeekV4AssistantReasoningContent(payload);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user