@demlik/tea 0.14.0 → 0.16.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 (116) hide show
  1. package/README.md +30 -7
  2. package/dist/agent/index.d.ts +49 -36
  3. package/dist/agent/index.js +12 -8
  4. package/dist/chunk-4LPY67E4.js +18 -0
  5. package/dist/chunk-4LPY67E4.js.map +1 -0
  6. package/dist/chunk-5XU6ZJO2.js +533 -0
  7. package/dist/chunk-5XU6ZJO2.js.map +1 -0
  8. package/dist/{chunk-AQ6ZIMEA.js → chunk-6NG4V5SB.js} +89 -115
  9. package/dist/chunk-6NG4V5SB.js.map +1 -0
  10. package/dist/{chunk-HYDWG35Q.js → chunk-7MGXQZPW.js} +11 -9
  11. package/dist/chunk-7MGXQZPW.js.map +1 -0
  12. package/dist/{chunk-BLJ2JQSH.js → chunk-BCTEOVOU.js} +3 -3
  13. package/dist/{chunk-BLJ2JQSH.js.map → chunk-BCTEOVOU.js.map} +1 -1
  14. package/dist/chunk-CH5KTOEZ.js +710 -0
  15. package/dist/chunk-CH5KTOEZ.js.map +1 -0
  16. package/dist/chunk-CIHSHLQX.js +64 -0
  17. package/dist/chunk-CIHSHLQX.js.map +1 -0
  18. package/dist/{chunk-Z2L3LSNV.js → chunk-EHUDXAKC.js} +246 -210
  19. package/dist/chunk-EHUDXAKC.js.map +1 -0
  20. package/dist/chunk-GOX2CYIM.js +380 -0
  21. package/dist/chunk-GOX2CYIM.js.map +1 -0
  22. package/dist/chunk-IVJP3GKJ.js +104 -0
  23. package/dist/chunk-IVJP3GKJ.js.map +1 -0
  24. package/dist/{chunk-F7FMAWLA.js → chunk-MVZS5FDM.js} +13 -6
  25. package/dist/chunk-MVZS5FDM.js.map +1 -0
  26. package/dist/{chunk-LYLTKJWM.js → chunk-MYNLY3HP.js} +9 -8
  27. package/dist/chunk-MYNLY3HP.js.map +1 -0
  28. package/dist/{chunk-I5MQMJDW.js → chunk-NSIAORRY.js} +20 -30
  29. package/dist/chunk-NSIAORRY.js.map +1 -0
  30. package/dist/{chunk-MYXFNWAJ.js → chunk-QNGYQMZB.js} +4 -4
  31. package/dist/chunk-QNGYQMZB.js.map +1 -0
  32. package/dist/chunk-WT5PBPLB.js +98 -0
  33. package/dist/chunk-WT5PBPLB.js.map +1 -0
  34. package/dist/{core-CTzMJ82M.d.ts → core-BbgtiXdg.d.ts} +231 -139
  35. package/dist/do/index.d.ts +37 -32
  36. package/dist/do/index.js +21 -14
  37. package/dist/do/index.js.map +1 -1
  38. package/dist/{durable-effects-B0-qGQDy.d.ts → durable-effects-7MTK_jnj.d.ts} +1 -1
  39. package/dist/effect/index.d.ts +151 -0
  40. package/dist/effect/index.js +98 -0
  41. package/dist/effect/index.js.map +1 -0
  42. package/dist/extension/index.d.ts +6 -7
  43. package/dist/extension/index.js +3 -2
  44. package/dist/extension/index.js.map +1 -1
  45. package/dist/flow/index.d.ts +68 -70
  46. package/dist/flow/index.js +32 -27
  47. package/dist/flow/index.js.map +1 -1
  48. package/dist/idempotency/index.d.ts +6 -7
  49. package/dist/idempotency/index.js +4 -2
  50. package/dist/{index-DJWIER_3.d.ts → index-7vV8xmsD.d.ts} +1 -1
  51. package/dist/{index-NjrT3fL2.d.ts → index-Bz5Rh9Ga.d.ts} +19 -96
  52. package/dist/index-CjFDUBeq.d.ts +207 -0
  53. package/dist/{index-6A7dB8f6.d.ts → index-CkFYA9Y6.d.ts} +14 -16
  54. package/dist/{index-B5BZ-_cT.d.ts → index-Cou86-GX.d.ts} +189 -108
  55. package/dist/{index-TvRb1KVf.d.ts → index-DU6JpQ8G.d.ts} +1 -1
  56. package/dist/{index-q0hXFeZ0.d.ts → index-Xufl55W8.d.ts} +286 -215
  57. package/dist/{index-4vZzljCD.d.ts → index-_dOR3xqA.d.ts} +57 -45
  58. package/dist/index.d.ts +181 -385
  59. package/dist/index.js +2 -1
  60. package/dist/jev/index.d.ts +147 -99
  61. package/dist/jev/index.js +329 -233
  62. package/dist/jev/index.js.map +1 -1
  63. package/dist/{machine-CdIcN2Xm.d.ts → machine-BQzTV8On.d.ts} +171 -280
  64. package/dist/machine-viz/index.d.ts +5 -5
  65. package/dist/machine-viz/index.js +8 -4
  66. package/dist/machine-viz/index.js.map +1 -1
  67. package/dist/mem/index.d.ts +3 -4
  68. package/dist/mem/index.js +2 -1
  69. package/dist/mem/index.js.map +1 -1
  70. package/dist/node/index.d.ts +119 -78
  71. package/dist/node/index.js +52 -38
  72. package/dist/node/index.js.map +1 -1
  73. package/dist/paginate/index.d.ts +27 -33
  74. package/dist/paginate/index.js +6 -4
  75. package/dist/parity/index.d.ts +4 -5
  76. package/dist/parity/index.js +3 -2
  77. package/dist/parity/index.js.map +1 -1
  78. package/dist/pbt/index.d.ts +2 -2
  79. package/dist/pbt/index.js +2 -1
  80. package/dist/pbt/index.js.map +1 -1
  81. package/dist/persistence/index.d.ts +6 -7
  82. package/dist/persistence/index.js +5 -3
  83. package/dist/promise/index.d.ts +186 -0
  84. package/dist/promise/index.js +5 -0
  85. package/dist/promise/index.js.map +1 -0
  86. package/dist/protocol-ClRZBhHQ.d.ts +53 -0
  87. package/dist/react/index.d.ts +36 -17
  88. package/dist/react/index.js +27 -4
  89. package/dist/react/index.js.map +1 -1
  90. package/dist/resilience/index.d.ts +63 -455
  91. package/dist/resilience/index.js +37 -483
  92. package/dist/resilience/index.js.map +1 -1
  93. package/dist/{runtime-types-LWDoi943.d.ts → runtime-types-CiVpC0HN.d.ts} +131 -388
  94. package/dist/testing/index.d.ts +165 -15
  95. package/dist/testing/index.js +104 -3
  96. package/dist/testing/index.js.map +1 -1
  97. package/dist/timing/index.d.ts +25 -22
  98. package/dist/timing/index.js +4 -3
  99. package/dist/timing/index.js.map +1 -1
  100. package/dist/{types-DP3f5NIl.d.ts → types-LxZxGYda.d.ts} +2 -2
  101. package/dist/work-queue/index.d.ts +5 -6
  102. package/package.json +18 -5
  103. package/dist/chunk-AQ6ZIMEA.js.map +0 -1
  104. package/dist/chunk-F2US5BW6.js +0 -72
  105. package/dist/chunk-F2US5BW6.js.map +0 -1
  106. package/dist/chunk-F7FMAWLA.js.map +0 -1
  107. package/dist/chunk-HUKZQX6U.js +0 -97
  108. package/dist/chunk-HUKZQX6U.js.map +0 -1
  109. package/dist/chunk-HYDWG35Q.js.map +0 -1
  110. package/dist/chunk-I5MQMJDW.js.map +0 -1
  111. package/dist/chunk-LYLTKJWM.js.map +0 -1
  112. package/dist/chunk-MYXFNWAJ.js.map +0 -1
  113. package/dist/chunk-RQULHGYH.js +0 -1804
  114. package/dist/chunk-RQULHGYH.js.map +0 -1
  115. package/dist/chunk-Z2L3LSNV.js.map +0 -1
  116. package/dist/index-DMCeMPMJ.d.ts +0 -272
