@minpeter/pss-runtime 0.1.0-next.1 → 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 (133) hide show
  1. package/README.md +290 -61
  2. package/dist/agent-host-session-store.js +10 -0
  3. package/dist/agent-host-session-store.js.map +1 -0
  4. package/dist/agent-loop.js +57 -28
  5. package/dist/agent-loop.js.map +1 -1
  6. package/dist/agent-namespace.js +6 -3
  7. package/dist/agent-namespace.js.map +1 -1
  8. package/dist/agent-options.d.ts +29 -0
  9. package/dist/agent-options.js +16 -0
  10. package/dist/agent-options.js.map +1 -0
  11. package/dist/agent-resume.js +63 -0
  12. package/dist/agent-resume.js.map +1 -0
  13. package/dist/agent-session-entry.d.ts +13 -0
  14. package/dist/agent.d.ts +8 -44
  15. package/dist/agent.js +61 -83
  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 +62 -0
  59. package/dist/execution/host.js.map +1 -0
  60. package/dist/execution/index.d.ts +6 -0
  61. package/dist/execution/index.js +4 -0
  62. package/dist/execution/memory-notifications.js +54 -0
  63. package/dist/execution/memory-notifications.js.map +1 -0
  64. package/dist/execution/memory-state.js +34 -0
  65. package/dist/execution/memory-state.js.map +1 -0
  66. package/dist/execution/memory-store.js +203 -0
  67. package/dist/execution/memory-store.js.map +1 -0
  68. package/dist/execution/memory.d.ts +7 -0
  69. package/dist/execution/memory.js +28 -0
  70. package/dist/execution/memory.js.map +1 -0
  71. package/dist/execution/types.d.ts +150 -0
  72. package/dist/index.d.ts +13 -6
  73. package/dist/index.js +6 -1
  74. package/dist/llm-tool-execution.d.ts +35 -0
  75. package/dist/llm-tool-execution.js +126 -0
  76. package/dist/llm-tool-execution.js.map +1 -0
  77. package/dist/llm.d.ts +11 -15
  78. package/dist/llm.js +5 -3
  79. package/dist/llm.js.map +1 -1
  80. package/dist/plugins.d.ts +42 -0
  81. package/dist/plugins.js +43 -0
  82. package/dist/plugins.js.map +1 -0
  83. package/dist/session/delegate-input.d.ts +9 -0
  84. package/dist/session/delegate-input.js +16 -0
  85. package/dist/session/delegate-input.js.map +1 -0
  86. package/dist/session/events.d.ts +43 -22
  87. package/dist/session/events.js +41 -0
  88. package/dist/session/events.js.map +1 -0
  89. package/dist/session/input-meta-types.d.ts +10 -0
  90. package/dist/session/input-meta.d.ts +13 -0
  91. package/dist/session/input-meta.js +45 -0
  92. package/dist/session/input-meta.js.map +1 -0
  93. package/dist/session/input.d.ts +4 -0
  94. package/dist/session/mapping.js +4 -2
  95. package/dist/session/mapping.js.map +1 -1
  96. package/dist/session/runtime-input-emit.js +41 -0
  97. package/dist/session/runtime-input-emit.js.map +1 -0
  98. package/dist/session/runtime-input.js +10 -24
  99. package/dist/session/runtime-input.js.map +1 -1
  100. package/dist/session/session-errors.js +1 -6
  101. package/dist/session/session-errors.js.map +1 -1
  102. package/dist/session/session-events.js +73 -0
  103. package/dist/session/session-events.js.map +1 -0
  104. package/dist/session/session-execution.js +88 -0
  105. package/dist/session/session-execution.js.map +1 -0
  106. package/dist/session/session-notification.js +59 -0
  107. package/dist/session/session-notification.js.map +1 -0
  108. package/dist/session/session-runtime-drain.js +3 -9
  109. package/dist/session/session-runtime-drain.js.map +1 -1
  110. package/dist/session/session-turn-processor.js +125 -0
  111. package/dist/session/session-turn-processor.js.map +1 -0
  112. package/dist/session/session.js +81 -102
  113. package/dist/session/session.js.map +1 -1
  114. package/dist/session/snapshot.js.map +1 -1
  115. package/package.json +16 -1
  116. package/dist/agent-validation.js +0 -35
  117. package/dist/agent-validation.js.map +0 -1
  118. package/dist/child-session-cleanups.js +0 -61
  119. package/dist/child-session-cleanups.js.map +0 -1
  120. package/dist/hooks.d.ts +0 -32
  121. package/dist/subagent-job-cancel.js +0 -28
  122. package/dist/subagent-job-cancel.js.map +0 -1
  123. package/dist/subagent-job-output.js +0 -63
  124. package/dist/subagent-job-output.js.map +0 -1
  125. package/dist/subagent-jobs.js +0 -151
  126. package/dist/subagent-jobs.js.map +0 -1
  127. package/dist/subagent-prompt-schema.js +0 -114
  128. package/dist/subagent-prompt-schema.js.map +0 -1
  129. package/dist/subagent-run.js +0 -111
  130. package/dist/subagent-run.js.map +0 -1
  131. package/dist/subagents.js +0 -92
  132. package/dist/subagents.js.map +0 -1
  133. /package/dist/session/{runtime-input.d.ts → session-execution.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"agent-namespace.js","names":[],"sources":["../src/agent-namespace.ts"],"sourcesContent":["export function randomAgentNamespace(): string {\n return agentNamespace(crypto.randomUUID());\n}\n\nexport function agentNamespace(namespace: string): string {\n return `agent:${namespacePart(namespace)}`;\n}\n\nexport function namespacePart(value: string): string {\n return encodeURIComponent(value);\n}\n\nexport function parentSessionNamespace({\n generation,\n sessionKey,\n sessionNamespace,\n}: {\n readonly generation: number;\n readonly sessionKey: string;\n readonly sessionNamespace: string;\n}): string {\n return `${sessionNamespace}:session:${namespacePart(\n sessionKey\n )}:generation:${generation}`;\n}\n"],"mappings":";AAAA,SAAgB,uBAA+B;CAC7C,OAAO,eAAe,OAAO,WAAW,CAAC;AAC3C;AAEA,SAAgB,eAAe,WAA2B;CACxD,OAAO,SAAS,cAAc,SAAS;AACzC;AAEA,SAAgB,cAAc,OAAuB;CACnD,OAAO,mBAAmB,KAAK;AACjC;AAEA,SAAgB,uBAAuB,EACrC,YACA,YACA,oBAKS;CACT,OAAO,GAAG,iBAAiB,WAAW,cACpC,UACF,EAAE,cAAc;AAClB"}
