fix(providers/anthropic): preserve Anthropic replay fidelity#35
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 81c8a9f59a
ℹ️ 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".
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
|
Upstreaming @ charmbracelet#237 & charmbracelet#238 |
Summary
Anthropic replay is sensitive to exact assistant content block ordering and metadata. When a prior assistant turn contains signed
thinkingorredacted_thinking, replay has to preserve those reasoning blocks and any interleaved provider-executed web search blocks without changing their structure. Our Anthropic adapter had two gaps in that contract: it never emitted aReasoningEndevent forredacted_thinking, and it only surfaced thinking signatures onsignature_deltainstead of also attaching the canonical signature to the finalReasoningEndevent. On the encode path, lossy provider-executedweb_search_tool_resultmetadata could degrade into malformed assistant history.Why this fixes it
ReasoningEndforredacted_thinking, carryingRedactedDataon the final eventReasoningEndfor normal thinking blocksweb_search_tool_resultcannot be reconstructed, drop the matchingserver_tool_usetoo so we do not emit orphan provider blocksWhy this belongs in fantasy
Treating signed reasoning replay as a first-class provider contract leads to a cleaner split of responsibilities.
coder/fantasyis the boundary that translates Anthropic SSE and message parts into fantasy stream parts and Anthropic wire blocks, so provider-specific lifecycle rules and replay invariants should be enforced there. That keeps downstream applications from reimplementing Anthropic quirks like missing redacted end events, signatures that only appear on deltas, or partially reconstructed provider tool blocks. The result is a provider adapter that behaves as though replay fidelity had been a foundational assumption from the start, while applications can keep their own persistence and sanitization logic focused on their own boundaries.Relates to CODAGT-409