@lunora/agent 1.0.0-alpha.40 → 1.0.0-alpha.42

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.
@@ -1,5 +1,5 @@
1
- import { A as AgentDefinition } from "./packem_shared/types.d-BC_N2z6_.mjs";
2
- export type { I as InboundChannelEvent } from "./packem_shared/types.d-BC_N2z6_.mjs";
1
+ import { A as AgentDefinition } from "./packem_shared/types.d-PMYeuDE7.mjs";
2
+ export type { I as InboundChannelEvent } from "./packem_shared/types.d-PMYeuDE7.mjs";
3
3
  import '@lunora/mail/inbound';
4
4
  import 'ai';
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { A as AgentDefinition } from "./packem_shared/types.d-BC_N2z6_.js";
2
- export type { I as InboundChannelEvent } from "./packem_shared/types.d-BC_N2z6_.js";
1
+ import { A as AgentDefinition } from "./packem_shared/types.d-PMYeuDE7.js";
2
+ export type { I as InboundChannelEvent } from "./packem_shared/types.d-PMYeuDE7.js";
3
3
  import '@lunora/mail/inbound';
4
4
  import 'ai';
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { A as AgentDefinition } from "./packem_shared/types.d-BC_N2z6_.mjs";
1
+ import { A as AgentDefinition } from "./packem_shared/types.d-PMYeuDE7.mjs";
2
2
  import '@lunora/mail/inbound';
3
3
  import 'ai';
4
4
  /**
package/dist/inbound.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as AgentDefinition } from "./packem_shared/types.d-BC_N2z6_.js";
1
+ import { A as AgentDefinition } from "./packem_shared/types.d-PMYeuDE7.js";
2
2
  import '@lunora/mail/inbound';
3
3
  import 'ai';
4
4
  /**
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AgentDefinition, c as AgentCompact, d as AgentEpisodeExtract, e as AgentGraphExtract, f as AgentGenerate, g as AgentTokenSink, h as AgentRunInput, i as AgentFunctionPaths, j as AgentRunFunction, k as AgentStepLike, l as AgentStreamGenerate, m as AgentRunResult, n as AgentMessageRow, o as AgentConfig, S as SkillDefinition, p as AnyAgentTool, q as AgentAsToolOptions, r as AgentSubToolInput, b as AgentToolDefinition, s as AgentBindingSpec, t as AgentHandle, u as AgentToolConfig, v as AgentFunctionReference, w as AgentModelInput, x as SkillConfig } from "./packem_shared/types.d-BC_N2z6_.mjs";
2
- export type { y as AgentApprovalContext, z as AgentEmailMapper, B as AgentEmailRun, C as AgentGenerateOptions, D as AgentGenerateResult, E as AgentInstructionsContext, F as AgentLiveEvent, G as AgentMemoryOptions, H as AgentMemorySource, J as AgentMessageStatus, K as AgentOnStepFinish, L as AgentPrepareStep, M as AgentPrepareStepInput, N as AgentPrepareStepResult, O as AgentProgressEvent, P as AgentRunHandle, Q as AgentStepFinishInfo, R as AgentStepInfo, T as AgentThreadStatus, U as AgentTokenDelta, V as AgentToolCall, a as AgentToolContext, W as AgentUsage, X as AgentVoiceConfig, Y as AgentWorkflowBindingLike, Z as AgentWorkflowInstanceLike } from "./packem_shared/types.d-BC_N2z6_.mjs";
1
+ import { A as AgentDefinition, d as AgentCompact, e as AgentEpisodeExtract, f as AgentGraphExtract, g as AgentGenerate, h as AgentTokenSink, i as AgentRunInput, j as AgentFunctionPaths, k as AgentRunFunction, l as AgentStepLike, m as AgentStreamGenerate, n as AgentRunResult, o as AgentMessageRow, p as AgentConfig, c as SkillDefinition, q as AnyAgentTool, r as AgentAsToolOptions, s as AgentSubToolInput, b as AgentToolDefinition, t as AgentBindingSpec, u as AgentHandle, v as AgentToolConfig, w as AgentFunctionReference, x as AgentModelInput, y as SkillConfig } from "./packem_shared/types.d-PMYeuDE7.mjs";
2
+ export type { z as AgentApprovalContext, B as AgentEmailMapper, C as AgentEmailRun, D as AgentGenerateOptions, E as AgentGenerateResult, F as AgentInstructionsContext, G as AgentLiveEvent, H as AgentMemoryOptions, J as AgentMemorySource, K as AgentMessageStatus, L as AgentOnStepFinish, M as AgentPrepareStep, N as AgentPrepareStepInput, O as AgentPrepareStepResult, P as AgentProgressEvent, Q as AgentRunHandle, R as AgentStepFinishInfo, T as AgentStepInfo, U as AgentThreadStatus, V as AgentTokenDelta, W as AgentToolCall, a as AgentToolContext, X as AgentUsage, Y as AgentVoiceConfig, Z as AgentWorkflowBindingLike, _ as AgentWorkflowInstanceLike } from "./packem_shared/types.d-PMYeuDE7.mjs";
3
3
  export { type AgentComponent, agentComponent, agentExtension } from "./component.mjs";
4
4
  import { FlexibleSchema, LanguageModel, ModelMessage } from 'ai';
5
5
  export { agentBindingName, agentClassName, agentDefaultName, voiceBindingName, voiceClassName } from "./naming.mjs";
@@ -183,7 +183,7 @@ declare const agentAsTool: (options: AgentAsToolOptions) => AgentToolDefinition<
183
183
  interface ToolScriptStep {
184
184
  /** A stable name later steps reference the output by. */