1
+ {"version":3,"file":"agent-namespace.js","names":[],"sources":["../src/agent-namespace.ts"],"sourcesContent":["export function randomAgentNamespace(): string {\n return agentNamespace(crypto.randomUUID());\n}\n\nexport function agentNamespace(namespace: string): string {\n return `agent:${namespacePart(namespace)}`;\n}\n\nexport function namespacePart(value: string): string {\n return encodeURIComponent(value);\n}\n\nexport function parentSessionNamespace({\n generation,\n sessionKey,\n sessionNamespace,\n}: {\n readonly generation: number;\n readonly sessionKey: string;\n readonly sessionNamespace: string;\n}): string {\n return `${sessionNamespace}:session:${namespacePart(\n sessionKey\n )}:generation:${generation}`;\n}\n\nexport function ownsAgentNamespace(\n ownerNamespace: string | undefined,\n sessionNamespace: string\n): boolean {\n return (\n ownerNamespace === sessionNamespace ||\n ownerNamespace?.startsWith(`${sessionNamespace}:session:`) === true\n );\n}\n\nexport function stableAgentNamespace({\n namespace,\n}: {\n readonly namespace?: string;\n}): string {\n return namespace ? agentNamespace(namespace) : randomAgentNamespace();\n}\n"],"mappings":";AAAA,SAAgB,uBAA+B;CAC7C,OAAO,eAAe,OAAO,WAAW,CAAC;AAC3C;AAEA,SAAgB,eAAe,WAA2B;CACxD,OAAO,SAAS,cAAc,SAAS;AACzC;AAEA,SAAgB,cAAc,OAAuB;CACnD,OAAO,mBAAmB,KAAK;AACjC;AAgBA,SAAgB,mBACd,gBACA,kBACS;CACT,OACE,mBAAmB,oBACnB,gBAAgB,WAAW,GAAG,iBAAiB,UAAU,MAAM;AAEnE;AAEA,SAAgB,qBAAqB,EACnC,aAGS;CACT,OAAO,YAAY,eAAe,SAAS,IAAI,qBAAqB;AACtE"}
@@ -0,0 +1,29 @@
1
+ import { AgentToolChoice, RuntimeLlm } from "./llm.js";
2
+ import { AgentHost } from "./execution/types.js";
3
+ import { AgentPlugin } from "./plugins.js";
4
+ import { LanguageModel, ToolSet } from "ai";
5
+
6
+ //#region src/agent-options.d.ts
7
+ interface AgentLanguageModelOptions {
8
+ readonly host?: AgentHost;
9
+ readonly instructions?: string;
10
+ readonly model: LanguageModel;
11
+ readonly namespace?: string;
12
+ readonly plugins?: readonly AgentPlugin[];
13
+ readonly toolChoice?: AgentToolChoice;
14
+ readonly tools?: ToolSet;
15
+ }
16
+ interface AgentRuntimeModelOptions {
17
+ readonly host?: AgentHost;
18
+ readonly instructions?: never;
19
+ readonly model: RuntimeLlm;
20
+ readonly namespace?: string;
21
+ readonly plugins?: readonly AgentPlugin[];
22
+ readonly toolChoice?: never;
23
+ readonly tools?: never;
24
+ }
25
+ type AgentOptions = AgentLanguageModelOptions | AgentRuntimeModelOptions;
26
+ type AgentConstructionOptions = AgentOptions;
27
+ //#endregion
28
+ export { AgentConstructionOptions, AgentOptions };
29
+ //# sourceMappingURL=agent-options.d.ts.map
@@ -0,0 +1,16 @@
1
+ //#region src/agent-options.ts
2
+ function assertAgentOptions(options) {
3
+ if (options === null || typeof options !== "object") throw new TypeError("Agent options are required. Provide { model }.");
4
+ if (!("model" in options && options.model != null)) throw new TypeError("Agent: missing options.model.");
5
+ if (typeof options.model !== "function" && (typeof options.model !== "object" || options.model === null)) throw new TypeError("Agent: invalid options.model.");
6
+ }
7
+ function hasRuntimeModel(options) {
8
+ return typeof options.model === "function";
9
+ }
10
+ function hasLanguageModel(options) {
11
+ return typeof options.model !== "function";
12
+ }
13
+ //#endregion
14
+ export { assertAgentOptions, hasLanguageModel, hasRuntimeModel };
15
+
16
+ //# sourceMappingURL=agent-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-options.js","names":[],"sources":["../src/agent-options.ts"],"sourcesContent":["import type { LanguageModel, ToolSet } from \"ai\";\nimport type { AgentHost } from \"./execution/types\";\nimport type { AgentToolChoice, RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\n\ninterface AgentLanguageModelOptions {\n readonly host?: AgentHost;\n readonly instructions?: string;\n readonly model: LanguageModel;\n readonly namespace?: string;\n readonly plugins?: readonly AgentPlugin[];\n readonly toolChoice?: AgentToolChoice;\n readonly tools?: ToolSet;\n}\n\ninterface AgentRuntimeModelOptions {\n readonly host?: AgentHost;\n readonly instructions?: never;\n readonly model: RuntimeLlm;\n readonly namespace?: string;\n readonly plugins?: readonly AgentPlugin[];\n readonly toolChoice?: never;\n readonly tools?: never;\n}\n\nexport type AgentModelOptions = Pick<\n AgentLanguageModelOptions,\n \"instructions\" | \"model\" | \"toolChoice\"\n>;\nexport type AgentOptions = AgentLanguageModelOptions | AgentRuntimeModelOptions;\n\nexport type AgentConstructionOptions = AgentOptions;\n\nexport function assertAgentOptions(\n options: unknown\n): asserts options is AgentConstructionOptions {\n if (options === null || typeof options !== \"object\") {\n throw new TypeError(\"Agent options are required. Provide { model }.\");\n }\n\n const hasModel = \"model\" in options && options.model != null;\n\n if (!hasModel) {\n throw new TypeError(\"Agent: missing options.model.\");\n }\n\n if (\n typeof options.model !== \"function\" &&\n (typeof options.model !== \"object\" || options.model === null)\n ) {\n throw new TypeError(\"Agent: invalid options.model.\");\n }\n}\n\nexport function hasRuntimeModel(\n options: AgentConstructionOptions\n): options is AgentRuntimeModelOptions {\n return typeof options.model === \"function\";\n}\n\nexport function hasLanguageModel(\n options: AgentConstructionOptions\n): options is AgentLanguageModelOptions {\n return typeof options.model !== \"function\";\n}\n"],"mappings":";AAiCA,SAAgB,mBACd,SAC6C;CAC7C,IAAI,YAAY,QAAQ,OAAO,YAAY,UACzC,MAAM,IAAI,UAAU,gDAAgD;CAKtE,IAAI,EAFa,WAAW,WAAW,QAAQ,SAAS,OAGtD,MAAM,IAAI,UAAU,+BAA+B;CAGrD,IACE,OAAO,QAAQ,UAAU,eACxB,OAAO,QAAQ,UAAU,YAAY,QAAQ,UAAU,OAExD,MAAM,IAAI,UAAU,+BAA+B;AAEvD;AAEA,SAAgB,gBACd,SACqC;CACrC,OAAO,OAAO,QAAQ,UAAU;AAClC;AAEA,SAAgB,iBACd,SACsC;CACtC,OAAO,OAAO,QAAQ,UAAU;AAClC"}
@@ -0,0 +1,63 @@
1
+ import { ownsAgentNamespace } from "./agent-namespace.js";
2
+ //#region src/agent-resume.ts
3
+ async function resumeAgentRun({ host, ownerNamespace, resumeNotification, runId }) {
4
+ const run = await host.store.runs.get(runId);
5
+ if (!run) return null;
6
+ if (!canAccessRun(run, ownerNamespace)) return null;
7
+ if (run.kind === "notification" && run.dedupeKey) {
8
+ const idempotencyKey = run.dedupeKey;
9
+ const claimed = await claimRun(host, run);
10
+ if (!claimed) return null;
11
+ const notification = await claimNotificationForRun({
12
+ host,
13
+ idempotencyKey,
14
+ ownerNamespace
15
+ });
16
+ if (!notification) return null;
17
+ try {
18
+ const notificationRun = await resumeNotification(notification);
19
+ await completeNotificationRun(host, claimed.runId);
20
+ return notificationRun;
21
+ } catch (error) {
22
+ await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);
23
+ throw error;
24
+ }
25
+ }
26
+ return null;
27
+ }
28
+ async function claimNotificationForRun({ host, idempotencyKey, ownerNamespace }) {
29
+ if (!ownsAgentNamespace((await host.store.notifications.getByIdempotencyKey(idempotencyKey))?.ownerNamespace, ownerNamespace)) return null;
30
+ const claim = await host.store.notifications.claimByIdempotencyKey(idempotencyKey);
31
+ if (claim.ok) {
32
+ if (ownsAgentNamespace(claim.record.ownerNamespace, ownerNamespace)) return claim.record;
33
+ await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);
34
+ return null;
35
+ }
36
+ if (claim.reason === "already-claimed" && ownsAgentNamespace(claim.record?.ownerNamespace, ownerNamespace)) return claim.record ?? null;
37
+ return null;
38
+ }
39
+ function canAccessRun(run, ownerNamespace) {
40
+ if (run.ownerNamespace) return ownsAgentNamespace(run.ownerNamespace, ownerNamespace);
41
+ return run.sessionKey.startsWith(`parent:${ownerNamespace}:`) || run.parentRunId?.startsWith(`${ownerNamespace}:session:`) === true;
42
+ }
43
+ async function completeNotificationRun(host, runId) {
44
+ const run = await host.store.runs.get(runId);
45
+ if (run?.kind !== "notification" || run.status === "completed") return;
46
+ await host.store.runs.update({
47
+ ...run,
48
+ status: "completed"
49
+ });
50
+ }
51
+ async function claimRun(host, run) {
52
+ const claim = await host.store.runs.claim(run.runId, {
53
+ attempt: (run.lease?.attempt ?? 0) + 1,
54
+ leaseId: crypto.randomUUID(),
55
+ leaseMs: 3e5,
56
+ nowMs: Date.now()
57
+ });
58
+ return claim.ok ? claim.record : null;
59
+ }
60
+ //#endregion
61
+ export { resumeAgentRun };
62
+
63
+ //# sourceMappingURL=agent-resume.js.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,13 @@
1
+ import { AgentInput } from "./session/input.js";
2
+ import { AgentRun } from "./session/run.js";
3
+ //#region src/agent-session-entry.d.ts
4
+ interface SessionHandle {
5
+ delete(): Promise<void>;
6
+ dispose(): Promise<void>;
7
+ interrupt(): void;
8
+ send(input: AgentInput): Promise<AgentRun>;
9
+ steer(input: AgentInput): Promise<AgentRun>;
10
+ }
11
+ //#endregion
12
+ export { SessionHandle };
13
+ //# sourceMappingURL=agent-session-entry.d.ts.map
package/dist/agent.d.ts CHANGED
@@ -1,55 +1,19 @@
1
- import { AgentToolChoice, Llm } from "./llm.js";
2
1
  import { AgentInput } from "./session/input.js";
