agents 0.22.0 → 0.23.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.
- package/README.md +20 -1
- package/dist/{agent-routing-CnkaHb-v.d.ts → agent-routing-DE5zmCQ8.d.ts} +1038 -394
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +26 -26
- package/dist/{agent-tools-C0XJqWzB.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
- package/dist/agent-tools.d.ts +21 -21
- package/dist/browser/ai.js +4 -1
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
- package/dist/callable-decorator.d.ts +18 -0
- package/dist/callable-decorator.js +71 -0
- package/dist/callable-decorator.js.map +1 -0
- package/dist/capability-BjSKYpzg.js.map +1 -1
- package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
- package/dist/channel-Bnm4S7T2.d.ts +491 -0
- package/dist/channels/ai-sdk.d.ts +46 -0
- package/dist/channels/ai-sdk.js +120 -0
- package/dist/channels/ai-sdk.js.map +1 -0
- package/dist/channels/email.d.ts +95 -0
- package/dist/channels/email.js +323 -0
- package/dist/channels/email.js.map +1 -0
- package/dist/channels/index.d.ts +233 -0
- package/dist/channels/index.js +608 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/slack.d.ts +140 -0
- package/dist/channels/slack.js +614 -0
- package/dist/channels/slack.js.map +1 -0
- package/dist/channels/tanstack-ai.d.ts +39 -0
- package/dist/channels/tanstack-ai.js +17 -0
- package/dist/channels/tanstack-ai.js.map +1 -0
- package/dist/channels/telegram.d.ts +106 -0
- package/dist/channels/telegram.js +427 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/voice.d.ts +45 -0
- package/dist/channels/voice.js +122 -0
- package/dist/channels/voice.js.map +1 -0
- package/dist/chat/index.d.ts +2325 -2019
- package/dist/chat/index.js +888 -518
- package/dist/chat/index.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +7 -7
- package/dist/chat-sdk/index.js +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/context/index.d.ts +216 -0
- package/dist/context/index.js +454 -0
- package/dist/context/index.js.map +1 -0
- package/dist/{current-agent-CuMErtly.d.ts → current-agent-Da_C9a3b.d.ts} +90 -107
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/{diagnostics-CaBjfz4J.js → diagnostics-BzvaX2UT.js} +5 -1
- package/dist/diagnostics-BzvaX2UT.js.map +1 -0
- package/dist/diagnostics-C4jcz3VK.js +360 -0
- package/dist/diagnostics-C4jcz3VK.js.map +1 -0
- package/dist/index-BB0kqhIz.d.ts +101 -0
- package/dist/index-BVVgDSdq.d.ts +1 -0
- package/dist/index-XDkuQ7zm.d.ts +89 -0
- package/dist/{index-DcSAZKsB.d.ts → index-YSKgfgg9.d.ts} +3 -1
- package/dist/index.d.ts +91 -82
- package/dist/index.js +3 -2
- package/dist/ingress-BfetZbMO.js +83 -0
- package/dist/ingress-BfetZbMO.js.map +1 -0
- package/dist/internal-CYlgHl1l.js +59 -0
- package/dist/internal-CYlgHl1l.js.map +1 -0
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +35 -17
- package/dist/lifecycle/index.js +1 -1
- package/dist/lifecycle-CMRGjZdw.js +1299 -0
- package/dist/lifecycle-CMRGjZdw.js.map +1 -0
- package/dist/mcp/client/index.d.ts +20 -20
- package/dist/mcp/index.d.ts +35 -35
- package/dist/mcp/index.js +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js +1 -1
- package/dist/react.d.ts +4 -4
- package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
- package/dist/retries.d.ts +8 -6
- package/dist/retries.js +13 -1
- package/dist/retries.js.map +1 -1
- package/dist/routing/index.d.ts +137 -0
- package/dist/routing/index.js +244 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/sanitize-D9TujEK8.js +79 -0
- package/dist/sanitize-D9TujEK8.js.map +1 -0
- package/dist/scheduler-DD9NdYbF.js +665 -0
- package/dist/scheduler-DD9NdYbF.js.map +1 -0
- package/dist/{scheduler-DQoTGoAW.d.ts → scheduler-Dwh85ZGl.d.ts} +21 -22
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
- package/dist/serializable.d.ts +1 -1
- package/dist/sessions/index.d.ts +441 -0
- package/dist/sessions/index.js +2063 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/skills/index.d.ts +99 -0
- package/dist/skills/index.js +254 -5
- package/dist/skills/index.js.map +1 -1
- package/dist/{src-5W6JNKVb.js → src-DlSHshb2.js} +1460 -1110
- package/dist/src-DlSHshb2.js.map +1 -0
- package/dist/streams/index.d.ts +120 -0
- package/dist/streams/index.js +107 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams-D6tJ0NN9.d.ts +370 -0
- package/dist/streams-DZKgAj9b.js +709 -0
- package/dist/streams-DZKgAj9b.js.map +1 -0
- package/dist/sub-routing.d.ts +12 -12
- package/dist/surface-bZZJqBka.js +17 -0
- package/dist/surface-bZZJqBka.js.map +1 -0
- package/dist/tasks/index.d.ts +64 -0
- package/dist/tasks/index.js +2 -0
- package/dist/tasks-BRJ5zgya.d.ts +517 -0
- package/dist/tasks-ylZgBjhj.js +1656 -0
- package/dist/tasks-ylZgBjhj.js.map +1 -0
- package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
- package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
- package/dist/text-stream-CpdiKrJB.js +272 -0
- package/dist/text-stream-CpdiKrJB.js.map +1 -0
- package/dist/tokens-nHAKcN6M.js +52 -0
- package/dist/tokens-nHAKcN6M.js.map +1 -0
- package/dist/tool-schema-CBjGPrsQ.js +31 -0
- package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
- package/dist/types-B7LojTe4.d.ts +202 -0
- package/dist/types-_Faxb570.d.ts +439 -0
- package/dist/voice/client.d.ts +226 -0
- package/dist/voice/client.js +932 -0
- package/dist/voice/client.js.map +1 -0
- package/dist/voice/errors.d.ts +43 -0
- package/dist/voice/errors.js +41 -0
- package/dist/voice/errors.js.map +1 -0
- package/dist/voice/index.d.ts +271 -0
- package/dist/voice/index.js +1812 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/react.d.ts +167 -0
- package/dist/voice/react.js +234 -0
- package/dist/voice/react.js.map +1 -0
- package/dist/voice/sfu.d.ts +71 -0
- package/dist/voice/sfu.js +157 -0
- package/dist/voice/sfu.js.map +1 -0
- package/dist/voice/text.d.ts +6 -0
- package/dist/voice/text.js +2 -0
- package/dist/voice/types.d.ts +58 -0
- package/dist/voice/types.js +18 -0
- package/dist/voice/types.js.map +1 -0
- package/dist/voice/workers-ai.d.ts +136 -0
- package/dist/voice/workers-ai.js +568 -0
- package/dist/voice/workers-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +192 -0
- package/dist/websockets/index.js +2 -0
- package/dist/websockets-DUfRHPRq.js +502 -0
- package/dist/websockets-DUfRHPRq.js.map +1 -0
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflows.d.ts +21 -21
- package/dist/workflows.js +1 -1
- package/docs/agent-class.md +2 -2
- package/docs/agent-tools.md +2 -1
- package/docs/channels.md +323 -0
- package/docs/chat-agents.md +6 -13
- package/docs/context.md +131 -0
- package/docs/index.md +15 -12
- package/docs/lifecycle.md +102 -55
- package/docs/long-running-agents.md +2 -2
- package/docs/mcp-servers.md +5 -1
- package/docs/resumable-streaming.md +1 -1
- package/docs/routing.md +105 -0
- package/docs/sessions.md +237 -871
- package/docs/streams.md +213 -0
- package/docs/sub-agents.md +184 -124
- package/docs/tasks.md +246 -0
- package/docs/voice.md +745 -0
- package/package.json +115 -13
- package/dist/capability-runner-CvHGZqUu.d.ts +0 -150
- package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
- package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
- package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
- package/dist/diagnostics-CaBjfz4J.js.map +0 -1
- package/dist/durable-object-lifecycle-D6nNQJJd.js +0 -862
- package/dist/durable-object-lifecycle-D6nNQJJd.js.map +0 -1
- package/dist/experimental/memory/session/index.d.ts +0 -671
- package/dist/experimental/memory/session/index.js +0 -2379
- package/dist/experimental/memory/session/index.js.map +0 -1
- package/dist/experimental/memory/utils/index.d.ts +0 -96
- package/dist/experimental/memory/utils/index.js +0 -79
- package/dist/experimental/memory/utils/index.js.map +0 -1
- package/dist/scheduler-CR9RHGos.js +0 -857
- package/dist/scheduler-CR9RHGos.js.map +0 -1
- package/dist/src-5W6JNKVb.js.map +0 -1
- package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
- package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks-ylZgBjhj.js","names":[],"sources":["../src/tasks/errors.ts","../src/tasks/serialization.ts","../src/tasks/store.ts","../src/tasks/duration.ts","../src/tasks/replay.ts","../src/tasks/engine-port.ts","../src/tasks/tasks.ts"],"sourcesContent":["/**\n * Error classes for the Tasks capability. Each carries a stable `name` so\n * hosts and tests can classify failures without depending on message text.\n */\n\n/**\n * Thrown by a step callback to fail its run immediately, skipping any\n * remaining retry attempts.\n *\n * Errors named `\"NonRetryableError\"` from other sources (for example\n * `cloudflare:workflows`) are honored the same way.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class NonRetryableError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"NonRetryableError\";\n }\n}\n\n/** True when an error should skip remaining step retry attempts. */\nexport function isNonRetryableError(error: unknown): boolean {\n return (\n error instanceof NonRetryableError ||\n (error instanceof Error && error.name === \"NonRetryableError\")\n );\n}\n\n/**\n * Thrown before executing user code when one replay uses the same step name\n * twice. Step names are durable journal keys and must be unique within a run.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class DuplicateTaskStepError extends Error {\n /** The step name used more than once. */\n readonly stepName: string;\n\n constructor(stepName: string) {\n super(\n `Step name \"${stepName}\" was already used in this run. Step names are ` +\n `durable journal keys; suffix loop steps with a stable index, e.g. ` +\n `\"${stepName}:0\".`\n );\n this.name = \"DuplicateTaskStepError\";\n this.stepName = stepName;\n }\n}\n\n/**\n * Thrown when a replay observes a journal that this handler code cannot have\n * written — a known step under a different kind, for example. The run fails\n * rather than guessing; changing a definition's step layout for in-flight\n * runs requires versioning the definition name.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class TaskReplayDivergedError extends Error {\n /** The step name where replay diverged from the journal. */\n readonly stepName: string;\n\n constructor(stepName: string, detail: string) {\n super(\n `Replay diverged from the journal at step \"${stepName}\": ${detail}. ` +\n `Version the definition name (e.g. \"name@v2\") instead of changing ` +\n `the step layout of in-flight runs.`\n );\n this.name = \"TaskReplayDivergedError\";\n this.stepName = stepName;\n }\n}\n\n/**\n * Recorded against a run whose persisted definition name is no longer\n * registered after a deployment. The run fails visibly; it is never silently\n * deleted and never replayed against a different handler.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class MissingTaskDefinitionError extends Error {\n /** The persisted definition name that no longer resolves. */\n readonly definition: string;\n\n constructor(definition: string) {\n super(\n `No Task definition named \"${definition}\" is registered. A deployment ` +\n `removed or renamed it while this run was active. Re-register the ` +\n `definition (or a versioned successor with the same name) to let the ` +\n `run finish.`\n );\n this.name = \"MissingTaskDefinitionError\";\n this.definition = definition;\n }\n}\n\n/**\n * Thrown when a Task input, step result, metadata value, or final result is\n * not JSON-serializable or exceeds the serialized size limit.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class TaskSerializationError extends Error {\n constructor(context: string, detail: string) {\n super(`Cannot serialize ${context}: ${detail}`);\n this.name = \"TaskSerializationError\";\n }\n}\n","/**\n * Value serialization for the Tasks capability.\n *\n * Task inputs, step results, metadata, and final results persist as JSON\n * text in SQLite. `undefined` (and a `void` handler result) is represented\n * as SQL `NULL` rather than a JSON envelope, so the JSON column space stays\n * plain: `\"null\"` is JSON `null`, column `NULL` is `undefined`.\n */\n\nimport { TaskSerializationError } from \"./errors\";\n\n/** Default ceiling for one serialized value (1 MiB). */\nexport const MAX_SERIALIZED_BYTES = 1_048_576;\n\nconst utf8 = new TextEncoder();\n\n/**\n * Serialize one Task value for storage.\n *\n * @param value - The value to persist.\n * @param context - What is being serialized, for error messages\n * (e.g. `input for definition \"report\"`, `result of step \"fetch\"`).\n * @returns JSON text, or `null` when the value is `undefined`.\n * @throws TaskSerializationError when the value is not JSON-serializable or\n * its serialized form exceeds {@link MAX_SERIALIZED_BYTES}.\n */\nexport function serializeTaskValue(\n value: unknown,\n context: string\n): string | null {\n if (value === undefined) return null;\n\n let json: string | undefined;\n try {\n json = JSON.stringify(value);\n } catch (error) {\n throw new TaskSerializationError(\n context,\n error instanceof Error ? error.message : String(error)\n );\n }\n if (json === undefined) {\n throw new TaskSerializationError(\n context,\n `value of type ${typeof value} has no JSON representation`\n );\n }\n\n const bytes = utf8.encode(json).byteLength;\n if (bytes > MAX_SERIALIZED_BYTES) {\n throw new TaskSerializationError(\n context,\n `serialized size ${bytes} bytes exceeds the ${MAX_SERIALIZED_BYTES}-byte limit`\n );\n }\n return json;\n}\n\n/**\n * Restore a value serialized by {@link serializeTaskValue}.\n *\n * @param stored - The stored column value.\n * @returns The original value; column `NULL` restores `undefined`.\n */\nexport function deserializeTaskValue(stored: string | null): unknown {\n if (stored === null) return undefined;\n return JSON.parse(stored);\n}\n","/**\n * Storage layer for the Tasks capability: owns the `cf_agents_task_runs` and\n * `cf_agents_task_steps` tables — DDL, row access, generation-fenced writes,\n * and the snapshot projection. The engine in `tasks.ts` holds the state\n * machine; every byte that touches SQLite goes through here.\n */\n\nimport { SqlError } from \"../sql-error\";\nimport { deserializeTaskValue } from \"./serialization\";\nimport type { TaskJson, TaskRunRow, TaskRunSnapshot, TaskValue } from \"./types\";\n\n/** @internal SQL-backed store for one Tasks capability instance. */\nexport class TaskStore {\n readonly #storage: DurableObjectStorage;\n\n constructor(storage: DurableObjectStorage) {\n this.#storage = storage;\n }\n\n sql<T = Record<string, string | number | boolean | null>>(\n strings: TemplateStringsArray,\n ...values: (string | number | boolean | null)[]\n ): T[] {\n const query = strings.reduce(\n (result, part, index) =>\n result + part + (index < values.length ? \"?\" : \"\"),\n \"\"\n );\n try {\n // SAFETY: Tasks queries select from its own schema; T describes the\n // projected columns of the accompanying query text.\n return [...this.#storage.sql.exec(query, ...values)] as T[];\n } catch (cause) {\n throw new SqlError(query, cause);\n }\n }\n\n write(query: string, params: (string | number | null)[]): number {\n try {\n return this.#storage.sql.exec(query, ...params).rowsWritten;\n } catch (cause) {\n throw new SqlError(query, cause);\n }\n }\n\n /**\n * Run one generation-fenced run mutation. Returns false when the fence\n * rejected it because another attempt superseded this one.\n */\n fencedWrite(\n runId: string,\n generation: string,\n query: string,\n leadingParams: (string | number | null)[]\n ): boolean {\n try {\n const cursor = this.#storage.sql.exec(\n query,\n ...leadingParams,\n runId,\n generation\n );\n return cursor.rowsWritten > 0;\n } catch (cause) {\n throw new SqlError(query, cause);\n }\n }\n\n getRun(runId: string): TaskRunRow | undefined {\n const rows = this.sql<TaskRunRow>`\n SELECT * FROM cf_agents_task_runs WHERE run_id = ${runId}\n `;\n return rows[0];\n }\n\n getRunByKey(idempotencyKey: string): TaskRunRow | undefined {\n const rows = this.sql<TaskRunRow>`\n SELECT * FROM cf_agents_task_runs WHERE idempotency_key = ${idempotencyKey}\n `;\n return rows[0];\n }\n\n deleteRun(runId: string): void {\n this.sql`DELETE FROM cf_agents_task_steps WHERE run_id = ${runId}`;\n this.sql`DELETE FROM cf_agents_task_runs WHERE run_id = ${runId}`;\n }\n\n ensureTables(): void {\n const rawSql = (query: string) => {\n try {\n this.#storage.sql.exec(query);\n } catch (cause) {\n throw new SqlError(query, cause);\n }\n };\n rawSql(`\n CREATE TABLE IF NOT EXISTS cf_agents_task_runs (\n run_id TEXT PRIMARY KEY,\n definition TEXT NOT NULL,\n input TEXT,\n state TEXT NOT NULL CHECK (state IN (\n 'pending', 'running', 'waiting',\n 'completed', 'failed', 'cancelled'\n )),\n result TEXT,\n error_name TEXT,\n error_message TEXT,\n status_message TEXT,\n metadata TEXT,\n idempotency_key TEXT UNIQUE,\n retain INTEGER NOT NULL DEFAULT 1,\n attempt INTEGER NOT NULL DEFAULT 0,\n generation TEXT,\n next_at INTEGER,\n wait_reason TEXT,\n cancel_requested INTEGER NOT NULL DEFAULT 0,\n cancel_reason TEXT,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n updated_at INTEGER NOT NULL,\n settled_at INTEGER\n ) WITHOUT ROWID`);\n // No (state, next_at) index: every claim, refresh, and settle rewrites\n // next_at, and Cloudflare bills each touched index as a row written —\n // a per-write tax on the hottest run mutations, paid to accelerate the\n // startup reconcile's one scan of a retention-bounded table. The\n // definition index stays: list-by-definition reads scale with retained\n // runs, and definition/created_at never change after insert.\n rawSql(`\n CREATE INDEX IF NOT EXISTS cf_agents_task_runs_definition\n ON cf_agents_task_runs (definition, created_at)\n `);\n rawSql(`\n CREATE TABLE IF NOT EXISTS cf_agents_task_steps (\n run_id TEXT NOT NULL,\n step_name TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('do', 'sleep')),\n state TEXT NOT NULL CHECK (state IN (\n 'running', 'waiting', 'completed', 'failed'\n )),\n result TEXT,\n error_name TEXT,\n error_message TEXT,\n attempt INTEGER NOT NULL DEFAULT 0,\n next_at INTEGER,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n updated_at INTEGER NOT NULL,\n completed_at INTEGER,\n PRIMARY KEY (run_id, step_name)\n ) WITHOUT ROWID`);\n }\n\n rowToSnapshot<Output extends TaskValue>(\n row: TaskRunRow\n ): TaskRunSnapshot<Output> {\n const metadata =\n row.metadata !== null\n ? (JSON.parse(row.metadata) as Record<string, TaskJson>)\n : undefined;\n const base = {\n runId: row.run_id,\n definition: row.definition,\n createdAt: row.created_at,\n ...(metadata !== undefined ? { metadata } : {})\n };\n switch (row.state) {\n case \"pending\":\n return { ...base, state: \"pending\" };\n case \"running\":\n return {\n ...base,\n state: \"running\",\n attempt: row.attempt,\n startedAt: row.started_at ?? row.created_at,\n ...(row.status_message !== null\n ? { statusMessage: row.status_message }\n : {})\n };\n case \"waiting\":\n return {\n ...base,\n state: \"waiting\",\n reason: row.wait_reason ?? \"sleep\",\n wakeAt: row.next_at ?? row.updated_at,\n ...(row.status_message !== null\n ? { statusMessage: row.status_message }\n : {})\n };\n case \"completed\":\n return {\n ...base,\n state: \"completed\",\n result: deserializeTaskValue(row.result) as Output,\n settledAt: row.settled_at ?? row.updated_at\n };\n case \"failed\":\n return {\n ...base,\n state: \"failed\",\n error: {\n name: row.error_name ?? \"Error\",\n message: row.error_message ?? \"Task run failed\"\n },\n settledAt: row.settled_at ?? row.updated_at\n };\n case \"cancelled\":\n return {\n ...base,\n state: \"cancelled\",\n ...(row.cancel_reason !== null ? { reason: row.cancel_reason } : {}),\n settledAt: row.settled_at ?? row.updated_at\n };\n }\n }\n}\n","/**\n * Duration parsing for the Tasks capability. Durations appear in step\n * retry delays, per-attempt timeouts, and durable sleeps.\n */\n\n/** Units accepted in a {@link TaskDurationString}. */\nexport type TaskDurationUnit = \"second\" | \"minute\" | \"hour\" | \"day\" | \"week\";\n\n/**\n * A human-readable duration such as `\"10 seconds\"` or `\"1 day\"`.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport type TaskDurationString = `${number} ${TaskDurationUnit}${\"\" | \"s\"}`;\n\nconst UNIT_MILLISECONDS: Record<TaskDurationUnit, number> = {\n second: 1000,\n minute: 60 * 1000,\n hour: 60 * 60 * 1000,\n day: 24 * 60 * 60 * 1000,\n week: 7 * 24 * 60 * 60 * 1000\n};\n\nconst DURATION_PATTERN = /^(\\d+(?:\\.\\d+)?)\\s+(second|minute|hour|day|week)s?$/;\n\n/**\n * Parse a duration into whole milliseconds.\n *\n * @param duration - Milliseconds, or a duration string such as `\"10 seconds\"`.\n * @param context - Name of the option being parsed, used in error messages.\n * @returns The duration in milliseconds, floored to an integer.\n * @throws Error when the duration is negative, not finite, or unparseable.\n */\nexport function parseTaskDuration(\n duration: number | TaskDurationString,\n context: string\n): number {\n if (typeof duration === \"number\") {\n if (!Number.isFinite(duration) || duration < 0) {\n throw new Error(\n `Invalid ${context}: expected a non-negative number of milliseconds, got ${duration}`\n );\n }\n return Math.floor(duration);\n }\n const match = DURATION_PATTERN.exec(duration.trim());\n if (!match) {\n throw new Error(\n `Invalid ${context}: expected milliseconds or a duration like \"10 seconds\", got ${JSON.stringify(duration)}`\n );\n }\n const amount = Number(match[1]);\n const unit = match[2] as TaskDurationUnit;\n return Math.floor(amount * UNIT_MILLISECONDS[unit]);\n}\n","/**\n * Replay step engine for the Tasks capability.\n *\n * `ReplayStep` implements the `TaskStep` surface one handler attempt\n * receives. It owns replay semantics — journal hits, journal misses, retry\n * policy, durable sleeps, the status live gate, and duplicate/divergence\n * detection — while all SQL stays behind the narrow {@link TaskStepEngine}\n * port implemented by the `Tasks` capability, the single owner of the\n * schema.\n */\n\nimport {\n isDurableObjectCodeUpdateReset,\n isDurableObjectMemoryLimitReset,\n isPlatformFailure\n} from \"../retries\";\nimport { parseTaskDuration, type TaskDurationString } from \"./duration\";\nimport {\n DuplicateTaskStepError,\n TaskReplayDivergedError,\n TaskSerializationError,\n isNonRetryableError\n} from \"./errors\";\nimport { deserializeTaskValue } from \"./serialization\";\nimport type {\n TaskStep,\n TaskStepAttempt,\n TaskStepConfig,\n TaskStepRow,\n TaskValue,\n TaskWaitReason\n} from \"./types\";\n\n/** Resolved per-step retry and timeout policy. */\nexport type ResolvedStepPolicy = {\n readonly retryLimit: number;\n readonly retryDelayMs: number;\n readonly backoff: \"constant\" | \"linear\" | \"exponential\";\n readonly timeoutMs: number;\n};\n\n/** Longest computed retry delay: backoff growth never exceeds one day. */\nconst MAX_RETRY_DELAY_MS = 24 * 60 * 60 * 1000;\n\n/** Steps per run ceiling; crossing it fails the run instead of degrading. */\nexport const MAX_STEPS_PER_RUN = 10_000;\n\n/** Longest accepted step name. Step names are durable journal keys. */\nexport const MAX_STEP_NAME_LENGTH = 256;\n\n/**\n * Thrown by the engine to end one execution attempt while its run waits for\n * a durable deadline (sleep or retry). Not an `Error` subclass so a step\n * callback's `catch (error)` around unrelated work is less likely to swallow\n * it; the capability re-checks with {@link isTaskSuspension}.\n */\nexport class TaskSuspension {\n readonly wakeAt: number;\n readonly reason: TaskWaitReason;\n\n constructor(wakeAt: number, reason: TaskWaitReason) {\n this.wakeAt = wakeAt;\n this.reason = reason;\n }\n}\n\n/** True when a thrown value is the engine's suspension signal. */\nexport function isTaskSuspension(value: unknown): value is TaskSuspension {\n return value instanceof TaskSuspension;\n}\n\n/**\n * Thrown by the engine when a step boundary observes the run's cancellation\n * request. The capability settles the run as cancelled.\n */\nexport class TaskCancellation {\n readonly reason: string | undefined;\n\n constructor(reason: string | undefined) {\n this.reason = reason;\n }\n}\n\n/** True when a thrown value is the engine's cancellation signal. */\nexport function isTaskCancellation(value: unknown): value is TaskCancellation {\n return value instanceof TaskCancellation;\n}\n\n/**\n * Thrown by engine writes when another execution attempt has superseded this\n * one. The stale attempt unwinds without settling anything; every durable\n * write it might still try is generation-fenced.\n */\nexport class AttemptSupersededError extends Error {\n constructor(runId: string) {\n super(\n `Task attempt superseded: run \"${runId}\" is no longer claimed by this ` +\n `execution attempt`\n );\n this.name = \"AttemptSupersededError\";\n }\n}\n\n/**\n * Storage and policy port the `Tasks` capability supplies to one attempt's\n * `ReplayStep`. Every mutation is fenced by the attempt's generation on the\n * capability side.\n */\nexport interface TaskStepEngine {\n /** Read one step row of this run, or undefined for a journal miss. */\n readStep(name: string): TaskStepRow | undefined;\n\n /** Number of step rows this run has journaled. */\n countSteps(): number;\n\n /** Insert a new step row claimed at attempt 1. */\n insertStep(name: string, kind: \"do\" | \"sleep\", wakeAt: number | null): void;\n\n /** Journal an already-elapsed sleep born-completed, in one row write. */\n insertCompletedSleep(name: string): void;\n\n /** Claim the next attempt of an existing step. Returns the new attempt. */\n claimStepAttempt(name: string): number;\n\n /** Persist a completed step. Serializes and validates the result. */\n completeStep(name: string, result: unknown): void;\n\n /** Persist a terminally failed step. */\n failStep(name: string, error: { name: string; message: string }): void;\n\n /** Move a step into its retry wait. */\n waitStep(name: string, wakeAt: number): void;\n\n /** Extend the run's claim deadline while a step attempt executes. */\n refreshClaim(): void;\n\n /** Persist the run's observable status message. */\n writeStatus(message: string): void;\n\n /** The cancellation reason when this run was asked to cancel, else null. */\n cancellationRequested(): { reason: string | undefined } | null;\n\n /** Abort signal for the whole attempt (cancellation or supersession). */\n readonly attemptSignal: AbortSignal;\n\n /** Emit one capability event. */\n emit(type: string, payload: Record<string, unknown>): void;\n\n /** Stable external deduplication key for one named step. */\n stepIdempotencyKey(name: string): string;\n\n /** Default policy applied where a step config leaves fields unset. */\n readonly defaults: ResolvedStepPolicy;\n}\n\n/** Compute the delay before the next attempt after `failedAttempt` failed. */\nexport function computeRetryDelayMs(\n policy: ResolvedStepPolicy,\n failedAttempt: number\n): number {\n const base = policy.retryDelayMs;\n let delay: number;\n switch (policy.backoff) {\n case \"constant\":\n delay = base;\n break;\n case \"linear\":\n delay = base * failedAttempt;\n break;\n case \"exponential\":\n delay = base * 2 ** (failedAttempt - 1);\n break;\n }\n return Math.min(delay, MAX_RETRY_DELAY_MS);\n}\n\n/** Resolve one `step.do()` config against the capability defaults. */\nexport function resolveStepPolicy(\n defaults: ResolvedStepPolicy,\n config: TaskStepConfig | undefined\n): ResolvedStepPolicy {\n const limit = config?.retries?.limit ?? defaults.retryLimit;\n if (!Number.isInteger(limit) || limit < 1) {\n throw new Error(\n `Invalid step retries.limit: expected an integer >= 1, got ${limit}`\n );\n }\n return {\n retryLimit: limit,\n retryDelayMs:\n config?.retries?.delay !== undefined\n ? parseTaskDuration(config.retries.delay, \"step retries.delay\")\n : defaults.retryDelayMs,\n backoff: config?.retries?.backoff ?? defaults.backoff,\n timeoutMs:\n config?.timeout !== undefined\n ? parseTaskDuration(config.timeout, \"step timeout\")\n : defaults.timeoutMs\n };\n}\n\n/**\n * The `TaskStep` implementation for one execution attempt.\n *\n * Attempt 1 starts live. A later attempt starts silent and becomes live at\n * the frontier of new ground — the first journal miss, or a step still\n * waiting or running — so replayed `status()` calls from completed ground\n * are suppressed instead of re-published as new progress.\n */\nexport class ReplayStep implements TaskStep {\n readonly #engine: TaskStepEngine;\n readonly #usedNames = new Set<string>();\n #live: boolean;\n readonly interrupted: {\n readonly name: string;\n readonly attempt: number;\n } | null;\n\n constructor(\n engine: TaskStepEngine,\n options: {\n startsLive: boolean;\n interrupted?: { name: string; attempt: number } | null;\n }\n ) {\n this.#engine = engine;\n this.#live = options.startsLive;\n this.interrupted = options.interrupted ?? null;\n }\n\n do<T extends TaskValue>(\n name: string,\n callback: (attempt: TaskStepAttempt) => T | Promise<T>\n ): Promise<T>;\n do<T extends TaskValue>(\n name: string,\n config: TaskStepConfig,\n callback: (attempt: TaskStepAttempt) => T | Promise<T>\n ): Promise<T>;\n async do<T extends TaskValue>(\n name: string,\n configOrCallback:\n | TaskStepConfig\n | ((attempt: TaskStepAttempt) => T | Promise<T>),\n maybeCallback?: (attempt: TaskStepAttempt) => T | Promise<T>\n ): Promise<T> {\n const config =\n typeof configOrCallback === \"function\" ? undefined : configOrCallback;\n const callback =\n typeof configOrCallback === \"function\" ? configOrCallback : maybeCallback;\n if (typeof callback !== \"function\") {\n throw new Error(`step.do(\"${name}\") requires a callback`);\n }\n const policy = resolveStepPolicy(this.#engine.defaults, config);\n this.#enterStep(name);\n\n const row = this.#engine.readStep(name);\n if (row === undefined) {\n this.#live = true;\n if (this.#engine.countSteps() >= MAX_STEPS_PER_RUN) {\n throw new Error(\n `Run exceeded ${MAX_STEPS_PER_RUN} steps; split the work across ` +\n `multiple Task runs`\n );\n }\n this.#engine.insertStep(name, \"do\", null);\n return this.#executeAttempt(name, 1, policy, callback);\n }\n\n if (row.kind !== \"do\") {\n throw new TaskReplayDivergedError(\n name,\n `journaled as a ${row.kind} step but replayed as a do step`\n );\n }\n\n switch (row.state) {\n case \"completed\":\n return deserializeTaskValue(row.result) as T;\n case \"failed\":\n // Defensive: a failed step fails its run, so replay should not reach\n // it. Surface the persisted terminal error rather than re-executing.\n throw restoreStepError(row);\n case \"waiting\": {\n // The frontier: a retry deadline from a previous attempt.\n this.#live = true;\n const wakeAt = row.next_at ?? Date.now();\n if (Date.now() < wakeAt) throw new TaskSuspension(wakeAt, \"retry\");\n const attempt = this.#engine.claimStepAttempt(name);\n this.#engine.emit(\"task:step:retry\", { step: name, attempt });\n return this.#executeAttempt(name, attempt, policy, callback);\n }\n case \"running\": {\n // A previous attempt was interrupted mid-step. Default replay\n // semantics: run it again under a fresh claim.\n this.#live = true;\n const attempt = this.#engine.claimStepAttempt(name);\n return this.#executeAttempt(name, attempt, policy, callback);\n }\n }\n }\n\n async sleep(\n name: string,\n duration: number | TaskDurationString\n ): Promise<void> {\n const durationMs = parseTaskDuration(duration, \"sleep duration\");\n return this.#sleepAt(name, () => Date.now() + durationMs);\n }\n\n async sleepUntil(name: string, when: number | Date): Promise<void> {\n const wakeAt = when instanceof Date ? when.getTime() : when;\n if (!Number.isFinite(wakeAt)) {\n throw new Error(\n `Invalid sleepUntil time for step \"${name}\": ${String(when)}`\n );\n }\n return this.#sleepAt(name, () => wakeAt);\n }\n\n async status(message: string): Promise<void> {\n if (!this.#live) return;\n this.#engine.writeStatus(String(message));\n }\n\n idempotencyKey(name: string): string {\n return this.#engine.stepIdempotencyKey(name);\n }\n\n // ── Internal ─────────────────────────────────────────────────────────────\n\n /** Validate a step boundary: name rules, duplicates, cancellation. */\n #enterStep(name: string): void {\n if (typeof name !== \"string\" || name.length === 0) {\n throw new Error(\"Step names must be non-empty strings\");\n }\n if (name.length > MAX_STEP_NAME_LENGTH) {\n throw new Error(\n `Step name exceeds ${MAX_STEP_NAME_LENGTH} characters: \"${name.slice(0, 40)}…\"`\n );\n }\n if (name.startsWith(\"__cf\")) {\n throw new Error(`Step names must not use the reserved \"__cf\" prefix`);\n }\n if (this.#usedNames.has(name)) {\n throw new DuplicateTaskStepError(name);\n }\n this.#usedNames.add(name);\n\n const cancellation = this.#engine.cancellationRequested();\n if (cancellation) throw new TaskCancellation(cancellation.reason);\n }\n\n /** First persist wins: the recorded wake time is authoritative. */\n async #sleepAt(name: string, wakeTime: () => number): Promise<void> {\n this.#enterStep(name);\n\n const row = this.#engine.readStep(name);\n if (row === undefined) {\n this.#live = true;\n const wakeAt = wakeTime();\n if (wakeAt <= Date.now()) {\n this.#engine.insertCompletedSleep(name);\n return;\n }\n this.#engine.insertStep(name, \"sleep\", wakeAt);\n throw new TaskSuspension(wakeAt, \"sleep\");\n }\n\n if (row.kind !== \"sleep\") {\n throw new TaskReplayDivergedError(\n name,\n `journaled as a ${row.kind} step but replayed as a sleep step`\n );\n }\n if (row.state === \"completed\") return;\n\n // The frontier: an unfinished sleep is the first unfinished step.\n this.#live = true;\n const wakeAt = row.next_at ?? 0;\n if (Date.now() < wakeAt) throw new TaskSuspension(wakeAt, \"sleep\");\n this.#engine.completeStep(name, undefined);\n }\n\n /** Execute one claimed attempt of a `do` step under timeout and retries. */\n async #executeAttempt<T extends TaskValue>(\n name: string,\n attempt: number,\n policy: ResolvedStepPolicy,\n callback: (attempt: TaskStepAttempt) => T | Promise<T>\n ): Promise<T> {\n this.#engine.refreshClaim();\n this.#engine.emit(\"task:step:started\", { step: name, attempt });\n\n const timeout = new AbortController();\n const onRunAbort = () => timeout.abort(this.#engine.attemptSignal.reason);\n this.#engine.attemptSignal.addEventListener(\"abort\", onRunAbort, {\n once: true\n });\n const timer = setTimeout(() => {\n timeout.abort(\n new Error(\n `Step \"${name}\" attempt ${attempt} timed out after ${policy.timeoutMs}ms`\n )\n );\n }, policy.timeoutMs);\n\n try {\n const result = await this.#raceTimeout<T>(\n Promise.resolve(\n callback({\n attempt,\n idempotencyKey: this.#engine.stepIdempotencyKey(name),\n signal: timeout.signal\n })\n ),\n timeout.signal\n );\n this.#engine.completeStep(name, result);\n this.#engine.emit(\"task:step:completed\", { step: name, attempt });\n return result;\n } catch (error) {\n if (error instanceof AttemptSupersededError) throw error;\n const cancellation = this.#engine.cancellationRequested();\n if (cancellation) throw new TaskCancellation(cancellation.reason);\n // A condemned isolate cannot recover in-process. Leave the journal row\n // running and let the whole Task reach the alarm boundary, where a code\n // update defers to fresh code and a memory reset enters the breaker.\n // Other platform transients (notably \"Network connection lost\") retain\n // the ordinary short step retry budget before the run defers.\n if (\n isDurableObjectCodeUpdateReset(error) ||\n isDurableObjectMemoryLimitReset(error)\n ) {\n throw error;\n }\n // Transient platform errors use the configured durable retry budget.\n // Once that budget is spent they still are not application failures:\n // keep the step claimed and defer the whole run to a later invocation.\n if (isPlatformFailure(error) && attempt >= policy.retryLimit) throw error;\n if (\n isNonRetryableError(error) ||\n error instanceof TaskSerializationError ||\n attempt >= policy.retryLimit\n ) {\n this.#engine.failStep(name, toErrorSummary(error));\n throw error;\n }\n const wakeAt = Date.now() + computeRetryDelayMs(policy, attempt);\n this.#engine.waitStep(name, wakeAt);\n throw new TaskSuspension(wakeAt, \"retry\");\n } finally {\n clearTimeout(timer);\n this.#engine.attemptSignal.removeEventListener(\"abort\", onRunAbort);\n }\n }\n\n /**\n * Settle with the callback or its timeout, whichever finishes first. A\n * callback that ignores its abort signal cannot wedge the attempt; its\n * late settlement is discarded and generation fencing rejects late writes.\n */\n #raceTimeout<T>(pending: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) return Promise.reject(signal.reason);\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => reject(signal.reason);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n pending.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(value);\n },\n (error) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error);\n }\n );\n });\n }\n}\n\n/** Rebuild a persisted terminal step error for rethrow. */\nfunction restoreStepError(row: TaskStepRow): Error {\n const error = new Error(row.error_message ?? \"Step failed\");\n error.name = row.error_name ?? \"Error\";\n return error;\n}\n\n/** Safe name/message projection of an arbitrary thrown value. */\nexport function toErrorSummary(error: unknown): {\n name: string;\n message: string;\n} {\n if (error instanceof Error) {\n return { name: error.name, message: error.message };\n }\n return { name: \"Error\", message: String(error) };\n}\n","/**\n * The step-engine port: the storage-side operations `ReplayStep` drives —\n * journal reads and writes, generation fencing, claim refresh, progress —\n * bound to one claimed attempt. `tasks.ts` owns the state machine; this\n * module owns nothing but the port's construction.\n */\n\nimport {\n AttemptSupersededError,\n type TaskStepEngine,\n type ResolvedStepPolicy\n} from \"./replay\";\nimport { serializeTaskValue } from \"./serialization\";\nimport type { TaskStepRow } from \"./types\";\nimport type { TaskStore } from \"./store\";\n\n/** @internal What one step engine needs from its owning capability. */\nexport type TaskStepEngineDeps = {\n store: TaskStore;\n runId: string;\n generation: string;\n signal: AbortSignal;\n claimTimeoutMs: () => number;\n /** When the attempt's claim write persisted its `next_at` backstop. */\n claimedAtMs: number;\n /**\n * Minimum wall time between claim writes. Sized to half the claim slack:\n * every claim write lands `step timeout + slack` ahead, so a refresh\n * skipped this recently still leaves a full step timeout plus half the\n * slack of headroom — no policy-respecting step can outlive the claim,\n * and a burst of fast steps pays zero claim-refresh row writes.\n */\n claimRefreshAfterMs: number;\n defaults: ResolvedStepPolicy;\n emit: (type: string, payload: Record<string, unknown>) => void;\n};\n\n/** @internal Build the engine port for one claimed attempt. */\nexport function createTaskStepEngine(deps: TaskStepEngineDeps): TaskStepEngine {\n const { runId, generation } = deps;\n // The newest claim deadline known durable. The queue's own backstop push\n // (a due wake observing the live attempt) only ever moves `next_at`\n // forward, so this stays a conservative lower bound.\n let lastClaimWriteAt = deps.claimedAtMs;\n // The last status message known durable — persisting an identical one\n // again would be a pure row-write duplicate.\n let lastStatusMessage: string | undefined;\n const assertCurrent = (): void => {\n const row = deps.store.getRun(runId);\n if (!row || row.generation !== generation) {\n throw new AttemptSupersededError(runId);\n }\n };\n return {\n readStep: (name) => {\n const rows = deps.store.sql<TaskStepRow>`\n SELECT * FROM cf_agents_task_steps\n WHERE run_id = ${runId} AND step_name = ${name}\n `;\n return rows[0];\n },\n countSteps: () => {\n const rows = deps.store.sql<{ count: number }>`\n SELECT COUNT(*) AS count FROM cf_agents_task_steps WHERE run_id = ${runId}\n `;\n return rows[0]?.count ?? 0;\n },\n insertStep: (name, kind, wakeAt) => {\n assertCurrent();\n const now = Date.now();\n deps.store.sql`\n INSERT INTO cf_agents_task_steps\n (run_id, step_name, kind, state, attempt, next_at, created_at,\n started_at, updated_at)\n VALUES\n (${runId}, ${name}, ${kind},\n ${kind === \"do\" ? \"running\" : wakeAt === null ? \"running\" : \"waiting\"},\n ${kind === \"do\" ? 1 : 0}, ${wakeAt},\n ${now}, ${kind === \"do\" ? now : null}, ${now})\n `;\n },\n insertCompletedSleep: (name) => {\n assertCurrent();\n const now = Date.now();\n // An already-elapsed sleep is journaled born-completed: one INSERT,\n // where insert-then-complete would write the same row twice in the\n // same synchronous block (one durable commit either way, so the\n // split bought no crash evidence).\n deps.store.sql`\n INSERT INTO cf_agents_task_steps\n (run_id, step_name, kind, state, attempt, next_at, created_at,\n completed_at, updated_at)\n VALUES\n (${runId}, ${name}, 'sleep', 'completed', 0, NULL, ${now},\n ${now}, ${now})\n `;\n },\n claimStepAttempt: (name) => {\n assertCurrent();\n const now = Date.now();\n deps.store.sql`\n UPDATE cf_agents_task_steps\n SET state = 'running', attempt = attempt + 1, next_at = NULL,\n started_at = ${now}, updated_at = ${now}\n WHERE run_id = ${runId} AND step_name = ${name}\n `;\n const rows = deps.store.sql<{ attempt: number }>`\n SELECT attempt FROM cf_agents_task_steps\n WHERE run_id = ${runId} AND step_name = ${name}\n `;\n return rows[0]?.attempt ?? 1;\n },\n completeStep: (name, result) => {\n assertCurrent();\n const resultJson = serializeTaskValue(\n result,\n `result of step \"${name}\" in run \"${runId}\"`\n );\n const now = Date.now();\n deps.store.sql`\n UPDATE cf_agents_task_steps\n SET state = 'completed', result = ${resultJson}, next_at = NULL,\n completed_at = ${now}, updated_at = ${now}\n WHERE run_id = ${runId} AND step_name = ${name}\n `;\n },\n failStep: (name, error) => {\n assertCurrent();\n const now = Date.now();\n deps.store.sql`\n UPDATE cf_agents_task_steps\n SET state = 'failed', error_name = ${error.name},\n error_message = ${error.message}, next_at = NULL, updated_at = ${now}\n WHERE run_id = ${runId} AND step_name = ${name}\n `;\n },\n waitStep: (name, wakeAt) => {\n assertCurrent();\n const now = Date.now();\n deps.store.sql`\n UPDATE cf_agents_task_steps\n SET state = 'waiting', next_at = ${wakeAt}, updated_at = ${now}\n WHERE run_id = ${runId} AND step_name = ${name}\n `;\n },\n refreshClaim: () => {\n const now = Date.now();\n if (now - lastClaimWriteAt < deps.claimRefreshAfterMs) return;\n const written = deps.store.fencedWrite(\n runId,\n generation,\n `UPDATE cf_agents_task_runs SET next_at = ?, updated_at = ?\n WHERE run_id = ? AND generation = ? AND state = 'running'`,\n [now + deps.claimTimeoutMs(), now]\n );\n if (written) lastClaimWriteAt = now;\n },\n writeStatus: (message) => {\n if (message === lastStatusMessage) return;\n const written = deps.store.fencedWrite(\n runId,\n generation,\n `UPDATE cf_agents_task_runs SET status_message = ?, updated_at = ?\n WHERE run_id = ? AND generation = ? AND state = 'running'`,\n [message, Date.now()]\n );\n if (written) lastStatusMessage = message;\n },\n cancellationRequested: () => {\n const row = deps.store.getRun(runId);\n if (!row || row.cancel_requested !== 1) return null;\n return { reason: row.cancel_reason ?? undefined };\n },\n attemptSignal: deps.signal,\n emit: deps.emit,\n stepIdempotencyKey: (name) => `${runId}:${name}`,\n defaults: deps.defaults\n };\n}\n","/**\n * Durable replayable execution for Lifecycle Objects. `Tasks` owns the\n * `cf_agents_task_runs` and `cf_agents_task_steps` tables, the definitions registry, run\n * acceptance, generation-fenced claiming, and due-run processing.\n *\n * Tasks consumes only the standard capability services: storage, the job\n * queue, the host invocation boundary, events, and routing. A run's storage\n * and step journal always live where it was accepted; only its deadline\n * mirrors as one Lifecycle queue job, routed to the root Lifecycle when\n * accepted on a routed sub-agent, since only the root owns the physical\n * alarm. Definition handlers run through Lifecycle's host invocation\n * boundary. Interrupted work replays: completed steps return journaled\n * results and handlers resume from durable evidence.\n */\n\nimport { nanoid } from \"nanoid\";\nimport { LifecycleCapability } from \"../lifecycle/capability\";\nimport type {\n LifecycleRouteAddress,\n LifecycleRouteContext\n} from \"../lifecycle/capability\";\nimport type { MemoryLimitContext } from \"../lifecycle/capability-runner\";\nimport type {\n LifecycleJobContext,\n LifecycleJobOutcome\n} from \"../lifecycle/job-queue\";\nimport { isPlatformFailure } from \"../retries\";\nimport { SqlError } from \"../sql-error\";\nimport { TaskStore } from \"./store\";\nimport { createTaskStepEngine } from \"./engine-port\";\nimport { parseTaskDuration } from \"./duration\";\nimport { MissingTaskDefinitionError } from \"./errors\";\nimport type { TaskEventType, TasksOptions } from \"./options\";\nimport {\n AttemptSupersededError,\n TaskCancellation,\n isTaskCancellation,\n isTaskSuspension,\n ReplayStep,\n toErrorSummary,\n type TaskStepEngine,\n type ResolvedStepPolicy\n} from \"./replay\";\nimport { deserializeTaskValue, serializeTaskValue } from \"./serialization\";\nimport type {\n Task,\n TaskCallbacks,\n TaskHandlers,\n TaskInput,\n TaskOutput,\n TaskReceipt,\n TaskRunOptions,\n TaskRunRow,\n TaskRunSnapshot,\n TaskRunState,\n TaskValue\n} from \"./types\";\n\n/**\n * A composition-root fallback for definition names outside the declared\n * map. The value type is the input-erased handler form (`TaskCallbacks`),\n * so a host resolving concretely-typed definitions casts once, here, and\n * nowhere else.\n */\nexport type TaskDefinitionResolver = (\n name: string\n) => TaskCallbacks[string] | undefined;\n\nconst taskDefinitionResolvers = new WeakMap<object, TaskDefinitionResolver>();\n\n/**\n * @internal Supply a composition-root fallback for definition names outside\n * the declared map. Frameworks use this to attach internal definitions (for\n * example a future Agent compatibility layer) without occupying the host's\n * constructor map; resolved handlers still run inside the Lifecycle host\n * boundary. The resolver must return the same definition for a name on\n * every Durable Object wake, or that name's in-flight runs cannot resume.\n */\nexport function setTaskDefinitionResolver(\n tasks: Tasks<never>,\n resolver: TaskDefinitionResolver\n): void {\n taskDefinitionResolvers.set(tasks, resolver);\n}\n\nconst taskRoutedMemoryLimitHandlers = new WeakMap<\n object,\n (context: MemoryLimitContext) => void | Promise<void>\n>();\n\n/**\n * @internal Supply a composition-root bridge from a routed run's sealed\n * strike to the owning host's own `onAlarmMemoryLimit` hook. A root's own\n * local runs already reach that hook through Lifecycle's alarm dispatch on\n * the same Durable Object; a routed run's owner is a different instance,\n * whose Lifecycle never observes the root's alarm directly.\n */\nexport function setTaskRoutedMemoryLimitHandler(\n tasks: Tasks<never>,\n handler: (context: MemoryLimitContext) => void | Promise<void>\n): void {\n taskRoutedMemoryLimitHandlers.set(tasks, handler);\n}\n\nconst FIBER_SCHEMA_VERSION_KEY = \"cf_agents:tasks_schema_version\";\nconst CURRENT_FIBER_SCHEMA_VERSION = 1;\n\nconst DEFAULT_STEP_POLICY: ResolvedStepPolicy = {\n retryLimit: 5,\n retryDelayMs: 1000,\n backoff: \"exponential\",\n timeoutMs: 5 * 60 * 1000\n};\n\n/**\n * Slack added to the default step timeout to form the claim deadline — the\n * durable recovery backstop that wakes the object when a claimed attempt's\n * isolate disappears.\n */\nconst CLAIM_SLACK_MS = 30_000;\n\nconst DEFAULT_LIST_LIMIT = 100;\nconst MAX_DEFINITION_NAME_LENGTH = 256;\n/**\n * Queue-job id prefix for run wakes. Run IDs are caller-selectable, so the\n * job id namespaces them instead of exposing them verbatim to the shared\n * job id space.\n */\nconst WAKE_JOB_PREFIX = \"task:\";\n/** Normal Task deadline dispatch. */\nconst WAKE_JOB_FN = \"wake\";\n/**\n * A platform failure that escapes an attempt (ReplayStep rethrows once the\n * step's own retry budget is spent) leaves the run claimed with a future\n * `next_at`. An in-driver retry would not re-run the step — `#executeRun`\n * returns at its claim guard — it would only read the claim back as a clean\n * `{ rescheduleAt }`, hiding the failure from the alarm boundary. One\n * attempt keeps JobDriver's platform-failure contract: the wake rejects, the\n * job row is preserved, and the platform re-runs the alarm on a fresh\n * invocation while the claim deadline stays the durable wake.\n */\nconst WAKE_JOB_RETRY = { maxAttempts: 1 } as const;\n/**\n * How long one queue-driven attempt may hold the serial dispatch loop\n * before detaching. Correctness never depends on the inline await — the\n * claim backstop owns the durable wake — so this only trades a prompt\n * inline settle for queue liveness.\n */\nconst DISPATCH_BUDGET_MS = 5_000;\n\nconst TERMINAL_STATES: ReadonlySet<TaskRunState> = new Set([\n \"completed\",\n \"failed\",\n \"cancelled\"\n]);\n\n/**\n * A wake job's payload. Owner fields are set only for a routed run's mirror\n * on the root Lifecycle — the run row and step journal stay on the owning\n * facet, which is where `dispatch` and `memoryLimit` route back to.\n */\ntype TaskWakeJobPayload = {\n readonly runId: string;\n readonly owner_path?: string | null;\n readonly owner_path_key?: string | null;\n};\n\nfunction isTaskWakeJobPayload(value: unknown): value is TaskWakeJobPayload {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as TaskWakeJobPayload).runId === \"string\"\n );\n}\n\n/** Tasks protocol messages routed between a facet and the root Lifecycle. */\ntype TaskRouteMessage =\n | {\n readonly type: \"syncWake\";\n readonly runId: string;\n readonly next: number | null;\n }\n | { readonly type: \"dispatch\"; readonly runId: string }\n | {\n readonly type: \"memoryLimit\";\n readonly runId: string;\n readonly context: MemoryLimitContext;\n };\n\n/**\n * Who drives an accepted run's first attempt: `warm` starts it detached in\n * the caller's invocation (the public `run()` behaviour), `queued` leaves it\n * to the durable wake, and `attached` lets the caller drive and await it.\n */\ntype TaskStartMode = \"warm\" | \"queued\" | \"attached\";\n\n/** One live execution attempt in this isolate. */\ntype ActiveAttempt = {\n readonly generation: string;\n readonly controller: AbortController;\n readonly promise: Promise<void>;\n};\n\n/** Filters accepted by {@link Tasks.list}. */\nexport type TaskListOptions = {\n definition?: string;\n status?: TaskRunState | TaskRunState[];\n limit?: number;\n};\n\n/** Filters accepted by {@link Tasks.delete}. */\nexport type TaskDeleteOptions = {\n status?: Array<\"completed\" | \"failed\" | \"cancelled\">;\n settledBefore?: Date;\n limit?: number;\n};\n\n/**\n * Durable replayable execution for a Lifecycle Object.\n *\n * Declare named definitions in the constructor and install the instance with\n * `Lifecycle.use()`. The constructor map is the registry: it is rebuilt on\n * every Durable Object wake, so in-flight runs always resolve their\n * persisted definition names. Each definition's handler replays from the\n * beginning on every execution attempt; completed steps return journaled\n * results, sleeps consult persisted deadlines, and interrupted work\n * continues from the first unfinished step after process loss.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class Tasks<\n Handlers extends TaskHandlers = TaskCallbacks\n> extends LifecycleCapability {\n readonly #definitions: TaskHandlers;\n readonly #registered = new Map<string, TaskCallbacks[string]>();\n readonly #active = new Map<string, ActiveAttempt>();\n #storeInstance: TaskStore | undefined;\n readonly #stepDefaults: ResolvedStepPolicy;\n readonly #onError: ((error: unknown) => void | Promise<void>) | undefined;\n\n /**\n * Create a Tasks capability.\n *\n * @param options - Named definitions plus default step retry/timeout\n * policy and alarm batching. Declaring `definitions` types {@link run} and\n * {@link handle} against the map — names and inputs are checked where the\n * handlers are declared and where runs start. Names outside the map are\n * rejected unless a composition-root resolver supplies them.\n */\n constructor(options: TasksOptions<Handlers> = {}) {\n super(\"tasks\");\n this.#definitions = options.definitions ?? {};\n this.#stepDefaults = {\n retryLimit: options.retries?.limit ?? DEFAULT_STEP_POLICY.retryLimit,\n retryDelayMs:\n options.retries?.delay !== undefined\n ? parseTaskDuration(options.retries.delay, \"retries.delay\")\n : DEFAULT_STEP_POLICY.retryDelayMs,\n backoff: options.retries?.backoff ?? DEFAULT_STEP_POLICY.backoff,\n timeoutMs:\n options.stepTimeout !== undefined\n ? parseTaskDuration(options.stepTimeout, \"stepTimeout\")\n : DEFAULT_STEP_POLICY.timeoutMs\n };\n this.#onError = options.onError;\n }\n\n #claimTimeoutMs(): number {\n return this.#stepDefaults.timeoutMs + CLAIM_SLACK_MS;\n }\n\n /** The SQL store over this Lifecycle's storage (see `store.ts`). */\n get #store(): TaskStore {\n this.#storeInstance ??= new TaskStore(this.lifecycle.storage);\n return this.#storeInstance;\n }\n\n // ── Definitions ──────────────────────────────────────────────────────────\n\n /** Resolve a name to its declared or composition-root-supplied handler. */\n #resolveDefinition(name: string): TaskCallbacks[string] | undefined {\n // SAFETY: declared definitions are constrained with `never` parameters\n // so concrete definition types satisfy the map under contravariance; the\n // values passed at dispatch were parsed from rows this definition's name\n // was persisted with.\n return (this.#definitions[name] ??\n this.#registered.get(name) ??\n taskDefinitionResolvers.get(this)?.(name)) as\n | TaskCallbacks[string]\n | undefined;\n }\n\n /** True when a name resolves to a runnable definition. */\n #hasDefinition(name: string): boolean {\n return this.#resolveDefinition(name) !== undefined;\n }\n\n #validateDefinitionName(name: string): void {\n if (typeof name !== \"string\" || name.length === 0) {\n throw new Error(\"Task definition names must be non-empty strings\");\n }\n if (name.length > MAX_DEFINITION_NAME_LENGTH) {\n throw new Error(\n `Task definition name exceeds ${MAX_DEFINITION_NAME_LENGTH} characters`\n );\n }\n if (name.startsWith(\"__cf\")) {\n throw new Error(\n `Task definition names must not use the reserved \"__cf\" prefix`\n );\n }\n if (!this.#hasDefinition(name)) {\n throw new Error(\n `Unknown Task definition \"${name}\": not declared on this Tasks`\n );\n }\n }\n\n /**\n * @internal Framework aperture: register one reserved (`__cf`-prefixed)\n * Task definition directly on this instance, bypassing the constructor's\n * `definitions` map so a host's own subclass layers can each declare their\n * own `definitions` / `taskDefinitions` field without colliding with — or\n * being silently clobbered by — a framework's internal names. Call once per\n * name from the owning host's own constructor, unconditionally, so the\n * definition is rebuilt identically on every Durable Object wake: an\n * in-flight run resolves the same handler for its persisted definition name\n * every time, or it cannot resume.\n *\n * Throws if `name` does not carry the reserved `__cf` prefix — this is not\n * a general-purpose registration path; declare ordinary definitions in the\n * constructor's `definitions` map instead — or if `name` is already\n * registered, which is always a real conflict: this method runs exactly\n * once per name per Tasks construction.\n */\n register(name: string, definition: TaskCallbacks[string]): void {\n if (typeof name !== \"string\" || name.length === 0) {\n throw new Error(\"Task definition names must be non-empty strings\");\n }\n if (name.length > MAX_DEFINITION_NAME_LENGTH) {\n throw new Error(\n `Task definition name exceeds ${MAX_DEFINITION_NAME_LENGTH} characters`\n );\n }\n if (!name.startsWith(\"__cf\")) {\n throw new Error(\n `register() requires a \"__cf\"-prefixed reserved definition name, got \"${name}\"`\n );\n }\n if (Object.hasOwn(this.#definitions, name) || this.#registered.has(name)) {\n throw new Error(\n `Task definition \"${name}\" is already registered on this Tasks capability`\n );\n }\n this.#registered.set(name, definition);\n }\n\n // ── Starting runs ────────────────────────────────────────────────────────\n\n /**\n * Durably accept one run of a declared definition and return a receipt\n * without waiting for terminal state. The same `idempotencyKey` or `runId`\n * joins the existing run (`accepted: false`) instead of creating a second.\n */\n async run<Name extends keyof Handlers & string>(\n definition: Name,\n input?: TaskInput<Handlers[Name]>,\n options?: TaskRunOptions\n ): Promise<TaskReceipt> {\n this.#validateDefinitionName(definition);\n return this.#accept(definition, input, options);\n }\n\n /**\n * A typed handle scoped to one declared definition: its `run`, `get`,\n * `getByIdempotencyKey`, and `cancel` see only that definition's runs. The\n * handle is a pure lens over this capability — it holds no state and may\n * be created at any time.\n */\n handle<Name extends keyof Handlers & string>(\n definition: Name\n ): Task<TaskInput<Handlers[Name]>, TaskOutput<Handlers[Name]>> {\n this.#validateDefinitionName(definition);\n return {\n name: definition,\n run: (input, options) => this.run(definition, input, options),\n get: (runId) => this.#snapshot(runId, definition),\n getByIdempotencyKey: (idempotencyKey) =>\n this.#snapshotByKey(idempotencyKey, definition),\n cancel: (runId, reason) => this.#cancelScoped(runId, definition, reason)\n };\n }\n\n /** Cancel through a handle: another definition's run is not visible. */\n async #cancelScoped(\n runId: string,\n definition: string,\n reason?: string\n ): Promise<boolean> {\n await this.lifecycle.ready();\n const row = this.#store.getRun(runId);\n if (!row || row.definition !== definition) return false;\n return this.cancel(runId, reason);\n }\n\n // ── Lifecycle capability hooks ───────────────────────────────────────────\n\n /** Migrate storage and reconcile run deadlines during Lifecycle startup. */\n async onStart(): Promise<void> {\n const storage = this.lifecycle.storage;\n const version = (await storage.get<number>(FIBER_SCHEMA_VERSION_KEY)) ?? 0;\n if (version < CURRENT_FIBER_SCHEMA_VERSION) {\n this.#store.ensureTables();\n await storage.put(FIBER_SCHEMA_VERSION_KEY, CURRENT_FIBER_SCHEMA_VERSION);\n }\n this.#reconcile();\n await this.#syncAllWakes();\n }\n\n /** Drive one due run's wake dispatched by the Lifecycle event loop. */\n async onJob(\n context: LifecycleJobContext\n ): Promise<LifecycleJobOutcome | void> {\n const timing = isTaskWakeJobPayload(context.job.payload)\n ? context.job.payload\n : undefined;\n const runId = timing?.runId ?? context.job.id.slice(WAKE_JOB_PREFIX.length);\n\n if (timing?.owner_path) {\n // This root mirrors a routed facet's wake; the run and its step\n // journal live on the owning facet, so dispatch routes back there.\n // The facet fully awaits its own dispatch — no local budget to race,\n // since this root now races its own await of the call and, on\n // budget, keeps the still-pending call tracked against this alarm's\n // memory-limit breaker domain instead of discarding it. Verified\n // against a deployed repro: a callee's real memory-limit reset mid\n // RPC rejects the caller's pending call with the platform's own\n // \"exceeded its memory limit\" text, exactly what the breaker already\n // matches on — so a late failure on the facet is attributed here\n // just like a local detached attempt would be.\n const target = {\n key: timing.owner_path_key ?? timing.owner_path,\n data: timing.owner_path\n };\n const call = this.lifecycle.routes.to(target, {\n type: \"dispatch\",\n runId\n } satisfies TaskRouteMessage);\n let budgetTimer: ReturnType<typeof setTimeout> | undefined;\n const budget = new Promise<\"budget\">((resolve) => {\n budgetTimer = setTimeout(() => resolve(\"budget\"), DISPATCH_BUDGET_MS);\n });\n try {\n const winner = await Promise.race([\n call.then((outcome) => ({ outcome })),\n budget\n ]);\n if (winner === \"budget\") {\n this.lifecycle.trackAlarmWork(call);\n // The facet's own routed #syncWake, made whenever it eventually\n // settles, supersedes whatever this returns (newer pushes win\n // over drive results), same as the local path below.\n return undefined;\n }\n return winner.outcome as LifecycleJobOutcome;\n } catch (error) {\n if (isPlatformFailure(error)) throw error;\n console.error(`error dispatching routed Task run \"${runId}\"`, error);\n return \"yield\";\n } finally {\n clearTimeout(budgetTimer);\n }\n }\n\n return this.#dispatchRun(runId);\n }\n\n /** Push a live attempt's durable claim deadline forward one claim window. */\n #refreshClaim(runId: string): void {\n this.#store.sql`\n UPDATE cf_agents_task_runs\n SET next_at = ${Date.now() + this.#claimTimeoutMs()}, updated_at = ${Date.now()}\n WHERE run_id = ${runId} AND state = 'running'\n `;\n }\n\n /**\n * Drive one local due run to its next durable boundary, bounded by the\n * dispatch budget, and return the wake outcome for this capability's own\n * queue job.\n */\n async #dispatchRun(runId: string): Promise<LifecycleJobOutcome> {\n const active = this.#active.get(runId);\n if (active) {\n // A live attempt in this isolate; push the claim backstop forward so\n // the due job does not hot-loop the alarm while it works.\n this.#refreshClaim(runId);\n this.lifecycle.trackAlarmWork(active.promise);\n return this.#wakeOutcome(runId);\n }\n // Dispatch is bounded: the queue drives jobs serially, so this attempt\n // may not hold the loop for its full step budget. Short attempts (the\n // common case — memoized replays, quick steps) settle inline; a longer\n // one detaches at the budget and keeps executing while this isolate\n // lives. Durability does not depend on the await: the claim backstop in\n // the run row is the wake that survives isolate death, and a detached\n // settle re-syncs the wake mirror, superseding the outcome returned\n // below (newer pushes win over drive results).\n let budgetTimer: ReturnType<typeof setTimeout> | undefined;\n const budget = new Promise<\"budget\">((resolve) => {\n budgetTimer = setTimeout(() => resolve(\"budget\"), DISPATCH_BUDGET_MS);\n });\n const runAttempt = this.#executeRun(runId);\n const attempt = runAttempt.then(() => \"settled\" as const);\n try {\n // A platform failure inside the budget rejects the race and re-enters\n // the driver's deferral path unchanged.\n const winner = await Promise.race([attempt, budget]);\n if (winner === \"budget\") {\n // Hand off the attempt's canonical promise — the one a later\n // claim-backstop wake finds in #active — so re-tracking is the\n // driver's documented no-op. The wrapper only unwinds it.\n this.lifecycle.trackAlarmWork(\n this.#active.get(runId)?.promise ?? runAttempt\n );\n return this.#wakeOutcome(runId);\n }\n } finally {\n clearTimeout(budgetTimer);\n }\n return this.#wakeOutcome(runId);\n }\n\n /**\n * Drive one routed dispatch to completion on this owning facet. There is\n * no local budget to race here: the root that sent this message races\n * its own await of the call instead, so a full await is safe regardless\n * of how long the attempt takes — the call keeps running on this facet\n * either way. An already-active attempt only needs its claim refreshed:\n * it is already tracked against whichever alarm's breaker domain\n * originally dispatched it (a root's pending routed call, or this\n * facet's own local alarm).\n */\n async #dispatchRoutedRun(runId: string): Promise<LifecycleJobOutcome> {\n const active = this.#active.get(runId);\n if (active) {\n this.#refreshClaim(runId);\n return this.#wakeOutcome(runId);\n }\n await this.#executeRun(runId);\n return this.#wakeOutcome(runId);\n }\n\n /**\n * Alarm memory-limit breaker policy (#1825) for the run whose wake struck.\n *\n * The run row is the durable source of truth: startup reconciliation\n * re-derives due-now wakes from it, so the breaker's queue-row backoff\n * and purge alone cannot contain a run whose attempt deterministically\n * exhausts memory — a fresh isolate would resurrect it immediately. On a\n * strike the run's claim is stripped and its deadline pushed to the\n * backoff wake: the row keeps its state, so a struck `running` row still\n * reads as an interrupted attempt (`step.interrupted`) when it is\n * reclaimed, while reconciliation leaves the claimless row alone instead\n * of flooring its deadline to now. When the breaker seals, the run\n * terminally fails with an observable `task:failed` outcome.\n */\n async onMemoryLimit(context: MemoryLimitContext): Promise<void> {\n const job = context.executing;\n if (job?.capability !== this.capabilityId) return;\n const timing = isTaskWakeJobPayload(job.payload) ? job.payload : undefined;\n const runId = timing?.runId ?? job.id.slice(WAKE_JOB_PREFIX.length);\n\n if (timing?.owner_path) {\n // The struck job was this root's mirror of a routed facet's wake; the\n // run row and its claim live on the facet, so the strike is forwarded\n // there to apply the same policy locally — clearing the claim and\n // backing off (or terminally failing, when sealed). Forwarding a\n // non-sealed strike too matters: this root's own mirror job backs off\n // on its own, but the facet's run row would otherwise keep its old\n // claim, and any facet startup before the backoff elapses would read\n // that claim as an interrupted attempt and reconcile it due again now\n // — resurrecting the run through the breaker.\n try {\n await this.lifecycle.routes.to(\n {\n key: timing.owner_path_key ?? timing.owner_path,\n data: timing.owner_path\n },\n { type: \"memoryLimit\", runId, context } satisfies TaskRouteMessage\n );\n } catch (error) {\n console.error(\n `Failed to route memory-limit policy for Task run \"${runId}\"`,\n error\n );\n }\n return;\n }\n await this.#applyMemoryLimit(runId, context);\n }\n\n /**\n * Apply the alarm memory-limit breaker policy (#1825) to one run, local to\n * whichever Lifecycle owns its storage — the root for an unrouted run, or\n * the owning facet when {@link onMemoryLimit} forwarded a routed strike.\n */\n async #applyMemoryLimit(\n runId: string,\n context: MemoryLimitContext\n ): Promise<void> {\n if (context.sealed) {\n await this.#settleFailed(runId, null, {\n name: \"TaskMemoryLimitSealed\",\n message:\n \"Sealed by the alarm memory-limit circuit breaker (#1825) after \" +\n \"consecutive Durable Object memory-limit resets.\"\n });\n return;\n }\n if (context.nextTime === undefined) return;\n const now = Date.now();\n this.#store.write(\n `UPDATE cf_agents_task_runs\n SET generation = NULL,\n next_at = CASE\n WHEN next_at IS NULL OR next_at < ? THEN ?\n ELSE next_at\n END,\n updated_at = ?\n WHERE run_id = ?\n AND state IN ('pending', 'waiting', 'running')`,\n [context.nextTime, context.nextTime, now, runId]\n );\n await this.#syncWake(runId);\n }\n\n /**\n * @internal Framework aperture: durably accept one run — reserved\n * (`__cf`-prefixed) definition names included, which the public `run()`\n * refuses so users cannot start framework runs — and drive its first\n * attempt in the caller's invocation, resolving when that attempt reaches\n * its next durable boundary. The receipt's run may already be terminal\n * when this resolves; callers that need the outcome read it from their own\n * channel (the run handler settles it) or from the snapshot.\n */\n async __DO_NOT_USE_WILL_BREAK__runAttached(\n definition: string,\n input: unknown,\n options?: TaskRunOptions\n ): Promise<TaskReceipt> {\n const receipt = await this.#acceptReserved(\n definition,\n input,\n options,\n \"attached\"\n );\n if (receipt.accepted) await this.#executeRun(receipt.runId);\n return receipt;\n }\n\n /**\n * @internal Framework aperture: durably accept one run — reserved names\n * included — and leave its first attempt to the durable queue wake instead\n * of warm-starting it in the caller's invocation. Chat recovery uses this\n * so a continuation always runs under an alarm, where `trackAlarmWork`\n * keeps its model turn inside the memory-limit breaker domain.\n */\n async __DO_NOT_USE_WILL_BREAK__enqueue(\n definition: string,\n input: unknown,\n options?: TaskRunOptions\n ): Promise<TaskReceipt> {\n return this.#acceptReserved(definition, input, options, \"queued\");\n }\n\n /** Accept a run of any resolvable definition, reserved names included. */\n async #acceptReserved(\n definition: string,\n input: unknown,\n options: TaskRunOptions | undefined,\n startMode: TaskStartMode\n ): Promise<TaskReceipt> {\n if (!this.#hasDefinition(definition)) {\n throw new Error(\n `Unknown Task definition \"${definition}\": not declared on this Tasks`\n );\n }\n return this.#accept(definition, input, options, startMode);\n }\n\n /**\n * The queue outcome for one run's wake job, derived from the run row's\n * authoritative `next_at` after dispatch. A same-id `#syncWake` push made\n * mid-drive supersedes this return at the queue (newer pushes win over\n * drive results), but both are computed from the same row, so the row is\n * the single source of truth for whether — and when — the run wakes\n * again either way.\n */\n #wakeOutcome(runId: string): LifecycleJobOutcome {\n const rows = this.#store.sql<{ next_at: number | null }>`\n SELECT next_at FROM cf_agents_task_runs\n WHERE run_id = ${runId}\n AND state IN ('pending', 'waiting', 'running')\n `;\n const next = rows[0]?.next_at;\n return typeof next === \"number\" ? { rescheduleAt: next } : undefined;\n }\n\n /**\n * Mirror one run's authoritative deadline into the Lifecycle job queue:\n * a non-terminal run with a `next_at` gets one job (id = `task:` plus the\n * run id, so a retime is a same-id replace); anything else cancels the\n * mirror. The prefix keeps caller-selected run IDs inside Tasks' own job\n * namespace. Every durable mutation of a run's deadline or state funnels\n * through here.\n *\n * @returns False when the queue already carried exactly this wake and\n * nothing was written — a same-values upsert is still a billed row write.\n */\n async #syncWake(runId: string): Promise<boolean> {\n const rows = this.#store.sql<{ next_at: number | null }>`\n SELECT next_at FROM cf_agents_task_runs\n WHERE run_id = ${runId}\n AND state IN ('pending', 'waiting', 'running')\n `;\n const next = rows[0]?.next_at ?? null;\n\n if (this.lifecycle.routes.source) {\n // The run row stays here; only its deadline mirrors to the root that\n // owns the physical alarm.\n return (await this.lifecycle.routes.toRoot({\n type: \"syncWake\",\n runId,\n next\n } satisfies TaskRouteMessage)) as boolean;\n }\n\n const jobId = `${WAKE_JOB_PREFIX}${runId}`;\n if (next === null) {\n await this.lifecycle.jobs.cancel(jobId);\n return true;\n }\n const existing = this.lifecycle.jobs.get(jobId);\n if (\n existing?.fn === WAKE_JOB_FN &&\n existing.time === next &&\n existing.retry?.maxAttempts === WAKE_JOB_RETRY.maxAttempts\n ) {\n return false;\n }\n await this.lifecycle.jobs.push({\n id: jobId,\n fn: WAKE_JOB_FN,\n time: next,\n payload: { runId } satisfies TaskWakeJobPayload,\n retry: WAKE_JOB_RETRY\n });\n return true;\n }\n\n /** Handle Tasks protocol messages routed by another Lifecycle. */\n async onRoute(context: LifecycleRouteContext): Promise<unknown> {\n const message = context.payload as TaskRouteMessage;\n switch (message.type) {\n case \"syncWake\": {\n const owner = context.source;\n if (!owner) throw new Error(\"Routed Tasks message missing source\");\n return this.#syncRoutedWake(owner, message.runId, message.next);\n }\n case \"dispatch\":\n return this.#dispatchRoutedRun(message.runId);\n case \"memoryLimit\": {\n await this.#applyMemoryLimit(message.runId, message.context);\n // The owner's own Lifecycle never observes the root's alarm; this\n // is its only path to the same `onAlarmMemoryLimit` host hook a\n // root's own local strike reaches through Lifecycle's alarm\n // dispatch.\n const handler = taskRoutedMemoryLimitHandlers.get(this);\n if (handler) {\n await this.lifecycle.runInHostContext(() => handler(message.context));\n }\n return true;\n }\n default:\n throw new Error(\"Unknown routed Tasks message\");\n }\n }\n\n /** Mirror a routed facet's run deadline into this root's job queue. */\n async #syncRoutedWake(\n owner: LifecycleRouteAddress,\n runId: string,\n next: number | null\n ): Promise<boolean> {\n const jobId = `${WAKE_JOB_PREFIX}${owner.key}:${runId}`;\n if (next === null) {\n await this.lifecycle.jobs.cancel(jobId);\n return true;\n }\n const existing = this.lifecycle.jobs.get(jobId);\n if (\n existing?.fn === WAKE_JOB_FN &&\n existing.time === next &&\n existing.retry?.maxAttempts === WAKE_JOB_RETRY.maxAttempts\n ) {\n return false;\n }\n await this.lifecycle.jobs.push({\n id: jobId,\n fn: WAKE_JOB_FN,\n time: next,\n payload: {\n runId,\n owner_path: owner.data,\n owner_path_key: owner.key\n } satisfies TaskWakeJobPayload,\n retry: WAKE_JOB_RETRY\n });\n return true;\n }\n\n /**\n * @internal Framework aperture: bulk-cancel this root's routed wake\n * mirrors for every run owned by a deleted facet subtree. The runs and\n * their step journals live on the deleted facets' own storage and are\n * wiped with them; only this root's mirror job needs an explicit cancel,\n * or it stays due forever, retrying a dispatch to a facet that is gone.\n */\n async __DO_NOT_USE_WILL_BREAK__cleanupRoutePrefix(\n prefix: string\n ): Promise<void> {\n for (const job of this.lifecycle.jobs.list()) {\n const timing = isTaskWakeJobPayload(job.payload)\n ? job.payload\n : undefined;\n const ownerKey = timing?.owner_path_key ?? timing?.owner_path;\n if (!timing?.owner_path || ownerKey === null || ownerKey === undefined) {\n continue;\n }\n if (ownerKey !== prefix && !ownerKey.startsWith(`${prefix}/`)) continue;\n await this.lifecycle.jobs.cancel(job.id);\n }\n }\n\n /** Mirror every non-terminal run into the queue (startup reconcile). */\n async #syncAllWakes(): Promise<void> {\n const rows = this.#store.sql<{ run_id: string }>`\n SELECT run_id FROM cf_agents_task_runs\n WHERE state IN ('pending', 'waiting', 'running')\n AND next_at IS NOT NULL\n `;\n // On restart the mirror usually survived alongside the run row (same\n // storage), so most rows write nothing; wakes from before the one-attempt\n // policy are rewritten once.\n let pushed = false;\n for (const { run_id } of rows) {\n if (await this.#syncWake(run_id)) pushed = true;\n }\n // Pushes re-arm the physical alarm as a side effect; a reconcile that\n // wrote nothing must recover a lost alarm explicitly.\n if (rows.length > 0 && !pushed) await this.lifecycle.jobs.rearm();\n }\n\n // ── Inspection and control ───────────────────────────────────────────────\n\n /** Read one run by ID across all definitions. */\n async get(runId: string): Promise<TaskRunSnapshot<TaskValue> | null> {\n return this.#snapshot(runId);\n }\n\n /** Read one run by idempotency key across all definitions. */\n async getByIdempotencyKey(\n idempotencyKey: string\n ): Promise<TaskRunSnapshot<TaskValue> | null> {\n return this.#snapshotByKey(idempotencyKey);\n }\n\n /** List runs, newest first. */\n async list(\n options: TaskListOptions = {}\n ): Promise<TaskRunSnapshot<TaskValue>[]> {\n await this.lifecycle.ready();\n let query = \"SELECT * FROM cf_agents_task_runs WHERE 1 = 1\";\n const params: (string | number)[] = [];\n if (options.definition !== undefined) {\n query += \" AND definition = ?\";\n params.push(options.definition);\n }\n const states = Array.isArray(options.status)\n ? options.status\n : options.status !== undefined\n ? [options.status]\n : [];\n if (states.length > 0) {\n query += ` AND state IN (${states.map(() => \"?\").join(\", \")})`;\n params.push(...states);\n }\n query += \" ORDER BY created_at DESC, run_id DESC LIMIT ?\";\n params.push(options.limit ?? DEFAULT_LIST_LIMIT);\n let rows: unknown[];\n try {\n rows = this.lifecycle.storage.sql.exec(query, ...params).toArray();\n } catch (cause) {\n throw new SqlError(query, cause);\n }\n // SAFETY: the query selects * from Tasks' own schema.\n return (rows as TaskRunRow[]).map((row) => this.#store.rowToSnapshot(row));\n }\n\n /**\n * Request cooperative cancellation of one run.\n *\n * A live attempt is aborted and settles as cancelled at its next step\n * boundary; a parked run settles immediately.\n *\n * @returns True when a non-terminal run accepted the request.\n */\n async cancel(runId: string, reason?: string): Promise<boolean> {\n await this.lifecycle.ready();\n const row = this.#store.getRun(runId);\n if (!row || TERMINAL_STATES.has(row.state)) return false;\n\n const active = this.#active.get(runId);\n if (active) {\n const now = Date.now();\n this.#store.sql`\n UPDATE cf_agents_task_runs\n SET cancel_requested = 1, cancel_reason = ${reason ?? null},\n next_at = ${now}, updated_at = ${now}\n WHERE run_id = ${runId}\n `;\n active.controller.abort(new TaskCancellation(reason));\n await this.#syncWake(runId);\n return true;\n }\n // A parked run settles in one write: #settleCancelled's UPDATE records\n // the request bits itself, so a separate request write would touch the\n // same row twice in the same synchronous block (one durable commit\n // either way — the split bought no crash evidence).\n await this.#settleCancelled(runId, null, reason);\n return true;\n }\n\n /**\n * Delete retained terminal runs and their step journals.\n *\n * @returns The number of runs deleted.\n */\n async delete(options: TaskDeleteOptions = {}): Promise<number> {\n await this.lifecycle.ready();\n const states = options.status ?? [\"completed\", \"failed\", \"cancelled\"];\n if (states.length === 0) return 0;\n let query = `SELECT run_id, definition FROM cf_agents_task_runs WHERE state IN (${states.map(() => \"?\").join(\", \")})`;\n const params: (string | number)[] = [...states];\n if (options.settledBefore) {\n query += \" AND settled_at < ?\";\n params.push(options.settledBefore.getTime());\n }\n query += \" ORDER BY settled_at ASC LIMIT ?\";\n params.push(options.limit ?? DEFAULT_LIST_LIMIT);\n let rows: unknown[];\n try {\n rows = this.lifecycle.storage.sql.exec(query, ...params).toArray();\n } catch (cause) {\n throw new SqlError(query, cause);\n }\n for (const row of rows as Array<{ run_id: string; definition: string }>) {\n this.#store.deleteRun(row.run_id);\n this.#emit(\"task:deleted\", {\n runId: row.run_id,\n definition: row.definition\n });\n }\n return rows.length;\n }\n\n // ── Acceptance ───────────────────────────────────────────────────────────\n\n async #accept(\n definition: string,\n input: unknown,\n options: TaskRunOptions = {},\n startMode: TaskStartMode = \"warm\"\n ): Promise<TaskReceipt> {\n await this.lifecycle.ready();\n if (options.runId !== undefined && options.runId.length === 0) {\n throw new Error(\"runId must be a non-empty string when provided\");\n }\n if (\n options.idempotencyKey !== undefined &&\n options.idempotencyKey.length === 0\n ) {\n throw new Error(\n \"idempotencyKey must be a non-empty string when provided\"\n );\n }\n\n const inputJson = serializeTaskValue(\n input,\n `input for Task definition \"${definition}\"`\n );\n const metadataJson = serializeTaskValue(\n options.metadata,\n `metadata for Task definition \"${definition}\"`\n );\n\n const existing =\n (options.runId !== undefined\n ? this.#store.getRun(options.runId)\n : undefined) ??\n (options.idempotencyKey !== undefined\n ? this.#store.getRunByKey(options.idempotencyKey)\n : undefined);\n if (existing) {\n if (existing.definition !== definition) {\n throw new Error(\n `Task run \"${existing.run_id}\" already belongs to definition ` +\n `\"${existing.definition}\"; refusing to reuse its ` +\n `${options.runId !== undefined ? \"run ID\" : \"idempotency key\"} for ` +\n `\"${definition}\"`\n );\n }\n // The idempotency key is the deduplication authority: a run matched\n // by its key joins even when the caller requested a different (still\n // unused) runId — the receipt carries the real id. The reverse is a\n // conflict: a run matched by ID whose stored key differs from the\n // provided one would silently bind the caller's key to nothing.\n if (\n options.idempotencyKey !== undefined &&\n existing.idempotency_key !== options.idempotencyKey\n ) {\n throw new Error(\n `Task run \"${existing.run_id}\" carries idempotency key ` +\n `${existing.idempotency_key === null ? \"none\" : `\"${existing.idempotency_key}\"`}; ` +\n `refusing to join it with conflicting key \"${options.idempotencyKey}\"`\n );\n }\n // A prior accept can throw after already durably inserting this row —\n // most likely here, on the wake mirror, rather than on the insert\n // itself — so a caller retrying the same runId or idempotencyKey\n // after a failure needs this join to repair a missing or stale\n // mirror, not just report accepted:false against a row nothing will\n // ever wake.\n // A prior accept can throw after already durably inserting this row —\n // most likely here, on the wake mirror, rather than on the insert\n // itself — so a caller retrying the same runId or idempotencyKey\n // after a failure needs this join to repair a missing or stale\n // mirror, not just report accepted:false against a row nothing will\n // ever wake.\n await this.#syncWake(existing.run_id);\n return {\n runId: existing.run_id,\n definition,\n accepted: false,\n state: existing.state,\n createdAt: existing.created_at\n };\n }\n\n const runId = options.runId ?? `task_${nanoid()}`;\n const now = Date.now();\n this.#store.sql`\n INSERT INTO cf_agents_task_runs\n (run_id, definition, input, state, metadata, idempotency_key, retain,\n attempt, next_at, cancel_requested, created_at, updated_at)\n VALUES\n (${runId}, ${definition}, ${inputJson}, 'pending', ${metadataJson},\n ${options.idempotencyKey ?? null}, ${options.retain === false ? 0 : 1},\n 0, ${now}, 0, ${now}, ${now})\n `;\n await this.#syncWake(runId);\n this.#emit(\"task:accepted\", { runId, definition, accepted: true });\n\n // Warm path: begin the first attempt immediately when the host is past\n // startup. The durable deadline above is authoritative either way.\n if (startMode === \"warm\" && !this.lifecycle.starting()) {\n void this.#executeRun(runId).catch(() => {});\n }\n\n return {\n runId,\n definition,\n accepted: true,\n state: \"pending\",\n createdAt: now\n };\n }\n\n // ── Execution ────────────────────────────────────────────────────────────\n\n /** Claim and drive one due run to its next durable boundary. */\n async #executeRun(runId: string): Promise<void> {\n if (this.#active.has(runId)) return;\n const row = this.#store.getRun(runId);\n if (!row || TERMINAL_STATES.has(row.state)) return;\n\n const now = Date.now();\n if (row.cancel_requested === 1) {\n await this.#settleCancelled(runId, null, row.cancel_reason ?? undefined);\n return;\n }\n if (row.next_at !== null && row.next_at > now) return;\n\n const handler = this.#resolveDefinition(row.definition);\n if (!handler) {\n const error = new MissingTaskDefinitionError(row.definition);\n console.error(error.message);\n await this.#settleFailed(runId, null, toErrorSummary(error));\n await this.#observeError(error);\n return;\n }\n\n // Unclean interruption: the previous attempt's isolate is gone. The\n // claim below replays the handler; completed steps return journaled\n // results, and the interrupted step rides `step.interrupted` as the\n // durable evidence the handler branches on.\n const interrupted =\n row.state === \"running\" ? this.#interruptedStep(runId) : null;\n if (row.state === \"running\") {\n this.#emit(\"task:attempt:interrupted\", {\n runId,\n definition: row.definition,\n attempt: row.attempt,\n step: interrupted?.name ?? null\n });\n }\n\n const generation = nanoid();\n const attempt = row.attempt + 1;\n this.#store.sql`\n UPDATE cf_agents_task_runs\n SET state = 'running', attempt = ${attempt}, generation = ${generation},\n started_at = coalesce(started_at, ${now}),\n next_at = ${now + this.#claimTimeoutMs()}, wait_reason = NULL,\n updated_at = ${now}\n WHERE run_id = ${runId}\n AND state IN ('pending', 'waiting', 'running')\n `;\n // Mirror the claim deadline before the handler runs, not after: a\n // routed run's root has no other way to learn it, and a push here\n // clears the queue row's in-flight marker, so it durably wins over a\n // root dispatch that later returns a stale outcome past its own\n // budget (job-queue's own \"newer pushes win\" guard on that marker).\n await this.#syncWake(runId);\n\n const controller = new AbortController();\n // Emitted before the handler starts: invocation is synchronous up to the\n // first await, so the first step event would otherwise precede this one.\n this.#emit(\"task:attempt:started\", {\n runId,\n definition: row.definition,\n attempt\n });\n const promise = this.#runAttempt(\n row,\n handler,\n generation,\n attempt,\n controller,\n interrupted,\n now\n );\n this.#active.set(runId, { generation, controller, promise });\n try {\n await promise;\n } finally {\n this.#active.delete(runId);\n }\n }\n\n /** Run one claimed attempt and persist its outcome, generation-fenced. */\n async #runAttempt(\n row: TaskRunRow,\n handler: TaskCallbacks[string],\n generation: string,\n attempt: number,\n controller: AbortController,\n interrupted: { name: string; attempt: number } | null,\n claimedAtMs: number\n ): Promise<void> {\n const runId = row.run_id;\n const input = deserializeTaskValue(row.input);\n const engine = this.#createEngine(\n runId,\n row.definition,\n generation,\n controller,\n claimedAtMs\n );\n const step = new ReplayStep(engine, {\n startsLive: attempt === 1,\n interrupted\n });\n\n try {\n const output = await this.lifecycle.runInHostContext(() =>\n handler(input, step)\n );\n const resultJson = serializeTaskValue(\n output,\n `result of Task definition \"${row.definition}\"`\n );\n const settled = this.#store.fencedWrite(\n runId,\n generation,\n `UPDATE cf_agents_task_runs\n SET state = 'completed', result = ?, generation = NULL, next_at = NULL,\n settled_at = ?, updated_at = ?\n WHERE run_id = ? AND generation = ? AND state = 'running'`,\n [resultJson, Date.now(), Date.now()]\n );\n if (settled) {\n this.#emit(\"task:completed\", { runId, definition: row.definition });\n await this.#finishTerminalSettlement(runId, row);\n }\n // Fence rejected: a newer generation owns the run, and every deadline\n // mutation it makes funnels through its own #syncWake — a push here\n // would be a redundant job-row write.\n } catch (thrown) {\n await this.#settleThrown(row, generation, thrown);\n }\n }\n\n /** Persist a non-completed attempt outcome. */\n async #settleThrown(\n row: TaskRunRow,\n generation: string,\n thrown: unknown\n ): Promise<void> {\n const runId = row.run_id;\n\n if (thrown instanceof AttemptSupersededError) {\n // A newer attempt owns the run; this one unwinds without settling.\n return;\n }\n\n if (isPlatformFailure(thrown)) {\n // Platform-class failure (superseded isolate, memory-limit reset,\n // storage transient): not an application outcome, so the run must not\n // settle. Unwind and rethrow — the claim backstop written at claim\n // time is the durable wake, and the next invocation reclaims and\n // replays the run; a queue-driven dispatch defers through the\n // driver's platform-failure path.\n throw thrown;\n }\n\n if (isTaskCancellation(thrown)) {\n await this.#settleCancelled(runId, generation, thrown.reason);\n return;\n }\n\n if (isTaskSuspension(thrown)) {\n // A cancel requested mid-attempt wins over parking the run.\n const current = this.#store.getRun(runId);\n if (current?.cancel_requested === 1) {\n await this.#settleCancelled(\n runId,\n generation,\n current.cancel_reason ?? undefined\n );\n return;\n }\n const suspended = this.#store.fencedWrite(\n runId,\n generation,\n `UPDATE cf_agents_task_runs\n SET state = 'waiting', wait_reason = ?, next_at = ?, generation = NULL,\n updated_at = ?\n WHERE run_id = ? AND generation = ? AND state = 'running'`,\n [thrown.reason, thrown.wakeAt, Date.now()]\n );\n if (suspended) {\n this.#emit(\"task:waiting\", {\n runId,\n definition: row.definition,\n reason: thrown.reason,\n wakeAt: thrown.wakeAt\n });\n await this.#syncWake(runId);\n }\n return;\n }\n\n const summary = toErrorSummary(thrown);\n const failed = await this.#settleFailed(runId, generation, summary);\n if (failed) {\n console.error(\n `Task run \"${runId}\" (definition \"${row.definition}\") failed: ${summary.name}: ${summary.message}`\n );\n }\n await this.#observeError(thrown);\n }\n\n async #observeError(error: unknown): Promise<void> {\n if (!this.#onError) return;\n try {\n // Observing terminal failures is host-facing user code: run it inside\n // the host invocation boundary, like definition handlers.\n await this.lifecycle.runInHostContext(() => this.#onError?.(error));\n } catch {\n // swallow onError errors\n }\n }\n\n // ── Step engine port ─────────────────────────────────────────────────────\n\n #createEngine(\n runId: string,\n definition: string,\n generation: string,\n controller: AbortController,\n claimedAtMs: number\n ): TaskStepEngine {\n return createTaskStepEngine({\n store: this.#store,\n runId,\n generation,\n signal: controller.signal,\n claimTimeoutMs: () => this.#claimTimeoutMs(),\n claimedAtMs,\n claimRefreshAfterMs: CLAIM_SLACK_MS / 2,\n defaults: this.#stepDefaults,\n emit: (type, payload) =>\n this.#emit(type as TaskEventType, { runId, definition, ...payload })\n });\n }\n\n /** The step a lost attempt left mid-execution — replay-entry evidence. */\n #interruptedStep(runId: string): { name: string; attempt: number } | null {\n const rows = this.#store.sql<{ step_name: string; attempt: number }>`\n SELECT step_name, attempt FROM cf_agents_task_steps\n WHERE run_id = ${runId} AND state = 'running'\n ORDER BY started_at DESC\n LIMIT 1\n `;\n return rows[0]\n ? { name: rows[0].step_name, attempt: rows[0].attempt }\n : null;\n }\n\n /**\n * Settle one run as cancelled and sync its queue mirror. Fenced when a\n * generation is supplied.\n */\n async #settleCancelled(\n runId: string,\n generation: string | null,\n reason: string | undefined\n ): Promise<void> {\n const now = Date.now();\n let settled: boolean;\n if (generation !== null) {\n settled = this.#store.fencedWrite(\n runId,\n generation,\n `UPDATE cf_agents_task_runs\n SET state = 'cancelled', cancel_requested = 1, cancel_reason = ?,\n generation = NULL, next_at = NULL, settled_at = ?, updated_at = ?\n WHERE run_id = ? AND generation = ?\n AND state = 'running'`,\n [reason ?? null, now, now]\n );\n } else {\n const written = this.#store.write(\n `UPDATE cf_agents_task_runs\n SET state = 'cancelled', cancel_requested = 1, cancel_reason = ?,\n generation = NULL, next_at = NULL, settled_at = ?, updated_at = ?\n WHERE run_id = ?\n AND state IN ('pending', 'waiting', 'running')`,\n [reason ?? null, now, now, runId]\n );\n settled = written > 0;\n }\n const row = settled ? this.#store.getRun(runId) : undefined;\n if (row) {\n this.#emit(\"task:cancelled\", {\n runId,\n definition: row.definition,\n reason: reason ?? null\n });\n await this.#finishTerminalSettlement(runId, row);\n }\n }\n\n /**\n * Settle one run as failed and sync its queue mirror. Fenced when a\n * generation is supplied.\n */\n async #settleFailed(\n runId: string,\n generation: string | null,\n error: { name: string; message: string }\n ): Promise<boolean> {\n const now = Date.now();\n let settled: boolean;\n if (generation !== null) {\n settled = this.#store.fencedWrite(\n runId,\n generation,\n `UPDATE cf_agents_task_runs\n SET state = 'failed', error_name = ?, error_message = ?,\n generation = NULL, next_at = NULL, settled_at = ?, updated_at = ?\n WHERE run_id = ? AND generation = ?\n AND state = 'running'`,\n [error.name, error.message, now, now]\n );\n } else {\n const written = this.#store.write(\n `UPDATE cf_agents_task_runs\n SET state = 'failed', error_name = ?, error_message = ?,\n generation = NULL, next_at = NULL, settled_at = ?, updated_at = ?\n WHERE run_id = ?\n AND state IN ('pending', 'waiting', 'running')`,\n [error.name, error.message, now, now, runId]\n );\n settled = written > 0;\n }\n const row = settled ? this.#store.getRun(runId) : undefined;\n if (row) {\n this.#emit(\"task:failed\", {\n runId,\n definition: row.definition,\n error: error.name\n });\n await this.#finishTerminalSettlement(runId, row);\n }\n return settled;\n }\n\n /** Apply terminal retention policy, then remove the run's wake mirror. */\n async #finishTerminalSettlement(\n runId: string,\n row: TaskRunRow | undefined\n ): Promise<void> {\n if (row?.retain === 0) this.#store.deleteRun(runId);\n await this.#syncWake(runId);\n }\n\n /** Make deadlines sane after a fresh isolate: interrupted work wakes now. */\n #reconcile(): void {\n const now = Date.now();\n // A fresh isolate has no live attempts, so every claimed row is an\n // interrupted attempt: make it due immediately for reclaim and replay.\n this.#store.sql`\n UPDATE cf_agents_task_runs SET next_at = ${now}, updated_at = ${now}\n WHERE state = 'running' AND generation IS NOT NULL\n `;\n // Non-terminal rows must always carry a deadline; repair any without one.\n this.#store.sql`\n UPDATE cf_agents_task_runs SET next_at = ${now}, updated_at = ${now}\n WHERE state IN ('pending', 'waiting') AND next_at IS NULL\n `;\n }\n\n // ── Snapshots ────────────────────────────────────────────────────────────\n\n async #snapshot<Output extends TaskValue>(\n runId: string,\n definition?: string\n ): Promise<TaskRunSnapshot<Output> | null> {\n await this.lifecycle.ready();\n const row = this.#store.getRun(runId);\n if (!row) return null;\n if (definition !== undefined && row.definition !== definition) return null;\n return this.#store.rowToSnapshot<Output>(row);\n }\n\n async #snapshotByKey<Output extends TaskValue>(\n idempotencyKey: string,\n definition?: string\n ): Promise<TaskRunSnapshot<Output> | null> {\n await this.lifecycle.ready();\n const row = this.#store.getRunByKey(idempotencyKey);\n if (!row) return null;\n if (definition !== undefined && row.definition !== definition) return null;\n return this.#store.rowToSnapshot<Output>(row);\n }\n\n #emit(type: TaskEventType | string, payload: Record<string, unknown>): void {\n this.lifecycle.events.emit(type, payload);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
|
|
2
|
+
import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
|
|
3
|
+
//#region src/chat/text-segment-joiner.ts
|
|
4
|
+
var _hasText = /* @__PURE__ */ new WeakMap();
|
|
5
|
+
var _lastTextEndedWithWhitespace = /* @__PURE__ */ new WeakMap();
|
|
6
|
+
var _needsBoundarySpace = /* @__PURE__ */ new WeakMap();
|
|
7
|
+
var _TextSegmentJoiner_brand = /* @__PURE__ */ new WeakSet();
|
|
8
|
+
/**
|
|
9
|
+
* @internal Converts structured stream chunks into text and boundary events
|
|
10
|
+
* without gluing words across non-text chunks. Sibling-package support for
|
|
11
|
+
* Voice and `@cloudflare/think`, not a public API.
|
|
12
|
+
*/
|
|
13
|
+
var TextSegmentJoiner = class {
|
|
14
|
+
constructor() {
|
|
15
|
+
_classPrivateMethodInitSpec(this, _TextSegmentJoiner_brand);
|
|
16
|
+
_classPrivateFieldInitSpec(this, _hasText, false);
|
|
17
|
+
_classPrivateFieldInitSpec(this, _lastTextEndedWithWhitespace, false);
|
|
18
|
+
_classPrivateFieldInitSpec(this, _needsBoundarySpace, false);
|
|
19
|
+
}
|
|
20
|
+
pushChunk(chunk) {
|
|
21
|
+
if (chunk.type === "text-delta") {
|
|
22
|
+
const text = textFromChunk(chunk);
|
|
23
|
+
return text ? _assertClassBrand(_TextSegmentJoiner_brand, this, _pushText).call(this, text) : [];
|
|
24
|
+
}
|
|
25
|
+
if (typeof chunk.type !== "string" || !_assertClassBrand(_TextSegmentJoiner_brand, this, _markBoundary).call(this)) return [];
|
|
26
|
+
return [{ type: "boundary" }];
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
function _markBoundary() {
|
|
30
|
+
if (!_classPrivateFieldGet2(_hasText, this) || _classPrivateFieldGet2(_needsBoundarySpace, this)) return false;
|
|
31
|
+
_classPrivateFieldSet2(_needsBoundarySpace, this, true);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
function _pushText(text) {
|
|
35
|
+
const events = [];
|
|
36
|
+
if (_classPrivateFieldGet2(_needsBoundarySpace, this) && !_classPrivateFieldGet2(_lastTextEndedWithWhitespace, this) && !/^\s/.test(text)) events.push({
|
|
37
|
+
type: "text",
|
|
38
|
+
text: " "
|
|
39
|
+
});
|
|
40
|
+
events.push({
|
|
41
|
+
type: "text",
|
|
42
|
+
text
|
|
43
|
+
});
|
|
44
|
+
_classPrivateFieldSet2(_hasText, this, true);
|
|
45
|
+
_classPrivateFieldSet2(_lastTextEndedWithWhitespace, this, /\s$/.test(text));
|
|
46
|
+
_classPrivateFieldSet2(_needsBoundarySpace, this, false);
|
|
47
|
+
return events;
|
|
48
|
+
}
|
|
49
|
+
function textFromChunk(chunk) {
|
|
50
|
+
if (typeof chunk.text === "string") return chunk.text;
|
|
51
|
+
if (typeof chunk.delta === "string") return chunk.delta;
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { TextSegmentJoiner as t };
|
|
56
|
+
|
|
57
|
+
//# sourceMappingURL=text-segment-joiner-BtAFQSA_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-segment-joiner-BtAFQSA_.js","names":[],"sources":["../src/chat/text-segment-joiner.ts"],"sourcesContent":["/** @internal A parsed structured-stream chunk accepted by the joiner. */\nexport interface TextSegmentChunk {\n delta?: unknown;\n text?: unknown;\n type?: unknown;\n}\n\n/** @internal A text or semantic boundary emitted by the joiner. */\nexport type TextSegmentEvent =\n | { type: \"text\"; text: string }\n | { type: \"boundary\" };\n\n/**\n * @internal Converts structured stream chunks into text and boundary events\n * without gluing words across non-text chunks. Sibling-package support for\n * Voice and `@cloudflare/think`, not a public API.\n */\nexport class TextSegmentJoiner {\n #hasText = false;\n #lastTextEndedWithWhitespace = false;\n #needsBoundarySpace = false;\n\n pushChunk(chunk: TextSegmentChunk): TextSegmentEvent[] {\n if (chunk.type === \"text-delta\") {\n const text = textFromChunk(chunk);\n return text ? this.#pushText(text) : [];\n }\n\n if (typeof chunk.type !== \"string\" || !this.#markBoundary()) return [];\n return [{ type: \"boundary\" }];\n }\n\n #markBoundary(): boolean {\n if (!this.#hasText || this.#needsBoundarySpace) return false;\n this.#needsBoundarySpace = true;\n return true;\n }\n\n #pushText(text: string): TextSegmentEvent[] {\n const events: TextSegmentEvent[] = [];\n if (\n this.#needsBoundarySpace &&\n !this.#lastTextEndedWithWhitespace &&\n !/^\\s/.test(text)\n ) {\n events.push({ type: \"text\", text: \" \" });\n }\n\n events.push({ type: \"text\", text });\n this.#hasText = true;\n this.#lastTextEndedWithWhitespace = /\\s$/.test(text);\n this.#needsBoundarySpace = false;\n return events;\n }\n}\n\nfunction textFromChunk(chunk: TextSegmentChunk): string | null {\n if (typeof chunk.text === \"string\") return chunk.text;\n if (typeof chunk.delta === \"string\") return chunk.delta;\n return null;\n}\n"],"mappings":";;;;;;;;;;;;AAiBA,IAAa,oBAAb,MAA+B;;;6CAClB,KAAA;iEACoB,KAAA;wDACT,KAAA;;CAEtB,UAAU,OAA6C;EACrD,IAAI,MAAM,SAAS,cAAc;GAC/B,MAAM,OAAO,cAAc,KAAK;GAChC,OAAO,OAAA,kBAAA,0BAAO,MAAA,SAAA,CAAA,CAAA,KAAA,MAAe,IAAI,IAAI,CAAC;EACxC;EAEA,IAAI,OAAO,MAAM,SAAS,YAAY,CAAA,kBAAA,0BAAC,MAAA,aAAA,CAAA,CAAA,KAAA,IAAmB,GAAG,OAAO,CAAC;EACrE,OAAO,CAAC,EAAE,MAAM,WAAW,CAAC;CAC9B;AAwBF;AAtBE,SAAA,gBAAyB;CACvB,IAAI,CAAA,uBAAA,UAAC,IAAA,KAAA,uBAAA,qBAAiB,IAAA,GAA0B,OAAO;CACvD,uBAAA,qBAAA,MAA2B,IAAA;CAC3B,OAAO;AACT;AAEA,SAAA,UAAU,MAAkC;CAC1C,MAAM,SAA6B,CAAC;CACpC,IAAA,uBAAA,qBACE,IAAA,KACA,CAAA,uBAAA,8BAAC,IAAA,KACD,CAAC,MAAM,KAAK,IAAI,GAEhB,OAAO,KAAK;EAAE,MAAM;EAAQ,MAAM;CAAI,CAAC;CAGzC,OAAO,KAAK;EAAE,MAAM;EAAQ;CAAK,CAAC;CAClC,uBAAA,UAAA,MAAgB,IAAA;CAChB,uBAAA,8BAAA,MAAoC,MAAM,KAAK,IAAI,CAAA;CACnD,uBAAA,qBAAA,MAA2B,KAAA;CAC3B,OAAO;AACT;AAGF,SAAS,cAAc,OAAwC;CAC7D,IAAI,OAAO,MAAM,SAAS,UAAU,OAAO,MAAM;CACjD,IAAI,OAAO,MAAM,UAAU,UAAU,OAAO,MAAM;CAClD,OAAO;AACT"}
|