185
185
  id: string;
186
- /** The tool's input; values may embed `{ "$from": "&lt;stepId>", "$path": "a.b" }` refs. */
186
+ /** The tool's input; values may embed `{ "$from": "<stepId>", "$path": "a.b" }` refs. */
187
187
  input?: Record<string, unknown>;
188
188
  /** The tool to call — one of the tools handed to {@link codeTool}. */
189
189
  tool: string;
@@ -821,15 +821,15 @@ declare class VoiceSessionDO {
821
821
  }
822
822
  /**
823
823
  * Compile a `defineAgent` definition into the workflow the generated
824
- * `&lt;Name>AgentWorkflow` entrypoint class runs. Codegen emits, per agent:
824
+ * `<Name>AgentWorkflow` entrypoint class runs. Codegen emits, per agent:
825
825
  *
826
826
  * ```ts
827
827
  * import LunoraWorkflow from "@lunora/workflow/do";
828
828
  * import { compileAgentWorkflow } from "@lunora/agent";
829
829
  * import { support } from "../agents.js";
830
830
  *
831
- * export class SupportAgentWorkflow extends LunoraWorkflow&lt;AgentRunInput, AgentRunResult> {
832
- * public constructor(ctx: ConstructorParameters&lt;typeof LunoraWorkflow>[0], env: Record&lt;string, unknown>) {
831
+ * export class SupportAgentWorkflow extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
832
+ * public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
833
833
  * super(ctx, env, compileAgentWorkflow(support, "support"), "support");
834
834
  * }
835
835
  * }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AgentDefinition, c as AgentCompact, d as AgentEpisodeExtract, e as AgentGraphExtract, f as AgentGenerate, g as AgentTokenSink, h as AgentRunInput, i as AgentFunctionPaths, j as AgentRunFunction, k as AgentStepLike, l as AgentStreamGenerate, m as AgentRunResult, n as AgentMessageRow, o as AgentConfig, S as SkillDefinition, p as AnyAgentTool, q as AgentAsToolOptions, r as AgentSubToolInput, b as AgentToolDefinition, s as AgentBindingSpec, t as AgentHandle, u as AgentToolConfig, v as AgentFunctionReference, w as AgentModelInput, x as SkillConfig } from "./packem_shared/types.d-BC_N2z6_.js";
2
- export type { y as AgentApprovalContext, z as AgentEmailMapper, B as AgentEmailRun, C as AgentGenerateOptions, D as AgentGenerateResult, E as AgentInstructionsContext, F as AgentLiveEvent, G as AgentMemoryOptions, H as AgentMemorySource, J as AgentMessageStatus, K as AgentOnStepFinish, L as AgentPrepareStep, M as AgentPrepareStepInput, N as AgentPrepareStepResult, O as AgentProgressEvent, P as AgentRunHandle, Q as AgentStepFinishInfo, R as AgentStepInfo, T as AgentThreadStatus, U as AgentTokenDelta, V as AgentToolCall, a as AgentToolContext, W as AgentUsage, X as AgentVoiceConfig, Y as AgentWorkflowBindingLike, Z as AgentWorkflowInstanceLike } from "./packem_shared/types.d-BC_N2z6_.js";
1
+ import { A as AgentDefinition, d as AgentCompact, e as AgentEpisodeExtract, f as AgentGraphExtract, g as AgentGenerate, h as AgentTokenSink, i as AgentRunInput, j as AgentFunctionPaths, k as AgentRunFunction, l as AgentStepLike, m as AgentStreamGenerate, n as AgentRunResult, o as AgentMessageRow, p as AgentConfig, c as SkillDefinition, q as AnyAgentTool, r as AgentAsToolOptions, s as AgentSubToolInput, b as AgentToolDefinition, t as AgentBindingSpec, u as AgentHandle, v as AgentToolConfig, w as AgentFunctionReference, x as AgentModelInput, y as SkillConfig } from "./packem_shared/types.d-PMYeuDE7.js";
2
+ export type { z as AgentApprovalContext, B as AgentEmailMapper, C as AgentEmailRun, D as AgentGenerateOptions, E as AgentGenerateResult, F as AgentInstructionsContext, G as AgentLiveEvent, H as AgentMemoryOptions, J as AgentMemorySource, K as AgentMessageStatus, L as AgentOnStepFinish, M as AgentPrepareStep, N as AgentPrepareStepInput, O as AgentPrepareStepResult, P as AgentProgressEvent, Q as AgentRunHandle, R as AgentStepFinishInfo, T as AgentStepInfo, U as AgentThreadStatus, V as AgentTokenDelta, W as AgentToolCall, a as AgentToolContext, X as AgentUsage, Y as AgentVoiceConfig, Z as AgentWorkflowBindingLike, _ as AgentWorkflowInstanceLike } from "./packem_shared/types.d-PMYeuDE7.js";
3
3
  export { type AgentComponent, agentComponent, agentExtension } from "./component.js";
4
4
  import { FlexibleSchema, LanguageModel, ModelMessage } from 'ai';
5
5
  export { agentBindingName, agentClassName, agentDefaultName, voiceBindingName, voiceClassName } from "./naming.js";
@@ -183,7 +183,7 @@ declare const agentAsTool: (options: AgentAsToolOptions) => AgentToolDefinition<
183
183
  interface ToolScriptStep {
184
184
  /** A stable name later steps reference the output by. */