3
- import { AgentHooks } from "./hooks.js";
2
+ import { AgentHost } from "./execution/types.js";
3
+ import { AgentConstructionOptions, AgentOptions } from "./agent-options.js";
4
4
  import { AgentRun } from "./session/run.js";
5
- import { SessionStore } from "./session/store/types.js";
6
- import { LanguageModel, ToolSet } from "ai";
5
+ import { SessionHandle } from "./agent-session-entry.js";
7
6
 
8
7
  //#region src/agent.d.ts
9
- interface AgentLanguageModelOptions {
10
- description?: string;
11
- hooks?: AgentHooks;
12
- instructions?: string;
13
- llm?: never;
14
- model: LanguageModel;
15
- name?: string;
16
- sessions?: AgentSessionOptions;
17
- subagents?: readonly Agent[];
18
- toolChoice?: AgentToolChoice;
19
- tools?: ToolSet;
20
- }
21
- interface AgentLlmOptions {
22
- description?: string;
23
- hooks?: AgentHooks;
24
- instructions?: never;
25
- llm: Llm;
26
- model?: never;
27
- name?: string;
28
- sessions?: AgentSessionOptions;
29
- subagents?: never;
30
- toolChoice?: never;
31
- tools?: never;
32
- }
33
- interface AgentSessionOptions {
34
- namespace?: string;
35
- store?: SessionStore;
36
- }
37
- interface SessionHandle {
38
- delete(): Promise<void>;
39
- interrupt(): void;
40
- kill(): void;
41
- send(input: AgentInput): Promise<AgentRun>;
42
- steer(input: AgentInput): Promise<AgentRun>;
43
- }
44
- type AgentOptions = AgentLanguageModelOptions | AgentLlmOptions;
45
8
  declare class Agent {
46
9
  #private;
47
- readonly description?: string;
48
- readonly name?: string;
49
- constructor(options: AgentOptions);
10
+ readonly host: AgentHost;
11
+ readonly namespace?: string;
12
+ constructor(options: AgentConstructionOptions);
50
13
  send(input: AgentInput): Promise<AgentRun>;
14
+ resume(runId: string): Promise<AgentRun | null>;
51
15
  session(key: string): SessionHandle;
52
16
  }
