@tangle-network/agent-runtime 0.143.0 → 0.153.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +32 -0
  2. package/dist/{activation-mi8TgSLM.js → activation-Bbic0THc.js} +3 -3
  3. package/dist/{activation-mi8TgSLM.js.map → activation-Bbic0THc.js.map} +1 -1
  4. package/dist/agent.d.ts +1 -1
  5. package/dist/agent.js +3 -3
  6. package/dist/{analyst-loop-CvkmfhUB.js → analyst-loop-Bouu53-l.js} +2 -2
  7. package/dist/{analyst-loop-CvkmfhUB.js.map → analyst-loop-Bouu53-l.js.map} +1 -1
  8. package/dist/analyst-loop.js +1 -1
  9. package/dist/{authoring-DuyShLdw.js → authoring-CcVhJ1lP.js} +2 -2
  10. package/dist/{authoring-DuyShLdw.js.map → authoring-CcVhJ1lP.js.map} +1 -1
  11. package/dist/candidate-execution/index.js +4 -4
  12. package/dist/{candidate-execution-CD5PoNmC.js → candidate-execution-DYOB1juU.js} +4 -4
  13. package/dist/{candidate-execution-CD5PoNmC.js.map → candidate-execution-DYOB1juU.js.map} +1 -1
  14. package/dist/{conversation-1hNtDeMM.js → conversation-BHMwAiMo.js} +28 -13
  15. package/dist/{conversation-1hNtDeMM.js.map → conversation-BHMwAiMo.js.map} +1 -1
  16. package/dist/conversation.d.ts +1 -1
  17. package/dist/conversation.js +1 -1
  18. package/dist/durable.d.ts +102 -4
  19. package/dist/durable.js +259 -13
  20. package/dist/durable.js.map +1 -1
  21. package/dist/{environment-provider-DCBJ13VP.js → environment-provider-3eCszBEm.js} +218 -34
  22. package/dist/environment-provider-3eCszBEm.js.map +1 -0
  23. package/dist/{environment-provider-B8eZ85Ga.d.ts → environment-provider-DJG0yIYl.d.ts} +2 -2
  24. package/dist/environment-provider.d.ts +1 -1
  25. package/dist/environment-provider.js +1 -1
  26. package/dist/executable-spec-BUcUcEPk.js +73 -0
  27. package/dist/executable-spec-BUcUcEPk.js.map +1 -0
  28. package/dist/{graph-De_XEsfH.js → graph-CIh2HDmH.js} +4 -4
  29. package/dist/{graph-De_XEsfH.js.map → graph-CIh2HDmH.js.map} +1 -1
  30. package/dist/{improvement-cycle-Bi-Tf4QF.js → improvement-cycle-GCDSsTN6.js} +7 -7
  31. package/dist/{improvement-cycle-Bi-Tf4QF.js.map → improvement-cycle-GCDSsTN6.js.map} +1 -1
  32. package/dist/{index-C2caGomG.d.ts → index-DLn9WI-f.d.ts} +342 -505
  33. package/dist/{index-B8rKtH3U.d.ts → index-lMADJLfq.d.ts} +4 -4
  34. package/dist/{index-D4sLkOPY.d.ts → index-rxVSm9-z.d.ts} +6 -4
  35. package/dist/index.d.ts +7 -7
  36. package/dist/index.js +13 -13
  37. package/dist/intelligence.d.ts +4 -4
  38. package/dist/intelligence.js +6 -6
  39. package/dist/jsonl-file-CDfsCI5s.js +59 -0
  40. package/dist/jsonl-file-CDfsCI5s.js.map +1 -0
  41. package/dist/kernel.d.ts +6 -6
  42. package/dist/kernel.js +13 -13
  43. package/dist/{knowledge-CVE6Wk1i.js → knowledge-CaY53BW2.js} +10 -7
  44. package/dist/{knowledge-CVE6Wk1i.js.map → knowledge-CaY53BW2.js.map} +1 -1
  45. package/dist/knowledge.d.ts +1 -1
  46. package/dist/knowledge.js +1 -1
  47. package/dist/{loop-runner-bin-BoHdQqLm.d.ts → loop-runner-bin-BwPqxKhR.d.ts} +3 -3
  48. package/dist/{loop-runner-bin-DdaI1nLL.js → loop-runner-bin-Dw43kB_-.js} +4 -4
  49. package/dist/{loop-runner-bin-DdaI1nLL.js.map → loop-runner-bin-Dw43kB_-.js.map} +1 -1
  50. package/dist/loop-runner-bin.d.ts +1 -1
  51. package/dist/loop-runner-bin.js +1 -1
  52. package/dist/{materialization-P86EciBw.js → materialization-Dl9J8ek4.js} +279 -58
  53. package/dist/materialization-Dl9J8ek4.js.map +1 -0
  54. package/dist/mcp/bin.js +3 -3
  55. package/dist/mcp/index.d.ts +3 -3
  56. package/dist/mcp/index.js +6 -6
  57. package/dist/{model-policy-DgRJIJse.js → model-policy-Sw4ywhtL.js} +68 -6
  58. package/dist/model-policy-Sw4ywhtL.js.map +1 -0
  59. package/dist/{openai-tools-BiAWKjh6.js → openai-tools-C4XKuK4t.js} +2 -2
  60. package/dist/{openai-tools-BiAWKjh6.js.map → openai-tools-C4XKuK4t.js.map} +1 -1
  61. package/dist/{prepare-D3n7cA39.js → prepare-C5tI-H4o.js} +2 -2
  62. package/dist/{prepare-D3n7cA39.js.map → prepare-C5tI-H4o.js.map} +1 -1
  63. package/dist/primeintellect/index.d.ts +1 -1
  64. package/dist/profiles.js +1 -1
  65. package/dist/{protected-model-port-bq6bD9YX.js → protected-model-port-DHDKNeY7.js} +2 -2
  66. package/dist/{protected-model-port-bq6bD9YX.js.map → protected-model-port-DHDKNeY7.js.map} +1 -1
  67. package/dist/{redact-DexTuAiX.d.ts → redact-NAptmqKw.d.ts} +3 -3
  68. package/dist/{researcher-CiSY6Wzb.js → researcher-BMFFPwKb.js} +2 -2
  69. package/dist/{researcher-CiSY6Wzb.js.map → researcher-BMFFPwKb.js.map} +1 -1
  70. package/dist/{run-layout-Be_Z0dF8.js → run-layout-C2jgwsCq.js} +111 -6
  71. package/dist/run-layout-C2jgwsCq.js.map +1 -0
  72. package/dist/{runtime-BnqjbOGX.js → runtime--Jsq8JCC.js} +118 -97
  73. package/dist/runtime--Jsq8JCC.js.map +1 -0
  74. package/dist/{runtime-J6Toky8K.d.ts → runtime-B-5dp5Iz.d.ts} +214 -14
  75. package/dist/{sandbox-events-COwCWUVB.js → sandbox-events-BVjstFgb.js} +70 -3
  76. package/dist/sandbox-events-BVjstFgb.js.map +1 -0
  77. package/dist/{spawn-journal-D2HKUImC.js → spawn-journal-BLnveCRS.js} +34 -104
  78. package/dist/spawn-journal-BLnveCRS.js.map +1 -0
  79. package/dist/{stream-agent-turn-C1Vs_3B9.d.ts → stream-agent-turn-BGyszuPH.d.ts} +2 -2
  80. package/dist/{stream-agent-turn-CXRugSGO.js → stream-agent-turn-DYi8ymsU.js} +91 -16
  81. package/dist/stream-agent-turn-DYi8ymsU.js.map +1 -0
  82. package/dist/{structural-rollout-CJgj9YXH.js → structural-rollout-D7V-HgXJ.js} +30 -13
  83. package/dist/structural-rollout-D7V-HgXJ.js.map +1 -0
  84. package/dist/{supervise-hCgG6ROJ.js → supervise-k_8VOASb.js} +2499 -2171
  85. package/dist/supervise-k_8VOASb.js.map +1 -0
  86. package/dist/{supervisor-s8SfZYbW.js → supervisor-CMZsJ7Wn.js} +673 -446
  87. package/dist/supervisor-CMZsJ7Wn.js.map +1 -0
  88. package/dist/testing.d.ts +2 -2
  89. package/dist/testing.js +12 -12
  90. package/dist/{top-app-BMOSKK06.js → top-app-3rYfFPTW.js} +192 -147
  91. package/dist/top-app-3rYfFPTW.js.map +1 -0
  92. package/dist/tui/bin.js +1 -1
  93. package/dist/tui/index.d.ts +32 -5
  94. package/dist/tui/index.js +1 -1
  95. package/dist/{types-Df9vulGc.d.ts → types-BPQhQRrC.d.ts} +507 -10
  96. package/dist/{util-C1bv6yog.js → util-D6ZEuBMi.js} +71 -2
  97. package/dist/util-D6ZEuBMi.js.map +1 -0
  98. package/dist/{workspace-archive-C52LjkeN.js → workspace-archive-B9ui4rrR.js} +2 -2
  99. package/dist/{workspace-archive-C52LjkeN.js.map → workspace-archive-B9ui4rrR.js.map} +1 -1
  100. package/package.json +7 -7
  101. package/dist/environment-provider-DCBJ13VP.js.map +0 -1
  102. package/dist/materialization-P86EciBw.js.map +0 -1
  103. package/dist/model-policy-DgRJIJse.js.map +0 -1
  104. package/dist/retained-run-binding-Dp2e8xne.js +0 -268
  105. package/dist/retained-run-binding-Dp2e8xne.js.map +0 -1
  106. package/dist/run-layout-Be_Z0dF8.js.map +0 -1
  107. package/dist/runtime-BnqjbOGX.js.map +0 -1
  108. package/dist/sandbox-events-COwCWUVB.js.map +0 -1
  109. package/dist/spawn-journal-D2HKUImC.js.map +0 -1
  110. package/dist/stream-agent-turn-CXRugSGO.js.map +0 -1
  111. package/dist/structural-rollout-CJgj9YXH.js.map +0 -1
  112. package/dist/supervise-hCgG6ROJ.js.map +0 -1
  113. package/dist/supervisor-s8SfZYbW.js.map +0 -1
  114. package/dist/top-app-BMOSKK06.js.map +0 -1
  115. package/dist/util-C1bv6yog.js.map +0 -1
