@minpeter/pss-runtime 0.1.0-next.2 → 0.1.0-next.3

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 (141) hide show
  1. package/README.md +166 -78
  2. package/dist/agent-host-session-store.js +2 -4
  3. package/dist/agent-host-session-store.js.map +1 -1
  4. package/dist/agent-loop.js +2 -3
  5. package/dist/agent-loop.js.map +1 -1
  6. package/dist/agent-namespace.js +3 -7
  7. package/dist/agent-namespace.js.map +1 -1
  8. package/dist/agent-options.d.ts +2 -8
  9. package/dist/agent-options.js +4 -4
  10. package/dist/agent-options.js.map +1 -1
  11. package/dist/agent-resume.js +2 -82
  12. package/dist/agent-resume.js.map +1 -1
  13. package/dist/agent-session-entry.d.ts +1 -1
  14. package/dist/agent.d.ts +4 -4
  15. package/dist/agent.js +16 -70
  16. package/dist/agent.js.map +1 -1
  17. package/dist/cloudflare/cloudflare-agent-context.d.ts +40 -0
  18. package/dist/cloudflare/cloudflare-agent-context.js +37 -0
  19. package/dist/cloudflare/cloudflare-agent-context.js.map +1 -0
  20. package/dist/cloudflare/cloudflare-alarm-budget.d.ts +18 -0
  21. package/dist/cloudflare/cloudflare-alarm-budget.js +77 -0
  22. package/dist/cloudflare/cloudflare-alarm-budget.js.map +1 -0
  23. package/dist/cloudflare/cloudflare-alarm-drainer.d.ts +45 -0
  24. package/dist/cloudflare/cloudflare-alarm-drainer.js +103 -0
  25. package/dist/cloudflare/cloudflare-alarm-drainer.js.map +1 -0
  26. package/dist/cloudflare/cloudflare-alarm-run-drain.d.ts +13 -0
  27. package/dist/cloudflare/cloudflare-alarm-run-drain.js +81 -0
  28. package/dist/cloudflare/cloudflare-alarm-run-drain.js.map +1 -0
  29. package/dist/cloudflare/cloudflare-alarm-work.js +110 -0
  30. package/dist/cloudflare/cloudflare-alarm-work.js.map +1 -0
  31. package/dist/cloudflare/cloudflare-checkpoint-store.js +39 -0
  32. package/dist/cloudflare/cloudflare-checkpoint-store.js.map +1 -0
  33. package/dist/cloudflare/cloudflare-durable-object-fetch.d.ts +21 -0
  34. package/dist/cloudflare/cloudflare-durable-object-fetch.js +11 -0
  35. package/dist/cloudflare/cloudflare-durable-object-fetch.js.map +1 -0
  36. package/dist/cloudflare/cloudflare-event-store.js +33 -0
  37. package/dist/cloudflare/cloudflare-event-store.js.map +1 -0
  38. package/dist/cloudflare/cloudflare-execution-session-store.js +40 -0
  39. package/dist/cloudflare/cloudflare-execution-session-store.js.map +1 -0
  40. package/dist/cloudflare/cloudflare-execution-store.js +35 -0
  41. package/dist/cloudflare/cloudflare-execution-store.js.map +1 -0
  42. package/dist/cloudflare/cloudflare-host.d.ts +61 -0
  43. package/dist/cloudflare/cloudflare-host.js +113 -0
  44. package/dist/cloudflare/cloudflare-host.js.map +1 -0
  45. package/dist/cloudflare/cloudflare-notification-store.js +59 -0
  46. package/dist/cloudflare/cloudflare-notification-store.js.map +1 -0
  47. package/dist/cloudflare/cloudflare-run-store.js +81 -0
  48. package/dist/cloudflare/cloudflare-run-store.js.map +1 -0
  49. package/dist/cloudflare/cloudflare-store-utils.js +43 -0
  50. package/dist/cloudflare/cloudflare-store-utils.js.map +1 -0
  51. package/dist/cloudflare/durable-object-storage.d.ts +20 -0
  52. package/dist/cloudflare/durable-object-storage.js +76 -0
  53. package/dist/cloudflare/durable-object-storage.js.map +1 -0
  54. package/dist/cloudflare/index.d.ts +7 -0
  55. package/dist/cloudflare/index.js +6 -0
  56. package/dist/execution/capabilities.d.ts +40 -0
  57. package/dist/execution/host.d.ts +9 -0
  58. package/dist/execution/host.js +49 -1
  59. package/dist/execution/host.js.map +1 -1
  60. package/dist/execution/index.d.ts +3 -1
  61. package/dist/execution/index.js +2 -1
  62. package/dist/execution/memory.js +1 -1
  63. package/dist/execution/memory.js.map +1 -1
  64. package/dist/execution/types.d.ts +5 -10
  65. package/dist/index.d.ts +8 -4
  66. package/dist/index.js +6 -1
  67. package/dist/plugins.d.ts +25 -3
  68. package/dist/plugins.js +35 -6
  69. package/dist/plugins.js.map +1 -1
  70. package/dist/session/delegate-input.d.ts +9 -0
  71. package/dist/session/delegate-input.js +16 -0
  72. package/dist/session/delegate-input.js.map +1 -0
  73. package/dist/session/events.d.ts +43 -25
  74. package/dist/session/events.js +41 -0
  75. package/dist/session/events.js.map +1 -0
  76. package/dist/session/input-meta-types.d.ts +10 -0
  77. package/dist/session/input-meta.d.ts +13 -0
  78. package/dist/session/input-meta.js +45 -0
  79. package/dist/session/input-meta.js.map +1 -0
  80. package/dist/session/input.d.ts +4 -0
  81. package/dist/session/mapping.js +4 -2
  82. package/dist/session/mapping.js.map +1 -1
  83. package/dist/session/runtime-input-emit.js +41 -0
  84. package/dist/session/runtime-input-emit.js.map +1 -0
  85. package/dist/session/runtime-input.js +5 -1
  86. package/dist/session/runtime-input.js.map +1 -1
  87. package/dist/session/session-events.js +20 -6
  88. package/dist/session/session-events.js.map +1 -1
  89. package/dist/session/session-notification.js +3 -2
  90. package/dist/session/session-notification.js.map +1 -1
  91. package/dist/session/session-runtime-drain.js +3 -9
  92. package/dist/session/session-runtime-drain.js.map +1 -1
  93. package/dist/session/session-turn-processor.js +7 -17
  94. package/dist/session/session-turn-processor.js.map +1 -1
  95. package/dist/session/session.js +11 -4
  96. package/dist/session/session.js.map +1 -1
  97. package/package.json +6 -1
  98. package/dist/agent-child-runs.js +0 -16
  99. package/dist/agent-child-runs.js.map +0 -1
  100. package/dist/agent-host-capabilities.js +0 -9
  101. package/dist/agent-host-capabilities.js.map +0 -1
  102. package/dist/agent-validation.js +0 -35
  103. package/dist/agent-validation.js.map +0 -1
  104. package/dist/child-session-cleanups.js +0 -61
  105. package/dist/child-session-cleanups.js.map +0 -1
  106. package/dist/execution/run.js +0 -55
  107. package/dist/execution/run.js.map +0 -1
  108. package/dist/subagent-background-child-run-state.js +0 -51
  109. package/dist/subagent-background-child-run-state.js.map +0 -1
  110. package/dist/subagent-background-child-run.js +0 -103
  111. package/dist/subagent-background-child-run.js.map +0 -1
  112. package/dist/subagent-background-in-process.js +0 -98
  113. package/dist/subagent-background-in-process.js.map +0 -1
  114. package/dist/subagent-background-notification-inbox.js +0 -106
  115. package/dist/subagent-background-notification-inbox.js.map +0 -1
  116. package/dist/subagent-background-notify.js +0 -136
  117. package/dist/subagent-background-notify.js.map +0 -1
  118. package/dist/subagent-background-resume-group.js +0 -99
  119. package/dist/subagent-background-resume-group.js.map +0 -1
  120. package/dist/subagent-background-runner.js +0 -115
  121. package/dist/subagent-background-runner.js.map +0 -1
  122. package/dist/subagent-background-schedule.js +0 -43
  123. package/dist/subagent-background-schedule.js.map +0 -1
  124. package/dist/subagent-child-run.js +0 -68
  125. package/dist/subagent-child-run.js.map +0 -1
  126. package/dist/subagent-job-cancel.js +0 -84
  127. package/dist/subagent-job-cancel.js.map +0 -1
  128. package/dist/subagent-job-observer.js +0 -19
  129. package/dist/subagent-job-observer.js.map +0 -1
  130. package/dist/subagent-job-output.js +0 -87
  131. package/dist/subagent-job-output.js.map +0 -1
  132. package/dist/subagent-job-state.js +0 -66
  133. package/dist/subagent-job-state.js.map +0 -1
  134. package/dist/subagent-jobs.js +0 -96
  135. package/dist/subagent-jobs.js.map +0 -1
  136. package/dist/subagent-prompt-schema.js +0 -114
  137. package/dist/subagent-prompt-schema.js.map +0 -1
  138. package/dist/subagent-run.js +0 -111
  139. package/dist/subagent-run.js.map +0 -1
  140. package/dist/subagents.js +0 -125
  141. package/dist/subagents.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"agent-resume.js","names":[],"sources":["../src/agent-resume.ts"],"sourcesContent":["import { ownsAgentNamespace } from \"./agent-namespace\";\nimport { StoredAgentRun } from \"./execution/run\";\nimport type {\n ExecutionHost,\n NotificationRecord,\n RunRecord,\n} from \"./execution/types\";\nimport { type AgentRun, BufferedAgentRun } from \"./session/run\";\nimport { readDurableBackgroundChildRunState } from \"./subagent-background-child-run-state\";\nimport { buildDurableResumeGroups } from \"./subagent-background-resume-group\";\nimport { runBackgroundJob } from \"./subagent-background-runner\";\nimport type { RuntimeInputSink, Subagent, SubagentJob } from \"./subagent-types\";\n\nconst defaultResumeLeaseMs = 300_000;\n\ninterface ResumeAgentRunInput {\n readonly host: ExecutionHost;\n readonly ownerNamespace: string;\n resumeNotification(notification: NotificationRecord): Promise<AgentRun>;\n readonly runId: string;\n readonly subagents: readonly Subagent[];\n}\n\nexport async function resumeAgentRun({\n host,\n ownerNamespace,\n resumeNotification,\n runId,\n subagents,\n}: ResumeAgentRunInput): Promise<AgentRun | null> {\n const run = await host.store.runs.get(runId);\n if (!run) {\n return null;\n }\n if (!canAccessRun(run, ownerNamespace)) {\n return null;\n }\n\n if (run.kind === \"background-subagent\") {\n return await resumeBackgroundSubagentRun({ host, run, subagents });\n }\n\n if (run.kind === \"notification\" && run.dedupeKey) {\n const idempotencyKey = run.dedupeKey;\n const claimed = await claimRun(host, run);\n if (!claimed) {\n return null;\n }\n\n const notification = await claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n });\n if (!notification) {\n return null;\n }\n\n try {\n const notificationRun = await resumeNotification(notification);\n await completeNotificationRun(host, claimed.runId);\n return notificationRun;\n } catch (error) {\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n throw error;\n }\n }\n\n return null;\n}\n\nasync function claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n}: {\n readonly host: ExecutionHost;\n readonly idempotencyKey: string;\n readonly ownerNamespace: string;\n}): Promise<NotificationRecord | null> {\n const current =\n await host.store.notifications.getByIdempotencyKey(idempotencyKey);\n if (!ownsAgentNamespace(current?.ownerNamespace, ownerNamespace)) {\n return null;\n }\n\n const claim =\n await host.store.notifications.claimByIdempotencyKey(idempotencyKey);\n if (claim.ok) {\n if (ownsAgentNamespace(claim.record.ownerNamespace, ownerNamespace)) {\n return claim.record;\n }\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n return null;\n }\n\n if (\n claim.reason === \"already-claimed\" &&\n ownsAgentNamespace(claim.record?.ownerNamespace, ownerNamespace)\n ) {\n return claim.record ?? null;\n }\n\n return null;\n}\n\nfunction canAccessRun(run: RunRecord, ownerNamespace: string): boolean {\n if (run.ownerNamespace) {\n return ownsAgentNamespace(run.ownerNamespace, ownerNamespace);\n }\n\n return (\n run.sessionKey.startsWith(`parent:${ownerNamespace}:`) ||\n run.parentRunId?.startsWith(`${ownerNamespace}:session:`) === true\n );\n}\n\nexport async function completeNotificationRun(\n host: ExecutionHost,\n runId: string\n): Promise<void> {\n const run = await host.store.runs.get(runId);\n if (run?.kind !== \"notification\" || run.status === \"completed\") {\n return;\n }\n\n await host.store.runs.update({ ...run, status: \"completed\" });\n}\n\nasync function resumeBackgroundSubagentRun({\n host,\n run,\n subagents,\n}: {\n readonly host: ExecutionHost;\n readonly run: RunRecord;\n readonly subagents: readonly Subagent[];\n}): Promise<AgentRun | null> {\n const claimed = await claimRun(host, run);\n if (!claimed) {\n return null;\n }\n\n const checkpoint = await host.store.checkpoints.latest(run.runId);\n const state = readDurableBackgroundChildRunState(checkpoint);\n if (!state) {\n throw new AgentResumeError(run.runId, \"missing background run state\");\n }\n\n const subagent = subagents.find(\n (candidate) => candidate.name === state.subagent\n );\n if (!subagent) {\n throw new AgentResumeError(\n run.runId,\n `missing subagent ${JSON.stringify(state.subagent)}`\n );\n }\n\n const childSession = subagent.session(claimed.sessionKey);\n const job: SubagentJob = {\n abort: () => childSession.interrupt(),\n childRunId: claimed.runId,\n childRunLeaseId: claimed.lease?.leaseId,\n cleanup: () => Promise.resolve(),\n dedupeKey: claimed.dedupeKey,\n delegateToolCallId: state.delegateToolCallId,\n description: state.description,\n executionHost: host,\n groupId: state.groupId,\n id: claimed.publicTaskId ?? claimed.runId,\n ownerNamespace: claimed.ownerNamespace,\n parentRunId: claimed.parentRunId,\n parentSessionKey: state.parentSessionKey,\n promise: Promise.resolve(),\n sessionKey: claimed.sessionKey,\n settled: false,\n status: \"running\",\n subagent: state.subagent,\n };\n const jobs = new Map([[job.id, job]]);\n const groups = await buildDurableResumeGroups({\n currentJob: job,\n host,\n run: claimed,\n state,\n jobs,\n });\n const parentSession = durableParentSession(host, run.runId);\n\n job.promise = runBackgroundJob({\n childSession,\n groups,\n jobs,\n job,\n parentSession,\n prompt: state.prompt,\n }).finally(() => {\n job.settled = true;\n });\n await job.promise;\n\n return new StoredAgentRun({\n eventStore: host.store.events,\n runId: run.runId,\n });\n}\n\nasync function claimRun(\n host: ExecutionHost,\n run: RunRecord\n): Promise<RunRecord | null> {\n const claim = await host.store.runs.claim(run.runId, {\n attempt: (run.lease?.attempt ?? 0) + 1,\n leaseId: crypto.randomUUID(),\n leaseMs: defaultResumeLeaseMs,\n nowMs: Date.now(),\n });\n return claim.ok ? claim.record : null;\n}\n\nfunction durableParentSession(\n host: ExecutionHost,\n runId: string\n): RuntimeInputSink {\n return {\n emitObserverEvent: (event) => host.store.events.append(runId, event).then(),\n enqueueRuntimeInput: () => undefined,\n notify: () => Promise.resolve(emptyRun()),\n };\n}\n\nfunction emptyRun(): AgentRun {\n const run = new BufferedAgentRun();\n run.close();\n return run;\n}\n\nclass AgentResumeError extends Error {\n constructor(runId: string, reason: string) {\n super(`Cannot resume agent run ${runId}: ${reason}`);\n this.name = \"AgentResumeError\";\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent-resume.js","names":[],"sources":["../src/agent-resume.ts"],"sourcesContent":["import { ownsAgentNamespace } from \"./agent-namespace\";\nimport type {\n ExecutionHost,\n NotificationRecord,\n RunRecord,\n} from \"./execution/types\";\nimport type { AgentRun } from \"./session/run\";\n\ninterface ResumeAgentRunInput {\n readonly host: ExecutionHost;\n readonly ownerNamespace: string;\n resumeNotification(notification: NotificationRecord): Promise<AgentRun>;\n readonly runId: string;\n}\n\nexport async function resumeAgentRun({\n host,\n ownerNamespace,\n resumeNotification,\n runId,\n}: ResumeAgentRunInput): Promise<AgentRun | null> {\n const run = await host.store.runs.get(runId);\n if (!run) {\n return null;\n }\n if (!canAccessRun(run, ownerNamespace)) {\n return null;\n }\n\n if (run.kind === \"notification\" && run.dedupeKey) {\n const idempotencyKey = run.dedupeKey;\n const claimed = await claimRun(host, run);\n if (!claimed) {\n return null;\n }\n\n const notification = await claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n });\n if (!notification) {\n return null;\n }\n\n try {\n const notificationRun = await resumeNotification(notification);\n await completeNotificationRun(host, claimed.runId);\n return notificationRun;\n } catch (error) {\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n throw error;\n }\n }\n\n return null;\n}\n\nasync function claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n}: {\n readonly host: ExecutionHost;\n readonly idempotencyKey: string;\n readonly ownerNamespace: string;\n}): Promise<NotificationRecord | null> {\n const current =\n await host.store.notifications.getByIdempotencyKey(idempotencyKey);\n if (!ownsAgentNamespace(current?.ownerNamespace, ownerNamespace)) {\n return null;\n }\n\n const claim =\n await host.store.notifications.claimByIdempotencyKey(idempotencyKey);\n if (claim.ok) {\n if (ownsAgentNamespace(claim.record.ownerNamespace, ownerNamespace)) {\n return claim.record;\n }\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n return null;\n }\n\n if (\n claim.reason === \"already-claimed\" &&\n ownsAgentNamespace(claim.record?.ownerNamespace, ownerNamespace)\n ) {\n return claim.record ?? null;\n }\n\n return null;\n}\n\nfunction canAccessRun(run: RunRecord, ownerNamespace: string): boolean {\n if (run.ownerNamespace) {\n return ownsAgentNamespace(run.ownerNamespace, ownerNamespace);\n }\n\n return (\n run.sessionKey.startsWith(`parent:${ownerNamespace}:`) ||\n run.parentRunId?.startsWith(`${ownerNamespace}:session:`) === true\n );\n}\n\nexport async function completeNotificationRun(\n host: ExecutionHost,\n runId: string\n): Promise<void> {\n const run = await host.store.runs.get(runId);\n if (run?.kind !== \"notification\" || run.status === \"completed\") {\n return;\n }\n\n await host.store.runs.update({ ...run, status: \"completed\" });\n}\n\nasync function claimRun(\n host: ExecutionHost,\n run: RunRecord\n): Promise<RunRecord | null> {\n const claim = await host.store.runs.claim(run.runId, {\n attempt: (run.lease?.attempt ?? 0) + 1,\n leaseId: crypto.randomUUID(),\n leaseMs: 300_000,\n nowMs: Date.now(),\n });\n return claim.ok ? claim.record : null;\n}\n"],"mappings":";;AAeA,eAAsB,eAAe,EACnC,MACA,gBACA,oBACA,SACgD;CAChD,MAAM,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,KAAK;CAC3C,IAAI,CAAC,KACH,OAAO;CAET,IAAI,CAAC,aAAa,KAAK,cAAc,GACnC,OAAO;CAGT,IAAI,IAAI,SAAS,kBAAkB,IAAI,WAAW;EAChD,MAAM,iBAAiB,IAAI;EAC3B,MAAM,UAAU,MAAM,SAAS,MAAM,GAAG;EACxC,IAAI,CAAC,SACH,OAAO;EAGT,MAAM,eAAe,MAAM,wBAAwB;GACjD;GACA;GACA;EACF,CAAC;EACD,IAAI,CAAC,cACH,OAAO;EAGT,IAAI;GACF,MAAM,kBAAkB,MAAM,mBAAmB,YAAY;GAC7D,MAAM,wBAAwB,MAAM,QAAQ,KAAK;GACjD,OAAO;EACT,SAAS,OAAO;GACd,MAAM,KAAK,MAAM,cAAc,wBAAwB,cAAc;GACrE,MAAM;EACR;CACF;CAEA,OAAO;AACT;AAEA,eAAe,wBAAwB,EACrC,MACA,gBACA,kBAKqC;CAGrC,IAAI,CAAC,oBAAmB,MADhB,KAAK,MAAM,cAAc,oBAAoB,cAAc,IAClC,gBAAgB,cAAc,GAC7D,OAAO;CAGT,MAAM,QACJ,MAAM,KAAK,MAAM,cAAc,sBAAsB,cAAc;CACrE,IAAI,MAAM,IAAI;EACZ,IAAI,mBAAmB,MAAM,OAAO,gBAAgB,cAAc,GAChE,OAAO,MAAM;EAEf,MAAM,KAAK,MAAM,cAAc,wBAAwB,cAAc;EACrE,OAAO;CACT;CAEA,IACE,MAAM,WAAW,qBACjB,mBAAmB,MAAM,QAAQ,gBAAgB,cAAc,GAE/D,OAAO,MAAM,UAAU;CAGzB,OAAO;AACT;AAEA,SAAS,aAAa,KAAgB,gBAAiC;CACrE,IAAI,IAAI,gBACN,OAAO,mBAAmB,IAAI,gBAAgB,cAAc;CAG9D,OACE,IAAI,WAAW,WAAW,UAAU,eAAe,EAAE,KACrD,IAAI,aAAa,WAAW,GAAG,eAAe,UAAU,MAAM;AAElE;AAEA,eAAsB,wBACpB,MACA,OACe;CACf,MAAM,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,KAAK;CAC3C,IAAI,KAAK,SAAS,kBAAkB,IAAI,WAAW,aACjD;CAGF,MAAM,KAAK,MAAM,KAAK,OAAO;EAAE,GAAG;EAAK,QAAQ;CAAY,CAAC;AAC9D;AAEA,eAAe,SACb,MACA,KAC2B;CAC3B,MAAM,QAAQ,MAAM,KAAK,MAAM,KAAK,MAAM,IAAI,OAAO;EACnD,UAAU,IAAI,OAAO,WAAW,KAAK;EACrC,SAAS,OAAO,WAAW;EAC3B,SAAS;EACT,OAAO,KAAK,IAAI;CAClB,CAAC;CACD,OAAO,MAAM,KAAK,MAAM,SAAS;AACnC"}