185
185
  id: string;
186
- /** The tool's input; values may embed `{ "$from": "&lt;stepId>", "$path": "a.b" }` refs. */
186
+ /** The tool's input; values may embed `{ "$from": "<stepId>", "$path": "a.b" }` refs. */
187
187
  input?: Record<string, unknown>;
188
188
  /** The tool to call — one of the tools handed to {@link codeTool}. */
189
189
  tool: string;
@@ -821,15 +821,15 @@ declare class VoiceSessionDO {
821
821
  }
822
822
  /**
823
823
  * Compile a `defineAgent` definition into the workflow the generated
824
- * `&lt;Name>AgentWorkflow` entrypoint class runs. Codegen emits, per agent:
824
+ * `<Name>AgentWorkflow` entrypoint class runs. Codegen emits, per agent:
825
825
  *
826
826
  * ```ts
827
827
  * import LunoraWorkflow from "@lunora/workflow/do";
828
828
  * import { compileAgentWorkflow } from "@lunora/agent";
829
829
  * import { support } from "../agents.js";
830
830
  *
831
- * export class SupportAgentWorkflow extends LunoraWorkflow&lt;AgentRunInput, AgentRunResult> {
832
- * public constructor(ctx: ConstructorParameters&lt;typeof LunoraWorkflow>[0], env: Record&lt;string, unknown>) {
831
+ * export class SupportAgentWorkflow extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
832
+ * public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
833
833
  * super(ctx, env, compileAgentWorkflow(support, "support"), "support");
834
834
  * }
835
835
  * }
@@ -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:&lt;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,7 +42,7 @@ 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
45
+ * (`tool:<name>:<toolCallId>`). A COMPLETED tool step is never re-run on a
46
46
  * workflow replay (native step memoization) — but a step that FAILS mid-body
47
47
  * is retried at-least-once, so a side-effecting tool (charge a card, send a
48
48
  * mail) must dedupe on this key itself.
@@ -138,7 +138,7 @@ interface AgentToolDefinition<Input = unknown, Output = unknown> {
138
138
  * Gate the tool behind a human approval (mirrors the AI SDK's
139
139
  * `needsApproval`). When it resolves truthy the durable run PAUSES — the
140
140
  * thread moves to `"awaiting_input"` and the workflow hibernates on
141
- * `approval:&lt;toolCallId>` — until a client calls `agents:agentResolveApproval`.
141
+ * `approval:<toolCallId>` — until a client calls `agents:agentResolveApproval`.
142
142
  * On approve the tool runs exactly as normal; on reject it is skipped and a
143
143
  * tool result explaining the rejection is persisted so the next turn recovers.
144
144
  * A boolean gates statically; a function gates per input. Default: `false`
@@ -146,7 +146,7 @@ interface AgentToolDefinition<Input = unknown, Output = unknown> {
146
146
  *
147
147
  * The boolean/`undefined` forms are compile-time constants re-derived
148
148
  * identically on every replay — no durable step. The FUNCTION form runs
149
- * inside its OWN durable step (`tool:approval-gate:&lt;toolCallId>`, distinct
149
+ * inside its OWN durable step (`tool:approval-gate:<toolCallId>`, distinct
150
150
  * from the tool's own step), so it now runs exactly once per call, not once
151
151
  * per replay. It must still be otherwise pure: deterministic given its
152
152
  * inputs (no `Date.now()`/`Math.random()`) and free of side effects — the
@@ -269,7 +269,7 @@ interface AgentMemoryOptions {
269
269
  * (`key: "default"`) from {@link AgentConfig.memory}, then one per skill that
270
270
  * carries `knowledge` (keyed by the skill's name). The key names the durable
271
271
  * step — the default source keeps the historic `"memory:retrieve"`, a skill
272
- * source uses `"memory:retrieve:&lt;key>"` — so replay stays deterministic.
272
+ * source uses `"memory:retrieve:<key>"` — so replay stays deterministic.
273
273
  * @experimental
274
274
  */
