From 1c36cf3ea0a32cbd9958874a954181b5582521dd Mon Sep 17 00:00:00 2001 From: yearthmain Date: Wed, 15 Jul 2026 15:03:04 +0800 Subject: [PATCH] fix(kosong): serialize reasoning-only assistant content --- .changeset/fix-reasoning-only-resume.md | 5 +++++ .../kosong/src/providers/openai-legacy.ts | 2 ++ packages/kosong/test/openai-legacy.test.ts | 20 +++++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 .changeset/fix-reasoning-only-resume.md diff --git a/.changeset/fix-reasoning-only-resume.md b/.changeset/fix-reasoning-only-resume.md new file mode 100644 index 0000000000..76a83964ee --- /dev/null +++ b/.changeset/fix-reasoning-only-resume.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Fix resumed reasoning-only sessions with OpenAI-compatible providers. diff --git a/packages/kosong/src/providers/openai-legacy.ts b/packages/kosong/src/providers/openai-legacy.ts index 98e109e891..518832a3bf 100644 --- a/packages/kosong/src/providers/openai-legacy.ts +++ b/packages/kosong/src/providers/openai-legacy.ts @@ -212,6 +212,8 @@ function convertMessage( result.content = nonThinkParts .map((p) => convertContentPart(p)) .filter((p): p is OpenAIContentPart => p !== null); + } else if (message.role === 'assistant' && message.toolCalls.length === 0) { + result.content = ''; } } diff --git a/packages/kosong/test/openai-legacy.test.ts b/packages/kosong/test/openai-legacy.test.ts index 2cd371adea..3bd2611c0f 100644 --- a/packages/kosong/test/openai-legacy.test.ts +++ b/packages/kosong/test/openai-legacy.test.ts @@ -1113,6 +1113,26 @@ describe('OpenAILegacyChatProvider', () => { }); }); + it('includes empty content for reasoning-only assistant messages without tool calls', async () => { + const provider = createProvider({ model: 'deepseek-reasoner' }); + const history: Message[] = [ + { + role: 'assistant', + content: [{ type: 'think', think: 'reasoning before the crash' }], + toolCalls: [], + }, + ]; + + const body = await captureRequestBody(provider, '', [], history); + const messages = body['messages'] as Record[]; + + expect(messages[0]).toEqual({ + role: 'assistant', + content: '', + reasoning_content: 'reasoning before the crash', + }); + }); + it('serializes an explicitly empty ThinkPart to reasoning_content', async () => { const provider = createProvider({ model: 'deepseek-reasoner' }); const history: Message[] = [