@@ -1,118 +1,129 @@
1
- import { createMonitoredRun } from './chunk-HYDWG35Q.js';
2
- import { createFanOut, initFanOut } from './chunk-MYXFNWAJ.js';
3
- import { MsgType, createResilientCall } from './chunk-AQ6ZIMEA.js';
4
- import { subscribeDeadline } from './chunk-F2US5BW6.js';
5
1
  import { describeError } from './chunk-G5E74IJB.js';
6
- import { Cmd, cmdEdgeOf, detachWorkOf, absurd, defineMachine, malformedResult, run, driveToDone } from './chunk-RQULHGYH.js';
7
- import { Result } from 'better-result';
8
- import { z } from 'zod';
2
+ import { createMonitoredRun } from './chunk-7MGXQZPW.js';
3
+ import { createFanOut, initFanOut } from './chunk-QNGYQMZB.js';
4
+ import { createResilientCall } from './chunk-6NG4V5SB.js';
5
+ import { rejectAll, unchecked } from './chunk-4LPY67E4.js';
6
+ import { deadlinesSub, subscribeDeadline } from './chunk-IVJP3GKJ.js';
7
+ import { run, driveToDone } from './chunk-WT5PBPLB.js';
8
+ import { Cmd, Outcome, cmdEdgeOf, detachWorkOf, absurd, defineMachine, validateSync, malformedResult } from './chunk-CH5KTOEZ.js';
9
9
 
10
10
  // src/internal/llm-call/index.ts
