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.
Files changed (186) hide show
  1. package/README.md +20 -1
  2. package/dist/{agent-routing-CnkaHb-v.d.ts → agent-routing-DE5zmCQ8.d.ts} +1038 -394
  3. package/dist/agent-routing.d.ts +1 -1
  4. package/dist/agent-tool-types.d.ts +26 -26
  5. package/dist/{agent-tools-C0XJqWzB.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
  6. package/dist/agent-tools.d.ts +21 -21
  7. package/dist/browser/ai.js +4 -1
  8. package/dist/browser/ai.js.map +1 -1
  9. package/dist/browser/tanstack-ai.js.map +1 -1
  10. package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
  11. package/dist/callable-decorator.d.ts +18 -0
  12. package/dist/callable-decorator.js +71 -0
  13. package/dist/callable-decorator.js.map +1 -0
  14. package/dist/capability-BjSKYpzg.js.map +1 -1
  15. package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
  16. package/dist/channel-Bnm4S7T2.d.ts +491 -0
  17. package/dist/channels/ai-sdk.d.ts +46 -0
  18. package/dist/channels/ai-sdk.js +120 -0
  19. package/dist/channels/ai-sdk.js.map +1 -0
  20. package/dist/channels/email.d.ts +95 -0
  21. package/dist/channels/email.js +323 -0
  22. package/dist/channels/email.js.map +1 -0
  23. package/dist/channels/index.d.ts +233 -0
  24. package/dist/channels/index.js +608 -0
  25. package/dist/channels/index.js.map +1 -0
  26. package/dist/channels/slack.d.ts +140 -0
  27. package/dist/channels/slack.js +614 -0
  28. package/dist/channels/slack.js.map +1 -0
  29. package/dist/channels/tanstack-ai.d.ts +39 -0
  30. package/dist/channels/tanstack-ai.js +17 -0
  31. package/dist/channels/tanstack-ai.js.map +1 -0
  32. package/dist/channels/telegram.d.ts +106 -0
  33. package/dist/channels/telegram.js +427 -0
  34. package/dist/channels/telegram.js.map +1 -0
  35. package/dist/channels/voice.d.ts +45 -0
  36. package/dist/channels/voice.js +122 -0
  37. package/dist/channels/voice.js.map +1 -0
  38. package/dist/chat/index.d.ts +2325 -2019
  39. package/dist/chat/index.js +888 -518
  40. package/dist/chat/index.js.map +1 -1
  41. package/dist/chat-sdk/index.d.ts +7 -7
  42. package/dist/chat-sdk/index.js +1 -1
  43. package/dist/client.d.ts +1 -1
  44. package/dist/context/index.d.ts +216 -0
  45. package/dist/context/index.js +454 -0
  46. package/dist/context/index.js.map +1 -0
  47. package/dist/{current-agent-CuMErtly.d.ts → current-agent-Da_C9a3b.d.ts} +90 -107
  48. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  49. package/dist/{diagnostics-CaBjfz4J.js → diagnostics-BzvaX2UT.js} +5 -1
  50. package/dist/diagnostics-BzvaX2UT.js.map +1 -0
  51. package/dist/diagnostics-C4jcz3VK.js +360 -0
  52. package/dist/diagnostics-C4jcz3VK.js.map +1 -0
  53. package/dist/index-BB0kqhIz.d.ts +101 -0
  54. package/dist/index-BVVgDSdq.d.ts +1 -0
  55. package/dist/index-XDkuQ7zm.d.ts +89 -0
  56. package/dist/{index-DcSAZKsB.d.ts → index-YSKgfgg9.d.ts} +3 -1
  57. package/dist/index.d.ts +91 -82
  58. package/dist/index.js +3 -2
  59. package/dist/ingress-BfetZbMO.js +83 -0
  60. package/dist/ingress-BfetZbMO.js.map +1 -0
  61. package/dist/internal-CYlgHl1l.js +59 -0
  62. package/dist/internal-CYlgHl1l.js.map +1 -0
  63. package/dist/internal_context.d.ts +1 -1
  64. package/dist/lifecycle/index.d.ts +35 -17
  65. package/dist/lifecycle/index.js +1 -1
  66. package/dist/lifecycle-CMRGjZdw.js +1299 -0
  67. package/dist/lifecycle-CMRGjZdw.js.map +1 -0
  68. package/dist/mcp/client/index.d.ts +20 -20
  69. package/dist/mcp/index.d.ts +35 -35
  70. package/dist/mcp/index.js +1 -1
  71. package/dist/observability/index.d.ts +1 -1
  72. package/dist/observability/index.js +1 -1
  73. package/dist/react.d.ts +4 -4
  74. package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
  75. package/dist/retries.d.ts +8 -6
  76. package/dist/retries.js +13 -1
  77. package/dist/retries.js.map +1 -1
  78. package/dist/routing/index.d.ts +137 -0
  79. package/dist/routing/index.js +244 -0
  80. package/dist/routing/index.js.map +1 -0
  81. package/dist/sanitize-D9TujEK8.js +79 -0
  82. package/dist/sanitize-D9TujEK8.js.map +1 -0
  83. package/dist/scheduler-DD9NdYbF.js +665 -0
  84. package/dist/scheduler-DD9NdYbF.js.map +1 -0
  85. package/dist/{scheduler-DQoTGoAW.d.ts → scheduler-Dwh85ZGl.d.ts} +21 -22
  86. package/dist/schedules/index.d.ts +1 -1
  87. package/dist/schedules/index.js +1 -1
  88. package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
  89. package/dist/serializable.d.ts +1 -1
  90. package/dist/sessions/index.d.ts +441 -0
  91. package/dist/sessions/index.js +2063 -0
  92. package/dist/sessions/index.js.map +1 -0
  93. package/dist/skills/index.d.ts +99 -0
  94. package/dist/skills/index.js +254 -5
  95. package/dist/skills/index.js.map +1 -1
  96. package/dist/{src-5W6JNKVb.js → src-DlSHshb2.js} +1460 -1110
  97. package/dist/src-DlSHshb2.js.map +1 -0
  98. package/dist/streams/index.d.ts +120 -0
  99. package/dist/streams/index.js +107 -0
  100. package/dist/streams/index.js.map +1 -0
  101. package/dist/streams-D6tJ0NN9.d.ts +370 -0
  102. package/dist/streams-DZKgAj9b.js +709 -0
  103. package/dist/streams-DZKgAj9b.js.map +1 -0
  104. package/dist/sub-routing.d.ts +12 -12
  105. package/dist/surface-bZZJqBka.js +17 -0
  106. package/dist/surface-bZZJqBka.js.map +1 -0
  107. package/dist/tasks/index.d.ts +64 -0
  108. package/dist/tasks/index.js +2 -0
  109. package/dist/tasks-BRJ5zgya.d.ts +517 -0
  110. package/dist/tasks-ylZgBjhj.js +1656 -0
  111. package/dist/tasks-ylZgBjhj.js.map +1 -0
  112. package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
  113. package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
  114. package/dist/text-stream-CpdiKrJB.js +272 -0
  115. package/dist/text-stream-CpdiKrJB.js.map +1 -0
  116. package/dist/tokens-nHAKcN6M.js +52 -0
  117. package/dist/tokens-nHAKcN6M.js.map +1 -0
  118. package/dist/tool-schema-CBjGPrsQ.js +31 -0
  119. package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
  120. package/dist/types-B7LojTe4.d.ts +202 -0
  121. package/dist/types-_Faxb570.d.ts +439 -0
  122. package/dist/voice/client.d.ts +226 -0
  123. package/dist/voice/client.js +932 -0
  124. package/dist/voice/client.js.map +1 -0
  125. package/dist/voice/errors.d.ts +43 -0
  126. package/dist/voice/errors.js +41 -0
  127. package/dist/voice/errors.js.map +1 -0
  128. package/dist/voice/index.d.ts +271 -0
  129. package/dist/voice/index.js +1812 -0
  130. package/dist/voice/index.js.map +1 -0
  131. package/dist/voice/react.d.ts +167 -0
  132. package/dist/voice/react.js +234 -0
  133. package/dist/voice/react.js.map +1 -0
  134. package/dist/voice/sfu.d.ts +71 -0
  135. package/dist/voice/sfu.js +157 -0
  136. package/dist/voice/sfu.js.map +1 -0
  137. package/dist/voice/text.d.ts +6 -0
  138. package/dist/voice/text.js +2 -0
  139. package/dist/voice/types.d.ts +58 -0
  140. package/dist/voice/types.js +18 -0
  141. package/dist/voice/types.js.map +1 -0
  142. package/dist/voice/workers-ai.d.ts +136 -0
  143. package/dist/voice/workers-ai.js +568 -0
  144. package/dist/voice/workers-ai.js.map +1 -0
  145. package/dist/websockets/index.d.ts +192 -0
  146. package/dist/websockets/index.js +2 -0
  147. package/dist/websockets-DUfRHPRq.js +502 -0
  148. package/dist/websockets-DUfRHPRq.js.map +1 -0
  149. package/dist/workflow-types.d.ts +25 -25
  150. package/dist/workflows.d.ts +21 -21
  151. package/dist/workflows.js +1 -1
  152. package/docs/agent-class.md +2 -2
  153. package/docs/agent-tools.md +2 -1
  154. package/docs/channels.md +323 -0
  155. package/docs/chat-agents.md +6 -13
  156. package/docs/context.md +131 -0
  157. package/docs/index.md +15 -12
  158. package/docs/lifecycle.md +102 -55
  159. package/docs/long-running-agents.md +2 -2
  160. package/docs/mcp-servers.md +5 -1
  161. package/docs/resumable-streaming.md +1 -1
  162. package/docs/routing.md +105 -0
  163. package/docs/sessions.md +237 -871
  164. package/docs/streams.md +213 -0
  165. package/docs/sub-agents.md +184 -124
  166. package/docs/tasks.md +246 -0
  167. package/docs/voice.md +745 -0
  168. package/package.json +115 -13
  169. package/dist/capability-runner-CvHGZqUu.d.ts +0 -150
  170. package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
  171. package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
  172. package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
  173. package/dist/diagnostics-CaBjfz4J.js.map +0 -1
  174. package/dist/durable-object-lifecycle-D6nNQJJd.js +0 -862
  175. package/dist/durable-object-lifecycle-D6nNQJJd.js.map +0 -1
  176. package/dist/experimental/memory/session/index.d.ts +0 -671
  177. package/dist/experimental/memory/session/index.js +0 -2379
  178. package/dist/experimental/memory/session/index.js.map +0 -1
  179. package/dist/experimental/memory/utils/index.d.ts +0 -96
  180. package/dist/experimental/memory/utils/index.js +0 -79
  181. package/dist/experimental/memory/utils/index.js.map +0 -1
  182. package/dist/scheduler-CR9RHGos.js +0 -857
  183. package/dist/scheduler-CR9RHGos.js.map +0 -1
  184. package/dist/src-5W6JNKVb.js.map +0 -1
  185. package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
  186. package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduler-CR9RHGos.js","names":[],"sources":["../src/schedules/schedule-timing.ts","../src/schedules/scheduler.ts"],"sourcesContent":["/**\n * Pure timing rules for persistent schedules.\n *\n * A `ScheduleTiming` is the parsed \"when and how it runs\" half of a\n * `Schedule` — everything except identity, callback, and payload. Parsing\n * user-facing inputs here keeps Scheduler's storage code to one insert path.\n */\n\nimport { parseCronExpression } from \"cron-schedule\";\n\n/** Longest allowed gap between interval executions: 30 days. */\nexport const MAX_INTERVAL_SECONDS = 30 * 24 * 60 * 60;\n\n/** When and how one schedule runs; a `Schedule` minus identity and payload. */\nexport type ScheduleTiming =\n | {\n /** One-time execution at a specific date. */\n readonly type: \"scheduled\";\n /** Unix timestamp in seconds. */\n readonly time: number;\n }\n | {\n /** One-time execution after a relative delay. */\n readonly type: \"delayed\";\n /** Unix timestamp in seconds. */\n readonly time: number;\n /** Delay from creation in seconds. */\n readonly delayInSeconds: number;\n }\n | {\n /** Recurring execution from a cron expression. */\n readonly type: \"cron\";\n /** Unix timestamp in seconds for the next execution. */\n readonly time: number;\n /** Cron expression defining the recurrence. */\n readonly cron: string;\n }\n | {\n /** Recurring execution at a fixed interval. */\n readonly type: \"interval\";\n /** Unix timestamp in seconds for the next execution. */\n readonly time: number;\n /** Number of seconds between executions. */\n readonly intervalSeconds: number;\n };\n\n/** True when this timing repeats and therefore deduplicates by default. */\nexport function isRecurring(timing: ScheduleTiming): boolean {\n return timing.type === \"cron\" || timing.type === \"interval\";\n}\n\n/**\n * Next wall-clock execution time for a cron expression.\n *\n * @param cron - A standard cron expression.\n * @param nowMs - Current epoch time in milliseconds.\n * @returns The next execution epoch time in milliseconds.\n * @throws For an unparseable cron expression.\n */\nexport function nextCronTimeMs(cron: string, nowMs: number): number {\n return parseCronExpression(cron).getNextDate(new Date(nowMs)).getTime();\n}\n\n/**\n * Parse a user-facing `when` into schedule timing.\n *\n * A `Date` runs once at that date, a number runs once after that many\n * seconds, and a string is a recurring cron expression.\n *\n * @param when - The requested execution time or recurrence.\n * @param nowMs - Current epoch time in milliseconds.\n * @param callback - Callback name, used only in error messages.\n * @returns The parsed timing.\n * @throws For a `when` value that is not a `Date`, number, or string.\n */\nexport function parseWhen(\n when: Date | string | number,\n nowMs: number,\n callback: string\n): ScheduleTiming {\n if (when instanceof Date) {\n return { type: \"scheduled\", time: Math.floor(when.getTime() / 1000) };\n }\n if (typeof when === \"number\") {\n return {\n type: \"delayed\",\n time: Math.floor((nowMs + when * 1000) / 1000),\n delayInSeconds: when\n };\n }\n if (typeof when === \"string\") {\n return {\n type: \"cron\",\n time: Math.floor(nextCronTimeMs(when, nowMs) / 1000),\n cron: when\n };\n }\n throw new Error(\n `Invalid schedule type: ${JSON.stringify(when)}(${typeof when}) trying to schedule ${callback}`\n );\n}\n\n/**\n * Reject an interval outside the supported range.\n *\n * @param intervalSeconds - The requested gap between executions.\n * @throws For a non-positive interval or one longer than 30 days.\n */\nexport function validateIntervalSeconds(intervalSeconds: number): void {\n if (typeof intervalSeconds !== \"number\" || intervalSeconds <= 0) {\n throw new Error(\"intervalSeconds must be a positive number\");\n }\n if (intervalSeconds > MAX_INTERVAL_SECONDS) {\n throw new Error(\n `intervalSeconds cannot exceed ${MAX_INTERVAL_SECONDS} seconds (30 days)`\n );\n }\n}\n\n/**\n * Parse a fixed interval into schedule timing.\n *\n * @param intervalSeconds - Seconds between executions.\n * @param nowMs - Current epoch time in milliseconds.\n * @returns The parsed timing with the first execution one interval from now.\n * @throws For an interval outside the supported range.\n */\nexport function parseInterval(\n intervalSeconds: number,\n nowMs: number\n): ScheduleTiming {\n validateIntervalSeconds(intervalSeconds);\n return {\n type: \"interval\",\n time: Math.floor((nowMs + intervalSeconds * 1000) / 1000),\n intervalSeconds\n };\n}\n","/**\n * Lifecycle scheduling primitive. Owns the `cf_agents_schedules` table,\n * callback retry policy, and due-row processing.\n *\n * Scheduler consumes only the standard capability services: storage, alarm\n * coordination, the host invocation boundary, events, and routing. Lifecycle combines\n * Scheduler's next wake-up candidate with contributions from other\n * capabilities and the host before arming the Durable Object.\n */\n\nimport { nanoid } from \"nanoid\";\nimport {\n LifecycleCapability,\n type LifecycleRouteAddress,\n type LifecycleRouteContext\n} from \"../lifecycle/capability\";\nimport {\n isDurableObjectCodeUpdateReset,\n isDurableObjectMemoryLimitReset,\n isPlatformTransientError,\n tryN,\n validateRetryOptions\n} from \"../retries\";\nimport type { RetryOptions } from \"../retries\";\nimport { SqlError } from \"../sql-error\";\nimport type { SchedulerEventType, SchedulerOptions } from \"./options\";\nimport {\n isRecurring,\n nextCronTimeMs,\n parseInterval,\n parseWhen,\n validateIntervalSeconds,\n type ScheduleTiming\n} from \"./schedule-timing\";\nimport type {\n Schedule,\n ScheduleCriteria,\n ScheduleOptions,\n ScheduleStorageRow,\n SchedulerCallbacks,\n SchedulerHandlers,\n SchedulerPayload\n} from \"./types\";\n\n/**\n * A resolved fallback handler for a callback name outside the registered map.\n */\ntype ResolvedSchedulerCallback = (\n payload: unknown,\n schedule: Schedule<unknown>\n) => unknown;\n\nconst schedulerCallbackResolvers = new WeakMap<\n object,\n (name: string) => ResolvedSchedulerCallback | undefined\n>();\n\n/**\n * @internal Supply a composition-root fallback for callback names outside the\n * registered map. Agent uses this to keep its historical name-based\n * scheduling API (`this.schedule(60, \"methodName\")`) working: the resolver\n * looks the method up on the Agent, and the resolved handler still runs\n * inside the Lifecycle host boundary.\n */\nexport function setSchedulerCallbackResolver(\n scheduler: Scheduler<never>,\n resolver: (name: string) => ResolvedSchedulerCallback | undefined\n): void {\n schedulerCallbackResolvers.set(scheduler, resolver);\n}\n\nconst SCHEDULE_SCHEMA_VERSION_KEY = \"cf_agents:schedules_schema_version\";\nconst CURRENT_SCHEDULE_SCHEMA_VERSION = 1;\n\nconst DEFAULT_RETRY: Required<RetryOptions> = {\n maxAttempts: 3,\n baseDelayMs: 100,\n maxDelayMs: 3000\n};\n\ntype SchedulerRouteMessage =\n | {\n readonly type: \"schedule\";\n readonly when: Date | string | number;\n readonly callback: string;\n readonly payload?: unknown;\n readonly options?: ScheduleOptions;\n }\n | {\n readonly type: \"every\";\n readonly intervalSeconds: number;\n readonly callback: string;\n readonly payload?: unknown;\n readonly options?: ScheduleOptions;\n }\n | { readonly type: \"get\" | \"cancel\"; readonly id: string }\n | { readonly type: \"list\"; readonly criteria?: ScheduleCriteria }\n | { readonly type: \"dispatch\"; readonly row: ScheduleStorageRow };\n\ntype InsertResult<T> = {\n readonly schedule: Schedule<T>;\n readonly created: boolean;\n};\n\nfunction parseRetryOptions(row: ScheduleStorageRow): RetryOptions | undefined {\n return typeof row.retry_options === \"string\"\n ? (JSON.parse(row.retry_options) as RetryOptions)\n : undefined;\n}\n\nfunction resolveRetryConfig(\n retry: RetryOptions | undefined,\n defaults: Required<RetryOptions>\n): Required<RetryOptions> {\n return {\n maxAttempts: retry?.maxAttempts ?? defaults.maxAttempts,\n baseDelayMs: retry?.baseDelayMs ?? defaults.baseDelayMs,\n maxDelayMs: retry?.maxDelayMs ?? defaults.maxDelayMs\n };\n}\n\n/**\n * @internal Create or migrate the schedule table. Idempotent. Shared with\n * Agent's constructor-time schema initialization so a brand-new Agent\n * exposes the table before Lifecycle startup completes, exactly as it did\n * before Scheduler was extracted; {@link Scheduler.onStart} applies the\n * same migration for plain Lifecycle Objects.\n */\nexport function ensureScheduleTable(storage: DurableObjectStorage): void {\n const rawSql = (query: string, ...params: (string | number | null)[]) =>\n storage.sql.exec(query, ...params);\n\n // The literal whitespace below is load-bearing: sqlite_master stores the\n // statement text verbatim, and the schema DDL snapshot test pins it, so the\n // stored DDL must stay byte-identical to what Agent created historically.\n rawSql(`\n CREATE TABLE IF NOT EXISTS cf_agents_schedules (\n id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),\n callback TEXT,\n payload TEXT,\n type TEXT NOT NULL CHECK(type IN ('scheduled', 'delayed', 'cron', 'interval')),\n time INTEGER,\n delayInSeconds INTEGER,\n cron TEXT,\n intervalSeconds INTEGER,\n running INTEGER DEFAULT 0,\n created_at INTEGER DEFAULT (unixepoch()),\n execution_started_at INTEGER,\n retry_options TEXT,\n owner_path TEXT,\n owner_path_key TEXT\n )\n `);\n\n const addColumnIfMissing = (statement: string): void => {\n try {\n rawSql(statement);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (!message.toLowerCase().includes(\"duplicate column\")) throw error;\n }\n };\n addColumnIfMissing(\n \"ALTER TABLE cf_agents_schedules ADD COLUMN intervalSeconds INTEGER\"\n );\n addColumnIfMissing(\n \"ALTER TABLE cf_agents_schedules ADD COLUMN running INTEGER DEFAULT 0\"\n );\n addColumnIfMissing(\n \"ALTER TABLE cf_agents_schedules ADD COLUMN execution_started_at INTEGER\"\n );\n addColumnIfMissing(\n \"ALTER TABLE cf_agents_schedules ADD COLUMN retry_options TEXT\"\n );\n addColumnIfMissing(\n \"ALTER TABLE cf_agents_schedules ADD COLUMN owner_path TEXT\"\n );\n addColumnIfMissing(\n \"ALTER TABLE cf_agents_schedules ADD COLUMN owner_path_key TEXT\"\n );\n\n const rows = rawSql(\n \"SELECT sql FROM sqlite_master WHERE type='table' AND name='cf_agents_schedules'\"\n ).toArray();\n const ddl = typeof rows[0]?.sql === \"string\" ? rows[0].sql : \"\";\n if (ddl && !ddl.includes(\"'interval'\")) {\n rawSql(\"DROP TABLE IF EXISTS cf_agents_schedules_new\");\n rawSql(`\n CREATE TABLE cf_agents_schedules_new (\n id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),\n callback TEXT,\n payload TEXT,\n type TEXT NOT NULL CHECK(type IN ('scheduled', 'delayed', 'cron', 'interval')),\n time INTEGER,\n delayInSeconds INTEGER,\n cron TEXT,\n intervalSeconds INTEGER,\n running INTEGER DEFAULT 0,\n created_at INTEGER DEFAULT (unixepoch()),\n execution_started_at INTEGER,\n retry_options TEXT,\n owner_path TEXT,\n owner_path_key TEXT\n )\n `);\n rawSql(`\n INSERT INTO cf_agents_schedules_new\n (id, callback, payload, type, time, delayInSeconds, cron,\n intervalSeconds, running, created_at, execution_started_at,\n retry_options, owner_path, owner_path_key)\n SELECT id, callback, payload, type, time, delayInSeconds, cron,\n intervalSeconds, running, created_at, execution_started_at,\n retry_options, owner_path, owner_path_key\n FROM cf_agents_schedules\n `);\n rawSql(\"DROP TABLE cf_agents_schedules\");\n rawSql(\"ALTER TABLE cf_agents_schedules_new RENAME TO cf_agents_schedules\");\n }\n\n // Keep-alive no longer uses schedule rows. Remove orphaned heartbeat rows\n // left by older Scheduler versions.\n rawSql(\n \"DELETE FROM cf_agents_schedules WHERE callback = '_cf_keepAliveHeartbeat'\"\n );\n}\n\n/**\n * Persistent task scheduling for a Lifecycle Object.\n *\n * Register callbacks in the constructor and install the instance with\n * `Lifecycle.use()`. Scheduler owns its SQL schema, task CRUD, callback\n * retries, and due-row processing. It contributes its next wake time while\n * Lifecycle owns the physical alarm, and it runs registered callbacks\n * through Lifecycle's host invocation boundary.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class Scheduler<\n Handlers extends SchedulerHandlers = SchedulerCallbacks\n> extends LifecycleCapability {\n readonly #handlers: SchedulerHandlers;\n readonly #retryDefaults: Required<RetryOptions>;\n readonly #hungScheduleTimeoutSeconds: number;\n readonly #onError: ((error: unknown) => void | Promise<void>) | undefined;\n readonly #warnedStartupCallbacks = new Set<string>();\n #executingRowId: string | undefined;\n\n /**\n * Create a persistent Scheduler.\n *\n * @param options - Registered callbacks plus optional retry,\n * hung-interval, and error policy. Registering `callbacks` types\n * {@link set} and {@link every} against the map — names and\n * payloads are checked where the handlers are declared and where they are\n * scheduled. Names outside the map are rejected unless a composition-root\n * resolver supplies them — the internal aperture behind `Agent`'s\n * name-based scheduling API.\n */\n constructor(options: SchedulerOptions<Handlers> = {}) {\n super(\"scheduler\");\n this.#handlers = options.callbacks ?? {};\n // Retry defaults are resolved, not validated, here: a host whose\n // historically tolerated invalid retry config throws at construction\n // would brick every entry point of its Durable Object. Invalid defaults\n // surface per execution as schedule:error instead, and per-schedule\n // retry overrides are still validated when each schedule is created.\n this.#retryDefaults = resolveRetryConfig(options.retry, DEFAULT_RETRY);\n this.#hungScheduleTimeoutSeconds = options.hungScheduleTimeoutSeconds ?? 30;\n this.#onError = options.onError;\n }\n\n // ── Lifecycle capability hooks ───────────────────────────────────────────\n\n /** Initialize and migrate schedule storage during Lifecycle startup. */\n async onStart(): Promise<void> {\n this.#warnedStartupCallbacks.clear();\n const storage = this.lifecycle.storage;\n const version =\n (await storage.get<number>(SCHEDULE_SCHEMA_VERSION_KEY)) ?? 0;\n if (version >= CURRENT_SCHEDULE_SCHEMA_VERSION) return;\n\n ensureScheduleTable(this.lifecycle.storage);\n await storage.put(\n SCHEDULE_SCHEMA_VERSION_KEY,\n CURRENT_SCHEDULE_SCHEMA_VERSION\n );\n }\n\n /** Execute due schedule rows during the Lifecycle alarm phase. */\n async onAlarm(): Promise<void> {\n await this.#fireDueSchedules();\n }\n\n /** Handle Scheduler protocol messages routed by another Lifecycle. */\n async onRoute(context: LifecycleRouteContext): Promise<unknown> {\n const message = context.payload as SchedulerRouteMessage;\n const owner = context.source ?? null;\n switch (message.type) {\n case \"schedule\":\n return this.#insert(\n owner,\n parseWhen(message.when, Date.now(), message.callback),\n message.callback,\n message.payload,\n message.options\n );\n case \"every\":\n return this.#insert(\n owner,\n parseInterval(message.intervalSeconds, Date.now()),\n message.callback,\n message.payload,\n message.options\n );\n case \"get\":\n return this.#getForOwner(owner, message.id);\n case \"list\":\n return this.#listForOwner(owner, message.criteria);\n case \"cancel\":\n return this.#cancelForOwner(owner, message.id);\n case \"dispatch\":\n await this.#executeCallback(message.row);\n return true;\n default:\n throw new Error(\"Unknown routed Scheduler message\");\n }\n }\n\n /** Contribute the earliest pending schedule to Lifecycle alarm selection. */\n getNextAlarm(): number | null {\n const nowMs = Date.now();\n const hungCutoffSeconds =\n Math.floor(nowMs / 1000) - this.#hungScheduleTimeoutSeconds;\n const nextSchedule = this.#nextScheduleTimeMs(nowMs, hungCutoffSeconds);\n const hungIntervalRecheck =\n this.#nextHungIntervalRecheckMs(hungCutoffSeconds);\n if (nextSchedule === null) return hungIntervalRecheck;\n if (hungIntervalRecheck === null) return nextSchedule;\n return Math.min(nextSchedule, hungIntervalRecheck);\n }\n\n // ── Scheduling API ───────────────────────────────────────────────────────\n\n /** Set a delayed, dated, or cron schedule for a registered callback. */\n async set<Name extends keyof Handlers & string>(\n when: Date | string | number,\n callback: Name,\n payload?: SchedulerPayload<Handlers[Name]>,\n options?: ScheduleOptions\n ): Promise<Schedule<SchedulerPayload<Handlers[Name]>>> {\n await this.lifecycle.ready();\n this.#validateSchedule(when, callback, options);\n const result = this.lifecycle.routes.source\n ? ((await this.lifecycle.routes.toRoot({\n type: \"schedule\",\n when,\n callback,\n payload,\n options\n } satisfies SchedulerRouteMessage)) as InsertResult<\n SchedulerPayload<Handlers[Name]>\n >)\n : await this.#insert<SchedulerPayload<Handlers[Name]>>(\n null,\n parseWhen(when, Date.now(), callback),\n callback,\n payload,\n options\n );\n this.#emitCreated(result);\n return result.schedule;\n }\n\n /** Set a fixed-interval schedule for a registered callback. */\n async every<Name extends keyof Handlers & string>(\n intervalSeconds: number,\n callback: Name,\n payload?: SchedulerPayload<Handlers[Name]>,\n options?: ScheduleOptions\n ): Promise<Schedule<SchedulerPayload<Handlers[Name]>>> {\n await this.lifecycle.ready();\n this.#validateInterval(intervalSeconds, callback, options?.retry);\n const result = this.lifecycle.routes.source\n ? ((await this.lifecycle.routes.toRoot({\n type: \"every\",\n intervalSeconds,\n callback,\n payload,\n options\n } satisfies SchedulerRouteMessage)) as InsertResult<\n SchedulerPayload<Handlers[Name]>\n >)\n : await this.#insert<SchedulerPayload<Handlers[Name]>>(\n null,\n parseInterval(intervalSeconds, Date.now()),\n callback,\n payload,\n options\n );\n this.#emitCreated(result);\n return result.schedule;\n }\n\n /** Get a schedule by ID. Works inside routed sub-agents. */\n async get(id: string): Promise<Schedule<unknown> | undefined> {\n await this.lifecycle.ready();\n return this.lifecycle.routes.source\n ? ((await this.lifecycle.routes.toRoot({\n type: \"get\",\n id\n } satisfies SchedulerRouteMessage)) as Schedule<unknown> | undefined)\n : this.#getForOwner(null, id);\n }\n\n /** List schedules matching criteria. Works inside routed sub-agents. */\n async list(criteria: ScheduleCriteria = {}): Promise<Schedule<unknown>[]> {\n await this.lifecycle.ready();\n return this.lifecycle.routes.source\n ? ((await this.lifecycle.routes.toRoot({\n type: \"list\",\n criteria\n } satisfies SchedulerRouteMessage)) as Schedule<unknown>[])\n : this.#listForOwner(null, criteria);\n }\n\n /**\n * Cancel one schedule owned by this Scheduler.\n *\n * @param id - ID of the schedule to cancel.\n * @returns True when a schedule was cancelled, false when none matched.\n */\n async cancel(id: string): Promise<boolean> {\n await this.lifecycle.ready();\n const result = this.lifecycle.routes.source\n ? ((await this.lifecycle.routes.toRoot({\n type: \"cancel\",\n id\n } satisfies SchedulerRouteMessage)) as {\n ok: boolean;\n callback?: string;\n })\n : await this.#cancelForOwner(null, id);\n if (result.ok && result.callback) {\n this.#emit(\"schedule:cancel\", { callback: result.callback, id });\n }\n return result.ok;\n }\n\n // ── Host-owned policy apertures ──────────────────────────────────────────\n\n /**\n * @internal Synchronous read backing Agent's deprecated `getSchedule()`.\n * Not part of the primitive's contract — use {@link get}. Cannot cross\n * Durable Object boundaries and throws inside routed sub-agents.\n */\n __DO_NOT_USE_WILL_REMOVE__getSchedule<T = string>(\n id: string\n ): Schedule<T> | undefined {\n if (this.lifecycle.routes.source) {\n throw new Error(\n \"getSchedule() is synchronous and cannot read routed schedule storage. \" +\n \"Use await getScheduleById(id) on Agent, or await scheduler.get(id) \" +\n \"on a standalone Scheduler.\"\n );\n }\n return this.#getForOwner(null, id);\n }\n\n /**\n * @internal Synchronous read backing Agent's deprecated `getSchedules()`.\n * Not part of the primitive's contract — use {@link list}. Cannot cross\n * Durable Object boundaries and throws inside routed sub-agents.\n */\n __DO_NOT_USE_WILL_REMOVE__getSchedules<T = string>(\n criteria: ScheduleCriteria = {}\n ): Schedule<T>[] {\n if (this.lifecycle.routes.source) {\n throw new Error(\n \"getSchedules() is synchronous and cannot read routed schedule storage. \" +\n \"Use await listSchedules(criteria) on Agent, or await \" +\n \"scheduler.list(criteria) on a standalone Scheduler.\"\n );\n }\n return this.#listForOwner(null, criteria);\n }\n\n /** @internal Remove rows owned by one routed Lifecycle subtree. */\n __DO_NOT_USE_WILL_BREAK__cleanupRoutePrefix(prefix: string): void {\n this.#cancelOwners(\n (owner) => owner.key === prefix || owner.key.startsWith(`${prefix}/`)\n );\n }\n\n /** @internal Apply Agent's outer alarm memory-limit policy to Scheduler rows. */\n __DO_NOT_USE_WILL_BREAK__handleAlarmMemoryLimit(options: {\n readonly callbacks: ReadonlyArray<string>;\n readonly sealed: boolean;\n readonly nextTime?: number;\n }): void {\n const executingRowId = this.#executingRowId;\n this.#executingRowId = undefined;\n if (options.sealed) {\n this.#deleteRows(options.callbacks, executingRowId);\n return;\n }\n if (options.nextTime === undefined) {\n throw new Error(\"Scheduler memory-limit backoff requires nextTime\");\n }\n this.#moveRows(options.callbacks, executingRowId, options.nextTime);\n }\n\n // ── Validation ───────────────────────────────────────────────────────────\n\n #validateSchedule(\n when: Date | string | number,\n callback: string,\n options?: ScheduleOptions\n ): void {\n if (typeof callback !== \"string\") {\n throw new Error(\"Callback must be a string\");\n }\n if (!this.#hasCallback(callback)) {\n throw new Error(\n `Unknown scheduled callback \"${callback}\": not registered on this Scheduler`\n );\n }\n if (options?.retry) {\n validateRetryOptions(options.retry, this.#retryDefaults);\n }\n if (\n !(when instanceof Date) &&\n typeof when !== \"number\" &&\n typeof when !== \"string\"\n ) {\n throw new Error(\n `Invalid schedule type: ${JSON.stringify(when)}(${typeof when}) trying to schedule ${callback}`\n );\n }\n this.#warnWhenScheduledDuringStartup(when, callback, options);\n }\n\n #validateInterval(\n intervalSeconds: number,\n callback: string,\n retry?: RetryOptions\n ): void {\n validateIntervalSeconds(intervalSeconds);\n if (typeof callback !== \"string\") {\n throw new Error(\"Callback must be a string\");\n }\n if (!this.#hasCallback(callback)) {\n throw new Error(\n `Unknown scheduled callback \"${callback}\": not registered on this Scheduler`\n );\n }\n if (retry) validateRetryOptions(retry, this.#retryDefaults);\n }\n\n /**\n * A non-idempotent one-shot created during startup accumulates one row per\n * Durable Object wake, whether it came from the host's onStart or another\n * startup hook. Warn once per callback; an explicit `idempotent` choice\n * (either value) opts out.\n */\n #warnWhenScheduledDuringStartup(\n when: Date | string | number,\n callback: string,\n options?: ScheduleOptions\n ): void {\n if (!this.lifecycle.starting()) return;\n if (options?.idempotent !== undefined) return;\n if (typeof when === \"string\") return;\n if (this.#warnedStartupCallbacks.has(callback)) return;\n this.#warnedStartupCallbacks.add(callback);\n console.warn(\n `Scheduling \"${callback}\" during startup (e.g. onStart()) without ` +\n `{ idempotent: true } creates a new row on every Durable Object ` +\n `restart, which can cause duplicate executions. Pass ` +\n `{ idempotent: true } to deduplicate, or use an interval schedule ` +\n `for recurring tasks.`\n );\n }\n\n /** Resolve a name to its registered or composition-root-supplied handler. */\n #resolveCallback(name: string): ResolvedSchedulerCallback | undefined {\n const handler = this.#handlers[name];\n if (handler) {\n // SAFETY: registered handlers are constrained with `never` parameters\n // so concrete handler types satisfy the map under contravariance; the\n // payload passed at dispatch was parsed from the row this handler's\n // name was persisted with.\n return handler as ResolvedSchedulerCallback;\n }\n return schedulerCallbackResolvers.get(this)?.(name);\n }\n\n /** True when a name resolves to a runnable callback. */\n #hasCallback(name: string): boolean {\n return this.#resolveCallback(name) !== undefined;\n }\n\n /** Run one resolved callback inside the host invocation boundary. */\n async #invokeCallback(\n name: string,\n payload: unknown,\n schedule: Schedule<unknown>\n ): Promise<void> {\n const handler = this.#resolveCallback(name);\n if (!handler) {\n throw new Error(`Unknown scheduled callback \"${name}\"`);\n }\n await this.lifecycle.runInHostContext(() => handler(payload, schedule));\n }\n\n // ── Storage ──────────────────────────────────────────────────────────────\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: Scheduler queries select from its own schema; T describes the\n // projected columns of the accompanying query text.\n return [...this.lifecycle.storage.sql.exec(query, ...values)] as T[];\n } catch (cause) {\n throw new SqlError(query, cause);\n }\n }\n\n /**\n * Insert a schedule row for the given owner, or return the existing row\n * when an idempotent request matches one. One-shot timings deduplicate only\n * when `idempotent: true` is passed; recurring timings deduplicate unless\n * `idempotent: false` opts out. `created: false` marks a dedup hit so\n * callers suppress the `schedule:create` event.\n */\n async #insert<T = string>(\n owner: LifecycleRouteAddress | null,\n timing: ScheduleTiming,\n callback: string,\n payload: unknown,\n options?: ScheduleOptions\n ): Promise<InsertResult<T>> {\n const payloadJson = JSON.stringify(payload);\n // Recurring timings deduplicate unless explicitly opted out; one-shot\n // timings deduplicate on any truthy value (historic Agent behavior).\n const idempotent = isRecurring(timing)\n ? options?.idempotent !== false\n : Boolean(options?.idempotent);\n\n if (idempotent) {\n const existing = this.#findMatchingRow(\n owner?.key ?? null,\n timing,\n callback,\n payloadJson\n );\n if (existing) {\n await this.lifecycle.alarms.rearm();\n return { schedule: this.#rowToSchedule<T>(existing), created: false };\n }\n }\n\n const id = nanoid(9);\n this.#sql`\n INSERT OR REPLACE INTO cf_agents_schedules\n (id, callback, payload, type, time, delayInSeconds, cron,\n intervalSeconds, running, retry_options, owner_path, owner_path_key)\n VALUES\n (${id}, ${callback}, ${payloadJson}, ${timing.type}, ${timing.time},\n ${timing.type === \"delayed\" ? timing.delayInSeconds : null},\n ${timing.type === \"cron\" ? timing.cron : null},\n ${timing.type === \"interval\" ? timing.intervalSeconds : null},\n 0,\n ${options?.retry ? JSON.stringify(options.retry) : null},\n ${owner?.data ?? null}, ${owner?.key ?? null})\n `;\n await this.lifecycle.alarms.rearm();\n\n return {\n schedule: {\n id,\n callback,\n // SAFETY: payload is optional at the call site; historical API shape\n // types an omitted payload as the schedule's payload type.\n payload: payload as T,\n retry: options?.retry,\n ...timing\n },\n created: true\n };\n }\n\n /** Find the row an idempotent insert deduplicates onto, if any. */\n #findMatchingRow(\n ownerKey: string | null,\n timing: ScheduleTiming,\n callback: string,\n payloadJson: string\n ): ScheduleStorageRow | undefined {\n let query =\n \"SELECT * FROM cf_agents_schedules \" +\n \"WHERE type = ? AND callback = ? AND payload IS ? AND owner_path_key IS ?\";\n const params: (string | number | null)[] = [\n timing.type,\n callback,\n payloadJson,\n ownerKey\n ];\n if (timing.type === \"cron\") {\n query += \" AND cron = ?\";\n params.push(timing.cron);\n }\n if (timing.type === \"interval\") {\n query += \" AND intervalSeconds = ?\";\n params.push(timing.intervalSeconds);\n }\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 Scheduler's own schema.\n return rows[0] as ScheduleStorageRow | undefined;\n }\n\n #rowToSchedule<T>(row: ScheduleStorageRow): Schedule<T> {\n const base = {\n callback: row.callback,\n id: row.id,\n payload: JSON.parse(row.payload) as T,\n retry: parseRetryOptions(row)\n };\n\n switch (row.type) {\n case \"scheduled\":\n return { ...base, time: row.time, type: \"scheduled\" };\n case \"delayed\":\n return {\n ...base,\n delayInSeconds: row.delayInSeconds ?? 0,\n time: row.time,\n type: \"delayed\"\n };\n case \"cron\":\n return { ...base, cron: row.cron ?? \"\", time: row.time, type: \"cron\" };\n case \"interval\":\n return {\n ...base,\n intervalSeconds: row.intervalSeconds ?? 0,\n time: row.time,\n type: \"interval\"\n };\n }\n }\n\n #getForOwner<T = string>(\n owner: LifecycleRouteAddress | null,\n id: string\n ): Schedule<T> | undefined {\n const ownerPathKey = owner?.key ?? null;\n const result = this.#sql<ScheduleStorageRow>`\n SELECT * FROM cf_agents_schedules\n WHERE id = ${id} AND owner_path_key IS ${ownerPathKey}\n `;\n if (result.length === 0) return undefined;\n return this.#rowToSchedule<T>(result[0]);\n }\n\n #listForOwner<T = string>(\n owner: LifecycleRouteAddress | null,\n criteria: ScheduleCriteria = {}\n ): Schedule<T>[] {\n let query = \"SELECT * FROM cf_agents_schedules WHERE owner_path_key IS ?\";\n const params: Array<string | number | null> = [owner?.key ?? null];\n\n if (criteria.id) {\n query += \" AND id = ?\";\n params.push(criteria.id);\n }\n if (criteria.type) {\n query += \" AND type = ?\";\n params.push(criteria.type);\n }\n if (criteria.timeRange) {\n query += \" AND time >= ? AND time <= ?\";\n const start = criteria.timeRange.start || new Date(0);\n const end = criteria.timeRange.end || new Date(999999999999999);\n params.push(\n Math.floor(start.getTime() / 1000),\n Math.floor(end.getTime() / 1000)\n );\n }\n\n return this.lifecycle.storage.sql\n .exec(query, ...params)\n .toArray()\n .map((row) =>\n // SAFETY: the query selects * from Scheduler's own schema.\n this.#rowToSchedule<T>(row as unknown as ScheduleStorageRow)\n );\n }\n\n async #cancelForOwner(\n owner: LifecycleRouteAddress | null,\n id: string\n ): Promise<{ ok: boolean; callback?: string }> {\n const ownerPathKey = owner?.key ?? null;\n const result = this.#sql<ScheduleStorageRow>`\n SELECT * FROM cf_agents_schedules\n WHERE id = ${id} AND owner_path_key IS ${ownerPathKey}\n `;\n if (result.length === 0) return { ok: false };\n\n const callback = result[0].callback;\n this.#sql`\n DELETE FROM cf_agents_schedules\n WHERE id = ${id} AND owner_path_key IS ${ownerPathKey}\n `;\n await this.lifecycle.alarms.rearm();\n return { ok: true, callback };\n }\n\n /** Cancel every owned row matched by a route-address predicate. */\n #cancelOwners(matches: (owner: LifecycleRouteAddress) => boolean): void {\n const rows = this.#sql<ScheduleStorageRow>`\n SELECT * FROM cf_agents_schedules\n WHERE owner_path IS NOT NULL\n `;\n for (const row of rows) {\n if (\n !row.owner_path ||\n !matches({\n key: row.owner_path_key ?? row.owner_path,\n data: row.owner_path\n })\n )\n continue;\n this.#emit(\"schedule:cancel\", { callback: row.callback, id: row.id });\n this.#sql`DELETE FROM cf_agents_schedules WHERE id = ${row.id}`;\n }\n }\n\n /** Delete rows selected by a host-owned failure policy. Best-effort. */\n #deleteRows(callbacks: ReadonlyArray<string>, executingRowId?: string): void {\n for (const callback of callbacks) {\n try {\n this.#sql`\n DELETE FROM cf_agents_schedules WHERE callback = ${callback}\n `;\n } catch {\n // best-effort at a host failure boundary\n }\n }\n if (executingRowId) {\n try {\n this.#sql`\n DELETE FROM cf_agents_schedules WHERE id = ${executingRowId}\n `;\n } catch {\n // best-effort at a host failure boundary\n }\n }\n }\n\n /** Delay rows selected by a host-owned failure policy. Best-effort. */\n #moveRows(\n callbacks: ReadonlyArray<string>,\n executingRowId: string | undefined,\n nextTime: number\n ): void {\n for (const callback of callbacks) {\n try {\n this.#sql`\n UPDATE cf_agents_schedules\n SET time = ${nextTime}\n WHERE callback = ${callback} AND time <= ${nextTime}\n `;\n } catch {\n // best-effort at a host failure boundary\n }\n }\n if (executingRowId) {\n try {\n this.#sql`\n UPDATE cf_agents_schedules\n SET time = ${nextTime}\n WHERE id = ${executingRowId} AND time <= ${nextTime}\n `;\n } catch {\n // best-effort at a host failure boundary\n }\n }\n }\n\n // ── Execution ────────────────────────────────────────────────────────────\n\n #emit(type: SchedulerEventType, payload: Record<string, unknown>): void {\n this.lifecycle.events.emit(type, payload);\n }\n\n #emitCreated(result: InsertResult<unknown>): void {\n if (!result.created) return;\n this.#emit(\"schedule:create\", {\n callback: result.schedule.callback,\n id: result.schedule.id\n });\n }\n\n /**\n * Execute a local schedule row with retry handling.\n *\n * The capability remains outside ambient context. Lifecycle's host\n * invocation boundary establishes host context only around the user\n * callback itself.\n */\n async #executeCallback(row: ScheduleStorageRow): Promise<void> {\n if (!this.#hasCallback(row.callback)) {\n console.error(`callback ${row.callback} not found`);\n return;\n }\n\n const { maxAttempts, baseDelayMs, maxDelayMs } = resolveRetryConfig(\n parseRetryOptions(row),\n this.#retryDefaults\n );\n\n let parsedPayload: unknown;\n try {\n parsedPayload = JSON.parse(row.payload);\n } catch (error) {\n console.error(\n `Failed to parse payload for schedule \"${row.id}\" (callback \"${row.callback}\")`,\n error\n );\n this.#emit(\"schedule:error\", {\n callback: row.callback,\n id: row.id,\n error: error instanceof Error ? error.message : String(error),\n attempts: 0\n });\n return;\n }\n\n // A one-shot row is deleted by the alarm phase once this returns\n // normally. If it fails with a superseded-isolate error (a deploy / code\n // update replaced the isolate — \"reset because its code was updated\" or\n // \"this script has been upgraded\"), burning in-process retries is futile\n // (code never reloads mid-invocation) and swallowing the error would let\n // the alarm phase delete the row. Re-throw platform transients so the\n // durable alarm can retry the preserved row on a fresh invocation.\n const isOneShotSchedule =\n row.type === \"delayed\" || row.type === \"scheduled\";\n const shouldDeferReset = (error: unknown): boolean =>\n isOneShotSchedule && isDurableObjectCodeUpdateReset(error);\n const shouldDeferOnExhaustion = (error: unknown): boolean =>\n isOneShotSchedule && isPlatformTransientError(error);\n const shouldDeferMemoryLimit = (error: unknown): boolean =>\n isOneShotSchedule && isDurableObjectMemoryLimitReset(error);\n\n const schedule = this.#rowToSchedule<unknown>(row);\n\n try {\n this.#emit(\"schedule:execute\", { callback: row.callback, id: row.id });\n\n await tryN(\n maxAttempts,\n async (attempt) => {\n if (attempt > 1) {\n this.#emit(\"schedule:retry\", {\n callback: row.callback,\n id: row.id,\n attempt,\n maxAttempts\n });\n }\n await this.#invokeCallback(row.callback, parsedPayload, schedule);\n },\n {\n baseDelayMs,\n maxDelayMs,\n shouldRetry: (error) => !shouldDeferReset(error)\n }\n );\n } catch (error) {\n if (shouldDeferReset(error)) {\n console.warn(\n `Deferring scheduled callback \"${row.callback}\" to a fresh invocation after a Durable Object code-update reset; the one-shot row is preserved and the alarm will re-run on new code.`\n );\n throw error;\n }\n if (shouldDeferOnExhaustion(error)) {\n console.warn(\n `Deferring scheduled callback \"${row.callback}\" after exhausting in-process retries on a transient platform error; the one-shot row is preserved and the alarm will re-run once the platform recovers.`\n );\n throw error;\n }\n if (shouldDeferMemoryLimit(error)) {\n console.warn(\n `Deferring scheduled callback \"${row.callback}\" to the alarm memory-limit circuit breaker after a Durable Object memory-limit reset; the one-shot row is preserved so the breaker can bound the retry loop and seal it (#1825).`\n );\n throw error;\n }\n console.error(\n `error executing callback \"${row.callback}\" after ${maxAttempts} attempts`,\n error\n );\n this.#emit(\"schedule:error\", {\n callback: row.callback,\n id: row.id,\n error: error instanceof Error ? error.message : String(error),\n attempts: maxAttempts\n });\n try {\n await this.#onError?.(error);\n } catch {\n // swallow onError errors\n }\n }\n }\n\n /** Execute every schedule row due in the current alarm phase. */\n async #fireDueSchedules(): Promise<void> {\n const now = Math.floor(Date.now() / 1000);\n const dueRows = this.#sql<ScheduleStorageRow>`\n SELECT * FROM cf_agents_schedules WHERE time <= ${now}\n `;\n this.#warnStaleOneShots(dueRows);\n\n for (const row of dueRows) {\n const outcome = await this.#runDueRow(row, now);\n if (outcome === \"stop\") return;\n if (outcome === \"executed\") this.#advanceRow(row);\n }\n }\n\n /**\n * Warn when many stale one-shot rows share the same callback — this\n * usually means one-shot schedules were created repeatedly (e.g. in\n * onStart) without idempotent:true and rows accumulated across restarts.\n */\n #warnStaleOneShots(dueRows: ReadonlyArray<ScheduleStorageRow>): void {\n const DUPLICATE_SCHEDULE_THRESHOLD = 10;\n const oneShotCounts = new Map<string, number>();\n for (const row of dueRows) {\n if (row.type === \"delayed\" || row.type === \"scheduled\") {\n oneShotCounts.set(\n row.callback,\n (oneShotCounts.get(row.callback) ?? 0) + 1\n );\n }\n }\n for (const [callback, count] of oneShotCounts) {\n if (count < DUPLICATE_SCHEDULE_THRESHOLD) continue;\n try {\n console.warn(\n `Processing ${count} stale \"${callback}\" schedules in a single alarm cycle. ` +\n `This usually means one-shot schedules are created repeatedly without ` +\n `the idempotent option. Consider an interval schedule for recurring ` +\n `tasks, or pass { idempotent: true } when creating one-shot schedules.`\n );\n this.#emit(\"schedule:duplicate_warning\", {\n callback,\n count,\n type: \"one-shot\"\n });\n } catch {\n // Warning emission is non-critical — never block row processing.\n }\n }\n }\n\n /**\n * Run one due row.\n *\n * @returns \"executed\" when the row ran and should advance, \"skipped\" when\n * it should be left for a later alarm cycle, and \"stop\" when host teardown\n * disabled further durable work mid-phase.\n */\n async #runDueRow(\n row: ScheduleStorageRow,\n now: number\n ): Promise<\"executed\" | \"skipped\" | \"stop\"> {\n // Overlap prevention for interval schedules with hung callback detection.\n if (row.type === \"interval\" && row.running === 1) {\n const elapsedSeconds = now - (row.execution_started_at ?? 0);\n if (elapsedSeconds < this.#hungScheduleTimeoutSeconds) {\n console.warn(\n `Skipping interval schedule ${row.id}: previous execution still running`\n );\n return \"skipped\";\n }\n // Previous execution appears hung; force reset and re-execute.\n console.warn(\n `Forcing reset of hung interval schedule ${row.id} (started ${elapsedSeconds}s ago)`\n );\n }\n\n if (row.type === \"interval\") {\n this.#sql`\n UPDATE cf_agents_schedules\n SET running = 1, execution_started_at = ${now}\n WHERE id = ${row.id}\n `;\n }\n\n let executed = false;\n if (row.owner_path) {\n try {\n executed = (await this.lifecycle.routes.to(\n { key: row.owner_path_key ?? row.owner_path, data: row.owner_path },\n { type: \"dispatch\", row } satisfies SchedulerRouteMessage\n )) as boolean;\n } catch (error) {\n console.error(\n `error dispatching scheduled callback \"${row.callback}\"`,\n error\n );\n this.#emit(\"schedule:error\", {\n callback: row.callback,\n id: row.id,\n error: error instanceof Error ? error.message : String(error),\n attempts: 0\n });\n try {\n await this.#onError?.(error);\n } catch {\n // swallow onError errors\n }\n // Reset the in-flight flag for interval rows so the row doesn't stay\n // stuck in `running=1` when dispatch fails (for example, a transport\n // can no longer resolve its owner). The next alarm cycle will retry.\n if (row.type === \"interval\") {\n this.#sql`\n UPDATE cf_agents_schedules SET running = 0 WHERE id = ${row.id}\n `;\n }\n return \"skipped\";\n }\n } else {\n // Retain the row ID while callback execution can escape so a host\n // failure policy can target the exact looping row without owning\n // storage.\n this.#executingRowId = row.id;\n await this.#executeCallback(row);\n this.#executingRowId = undefined;\n executed = true;\n }\n\n // A callback may have destroyed the host; its storage is gone.\n if (this.lifecycle.alarms.disabled()) return \"stop\";\n return executed ? \"executed\" : \"skipped\";\n }\n\n /** Reschedule a recurring row or delete an executed one-shot row. */\n #advanceRow(row: ScheduleStorageRow): void {\n if (row.type === \"cron\") {\n const nextTimestamp = Math.floor(\n nextCronTimeMs(row.cron ?? \"\", Date.now()) / 1000\n );\n this.#sql`\n UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}\n `;\n } else if (row.type === \"interval\") {\n const nextTimestamp =\n Math.floor(Date.now() / 1000) + (row.intervalSeconds ?? 0);\n this.#sql`\n UPDATE cf_agents_schedules\n SET running = 0, time = ${nextTimestamp}\n WHERE id = ${row.id}\n `;\n } else {\n this.#sql`\n DELETE FROM cf_agents_schedules WHERE id = ${row.id}\n `;\n }\n }\n\n // ── Alarm contribution ───────────────────────────────────────────────────\n\n /**\n * Earliest wall-clock time (ms) a schedule row is ready to execute,\n * clamped to the future, or `null` when no row qualifies.\n */\n #nextScheduleTimeMs(nowMs: number, hungCutoffSeconds: number): number | null {\n // Find the earliest schedule row that is safe to execute now, even if it\n // is already overdue. Overdue schedules can happen after a DO restart\n // because the SQLite row survives but the in-memory alarm does not.\n const readySchedules = this.#sql<{ time: number }>`\n SELECT time FROM cf_agents_schedules\n WHERE type != 'interval'\n OR running = 0\n OR coalesce(execution_started_at, 0) <= ${hungCutoffSeconds}\n ORDER BY time ASC\n LIMIT 1\n `;\n\n if (readySchedules.length > 0 && \"time\" in readySchedules[0]) {\n return Math.max(readySchedules[0].time * 1000, nowMs + 1);\n }\n return null;\n }\n\n /**\n * Wall-clock time (ms) at which the earliest still-running (not yet hung)\n * interval schedule crosses the hung timeout and must be re-checked, or\n * `null` when none is running.\n */\n #nextHungIntervalRecheckMs(hungCutoffSeconds: number): number | null {\n // Running interval schedules that are not hung yet still need a future\n // alarm so the runtime can re-check them once they cross the hung timeout.\n const recoveringIntervals = this.#sql<{\n execution_started_at: number | null;\n }>`\n SELECT execution_started_at FROM cf_agents_schedules\n WHERE type = 'interval'\n AND running = 1\n AND coalesce(execution_started_at, 0) > ${hungCutoffSeconds}\n ORDER BY execution_started_at ASC\n LIMIT 1\n `;\n\n const startedAt = recoveringIntervals[0]?.execution_started_at;\n if (startedAt !== null && startedAt !== undefined) {\n return (startedAt + this.#hungScheduleTimeoutSeconds) * 1000;\n }\n return null;\n }\n}\n"],"mappings":"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"}