53
17
  //#endregion
54
- export { Agent, AgentOptions, AgentSessionOptions, SessionHandle };
18
+ export { Agent };
55
19
  //# sourceMappingURL=agent.d.ts.map
package/dist/agent.js CHANGED
@@ -1,35 +1,33 @@
1
- import { agentNamespace, parentSessionNamespace, randomAgentNamespace } from "./agent-namespace.js";
2
- import { assertSubagents } from "./agent-validation.js";
3
- import { ChildSessionCleanups } from "./child-session-cleanups.js";
1
+ import { executionHost } from "./execution/host.js";
2
+ import { sessionStoreForHost } from "./agent-host-session-store.js";
3
+ import { stableAgentNamespace } from "./agent-namespace.js";
4
+ import { assertAgentOptions, hasLanguageModel, hasRuntimeModel } from "./agent-options.js";
5
+ import { resumeAgentRun } from "./agent-resume.js";
6
+ import { createInMemoryExecutionHost } from "./execution/memory.js";
4
7
  import { createLlm } from "./llm.js";
5
8
  import { AgentSession } from "./session/session.js";
6
- import { MemorySessionStore } from "./session/store/memory.js";
7
- import { createSubagentTools } from "./subagents.js";
8
9
  //#region src/agent.ts
9
- var Agent = class Agent {
10
+ var Agent = class {
10
11
  #baseTools;
11
- #hooks;
12
12
  #llm;
13
13
  #modelOptions;
14
- #childSessionCleanups = new ChildSessionCleanups();
15
- #sessionGenerations = /* @__PURE__ */ new Map();
16
14
  #sessions = /* @__PURE__ */ new Map();
17
15
  #sessionNamespace;
18
16
  #store;
19
- #subagents;
20
- description;
21
- name;
17
+ #host;
18
+ #plugins;
19
+ host;
20
+ namespace;
22
21
  constructor(options) {
23
22
  assertAgentOptions(options);
24
- this.description = options.description;
25
- this.name = options.name;
26
- this.#sessionNamespace = stableAgentNamespace(options);
27
- this.#store = options.sessions?.store ?? new MemorySessionStore();
28
- this.#hooks = options.hooks;
29
- assertSubagents(options, Agent, hasCustomLlm(options));
30
- this.#subagents = hasCustomLlm(options) ? [] : options.subagents ?? [];
31
- if (hasCustomLlm(options)) this.#llm = options.llm;
32
- else {
23
+ this.namespace = options.namespace;
24
+ this.#sessionNamespace = stableAgentNamespace({ namespace: options.namespace });
25
+ this.#host = options.host ?? createInMemoryExecutionHost();
26
+ this.host = this.#host;
27
+ this.#store = sessionStoreForHost(this.#host);
28
+ this.#plugins = options.plugins ?? [];
29
+ if (hasRuntimeModel(options)) this.#llm = options.model;
30
+ else if (hasLanguageModel(options)) {
33
31
  this.#baseTools = options.tools;
34
32
  this.#modelOptions = {
35
33
  instructions: options.instructions,
@@ -41,85 +39,65 @@ var Agent = class Agent {
41
39
  send(input) {
42
40
  return this.session("default").send(input);
43
41
  }
42
+ async resume(runId) {
43
+ const host = executionHost(this.#host);
44
+ if (!host) throw new Error("Agent host does not support durable run resume.");
45
+ return await resumeAgentRun({
46
+ host,
47
+ ownerNamespace: this.#sessionNamespace,
48
+ resumeNotification: (notification) => this.#resumeNotification(notification),
49
+ runId
50
+ });
51
+ }
44
52
  session(key) {
53
+ return this.#sessionEntry(key).publicHandle;
54
+ }
55
+ #sessionEntry(key) {
45
56
  const existing = this.#sessions.get(key);
46
57
  if (existing) return existing;
47
58
  let session;
48
- const getSession = () => {
49
- if (!session) throw new Error("Agent session is not initialized.");
50
- return session;
51
- };
52
- const parentAgentNamespace = parentSessionNamespace({
53
- generation: this.#sessionGenerations.get(key) ?? 0,
54
- sessionKey: key,
55
- sessionNamespace: this.#sessionNamespace
56
- });
57
- session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession(key, parentAgentNamespace, (input, placement) => getSession().enqueueRuntimeInput(input, placement), (event) => getSession().emitObserverEvent(event))), {
59
+ session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession()), {
58
60
  key,
59
61
  store: this.#store
60
- }, this.#hooks);
61
- const handle = {
62
- delete: async () => {
63
- await session.delete();
64
- this.#sessions.delete(key);
65
- this.#sessionGenerations.set(key, (this.#sessionGenerations.get(key) ?? 0) + 1);
66
- await this.#deleteChildSessions(key);
67
- },
68
- interrupt: () => session.interrupt(),
69
- kill: () => {
70
- session.kill();
71
- this.#sessionGenerations.set(key, (this.#sessionGenerations.get(key) ?? 0) + 1);
72
- this.#deleteChildSessions(key).catch(() => void 0);
73
- this.#sessions.delete(key);
74
- },
75
- send: (input) => session.send(input),
76
- steer: (input) => session.steer(input)
62
+ }, this.#plugins, { executionHost: executionHost(this.#host) });
63
+ const entry = {
64
+ notify: (input, options) => session.notify(input, options),
65
+ publicHandle: {
66
+ delete: async () => {
67
+ session.kill();
68
+ this.#evictSessionHandle(key);
69
+ await session.delete();
70
+ },
71
+ dispose: () => {
72
+ session.kill();
73
+ this.#evictSessionHandle(key);
74
+ return Promise.resolve();
75
+ },
76
+ interrupt: () => session.interrupt(),
77
+ send: (input) => session.send(input),
78
+ steer: (input) => session.steer(input)
79
+ }
77
80
  };
78
- this.#sessions.set(key, handle);
79
- return handle;
81
+ this.#sessions.set(key, entry);
82
+ return entry;
83
+ }
84
+ #evictSessionHandle(key) {
85
+ this.#sessions.delete(key);
86
+ }
87
+ #resumeNotification(notification) {
88
+ return this.#sessionEntry(notification.sessionKey).notify(notification.input, { observerEvents: notification.observerEvents });
80
89
  }
81
- #createLlmOptionsForSession(key, parentAgentNamespace, enqueueRuntimeInput, emitObserverEvent) {
90
+ #createLlmOptionsForSession() {
82
91
  const modelOptions = this.#modelOptions;
83
92
  if (!modelOptions) throw new Error("Agent: missing model options.");
84
- const tools = this.#subagents.length === 0 ? this.#baseTools : {
85
- ...this.#baseTools,
86
- ...createSubagentTools({
87
- parentAgentNamespace,
88
- parentSession: {
89
- emitObserverEvent,
90
- enqueueRuntimeInput
91
- },
92
- parentSessionKey: key,
93
- registerChildSession: (sessionKey, cleanup) => this.#childSessionCleanups.register(sessionKey, cleanup),
94
- subagents: this.#subagents
95
- })
96
- };
97
93
  return {
98
94
  instructions: modelOptions.instructions,
99
95
  model: modelOptions.model,
100
96
  toolChoice: modelOptions.toolChoice,
101
- tools
97
+ tools: this.#baseTools
102
98
  };
103
99
  }
104
- async #deleteChildSessions(parentSessionKey) {
105
- await this.#childSessionCleanups.delete(parentSessionKey);
106
- }
107
100
  };
