@demlik/tea 0.15.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 (115) hide show
  1. package/README.md +30 -7
  2. package/dist/agent/index.d.ts +49 -37
  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-AYS5N6WY.js → chunk-6NG4V5SB.js} +62 -172
  9. package/dist/chunk-6NG4V5SB.js.map +1 -0
  10. package/dist/{chunk-3B5X7SBB.js → chunk-7MGXQZPW.js} +11 -9
  11. package/dist/chunk-7MGXQZPW.js.map +1 -0
  12. package/dist/{chunk-V46HSVCK.js → chunk-BCTEOVOU.js} +3 -3
  13. package/dist/{chunk-V46HSVCK.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-TCLBCERH.js → chunk-EHUDXAKC.js} +238 -212
  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-22POWGFA.js → chunk-IVJP3GKJ.js} +46 -20
  23. package/dist/chunk-IVJP3GKJ.js.map +1 -0
  24. package/dist/{chunk-QPEVCJ5Q.js → chunk-MVZS5FDM.js} +13 -6
  25. package/dist/chunk-MVZS5FDM.js.map +1 -0
  26. package/dist/{chunk-VTQI2NHP.js → chunk-MYNLY3HP.js} +9 -8
  27. package/dist/chunk-MYNLY3HP.js.map +1 -0
  28. package/dist/{chunk-Q5CQTBFA.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-DnzqWy6u.d.ts → core-BbgtiXdg.d.ts} +231 -139
  35. package/dist/do/index.d.ts +37 -33
  36. package/dist/do/index.js +21 -14
  37. package/dist/do/index.js.map +1 -1
  38. package/dist/{durable-effects-CWzA-o2B.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 -59
  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-CSyMYDAB.d.ts → index-7vV8xmsD.d.ts} +1 -1
  51. package/dist/{index-KXqTRJyb.d.ts → index-Bz5Rh9Ga.d.ts} +19 -96
  52. package/dist/index-CjFDUBeq.d.ts +207 -0
  53. package/dist/{index-CuNO9m8i.d.ts → index-CkFYA9Y6.d.ts} +14 -16
  54. package/dist/{index-CA_7I5g9.d.ts → index-Cou86-GX.d.ts} +137 -246
  55. package/dist/{index-DrIRb_Ch.d.ts → index-DU6JpQ8G.d.ts} +1 -1
  56. package/dist/{index-HSYgG2Yt.d.ts → index-Xufl55W8.d.ts} +247 -211
  57. package/dist/{index-C2DwkjlP.d.ts → index-_dOR3xqA.d.ts} +57 -45
  58. package/dist/index.d.ts +121 -385
  59. package/dist/index.js +2 -1
  60. package/dist/jev/index.d.ts +133 -97
  61. package/dist/jev/index.js +205 -161
  62. package/dist/jev/index.js.map +1 -1
  63. package/dist/{machine-DGlPWCWI.d.ts → machine-BQzTV8On.d.ts} +171 -288
  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 -22
  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-D8VbH-VH.d.ts → protocol-ClRZBhHQ.d.ts} +7 -8
  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 -456
  91. package/dist/resilience/index.js +37 -483
  92. package/dist/resilience/index.js.map +1 -1
  93. package/dist/{runtime-types-CMF13BBh.d.ts → runtime-types-CiVpC0HN.d.ts} +131 -388
  94. package/dist/testing/index.d.ts +22 -16
  95. package/dist/testing/index.js +15 -7
  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-BseNPIhr.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-22POWGFA.js.map +0 -1
  104. package/dist/chunk-3B5X7SBB.js.map +0 -1
  105. package/dist/chunk-66PY5WYF.js +0 -1816
  106. package/dist/chunk-66PY5WYF.js.map +0 -1
  107. package/dist/chunk-AYS5N6WY.js.map +0 -1
  108. package/dist/chunk-L3TND7LA.js +0 -97
  109. package/dist/chunk-L3TND7LA.js.map +0 -1
  110. package/dist/chunk-MYXFNWAJ.js.map +0 -1
  111. package/dist/chunk-Q5CQTBFA.js.map +0 -1
  112. package/dist/chunk-QPEVCJ5Q.js.map +0 -1
  113. package/dist/chunk-TCLBCERH.js.map +0 -1
  114. package/dist/chunk-VTQI2NHP.js.map +0 -1
  115. package/dist/index-ZCMhnVKN.d.ts +0 -272