11
- function plainModel(fn) {
12
- return () => ({
13
- withStructuredOutput(schema) {
14
- return {
15
- invoke: async (messages) => schema.parse(await fn(messages))
16
- };
17
- }
18
- });
19
- }
20
- function isPlainModel(model) {
21
- return Object.prototype.toString.call(model) === "[object AsyncFunction]";
22
- }
23
- var PLAIN_MODEL_MISROUTE_REASON = "model: a sync function returned a Promise where an Llm was expected \u2014 a promise-returning model that is not declared `async` must be wrapped in plainModel(fn) (see the llm-call module)";
24
- function isThenable(value) {
25
- return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
26
- }
27
- function asModelFactory(model) {
28
- if (isPlainModel(model)) return plainModel(model);
29
- return (modelId) => {
30
- const llm = model(modelId);
31
- if (isThenable(llm)) {
32
- llm.then(void 0, () => void 0);
33
- throw new Error(PLAIN_MODEL_MISROUTE_REASON);
34
- }
35
- return llm;
36
- };
37
- }
38
11
  function createLlmCall(config, rng = Math.random) {
39
12
  const resilientConfig = {
40
13
  ...config.retry === void 0 ? {} : { retry: config.retry }
41
14
  };
42
15
  const rc = createResilientCall(resilientConfig, rng);
43
- const modelOf = asModelFactory(config.model);
44
16
  function init() {
45
17
  return rc.init();
46
18
  }
47
19
  function attempt(s, input, at, key = input.purpose) {
48
20
  return rc.attempt(s, key, input, at);
49
21
  }
50
- function succeed(s, key, msg) {
51
- return rc.succeed(s, key, msg);
22
+ function succeed(s, msg) {
23
+ const { call, cmds } = rc.settle(s, msg);
24
+ return [call, cmds];
25
+ }
26
+ function errOf(msg) {
27
+ const error = msg.error;
28
+ const cause = "cause" in error ? error.cause : error;
29
+ return {
30
+ key: msg.cmd.key,
31
+ purpose: msg.cmd.input.purpose,
32
+ reason: describeError(cause),
33
+ error: cause
34
+ };
52
35
  }
53
- function fail(s, key, msg) {
54
- return rc.fail(s, key, msg);
36
+ function fail(s, msg) {
37
+ const { call, cmds } = rc.settle(s, { ...msg, error: errOf(msg) });
38
+ return [call, cmds];
55
39
  }
56
40
  function onTimer(s, msg) {
57
41
  return rc.onTimer(s, msg);
58
42
  }
59
- function subs(s) {
60
- return rc.subs(s);
61
- }
62
- async function invokeOne(input) {
63
- const model = modelOf(input.model);
64
- const messages = config.loadMessages ? await config.loadMessages(input) : [];
65
- const schema = config.schemas[input.purpose];
66
- const structured = model.withStructuredOutput(schema);
67
- const raw = await structured.invoke(messages);
68
- const output = schema.parse(raw);
69
- return { key: input.purpose, purpose: input.purpose, output };
43
+ function deadlines(s) {
44
+ return rc.deadlines(s);
70
45
  }
71
- const resilientRunHandler = rc.handlers({
72
- run: (input) => invokeOne(input)
73
- }).resilient_run;
74
- async function settleOf(cmd) {
75
- const settle = await resilientRunHandler(cmd, {});
76
- if (settle.type === MsgType.ResilientOk) {
77
- return { ...settle, result: { ...settle.result, key: cmd.key } };
46
+ function decode(cmd, raw) {
47
+ const { purpose } = cmd.input;
48
+ try {
49
+ const output = config.schemas[purpose].parse(raw);
50
+ return Outcome.ok({ key: cmd.key, purpose, output });
51
+ } catch (cause) {
52
+ return rejected2(cause);
78
53
  }
79
- const rawError = settle.error;
80
- const err = {
81
- key: cmd.key,
82
- purpose: cmd.input.purpose,
83
- reason: describeError(rawError),
84
- error: rawError
85
- };
86
- return {
87
- type: MsgType.ResilientErr,
88
- key: settle.key,
89
- error: err,
90
- at: settle.at
91
- };
92
54
  }
93
- function handlers(ports) {
94
- if (ports === void 0) {
95
- return { resilient_run: (cmd) => settleOf(cmd) };
96
- }
97
- return {
98
- resilient_run: (cmd, ctx) => {
99
- const fired = (async () => {
100
- const settle = await settleOf(cmd);
101
- if (settle.type === MsgType.ResilientOk) {
102
- const msg2 = ports.onOk(settle.result);
103
- if (msg2 !== void 0) await ctx.dispatch(msg2);
104
- return;
105
- }
106
- const msg = ports.onErr(settle.error);
107
- if (msg !== void 0) await ctx.dispatch(msg);
108
- })();
109
- ctx.waitUntil(fired);
110
- }
111
- };
55
+ function rejected2(cause) {
56
+ return Outcome.err({ _tag: "port_rejected", cause });
112
57
  }
113
- return { init, attempt, succeed, fail, onTimer, subs, handlers, invokeOne };
58
+ return {
59
+ name: rc.name,
60
+ /** The `Cmd.define`d run Cmd — list it in the machine's `cmds`. */
61
+ run: rc.run,
62
+ init,
63
+ attempt,
64
+ succeed,
65
+ fail,
66
+ errOf,
67
+ onTimer,
68
+ deadlines,
69
+ /** The built-in `timer` Sub's deps — resilient-call's `timer`. */
70
+ timer: rc.timer,
71
+ decode,
72
+ rejected: rejected2,
73
+ /** The structured-output schema for `purpose`. */
74
+ schemaOf: (purpose) => config.schemas[purpose]
75
+ };
114
76
  }
115
77
 
78
+ // src/protocol.ts
79
+ var MsgType = {
80
+ // --- resilient-call: the run Cmd + its two settle Msgs -------------------
81
+ /** The "run the port for `key`" effect Cmd resilient-call emits. */
82
+ ResilientRun: "resilient_run",
83
+ /**
84
+ * PRIVATE success settle Msg (read only by `agentEvents`, #47). The engine
85
+ * mints it from the run Cmd's outcome (ADR 0021), so it is `<run>_ok`.
86
+ */
87
+ ResilientOk: "resilient_run_ok",
88
+ /** Failure settle Msg — routed to `settle` (back off via retry). */
89
+ ResilientErr: "resilient_run_err",
90
+ // --- agent: the wired machine's own entry-point Msgs ---------------------
91
+ /** Begin a run. */
92
+ AgentStart: "agent_start",
93
+ /** PRIVATE tool-fan-out success settle Msg (read only by `agentEvents`, #47). */
94
+ AgentToolOk: "agent_tool_ok",
95
+ /** Tool-fan-out failure settle Msg. */
96
+ AgentToolErr: "agent_tool_err",
97
+ /**
98
+ * Re-fire the one outstanding effect on rehydrate (the do↔agent seam). Fired
99
+ * by `do/host`'s `autoBoot` via the typed `agentBootMsg` constructor, matched
100
+ * by the agent reducer — see `AgentBootPort` in `../agent`.
101
+ */
102
+ AgentBoot: "agent_boot",
103
+ /**
104
+ * Stop the run from outside and settle it `cancelled` — what an `AbortSignal`
105
+ * handed to `driveToDone` / a defined agent's `run` dispatches on abort. A
106
+ * transition, never a throw: the outcome lands in the Model, so a reload reads
107
+ * a run that ended rather than one to resume.
108
+ */
109
+ AgentCancel: "agent_cancel",
110
+ // --- agent: the context-compaction round-trip (#85) ----------------------
111
+ /**
112
+ * The "summarize the oldest N turns" effect Cmd the agent emits when its
113
+ * `CompactionPolicy` asks to compact before a brain call. A DEDICATED
114
+ * round-trip (design B1), distinct from the brain call's `resilient_run`, so
115
+ * compaction is its own honest `Awaiting` state — see `../agent`.
116
+ */
117
+ CompactRun: "compact_run",
118
+ /** Compaction round-trip resolved — carries the summary text the fold-back folds. */
119
+ CompactOk: "compact_ok",
120
+ /** Compaction round-trip failed (exhausted retry) — surfaced as data, not a stall. */
121
+ CompactErr: "compact_err",
122
+ // --- authed-call: the 401 trigger ----------------------------------------
123
+ /** The 401 the consumer dispatches when a guarded call comes back unauthorized. */
124
+ Unauthorized: "unauthorized"
125
+ };
126
+
116
127
  // src/agent/schema.ts
117
128
  function schemaFromGuard(guard, name) {
118
129
  return {
@@ -217,7 +228,7 @@ function agentEvents(opts) {
217
228
  function projectOwn(msg, events, refused) {
218
229
  switch (msg.type) {
219
230
  case MsgType.ResilientOk:
220
- events.push({ type: "TurnSettled", turn: msg.result.output });
231
+ events.push({ type: "TurnSettled", turn: msg.value.output });
221
232
  break;
222
233
  case MsgType.AgentToolOk:
223
234
  if (!refused.has(msg.callId)) {
@@ -228,23 +239,6 @@ function projectOwn(msg, events, refused) {
228
239
  });
229
240
  }
230
241
  break;
231
- // start / boot / cancel / timer / the *_err arms / the compaction settles
232
- // carry no public event. (No `default`: the switch is exhaustive over the Msg
233
- // discriminant, so a new Msg variant forces a decision here at compile
234
- // time.) Compaction is an internal optimization, not a semantic lifecycle
235
- // moment a UI folds — its settles are deliberately silent here. Cancel is
236
- // silent for a stronger reason: the run the caller stopped owes the public
237
- // channel nothing after the stop, so a `RunCancelled` would be one more
238
- // late thing to have to ignore.
239
- case MsgType.AgentStart:
240
- case MsgType.AgentCancel:
241
- case MsgType.AgentToolErr:
242
- case MsgType.ResilientErr:
243
- case MsgType.CompactOk:
244
- case MsgType.CompactErr:
245
- case "deadline_exceeded":
246
- case MsgType.AgentBoot:
247
- break;
248
242
  }
249
243
  }
250
244
  function mergeInterpret(a, b) {
@@ -253,6 +247,50 @@ function mergeInterpret(a, b) {
253
247
  function liftAgent(state, [slice, cmds]) {
254
248
  return [{ ...state, agent: slice }, cmds];
255
249
  }
250
+
251
+ // src/agent/model.ts
252
+ function plainModel(fn) {
253
+ return () => ({
254
+ withStructuredOutput(schema) {
255
+ return {
256
+ invoke: async (messages) => schema.parse(await fn(messages))
257
+ };
258
+ }
259
+ });
260
+ }
261
+ function isPlainModel(model) {
262
+ return Object.prototype.toString.call(model) === "[object AsyncFunction]";
263
+ }
264
+ var PLAIN_MODEL_MISROUTE_REASON = "model: a sync function returned a Promise where an Llm was expected \u2014 a promise-returning model that is not declared `async` must be wrapped in plainModel(fn) (see the agent's model ports)";
265
+ function isThenable(value) {
266
+ return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
267
+ }
268
+ function asModelFactory(model) {
269
+ if (isPlainModel(model)) return plainModel(model);
270
+ return (modelId) => {
271
+ const llm = model(modelId);
272
+ if (isThenable(llm)) {
273
+ llm.then(void 0, () => void 0);
274
+ throw new Error(PLAIN_MODEL_MISROUTE_REASON);
275
+ }
276
+ return llm;
277
+ };
278
+ }
279
+ function brainHandler(llm, ports) {
280
+ const modelOf = asModelFactory(ports.model);
281
+ return async (cmd) => {
282
+ try {
283
+ const model = modelOf(cmd.input.model);
284
+ const messages = ports.loadMessages ? await ports.loadMessages(cmd.input) : [];
285
+ const bound = model.withStructuredOutput(llm.schemaOf(cmd.input.purpose));
286
+ return llm.decode(cmd, await bound.invoke(messages));
287
+ } catch (cause) {
288
+ return llm.rejected(cause);
289
+ }
290
+ };
291
+ }
292
+
293
+ // src/agent/tool.ts
256
294
  var REJECTED_TYPE = "tool_rejected";
257
295
  var SNAPSHOT_WRITE_TYPE = "snapshot_write";
258
296
  var SETTLE_SUFFIX = /_(?:ok|err|run)$/;
@@ -275,41 +313,27 @@ function tool(name, spec, handler) {
275
313
  );
276
314
  }
277
315
  const def = Cmd.define(name, {
278
- input: z.object({
279
- callId: z.string(),
280
- args: spec.input
281
- }),
316
+ // The router parses `args` against `spec.input` before it builds the Cmd,
317
+ // so the Cmd's own input schema only names the type.
318
+ input: unchecked(),
282
319
  ok: spec.ok,
283
- err: [...spec.err, "thrown"],
284
- requirements: spec.requirements
320
+ err: [...spec.err, "thrown"]
285
321
  });
286
322
  const declared = new Set(spec.err);
287
323
  const settle = {
288
- ok: (value) => Result.ok(value),
289
- fail: (error) => Result.err(error)
324
+ ok: Outcome.ok,
325
+ fail: Outcome.err
290
326
  };
291
327
  const asDeclared = (thrown) => {
292
328
  if (isTagged(thrown) && declared.has(thrown._tag)) return thrown;
293
329
  return { _tag: "thrown", message: describeError(thrown) };
294
330
  };
295
331
  const interpret = async (cmd, ctx) => {
296
- let result;
297
332
  try {
298
- result = await handler(cmd.args, ctx, settle);
333
+ return await handler(cmd.args, ctx, settle);
299
334
  } catch (thrown) {
300
- return def.err(cmd, asDeclared(thrown));
335
+ return Outcome.err(asDeclared(thrown));
301
336
  }
302
- return result.match({
303
- ok: (value) => {
304
- const parsed = spec.ok.safeParse(value);
305
- return parsed.success ? def.ok(cmd, parsed.data) : {
306
- type: def.errType,
307
- cmd,
308
- error: malformedResult(parsed.error.issues)
309
- };
310
- },
311
- err: (error) => def.err(cmd, error)
312
- });
313
337
  };
314
338
  return Object.assign(def, {
315
339
  description: spec.description,
@@ -329,10 +353,8 @@ function isTagged(value) {
329
353
  return typeof value === "object" && value !== null && typeof value._tag === "string";
330
354
  }
331
355
  var rejected = Cmd.define(REJECTED_TYPE, {
332
- input: z.custom(
333
- () => true
334
- ),
335
- ok: z.never(),
356
+ input: unchecked(),
357
+ ok: rejectAll,
336
358
  err: ["unknown_tool", "malformed_args"]
337
359
  });
338
360
  function toolRouter(tools) {
@@ -354,22 +376,26 @@ function toolRouter(tools) {
354
376
  error: { _tag: "unknown_tool", name: call.name }
355
377
  });
356
378
  }
357
- const parsed = t.args.safeParse(call.args);
358
- if (!parsed.success) {
379
+ const parsed = validateSync(
380
+ t.args,
381
+ call.args,
382
+ `the "${call.name}" tool's input schema`
383
+ );
384
+ if (parsed.issues !== void 0) {
359
385
  return rejected({
360
386
  callId: call.callId,
361
387
  error: {
362
388
  _tag: "malformed_args",
363
389
  name: call.name,
364
- issues: malformedResult(parsed.error.issues).issues
390
+ issues: malformedResult(parsed.issues).issues
365
391
  }
366
392
  });
367
393
  }
368
394
  const build = t;
369
- return build({ callId: call.callId, args: parsed.data });
395
+ return build({ callId: call.callId, args: parsed.value });
370
396
  };
371
397
  const handlers = {
372
- [rejected.cmdType]: async (cmd) => rejected.err(cmd, cmd.error)
398
+ [rejected.cmdType]: async (cmd) => Outcome.err(cmd.error)
373
399
  };
374
400
  for (const t of tools) handlers[t.cmdType] = t.interpret;
375
401
  const interpret = handlers;
@@ -564,10 +590,9 @@ function createToolLadder(resilienceOf2, toolOf, rng) {
564
590
  const rc = rcFor(call);
565
591
  if (rc === null) return s;
566
592
  const key = toolCallKey(call.name, call.callId);
567
- const [slice] = rc.succeed(sliceOf(s, call.name, rc), key, {
568
- type: MsgType.ResilientOk,
569
- key,
570
- result: null,
593
+ const { call: slice } = rc.settle(sliceOf(s, call.name, rc), {
594
+ cmd: { key },
595
+ value: null,
571
596
  at
572
597
  });
573
598
  return { ...s, [call.name]: forget(slice, key) };
@@ -577,13 +602,12 @@ function createToolLadder(resilienceOf2, toolOf, rng) {
577
602
  if (rc === null) return [s, failure];
578
603
  const key = toolCallKey(call.name, call.callId);
579
604
  const before = sliceOf(s, call.name, rc);
580
- const [slice] = rc.fail(before, key, {
581
- type: MsgType.ResilientErr,
582
- key,
605
+ const { call: slice, outcome } = rc.settle(before, {
606
+ cmd: { key },
583
607
  error: failure,
584
608
  at
585
609
  });
586
- if (slice.calls[key]?.phase === "waiting_retry") {
610
+ if (outcome.kind === "retrying") {
587
611
  return [{ ...s, [call.name]: slice }, null];
588
612
  }
589
613
  const attempts = before.retry[key]?.attempt;
@@ -654,7 +678,7 @@ function createToolLadder(resilienceOf2, toolOf, rng) {
654
678
  for (const slice of Object.values(s)) {
655
679
  const sample = firstInput(slice);
656
680
  const rc = sample === null ? null : rcFor(sample);
657
- if (rc !== null) out.push(...rc.subs(slice));
681
+ if (rc !== null) out.push(...rc.deadlines(slice));
658
682
  }
659
683
  return out;
660
684
  };
@@ -735,12 +759,14 @@ function definedAgent(config, wiring, overlays) {
735
759
  };
736
760
  const compaction = config.compaction;
737
761
  const agent = compaction === void 0 ? (
738
- // The one assertion in the pair, and it widens the Cmd union rather
739
- // than the interpret obligation: this machine's `AgentCmd` fixes
740
- // compaction OFF, `DefinedAgentMachine` names the ON superset, and the
741
- // gap is the `compact_run` Cmd a policy-less reducer provably never
742
- // emits. Widening a union nothing can produce is sound; the reverse —
743
- // claiming a cell that is not wired — is what the discriminant refuses.
762
+ // The one assertion in the pair, and it widens the Cmd union: this
763
+ // machine's `AgentCmd` fixes compaction OFF, `DefinedAgentMachine`
764
+ // names the ON superset, and the gap is the `compact_run` Cmd a
765
+ // policy-less reducer provably never emits. Widening a union nothing
766
+ // can produce is sound. The table beside it is read at that same
767
+ // superset type, and it holds no `compact_run` cell — the Cmd it would
768
+ // serve never fires, and `overlaid` reads the table's own keys, so an
769
+ // overlay naming that cell still gets the "has none" throw.
744
770
  createAgent(core).toMachine({
745
771
  tools
746
772
  })
@@ -750,8 +776,11 @@ function definedAgent(config, wiring, overlays) {
750
776
  const machine = (input) => machineWith(input, void 0);
751
777
  const drive = (input, ...[opts = noHost()]) => {
752
778
  const { onEvent, onChunk } = opts;
753
- const handle = run(machineWith(input, onChunk), {
779
+ const wired = machineWith(input, onChunk);
780
+ const handle = run(wired.machine, {
754
781
  ...opts,
782
+ interpret: wired.interpret,
783
+ subscribe: wired.subscribe,
755
784
  terminal: isEnded,
756
785
  events: onEvent === void 0 ? void 0 : agentEvents({
757
786
  tools
@@ -784,9 +813,9 @@ function definedAgent(config, wiring, overlays) {
784
813
  with: (overlay) => definedAgent(config, wiring, [...overlays, overlay.interpret])
785
814
  };
786
815
  }
787
- function overlaid(machine, overlays) {
788
- if (overlays.length === 0) return machine;
789
- const cells = { ...machine.interpret };
816
+ function overlaid(wired, overlays) {
817
+ if (overlays.length === 0) return wired;
818
+ const cells = { ...wired.interpret };
790
819
  for (const overlay of overlays) {
791
820
  const wrappers = overlay;
792
821
  for (const [type, wrap] of Object.entries(wrappers)) {
@@ -799,10 +828,7 @@ function overlaid(machine, overlays) {
799
828
  cells[type] = wrap(cell);
800
829
  }
801
830
  }
802
- return defineMachine({
803
- ...machine,
804
- interpret: cells
805
- });
831
+ return { ...wired, interpret: cells };
806
832
  }
807
833
  function brainOf(model, onChunk) {
808
834
  if (!isStreamingModel(model)) {
@@ -831,7 +857,9 @@ function compactingMachine(core, knob, brain, tools) {
831
857
  tools,
832
858
  toolInterpret: { compact_run: summarizeWith(brain) }
833
859
  };
834
- return agent.toMachine(wiring);
860
+ return agent.toMachine(
861
+ wiring
862
+ );
835
863
  }
836
864
  var SUMMARIZE_INSTRUCTION = "Summarize the conversation so far. Preserve the facts, decisions and tool results a continuation would need, and drop everything else. Reply with the summary as your message content and request no tools.";
837
865
  function compactionPolicyOf(knob) {
@@ -930,11 +958,12 @@ function withToolErrorHook(router, onToolError) {
930
958
  const wrapped = {};
931
959
  for (const [type, handler] of Object.entries(handlers)) {
932
960
  wrapped[type] = async (cmd, ctx) => {
933
- const msg = await handler(cmd, ctx);
934
- if (msg === void 0) return msg;
961
+ const returned = await handler(cmd, ctx);
962
+ const msg = cmdEdgeOf(ctx)(cmd, returned);
963
+ if (typeof msg !== "object" || msg === null) return returned;
935
964
  const settled = router.outcomeOf(msg);
936
- if (settled === null || settled.outcome.kind === "ok") return msg;
937
- if (ownedByLadder(router, cmd, settled.callId)) return msg;
965
+ if (settled === null || settled.outcome.kind === "ok") return returned;
966
+ if (ownedByLadder(router, cmd, settled.callId)) return returned;
938
967
  try {
939
968
  await onToolError(settled.outcome, {
940
969
  callId: settled.callId,
@@ -943,7 +972,7 @@ function withToolErrorHook(router, onToolError) {
943
972
  } catch (err) {
944
973
  console.warn("@demlik/tea: a run's onToolError hook threw", err);
945
974
  }
946
- return msg;
975
+ return returned;
947
976
  };
948
977
  }
949
978
  return {
@@ -1010,13 +1039,15 @@ function createAgent(config) {
1010
1039
  });
1011
1040
  const llm = createLlmCall(
1012
1041
  {
1013
- model: config.model,
1014
1042
  schemas: config.schemas,
1015
- ...config.retry !== void 0 ? { retry: config.retry } : {},
1016
- ...config.loadMessages !== void 0 ? { loadMessages: config.loadMessages } : {}
1043
+ ...config.retry !== void 0 ? { retry: config.retry } : {}
1017
1044
  },
1018
1045
  rng
1019
1046
  );
1047
+ const invokeBrain = brainHandler(llm, {
1048
+ model: config.model,
1049
+ ...config.loadMessages !== void 0 ? { loadMessages: config.loadMessages } : {}
1050
+ });
1020
1051
  const compactRc = createResilientCall({ ...config.retry !== void 0 ? { retry: config.retry } : {} }, rng);
1021
1052
  const fan = createFanOut({
1022
1053
  concurrency: config.toolConcurrency ?? 1,
@@ -1071,8 +1102,10 @@ function createAgent(config) {
1071
1102
  }
1072
1103
  const compact = {
1073
1104
  attempt: (slice, key, input, at) => reKeyCompactCmds(compactRc.attempt(slice, key, input, at)),
1074
- succeed: (slice, key, msg) => reKeyCompactCmds(compactRc.succeed(slice, key, msg)),
1075
- fail: (slice, key, msg) => reKeyCompactCmds(compactRc.fail(slice, key, msg)),
1105
+ settle: (slice, msg) => {
1106
+ const { call, cmds, outcome } = compactRc.settle(slice, msg);
1107
+ return { call, cmds: cmds.map(toCompactRunCmd), outcome };
1108
+ },
1076
1109
  onTimer: (slice, msg) => reKeyCompactCmds(compactRc.onTimer(slice, msg))
1077
1110
  };
1078
1111
  function start(s, runId, at) {
@@ -1265,23 +1298,22 @@ function createAgent(config) {
1265
1298
  if (config.stopWhen?.(s) === true) return cancel(s, at);
1266
1299
  return null;
1267
1300
  }
1268
- function succeed(s, key, msg, at) {
1269
- const [resilience, retryCmds] = llm.succeed(s.resilience, key, msg);
1301
+ function succeed(s, msg, at) {
1302
+ const [resilience, retryCmds] = llm.succeed(s.resilience, msg);
1270
1303
  const settled = { ...s, resilience };
1271
- const [withTurn, turnCmds] = turn(settled, msg.result.output, at);
1304
+ const [withTurn, turnCmds] = turn(settled, msg.value.output, at);
1272
1305
  return [withTurn, [...retryCmds, ...turnCmds]];
1273
1306
  }
1274
- function fail(s, key, msg, at) {
1275
- const [resilience, cmds] = llm.fail(s.resilience, key, msg);
1276
- const call = resilience.calls[key];
1277
- const failure = call?.phase === "failed" ? { reason: "llm", error: msg.error, at } : s.failure;
1307
+ function fail(s, msg, at) {
1308
+ const [resilience, cmds] = llm.fail(s.resilience, msg);
1309
+ const call = resilience.calls[msg.cmd.key];
1310
+ const failure = call?.phase === "failed" ? { reason: "llm", error: llm.errOf(msg), at } : s.failure;
1278
1311
  return [{ ...s, resilience, failure }, cmds];
1279
1312
  }
1280
1313
  function compactOk(s, key, msg, at) {
1281
- const [compaction, retryCmds] = compact.succeed(s.compaction, key, {
1282
- type: MsgType.ResilientOk,
1283
- key: msg.key,
1284
- result: msg.result,
1314
+ const { call: compaction, cmds: retryCmds } = compact.settle(s.compaction, {
1315
+ cmd: { key },
1316
+ value: msg.result,
1285
1317
  at: msg.at
1286
1318
  });
1287
1319
  const settledRetry = { ...s, compaction };
@@ -1300,15 +1332,17 @@ function createAgent(config) {
1300
1332
  return [fired, [...retryCmds, ...llmCmds]];
1301
1333
  }
1302
1334
  function compactErr(s, key, msg, at) {
1303
- const [compaction, cmds] = compact.fail(s.compaction, key, {
1304
- type: MsgType.ResilientErr,
1305
- key: msg.key,
1335
+ const {
1336
+ call: compaction,
1337
+ cmds,
1338
+ outcome
1339
+ } = compact.settle(s.compaction, {
1340
+ cmd: { key },
1306
1341
  error: msg.error,
1307
1342
  at: msg.at
1308
1343
  });
1309
1344
  const settledRetry = { ...s, compaction };
1310
- const call = compaction.calls[key];
1311
- if (call?.phase === "waiting_retry") {
1345
+ if (outcome.kind === "retrying") {
1312
1346
  return [settledRetry, cmds];
1313
1347
  }
1314
1348
  const conv = requireAwaiting(settledRetry, "compacting");
@@ -1379,17 +1413,14 @@ function createAgent(config) {
1379
1413
  }
1380
1414
  function subs(s) {
1381
1415
  return [
1382
- ...llm.subs(s.resilience),
1383
- ...compactRc.subs(s.compaction),
1416
+ ...llm.deadlines(s.resilience),
1417
+ ...compactRc.deadlines(s.compaction),
1384
1418
  ...ladder.subs(toolSlice(s)),
1385
- ...run2.subs(s.run)
1419
+ ...run2.deadlines(s.run)
1386
1420
  ];
1387
1421
  }
1388
- function unsafeDetachedHandlers(ports) {
1389
- return llm.handlers(ports);
1390
- }
1391
1422
  function brainHandlers() {
1392
- return llm.handlers();
1423
+ return { resilient_run: invokeBrain };
1393
1424
  }
1394
1425
  function toMachine(opts) {
1395
1426
  const tools = opts?.tools;
@@ -1416,10 +1447,10 @@ function createAgent(config) {
1416
1447
  // shape is a bare `reason` string — a consumer routing their own interpret
1417
1448
  // through it never declared a tag, so the failure it mints carries none.
1418
1449
  [MsgType.AgentToolErr]: (s, m) => toolErr(s, m.callId, m.reason, m.at),
1419
- // The re-entered brain-call settle Msgs (from `brainHandlers`): success
1420
- // runs `succeed` (reset retry + fold the turn), failure runs `fail`.
1421
- [MsgType.ResilientOk]: (s, m) => succeed(s, m.key, m, m.at),
1422
- [MsgType.ResilientErr]: (s, m) => fail(s, m.key, m, m.at),
1450
+ // The engine-minted brain-call settle Msgs (from `brainHandlers`' outcome):
1451
+ // success runs `succeed` (reset retry + fold the turn), failure runs `fail`.
1452
+ [MsgType.ResilientOk]: (s, m) => succeed(s, m, m.at),
1453
+ [MsgType.ResilientErr]: (s, m) => fail(s, m, m.at),
1423
1454
  // The re-entered compaction settle Msgs (from the consumer's `compact_run`
1424
1455
  // cell, #85): `compact_ok` folds the summary back (drop oldest turns +
1425
1456
  // their records, fire the next brain call), `compact_err` backs off via the
@@ -1434,12 +1465,17 @@ function createAgent(config) {
1434
1465
  const machine = {
1435
1466
  init: (loaded) => loaded !== null ? [loaded, []] : [init(), []],
1436
1467
  update,
1437
- subscriptions: (s) => subs(s),
1438
- subscribe: { deadline: subscribeDeadline },
1468
+ subs: [deadlinesSub(subs)],
1469
+ // The brain run Cmd is `Cmd.define`d: listing it is what makes the
1470
+ // engine mint `resilient_run_ok` / `resilient_run_err` from the brain
1471
+ // handler's outcome. The router's defs ride beside it.
1472
+ cmds: [llm.run, ...tools?.defs ?? []]
1473
+ };
1474
+ return {
1475
+ machine: defineMachine(machine),
1439
1476
  interpret,
1440
- ...tools !== void 0 ? { cmds: tools.defs } : {}
1477
+ subscribe: { deadline: subscribeDeadline }
1441
1478
  };
1442
- return defineMachine(machine);
1443
1479
  }
1444
1480
  return {
1445
1481
  init,
@@ -1457,14 +1493,14 @@ function createAgent(config) {
1457
1493
  currentStage,
1458
1494
  brainCall,
1459
1495
  subs,
1460
- // `toMachine` is THE wired path. `unsafeDetachedHandlers` is the
1461
- // hand-wiring escape hatch — named to advertise the retry-loop gap so it is
1462
- // never mistaken for the loop driver (#54).
1496
+ // `toMachine` is THE wired path; `brainInterpret` / `brain` are the two
1497
+ // pieces a consumer wiring the verbs by hand needs.
1463
1498
  toMachine,
1464
- unsafeDetachedHandlers
1499
+ brainInterpret: brainHandlers,
1500
+ brain: llm.run
1465
1501
  };
1466
1502
  }
1467
1503
 
1468
1504
  export { COMPACTION_PURPOSE, PLAIN_MODEL_MISROUTE_REASON, TOOL_RETRY_EXHAUSTED_TAG, TOOL_TIMEOUT_TAG, agentBootMsg, agentCancelMsg, agentEvents, agentTurnSchema, compactionSummarySchema, createAgent, defineAgent, fanOutInterpret, isAgentTurn, isCompactionSummary, isReservedToolName, isStreamingModel, liftAgent, mergeInterpret, plainModel, renderPrompt, status, tool, toolErrorReason, toolRouter, transcript };
1469
- //# sourceMappingURL=chunk-Z2L3LSNV.js.map
1470
- //# sourceMappingURL=chunk-Z2L3LSNV.js.map
1505
+ //# sourceMappingURL=chunk-EHUDXAKC.js.map
1506
+ //# sourceMappingURL=chunk-EHUDXAKC.js.map