Problem
runLoop in agent-runtime v0.78.0 now supports ExecCtx.onSandboxEvent, which forwards every raw SandboxEvent as it arrives. openSandboxRun is the persistent-box path used by product-shaped AgentProfile runs, but its OpenSandboxRunOptions currently exposes hooks and final TurnResult.events, not a per-event observer.
Source check:
src/runtime/types.ts: ExecCtx.onSandboxEvent exists for runLoop.
src/runtime/run-loop.ts: the stream drain calls args.ctx.onSandboxEvent(...) per event.
src/runtime/sandbox-run.ts: OpenSandboxRunOptions has hooks, but no per-event tee; settle() only collects events and returns them after the turn.
Why it matters
For stateful artifact runs, hosts need the same live/partial event capture as runLoop: tokens, tool calls, provider errors, and partial traces should be observable before the final artifact read succeeds. Today callers can recover drained events from SandboxRunAbortError on abort, but cannot stream raw events during successful long turns.
Requested shape
Add an optional observer to OpenSandboxRunOptions, matching ExecCtx.onSandboxEvent semantics as closely as possible:
onSandboxEvent?: (event: SandboxEvent, meta: { turnIndex: number; turnKind: 'start' | 'resume'; agentRunName: string }) => void | PromiseLike<void>
The observer should be best-effort, receive defensive copies, and never block or fail the run, same as runLoop.
Non-goal
Do not change AgentProfile semantics or add harness-specific config. This is runtime observability parity for the existing persistent-box primitive.
Problem
runLoopin agent-runtime v0.78.0 now supportsExecCtx.onSandboxEvent, which forwards every rawSandboxEventas it arrives.openSandboxRunis the persistent-box path used by product-shaped AgentProfile runs, but itsOpenSandboxRunOptionscurrently exposes hooks and finalTurnResult.events, not a per-event observer.Source check:
src/runtime/types.ts:ExecCtx.onSandboxEventexists forrunLoop.src/runtime/run-loop.ts: the stream drain callsargs.ctx.onSandboxEvent(...)per event.src/runtime/sandbox-run.ts:OpenSandboxRunOptionshashooks, but no per-event tee;settle()only collects events and returns them after the turn.Why it matters
For stateful artifact runs, hosts need the same live/partial event capture as
runLoop: tokens, tool calls, provider errors, and partial traces should be observable before the final artifact read succeeds. Today callers can recover drained events fromSandboxRunAbortErroron abort, but cannot stream raw events during successful long turns.Requested shape
Add an optional observer to
OpenSandboxRunOptions, matchingExecCtx.onSandboxEventsemantics as closely as possible:The observer should be best-effort, receive defensive copies, and never block or fail the run, same as
runLoop.Non-goal
Do not change AgentProfile semantics or add harness-specific config. This is runtime observability parity for the existing persistent-box primitive.