Loading workspace insights... Statistics interval
7 days30 daysLatest CI Pipeline Executions
b2d3cc13 fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops (#391)
* fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops
- Track thinking per-step via stepId instead of merging into single ThinkingPart
- Capture Anthropic signature_delta and preserve through the full stack
- Server-side TextEngine accumulates thinking + signatures per iteration
- Include thinking blocks in Anthropic message history for multi-turn context
- Add interleaved-thinking-2025-05-14 beta header when thinking is enabled
- Add tests for multi-step thinking, backward compat, and result aggregation
Closes TanStack/ai#340
* ci: apply automated fixes
* fix(ai, ai-anthropic): scope interleaved-thinking betas to beta endpoint; clear stale pendingThinkingStepId
- Move `betas: ['interleaved-thinking-2025-05-14']` out of the shared mapper
and onto the `beta.messages.create` call site in chatStream. Prevents the
non-beta structuredOutput endpoint from receiving an invalid `betas` field
when a thinking budget is configured.
- Clear `pendingThinkingStepId` when a later STEP_STARTED takes the
active-message branch, and also in `resetStreamState`, so a stale pending
id can't misattribute a later STEP_FINISHED's delta to an earlier step.
- Add covering test for the pendingThinkingStepId leak (red-green verified).
* test(e2e), changeset: multi-step thinking scenario and release note
- Add `thinking-multi-step` mock scenario to the e2e harness emitting
STEP_STARTED/STEP_FINISHED pairs for two distinct stepIds with
provider signatures, followed by a text message and RUN_FINISHED.
- Expose thinkingPartCount / thinkingStepIds on the mock chat page via
data-* attributes for assertion.
- Add tests/thinking.spec.ts asserting two ThinkingParts with distinct
stepIds and matching signatures are produced (pre-PR behavior merged
them into a single part).
- Add .changeset/thinking-blocks-per-step.md bumping @tanstack/ai,
@tanstack/ai-anthropic, and @tanstack/ai-client.
* fix(ai): consume pending stepId in REASONING_MESSAGE_CONTENT
When STEP_STARTED arrives before the assistant message exists, its
stepId is stashed in pendingThinkingStepId. handleStepFinishedEvent
already consumes it, but handleReasoningMessageContentEvent did not,
so reasoning deltas were keyed by the reasoning messageId and the
matching signature from STEP_FINISHED landed on a different
ThinkingPart. With Anthropic's interleaved thinking around tool calls
this produced two ThinkingParts per block (one unsigned content, one
signed empty). Consume the pending stepId here too so both event
paths attribute to the same step.
* ci: apply automated fixes
* refactor(ai): extract consumePendingThinkingStep helper
Both handleStepFinishedEvent and handleReasoningMessageContentEvent
need to promote a pending stepId from a STEP_STARTED that arrived
before the assistant message existed. Pull the shared logic into a
small private helper instead of duplicating it.
* fix(ai-anthropic): wrap signed STEP_FINISHED yield in asChunk
The bare yield bypassed the file's existing StreamChunk cast helper,
so after the merge from main StepFinishedEvent now extends the stricter
AG-UI base (requires stepName, no signature) and CI failed to build.
Use asChunk like every other yield in this generator and add stepName.
* test(ai): cover multi-turn anthropic reasoning
* chore: adjust thinking callback changeset bump
* fix(ai): satisfy lint for tool name fallback
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Alem Tuzlak <t.zlak@hotmail.com> d3275020 fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops (#391)
* fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops
- Track thinking per-step via stepId instead of merging into single ThinkingPart
- Capture Anthropic signature_delta and preserve through the full stack
- Server-side TextEngine accumulates thinking + signatures per iteration
- Include thinking blocks in Anthropic message history for multi-turn context
- Add interleaved-thinking-2025-05-14 beta header when thinking is enabled
- Add tests for multi-step thinking, backward compat, and result aggregation
Closes TanStack/ai#340
* ci: apply automated fixes
* fix(ai, ai-anthropic): scope interleaved-thinking betas to beta endpoint; clear stale pendingThinkingStepId
- Move `betas: ['interleaved-thinking-2025-05-14']` out of the shared mapper
and onto the `beta.messages.create` call site in chatStream. Prevents the
non-beta structuredOutput endpoint from receiving an invalid `betas` field
when a thinking budget is configured.
- Clear `pendingThinkingStepId` when a later STEP_STARTED takes the
active-message branch, and also in `resetStreamState`, so a stale pending
id can't misattribute a later STEP_FINISHED's delta to an earlier step.
- Add covering test for the pendingThinkingStepId leak (red-green verified).
* test(e2e), changeset: multi-step thinking scenario and release note
- Add `thinking-multi-step` mock scenario to the e2e harness emitting
STEP_STARTED/STEP_FINISHED pairs for two distinct stepIds with
provider signatures, followed by a text message and RUN_FINISHED.
- Expose thinkingPartCount / thinkingStepIds on the mock chat page via
data-* attributes for assertion.
- Add tests/thinking.spec.ts asserting two ThinkingParts with distinct
stepIds and matching signatures are produced (pre-PR behavior merged
them into a single part).
- Add .changeset/thinking-blocks-per-step.md bumping @tanstack/ai,
@tanstack/ai-anthropic, and @tanstack/ai-client.
* fix(ai): consume pending stepId in REASONING_MESSAGE_CONTENT
When STEP_STARTED arrives before the assistant message exists, its
stepId is stashed in pendingThinkingStepId. handleStepFinishedEvent
already consumes it, but handleReasoningMessageContentEvent did not,
so reasoning deltas were keyed by the reasoning messageId and the
matching signature from STEP_FINISHED landed on a different
ThinkingPart. With Anthropic's interleaved thinking around tool calls
this produced two ThinkingParts per block (one unsigned content, one
signed empty). Consume the pending stepId here too so both event
paths attribute to the same step.
* ci: apply automated fixes
* refactor(ai): extract consumePendingThinkingStep helper
Both handleStepFinishedEvent and handleReasoningMessageContentEvent
need to promote a pending stepId from a STEP_STARTED that arrived
before the assistant message existed. Pull the shared logic into a
small private helper instead of duplicating it.
* fix(ai-anthropic): wrap signed STEP_FINISHED yield in asChunk
The bare yield bypassed the file's existing StreamChunk cast helper,
so after the merge from main StepFinishedEvent now extends the stricter
AG-UI base (requires stepName, no signature) and CI failed to build.
Use asChunk like every other yield in this generator and add stepName.
* test(ai): cover multi-turn anthropic reasoning
* chore: adjust thinking callback changeset bump
* fix(ai): satisfy lint for tool name fallback
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Alem Tuzlak <t.zlak@hotmail.com> d3275020 fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops (#391)
* fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops
- Track thinking per-step via stepId instead of merging into single ThinkingPart
- Capture Anthropic signature_delta and preserve through the full stack
- Server-side TextEngine accumulates thinking + signatures per iteration
- Include thinking blocks in Anthropic message history for multi-turn context
- Add interleaved-thinking-2025-05-14 beta header when thinking is enabled
- Add tests for multi-step thinking, backward compat, and result aggregation
Closes TanStack/ai#340
* ci: apply automated fixes
* fix(ai, ai-anthropic): scope interleaved-thinking betas to beta endpoint; clear stale pendingThinkingStepId
- Move `betas: ['interleaved-thinking-2025-05-14']` out of the shared mapper
and onto the `beta.messages.create` call site in chatStream. Prevents the
non-beta structuredOutput endpoint from receiving an invalid `betas` field
when a thinking budget is configured.
- Clear `pendingThinkingStepId` when a later STEP_STARTED takes the
active-message branch, and also in `resetStreamState`, so a stale pending
id can't misattribute a later STEP_FINISHED's delta to an earlier step.
- Add covering test for the pendingThinkingStepId leak (red-green verified).
* test(e2e), changeset: multi-step thinking scenario and release note
- Add `thinking-multi-step` mock scenario to the e2e harness emitting
STEP_STARTED/STEP_FINISHED pairs for two distinct stepIds with
provider signatures, followed by a text message and RUN_FINISHED.
- Expose thinkingPartCount / thinkingStepIds on the mock chat page via
data-* attributes for assertion.
- Add tests/thinking.spec.ts asserting two ThinkingParts with distinct
stepIds and matching signatures are produced (pre-PR behavior merged
them into a single part).
- Add .changeset/thinking-blocks-per-step.md bumping @tanstack/ai,
@tanstack/ai-anthropic, and @tanstack/ai-client.
* fix(ai): consume pending stepId in REASONING_MESSAGE_CONTENT
When STEP_STARTED arrives before the assistant message exists, its
stepId is stashed in pendingThinkingStepId. handleStepFinishedEvent
already consumes it, but handleReasoningMessageContentEvent did not,
so reasoning deltas were keyed by the reasoning messageId and the
matching signature from STEP_FINISHED landed on a different
ThinkingPart. With Anthropic's interleaved thinking around tool calls
this produced two ThinkingParts per block (one unsigned content, one
signed empty). Consume the pending stepId here too so both event
paths attribute to the same step.
* ci: apply automated fixes
* refactor(ai): extract consumePendingThinkingStep helper
Both handleStepFinishedEvent and handleReasoningMessageContentEvent
need to promote a pending stepId from a STEP_STARTED that arrived
before the assistant message existed. Pull the shared logic into a
small private helper instead of duplicating it.
* fix(ai-anthropic): wrap signed STEP_FINISHED yield in asChunk
The bare yield bypassed the file's existing StreamChunk cast helper,
so after the merge from main StepFinishedEvent now extends the stricter
AG-UI base (requires stepName, no signature) and CI failed to build.
Use asChunk like every other yield in this generator and add stepName.
* test(ai): cover multi-turn anthropic reasoning
* chore: adjust thinking callback changeset bump
* fix(ai): satisfy lint for tool name fallback
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Alem Tuzlak <t.zlak@hotmail.com> b2d3cc13 fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops (#391)
* fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops
- Track thinking per-step via stepId instead of merging into single ThinkingPart
- Capture Anthropic signature_delta and preserve through the full stack
- Server-side TextEngine accumulates thinking + signatures per iteration
- Include thinking blocks in Anthropic message history for multi-turn context
- Add interleaved-thinking-2025-05-14 beta header when thinking is enabled
- Add tests for multi-step thinking, backward compat, and result aggregation
Closes TanStack/ai#340
* ci: apply automated fixes
* fix(ai, ai-anthropic): scope interleaved-thinking betas to beta endpoint; clear stale pendingThinkingStepId
- Move `betas: ['interleaved-thinking-2025-05-14']` out of the shared mapper
and onto the `beta.messages.create` call site in chatStream. Prevents the
non-beta structuredOutput endpoint from receiving an invalid `betas` field
when a thinking budget is configured.
- Clear `pendingThinkingStepId` when a later STEP_STARTED takes the
active-message branch, and also in `resetStreamState`, so a stale pending
id can't misattribute a later STEP_FINISHED's delta to an earlier step.
- Add covering test for the pendingThinkingStepId leak (red-green verified).
* test(e2e), changeset: multi-step thinking scenario and release note
- Add `thinking-multi-step` mock scenario to the e2e harness emitting
STEP_STARTED/STEP_FINISHED pairs for two distinct stepIds with
provider signatures, followed by a text message and RUN_FINISHED.
- Expose thinkingPartCount / thinkingStepIds on the mock chat page via
data-* attributes for assertion.
- Add tests/thinking.spec.ts asserting two ThinkingParts with distinct
stepIds and matching signatures are produced (pre-PR behavior merged
them into a single part).
- Add .changeset/thinking-blocks-per-step.md bumping @tanstack/ai,
@tanstack/ai-anthropic, and @tanstack/ai-client.
* fix(ai): consume pending stepId in REASONING_MESSAGE_CONTENT
When STEP_STARTED arrives before the assistant message exists, its
stepId is stashed in pendingThinkingStepId. handleStepFinishedEvent
already consumes it, but handleReasoningMessageContentEvent did not,
so reasoning deltas were keyed by the reasoning messageId and the
matching signature from STEP_FINISHED landed on a different
ThinkingPart. With Anthropic's interleaved thinking around tool calls
this produced two ThinkingParts per block (one unsigned content, one
signed empty). Consume the pending stepId here too so both event
paths attribute to the same step.
* ci: apply automated fixes
* refactor(ai): extract consumePendingThinkingStep helper
Both handleStepFinishedEvent and handleReasoningMessageContentEvent
need to promote a pending stepId from a STEP_STARTED that arrived
before the assistant message existed. Pull the shared logic into a
small private helper instead of duplicating it.
* fix(ai-anthropic): wrap signed STEP_FINISHED yield in asChunk
The bare yield bypassed the file's existing StreamChunk cast helper,
so after the merge from main StepFinishedEvent now extends the stricter
AG-UI base (requires stepName, no signature) and CI failed to build.
Use asChunk like every other yield in this generator and add stepName.
* test(ai): cover multi-turn anthropic reasoning
* chore: adjust thinking callback changeset bump
* fix(ai): satisfy lint for tool name fallback
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Alem Tuzlak <t.zlak@hotmail.com> b2d3cc13 fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops (#391)
* fix(ai, ai-anthropic): thinking blocks missing on turn 2+ in tool loops
- Track thinking per-step via stepId instead of merging into single ThinkingPart
- Capture Anthropic signature_delta and preserve through the full stack
- Server-side TextEngine accumulates thinking + signatures per iteration
- Include thinking blocks in Anthropic message history for multi-turn context
- Add interleaved-thinking-2025-05-14 beta header when thinking is enabled
- Add tests for multi-step thinking, backward compat, and result aggregation
Closes TanStack/ai#340
* ci: apply automated fixes
* fix(ai, ai-anthropic): scope interleaved-thinking betas to beta endpoint; clear stale pendingThinkingStepId
- Move `betas: ['interleaved-thinking-2025-05-14']` out of the shared mapper
and onto the `beta.messages.create` call site in chatStream. Prevents the
non-beta structuredOutput endpoint from receiving an invalid `betas` field
when a thinking budget is configured.
- Clear `pendingThinkingStepId` when a later STEP_STARTED takes the
active-message branch, and also in `resetStreamState`, so a stale pending
id can't misattribute a later STEP_FINISHED's delta to an earlier step.
- Add covering test for the pendingThinkingStepId leak (red-green verified).
* test(e2e), changeset: multi-step thinking scenario and release note
- Add `thinking-multi-step` mock scenario to the e2e harness emitting
STEP_STARTED/STEP_FINISHED pairs for two distinct stepIds with
provider signatures, followed by a text message and RUN_FINISHED.
- Expose thinkingPartCount / thinkingStepIds on the mock chat page via
data-* attributes for assertion.
- Add tests/thinking.spec.ts asserting two ThinkingParts with distinct
stepIds and matching signatures are produced (pre-PR behavior merged
them into a single part).
- Add .changeset/thinking-blocks-per-step.md bumping @tanstack/ai,
@tanstack/ai-anthropic, and @tanstack/ai-client.
* fix(ai): consume pending stepId in REASONING_MESSAGE_CONTENT
When STEP_STARTED arrives before the assistant message exists, its
stepId is stashed in pendingThinkingStepId. handleStepFinishedEvent
already consumes it, but handleReasoningMessageContentEvent did not,
so reasoning deltas were keyed by the reasoning messageId and the
matching signature from STEP_FINISHED landed on a different
ThinkingPart. With Anthropic's interleaved thinking around tool calls
this produced two ThinkingParts per block (one unsigned content, one
signed empty). Consume the pending stepId here too so both event
paths attribute to the same step.
* ci: apply automated fixes
* refactor(ai): extract consumePendingThinkingStep helper
Both handleStepFinishedEvent and handleReasoningMessageContentEvent
need to promote a pending stepId from a STEP_STARTED that arrived
before the assistant message existed. Pull the shared logic into a
small private helper instead of duplicating it.
* fix(ai-anthropic): wrap signed STEP_FINISHED yield in asChunk
The bare yield bypassed the file's existing StreamChunk cast helper,
so after the merge from main StepFinishedEvent now extends the stricter
AG-UI base (requires stepName, no signature) and CI failed to build.
Use asChunk like every other yield in this generator and add stepName.
* test(ai): cover multi-turn anthropic reasoning
* chore: adjust thinking callback changeset bump
* fix(ai): satisfy lint for tool name fallback
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Alem Tuzlak <t.zlak@hotmail.com>