@@ -1,7 +1,7 @@
1
- import { E as SandboxClient, i as ExecCtx, k as Validator } from "./types-DeX8ibLc.js";
2
- import { I as Scope, Q as UsageEvent, U as Spend, a as DefaultVerdict, d as ExecutorFactory, gn as ExecutorProgress, ln as TraceSource, m as ExecutorRegistry } from "./types-Df9vulGc.js";
3
- import { i as AgentEnvironmentProvider, o as AgentEnvironmentProviderRegistry, w as ProviderExecutorOptions } from "./environment-provider-B8eZ85Ga.js";
4
- import { AgentProfile, AgentProfileMcpServer, HarnessType, ReasoningEffort } from "@tangle-network/agent-interface";
1
+ import { E as SandboxClient, at as RuntimeStreamEvent, i as ExecCtx, k as Validator } from "./types-DeX8ibLc.js";
2
+ import { B as Scope, Cn as ExecutorProgress, _ as ExecutorRegistry, a as DefaultVerdict, g as ExecutorProgressEvent, gn as TraceSource, l as ExecutorCancellation, p as ExecutorFactory, q as Spend, rt as UsageEvent, u as ExecutorCancellationRequest, y as ExecutorToolCall } from "./types-BPQhQRrC.js";
3
+ import { i as AgentEnvironmentProvider, o as AgentEnvironmentProviderRegistry, w as ProviderExecutorOptions } from "./environment-provider-DJG0yIYl.js";
4
+ import { AgentProfile, AgentProfileMcpServer, HarnessType, ReasoningEffort, StreamEvent } from "@tangle-network/agent-interface";
5
5
  import { WorkspacePlanReceipt } from "@tangle-network/agent-profile-materialize";
6
6
  import { ChildProcess } from "node:child_process";
7
7
  import { AgentRunOutcome } from "@tangle-network/sandbox/runtime";
