@ironflow/node 0.19.3 → 0.20.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 (81) hide show
  1. package/README.md +5 -2
  2. package/dist/agent/agent.d.ts +60 -0
  3. package/dist/agent/agent.d.ts.map +1 -0
  4. package/dist/agent/agent.js +133 -0
  5. package/dist/agent/agent.js.map +1 -0
  6. package/dist/agent/approve.d.ts +23 -0
  7. package/dist/agent/approve.d.ts.map +1 -0
  8. package/dist/agent/approve.js +42 -0
  9. package/dist/agent/approve.js.map +1 -0
  10. package/dist/agent/dispatch.d.ts +63 -0
  11. package/dist/agent/dispatch.d.ts.map +1 -0
  12. package/dist/agent/dispatch.js +130 -0
  13. package/dist/agent/dispatch.js.map +1 -0
  14. package/dist/agent/errors.d.ts +90 -0
  15. package/dist/agent/errors.d.ts.map +1 -0
  16. package/dist/agent/errors.js +136 -0
  17. package/dist/agent/errors.js.map +1 -0
  18. package/dist/agent/index.d.ts +30 -0
  19. package/dist/agent/index.d.ts.map +1 -0
  20. package/dist/agent/index.js +27 -0
  21. package/dist/agent/index.js.map +1 -0
  22. package/dist/agent/internal-registry.d.ts +27 -0
  23. package/dist/agent/internal-registry.d.ts.map +1 -0
  24. package/dist/agent/internal-registry.js +36 -0
  25. package/dist/agent/internal-registry.js.map +1 -0
  26. package/dist/agent/internal.d.ts +24 -0
  27. package/dist/agent/internal.d.ts.map +1 -0
  28. package/dist/agent/internal.js +29 -0
  29. package/dist/agent/internal.js.map +1 -0
  30. package/dist/agent/llm.d.ts +39 -0
  31. package/dist/agent/llm.d.ts.map +1 -0
  32. package/dist/agent/llm.js +59 -0
  33. package/dist/agent/llm.js.map +1 -0
  34. package/dist/agent/mcp.d.ts +51 -0
  35. package/dist/agent/mcp.d.ts.map +1 -0
  36. package/dist/agent/mcp.js +155 -0
  37. package/dist/agent/mcp.js.map +1 -0
  38. package/dist/agent/memory.d.ts +74 -0
  39. package/dist/agent/memory.d.ts.map +1 -0
  40. package/dist/agent/memory.js +130 -0
  41. package/dist/agent/memory.js.map +1 -0
  42. package/dist/agent/spawn.d.ts +20 -0
  43. package/dist/agent/spawn.d.ts.map +1 -0
  44. package/dist/agent/spawn.js +29 -0
  45. package/dist/agent/spawn.js.map +1 -0
  46. package/dist/agent/tool.d.ts +39 -0
  47. package/dist/agent/tool.d.ts.map +1 -0
  48. package/dist/agent/tool.js +103 -0
  49. package/dist/agent/tool.js.map +1 -0
  50. package/dist/agent/types.d.ts +363 -0
  51. package/dist/agent/types.d.ts.map +1 -0
  52. package/dist/agent/types.js +9 -0
  53. package/dist/agent/types.js.map +1 -0
  54. package/dist/client.d.ts +21 -3
  55. package/dist/client.d.ts.map +1 -1
  56. package/dist/client.js +75 -44
  57. package/dist/client.js.map +1 -1
  58. package/dist/function.d.ts.map +1 -1
  59. package/dist/function.js +16 -0
  60. package/dist/function.js.map +1 -1
  61. package/dist/internal/assert-defined.d.ts +10 -0
  62. package/dist/internal/assert-defined.d.ts.map +1 -0
  63. package/dist/internal/assert-defined.js +15 -0
  64. package/dist/internal/assert-defined.js.map +1 -0
  65. package/dist/projection-runner.d.ts.map +1 -1
  66. package/dist/projection-runner.js +29 -1
  67. package/dist/projection-runner.js.map +1 -1
  68. package/dist/serve.d.ts.map +1 -1
  69. package/dist/serve.js +26 -0
  70. package/dist/serve.js.map +1 -1
  71. package/dist/test/index.d.ts +2 -2
  72. package/dist/test/index.d.ts.map +1 -1
  73. package/dist/test/index.js.map +1 -1
  74. package/dist/types.d.ts +3 -3
  75. package/dist/types.d.ts.map +1 -1
  76. package/dist/version.d.ts +1 -1
  77. package/dist/version.js +1 -1
  78. package/dist/worker.d.ts.map +1 -1
  79. package/dist/worker.js +22 -3
  80. package/dist/worker.js.map +1 -1
  81. package/package.json +15 -9
