Skip to content

feat(0.16.0): yank durable substrate, add AgentExecutionHandle contract#34

Merged
tangletools merged 4 commits into
mainfrom
chore/yank-supervisor-add-execution-handle
May 23, 2026
Merged

feat(0.16.0): yank durable substrate, add AgentExecutionHandle contract#34
tangletools merged 4 commits into
mainfrom
chore/yank-supervisor-add-execution-handle

Conversation

@tangletools

Copy link
Copy Markdown
Contributor

Summary

Yanks the Worker-hosted durable substrate (SessionSupervisorDO, runSupervisedTurn, runDurableTurn, runDurable, runOnWorkflowStep, DurableRunStore + D1 / FS / in-memory impls, schema, identity helpers) and replaces it with a thin contract over what the substrate already does:

  • AgentExecutionHandle + deriveExecutionId — typed pointer products persist so a client retry lands on the same substrate execution. The sandbox SDK + orchestrator already buffer by executionId, replay strictly after lastEventId, and never spawn a duplicate.
  • ChatTurnEngine / chatTurnEngine — framework-neutral chat-turn lifecycle: NDJSON framing, session.run.* envelope, persist / post-process / trace-flush hook ordering. No longer hosts execution state.

Why now

Cross-repo audit showed the supervisor surface competed with primitives that already live in @tangle-network/sandbox + orchestrator:

  • box.streamPrompt({ executionId, lastEventId }) already reconnects + replays.
  • Orchestrator /agents/run/stream already handles X-Execution-ID / Last-Event-ID and never spawns a duplicate.
  • execution-buffer.ts keyed by {sidecarId}:{executionId} already buffers events.
  • session-gateway already does browser-level reconnect.

Adoption proved it:

Symbol tax legal creative gtm
createSessionSupervisorDO
runSupervisedTurn 1 call
runDurable / runOnWorkflowStep
DurableChatTurnEngine (kept, reshaped) 1 1 1 1

SessionSupervisorDO was dead code in every product. runDurable / runOnWorkflowStep were unused entirely. runSupervisedTurn had one caller, stacked on top of DurableChatTurnEngine (double-buffering the same concern).

Diff size

  • 37 files changed, 565 +, 6987 − (net ~6.4k lines removed)
  • durable/ drops from 13 source files to 3 (execution-handle.ts, chat-engine.ts, index.ts)
  • pnpm-lock drops 110 packages (workerd test pool, better-sqlite3, wrangler, @cloudflare/workers-types)

Test plan

  • pnpm typecheck — clean
  • pnpm test — 179/179 pass (was 251 — store-matrix tests removed)
  • pnpm lint — clean
  • pnpm build — success

Consumer migration

tax-agent, legal-agent, creative-agent, gtm-agent all use:

  • DurableChatTurnEngine.runTurn(...) → renamed to ChatTurnEngine.runTurn(...), drops the store / projectId / domain / model / userMessage / workerId / leaseMs inputs; hook signature drops record
  • D1DurableRunStore → gone (engine no longer needs a store)
  • runSupervisedTurn (gtm only) → box.streamPrompt({ executionId: deriveExecutionId({...}), lastEventId }) directly

Consumer PRs follow.

drewstone added 4 commits May 23, 2026 06:00
Long-running execution durability lives in the substrate (sandbox SDK +
orchestrator already buffer the stream by executionId and replay strictly
after lastEventId). The Worker-hosted SessionSupervisorDO, runSupervisedTurn,
runDurableTurn, runDurable, runOnWorkflowStep, DurableRunStore (+ D1 / FS /
in-memory impls), schema, and supervisor adapter all competed with primitives
that already exist below — and adoption proved it: SessionSupervisorDO had
zero callers, runDurable / runOnWorkflowStep had zero callers, runSupervisedTurn
had one (gtm-agent).

Replaced with two surfaces:

- AgentExecutionHandle + deriveExecutionId — the typed pointer products
  persist so a client retry lands on the same substrate execution.
- ChatTurnEngine / chatTurnEngine — the framework-neutral chat-turn
  lifecycle (NDJSON, session.run.* envelope, persist / post-process /
  trace-flush hook ordering). No longer hosts execution state.

Build: 179 tests pass (was 251 — store-matrix tests removed). pnpm-lock
drops 110 packages (workerd test pool, better-sqlite3, wrangler).

Consumers (tax / legal / creative / gtm) bump on a separate PR; they only
use DurableChatTurnEngine.runTurn(...) and D1DurableRunStore — both
adopted shallow, easy migration.
…ending)

@tangle-network/sandbox@0.1.2 PromptOptions does not yet surface
executionId / lastEventId. In-call reconnect is automatic; cross-process
reconnect requires either bypassing the SDK (raw HTTP + X-Execution-ID
header) or a future SDK release. Doc clarified to reflect actual state.

Also: fix stale 'durable substrate' framing in src/index.ts and
README.md headline.
Round-1 audit critiques applied:

- ChatTurnEngine class + chatTurnEngine singleton → handleChatTurn
  function. The class wrapped a single stateless method; the singleton
  was the singleton-of-a-stateless-class antipattern. One symbol now.
- Renamed to `handleChatTurn` (not `runChatTurn`) to disambiguate from
  the existing `chat-turn.ts:runChatTurn` sandbox-stream primitive —
  different concern, different name.
- Dropped `AgentExecutionHandle` interface — only the executionId
  string is used at call sites; the wrapper type bought nothing.
- Dropped `AgentExecutionHandle.lastEventId` — the public sandbox SDK
  does not surface it, and no consumer used it. Adding back when SDK
  exposes it.
- Dropped `ReconnectableAgentStream<TEvent>` — exported with zero
  callers, premature abstraction.
- Dropped `ChatTurnHooks.accumulate` — unused by all consumers; the
  producer's `finalText()` is the single source of truth.
- Default `log` to `console.error` so swallowed hook errors don't
  vanish silently when no logger is wired.

durable/ source now: chat-engine.ts (handleChatTurn), execution-handle.ts
(deriveExecutionId only), index.ts (exports). README + concepts + the
chat-handler example all simplified to match.

179 tests pass.
@tangletools tangletools force-pushed the chore/yank-supervisor-add-execution-handle branch from 831b9f4 to 13a1283 Compare May 23, 2026 12:01
@tangletools tangletools merged commit a9a8df3 into main May 23, 2026
1 check failed
@tangletools tangletools deleted the chore/yank-supervisor-add-execution-handle branch May 23, 2026 12:01
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