275
275
  interface AgentMemorySource extends AgentMemoryOptions {
@@ -325,7 +325,7 @@ interface SkillConfig {
325
325
  knowledge?: AgentMemoryOptions;
326
326
  /**
327
327
  * The skill's identifier — namespaces this skill's `knowledge` memory source
328
- * (the durable step `memory:retrieve:&lt;name>`). Must be identifier-shaped.
328
+ * (the durable step `memory:retrieve:<name>`). Must be identifier-shaped.
329
329
  */
330
330
  name: string;
331
331
  /**
@@ -335,6 +335,12 @@ interface SkillConfig {
335
335
  */
336
336
  tools?: Record<string, AnyAgentTool>;
337
337
  }
338
+ /**
339
+ * The code-side parts of a markdown-authored skill — everything `SKILL.md`
340
+ * cannot carry. `name` and `instructions` come from the file itself.
341
+ * @experimental
342
+ */
343
+ type SkillMarkdownExtras = Omit<SkillConfig, "instructions" | "name">;
338
344
  /**
339
345
  * A `defineSkill` result — config plus the brand the agent merge checks.
340
346
  * @experimental
@@ -375,7 +381,7 @@ interface AgentStepFinishInfo {
375
381
  }
376
382
  /**
377
383
  * Called after each LLM turn with that turn's text, tool calls, and usage. Runs
378
- * inside a named durable step (`agent:step-finish:&lt;turn>`) so it fires exactly
384
+ * inside a named durable step (`agent:step-finish:<turn>`) so it fires exactly
379
385
  * once per turn even across a workflow replay.
380
386
  * @experimental
381
387
  */
@@ -547,7 +553,7 @@ interface AgentConfig {
547
553
  model: AgentModelInput;
548
554
  /**
549
555
  * Optional override for the deployed workflow name (`wrangler.jsonc`
550
- * `workflows[].name`). Defaults to `agent-&lt;kebab-cased export name>`. Does
556
+ * `workflows[].name`). Defaults to `agent-<kebab-cased export name>`. Does
551
557
  * NOT change the binding name, which is always derived from the export
552
558
  * name (`support` → `AGENT_SUPPORT`).
553
559
  */
@@ -594,7 +600,7 @@ interface AgentConfig {
594
600
  * Opt this agent into being STARTED over the public RPC boundary — i.e. via
595
601
  * the auto-registered `agents:agentRun` mutation an HTTP-only client (e.g.
596
602
  * the `@lunora/mcp` server) calls. Default `false`: an agent is startable
597
- * only from server-side app code (`ctx.agents.&lt;name>.run(...)`), so declaring
603
+ * only from server-side app code (`ctx.agents.<name>.run(...)`), so declaring
598
604
  * an agent does NOT expose it to arbitrary RPC callers. Fail-closed — the run
599
605
  * mutation refuses an agent that has not opted in, regardless of any MCP-side
600
606
  * `allowAgents` configuration. A started thread is still owner-scoped to
@@ -705,7 +711,7 @@ interface AgentAsToolOptions {
705
711
  /** Cap on child-run status polls before giving up. Default 120. */
706
712
  maxPolls?: number;
707
713
  /**
708
- * The child agent's export name — selects its `AGENT_&lt;NAME>` Workflow
714
+ * The child agent's export name — selects its `AGENT_<NAME>` Workflow
709
715
  * binding (e.g. `"researcher"` → `AGENT_RESEARCHER`). The model-facing tool
710
716
  * name is the KEY assigned in the parent's `tools` map, not this.
711
717
  */
@@ -1095,7 +1101,7 @@ interface AgentRunHandle {
1095
1101
  id: string;
1096
1102
  }
1097
1103
  /**
1098
- * The `ctx.agents.&lt;name>` producer handle.
1104
+ * The `ctx.agents.<name>` producer handle.
1099
1105
  * @experimental
1100
1106
  */
1101
1107
  interface AgentHandle {
@@ -1128,4 +1134,4 @@ interface AgentHandle {
1128
1134
  /** Read a run's workflow status by instance id. */
1129
1135
  status: (id: string) => Promise<unknown>;
1130
1136
  }
1131
- export { AgentDefinition as A, AgentEmailRun as B, AgentGenerateOptions as C, AgentGenerateResult as D, AgentInstructionsContext as E, AgentLiveEvent as F, AgentMemoryOptions as G, AgentMemorySource as H, InboundChannelEvent as I, AgentMessageStatus as J, AgentOnStepFinish as K, AgentPrepareStep as L, AgentPrepareStepInput as M, AgentPrepareStepResult as N, AgentProgressEvent as O, AgentRunHandle as P, AgentStepFinishInfo as Q, AgentStepInfo as R, SkillDefinition as S, AgentThreadStatus as T, AgentTokenDelta as U, AgentToolCall as V, AgentUsage as W, AgentVoiceConfig as X, AgentWorkflowBindingLike as Y, AgentWorkflowInstanceLike as Z, 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, AgentApprovalContext as y, AgentEmailMapper as z };
1137
+ export { AgentDefinition as A, AgentEmailMapper as B, AgentEmailRun as C, AgentGenerateOptions as D, AgentGenerateResult as E, AgentInstructionsContext as F, AgentLiveEvent as G, AgentMemoryOptions as H, InboundChannelEvent as I, AgentMemorySource as J, AgentMessageStatus as K, AgentOnStepFinish as L, AgentPrepareStep as M, AgentPrepareStepInput as N, AgentPrepareStepResult as O, AgentProgressEvent as P, AgentRunHandle as Q, AgentStepFinishInfo as R, SkillMarkdownExtras as S, AgentStepInfo as T, AgentThreadStatus as U, AgentTokenDelta as V, AgentToolCall as W, AgentUsage as X, AgentVoiceConfig as Y, AgentWorkflowBindingLike as Z, AgentWorkflowInstanceLike as _, AgentToolContext as a, AgentToolDefinition as b, SkillDefinition as c, AgentCompact as d, AgentEpisodeExtract as e, AgentGraphExtract as f, AgentGenerate as g, AgentTokenSink as h, AgentRunInput as i, AgentFunctionPaths as j, AgentRunFunction as k, AgentStepLike as l, AgentStreamGenerate as m, AgentRunResult as n, AgentMessageRow as o, AgentConfig as p, AnyAgentTool as q, AgentAsToolOptions as r, AgentSubToolInput as s, AgentBindingSpec as t, AgentHandle as u, AgentToolConfig as v, AgentFunctionReference as w, AgentModelInput as x, SkillConfig as y, AgentApprovalContext as z };
@@ -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:&lt;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,7 +42,7 @@ 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
45
+ * (`tool:<name>:<toolCallId>`). A COMPLETED tool step is never re-run on a
46
46
  * workflow replay (native step memoization) — but a step that FAILS mid-body
47
47
  * is retried at-least-once, so a side-effecting tool (charge a card, send a
48
48
  * mail) must dedupe on this key itself.
@@ -138,7 +138,7 @@ interface AgentToolDefinition<Input = unknown, Output = unknown> {
138
138
  * Gate the tool behind a human approval (mirrors the AI SDK's
139
139
  * `needsApproval`). When it resolves truthy the durable run PAUSES — the
140
140
  * thread moves to `"awaiting_input"` and the workflow hibernates on
141
- * `approval:&lt;toolCallId>` — until a client calls `agents:agentResolveApproval`.
141
+ * `approval:<toolCallId>` — until a client calls `agents:agentResolveApproval`.
142
142
  * On approve the tool runs exactly as normal; on reject it is skipped and a
143
143
  * tool result explaining the rejection is persisted so the next turn recovers.
144
144
  * A boolean gates statically; a function gates per input. Default: `false`
@@ -146,7 +146,7 @@ interface AgentToolDefinition<Input = unknown, Output = unknown> {
146
146
  *
147
147
  * The boolean/`undefined` forms are compile-time constants re-derived
148
148
  * identically on every replay — no durable step. The FUNCTION form runs
149
- * inside its OWN durable step (`tool:approval-gate:&lt;toolCallId>`, distinct
149
+ * inside its OWN durable step (`tool:approval-gate:<toolCallId>`, distinct
150
150
  * from the tool's own step), so it now runs exactly once per call, not once
151
151
  * per replay. It must still be otherwise pure: deterministic given its
152
152
  * inputs (no `Date.now()`/`Math.random()`) and free of side effects — the
@@ -269,7 +269,7 @@ interface AgentMemoryOptions {
269
269
  * (`key: "default"`) from {@link AgentConfig.memory}, then one per skill that
270
270
  * carries `knowledge` (keyed by the skill's name). The key names the durable
271
271
  * step — the default source keeps the historic `"memory:retrieve"`, a skill
272
- * source uses `"memory:retrieve:&lt;key>"` — so replay stays deterministic.
272
+ * source uses `"memory:retrieve:<key>"` — so replay stays deterministic.
273
273
  * @experimental
274
274
  */
275
275
  interface AgentMemorySource extends AgentMemoryOptions {
@@ -325,7 +325,7 @@ interface SkillConfig {
325
325
  knowledge?: AgentMemoryOptions;
326
326
  /**
327
327
  * The skill's identifier — namespaces this skill's `knowledge` memory source
328
- * (the durable step `memory:retrieve:&lt;name>`). Must be identifier-shaped.
328
+ * (the durable step `memory:retrieve:<name>`). Must be identifier-shaped.
329
329
  */
330
330
  name: string;
331
331
  /**
@@ -335,6 +335,12 @@ interface SkillConfig {
335
335
  */
336
336
  tools?: Record<string, AnyAgentTool>;
337
337
  }
338
+ /**
339
+ * The code-side parts of a markdown-authored skill — everything `SKILL.md`
340
+ * cannot carry. `name` and `instructions` come from the file itself.
341
+ * @experimental
342
+ */
343
+ type SkillMarkdownExtras = Omit<SkillConfig, "instructions" | "name">;
338
344
  /**
339
345
  * A `defineSkill` result — config plus the brand the agent merge checks.
340
346
  * @experimental
@@ -375,7 +381,7 @@ interface AgentStepFinishInfo {
375
381
  }
376
382
  /**
377
383
  * Called after each LLM turn with that turn's text, tool calls, and usage. Runs
378
- * inside a named durable step (`agent:step-finish:&lt;turn>`) so it fires exactly
384
+ * inside a named durable step (`agent:step-finish:<turn>`) so it fires exactly
379
385
  * once per turn even across a workflow replay.
380
386
  * @experimental
381
387
  */
@@ -547,7 +553,7 @@ interface AgentConfig {
547
553
  model: AgentModelInput;
548
554
  /**
549
555
  * Optional override for the deployed workflow name (`wrangler.jsonc`
550
- * `workflows[].name`). Defaults to `agent-&lt;kebab-cased export name>`. Does
556
+ * `workflows[].name`). Defaults to `agent-<kebab-cased export name>`. Does
551
557
  * NOT change the binding name, which is always derived from the export
552
558
  * name (`support` → `AGENT_SUPPORT`).
553
559
  */
@@ -594,7 +600,7 @@ interface AgentConfig {
594
600
  * Opt this agent into being STARTED over the public RPC boundary — i.e. via
595
601
  * the auto-registered `agents:agentRun` mutation an HTTP-only client (e.g.
596
602
  * the `@lunora/mcp` server) calls. Default `false`: an agent is startable
597
- * only from server-side app code (`ctx.agents.&lt;name>.run(...)`), so declaring
603
+ * only from server-side app code (`ctx.agents.<name>.run(...)`), so declaring
598
604
  * an agent does NOT expose it to arbitrary RPC callers. Fail-closed — the run
599
605
  * mutation refuses an agent that has not opted in, regardless of any MCP-side
600
606
  * `allowAgents` configuration. A started thread is still owner-scoped to
@@ -705,7 +711,7 @@ interface AgentAsToolOptions {
705
711
  /** Cap on child-run status polls before giving up. Default 120. */
706
712
  maxPolls?: number;
707
713
  /**
708
- * The child agent's export name — selects its `AGENT_&lt;NAME>` Workflow
714
+ * The child agent's export name — selects its `AGENT_<NAME>` Workflow
709
715
  * binding (e.g. `"researcher"` → `AGENT_RESEARCHER`). The model-facing tool
710
716
  * name is the KEY assigned in the parent's `tools` map, not this.
711
717
  */
@@ -1095,7 +1101,7 @@ interface AgentRunHandle {
1095
1101
  id: string;
1096
1102
  }
1097
1103
  /**
1098
- * The `ctx.agents.&lt;name>` producer handle.
1104
+ * The `ctx.agents.<name>` producer handle.
1099
1105
  * @experimental
1100
1106
  */
1101
1107
  interface AgentHandle {
@@ -1128,4 +1134,4 @@ interface AgentHandle {
1128
1134
  /** Read a run's workflow status by instance id. */
1129
1135
  status: (id: string) => Promise<unknown>;
1130
1136
  }
1131
- export { AgentDefinition as A, AgentEmailRun as B, AgentGenerateOptions as C, AgentGenerateResult as D, AgentInstructionsContext as E, AgentLiveEvent as F, AgentMemoryOptions as G, AgentMemorySource as H, InboundChannelEvent as I, AgentMessageStatus as J, AgentOnStepFinish as K, AgentPrepareStep as L, AgentPrepareStepInput as M, AgentPrepareStepResult as N, AgentProgressEvent as O, AgentRunHandle as P, AgentStepFinishInfo as Q, AgentStepInfo as R, SkillDefinition as S, AgentThreadStatus as T, AgentTokenDelta as U, AgentToolCall as V, AgentUsage as W, AgentVoiceConfig as X, AgentWorkflowBindingLike as Y, AgentWorkflowInstanceLike as Z, 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, AgentApprovalContext as y, AgentEmailMapper as z };
1137
+ export { AgentDefinition as A, AgentEmailMapper as B, AgentEmailRun as C, AgentGenerateOptions as D, AgentGenerateResult as E, AgentInstructionsContext as F, AgentLiveEvent as G, AgentMemoryOptions as H, InboundChannelEvent as I, AgentMemorySource as J, AgentMessageStatus as K, AgentOnStepFinish as L, AgentPrepareStep as M, AgentPrepareStepInput as N, AgentPrepareStepResult as O, AgentProgressEvent as P, AgentRunHandle as Q, AgentStepFinishInfo as R, SkillMarkdownExtras as S, AgentStepInfo as T, AgentThreadStatus as U, AgentTokenDelta as V, AgentToolCall as W, AgentUsage as X, AgentVoiceConfig as Y, AgentWorkflowBindingLike as Z, AgentWorkflowInstanceLike as _, AgentToolContext as a, AgentToolDefinition as b, SkillDefinition as c, AgentCompact as d, AgentEpisodeExtract as e, AgentGraphExtract as f, AgentGenerate as g, AgentTokenSink as h, AgentRunInput as i, AgentFunctionPaths as j, AgentRunFunction as k, AgentStepLike as l, AgentStreamGenerate as m, AgentRunResult as n, AgentMessageRow as o, AgentConfig as p, AnyAgentTool as q, AgentAsToolOptions as r, AgentSubToolInput as s, AgentBindingSpec as t, AgentHandle as u, AgentToolConfig as v, AgentFunctionReference as w, AgentModelInput as x, SkillConfig as y, AgentApprovalContext as z };
@@ -1,4 +1,4 @@
1
- import { a as AgentToolContext, b as AgentToolDefinition } from "./packem_shared/types.d-BC_N2z6_.mjs";
1
+ import { a as AgentToolContext, b as AgentToolDefinition } from "./packem_shared/types.d-PMYeuDE7.mjs";
2
2
  import '@lunora/mail/inbound';
3
3
  import 'ai';
4
4
  /**
@@ -149,7 +149,7 @@ interface ContainerToolOptions {
149
149
  declare const browserTool: (options?: BrowserToolOptions) => AgentToolDefinition<BrowserToolInput, string>;
150
150
  /**
151
151
  * A batteries-included agent tool that talks to a declared Cloudflare
152
- * Container. `name` is the `ctx.containers.&lt;name>` key (the `lunora/containers.ts`
152
+ * Container. `name` is the `ctx.containers.<name>` key (the `lunora/containers.ts`
153
153
  * export). One tool exposes `fetch` (HTTP request) and `exec` (run a command);
154
154
  * the model picks via `op`. The call dispatches to the auto-registered
155
155
  * `sandbox:invoke` action, which carries `ctx.containers`.
package/dist/sandbox.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as AgentToolContext, b as AgentToolDefinition } from "./packem_shared/types.d-BC_N2z6_.js";
1
+ import { a as AgentToolContext, b as AgentToolDefinition } from "./packem_shared/types.d-PMYeuDE7.js";
2
2
  import '@lunora/mail/inbound';
3
3
  import 'ai';
4
4
  /**
@@ -149,7 +149,7 @@ interface ContainerToolOptions {
149
149
  declare const browserTool: (options?: BrowserToolOptions) => AgentToolDefinition<BrowserToolInput, string>;
150
150
  /**
151
151
  * A batteries-included agent tool that talks to a declared Cloudflare
152
- * Container. `name` is the `ctx.containers.&lt;name>` key (the `lunora/containers.ts`
152
+ * Container. `name` is the `ctx.containers.<name>` key (the `lunora/containers.ts`
153
153
  * export). One tool exposes `fetch` (HTTP request) and `exec` (run a command);
154
154
  * the model picks via `op`. The call dispatches to the auto-registered
155
155
  * `sandbox:invoke` action, which carries `ctx.containers`.
@@ -0,0 +1,36 @@
1
+ import { S as SkillMarkdownExtras, c as SkillDefinition } from "./packem_shared/types.d-PMYeuDE7.mjs";
2
+ import '@lunora/mail/inbound';
3
+ import 'ai';
4
+ /**
5
+ * Declare a skill whose prose lives in a markdown file.
6
+ *
7
+ * ```ts
8
+ * import triage from "./skills/triage/SKILL.md?raw";
9
+ * import { functionTool } from "@lunora/agent";
10
+ * import { skillFromMarkdown } from "@lunora/agent/skill-markdown";
11
+ *
12
+ * export const triageSkill = skillFromMarkdown(triage, {
13
+ * tools: { searchCode: functionTool(api.code.search, { ... }) },
14
+ * });
15
+ * ```
16
+ *
17
+ * ```md
18
+ * ---
19
+ * name: triage
20
+ * ---
21
+ * Reproduce the report before proposing a cause. Cite the failing test.
22
+ * ```
23
+ *
24
+ * The split is the point: the instructions are the part a non-author reads,
25
+ * reviews and copies between projects, so they belong in a file that is legible
26
+ * on its own — and the `name` travels WITH that file, so a skill can move
27
+ * without a matching TypeScript wrapper. Tools and `knowledge` stay in code,
28
+ * because they are code.
29
+ *
30
+ * Getting the markdown here is the caller's job (`?raw` under Vite, a build-time
31
+ * import elsewhere) — a Worker has no filesystem to read it from at runtime, so
32
+ * this takes the string rather than a path.
33
+ * @experimental
34
+ */
35
+ declare const skillFromMarkdown: (markdown: string, extras?: SkillMarkdownExtras) => SkillDefinition;
36
+ export { type SkillMarkdownExtras, skillFromMarkdown };
@@ -0,0 +1,36 @@
1
+ import { S as SkillMarkdownExtras, c as SkillDefinition } from "./packem_shared/types.d-PMYeuDE7.js";
2
+ import '@lunora/mail/inbound';
3
+ import 'ai';
4
+ /**
5
+ * Declare a skill whose prose lives in a markdown file.
6
+ *
7
+ * ```ts
8
+ * import triage from "./skills/triage/SKILL.md?raw";
9
+ * import { functionTool } from "@lunora/agent";
10
+ * import { skillFromMarkdown } from "@lunora/agent/skill-markdown";
11
+ *
12
+ * export const triageSkill = skillFromMarkdown(triage, {
13
+ * tools: { searchCode: functionTool(api.code.search, { ... }) },
14
+ * });
15
+ * ```
16
+ *
17
+ * ```md
18
+ * ---
19
+ * name: triage
20
+ * ---
21
+ * Reproduce the report before proposing a cause. Cite the failing test.
22
+ * ```
23
+ *
24
+ * The split is the point: the instructions are the part a non-author reads,
25
+ * reviews and copies between projects, so they belong in a file that is legible
26
+ * on its own — and the `name` travels WITH that file, so a skill can move
27
+ * without a matching TypeScript wrapper. Tools and `knowledge` stay in code,
28
+ * because they are code.
29
+ *
30
+ * Getting the markdown here is the caller's job (`?raw` under Vite, a build-time
31
+ * import elsewhere) — a Worker has no filesystem to read it from at runtime, so
32
+ * this takes the string rather than a path.
33
+ * @experimental
34
+ */
35
+ declare const skillFromMarkdown: (markdown: string, extras?: SkillMarkdownExtras) => SkillDefinition;
36
+ export { type SkillMarkdownExtras, skillFromMarkdown };
@@ -0,0 +1 @@
1
+ import{LunoraError as o}from"@lunora/errors";import{parse as s}from"yaml";import{defineSkill as l}from"./packem_shared/defineSkill-DfJxCwfZ.mjs";const m=/^\uFEFF?[ \t]*---[ \t]*\r?\n/u,d=/^---[ \t]*$/mu,h=n=>{const r=m.exec(n);if(!r)return{body:n.trim(),data:{}};const t=n.slice(r[0].length),e=d.exec(t);if(!e)throw new o("INTERNAL","@lunora/agent: the skill markdown opens with `---` but never closes the frontmatter block. Add a closing `---` on its own line.");let a;try{a=s(t.slice(0,e.index))}catch(i){throw new o("INTERNAL",`@lunora/agent: the skill markdown has invalid YAML frontmatter — ${i instanceof Error?i.message:String(i)}`)}return{body:t.slice(e.index+e[0].length).trim(),data:typeof a=="object"&&a!==null?a:{}}},c=(n,r={})=>{if(typeof n!="string")throw new o("INTERNAL",`@lunora/agent: skillFromMarkdown expects the markdown SOURCE as a string, got ${typeof n}`);const{body:t,data:e}=h(n);if(e.name!==void 0&&typeof e.name!="string")throw new o("INTERNAL",`@lunora/agent: the skill markdown's \`name\` must be a string, got ${Array.isArray(e.name)?"array":typeof e.name}. Quote it if the value looks like a number or a boolean (\`name: "2fa"\`).`);if(typeof e.name!="string")throw new o("INTERNAL","@lunora/agent: skillFromMarkdown found no `name` in the markdown frontmatter. Open the file with a `---` line, put `name: <identifier>` on its own line, and close it with `---`. Other keys are parsed and ignored — only `name` is read here.");if(t==="")throw new o("INTERNAL",`@lunora/agent: the skill markdown for "${e.name}" has no body — the instructions below the closing \`---\` are what the skill contributes.`);return l({...r,instructions:t,name:e.name})};export{c as skillFromMarkdown};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/agent",
3
- "version": "1.0.0-alpha.40",
3
+ "version": "1.0.0-alpha.42",
4
4
  "description": "Durable AI agents for Lunora: defineAgent compiles a replay-safe tool-loop onto Cloudflare Workflows, with DO SQLite threads and live message subscriptions",
5
5
  "keywords": [
6
6
  "agent",
@@ -62,6 +62,10 @@
62
62
  "types": "./dist/naming.d.ts",
63
63
  "import": "./dist/naming.mjs"
64
64
  },
65
+ "./skill-markdown": {
66
+ "types": "./dist/skill-markdown.d.ts",
67
+ "import": "./dist/skill-markdown.mjs"
68
+ },
65
69
  "./sandbox": {
66
70
  "types": "./dist/sandbox.d.ts",
67
71
  "import": "./dist/sandbox.mjs"
@@ -76,14 +80,15 @@
76
80
  "access": "public"
77
81
  },
78
82
  "dependencies": {
79
- "@lunora/ai": "1.0.0-alpha.47",
80
- "@lunora/errors": "1.0.0-alpha.13",
81
- "@lunora/mail": "1.0.0-alpha.40",
82
- "@lunora/server": "1.0.0-alpha.61",
83
- "@lunora/values": "1.0.0-alpha.18",
84
- "@lunora/workflow": "1.0.0-alpha.20",
83
+ "@lunora/ai": "1.0.0-alpha.48",
84
+ "@lunora/errors": "1.0.0-alpha.14",
85
+ "@lunora/mail": "1.0.0-alpha.41",
86
+ "@lunora/server": "1.0.0-alpha.62",
87
+ "@lunora/values": "1.0.0-alpha.19",
88
+ "@lunora/workflow": "1.0.0-alpha.21",
85
89
  "@modelcontextprotocol/sdk": "^1.29.0",
86
- "ai": "7.0.37"
90
+ "ai": "7.0.37",
91
+ "yaml": "^2.9.0"
87
92
  },
88
93
  "engines": {
89
94
  "node": "^22.15.0 || >=24.11.0"