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

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 (101) hide show
  1. package/README.md +169 -28
  2. package/dist/agent-child-runs.js +16 -0
  3. package/dist/agent-child-runs.js.map +1 -0
  4. package/dist/agent-host-capabilities.js +9 -0
  5. package/dist/agent-host-capabilities.js.map +1 -0
  6. package/dist/agent-host-session-store.js +12 -0
  7. package/dist/agent-host-session-store.js.map +1 -0
  8. package/dist/agent-loop.js +58 -28
  9. package/dist/agent-loop.js.map +1 -1
  10. package/dist/agent-namespace.js +8 -1
  11. package/dist/agent-namespace.js.map +1 -1
  12. package/dist/agent-options.d.ts +35 -0
  13. package/dist/agent-options.js +16 -0
  14. package/dist/agent-options.js.map +1 -0
  15. package/dist/agent-resume.js +143 -0
  16. package/dist/agent-resume.js.map +1 -0
  17. package/dist/agent-session-entry.d.ts +13 -0
  18. package/dist/agent-validation.js +2 -2
  19. package/dist/agent-validation.js.map +1 -1
  20. package/dist/agent.d.ts +5 -41
  21. package/dist/agent.js +81 -49
  22. package/dist/agent.js.map +1 -1
  23. package/dist/execution/host.js +14 -0
  24. package/dist/execution/host.js.map +1 -0
  25. package/dist/execution/index.d.ts +4 -0
  26. package/dist/execution/index.js +3 -0
  27. package/dist/execution/memory-notifications.js +54 -0
  28. package/dist/execution/memory-notifications.js.map +1 -0
  29. package/dist/execution/memory-state.js +34 -0
  30. package/dist/execution/memory-state.js.map +1 -0
  31. package/dist/execution/memory-store.js +203 -0
  32. package/dist/execution/memory-store.js.map +1 -0
  33. package/dist/execution/memory.d.ts +7 -0
  34. package/dist/execution/memory.js +28 -0
  35. package/dist/execution/memory.js.map +1 -0
  36. package/dist/execution/run.js +55 -0
  37. package/dist/execution/run.js.map +1 -0
  38. package/dist/execution/types.d.ts +155 -0
  39. package/dist/index.d.ts +8 -5
  40. package/dist/llm-tool-execution.d.ts +35 -0
  41. package/dist/llm-tool-execution.js +126 -0
  42. package/dist/llm-tool-execution.js.map +1 -0
  43. package/dist/llm.d.ts +11 -15
  44. package/dist/llm.js +5 -3
  45. package/dist/llm.js.map +1 -1
  46. package/dist/plugins.d.ts +20 -0
  47. package/dist/plugins.js +14 -0
  48. package/dist/plugins.js.map +1 -0
  49. package/dist/session/events.d.ts +3 -0
  50. package/dist/session/runtime-input.js +5 -23
  51. package/dist/session/runtime-input.js.map +1 -1
  52. package/dist/session/session-errors.js +1 -6
  53. package/dist/session/session-errors.js.map +1 -1
  54. package/dist/session/session-events.js +59 -0
  55. package/dist/session/session-events.js.map +1 -0
  56. package/dist/session/session-execution.js +88 -0
  57. package/dist/session/session-execution.js.map +1 -0
  58. package/dist/session/session-notification.js +58 -0
  59. package/dist/session/session-notification.js.map +1 -0
  60. package/dist/session/session-runtime-drain.js +2 -2
  61. package/dist/session/session-runtime-drain.js.map +1 -1
  62. package/dist/session/session-turn-processor.js +135 -0
  63. package/dist/session/session-turn-processor.js.map +1 -0
  64. package/dist/session/session.js +73 -101
  65. package/dist/session/session.js.map +1 -1
  66. package/dist/session/snapshot.js.map +1 -1
  67. package/dist/subagent-background-child-run-state.js +51 -0
  68. package/dist/subagent-background-child-run-state.js.map +1 -0
  69. package/dist/subagent-background-child-run.js +103 -0
  70. package/dist/subagent-background-child-run.js.map +1 -0
  71. package/dist/subagent-background-in-process.js +98 -0
  72. package/dist/subagent-background-in-process.js.map +1 -0
  73. package/dist/subagent-background-notification-inbox.js +106 -0
  74. package/dist/subagent-background-notification-inbox.js.map +1 -0
  75. package/dist/subagent-background-notify.js +136 -0
  76. package/dist/subagent-background-notify.js.map +1 -0
  77. package/dist/subagent-background-resume-group.js +99 -0
  78. package/dist/subagent-background-resume-group.js.map +1 -0
  79. package/dist/subagent-background-runner.js +115 -0
  80. package/dist/subagent-background-runner.js.map +1 -0
  81. package/dist/subagent-background-schedule.js +43 -0
  82. package/dist/subagent-background-schedule.js.map +1 -0
  83. package/dist/subagent-child-run.js +68 -0
  84. package/dist/subagent-child-run.js.map +1 -0
  85. package/dist/subagent-job-cancel.js +60 -4
  86. package/dist/subagent-job-cancel.js.map +1 -1
  87. package/dist/subagent-job-observer.js +19 -0
  88. package/dist/subagent-job-observer.js.map +1 -0
  89. package/dist/subagent-job-output.js +28 -4
  90. package/dist/subagent-job-output.js.map +1 -1
  91. package/dist/subagent-job-state.js +66 -0
  92. package/dist/subagent-job-state.js.map +1 -0
  93. package/dist/subagent-jobs.js +78 -133
  94. package/dist/subagent-jobs.js.map +1 -1
  95. package/dist/subagent-run.js +4 -4
  96. package/dist/subagent-run.js.map +1 -1
  97. package/dist/subagents.js +68 -35
  98. package/dist/subagents.js.map +1 -1
  99. package/package.json +11 -1
  100. package/dist/hooks.d.ts +0 -32
  101. /package/dist/session/{runtime-input.d.ts → session-execution.d.ts} +0 -0