108
- function stableAgentNamespace(options) {
109
- const namespace = options.sessions?.namespace ?? options.name;
110
- return namespace ? agentNamespace(namespace) : randomAgentNamespace();
111
- }
112
- function assertAgentOptions(options) {
113
- if (options === null || typeof options !== "object") throw new TypeError("Agent options are required. Provide either { model } or { llm }.");
114
- const hasLlm = hasCustomLlm(options);
115
- const hasModel = "model" in options && options.model != null;
116
- if (hasLlm && hasModel) throw new TypeError("Agent: provide either options.llm or options.model.");
117
- if ("llm" in options && options.llm !== void 0 && !hasLlm) throw new TypeError("Agent: invalid options.llm.");
118
- if (!(hasLlm || hasModel)) throw new TypeError("Agent: missing options.model.");
119
- }
120
- function hasCustomLlm(options) {
121
- return "llm" in options && typeof options.llm === "function";
122
- }
123
101
  //#endregion
124
102
  export { Agent };
125
103
 
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","names":["#baseTools","#hooks","#llm","#modelOptions","#childSessionCleanups","#sessionGenerations","#sessions","#sessionNamespace","#store","#subagents","#createLlmOptionsForSession","#deleteChildSessions"],"sources":["../src/agent.ts"],"sourcesContent":["import type { LanguageModel, ToolSet } from \"ai\";\nimport {\n agentNamespace,\n parentSessionNamespace,\n randomAgentNamespace,\n} from \"./agent-namespace\";\nimport { assertSubagents } from \"./agent-validation\";\nimport { ChildSessionCleanups } from \"./child-session-cleanups\";\nimport type { AgentHooks } from \"./hooks\";\nimport { type AgentToolChoice, createLlm, type Llm } from \"./llm\";\nimport type { UserInput } from \"./session/events\";\nimport type { AgentRun } from \"./session/run\";\nimport { type AgentInput, AgentSession } from \"./session/session\";\nimport { MemorySessionStore } from \"./session/store/memory\";\nimport type { SessionStore } from \"./session/store/types\";\nimport { createSubagentTools } from \"./subagents\";\n\ninterface AgentLanguageModelOptions {\n description?: string;\n hooks?: AgentHooks;\n instructions?: string;\n llm?: never;\n model: LanguageModel;\n name?: string;\n sessions?: AgentSessionOptions;\n subagents?: readonly Agent[];\n toolChoice?: AgentToolChoice;\n tools?: ToolSet;\n}\n\ninterface AgentLlmOptions {\n description?: string;\n hooks?: AgentHooks;\n instructions?: never;\n llm: Llm;\n model?: never;\n name?: string;\n sessions?: AgentSessionOptions;\n subagents?: never;\n toolChoice?: never;\n tools?: never;\n}\n\nexport interface AgentSessionOptions {\n namespace?: string;\n store?: SessionStore;\n}\n\nexport interface SessionHandle {\n delete(): Promise<void>;\n interrupt(): void;\n kill(): void;\n send(input: AgentInput): Promise<AgentRun>;\n steer(input: AgentInput): Promise<AgentRun>;\n}\n\nexport type AgentOptions = AgentLanguageModelOptions | AgentLlmOptions;\ntype AgentModelOptions = Pick<\n AgentLanguageModelOptions,\n \"instructions\" | \"model\" | \"toolChoice\"\n>;\n\nexport class Agent {\n readonly #baseTools?: ToolSet;\n readonly #hooks?: AgentHooks;\n readonly #llm?: Llm;\n readonly #modelOptions?: AgentModelOptions;\n readonly #childSessionCleanups = new ChildSessionCleanups();\n readonly #sessionGenerations = new Map<string, number>();\n readonly #sessions = new Map<string, SessionHandle>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\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(options);\n this.#store = options.sessions?.store ?? new MemorySessionStore();\n this.#hooks = options.hooks;\n assertSubagents(options, Agent, hasCustomLlm(options));\n this.#subagents = hasCustomLlm(options) ? [] : (options.subagents ?? []);\n if (hasCustomLlm(options)) {\n this.#llm = options.llm;\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 session(key: string): SessionHandle {\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 )\n );\n session = new AgentSession(llm, { key, store: this.#store }, this.#hooks);\n const handle: SessionHandle = {\n delete: async () => {\n await session.delete();\n this.#sessions.delete(key);\n this.#sessionGenerations.set(\n key,\n (this.#sessionGenerations.get(key) ?? 0) + 1\n );\n await this.#deleteChildSessions(key);\n },\n interrupt: () => session.interrupt(),\n kill: () => {\n session.kill();\n this.#sessionGenerations.set(\n key,\n (this.#sessionGenerations.get(key) ?? 0) + 1\n );\n this.#deleteChildSessions(key).catch(() => undefined);\n this.#sessions.delete(key);\n },\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n this.#sessions.set(key, handle);\n return handle;\n }\n\n #createLlmOptionsForSession(\n key: string,\n parentAgentNamespace: string,\n enqueueRuntimeInput: AgentSession[\"enqueueRuntimeInput\"],\n emitObserverEvent: AgentSession[\"emitObserverEvent\"]\n ): Parameters<typeof createLlm>[0] {\n const modelOptions = this.#modelOptions;\n if (!modelOptions) {\n throw new Error(\"Agent: missing model options.\");\n }\n const tools =\n this.#subagents.length === 0\n ? this.#baseTools\n : {\n ...this.#baseTools,\n ...createSubagentTools({\n parentAgentNamespace,\n parentSession: { emitObserverEvent, enqueueRuntimeInput },\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 async #deleteChildSessions(parentSessionKey: string): Promise<void> {\n await this.#childSessionCleanups.delete(parentSessionKey);\n }\n}\n\nfunction stableAgentNamespace(options: AgentOptions): string {\n const namespace = options.sessions?.namespace ?? options.name;\n return namespace ? agentNamespace(namespace) : randomAgentNamespace();\n}\n\nfunction assertAgentOptions(options: unknown): asserts options is AgentOptions {\n if (options === null || typeof options !== \"object\") {\n throw new TypeError(\n \"Agent options are required. Provide either { model } or { llm }.\"\n );\n }\n\n const hasLlm = hasCustomLlm(options);\n const hasModel = \"model\" in options && options.model != null;\n\n if (hasLlm && hasModel) {\n throw new TypeError(\"Agent: provide either options.llm or options.model.\");\n }\n\n if (\"llm\" in options && options.llm !== undefined && !hasLlm) {\n throw new TypeError(\"Agent: invalid options.llm.\");\n }\n\n if (!(hasLlm || hasModel)) {\n throw new TypeError(\"Agent: missing options.model.\");\n }\n}\n\nfunction hasCustomLlm(options: object): options is AgentLlmOptions {\n return \"llm\" in options && typeof options.llm === \"function\";\n}\n"],"mappings":";;;;;;;;AA8DA,IAAa,QAAb,MAAa,MAAM;CACjB;CACA;CACA;CACA;CACA,wBAAiC,IAAI,qBAAqB;CAC1D,sCAA+B,IAAI,IAAoB;CACvD,4BAAqB,IAAI,IAA2B;CACpD;CACA;CACA;CACA;CACA;CAEA,YAAY,SAAuB;EACjC,mBAAmB,OAAO;EAE1B,KAAK,cAAc,QAAQ;EAC3B,KAAK,OAAO,QAAQ;EACpB,KAAKO,oBAAoB,qBAAqB,OAAO;EACrD,KAAKC,SAAS,QAAQ,UAAU,SAAS,IAAI,mBAAmB;EAChE,KAAKP,SAAS,QAAQ;EACtB,gBAAgB,SAAS,OAAO,aAAa,OAAO,CAAC;EACrD,KAAKQ,aAAa,aAAa,OAAO,IAAI,CAAC,IAAK,QAAQ,aAAa,CAAC;EACtE,IAAI,aAAa,OAAO,GACtB,KAAKP,OAAO,QAAQ;OACf;GACL,KAAKF,aAAa,QAAQ;GAC1B,KAAKG,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,QAAQ,KAA4B;EAClC,MAAM,WAAW,KAAKG,UAAU,IAAI,GAAG;EACvC,IAAI,UACF,OAAO;EAGT,IAAI;EACJ,MAAM,mBAAmB;GACvB,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,mCAAmC;GAErD,OAAO;EACT;EACA,MAAM,uBAAuB,uBAAuB;GAClD,YAAY,KAAKD,oBAAoB,IAAI,GAAG,KAAK;GACjD,YAAY;GACZ,kBAAkB,KAAKE;EACzB,CAAC;EAYD,UAAU,IAAI,aAVZ,KAAKL,QACL,UACE,KAAKQ,4BACH,KACA,uBACC,OAAkB,cACjB,WAAW,EAAE,oBAAoB,OAAO,SAAS,IAClD,UAAU,WAAW,EAAE,kBAAkB,KAAK,CACjD,CACF,GAC8B;GAAE;GAAK,OAAO,KAAKF;EAAO,GAAG,KAAKP,MAAM;EACxE,MAAM,SAAwB;GAC5B,QAAQ,YAAY;IAClB,MAAM,QAAQ,OAAO;IACrB,KAAKK,UAAU,OAAO,GAAG;IACzB,KAAKD,oBAAoB,IACvB,MACC,KAAKA,oBAAoB,IAAI,GAAG,KAAK,KAAK,CAC7C;IACA,MAAM,KAAKM,qBAAqB,GAAG;GACrC;GACA,iBAAiB,QAAQ,UAAU;GACnC,YAAY;IACV,QAAQ,KAAK;IACb,KAAKN,oBAAoB,IACvB,MACC,KAAKA,oBAAoB,IAAI,GAAG,KAAK,KAAK,CAC7C;IACA,KAAKM,qBAAqB,GAAG,EAAE,YAAY,KAAA,CAAS;IACpD,KAAKL,UAAU,OAAO,GAAG;GAC3B;GACA,OAAO,UAAU,QAAQ,KAAK,KAAK;GACnC,QAAQ,UAAU,QAAQ,MAAM,KAAK;EACvC;EACA,KAAKA,UAAU,IAAI,KAAK,MAAM;EAC9B,OAAO;CACT;CAEA,4BACE,KACA,sBACA,qBACA,mBACiC;EACjC,MAAM,eAAe,KAAKH;EAC1B,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,+BAA+B;EAEjD,MAAM,QACJ,KAAKM,WAAW,WAAW,IACvB,KAAKT,aACL;GACE,GAAG,KAAKA;GACR,GAAG,oBAAoB;IACrB;IACA,eAAe;KAAE;KAAmB;IAAoB;IACxD,kBAAkB;IAClB,uBAAuB,YAAY,YACjC,KAAKI,sBAAsB,SAAS,YAAY,OAAO;IACzD,WAAW,KAAKK;GAClB,CAAC;EACH;EAEN,OAAO;GACL,cAAc,aAAa;GAC3B,OAAO,aAAa;GACpB,YAAY,aAAa;GACzB;EACF;CACF;CAEA,MAAME,qBAAqB,kBAAyC;EAClE,MAAM,KAAKP,sBAAsB,OAAO,gBAAgB;CAC1D;AACF;AAEA,SAAS,qBAAqB,SAA+B;CAC3D,MAAM,YAAY,QAAQ,UAAU,aAAa,QAAQ;CACzD,OAAO,YAAY,eAAe,SAAS,IAAI,qBAAqB;AACtE;AAEA,SAAS,mBAAmB,SAAmD;CAC7E,IAAI,YAAY,QAAQ,OAAO,YAAY,UACzC,MAAM,IAAI,UACR,kEACF;CAGF,MAAM,SAAS,aAAa,OAAO;CACnC,MAAM,WAAW,WAAW,WAAW,QAAQ,SAAS;CAExD,IAAI,UAAU,UACZ,MAAM,IAAI,UAAU,qDAAqD;CAG3E,IAAI,SAAS,WAAW,QAAQ,QAAQ,KAAA,KAAa,CAAC,QACpD,MAAM,IAAI,UAAU,6BAA6B;CAGnD,IAAI,EAAE,UAAU,WACd,MAAM,IAAI,UAAU,+BAA+B;AAEvD;AAEA,SAAS,aAAa,SAA6C;CACjE,OAAO,SAAS,WAAW,OAAO,QAAQ,QAAQ;AACpD"}
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"}