@@ -3,8 +3,8 @@ import { AgentRun } from "./session/run.js";
3
3
  //#region src/agent-session-entry.d.ts
4
4
  interface SessionHandle {
5
5
  delete(): Promise<void>;
6
+ dispose(): Promise<void>;
6
7
  interrupt(): void;
7
- kill(): Promise<void>;
8
8
  send(input: AgentInput): Promise<AgentRun>;
9
9
  steer(input: AgentInput): Promise<AgentRun>;
10
10
  }
package/dist/agent.d.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import { AgentInput } from "./session/input.js";
2
2
  import { AgentHost } from "./execution/types.js";
3
- import { AgentOptions } from "./agent-options.js";
3
+ import { AgentConstructionOptions, AgentOptions } from "./agent-options.js";
4
4
  import { AgentRun } from "./session/run.js";
5
5
  import { SessionHandle } from "./agent-session-entry.js";
6
6
 
7
7
  //#region src/agent.d.ts
8
8
  declare class Agent {
9
9
  #private;
10
- readonly description?: string;
11
- readonly name?: string;
12
- constructor(options: AgentOptions);
10
+ readonly host: AgentHost;
11
+ readonly namespace?: string;
12
+ constructor(options: AgentConstructionOptions);
13
13
  send(input: AgentInput): Promise<AgentRun>;
14
14
  resume(runId: string): Promise<AgentRun | null>;
15
15
  session(key: string): SessionHandle;
package/dist/agent.js CHANGED
@@ -1,46 +1,33 @@
1
1
  import { executionHost } from "./execution/host.js";
2
- import { cancelDurableChildRuns } from "./agent-child-runs.js";
3
- import { supportsBackgroundSubagents } from "./agent-host-capabilities.js";
4
2
  import { sessionStoreForHost } from "./agent-host-session-store.js";
5
- import { parentSessionNamespace, stableAgentNamespace } from "./agent-namespace.js";
6
- import { assertAgentOptions, hasRuntimeModel } from "./agent-options.js";
3
+ import { stableAgentNamespace } from "./agent-namespace.js";
4
+ import { assertAgentOptions, hasLanguageModel, hasRuntimeModel } from "./agent-options.js";
7
5
  import { resumeAgentRun } from "./agent-resume.js";
8
- import { assertSubagents } from "./agent-validation.js";
9
- import { ChildSessionCleanups } from "./child-session-cleanups.js";
10
6
  import { createInMemoryExecutionHost } from "./execution/memory.js";
11
7
  import { createLlm } from "./llm.js";
12
8
  import { AgentSession } from "./session/session.js";
13
- import { createSubagentTools } from "./subagents.js";
14
9
  //#region src/agent.ts
15
- var Agent = class Agent {
10
+ var Agent = class {
16
11
  #baseTools;
17
12
  #llm;
18
13
  #modelOptions;
19
- #childSessionCleanups = new ChildSessionCleanups();
20
- #sessionGenerations = /* @__PURE__ */ new Map();
21
14
  #sessions = /* @__PURE__ */ new Map();
22
15
  #sessionNamespace;
23
16
  #store;
24
17
  #host;
25
18
  #plugins;
26
- #subagents;
27
- description;
28
- name;
19
+ host;
20
+ namespace;
29
21
  constructor(options) {
30
22
  assertAgentOptions(options);
31
- this.description = options.description;
32
- this.name = options.name;
33
- this.#sessionNamespace = stableAgentNamespace({
34
- name: options.name,
35
- namespace: options.namespace
36
- });
23
+ this.namespace = options.namespace;
24
+ this.#sessionNamespace = stableAgentNamespace({ namespace: options.namespace });
37
25
  this.#host = options.host ?? createInMemoryExecutionHost();
26
+ this.host = this.#host;
38
27
  this.#store = sessionStoreForHost(this.#host);
39
28
  this.#plugins = options.plugins ?? [];
40
- assertSubagents(options, Agent, hasRuntimeModel(options));
41
- this.#subagents = hasRuntimeModel(options) ? [] : options.subagents ?? [];
42
29
  if (hasRuntimeModel(options)) this.#llm = options.model;
43
- else {
30
+ else if (hasLanguageModel(options)) {
44
31
  this.#baseTools = options.tools;
45
32
  this.#modelOptions = {
46
33
  instructions: options.instructions,
@@ -59,8 +46,7 @@ var Agent = class Agent {
59
46
  host,
60
47
  ownerNamespace: this.#sessionNamespace,
61
48
  resumeNotification: (notification) => this.#resumeNotification(notification),
62
- runId,
63
- subagents: this.#subagents
49
+ runId
64
50
  });
65
51
  }
66
52
  session(key) {
@@ -70,16 +56,7 @@ var Agent = class Agent {
70
56
  const existing = this.#sessions.get(key);
71
57
  if (existing) return existing;
72
58
  let session;
73
- const getSession = () => {
74
- if (!session) throw new Error("Agent session is not initialized.");
75
- return session;
76
- };
77
- const parentAgentNamespace = parentSessionNamespace({
78
- generation: this.#sessionGenerations.get(key) ?? 0,
79
- sessionKey: key,
80
- sessionNamespace: this.#sessionNamespace
81
- });
82
- session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession(key, parentAgentNamespace, (input, placement) => getSession().enqueueRuntimeInput(input, placement), (event) => getSession().emitObserverEvent(event), (input, options) => getSession().notify(input, options), () => getSession().currentTurnId(), () => parentAgentNamespace)), {
59
+ session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession()), {
83
60
  key,
84
61
  store: this.#store
85
62
  }, this.#plugins, { executionHost: executionHost(this.#host) });
@@ -88,18 +65,15 @@ var Agent = class Agent {
88
65
  publicHandle: {
89
66
  delete: async () => {
90
67
  session.kill();
91
- await this.#cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace);
92
68
  this.#evictSessionHandle(key);
93
69
  await session.delete();
94
- await this.#childSessionCleanups.delete(key);
95
70
  },
96
- interrupt: () => session.interrupt(),
97
- kill: async () => {
71
+ dispose: () => {
98
72
  session.kill();
99
- await this.#cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace);
100
73
  this.#evictSessionHandle(key);
101
- await this.#childSessionCleanups.delete(key);
74
+ return Promise.resolve();
102
75
  },
76
+ interrupt: () => session.interrupt(),
103
77
  send: (input) => session.send(input),
104
78
  steer: (input) => session.steer(input)
105
79
  }
@@ -107,48 +81,20 @@ var Agent = class Agent {
107
81
  this.#sessions.set(key, entry);
108
82
  return entry;
109
83
  }
110
- async #cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace) {
111
- try {
112
- await cancelDurableChildRuns(this.#host, parentAgentNamespace);
113
- } catch (error) {
114
- this.#evictSessionHandle(key);
115
- throw error;
116
- }
117
- }
118
84
  #evictSessionHandle(key) {
119
85
  this.#sessions.delete(key);
120
- this.#sessionGenerations.set(key, (this.#sessionGenerations.get(key) ?? 0) + 1);
121
86
  }
122
87
  #resumeNotification(notification) {
123
88
  return this.#sessionEntry(notification.sessionKey).notify(notification.input, { observerEvents: notification.observerEvents });
124
89
  }
125
- #createLlmOptionsForSession(key, parentAgentNamespace, enqueueRuntimeInput, emitObserverEvent, notify, currentBackgroundGroupId, currentRunId) {
90
+ #createLlmOptionsForSession() {
126
91
  const modelOptions = this.#modelOptions;
127
92
  if (!modelOptions) throw new Error("Agent: missing model options.");
128
- const hostExecution = executionHost(this.#host);
129
- const tools = this.#subagents.length === 0 ? this.#baseTools : {
130
- ...this.#baseTools,
131
- ...createSubagentTools({
132
- backgroundSubagents: supportsBackgroundSubagents(this.#host, hostExecution),
133
- executionHost: hostExecution,
134
- parentAgentNamespace,
135
- parentSession: {
136
- currentBackgroundGroupId,
137
- currentRunId,
138
- emitObserverEvent,
139
- enqueueRuntimeInput,
140
- notify
141
- },
142
- parentSessionKey: key,
143
- registerChildSession: (sessionKey, cleanup) => this.#childSessionCleanups.register(sessionKey, cleanup),
144
- subagents: this.#subagents
145
- })
146
- };
147
93
  return {
148
94
  instructions: modelOptions.instructions,
149
95
  model: modelOptions.model,
150
96
  toolChoice: modelOptions.toolChoice,
151
- tools
97
+ tools: this.#baseTools
152
98
  };
153
99
  }
154
100
  };
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","names":["#baseTools","#llm","#modelOptions","#childSessionCleanups","#sessionGenerations","#sessions","#sessionNamespace","#store","#host","#plugins","#subagents","#resumeNotification","#sessionEntry","#createLlmOptionsForSession","#cancelDurableChildRunsBeforeLocalCleanup","#evictSessionHandle"],"sources":["../src/agent.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport { cancelDurableChildRuns } from \"./agent-child-runs\";\nimport { supportsBackgroundSubagents } from \"./agent-host-capabilities\";\nimport { sessionStoreForHost } from \"./agent-host-session-store\";\nimport {\n parentSessionNamespace,\n stableAgentNamespace,\n} from \"./agent-namespace\";\nimport {\n type AgentModelOptions,\n type AgentOptions,\n assertAgentOptions,\n hasRuntimeModel,\n} from \"./agent-options\";\nimport { resumeAgentRun } from \"./agent-resume\";\nimport type { AgentSessionEntry, SessionHandle } from \"./agent-session-entry\";\nimport { assertSubagents } from \"./agent-validation\";\nimport { ChildSessionCleanups } from \"./child-session-cleanups\";\nimport { executionHost } from \"./execution/host\";\nimport { createInMemoryExecutionHost } from \"./execution/memory\";\nimport type { AgentHost, NotificationRecord } from \"./execution/types\";\nimport { createLlm, type RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\nimport type { UserInput } from \"./session/events\";\nimport type { AgentRun } from \"./session/run\";\nimport {\n type AgentInput,\n AgentSession,\n type NotifyOptions,\n} from \"./session/session\";\nimport type { SessionStore } from \"./session/store/types\";\nimport { createSubagentTools } from \"./subagents\";\n\nexport type { AgentOptions } from \"./agent-options\";\nexport type { SessionHandle } from \"./agent-session-entry\";\nexport type { AgentHost } from \"./execution/types\";\n\nexport class Agent {\n readonly #baseTools?: ToolSet;\n readonly #llm?: RuntimeLlm;\n readonly #modelOptions?: AgentModelOptions;\n readonly #childSessionCleanups = new ChildSessionCleanups();\n readonly #sessionGenerations = new Map<string, number>();\n readonly #sessions = new Map<string, AgentSessionEntry>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\n readonly #host: AgentHost;\n readonly #plugins: readonly AgentPlugin[];\n readonly #subagents: readonly Agent[];\n readonly description?: string;\n readonly name?: string;\n\n constructor(options: AgentOptions) {\n assertAgentOptions(options);\n\n this.description = options.description;\n this.name = options.name;\n this.#sessionNamespace = stableAgentNamespace({\n name: options.name,\n namespace: options.namespace,\n });\n this.#host = options.host ?? createInMemoryExecutionHost();\n this.#store = sessionStoreForHost(this.#host);\n this.#plugins = options.plugins ?? [];\n assertSubagents(options, Agent, hasRuntimeModel(options));\n this.#subagents = hasRuntimeModel(options) ? [] : (options.subagents ?? []);\n if (hasRuntimeModel(options)) {\n this.#llm = options.model;\n } else {\n this.#baseTools = options.tools;\n this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n };\n }\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n async resume(runId: string): Promise<AgentRun | null> {\n const host = executionHost(this.#host);\n if (!host) {\n throw new Error(\"Agent host does not support durable run resume.\");\n }\n\n return await resumeAgentRun({\n host,\n ownerNamespace: this.#sessionNamespace,\n resumeNotification: (notification) =>\n this.#resumeNotification(notification),\n runId,\n subagents: this.#subagents,\n });\n }\n\n session(key: string): SessionHandle {\n return this.#sessionEntry(key).publicHandle;\n }\n\n #sessionEntry(key: string): AgentSessionEntry {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n let session: AgentSession | undefined;\n const getSession = () => {\n if (!session) {\n throw new Error(\"Agent session is not initialized.\");\n }\n return session;\n };\n const parentAgentNamespace = parentSessionNamespace({\n generation: this.#sessionGenerations.get(key) ?? 0,\n sessionKey: key,\n sessionNamespace: this.#sessionNamespace,\n });\n const llm =\n this.#llm ??\n createLlm(\n this.#createLlmOptionsForSession(\n key,\n parentAgentNamespace,\n (input: UserInput, placement?: \"turn-start\") =>\n getSession().enqueueRuntimeInput(input, placement),\n (event) => getSession().emitObserverEvent(event),\n (input: UserInput, options?: NotifyOptions) =>\n getSession().notify(input, options),\n () => getSession().currentTurnId(),\n () => parentAgentNamespace\n )\n );\n session = new AgentSession(\n llm,\n { key, store: this.#store },\n this.#plugins,\n {\n executionHost: executionHost(this.#host),\n }\n );\n const publicHandle: SessionHandle = {\n delete: async () => {\n session.kill();\n await this.#cancelDurableChildRunsBeforeLocalCleanup(\n key,\n parentAgentNamespace\n );\n this.#evictSessionHandle(key);\n await session.delete();\n await this.#childSessionCleanups.delete(key);\n },\n interrupt: () => session.interrupt(),\n kill: async () => {\n session.kill();\n await this.#cancelDurableChildRunsBeforeLocalCleanup(\n key,\n parentAgentNamespace\n );\n this.#evictSessionHandle(key);\n await this.#childSessionCleanups.delete(key);\n },\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n const entry: AgentSessionEntry = {\n notify: (input, options) => session.notify(input, options),\n publicHandle,\n };\n this.#sessions.set(key, entry);\n return entry;\n }\n\n async #cancelDurableChildRunsBeforeLocalCleanup(\n key: string,\n parentAgentNamespace: string\n ): Promise<void> {\n try {\n await cancelDurableChildRuns(this.#host, parentAgentNamespace);\n } catch (error) {\n this.#evictSessionHandle(key);\n throw error;\n }\n }\n\n #evictSessionHandle(key: string): void {\n this.#sessions.delete(key);\n this.#sessionGenerations.set(\n key,\n (this.#sessionGenerations.get(key) ?? 0) + 1\n );\n }\n\n #resumeNotification(notification: NotificationRecord): Promise<AgentRun> {\n return this.#sessionEntry(notification.sessionKey).notify(\n notification.input,\n { observerEvents: notification.observerEvents }\n );\n }\n\n #createLlmOptionsForSession(\n key: string,\n parentAgentNamespace: string,\n enqueueRuntimeInput: AgentSession[\"enqueueRuntimeInput\"],\n emitObserverEvent: AgentSession[\"emitObserverEvent\"],\n notify: (input: UserInput, options?: NotifyOptions) => Promise<AgentRun>,\n currentBackgroundGroupId: () => string | undefined,\n currentRunId: () => string | undefined\n ): Parameters<typeof createLlm>[0] {\n const modelOptions = this.#modelOptions;\n if (!modelOptions) {\n throw new Error(\"Agent: missing model options.\");\n }\n const hostExecution = executionHost(this.#host);\n const tools =\n this.#subagents.length === 0\n ? this.#baseTools\n : {\n ...this.#baseTools,\n ...createSubagentTools({\n backgroundSubagents: supportsBackgroundSubagents(\n this.#host,\n hostExecution\n ),\n executionHost: hostExecution,\n parentAgentNamespace,\n parentSession: {\n currentBackgroundGroupId,\n currentRunId,\n emitObserverEvent,\n enqueueRuntimeInput,\n notify,\n },\n parentSessionKey: key,\n registerChildSession: (sessionKey, cleanup) =>\n this.#childSessionCleanups.register(sessionKey, cleanup),\n subagents: this.#subagents,\n }),\n };\n\n return {\n instructions: modelOptions.instructions,\n model: modelOptions.model,\n toolChoice: modelOptions.toolChoice,\n tools,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","names":["#baseTools","#llm","#modelOptions","#sessions","#sessionNamespace","#store","#host","#plugins","#resumeNotification","#sessionEntry","#createLlmOptionsForSession","#evictSessionHandle"],"sources":["../src/agent.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport { sessionStoreForHost } from \"./agent-host-session-store\";\nimport { stableAgentNamespace } from \"./agent-namespace\";\nimport {\n type AgentConstructionOptions,\n type AgentModelOptions,\n assertAgentOptions,\n hasLanguageModel,\n hasRuntimeModel,\n} from \"./agent-options\";\nimport { resumeAgentRun } from \"./agent-resume\";\nimport type { AgentSessionEntry, SessionHandle } from \"./agent-session-entry\";\nimport { executionHost } from \"./execution/host\";\nimport { createInMemoryExecutionHost } from \"./execution/memory\";\nimport type { AgentHost, NotificationRecord } from \"./execution/types\";\nimport { createLlm, type RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\nimport type { AgentRun } from \"./session/run\";\nimport { type AgentInput, AgentSession } from \"./session/session\";\nimport type { SessionStore } from \"./session/store/types\";\n\nexport type { AgentOptions } from \"./agent-options\";\nexport type { SessionHandle } from \"./agent-session-entry\";\nexport type { AgentHost } from \"./execution/types\";\n\nexport class Agent {\n readonly #baseTools?: ToolSet;\n readonly #llm?: RuntimeLlm;\n readonly #modelOptions?: AgentModelOptions;\n readonly #sessions = new Map<string, AgentSessionEntry>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\n readonly #host: AgentHost;\n readonly #plugins: readonly AgentPlugin[];\n readonly host: AgentHost;\n readonly namespace?: string;\n constructor(options: AgentConstructionOptions) {\n assertAgentOptions(options);\n\n this.namespace = options.namespace;\n this.#sessionNamespace = stableAgentNamespace({\n namespace: options.namespace,\n });\n this.#host = options.host ?? createInMemoryExecutionHost();\n this.host = this.#host;\n this.#store = sessionStoreForHost(this.#host);\n this.#plugins = options.plugins ?? [];\n if (hasRuntimeModel(options)) {\n this.#llm = options.model;\n } else if (hasLanguageModel(options)) {\n this.#baseTools = options.tools;\n this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n };\n }\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n async resume(runId: string): Promise<AgentRun | null> {\n const host = executionHost(this.#host);\n if (!host) {\n throw new Error(\"Agent host does not support durable run resume.\");\n }\n\n return await resumeAgentRun({\n host,\n ownerNamespace: this.#sessionNamespace,\n resumeNotification: (notification) =>\n this.#resumeNotification(notification),\n runId,\n });\n }\n\n session(key: string): SessionHandle {\n return this.#sessionEntry(key).publicHandle;\n }\n\n #sessionEntry(key: string): AgentSessionEntry {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n let session: AgentSession | undefined;\n const llm = this.#llm ?? createLlm(this.#createLlmOptionsForSession());\n session = new AgentSession(\n llm,\n { key, store: this.#store },\n this.#plugins,\n {\n executionHost: executionHost(this.#host),\n }\n );\n const publicHandle: SessionHandle = {\n delete: async () => {\n session.kill();\n this.#evictSessionHandle(key);\n await session.delete();\n },\n dispose: () => {\n session.kill();\n this.#evictSessionHandle(key);\n return Promise.resolve();\n },\n interrupt: () => session.interrupt(),\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n const entry: AgentSessionEntry = {\n notify: (input, options) => session.notify(input, options),\n publicHandle,\n };\n this.#sessions.set(key, entry);\n return entry;\n }\n\n #evictSessionHandle(key: string): void {\n this.#sessions.delete(key);\n }\n\n #resumeNotification(notification: NotificationRecord): Promise<AgentRun> {\n return this.#sessionEntry(notification.sessionKey).notify(\n notification.input,\n { observerEvents: notification.observerEvents }\n );\n }\n\n #createLlmOptionsForSession(): Parameters<typeof createLlm>[0] {\n const modelOptions = this.#modelOptions;\n if (!modelOptions) {\n throw new Error(\"Agent: missing model options.\");\n }\n\n return {\n instructions: modelOptions.instructions,\n model: modelOptions.model,\n toolChoice: modelOptions.toolChoice,\n tools: this.#baseTools,\n };\n }\n}\n"],"mappings":";;;;;;;;;AAyBA,IAAa,QAAb,MAAmB;CACjB;CACA;CACA;CACA,4BAAqB,IAAI,IAA+B;CACxD;CACA;CACA;CACA;CACA;CACA;CACA,YAAY,SAAmC;EAC7C,mBAAmB,OAAO;EAE1B,KAAK,YAAY,QAAQ;EACzB,KAAKI,oBAAoB,qBAAqB,EAC5C,WAAW,QAAQ,UACrB,CAAC;EACD,KAAKE,QAAQ,QAAQ,QAAQ,4BAA4B;EACzD,KAAK,OAAO,KAAKA;EACjB,KAAKD,SAAS,oBAAoB,KAAKC,KAAK;EAC5C,KAAKC,WAAW,QAAQ,WAAW,CAAC;EACpC,IAAI,gBAAgB,OAAO,GACzB,KAAKN,OAAO,QAAQ;OACf,IAAI,iBAAiB,OAAO,GAAG;GACpC,KAAKD,aAAa,QAAQ;GAC1B,KAAKE,gBAAgB;IACnB,cAAc,QAAQ;IACtB,OAAO,QAAQ;IACf,YAAY,QAAQ;GACtB;EACF;CACF;CAEA,KAAK,OAAsC;EACzC,OAAO,KAAK,QAAQ,SAAS,EAAE,KAAK,KAAK;CAC3C;CAEA,MAAM,OAAO,OAAyC;EACpD,MAAM,OAAO,cAAc,KAAKI,KAAK;EACrC,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,iDAAiD;EAGnE,OAAO,MAAM,eAAe;GAC1B;GACA,gBAAgB,KAAKF;GACrB,qBAAqB,iBACnB,KAAKI,oBAAoB,YAAY;GACvC;EACF,CAAC;CACH;CAEA,QAAQ,KAA4B;EAClC,OAAO,KAAKC,cAAc,GAAG,EAAE;CACjC;CAEA,cAAc,KAAgC;EAC5C,MAAM,WAAW,KAAKN,UAAU,IAAI,GAAG;EACvC,IAAI,UACF,OAAO;EAGT,IAAI;EAEJ,UAAU,IAAI,aADF,KAAKF,QAAQ,UAAU,KAAKS,4BAA4B,CAAC,GAGnE;GAAE;GAAK,OAAO,KAAKL;EAAO,GAC1B,KAAKE,UACL,EACE,eAAe,cAAc,KAAKD,KAAK,EACzC,CACF;EAgBA,MAAM,QAA2B;GAC/B,SAAS,OAAO,YAAY,QAAQ,OAAO,OAAO,OAAO;GACzD,cAAA;IAhBA,QAAQ,YAAY;KAClB,QAAQ,KAAK;KACb,KAAKK,oBAAoB,GAAG;KAC5B,MAAM,QAAQ,OAAO;IACvB;IACA,eAAe;KACb,QAAQ,KAAK;KACb,KAAKA,oBAAoB,GAAG;KAC5B,OAAO,QAAQ,QAAQ;IACzB;IACA,iBAAiB,QAAQ,UAAU;IACnC,OAAO,UAAU,QAAQ,KAAK,KAAK;IACnC,QAAQ,UAAU,QAAQ,MAAM,KAAK;GAI1B;EACb;EACA,KAAKR,UAAU,IAAI,KAAK,KAAK;EAC7B,OAAO;CACT;CAEA,oBAAoB,KAAmB;EACrC,KAAKA,UAAU,OAAO,GAAG;CAC3B;CAEA,oBAAoB,cAAqD;EACvE,OAAO,KAAKM,cAAc,aAAa,UAAU,EAAE,OACjD,aAAa,OACb,EAAE,gBAAgB,aAAa,eAAe,CAChD;CACF;CAEA,8BAA+D;EAC7D,MAAM,eAAe,KAAKP;EAC1B,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,+BAA+B;EAGjD,OAAO;GACL,cAAc,aAAa;GAC3B,OAAO,aAAa;GACpB,YAAY,aAAa;GACzB,OAAO,KAAKF;EACd;CACF;AACF"}
@@ -0,0 +1,40 @@
1
+ import { ExecutionHost } from "../execution/types.js";
2
+ import { CloudflareAlarmDrainBudget } from "./cloudflare-alarm-budget.js";
3
+ import { CloudflareDurableObjectStorage } from "./cloudflare-host.js";
4
+ import { CloudflareAlarmAgent, CloudflareAlarmDrainSummary } from "./cloudflare-alarm-drainer.js";
5
+
6
+ //#region src/cloudflare/cloudflare-agent-context.d.ts
7
+ type MaybePromise<T> = Promise<T> | T;
8
+ interface CloudflareAgentContextFactoryOptions<Env> {
9
+ readonly env: Env;
10
+ readonly host: ExecutionHost;
11
+ readonly prefix: string;
12
+ readonly storage: CloudflareDurableObjectStorage;
13
+ }
14
+ interface CloudflareAgentContextPrefixOptions<Env> {
15
+ readonly env: Env;
16
+ readonly storage: CloudflareDurableObjectStorage;
17
+ }
18
+ interface CloudflareAgentContextOptions<Env, Agent extends CloudflareAlarmAgent> {
19
+ readonly createAgent: (options: CloudflareAgentContextFactoryOptions<Env>) => Agent;
20
+ readonly defaultPrefix?: string;
21
+ readonly env: Env;
22
+ readonly readPrefix?: (options: CloudflareAgentContextPrefixOptions<Env>) => MaybePromise<string | undefined>;
23
+ readonly storage: CloudflareDurableObjectStorage;
24
+ }
25
+ interface CloudflareAgentContext<Agent extends CloudflareAlarmAgent> {
26
+ agent(prefix?: string): Agent;
27
+ drainAlarm(budget?: CloudflareAlarmDrainBudget): Promise<CloudflareAlarmDrainSummary>;
28
+ host(prefix?: string): ExecutionHost;
29
+ readonly storage: CloudflareDurableObjectStorage;
30
+ }
31
+ declare function createCloudflareAgentContext<Env, Agent extends CloudflareAlarmAgent>({
32
+ createAgent,
33
+ defaultPrefix,
34
+ env,
35
+ readPrefix,
36
+ storage
37
+ }: CloudflareAgentContextOptions<Env, Agent>): CloudflareAgentContext<Agent>;
38
+ //#endregion
39
+ export { CloudflareAgentContext, CloudflareAgentContextFactoryOptions, CloudflareAgentContextOptions, CloudflareAgentContextPrefixOptions, createCloudflareAgentContext };
40
+ //# sourceMappingURL=cloudflare-agent-context.d.ts.map
@@ -0,0 +1,37 @@
1
+ import { createCloudflareDurableObjectHost } from "./cloudflare-host.js";
2
+ import { drainCloudflareAlarm } from "./cloudflare-alarm-drainer.js";
3
+ //#region src/cloudflare/cloudflare-agent-context.ts
4
+ const defaultContextPrefix = "pss-runtime";
5
+ function createCloudflareAgentContext({ createAgent, defaultPrefix = defaultContextPrefix, env, readPrefix, storage }) {
6
+ const createHost = (prefix = defaultPrefix) => createCloudflareDurableObjectHost({
7
+ prefix,
8
+ storage
9
+ });
10
+ const createContextAgent = (prefix = defaultPrefix) => createAgent({
11
+ env,
12
+ host: createHost(prefix),
13
+ prefix,
14
+ storage
15
+ });
16
+ return {
17
+ agent: createContextAgent,
18
+ drainAlarm: async (budget) => {
19
+ const prefix = await readPrefix?.({
20
+ env,
21
+ storage
22
+ }) ?? defaultPrefix;
23
+ return await drainCloudflareAlarm({
24
+ agent: createContextAgent(prefix),
25
+ ...budget,
26
+ prefix,
27
+ storage
28
+ });
29
+ },
30
+ host: createHost,
31
+ storage
32
+ };
33
+ }
34
+ //#endregion
35
+ export { createCloudflareAgentContext };
36
+
37
+ //# sourceMappingURL=cloudflare-agent-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare-agent-context.js","names":[],"sources":["../../src/cloudflare/cloudflare-agent-context.ts"],"sourcesContent":["import type { ExecutionHost } from \"../execution\";\nimport type { CloudflareAlarmDrainBudget } from \"./cloudflare-alarm-budget\";\nimport type {\n CloudflareAlarmAgent,\n CloudflareAlarmDrainSummary,\n} from \"./cloudflare-alarm-drainer\";\nimport { drainCloudflareAlarm } from \"./cloudflare-alarm-drainer\";\nimport {\n type CloudflareDurableObjectStorage,\n createCloudflareDurableObjectHost,\n} from \"./cloudflare-host\";\n\nconst defaultContextPrefix = \"pss-runtime\";\n\ntype MaybePromise<T> = Promise<T> | T;\n\nexport interface CloudflareAgentContextFactoryOptions<Env> {\n readonly env: Env;\n readonly host: ExecutionHost;\n readonly prefix: string;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport interface CloudflareAgentContextPrefixOptions<Env> {\n readonly env: Env;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport interface CloudflareAgentContextOptions<\n Env,\n Agent extends CloudflareAlarmAgent,\n> {\n readonly createAgent: (\n options: CloudflareAgentContextFactoryOptions<Env>\n ) => Agent;\n readonly defaultPrefix?: string;\n readonly env: Env;\n readonly readPrefix?: (\n options: CloudflareAgentContextPrefixOptions<Env>\n ) => MaybePromise<string | undefined>;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport interface CloudflareAgentContext<Agent extends CloudflareAlarmAgent> {\n agent(prefix?: string): Agent;\n drainAlarm(\n budget?: CloudflareAlarmDrainBudget\n ): Promise<CloudflareAlarmDrainSummary>;\n host(prefix?: string): ExecutionHost;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport function createCloudflareAgentContext<\n Env,\n Agent extends CloudflareAlarmAgent,\n>({\n createAgent,\n defaultPrefix = defaultContextPrefix,\n env,\n readPrefix,\n storage,\n}: CloudflareAgentContextOptions<Env, Agent>): CloudflareAgentContext<Agent> {\n const createHost = (prefix = defaultPrefix) =>\n createCloudflareDurableObjectHost({ prefix, storage });\n const createContextAgent = (prefix = defaultPrefix) =>\n createAgent({\n env,\n host: createHost(prefix),\n prefix,\n storage,\n });\n\n return {\n agent: createContextAgent,\n drainAlarm: async (budget) => {\n const prefix = (await readPrefix?.({ env, storage })) ?? defaultPrefix;\n return await drainCloudflareAlarm({\n agent: createContextAgent(prefix),\n ...budget,\n prefix,\n storage,\n });\n },\n host: createHost,\n storage,\n };\n}\n"],"mappings":";;;AAYA,MAAM,uBAAuB;AAwC7B,SAAgB,6BAGd,EACA,aACA,gBAAgB,sBAChB,KACA,YACA,WAC2E;CAC3E,MAAM,cAAc,SAAS,kBAC3B,kCAAkC;EAAE;EAAQ;CAAQ,CAAC;CACvD,MAAM,sBAAsB,SAAS,kBACnC,YAAY;EACV;EACA,MAAM,WAAW,MAAM;EACvB;EACA;CACF,CAAC;CAEH,OAAO;EACL,OAAO;EACP,YAAY,OAAO,WAAW;GAC5B,MAAM,SAAU,MAAM,aAAa;IAAE;IAAK;GAAQ,CAAC,KAAM;GACzD,OAAO,MAAM,qBAAqB;IAChC,OAAO,mBAAmB,MAAM;IAChC,GAAG;IACH;IACA;GACF,CAAC;EACH;EACA,MAAM;EACN;CACF;AACF"}
@@ -0,0 +1,18 @@
1
+ //#region src/cloudflare/cloudflare-alarm-budget.d.ts
2
+ type CloudflareAlarmContinuationReason = "deadline" | "event-budget" | "failure" | "run-budget" | "session-prompt-budget";
3
+ interface CloudflareAlarmDrainBudget {
4
+ readonly continuationRunAfterMs?: number;
5
+ readonly deadlineMs?: number;
6
+ readonly failureRunAfterMs?: number;
7
+ readonly maxEvents?: number;
8
+ readonly maxRuns?: number;
9
+ readonly maxSessionPrompts?: number;
10
+ readonly throwOnFailure?: boolean;
11
+ }
12
+ interface FailedScheduledWork {
13
+ readonly error: string;
14
+ readonly id: string;
15
+ }
16
+ //#endregion
17
+ export { CloudflareAlarmContinuationReason, CloudflareAlarmDrainBudget, FailedScheduledWork };
18
+ //# sourceMappingURL=cloudflare-alarm-budget.d.ts.map
@@ -0,0 +1,77 @@
1
+ //#region src/cloudflare/cloudflare-alarm-budget.ts
2
+ const defaultAlarmDrainBudget = {
3
+ continuationRunAfterMs: 0,
4
+ deadlineMs: 3e4,
5
+ failureRunAfterMs: 1e3,
6
+ maxEvents: 1e3,
7
+ maxRuns: 25,
8
+ maxSessionPrompts: 25,
9
+ throwOnFailure: false
10
+ };
11
+ function createAlarmDrainState() {
12
+ return {
13
+ consumedSessionPrompts: [],
14
+ droppedEvents: 0,
15
+ events: [],
16
+ failedRuns: [],
17
+ failedSessionPrompts: [],
18
+ reasons: /* @__PURE__ */ new Set(),
19
+ resumedRuns: [],
20
+ runAttempts: 0,
21
+ sessionPromptAttempts: 0
22
+ };
23
+ }
24
+ function normalizeAlarmDrainBudget(budget = {}) {
25
+ return {
26
+ continuationRunAfterMs: nonNegativeInteger(budget.continuationRunAfterMs ?? defaultAlarmDrainBudget.continuationRunAfterMs),
27
+ deadlineMs: nonNegativeInteger(budget.deadlineMs ?? defaultAlarmDrainBudget.deadlineMs),
28
+ failureRunAfterMs: nonNegativeInteger(budget.failureRunAfterMs ?? defaultAlarmDrainBudget.failureRunAfterMs),
29
+ maxEvents: nonNegativeInteger(budget.maxEvents ?? defaultAlarmDrainBudget.maxEvents),
30
+ maxRuns: nonNegativeInteger(budget.maxRuns ?? defaultAlarmDrainBudget.maxRuns),
31
+ maxSessionPrompts: nonNegativeInteger(budget.maxSessionPrompts ?? defaultAlarmDrainBudget.maxSessionPrompts),
32
+ startedAt: Date.now(),
33
+ throwOnFailure: budget.throwOnFailure ?? defaultAlarmDrainBudget.throwOnFailure
34
+ };
35
+ }
36
+ function eventSlotsRemaining(state, budget) {
37
+ return Math.max(0, budget.maxEvents - state.events.length);
38
+ }
39
+ function shouldStopForDeadline(budget) {
40
+ return Date.now() - budget.startedAt >= budget.deadlineMs;
41
+ }
42
+ function shouldStopRuns(state, budget) {
43
+ if (shouldStopForDeadline(budget)) {
44
+ state.reasons.add("deadline");
45
+ return true;
46
+ }
47
+ if (shouldStopForEventBudget(state, budget)) return true;
48
+ if (state.runAttempts >= budget.maxRuns) {
49
+ state.reasons.add("run-budget");
50
+ return true;
51
+ }
52
+ return false;
53
+ }
54
+ function shouldStopSessionPrompts(state, budget) {
55
+ if (shouldStopForDeadline(budget)) {
56
+ state.reasons.add("deadline");
57
+ return true;
58
+ }
59
+ if (shouldStopForEventBudget(state, budget)) return true;
60
+ if (state.sessionPromptAttempts >= budget.maxSessionPrompts) {
61
+ state.reasons.add("session-prompt-budget");
62
+ return true;
63
+ }
64
+ return false;
65
+ }
66
+ function shouldStopForEventBudget(state, budget) {
67
+ if (state.events.length < budget.maxEvents) return false;
68
+ state.reasons.add("event-budget");
69
+ return true;
70
+ }
71
+ function nonNegativeInteger(value) {
72
+ return Math.max(0, Math.floor(value));
73
+ }
74
+ //#endregion
75
+ export { createAlarmDrainState, eventSlotsRemaining, normalizeAlarmDrainBudget, shouldStopRuns, shouldStopSessionPrompts };
76
+
77
+ //# sourceMappingURL=cloudflare-alarm-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare-alarm-budget.js","names":[],"sources":["../../src/cloudflare/cloudflare-alarm-budget.ts"],"sourcesContent":["import type { AgentEvent } from \"../index\";\n\nexport type CloudflareAlarmContinuationReason =\n | \"deadline\"\n | \"event-budget\"\n | \"failure\"\n | \"run-budget\"\n | \"session-prompt-budget\";\n\nexport interface CloudflareAlarmDrainBudget {\n readonly continuationRunAfterMs?: number;\n readonly deadlineMs?: number;\n readonly failureRunAfterMs?: number;\n readonly maxEvents?: number;\n readonly maxRuns?: number;\n readonly maxSessionPrompts?: number;\n readonly throwOnFailure?: boolean;\n}\n\nexport interface FailedScheduledWork {\n readonly error: string;\n readonly id: string;\n}\n\nexport interface AlarmDrainState {\n readonly consumedSessionPrompts: string[];\n droppedEvents: number;\n readonly events: AgentEvent[];\n readonly failedRuns: FailedScheduledWork[];\n readonly failedSessionPrompts: FailedScheduledWork[];\n readonly reasons: Set<CloudflareAlarmContinuationReason>;\n readonly resumedRuns: string[];\n runAttempts: number;\n sessionPromptAttempts: number;\n}\n\nexport interface NormalizedAlarmDrainBudget {\n readonly continuationRunAfterMs: number;\n readonly deadlineMs: number;\n readonly failureRunAfterMs: number;\n readonly maxEvents: number;\n readonly maxRuns: number;\n readonly maxSessionPrompts: number;\n readonly startedAt: number;\n readonly throwOnFailure: boolean;\n}\n\nconst defaultAlarmDrainBudget = {\n continuationRunAfterMs: 0,\n deadlineMs: 30_000,\n failureRunAfterMs: 1000,\n maxEvents: 1000,\n maxRuns: 25,\n maxSessionPrompts: 25,\n throwOnFailure: false,\n} satisfies Required<CloudflareAlarmDrainBudget>;\n\nexport function createAlarmDrainState(): AlarmDrainState {\n return {\n consumedSessionPrompts: [],\n droppedEvents: 0,\n events: [],\n failedRuns: [],\n failedSessionPrompts: [],\n reasons: new Set<CloudflareAlarmContinuationReason>(),\n resumedRuns: [],\n runAttempts: 0,\n sessionPromptAttempts: 0,\n };\n}\n\nexport function normalizeAlarmDrainBudget(\n budget: CloudflareAlarmDrainBudget = {}\n): NormalizedAlarmDrainBudget {\n return {\n continuationRunAfterMs: nonNegativeInteger(\n budget.continuationRunAfterMs ??\n defaultAlarmDrainBudget.continuationRunAfterMs\n ),\n deadlineMs: nonNegativeInteger(\n budget.deadlineMs ?? defaultAlarmDrainBudget.deadlineMs\n ),\n failureRunAfterMs: nonNegativeInteger(\n budget.failureRunAfterMs ?? defaultAlarmDrainBudget.failureRunAfterMs\n ),\n maxEvents: nonNegativeInteger(\n budget.maxEvents ?? defaultAlarmDrainBudget.maxEvents\n ),\n maxRuns: nonNegativeInteger(\n budget.maxRuns ?? defaultAlarmDrainBudget.maxRuns\n ),\n maxSessionPrompts: nonNegativeInteger(\n budget.maxSessionPrompts ?? defaultAlarmDrainBudget.maxSessionPrompts\n ),\n startedAt: Date.now(),\n throwOnFailure:\n budget.throwOnFailure ?? defaultAlarmDrainBudget.throwOnFailure,\n };\n}\n\nexport function eventSlotsRemaining(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): number {\n return Math.max(0, budget.maxEvents - state.events.length);\n}\n\nexport function shouldStopForDeadline(\n budget: NormalizedAlarmDrainBudget\n): boolean {\n return Date.now() - budget.startedAt >= budget.deadlineMs;\n}\n\nexport function shouldStopRuns(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): boolean {\n if (shouldStopForDeadline(budget)) {\n state.reasons.add(\"deadline\");\n return true;\n }\n if (shouldStopForEventBudget(state, budget)) {\n return true;\n }\n if (state.runAttempts >= budget.maxRuns) {\n state.reasons.add(\"run-budget\");\n return true;\n }\n return false;\n}\n\nexport function shouldStopSessionPrompts(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): boolean {\n if (shouldStopForDeadline(budget)) {\n state.reasons.add(\"deadline\");\n return true;\n }\n if (shouldStopForEventBudget(state, budget)) {\n return true;\n }\n if (state.sessionPromptAttempts >= budget.maxSessionPrompts) {\n state.reasons.add(\"session-prompt-budget\");\n return true;\n }\n return false;\n}\n\nfunction shouldStopForEventBudget(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): boolean {\n if (state.events.length < budget.maxEvents) {\n return false;\n }\n state.reasons.add(\"event-budget\");\n return true;\n}\n\nfunction nonNegativeInteger(value: number): number {\n return Math.max(0, Math.floor(value));\n}\n"],"mappings":";AA+CA,MAAM,0BAA0B;CAC9B,wBAAwB;CACxB,YAAY;CACZ,mBAAmB;CACnB,WAAW;CACX,SAAS;CACT,mBAAmB;CACnB,gBAAgB;AAClB;AAEA,SAAgB,wBAAyC;CACvD,OAAO;EACL,wBAAwB,CAAC;EACzB,eAAe;EACf,QAAQ,CAAC;EACT,YAAY,CAAC;EACb,sBAAsB,CAAC;EACvB,yBAAS,IAAI,IAAuC;EACpD,aAAa,CAAC;EACd,aAAa;EACb,uBAAuB;CACzB;AACF;AAEA,SAAgB,0BACd,SAAqC,CAAC,GACV;CAC5B,OAAO;EACL,wBAAwB,mBACtB,OAAO,0BACL,wBAAwB,sBAC5B;EACA,YAAY,mBACV,OAAO,cAAc,wBAAwB,UAC/C;EACA,mBAAmB,mBACjB,OAAO,qBAAqB,wBAAwB,iBACtD;EACA,WAAW,mBACT,OAAO,aAAa,wBAAwB,SAC9C;EACA,SAAS,mBACP,OAAO,WAAW,wBAAwB,OAC5C;EACA,mBAAmB,mBACjB,OAAO,qBAAqB,wBAAwB,iBACtD;EACA,WAAW,KAAK,IAAI;EACpB,gBACE,OAAO,kBAAkB,wBAAwB;CACrD;AACF;AAEA,SAAgB,oBACd,OACA,QACQ;CACR,OAAO,KAAK,IAAI,GAAG,OAAO,YAAY,MAAM,OAAO,MAAM;AAC3D;AAEA,SAAgB,sBACd,QACS;CACT,OAAO,KAAK,IAAI,IAAI,OAAO,aAAa,OAAO;AACjD;AAEA,SAAgB,eACd,OACA,QACS;CACT,IAAI,sBAAsB,MAAM,GAAG;EACjC,MAAM,QAAQ,IAAI,UAAU;EAC5B,OAAO;CACT;CACA,IAAI,yBAAyB,OAAO,MAAM,GACxC,OAAO;CAET,IAAI,MAAM,eAAe,OAAO,SAAS;EACvC,MAAM,QAAQ,IAAI,YAAY;EAC9B,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAgB,yBACd,OACA,QACS;CACT,IAAI,sBAAsB,MAAM,GAAG;EACjC,MAAM,QAAQ,IAAI,UAAU;EAC5B,OAAO;CACT;CACA,IAAI,yBAAyB,OAAO,MAAM,GACxC,OAAO;CAET,IAAI,MAAM,yBAAyB,OAAO,mBAAmB;EAC3D,MAAM,QAAQ,IAAI,uBAAuB;EACzC,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAS,yBACP,OACA,QACS;CACT,IAAI,MAAM,OAAO,SAAS,OAAO,WAC/B,OAAO;CAET,MAAM,QAAQ,IAAI,cAAc;CAChC,OAAO;AACT;AAEA,SAAS,mBAAmB,OAAuB;CACjD,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACtC"}
@@ -0,0 +1,45 @@
1
+ import { AgentEvent } from "../session/events.js";
2
+ import { AgentRun } from "../session/run.js";
3
+ import { CloudflareAlarmContinuationReason, CloudflareAlarmDrainBudget, FailedScheduledWork } from "./cloudflare-alarm-budget.js";
4
+ import { CloudflareDurableObjectStorage } from "./cloudflare-host.js";
5
+
6
+ //#region src/cloudflare/cloudflare-alarm-drainer.d.ts
7
+ interface CloudflareAlarmDrainSummary {
8
+ readonly consumedSessionPrompts: readonly string[];
9
+ readonly continuationReasons: readonly CloudflareAlarmContinuationReason[];
10
+ readonly continuationScheduled: boolean;
11
+ readonly droppedEvents: number;
12
+ readonly events: readonly AgentEvent[];
13
+ readonly failedRuns: readonly FailedScheduledWork[];
14
+ readonly failedSessionPrompts: readonly FailedScheduledWork[];
15
+ readonly markers: readonly string[];
16
+ readonly remainingRuns: number;
17
+ readonly remainingSessionPrompts: number;
18
+ readonly resumedRuns: readonly string[];
19
+ }
20
+ interface CloudflareAlarmAgent {
21
+ resume(runId: string): Promise<AgentRun | null>;
22
+ }
23
+ declare class CloudflareAlarmDrainFailureError extends Error {
24
+ readonly summary: CloudflareAlarmDrainSummary;
25
+ constructor(summary: CloudflareAlarmDrainSummary);
26
+ }
27
+ declare function drainCloudflareAlarm({
28
+ agent,
29
+ continuationRunAfterMs,
30
+ deadlineMs,
31
+ failureRunAfterMs,
32
+ maxEvents,
33
+ maxRuns,
34
+ maxSessionPrompts,
35
+ prefix,
36
+ storage,
37
+ throwOnFailure
38
+ }: {
39
+ readonly agent: CloudflareAlarmAgent;
40
+ readonly prefix: string;
41
+ readonly storage: CloudflareDurableObjectStorage;
42
+ } & CloudflareAlarmDrainBudget): Promise<CloudflareAlarmDrainSummary>;
43
+ //#endregion
44
+ export { CloudflareAlarmAgent, CloudflareAlarmDrainFailureError, CloudflareAlarmDrainSummary, drainCloudflareAlarm };
45
+ //# sourceMappingURL=cloudflare-alarm-drainer.d.ts.map
@@ -0,0 +1,103 @@
1
+ import { createAlarmDrainState, normalizeAlarmDrainBudget, shouldStopRuns, shouldStopSessionPrompts } from "./cloudflare-alarm-budget.js";
2
+ import { listScheduledCloudflareRuns, listScheduledCloudflareSessionPrompts, rescheduleCloudflareAlarm } from "./cloudflare-host.js";
3
+ import { resumeScheduledRun, resumeScheduledSessionPrompt } from "./cloudflare-alarm-work.js";
4
+ //#region src/cloudflare/cloudflare-alarm-drainer.ts
5
+ var CloudflareAlarmDrainFailureError = class extends Error {
6
+ summary;
7
+ constructor(summary) {
8
+ super("Cloudflare alarm drain completed with failed scheduled work.");
9
+ this.name = "CloudflareAlarmDrainFailureError";
10
+ this.summary = summary;
11
+ }
12
+ };
13
+ async function drainCloudflareAlarm({ agent, continuationRunAfterMs, deadlineMs, failureRunAfterMs, maxEvents, maxRuns, maxSessionPrompts, prefix, storage, throwOnFailure }) {
14
+ const budget = normalizeAlarmDrainBudget({
15
+ continuationRunAfterMs,
16
+ deadlineMs,
17
+ failureRunAfterMs,
18
+ maxEvents,
19
+ maxRuns,
20
+ maxSessionPrompts,
21
+ throwOnFailure
22
+ });
23
+ const state = createAlarmDrainState();
24
+ await drainRuns({
25
+ agent,
26
+ budget,
27
+ prefix,
28
+ state,
29
+ storage
30
+ });
31
+ await drainSessionPrompts({
32
+ agent,
33
+ budget,
34
+ prefix,
35
+ state,
36
+ storage
37
+ });
38
+ const summary = await summarizeDrain({
39
+ budget,
40
+ prefix,
41
+ state,
42
+ storage
43
+ });
44
+ if (budget.throwOnFailure && hasFailures(summary)) throw new CloudflareAlarmDrainFailureError(summary);
45
+ return summary;
46
+ }
47
+ async function drainRuns(options) {
48
+ for (const runId of await listScheduledCloudflareRuns(options.storage, { prefix: options.prefix })) {
49
+ if (shouldStopRuns(options.state, options.budget)) break;
50
+ options.state.runAttempts += 1;
51
+ await resumeScheduledRun({
52
+ ...options,
53
+ runId
54
+ });
55
+ }
56
+ }
57
+ async function drainSessionPrompts(options) {
58
+ const prompts = await listScheduledCloudflareSessionPrompts(options.storage, { prefix: options.prefix });
59
+ for (const prompt of prompts) {
60
+ if (shouldStopSessionPrompts(options.state, options.budget)) break;
61
+ options.state.sessionPromptAttempts += 1;
62
+ await resumeScheduledSessionPrompt({
63
+ ...options,
64
+ prompt
65
+ });
66
+ }
67
+ }
68
+ async function summarizeDrain({ budget, prefix, state, storage }) {
69
+ const remainingRuns = await listScheduledCloudflareRuns(storage, { prefix });
70
+ const remainingPrompts = await listScheduledCloudflareSessionPrompts(storage, { prefix });
71
+ if (state.failedRuns.length > 0 || state.failedSessionPrompts.length > 0) state.reasons.add("failure");
72
+ const continuationScheduled = shouldRearm(state, remainingRuns.length, remainingPrompts.length);
73
+ if (continuationScheduled) await rescheduleCloudflareAlarm(storage, { runAfterMs: state.reasons.has("failure") ? budget.failureRunAfterMs : budget.continuationRunAfterMs });
74
+ return {
75
+ consumedSessionPrompts: state.consumedSessionPrompts,
76
+ continuationReasons: [...state.reasons],
77
+ continuationScheduled,
78
+ droppedEvents: state.droppedEvents,
79
+ events: state.events,
80
+ failedRuns: state.failedRuns,
81
+ failedSessionPrompts: state.failedSessionPrompts,
82
+ markers: markersFor(state.reasons),
83
+ remainingRuns: remainingRuns.length,
84
+ remainingSessionPrompts: remainingPrompts.length,
85
+ resumedRuns: state.resumedRuns
86
+ };
87
+ }
88
+ function shouldRearm(state, remainingRuns, remainingPrompts) {
89
+ return state.reasons.size > 0 && (remainingRuns > 0 || remainingPrompts > 0 || state.reasons.has("failure"));
90
+ }
91
+ function hasFailures(summary) {
92
+ return summary.failedRuns.length > 0 || summary.failedSessionPrompts.length > 0;
93
+ }
94
+ function markersFor(reasons) {
95
+ const markers = ["alarm:resume", "resume:session-prompt"];
96
+ if (reasons.size > 0) markers.push("alarm:continuation-rearm");
97
+ if (reasons.has("failure")) markers.push("alarm:failure");
98
+ return markers;
99
+ }
100
+ //#endregion
101
+ export { CloudflareAlarmDrainFailureError, drainCloudflareAlarm };
102
+
103
+ //# sourceMappingURL=cloudflare-alarm-drainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare-alarm-drainer.js","names":[],"sources":["../../src/cloudflare/cloudflare-alarm-drainer.ts"],"sourcesContent":["import type { AgentEvent, AgentRun } from \"../index\";\nimport {\n type AlarmDrainState,\n type CloudflareAlarmContinuationReason,\n type CloudflareAlarmDrainBudget,\n createAlarmDrainState,\n type FailedScheduledWork,\n type NormalizedAlarmDrainBudget,\n normalizeAlarmDrainBudget,\n shouldStopRuns,\n shouldStopSessionPrompts,\n} from \"./cloudflare-alarm-budget\";\nimport {\n resumeScheduledRun,\n resumeScheduledSessionPrompt,\n} from \"./cloudflare-alarm-work\";\nimport {\n type CloudflareDurableObjectStorage,\n listScheduledCloudflareRuns,\n listScheduledCloudflareSessionPrompts,\n rescheduleCloudflareAlarm,\n} from \"./cloudflare-host\";\n\nexport type {\n CloudflareAlarmContinuationReason,\n CloudflareAlarmDrainBudget,\n FailedScheduledWork,\n} from \"./cloudflare-alarm-budget\";\n\nexport interface CloudflareAlarmDrainSummary {\n readonly consumedSessionPrompts: readonly string[];\n readonly continuationReasons: readonly CloudflareAlarmContinuationReason[];\n readonly continuationScheduled: boolean;\n readonly droppedEvents: number;\n readonly events: readonly AgentEvent[];\n readonly failedRuns: readonly FailedScheduledWork[];\n readonly failedSessionPrompts: readonly FailedScheduledWork[];\n readonly markers: readonly string[];\n readonly remainingRuns: number;\n readonly remainingSessionPrompts: number;\n readonly resumedRuns: readonly string[];\n}\n\nexport interface CloudflareAlarmAgent {\n resume(runId: string): Promise<AgentRun | null>;\n}\n\nexport class CloudflareAlarmDrainFailureError extends Error {\n readonly summary: CloudflareAlarmDrainSummary;\n\n constructor(summary: CloudflareAlarmDrainSummary) {\n super(\"Cloudflare alarm drain completed with failed scheduled work.\");\n this.name = \"CloudflareAlarmDrainFailureError\";\n this.summary = summary;\n }\n}\n\nexport async function drainCloudflareAlarm({\n agent,\n continuationRunAfterMs,\n deadlineMs,\n failureRunAfterMs,\n maxEvents,\n maxRuns,\n maxSessionPrompts,\n prefix,\n storage,\n throwOnFailure,\n}: {\n readonly agent: CloudflareAlarmAgent;\n readonly prefix: string;\n readonly storage: CloudflareDurableObjectStorage;\n} & CloudflareAlarmDrainBudget): Promise<CloudflareAlarmDrainSummary> {\n const budget = normalizeAlarmDrainBudget({\n continuationRunAfterMs,\n deadlineMs,\n failureRunAfterMs,\n maxEvents,\n maxRuns,\n maxSessionPrompts,\n throwOnFailure,\n });\n const state = createAlarmDrainState();\n\n await drainRuns({ agent, budget, prefix, state, storage });\n await drainSessionPrompts({ agent, budget, prefix, state, storage });\n\n const summary = await summarizeDrain({ budget, prefix, state, storage });\n if (budget.throwOnFailure && hasFailures(summary)) {\n throw new CloudflareAlarmDrainFailureError(summary);\n }\n return summary;\n}\n\nasync function drainRuns(options: DrainLoopOptions): Promise<void> {\n for (const runId of await listScheduledCloudflareRuns(options.storage, {\n prefix: options.prefix,\n })) {\n if (shouldStopRuns(options.state, options.budget)) {\n break;\n }\n options.state.runAttempts += 1;\n await resumeScheduledRun({ ...options, runId });\n }\n}\n\nasync function drainSessionPrompts(options: DrainLoopOptions): Promise<void> {\n const prompts = await listScheduledCloudflareSessionPrompts(options.storage, {\n prefix: options.prefix,\n });\n for (const prompt of prompts) {\n if (shouldStopSessionPrompts(options.state, options.budget)) {\n break;\n }\n options.state.sessionPromptAttempts += 1;\n await resumeScheduledSessionPrompt({ ...options, prompt });\n }\n}\n\nasync function summarizeDrain({\n budget,\n prefix,\n state,\n storage,\n}: {\n readonly budget: NormalizedAlarmDrainBudget;\n readonly prefix: string;\n readonly state: AlarmDrainState;\n readonly storage: CloudflareDurableObjectStorage;\n}): Promise<CloudflareAlarmDrainSummary> {\n const remainingRuns = await listScheduledCloudflareRuns(storage, { prefix });\n const remainingPrompts = await listScheduledCloudflareSessionPrompts(\n storage,\n {\n prefix,\n }\n );\n if (state.failedRuns.length > 0 || state.failedSessionPrompts.length > 0) {\n state.reasons.add(\"failure\");\n }\n const continuationScheduled = shouldRearm(\n state,\n remainingRuns.length,\n remainingPrompts.length\n );\n if (continuationScheduled) {\n await rescheduleCloudflareAlarm(storage, {\n runAfterMs: state.reasons.has(\"failure\")\n ? budget.failureRunAfterMs\n : budget.continuationRunAfterMs,\n });\n }\n return {\n consumedSessionPrompts: state.consumedSessionPrompts,\n continuationReasons: [...state.reasons],\n continuationScheduled,\n droppedEvents: state.droppedEvents,\n events: state.events,\n failedRuns: state.failedRuns,\n failedSessionPrompts: state.failedSessionPrompts,\n markers: markersFor(state.reasons),\n remainingRuns: remainingRuns.length,\n remainingSessionPrompts: remainingPrompts.length,\n resumedRuns: state.resumedRuns,\n };\n}\n\ninterface DrainLoopOptions {\n readonly agent: CloudflareAlarmAgent;\n readonly budget: NormalizedAlarmDrainBudget;\n readonly prefix: string;\n readonly state: AlarmDrainState;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nfunction shouldRearm(\n state: AlarmDrainState,\n remainingRuns: number,\n remainingPrompts: number\n): boolean {\n return (\n state.reasons.size > 0 &&\n (remainingRuns > 0 || remainingPrompts > 0 || state.reasons.has(\"failure\"))\n );\n}\n\nfunction hasFailures(summary: CloudflareAlarmDrainSummary): boolean {\n return (\n summary.failedRuns.length > 0 || summary.failedSessionPrompts.length > 0\n );\n}\n\nfunction markersFor(\n reasons: ReadonlySet<CloudflareAlarmContinuationReason>\n): readonly string[] {\n const markers = [\"alarm:resume\", \"resume:session-prompt\"];\n if (reasons.size > 0) {\n markers.push(\"alarm:continuation-rearm\");\n }\n if (reasons.has(\"failure\")) {\n markers.push(\"alarm:failure\");\n }\n return markers;\n}\n"],"mappings":";;;;AA+CA,IAAa,mCAAb,cAAsD,MAAM;CAC1D;CAEA,YAAY,SAAsC;EAChD,MAAM,8DAA8D;EACpE,KAAK,OAAO;EACZ,KAAK,UAAU;CACjB;AACF;AAEA,eAAsB,qBAAqB,EACzC,OACA,wBACA,YACA,mBACA,WACA,SACA,mBACA,QACA,SACA,kBAKoE;CACpE,MAAM,SAAS,0BAA0B;EACvC;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,MAAM,QAAQ,sBAAsB;CAEpC,MAAM,UAAU;EAAE;EAAO;EAAQ;EAAQ;EAAO;CAAQ,CAAC;CACzD,MAAM,oBAAoB;EAAE;EAAO;EAAQ;EAAQ;EAAO;CAAQ,CAAC;CAEnE,MAAM,UAAU,MAAM,eAAe;EAAE;EAAQ;EAAQ;EAAO;CAAQ,CAAC;CACvE,IAAI,OAAO,kBAAkB,YAAY,OAAO,GAC9C,MAAM,IAAI,iCAAiC,OAAO;CAEpD,OAAO;AACT;AAEA,eAAe,UAAU,SAA0C;CACjE,KAAK,MAAM,SAAS,MAAM,4BAA4B,QAAQ,SAAS,EACrE,QAAQ,QAAQ,OAClB,CAAC,GAAG;EACF,IAAI,eAAe,QAAQ,OAAO,QAAQ,MAAM,GAC9C;EAEF,QAAQ,MAAM,eAAe;EAC7B,MAAM,mBAAmB;GAAE,GAAG;GAAS;EAAM,CAAC;CAChD;AACF;AAEA,eAAe,oBAAoB,SAA0C;CAC3E,MAAM,UAAU,MAAM,sCAAsC,QAAQ,SAAS,EAC3E,QAAQ,QAAQ,OAClB,CAAC;CACD,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,yBAAyB,QAAQ,OAAO,QAAQ,MAAM,GACxD;EAEF,QAAQ,MAAM,yBAAyB;EACvC,MAAM,6BAA6B;GAAE,GAAG;GAAS;EAAO,CAAC;CAC3D;AACF;AAEA,eAAe,eAAe,EAC5B,QACA,QACA,OACA,WAMuC;CACvC,MAAM,gBAAgB,MAAM,4BAA4B,SAAS,EAAE,OAAO,CAAC;CAC3E,MAAM,mBAAmB,MAAM,sCAC7B,SACA,EACE,OACF,CACF;CACA,IAAI,MAAM,WAAW,SAAS,KAAK,MAAM,qBAAqB,SAAS,GACrE,MAAM,QAAQ,IAAI,SAAS;CAE7B,MAAM,wBAAwB,YAC5B,OACA,cAAc,QACd,iBAAiB,MACnB;CACA,IAAI,uBACF,MAAM,0BAA0B,SAAS,EACvC,YAAY,MAAM,QAAQ,IAAI,SAAS,IACnC,OAAO,oBACP,OAAO,uBACb,CAAC;CAEH,OAAO;EACL,wBAAwB,MAAM;EAC9B,qBAAqB,CAAC,GAAG,MAAM,OAAO;EACtC;EACA,eAAe,MAAM;EACrB,QAAQ,MAAM;EACd,YAAY,MAAM;EAClB,sBAAsB,MAAM;EAC5B,SAAS,WAAW,MAAM,OAAO;EACjC,eAAe,cAAc;EAC7B,yBAAyB,iBAAiB;EAC1C,aAAa,MAAM;CACrB;AACF;AAUA,SAAS,YACP,OACA,eACA,kBACS;CACT,OACE,MAAM,QAAQ,OAAO,MACpB,gBAAgB,KAAK,mBAAmB,KAAK,MAAM,QAAQ,IAAI,SAAS;AAE7E;AAEA,SAAS,YAAY,SAA+C;CAClE,OACE,QAAQ,WAAW,SAAS,KAAK,QAAQ,qBAAqB,SAAS;AAE3E;AAEA,SAAS,WACP,SACmB;CACnB,MAAM,UAAU,CAAC,gBAAgB,uBAAuB;CACxD,IAAI,QAAQ,OAAO,GACjB,QAAQ,KAAK,0BAA0B;CAEzC,IAAI,QAAQ,IAAI,SAAS,GACvB,QAAQ,KAAK,eAAe;CAE9B,OAAO;AACT"}