@@ -0,0 +1,143 @@
1
+ import { readDurableBackgroundChildRunState } from "./subagent-background-child-run-state.js";
2
+ import { ownsAgentNamespace } from "./agent-namespace.js";
3
+ import { StoredAgentRun } from "./execution/run.js";
4
+ import { BufferedAgentRun } from "./session/run.js";
5
+ import { buildDurableResumeGroups } from "./subagent-background-resume-group.js";
6
+ import { runBackgroundJob } from "./subagent-background-runner.js";
7
+ //#region src/agent-resume.ts
8
+ const defaultResumeLeaseMs = 3e5;
9
+ async function resumeAgentRun({ host, ownerNamespace, resumeNotification, runId, subagents }) {
10
+ const run = await host.store.runs.get(runId);
11
+ if (!run) return null;
12
+ if (!canAccessRun(run, ownerNamespace)) return null;
13
+ if (run.kind === "background-subagent") return await resumeBackgroundSubagentRun({
14
+ host,
15
+ run,
16
+ subagents
17
+ });
18
+ if (run.kind === "notification" && run.dedupeKey) {
19
+ const idempotencyKey = run.dedupeKey;
20
+ const claimed = await claimRun(host, run);
21
+ if (!claimed) return null;
22
+ const notification = await claimNotificationForRun({
23
+ host,
24
+ idempotencyKey,
25
+ ownerNamespace
26
+ });
27
+ if (!notification) return null;
28
+ try {
29
+ const notificationRun = await resumeNotification(notification);
30
+ await completeNotificationRun(host, claimed.runId);
31
+ return notificationRun;
32
+ } catch (error) {
33
+ await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);
34
+ throw error;
35
+ }
36
+ }
37
+ return null;
38
+ }
39
+ async function claimNotificationForRun({ host, idempotencyKey, ownerNamespace }) {
40
+ if (!ownsAgentNamespace((await host.store.notifications.getByIdempotencyKey(idempotencyKey))?.ownerNamespace, ownerNamespace)) return null;
41
+ const claim = await host.store.notifications.claimByIdempotencyKey(idempotencyKey);
42
+ if (claim.ok) {
43
+ if (ownsAgentNamespace(claim.record.ownerNamespace, ownerNamespace)) return claim.record;
44
+ await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);
45
+ return null;
46
+ }
47
+ if (claim.reason === "already-claimed" && ownsAgentNamespace(claim.record?.ownerNamespace, ownerNamespace)) return claim.record ?? null;
48
+ return null;
49
+ }
50
+ function canAccessRun(run, ownerNamespace) {
51
+ if (run.ownerNamespace) return ownsAgentNamespace(run.ownerNamespace, ownerNamespace);
52
+ return run.sessionKey.startsWith(`parent:${ownerNamespace}:`) || run.parentRunId?.startsWith(`${ownerNamespace}:session:`) === true;
53
+ }
54
+ async function completeNotificationRun(host, runId) {
55
+ const run = await host.store.runs.get(runId);
56
+ if (run?.kind !== "notification" || run.status === "completed") return;
57
+ await host.store.runs.update({
58
+ ...run,
59
+ status: "completed"
60
+ });
61
+ }
62
+ async function resumeBackgroundSubagentRun({ host, run, subagents }) {
63
+ const claimed = await claimRun(host, run);
64
+ if (!claimed) return null;
65
+ const state = readDurableBackgroundChildRunState(await host.store.checkpoints.latest(run.runId));
66
+ if (!state) throw new AgentResumeError(run.runId, "missing background run state");
67
+ const subagent = subagents.find((candidate) => candidate.name === state.subagent);
68
+ if (!subagent) throw new AgentResumeError(run.runId, `missing subagent ${JSON.stringify(state.subagent)}`);
69
+ const childSession = subagent.session(claimed.sessionKey);
70
+ const job = {
71
+ abort: () => childSession.interrupt(),
72
+ childRunId: claimed.runId,
73
+ childRunLeaseId: claimed.lease?.leaseId,
74
+ cleanup: () => Promise.resolve(),
75
+ dedupeKey: claimed.dedupeKey,
76
+ delegateToolCallId: state.delegateToolCallId,
77
+ description: state.description,
78
+ executionHost: host,
79
+ groupId: state.groupId,
80
+ id: claimed.publicTaskId ?? claimed.runId,
81
+ ownerNamespace: claimed.ownerNamespace,
82
+ parentRunId: claimed.parentRunId,
83
+ parentSessionKey: state.parentSessionKey,
84
+ promise: Promise.resolve(),
85
+ sessionKey: claimed.sessionKey,
86
+ settled: false,
87
+ status: "running",
88
+ subagent: state.subagent
89
+ };
90
+ const jobs = new Map([[job.id, job]]);
91
+ job.promise = runBackgroundJob({
92
+ childSession,
93
+ groups: await buildDurableResumeGroups({
94
+ currentJob: job,
95
+ host,
96
+ run: claimed,
97
+ state,
98
+ jobs
99
+ }),
100
+ jobs,
101
+ job,
102
+ parentSession: durableParentSession(host, run.runId),
103
+ prompt: state.prompt
104
+ }).finally(() => {
105
+ job.settled = true;
106
+ });
107
+ await job.promise;
108
+ return new StoredAgentRun({
109
+ eventStore: host.store.events,
110
+ runId: run.runId
111
+ });
112
+ }
113
+ async function claimRun(host, run) {
114
+ const claim = await host.store.runs.claim(run.runId, {
115
+ attempt: (run.lease?.attempt ?? 0) + 1,
116
+ leaseId: crypto.randomUUID(),
117
+ leaseMs: defaultResumeLeaseMs,
118
+ nowMs: Date.now()
119
+ });
120
+ return claim.ok ? claim.record : null;
121
+ }
122
+ function durableParentSession(host, runId) {
123
+ return {
124
+ emitObserverEvent: (event) => host.store.events.append(runId, event).then(),
125
+ enqueueRuntimeInput: () => void 0,
126
+ notify: () => Promise.resolve(emptyRun())
127
+ };
128
+ }
129
+ function emptyRun() {
130
+ const run = new BufferedAgentRun();
131
+ run.close();
132
+ return run;
133
+ }
134
+ var AgentResumeError = class extends Error {
135
+ constructor(runId, reason) {
136
+ super(`Cannot resume agent run ${runId}: ${reason}`);
137
+ this.name = "AgentResumeError";
138
+ }
139
+ };
140
+ //#endregion
141
+ export { resumeAgentRun };
142
+
143
+ //# 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 { StoredAgentRun } from \"./execution/run\";\nimport type {\n ExecutionHost,\n NotificationRecord,\n RunRecord,\n} from \"./execution/types\";\nimport { type AgentRun, BufferedAgentRun } from \"./session/run\";\nimport { readDurableBackgroundChildRunState } from \"./subagent-background-child-run-state\";\nimport { buildDurableResumeGroups } from \"./subagent-background-resume-group\";\nimport { runBackgroundJob } from \"./subagent-background-runner\";\nimport type { RuntimeInputSink, Subagent, SubagentJob } from \"./subagent-types\";\n\nconst defaultResumeLeaseMs = 300_000;\n\ninterface ResumeAgentRunInput {\n readonly host: ExecutionHost;\n readonly ownerNamespace: string;\n resumeNotification(notification: NotificationRecord): Promise<AgentRun>;\n readonly runId: string;\n readonly subagents: readonly Subagent[];\n}\n\nexport async function resumeAgentRun({\n host,\n ownerNamespace,\n resumeNotification,\n runId,\n subagents,\n}: ResumeAgentRunInput): Promise<AgentRun | null> {\n const run = await host.store.runs.get(runId);\n if (!run) {\n return null;\n }\n if (!canAccessRun(run, ownerNamespace)) {\n return null;\n }\n\n if (run.kind === \"background-subagent\") {\n return await resumeBackgroundSubagentRun({ host, run, subagents });\n }\n\n if (run.kind === \"notification\" && run.dedupeKey) {\n const idempotencyKey = run.dedupeKey;\n const claimed = await claimRun(host, run);\n if (!claimed) {\n return null;\n }\n\n const notification = await claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n });\n if (!notification) {\n return null;\n }\n\n try {\n const notificationRun = await resumeNotification(notification);\n await completeNotificationRun(host, claimed.runId);\n return notificationRun;\n } catch (error) {\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n throw error;\n }\n }\n\n return null;\n}\n\nasync function claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n}: {\n readonly host: ExecutionHost;\n readonly idempotencyKey: string;\n readonly ownerNamespace: string;\n}): Promise<NotificationRecord | null> {\n const current =\n await host.store.notifications.getByIdempotencyKey(idempotencyKey);\n if (!ownsAgentNamespace(current?.ownerNamespace, ownerNamespace)) {\n return null;\n }\n\n const claim =\n await host.store.notifications.claimByIdempotencyKey(idempotencyKey);\n if (claim.ok) {\n if (ownsAgentNamespace(claim.record.ownerNamespace, ownerNamespace)) {\n return claim.record;\n }\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n return null;\n }\n\n if (\n claim.reason === \"already-claimed\" &&\n ownsAgentNamespace(claim.record?.ownerNamespace, ownerNamespace)\n ) {\n return claim.record ?? null;\n }\n\n return null;\n}\n\nfunction canAccessRun(run: RunRecord, ownerNamespace: string): boolean {\n if (run.ownerNamespace) {\n return ownsAgentNamespace(run.ownerNamespace, ownerNamespace);\n }\n\n return (\n run.sessionKey.startsWith(`parent:${ownerNamespace}:`) ||\n run.parentRunId?.startsWith(`${ownerNamespace}:session:`) === true\n );\n}\n\nexport async function completeNotificationRun(\n host: ExecutionHost,\n runId: string\n): Promise<void> {\n const run = await host.store.runs.get(runId);\n if (run?.kind !== \"notification\" || run.status === \"completed\") {\n return;\n }\n\n await host.store.runs.update({ ...run, status: \"completed\" });\n}\n\nasync function resumeBackgroundSubagentRun({\n host,\n run,\n subagents,\n}: {\n readonly host: ExecutionHost;\n readonly run: RunRecord;\n readonly subagents: readonly Subagent[];\n}): Promise<AgentRun | null> {\n const claimed = await claimRun(host, run);\n if (!claimed) {\n return null;\n }\n\n const checkpoint = await host.store.checkpoints.latest(run.runId);\n const state = readDurableBackgroundChildRunState(checkpoint);\n if (!state) {\n throw new AgentResumeError(run.runId, \"missing background run state\");\n }\n\n const subagent = subagents.find(\n (candidate) => candidate.name === state.subagent\n );\n if (!subagent) {\n throw new AgentResumeError(\n run.runId,\n `missing subagent ${JSON.stringify(state.subagent)}`\n );\n }\n\n const childSession = subagent.session(claimed.sessionKey);\n const job: SubagentJob = {\n abort: () => childSession.interrupt(),\n childRunId: claimed.runId,\n childRunLeaseId: claimed.lease?.leaseId,\n cleanup: () => Promise.resolve(),\n dedupeKey: claimed.dedupeKey,\n delegateToolCallId: state.delegateToolCallId,\n description: state.description,\n executionHost: host,\n groupId: state.groupId,\n id: claimed.publicTaskId ?? claimed.runId,\n ownerNamespace: claimed.ownerNamespace,\n parentRunId: claimed.parentRunId,\n parentSessionKey: state.parentSessionKey,\n promise: Promise.resolve(),\n sessionKey: claimed.sessionKey,\n settled: false,\n status: \"running\",\n subagent: state.subagent,\n };\n const jobs = new Map([[job.id, job]]);\n const groups = await buildDurableResumeGroups({\n currentJob: job,\n host,\n run: claimed,\n state,\n jobs,\n });\n const parentSession = durableParentSession(host, run.runId);\n\n job.promise = runBackgroundJob({\n childSession,\n groups,\n jobs,\n job,\n parentSession,\n prompt: state.prompt,\n }).finally(() => {\n job.settled = true;\n });\n await job.promise;\n\n return new StoredAgentRun({\n eventStore: host.store.events,\n runId: run.runId,\n });\n}\n\nasync function claimRun(\n host: ExecutionHost,\n run: RunRecord\n): Promise<RunRecord | null> {\n const claim = await host.store.runs.claim(run.runId, {\n attempt: (run.lease?.attempt ?? 0) + 1,\n leaseId: crypto.randomUUID(),\n leaseMs: defaultResumeLeaseMs,\n nowMs: Date.now(),\n });\n return claim.ok ? claim.record : null;\n}\n\nfunction durableParentSession(\n host: ExecutionHost,\n runId: string\n): RuntimeInputSink {\n return {\n emitObserverEvent: (event) => host.store.events.append(runId, event).then(),\n enqueueRuntimeInput: () => undefined,\n notify: () => Promise.resolve(emptyRun()),\n };\n}\n\nfunction emptyRun(): AgentRun {\n const run = new BufferedAgentRun();\n run.close();\n return run;\n}\n\nclass AgentResumeError extends Error {\n constructor(runId: string, reason: string) {\n super(`Cannot resume agent run ${runId}: ${reason}`);\n this.name = \"AgentResumeError\";\n }\n}\n"],"mappings":"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"}
@@ -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
+ interrupt(): void;
7
+ kill(): Promise<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
@@ -1,8 +1,8 @@
1
1
  //#region src/agent-validation.ts