package/README.md CHANGED
@@ -96,10 +96,12 @@ All fields on the config object:
96
96
  |-------|------|-------------|
97
97
  | `id` | `string` | **Required.** Unique function identifier. |
98
98
  | `name` | `string` | Display name. Defaults to `id`. |
99
+ | `description` | `string` | Human-readable description shown in the dashboard. |
99
100
  | `triggers` | `Trigger[]` | **Required.** Array of event triggers (can be empty for invoke-only functions). |
100
101
  | `retry` | `RetryConfig` | Retry policy for failed steps. |
101
102
  | `timeout` | `number` | Function timeout in milliseconds (default: 600000 = 10 min). |
102
103
  | `concurrency` | `ConcurrencyConfig` | Concurrency control. |
104
+ | `debounce` | `DebounceConfig` | Debounce configuration — collapses rapid-fire events into a single invocation. |
103
105
  | `mode` | `"push" \| "pull"` | Preferred execution mode. |
104
106
  | `actorKey` | `string` | JSON path for actor-based sticky routing (e.g., `"event.data.customerId"`). |
105
107
  | `schema` | `ZodType` | Zod schema for event data validation and type inference. |
@@ -108,6 +110,7 @@ All fields on the config object:
108
110
  | `recording` | `boolean` | Enable audit recording for this function. |
109
111
  | `recordingRetention` | `string` | Retention period for audit events (`"7d"`, `"30d"`, `"90d"`, `"forever"`). |
110
112
  | `pauseBehavior` | `"hold" \| "release"` | Controls whether a paused run retains (`"hold"`, default) or releases (`"release"`) its concurrency lane slot. |
113
+ | `compensateOnCancel` | `boolean` | Run registered `step.compensate()` handlers in reverse order when a pull-mode run is cancelled mid-saga. Ignored for push-mode. |
111
114
  | `metadata` | `Record<string, unknown>` | Arbitrary metadata attached to the function definition. |
112
115
 
113
116
  **Trigger** fields:
@@ -1290,8 +1293,8 @@ Receive and transform external HTTP events from third-party services.
1290
1293
  | Field | Type | Description |
1291
1294
  |-------|------|-------------|
1292
1295
  | `id` | `string` | Webhook source identifier (used in URL path). |
1293
- | `verify` | `(req) => void \| Promise<void>` | Verification function. Throw to reject. |
1294
- | `transform` | `(payload) => WebhookEvent` | Transform raw payload to an Ironflow event. |
1296
+ | `verify` | `(req) => unknown \| Promise<unknown>` | Verify the request and return the parsed payload (or throw to reject). |
1297
+ | `transform` | `(payload) => WebhookEvent \| Promise<WebhookEvent>` | Transform the verified payload to an Ironflow event. |
1295
1298
 
1296
1299
  ### Stripe webhook example
1297
1300
 
