@demlik/tea 0.17.0 → 0.19.0

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 (119) hide show
  1. package/README.md +4 -3
  2. package/dist/agent/index.d.ts +182 -35
  3. package/dist/agent/index.js +11 -11
  4. package/dist/{chunk-KWNCM6XM.js → chunk-AHW2CLPT.js} +65 -18
  5. package/dist/chunk-AHW2CLPT.js.map +1 -0
  6. package/dist/{chunk-K4ETBNKS.js → chunk-AIIXV4XB.js} +38 -9
  7. package/dist/chunk-AIIXV4XB.js.map +1 -0
  8. package/dist/{chunk-LYVOGOBC.js → chunk-BRX3243I.js} +3 -3
  9. package/dist/{chunk-LYVOGOBC.js.map → chunk-BRX3243I.js.map} +1 -1
  10. package/dist/{chunk-GWWCCSDH.js → chunk-C3G2QFEZ.js} +4 -4
  11. package/dist/{chunk-GWWCCSDH.js.map → chunk-C3G2QFEZ.js.map} +1 -1
  12. package/dist/{chunk-C4U5D5HP.js → chunk-FNGZMVIT.js} +3 -3
  13. package/dist/chunk-FNGZMVIT.js.map +1 -0
  14. package/dist/{chunk-QWIPH4YH.js → chunk-H2ELKHI6.js} +16 -6
  15. package/dist/chunk-H2ELKHI6.js.map +1 -0
  16. package/dist/chunk-H3MWNH7A.js +119 -0
  17. package/dist/chunk-H3MWNH7A.js.map +1 -0
  18. package/dist/chunk-I7E7AD2S.js +213 -0
  19. package/dist/chunk-I7E7AD2S.js.map +1 -0
  20. package/dist/{chunk-OYR7ENKU.js → chunk-IHUNKHDX.js} +3 -3
  21. package/dist/{chunk-OYR7ENKU.js.map → chunk-IHUNKHDX.js.map} +1 -1
  22. package/dist/chunk-JVE2LBFJ.js +21 -0
  23. package/dist/chunk-JVE2LBFJ.js.map +1 -0
  24. package/dist/chunk-JVKU2UQC.js +34 -0
  25. package/dist/chunk-JVKU2UQC.js.map +1 -0
  26. package/dist/{chunk-OPH6Y4UT.js → chunk-JYNYG5SF.js} +4 -4
  27. package/dist/{chunk-OPH6Y4UT.js.map → chunk-JYNYG5SF.js.map} +1 -1
  28. package/dist/{chunk-XBZQT2TD.js → chunk-PCJA2HTZ.js} +437 -162
  29. package/dist/chunk-PCJA2HTZ.js.map +1 -0
  30. package/dist/{chunk-DFUEAA6L.js → chunk-PQSDUX6B.js} +3 -3
  31. package/dist/{chunk-DFUEAA6L.js.map → chunk-PQSDUX6B.js.map} +1 -1
  32. package/dist/{chunk-6XBEYZME.js → chunk-WTSOW2MD.js} +5 -5
  33. package/dist/{chunk-6XBEYZME.js.map → chunk-WTSOW2MD.js.map} +1 -1
  34. package/dist/{chunk-4PXNZ5UY.js → chunk-XVIKSRCK.js} +4 -4
  35. package/dist/{chunk-4PXNZ5UY.js.map → chunk-XVIKSRCK.js.map} +1 -1
  36. package/dist/{chunk-4NTCPTNQ.js → chunk-YIMOFXST.js} +3 -3
  37. package/dist/{chunk-4NTCPTNQ.js.map → chunk-YIMOFXST.js.map} +1 -1
  38. package/dist/{core-rDbOaJTN.d.ts → core-Ce9ncpuv.d.ts} +5 -4
  39. package/dist/do/index.d.ts +140 -64
  40. package/dist/do/index.js +17 -18
  41. package/dist/do/index.js.map +1 -1
  42. package/dist/drive-loop-CsUsW3Wo.d.ts +127 -0
  43. package/dist/{durable-effects-CNaw97Be.d.ts → durable-effects-BmUrRA-h.d.ts} +1 -1
  44. package/dist/effect/index.d.ts +6 -150
  45. package/dist/effect/index.js +4 -96
  46. package/dist/effect/index.js.map +1 -1
  47. package/dist/extension/index.d.ts +7 -5
  48. package/dist/extension/index.js +2 -3
  49. package/dist/extension/index.js.map +1 -1
  50. package/dist/flow/index.d.ts +13 -13
  51. package/dist/flow/index.js +13 -12
  52. package/dist/flow/index.js.map +1 -1
  53. package/dist/idempotency/index.d.ts +3 -3
  54. package/dist/idempotency/index.js +4 -4
  55. package/dist/{index-q1PoukOZ.d.ts → index-2kNxy6az.d.ts} +2 -2
  56. package/dist/{index-B_BxplWi.d.ts → index-B1Wzarkl.d.ts} +1 -1
  57. package/dist/{index-Cberb5Rr.d.ts → index-Bf9_bNql.d.ts} +2 -2
  58. package/dist/index-BnsAqn0-.d.ts +286 -0
  59. package/dist/{index-Cx0F2M34.d.ts → index-Ce5GYAuI.d.ts} +2 -2
  60. package/dist/{index-CWmsXNdX.d.ts → index-D8sYVzCI.d.ts} +1 -1
  61. package/dist/{index-CcrKLtse.d.ts → index-DWdg7R1l.d.ts} +1 -1
  62. package/dist/{index-BOrsbdAf.d.ts → index-Dy3379ve.d.ts} +5 -5
  63. package/dist/{index-DaX_P35Q.d.ts → index-e36uEyl4.d.ts} +3 -3
  64. package/dist/index.d.ts +109 -36
  65. package/dist/index.js +2 -2
  66. package/dist/jev/index.d.ts +8 -8
  67. package/dist/jev/index.js +6 -7
  68. package/dist/jev/index.js.map +1 -1
  69. package/dist/{machine-BcfCFMYF.d.ts → machine-CuojfZup.d.ts} +353 -57
  70. package/dist/machine-viz/index.d.ts +1 -1
  71. package/dist/machine-viz/index.js +2 -2
  72. package/dist/mem/index.d.ts +6 -6
  73. package/dist/mem/index.js +6 -2
  74. package/dist/mem/index.js.map +1 -1
  75. package/dist/node/index.d.ts +16 -10
  76. package/dist/node/index.js +22 -3
  77. package/dist/node/index.js.map +1 -1
  78. package/dist/otel/index.d.ts +161 -0
  79. package/dist/otel/index.js +403 -0
  80. package/dist/otel/index.js.map +1 -0
  81. package/dist/paginate/index.d.ts +4 -4
  82. package/dist/paginate/index.js +5 -5
  83. package/dist/parity/index.d.ts +3 -3
  84. package/dist/parity/index.js +3 -3
  85. package/dist/pbt/index.d.ts +166 -53
  86. package/dist/pbt/index.js +2 -2
  87. package/dist/pbt/index.js.map +1 -1
  88. package/dist/persistence/index.d.ts +5 -5
  89. package/dist/persistence/index.js +5 -5
  90. package/dist/promise/index.d.ts +2 -2
  91. package/dist/promise/index.js +4 -3
  92. package/dist/react/index.d.ts +2 -2
  93. package/dist/resilience/index.d.ts +13 -9
  94. package/dist/resilience/index.js +5 -5
  95. package/dist/resilience/index.js.map +1 -1
  96. package/dist/{runtime-types-B62Ucnxr.d.ts → runtime-types-BKg2CGMx.d.ts} +88 -14
  97. package/dist/testing/effect/index.d.ts +65 -0
  98. package/dist/testing/effect/index.js +148 -0
  99. package/dist/testing/effect/index.js.map +1 -0
  100. package/dist/testing/index.d.ts +12 -158
  101. package/dist/testing/index.js +4 -130
  102. package/dist/testing/index.js.map +1 -1
  103. package/dist/testing/promise/index.d.ts +41 -0
  104. package/dist/testing/promise/index.js +37 -0
  105. package/dist/testing/promise/index.js.map +1 -0
  106. package/dist/timing/index.d.ts +4 -4
  107. package/dist/timing/index.js +4 -4
  108. package/dist/{types-DPm5YCDQ.d.ts → types-SzNSHKlV.d.ts} +1 -1
  109. package/dist/work-queue/index.d.ts +4 -4
  110. package/dist/work-queue/index.js +4 -3
  111. package/dist/work-queue/index.js.map +1 -1
  112. package/package.json +26 -14
  113. package/dist/chunk-C4U5D5HP.js.map +0 -1
  114. package/dist/chunk-G5E74IJB.js +0 -8
  115. package/dist/chunk-G5E74IJB.js.map +0 -1
  116. package/dist/chunk-K4ETBNKS.js.map +0 -1
  117. package/dist/chunk-KWNCM6XM.js.map +0 -1
  118. package/dist/chunk-QWIPH4YH.js.map +0 -1
  119. package/dist/chunk-XBZQT2TD.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import { C as Cmd, r as Tagged, o as Interpret, A as AnyCmdDef, c as CmdOf, b as CmdDef, j as Settled, s as OkOf, t as ErrOf, q as MalformedResult, l as Outcome, u as CmdValue, H as HandlerCtx, g as TaggedError, M as Machine, d as Subscribe } from './core-rDbOaJTN.js';
