Skip to content

fix(kosong): preserve unsigned thinking in anthropic history serialization - #222

Merged
RealKai42 merged 2 commits into
mainfrom
kaiyi/doha
May 29, 2026
Merged

fix(kosong): preserve unsigned thinking in anthropic history serialization#222
RealKai42 merged 2 commits into
mainfrom
kaiyi/doha

Conversation

@RealKai42

Copy link
Copy Markdown
Collaborator

Problem

Multi-step tool use was broken against Anthropic-compatible backends (e.g. Kimi's
Anthropic-protocol endpoint). After the first tool call, the follow-up request failed with:

400 thinking is enabled but reasoning_content is missing in assistant tool call message

The Anthropic provider's convertMessage() dropped any assistant thinking block that had
no signature. That guard was meant for api.anthropic.com (which rejects thinking blocks with
an invalid/empty signature), but it also discarded the thinking streamed by backends that
don't emit a signature_delta. Those backends require the thinking to remain present on a
tool-call turn, so dropping it made every multi-step turn fail.

What changed

convertMessage() now preserves unsigned thinking instead of dropping it, emitting it
without a signature field. The two backends are cleanly partitioned by signature presence,
so no backend switch is needed:

  • api.anthropic.com always supplies a signature -> its history takes the signed branch, unchanged.
  • Anthropic-compatible backends (Kimi) never supply one -> their thinking is now kept,
    fixing the "reasoning_content is missing" failure.

Empty-and-unsigned parts carry no information and are still skipped. The streaming merge
logic (mergeInPlace) was checked and is correct, so it is left untouched -- this is purely
a history-serialization fix.

Verified against both real endpoints: the Kimi Anthropic endpoint now accepts the multi-step
request, while api.anthropic.com behaves exactly as before (it requires a valid signature,
which it always provides). Added regression tests covering unsigned thinking both standalone
and immediately before a tool_use block.

RealKai42 added 2 commits May 29, 2026 21:32
…ation

When converting assistant history to the Anthropic wire format,
convertMessage() dropped any thinking block that had no signature. That
was meant to satisfy api.anthropic.com (which requires a valid signature
on thinking blocks), but it broke Anthropic-compatible backends.

Kimi's Anthropic-protocol endpoint streams thinking without a
signature_delta, yet requires the thinking to be present on a tool-call
turn — once it was dropped, the next request failed with "thinking is
enabled but reasoning_content is missing in assistant tool call message",
making multi-step tool use unusable on those backends.

Preserve unsigned thinking instead, emitting it without a `signature`
field. The two backends are partitioned by signature presence:
api.anthropic.com always supplies a signature (its history takes the
signed branch unchanged), while Kimi never does (its thinking is now
kept). Empty-and-unsigned parts carry nothing and are still skipped.
@changeset-bot

changeset-bot Bot commented May 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f50169b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kosong Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented May 29, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@f50169b
npx https://pkg.pr.new/@moonshot-ai/kimi-code@f50169b

commit: f50169b

@RealKai42
RealKai42 merged commit 13e0fff into main May 29, 2026
7 checks passed
@RealKai42
RealKai42 deleted the kaiyi/doha branch May 29, 2026 13:41

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f50169b367

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +482 to +483
} else if (part.think !== '') {
blocks.push({ type: 'thinking', thinking: part.think } as unknown as ThinkingBlockParam);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate unsigned thinking to compatible backends

When this provider targets api.anthropic.com and the caller supplies history containing an unsigned ThinkPart (for example after restoring or switching from an Anthropic-compatible backend that does not emit signature_delta), this now serializes a thinking block with no signature. Anthropic's extended-thinking flow returns a signature/signature_delta and requires the complete original thinking block to be passed back unchanged (https://platform.claude.com/docs/en/build-with-claude/extended-thinking), so these requests can be rejected where the old code skipped the unsigned block. Please keep the unsigned preservation behind a backend/capability check or otherwise avoid sending unsigned thinking to the official Anthropic API.

Useful? React with 👍 / 👎.

@github-actions github-actions Bot mentioned this pull request May 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant