Skip to content

feat: bounded turn-level tool-dispatch loop (runToolLoop / streamToolLoop)#137

Merged
drewstone merged 2 commits into
mainfrom
feat/turn-tool-loop
Jun 3, 2026
Merged

feat: bounded turn-level tool-dispatch loop (runToolLoop / streamToolLoop)#137
drewstone merged 2 commits into
mainfrom
feat/turn-tool-loop

Conversation

@drewstone
Copy link
Copy Markdown
Contributor

What

Adds the everyday interactive tool loop that sits between runAgentTaskStream (one turn) and runLoop (delegated refine/fanout topologies) — the loop every agent app's chat runtime hand-rolls:

stream a model turn → collect the tool calls it emitted → execute each → fold the results back as a message → re-run until the model stops (or a turn cap).

Two forms:

  • runToolLoop(opts) — awaitable; for drain-only callers + tests.
  • streamToolLoop<Raw>(opts) — async generator; yields each raw turn event (caller maps + telemetries + re-emits) and each tool_result, with one capped signal at the turn limit. For SSE chat runtimes that need per-event streaming + telemetry.

Substrate-neutral by design — the caller supplies streamTurn (wraps any backend / runAgentTaskStream) and executeToolCall (routes to its integration / app-tool executors). This module owns the loop control flow; the caller owns the model and executors. Imports nothing.

Why

Lifted from @tangle-network/agent-app, where it was proven on insurance-agent's chat runtime (the streaming variant drives its eval + production tool dispatch). It's a generic runtime capability, not an app-shell one — so contributing it down so agent-runtime owns the primitive, per the engine-vs-shell layering rule. Once released, agent-app/runtime becomes a thin re-export.

Surface

Additive only — new src/tool-loop.ts + export block in src/index.ts. No existing export changed → no consumer needs to move; opt-in.

Verification

pnpm typecheck ✅ · pnpm test (7 new tests in src/tool-loop.test.ts, covering single-turn, fold+re-run, non-executable skip, cap, executor-throw, streaming yields + capped) ✅ · biome check ✅ · pnpm build ✅ · verify:package

Draft for review — not requesting merge/publish yet.

drewstone added 2 commits June 3, 2026 10:25
…Loop)

Adds the everyday interactive loop that sits between runAgentTaskStream (one
turn) and runLoop (delegated refine/fanout): stream a turn, dispatch the model's
tool calls, fold results back, re-run until the model stops or a turn cap.
Substrate-neutral — caller supplies streamTurn + executeToolCall seams; this
owns the loop. Awaitable (runToolLoop) + streaming (streamToolLoop, for SSE
runtimes with per-event telemetry). Additive export; no existing API changed.

Lifted from @tangle-network/agent-app where it was proven on insurance-agent's
chat runtime; contributing it down so the runtime owns the primitive.
@drewstone drewstone marked this pull request as ready for review June 3, 2026 16:42
@drewstone drewstone merged commit 9f711d7 into main Jun 3, 2026
1 check passed
drewstone added a commit that referenced this pull request Jun 6, 2026
Cuts the 58-commit backlog on main into a published release. Headline surface:
- runToolLoop / streamToolLoop — bounded turn-level tool-dispatch loop (#137)
- RSI agent tree: recursive Agent.act, Supervisor keystone, runProgram, the
  adaptive-driver channel (#139/#151/#165)
- optimization API collapsed onto agent-eval selfImprove; the runtime keeps the
  CODE-surface ImprovementDriver you pass as driver (#172)
- deployable benchmark adapters: AppWorld, commit0, aec-bench, EnterpriseOps-Gym;
  runBenchmarks over one ADAPTERS registry (#153/#156/#157)
- agent-eval floor raised to >=0.83.0 (#175)
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.

1 participant