2
- import { a as MonitoredRunState, R as RunFailure, M as MonitoredRunCmd } from './index-BOrsbdAf.js';
3
- import { R as RunCmd, S as SucceedMsg, F as FailMsg, a as ResilientState, r as RunCmdDef } from './index-q1PoukOZ.js';
4
- import { D as DeadlineExceeded, a as DeadlineSub, b as DeadlinesSub } from './index-DaX_P35Q.js';
1
+ import { C as Cmd, o as Tagged, I as Interpret, A as AnyCmdDef, a as CmdOf, b as CmdDef, h as Settled, p as OkOf, E as ErrOf, n as MalformedResult, O as Outcome, q as CmdValue, H as HandlerCtx, f as TaggedError, M as Machine, S as Subscribe } from './core-Ce9ncpuv.js';
2
+ import { b as MonitoredRunState, R as RunFailure, M as MonitoredRunCmd } from './index-Dy3379ve.js';
3
+ import { R as RunCmd, S as SucceedMsg, F as FailMsg, a as ResilientState, r as RunCmdDef } from './index-2kNxy6az.js';
4
+ import { D as DeadlineExceeded, a as DeadlineSub, b as DeadlinesSub } from './index-e36uEyl4.js';
5
5
  import { M as MsgType, a as MsgTypeValue } from './protocol-ClRZBhHQ.js';
6
- import { F as FanOutState } from './index-Cx0F2M34.js';
6
+ import { F as FanOutState } from './index-Ce5GYAuI.js';
7
7
  import { RetryPolicy, AnyRetryPolicy } from './retry-backoff/index.js';
8
8
  import { StandardSchemaV1 } from '@standard-schema/spec';
9
9
 