@@ -321,6 +321,13 @@ interface RouterConfig extends RouterTransportConfig {
321
321
  * lives here rather than on one call site.
322
322
  */
323
323
  maxTokens?: number;
324
+ /**
325
+ * Optional ceiling on TOTAL completion tokens — visible answer plus hidden reasoning —
326
+ * forwarded as `max_completion_tokens`. Distinct from `maxTokens`: a reasoning model can spend
327
+ * an entire `max_tokens` budget on hidden thinking, so only this field bounds what the provider
328
+ * bills for one completion.
329
+ */
330
+ maxCompletionTokens?: number;
324
331
  /**
325
332
  * Take the tool-calling completion over SSE instead of one buffered POST. Off by default —
326
333
  * `routerChatWithTools` never streams, and every existing caller keeps the buffered transport
@@ -771,18 +778,209 @@ interface ResolvedMcpServerLaunch {
771
778
  */
772
779
  declare function resolveMcpServerLaunch(server: AgentProfileMcpServer, keys: KeyProvider | undefined, label: string): Promise<ResolvedMcpServerLaunch>;
773
780
  //#endregion
774
- //#region src/runtime/sandbox-executor-output.d.ts
775
- /** One tool call retained in a Sandbox executor artifact. */
776
- interface SandboxExecutorToolCall {
777
- id?: string;
778
- name: string;
779
- arguments: unknown;
781
+ //#region src/runtime/sandbox-events.d.ts
782
+ /** The provider/model the platform reports it actually bound to a turn, when it reports one.
783
+ * `source` is the platform's own account of where that choice came from — `environment` means
784
+ * the platform chose, not the request. */
785
+ interface SandboxServedBackend {
786
+ readonly provider?: string;
787
+ readonly model?: string;
788
+ readonly source?: string;
780
789
  }
790
+ /**
791
+ * Read the served execution identity off one Sandbox event.
792
+ *
793
+ * The platform reports `effectiveBackend` on `execution.started` and again on the terminal
794
+ * event (`@tangle-network/sandbox`, `EffectiveBackend`). Absence returns `undefined`
795
+ * and must stay unknown — a request is not a receipt, so nothing here may be inferred from
796
+ * what was asked for.
797
+ */
798
+ declare function sandboxEventServedBackend(event: SandboxEvent): SandboxServedBackend | undefined;
799
+ /**
800
+ * Fail the execution when the platform reports serving a model other than the exact one asked for.
801
+ *
802
+ * Measured motive (agent-runtime#892, live infrastructure 2026-08-17): 6 of 6 boxes whose profile
803
+ * declared `zai-coding-plan/glm-5.2` reported
804
+ * `{"provider":"openai-compat","model":"deepseek/deepseek-v4-flash","source":"environment"}`,
805
+ * while the materialization receipt recorded the declared model as `status: "known"`. Sending
806
+ * `backend.model` makes that substitution unlikely; only reading the report back makes it
807
+ * detectable. A run that cannot say which model produced its evidence must not settle as one
808
+ * that can.
809
+ *
810
+ * Silent when the platform reports no served model: unobserved stays unobserved.
811
+ */
812
+ declare function assertSandboxServedModel(event: SandboxEvent, expected: {
813
+ readonly provider?: string;
814
+ readonly model?: string;
815
+ } | undefined): void;
816
+ /**
817
+ * Extract a `RuntimeStreamEvent`-shaped `llm_call` from a sandbox event when
818
+ * the event carries usage/cost data. Returns `undefined` for non-cost events
819
+ * so the kernel can iterate the full stream without branching.
820
+ *
821
+ * Pure by contract: it never throws on a failed run. The terminal truth
822
+ * boundary is the public Sandbox outcome tracker, applied after the complete
823
+ * stream. Post-hoc readers — {@link sumSandboxUsage}, the
824
+ * analyst trace store, the chat projection — must stay able to read a failed
825
+ * turn's events, which is when reading them matters most.
826
+ *
827
+ * Canonical cost-carrying types observed in the wild:
828
+ * - `llm_call` — `data: { model, tokensIn, tokensOut, costUsd, ... }`
829
+ * - `message.completed` / `result` — `data: { usage: { inputTokens,
830
+ * outputTokens, totalCostUsd? } }`
831
+ * - `cost.usage` / `usage` — same shape under a dedicated type
832
+ *
833
+ * Numeric coercion is strict: `Number.isFinite` gates every accumulator write
834
+ * so a sentinel `NaN` from a misbehaving backend cannot poison the ledger.
835
+ */
836
+ declare function extractLlmCallEvent(event: SandboxEvent, agentRunName: string): (RuntimeStreamEvent & {
837
+ type: 'llm_call';
838
+ }) | undefined;
839
+ /**
840
+ * Sum the token usage + USD cost of a sandbox turn's events — the one honest way to meter an
841
+ * `openSandboxRun` cell. Folds `extractLlmCallEvent` over the stream (which reads usage off EVERY backend
842
+ * event shape), so a `runProfileMatrix` dispatch can report it to `ctx.cost`:
843
+ *
844
+ * receipt: (turn) => {
845
+ * const u = sumSandboxUsage(turn.events)
846
+ * return { model, inputTokens: u.input, outputTokens: u.output,
847
+ * ...(u.tokensKnown === false ? { usageUnknown: true } : {}),
848
+ * ...(u.usdKnown !== false && u.costUsd > 0 ? { actualCostUsd: u.costUsd } : {}),
849
+ * ...(u.usdKnown === false ? { costUnknown: true } : {}),
850
+ * ...(u.estimatedCostUsd !== undefined ? { estimatedCostUsd: u.estimatedCostUsd } : {}) }
851
+ * }
852
+ *
853
+ * Without this a cell reads `{tokens:0, cost:0}` and the backend-integrity guard correctly aborts the
854
+ * matrix as a stub. `agentRunName` is the fallback model label for cost-only events (default `'agent'`).
855
+ */
856
+ declare function sumSandboxUsage(events: readonly SandboxEvent[], agentRunName?: string): {
857
+ input: number;
858
+ output: number;
859
+ costUsd: number;
860
+ tokensKnown?: false;
861
+ usdKnown?: false;
862
+ estimatedCostUsd?: number;
863
+ };
864
+ /**
865
+ * Cross-event state for {@link mapSandboxToolEvent}. Sandbox backends emit a
866
+ * tool invocation as MANY `message.part.updated` frames on the same call id
867
+ * (pending → running → completed), so faithful projection needs per-call
868
+ * status memory: one `tool_call` on first sighting, at most one `tool_result`
869
+ * on the terminal transition, nothing on intermediate re-frames. Create one
870
+ * state per turn via {@link createSandboxToolPartState}.
871
+ *
872
+ * @experimental
873
+ */
874
+ interface SandboxToolPartState {
875
+ /** Last seen status per tool call id. A terminal status is sticky — later
876
+ * frames on a settled call project to nothing. */
877
+ statusByCall: Map<string, string>;
878
+ /** Sequence for synthesized call ids when an event carries none. */
879
+ seq: number;
880
+ }
881
+ /**
882
+ * Fresh per-turn {@link SandboxToolPartState} for {@link mapSandboxToolEvent} — an
883
+ * empty call-status map so each turn projects tool frames independently.
884
+ *
885
+ * @experimental
886
+ */
887
+ declare function createSandboxToolPartState(): SandboxToolPartState;
888
+ /**
889
+ * Project one `SandboxEvent` onto the `tool_call` / `tool_result` variants of
890
+ * `RuntimeStreamEvent` — the tool-part projection `mapSandboxEvent`
891
+ * deliberately does NOT perform. Opt-in and additive: `mapSandboxEvent`'s
892
+ * default vocabulary (text/reasoning deltas + `llm_call`) is unchanged;
893
+ * consumers that need the tool surface (chat UIs rendering tool activity)
894
+ * compose this projector alongside it — `streamAgentTurn` does exactly that
895
+ * under its `preserveToolParts` option.
896
+ *
897
+ * Handled shapes (observed on the opencode / claude-code sandbox backends):
898
+ * - `message.part.updated` with `part.type === 'tool'` — stateful: a
899
+ * `tool_call` on the call id's first frame (args from `state.input` or
900
+ * `state.metadata.input`), a `tool_result` when the status transitions to
901
+ * `completed` (result from `state.output` / `metadata.output`) or to a
902
+ * terminal failure (result is `{ error, status, output? }` — the error
903
+ * surfaced in-band, never dropped).
904
+ * - bare `tool*` event types (`tool.call`, `tool_result`, …) — stateless:
905
+ * `*result*` types project to `tool_result`, the rest to `tool_call`.
906
+ *
907
+ * Returns `[]` for every non-tool event.
908
+ *
909
+ * @experimental
910
+ */
911
+ declare function mapSandboxToolEvent(event: SandboxEvent, state: SandboxToolPartState): (RuntimeStreamEvent & {
912
+ type: 'tool_call' | 'tool_result';
913
+ })[];
914
+ /**
915
+ * Project one `SandboxEvent` onto the `RuntimeStreamEvent` chat-UX vocabulary,
916
+ * for runtimes that bridge a sandbox `streamPrompt` into the
917
+ * `AgentRuntime.act` streaming contract. Returns `undefined` for events that
918
+ * have no faithful projection — the raw stream is preserved separately for the
919
+ * `OutputAdapter`, so an unmapped event never loses data.
920
+ *
921
+ * Mapped (the task-optional incremental variants — no synthesized task
922
+ * lifecycle, no guessed tool-part shapes):
923
+ * - `message.part.updated` text part → `text_delta`
924
+ * - `message.part.updated` reasoning/thinking part → `reasoning_delta`
925
+ * - cost-bearing events → `llm_call` (shared with the ledger extractor)
926
+ *
927
+ * Tool parts are deliberately NOT mapped here (unchanged default) — compose
928
+ * {@link mapSandboxToolEvent} alongside when a consumer needs them.
929
+ *
930
+ * The opencode backend emits incremental text as
931
+ * `{ type: 'message.part.updated', data: { part: { type, text }, delta } }`;
932
+ * `delta` is the increment, `part.text` the running accumulation.
933
+ */
934
+ declare function mapSandboxEvent(event: SandboxEvent, opts?: {
935
+ agentRunName?: string;
936
+ }): RuntimeStreamEvent | undefined;
937
+ /**
938
+ * Project one `SandboxEvent` onto Runtime's executor progress vocabulary: incremental text and
939
+ * reasoning, tool calls and results, and an interaction request. It composes the existing
940
+ * projections ({@link mapSandboxEvent}, {@link mapSandboxToolEvent}, and the canonical Agent
941
+ * Interface decode) so every sandbox-shaped executor publishes live output through one reader.
942
+ * Usage-bearing events project to nothing here — accounting stays on the `tokens`/`cost`
943
+ * channels.
944
+ *
945
+ * Pass one {@link SandboxToolPartState} per turn so a multi-frame tool call yields one call and
946
+ * at most one result.
947
+ *
948
+ * @experimental
949
+ */
950
+ declare function sandboxProgressEvents(event: SandboxEvent, state: SandboxToolPartState): ExecutorProgressEvent[];
951
+ //#endregion
952
+ //#region src/runtime/sandbox-executor-output.d.ts
953
+ /**
954
+ * What a settled turn produced, as an explicit marker.
955
+ *
956
+ * `text` carries the byte length of the answer, `empty` says a text-bearing terminal event was
957
+ * observed and carried nothing, and `absent` says no text-bearing event was observed at all.
958
+ * The three are distinct on purpose: an empty settle blob used to be indistinguishable from lost
959
+ * output, so a reader could not tell a box that produced nothing from one whose answer never
960
+ * arrived.
961
+ */
962
+ type SandboxOutputMarker = {
963
+ readonly kind: 'text';
964
+ readonly bytes: number;
965
+ } | {
966
+ readonly kind: 'empty';
967
+ } | {
968
+ readonly kind: 'absent';
969
+ };
781
970
  /** Parsed output of one Sandbox executor turn. */
782
971
  interface SandboxLeafOut {
783
972
  events: SandboxEvent[];
784
- content: string;
785
- toolCalls?: SandboxExecutorToolCall[];
973
+ /** The observed answer. `undefined` when no text-bearing event was observed — never `''`. */
974
+ content: string | undefined;
975
+ /** Explicit account of what the turn produced. */
976
+ output: SandboxOutputMarker;
977
+ /**
978
+ * Provider and model the platform reported serving this turn, when it reported one. Absent means
979
+ * the platform said nothing; it is never filled from the request, because a request is not a
980
+ * receipt.
981
+ */
982
+ servedBackend?: SandboxServedBackend;
983
+ toolCalls?: ExecutorToolCall[];
786
984
  outcome?: AgentRunOutcome;
787
985
  }
788
986
  //#endregion
@@ -845,6 +1043,8 @@ interface SteerableSandboxSession {
845
1043
  /** Drive the worker to settlement. `signal` is the spawn-scoped abort handed to `execute`. */
846
1044
  stream(task: unknown, signal: AbortSignal): AsyncIterable<UsageEvent>;
847
1045
  progress(): ExecutorProgress;
1046
+ /** Ask the box to stop the running execution on this exact session and report what it answered. */
1047
+ cancel(request: ExecutorCancellationRequest): Promise<ExecutorCancellation>;
848
1048
  traceSource(): TraceSource;
849
1049
  artifact(): {
850
1050
  outRef: string;
@@ -1173,5 +1373,5 @@ declare function createExecutor(config: ExecutorConfig): ExecutorFactory<unknown
1173
1373
  */
1174
1374
  declare function createExecutorRegistry(): ExecutorRegistry;
1175
1375
  //#endregion
1176
- export { RemoveWorktreeOptions as $, resolveMcpServerLaunch as A, JsonRpcMessage as At, DEFAULT_LOCAL_HARNESS as B, createInbox as C, PeerMailbox as Ct, ResolvedMcpServerLaunch as D, isPeerMailEnvelope as Dt, KeyProvider as E, createPeerMailbox as Et, WorktreeHarnessResult as F, harnessSupportsReasoningEffort as G, LocalHarness as H, WorktreeProfileMaterializationReceipt as I, runLocalHarness as J, localHarnessExecutable as K, CodexExecutionEvidence as L, secretEnvOfMcpServer as M, McpToolDescriptor as Mt, WorktreeCheckRunner as N, McpTransport as Nt, envKeyProvider as O, peerMailTools as Ot, WorktreeCommandResult as P, GitRunner as Q, CodexExecutionPolicy as R, PeerInboxMessage as S, PeerMailSendInput as St, SandboxLeafOut as T, claimsAuthority as Tt, LocalHarnessResult as U, LOCAL_HARNESSES as V, RunLocalHarnessOptions as W, DiffOptions as X, CreateWorktreeOptions as Y, DiffResult as Z, SteerableSandboxSession as _, PeerMailKind as _t, CliWorktreeSeam as a, ToolSpec as at, Inbox as b, PeerMailReadout as bt, RouterSeam as c, ToolLoopCompaction as ct, cliWorktreeExecutor as d, ToolLoopToolCall as dt, WorktreeHandle as et, createExecutor as f, AUTHORITY_MARKERS as ft, SteerableSandboxArgs as g, PeerMailEvent as gt, SandboxSteeringOptions as h, PeerMailEnvelope as ht, CliWorktreeBridgeSeam as i, RouterTransportConfig as it, resolveSecretEnv as j, JsonRpcResponse as jt, mcpSecretEnvMetadataKey as k, peerMailVerbNames as kt, RouterToolsSeam as l, ToolLoopCompactionOptions as lt, DEFAULT_SANDBOX_STEERING_MAX_TURNS as m, PEER_MAIL_WIRE_KEY as mt, BridgeSeam as n, createWorktree as nt, ExecutorConfig as o, ToolLoopCallContext as ot, createExecutorRegistry as p, DEFAULT_PEER_MAIL_LIMITS as pt, parseCodexTokenUsage as q, CliSeam as r, removeWorktree as rt, ProviderSeam as s, ToolLoopChat as st, BridgeModelCredential as t, captureWorktreeDiff as tt, SandboxSeam as u, ToolLoopMessageRecord as ut, createSteerableSandboxSession as v, PeerMailLimits as vt, SandboxExecutorToolCall as w, PeerMailboxOptions as wt, InboxMessage as x, PeerMailRefusal as xt, AuthorityInboxMessage as y, PeerMailOutcome as yt, CodexTokenUsage as z };
1177
- //# sourceMappingURL=runtime-J6Toky8K.d.ts.map
1376
+ export { LocalHarnessResult as $, extractLlmCallEvent as A, PeerMailReadout as At, resolveMcpServerLaunch as B, JsonRpcMessage as Bt, createInbox as C, DEFAULT_PEER_MAIL_LIMITS as Ct, SandboxToolPartState as D, PeerMailKind as Dt, SandboxServedBackend as E, PeerMailEvent as Et, sumSandboxUsage as F, claimsAuthority as Ft, WorktreeHarnessResult as G, secretEnvOfMcpServer as H, McpToolDescriptor as Ht, KeyProvider as I, createPeerMailbox as It, CodexExecutionPolicy as J, WorktreeProfileMaterializationReceipt as K, ResolvedMcpServerLaunch as L, isPeerMailEnvelope as Lt, mapSandboxToolEvent as M, PeerMailSendInput as Mt, sandboxEventServedBackend as N, PeerMailbox as Nt, assertSandboxServedModel as O, PeerMailLimits as Ot, sandboxProgressEvents as P, PeerMailboxOptions as Pt, LocalHarness as Q, envKeyProvider as R, peerMailTools as Rt, PeerInboxMessage as S, AUTHORITY_MARKERS as St, SandboxOutputMarker as T, PeerMailEnvelope as Tt, WorktreeCheckRunner as U, McpTransport as Ut, resolveSecretEnv as V, JsonRpcResponse as Vt, WorktreeCommandResult as W, DEFAULT_LOCAL_HARNESS as X, CodexTokenUsage as Y, LOCAL_HARNESSES as Z, SteerableSandboxSession as _, ToolLoopChat as _t, CliWorktreeSeam as a, CreateWorktreeOptions as at, Inbox as b, ToolLoopMessageRecord as bt, RouterSeam as c, GitRunner as ct, cliWorktreeExecutor as d, captureWorktreeDiff as dt, RunLocalHarnessOptions as et, createExecutor as f, createWorktree as ft, SteerableSandboxArgs as g, ToolLoopCallContext as gt, SandboxSteeringOptions as h, ToolSpec as ht, CliWorktreeBridgeSeam as i, runLocalHarness as it, mapSandboxEvent as j, PeerMailRefusal as jt, createSandboxToolPartState as k, PeerMailOutcome as kt, RouterToolsSeam as l, RemoveWorktreeOptions as lt, DEFAULT_SANDBOX_STEERING_MAX_TURNS as m, RouterTransportConfig as mt, BridgeSeam as n, localHarnessExecutable as nt, ExecutorConfig as o, DiffOptions as ot, createExecutorRegistry as p, removeWorktree as pt, CodexExecutionEvidence as q, CliSeam as r, parseCodexTokenUsage as rt, ProviderSeam as s, DiffResult as st, BridgeModelCredential as t, harnessSupportsReasoningEffort as tt, SandboxSeam as u, WorktreeHandle as ut, createSteerableSandboxSession as v, ToolLoopCompaction as vt, SandboxLeafOut as w, PEER_MAIL_WIRE_KEY as wt, InboxMessage as x, ToolLoopToolCall as xt, AuthorityInboxMessage as y, ToolLoopCompactionOptions as yt, mcpSecretEnvMetadataKey as z, peerMailVerbNames as zt };
1377
+ //# sourceMappingURL=runtime-B-5dp5Iz.d.ts.map
@@ -98,6 +98,7 @@ function isRecord(value) {
98
98
  //#endregion
99
99
  //#region src/runtime/sandbox-events.ts
100
100
  const CANONICAL_STREAM_EVENT_TYPES = /* @__PURE__ */ new Set([
101
+ "child-task",
101
102
  "message.part.updated",
102
103
  "tool-heartbeat",
103
104
  "tool-slow",
@@ -230,6 +231,26 @@ function stripProviderPrefix(id, providers) {
230
231
  function firstString(...values) {
231
232
  return values.find((value) => typeof value === "string" && value.length > 0);
232
233
  }
234
+ const terminalTypes = /* @__PURE__ */ new Set([
235
+ "message.completed",
236
+ "result",
237
+ "final",
238
+ "done"
239
+ ]);
240
+ /** True for an event type that ends a sandbox turn. */
241
+ function isSandboxTerminalEvent(type) {
242
+ return terminalTypes.has(type);
243
+ }
244
+ /**
245
+ * Which member of a terminal event's `data` carries its usage receipt.
246
+ *
247
+ * The one place the terminal types legitimately differ, stated rather than implied by two lists:
248
+ * sandbox 0.4.0's `done` reports under `tokenUsage` with the cost at the top level, every other
249
+ * terminal type reports under `usage`.
250
+ */
251
+ function sandboxTerminalUsageField(type) {
252
+ return type === "done" ? "tokenUsage" : "usage";
253
+ }
233
254
  /**
234
255
  * Extract a `RuntimeStreamEvent`-shaped `llm_call` from a sandbox event when
235
256
  * the event carries usage/cost data. Returns `undefined` for non-cost events
@@ -255,7 +276,7 @@ function extractLlmCallEvent(event, agentRunName) {
255
276
  const type = String(event.type ?? "");
256
277
  const data = event.data && typeof event.data === "object" ? event.data : {};
257
278
  if (type === "llm_call" || type === "cost.usage" || type === "usage") return buildLlmCall(data, agentRunName);
258
- if (type === "message.completed" || type === "result" || type === "final") {
279
+ if (isSandboxTerminalEvent(type) && sandboxTerminalUsageField(type) === "usage") {
259
280
  const usage = data.usage;
260
281
  if (!usage || typeof usage !== "object") return void 0;
261
282
  return buildLlmCall({
@@ -646,7 +667,53 @@ function mapSandboxEvent(event, opts = {}) {
646
667
  }
647
668
  return extractLlmCallEvent(event, opts.agentRunName ?? "agent");
648
669
  }
670
+ /**
671
+ * Project one `SandboxEvent` onto Runtime's executor progress vocabulary: incremental text and
672
+ * reasoning, tool calls and results, and an interaction request. It composes the existing
673
+ * projections ({@link mapSandboxEvent}, {@link mapSandboxToolEvent}, and the canonical Agent
674
+ * Interface decode) so every sandbox-shaped executor publishes live output through one reader.
675
+ * Usage-bearing events project to nothing here — accounting stays on the `tokens`/`cost`
676
+ * channels.
677
+ *
678
+ * Pass one {@link SandboxToolPartState} per turn so a multi-frame tool call yields one call and
679
+ * at most one result.
680
+ *
681
+ * @experimental
682
+ */
683
+ function sandboxProgressEvents(event, state) {
684
+ const canonical = canonicalStreamEventFromSandboxEvent(event);
685
+ if (canonical?.type === "interaction") return [{
686
+ kind: "interaction",
687
+ request: canonical.request
688
+ }];
689
+ if (canonical?.type === "child-task") return [{
690
+ kind: "child_task",
691
+ event: canonical
692
+ }];
693
+ const tools = mapSandboxToolEvent(event, state).map((projected) => projected.type === "tool_call" ? {
694
+ kind: "tool_call",
695
+ toolName: projected.toolName,
696
+ ...projected.toolCallId === void 0 ? {} : { toolCallId: projected.toolCallId },
697
+ ...projected.args === void 0 ? {} : { args: projected.args }
698
+ } : {
699
+ kind: "tool_result",
700
+ toolName: projected.toolName,
701
+ ...projected.toolCallId === void 0 ? {} : { toolCallId: projected.toolCallId },
702
+ ...projected.result === void 0 ? {} : { result: projected.result }
703
+ });
704
+ if (tools.length > 0) return tools;
705
+ const mapped = mapSandboxEvent(event);
706
+ if (mapped?.type === "text_delta") return [{
707
+ kind: "text_delta",
708
+ text: mapped.text
709
+ }];
710
+ if (mapped?.type === "reasoning_delta") return [{
711
+ kind: "reasoning_delta",
712
+ text: mapped.text
713
+ }];
714
+ return [];
715
+ }
649
716
  //#endregion
650
- export { mapSandboxEvent as a, sandboxEventServedBackend as c, parseCanonicalTransportEvent as d, extractLlmCallEvent as i, sumSandboxUsage as l, canonicalStreamEventFromSandboxEvent as n, mapSandboxToolEvent as o, createSandboxToolPartState as r, notifySandboxEventObserver as s, assertSandboxServedModel as t, extractTransportEventIdentity as u };
717
+ export { isSandboxTerminalEvent as a, notifySandboxEventObserver as c, sandboxTerminalUsageField as d, sumSandboxUsage as f, extractLlmCallEvent as i, sandboxEventServedBackend as l, parseCanonicalTransportEvent as m, canonicalStreamEventFromSandboxEvent as n, mapSandboxEvent as o, extractTransportEventIdentity as p, createSandboxToolPartState as r, mapSandboxToolEvent as s, assertSandboxServedModel as t, sandboxProgressEvents as u };
651
718
 
652
- //# sourceMappingURL=sandbox-events-COwCWUVB.js.map
719
+ //# sourceMappingURL=sandbox-events-BVjstFgb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-events-BVjstFgb.js","names":[],"sources":["../src/runtime/timestamps.ts","../src/runtime/sandbox-transport-events.ts","../src/runtime/sandbox-events.ts"],"sourcesContent":["import { RuntimeEventEnvelopeSchema } from '@tangle-network/agent-interface'\n\nconst validTimestamp = '2026-01-01T00:00:00.000Z'\n\n/** Validate a timestamp with the public runtime envelope contract. */\nexport function assertRuntimeTimestamp(value: unknown, label: string): asserts value is string {\n try {\n RuntimeEventEnvelopeSchema.parse({\n runId: 'runtime',\n eventId: 'event',\n sequence: 0,\n occurredAt: value,\n receivedAt: validTimestamp,\n event: { type: 'status', status: 'processing' },\n })\n } catch (error) {\n throw new Error(`${label} must be a valid ISO timestamp`, { cause: error })\n }\n}\n\n/** Return whether a value satisfies the public runtime timestamp contract. */\nexport function isRuntimeTimestamp(value: unknown): value is string {\n try {\n assertRuntimeTimestamp(value, 'occurredAt')\n return true\n } catch {\n return false\n }\n}\n","import { CanonicalStreamEventSchema, type StreamEvent } from '@tangle-network/agent-interface'\nimport { assertRuntimeTimestamp } from './timestamps'\n\n/** Parse canonical payload fields without treating transport identity as event data. */\nexport function parseCanonicalTransportEvent(\n type: unknown,\n data: Record<string, unknown>,\n normalized: unknown,\n source: string,\n): StreamEvent | undefined {\n if (!isRecord(data)) {\n throw new Error(`${source} emitted a canonical event without an object payload`)\n }\n const outerType = String(type ?? '')\n if (normalized !== undefined) {\n if (\n typeof normalized === 'object' &&\n normalized !== null &&\n 'type' in normalized &&\n typeof normalized.type === 'string' &&\n normalized.type !== outerType\n ) {\n throw new Error(\n `${source} canonical event type \"${normalized.type}\" does not match transport type \"${outerType}\"`,\n )\n }\n const candidate = CanonicalStreamEventSchema.safeParse(normalized)\n if (!candidate.success) {\n throw new Error(`${source} emitted an invalid normalized canonical event`, {\n cause: candidate.error,\n })\n }\n return candidate.data\n }\n const {\n type: embeddedType,\n eventId: _eventId,\n cursor: _cursor,\n sequence: _sequence,\n occurredAt: _occurredAt,\n normalized: _normalized,\n ...payload\n } = data\n if (embeddedType !== undefined && embeddedType !== outerType) {\n throw new Error(\n `${source} canonical event type \"${String(embeddedType)}\" does not match transport type \"${outerType}\"`,\n )\n }\n const candidate = CanonicalStreamEventSchema.safeParse({ ...payload, type: outerType })\n return candidate.success ? candidate.data : undefined\n}\n\n/** Identity fields carried by either the transport envelope or its data payload. */\nexport interface TransportEventIdentity {\n readonly eventId?: string\n readonly cursor?: string\n readonly sequence?: number\n readonly occurredAt?: string\n}\n\n/** Extract shared event identity without privileging one provider wire shape. */\nexport function extractTransportEventIdentity(event: unknown): TransportEventIdentity {\n const record = isRecord(event) ? event : {}\n const data = isRecord(record.data) ? record.data : {}\n const providerEvent = isRecord(record.providerEvent) ? record.providerEvent : {}\n const providerData = isRecord(providerEvent.data) ? providerEvent.data : {}\n const eventId = canonicalEventId(record, data, providerEvent, providerData)\n const cursor = stableString(\n record.cursor ?? data.cursor ?? providerEvent.cursor ?? providerData.cursor,\n )\n const sequence = optionalSequence(\n record.sequence ?? data.sequence ?? providerEvent.sequence ?? providerData.sequence,\n )\n const occurredAt = optionalTimestamp(\n record.occurredAt ?? data.occurredAt ?? providerEvent.occurredAt ?? providerData.occurredAt,\n )\n return {\n ...(eventId === undefined ? {} : { eventId }),\n ...(cursor === undefined ? {} : { cursor }),\n ...(sequence === undefined ? {} : { sequence }),\n ...(occurredAt === undefined ? {} : { occurredAt }),\n }\n}\n\nfunction canonicalEventId(\n record: Record<string, unknown>,\n data: Record<string, unknown>,\n providerEvent: Record<string, unknown>,\n providerData: Record<string, unknown>,\n): string | undefined {\n const candidates = [\n ['data.eventId', data.eventId],\n ['providerEvent.eventId', providerEvent.eventId],\n ['providerData.eventId', providerData.eventId],\n ['record.eventId', record.eventId],\n ] as const\n const present = candidates.filter(([, value]) => value !== undefined)\n // `record.id` may be the provider's replay cursor, so use it only without a canonical field.\n if (present.length === 0) return stableString(record.id ?? providerEvent.id)\n\n const normalized = present.map(([source, value]) => {\n const eventId = stableString(value)\n if (eventId === undefined) throw new Error(`transport event ${source} must be a stable string`)\n return { source, eventId }\n })\n const first = normalized[0]!\n if (normalized.some((candidate) => candidate.eventId !== first.eventId)) {\n throw new Error('transport event canonical identities disagree')\n }\n return first.eventId\n}\n\nfunction stableString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 && value.trim() === value ? value : undefined\n}\n\nfunction finiteNonNegativeInteger(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined\n}\n\nfunction optionalSequence(value: unknown): number | undefined {\n if (value === undefined) return undefined\n if (finiteNonNegativeInteger(value) === undefined) {\n throw new Error('transport event sequence must be a non-negative safe integer')\n }\n return value as number\n}\n\nfunction optionalTimestamp(value: unknown): string | undefined {\n if (value === undefined) return undefined\n assertRuntimeTimestamp(value, 'occurredAt')\n return value\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","/**\n * Sandbox-event → runtime-event mapping.\n *\n * The sandbox SDK emits a polymorphic `SandboxEvent = { type, data, id? }`\n * whose `type` vocabulary is backend-determined (opencode, etc.) rather than\n * enumerated by the SDK. Two consumers project it:\n * - the loop kernel's cost ledger (`extractLlmCallEvent`) — sums usage off\n * every cost-bearing event, regardless of stream shape;\n * - the `AgentRuntime.act` streaming contract (`mapSandboxEvent`) — projects\n * incremental events to the `RuntimeStreamEvent` chat-UX vocabulary.\n *\n * Both live here so the empirically-observed `type` vocabulary has one home.\n */\n\nimport type { StreamEvent } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport type { RuntimeStreamEvent } from '../types'\nimport { parseCanonicalTransportEvent } from './sandbox-transport-events'\nimport type { ExecutorProgressEvent } from './supervise/types'\n\nconst CANONICAL_STREAM_EVENT_TYPES: ReadonlySet<string> = new Set([\n 'child-task',\n 'message.part.updated',\n 'tool-heartbeat',\n 'tool-slow',\n 'model-processing',\n 'status',\n 'warning',\n 'raw',\n 'session.updated',\n 'interaction',\n 'interaction.cancel',\n 'plan.submitted',\n])\n\n/** Decode one known Agent Interface event from a Sandbox event. */\nexport function canonicalStreamEventFromSandboxEvent(event: SandboxEvent): StreamEvent | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n const normalized = data.normalized\n if (normalized === undefined && !CANONICAL_STREAM_EVENT_TYPES.has(type)) return undefined\n return parseCanonicalTransportEvent(type, data, normalized, 'sandbox')\n}\n\n/**\n * Forward a sandbox event to an optional observer without letting observer\n * behavior affect the run. The observer receives a defensive copy, synchronous\n * throws are swallowed, and returned promises are deliberately not awaited.\n */\nexport function notifySandboxEventObserver<Meta>(\n event: SandboxEvent,\n observer: ((event: SandboxEvent, meta: Meta) => void | PromiseLike<void>) | undefined,\n meta: Meta,\n): void {\n if (!observer) return\n try {\n const result = observer(cloneEventForObserver(event), meta)\n if (result && typeof result.then === 'function') {\n void result.then(undefined, () => {})\n }\n } catch {\n // Live observation is optional and must never interrupt the event stream.\n }\n}\n\nfunction cloneEventForObserver(event: SandboxEvent): SandboxEvent {\n try {\n return structuredClone(event)\n } catch {\n return copyPlainSpine(event, new WeakMap()) as SandboxEvent\n }\n}\n\nfunction copyPlainSpine(value: unknown, seen: WeakMap<object, unknown>): unknown {\n if (value === null || typeof value !== 'object') return value\n const existing = seen.get(value)\n if (existing !== undefined) return existing\n if (Array.isArray(value)) {\n const copy: unknown[] = []\n seen.set(value, copy)\n for (const item of value) copy.push(copyPlainSpine(item, seen))\n return copy\n }\n const proto = Object.getPrototypeOf(value)\n if (proto !== Object.prototype && proto !== null) return {}\n const copy: Record<string, unknown> = {}\n seen.set(value, copy)\n for (const [key, child] of Object.entries(value)) {\n copy[key] = copyPlainSpine(child, seen)\n }\n return copy\n}\n\n/** The provider/model the platform reports it actually bound to a turn, when it reports one.\n * `source` is the platform's own account of where that choice came from — `environment` means\n * the platform chose, not the request. */\nexport interface SandboxServedBackend {\n readonly provider?: string\n readonly model?: string\n readonly source?: string\n}\n\n/**\n * Read the served execution identity off one Sandbox event.\n *\n * The platform reports `effectiveBackend` on `execution.started` and again on the terminal\n * event (`@tangle-network/sandbox`, `EffectiveBackend`). Absence returns `undefined`\n * and must stay unknown — a request is not a receipt, so nothing here may be inferred from\n * what was asked for.\n */\nexport function sandboxEventServedBackend(event: SandboxEvent): SandboxServedBackend | undefined {\n if (!event || typeof event !== 'object') return undefined\n const data = plainRecord(event.data)\n const served = plainRecord(data?.effectiveBackend)\n if (!served) return undefined\n const provider = firstString(served.provider)\n const model = firstString(served.model)\n const source = firstString(served.source)\n if (provider === undefined && model === undefined) return undefined\n return {\n ...(provider !== undefined ? { provider } : {}),\n ...(model !== undefined ? { model } : {}),\n ...(source !== undefined ? { source } : {}),\n }\n}\n\n/**\n * Fail the execution when the platform reports serving a model other than the exact one asked for.\n *\n * Measured motive (agent-runtime#892, live infrastructure 2026-08-17): 6 of 6 boxes whose profile\n * declared `zai-coding-plan/glm-5.2` reported\n * `{\"provider\":\"openai-compat\",\"model\":\"deepseek/deepseek-v4-flash\",\"source\":\"environment\"}`,\n * while the materialization receipt recorded the declared model as `status: \"known\"`. Sending\n * `backend.model` makes that substitution unlikely; only reading the report back makes it\n * detectable. A run that cannot say which model produced its evidence must not settle as one\n * that can.\n *\n * Silent when the platform reports no served model: unobserved stays unobserved.\n */\nexport function assertSandboxServedModel(\n event: SandboxEvent,\n expected: { readonly provider?: string; readonly model?: string } | undefined,\n): void {\n const wanted = expected?.model?.trim()\n if (!wanted) return\n const served = sandboxEventServedBackend(event)\n if (served?.model === undefined) return\n if (sameModelId(served.model, wanted, [served.provider, expected?.provider])) return\n const attribution = [\n served.provider !== undefined ? `provider ${JSON.stringify(served.provider)}` : undefined,\n served.source !== undefined ? `source ${JSON.stringify(served.source)}` : undefined,\n ].filter((part): part is string => part !== undefined)\n const detail = attribution.length > 0 ? ` (${attribution.join(', ')})` : ''\n throw new Error(\n `sandbox served model ${JSON.stringify(served.model)}${detail} instead of the exact profile model ${JSON.stringify(wanted)}`,\n )\n}\n\n/**\n * Do two model ids name the same model, allowing for routing prefixes?\n *\n * Either side may spell the model bare (`glm-5.2`), provider-qualified\n * (`zai-coding-plan/glm-5.2`), or route-qualified, and the platform reports the provider in its\n * own field rather than always in the id. So the comparison drops any known provider prefix and\n * then accepts a `/`-boundary suffix match: a longer route to the SAME leaf model is a routing\n * difference, not a substitution.\n *\n * What it deliberately does NOT absorb is a different leaf: `glm-5.2` against `glm-5.3` stays a\n * mismatch, which is the substitution measured directly against the provider API (a request for\n * `glm-5.2` was served `glm-5.3`). A version suffix is the whole difference between two\n * instruments, so nothing here may treat it as noise.\n */\nfunction sameModelId(\n served: string,\n wanted: string,\n providers: readonly (string | undefined)[],\n): boolean {\n const a = stripProviderPrefix(served, providers)\n const b = stripProviderPrefix(wanted, providers)\n return a === b || a.endsWith(`/${b}`) || b.endsWith(`/${a}`)\n}\n\nfunction stripProviderPrefix(id: string, providers: readonly (string | undefined)[]): string {\n let out = id.trim().toLowerCase()\n for (const provider of providers) {\n const prefix = provider?.trim().toLowerCase()\n if (prefix && out.startsWith(`${prefix}/`)) out = out.slice(prefix.length + 1)\n }\n return out\n}\n\nfunction firstString(...values: unknown[]): string | undefined {\n return values.find((value): value is string => typeof value === 'string' && value.length > 0)\n}\n\n/**\n * The sandbox event types that END a turn.\n *\n * One list, because two consumers ask this question about the same wire event and must agree: the\n * usage credit below, and the terminal-text lift in `stream-agent-turn.ts`. Written separately they\n * drifted by exactly one member — `message.completed` credited tokens and dollars while its final\n * text was never lifted, so a backend whose terminal frame carries that type produced a run that\n * was billed and recorded no answer.\n */\nexport const sandboxTerminalEventTypes = ['message.completed', 'result', 'final', 'done'] as const\n\nexport type SandboxTerminalEventType = (typeof sandboxTerminalEventTypes)[number]\n\nconst terminalTypes: ReadonlySet<string> = new Set<string>(sandboxTerminalEventTypes)\n\n/** True for an event type that ends a sandbox turn. */\nexport function isSandboxTerminalEvent(type: string): type is SandboxTerminalEventType {\n return terminalTypes.has(type)\n}\n\n/**\n * Which member of a terminal event's `data` carries its usage receipt.\n *\n * The one place the terminal types legitimately differ, stated rather than implied by two lists:\n * sandbox 0.4.0's `done` reports under `tokenUsage` with the cost at the top level, every other\n * terminal type reports under `usage`.\n */\nexport function sandboxTerminalUsageField(type: SandboxTerminalEventType): 'usage' | 'tokenUsage' {\n return type === 'done' ? 'tokenUsage' : 'usage'\n}\n\n/**\n * Extract a `RuntimeStreamEvent`-shaped `llm_call` from a sandbox event when\n * the event carries usage/cost data. Returns `undefined` for non-cost events\n * so the kernel can iterate the full stream without branching.\n *\n * Pure by contract: it never throws on a failed run. The terminal truth\n * boundary is the public Sandbox outcome tracker, applied after the complete\n * stream. Post-hoc readers — {@link sumSandboxUsage}, the\n * analyst trace store, the chat projection — must stay able to read a failed\n * turn's events, which is when reading them matters most.\n *\n * Canonical cost-carrying types observed in the wild:\n * - `llm_call` — `data: { model, tokensIn, tokensOut, costUsd, ... }`\n * - `message.completed` / `result` — `data: { usage: { inputTokens,\n * outputTokens, totalCostUsd? } }`\n * - `cost.usage` / `usage` — same shape under a dedicated type\n *\n * Numeric coercion is strict: `Number.isFinite` gates every accumulator write\n * so a sentinel `NaN` from a misbehaving backend cannot poison the ledger.\n */\nexport function extractLlmCallEvent(\n event: SandboxEvent,\n agentRunName: string,\n): (RuntimeStreamEvent & { type: 'llm_call' }) | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'llm_call' || type === 'cost.usage' || type === 'usage') {\n return buildLlmCall(data, agentRunName)\n }\n if (isSandboxTerminalEvent(type) && sandboxTerminalUsageField(type) === 'usage') {\n const usage = data.usage as Record<string, unknown> | undefined\n if (!usage || typeof usage !== 'object') return undefined\n return buildLlmCall({ ...usage, model: data.model ?? usage.model }, agentRunName)\n }\n // sandbox 0.4.0 terminal event: `data = { tokenUsage: { inputTokens, outputTokens,\n // reasoningTokens, cacheReadInputTokens }, totalCostUsd }`. Usage lives under\n // `tokenUsage` (not `usage`) and the cost is top-level — neither matched the\n // branches above, so an in-process loopDispatch run reported {0,0} and the\n // backend-integrity guard misread a real run as a stub. Reasoning tokens are\n // billed output (reasoning models), so they fold into the output count. The prompt-cache\n // counters are read off the SAME `tokenUsage` record rather than re-derived, because only\n // that record states what the provider billed.\n if (type === 'done') {\n const usage = data.tokenUsage as Record<string, unknown> | undefined\n if (!usage || typeof usage !== 'object') return undefined\n const out = pickFiniteNumber(usage, ['outputTokens', 'completion_tokens', 'tokensOut'])\n const reasoning = pickFiniteNumber(usage, ['reasoningTokens'])\n const mergedOut =\n out !== undefined || reasoning !== undefined ? (out ?? 0) + (reasoning ?? 0) : undefined\n const cache = readPromptCacheUsage(usage)\n return buildLlmCall(\n {\n inputTokens: usage.inputTokens,\n outputTokens: mergedOut,\n totalCostUsd: data.totalCostUsd,\n model: data.model ?? usage.model,\n ...(cache !== undefined ? { promptCache: cache } : {}),\n },\n agentRunName,\n )\n }\n return undefined\n}\n\n/**\n * Sum the token usage + USD cost of a sandbox turn's events — the one honest way to meter an\n * `openSandboxRun` cell. Folds `extractLlmCallEvent` over the stream (which reads usage off EVERY backend\n * event shape), so a `runProfileMatrix` dispatch can report it to `ctx.cost`:\n *\n * receipt: (turn) => {\n * const u = sumSandboxUsage(turn.events)\n * return { model, inputTokens: u.input, outputTokens: u.output,\n * ...(u.tokensKnown === false ? { usageUnknown: true } : {}),\n * ...(u.usdKnown !== false && u.costUsd > 0 ? { actualCostUsd: u.costUsd } : {}),\n * ...(u.usdKnown === false ? { costUnknown: true } : {}),\n * ...(u.estimatedCostUsd !== undefined ? { estimatedCostUsd: u.estimatedCostUsd } : {}) }\n * }\n *\n * Without this a cell reads `{tokens:0, cost:0}` and the backend-integrity guard correctly aborts the\n * matrix as a stub. `agentRunName` is the fallback model label for cost-only events (default `'agent'`).\n */\nexport function sumSandboxUsage(\n events: readonly SandboxEvent[],\n agentRunName = 'agent',\n): {\n input: number\n output: number\n costUsd: number\n tokensKnown?: false\n usdKnown?: false\n estimatedCostUsd?: number\n} {\n let input = 0\n let output = 0\n let costUsd = 0\n let estimatedCostUsd = 0\n let sawEstimate = false\n let sawCall = false\n let tokensKnown = true\n let usdKnown = true\n for (const ev of events) {\n const call = extractLlmCallEvent(ev, agentRunName)\n if (!call) continue\n sawCall = true\n input += call.tokensIn ?? 0\n output += call.tokensOut ?? 0\n costUsd += call.costUsd ?? 0\n if (call.tokensKnown === false) tokensKnown = false\n if (call.usdKnown === false) usdKnown = false\n if (call.estimatedCostUsd !== undefined) {\n estimatedCostUsd += call.estimatedCostUsd\n sawEstimate = true\n }\n }\n return {\n input,\n output,\n costUsd,\n ...(sawCall && tokensKnown ? {} : { tokensKnown: false as const }),\n ...(sawCall && usdKnown ? {} : { usdKnown: false as const }),\n ...(sawEstimate ? { estimatedCostUsd } : {}),\n }\n}\n\nfunction buildLlmCall(\n data: Record<string, unknown>,\n agentRunName: string,\n): (RuntimeStreamEvent & { type: 'llm_call' }) | undefined {\n const tokensIn = pickFiniteNumber(data, ['tokensIn', 'inputTokens', 'prompt_tokens'])\n const outputTokens = pickFiniteNumber(data, ['tokensOut', 'outputTokens', 'completion_tokens'])\n const reasoningTokens = pickFiniteNumber(data, ['reasoningTokens'])\n const tokensOut =\n outputTokens !== undefined || reasoningTokens !== undefined\n ? (outputTokens ?? 0) + (reasoningTokens ?? 0)\n : undefined\n const reportedCostUsd = pickFiniteNumber(data, ['costUsd', 'totalCostUsd', 'cost_usd', 'cost'])\n const explicitTokensKnown = data.tokensKnown ?? data.tokens_known\n const explicitCostKnown = data.costKnown ?? data.cost_known ?? data.usdKnown ?? data.usd_known\n const costProvenance = data.costProvenance ?? data.cost_provenance\n const explicitEstimate = pickFiniteNumber(data, ['estimatedCostUsd', 'estimated_cost_usd'])\n const catalogEstimate =\n costProvenance === 'catalog-estimate' ? (explicitEstimate ?? reportedCostUsd) : explicitEstimate\n const costUsd = costProvenance === 'catalog-estimate' ? undefined : reportedCostUsd\n const promptCache = readPromptCacheUsage(data)\n const tokensKnown =\n explicitTokensKnown !== false && tokensIn !== undefined && tokensOut !== undefined\n // Sandbox's canonical terminal `totalCostUsd` is already the provider-reported receipt. The\n // current SDK carries no provenance tag, so absence means the canonical receipt rather than\n // \"unknown\". Explicit estimates and explicit false-known markers remain unknown.\n const usdKnown =\n explicitCostKnown !== false &&\n costUsd !== undefined &&\n (costProvenance === undefined ||\n costProvenance === 'provider-receipt' ||\n costProvenance === 'billing-receipt')\n if (\n tokensIn === undefined &&\n tokensOut === undefined &&\n costUsd === undefined &&\n catalogEstimate === undefined &&\n promptCache === undefined &&\n explicitTokensKnown !== false &&\n explicitCostKnown !== false\n ) {\n return undefined\n }\n const model = typeof data.model === 'string' && data.model.length > 0 ? data.model : agentRunName\n const event: RuntimeStreamEvent & { type: 'llm_call' } = {\n type: 'llm_call',\n model,\n }\n if (tokensIn !== undefined) event.tokensIn = tokensIn\n if (tokensOut !== undefined) event.tokensOut = tokensOut\n if (!tokensKnown) event.tokensKnown = false\n if (costUsd !== undefined) event.costUsd = costUsd\n if (!usdKnown) event.usdKnown = false\n if (catalogEstimate !== undefined) event.estimatedCostUsd = catalogEstimate\n if (promptCache !== undefined) event.promptCache = promptCache\n return event\n}\n\n/**\n * Every wire spelling of a prompt-cache READ counter, in precedence order: the canonical name\n * first, then the spellings observed on the paths that reach this extractor — the sandbox terminal\n * `tokenUsage` record, the cli-bridge OpenAI-compatible usage object (which normalizes every\n * backend to Anthropic's `cache_read_input_tokens`), Anthropic verbatim, OpenAI's\n * `prompt_tokens_details.cached_tokens`, and DeepSeek's `prompt_cache_hit_tokens`.\n */\nconst PROMPT_CACHE_READ_KEYS = [\n 'readTokens',\n 'read_tokens',\n 'cacheReadInputTokens',\n 'cache_read_input_tokens',\n 'cacheRead',\n 'cache_read',\n 'cachedInputTokens',\n 'cachedTokens',\n 'cached_tokens',\n 'prompt_cache_hit_tokens',\n]\n\n/**\n * Every wire spelling of a prompt-cache WRITE counter. OpenAI reports no write counter at all, so\n * an OpenAI-shaped usage record matches nothing here and the write stays absent — which is the\n * point: absent is not zero.\n */\nconst PROMPT_CACHE_WRITE_KEYS = [\n 'writeTokens',\n 'write_tokens',\n 'cacheWriteInputTokens',\n 'cache_write_input_tokens',\n 'cacheCreationInputTokens',\n 'cache_creation_input_tokens',\n 'cacheWrite',\n 'cache_write',\n]\n\nconst PROMPT_CACHE_MISS_KEYS = ['missTokens', 'miss_tokens', 'prompt_cache_miss_tokens']\n\nconst PROMPT_CACHE_SAVINGS_KEYS = ['readSavingsUsd', 'read_savings_usd']\n\n/**\n * Read the provider's own prompt-cache accounting off one usage-bearing event payload, in the\n * `PromptCacheUsage` vocabulary the router, driver, and chat-client paths already speak.\n *\n * Two sources, one record. A payload that already carries a `promptCache` / `prompt_cache` object\n * is forwarded VERBATIM — those fields are the provider's own report, and an unrecognized one must\n * stay visible rather than be bucketed away. On top of that, flat provider counters are translated\n * to the canonical names, filling only the names the verbatim object did not already define.\n *\n * A counter the payload does not carry is left out. Defaulting it to zero would assert the provider\n * measured no cache, which is a different fact from a provider that reported nothing — and it is\n * the fact the budget reads to decide whether its charge is a measurement or a bound.\n */\nfunction readPromptCacheUsage(\n data: Record<string, unknown>,\n): Record<string, number | string> | undefined {\n const declared = finiteMetadata(data.promptCache ?? data.prompt_cache)\n const nested = plainRecord(data.promptCache) ?? plainRecord(data.prompt_cache)\n const details = plainRecord(data.prompt_tokens_details)\n const sources = [nested, data, details].filter(\n (s): s is Record<string, unknown> => s !== undefined,\n )\n\n const canonical: Record<string, number | string> = {}\n const readTokens = pickTokenCount(sources, PROMPT_CACHE_READ_KEYS)\n const writeTokens = pickTokenCount(sources, PROMPT_CACHE_WRITE_KEYS)\n const missTokens = pickTokenCount(sources, PROMPT_CACHE_MISS_KEYS)\n const readSavingsUsd = pickNonNegativeNumber(sources, PROMPT_CACHE_SAVINGS_KEYS)\n const status =\n nested !== undefined && typeof nested.status === 'string' ? nested.status : undefined\n if (readTokens !== undefined) canonical.readTokens = readTokens\n if (writeTokens !== undefined) canonical.writeTokens = writeTokens\n if (missTokens !== undefined) canonical.missTokens = missTokens\n if (readSavingsUsd !== undefined) canonical.readSavingsUsd = readSavingsUsd\n if (status !== undefined) canonical.status = status\n\n const merged = { ...canonical, ...declared }\n return Object.keys(merged).length > 0 ? merged : undefined\n}\n\nfunction plainRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined\n}\n\nfunction pickTokenCount(\n sources: readonly Record<string, unknown>[],\n keys: readonly string[],\n): number | undefined {\n for (const key of keys) {\n for (const source of sources) {\n const value = source[key]\n if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return value\n }\n }\n return undefined\n}\n\nfunction pickNonNegativeNumber(\n sources: readonly Record<string, unknown>[],\n keys: readonly string[],\n): number | undefined {\n for (const key of keys) {\n for (const source of sources) {\n const value = source[key]\n if (typeof value === 'number' && Number.isFinite(value) && value >= 0) return value\n }\n }\n return undefined\n}\n\nfunction finiteMetadata(value: unknown): Record<string, number | string> | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined\n const result: Record<string, number | string> = {}\n for (const [key, entry] of Object.entries(value)) {\n if ((typeof entry === 'number' && Number.isFinite(entry)) || typeof entry === 'string') {\n result[key] = entry\n }\n }\n return Object.keys(result).length > 0 ? result : undefined\n}\n\nfunction pickFiniteNumber(data: Record<string, unknown>, keys: string[]): number | undefined {\n for (const key of keys) {\n const value = data[key]\n if (typeof value === 'number' && Number.isFinite(value)) return value\n }\n return undefined\n}\n\n/**\n * Cross-event state for {@link mapSandboxToolEvent}. Sandbox backends emit a\n * tool invocation as MANY `message.part.updated` frames on the same call id\n * (pending → running → completed), so faithful projection needs per-call\n * status memory: one `tool_call` on first sighting, at most one `tool_result`\n * on the terminal transition, nothing on intermediate re-frames. Create one\n * state per turn via {@link createSandboxToolPartState}.\n *\n * @experimental\n */\nexport interface SandboxToolPartState {\n /** Last seen status per tool call id. A terminal status is sticky — later\n * frames on a settled call project to nothing. */\n statusByCall: Map<string, string>\n /** Sequence for synthesized call ids when an event carries none. */\n seq: number\n}\n\n/**\n * Fresh per-turn {@link SandboxToolPartState} for {@link mapSandboxToolEvent} — an\n * empty call-status map so each turn projects tool frames independently.\n *\n * @experimental\n */\nexport function createSandboxToolPartState(): SandboxToolPartState {\n return { statusByCall: new Map(), seq: 0 }\n}\n\n/** Statuses that settle one tool call as a failure. A failed tool call stays a tool result:\n * the run's terminal state comes from the public Sandbox outcome tracker, never from here. */\nconst TERMINAL_FAILURE = /^(error|errored|failed|failure|cancelled|canceled|timeout|timed_out)$/i\n\n/**\n * Project one `SandboxEvent` onto the `tool_call` / `tool_result` variants of\n * `RuntimeStreamEvent` — the tool-part projection `mapSandboxEvent`\n * deliberately does NOT perform. Opt-in and additive: `mapSandboxEvent`'s\n * default vocabulary (text/reasoning deltas + `llm_call`) is unchanged;\n * consumers that need the tool surface (chat UIs rendering tool activity)\n * compose this projector alongside it — `streamAgentTurn` does exactly that\n * under its `preserveToolParts` option.\n *\n * Handled shapes (observed on the opencode / claude-code sandbox backends):\n * - `message.part.updated` with `part.type === 'tool'` — stateful: a\n * `tool_call` on the call id's first frame (args from `state.input` or\n * `state.metadata.input`), a `tool_result` when the status transitions to\n * `completed` (result from `state.output` / `metadata.output`) or to a\n * terminal failure (result is `{ error, status, output? }` — the error\n * surfaced in-band, never dropped).\n * - bare `tool*` event types (`tool.call`, `tool_result`, …) — stateless:\n * `*result*` types project to `tool_result`, the rest to `tool_call`.\n *\n * Returns `[]` for every non-tool event.\n *\n * @experimental\n */\nexport function mapSandboxToolEvent(\n event: SandboxEvent,\n state: SandboxToolPartState,\n): (RuntimeStreamEvent & { type: 'tool_call' | 'tool_result' })[] {\n if (!event || typeof event !== 'object') return []\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'message.part.updated') {\n const part =\n data.part && typeof data.part === 'object' ? (data.part as Record<string, unknown>) : {}\n if (String(part.type ?? '') !== 'tool') return []\n return projectToolPart(part, state, typeof event.id === 'string' ? event.id : undefined)\n }\n\n if (type.includes('tool')) {\n const callId =\n pickString(data, ['toolCallId', 'tool_use_id', 'id']) ??\n (typeof event.id === 'string' ? event.id : undefined) ??\n `sandbox-tool-${++state.seq}`\n const toolName = pickString(data, ['name', 'toolName', 'tool']) ?? 'sandbox_tool'\n if (type.includes('result')) {\n return [\n {\n type: 'tool_result',\n toolName,\n toolCallId: callId,\n result: data.output ?? data.result ?? data.content ?? data,\n },\n ]\n }\n return [\n { type: 'tool_call', toolName, toolCallId: callId, args: data.input ?? data.args ?? {} },\n ]\n }\n\n return []\n}\n\nfunction projectToolPart(\n part: Record<string, unknown>,\n state: SandboxToolPartState,\n eventId: string | undefined,\n): (RuntimeStreamEvent & { type: 'tool_call' | 'tool_result' })[] {\n const callId =\n pickString(part, ['callID', 'callId', 'toolCallId', 'id']) ??\n eventId ??\n `sandbox-tool-${++state.seq}`\n const toolName = pickString(part, ['tool', 'toolName', 'name']) ?? 'sandbox_tool'\n const toolState =\n part.state && typeof part.state === 'object' ? (part.state as Record<string, unknown>) : {}\n const metadata =\n toolState.metadata && typeof toolState.metadata === 'object'\n ? (toolState.metadata as Record<string, unknown>)\n : {}\n const status = pickString(toolState, ['status']) ?? 'updated'\n\n const previous = state.statusByCall.get(callId)\n const settled =\n previous === 'completed' || (previous !== undefined && TERMINAL_FAILURE.test(previous))\n if (settled) return []\n\n const out: (RuntimeStreamEvent & { type: 'tool_call' | 'tool_result' })[] = []\n if (previous === undefined) {\n out.push({\n type: 'tool_call',\n toolName,\n toolCallId: callId,\n args: toolState.input ?? metadata.input ?? {},\n })\n }\n state.statusByCall.set(callId, status)\n\n if (status === 'completed') {\n out.push({\n type: 'tool_result',\n toolName,\n toolCallId: callId,\n result: toolState.output ?? metadata.output ?? '',\n })\n } else if (TERMINAL_FAILURE.test(status)) {\n const message =\n pickString(toolState, ['error', 'message']) ??\n pickString(metadata, ['error', 'message']) ??\n `sandbox tool ended with status ${status}`\n const output = toolState.output ?? metadata.output\n out.push({\n type: 'tool_result',\n toolName,\n toolCallId: callId,\n result: { error: message, status, ...(output !== undefined ? { output } : {}) },\n })\n }\n return out\n}\n\nfunction pickString(data: Record<string, unknown>, keys: string[]): string | undefined {\n for (const key of keys) {\n const value = data[key]\n if (typeof value === 'string' && value.length > 0) return value\n }\n return undefined\n}\n\n/**\n * Project one `SandboxEvent` onto the `RuntimeStreamEvent` chat-UX vocabulary,\n * for runtimes that bridge a sandbox `streamPrompt` into the\n * `AgentRuntime.act` streaming contract. Returns `undefined` for events that\n * have no faithful projection — the raw stream is preserved separately for the\n * `OutputAdapter`, so an unmapped event never loses data.\n *\n * Mapped (the task-optional incremental variants — no synthesized task\n * lifecycle, no guessed tool-part shapes):\n * - `message.part.updated` text part → `text_delta`\n * - `message.part.updated` reasoning/thinking part → `reasoning_delta`\n * - cost-bearing events → `llm_call` (shared with the ledger extractor)\n *\n * Tool parts are deliberately NOT mapped here (unchanged default) — compose\n * {@link mapSandboxToolEvent} alongside when a consumer needs them.\n *\n * The opencode backend emits incremental text as\n * `{ type: 'message.part.updated', data: { part: { type, text }, delta } }`;\n * `delta` is the increment, `part.text` the running accumulation.\n */\nexport function mapSandboxEvent(\n event: SandboxEvent,\n opts: { agentRunName?: string } = {},\n): RuntimeStreamEvent | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'message.part.updated') {\n const part =\n data.part && typeof data.part === 'object' ? (data.part as Record<string, unknown>) : {}\n const partType = String(part.type ?? '')\n const delta = typeof data.delta === 'string' ? data.delta : undefined\n const text = delta ?? (typeof part.text === 'string' ? part.text : undefined)\n if (text === undefined) return undefined\n if (partType === 'text') return { type: 'text_delta', text }\n if (partType === 'reasoning' || partType === 'thinking')\n return { type: 'reasoning_delta', text }\n return undefined\n }\n\n return extractLlmCallEvent(event, opts.agentRunName ?? 'agent')\n}\n\n/**\n * Project one `SandboxEvent` onto Runtime's executor progress vocabulary: incremental text and\n * reasoning, tool calls and results, and an interaction request. It composes the existing\n * projections ({@link mapSandboxEvent}, {@link mapSandboxToolEvent}, and the canonical Agent\n * Interface decode) so every sandbox-shaped executor publishes live output through one reader.\n * Usage-bearing events project to nothing here — accounting stays on the `tokens`/`cost`\n * channels.\n *\n * Pass one {@link SandboxToolPartState} per turn so a multi-frame tool call yields one call and\n * at most one result.\n *\n * @experimental\n */\nexport function sandboxProgressEvents(\n event: SandboxEvent,\n state: SandboxToolPartState,\n): ExecutorProgressEvent[] {\n const canonical = canonicalStreamEventFromSandboxEvent(event)\n if (canonical?.type === 'interaction') {\n return [{ kind: 'interaction', request: canonical.request }]\n }\n if (canonical?.type === 'child-task') {\n return [{ kind: 'child_task', event: canonical }]\n }\n const tools = mapSandboxToolEvent(event, state).map((projected) =>\n projected.type === 'tool_call'\n ? ({\n kind: 'tool_call',\n toolName: projected.toolName,\n ...(projected.toolCallId === undefined ? {} : { toolCallId: projected.toolCallId }),\n ...(projected.args === undefined ? {} : { args: projected.args }),\n } as const)\n : ({\n kind: 'tool_result',\n toolName: projected.toolName,\n ...(projected.toolCallId === undefined ? {} : { toolCallId: projected.toolCallId }),\n ...(projected.result === undefined ? {} : { result: projected.result }),\n } as const),\n )\n if (tools.length > 0) return tools\n const mapped = mapSandboxEvent(event)\n if (mapped?.type === 'text_delta') return [{ kind: 'text_delta', text: mapped.text }]\n if (mapped?.type === 'reasoning_delta') return [{ kind: 'reasoning_delta', text: mapped.text }]\n return []\n}\n\nexport {\n extractTransportEventIdentity,\n parseCanonicalTransportEvent,\n type TransportEventIdentity,\n} from './sandbox-transport-events'\n"],"mappings":"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"}