Skip to content

fix(ai-client): re-evaluate continuation after chained tool approvals#347

Merged
jherr merged 4 commits intomainfrom
multiple-approvals
Mar 6, 2026
Merged

fix(ai-client): re-evaluate continuation after chained tool approvals#347
jherr merged 4 commits intomainfrom
multiple-approvals

Conversation

@jherr
Copy link
Contributor

@jherr jherr commented Mar 6, 2026

Summary

  • Fixes a bug where a second tool approval arriving while a continuation stream is already in progress gets silently dropped, preventing chained approval flows from completing
  • Adds a continuationSkipped flag that triggers a re-evaluation of checkForContinuation once the active stream finishes
  • Adds a comprehensive test covering the chained approval scenario

Test plan

  • Added unit test should continue after second approval arrives during active continuation stream
  • Run pnpm test:lib in packages/typescript/ai-client
  • Verify existing tests still pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Chained tool approvals now correctly handle a second approval received during an active continuation stream instead of dropping it.
  • Tests

    • Added end-to-end tests covering multi-stream approval workflows with interleaved approvals and stream pause/resume behavior.
  • Documentation

    • New architecture doc detailing approval-flow processing, lifecycles, stream protocol, and continuation behavior.
  • Chores

    • Added a changeset for a patch release.

jherr and others added 2 commits March 6, 2026 11:10
When a second tool approval arrives while a continuation stream is
already in progress, the checkForContinuation call is skipped due to
the continuationPending guard. This adds a continuationSkipped flag so
that, once the active stream finishes, the client re-checks whether
another continuation is needed, ensuring chained approval flows
complete correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4297374c-8eb9-4fbe-b051-ba54cbc764f0

📥 Commits

Reviewing files that changed from the base of the PR and between b62378f and 3370830.

📒 Files selected for processing (1)
  • packages/typescript/ai-client/src/chat-client.ts

📝 Walkthrough

Walkthrough

Adds handling for chained tool approvals by introducing a continuationSkipped flag and changing stream continuation logic in ChatClient; includes a new test exercising interleaved approvals, a test helper to emit approval-requested stream chunks, an architecture doc, and a changeset entry.

Changes

Cohort / File(s) Summary
Changeset Documentation
.changeset/chained-approvals-fix.md
Patch-level changeset added for @tanstack/ai-client documenting the chained tool approvals fix.
ChatClient Logic
packages/typescript/ai-client/src/chat-client.ts
Adds private continuationSkipped: boolean; changes streamResponse() return type from Promise<void>Promise<boolean>; updates checkForContinuation and post-stream logic to mark skipped checks when continuation is pending and to re-run continuation after stream completion.
Approval Test Suite
packages/typescript/ai-client/tests/chat-client.test.ts
Adds "chained tool approvals" test that simulates multi-stream workflow with two consecutive tool calls requiring approvals mid-stream, uses a custom ConnectionAdapter to pause/resume streams, and asserts three streams plus final assistant text.
Test Utilities
packages/typescript/ai-client/tests/test-utils.ts
Adds exported createApprovalToolCallChunks(...) helper to generate AG-UI formatted stream chunks including approval-requested custom events with approvalId.
Architecture Docs
docs/architecture/approval-flow-processing.md
New document describing approval flow processing, state machine, event formats, flags (continuationPending, continuationSkipped), single and chained approval lifecycles, and relevant source mappings.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    rect rgba(200,230,250,0.5)
    participant ConnectionAdapter
    participant ChatClient
    participant ApprovalUI
    participant ToolRuntime
    end
    ConnectionAdapter->>+ChatClient: stream chunks (tool call start / approval-requested)
    ChatClient->>+ApprovalUI: emit approval request
    ApprovalUI-->>-ChatClient: user approves (may occur during active stream)
    alt continuationPending true
      ChatClient-->>ChatClient: set continuationSkipped = true
      Note right of ChatClient: wait for stream to finish
    end
    ChatClient->>+ToolRuntime: continue / invoke next tool (shouldAutoSend)
    ToolRuntime-->>-ChatClient: stream chunks (tool output / run_finished)
    ChatClient->>ChatClient: if continuationSkipped -> clear flag and re-run checkForContinuation
    ChatClient->>+ToolRuntime: final assistant generation (if any)
    ToolRuntime-->>-ChatClient: final assistant text
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through streams both wide and deep,
Found approvals waking from their sleep.
I flagged the skips that hid mid-run,
So chained approvals won't be shunned.
Now flows resume — a joyful hop!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main fix: re-evaluating continuation logic after chained tool approvals, which is the core change across the modified files.
Description check ✅ Passed The PR description covers the main changes, test additions, and includes a test plan section, but does not include the required checklist items or changeset documentation mentioned in the template.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch multiple-approvals

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Mar 6, 2026

View your CI Pipeline Execution ↗ for commit 3370830

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 1m 57s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 56s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-06 21:57:50 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 6, 2026

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai@347

@tanstack/ai-anthropic

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-anthropic@347

@tanstack/ai-client

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-client@347

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-devtools-core@347