2
2
  const subagentNamePattern = /^[a-z][a-z0-9_-]{0,51}$/;
3
- function assertSubagents(options, agentClass, hasCustomLlm) {
3
+ function assertSubagents(options, agentClass, hasRuntimeModel) {
4
4
  if (!("subagents" in options) || options.subagents === void 0) return;
5
- if (hasCustomLlm) throw new TypeError("Agent: subagents require options.model.");
5
+ if (hasRuntimeModel) throw new TypeError("Agent: subagents require an AI SDK model.");
6
6
  if (!Array.isArray(options.subagents)) throw new TypeError("Agent: subagents must be an array.");
7
7
  assertSubagentTools(options.subagents, agentClass, options.tools ?? {});
8
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-validation.js","names":[],"sources":["../src/agent-validation.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport type { Agent, AgentOptions } from \"./agent\";\n\nconst subagentNamePattern = /^[a-z][a-z0-9_-]{0,51}$/;\n\nexport function assertSubagents(\n options: AgentOptions,\n agentClass: new (options: AgentOptions) => Agent,\n hasCustomLlm: boolean\n): void {\n if (!(\"subagents\" in options) || options.subagents === undefined) {\n return;\n }\n\n if (hasCustomLlm) {\n throw new TypeError(\"Agent: subagents require options.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":";AAGA,MAAM,sBAAsB;AAE5B,SAAgB,gBACd,SACA,YACA,cACM;CACN,IAAI,EAAE,eAAe,YAAY,QAAQ,cAAc,KAAA,GACrD;CAGF,IAAI,cACF,MAAM,IAAI,UAAU,yCAAyC;CAG/D,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
+ {"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"}
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 { 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
10
  readonly description?: string;
48
11
  readonly name?: string;
49
12
  constructor(options: AgentOptions);
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,14 +1,19 @@
1
- import { agentNamespace, parentSessionNamespace, randomAgentNamespace } from "./agent-namespace.js";
1
+ import { executionHost } from "./execution/host.js";
2
+ import { cancelDurableChildRuns } from "./agent-child-runs.js";
3
+ import { supportsBackgroundSubagents } from "./agent-host-capabilities.js";
4
+ import { sessionStoreForHost } from "./agent-host-session-store.js";
5
+ import { parentSessionNamespace, stableAgentNamespace } from "./agent-namespace.js";
6
+ import { assertAgentOptions, hasRuntimeModel } from "./agent-options.js";
7
+ import { resumeAgentRun } from "./agent-resume.js";
2
8
  import { assertSubagents } from "./agent-validation.js";
3
9
  import { ChildSessionCleanups } from "./child-session-cleanups.js";
10
+ import { createInMemoryExecutionHost } from "./execution/memory.js";
4
11
  import { createLlm } from "./llm.js";
5
12
  import { AgentSession } from "./session/session.js";
6
- import { MemorySessionStore } from "./session/store/memory.js";
7
13
  import { createSubagentTools } from "./subagents.js";
8
14
  //#region src/agent.ts
9
15
  var Agent = class Agent {
10
16
  #baseTools;
11
- #hooks;
12
17
  #llm;
13
18
  #modelOptions;
14
19
  #childSessionCleanups = new ChildSessionCleanups();
@@ -16,6 +21,8 @@ var Agent = class Agent {
16
21
  #sessions = /* @__PURE__ */ new Map();
17
22
  #sessionNamespace;
18
23
  #store;
24
+ #host;
25
+ #plugins;
19
26
  #subagents;
20
27
  description;
21
28
  name;
@@ -23,12 +30,16 @@ var Agent = class Agent {
23
30
  assertAgentOptions(options);
24
31
  this.description = options.description;
25
32
  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;
33
+ this.#sessionNamespace = stableAgentNamespace({
34
+ name: options.name,
35
+ namespace: options.namespace
36
+ });
37
+ this.#host = options.host ?? createInMemoryExecutionHost();
38
+ this.#store = sessionStoreForHost(this.#host);
39
+ this.#plugins = options.plugins ?? [];
40
+ assertSubagents(options, Agent, hasRuntimeModel(options));
41
+ this.#subagents = hasRuntimeModel(options) ? [] : options.subagents ?? [];
42
+ if (hasRuntimeModel(options)) this.#llm = options.model;
32
43
  else {
33
44
  this.#baseTools = options.tools;
34
45
  this.#modelOptions = {
@@ -41,7 +52,21 @@ var Agent = class Agent {
41
52
  send(input) {
42
53
  return this.session("default").send(input);
43
54
  }
55
+ async resume(runId) {
56
+ const host = executionHost(this.#host);
57
+ if (!host) throw new Error("Agent host does not support durable run resume.");
58
+ return await resumeAgentRun({
59
+ host,
60
+ ownerNamespace: this.#sessionNamespace,
61
+ resumeNotification: (notification) => this.#resumeNotification(notification),
62
+ runId,
63
+ subagents: this.#subagents
64
+ });
65
+ }
44
66
  session(key) {
67
+ return this.#sessionEntry(key).publicHandle;
68
+ }
69
+ #sessionEntry(key) {
45
70
  const existing = this.#sessions.get(key);
46
71
  if (existing) return existing;
47
72
  let session;
@@ -54,40 +79,65 @@ var Agent = class Agent {
54
79
  sessionKey: key,
55
80
  sessionNamespace: this.#sessionNamespace
56
81
  });
57
- session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession(key, parentAgentNamespace, (input, placement) => getSession().enqueueRuntimeInput(input, placement), (event) => getSession().emitObserverEvent(event))), {
82
+ session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession(key, parentAgentNamespace, (input, placement) => getSession().enqueueRuntimeInput(input, placement), (event) => getSession().emitObserverEvent(event), (input, options) => getSession().notify(input, options), () => getSession().currentTurnId(), () => parentAgentNamespace)), {
58
83
  key,
59
84
  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)
85
+ }, this.#plugins, { executionHost: executionHost(this.#host) });
86
+ const entry = {
87
+ notify: (input, options) => session.notify(input, options),
88
+ publicHandle: {
89
+ delete: async () => {
90
+ session.kill();
91
+ await this.#cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace);
92
+ this.#evictSessionHandle(key);
93
+ await session.delete();
94
+ await this.#childSessionCleanups.delete(key);
95
+ },
96
+ interrupt: () => session.interrupt(),
97
+ kill: async () => {
98
+ session.kill();
99
+ await this.#cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace);
100
+ this.#evictSessionHandle(key);
101
+ await this.#childSessionCleanups.delete(key);
102
+ },
103
+ send: (input) => session.send(input),
104
+ steer: (input) => session.steer(input)
105
+ }
77
106
  };
78
- this.#sessions.set(key, handle);
79
- return handle;
107
+ this.#sessions.set(key, entry);
108
+ return entry;
80
109
  }
81
- #createLlmOptionsForSession(key, parentAgentNamespace, enqueueRuntimeInput, emitObserverEvent) {
110
+ async #cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace) {
111
+ try {
112
+ await cancelDurableChildRuns(this.#host, parentAgentNamespace);
113
+ } catch (error) {
114
+ this.#evictSessionHandle(key);
115
+ throw error;
116
+ }
117
+ }
118
+ #evictSessionHandle(key) {
119
+ this.#sessions.delete(key);
120
+ this.#sessionGenerations.set(key, (this.#sessionGenerations.get(key) ?? 0) + 1);
121
+ }
122
+ #resumeNotification(notification) {
123
+ return this.#sessionEntry(notification.sessionKey).notify(notification.input, { observerEvents: notification.observerEvents });
124
+ }
125
+ #createLlmOptionsForSession(key, parentAgentNamespace, enqueueRuntimeInput, emitObserverEvent, notify, currentBackgroundGroupId, currentRunId) {
82
126
  const modelOptions = this.#modelOptions;
83
127
  if (!modelOptions) throw new Error("Agent: missing model options.");
128
+ const hostExecution = executionHost(this.#host);
84
129
  const tools = this.#subagents.length === 0 ? this.#baseTools : {
85
130
  ...this.#baseTools,
86
131
  ...createSubagentTools({
132
+ backgroundSubagents: supportsBackgroundSubagents(this.#host, hostExecution),
133
+ executionHost: hostExecution,
87
134
  parentAgentNamespace,
88
135
  parentSession: {
136
+ currentBackgroundGroupId,
137
+ currentRunId,
89
138
  emitObserverEvent,
90
- enqueueRuntimeInput
139
+ enqueueRuntimeInput,
140
+ notify
91
141
  },
92
142
  parentSessionKey: key,
93
143
  registerChildSession: (sessionKey, cleanup) => this.#childSessionCleanups.register(sessionKey, cleanup),
@@ -101,25 +151,7 @@ var Agent = class Agent {
101
151
  tools
102
152
  };
103
153
  }
104
- async #deleteChildSessions(parentSessionKey) {
105
- await this.#childSessionCleanups.delete(parentSessionKey);
106
- }
107
154
  };
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
155
  //#endregion
124
156
  export { Agent };
125
157
 
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":"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"}
1
+ {"version":3,"file":"agent.js","names":["#baseTools","#llm","#modelOptions","#childSessionCleanups","#sessionGenerations","#sessions","#sessionNamespace","#store","#host","#plugins","#subagents","#resumeNotification","#sessionEntry","#createLlmOptionsForSession","#cancelDurableChildRunsBeforeLocalCleanup","#evictSessionHandle"],"sources":["../src/agent.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport { cancelDurableChildRuns } from \"./agent-child-runs\";\nimport { supportsBackgroundSubagents } from \"./agent-host-capabilities\";\nimport { sessionStoreForHost } from \"./agent-host-session-store\";\nimport {\n parentSessionNamespace,\n stableAgentNamespace,\n} from \"./agent-namespace\";\nimport {\n type AgentModelOptions,\n type AgentOptions,\n assertAgentOptions,\n hasRuntimeModel,\n} from \"./agent-options\";\nimport { resumeAgentRun } from \"./agent-resume\";\nimport type { AgentSessionEntry, SessionHandle } from \"./agent-session-entry\";\nimport { assertSubagents } from \"./agent-validation\";\nimport { ChildSessionCleanups } from \"./child-session-cleanups\";\nimport { executionHost } from \"./execution/host\";\nimport { createInMemoryExecutionHost } from \"./execution/memory\";\nimport type { AgentHost, NotificationRecord } from \"./execution/types\";\nimport { createLlm, type RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\nimport type { UserInput } from \"./session/events\";\nimport type { AgentRun } from \"./session/run\";\nimport {\n type AgentInput,\n AgentSession,\n type NotifyOptions,\n} from \"./session/session\";\nimport type { SessionStore } from \"./session/store/types\";\nimport { createSubagentTools } from \"./subagents\";\n\nexport type { AgentOptions } from \"./agent-options\";\nexport type { SessionHandle } from \"./agent-session-entry\";\nexport type { AgentHost } from \"./execution/types\";\n\nexport class Agent {\n readonly #baseTools?: ToolSet;\n readonly #llm?: RuntimeLlm;\n readonly #modelOptions?: AgentModelOptions;\n readonly #childSessionCleanups = new ChildSessionCleanups();\n readonly #sessionGenerations = new Map<string, number>();\n readonly #sessions = new Map<string, AgentSessionEntry>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\n readonly #host: AgentHost;\n readonly #plugins: readonly AgentPlugin[];\n readonly #subagents: readonly Agent[];\n readonly description?: string;\n readonly name?: string;\n\n constructor(options: AgentOptions) {\n assertAgentOptions(options);\n\n this.description = options.description;\n this.name = options.name;\n this.#sessionNamespace = stableAgentNamespace({\n name: options.name,\n namespace: options.namespace,\n });\n this.#host = options.host ?? createInMemoryExecutionHost();\n this.#store = sessionStoreForHost(this.#host);\n this.#plugins = options.plugins ?? [];\n assertSubagents(options, Agent, hasRuntimeModel(options));\n this.#subagents = hasRuntimeModel(options) ? [] : (options.subagents ?? []);\n if (hasRuntimeModel(options)) {\n this.#llm = options.model;\n } else {\n this.#baseTools = options.tools;\n this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n };\n }\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n async resume(runId: string): Promise<AgentRun | null> {\n const host = executionHost(this.#host);\n if (!host) {\n throw new Error(\"Agent host does not support durable run resume.\");\n }\n\n return await resumeAgentRun({\n host,\n ownerNamespace: this.#sessionNamespace,\n resumeNotification: (notification) =>\n this.#resumeNotification(notification),\n runId,\n subagents: this.#subagents,\n });\n }\n\n session(key: string): SessionHandle {\n return this.#sessionEntry(key).publicHandle;\n }\n\n #sessionEntry(key: string): AgentSessionEntry {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n let session: AgentSession | undefined;\n const getSession = () => {\n if (!session) {\n throw new Error(\"Agent session is not initialized.\");\n }\n return session;\n };\n const parentAgentNamespace = parentSessionNamespace({\n generation: this.#sessionGenerations.get(key) ?? 0,\n sessionKey: key,\n sessionNamespace: this.#sessionNamespace,\n });\n const llm =\n this.#llm ??\n createLlm(\n this.#createLlmOptionsForSession(\n key,\n parentAgentNamespace,\n (input: UserInput, placement?: \"turn-start\") =>\n getSession().enqueueRuntimeInput(input, placement),\n (event) => getSession().emitObserverEvent(event),\n (input: UserInput, options?: NotifyOptions) =>\n getSession().notify(input, options),\n () => getSession().currentTurnId(),\n () => parentAgentNamespace\n )\n );\n session = new AgentSession(\n llm,\n { key, store: this.#store },\n this.#plugins,\n {\n executionHost: executionHost(this.#host),\n }\n );\n const publicHandle: SessionHandle = {\n delete: async () => {\n session.kill();\n await this.#cancelDurableChildRunsBeforeLocalCleanup(\n key,\n parentAgentNamespace\n );\n this.#evictSessionHandle(key);\n await session.delete();\n await this.#childSessionCleanups.delete(key);\n },\n interrupt: () => session.interrupt(),\n kill: async () => {\n session.kill();\n await this.#cancelDurableChildRunsBeforeLocalCleanup(\n key,\n parentAgentNamespace\n );\n this.#evictSessionHandle(key);\n await this.#childSessionCleanups.delete(key);\n },\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n const entry: AgentSessionEntry = {\n notify: (input, options) => session.notify(input, options),\n publicHandle,\n };\n this.#sessions.set(key, entry);\n return entry;\n }\n\n async #cancelDurableChildRunsBeforeLocalCleanup(\n key: string,\n parentAgentNamespace: string\n ): Promise<void> {\n try {\n await cancelDurableChildRuns(this.#host, parentAgentNamespace);\n } catch (error) {\n this.#evictSessionHandle(key);\n throw error;\n }\n }\n\n #evictSessionHandle(key: string): void {\n this.#sessions.delete(key);\n this.#sessionGenerations.set(\n key,\n (this.#sessionGenerations.get(key) ?? 0) + 1\n );\n }\n\n #resumeNotification(notification: NotificationRecord): Promise<AgentRun> {\n return this.#sessionEntry(notification.sessionKey).notify(\n notification.input,\n { observerEvents: notification.observerEvents }\n );\n }\n\n #createLlmOptionsForSession(\n key: string,\n parentAgentNamespace: string,\n enqueueRuntimeInput: AgentSession[\"enqueueRuntimeInput\"],\n emitObserverEvent: AgentSession[\"emitObserverEvent\"],\n notify: (input: UserInput, options?: NotifyOptions) => Promise<AgentRun>,\n currentBackgroundGroupId: () => string | undefined,\n currentRunId: () => string | undefined\n ): Parameters<typeof createLlm>[0] {\n const modelOptions = this.#modelOptions;\n if (!modelOptions) {\n throw new Error(\"Agent: missing model options.\");\n }\n const hostExecution = executionHost(this.#host);\n const tools =\n this.#subagents.length === 0\n ? this.#baseTools\n : {\n ...this.#baseTools,\n ...createSubagentTools({\n backgroundSubagents: supportsBackgroundSubagents(\n this.#host,\n hostExecution\n ),\n executionHost: hostExecution,\n parentAgentNamespace,\n parentSession: {\n currentBackgroundGroupId,\n currentRunId,\n emitObserverEvent,\n enqueueRuntimeInput,\n notify,\n },\n parentSessionKey: key,\n registerChildSession: (sessionKey, cleanup) =>\n this.#childSessionCleanups.register(sessionKey, cleanup),\n subagents: this.#subagents,\n }),\n };\n\n return {\n instructions: modelOptions.instructions,\n model: modelOptions.model,\n toolChoice: modelOptions.toolChoice,\n tools,\n };\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ //#region src/execution/host.ts
2
+ function executionHost(host) {
3
+ if (isExecutionHost(host)) return host;
4
+ }
5
+ function isExecutionHost(host) {
6
+ return "scheduler" in host && "store" in host && isExecutionStore(host.store);
7
+ }
8
+ function isExecutionStore(store) {
9
+ return typeof store === "object" && store !== null && "checkpoints" in store && "events" in store && "notifications" in store && "runs" in store && "sessions" in store;
10
+ }
11
+ //#endregion
12
+ export { executionHost };
13
+
14
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","names":[],"sources":["../../src/execution/host.ts"],"sourcesContent":["import type { AgentHost, ExecutionHost } from \"./types\";\n\nexport function executionHost(host: AgentHost): ExecutionHost | undefined {\n if (isExecutionHost(host)) {\n return host;\n }\n\n return;\n}\n\nfunction isExecutionHost(host: AgentHost): host is ExecutionHost {\n return \"scheduler\" in host && \"store\" in host && isExecutionStore(host.store);\n}\n\nfunction isExecutionStore(store: unknown): store is ExecutionHost[\"store\"] {\n return (\n typeof store === \"object\" &&\n store !== null &&\n \"checkpoints\" in store &&\n \"events\" in store &&\n \"notifications\" in store &&\n \"runs\" in store &&\n \"sessions\" in store\n );\n}\n"],"mappings":";AAEA,SAAgB,cAAc,MAA4C;CACxE,IAAI,gBAAgB,IAAI,GACtB,OAAO;AAIX;AAEA,SAAS,gBAAgB,MAAwC;CAC/D,OAAO,eAAe,QAAQ,WAAW,QAAQ,iBAAiB,KAAK,KAAK;AAC9E;AAEA,SAAS,iBAAiB,OAAiD;CACzE,OACE,OAAO,UAAU,YACjB,UAAU,QACV,iBAAiB,SACjB,YAAY,SACZ,mBAAmB,SACnB,UAAU,SACV,cAAc;AAElB"}
@@ -0,0 +1,4 @@
1
+ import { RuntimeToolExecutionCheckpoint, RuntimeToolExecutionContext, RuntimeToolExecutionDecision, RuntimeToolRetryPolicy, ToolExecutionNeedsRecoveryError } from "../llm-tool-execution.js";
2
+ import { AgentHostCapabilities, CheckpointPhase, CheckpointStore, CheckpointWriteResult, ClaimRunOptions, ClaimRunResult, EventCursor, EventStore, ExecutionHost, ExecutionScheduler, ExecutionStore, ExecutionStoreTransaction, NotificationClaimResult, NotificationInbox, NotificationRecord, NotificationStatus, NotificationWriteResult, ResumeSessionOptions, RunCheckpoint, RunKind, RunLease, RunRecord, RunStatus, RunStore, StoredAgentEvent } from "./types.js";
3
+ import { createInMemoryExecutionHost } from "./memory.js";
4
+ export { type AgentHostCapabilities, type CheckpointPhase, type CheckpointStore, type CheckpointWriteResult, type ClaimRunOptions, type ClaimRunResult, type EventCursor, type EventStore, type ExecutionHost, type ExecutionScheduler, type ExecutionStore, type ExecutionStoreTransaction, type NotificationClaimResult, type NotificationInbox, type NotificationRecord, type NotificationStatus, type NotificationWriteResult, type ResumeSessionOptions, type RunCheckpoint, type RunKind, type RunLease, type RunRecord, type RunStatus, type RunStore, type RuntimeToolExecutionCheckpoint, type RuntimeToolExecutionContext, type RuntimeToolExecutionDecision, type RuntimeToolRetryPolicy, type StoredAgentEvent, ToolExecutionNeedsRecoveryError, createInMemoryExecutionHost };
@@ -0,0 +1,3 @@
1
+ import { createInMemoryExecutionHost } from "./memory.js";
2
+ import { ToolExecutionNeedsRecoveryError } from "../llm-tool-execution.js";
3
+ export { ToolExecutionNeedsRecoveryError, createInMemoryExecutionHost };
@@ -0,0 +1,54 @@
1
+ //#region src/execution/memory-notifications.ts
2
+ var InMemoryNotificationInbox = class {
3
+ #state;
4
+ constructor(state) {
5
+ this.#state = state;
6
+ }
7
+ claimByIdempotencyKey(idempotencyKey) {
8
+ const record = this.#state().notificationsByKey.get(idempotencyKey);
9
+ if (!record) return Promise.resolve({
10
+ ok: false,
11
+ reason: "not-found"
12
+ });
13
+ if (record.status !== "pending") return Promise.resolve({
14
+ ok: false,
15
+ reason: "already-claimed",
16
+ record: structuredClone(record)
17
+ });
18
+ this.#state().notificationsByKey.set(idempotencyKey, {
19
+ ...record,
20
+ status: "acked"
21
+ });
22
+ return Promise.resolve({
23
+ ok: true,
24
+ record: structuredClone(record)
25
+ });
26
+ }
27
+ enqueue(record) {
28
+ const existing = this.#state().notificationsByKey.get(record.idempotencyKey);
29
+ if (existing) return Promise.resolve({
30
+ existingNotificationId: existing.notificationId,
31
+ ok: false,
32
+ reason: "duplicate"
33
+ });
34
+ this.#state().notificationsByKey.set(record.idempotencyKey, structuredClone(record));
35
+ return Promise.resolve({ ok: true });
36
+ }
37
+ getByIdempotencyKey(idempotencyKey) {
38
+ const record = this.#state().notificationsByKey.get(idempotencyKey);
39
+ return Promise.resolve(record ? structuredClone(record) : null);
40
+ }
41
+ releaseByIdempotencyKey(idempotencyKey) {
42
+ const record = this.#state().notificationsByKey.get(idempotencyKey);
43
+ if (record?.status !== "acked") return Promise.resolve();
44
+ this.#state().notificationsByKey.set(idempotencyKey, {
45
+ ...record,
46
+ status: "pending"
47
+ });
48
+ return Promise.resolve();
49
+ }
50
+ };
51
+ //#endregion
52
+ export { InMemoryNotificationInbox };
53
+
54
+ //# sourceMappingURL=memory-notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-notifications.js","names":["#state"],"sources":["../../src/execution/memory-notifications.ts"],"sourcesContent":["import type { ExecutionState } from \"./memory-state\";\nimport type {\n NotificationClaimResult,\n NotificationInbox,\n NotificationRecord,\n NotificationWriteResult,\n} from \"./types\";\n\nexport class InMemoryNotificationInbox implements NotificationInbox {\n readonly #state: () => ExecutionState;\n\n constructor(state: () => ExecutionState) {\n this.#state = state;\n }\n\n claimByIdempotencyKey(\n idempotencyKey: string\n ): Promise<NotificationClaimResult> {\n const record = this.#state().notificationsByKey.get(idempotencyKey);\n if (!record) {\n return Promise.resolve({ ok: false, reason: \"not-found\" });\n }\n\n if (record.status !== \"pending\") {\n return Promise.resolve({\n ok: false,\n reason: \"already-claimed\",\n record: structuredClone(record),\n });\n }\n\n this.#state().notificationsByKey.set(idempotencyKey, {\n ...record,\n status: \"acked\",\n });\n return Promise.resolve({\n ok: true,\n record: structuredClone(record),\n });\n }\n\n enqueue(record: NotificationRecord): Promise<NotificationWriteResult> {\n const existing = this.#state().notificationsByKey.get(\n record.idempotencyKey\n );\n if (existing) {\n return Promise.resolve({\n existingNotificationId: existing.notificationId,\n ok: false,\n reason: \"duplicate\",\n });\n }\n\n this.#state().notificationsByKey.set(\n record.idempotencyKey,\n structuredClone(record)\n );\n return Promise.resolve({ ok: true });\n }\n\n getByIdempotencyKey(\n idempotencyKey: string\n ): Promise<NotificationRecord | null> {\n const record = this.#state().notificationsByKey.get(idempotencyKey);\n return Promise.resolve(record ? structuredClone(record) : null);\n }\n\n releaseByIdempotencyKey(idempotencyKey: string): Promise<void> {\n const record = this.#state().notificationsByKey.get(idempotencyKey);\n if (record?.status !== \"acked\") {\n return Promise.resolve();\n }\n\n this.#state().notificationsByKey.set(idempotencyKey, {\n ...record,\n status: \"pending\",\n });\n return Promise.resolve();\n }\n}\n"],"mappings":";AAQA,IAAa,4BAAb,MAAoE;CAClE;CAEA,YAAY,OAA6B;EACvC,KAAKA,SAAS;CAChB;CAEA,sBACE,gBACkC;EAClC,MAAM,SAAS,KAAKA,OAAO,EAAE,mBAAmB,IAAI,cAAc;EAClE,IAAI,CAAC,QACH,OAAO,QAAQ,QAAQ;GAAE,IAAI;GAAO,QAAQ;EAAY,CAAC;EAG3D,IAAI,OAAO,WAAW,WACpB,OAAO,QAAQ,QAAQ;GACrB,IAAI;GACJ,QAAQ;GACR,QAAQ,gBAAgB,MAAM;EAChC,CAAC;EAGH,KAAKA,OAAO,EAAE,mBAAmB,IAAI,gBAAgB;GACnD,GAAG;GACH,QAAQ;EACV,CAAC;EACD,OAAO,QAAQ,QAAQ;GACrB,IAAI;GACJ,QAAQ,gBAAgB,MAAM;EAChC,CAAC;CACH;CAEA,QAAQ,QAA8D;EACpE,MAAM,WAAW,KAAKA,OAAO,EAAE,mBAAmB,IAChD,OAAO,cACT;EACA,IAAI,UACF,OAAO,QAAQ,QAAQ;GACrB,wBAAwB,SAAS;GACjC,IAAI;GACJ,QAAQ;EACV,CAAC;EAGH,KAAKA,OAAO,EAAE,mBAAmB,IAC/B,OAAO,gBACP,gBAAgB,MAAM,CACxB;EACA,OAAO,QAAQ,QAAQ,EAAE,IAAI,KAAK,CAAC;CACrC;CAEA,oBACE,gBACoC;EACpC,MAAM,SAAS,KAAKA,OAAO,EAAE,mBAAmB,IAAI,cAAc;EAClE,OAAO,QAAQ,QAAQ,SAAS,gBAAgB,MAAM,IAAI,IAAI;CAChE;CAEA,wBAAwB,gBAAuC;EAC7D,MAAM,SAAS,KAAKA,OAAO,EAAE,mBAAmB,IAAI,cAAc;EAClE,IAAI,QAAQ,WAAW,SACrB,OAAO,QAAQ,QAAQ;EAGzB,KAAKA,OAAO,EAAE,mBAAmB,IAAI,gBAAgB;GACnD,GAAG;GACH,QAAQ;EACV,CAAC;EACD,OAAO,QAAQ,QAAQ;CACzB;AACF"}