@lunora/agent 1.0.0-alpha.7 → 1.0.0-alpha.71

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 (84) hide show
  1. package/dist/channels.d.mts +2 -2
  2. package/dist/channels.d.ts +2 -2
  3. package/dist/channels.mjs +1 -181
  4. package/dist/component.d.mts +2 -0
  5. package/dist/component.d.ts +2 -0
  6. package/dist/component.mjs +2 -418
  7. package/dist/inbound.d.mts +1 -1
  8. package/dist/inbound.d.ts +1 -1
  9. package/dist/inbound.mjs +1 -32
  10. package/dist/index.d.mts +38 -8
  11. package/dist/index.d.ts +38 -8
  12. package/dist/index.mjs +1 -18
  13. package/dist/naming.mjs +1 -8
  14. package/dist/packem_shared/AGENT_MODULE-M4D1EejI.mjs +1 -0
  15. package/dist/packem_shared/VoiceSessionDO-Dxj0V8Ej.mjs +1 -0
  16. package/dist/packem_shared/adaptMcpResult-CVlq-_TO.mjs +2 -0
  17. package/dist/packem_shared/agentAsTool-DrFnh9UQ.mjs +1 -0
  18. package/dist/packem_shared/base64-5eyBfWO3.mjs +1 -0
  19. package/dist/packem_shared/braintrustTelemetry-CoYK-pq7.mjs +1 -0
  20. package/dist/packem_shared/branch-marker-boZ00zmk.mjs +1 -0
  21. package/dist/packem_shared/buildModelMessages-Y4tGo1T9.mjs +5 -0
  22. package/dist/packem_shared/codeTool-qdwj8j8S.mjs +1 -0
  23. package/dist/packem_shared/collectAgenticMemoryTools-BeMWT2qt.mjs +1 -0
  24. package/dist/packem_shared/combineTelemetry-DgE9W9G8.mjs +1 -0
  25. package/dist/packem_shared/common-CJSjtsfv.mjs +1 -0
  26. package/dist/packem_shared/compileAgentWorkflow-GDJ_HWln.mjs +1 -0
  27. package/dist/packem_shared/component-shared-IZozysYq.mjs +1 -0
  28. package/dist/packem_shared/consoleTelemetry-BZY3Y-Ly.mjs +1 -0
  29. package/dist/packem_shared/createAgentContext-iS35-Xrs.mjs +1 -0
  30. package/dist/packem_shared/createAgentGenerate-9bZ2YhpN.mjs +3 -0
  31. package/dist/packem_shared/createDispatchRunner-pLyQ70FK-2_j6ocGT.mjs +1 -0
  32. package/dist/packem_shared/defineAgent-CZdh7y3W.mjs +3 -0
  33. package/dist/packem_shared/defineSkill-DGGvDWNq.mjs +1 -0
  34. package/dist/packem_shared/functionTool-D3CP4f8-.mjs +1 -0
  35. package/dist/packem_shared/memory-JI0lUu84.mjs +1 -0
  36. package/dist/packem_shared/normalizeEntityName-Ce0X6Afj.mjs +2 -0
  37. package/dist/packem_shared/otlpTelemetry-CoyeTO8S.mjs +1 -0
  38. package/dist/packem_shared/runAgentLoop-KUUoFT3r.mjs +3 -0
  39. package/dist/packem_shared/runVoiceTurn-CRPeNXsS.mjs +1 -0
  40. package/dist/packem_shared/sandboxComponent-BtOkUYpY.mjs +5 -0
  41. package/dist/packem_shared/sentryTelemetry-CPqEbFPA.mjs +1 -0
  42. package/dist/packem_shared/{types.d-boAM2Yi1.d.mts → types.d-eCuvcLzf.d.mts} +211 -21
  43. package/dist/packem_shared/{types.d-boAM2Yi1.d.ts → types.d-eCuvcLzf.d.ts} +211 -21
  44. package/dist/packem_shared/voice-turn-DbVR0H6T.mjs +1 -0
  45. package/dist/reply.d.mts +40 -0
  46. package/dist/reply.d.ts +40 -0
  47. package/dist/reply.mjs +1 -0
  48. package/dist/sandbox.d.mts +14 -13
  49. package/dist/sandbox.d.ts +14 -13
  50. package/dist/sandbox.mjs +1 -113
  51. package/dist/skill-markdown.d.mts +36 -0
  52. package/dist/skill-markdown.d.ts +36 -0
  53. package/dist/skill-markdown.mjs +1 -0
  54. package/dist/telemetry/index.d.mts +72 -9
  55. package/dist/telemetry/index.d.ts +72 -9
  56. package/dist/telemetry/index.mjs +1 -5
  57. package/package.json +18 -9
  58. package/dist/packem_shared/AGENT_MODULE-Dnt_-AAT.mjs +0 -24
  59. package/dist/packem_shared/VoiceSessionDO-DLoXsHGF.mjs +0 -297
  60. package/dist/packem_shared/adaptMcpResult-wtNMvLoP.mjs +0 -65
  61. package/dist/packem_shared/agentAsTool-CUHlWsmt.mjs +0 -98
  62. package/dist/packem_shared/base64-BVwtgRJV.mjs +0 -18
  63. package/dist/packem_shared/braintrustTelemetry-wuGDErob.mjs +0 -47
  64. package/dist/packem_shared/buildModelMessages-BWFigaoo.mjs +0 -69
  65. package/dist/packem_shared/codeTool-CjgJOC9t.mjs +0 -122
  66. package/dist/packem_shared/collectAgenticMemoryTools-QrzpV-WX.mjs +0 -97
  67. package/dist/packem_shared/combineTelemetry-DCyaaWAI.mjs +0 -43
  68. package/dist/packem_shared/common-DAeFCot5.mjs +0 -61
  69. package/dist/packem_shared/compileAgentWorkflow-DX90058f.mjs +0 -55
  70. package/dist/packem_shared/consoleTelemetry-z2MiP1jt.mjs +0 -93
  71. package/dist/packem_shared/createAgentContext-4xJGXNR4.mjs +0 -50
  72. package/dist/packem_shared/createAgentGenerate-BQv9YJ01.mjs +0 -192
  73. package/dist/packem_shared/createDispatchRunner-DSbp_dph-ZHTtxy3f.mjs +0 -69
  74. package/dist/packem_shared/defineAgent-DAwAZC9P.mjs +0 -148
  75. package/dist/packem_shared/defineSkill-Ctf_S-rz.mjs +0 -22
  76. package/dist/packem_shared/functionTool-D6lCa2jB.mjs +0 -20
  77. package/dist/packem_shared/graph-component-Bbaxxymp.mjs +0 -217
  78. package/dist/packem_shared/memory-D4FPcBsX.mjs +0 -12
  79. package/dist/packem_shared/normalizeEntityName-BouctxLC.mjs +0 -3
  80. package/dist/packem_shared/otlpTelemetry-DL6iZ9e2.mjs +0 -164
  81. package/dist/packem_shared/runAgentLoop-B3Q2o-Uz.mjs +0 -493
  82. package/dist/packem_shared/runVoiceTurn-LnqLvCRR.mjs +0 -211
  83. package/dist/packem_shared/sandboxComponent-DR3pTwBL.mjs +0 -194
  84. package/dist/packem_shared/sentryTelemetry-CgqFJyLO.mjs +0 -36