@tanstack/ai-fal

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-fal@347

@tanstack/ai-gemini

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-gemini@347

@tanstack/ai-grok

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-grok@347

@tanstack/ai-groq

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-groq@347

@tanstack/ai-ollama

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-ollama@347

@tanstack/ai-openai

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-openai@347

@tanstack/ai-openrouter

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-openrouter@347

@tanstack/ai-preact

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-preact@347

@tanstack/ai-react

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-react@347

@tanstack/ai-react-ui

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-react-ui@347

@tanstack/ai-solid

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-solid@347

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-solid-ui@347

@tanstack/ai-svelte

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-svelte@347

@tanstack/ai-vue

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-vue@347

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-vue-ui@347

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/preact-ai-devtools@347

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/react-ai-devtools@347

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/solid-ai-devtools@347

commit: bcebc48

Copy link
Contributor Author

@jherr jherr left a comment

Choose a reason for hiding this comment

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

Fix for mulitool approvals

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/typescript/ai-client/tests/chat-client.test.ts (1)

3-10: ⚠️ Potential issue | 🟡 Minor

Sort the ./test-utils named imports to satisfy sort-imports.

This specifier list is out of alphabetical order, so ESLint will fail on the new import.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/typescript/ai-client/tests/chat-client.test.ts` around lines 3 - 10,
The named imports from './test-utils' are not alphabetized; reorder the
specifier list so it is sorted alphabetically (e.g.,
createApprovalToolCallChunks, createCustomEventChunks,
createMockConnectionAdapter, createThinkingChunks, createTextChunks,
createToolCallChunks) to satisfy the sort-imports ESLint rule and update the
single import statement that currently imports those symbols.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/typescript/ai-client/src/chat-client.ts`:
- Around line 649-655: The current logic unconditionally replays a queued
continuation when continuationSkipped is true, which can run even if the awaited
streamResponse() aborted; change the behavior so replay only happens after
streamResponse() reports success. Specifically, have streamResponse() return (or
set) a success boolean/state and check that signal before clearing
continuationSkipped and calling checkForContinuation(); reference the
continuationSkipped flag, the checkForContinuation() method, and the
streamResponse() call so you only replay when streamResponse() succeeded (and
still respect stop() by not replaying on abort/failure).

---

Outside diff comments:
In `@packages/typescript/ai-client/tests/chat-client.test.ts`:
- Around line 3-10: The named imports from './test-utils' are not alphabetized;
reorder the specifier list so it is sorted alphabetically (e.g.,
createApprovalToolCallChunks, createCustomEventChunks,
createMockConnectionAdapter, createThinkingChunks, createTextChunks,
createToolCallChunks) to satisfy the sort-imports ESLint rule and update the
single import statement that currently imports those symbols.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 878b9ce8-96d6-469a-b36d-94a78b079493

📥 Commits

Reviewing files that changed from the base of the PR and between 0ea82f6 and ca9877d.

📒 Files selected for processing (4)
  • .changeset/chained-approvals-fix.md
  • packages/typescript/ai-client/src/chat-client.ts
  • packages/typescript/ai-client/tests/chat-client.test.ts
  • packages/typescript/ai-client/tests/test-utils.ts

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
docs/architecture/approval-flow-processing.md (1)

176-176: Optional: Add language specifiers to code blocks.

The markdownlint tool flags these code blocks for missing language specifiers. Since they contain pseudo-code and execution timelines rather than valid code in a specific language, consider adding text as the language specifier to silence the warnings:

```text
Timeline:
...
```

This is purely a style preference and doesn't affect the documentation quality.

Also applies to: 191-191, 202-202, 215-215, 226-226, 247-247, 330-330, 396-396

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/architecture/approval-flow-processing.md` at line 176, Several fenced
code blocks in the approval-flow-processing markdown contain
pseudo-code/timeline text without a language specifier; update each of those
fences (the ones that start with ``` and include the "Timeline:" sections and
similar pseudo-code blocks) to use ```text so markdownlint stops flagging them,
i.e., replace ``` with ```text for those blocks throughout the document.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@docs/architecture/approval-flow-processing.md`:
- Line 176: Several fenced code blocks in the approval-flow-processing markdown
contain pseudo-code/timeline text without a language specifier; update each of
those fences (the ones that start with ``` and include the "Timeline:" sections
and similar pseudo-code blocks) to use ```text so markdownlint stops flagging
them, i.e., replace ``` with ```text for those blocks throughout the document.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3c85f29f-735d-41b6-8945-0c18f523191d

📥 Commits

Reviewing files that changed from the base of the PR and between ca9877d and b62378f.

📒 Files selected for processing (1)
  • docs/architecture/approval-flow-processing.md

Copy link
Contributor

@AlemTuzlak AlemTuzlak left a comment

Choose a reason for hiding this comment

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

Check codersbbit

@jherr jherr merged commit 4fe31d4 into main Mar 6, 2026
5 checks passed
@jherr jherr deleted the multiple-approvals branch March 6, 2026 22:02
@github-actions github-actions bot mentioned this pull request Mar 6, 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.

2 participants