@@ -191,6 +191,15 @@ interface ToolCall {
191
191
  * which must be JSON-serializable like the rest of the Model. A compaction fold
192
192
  * (ADR 0004) summarises turns into text, so it drops the slot with the turns it
193
193
  * summarises. Optional and additive: a persisted turn without it still parses.
194
+ *
195
+ * `usage` is what the provider REPORTED this call cost (#332) — never an
196
+ * estimate tea computes. It is part of the brain call's journaled outcome, like
197
+ * `content`, so a replay folds the same numbers (ADR 0004's "no token estimate
198
+ * enters the Model" still holds). The run sums it into its running total
199
+ * ({@link AgentState.usage}) and the conversation reads the latest context size
200
+ * off it. Optional and additive: a turn
201
+ * whose adapter maps no usage, or one persisted before the field existed,
202
+ * parses and simply counts for nothing.
194
203
  */
195
204
  interface AgentTurn {
196
205
  /** Free-text narration the model produced this turn (folded into the conversation). */
@@ -199,7 +208,39 @@ interface AgentTurn {
199
208
  readonly toolCalls: readonly ToolCall[];
200
209
  /** Provider-opaque blocks to echo back verbatim next turn. tea never reads it. */
201
210
  readonly provider?: unknown;
211
+ /** The token usage the provider reported for this call. Omit → none reported. */
212
+ readonly usage?: TurnUsage;
202
213
  }
214
+ /**
215
+ * The token usage a provider reported for one model call, in the provider's own
216
+ * counts. Every field is a non-negative integer; `agentTurnSchema` refuses
217
+ * anything else, so a malformed report is the brain call's `llm` failure rather
218
+ * than a `NaN` in the running total.
219
+ *
220
+ * `inputTokens` is the WHOLE prompt the call read, cached tokens included —
221
+ * the number that says how full the context window is. `cachedInputTokens` is
222
+ * the part of it the provider served from its prompt cache, so it never exceeds
223
+ * `inputTokens`. An adapter whose provider reports the two apart (Anthropic's
224
+ * `input_tokens` excludes cache reads) adds them back together here.
225
+ *
226
+ * The same shape is the run's running total ({@link AgentState.usage}): the
227
+ * sum, field by field, of every turn that reported one.
228
+ */
229
+ interface TurnUsage {
230
+ /** Prompt tokens the call read, cached ones included. */
231
+ readonly inputTokens: number;
232
+ /** Tokens the model produced. */
233
+ readonly outputTokens: number;
234
+ /** Of `outputTokens`, those spent on reasoning — when the provider says. */
235
+ readonly reasoningTokens?: number;
236
+ /** Of `inputTokens`, those served from the provider's prompt cache — when it says. */
237
+ readonly cachedInputTokens?: number;
238
+ }
239
+ /**
240
+ * Narrow an unknown to a {@link TurnUsage} — the two required counts present,
241
+ * and each optional one either absent or a count too. PURE — allocates no Error.
242
+ */
243
+ declare function isTurnUsage(value: unknown): value is TurnUsage;
203
244
  /**
204
245
  * One partial piece of a turn the model is still producing — a token delta, as
205
246
  * the provider emitted it.
@@ -262,8 +303,9 @@ declare function isStreamingModel(model: (...args: never[]) => unknown): boolean
262
303
  * agent exports both. Checks the load-bearing fields: `content` is a string and
263
304
  * `toolCalls` is an array of `ToolCall` (each element guarded — the narrow is a
264
305
  * real parse of the boundary, not a shallow `Array.isArray`). `provider` is
265
- * opaque, so its presence or absence is not a fact the guard reads. PURE —
266
- * allocates no Error.
306
+ * opaque, so its presence or absence is not a fact the guard reads. `usage` is
307
+ * not opaque — the reducer sums it — so it is either absent or a well-formed
308
+ * {@link TurnUsage}. PURE — allocates no Error.
267
309
  */
268
310
  declare function isAgentTurn(value: unknown): value is AgentTurn;
269
311
  /**
@@ -436,6 +478,11 @@ type Awaiting = {
436
478
  * effect for the agentic stage.
437
479
  *
438
480
  * Generic over the consumer's tool-result type `R` (what `toolOk` carries).
481
+ *
482
+ * `contextTokens` is this transcript's reading of provider-reported usage
483
+ * (#332); the run's total is not the transcript's, so it lives on
484
+ * {@link AgentState.usage}. A Model persisted before `contextTokens` existed
485
+ * comes back without it, and the first transition fills it in as `null`.
439
486
  */
440
487
  interface Conversation<R> {
441
488
  /** Model turns this stage has produced, in order. */
@@ -446,6 +493,14 @@ interface Conversation<R> {
446
493
  readonly turnCount: number;
447
494
  /** What the loop is waiting for next. */
448
495
  readonly awaiting: Awaiting;
496
+ /**
497
+ * The latest context size: `inputTokens + outputTokens` of the most recent
498
+ * brain turn — how much of the context window the transcript now fills.
499
+ * `null` when that turn reported no usage, when a compaction fold has run
500
+ * since (the pre-fold size describes a transcript that no longer exists), and
501
+ * at the start of each stage. `compaction.afterContextTokens` reads it.
502
+ */
503
+ readonly contextTokens: number | null;
449
504
  }
450
505
  /**
451
506
  * The snapshotting discriminant. Checkpointing is either OFF — in which
@@ -595,8 +650,10 @@ interface AgentConfigCore<Stage, P extends string, O extends Record<P, AgentTurn
595
650
  * transcript stands and no further model call goes out. Omit → no predicate.
596
651
  *
597
652
  * Where `maxTurns` and `maxElapsedMs` bound a quantity this agent counts,
598
- * this bounds one only the caller can see (a token ledger, an external flag,
599
- * a condition on the turns so far). It must be PURE and total over the state
653
+ * this bounds one only the caller can see (an external flag, a condition on
654
+ * the turns so far) — or a token budget: `state.usage` is the run's running
655
+ * total of provider-reported usage, so a budget stop is a predicate over it
656
+ * and needs no knob of its own (#332). It must be PURE and total over the state
600
657
  * it is handed — the reducer calls it, so a replay of the same Msg log calls
601
658
  * it with the same state and must get the same answer. It is config, not
602
659
  * Model: a resumed run consults the predicate the config passed to THIS boot.
@@ -646,6 +703,8 @@ type AgentFailure = {
646
703
  * - `tools` — the `../fan-out` ledger for the current turn's tools.
647
704
  * - `conversation` — the agentic-stage loop state. `null` until the loop is
648
705
  * entered (the consumer seeds it at the agentic stage).
706
+ * - `usage` — the run's provider-reported token total. It outlives
707
+ * every conversation, `done` included.
649
708
  * - `failure` — the agent-specific terminal annotation (turn-limit /
650
709
  * llm), null otherwise. Distinct from `run.failure`.
651
710
  * - `instructions` — the system prompt this run was configured with, set at
@@ -656,6 +715,20 @@ interface AgentState<Stage, P extends string, O extends Record<P, unknown>, R> {
656
715
  readonly resilience: ResilientState<LlmCall<P>, LlmOk<P, O>>;
657
716
  readonly tools: FanOutState<ToolCall, ToolOutcome<R>>;
658
717
  readonly conversation: Conversation<R> | null;
718
+ /**
719
+ * The run's running usage total (#332, #354): every brain turn of this RUN
720
+ * that reported usage, summed field by field. It is what the run cost, so it
721
+ * belongs to the run and not to any one conversation: a compaction fold keeps
722
+ * it, a stage advance keeps it, and the retire to `done` keeps it after the
723
+ * conversation is cleared — `status(state)`'s `done` arm hands it on. Only
724
+ * `agent_start` resets it to zero. Read it from `stopWhen` for a token budget.
725
+ *
726
+ * The one place the total lives. A Model persisted before this field held its
727
+ * total on `conversation.usage`, and one persisted by 0.17.x held none; the
728
+ * first transition either takes over lifts the old total here (or starts from
729
+ * zero) and drops the conversation's copy.
730
+ */
731
+ readonly usage: TurnUsage;
659
732
  /**
660
733
  * The compaction round-trip's resilient slice (#85, design B1) — a DEDICATED
661
734
  * resilient-call slice for the reserved `$compact` purpose, separate from the
@@ -702,6 +775,22 @@ interface AgentState<Stage, P extends string, O extends Record<P, unknown>, R> {
702
775
  * retire on purpose — that is exactly when a late settle arrives.
703
776
  */
704
777
  readonly refusedCalls: readonly string[];
778
+ /**
779
+ * What THIS transition started, failed or ended (#331) — the outbox the
780
+ * event projector reads. Cleared on entry to every verb, so it only ever
781
+ * holds the one transition's facts.
782
+ *
783
+ * The projector sees `(msg, post-state)` and nothing else, and none of these
784
+ * facts can be read back off that pair: a brain call issued after a batch
785
+ * drains, a queued tool backfilling a slot, a timeout the ladder settled and
786
+ * the transition that ended the run all leave a state that looks like the
787
+ * one before. The reducer knows at the moment it does them, so it writes
788
+ * them down here, the same way `refusedCalls` carries the one fact the
789
+ * projector could not derive.
790
+ *
791
+ * Absent on a Model persisted before 0.18; every reader treats that as empty.
792
+ */
793
+ readonly lifecycle: readonly AgentLifecycleNote[];
705
794
  readonly failure: AgentFailure | null;
706
795
  /**
707
796
  * The run's terminal output — the FIRST-CLASS result (issue #46). `null`
@@ -750,6 +839,45 @@ interface AgentState<Stage, P extends string, O extends Record<P, unknown>, R> {
750
839
  * without knowing which channel produced it.
751
840
  */
752
841
  type AgentTerminalFailure<Stage> = AgentFailure | RunFailure<Stage>;
842
+ /**
843
+ * One fact a transition recorded on {@link AgentState.lifecycle} — the input
844
+ * the `agentEvents` projector turns into `BrainStarted`, `ToolStarted`,
845
+ * `ToolFailed` and `RunDone`.
846
+ *
847
+ * - `brain_started` — a brain call was issued for conversation turn `turn`.
848
+ * Once per turn, and again on a cold-wake `boot` that re-fires it; a retry
849
+ * of the same turn is not a new start. It names the call by its `purpose`,
850
+ * which is the call's key on {@link AgentState.resilience}, and carries no
851
+ * copy of the request: the in-flight `LlmCall` is already on that slice, so
852
+ * a checkpoint holds the prompt once (#354). The projector reads the
853
+ * request's `payload` from there.
854
+ * - `tool_started` — a tool call was issued: launched from a batch, a
855
+ * queued call backfilling a slot, or re-fired by `boot`. A retry is not a
856
+ * new start.
857
+ * - `tool_failed` — a call ended on a failure the model will read: its own
858
+ * error, a spent retry budget, or its timeout.
859
+ * - `run_ended` — the run reached `done`, `failed` or `cancelled` on
860
+ * this transition.
861
+ */
862
+ type AgentLifecycleNote = {
863
+ readonly kind: "brain_started";
864
+ readonly turn: number;
865
+ readonly purpose: string;
866
+ readonly model: string | null;
867
+ readonly at: number;
868
+ } | {
869
+ readonly kind: "tool_started";
870
+ readonly call: ToolCall;
871
+ readonly at: number;
872
+ } | {
873
+ readonly kind: "tool_failed";
874
+ readonly call: ToolCall;
875
+ readonly failure: ToolFailure;
876
+ readonly at: number;
877
+ } | {
878
+ readonly kind: "run_ended";
879
+ readonly at: number;
880
+ };
753
881
  /**
754
882
  * The agent's lifecycle status — THE single typed channel for "what is this run
755
883
  * doing?". A discriminated union on `kind` so any change to the
@@ -774,7 +902,8 @@ type AgentTerminalFailure<Stage> = AgentFailure | RunFailure<Stage>;
774
902
  * `agentIsResumable` re-derived by hand.
775
903
  * - `done` — the pipeline finished; `output` is the terminal model turn
776
904
  * stamped on `state.output` (issue #46), `null` if the run
777
- * produced no turn.
905
+ * produced no turn. `usage` is what the whole run cost,
906
+ * `state.usage` (#354).
778
907
  * - `failed` — terminal failure; `failure` is the UNIFIED channel
779
908
  * (`AgentTerminalFailure`), absorbing the `state.failure` vs
780
909
  * `state.run.failure` dual channel so callers stop unioning.
@@ -797,6 +926,7 @@ type AgentStatus<Stage> = {
797
926
  } | {
798
927
  readonly kind: "done";
799
928
  readonly output: AgentTurn | null;
929
+ readonly usage: TurnUsage;
800
930
  } | {
801
931
  readonly kind: "failed";
802
932
  readonly failure: AgentTerminalFailure<Stage>;
@@ -804,6 +934,14 @@ type AgentStatus<Stage> = {
804
934
  readonly kind: "cancelled";
805
935
  readonly at: number;
806
936
  };
937
+ /**
938
+ * The three {@link AgentStatus} arms a run can end on — what `RunDone` carries.
939
+ * `done` holds the output, `failed` the unified failure, `cancelled` when the
940
+ * stop landed.
941
+ */
942
+ type AgentEndedStatus<Stage = unknown> = Extract<AgentStatus<Stage>, {
943
+ readonly kind: "done" | "failed" | "cancelled";
944
+ }>;
807
945
  /**
808
946
  * Ask where an agent run stands: pass its state, get back one of `idle`,
809
947
  * `running`, `suspended` (with the tool calls it is waiting on), `done` (with
@@ -825,7 +963,8 @@ type AgentStatus<Stage> = {
825
963
  * an `init` slice is never mistaken for a run in flight.
826
964
  * 3. `run.phase === "failed"` → `failed`, carrying `run.failure` (deadline /
827
965
  * stage). The fallback channel.
828
- * 4. `run.phase === "done"` → `done` with `state.output` (#46).
966
+ * 4. `run.phase === "done"` → `done` with `state.output` (#46) and the run's
967
+ * usage total (#354).
829
968
  * 5. `run.phase === "cancelled"` → `cancelled`, carrying when the stop landed.
830
969
  * 6. `running` / `stale` + conversation + `awaiting.kind === "tools"` →
831
970
  * `suspended` with the outstanding tool calls (`tools.running`). THE
@@ -985,17 +1124,81 @@ type CompactInterpret<M extends {
985
1124
  };
986
1125
 
987
1126
  /**
988
- * @demlik/tea/agent — `tool()` + `toolRouter()`: declare a tool once and derive
989
- * what a consumer used to hand-write twice — the `toolOf` mapping from a
990
- * model's `ToolCall` to an effect Cmd, and the interpret handler that runs it
991
- * and settles it.
1127
+ * @demlik/tea/agent — content parts: the provider-neutral shape a multimodal
1128
+ * message is written in.
992
1129
  *
993
- * A tool is a `Cmd.define`d effect whose input is the model's call —
994
- * `{ callId, args }` — with the handler colocated on the constructor. The
995
- * router folds a set of them into one `toolOf` and one interpret table; the
996
- * handlers settle through the minted `<name>_ok` / `<name>_err` Msgs, errors as
997
- * `{ _tag }` data (ADR 0011). `createAgent(...).toMachine({ tools })` folds
998
- * those settles into the conversation, so a consumer names nothing twice.
1130
+ * A `user` message's content is a string or a list of parts, and a tool can
1131
+ * hand the model parts beside its outcome (a screenshot, a PDF). The three
1132
+ * kinds are the intersection Anthropic's and OpenAI's content blocks both map
1133
+ * onto — text, an image, a file — and tea imports neither SDK: the adapter
1134
+ * maps a part to its provider's block, exactly as it maps a whole message.
1135
+ */
1136
+ /**
1137
+ * Where an image's or a file's bytes are. Inline as base64 text, inline as raw
1138
+ * bytes, or out of band at a URL — one of the three, never a part that carries
1139
+ * both data and a URL.
1140
+ *
1141
+ * A part a tool derives from its result is re-derived on every render from the
1142
+ * durable result, so the part itself is never stored; the RESULT is. Keep what
1143
+ * the result holds JSON-shaped — base64 text survives a JSON `Store`, a
1144
+ * `Uint8Array` does not — and derive `bytes` from it only if your adapter wants
1145
+ * them.
1146
+ */
1147
+ type MediaSource = {
1148
+ readonly type: "base64";
1149
+ readonly data: string;
1150
+ } | {
1151
+ readonly type: "bytes";
1152
+ readonly data: Uint8Array;
1153
+ } | {
1154
+ readonly type: "url";
1155
+ readonly url: string;
1156
+ };
1157
+ /** A run of text. */
1158
+ interface TextPart {
1159
+ readonly type: "text";
1160
+ readonly text: string;
1161
+ }
1162
+ /** An image the model looks at; `mediaType` is its IANA type, such as `image/jpeg`. */
1163
+ interface ImagePart {
1164
+ readonly type: "image";
1165
+ readonly mediaType: string;
1166
+ readonly source: MediaSource;
1167
+ }
1168
+ /** A document the model reads; `mediaType` is its IANA type, such as `application/pdf`. */
1169
+ interface FilePart {
1170
+ readonly type: "file";
1171
+ readonly mediaType: string;
1172
+ readonly source: MediaSource;
1173
+ }
1174
+ /** One part of a multimodal message. */
1175
+ type ContentPart = TextPart | ImagePart | FilePart;
1176
+ /** A message's content: a plain string, or a list of parts. */
1177
+ type MessageContent = string | readonly ContentPart[];
1178
+ /**
1179
+ * A message's content as parts — a string reads as one text part, so an adapter
1180
+ * maps one shape whichever it was handed. PURE.
1181
+ */
1182
+ declare function contentParts(content: MessageContent): readonly ContentPart[];
1183
+ /** The text an omitted image stands in as. */
1184
+ declare const IMAGE_OMITTED = "[image omitted]";
1185
+ /** The text an omitted file stands in as. */
1186
+ declare const FILE_OMITTED = "[file omitted]";
1187
+ /**
1188
+ * The parts with every image and file replaced by a text placeholder — what a
1189
+ * summarizer is handed, since the summary is text and cannot carry the pixels
1190
+ * forward. Text parts pass through by reference. PURE.
1191
+ */
1192
+ declare function omitMedia(parts: readonly ContentPart[]): readonly ContentPart[];
1193
+
1194
+ /**
1195
+ * @demlik/tea/agent — the one construction every tool definition goes through.
1196
+ *
1197
+ * NOT part of the public `./agent` barrel. `tool()` and `agentTool()` are two
1198
+ * doors onto the same `ToolDef`: `tool()` hands its handler the parsed `args`,
1199
+ * and `agentTool()` needs the whole Cmd — `callId` included — because the call's
1200
+ * identity is what keys the child run. Both are built here, so the reserved-name
1201
+ * refusal, the `thrown` channel and the resilience knob have one definition.
999
1202
  */
1000
1203
 
1001
1204
  /**
@@ -1007,7 +1210,7 @@ type SettlePrefixOf<T extends string> = T extends `${infer P}_ok` | `${infer P}_
1007
1210
  declare const REJECTED_TYPE = "tool_rejected";
1008
1211
  declare const SNAPSHOT_WRITE_TYPE = "snapshot_write";
1009
1212
  /**
1010
- * A tool name `tool()` refuses. A tool's name is its Cmd `type` — so
1213
+ * A tool name `tool()` and `agentTool()` refuse. A tool's name is its Cmd `type` — so
1011
1214
  * its interpret key — and the prefix of its settle Msgs, so every string
1012
1215
  * already spoken by the protocol is taken twice over: the settle prefixes
1013
1216
  * (`resilient_run`, `agent_tool`, `compact`) would overwrite the agent's own
@@ -1022,15 +1225,30 @@ declare const SNAPSHOT_WRITE_TYPE = "snapshot_write";
1022
1225
  * `snapshot_write`, which `toMachine` merges under the consumer's key.
1023
1226
  */
1024
1227
  type ReservedToolName = MsgTypeValue | SettlePrefixOf<MsgTypeValue> | typeof REJECTED_TYPE | typeof SNAPSHOT_WRITE_TYPE;
1228
+ /** Whether `name` is one a tool door refuses — the set `ReservedToolName` types. */
1229
+ declare function isReservedToolName(name: string): name is ReservedToolName;
1025
1230
  /**
1026
1231
  * Widens to `unknown` for a name outside the reserved set and to `never`
1027
1232
  * inside it, so `Name & NotReserved<Name>` is the name itself or
1028
1233
  * unconstructible. A widened `string` passes here — the runtime check in
1029
- * `tool()` is what catches a reserved name built from one.
1234
+ * `definedTool` is what catches a reserved name built from one.
1030
1235
  */
1031
1236
  type NotReserved<Name extends string> = Name extends ReservedToolName ? never : unknown;
1032
- /** Whether `name` is one `tool()` refuses — the set `ReservedToolName` types. */
1033
- declare function isReservedToolName(name: string): name is ReservedToolName;
1237
+
1238
+ /**
1239
+ * @demlik/tea/agent — `tool()` + `toolRouter()`: declare a tool once and derive
1240
+ * what a consumer used to hand-write twice — the `toolOf` mapping from a
1241
+ * model's `ToolCall` to an effect Cmd, and the interpret handler that runs it
1242
+ * and settles it.
1243
+ *
1244
+ * A tool is a `Cmd.define`d effect whose input is the model's call —
1245
+ * `{ callId, args }` — with the handler colocated on the constructor. The
1246
+ * router folds a set of them into one `toolOf` and one interpret table; the
1247
+ * handlers settle through the minted `<name>_ok` / `<name>_err` Msgs, errors as
1248
+ * `{ _tag }` data (ADR 0011). `createAgent(...).toMachine({ tools })` folds
1249
+ * those settles into the conversation, so a consumer names nothing twice.
1250
+ */
1251
+
1034
1252
  /**
1035
1253
  * The input a tool Cmd carries: the model's `callId` (the fan-out identity the
1036
1254
  * settle folds back on) and the `args` already parsed against the tool's
@@ -1096,6 +1314,11 @@ type ToolDef<Name extends string, Args, Ok, E extends Tagged, Ctx> = CmdDef<Name
1096
1314
  * neither. `toolRouter` serves it to the agent as `resilienceOf`.
1097
1315
  */
1098
1316
  readonly resilience: ToolResilience | null;
1317
+ /**
1318
+ * The parts the model reads for an `ok` result, or `null` when the tool
1319
+ * declared no `content` and the model reads the result as data.
1320
+ */
1321
+ readonly content: ((result: Ok) => readonly ContentPart[]) | null;
1099
1322
  /**
1100
1323
  * The colocated handler, as an interpret cell: it returns the tool's
1101
1324
  * outcome, and the engine mints `<name>_ok` / `<name>_err` from it.
@@ -1109,6 +1332,7 @@ type AnyToolDef = AnyCmdDef & {
1109
1332
  readonly description: string;
1110
1333
  readonly args: StandardSchemaV1;
1111
1334
  readonly resilience: ToolResilience | null;
1335
+ readonly content: ((result: never) => readonly ContentPart[]) | null;
1112
1336
  readonly interpret: (cmd: never, ctx: never) => Promise<unknown>;
1113
1337
  };
1114
1338
  /**
@@ -1163,6 +1387,16 @@ declare function tool<const Name extends string, Args, Ok, const Tags extends re
1163
1387
  * Omit → the first failure is the outcome.
1164
1388
  */
1165
1389
  readonly retry?: ToolResilience["retry"];
1390
+ /**
1391
+ * What the model SEES of an `ok` result, as content parts. A screenshot
1392
+ * tool whose result is `{ jpeg }` (base64) declares
1393
+ * `content: (r) => [{ type: "image", mediaType: "image/jpeg", source: { type: "base64", data: r.jpeg } }]`.
1394
+ * The parts ride on the `tool` message beside the outcome, so an adapter
1395
+ * sends them instead of stringifying the result. PURE: it runs on every
1396
+ * render, over the result as the `Store` hands it back, and never on a
1397
+ * failure. Omit → the model reads the outcome as data, as before.
1398
+ */
1399
+ readonly content?: (result: Ok) => readonly ContentPart[];
1166
1400
  }, handler: ToolHandler<Args, Ok, TaggedError<Tags[number]>, Ctx>): ToolDef<Name, Args, Ok, TaggedError<Tags[number] | "thrown">, Ctx>;
1167
1401
  /**
1168
1402
  * A call the router could not hand to a tool: the model named a tool nobody
@@ -1264,6 +1498,12 @@ interface ToolRouter<T extends AnyToolDef> {
1264
1498
  * path settles in the reducer and never runs an effect to time out). PURE.
1265
1499
  */
1266
1500
  readonly resilienceOf: (call: ToolCall) => ToolResilience | null;
1501
+ /**
1502
+ * The parts the model reads for one settled call: the called tool's
1503
+ * `content` over an `ok` result. `null` for a failure, for a tool that
1504
+ * declared no `content`, and for a call no tool answers. PURE.
1505
+ */
1506
+ readonly partsOf: (call: ToolCall, outcome: ToolOutcome<unknown>) => readonly ContentPart[] | null;
1267
1507
  /**
1268
1508
  * Read a settled tool off a Msg: `null` when the Msg is not one of this
1269
1509
  * router's `<name>_ok` / `<name>_err`. The one place a `{ _tag }` failure is
@@ -1568,60 +1808,116 @@ type AgentMachineMsg<P extends string, O extends Record<P, unknown>, R> = {
1568
1808
  * or any exported type, so a UI built on `TurnSettled` does not break the day
1569
1809
  * the retry plumbing is renamed.
1570
1810
  *
1811
+ * Every event carries the run's `runId` and the `at` of the transition that
1812
+ * produced it. `runId` is the one the host passed to `agent_start` and it lives
1813
+ * on the durable Model, so a run killed and resumed from its `Store` reports
1814
+ * the same id on both sides of the kill (#331).
1815
+ *
1816
+ * - `BrainStarted` — a brain call was issued for conversation turn `turn`,
1817
+ * with the request's `purpose`, `model` and `payload`. Once per turn: a
1818
+ * retry of the same turn is not a new start, a cold-wake `boot` that
1819
+ * re-fires it is.
1571
1820
  * - `TurnSettled` — a brain turn settled (the model produced an `AgentTurn`).
1572
- * Projected off the private `resilient_run_ok` settle Msg; carries the parsed
1573
- * `turn` (the narration + tool calls the model asked for).
1574
- * - `ToolSettled` — a tool call settled OK. Projected off the private
1575
- * `agent_tool_ok` Msg; carries the `callId` and the tool `result`.
1576
- * - `RunDone` — the run finished. Projected off the post-transition State
1577
- * reaching `run.phase === "done"`; carries the run's `output` (the terminal
1578
- * model turn, or `null`) — the same first-class result `Runtime.result()`
1579
- * reads (#46), surfaced as an event for the streaming consumer.
1580
- */
1581
- type AgentEvent<R> = {
1821
+ * Carries the parsed `turn`, and — when the provider reported one — that
1822
+ * call's `usage` beside it (#332), so a progress surface reads the context
1823
+ * size without digging into the turn.
1824
+ * - `ToolStarted` — a tool call was issued: launched with its batch, a
1825
+ * queued call backfilling a freed slot, or re-fired by `boot`. A laddered
1826
+ * retry is not a new start.
1827
+ * - `ToolSettled` — a tool call settled OK, with the `callId` and `result`.
1828
+ * - `ToolFailed` — a tool call ended on the failure the model will read: its
1829
+ * own error, a spent retry budget, or its timeout. `failure` is the
1830
+ * `{ kind, reason, _tag? }` the conversation keeps.
1831
+ * - `RunDone` — the run ended, once. `status` says how: `done` with the
1832
+ * terminal turn, `failed` with the unified failure, or `cancelled`.
1833
+ */
1834
+ type AgentEvent<R> = (AgentEventHead & {
1835
+ readonly type: "BrainStarted";
1836
+ readonly turn: number;
1837
+ readonly purpose: string;
1838
+ readonly model: string | null;
1839
+ readonly payload: unknown;
1840
+ }) | (AgentEventHead & {
1582
1841
  readonly type: "TurnSettled";
1583
1842
  readonly turn: AgentTurn;
1584
- } | {
1843
+ /** The usage the provider reported for this turn. Absent → none reported. */
1844
+ readonly usage?: TurnUsage;
1845
+ }) | (AgentEventHead & {
1846
+ readonly type: "ToolStarted";
1847
+ readonly callId: string;
1848
+ readonly name: string;
1849
+ readonly args: Readonly<Record<string, unknown>>;
1850
+ }) | (AgentEventHead & {
1585
1851
  readonly type: "ToolSettled";
1586
1852
  readonly callId: string;
1587
1853
  readonly result: R;
1588
- } | {
1854
+ }) | (AgentEventHead & {
1855
+ readonly type: "ToolFailed";
1856
+ readonly callId: string;
1857
+ readonly name: string;
1858
+ readonly failure: ToolFailure;
1859
+ }) | (AgentEventHead & {
1589
1860
  readonly type: "RunDone";
1590
- readonly output: AgentTurn | null;
1591
- };
1861
+ readonly status: AgentEndedStatus;
1862
+ });
1863
+ /** The two fields every {@link AgentEvent} carries. */
1864
+ interface AgentEventHead {
1865
+ /** The run this event belongs to — stable across a kill and resume. */
1866
+ readonly runId: string;
1867
+ /** When the transition that produced it happened. */
1868
+ readonly at: number;
1869
+ }
1870
+ /**
1871
+ * Every {@link AgentEvent} `type`. A subscriber that wants the whole stream
1872
+ * off `runtime.on` subscribes once per entry. `satisfies` proves each entry is
1873
+ * a real type; a type test proves no real type is missing.
1874
+ */
1875
+ declare const AGENT_EVENT_TYPES: readonly ["BrainStarted", "TurnSettled", "ToolStarted", "ToolSettled", "ToolFailed", "RunDone"];
1592
1876
  /**
1593
1877
  * Project one APPLIED agent transition `(msg, state)` to its semantic
1594
1878
  * {@link AgentEvent}s — the `events` projector a consumer passes to
1595
1879
  * `run(machine, { events: agentEvents() })` to light up `runtime.on(...)`.
1596
1880
  *
1597
- * This is the ONE place the agent's PRIVATE Msg names are read: it maps
1598
- * `resilient_run_ok` → `TurnSettled` and `agent_tool_ok` → `ToolSettled`, and reads
1599
- * the post-transition `run.phase` for `RunDone`. The mapping is total over the
1600
- * Msg union (a `default`-free switch on the discriminant) and returns `[]` for
1601
- * the transitions that carry no public event (start / boot / timer / the error
1602
- * arms), so a private name never escapes into `AgentEvent`.
1881
+ * Two sources, in this order:
1603
1882
  *
1604
- * A single transition may emit more than one event: the brain turn that retires
1605
- * the final stage settles a turn (`TurnSettled`) AND finishes the run
1606
- * (`RunDone`) — both are projected from that one `resilient_run_ok` transition.
1607
- * `RunDone` is gated on `run.phase === "done"`, which the wired loop reaches
1608
- * exactly once (the agent is terminal there and dispatches no further
1609
- * transition), so the event fires once per run.
1883
+ * 1. The Msg. `resilient_run_ok` → `TurnSettled`, `agent_tool_ok` (or a
1884
+ * router's `<name>_ok`) → `ToolSettled`. This is the ONE place the
1885
+ * agent's PRIVATE Msg names are read; the switch is total over the Msg
1886
+ * union, so a private name never escapes into `AgentEvent`.
1887
+ * 2. The transition's lifecycle outbox, `state.lifecycle` — what the reducer
1888
+ * noted as it started a brain call or a tool, failed a tool, or ended the
1889
+ * run. These cannot be read off `(msg, state)`: a brain call issued after
1890
+ * a batch drains, a queued tool backfilling a slot, a timeout the ladder
1891
+ * settled and the transition that ended the run all leave a state that
1892
+ * looks like the one before (#331).
1893
+ *
1894
+ * So a turn that asks for tools reads `TurnSettled`, then one `ToolStarted`
1895
+ * per launched call; the last tool of a batch reads `ToolSettled` (or
1896
+ * `ToolFailed`), then the next `BrainStarted`; and the final turn reads
1897
+ * `TurnSettled`, then `RunDone`.
1610
1898
  *
1611
1899
  * A `ToolSettled` is gated on `state.refusedCalls` (#145): a call whose public
1612
1900
  * outcome was already a failure — the ladder's `timeout` / `retry_exhausted`,
1613
1901
  * or the tool's own error — never emits a success here, however late its
1614
1902
  * abandoned attempt resolves. Both settle arms read the same list, so a
1615
- * router-wired agent and a fan-out-wired one are silent on the same calls, and
1616
- * the decision is made in the PURE layer rather than filtered at a
1617
- * subscription seam — `runtime.on` and `defineAgent`'s `onEvent` see one
1618
- * stream.
1903
+ * router-wired agent and a fan-out-wired one are silent on the same calls.
1904
+ * A cancelled run's Msg-shaped events are closed the same way — a tool that
1905
+ * was in flight when the abort landed pushes nothing — while the cancel's own
1906
+ * `RunDone` still comes through, because it is noted, not Msg-shaped.
1907
+ *
1908
+ * A run cancelled before it ever started has no `runId`, and projects nothing.
1619
1909
  *
1620
1910
  * A machine wired with `toMachine({ tools })` settles tools through the
1621
1911
  * router's `<name>_ok` Msgs instead of `agent_tool_ok`; pass the same router
1622
1912
  * here so those settles project to `ToolSettled` too.
1623
1913
  *
1624
- * PURE — reads only the passed `(msg, state)`; no clock, no RNG, no throw.
1914
+ * Each outbox is projected once per projector (#355). A host that wires the
1915
+ * verbs by hand and folds a Msg of its own leaves `state.lifecycle` as the
1916
+ * previous agent transition left it, and that transition's notes are not
1917
+ * projected a second time.
1918
+ *
1919
+ * Reads only the passed `(msg, state)` and the set of outboxes it has already
1920
+ * projected; no clock, no RNG, no throw.
1625
1921
  *
1626
1922
  * @typeParam P Brain-call purposes.
1627
1923
  * @typeParam O Per-purpose outputs (bound to `AgentTurn`, the agentic shape).
@@ -1661,4 +1957,4 @@ declare function liftAgent<S extends {
1661
1957
  agent: AgentState<Stage, P, O, R>;
1662
1958
  }, Stage, P extends string, O extends Record<P, unknown>, R, C extends Cmd>(state: S, [slice, cmds]: readonly [AgentState<Stage, P, O, R>, readonly C[]]): readonly [S, readonly C[]];
1663
1959
 
1664
- export { PLAIN_MODEL_MISROUTE_REASON as $, type AnyToolDef as A, type AgentStatus as B, type Conversation as C, type AgentTerminalFailure as D, type AgentTimerMsg as E, type AgentToMachine as F, type Awaiting as G, COMPACTION_PURPOSE as H, type CompactInterpret as I, type CompactionOutputs as J, type CompactionPurpose as K, type CompactionSummary as L, type Llm as M, type LlmCall as N, type LlmErr as O, type PlainModel as P, type LlmFailMsg as Q, type LlmOk as R, type StreamingModel as S, type ToolCall as T, type LlmRunCmd as U, type LlmSucceedMsg as V, type WiredToolMsg as W, type MessageLoader as X, type ModelFactory as Y, type ModelPort as Z, type ModelStream as _, type ToolOutcome as a, type ReservedToolName as a0, type Schema as a1, type SnapshotInterpret as a2, TOOL_RETRY_EXHAUSTED_TAG as a3, TOOL_TIMEOUT_TAG as a4, type TaggedFailure as a5, type ToolConstructors as a6, type ToolDef as a7, type ToolError as a8, type ToolFail as a9, liftAgent as aA, mergeInterpret as aB, plainModel as aC, status as aD, tool as aE, toolErrorReason as aF, toolRouter as aG, type ToolFailure as aa, type ToolHandler as ab, type ToolInput as ac, type ToolMsg as ad, type ToolOk as ae, type ToolRecord as af, type ToolRejectedCmd as ag, type ToolRejection as ah, type ToolResilience as ai, type ToolResilienceError as aj, type ToolRetryExhausted as ak, type ToolRouter as al, type ToolSettlement as am, type ToolThrown as an, type ToolTimedOut as ao, type WiredToolCmd as ap, agentBootMsg as aq, agentCancelMsg as ar, agentEvents as as, agentTurnSchema as at, compactionSummarySchema as au, fanOutInterpret as av, isAgentTurn as aw, isCompactionSummary as ax, isReservedToolName as ay, isStreamingModel as az, type AgentTurn as b, type AgentState as c, type ToolResult as d, type ToolFailureOf as e, type ToolsCtx as f, type AgentEvent as g, type TurnChunk as h, type AgentMachineMsg as i, type AgentCmd as j, type ToolCmd as k, type AgentConfigCore as l, type CompactionPolicy as m, type AgentKnob as n, type AgentBootMsg as o, type AgentCancelMsg as p, type AgentCompactErrMsg as q, type AgentCompactOkMsg as r, type AgentCompactRunCmd as s, type AgentCompactionConfig as t, type AgentConfig as u, type AgentFailure as v, type AgentLlmErrMsg as w, type AgentLlmOkMsg as x, type AgentLlmRunCmd as y, type AgentSnapshotConfig as z };
1960
+ export { IMAGE_OMITTED as $, type AgentEvent as A, type AgentConfig as B, type ContentPart as C, type AgentEventHead as D, type AgentFailure as E, type AgentLifecycleNote as F, type AgentLlmErrMsg as G, type AgentLlmOkMsg as H, type AgentLlmRunCmd as I, type AgentSnapshotConfig as J, type AgentStatus as K, type AgentTimerMsg as L, type MessageContent as M, type NotReserved as N, type AgentToMachine as O, type PlainModel as P, type Awaiting as Q, COMPACTION_PURPOSE as R, type StreamingModel as S, type ToolCall as T, type CompactInterpret as U, type CompactionOutputs as V, type WiredToolMsg as W, type CompactionPurpose as X, type CompactionSummary as Y, FILE_OMITTED as Z, type FilePart as _, type ToolOutcome as a, type ImagePart as a0, type Llm as a1, type LlmCall as a2, type LlmErr as a3, type LlmFailMsg as a4, type LlmOk as a5, type LlmRunCmd as a6, type LlmSucceedMsg as a7, type MediaSource as a8, type MessageLoader as a9, type ToolSettlement as aA, type ToolTimedOut as aB, type TurnUsage as aC, type WiredToolCmd as aD, agentBootMsg as aE, agentCancelMsg as aF, agentEvents as aG, agentTurnSchema as aH, compactionSummarySchema as aI, contentParts as aJ, fanOutInterpret as aK, isAgentTurn as aL, isCompactionSummary as aM, isReservedToolName as aN, isStreamingModel as aO, isTurnUsage as aP, liftAgent as aQ, mergeInterpret as aR, omitMedia as aS, plainModel as aT, status as aU, tool as aV, toolErrorReason as aW, toolRouter as aX, type ModelFactory as aa, type ModelPort as ab, type ModelStream as ac, PLAIN_MODEL_MISROUTE_REASON as ad, type ReservedToolName as ae, type Schema as af, type SnapshotInterpret as ag, TOOL_RETRY_EXHAUSTED_TAG as ah, TOOL_TIMEOUT_TAG as ai, type TaggedFailure as aj, type TextPart as ak, type ToolConstructors as al, type ToolError as am, type ToolFail as an, type ToolFailure as ao, type ToolHandler as ap, type ToolInput as aq, type ToolMsg as ar, type ToolOk as as, type ToolRecord as at, type ToolRejectedCmd as au, type ToolRejection as av, type ToolResilience as aw, type ToolResilienceError as ax, type ToolRetryExhausted as ay, type ToolRouter as az, type Conversation as b, type AnyToolDef as c, type ToolsCtx as d, type AgentState as e, type AgentTurn as f, type ToolResult as g, type TurnChunk as h, type AgentMachineMsg as i, type AgentCmd as j, type ToolCmd as k, type ToolFailureOf as l, type AgentTerminalFailure as m, type ToolDef as n, type ToolThrown as o, type AgentEndedStatus as p, type AgentConfigCore as q, type CompactionPolicy as r, type AgentKnob as s, AGENT_EVENT_TYPES as t, type AgentBootMsg as u, type AgentCancelMsg as v, type AgentCompactErrMsg as w, type AgentCompactOkMsg as x, type AgentCompactRunCmd as y, type AgentCompactionConfig as z };
@@ -1,4 +1,4 @@
1
- import { C as Cmd, S as Sub, M as Machine } from '../core-rDbOaJTN.js';
1
+ import { C as Cmd, c as Sub, M as Machine } from '../core-Ce9ncpuv.js';
2
2
  import '@standard-schema/spec';
3
3
 
4
4
  /**
@@ -1,5 +1,5 @@
1
- import '../chunk-C4U5D5HP.js';
2
- import { formOf, subEntriesOf, desiredSub } from '../chunk-K4ETBNKS.js';
1
+ import '../chunk-FNGZMVIT.js';
2
+ import { formOf, subEntriesOf, desiredSub } from '../chunk-AIIXV4XB.js';
3
3
 
4
4
  // src/machine-viz/mermaid-id.ts
5
5
  function safeId(raw) {