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

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 (145) hide show
  1. package/README.md +172 -85
  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 +9 -8
  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 +4 -19
  9. package/dist/agent-options.js +2 -8
  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 +19 -89
  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 +9 -5
  66. package/dist/index.js +6 -2
  67. package/dist/llm-tool-execution.js.map +1 -1
  68. package/dist/llm.d.ts +1 -21
  69. package/dist/llm.js +12 -14
  70. package/dist/llm.js.map +1 -1
  71. package/dist/plugins.d.ts +27 -5
  72. package/dist/plugins.js +35 -6
  73. package/dist/plugins.js.map +1 -1
  74. package/dist/session/delegate-input.d.ts +9 -0
  75. package/dist/session/delegate-input.js +16 -0
  76. package/dist/session/delegate-input.js.map +1 -0
  77. package/dist/session/events.d.ts +43 -25
  78. package/dist/session/events.js +41 -0
  79. package/dist/session/events.js.map +1 -0
  80. package/dist/session/input-meta-types.d.ts +10 -0
  81. package/dist/session/input-meta.d.ts +13 -0
  82. package/dist/session/input-meta.js +45 -0
  83. package/dist/session/input-meta.js.map +1 -0
  84. package/dist/session/input.d.ts +4 -0
  85. package/dist/session/mapping.js +4 -2
  86. package/dist/session/mapping.js.map +1 -1
  87. package/dist/session/runtime-input-emit.js +41 -0
  88. package/dist/session/runtime-input-emit.js.map +1 -0
  89. package/dist/session/runtime-input.js +5 -1
  90. package/dist/session/runtime-input.js.map +1 -1
  91. package/dist/session/session-events.js +20 -6
  92. package/dist/session/session-events.js.map +1 -1
  93. package/dist/session/session-notification.js +3 -2
  94. package/dist/session/session-notification.js.map +1 -1
  95. package/dist/session/session-runtime-drain.js +3 -9
  96. package/dist/session/session-runtime-drain.js.map +1 -1
  97. package/dist/session/session-turn-processor.js +10 -20
  98. package/dist/session/session-turn-processor.js.map +1 -1
  99. package/dist/session/session.js +15 -8
  100. package/dist/session/session.js.map +1 -1
  101. package/package.json +6 -1
  102. package/dist/agent-child-runs.js +0 -16
  103. package/dist/agent-child-runs.js.map +0 -1
  104. package/dist/agent-host-capabilities.js +0 -9
  105. package/dist/agent-host-capabilities.js.map +0 -1
  106. package/dist/agent-validation.js +0 -35
  107. package/dist/agent-validation.js.map +0 -1
  108. package/dist/child-session-cleanups.js +0 -61
  109. package/dist/child-session-cleanups.js.map +0 -1
  110. package/dist/execution/run.js +0 -55
  111. package/dist/execution/run.js.map +0 -1
  112. package/dist/subagent-background-child-run-state.js +0 -51
  113. package/dist/subagent-background-child-run-state.js.map +0 -1
  114. package/dist/subagent-background-child-run.js +0 -103
  115. package/dist/subagent-background-child-run.js.map +0 -1
  116. package/dist/subagent-background-in-process.js +0 -98
  117. package/dist/subagent-background-in-process.js.map +0 -1
  118. package/dist/subagent-background-notification-inbox.js +0 -106
  119. package/dist/subagent-background-notification-inbox.js.map +0 -1
  120. package/dist/subagent-background-notify.js +0 -136
  121. package/dist/subagent-background-notify.js.map +0 -1
  122. package/dist/subagent-background-resume-group.js +0 -99
  123. package/dist/subagent-background-resume-group.js.map +0 -1
  124. package/dist/subagent-background-runner.js +0 -115
  125. package/dist/subagent-background-runner.js.map +0 -1
  126. package/dist/subagent-background-schedule.js +0 -43
  127. package/dist/subagent-background-schedule.js.map +0 -1
  128. package/dist/subagent-child-run.js +0 -68
  129. package/dist/subagent-child-run.js.map +0 -1
  130. package/dist/subagent-job-cancel.js +0 -84
  131. package/dist/subagent-job-cancel.js.map +0 -1
  132. package/dist/subagent-job-observer.js +0 -19
  133. package/dist/subagent-job-observer.js.map +0 -1
  134. package/dist/subagent-job-output.js +0 -87
  135. package/dist/subagent-job-output.js.map +0 -1
  136. package/dist/subagent-job-state.js +0 -66
  137. package/dist/subagent-job-state.js.map +0 -1
  138. package/dist/subagent-jobs.js +0 -96
  139. package/dist/subagent-jobs.js.map +0 -1
  140. package/dist/subagent-prompt-schema.js +0 -114
  141. package/dist/subagent-prompt-schema.js.map +0 -1
  142. package/dist/subagent-run.js +0 -111
  143. package/dist/subagent-run.js.map +0 -1
  144. package/dist/subagents.js +0 -125
  145. package/dist/subagents.js.map +0 -1