@@ -1,128 +1,129 @@
1
- import { createMonitoredRun } from './chunk-3B5X7SBB.js';
2
- import { createFanOut, initFanOut } from './chunk-MYXFNWAJ.js';
3
- import { MsgType, createResilientCall } from './chunk-AYS5N6WY.js';
4
- import { subscribeDeadline } from './chunk-22POWGFA.js';
5
1
  import { describeError } from './chunk-G5E74IJB.js';
6
- import { Cmd, cmdEdgeOf, detachWorkOf, absurd, defineMachine, malformedResult, run, driveToDone } from './chunk-66PY5WYF.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];
52
25
  }
53
- function fail(s, key, msg) {
54
- return rc.fail(s, key, msg);
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
+ };
35
+ }
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
58
  return {
114
59
  name: rc.name,
60
+ /** The `Cmd.define`d run Cmd — list it in the machine's `cmds`. */
61
+ run: rc.run,
115
62
  init,
116
63
  attempt,
117
64
  succeed,
118
65
  fail,
66
+ errOf,
119
67
  onTimer,
120
- subs,
121
- handlers,
122
- invokeOne
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]
123
75
  };
124
76
  }
125
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
+
126
127
  // src/agent/schema.ts
127
128
  function schemaFromGuard(guard, name) {
128
129
  return {
@@ -227,7 +228,7 @@ function agentEvents(opts) {
227
228
  function projectOwn(msg, events, refused) {
228
229
  switch (msg.type) {
229
230
  case MsgType.ResilientOk:
230
- events.push({ type: "TurnSettled", turn: msg.result.output });
231
+ events.push({ type: "TurnSettled", turn: msg.value.output });
231
232
  break;
232
233
  case MsgType.AgentToolOk:
233
234
  if (!refused.has(msg.callId)) {
@@ -238,23 +239,6 @@ function projectOwn(msg, events, refused) {
238
239
  });
239
240
  }
240
241
  break;
241
- // start / boot / cancel / timer / the *_err arms / the compaction settles
242
- // carry no public event. (No `default`: the switch is exhaustive over the Msg
243
- // discriminant, so a new Msg variant forces a decision here at compile
244
- // time.) Compaction is an internal optimization, not a semantic lifecycle
245
- // moment a UI folds — its settles are deliberately silent here. Cancel is
246
- // silent for a stronger reason: the run the caller stopped owes the public
247
- // channel nothing after the stop, so a `RunCancelled` would be one more
248
- // late thing to have to ignore.
249
- case MsgType.AgentStart:
250
- case MsgType.AgentCancel:
251
- case MsgType.AgentToolErr:
252
- case MsgType.ResilientErr:
253
- case MsgType.CompactOk:
254
- case MsgType.CompactErr:
255
- case "deadline_exceeded":
256
- case MsgType.AgentBoot:
257
- break;
258
242
  }
259
243
  }
260
244
  function mergeInterpret(a, b) {
@@ -263,6 +247,50 @@ function mergeInterpret(a, b) {
263
247
  function liftAgent(state, [slice, cmds]) {
264
248
  return [{ ...state, agent: slice }, cmds];
265
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
266
294
  var REJECTED_TYPE = "tool_rejected";
267
295
  var SNAPSHOT_WRITE_TYPE = "snapshot_write";
268
296
  var SETTLE_SUFFIX = /_(?:ok|err|run)$/;
@@ -285,41 +313,27 @@ function tool(name, spec, handler) {
285
313
  );
286
314
  }
287
315
  const def = Cmd.define(name, {
288
- input: z.object({
289
- callId: z.string(),
290
- args: spec.input
291
- }),
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(),
292
319
  ok: spec.ok,
293
- err: [...spec.err, "thrown"],
294
- requirements: spec.requirements
320
+ err: [...spec.err, "thrown"]
295
321
  });
296
322
  const declared = new Set(spec.err);
297
323
  const settle = {
298
- ok: (value) => Result.ok(value),
299
- fail: (error) => Result.err(error)
324
+ ok: Outcome.ok,
325
+ fail: Outcome.err
300
326
  };
301
327
  const asDeclared = (thrown) => {
302
328
  if (isTagged(thrown) && declared.has(thrown._tag)) return thrown;
303
329
  return { _tag: "thrown", message: describeError(thrown) };
304
330
  };
305
331
  const interpret = async (cmd, ctx) => {
306
- let result;
307
332
  try {
308
- result = await handler(cmd.args, ctx, settle);
333
+ return await handler(cmd.args, ctx, settle);
309
334
  } catch (thrown) {
310
- return def.err(cmd, asDeclared(thrown));
335
+ return Outcome.err(asDeclared(thrown));
311
336
  }
312
- return result.match({
313
- ok: (value) => {
314
- const parsed = spec.ok.safeParse(value);
315
- return parsed.success ? def.ok(cmd, parsed.data) : {
316
- type: def.errType,
317
- cmd,
318
- error: malformedResult(parsed.error.issues)
319
- };
320
- },
321
- err: (error) => def.err(cmd, error)
322
- });
323
337
  };
324
338
  return Object.assign(def, {
325
339
  description: spec.description,
@@ -339,10 +353,8 @@ function isTagged(value) {
339
353
  return typeof value === "object" && value !== null && typeof value._tag === "string";
340
354
  }
341
355
  var rejected = Cmd.define(REJECTED_TYPE, {
342
- input: z.custom(
343
- () => true
344
- ),
345
- ok: z.never(),
356
+ input: unchecked(),
357
+ ok: rejectAll,
346
358
  err: ["unknown_tool", "malformed_args"]
347
359
  });
348
360
  function toolRouter(tools) {
@@ -364,22 +376,26 @@ function toolRouter(tools) {
364
376
  error: { _tag: "unknown_tool", name: call.name }
365
377
  });
366
378
  }
367
- const parsed = t.args.safeParse(call.args);
368
- 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) {
369
385
  return rejected({
370
386
  callId: call.callId,
371
387
  error: {
372
388
  _tag: "malformed_args",
373
389
  name: call.name,
374
- issues: malformedResult(parsed.error.issues).issues
390
+ issues: malformedResult(parsed.issues).issues
375
391
  }
376
392
  });
377
393
  }
378
394
  const build = t;
379
- return build({ callId: call.callId, args: parsed.data });
395
+ return build({ callId: call.callId, args: parsed.value });
380
396
  };
381
397
  const handlers = {
382
- [rejected.cmdType]: async (cmd) => rejected.err(cmd, cmd.error)
398
+ [rejected.cmdType]: async (cmd) => Outcome.err(cmd.error)
383
399
  };
384
400
  for (const t of tools) handlers[t.cmdType] = t.interpret;
385
401
  const interpret = handlers;
@@ -574,10 +590,9 @@ function createToolLadder(resilienceOf2, toolOf, rng) {
574
590
  const rc = rcFor(call);
575
591
  if (rc === null) return s;
576
592
  const key = toolCallKey(call.name, call.callId);
577
- const [slice] = rc.succeed(sliceOf(s, call.name, rc), key, {
578
- type: MsgType.ResilientOk,
579
- key,
580
- result: null,
593
+ const { call: slice } = rc.settle(sliceOf(s, call.name, rc), {
594
+ cmd: { key },
595
+ value: null,
581
596
  at
582
597
  });
583
598
  return { ...s, [call.name]: forget(slice, key) };
@@ -587,13 +602,12 @@ function createToolLadder(resilienceOf2, toolOf, rng) {
587
602
  if (rc === null) return [s, failure];
588
603
  const key = toolCallKey(call.name, call.callId);
589
604
  const before = sliceOf(s, call.name, rc);
590
- const [slice] = rc.fail(before, key, {
591
- type: MsgType.ResilientErr,
592
- key,
605
+ const { call: slice, outcome } = rc.settle(before, {
606
+ cmd: { key },
593
607
  error: failure,
594
608
  at
595
609
  });
596
- if (slice.calls[key]?.phase === "waiting_retry") {
610
+ if (outcome.kind === "retrying") {
597
611
  return [{ ...s, [call.name]: slice }, null];
598
612
  }
599
613
  const attempts = before.retry[key]?.attempt;
@@ -664,7 +678,7 @@ function createToolLadder(resilienceOf2, toolOf, rng) {
664
678
  for (const slice of Object.values(s)) {
665
679
  const sample = firstInput(slice);
666
680
  const rc = sample === null ? null : rcFor(sample);
667
- if (rc !== null) out.push(...rc.subs(slice));
681
+ if (rc !== null) out.push(...rc.deadlines(slice));
668
682
  }
669
683
  return out;
670
684
  };
@@ -745,12 +759,14 @@ function definedAgent(config, wiring, overlays) {
745
759
  };
746
760
  const compaction = config.compaction;
747
761
  const agent = compaction === void 0 ? (
748
- // The one assertion in the pair, and it widens the Cmd union rather
749
- // than the interpret obligation: this machine's `AgentCmd` fixes
750
- // compaction OFF, `DefinedAgentMachine` names the ON superset, and the
751
- // gap is the `compact_run` Cmd a policy-less reducer provably never
752
- // emits. Widening a union nothing can produce is sound; the reverse —
753
- // 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.
754
770
  createAgent(core).toMachine({
755
771
  tools
756
772
  })
@@ -760,8 +776,11 @@ function definedAgent(config, wiring, overlays) {
760
776
  const machine = (input) => machineWith(input, void 0);
761
777
  const drive = (input, ...[opts = noHost()]) => {
762
778
  const { onEvent, onChunk } = opts;
763
- const handle = run(machineWith(input, onChunk), {
779
+ const wired = machineWith(input, onChunk);
780
+ const handle = run(wired.machine, {
764
781
  ...opts,
782
+ interpret: wired.interpret,
783
+ subscribe: wired.subscribe,
765
784
  terminal: isEnded,
766
785
  events: onEvent === void 0 ? void 0 : agentEvents({
767
786
  tools
@@ -794,9 +813,9 @@ function definedAgent(config, wiring, overlays) {
794
813
  with: (overlay) => definedAgent(config, wiring, [...overlays, overlay.interpret])
795
814
  };
796
815
  }
797
- function overlaid(machine, overlays) {
798
- if (overlays.length === 0) return machine;
799
- const cells = { ...machine.interpret };
816
+ function overlaid(wired, overlays) {
817
+ if (overlays.length === 0) return wired;
818
+ const cells = { ...wired.interpret };
800
819
  for (const overlay of overlays) {
801
820
  const wrappers = overlay;
802
821
  for (const [type, wrap] of Object.entries(wrappers)) {
@@ -809,10 +828,7 @@ function overlaid(machine, overlays) {
809
828
  cells[type] = wrap(cell);
810
829
  }
811
830
  }
812
- return defineMachine({
813
- ...machine,
814
- interpret: cells
815
- });
831
+ return { ...wired, interpret: cells };
816
832
  }
817
833
  function brainOf(model, onChunk) {
818
834
  if (!isStreamingModel(model)) {
@@ -841,7 +857,9 @@ function compactingMachine(core, knob, brain, tools) {
841
857
  tools,
842
858
  toolInterpret: { compact_run: summarizeWith(brain) }
843
859
  };
844
- return agent.toMachine(wiring);
860
+ return agent.toMachine(
861
+ wiring
862
+ );
845
863
  }
846
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.";
847
865
  function compactionPolicyOf(knob) {
@@ -940,11 +958,12 @@ function withToolErrorHook(router, onToolError) {
940
958
  const wrapped = {};
941
959
  for (const [type, handler] of Object.entries(handlers)) {
942
960
  wrapped[type] = async (cmd, ctx) => {
943
- const msg = await handler(cmd, ctx);
944
- 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;
945
964
  const settled = router.outcomeOf(msg);
946
- if (settled === null || settled.outcome.kind === "ok") return msg;
947
- 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;
948
967
  try {
949
968
  await onToolError(settled.outcome, {
950
969
  callId: settled.callId,
@@ -953,7 +972,7 @@ function withToolErrorHook(router, onToolError) {
953
972
  } catch (err) {
954
973
  console.warn("@demlik/tea: a run's onToolError hook threw", err);
955
974
  }
956
- return msg;
975
+ return returned;
957
976
  };
958
977
  }
959
978
  return {
@@ -1020,13 +1039,15 @@ function createAgent(config) {
1020
1039
  });
1021
1040
  const llm = createLlmCall(
1022
1041
  {
1023
- model: config.model,
1024
1042
  schemas: config.schemas,
1025
- ...config.retry !== void 0 ? { retry: config.retry } : {},
1026
- ...config.loadMessages !== void 0 ? { loadMessages: config.loadMessages } : {}
1043
+ ...config.retry !== void 0 ? { retry: config.retry } : {}
1027
1044
  },
1028
1045
  rng
1029
1046
  );
1047
+ const invokeBrain = brainHandler(llm, {
1048
+ model: config.model,
1049
+ ...config.loadMessages !== void 0 ? { loadMessages: config.loadMessages } : {}
1050
+ });
1030
1051
  const compactRc = createResilientCall({ ...config.retry !== void 0 ? { retry: config.retry } : {} }, rng);
1031
1052
  const fan = createFanOut({
1032
1053
  concurrency: config.toolConcurrency ?? 1,
@@ -1081,8 +1102,10 @@ function createAgent(config) {
1081
1102
  }
1082
1103
  const compact = {
1083
1104
  attempt: (slice, key, input, at) => reKeyCompactCmds(compactRc.attempt(slice, key, input, at)),
1084
- succeed: (slice, key, msg) => reKeyCompactCmds(compactRc.succeed(slice, key, msg)),
1085
- 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
+ },
1086
1109
  onTimer: (slice, msg) => reKeyCompactCmds(compactRc.onTimer(slice, msg))
1087
1110
  };
1088
1111
  function start(s, runId, at) {
@@ -1275,23 +1298,22 @@ function createAgent(config) {
1275
1298
  if (config.stopWhen?.(s) === true) return cancel(s, at);
1276
1299
  return null;
1277
1300
  }
1278
- function succeed(s, key, msg, at) {
1279
- const [resilience, retryCmds] = llm.succeed(s.resilience, key, msg);
1301
+ function succeed(s, msg, at) {
1302
+ const [resilience, retryCmds] = llm.succeed(s.resilience, msg);
1280
1303
  const settled = { ...s, resilience };
1281
- const [withTurn, turnCmds] = turn(settled, msg.result.output, at);
1304
+ const [withTurn, turnCmds] = turn(settled, msg.value.output, at);
1282
1305
  return [withTurn, [...retryCmds, ...turnCmds]];
1283
1306
  }
1284
- function fail(s, key, msg, at) {
1285
- const [resilience, cmds] = llm.fail(s.resilience, key, msg);
1286
- const call = resilience.calls[key];
1287
- 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;
1288
1311
  return [{ ...s, resilience, failure }, cmds];
1289
1312
  }
1290
1313
  function compactOk(s, key, msg, at) {
1291
- const [compaction, retryCmds] = compact.succeed(s.compaction, key, {
1292
- type: MsgType.ResilientOk,
1293
- key: msg.key,
1294
- result: msg.result,
1314
+ const { call: compaction, cmds: retryCmds } = compact.settle(s.compaction, {
1315
+ cmd: { key },
1316
+ value: msg.result,
1295
1317
  at: msg.at
1296
1318
  });
1297
1319
  const settledRetry = { ...s, compaction };
@@ -1310,15 +1332,17 @@ function createAgent(config) {
1310
1332
  return [fired, [...retryCmds, ...llmCmds]];
1311
1333
  }
1312
1334
  function compactErr(s, key, msg, at) {
1313
- const [compaction, cmds] = compact.fail(s.compaction, key, {
1314
- type: MsgType.ResilientErr,
1315
- key: msg.key,
1335
+ const {
1336
+ call: compaction,
1337
+ cmds,
1338
+ outcome
1339
+ } = compact.settle(s.compaction, {
1340
+ cmd: { key },
1316
1341
  error: msg.error,
1317
1342
  at: msg.at
1318
1343
  });
1319
1344
  const settledRetry = { ...s, compaction };
1320
- const call = compaction.calls[key];
1321
- if (call?.phase === "waiting_retry") {
1345
+ if (outcome.kind === "retrying") {
1322
1346
  return [settledRetry, cmds];
1323
1347
  }
1324
1348
  const conv = requireAwaiting(settledRetry, "compacting");
@@ -1389,17 +1413,14 @@ function createAgent(config) {
1389
1413
  }
1390
1414
  function subs(s) {
1391
1415
  return [
1392
- ...llm.subs(s.resilience),
1393
- ...compactRc.subs(s.compaction),
1416
+ ...llm.deadlines(s.resilience),
1417
+ ...compactRc.deadlines(s.compaction),
1394
1418
  ...ladder.subs(toolSlice(s)),
1395
- ...run2.subs(s.run)
1419
+ ...run2.deadlines(s.run)
1396
1420
  ];
1397
1421
  }
1398
- function unsafeDetachedHandlers(ports) {
1399
- return llm.handlers(ports);
1400
- }
1401
1422
  function brainHandlers() {
1402
- return llm.handlers();
1423
+ return { resilient_run: invokeBrain };
1403
1424
  }
1404
1425
  function toMachine(opts) {
1405
1426
  const tools = opts?.tools;
@@ -1426,10 +1447,10 @@ function createAgent(config) {
1426
1447
  // shape is a bare `reason` string — a consumer routing their own interpret
1427
1448
  // through it never declared a tag, so the failure it mints carries none.
1428
1449
  [MsgType.AgentToolErr]: (s, m) => toolErr(s, m.callId, m.reason, m.at),
1429
- // The re-entered brain-call settle Msgs (from `brainHandlers`): success
1430
- // runs `succeed` (reset retry + fold the turn), failure runs `fail`.
1431
- [MsgType.ResilientOk]: (s, m) => succeed(s, m.key, m, m.at),
1432
- [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),
1433
1454
  // The re-entered compaction settle Msgs (from the consumer's `compact_run`
1434
1455
  // cell, #85): `compact_ok` folds the summary back (drop oldest turns +
1435
1456
  // their records, fire the next brain call), `compact_err` backs off via the
@@ -1444,12 +1465,17 @@ function createAgent(config) {
1444
1465
  const machine = {
1445
1466
  init: (loaded) => loaded !== null ? [loaded, []] : [init(), []],
1446
1467
  update,
1447
- subscriptions: (s) => subs(s),
1448
- 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),
1449
1476
  interpret,
1450
- ...tools !== void 0 ? { cmds: tools.defs } : {}
1477
+ subscribe: { deadline: subscribeDeadline }
1451
1478
  };
1452
- return defineMachine(machine);
1453
1479
  }
1454
1480
  return {
1455
1481
  init,
@@ -1467,14 +1493,14 @@ function createAgent(config) {
1467
1493
  currentStage,
1468
1494
  brainCall,
1469
1495
  subs,
1470
- // `toMachine` is THE wired path. `unsafeDetachedHandlers` is the
1471
- // hand-wiring escape hatch — named to advertise the retry-loop gap so it is
1472
- // 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.
1473
1498
  toMachine,
1474
- unsafeDetachedHandlers
1499
+ brainInterpret: brainHandlers,
1500
+ brain: llm.run
1475
1501
  };
1476
1502
  }
1477
1503
 
1478
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 };
1479
- //# sourceMappingURL=chunk-TCLBCERH.js.map
1480
- //# sourceMappingURL=chunk-TCLBCERH.js.map
1505
+ //# sourceMappingURL=chunk-EHUDXAKC.js.map
1506
+ //# sourceMappingURL=chunk-EHUDXAKC.js.map