@@ -0,0 +1,60 @@
1
+ /**
2
+ * agent() — entrypoint for durable AI agents.
3
+ *
4
+ * Wraps createFunction() with an extended handler context that carries
5
+ * agent-shaped primitives (tool, llm, approve, memory, spawn). The
6
+ * returned value is a plain IronflowFunction so existing serve() and
7
+ * createWorker() register agents with zero changes.
8
+ *
9
+ * Runtime shape:
10
+ * - Per-run turn counter (drives ctx.turn + maxTurns enforcement).
11
+ * - Per-run tool registry built from AgentConfig.tools (drives by-name
12
+ * dispatch in ctx.tool(name, args) for LLM-driven tool calls).
13
+ * - Per-run byArgs idempotency cache for ctx.tool().
14
+ * - Per-run in-memory cache for memory.get() reads.
15
+ *
16
+ * All wrappers compose over ctx.step — agents inherit Ironflow's
17
+ * crash-resume, replay, and audit semantics from the existing runtime.
18
+ */
19
+ import type { z } from "zod";
20
+ import type { AgentConfig, AgentHandler, IronflowAgent } from "./types.js";
21
+ /**
22
+ * Define a durable agent.
23
+ *
24
+ * When `config.memory` is set, the runtime constructs an IronflowClient
25
+ * from `process.env.IRONFLOW_URL` (or `IRONFLOW_SERVER_URL`) plus
26
+ * `IRONFLOW_API_KEY` for the memory backend. Workers that pass
27
+ * `serverUrl` explicitly to `serve()` / `createWorker()` should also
28
+ * export the matching env vars so memory operations resolve correctly.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * import { agent, defineTool } from "@ironflow/node/agent";
33
+ * import { z } from "zod";
34
+ *
35
+ * const fetchDiff = defineTool({
36
+ * name: "fetch-diff",
37
+ * input: z.object({ pr: z.number() }),
38
+ * handler: async ({ pr }) => api.diff(pr),
39
+ * });
40
+ *
41
+ * export const reviewAgent = agent(
42
+ * {
43
+ * id: "code-review",
44
+ * triggers: [{ event: "pr.opened" }],
45
+ * tools: [fetchDiff],
46
+ * },
47
+ * async ({ step, tool, llm, approve }) => {
48
+ * const diff = await tool(fetchDiff, { pr: event.data.prNumber });
49
+ * const findings = await llm.complete({
50
+ * messages: [{ role: "user", content: `Review:\n${diff}` }],
51
+ * call: () => myProvider.complete(...),
52
+ * });
53
+ * const decision = await approve("ship-it", { ttl: "24h", payload: findings });
54
+ * return { approved: decision.approved };
55
+ * }
56
+ * );
57
+ * ```
58
+ */
59
+ export declare function agent<TEventSchema extends z.ZodType = z.ZodType<unknown>, TResult = unknown>(config: AgentConfig<TEventSchema>, handler: AgentHandler<z.infer<TEventSchema>, TResult>): IronflowAgent<z.infer<TEventSchema>, TResult>;
60
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/agent/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAc7B,OAAO,KAAK,EACV,WAAW,EAEX,YAAY,EAEZ,aAAa,EACd,MAAM,YAAY,CAAC;AAKpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,KAAK,CAAC,YAAY,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,EAC1F,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,EACjC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,GACpD,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,CAoC/C"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * agent() — entrypoint for durable AI agents.
3
+ *
4
+ * Wraps createFunction() with an extended handler context that carries
5
+ * agent-shaped primitives (tool, llm, approve, memory, spawn). The
6
+ * returned value is a plain IronflowFunction so existing serve() and
7
+ * createWorker() register agents with zero changes.
8
+ *
9
+ * Runtime shape:
10
+ * - Per-run turn counter (drives ctx.turn + maxTurns enforcement).
11
+ * - Per-run tool registry built from AgentConfig.tools (drives by-name
12
+ * dispatch in ctx.tool(name, args) for LLM-driven tool calls).
13
+ * - Per-run byArgs idempotency cache for ctx.tool().
14
+ * - Per-run in-memory cache for memory.get() reads.
15
+ *
16
+ * All wrappers compose over ctx.step — agents inherit Ironflow's
17
+ * crash-resume, replay, and audit semantics from the existing runtime.
18
+ */
19
+ import { IronflowClient } from "../client.js";
20
+ import { createFunction } from "../function.js";
21
+ import { makeApprove } from "./approve.js";
22
+ import { DuplicateToolError } from "./errors.js";
23
+ import { createTurnCounter, makeLlm } from "./llm.js";
24
+ import { createMemoryRuntimeCache, createMemoryRuntimeCounters, makeMemory, } from "./memory.js";
25
+ import { makeSpawn } from "./spawn.js";
26
+ import { createToolRuntime, makeTool } from "./tool.js";
27
+ /** Default agent turn budget. Configurable via AgentConfig.maxTurns. */
28
+ const DEFAULT_MAX_TURNS = 20;
29
+ /**
30
+ * Define a durable agent.
31
+ *
32
+ * When `config.memory` is set, the runtime constructs an IronflowClient
33
+ * from `process.env.IRONFLOW_URL` (or `IRONFLOW_SERVER_URL`) plus
34
+ * `IRONFLOW_API_KEY` for the memory backend. Workers that pass
35
+ * `serverUrl` explicitly to `serve()` / `createWorker()` should also
36
+ * export the matching env vars so memory operations resolve correctly.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import { agent, defineTool } from "@ironflow/node/agent";
41
+ * import { z } from "zod";
42
+ *
43
+ * const fetchDiff = defineTool({
44
+ * name: "fetch-diff",
45
+ * input: z.object({ pr: z.number() }),
46
+ * handler: async ({ pr }) => api.diff(pr),
47
+ * });
48
+ *
49
+ * export const reviewAgent = agent(
50
+ * {
51
+ * id: "code-review",
52
+ * triggers: [{ event: "pr.opened" }],
53
+ * tools: [fetchDiff],
54
+ * },
55
+ * async ({ step, tool, llm, approve }) => {
56
+ * const diff = await tool(fetchDiff, { pr: event.data.prNumber });
57
+ * const findings = await llm.complete({
58
+ * messages: [{ role: "user", content: `Review:\n${diff}` }],
59
+ * call: () => myProvider.complete(...),
60
+ * });
61
+ * const decision = await approve("ship-it", { ttl: "24h", payload: findings });
62
+ * return { approved: decision.approved };
63
+ * }
64
+ * );
65
+ * ```
66
+ */
67
+ export function agent(config, handler) {
68
+ const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;
69
+ const registry = buildRegistry(config.tools);
70
+ return createFunction(config, async (ctx) => {
71
+ const counter = createTurnCounter();
72
+ const toolRuntime = createToolRuntime();
73
+ const memoryCache = createMemoryRuntimeCache();
74
+ const memoryCounters = createMemoryRuntimeCounters();
75
+ const memoryBackend = config.memory ? createDefaultMemoryBackend() : undefined;
76
+ const agentCtx = {
77
+ event: ctx.event,
78
+ step: ctx.step,
79
+ run: ctx.run,
80
+ logger: ctx.logger,
81
+ secrets: ctx.secrets,
82
+ tool: makeTool(ctx.step, registry, toolRuntime),
83
+ llm: makeLlm(ctx.step, counter, maxTurns),
84
+ approve: makeApprove(ctx.step, ctx.run.id),
85
+ memory: makeMemory(ctx.step, config.memory, ctx.run.id, memoryCache, memoryBackend, memoryCounters),
86
+ spawn: makeSpawn(ctx.step),
87
+ get turn() {
88
+ return counter.value;
89
+ },
90
+ };
91
+ return handler(agentCtx);
92
+ });
93
+ }
94
+ /**
95
+ * Construct the default MemoryBackend from environment variables.
96
+ *
97
+ * Reads IRONFLOW_URL / IRONFLOW_SERVER_URL for the server endpoint and
98
+ * IRONFLOW_API_KEY for auth. Returns undefined when no URL is set so
99
+ * makeMemory() can surface a clear "no backend" error on first use.
100
+ */
101
+ function createDefaultMemoryBackend() {
102
+ const serverUrl = process.env.IRONFLOW_URL ?? process.env.IRONFLOW_SERVER_URL;
103
+ if (!serverUrl)
104
+ return undefined;
105
+ const client = new IronflowClient({
106
+ serverUrl,
107
+ apiKey: process.env.IRONFLOW_API_KEY,
108
+ });
109
+ return {
110
+ appendEvent: (streamId, input) => client.streams.append(streamId, { name: input.name, data: input.data, entityType: input.entityType }, { idempotencyKey: input.idempotencyKey, metadata: input.metadata }),
111
+ getProjection: (name) => client.projections.get(name),
112
+ waitForCatchup: async (name, opts) => {
113
+ await client.projections.waitForCatchup(name, {
114
+ minSeq: opts.minSeq,
115
+ partition: opts.partition,
116
+ timeoutMs: opts.timeoutMs,
117
+ });
118
+ },
119
+ };
120
+ }
121
+ function buildRegistry(tools) {
122
+ const map = new Map();
123
+ if (!tools)
124
+ return map;
125
+ for (const def of tools) {
126
+ if (map.has(def.name)) {
127
+ throw new DuplicateToolError(def.name);
128
+ }
129
+ map.set(def.name, def);
130
+ }
131
+ return map;
132
+ }
133
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/agent/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * approve() — durable human-approval gate.
3
+ *
4
+ * Wraps step.waitForEvent on a deterministic event name derived from the
5
+ * agent run + approval name. The default behavior on TTL elapse is to
6
+ * resolve with approved=false, reason="timeout" — explicit rejection vs
7
+ * timeout is observable to the caller via the returned reason field.
8
+ *
9
+ * Approval events follow the convention:
10
+ * name: "agent.approve.{name}"
11
+ * filter: runId === ctx.run.id
12
+ * data shape:
13
+ * { approved: boolean, approver?: string, payload?, reason? }
14
+ */
15
+ import type { StepClient } from "@ironflow/core";
16
+ import type { ApproveFn } from "./types.js";
17
+ /**
18
+ * Build an ApproveFn bound to the given step + run.
19
+ *
20
+ * Exported for use by agent.ts; not part of the public API surface.
21
+ */
22
+ export declare function makeApprove(step: StepClient, runId: string): ApproveFn;
23
+ //# sourceMappingURL=approve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../src/agent/approve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAiC,MAAM,YAAY,CAAC;AAI3E;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CA4BtE"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * approve() — durable human-approval gate.
3
+ *
4
+ * Wraps step.waitForEvent on a deterministic event name derived from the
5
+ * agent run + approval name. The default behavior on TTL elapse is to
6
+ * resolve with approved=false, reason="timeout" — explicit rejection vs
7
+ * timeout is observable to the caller via the returned reason field.
8
+ *
9
+ * Approval events follow the convention:
10
+ * name: "agent.approve.{name}"
11
+ * filter: runId === ctx.run.id
12
+ * data shape:
13
+ * { approved: boolean, approver?: string, payload?, reason? }
14
+ */
15
+ import { escapeMatchValue, normalizeDuration } from "./internal.js";
16
+ const APPROVE_EVENT_PREFIX = "agent.approve.";
17
+ /**
18
+ * Build an ApproveFn bound to the given step + run.
19
+ *
20
+ * Exported for use by agent.ts; not part of the public API surface.
21
+ */
22
+ export function makeApprove(step, runId) {
23
+ return async function approve(name, options) {
24
+ const eventName = APPROVE_EVENT_PREFIX + name;
25
+ const event = await step.waitForEvent(`approve.${name}`, {
26
+ event: eventName,
27
+ timeout: normalizeDuration(options.ttl),
28
+ match: `data.runId == "${escapeMatchValue(runId)}"`,
29
+ });
30
+ if (event === null || event === undefined) {
31
+ return { approved: false, reason: "timeout" };
32
+ }
33
+ const data = event.data;
34
+ return {
35
+ approved: Boolean(data?.approved),
36
+ approver: data?.approver,
37
+ payload: data?.payload,
38
+ reason: data?.reason,
39
+ };
40
+ };
41
+ }
42
+ //# sourceMappingURL=approve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/agent/approve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGpE,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AAE9C;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAgB,EAAE,KAAa;IACzD,OAAO,KAAK,UAAU,OAAO,CAC3B,IAAY,EACZ,OAAiC;QAEjC,MAAM,SAAS,GAAG,oBAAoB,GAAG,IAAI,CAAC;QAE9C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CACnC,WAAW,IAAI,EAAE,EACjB;YACE,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC;YACvC,KAAK,EAAE,kBAAkB,gBAAgB,CAAC,KAAK,CAAC,GAAG;SACpD,CACF,CAAC;QAEF,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAChD,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACxB,OAAO;YACL,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;YACjC,QAAQ,EAAE,IAAI,EAAE,QAAQ;YACxB,OAAO,EAAE,IAAI,EAAE,OAAO;YACtB,MAAM,EAAE,IAAI,EAAE,MAAM;SACrB,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Inbound callback handler for Ironflow → SDK agent-tool dispatch.
3
+ *
4
+ * The Ironflow server's `agent_tools.Dispatcher` POSTs an HMAC-signed
5
+ * request to `${callbackUrl}` (the user's serve() mount). serve() routes
6
+ * `/ironflow/agent-tools/dispatch` here. We:
7
+ *
8
+ * 1. Verify HMAC + replay window (5min past, 1min future).
9
+ * 2. Look up the qualified tool in the local registry.
10
+ * 3. Validate input against the McpToolDef Zod schema.
11
+ * 4. Run the handler, mapping success → {output} and any throw →
12
+ * {error:{code:"HANDLER_ERROR", message}} (200 with envelope so the
13
+ * Go dispatcher decodes it as a tool error instead of a transport
14
+ * failure — see internal/agent_tools/dispatcher.go:182).
15
+ *
16
+ * server SDK serve()
17
+ * │ POST /…/dispatch │
18
+ * │ X-Ironflow-Timestamp: <unix> │
19
+ * │ X-Ironflow-Signature: sha256=… │
20
+ * │ body: {qualified_name, input} │
21
+ * │ ─────────────────────────────▶│
22
+ * │ │ verify HMAC
23
+ * │ │ lookupLocal()
24
+ * │ │ Zod parse(input)
25
+ * │ │ def.handler(input)
26
+ * │ │
27
+ * │ 200 {output} | 200 {error} | │
28
+ * │ 401 sig | 400 schema │
29
+ * │ ◀───────────────────────────── │
30
+ */
31
+ /** Path served on the user's serve() mount. */
32
+ export declare const DISPATCH_PATH = "/ironflow/agent-tools/dispatch";
33
+ interface DispatchEnvelope {
34
+ output?: unknown;
35
+ error?: {
36
+ code: string;
37
+ message: string;
38
+ };
39
+ }
40
+ interface DispatchResult {
41
+ status: number;
42
+ body: DispatchEnvelope;
43
+ }
44
+ interface MinimalRequest {
45
+ text(): Promise<string>;
46
+ headers: {
47
+ get(name: string): string | null;
48
+ };
49
+ }
50
+ /**
51
+ * Process an inbound dispatch request. Returns status + body envelope —
52
+ * the caller (serve()) is responsible for serializing.
53
+ */
54
+ export declare function handleAgentToolDispatch(request: MinimalRequest): Promise<DispatchResult>;
55
+ /**
56
+ * verifyHmac is exported for cross-language vector parity tests
57
+ * (testdata/hmac_vectors.json, issue #595 S8). It is NOT part of the
58
+ * public @ironflow/node/agent surface — production callers reach it
59
+ * via handleAgentToolDispatch().
60
+ */
61
+ export declare function verifyHmac(rawBody: string, ts: number, receivedHex: string, secretHex: string): boolean;
62
+ export {};
63
+ //# sourceMappingURL=dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/agent/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAYH,+CAA+C;AAC/C,eAAO,MAAM,aAAa,mCAAmC,CAAC;AAE9D,UAAU,gBAAgB;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3C;AAOD,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAED,UAAU,cAAc;IACtB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACxB,OAAO,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAC/C;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC,CAgEzB;AAMD;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAkBT"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Inbound callback handler for Ironflow → SDK agent-tool dispatch.
3
+ *
4
+ * The Ironflow server's `agent_tools.Dispatcher` POSTs an HMAC-signed
5
+ * request to `${callbackUrl}` (the user's serve() mount). serve() routes
6
+ * `/ironflow/agent-tools/dispatch` here. We:
7
+ *
8
+ * 1. Verify HMAC + replay window (5min past, 1min future).
9
+ * 2. Look up the qualified tool in the local registry.
10
+ * 3. Validate input against the McpToolDef Zod schema.
11
+ * 4. Run the handler, mapping success → {output} and any throw →
12
+ * {error:{code:"HANDLER_ERROR", message}} (200 with envelope so the
13
+ * Go dispatcher decodes it as a tool error instead of a transport
14
+ * failure — see internal/agent_tools/dispatcher.go:182).
15
+ *
16
+ * server SDK serve()
17
+ * │ POST /…/dispatch │
18
+ * │ X-Ironflow-Timestamp: <unix> │
19
+ * │ X-Ironflow-Signature: sha256=… │
20
+ * │ body: {qualified_name, input} │
21
+ * │ ─────────────────────────────▶│
22
+ * │ │ verify HMAC
23
+ * │ │ lookupLocal()
24
+ * │ │ Zod parse(input)
25
+ * │ │ def.handler(input)
26
+ * │ │
27
+ * │ 200 {output} | 200 {error} | │
28
+ * │ 401 sig | 400 schema │
29
+ * │ ◀───────────────────────────── │
30
+ */
31
+ import { createHmac, timingSafeEqual } from "node:crypto";
32
+ import { lookupLocal } from "./internal-registry.js";
33
+ const HEADER_SIGNATURE = "x-ironflow-signature";
34
+ const HEADER_TIMESTAMP = "x-ironflow-timestamp";
35
+ const SIGNATURE_PREFIX = "sha256=";
36
+ const REPLAY_WINDOW_SEC = 5 * 60;
37
+ const FUTURE_SKEW_SEC = 60;
38
+ /** Path served on the user's serve() mount. */
39
+ export const DISPATCH_PATH = "/ironflow/agent-tools/dispatch";
40
+ /**
41
+ * Process an inbound dispatch request. Returns status + body envelope —
42
+ * the caller (serve()) is responsible for serializing.
43
+ */
44
+ export async function handleAgentToolDispatch(request) {
45
+ const rawBody = await request.text();
46
+ const sigHeader = request.headers.get(HEADER_SIGNATURE);
47
+ const tsHeader = request.headers.get(HEADER_TIMESTAMP);
48
+ if (!sigHeader || !tsHeader) {
49
+ return errorResponse(401, "SIGNATURE_MISMATCH", "missing HMAC headers");
50
+ }
51
+ if (!sigHeader.startsWith(SIGNATURE_PREFIX)) {
52
+ return errorResponse(401, "SIGNATURE_MISMATCH", "invalid signature format");
53
+ }
54
+ const ts = Number.parseInt(tsHeader, 10);
55
+ if (!Number.isFinite(ts)) {
56
+ return errorResponse(401, "TIMESTAMP_SKEW", "invalid timestamp");
57
+ }
58
+ const now = Math.floor(Date.now() / 1000);
59
+ if (now - ts > REPLAY_WINDOW_SEC) {
60
+ return errorResponse(401, "TIMESTAMP_SKEW", "request timestamp too old");
61
+ }
62
+ if (ts - now > FUTURE_SKEW_SEC) {
63
+ return errorResponse(401, "TIMESTAMP_SKEW", "request timestamp too far in future");
64
+ }
65
+ let payload;
66
+ try {
67
+ payload = JSON.parse(rawBody);
68
+ }
69
+ catch {
70
+ return errorResponse(400, "INVALID_REQUEST", "callback body is not valid JSON");
71
+ }
72
+ const qualifiedName = typeof payload.qualified_name === "string" ? payload.qualified_name : "";
73
+ if (!qualifiedName) {
74
+ return errorResponse(400, "INVALID_REQUEST", "qualified_name missing");
75
+ }
76
+ const entry = lookupLocal(qualifiedName);
77
+ if (!entry) {
78
+ console.warn(`ironflow.agent.dispatch unknown_tool qualified_name=${JSON.stringify(qualifiedName)}`);
79
+ return errorResponse(401, "SIGNATURE_MISMATCH", "HMAC mismatch");
80
+ }
81
+ if (!verifyHmac(rawBody, ts, sigHeader.slice(SIGNATURE_PREFIX.length), entry.hmacSecret)) {
82
+ return errorResponse(401, "SIGNATURE_MISMATCH", "HMAC mismatch");
83
+ }
84
+ const parseResult = entry.def.input.safeParse(payload.input);
85
+ if (!parseResult.success) {
86
+ const issues = parseResult.error.issues
87
+ .map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`)
88
+ .join("; ");
89
+ return errorResponse(400, "INPUT_SCHEMA_INVALID", issues);
90
+ }
91
+ try {
92
+ const output = await entry.def.handler(parseResult.data);
93
+ return { status: 200, body: { output } };
94
+ }
95
+ catch (err) {
96
+ const message = err instanceof Error ? err.message : String(err);
97
+ return { status: 200, body: { error: { code: "HANDLER_ERROR", message } } };
98
+ }
99
+ }
100
+ function errorResponse(status, code, message) {
101
+ return { status, body: { error: { code, message } } };
102
+ }
103
+ /**
104
+ * verifyHmac is exported for cross-language vector parity tests
105
+ * (testdata/hmac_vectors.json, issue #595 S8). It is NOT part of the
106
+ * public @ironflow/node/agent surface — production callers reach it
107
+ * via handleAgentToolDispatch().
108
+ */
109
+ export function verifyHmac(rawBody, ts, receivedHex, secretHex) {
110
+ // Buffer.from(..., "hex") silently truncates at the first non-hex char
111
+ // instead of throwing. Validate explicitly so a malformed secret/sig
112
+ // can't quietly produce a partial buffer that passes timingSafeEqual.
113
+ if (!isHex(secretHex) || !isHex(receivedHex)) {
114
+ return false;
115
+ }
116
+ const secretBuf = Buffer.from(secretHex, "hex");
117
+ const expectedHex = createHmac("sha256", secretBuf)
118
+ .update(`${ts}.${rawBody}`)
119
+ .digest("hex");
120
+ const receivedBuf = Buffer.from(receivedHex, "hex");
121
+ const expectedBuf = Buffer.from(expectedHex, "hex");
122
+ if (receivedBuf.length !== expectedBuf.length || receivedBuf.length === 0) {
123
+ return false;
124
+ }
125
+ return timingSafeEqual(receivedBuf, expectedBuf);
126
+ }
127
+ function isHex(s) {
128
+ return s.length > 0 && s.length % 2 === 0 && /^[0-9a-fA-F]+$/.test(s);
129
+ }
130
+ //# sourceMappingURL=dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/agent/dispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Agent module error classes.
3
+ *
4
+ * All extend IronflowError. Codes are stable for programmatic handling.
5
+ */
6
+ import { IronflowError } from "@ironflow/core";
7
+ /**
8
+ * Thrown when an agent exceeds its configured turn budget.
9
+ *
10
+ * Default budget is 20 turns. Configurable via AgentConfig.maxTurns.
11
+ */
12
+ export declare class MaxTurnsExceededError extends IronflowError {
13
+ constructor(maxTurns: number, options?: {
14
+ cause?: Error;
15
+ });
16
+ }
17
+ /**
18
+ * Base class for classified LLM errors emitted by llm().
19
+ */
20
+ export declare class LLMError extends IronflowError {
21
+ constructor(message: string, options: {
22
+ code: string;
23
+ retryable?: boolean;
24
+ details?: Record<string, unknown>;
25
+ cause?: Error;
26
+ });
27
+ }
28
+ /**
29
+ * Provider refused the request (safety, policy, etc.).
30
+ */
31
+ export declare class LLMRefusalError extends LLMError {
32
+ constructor(message: string, options?: {
33
+ details?: Record<string, unknown>;
34
+ cause?: Error;
35
+ });
36
+ }
37
+ /**
38
+ * Provider returned content that failed JSON parsing when JSON was required.
39
+ */
40
+ export declare class LLMInvalidJSONError extends LLMError {
41
+ constructor(message: string, options?: {
42
+ details?: Record<string, unknown>;
43
+ cause?: Error;
44
+ });
45
+ }
46
+ /**
47
+ * Provider truncated the response by hitting max_tokens.
48
+ */
49
+ export declare class LLMMaxTokensError extends LLMError {
50
+ constructor(message: string, options?: {
51
+ details?: Record<string, unknown>;
52
+ cause?: Error;
53
+ });
54
+ }
55
+ /**
56
+ * Thrown when tool() input fails Zod validation.
57
+ *
58
+ * Distinct from generic ValidationError so callers can differentiate
59
+ * agent-tool input failures from event-payload schema failures.
60
+ */
61
+ export declare class ToolValidationError extends IronflowError {
62
+ constructor(toolName: string, issues: unknown, options?: {
63
+ cause?: Error;
64
+ });
65
+ }
66
+ /**
67
+ * Thrown when AgentConfig.tools contains two or more definitions sharing
68
+ * the same name. Silent overwrite would let LLM-driven dispatch route to
69
+ * an unintended handler — so we fail loudly at agent construction.
70
+ */
71
+ export declare class DuplicateToolError extends IronflowError {
72
+ constructor(toolName: string);
73
+ }
74
+ /**
75
+ * Thrown when ctx.tool(name, args) is called with a name that isn't
76
+ * registered on AgentConfig.tools.
77
+ */
78
+ export declare class ToolNotFoundError extends IronflowError {
79
+ constructor(toolName: string);
80
+ }
81
+ /**
82
+ * Thrown when memory.entityStream() is called without a projection.
83
+ *
84
+ * Per architecture decision: raw event replay is not exposed through
85
+ * the agent memory API. Consumers must define a projection.
86
+ */
87
+ export declare class MemoryProjectionRequiredError extends IronflowError {
88
+ constructor(streamId: string);
89
+ }
90
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/agent/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;gBAC1C,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAS1D;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,aAAa;gBAEvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClC,KAAK,CAAC,EAAE,KAAK,CAAC;KACf;CAKJ;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAS5F;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;gBACnC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAS5F;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAS5F;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,aAAa;gBAElD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAU9B;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,aAAa;gBACvC,QAAQ,EAAE,MAAM;CAQ7B;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,QAAQ,EAAE,MAAM;CAW7B;AAED;;;;;GAKG;AACH,qBAAa,6BAA8B,SAAQ,aAAa;gBAClD,QAAQ,EAAE,MAAM;CAW7B"}