fix(ai-isolate-cloudflare): accumulate toolResults across rounds#524
fix(ai-isolate-cloudflare): accumulate toolResults across rounds#524Sriketk wants to merge 2 commits intoTanStack:mainfrom
Conversation
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.
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe Cloudflare isolate driver is fixed to accumulate ChangesTool Results Accumulation Fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
View your CI Pipeline Execution ↗ for commit 5fd3edc
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-anthropic
@tanstack/ai-client
@tanstack/ai-code-mode
@tanstack/ai-code-mode-skills
@tanstack/ai-devtools-core
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-groq
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-openrouter
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
Summary
The Cloudflare isolate driver wipes
toolResultsbetweenneed_toolsrounds (packages/typescript/ai-isolate-cloudflare/src/isolate-driver.ts:178).wrap-codeuses sequentialtc_<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:ping-pong between
{tc_0}and{tc_1}:(none)tc_0{tc_0}tc_1{tc_1}(pre-fix)tc_0again{tc_0}tc_1againMaxRoundsExceededSingle-tool code worked because only one cache entry was ever needed in a given round.
Fix
One-line change:
toolResults = {}→toolResults = { ...(toolResults ?? {}) }. Within anexecute()call's round loop only —toolResultsis local toexecute(), so each newexecute()still starts fresh (independent code, independent ids).Why this slipped through
Existing
isolate-driver.test.tscases:need_toolscases are single-round (need_tools → done).add_1,getA_1— neverwrap-code's realtc_<idx>format. The end-to-end contract between driver andwrap-codewas never validated.MaxRoundsExceededtest loops the same tool, so doesn't exercise the multi-tool ping-pong.Test plan
Adds
accumulates toolResults across rounds for sequential tool callstotests/isolate-driver.test.ts. Usestc_<idx>-shaped ids matchingwrap-codeand asserts round 3 carries bothtc_0andtc_1.expected {success:true, value:'a'}, received undefinedfortc_0in round 3)pnpm vitest run tests/isolate-driver.test.ts)cobalt-sandbox.sriketk5.workers.dev) confirms multi-tool code converges in 3 rounds post-fixRelated
Discovered while running multi-tool code through
@tanstack/ai-isolate-cloudflare@0.1.8from a Cobalt MCP integration. Independent of #523 (which ports the worker fromunsafe_evaltoworker_loader); this fix touchesisolate-driver.tsonly and applies to both the legacy and ported binding paths.Summary by CodeRabbit
Bug Fixes
Tests