@@ -23,7 +23,7 @@ interface AgentStepLike {
23
23
  /**
24
24
  * Durably hibernate until an external event of `type` arrives, then return
25
25
  * its payload. Used for human-in-the-loop approvals: a run pauses on
26
- * `approval:<toolCallId>` until a client resolves it. Like `do`, a resolved
26
+ * `approval:<toolCallId>` until a client resolves it. Like `do`, a resolved
27
27
  * wait is memoized — a replay returns the recorded decision without pausing
28
28
  * again. Signature mirrors `@lunora/workflow`'s `WorkflowStepLike`.
29
29
  */
@@ -42,10 +42,16 @@ interface AgentStepLike {
42
42
  * `idempotencyKey`.
43
43
  *
44
44
  * The `idempotencyKey` is the deterministic durable-step name
45
- * (`tool:&lt;name>:&lt;toolCallId>`). A COMPLETED tool step is never re-run on a
46
- * workflow replay (native step memoization) but a step that FAILS mid-body
47
- * is retried at-least-once, so a side-effecting tool (charge a card, send a
48
- * mail) must dedupe on this key itself.
45
+ * (`tool:<name>:<toolCallId>`, further suffixed per script step for a
46
+ * `codeTool`). A COMPLETED tool step is never re-run on a workflow replay
47
+ * (native step memoization) but a step that FAILS mid-body is retried
48
+ * at-least-once, so a side-effecting tool (charge a card, send a mail) must
49
+ * dedupe on this key itself. `functionTool` forwards it to the dispatched
50
+ * function as `args.idempotencyKey` (pinned after the model input, so it
51
+ * can't be overridden) — a function that wants to dedupe declares
52
+ * `idempotencyKey: v.optional(v.string())` in its own args and checks it; a
53
+ * function that ignores it is unaffected (an undeclared arg field is dropped,
54
+ * not rejected).
49
55
  * @experimental
50
56
  */
51
57
  interface AgentToolContext {
@@ -102,11 +108,45 @@ interface AgentToolContext {
102
108
  * skip the write when it is already present.
103
109
  */
104
110
  setState: (state: Record<string, unknown>) => Promise<void>;
111
+ /**
112
+ * The durable-step handle (`step.do`/`waitForEvent`). ALWAYS present:
113
+ * `agent-loop.ts` threads it into every tool's context unconditionally, and
114
+ * it is required rather than optional so a missing handle is a compile
115
+ * error instead of a silent durability downgrade. `codeTool` uses it to give
116
+ * each script step its OWN nested durable boundary — see `code-tool.ts` — so
117
+ * a failure at script step 3 retries only step 3, not steps 1–2's
118
+ * already-committed side effects. Cloudflare Workflows supports a `step.do`
119
+ * nested inside another `step.do`'s callback (the codeTool call's own
120
+ * enclosing step). Most tools never touch this directly; a test driving
121
+ * `execute`/`runToolScript` by hand passes a pass-through double.
122
+ */
123
+ step: AgentStepLike;
105
124
  /** The thread this tool call belongs to. */
106
125
  threadKey: string;
107
126
  /** The provider-issued tool-call id. */
108
127
  toolCallId: string;
109
128
  }
129
+ /**
130
+ * The view of {@link AgentToolContext} handed to a `needsApproval` gate
131
+ * function — every field except `setState`, `step`, and `reportProgress`.
132
+ *
133
+ * `setState` is dropped because a gate that mutates thread state is a side
134
+ * effect inside a decision predicate, and `reportProgress` because emitting a
135
+ * live event is the same thing in observable form — the decision is what the
136
+ * loop reports, not the deciding. `step` goes because the loop already runs the
137
+ * gate inside a durable step of its own, so a gate has no business opening
138
+ * another.
139
+ *
140
+ * `getState` and `run` stay: reads are legitimate gate inputs (gate on the
141
+ * caller's plan tier, on a spend total), and the gate resolves inside its own
142
+ * durable step, so they are replay-safe there. Note this makes the type a
143
+ * NARROWING, not a proof of purity — `run` takes any
144
+ * {@link AgentFunctionReference}, so a gate can still dispatch a mutation
145
+ * before approval. Nothing in the type system distinguishes a query reference
146
+ * from a mutation one; keeping the gate side-effect-free is the author's.
147
+ * @experimental
148
+ */
149
+ type AgentApprovalContext = Omit<AgentToolContext, "reportProgress" | "setState" | "step">;
110
150
  /**
111
151
  * An agent tool. Unlike a raw AI SDK tool, `execute` is NOT handed to the
112
152
  * model call — the loop runs it itself inside a named durable step so a
@@ -127,17 +167,25 @@ interface AgentToolDefinition<Input = unknown, Output = unknown> {
127
167
  * Gate the tool behind a human approval (mirrors the AI SDK's
128
168
  * `needsApproval`). When it resolves truthy the durable run PAUSES — the
129
169
  * thread moves to `"awaiting_input"` and the workflow hibernates on
130
- * `approval:&lt;toolCallId>` — until a client calls `agents:agentResolveApproval`.
170
+ * `approval:<toolCallId>` — until a client calls `agents:agentResolveApproval`.
131
171
  * On approve the tool runs exactly as normal; on reject it is skipped and a
132
172
  * tool result explaining the rejection is persisted so the next turn recovers.
133
173
  * A boolean gates statically; a function gates per input. Default: `false`
134
- * (unchanged behavior). Evaluated from replay-stable input OUTSIDE the
135
- * durable step (it re-runs on every replay), so it must be a PURE predicate:
136
- * deterministic (no `Date.now()`/`Math.random()`) and free of side effects —
137
- * never call {@link AgentToolContext.setState}/`getState` or a mutating `run`
138
- * here; state writes belong only in `execute`, inside the memoized step.
174
+ * (unchanged behavior).
175
+ *
176
+ * The boolean/`undefined` forms are compile-time constants re-derived
177
+ * identically on every replay — no durable step. The FUNCTION form runs
178
+ * inside its OWN durable step (`tool:approval-gate:<toolCallId>`, distinct
179
+ * from the tool's own step), so it now runs exactly once per call, not once
180
+ * per replay. It must still be otherwise pure: deterministic given its
181
+ * inputs (no `Date.now()`/`Math.random()`) and free of side effects — the
182
+ * context it receives is {@link AgentApprovalContext}, which has neither
183
+ * `setState` nor `reportProgress`; state writes and progress events belong
184
+ * only in `execute`, inside the tool's own memoized step. It still holds
185
+ * `run`, which the type cannot narrow to reads — see
186
+ * {@link AgentApprovalContext}.
139
187
  */
140
- needsApproval?: ((input: Input, context: AgentToolContext) => boolean | Promise<boolean>) | boolean;
188
+ needsApproval?: ((input: Input, context: AgentApprovalContext) => boolean | Promise<boolean>) | boolean;
141
189
  }
142
190
  /**
143
191
  * Author-supplied tool config (see {@link AgentToolDefinition}).
@@ -252,7 +300,7 @@ interface AgentMemoryOptions {
252
300
  * (`key: "default"`) from {@link AgentConfig.memory}, then one per skill that
253
301
  * carries `knowledge` (keyed by the skill's name). The key names the durable
254
302
  * step — the default source keeps the historic `"memory:retrieve"`, a skill
255
- * source uses `"memory:retrieve:&lt;key>"` — so replay stays deterministic.
303
+ * source uses `"memory:retrieve:<key>"` — so replay stays deterministic.
256
304
  * @experimental
257
305
  */
258
306
  interface AgentMemorySource extends AgentMemoryOptions {
@@ -308,7 +356,7 @@ interface SkillConfig {
308
356
  knowledge?: AgentMemoryOptions;
309
357
  /**
310
358
  * The skill's identifier — namespaces this skill's `knowledge` memory source
311
- * (the durable step `memory:retrieve:&lt;name>`). Must be identifier-shaped.
359
+ * (the durable step `memory:retrieve:<name>`). Must be identifier-shaped.
312
360
  */
313
361
  name: string;
314
362
  /**
@@ -318,6 +366,12 @@ interface SkillConfig {
318
366
  */
319
367
  tools?: Record<string, AnyAgentTool>;
320
368
  }
369
+ /**
370
+ * The code-side parts of a markdown-authored skill — everything `SKILL.md`
371
+ * cannot carry. `name` and `instructions` come from the file itself.
372
+ * @experimental
373
+ */
374
+ type SkillMarkdownExtras = Omit<SkillConfig, "instructions" | "name">;
321
375
  /**
322
376
  * A `defineSkill` result — config plus the brand the agent merge checks.
323
377
  * @experimental
@@ -358,11 +412,43 @@ interface AgentStepFinishInfo {
358
412
  }
359
413
  /**
360
414
  * Called after each LLM turn with that turn's text, tool calls, and usage. Runs
361
- * inside a named durable step (`agent:step-finish:&lt;turn>`) so it fires exactly
415
+ * inside a named durable step (`agent:step-finish:<turn>`) so it fires exactly
362
416
  * once per turn even across a workflow replay.
363
417
  * @experimental
364
418
  */
365
419
  type AgentOnStepFinish = (info: AgentStepFinishInfo) => Promise<void> | void;
420
+ /**
421
+ * What {@link AgentConfig.onReply} is called with when a triggered run reaches
422
+ * its final answer.
423
+ * @experimental
424
+ */
425
+ interface AgentReplyInfo {
426
+ /** The worker `env` — where an outbound credential (a bot token, a mailer binding) lives. */
427
+ env: Record<string, unknown>;
428
+ /** Where to reply, captured by the mapper that started this run. */
429
+ replyRef: AgentReplyRef;
430
+ /** The run's final answer. */
431
+ result: AgentRunResult;
432
+ /** The thread this run belongs to. */
433
+ threadKey: string;
434
+ }
435
+ /**
436
+ * Send a triggered run's answer back where it came from — the outbound half of
437
+ * an `onEmail` / `onInbound` trigger.
438
+ *
439
+ * Called once, automatically, when a run started with a `replyRef` produces a
440
+ * final answer; a run without one (an ordinary in-app `ctx.agents.<name>.run`)
441
+ * never calls it. It runs inside a named durable step, so a transient failure
442
+ * is retried and a workflow replay does not send the answer twice.
443
+ *
444
+ * Delivery is the app's call, because only the app has the credential: email
445
+ * has a home already (`replyToEmail(mailer, ref, body)` from
446
+ * `@lunora/agent/reply`), while Slack/GitHub/Discord bot tokens have no
447
+ * framework-owned store yet — read them from `info.env` and make the provider
448
+ * call.
449
+ * @experimental
450
+ */
451
+ type AgentOnReply = (info: AgentReplyInfo) => Promise<void> | void;
366
452
  /**
367
453
  * The input {@link AgentConfig.prepareStep} sees before a turn runs.
368
454
  * @experimental
@@ -404,6 +490,39 @@ type AgentPrepareStep = (input: AgentPrepareStepInput) => AgentPrepareStepResult
404
490
  * start a run from an inbound email.
405
491
  * @experimental
406
492
  */
493
+ /**
494
+ * Where a triggered run should send its answer back to — captured by the
495
+ * mapper, from fields the verified inbound payload already carries, and carried
496
+ * through the run so {@link AgentConfig.onReply} can answer in the same place
497
+ * the question was asked.
498
+ *
499
+ * A discriminated union rather than an opaque blob because each channel threads
500
+ * differently: email by RFC 5322 `In-Reply-To`/`References`, Slack by
501
+ * `thread_ts`, GitHub by issue number, Discord by channel (plus the triggering
502
+ * message for a true reply).
503
+ * @experimental
504
+ */
505
+ type AgentReplyRef = {
506
+ channel: "discord";
507
+ channelId: string;
508
+ messageId?: string;
509
+ } | {
510
+ channel: "email";
511
+ from: string;
512
+ messageId: string;
513
+ references?: string;
514
+ to: string[];
515
+ } | {
516
+ channel: "github";
517
+ commentId?: number;
518
+ issueNumber: number;
519
+ owner: string;
520
+ repo: string;
521
+ } | {
522
+ channel: "slack";
523
+ channelId: string;
524
+ threadTs: string;
525
+ };
407
526
  interface AgentEmailRun {
408
527
  /** The user message that starts (or continues) the thread — the model's prompt. */
409
528
  input: string;
@@ -414,6 +533,13 @@ interface AgentEmailRun {
414
533
  * `email.from`.
415
534
  */
416
535
  owner?: string;
536
+ /**
537
+ * Where to send the answer — see {@link AgentReplyRef}. Populate it from the
538
+ * event the mapper already has (`captureEmailReplyRef(email)` does it for
539
+ * email) and the run calls {@link AgentConfig.onReply} with it once the
540
+ * final answer is ready. Omit it and the run simply never replies.
541
+ */
542
+ replyRef?: AgentReplyRef;
417
543
  /** The thread key — reuse to continue a conversation (e.g. a ticket id parsed from the subject). */
418
544
  threadKey: string;
419
545
  /** Optional thread title, set on first creation. */
@@ -484,6 +610,22 @@ interface AgentInboundChannel {
484
610
  interface AgentConfig {
485
611
  /** Restrict the tools the model may call, by name. Default: all tools. */
486
612
  activeTools?: ReadonlyArray<string>;
613
+ /**
614
+ * How long a human-in-the-loop tool approval may stay pending before the
615
+ * run stops waiting — a Cloudflare Workflows duration: milliseconds, or a
616
+ * `"<n> <unit>"` string like `"3 days"` (the unit set is the host's, so a
617
+ * typo is a compile error). Default `"3 days"`.
618
+ *
619
+ * On timeout the call is treated as REJECTED (the run records why and
620
+ * continues down the normal rejection path), so a run whose approver never
621
+ * answers ends instead of hibernating forever.
622
+ *
623
+ * CLAMPED to one week. A longer wait would outlive the thread's
624
+ * abandoned-run horizon, letting a new run reclaim the thread while the
625
+ * approval is still pending — which is the exact failure this timeout
626
+ * exists to prevent, so it cannot be configured back into existence.
627
+ */
628
+ approvalTimeout?: `${number} ${"day" | "hour" | "minute" | "month" | "second" | "week" | "year"}${"s" | ""}` | number;
487
629
  /**
488
630
  * Automatic thread-history compaction. When the persisted history exceeds
489
631
  * `maxMessages`, the loop summarizes the older messages (all but the most
@@ -530,7 +672,7 @@ interface AgentConfig {
530
672
  model: AgentModelInput;
531
673
  /**
532
674
  * Optional override for the deployed workflow name (`wrangler.jsonc`
533
- * `workflows[].name`). Defaults to `agent-&lt;kebab-cased export name>`. Does
675
+ * `workflows[].name`). Defaults to `agent-<kebab-cased export name>`. Does
534
676
  * NOT change the binding name, which is always derived from the export
535
677
  * name (`support` → `AGENT_SUPPORT`).
536
678
  */
@@ -543,7 +685,16 @@ interface AgentConfig {
543
685
  *
544
686
  * - `"reject"` (default) — fail the new run fast with a `CONFLICT` error.
545
687
  * - `"replace"` — terminate the in-flight instance and take the thread over.
546
- * - `"queue"` — reserved for a future durable queue; currently degrades to `"reject"` (no queue exists yet), tracked as a follow-up.
688
+ * - `"queue"` — park the new run behind the one in flight (FIFO, up to five deep) and hibernate it until the thread is handed over.
689
+ *
690
+ * Each parked run is a live workflow instance waiting on an event, so the
691
+ * queue's depth cap is a real resource bound: past it, a start is rejected
692
+ * exactly as `"reject"` would. A `"replace"` arriving later supersedes the
693
+ * run in FLIGHT, not the queue — parked runs still take their turn after it.
694
+ *
695
+ * A dispatch with no instance id (the inbound-email / inbound-channel
696
+ * paths) cannot be parked, because nothing later can tell it apart from
697
+ * another such dispatch to wake it; `"queue"` rejects those.
547
698
  *
548
699
  * A workflow REPLAY re-enters the bootstrap under the SAME instance id and
549
700
  * is never a concurrent run (the guard compares the stored instance id).
@@ -563,6 +714,12 @@ interface AgentConfig {
563
714
  * signature over the raw body before calling `map`.
564
715
  */
565
716
  onInbound?: AgentInboundChannel;
717
+ /**
718
+ * Called with the final answer when the run was triggered from a channel
719
+ * that gave it a `replyRef` — see {@link AgentOnReply}. This is how an
720
+ * inbound-triggered agent answers where it was asked.
721
+ */
722
+ onReply?: AgentOnReply;
566
723
  /** Called after each LLM turn — see {@link AgentOnStepFinish}. */
567
724
  onStepFinish?: AgentOnStepFinish;
568
725
  /**
@@ -577,7 +734,7 @@ interface AgentConfig {
577
734
  * Opt this agent into being STARTED over the public RPC boundary — i.e. via
578
735
  * the auto-registered `agents:agentRun` mutation an HTTP-only client (e.g.
579
736
  * the `@lunora/mcp` server) calls. Default `false`: an agent is startable
580
- * only from server-side app code (`ctx.agents.&lt;name>.run(...)`), so declaring
737
+ * only from server-side app code (`ctx.agents.<name>.run(...)`), so declaring
581
738
  * an agent does NOT expose it to arbitrary RPC callers. Fail-closed — the run
582
739
  * mutation refuses an agent that has not opted in, regardless of any MCP-side
583
740
  * `allowAgents` configuration. A started thread is still owner-scoped to
@@ -688,7 +845,7 @@ interface AgentAsToolOptions {
688
845
  /** Cap on child-run status polls before giving up. Default 120. */
689
846
  maxPolls?: number;
690
847
  /**
691
- * The child agent's export name — selects its `AGENT_&lt;NAME>` Workflow
848
+ * The child agent's export name — selects its `AGENT_<NAME>` Workflow
692
849
  * binding (e.g. `"researcher"` → `AGENT_RESEARCHER`). The model-facing tool
693
850
  * name is the KEY assigned in the parent's `tools` map, not this.
694
851
  */
@@ -725,6 +882,26 @@ interface AgentDefinition extends AgentConfig {
725
882
  */
726
883
  memorySources?: ReadonlyArray<AgentMemorySource>;
727
884
  }
885
+ /**
886
+ * What `agentEnsureThread` reports back to the loop.
887
+ *
888
+ * A discriminated union rather than a bag of optional booleans: the four
889
+ * outcomes are mutually exclusive, and the data each carries only exists for its
890
+ * own case. `queued` has a position, `replaced` has the instance it took the
891
+ * thread from, and the other two have nothing — encoding that as five
892
+ * independent optional fields made every reader re-derive which combination was
893
+ * legal.
894
+ * @experimental
895
+ */
896
+ type EnsureThreadOutcome = {
897
+ outcome: "continued" | "created";
898
+ } | {
899
+ outcome: "queued";
900
+ position: number;
901
+ } | {
902
+ outcome: "replaced";
903
+ priorInstanceId: string;
904
+ };
728
905
  /**
729
906
  * Params of one agent run (the compiled workflow's payload).
730
907
  * @experimental
@@ -741,6 +918,8 @@ interface AgentRunInput {
741
918
  * the first run.
742
919
  */
743
920
  owner?: string;
921
+ /** Where a triggered run sends its answer — see {@link AgentReplyRef}. */
922
+ replyRef?: AgentReplyRef;
744
923
  /** The thread key — reuse to continue a conversation. */
745
924
  threadKey: string;
746
925
  /** Optional thread title, set on first creation. */
@@ -773,6 +952,17 @@ interface AgentRunResult {
773
952
  */
774
953
  interface AgentFunctionPaths {
775
954
  appendMessage: string;
955
+ /**
956
+ * The internal `agents:agentCompleteRun` mutation the loop dispatches at the
957
+ * end of a run: it writes the terminal status AND hands the thread to the
958
+ * next queued run in the same mutation.
959
+ */
960
+ completeRun: string;
961
+ /**
962
+ * The internal `agents:agentDeleteMessage` mutation the loop dispatches to
963
+ * retire the HITL approval marker once the decision has landed.
964
+ */
965
+ deleteMessage: string;
776
966
  ensureThread: string;
777
967
  /** The internal `agents:agentEpisodeRecall` query the loop dispatches for an episodic-kind read. */
778
968
  episodeRecall: string;
@@ -1078,7 +1268,7 @@ interface AgentRunHandle {
1078
1268
  id: string;
1079
1269
  }
1080
1270
  /**
1081
- * The `ctx.agents.&lt;name>` producer handle.
1271
+ * The `ctx.agents.<name>` producer handle.
1082
1272
  * @experimental
1083
1273
  */
1084
1274
  interface AgentHandle {
@@ -1111,4 +1301,4 @@ interface AgentHandle {
1111
1301
  /** Read a run's workflow status by instance id. */
1112
1302
  status: (id: string) => Promise<unknown>;
1113
1303
  }
1114
- export { AgentDefinition as A, AgentGenerateOptions as B, AgentGenerateResult as C, AgentInstructionsContext as D, AgentLiveEvent as E, AgentMemoryOptions as F, AgentMemorySource as G, AgentMessageStatus as H, InboundChannelEvent as I, AgentOnStepFinish as J, AgentPrepareStep as K, AgentPrepareStepInput as L, AgentPrepareStepResult as M, AgentProgressEvent as N, AgentRunHandle as O, AgentStepFinishInfo as P, AgentStepInfo as Q, AgentThreadStatus as R, SkillDefinition as S, AgentTokenDelta as T, AgentToolCall as U, AgentUsage as V, AgentVoiceConfig as W, AgentWorkflowBindingLike as X, AgentWorkflowInstanceLike as Y, AgentToolContext as a, AgentToolDefinition as b, AgentCompact as c, AgentEpisodeExtract as d, AgentGraphExtract as e, AgentGenerate as f, AgentTokenSink as g, AgentRunInput as h, AgentFunctionPaths as i, AgentRunFunction as j, AgentStepLike as k, AgentStreamGenerate as l, AgentRunResult as m, AgentMessageRow as n, AgentConfig as o, AnyAgentTool as p, AgentAsToolOptions as q, AgentSubToolInput as r, AgentBindingSpec as s, AgentHandle as t, AgentToolConfig as u, AgentFunctionReference as v, AgentModelInput as w, SkillConfig as x, AgentEmailMapper as y, AgentEmailRun as z };
1304
+ export { AgentVoiceConfig as $, AgentDefinition as A, AgentApprovalContext as B, AgentEmailMapper as C, AgentEmailRun as D, AgentGenerateOptions as E, AgentGenerateResult as F, AgentInstructionsContext as G, AgentLiveEvent as H, InboundChannelEvent as I, AgentMemoryOptions as J, AgentMemorySource as K, AgentMessageStatus as L, AgentOnReply as M, AgentOnStepFinish as N, AgentPrepareStep as O, AgentPrepareStepInput as P, AgentPrepareStepResult as Q, AgentProgressEvent as R, SkillMarkdownExtras as S, AgentReplyInfo as T, AgentRunHandle as U, AgentStepFinishInfo as V, AgentStepInfo as W, AgentThreadStatus as X, AgentTokenDelta as Y, AgentToolCall as Z, AgentUsage as _, AgentReplyRef as a, AgentWorkflowBindingLike as a0, AgentWorkflowInstanceLike as a1, EnsureThreadOutcome as a2, AgentToolContext as b, AgentToolDefinition as c, SkillDefinition as d, AgentCompact as e, AgentEpisodeExtract as f, AgentGraphExtract as g, AgentGenerate as h, AgentTokenSink as i, AgentRunInput as j, AgentFunctionPaths as k, AgentRunFunction as l, AgentStepLike as m, AgentStreamGenerate as n, AgentRunResult as o, AgentMessageRow as p, AgentConfig as q, AnyAgentTool as r, AgentAsToolOptions as s, AgentSubToolInput as t, AgentBindingSpec as u, AgentHandle as v, AgentToolConfig as w, AgentFunctionReference as x, AgentModelInput as y, SkillConfig as z };