@@ -1,35 +0,0 @@
1
- //#region src/agent-validation.ts
2
- const subagentNamePattern = /^[a-z][a-z0-9_-]{0,51}$/;
3
- function assertSubagents(options, agentClass, hasRuntimeModel) {
4
- if (!("subagents" in options) || options.subagents === void 0) return;
5
- if (hasRuntimeModel) throw new TypeError("Agent: subagents require an AI SDK model.");
6
- if (!Array.isArray(options.subagents)) throw new TypeError("Agent: subagents must be an array.");
7
- assertSubagentTools(options.subagents, agentClass, options.tools ?? {});
8
- }
9
- function assertSubagentTools(subagents, agentClass, tools) {
10
- const toolNames = new Set(Object.keys(tools));
11
- const generatedToolNames = /* @__PURE__ */ new Set();
12
- for (const [index, subagent] of subagents.entries()) {
13
- const toolName = `delegate_to_${assertSubagentMetadata(subagent, index, agentClass).replaceAll("-", "_")}`;
14
- if (toolNames.has(toolName)) throw new TypeError(`Agent: subagent tool ${toolName} collides with an existing tool.`);
15
- if (generatedToolNames.has(toolName)) throw new TypeError(`Agent: duplicate subagent tool name ${toolName}.`);
16
- generatedToolNames.add(toolName);
17
- }
18
- for (const reservedToolName of ["background_output", "background_cancel"]) if (toolNames.has(reservedToolName)) throw new TypeError(`Agent: ${reservedToolName} collides with a reserved subagent tool.`);
19
- }
20
- function assertSubagentMetadata(subagent, index, agentClass) {
21
- if (!(subagent instanceof agentClass)) throw new TypeError(`Agent: subagents[${index}] must be an Agent.`);
22
- if (!isValidSubagentName(subagent.name)) throw new TypeError(`Agent: subagents[${index}].name is required or too long.`);
23
- if (!isNonEmptyText(subagent.description)) throw new TypeError(`Agent: subagents[${index}].description is required.`);
24
- return subagent.name;
25
- }
26
- function isNonEmptyText(value) {
27
- return typeof value === "string" && value.trim().length > 0;
28
- }
29
- function isValidSubagentName(value) {
30
- return typeof value === "string" && subagentNamePattern.test(value);
31
- }
32
- //#endregion
33
- export { assertSubagents };
34
-
35
- //# sourceMappingURL=agent-validation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent-validation.js","names":[],"sources":["../src/agent-validation.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport type { Agent } from \"./agent\";\nimport type { AgentOptions } from \"./agent-options\";\n\nconst subagentNamePattern = /^[a-z][a-z0-9_-]{0,51}$/;\n\nexport function assertSubagents(\n options: AgentOptions,\n agentClass: new (options: AgentOptions) => Agent,\n hasRuntimeModel: boolean\n): void {\n if (!(\"subagents\" in options) || options.subagents === undefined) {\n return;\n }\n\n if (hasRuntimeModel) {\n throw new TypeError(\"Agent: subagents require an AI SDK model.\");\n }\n\n if (!Array.isArray(options.subagents)) {\n throw new TypeError(\"Agent: subagents must be an array.\");\n }\n\n assertSubagentTools(options.subagents, agentClass, options.tools ?? {});\n}\n\nfunction assertSubagentTools(\n subagents: readonly Agent[],\n agentClass: new (options: AgentOptions) => Agent,\n tools: ToolSet\n): void {\n const toolNames = new Set(Object.keys(tools));\n const generatedToolNames = new Set<string>();\n for (const [index, subagent] of subagents.entries()) {\n const name = assertSubagentMetadata(subagent, index, agentClass);\n const toolName = `delegate_to_${name.replaceAll(\"-\", \"_\")}`;\n if (toolNames.has(toolName)) {\n throw new TypeError(\n `Agent: subagent tool ${toolName} collides with an existing tool.`\n );\n }\n\n if (generatedToolNames.has(toolName)) {\n throw new TypeError(`Agent: duplicate subagent tool name ${toolName}.`);\n }\n\n generatedToolNames.add(toolName);\n }\n\n for (const reservedToolName of [\"background_output\", \"background_cancel\"]) {\n if (toolNames.has(reservedToolName)) {\n throw new TypeError(\n `Agent: ${reservedToolName} collides with a reserved subagent tool.`\n );\n }\n }\n}\n\nfunction assertSubagentMetadata(\n subagent: Agent,\n index: number,\n agentClass: new (options: AgentOptions) => Agent\n): string {\n if (!(subagent instanceof agentClass)) {\n throw new TypeError(`Agent: subagents[${index}] must be an Agent.`);\n }\n\n if (!isValidSubagentName(subagent.name)) {\n throw new TypeError(\n `Agent: subagents[${index}].name is required or too long.`\n );\n }\n\n if (!isNonEmptyText(subagent.description)) {\n throw new TypeError(`Agent: subagents[${index}].description is required.`);\n }\n\n return subagent.name;\n}\n\nfunction isNonEmptyText(value: string | undefined): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction isValidSubagentName(value: string | undefined): value is string {\n return typeof value === \"string\" && subagentNamePattern.test(value);\n}\n"],"mappings":";AAIA,MAAM,sBAAsB;AAE5B,SAAgB,gBACd,SACA,YACA,iBACM;CACN,IAAI,EAAE,eAAe,YAAY,QAAQ,cAAc,KAAA,GACrD;CAGF,IAAI,iBACF,MAAM,IAAI,UAAU,2CAA2C;CAGjE,IAAI,CAAC,MAAM,QAAQ,QAAQ,SAAS,GAClC,MAAM,IAAI,UAAU,oCAAoC;CAG1D,oBAAoB,QAAQ,WAAW,YAAY,QAAQ,SAAS,CAAC,CAAC;AACxE;AAEA,SAAS,oBACP,WACA,YACA,OACM;CACN,MAAM,YAAY,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC;CAC5C,MAAM,qCAAqB,IAAI,IAAY;CAC3C,KAAK,MAAM,CAAC,OAAO,aAAa,UAAU,QAAQ,GAAG;EAEnD,MAAM,WAAW,eADJ,uBAAuB,UAAU,OAAO,UAClB,EAAE,WAAW,KAAK,GAAG;EACxD,IAAI,UAAU,IAAI,QAAQ,GACxB,MAAM,IAAI,UACR,wBAAwB,SAAS,iCACnC;EAGF,IAAI,mBAAmB,IAAI,QAAQ,GACjC,MAAM,IAAI,UAAU,uCAAuC,SAAS,EAAE;EAGxE,mBAAmB,IAAI,QAAQ;CACjC;CAEA,KAAK,MAAM,oBAAoB,CAAC,qBAAqB,mBAAmB,GACtE,IAAI,UAAU,IAAI,gBAAgB,GAChC,MAAM,IAAI,UACR,UAAU,iBAAiB,yCAC7B;AAGN;AAEA,SAAS,uBACP,UACA,OACA,YACQ;CACR,IAAI,EAAE,oBAAoB,aACxB,MAAM,IAAI,UAAU,oBAAoB,MAAM,oBAAoB;CAGpE,IAAI,CAAC,oBAAoB,SAAS,IAAI,GACpC,MAAM,IAAI,UACR,oBAAoB,MAAM,gCAC5B;CAGF,IAAI,CAAC,eAAe,SAAS,WAAW,GACtC,MAAM,IAAI,UAAU,oBAAoB,MAAM,2BAA2B;CAG3E,OAAO,SAAS;AAClB;AAEA,SAAS,eAAe,OAA4C;CAClE,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS;AAC5D;AAEA,SAAS,oBAAoB,OAA4C;CACvE,OAAO,OAAO,UAAU,YAAY,oBAAoB,KAAK,KAAK;AACpE"}
@@ -1,61 +0,0 @@
1
- //#region src/child-session-cleanups.ts
2
- var ChildSessionCleanups = class {
3
- #byParentSession = /* @__PURE__ */ new Map();
4
- async delete(parentSessionKey) {
5
- const cleanups = this.#byParentSession.get(parentSessionKey);
6
- if (!cleanups) return;
7
- this.#byParentSession.delete(parentSessionKey);
8
- const results = await Promise.all([...cleanups].map(runCleanup));
9
- const failedCleanups = [];
10
- let firstError;
11
- for (const result of results) {
12
- if (result.ok) continue;
13
- firstError ??= result.error;
14
- failedCleanups.push(result.cleanup);
15
- }
16
- if (failedCleanups.length === 0) return;
17
- this.#restore(parentSessionKey, failedCleanups);
18
- throw firstError instanceof Error ? firstError : new Error(String(firstError));
19
- }
20
- register(parentSessionKey, cleanup) {
21
- const existing = this.#byParentSession.get(parentSessionKey);
22
- if (existing) {
23
- existing.add(cleanup);
24
- return () => this.#unregister(parentSessionKey, existing, cleanup);
25
- }
26
- const cleanups = new Set([cleanup]);
27
- this.#byParentSession.set(parentSessionKey, cleanups);
28
- return () => this.#unregister(parentSessionKey, cleanups, cleanup);
29
- }
30
- #unregister(parentSessionKey, cleanups, cleanup) {
31
- cleanups.delete(cleanup);
32
- if (cleanups.size === 0 && this.#byParentSession.get(parentSessionKey) === cleanups) this.#byParentSession.delete(parentSessionKey);
33
- }
34
- #restore(parentSessionKey, failedCleanups) {
35
- const current = this.#byParentSession.get(parentSessionKey);
36
- if (current) {
37
- for (const cleanup of failedCleanups) current.add(cleanup);
38
- return;
39
- }
40
- this.#byParentSession.set(parentSessionKey, new Set(failedCleanups));
41
- }
42
- };
43
- async function runCleanup(cleanup) {
44
- try {
45
- await cleanup();
46
- return {
47
- cleanup,
48
- ok: true
49
- };
50
- } catch (error) {
51
- return {
52
- cleanup,
53
- error,
54
- ok: false
55
- };
56
- }
57
- }
58
- //#endregion
59
- export { ChildSessionCleanups };
60
-
61
- //# sourceMappingURL=child-session-cleanups.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"child-session-cleanups.js","names":["#byParentSession","#restore","#unregister"],"sources":["../src/child-session-cleanups.ts"],"sourcesContent":["type ChildSessionCleanup = () => Promise<void>;\n\ntype CleanupResult =\n | { readonly cleanup: ChildSessionCleanup; readonly ok: true }\n | {\n readonly cleanup: ChildSessionCleanup;\n readonly error: unknown;\n readonly ok: false;\n };\n\nexport class ChildSessionCleanups {\n readonly #byParentSession = new Map<string, Set<ChildSessionCleanup>>();\n\n async delete(parentSessionKey: string): Promise<void> {\n const cleanups = this.#byParentSession.get(parentSessionKey);\n if (!cleanups) {\n return;\n }\n\n this.#byParentSession.delete(parentSessionKey);\n const results = await Promise.all([...cleanups].map(runCleanup));\n const failedCleanups: ChildSessionCleanup[] = [];\n let firstError: unknown;\n for (const result of results) {\n if (result.ok) {\n continue;\n }\n\n firstError ??= result.error;\n failedCleanups.push(result.cleanup);\n }\n\n if (failedCleanups.length === 0) {\n return;\n }\n\n this.#restore(parentSessionKey, failedCleanups);\n throw firstError instanceof Error\n ? firstError\n : new Error(String(firstError));\n }\n\n register(parentSessionKey: string, cleanup: ChildSessionCleanup): () => void {\n const existing = this.#byParentSession.get(parentSessionKey);\n if (existing) {\n existing.add(cleanup);\n return () => this.#unregister(parentSessionKey, existing, cleanup);\n }\n\n const cleanups = new Set([cleanup]);\n this.#byParentSession.set(parentSessionKey, cleanups);\n return () => this.#unregister(parentSessionKey, cleanups, cleanup);\n }\n\n #unregister(\n parentSessionKey: string,\n cleanups: Set<ChildSessionCleanup>,\n cleanup: ChildSessionCleanup\n ): void {\n cleanups.delete(cleanup);\n if (\n cleanups.size === 0 &&\n this.#byParentSession.get(parentSessionKey) === cleanups\n ) {\n this.#byParentSession.delete(parentSessionKey);\n }\n }\n\n #restore(\n parentSessionKey: string,\n failedCleanups: readonly ChildSessionCleanup[]\n ): void {\n const current = this.#byParentSession.get(parentSessionKey);\n if (current) {\n for (const cleanup of failedCleanups) {\n current.add(cleanup);\n }\n return;\n }\n\n this.#byParentSession.set(parentSessionKey, new Set(failedCleanups));\n }\n}\n\nasync function runCleanup(\n cleanup: ChildSessionCleanup\n): Promise<CleanupResult> {\n try {\n await cleanup();\n return { cleanup, ok: true };\n } catch (error) {\n return { cleanup, error, ok: false };\n }\n}\n"],"mappings":";AAUA,IAAa,uBAAb,MAAkC;CAChC,mCAA4B,IAAI,IAAsC;CAEtE,MAAM,OAAO,kBAAyC;EACpD,MAAM,WAAW,KAAKA,iBAAiB,IAAI,gBAAgB;EAC3D,IAAI,CAAC,UACH;EAGF,KAAKA,iBAAiB,OAAO,gBAAgB;EAC7C,MAAM,UAAU,MAAM,QAAQ,IAAI,CAAC,GAAG,QAAQ,EAAE,IAAI,UAAU,CAAC;EAC/D,MAAM,iBAAwC,CAAC;EAC/C,IAAI;EACJ,KAAK,MAAM,UAAU,SAAS;GAC5B,IAAI,OAAO,IACT;GAGF,eAAe,OAAO;GACtB,eAAe,KAAK,OAAO,OAAO;EACpC;EAEA,IAAI,eAAe,WAAW,GAC5B;EAGF,KAAKC,SAAS,kBAAkB,cAAc;EAC9C,MAAM,sBAAsB,QACxB,aACA,IAAI,MAAM,OAAO,UAAU,CAAC;CAClC;CAEA,SAAS,kBAA0B,SAA0C;EAC3E,MAAM,WAAW,KAAKD,iBAAiB,IAAI,gBAAgB;EAC3D,IAAI,UAAU;GACZ,SAAS,IAAI,OAAO;GACpB,aAAa,KAAKE,YAAY,kBAAkB,UAAU,OAAO;EACnE;EAEA,MAAM,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC;EAClC,KAAKF,iBAAiB,IAAI,kBAAkB,QAAQ;EACpD,aAAa,KAAKE,YAAY,kBAAkB,UAAU,OAAO;CACnE;CAEA,YACE,kBACA,UACA,SACM;EACN,SAAS,OAAO,OAAO;EACvB,IACE,SAAS,SAAS,KAClB,KAAKF,iBAAiB,IAAI,gBAAgB,MAAM,UAEhD,KAAKA,iBAAiB,OAAO,gBAAgB;CAEjD;CAEA,SACE,kBACA,gBACM;EACN,MAAM,UAAU,KAAKA,iBAAiB,IAAI,gBAAgB;EAC1D,IAAI,SAAS;GACX,KAAK,MAAM,WAAW,gBACpB,QAAQ,IAAI,OAAO;GAErB;EACF;EAEA,KAAKA,iBAAiB,IAAI,kBAAkB,IAAI,IAAI,cAAc,CAAC;CACrE;AACF;AAEA,eAAe,WACb,SACwB;CACxB,IAAI;EACF,MAAM,QAAQ;EACd,OAAO;GAAE;GAAS,IAAI;EAAK;CAC7B,SAAS,OAAO;EACd,OAAO;GAAE;GAAS;GAAO,IAAI;EAAM;CACrC;AACF"}
@@ -1,55 +0,0 @@
1
- //#region src/execution/run.ts
2
- var StoredAgentRun = class {
3
- #cursor;
4
- #eventStore;
5
- #runId;
6
- #eventsStarted = false;
7
- constructor({ cursor, eventStore, runId }) {
8
- this.#cursor = cursor;
9
- this.#eventStore = eventStore;
10
- this.#runId = runId;
11
- }
12
- events() {
13
- if (this.#eventsStarted) throw new Error("AgentRun.events() can only be consumed once");
14
- this.#eventsStarted = true;
15
- return new StoredAgentEventIterator(this.#eventStore.read(this.#runId, this.#cursor));
16
- }
17
- };
18
- var StoredAgentEventIterator = class {
19
- #source;
20
- #nextPending = false;
21
- constructor(events) {
22
- this.#source = events[Symbol.asyncIterator]();
23
- }
24
- [Symbol.asyncIterator]() {
25
- return this;
26
- }
27
- async next() {
28
- if (this.#nextPending) throw new Error("AgentRun.events() does not allow concurrent next() calls");
29
- this.#nextPending = true;
30
- try {
31
- const next = await this.#source.next();
32
- if (next.done) return {
33
- done: true,
34
- value: void 0
35
- };
36
- return {
37
- done: false,
38
- value: next.value.event
39
- };
40
- } finally {
41
- this.#nextPending = false;
42
- }
43
- }
44
- async return() {
45
- await this.#source.return?.();
46
- return {
47
- done: true,
48
- value: void 0
49
- };
50
- }
51
- };
52
- //#endregion
53
- export { StoredAgentRun };
54
-
55
- //# sourceMappingURL=run.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"run.js","names":["#cursor","#eventStore","#runId","#eventsStarted","#source","#nextPending"],"sources":["../../src/execution/run.ts"],"sourcesContent":["import type { AgentEvent } from \"../session/events\";\nimport type { AgentRun } from \"../session/run\";\nimport type { EventCursor, EventStore, StoredAgentEvent } from \"./types\";\n\nexport class StoredAgentRun implements AgentRun {\n readonly #cursor: EventCursor | undefined;\n readonly #eventStore: EventStore;\n readonly #runId: string;\n #eventsStarted = false;\n\n constructor({\n cursor,\n eventStore,\n runId,\n }: {\n readonly cursor?: EventCursor;\n readonly eventStore: EventStore;\n readonly runId: string;\n }) {\n this.#cursor = cursor;\n this.#eventStore = eventStore;\n this.#runId = runId;\n }\n\n events(): AsyncIterable<AgentEvent> {\n if (this.#eventsStarted) {\n throw new Error(\"AgentRun.events() can only be consumed once\");\n }\n this.#eventsStarted = true;\n\n return new StoredAgentEventIterator(\n this.#eventStore.read(this.#runId, this.#cursor)\n );\n }\n}\n\nclass StoredAgentEventIterator implements AsyncIterableIterator<AgentEvent> {\n readonly #source: AsyncIterator<StoredAgentEvent>;\n #nextPending = false;\n\n constructor(events: AsyncIterable<StoredAgentEvent>) {\n this.#source = events[Symbol.asyncIterator]();\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<AgentEvent> {\n return this;\n }\n\n async next(): Promise<IteratorResult<AgentEvent>> {\n if (this.#nextPending) {\n throw new Error(\n \"AgentRun.events() does not allow concurrent next() calls\"\n );\n }\n\n this.#nextPending = true;\n try {\n const next = await this.#source.next();\n if (next.done) {\n return { done: true, value: undefined };\n }\n\n return { done: false, value: next.value.event };\n } finally {\n this.#nextPending = false;\n }\n }\n\n async return(): Promise<IteratorResult<AgentEvent>> {\n await this.#source.return?.();\n return { done: true, value: undefined };\n }\n}\n"],"mappings":";AAIA,IAAa,iBAAb,MAAgD;CAC9C;CACA;CACA;CACA,iBAAiB;CAEjB,YAAY,EACV,QACA,YACA,SAKC;EACD,KAAKA,UAAU;EACf,KAAKC,cAAc;EACnB,KAAKC,SAAS;CAChB;CAEA,SAAoC;EAClC,IAAI,KAAKC,gBACP,MAAM,IAAI,MAAM,6CAA6C;EAE/D,KAAKA,iBAAiB;EAEtB,OAAO,IAAI,yBACT,KAAKF,YAAY,KAAK,KAAKC,QAAQ,KAAKF,OAAO,CACjD;CACF;AACF;AAEA,IAAM,2BAAN,MAA4E;CAC1E;CACA,eAAe;CAEf,YAAY,QAAyC;EACnD,KAAKI,UAAU,OAAO,OAAO,eAAe;CAC9C;CAEA,CAAC,OAAO,iBAAoD;EAC1D,OAAO;CACT;CAEA,MAAM,OAA4C;EAChD,IAAI,KAAKC,cACP,MAAM,IAAI,MACR,0DACF;EAGF,KAAKA,eAAe;EACpB,IAAI;GACF,MAAM,OAAO,MAAM,KAAKD,QAAQ,KAAK;GACrC,IAAI,KAAK,MACP,OAAO;IAAE,MAAM;IAAM,OAAO,KAAA;GAAU;GAGxC,OAAO;IAAE,MAAM;IAAO,OAAO,KAAK,MAAM;GAAM;EAChD,UAAU;GACR,KAAKC,eAAe;EACtB;CACF;CAEA,MAAM,SAA8C;EAClD,MAAM,KAAKD,QAAQ,SAAS;EAC5B,OAAO;GAAE,MAAM;GAAM,OAAO,KAAA;EAAU;CACxC;AACF"}
@@ -1,51 +0,0 @@
1
- //#region src/subagent-background-child-run-state.ts
2
- function durableBackgroundChildRunState({ delegateToolCallId, description, groupId, parentSessionKey, prompt, subagent }) {
3
- return {
4
- ...delegateToolCallId ? { delegateToolCallId } : {},
5
- ...description ? { description } : {},
6
- ...groupId ? { groupId } : {},
7
- kind: "background-subagent",
8
- ...parentSessionKey ? { parentSessionKey } : {},
9
- prompt: structuredClone(prompt),
10
- subagent: subagent ?? "subagent"
11
- };
12
- }
13
- function readDurableBackgroundChildRunState(checkpoint) {
14
- const state = checkpoint?.runtimeState;
15
- if (!isRecord(state) || state.kind !== "background-subagent") return null;
16
- if (!isAgentInput(state.prompt) || typeof state.subagent !== "string") return null;
17
- return {
18
- ...typeof state.delegateToolCallId === "string" ? { delegateToolCallId: state.delegateToolCallId } : {},
19
- ...typeof state.description === "string" ? { description: state.description } : {},
20
- ...typeof state.groupId === "string" ? { groupId: state.groupId } : {},
21
- kind: "background-subagent",
22
- ...typeof state.parentSessionKey === "string" ? { parentSessionKey: state.parentSessionKey } : {},
23
- prompt: state.prompt,
24
- subagent: state.subagent
25
- };
26
- }
27
- function isAgentInput(value) {
28
- return typeof value === "string" || isStringArray(value) || isUserInput(value) || isMessageContent(value);
29
- }
30
- function isUserInput(value) {
31
- if (!isRecord(value)) return false;
32
- if (value.type === "user-text") return typeof value.text === "string" || isStringArray(value.text);
33
- return value.type === "user-message" && isMessageContent(value.content);
34
- }
35
- function isMessageContent(value) {
36
- return Array.isArray(value) && value.every(isMessageContentPart);
37
- }
38
- function isMessageContentPart(value) {
39
- if (!isRecord(value) || typeof value.type !== "string") return false;
40
- return value.type === "text" || value.type === "image" || value.type === "file";
41
- }
42
- function isRecord(value) {
43
- return typeof value === "object" && value !== null;
44
- }
45
- function isStringArray(value) {
46
- return Array.isArray(value) && value.every((item) => typeof item === "string");
47
- }
48
- //#endregion
49
- export { durableBackgroundChildRunState, readDurableBackgroundChildRunState };
50
-
51
- //# sourceMappingURL=subagent-background-child-run-state.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"subagent-background-child-run-state.js","names":[],"sources":["../src/subagent-background-child-run-state.ts"],"sourcesContent":["import type { RunCheckpoint } from \"./execution/types\";\nimport type { AgentInput } from \"./session/input\";\n\nexport interface DurableBackgroundChildRunState {\n readonly delegateToolCallId?: string;\n readonly description?: string;\n readonly groupId?: string;\n readonly kind: \"background-subagent\";\n readonly parentSessionKey?: string;\n readonly prompt: AgentInput;\n readonly subagent: string;\n}\n\nexport function durableBackgroundChildRunState({\n delegateToolCallId,\n description,\n groupId,\n parentSessionKey,\n prompt,\n subagent,\n}: {\n readonly delegateToolCallId?: string;\n readonly description?: string;\n readonly groupId?: string;\n readonly parentSessionKey?: string;\n readonly prompt: AgentInput;\n readonly subagent?: string;\n}): DurableBackgroundChildRunState {\n return {\n ...(delegateToolCallId ? { delegateToolCallId } : {}),\n ...(description ? { description } : {}),\n ...(groupId ? { groupId } : {}),\n kind: \"background-subagent\",\n ...(parentSessionKey ? { parentSessionKey } : {}),\n prompt: structuredClone(prompt),\n subagent: subagent ?? \"subagent\",\n };\n}\n\nexport function readDurableBackgroundChildRunState(\n checkpoint: RunCheckpoint | null\n): DurableBackgroundChildRunState | null {\n const state = checkpoint?.runtimeState;\n if (!isRecord(state) || state.kind !== \"background-subagent\") {\n return null;\n }\n\n if (!isAgentInput(state.prompt) || typeof state.subagent !== \"string\") {\n return null;\n }\n\n return {\n ...(typeof state.delegateToolCallId === \"string\"\n ? { delegateToolCallId: state.delegateToolCallId }\n : {}),\n ...(typeof state.description === \"string\"\n ? { description: state.description }\n : {}),\n ...(typeof state.groupId === \"string\" ? { groupId: state.groupId } : {}),\n kind: \"background-subagent\",\n ...(typeof state.parentSessionKey === \"string\"\n ? { parentSessionKey: state.parentSessionKey }\n : {}),\n prompt: state.prompt,\n subagent: state.subagent,\n };\n}\n\nfunction isAgentInput(value: unknown): value is AgentInput {\n return (\n typeof value === \"string\" ||\n isStringArray(value) ||\n isUserInput(value) ||\n isMessageContent(value)\n );\n}\n\nfunction isUserInput(value: unknown): boolean {\n if (!isRecord(value)) {\n return false;\n }\n\n if (value.type === \"user-text\") {\n return typeof value.text === \"string\" || isStringArray(value.text);\n }\n\n return value.type === \"user-message\" && isMessageContent(value.content);\n}\n\nfunction isMessageContent(value: unknown): boolean {\n return Array.isArray(value) && value.every(isMessageContentPart);\n}\n\nfunction isMessageContentPart(value: unknown): boolean {\n if (!isRecord(value) || typeof value.type !== \"string\") {\n return false;\n }\n\n return (\n value.type === \"text\" || value.type === \"image\" || value.type === \"file\"\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isStringArray(value: unknown): value is readonly string[] {\n return (\n Array.isArray(value) && value.every((item) => typeof item === \"string\")\n );\n}\n"],"mappings":";AAaA,SAAgB,+BAA+B,EAC7C,oBACA,aACA,SACA,kBACA,QACA,YAQiC;CACjC,OAAO;EACL,GAAI,qBAAqB,EAAE,mBAAmB,IAAI,CAAC;EACnD,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;EACrC,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,MAAM;EACN,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;EAC/C,QAAQ,gBAAgB,MAAM;EAC9B,UAAU,YAAY;CACxB;AACF;AAEA,SAAgB,mCACd,YACuC;CACvC,MAAM,QAAQ,YAAY;CAC1B,IAAI,CAAC,SAAS,KAAK,KAAK,MAAM,SAAS,uBACrC,OAAO;CAGT,IAAI,CAAC,aAAa,MAAM,MAAM,KAAK,OAAO,MAAM,aAAa,UAC3D,OAAO;CAGT,OAAO;EACL,GAAI,OAAO,MAAM,uBAAuB,WACpC,EAAE,oBAAoB,MAAM,mBAAmB,IAC/C,CAAC;EACL,GAAI,OAAO,MAAM,gBAAgB,WAC7B,EAAE,aAAa,MAAM,YAAY,IACjC,CAAC;EACL,GAAI,OAAO,MAAM,YAAY,WAAW,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;EACtE,MAAM;EACN,GAAI,OAAO,MAAM,qBAAqB,WAClC,EAAE,kBAAkB,MAAM,iBAAiB,IAC3C,CAAC;EACL,QAAQ,MAAM;EACd,UAAU,MAAM;CAClB;AACF;AAEA,SAAS,aAAa,OAAqC;CACzD,OACE,OAAO,UAAU,YACjB,cAAc,KAAK,KACnB,YAAY,KAAK,KACjB,iBAAiB,KAAK;AAE1B;AAEA,SAAS,YAAY,OAAyB;CAC5C,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO;CAGT,IAAI,MAAM,SAAS,aACjB,OAAO,OAAO,MAAM,SAAS,YAAY,cAAc,MAAM,IAAI;CAGnE,OAAO,MAAM,SAAS,kBAAkB,iBAAiB,MAAM,OAAO;AACxE;AAEA,SAAS,iBAAiB,OAAyB;CACjD,OAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,oBAAoB;AACjE;AAEA,SAAS,qBAAqB,OAAyB;CACrD,IAAI,CAAC,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS,UAC5C,OAAO;CAGT,OACE,MAAM,SAAS,UAAU,MAAM,SAAS,WAAW,MAAM,SAAS;AAEtE;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,cAAc,OAA4C;CACjE,OACE,MAAM,QAAQ,KAAK,KAAK,MAAM,OAAO,SAAS,OAAO,SAAS,QAAQ;AAE1E"}
@@ -1,103 +0,0 @@
1
- import { durableBackgroundChildRunState } from "./subagent-background-child-run-state.js";
2
- //#region src/subagent-background-child-run.ts
3
- function createBackgroundTaskId() {
4
- return `bg_${crypto.randomUUID().replaceAll("-", "")}`;
5
- }
6
- async function createDurableBackgroundTaskId({ delegateToolCallId, prompt, sessionKey }) {
7
- const digestInput = backgroundSubagentDedupeKey({
8
- delegateToolCallId,
9
- prompt,
10
- sessionKey
11
- });
12
- const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(digestInput));
13
- return `bg_${[...new Uint8Array(digest.slice(0, 16))].map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
14
- }
15
- async function getBackgroundChildRun({ delegateToolCallId, executionHost, prompt, sessionKey }) {
16
- if (!executionHost) return;
17
- const dedupeKey = backgroundSubagentDedupeKey({
18
- delegateToolCallId,
19
- prompt,
20
- sessionKey
21
- });
22
- return await executionHost.store.runs.getByDedupeKey(dedupeKey) ?? void 0;
23
- }
24
- async function getOrCreateBackgroundChildRun(input) {
25
- if (!input.executionHost) return;
26
- const id = input.publicTaskId ?? createBackgroundTaskId();
27
- const dedupeKey = backgroundSubagentDedupeKey(input);
28
- return await input.executionHost.store.transaction(async (tx) => {
29
- const existing = await tx.runs.getByDedupeKey(dedupeKey);
30
- if (existing) return existing;
31
- const parentRunId = input.parentRunId ?? input.parentSessionKey ?? input.sessionKey;
32
- const runtimeState = durableBackgroundChildRunState(input);
33
- const run = {
34
- checkpointVersion: 0,
35
- dedupeKey,
36
- kind: "background-subagent",
37
- ...input.ownerNamespace ? { ownerNamespace: input.ownerNamespace } : {},
38
- parentRunId,
39
- publicTaskId: id,
40
- rootRunId: parentRunId,
41
- runId: `background:${id}`,
42
- sessionKey: `${input.sessionKey}:task:${id}`,
43
- status: "queued"
44
- };
45
- await tx.runs.create(run);
46
- await tx.checkpoints.append({
47
- checkpointId: crypto.randomUUID(),
48
- phase: "before-child-run",
49
- runId: run.runId,
50
- runtimeState,
51
- sessionSnapshot: {},
52
- version: 1
53
- }, { expectedVersion: 0 });
54
- await tx.checkpoints.append({
55
- checkpointId: crypto.randomUUID(),
56
- childRunId: run.runId,
57
- phase: "child-linked",
58
- runId: run.runId,
59
- runtimeState,
60
- sessionSnapshot: {},
61
- version: 2
62
- }, { expectedVersion: 1 });
63
- return await tx.runs.get(run.runId) ?? run;
64
- });
65
- }
66
- async function updateBackgroundRunStatus(job, status) {
67
- if (!(job.executionHost && job.childRunId)) return true;
68
- return await job.executionHost.store.transaction(async (tx) => {
69
- const run = await tx.runs.get(job.childRunId ?? "");
70
- if (!run || isTerminalBackgroundRunStatus(run.status)) return false;
71
- if (job.childRunLeaseId && run.lease?.leaseId !== job.childRunLeaseId) return false;
72
- await tx.runs.update({
73
- ...run,
74
- output: job.result ?? run.output,
75
- status
76
- });
77
- return true;
78
- });
79
- }
80
- async function cancelBackgroundChildRun({ executionHost, runId }) {
81
- return await executionHost.store.transaction(async (tx) => {
82
- const run = await tx.runs.get(runId);
83
- if (!run || isTerminalBackgroundRunStatus(run.status)) return run;
84
- return await tx.runs.update({
85
- ...run,
86
- status: "cancelled"
87
- });
88
- });
89
- }
90
- function childRunStatus(result) {
91
- if (result === "aborted") return "cancelled";
92
- return result;
93
- }
94
- function backgroundSubagentDedupeKey({ delegateToolCallId, prompt, sessionKey }) {
95
- return `background-subagent:${sessionKey}:${delegateToolCallId ?? "unknown"}:${JSON.stringify(prompt)}`;
96
- }
97
- function isTerminalBackgroundRunStatus(status) {
98
- return status === "cancelled" || status === "completed" || status === "error";
99
- }
100
- //#endregion
101
- export { cancelBackgroundChildRun, childRunStatus, createBackgroundTaskId, createDurableBackgroundTaskId, getBackgroundChildRun, getOrCreateBackgroundChildRun, updateBackgroundRunStatus };
102
-
103
- //# sourceMappingURL=subagent-background-child-run.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"subagent-background-child-run.js","names":[],"sources":["../src/subagent-background-child-run.ts"],"sourcesContent":["import type { ExecutionHost, RunRecord, RunStatus } from \"./execution/types\";\nimport type { AgentInput } from \"./session/input\";\nimport { durableBackgroundChildRunState } from \"./subagent-background-child-run-state\";\nimport type { SubagentJob } from \"./subagent-types\";\n\ninterface BackgroundChildRunInput {\n readonly delegateToolCallId?: string;\n readonly description?: string;\n readonly executionHost?: ExecutionHost;\n readonly groupId?: string;\n readonly ownerNamespace?: string;\n readonly parentRunId?: string;\n readonly parentSessionKey?: string;\n readonly prompt: AgentInput;\n readonly publicTaskId?: string;\n readonly sessionKey: string;\n readonly subagent?: string;\n}\n\nexport function createBackgroundTaskId(): string {\n return `bg_${crypto.randomUUID().replaceAll(\"-\", \"\")}`;\n}\n\nexport async function createDurableBackgroundTaskId({\n delegateToolCallId,\n prompt,\n sessionKey,\n}: Pick<\n BackgroundChildRunInput,\n \"delegateToolCallId\" | \"prompt\" | \"sessionKey\"\n>): Promise<string> {\n const digestInput = backgroundSubagentDedupeKey({\n delegateToolCallId,\n prompt,\n sessionKey,\n });\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(digestInput)\n );\n const bytes = [...new Uint8Array(digest.slice(0, 16))];\n const hex = bytes.map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n return `bg_${hex}`;\n}\n\nexport async function getBackgroundChildRun({\n delegateToolCallId,\n executionHost,\n prompt,\n sessionKey,\n}: BackgroundChildRunInput): Promise<RunRecord | undefined> {\n if (!executionHost) {\n return;\n }\n\n const dedupeKey = backgroundSubagentDedupeKey({\n delegateToolCallId,\n prompt,\n sessionKey,\n });\n return (\n (await executionHost.store.runs.getByDedupeKey(dedupeKey)) ?? undefined\n );\n}\n\nexport async function getOrCreateBackgroundChildRun(\n input: BackgroundChildRunInput\n): Promise<RunRecord | undefined> {\n if (!input.executionHost) {\n return;\n }\n\n const id = input.publicTaskId ?? createBackgroundTaskId();\n const dedupeKey = backgroundSubagentDedupeKey(input);\n return await input.executionHost.store.transaction(async (tx) => {\n const existing = await tx.runs.getByDedupeKey(dedupeKey);\n if (existing) {\n return existing;\n }\n\n const parentRunId =\n input.parentRunId ?? input.parentSessionKey ?? input.sessionKey;\n const runtimeState = durableBackgroundChildRunState(input);\n const run: RunRecord = {\n checkpointVersion: 0,\n dedupeKey,\n kind: \"background-subagent\",\n ...(input.ownerNamespace ? { ownerNamespace: input.ownerNamespace } : {}),\n parentRunId,\n publicTaskId: id,\n rootRunId: parentRunId,\n runId: `background:${id}`,\n sessionKey: `${input.sessionKey}:task:${id}`,\n status: \"queued\",\n };\n await tx.runs.create(run);\n await tx.checkpoints.append(\n {\n checkpointId: crypto.randomUUID(),\n phase: \"before-child-run\",\n runId: run.runId,\n runtimeState,\n sessionSnapshot: {},\n version: 1,\n },\n { expectedVersion: 0 }\n );\n await tx.checkpoints.append(\n {\n checkpointId: crypto.randomUUID(),\n childRunId: run.runId,\n phase: \"child-linked\",\n runId: run.runId,\n runtimeState,\n sessionSnapshot: {},\n version: 2,\n },\n { expectedVersion: 1 }\n );\n return (await tx.runs.get(run.runId)) ?? run;\n });\n}\n\nexport async function updateBackgroundRunStatus(\n job: SubagentJob,\n status: Extract<RunStatus, \"cancelled\" | \"completed\" | \"error\">\n): Promise<boolean> {\n if (!(job.executionHost && job.childRunId)) {\n return true;\n }\n\n return await job.executionHost.store.transaction(async (tx) => {\n const run = await tx.runs.get(job.childRunId ?? \"\");\n if (!run || isTerminalBackgroundRunStatus(run.status)) {\n return false;\n }\n if (job.childRunLeaseId && run.lease?.leaseId !== job.childRunLeaseId) {\n return false;\n }\n\n await tx.runs.update({\n ...run,\n output: job.result ?? run.output,\n status,\n });\n return true;\n });\n}\n\nexport async function cancelBackgroundChildRun({\n executionHost,\n runId,\n}: {\n readonly executionHost: ExecutionHost;\n readonly runId: string;\n}): Promise<RunRecord | null> {\n return await executionHost.store.transaction(async (tx) => {\n const run = await tx.runs.get(runId);\n if (!run || isTerminalBackgroundRunStatus(run.status)) {\n return run;\n }\n\n return await tx.runs.update({ ...run, status: \"cancelled\" });\n });\n}\n\nexport function childRunStatus(\n result: Exclude<SubagentJob[\"status\"], \"cancelled\" | \"pending\" | \"running\">\n): Extract<RunStatus, \"cancelled\" | \"completed\" | \"error\"> {\n if (result === \"aborted\") {\n return \"cancelled\";\n }\n\n return result;\n}\n\nfunction backgroundSubagentDedupeKey({\n delegateToolCallId,\n prompt,\n sessionKey,\n}: {\n readonly delegateToolCallId?: string;\n readonly prompt: AgentInput;\n readonly sessionKey: string;\n}): string {\n return `background-subagent:${sessionKey}:${delegateToolCallId ?? \"unknown\"}:${JSON.stringify(prompt)}`;\n}\n\nfunction isTerminalBackgroundRunStatus(status: RunStatus): boolean {\n return status === \"cancelled\" || status === \"completed\" || status === \"error\";\n}\n"],"mappings":";;AAmBA,SAAgB,yBAAiC;CAC/C,OAAO,MAAM,OAAO,WAAW,EAAE,WAAW,KAAK,EAAE;AACrD;AAEA,eAAsB,8BAA8B,EAClD,oBACA,QACA,cAIkB;CAClB,MAAM,cAAc,4BAA4B;EAC9C;EACA;EACA;CACF,CAAC;CACD,MAAM,SAAS,MAAM,OAAO,OAAO,OACjC,WACA,IAAI,YAAY,EAAE,OAAO,WAAW,CACtC;CAGA,OAAO,MADK,CADG,GAAG,IAAI,WAAW,OAAO,MAAM,GAAG,EAAE,CAAC,CACpC,EAAE,KAAK,SAAS,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAC1D;AACjB;AAEA,eAAsB,sBAAsB,EAC1C,oBACA,eACA,QACA,cAC0D;CAC1D,IAAI,CAAC,eACH;CAGF,MAAM,YAAY,4BAA4B;EAC5C;EACA;EACA;CACF,CAAC;CACD,OACG,MAAM,cAAc,MAAM,KAAK,eAAe,SAAS,KAAM,KAAA;AAElE;AAEA,eAAsB,8BACpB,OACgC;CAChC,IAAI,CAAC,MAAM,eACT;CAGF,MAAM,KAAK,MAAM,gBAAgB,uBAAuB;CACxD,MAAM,YAAY,4BAA4B,KAAK;CACnD,OAAO,MAAM,MAAM,cAAc,MAAM,YAAY,OAAO,OAAO;EAC/D,MAAM,WAAW,MAAM,GAAG,KAAK,eAAe,SAAS;EACvD,IAAI,UACF,OAAO;EAGT,MAAM,cACJ,MAAM,eAAe,MAAM,oBAAoB,MAAM;EACvD,MAAM,eAAe,+BAA+B,KAAK;EACzD,MAAM,MAAiB;GACrB,mBAAmB;GACnB;GACA,MAAM;GACN,GAAI,MAAM,iBAAiB,EAAE,gBAAgB,MAAM,eAAe,IAAI,CAAC;GACvE;GACA,cAAc;GACd,WAAW;GACX,OAAO,cAAc;GACrB,YAAY,GAAG,MAAM,WAAW,QAAQ;GACxC,QAAQ;EACV;EACA,MAAM,GAAG,KAAK,OAAO,GAAG;EACxB,MAAM,GAAG,YAAY,OACnB;GACE,cAAc,OAAO,WAAW;GAChC,OAAO;GACP,OAAO,IAAI;GACX;GACA,iBAAiB,CAAC;GAClB,SAAS;EACX,GACA,EAAE,iBAAiB,EAAE,CACvB;EACA,MAAM,GAAG,YAAY,OACnB;GACE,cAAc,OAAO,WAAW;GAChC,YAAY,IAAI;GAChB,OAAO;GACP,OAAO,IAAI;GACX;GACA,iBAAiB,CAAC;GAClB,SAAS;EACX,GACA,EAAE,iBAAiB,EAAE,CACvB;EACA,OAAQ,MAAM,GAAG,KAAK,IAAI,IAAI,KAAK,KAAM;CAC3C,CAAC;AACH;AAEA,eAAsB,0BACpB,KACA,QACkB;CAClB,IAAI,EAAE,IAAI,iBAAiB,IAAI,aAC7B,OAAO;CAGT,OAAO,MAAM,IAAI,cAAc,MAAM,YAAY,OAAO,OAAO;EAC7D,MAAM,MAAM,MAAM,GAAG,KAAK,IAAI,IAAI,cAAc,EAAE;EAClD,IAAI,CAAC,OAAO,8BAA8B,IAAI,MAAM,GAClD,OAAO;EAET,IAAI,IAAI,mBAAmB,IAAI,OAAO,YAAY,IAAI,iBACpD,OAAO;EAGT,MAAM,GAAG,KAAK,OAAO;GACnB,GAAG;GACH,QAAQ,IAAI,UAAU,IAAI;GAC1B;EACF,CAAC;EACD,OAAO;CACT,CAAC;AACH;AAEA,eAAsB,yBAAyB,EAC7C,eACA,SAI4B;CAC5B,OAAO,MAAM,cAAc,MAAM,YAAY,OAAO,OAAO;EACzD,MAAM,MAAM,MAAM,GAAG,KAAK,IAAI,KAAK;EACnC,IAAI,CAAC,OAAO,8BAA8B,IAAI,MAAM,GAClD,OAAO;EAGT,OAAO,MAAM,GAAG,KAAK,OAAO;GAAE,GAAG;GAAK,QAAQ;EAAY,CAAC;CAC7D,CAAC;AACH;AAEA,SAAgB,eACd,QACyD;CACzD,IAAI,WAAW,WACb,OAAO;CAGT,OAAO;AACT;AAEA,SAAS,4BAA4B,EACnC,oBACA,QACA,cAKS;CACT,OAAO,uBAAuB,WAAW,GAAG,sBAAsB,UAAU,GAAG,KAAK,UAAU,MAAM;AACtG;AAEA,SAAS,8BAA8B,QAA4B;CACjE,OAAO,WAAW,eAAe,WAAW,eAAe,WAAW;AACxE"}
@@ -1,98 +0,0 @@
1
- import { cancelBackgroundChildRun } from "./subagent-background-child-run.js";
2
- import { backgroundCancelledLaunchOutput, backgroundLaunchOutput, backgroundReplayOutput, backgroundRunJobStatus } from "./subagent-job-state.js";
3
- import { registerBackgroundJobGroup } from "./subagent-background-notify.js";
4
- import { runBackgroundJob } from "./subagent-background-runner.js";
5
- //#region src/subagent-background-in-process.ts
6
- async function startInProcessBackgroundJob({ abortSignal, childRun, delegateToolCallId, description, executionHost, groupId, groups, id, jobs, parentRunId, parentSession, parentSessionKey, ownerNamespace, prompt, registerCleanup, sessionKey, subagent }) {
7
- const subagentName = subagent.name ?? "subagent";
8
- const claimedChildRun = childRun ? await claimBackgroundChildRun({
9
- executionHost,
10
- run: childRun,
11
- subagent: subagentName
12
- }) : void 0;
13
- if (claimedChildRun?.replay) return claimedChildRun.replay;
14
- if (abortSignal.aborted) {
15
- if (executionHost && claimedChildRun?.run) await cancelBackgroundChildRun({
16
- executionHost,
17
- runId: claimedChildRun.run.runId
18
- });
19
- return backgroundCancelledLaunchOutput({
20
- id,
21
- subagent: subagent.name
22
- });
23
- }
24
- const childSessionKey = claimedChildRun?.run.sessionKey ?? `${sessionKey}:task:${id}`;
25
- const childSession = subagent.session(childSessionKey);
26
- const abort = () => childSession.interrupt();
27
- abortSignal.addEventListener("abort", abort, { once: true });
28
- const cleanup = () => childSession.delete();
29
- const unregisterCleanup = registerCleanup(cleanup);
30
- const job = {
31
- abort,
32
- childRunId: claimedChildRun?.run.runId,
33
- childRunLeaseId: claimedChildRun?.run.lease?.leaseId,
34
- cleanup,
35
- dedupeKey: claimedChildRun?.run.dedupeKey,
36
- description,
37
- id,
38
- delegateToolCallId,
39
- executionHost,
40
- ownerNamespace,
41
- parentSessionKey,
42
- parentRunId,
43
- promise: Promise.resolve(),
44
- groupId,
45
- sessionKey: childSessionKey,
46
- settled: false,
47
- status: "pending",
48
- subagent: subagentName,
49
- unregisterCleanup
50
- };
51
- jobs.set(id, job);
52
- registerBackgroundJobGroup({
53
- groupId,
54
- groups,
55
- job
56
- });
57
- await parentSession.emitObserverEvent({
58
- description,
59
- delegateToolCallId,
60
- run_in_background: true,
61
- subagent: subagentName,
62
- task_id: id,
63
- type: "subagent-job-start"
64
- });
65
- job.status = "running";
66
- job.promise = runBackgroundJob({
67
- childSession,
68
- groups,
69
- jobs,
70
- job,
71
- parentSession,
72
- prompt
73
- }).finally(() => {
74
- abortSignal.removeEventListener("abort", abort);
75
- job.settled = true;
76
- });
77
- return backgroundLaunchOutput(job);
78
- }
79
- async function claimBackgroundChildRun({ executionHost, run, subagent }) {
80
- if (!executionHost) return { run };
81
- const claim = await executionHost.store.runs.claim(run.runId, {
82
- attempt: (run.lease?.attempt ?? 0) + 1,
83
- leaseId: crypto.randomUUID(),
84
- leaseMs: 3e5,
85
- nowMs: Date.now()
86
- });
87
- if (claim.ok) return { run: claim.record };
88
- const status = backgroundRunJobStatus((await executionHost.store.runs.get(run.runId))?.status) ?? "pending";
89
- return { replay: backgroundReplayOutput({
90
- id: run.publicTaskId ?? run.runId,
91
- status,
92
- subagent
93
- }) };
94
- }
95
- //#endregion
96
- export { startInProcessBackgroundJob };
97
-
98
- //# sourceMappingURL=subagent-background-in-process.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"subagent-background-in-process.js","names":[],"sources":["../src/subagent-background-in-process.ts"],"sourcesContent":["import type { ExecutionHost, RunRecord } from \"./execution/types\";\nimport type { AgentInput } from \"./session/input\";\nimport { cancelBackgroundChildRun } from \"./subagent-background-child-run\";\nimport { registerBackgroundJobGroup } from \"./subagent-background-notify\";\nimport { runBackgroundJob } from \"./subagent-background-runner\";\nimport {\n backgroundCancelledLaunchOutput,\n backgroundLaunchOutput,\n backgroundReplayOutput,\n backgroundRunJobStatus,\n} from \"./subagent-job-state\";\nimport type {\n RuntimeInputSink,\n Subagent,\n SubagentJob,\n SubagentJobGroup,\n} from \"./subagent-types\";\n\nexport async function startInProcessBackgroundJob({\n abortSignal,\n childRun,\n delegateToolCallId,\n description,\n executionHost,\n groupId,\n groups,\n id,\n jobs,\n parentRunId,\n parentSession,\n parentSessionKey,\n ownerNamespace,\n prompt,\n registerCleanup,\n sessionKey,\n subagent,\n}: {\n readonly abortSignal: AbortSignal;\n readonly childRun?: RunRecord;\n readonly delegateToolCallId?: string;\n readonly description?: string;\n readonly executionHost?: ExecutionHost;\n readonly groupId?: string;\n readonly groups: Map<string, SubagentJobGroup>;\n readonly id: string;\n readonly jobs: Map<string, SubagentJob>;\n readonly parentRunId?: string;\n readonly parentSession: RuntimeInputSink;\n readonly parentSessionKey?: string;\n readonly ownerNamespace?: string;\n readonly prompt: AgentInput;\n readonly registerCleanup: (cleanup: () => Promise<void>) => () => void;\n readonly sessionKey: string;\n readonly subagent: Subagent;\n}) {\n const subagentName = subagent.name ?? \"subagent\";\n const claimedChildRun = childRun\n ? await claimBackgroundChildRun({\n executionHost,\n run: childRun,\n subagent: subagentName,\n })\n : undefined;\n if (claimedChildRun?.replay) {\n return claimedChildRun.replay;\n }\n if (abortSignal.aborted) {\n if (executionHost && claimedChildRun?.run) {\n await cancelBackgroundChildRun({\n executionHost,\n runId: claimedChildRun.run.runId,\n });\n }\n return backgroundCancelledLaunchOutput({ id, subagent: subagent.name });\n }\n\n const childSessionKey =\n claimedChildRun?.run.sessionKey ?? `${sessionKey}:task:${id}`;\n const childSession = subagent.session(childSessionKey);\n const abort = () => childSession.interrupt();\n abortSignal.addEventListener(\"abort\", abort, { once: true });\n const cleanup = () => childSession.delete();\n const unregisterCleanup = registerCleanup(cleanup);\n const job: SubagentJob = {\n abort,\n childRunId: claimedChildRun?.run.runId,\n childRunLeaseId: claimedChildRun?.run.lease?.leaseId,\n cleanup,\n dedupeKey: claimedChildRun?.run.dedupeKey,\n description,\n id,\n delegateToolCallId,\n executionHost,\n ownerNamespace,\n parentSessionKey,\n parentRunId,\n promise: Promise.resolve(),\n groupId,\n sessionKey: childSessionKey,\n settled: false,\n status: \"pending\",\n subagent: subagentName,\n unregisterCleanup,\n };\n jobs.set(id, job);\n registerBackgroundJobGroup({ groupId, groups, job });\n await parentSession.emitObserverEvent({\n description,\n delegateToolCallId,\n run_in_background: true,\n subagent: subagentName,\n task_id: id,\n type: \"subagent-job-start\",\n });\n job.status = \"running\";\n job.promise = runBackgroundJob({\n childSession,\n groups,\n jobs,\n job,\n parentSession,\n prompt,\n }).finally(() => {\n abortSignal.removeEventListener(\"abort\", abort);\n job.settled = true;\n });\n\n return backgroundLaunchOutput(job);\n}\n\nasync function claimBackgroundChildRun({\n executionHost,\n run,\n subagent,\n}: {\n readonly executionHost: ExecutionHost | undefined;\n readonly run: RunRecord;\n readonly subagent: string;\n}): Promise<\n | { readonly replay?: never; readonly run: RunRecord }\n | {\n readonly replay: ReturnType<typeof backgroundReplayOutput>;\n readonly run?: never;\n }\n> {\n if (!executionHost) {\n return { run };\n }\n\n const claim = await executionHost.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 if (claim.ok) {\n return { run: claim.record };\n }\n\n const latestRun = await executionHost.store.runs.get(run.runId);\n const status = backgroundRunJobStatus(latestRun?.status) ?? \"pending\";\n return {\n replay: backgroundReplayOutput({\n id: run.publicTaskId ?? run.runId,\n status,\n subagent,\n }),\n };\n}\n"],"mappings":";;;;;AAkBA,eAAsB,4BAA4B,EAChD,aACA,UACA,oBACA,aACA,eACA,SACA,QACA,IACA,MACA,aACA,eACA,kBACA,gBACA,QACA,iBACA,YACA,YAmBC;CACD,MAAM,eAAe,SAAS,QAAQ;CACtC,MAAM,kBAAkB,WACpB,MAAM,wBAAwB;EAC5B;EACA,KAAK;EACL,UAAU;CACZ,CAAC,IACD,KAAA;CACJ,IAAI,iBAAiB,QACnB,OAAO,gBAAgB;CAEzB,IAAI,YAAY,SAAS;EACvB,IAAI,iBAAiB,iBAAiB,KACpC,MAAM,yBAAyB;GAC7B;GACA,OAAO,gBAAgB,IAAI;EAC7B,CAAC;EAEH,OAAO,gCAAgC;GAAE;GAAI,UAAU,SAAS;EAAK,CAAC;CACxE;CAEA,MAAM,kBACJ,iBAAiB,IAAI,cAAc,GAAG,WAAW,QAAQ;CAC3D,MAAM,eAAe,SAAS,QAAQ,eAAe;CACrD,MAAM,cAAc,aAAa,UAAU;CAC3C,YAAY,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;CAC3D,MAAM,gBAAgB,aAAa,OAAO;CAC1C,MAAM,oBAAoB,gBAAgB,OAAO;CACjD,MAAM,MAAmB;EACvB;EACA,YAAY,iBAAiB,IAAI;EACjC,iBAAiB,iBAAiB,IAAI,OAAO;EAC7C;EACA,WAAW,iBAAiB,IAAI;EAChC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,QAAQ,QAAQ;EACzB;EACA,YAAY;EACZ,SAAS;EACT,QAAQ;EACR,UAAU;EACV;CACF;CACA,KAAK,IAAI,IAAI,GAAG;CAChB,2BAA2B;EAAE;EAAS;EAAQ;CAAI,CAAC;CACnD,MAAM,cAAc,kBAAkB;EACpC;EACA;EACA,mBAAmB;EACnB,UAAU;EACV,SAAS;EACT,MAAM;CACR,CAAC;CACD,IAAI,SAAS;CACb,IAAI,UAAU,iBAAiB;EAC7B;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,EAAE,cAAc;EACf,YAAY,oBAAoB,SAAS,KAAK;EAC9C,IAAI,UAAU;CAChB,CAAC;CAED,OAAO,uBAAuB,GAAG;AACnC;AAEA,eAAe,wBAAwB,EACrC,eACA,KACA,YAWA;CACA,IAAI,CAAC,eACH,OAAO,EAAE,IAAI;CAGf,MAAM,QAAQ,MAAM,cAAc,MAAM,KAAK,MAAM,IAAI,OAAO;EAC5D,UAAU,IAAI,OAAO,WAAW,KAAK;EACrC,SAAS,OAAO,WAAW;EAC3B,SAAS;EACT,OAAO,KAAK,IAAI;CAClB,CAAC;CACD,IAAI,MAAM,IACR,OAAO,EAAE,KAAK,MAAM,OAAO;CAI7B,MAAM,SAAS,wBAAuB,MADd,cAAc,MAAM,KAAK,IAAI,IAAI,KAAK,IACb,MAAM,KAAK;CAC5D,OAAO,EACL,QAAQ,uBAAuB;EAC7B,IAAI,IAAI,gBAAgB,IAAI;EAC5B;EACA;CACF,CAAC,EACH;AACF"}
@@ -1,106 +0,0 @@
1
- //#region src/subagent-background-notification-inbox.ts
2
- async function enqueueDurableBackgroundNotification({ input, jobs, observerEvents }) {
3
- const host = findExecutionHost(jobs);
4
- const parentSessionKey = findParentSessionKey(jobs);
5
- const ownerNamespace = findOwnerNamespace(jobs);
6
- if (!host) return "inline";
7
- if (await allChildRunsCancelled({
8
- host,
9
- jobs
10
- })) return "queued-only";
11
- if (!(parentSessionKey && ownerNamespace)) return "inline";
12
- if (host.capabilities.backgroundSubagents !== "durable") return "inline";
13
- const idempotencyKey = backgroundNotificationIdempotencyKey({
14
- jobs,
15
- parentSessionKey
16
- });
17
- const existing = await host.store.notifications.getByIdempotencyKey(idempotencyKey);
18
- if (existing) {
19
- if (existing.status === "pending" && host.capabilities.backgroundSubagents === "durable") await host.scheduler.resumeSession(existing.sessionKey, resumePayloadFromNotification(existing));
20
- return "queued-only";
21
- }
22
- const created = await createNotificationRecord({
23
- host,
24
- idempotencyKey,
25
- input,
26
- jobs,
27
- observerEvents,
28
- ownerNamespace,
29
- parentSessionKey
30
- });
31
- if (created) await host.scheduler.resumeSession(parentSessionKey, created);
32
- return "queued-only";
33
- }
34
- async function allChildRunsCancelled({ host, jobs }) {
35
- let childRunCount = 0;
36
- for (const job of jobs) {
37
- if (!job.childRunId) continue;
38
- childRunCount += 1;
39
- if ((await host.store.runs.get(job.childRunId))?.status !== "cancelled") return false;
40
- }
41
- return childRunCount > 0;
42
- }
43
- function findExecutionHost(jobs) {
44
- return jobs.find((job) => job.executionHost)?.executionHost;
45
- }
46
- function findParentSessionKey(jobs) {
47
- return jobs.find((job) => job.parentSessionKey)?.parentSessionKey;
48
- }
49
- function findOwnerNamespace(jobs) {
50
- return jobs.find((job) => job.ownerNamespace)?.ownerNamespace;
51
- }
52
- function backgroundNotificationIdempotencyKey({ jobs, parentSessionKey }) {
53
- return `background-complete:${parentSessionKey}:${jobs.map((job) => job.id).sort().join(",")}`;
54
- }
55
- async function createNotificationRecord({ host, idempotencyKey, input, jobs, observerEvents, ownerNamespace, parentSessionKey }) {
56
- const notificationId = `ntf_${crypto.randomUUID().replaceAll("-", "")}`;
57
- const runId = `notification:${notificationId}`;
58
- return await host.store.transaction(async (tx) => {
59
- if (await tx.notifications.getByIdempotencyKey(idempotencyKey)) return;
60
- if (!(await tx.notifications.enqueue({
61
- idempotencyKey,
62
- input,
63
- notificationId,
64
- observerEvents,
65
- ownerNamespace,
66
- runId,
67
- sessionKey: parentSessionKey,
68
- status: "pending"
69
- })).ok) return;
70
- await tx.runs.create({
71
- checkpointVersion: 0,
72
- dedupeKey: idempotencyKey,
73
- kind: "notification",
74
- ownerNamespace,
75
- parentRunId: jobs.length === 1 ? jobs[0]?.childRunId : void 0,
76
- rootRunId: runId,
77
- runId,
78
- sessionKey: parentSessionKey,
79
- status: "queued"
80
- });
81
- if (!(await tx.checkpoints.append({
82
- checkpointId: crypto.randomUUID(),
83
- phase: "before-notification",
84
- runId,
85
- runtimeState: {},
86
- sessionSnapshot: {},
87
- version: 1
88
- }, { expectedVersion: 0 })).ok) throw new Error("Failed to write background notification checkpoint.");
89
- return {
90
- idempotencyKey,
91
- notificationId,
92
- runId
93
- };
94
- });
95
- }
96
- function resumePayloadFromNotification(notification) {
97
- return {
98
- idempotencyKey: notification.idempotencyKey,
99
- notificationId: notification.notificationId,
100
- runId: notification.runId
101
- };
102
- }
103
- //#endregion
104
- export { enqueueDurableBackgroundNotification };
105
-
106
- //# sourceMappingURL=subagent-background-notification-inbox.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"subagent-background-notification-inbox.js","names":[],"sources":["../src/subagent-background-notification-inbox.ts"],"sourcesContent":["import type { ExecutionHost } from \"./execution/types\";\nimport type { AgentEvent } from \"./session/events\";\nimport type { UserInput } from \"./session/input\";\nimport type { SubagentJob } from \"./subagent-types\";\n\ntype InlineNotificationMode = \"inline\" | \"queued-only\";\n\ninterface NotificationResumePayload {\n readonly idempotencyKey: string;\n readonly notificationId: string;\n readonly runId: string;\n}\n\nexport async function enqueueDurableBackgroundNotification({\n input,\n jobs,\n observerEvents,\n}: {\n readonly input: UserInput;\n readonly jobs: readonly SubagentJob[];\n readonly observerEvents: readonly AgentEvent[];\n}): Promise<InlineNotificationMode> {\n const host = findExecutionHost(jobs);\n const parentSessionKey = findParentSessionKey(jobs);\n const ownerNamespace = findOwnerNamespace(jobs);\n if (!host) {\n return \"inline\";\n }\n\n if (await allChildRunsCancelled({ host, jobs })) {\n return \"queued-only\";\n }\n\n if (!(parentSessionKey && ownerNamespace)) {\n return \"inline\";\n }\n\n if (host.capabilities.backgroundSubagents !== \"durable\") {\n return \"inline\";\n }\n\n const idempotencyKey = backgroundNotificationIdempotencyKey({\n jobs,\n parentSessionKey,\n });\n const existing =\n await host.store.notifications.getByIdempotencyKey(idempotencyKey);\n if (existing) {\n if (\n existing.status === \"pending\" &&\n host.capabilities.backgroundSubagents === \"durable\"\n ) {\n await host.scheduler.resumeSession(\n existing.sessionKey,\n resumePayloadFromNotification(existing)\n );\n }\n return \"queued-only\";\n }\n\n const created = await createNotificationRecord({\n host,\n idempotencyKey,\n input,\n jobs,\n observerEvents,\n ownerNamespace,\n parentSessionKey,\n });\n if (created) {\n await host.scheduler.resumeSession(parentSessionKey, created);\n }\n\n return \"queued-only\";\n}\n\nasync function allChildRunsCancelled({\n host,\n jobs,\n}: {\n readonly host: ExecutionHost;\n readonly jobs: readonly SubagentJob[];\n}): Promise<boolean> {\n let childRunCount = 0;\n for (const job of jobs) {\n if (!job.childRunId) {\n continue;\n }\n\n childRunCount += 1;\n const run = await host.store.runs.get(job.childRunId);\n if (run?.status !== \"cancelled\") {\n return false;\n }\n }\n\n return childRunCount > 0;\n}\n\nfunction findExecutionHost(\n jobs: readonly SubagentJob[]\n): ExecutionHost | undefined {\n return jobs.find((job) => job.executionHost)?.executionHost;\n}\n\nfunction findParentSessionKey(\n jobs: readonly SubagentJob[]\n): string | undefined {\n return jobs.find((job) => job.parentSessionKey)?.parentSessionKey;\n}\n\nfunction findOwnerNamespace(jobs: readonly SubagentJob[]): string | undefined {\n return jobs.find((job) => job.ownerNamespace)?.ownerNamespace;\n}\n\nfunction backgroundNotificationIdempotencyKey({\n jobs,\n parentSessionKey,\n}: {\n readonly jobs: readonly SubagentJob[];\n readonly parentSessionKey: string;\n}): string {\n const taskIds = jobs\n .map((job) => job.id)\n .sort()\n .join(\",\");\n return `background-complete:${parentSessionKey}:${taskIds}`;\n}\n\nasync function createNotificationRecord({\n host,\n idempotencyKey,\n input,\n jobs,\n observerEvents,\n ownerNamespace,\n parentSessionKey,\n}: {\n readonly host: ExecutionHost;\n readonly idempotencyKey: string;\n readonly input: UserInput;\n readonly jobs: readonly SubagentJob[];\n readonly observerEvents: readonly AgentEvent[];\n readonly ownerNamespace: string;\n readonly parentSessionKey: string;\n}): Promise<NotificationResumePayload | undefined> {\n const notificationId = `ntf_${crypto.randomUUID().replaceAll(\"-\", \"\")}`;\n const runId = `notification:${notificationId}`;\n return await host.store.transaction(async (tx) => {\n const duplicate =\n await tx.notifications.getByIdempotencyKey(idempotencyKey);\n if (duplicate) {\n return;\n }\n\n const enqueued = await tx.notifications.enqueue({\n idempotencyKey,\n input,\n notificationId,\n observerEvents,\n ownerNamespace,\n runId,\n sessionKey: parentSessionKey,\n status: \"pending\",\n });\n if (!enqueued.ok) {\n return;\n }\n\n await tx.runs.create({\n checkpointVersion: 0,\n dedupeKey: idempotencyKey,\n kind: \"notification\",\n ownerNamespace,\n parentRunId: jobs.length === 1 ? jobs[0]?.childRunId : undefined,\n rootRunId: runId,\n runId,\n sessionKey: parentSessionKey,\n status: \"queued\",\n });\n const checkpoint = await tx.checkpoints.append(\n {\n checkpointId: crypto.randomUUID(),\n phase: \"before-notification\",\n runId,\n runtimeState: {},\n sessionSnapshot: {},\n version: 1,\n },\n { expectedVersion: 0 }\n );\n if (!checkpoint.ok) {\n throw new Error(\"Failed to write background notification checkpoint.\");\n }\n return { idempotencyKey, notificationId, runId };\n });\n}\n\nfunction resumePayloadFromNotification(\n notification: NotificationResumePayload\n): NotificationResumePayload {\n return {\n idempotencyKey: notification.idempotencyKey,\n notificationId: notification.notificationId,\n runId: notification.runId,\n };\n}\n"],"mappings":";AAaA,eAAsB,qCAAqC,EACzD,OACA,MACA,kBAKkC;CAClC,MAAM,OAAO,kBAAkB,IAAI;CACnC,MAAM,mBAAmB,qBAAqB,IAAI;CAClD,MAAM,iBAAiB,mBAAmB,IAAI;CAC9C,IAAI,CAAC,MACH,OAAO;CAGT,IAAI,MAAM,sBAAsB;EAAE;EAAM;CAAK,CAAC,GAC5C,OAAO;CAGT,IAAI,EAAE,oBAAoB,iBACxB,OAAO;CAGT,IAAI,KAAK,aAAa,wBAAwB,WAC5C,OAAO;CAGT,MAAM,iBAAiB,qCAAqC;EAC1D;EACA;CACF,CAAC;CACD,MAAM,WACJ,MAAM,KAAK,MAAM,cAAc,oBAAoB,cAAc;CACnE,IAAI,UAAU;EACZ,IACE,SAAS,WAAW,aACpB,KAAK,aAAa,wBAAwB,WAE1C,MAAM,KAAK,UAAU,cACnB,SAAS,YACT,8BAA8B,QAAQ,CACxC;EAEF,OAAO;CACT;CAEA,MAAM,UAAU,MAAM,yBAAyB;EAC7C;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,IAAI,SACF,MAAM,KAAK,UAAU,cAAc,kBAAkB,OAAO;CAG9D,OAAO;AACT;AAEA,eAAe,sBAAsB,EACnC,MACA,QAImB;CACnB,IAAI,gBAAgB;CACpB,KAAK,MAAM,OAAO,MAAM;EACtB,IAAI,CAAC,IAAI,YACP;EAGF,iBAAiB;EAEjB,KAAI,MADc,KAAK,MAAM,KAAK,IAAI,IAAI,UAAU,IAC3C,WAAW,aAClB,OAAO;CAEX;CAEA,OAAO,gBAAgB;AACzB;AAEA,SAAS,kBACP,MAC2B;CAC3B,OAAO,KAAK,MAAM,QAAQ,IAAI,aAAa,GAAG;AAChD;AAEA,SAAS,qBACP,MACoB;CACpB,OAAO,KAAK,MAAM,QAAQ,IAAI,gBAAgB,GAAG;AACnD;AAEA,SAAS,mBAAmB,MAAkD;CAC5E,OAAO,KAAK,MAAM,QAAQ,IAAI,cAAc,GAAG;AACjD;AAEA,SAAS,qCAAqC,EAC5C,MACA,oBAIS;CAKT,OAAO,uBAAuB,iBAAiB,GAJ/B,KACb,KAAK,QAAQ,IAAI,EAAE,EACnB,KAAK,EACL,KAAK,GACgD;AAC1D;AAEA,eAAe,yBAAyB,EACtC,MACA,gBACA,OACA,MACA,gBACA,gBACA,oBASiD;CACjD,MAAM,iBAAiB,OAAO,OAAO,WAAW,EAAE,WAAW,KAAK,EAAE;CACpE,MAAM,QAAQ,gBAAgB;CAC9B,OAAO,MAAM,KAAK,MAAM,YAAY,OAAO,OAAO;EAGhD,IAAI,MADI,GAAG,cAAc,oBAAoB,cAAc,GAEzD;EAaF,IAAI,EAAC,MAVkB,GAAG,cAAc,QAAQ;GAC9C;GACA;GACA;GACA;GACA;GACA;GACA,YAAY;GACZ,QAAQ;EACV,CAAC,GACa,IACZ;EAGF,MAAM,GAAG,KAAK,OAAO;GACnB,mBAAmB;GACnB,WAAW;GACX,MAAM;GACN;GACA,aAAa,KAAK,WAAW,IAAI,KAAK,IAAI,aAAa,KAAA;GACvD,WAAW;GACX;GACA,YAAY;GACZ,QAAQ;EACV,CAAC;EAYD,IAAI,EAAC,MAXoB,GAAG,YAAY,OACtC;GACE,cAAc,OAAO,WAAW;GAChC,OAAO;GACP;GACA,cAAc,CAAC;GACf,iBAAiB,CAAC;GAClB,SAAS;EACX,GACA,EAAE,iBAAiB,EAAE,CACvB,GACgB,IACd,MAAM,IAAI,MAAM,qDAAqD;EAEvE,OAAO;GAAE;GAAgB;GAAgB;EAAM;CACjD,CAAC;AACH;AAEA,SAAS,8BACP,cAC2B;CAC3B,OAAO;EACL,gBAAgB,aAAa;EAC7B,gBAAgB,aAAa;EAC7B,OAAO,aAAa;CACtB;AACF"}