Skip to content

fix(ai-isolate-cloudflare): accumulate toolResults across rounds#524

Open
Sriketk wants to merge 2 commits intoTanStack:mainfrom
Sriketk:fix/ai-isolate-cloudflare-accumulate-tool-results
Open

fix(ai-isolate-cloudflare): accumulate toolResults across rounds#524
Sriketk wants to merge 2 commits intoTanStack:mainfrom
Sriketk:fix/ai-isolate-cloudflare-accumulate-tool-results

Conversation

@Sriketk
Copy link
Copy Markdown

@Sriketk Sriketk commented May 3, 2026

Summary

The Cloudflare isolate driver wipes toolResults between need_tools rounds (packages/typescript/ai-isolate-cloudflare/src/isolate-driver.ts:178). wrap-code uses sequential tc_<idx> ids that are re-derived from scratch every time the Worker re-executes user code, so prior-round results must stay in the cache. With the wipe, multi-tool programs like:

const x = await A();
const y = await B();
return x + y;

ping-pong between {tc_0} and {tc_1}:

round sent toolResults worker reaction
1 (none) throws on tc_0
2 {tc_0} tc_0 cached → throws on tc_1
3 {tc_1} (pre-fix) tc_0 missing → throws on tc_0 again
4 {tc_0} tc_1 missing → throws on tc_1 again
... ... until MaxRoundsExceeded

Single-tool code worked because only one cache entry was ever needed in a given round.

Fix

One-line change: toolResults = {}toolResults = { ...(toolResults ?? {}) }. Within an execute() call's round loop only — toolResults is local to execute(), so each new execute() still starts fresh (independent code, independent ids).

Why this slipped through

Existing isolate-driver.test.ts cases:

  • All need_tools cases are single-round (need_tools → done).
  • IDs in tests use ad-hoc shapes like add_1, getA_1 — never wrap-code's real tc_<idx> format. The end-to-end contract between driver and wrap-code was never validated.
  • The MaxRoundsExceeded test loops the same tool, so doesn't exercise the multi-tool ping-pong.

Test plan

Adds accumulates toolResults across rounds for sequential tool calls to tests/isolate-driver.test.ts. Uses tc_<idx>-shaped ids matching wrap-code and asserts round 3 carries both tc_0 and tc_1.

  • New test fails on prior implementation (expected {success:true, value:'a'}, received undefined for tc_0 in round 3)
  • All 16 driver tests pass with the fix (pnpm vitest run tests/isolate-driver.test.ts)
  • Live repro against deployed Worker (cobalt-sandbox.sriketk5.workers.dev) confirms multi-tool code converges in 3 rounds post-fix

Related

Discovered while running multi-tool code through @tanstack/ai-isolate-cloudflare@0.1.8 from a Cobalt MCP integration. Independent of #523 (which ports the worker from unsafe_eval to worker_loader); this fix touches isolate-driver.ts only and applies to both the legacy and ported binding paths.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed Cloudflare isolate driver behavior to preserve tool results across successive execution rounds, preventing premature round exhaustion and errors in multi-tool workflows.
  • Tests

    • Added a regression test that simulates sequential tool calls to verify tool results are accumulated and retained across multiple rounds.

The Cloudflare isolate driver wiped toolResults between need_tools rounds.
wrap-code uses sequential tc_<idx> ids that are re-derived from scratch
every time the Worker re-executes user code, so prior-round results must
remain in the cache. With the wipe, multi-tool programs (e.g.
`await A(); await B();`) ping-pong between {tc_0} and {tc_1} and exhaust
maxToolRounds, surfacing as MaxRoundsExceeded.

Single-tool code worked because only one cache entry was ever needed in a
given round. Existing tests covered single-round flows only and used
ad-hoc tool-call ids rather than wrap-code's real tc_<idx> shape, so the
regression slipped through.

Adds a tc_<idx>-shaped regression test covering two sequential tool
calls. The test fails on the prior implementation and passes after the
one-line fix.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 3, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2c56402d-b2b8-4068-8e51-84a2ad4fe01c

📥 Commits

Reviewing files that changed from the base of the PR and between ed7240f and 5fd3edc.

📒 Files selected for processing (1)
  • .changeset/accumulate-tool-results.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/accumulate-tool-results.md

📝 Walkthrough

Walkthrough

The Cloudflare isolate driver is fixed to accumulate toolResults across multiple tool-execution rounds instead of resetting to empty each round, preventing tool-ID reuse from causing round exhaustion. A regression test validates multi-tool sequential behavior.

Changes

Tool Results Accumulation Fix

Layer / File(s) Summary
Core Logic Fix
packages/typescript/ai-isolate-cloudflare/src/isolate-driver.ts
In CloudflareIsolateContext.execute, toolResults is now carried forward across rounds by cloning prior results instead of resetting to {} each iteration. Inline comments explain why sequential tc_<idx> tool IDs require result retention.
Regression Test
packages/typescript/ai-isolate-cloudflare/tests/isolate-driver.test.ts
New test case accumulates toolResults across rounds for sequential tool calls verifies that toolResults from tc_0 and tc_1 are both present in the final request POST body after three worker rounds.
Changelog
.changeset/accumulate-tool-results.md
Patch release entry documents the toolResults accumulation fix and notes the new end-to-end regression test covering previously missing multi-tool behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A rabbit hops through tool rounds with glee,
No more results lost, hooray!
Sequential tools now dance, tc_0 and tc_1 stay,
Cloudflare's isolate, both safe and spry! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: fixing the Cloudflare isolate driver to accumulate toolResults across rounds instead of wiping them.
Description check ✅ Passed The description is comprehensive and follows the template structure with clear sections covering changes, test plan, and checklist items marked appropriately.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown

nx-cloud Bot commented May 7, 2026

View your CI Pipeline Execution ↗ for commit 5fd3edc

Command Status Duration Result
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 4s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-07 09:00:21 UTC

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 7, 2026

Open in StackBlitz

@tanstack/ai

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

@tanstack/ai-anthropic

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

@tanstack/ai-client

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

@tanstack/ai-code-mode

npm i https://pkg.pr.new/@tanstack/ai-code-mode@524

@tanstack/ai-code-mode-skills

npm i https://pkg.pr.new/@tanstack/ai-code-mode-skills@524

@tanstack/ai-devtools-core

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

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@524

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@524

@tanstack/ai-fal

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

@tanstack/ai-gemini

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

@tanstack/ai-grok

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

@tanstack/ai-groq

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

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-isolate-cloudflare@524

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/@tanstack/ai-isolate-node@524

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs@524

@tanstack/ai-ollama

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

@tanstack/ai-openai

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

@tanstack/ai-openrouter

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

@tanstack/ai-preact

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

@tanstack/ai-react

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

@tanstack/ai-react-ui

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

@tanstack/ai-solid

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

@tanstack/ai-solid-ui

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

@tanstack/ai-svelte

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

@tanstack/ai-vue

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

@tanstack/ai-vue-ui

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

@tanstack/preact-ai-devtools

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

@tanstack/react-ai-devtools

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

@tanstack/solid-ai-devtools

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

commit: 5fd3edc

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