@minpeter/pss-runtime 0.1.0-next.1 → 0.1.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +290 -61
- package/dist/agent-host-session-store.js +10 -0
- package/dist/agent-host-session-store.js.map +1 -0
- package/dist/agent-loop.js +57 -28
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent-namespace.js +6 -3
- package/dist/agent-namespace.js.map +1 -1
- package/dist/agent-options.d.ts +29 -0
- package/dist/agent-options.js +16 -0
- package/dist/agent-options.js.map +1 -0
- package/dist/agent-resume.js +63 -0
- package/dist/agent-resume.js.map +1 -0
- package/dist/agent-session-entry.d.ts +13 -0
- package/dist/agent.d.ts +8 -44
- package/dist/agent.js +61 -83
- package/dist/agent.js.map +1 -1
- package/dist/cloudflare/cloudflare-agent-context.d.ts +40 -0
- package/dist/cloudflare/cloudflare-agent-context.js +37 -0
- package/dist/cloudflare/cloudflare-agent-context.js.map +1 -0
- package/dist/cloudflare/cloudflare-alarm-budget.d.ts +18 -0
- package/dist/cloudflare/cloudflare-alarm-budget.js +77 -0
- package/dist/cloudflare/cloudflare-alarm-budget.js.map +1 -0
- package/dist/cloudflare/cloudflare-alarm-drainer.d.ts +45 -0
- package/dist/cloudflare/cloudflare-alarm-drainer.js +103 -0
- package/dist/cloudflare/cloudflare-alarm-drainer.js.map +1 -0
- package/dist/cloudflare/cloudflare-alarm-run-drain.d.ts +13 -0
- package/dist/cloudflare/cloudflare-alarm-run-drain.js +81 -0
- package/dist/cloudflare/cloudflare-alarm-run-drain.js.map +1 -0
- package/dist/cloudflare/cloudflare-alarm-work.js +110 -0
- package/dist/cloudflare/cloudflare-alarm-work.js.map +1 -0
- package/dist/cloudflare/cloudflare-checkpoint-store.js +39 -0
- package/dist/cloudflare/cloudflare-checkpoint-store.js.map +1 -0
- package/dist/cloudflare/cloudflare-durable-object-fetch.d.ts +21 -0
- package/dist/cloudflare/cloudflare-durable-object-fetch.js +11 -0
- package/dist/cloudflare/cloudflare-durable-object-fetch.js.map +1 -0
- package/dist/cloudflare/cloudflare-event-store.js +33 -0
- package/dist/cloudflare/cloudflare-event-store.js.map +1 -0
- package/dist/cloudflare/cloudflare-execution-session-store.js +40 -0
- package/dist/cloudflare/cloudflare-execution-session-store.js.map +1 -0
- package/dist/cloudflare/cloudflare-execution-store.js +35 -0
- package/dist/cloudflare/cloudflare-execution-store.js.map +1 -0
- package/dist/cloudflare/cloudflare-host.d.ts +61 -0
- package/dist/cloudflare/cloudflare-host.js +113 -0
- package/dist/cloudflare/cloudflare-host.js.map +1 -0
- package/dist/cloudflare/cloudflare-notification-store.js +59 -0
- package/dist/cloudflare/cloudflare-notification-store.js.map +1 -0
- package/dist/cloudflare/cloudflare-run-store.js +81 -0
- package/dist/cloudflare/cloudflare-run-store.js.map +1 -0
- package/dist/cloudflare/cloudflare-store-utils.js +43 -0
- package/dist/cloudflare/cloudflare-store-utils.js.map +1 -0
- package/dist/cloudflare/durable-object-storage.d.ts +20 -0
- package/dist/cloudflare/durable-object-storage.js +76 -0
- package/dist/cloudflare/durable-object-storage.js.map +1 -0
- package/dist/cloudflare/index.d.ts +7 -0
- package/dist/cloudflare/index.js +6 -0
- package/dist/execution/capabilities.d.ts +40 -0
- package/dist/execution/host.d.ts +9 -0
- package/dist/execution/host.js +62 -0
- package/dist/execution/host.js.map +1 -0
- package/dist/execution/index.d.ts +6 -0
- package/dist/execution/index.js +4 -0
- package/dist/execution/memory-notifications.js +54 -0
- package/dist/execution/memory-notifications.js.map +1 -0
- package/dist/execution/memory-state.js +34 -0
- package/dist/execution/memory-state.js.map +1 -0
- package/dist/execution/memory-store.js +203 -0
- package/dist/execution/memory-store.js.map +1 -0
- package/dist/execution/memory.d.ts +7 -0
- package/dist/execution/memory.js +28 -0
- package/dist/execution/memory.js.map +1 -0
- package/dist/execution/types.d.ts +150 -0
- package/dist/index.d.ts +13 -6
- package/dist/index.js +6 -1
- package/dist/llm-tool-execution.d.ts +35 -0
- package/dist/llm-tool-execution.js +126 -0
- package/dist/llm-tool-execution.js.map +1 -0
- package/dist/llm.d.ts +11 -15
- package/dist/llm.js +5 -3
- package/dist/llm.js.map +1 -1
- package/dist/plugins.d.ts +42 -0
- package/dist/plugins.js +43 -0
- package/dist/plugins.js.map +1 -0
- package/dist/session/delegate-input.d.ts +9 -0
- package/dist/session/delegate-input.js +16 -0
- package/dist/session/delegate-input.js.map +1 -0
- package/dist/session/events.d.ts +43 -22
- package/dist/session/events.js +41 -0
- package/dist/session/events.js.map +1 -0
- package/dist/session/input-meta-types.d.ts +10 -0
- package/dist/session/input-meta.d.ts +13 -0
- package/dist/session/input-meta.js +45 -0
- package/dist/session/input-meta.js.map +1 -0
- package/dist/session/input.d.ts +4 -0
- package/dist/session/mapping.js +4 -2
- package/dist/session/mapping.js.map +1 -1
- package/dist/session/runtime-input-emit.js +41 -0
- package/dist/session/runtime-input-emit.js.map +1 -0
- package/dist/session/runtime-input.js +10 -24
- package/dist/session/runtime-input.js.map +1 -1
- package/dist/session/session-errors.js +1 -6
- package/dist/session/session-errors.js.map +1 -1
- package/dist/session/session-events.js +73 -0
- package/dist/session/session-events.js.map +1 -0
- package/dist/session/session-execution.js +88 -0
- package/dist/session/session-execution.js.map +1 -0
- package/dist/session/session-notification.js +59 -0
- package/dist/session/session-notification.js.map +1 -0
- package/dist/session/session-runtime-drain.js +3 -9
- package/dist/session/session-runtime-drain.js.map +1 -1
- package/dist/session/session-turn-processor.js +125 -0
- package/dist/session/session-turn-processor.js.map +1 -0
- package/dist/session/session.js +81 -102
- package/dist/session/session.js.map +1 -1
- package/dist/session/snapshot.js.map +1 -1
- package/package.json +16 -1
- package/dist/agent-validation.js +0 -35
- package/dist/agent-validation.js.map +0 -1
- package/dist/child-session-cleanups.js +0 -61
- package/dist/child-session-cleanups.js.map +0 -1
- package/dist/hooks.d.ts +0 -32
- package/dist/subagent-job-cancel.js +0 -28
- package/dist/subagent-job-cancel.js.map +0 -1
- package/dist/subagent-job-output.js +0 -63
- package/dist/subagent-job-output.js.map +0 -1
- package/dist/subagent-jobs.js +0 -151
- package/dist/subagent-jobs.js.map +0 -1
- package/dist/subagent-prompt-schema.js +0 -114
- package/dist/subagent-prompt-schema.js.map +0 -1
- package/dist/subagent-run.js +0 -111
- package/dist/subagent-run.js.map +0 -1
- package/dist/subagents.js +0 -92
- package/dist/subagents.js.map +0 -1
- /package/dist/session/{runtime-input.d.ts → session-execution.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-namespace.js","names":[],"sources":["../src/agent-namespace.ts"],"sourcesContent":["export function randomAgentNamespace(): string {\n return agentNamespace(crypto.randomUUID());\n}\n\nexport function agentNamespace(namespace: string): string {\n return `agent:${namespacePart(namespace)}`;\n}\n\nexport function namespacePart(value: string): string {\n return encodeURIComponent(value);\n}\n\nexport function parentSessionNamespace({\n generation,\n sessionKey,\n sessionNamespace,\n}: {\n readonly generation: number;\n readonly sessionKey: string;\n readonly sessionNamespace: string;\n}): string {\n return `${sessionNamespace}:session:${namespacePart(\n sessionKey\n )}:generation:${generation}`;\n}\n"],"mappings":";AAAA,SAAgB,uBAA+B;CAC7C,OAAO,eAAe,OAAO,WAAW,CAAC;AAC3C;AAEA,SAAgB,eAAe,WAA2B;CACxD,OAAO,SAAS,cAAc,SAAS;AACzC;AAEA,SAAgB,cAAc,OAAuB;CACnD,OAAO,mBAAmB,KAAK;AACjC;
|
|
1
|
+
{"version":3,"file":"agent-namespace.js","names":[],"sources":["../src/agent-namespace.ts"],"sourcesContent":["export function randomAgentNamespace(): string {\n return agentNamespace(crypto.randomUUID());\n}\n\nexport function agentNamespace(namespace: string): string {\n return `agent:${namespacePart(namespace)}`;\n}\n\nexport function namespacePart(value: string): string {\n return encodeURIComponent(value);\n}\n\nexport function parentSessionNamespace({\n generation,\n sessionKey,\n sessionNamespace,\n}: {\n readonly generation: number;\n readonly sessionKey: string;\n readonly sessionNamespace: string;\n}): string {\n return `${sessionNamespace}:session:${namespacePart(\n sessionKey\n )}:generation:${generation}`;\n}\n\nexport function ownsAgentNamespace(\n ownerNamespace: string | undefined,\n sessionNamespace: string\n): boolean {\n return (\n ownerNamespace === sessionNamespace ||\n ownerNamespace?.startsWith(`${sessionNamespace}:session:`) === true\n );\n}\n\nexport function stableAgentNamespace({\n namespace,\n}: {\n readonly namespace?: string;\n}): string {\n return namespace ? agentNamespace(namespace) : randomAgentNamespace();\n}\n"],"mappings":";AAAA,SAAgB,uBAA+B;CAC7C,OAAO,eAAe,OAAO,WAAW,CAAC;AAC3C;AAEA,SAAgB,eAAe,WAA2B;CACxD,OAAO,SAAS,cAAc,SAAS;AACzC;AAEA,SAAgB,cAAc,OAAuB;CACnD,OAAO,mBAAmB,KAAK;AACjC;AAgBA,SAAgB,mBACd,gBACA,kBACS;CACT,OACE,mBAAmB,oBACnB,gBAAgB,WAAW,GAAG,iBAAiB,UAAU,MAAM;AAEnE;AAEA,SAAgB,qBAAqB,EACnC,aAGS;CACT,OAAO,YAAY,eAAe,SAAS,IAAI,qBAAqB;AACtE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AgentToolChoice, RuntimeLlm } from "./llm.js";
|
|
2
|
+
import { AgentHost } from "./execution/types.js";
|
|
3
|
+
import { AgentPlugin } from "./plugins.js";
|
|
4
|
+
import { LanguageModel, ToolSet } from "ai";
|
|
5
|
+
|
|
6
|
+
//#region src/agent-options.d.ts
|
|
7
|
+
interface AgentLanguageModelOptions {
|
|
8
|
+
readonly host?: AgentHost;
|
|
9
|
+
readonly instructions?: string;
|
|
10
|
+
readonly model: LanguageModel;
|
|
11
|
+
readonly namespace?: string;
|
|
12
|
+
readonly plugins?: readonly AgentPlugin[];
|
|
13
|
+
readonly toolChoice?: AgentToolChoice;
|
|
14
|
+
readonly tools?: ToolSet;
|
|
15
|
+
}
|
|
16
|
+
interface AgentRuntimeModelOptions {
|
|
17
|
+
readonly host?: AgentHost;
|
|
18
|
+
readonly instructions?: never;
|
|
19
|
+
readonly model: RuntimeLlm;
|
|
20
|
+
readonly namespace?: string;
|
|
21
|
+
readonly plugins?: readonly AgentPlugin[];
|
|
22
|
+
readonly toolChoice?: never;
|
|
23
|
+
readonly tools?: never;
|
|
24
|
+
}
|
|
25
|
+
type AgentOptions = AgentLanguageModelOptions | AgentRuntimeModelOptions;
|
|
26
|
+
type AgentConstructionOptions = AgentOptions;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { AgentConstructionOptions, AgentOptions };
|
|
29
|
+
//# sourceMappingURL=agent-options.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/agent-options.ts
|
|
2
|
+
function assertAgentOptions(options) {
|
|
3
|
+
if (options === null || typeof options !== "object") throw new TypeError("Agent options are required. Provide { model }.");
|
|
4
|
+
if (!("model" in options && options.model != null)) throw new TypeError("Agent: missing options.model.");
|
|
5
|
+
if (typeof options.model !== "function" && (typeof options.model !== "object" || options.model === null)) throw new TypeError("Agent: invalid options.model.");
|
|
6
|
+
}
|
|
7
|
+
function hasRuntimeModel(options) {
|
|
8
|
+
return typeof options.model === "function";
|
|
9
|
+
}
|
|
10
|
+
function hasLanguageModel(options) {
|
|
11
|
+
return typeof options.model !== "function";
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { assertAgentOptions, hasLanguageModel, hasRuntimeModel };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=agent-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-options.js","names":[],"sources":["../src/agent-options.ts"],"sourcesContent":["import type { LanguageModel, ToolSet } from \"ai\";\nimport type { AgentHost } from \"./execution/types\";\nimport type { AgentToolChoice, RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\n\ninterface AgentLanguageModelOptions {\n readonly host?: AgentHost;\n readonly instructions?: string;\n readonly model: LanguageModel;\n readonly namespace?: string;\n readonly plugins?: readonly AgentPlugin[];\n readonly toolChoice?: AgentToolChoice;\n readonly tools?: ToolSet;\n}\n\ninterface AgentRuntimeModelOptions {\n readonly host?: AgentHost;\n readonly instructions?: never;\n readonly model: RuntimeLlm;\n readonly namespace?: string;\n readonly plugins?: readonly AgentPlugin[];\n readonly toolChoice?: never;\n readonly tools?: never;\n}\n\nexport type AgentModelOptions = Pick<\n AgentLanguageModelOptions,\n \"instructions\" | \"model\" | \"toolChoice\"\n>;\nexport type AgentOptions = AgentLanguageModelOptions | AgentRuntimeModelOptions;\n\nexport type AgentConstructionOptions = AgentOptions;\n\nexport function assertAgentOptions(\n options: unknown\n): asserts options is AgentConstructionOptions {\n if (options === null || typeof options !== \"object\") {\n throw new TypeError(\"Agent options are required. Provide { model }.\");\n }\n\n const hasModel = \"model\" in options && options.model != null;\n\n if (!hasModel) {\n throw new TypeError(\"Agent: missing options.model.\");\n }\n\n if (\n typeof options.model !== \"function\" &&\n (typeof options.model !== \"object\" || options.model === null)\n ) {\n throw new TypeError(\"Agent: invalid options.model.\");\n }\n}\n\nexport function hasRuntimeModel(\n options: AgentConstructionOptions\n): options is AgentRuntimeModelOptions {\n return typeof options.model === \"function\";\n}\n\nexport function hasLanguageModel(\n options: AgentConstructionOptions\n): options is AgentLanguageModelOptions {\n return typeof options.model !== \"function\";\n}\n"],"mappings":";AAiCA,SAAgB,mBACd,SAC6C;CAC7C,IAAI,YAAY,QAAQ,OAAO,YAAY,UACzC,MAAM,IAAI,UAAU,gDAAgD;CAKtE,IAAI,EAFa,WAAW,WAAW,QAAQ,SAAS,OAGtD,MAAM,IAAI,UAAU,+BAA+B;CAGrD,IACE,OAAO,QAAQ,UAAU,eACxB,OAAO,QAAQ,UAAU,YAAY,QAAQ,UAAU,OAExD,MAAM,IAAI,UAAU,+BAA+B;AAEvD;AAEA,SAAgB,gBACd,SACqC;CACrC,OAAO,OAAO,QAAQ,UAAU;AAClC;AAEA,SAAgB,iBACd,SACsC;CACtC,OAAO,OAAO,QAAQ,UAAU;AAClC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ownsAgentNamespace } from "./agent-namespace.js";
|
|
2
|
+
//#region src/agent-resume.ts
|
|
3
|
+
async function resumeAgentRun({ host, ownerNamespace, resumeNotification, runId }) {
|
|
4
|
+
const run = await host.store.runs.get(runId);
|
|
5
|
+
if (!run) return null;
|
|
6
|
+
if (!canAccessRun(run, ownerNamespace)) return null;
|
|
7
|
+
if (run.kind === "notification" && run.dedupeKey) {
|
|
8
|
+
const idempotencyKey = run.dedupeKey;
|
|
9
|
+
const claimed = await claimRun(host, run);
|
|
10
|
+
if (!claimed) return null;
|
|
11
|
+
const notification = await claimNotificationForRun({
|
|
12
|
+
host,
|
|
13
|
+
idempotencyKey,
|
|
14
|
+
ownerNamespace
|
|
15
|
+
});
|
|
16
|
+
if (!notification) return null;
|
|
17
|
+
try {
|
|
18
|
+
const notificationRun = await resumeNotification(notification);
|
|
19
|
+
await completeNotificationRun(host, claimed.runId);
|
|
20
|
+
return notificationRun;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
async function claimNotificationForRun({ host, idempotencyKey, ownerNamespace }) {
|
|
29
|
+
if (!ownsAgentNamespace((await host.store.notifications.getByIdempotencyKey(idempotencyKey))?.ownerNamespace, ownerNamespace)) return null;
|
|
30
|
+
const claim = await host.store.notifications.claimByIdempotencyKey(idempotencyKey);
|
|
31
|
+
if (claim.ok) {
|
|
32
|
+
if (ownsAgentNamespace(claim.record.ownerNamespace, ownerNamespace)) return claim.record;
|
|
33
|
+
await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
if (claim.reason === "already-claimed" && ownsAgentNamespace(claim.record?.ownerNamespace, ownerNamespace)) return claim.record ?? null;
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
function canAccessRun(run, ownerNamespace) {
|
|
40
|
+
if (run.ownerNamespace) return ownsAgentNamespace(run.ownerNamespace, ownerNamespace);
|
|
41
|
+
return run.sessionKey.startsWith(`parent:${ownerNamespace}:`) || run.parentRunId?.startsWith(`${ownerNamespace}:session:`) === true;
|
|
42
|
+
}
|
|
43
|
+
async function completeNotificationRun(host, runId) {
|
|
44
|
+
const run = await host.store.runs.get(runId);
|
|
45
|
+
if (run?.kind !== "notification" || run.status === "completed") return;
|
|
46
|
+
await host.store.runs.update({
|
|
47
|
+
...run,
|
|
48
|
+
status: "completed"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async function claimRun(host, run) {
|
|
52
|
+
const claim = await host.store.runs.claim(run.runId, {
|
|
53
|
+
attempt: (run.lease?.attempt ?? 0) + 1,
|
|
54
|
+
leaseId: crypto.randomUUID(),
|
|
55
|
+
leaseMs: 3e5,
|
|
56
|
+
nowMs: Date.now()
|
|
57
|
+
});
|
|
58
|
+
return claim.ok ? claim.record : null;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { resumeAgentRun };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=agent-resume.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-resume.js","names":[],"sources":["../src/agent-resume.ts"],"sourcesContent":["import { ownsAgentNamespace } from \"./agent-namespace\";\nimport type {\n ExecutionHost,\n NotificationRecord,\n RunRecord,\n} from \"./execution/types\";\nimport type { AgentRun } from \"./session/run\";\n\ninterface ResumeAgentRunInput {\n readonly host: ExecutionHost;\n readonly ownerNamespace: string;\n resumeNotification(notification: NotificationRecord): Promise<AgentRun>;\n readonly runId: string;\n}\n\nexport async function resumeAgentRun({\n host,\n ownerNamespace,\n resumeNotification,\n runId,\n}: ResumeAgentRunInput): Promise<AgentRun | null> {\n const run = await host.store.runs.get(runId);\n if (!run) {\n return null;\n }\n if (!canAccessRun(run, ownerNamespace)) {\n return null;\n }\n\n if (run.kind === \"notification\" && run.dedupeKey) {\n const idempotencyKey = run.dedupeKey;\n const claimed = await claimRun(host, run);\n if (!claimed) {\n return null;\n }\n\n const notification = await claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n });\n if (!notification) {\n return null;\n }\n\n try {\n const notificationRun = await resumeNotification(notification);\n await completeNotificationRun(host, claimed.runId);\n return notificationRun;\n } catch (error) {\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n throw error;\n }\n }\n\n return null;\n}\n\nasync function claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n}: {\n readonly host: ExecutionHost;\n readonly idempotencyKey: string;\n readonly ownerNamespace: string;\n}): Promise<NotificationRecord | null> {\n const current =\n await host.store.notifications.getByIdempotencyKey(idempotencyKey);\n if (!ownsAgentNamespace(current?.ownerNamespace, ownerNamespace)) {\n return null;\n }\n\n const claim =\n await host.store.notifications.claimByIdempotencyKey(idempotencyKey);\n if (claim.ok) {\n if (ownsAgentNamespace(claim.record.ownerNamespace, ownerNamespace)) {\n return claim.record;\n }\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n return null;\n }\n\n if (\n claim.reason === \"already-claimed\" &&\n ownsAgentNamespace(claim.record?.ownerNamespace, ownerNamespace)\n ) {\n return claim.record ?? null;\n }\n\n return null;\n}\n\nfunction canAccessRun(run: RunRecord, ownerNamespace: string): boolean {\n if (run.ownerNamespace) {\n return ownsAgentNamespace(run.ownerNamespace, ownerNamespace);\n }\n\n return (\n run.sessionKey.startsWith(`parent:${ownerNamespace}:`) ||\n run.parentRunId?.startsWith(`${ownerNamespace}:session:`) === true\n );\n}\n\nexport async function completeNotificationRun(\n host: ExecutionHost,\n runId: string\n): Promise<void> {\n const run = await host.store.runs.get(runId);\n if (run?.kind !== \"notification\" || run.status === \"completed\") {\n return;\n }\n\n await host.store.runs.update({ ...run, status: \"completed\" });\n}\n\nasync function claimRun(\n host: ExecutionHost,\n run: RunRecord\n): Promise<RunRecord | null> {\n const claim = await host.store.runs.claim(run.runId, {\n attempt: (run.lease?.attempt ?? 0) + 1,\n leaseId: crypto.randomUUID(),\n leaseMs: 300_000,\n nowMs: Date.now(),\n });\n return claim.ok ? claim.record : null;\n}\n"],"mappings":";;AAeA,eAAsB,eAAe,EACnC,MACA,gBACA,oBACA,SACgD;CAChD,MAAM,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,KAAK;CAC3C,IAAI,CAAC,KACH,OAAO;CAET,IAAI,CAAC,aAAa,KAAK,cAAc,GACnC,OAAO;CAGT,IAAI,IAAI,SAAS,kBAAkB,IAAI,WAAW;EAChD,MAAM,iBAAiB,IAAI;EAC3B,MAAM,UAAU,MAAM,SAAS,MAAM,GAAG;EACxC,IAAI,CAAC,SACH,OAAO;EAGT,MAAM,eAAe,MAAM,wBAAwB;GACjD;GACA;GACA;EACF,CAAC;EACD,IAAI,CAAC,cACH,OAAO;EAGT,IAAI;GACF,MAAM,kBAAkB,MAAM,mBAAmB,YAAY;GAC7D,MAAM,wBAAwB,MAAM,QAAQ,KAAK;GACjD,OAAO;EACT,SAAS,OAAO;GACd,MAAM,KAAK,MAAM,cAAc,wBAAwB,cAAc;GACrE,MAAM;EACR;CACF;CAEA,OAAO;AACT;AAEA,eAAe,wBAAwB,EACrC,MACA,gBACA,kBAKqC;CAGrC,IAAI,CAAC,oBAAmB,MADhB,KAAK,MAAM,cAAc,oBAAoB,cAAc,IAClC,gBAAgB,cAAc,GAC7D,OAAO;CAGT,MAAM,QACJ,MAAM,KAAK,MAAM,cAAc,sBAAsB,cAAc;CACrE,IAAI,MAAM,IAAI;EACZ,IAAI,mBAAmB,MAAM,OAAO,gBAAgB,cAAc,GAChE,OAAO,MAAM;EAEf,MAAM,KAAK,MAAM,cAAc,wBAAwB,cAAc;EACrE,OAAO;CACT;CAEA,IACE,MAAM,WAAW,qBACjB,mBAAmB,MAAM,QAAQ,gBAAgB,cAAc,GAE/D,OAAO,MAAM,UAAU;CAGzB,OAAO;AACT;AAEA,SAAS,aAAa,KAAgB,gBAAiC;CACrE,IAAI,IAAI,gBACN,OAAO,mBAAmB,IAAI,gBAAgB,cAAc;CAG9D,OACE,IAAI,WAAW,WAAW,UAAU,eAAe,EAAE,KACrD,IAAI,aAAa,WAAW,GAAG,eAAe,UAAU,MAAM;AAElE;AAEA,eAAsB,wBACpB,MACA,OACe;CACf,MAAM,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,KAAK;CAC3C,IAAI,KAAK,SAAS,kBAAkB,IAAI,WAAW,aACjD;CAGF,MAAM,KAAK,MAAM,KAAK,OAAO;EAAE,GAAG;EAAK,QAAQ;CAAY,CAAC;AAC9D;AAEA,eAAe,SACb,MACA,KAC2B;CAC3B,MAAM,QAAQ,MAAM,KAAK,MAAM,KAAK,MAAM,IAAI,OAAO;EACnD,UAAU,IAAI,OAAO,WAAW,KAAK;EACrC,SAAS,OAAO,WAAW;EAC3B,SAAS;EACT,OAAO,KAAK,IAAI;CAClB,CAAC;CACD,OAAO,MAAM,KAAK,MAAM,SAAS;AACnC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AgentInput } from "./session/input.js";
|
|
2
|
+
import { AgentRun } from "./session/run.js";
|
|
3
|
+
//#region src/agent-session-entry.d.ts
|
|
4
|
+
interface SessionHandle {
|
|
5
|
+
delete(): Promise<void>;
|
|
6
|
+
dispose(): Promise<void>;
|
|
7
|
+
interrupt(): void;
|
|
8
|
+
send(input: AgentInput): Promise<AgentRun>;
|
|
9
|
+
steer(input: AgentInput): Promise<AgentRun>;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { SessionHandle };
|
|
13
|
+
//# sourceMappingURL=agent-session-entry.d.ts.map
|
package/dist/agent.d.ts
CHANGED
|
@@ -1,55 +1,19 @@
|
|
|
1
|
-
import { AgentToolChoice, Llm } from "./llm.js";
|
|
2
1
|
import { AgentInput } from "./session/input.js";
|
|
3
|
-
import {
|
|
2
|
+
import { AgentHost } from "./execution/types.js";
|
|
3
|
+
import { AgentConstructionOptions, AgentOptions } from "./agent-options.js";
|
|
4
4
|
import { AgentRun } from "./session/run.js";
|
|
5
|
-
import {
|
|
6
|
-
import { LanguageModel, ToolSet } from "ai";
|
|
5
|
+
import { SessionHandle } from "./agent-session-entry.js";
|
|
7
6
|
|
|
8
7
|
//#region src/agent.d.ts
|
|
9
|
-
interface AgentLanguageModelOptions {
|
|
10
|
-
description?: string;
|
|
11
|
-
hooks?: AgentHooks;
|
|
12
|
-
instructions?: string;
|
|
13
|
-
llm?: never;
|
|
14
|
-
model: LanguageModel;
|
|
15
|
-
name?: string;
|
|
16
|
-
sessions?: AgentSessionOptions;
|
|
17
|
-
subagents?: readonly Agent[];
|
|
18
|
-
toolChoice?: AgentToolChoice;
|
|
19
|
-
tools?: ToolSet;
|
|
20
|
-
}
|
|
21
|
-
interface AgentLlmOptions {
|
|
22
|
-
description?: string;
|
|
23
|
-
hooks?: AgentHooks;
|
|
24
|
-
instructions?: never;
|
|
25
|
-
llm: Llm;
|
|
26
|
-
model?: never;
|
|
27
|
-
name?: string;
|
|
28
|
-
sessions?: AgentSessionOptions;
|
|
29
|
-
subagents?: never;
|
|
30
|
-
toolChoice?: never;
|
|
31
|
-
tools?: never;
|
|
32
|
-
}
|
|
33
|
-
interface AgentSessionOptions {
|
|
34
|
-
namespace?: string;
|
|
35
|
-
store?: SessionStore;
|
|
36
|
-
}
|
|
37
|
-
interface SessionHandle {
|
|
38
|
-
delete(): Promise<void>;
|
|
39
|
-
interrupt(): void;
|
|
40
|
-
kill(): void;
|
|
41
|
-
send(input: AgentInput): Promise<AgentRun>;
|
|
42
|
-
steer(input: AgentInput): Promise<AgentRun>;
|
|
43
|
-
}
|
|
44
|
-
type AgentOptions = AgentLanguageModelOptions | AgentLlmOptions;
|
|
45
8
|
declare class Agent {
|
|
46
9
|
#private;
|
|
47
|
-
readonly
|
|
48
|
-
readonly
|
|
49
|
-
constructor(options:
|
|
10
|
+
readonly host: AgentHost;
|
|
11
|
+
readonly namespace?: string;
|
|
12
|
+
constructor(options: AgentConstructionOptions);
|
|
50
13
|
send(input: AgentInput): Promise<AgentRun>;
|
|
14
|
+
resume(runId: string): Promise<AgentRun | null>;
|
|
51
15
|
session(key: string): SessionHandle;
|
|
52
16
|
}
|
|
53
17
|
//#endregion
|
|
54
|
-
export { Agent
|
|
18
|
+
export { Agent };
|
|
55
19
|
//# sourceMappingURL=agent.d.ts.map
|
package/dist/agent.js
CHANGED
|
@@ -1,35 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { executionHost } from "./execution/host.js";
|
|
2
|
+
import { sessionStoreForHost } from "./agent-host-session-store.js";
|
|
3
|
+
import { stableAgentNamespace } from "./agent-namespace.js";
|
|
4
|
+
import { assertAgentOptions, hasLanguageModel, hasRuntimeModel } from "./agent-options.js";
|
|
5
|
+
import { resumeAgentRun } from "./agent-resume.js";
|
|
6
|
+
import { createInMemoryExecutionHost } from "./execution/memory.js";
|
|
4
7
|
import { createLlm } from "./llm.js";
|
|
5
8
|
import { AgentSession } from "./session/session.js";
|
|
6
|
-
import { MemorySessionStore } from "./session/store/memory.js";
|
|
7
|
-
import { createSubagentTools } from "./subagents.js";
|
|
8
9
|
//#region src/agent.ts
|
|
9
|
-
var Agent = class
|
|
10
|
+
var Agent = class {
|
|
10
11
|
#baseTools;
|
|
11
|
-
#hooks;
|
|
12
12
|
#llm;
|
|
13
13
|
#modelOptions;
|
|
14
|
-
#childSessionCleanups = new ChildSessionCleanups();
|
|
15
|
-
#sessionGenerations = /* @__PURE__ */ new Map();
|
|
16
14
|
#sessions = /* @__PURE__ */ new Map();
|
|
17
15
|
#sessionNamespace;
|
|
18
16
|
#store;
|
|
19
|
-
#
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
#host;
|
|
18
|
+
#plugins;
|
|
19
|
+
host;
|
|
20
|
+
namespace;
|
|
22
21
|
constructor(options) {
|
|
23
22
|
assertAgentOptions(options);
|
|
24
|
-
this.
|
|
25
|
-
this
|
|
26
|
-
this.#
|
|
27
|
-
this
|
|
28
|
-
this.#
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
else {
|
|
23
|
+
this.namespace = options.namespace;
|
|
24
|
+
this.#sessionNamespace = stableAgentNamespace({ namespace: options.namespace });
|
|
25
|
+
this.#host = options.host ?? createInMemoryExecutionHost();
|
|
26
|
+
this.host = this.#host;
|
|
27
|
+
this.#store = sessionStoreForHost(this.#host);
|
|
28
|
+
this.#plugins = options.plugins ?? [];
|
|
29
|
+
if (hasRuntimeModel(options)) this.#llm = options.model;
|
|
30
|
+
else if (hasLanguageModel(options)) {
|
|
33
31
|
this.#baseTools = options.tools;
|
|
34
32
|
this.#modelOptions = {
|
|
35
33
|
instructions: options.instructions,
|
|
@@ -41,85 +39,65 @@ var Agent = class Agent {
|
|
|
41
39
|
send(input) {
|
|
42
40
|
return this.session("default").send(input);
|
|
43
41
|
}
|
|
42
|
+
async resume(runId) {
|
|
43
|
+
const host = executionHost(this.#host);
|
|
44
|
+
if (!host) throw new Error("Agent host does not support durable run resume.");
|
|
45
|
+
return await resumeAgentRun({
|
|
46
|
+
host,
|
|
47
|
+
ownerNamespace: this.#sessionNamespace,
|
|
48
|
+
resumeNotification: (notification) => this.#resumeNotification(notification),
|
|
49
|
+
runId
|
|
50
|
+
});
|
|
51
|
+
}
|
|
44
52
|
session(key) {
|
|
53
|
+
return this.#sessionEntry(key).publicHandle;
|
|
54
|
+
}
|
|
55
|
+
#sessionEntry(key) {
|
|
45
56
|
const existing = this.#sessions.get(key);
|
|
46
57
|
if (existing) return existing;
|
|
47
58
|
let session;
|
|
48
|
-
|
|
49
|
-
if (!session) throw new Error("Agent session is not initialized.");
|
|
50
|
-
return session;
|
|
51
|
-
};
|
|
52
|
-
const parentAgentNamespace = parentSessionNamespace({
|
|
53
|
-
generation: this.#sessionGenerations.get(key) ?? 0,
|
|
54
|
-
sessionKey: key,
|
|
55
|
-
sessionNamespace: this.#sessionNamespace
|
|
56
|
-
});
|
|
57
|
-
session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession(key, parentAgentNamespace, (input, placement) => getSession().enqueueRuntimeInput(input, placement), (event) => getSession().emitObserverEvent(event))), {
|
|
59
|
+
session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession()), {
|
|
58
60
|
key,
|
|
59
61
|
store: this.#store
|
|
60
|
-
}, this.#
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
62
|
+
}, this.#plugins, { executionHost: executionHost(this.#host) });
|
|
63
|
+
const entry = {
|
|
64
|
+
notify: (input, options) => session.notify(input, options),
|
|
65
|
+
publicHandle: {
|
|
66
|
+
delete: async () => {
|
|
67
|
+
session.kill();
|
|
68
|
+
this.#evictSessionHandle(key);
|
|
69
|
+
await session.delete();
|
|
70
|
+
},
|
|
71
|
+
dispose: () => {
|
|
72
|
+
session.kill();
|
|
73
|
+
this.#evictSessionHandle(key);
|
|
74
|
+
return Promise.resolve();
|
|
75
|
+
},
|
|
76
|
+
interrupt: () => session.interrupt(),
|
|
77
|
+
send: (input) => session.send(input),
|
|
78
|
+
steer: (input) => session.steer(input)
|
|
79
|
+
}
|
|
77
80
|
};
|
|
78
|
-
this.#sessions.set(key,
|
|
79
|
-
return
|
|
81
|
+
this.#sessions.set(key, entry);
|
|
82
|
+
return entry;
|
|
83
|
+
}
|
|
84
|
+
#evictSessionHandle(key) {
|
|
85
|
+
this.#sessions.delete(key);
|
|
86
|
+
}
|
|
87
|
+
#resumeNotification(notification) {
|
|
88
|
+
return this.#sessionEntry(notification.sessionKey).notify(notification.input, { observerEvents: notification.observerEvents });
|
|
80
89
|
}
|
|
81
|
-
#createLlmOptionsForSession(
|
|
90
|
+
#createLlmOptionsForSession() {
|
|
82
91
|
const modelOptions = this.#modelOptions;
|
|
83
92
|
if (!modelOptions) throw new Error("Agent: missing model options.");
|
|
84
|
-
const tools = this.#subagents.length === 0 ? this.#baseTools : {
|
|
85
|
-
...this.#baseTools,
|
|
86
|
-
...createSubagentTools({
|
|
87
|
-
parentAgentNamespace,
|
|
88
|
-
parentSession: {
|
|
89
|
-
emitObserverEvent,
|
|
90
|
-
enqueueRuntimeInput
|
|
91
|
-
},
|
|
92
|
-
parentSessionKey: key,
|
|
93
|
-
registerChildSession: (sessionKey, cleanup) => this.#childSessionCleanups.register(sessionKey, cleanup),
|
|
94
|
-
subagents: this.#subagents
|
|
95
|
-
})
|
|
96
|
-
};
|
|
97
93
|
return {
|
|
98
94
|
instructions: modelOptions.instructions,
|
|
99
95
|
model: modelOptions.model,
|
|
100
96
|
toolChoice: modelOptions.toolChoice,
|
|
101
|
-
tools
|
|
97
|
+
tools: this.#baseTools
|
|
102
98
|
};
|
|
103
99
|
}
|
|
104
|
-
async #deleteChildSessions(parentSessionKey) {
|
|
105
|
-
await this.#childSessionCleanups.delete(parentSessionKey);
|
|
106
|
-
}
|
|
107
100
|
};
|
|
108
|
-
function stableAgentNamespace(options) {
|
|
109
|
-
const namespace = options.sessions?.namespace ?? options.name;
|
|
110
|
-
return namespace ? agentNamespace(namespace) : randomAgentNamespace();
|
|
111
|
-
}
|
|
112
|
-
function assertAgentOptions(options) {
|
|
113
|
-
if (options === null || typeof options !== "object") throw new TypeError("Agent options are required. Provide either { model } or { llm }.");
|
|
114
|
-
const hasLlm = hasCustomLlm(options);
|
|
115
|
-
const hasModel = "model" in options && options.model != null;
|
|
116
|
-
if (hasLlm && hasModel) throw new TypeError("Agent: provide either options.llm or options.model.");
|
|
117
|
-
if ("llm" in options && options.llm !== void 0 && !hasLlm) throw new TypeError("Agent: invalid options.llm.");
|
|
118
|
-
if (!(hasLlm || hasModel)) throw new TypeError("Agent: missing options.model.");
|
|
119
|
-
}
|
|
120
|
-
function hasCustomLlm(options) {
|
|
121
|
-
return "llm" in options && typeof options.llm === "function";
|
|
122
|
-
}
|
|
123
101
|
//#endregion
|
|
124
102
|
export { Agent };
|
|
125
103
|
|
package/dist/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","names":["#baseTools","#hooks","#llm","#modelOptions","#childSessionCleanups","#sessionGenerations","#sessions","#sessionNamespace","#store","#subagents","#createLlmOptionsForSession","#deleteChildSessions"],"sources":["../src/agent.ts"],"sourcesContent":["import type { LanguageModel, ToolSet } from \"ai\";\nimport {\n agentNamespace,\n parentSessionNamespace,\n randomAgentNamespace,\n} from \"./agent-namespace\";\nimport { assertSubagents } from \"./agent-validation\";\nimport { ChildSessionCleanups } from \"./child-session-cleanups\";\nimport type { AgentHooks } from \"./hooks\";\nimport { type AgentToolChoice, createLlm, type Llm } from \"./llm\";\nimport type { UserInput } from \"./session/events\";\nimport type { AgentRun } from \"./session/run\";\nimport { type AgentInput, AgentSession } from \"./session/session\";\nimport { MemorySessionStore } from \"./session/store/memory\";\nimport type { SessionStore } from \"./session/store/types\";\nimport { createSubagentTools } from \"./subagents\";\n\ninterface AgentLanguageModelOptions {\n description?: string;\n hooks?: AgentHooks;\n instructions?: string;\n llm?: never;\n model: LanguageModel;\n name?: string;\n sessions?: AgentSessionOptions;\n subagents?: readonly Agent[];\n toolChoice?: AgentToolChoice;\n tools?: ToolSet;\n}\n\ninterface AgentLlmOptions {\n description?: string;\n hooks?: AgentHooks;\n instructions?: never;\n llm: Llm;\n model?: never;\n name?: string;\n sessions?: AgentSessionOptions;\n subagents?: never;\n toolChoice?: never;\n tools?: never;\n}\n\nexport interface AgentSessionOptions {\n namespace?: string;\n store?: SessionStore;\n}\n\nexport interface SessionHandle {\n delete(): Promise<void>;\n interrupt(): void;\n kill(): void;\n send(input: AgentInput): Promise<AgentRun>;\n steer(input: AgentInput): Promise<AgentRun>;\n}\n\nexport type AgentOptions = AgentLanguageModelOptions | AgentLlmOptions;\ntype AgentModelOptions = Pick<\n AgentLanguageModelOptions,\n \"instructions\" | \"model\" | \"toolChoice\"\n>;\n\nexport class Agent {\n readonly #baseTools?: ToolSet;\n readonly #hooks?: AgentHooks;\n readonly #llm?: Llm;\n readonly #modelOptions?: AgentModelOptions;\n readonly #childSessionCleanups = new ChildSessionCleanups();\n readonly #sessionGenerations = new Map<string, number>();\n readonly #sessions = new Map<string, SessionHandle>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\n readonly #subagents: readonly Agent[];\n readonly description?: string;\n readonly name?: string;\n\n constructor(options: AgentOptions) {\n assertAgentOptions(options);\n\n this.description = options.description;\n this.name = options.name;\n this.#sessionNamespace = stableAgentNamespace(options);\n this.#store = options.sessions?.store ?? new MemorySessionStore();\n this.#hooks = options.hooks;\n assertSubagents(options, Agent, hasCustomLlm(options));\n this.#subagents = hasCustomLlm(options) ? [] : (options.subagents ?? []);\n if (hasCustomLlm(options)) {\n this.#llm = options.llm;\n } else {\n this.#baseTools = options.tools;\n this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n };\n }\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n session(key: string): SessionHandle {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n let session: AgentSession | undefined;\n const getSession = () => {\n if (!session) {\n throw new Error(\"Agent session is not initialized.\");\n }\n return session;\n };\n const parentAgentNamespace = parentSessionNamespace({\n generation: this.#sessionGenerations.get(key) ?? 0,\n sessionKey: key,\n sessionNamespace: this.#sessionNamespace,\n });\n const llm =\n this.#llm ??\n createLlm(\n this.#createLlmOptionsForSession(\n key,\n parentAgentNamespace,\n (input: UserInput, placement?: \"turn-start\") =>\n getSession().enqueueRuntimeInput(input, placement),\n (event) => getSession().emitObserverEvent(event)\n )\n );\n session = new AgentSession(llm, { key, store: this.#store }, this.#hooks);\n const handle: SessionHandle = {\n delete: async () => {\n await session.delete();\n this.#sessions.delete(key);\n this.#sessionGenerations.set(\n key,\n (this.#sessionGenerations.get(key) ?? 0) + 1\n );\n await this.#deleteChildSessions(key);\n },\n interrupt: () => session.interrupt(),\n kill: () => {\n session.kill();\n this.#sessionGenerations.set(\n key,\n (this.#sessionGenerations.get(key) ?? 0) + 1\n );\n this.#deleteChildSessions(key).catch(() => undefined);\n this.#sessions.delete(key);\n },\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n this.#sessions.set(key, handle);\n return handle;\n }\n\n #createLlmOptionsForSession(\n key: string,\n parentAgentNamespace: string,\n enqueueRuntimeInput: AgentSession[\"enqueueRuntimeInput\"],\n emitObserverEvent: AgentSession[\"emitObserverEvent\"]\n ): Parameters<typeof createLlm>[0] {\n const modelOptions = this.#modelOptions;\n if (!modelOptions) {\n throw new Error(\"Agent: missing model options.\");\n }\n const tools =\n this.#subagents.length === 0\n ? this.#baseTools\n : {\n ...this.#baseTools,\n ...createSubagentTools({\n parentAgentNamespace,\n parentSession: { emitObserverEvent, enqueueRuntimeInput },\n parentSessionKey: key,\n registerChildSession: (sessionKey, cleanup) =>\n this.#childSessionCleanups.register(sessionKey, cleanup),\n subagents: this.#subagents,\n }),\n };\n\n return {\n instructions: modelOptions.instructions,\n model: modelOptions.model,\n toolChoice: modelOptions.toolChoice,\n tools,\n };\n }\n\n async #deleteChildSessions(parentSessionKey: string): Promise<void> {\n await this.#childSessionCleanups.delete(parentSessionKey);\n }\n}\n\nfunction stableAgentNamespace(options: AgentOptions): string {\n const namespace = options.sessions?.namespace ?? options.name;\n return namespace ? agentNamespace(namespace) : randomAgentNamespace();\n}\n\nfunction assertAgentOptions(options: unknown): asserts options is AgentOptions {\n if (options === null || typeof options !== \"object\") {\n throw new TypeError(\n \"Agent options are required. Provide either { model } or { llm }.\"\n );\n }\n\n const hasLlm = hasCustomLlm(options);\n const hasModel = \"model\" in options && options.model != null;\n\n if (hasLlm && hasModel) {\n throw new TypeError(\"Agent: provide either options.llm or options.model.\");\n }\n\n if (\"llm\" in options && options.llm !== undefined && !hasLlm) {\n throw new TypeError(\"Agent: invalid options.llm.\");\n }\n\n if (!(hasLlm || hasModel)) {\n throw new TypeError(\"Agent: missing options.model.\");\n }\n}\n\nfunction hasCustomLlm(options: object): options is AgentLlmOptions {\n return \"llm\" in options && typeof options.llm === \"function\";\n}\n"],"mappings":";;;;;;;;AA8DA,IAAa,QAAb,MAAa,MAAM;CACjB;CACA;CACA;CACA;CACA,wBAAiC,IAAI,qBAAqB;CAC1D,sCAA+B,IAAI,IAAoB;CACvD,4BAAqB,IAAI,IAA2B;CACpD;CACA;CACA;CACA;CACA;CAEA,YAAY,SAAuB;EACjC,mBAAmB,OAAO;EAE1B,KAAK,cAAc,QAAQ;EAC3B,KAAK,OAAO,QAAQ;EACpB,KAAKO,oBAAoB,qBAAqB,OAAO;EACrD,KAAKC,SAAS,QAAQ,UAAU,SAAS,IAAI,mBAAmB;EAChE,KAAKP,SAAS,QAAQ;EACtB,gBAAgB,SAAS,OAAO,aAAa,OAAO,CAAC;EACrD,KAAKQ,aAAa,aAAa,OAAO,IAAI,CAAC,IAAK,QAAQ,aAAa,CAAC;EACtE,IAAI,aAAa,OAAO,GACtB,KAAKP,OAAO,QAAQ;OACf;GACL,KAAKF,aAAa,QAAQ;GAC1B,KAAKG,gBAAgB;IACnB,cAAc,QAAQ;IACtB,OAAO,QAAQ;IACf,YAAY,QAAQ;GACtB;EACF;CACF;CAEA,KAAK,OAAsC;EACzC,OAAO,KAAK,QAAQ,SAAS,EAAE,KAAK,KAAK;CAC3C;CAEA,QAAQ,KAA4B;EAClC,MAAM,WAAW,KAAKG,UAAU,IAAI,GAAG;EACvC,IAAI,UACF,OAAO;EAGT,IAAI;EACJ,MAAM,mBAAmB;GACvB,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,mCAAmC;GAErD,OAAO;EACT;EACA,MAAM,uBAAuB,uBAAuB;GAClD,YAAY,KAAKD,oBAAoB,IAAI,GAAG,KAAK;GACjD,YAAY;GACZ,kBAAkB,KAAKE;EACzB,CAAC;EAYD,UAAU,IAAI,aAVZ,KAAKL,QACL,UACE,KAAKQ,4BACH,KACA,uBACC,OAAkB,cACjB,WAAW,EAAE,oBAAoB,OAAO,SAAS,IAClD,UAAU,WAAW,EAAE,kBAAkB,KAAK,CACjD,CACF,GAC8B;GAAE;GAAK,OAAO,KAAKF;EAAO,GAAG,KAAKP,MAAM;EACxE,MAAM,SAAwB;GAC5B,QAAQ,YAAY;IAClB,MAAM,QAAQ,OAAO;IACrB,KAAKK,UAAU,OAAO,GAAG;IACzB,KAAKD,oBAAoB,IACvB,MACC,KAAKA,oBAAoB,IAAI,GAAG,KAAK,KAAK,CAC7C;IACA,MAAM,KAAKM,qBAAqB,GAAG;GACrC;GACA,iBAAiB,QAAQ,UAAU;GACnC,YAAY;IACV,QAAQ,KAAK;IACb,KAAKN,oBAAoB,IACvB,MACC,KAAKA,oBAAoB,IAAI,GAAG,KAAK,KAAK,CAC7C;IACA,KAAKM,qBAAqB,GAAG,EAAE,YAAY,KAAA,CAAS;IACpD,KAAKL,UAAU,OAAO,GAAG;GAC3B;GACA,OAAO,UAAU,QAAQ,KAAK,KAAK;GACnC,QAAQ,UAAU,QAAQ,MAAM,KAAK;EACvC;EACA,KAAKA,UAAU,IAAI,KAAK,MAAM;EAC9B,OAAO;CACT;CAEA,4BACE,KACA,sBACA,qBACA,mBACiC;EACjC,MAAM,eAAe,KAAKH;EAC1B,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,+BAA+B;EAEjD,MAAM,QACJ,KAAKM,WAAW,WAAW,IACvB,KAAKT,aACL;GACE,GAAG,KAAKA;GACR,GAAG,oBAAoB;IACrB;IACA,eAAe;KAAE;KAAmB;IAAoB;IACxD,kBAAkB;IAClB,uBAAuB,YAAY,YACjC,KAAKI,sBAAsB,SAAS,YAAY,OAAO;IACzD,WAAW,KAAKK;GAClB,CAAC;EACH;EAEN,OAAO;GACL,cAAc,aAAa;GAC3B,OAAO,aAAa;GACpB,YAAY,aAAa;GACzB;EACF;CACF;CAEA,MAAME,qBAAqB,kBAAyC;EAClE,MAAM,KAAKP,sBAAsB,OAAO,gBAAgB;CAC1D;AACF;AAEA,SAAS,qBAAqB,SAA+B;CAC3D,MAAM,YAAY,QAAQ,UAAU,aAAa,QAAQ;CACzD,OAAO,YAAY,eAAe,SAAS,IAAI,qBAAqB;AACtE;AAEA,SAAS,mBAAmB,SAAmD;CAC7E,IAAI,YAAY,QAAQ,OAAO,YAAY,UACzC,MAAM,IAAI,UACR,kEACF;CAGF,MAAM,SAAS,aAAa,OAAO;CACnC,MAAM,WAAW,WAAW,WAAW,QAAQ,SAAS;CAExD,IAAI,UAAU,UACZ,MAAM,IAAI,UAAU,qDAAqD;CAG3E,IAAI,SAAS,WAAW,QAAQ,QAAQ,KAAA,KAAa,CAAC,QACpD,MAAM,IAAI,UAAU,6BAA6B;CAGnD,IAAI,EAAE,UAAU,WACd,MAAM,IAAI,UAAU,+BAA+B;AAEvD;AAEA,SAAS,aAAa,SAA6C;CACjE,OAAO,SAAS,WAAW,OAAO,QAAQ,QAAQ;AACpD"}
|
|
1
|
+
{"version":3,"file":"agent.js","names":["#baseTools","#llm","#modelOptions","#sessions","#sessionNamespace","#store","#host","#plugins","#resumeNotification","#sessionEntry","#createLlmOptionsForSession","#evictSessionHandle"],"sources":["../src/agent.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport { sessionStoreForHost } from \"./agent-host-session-store\";\nimport { stableAgentNamespace } from \"./agent-namespace\";\nimport {\n type AgentConstructionOptions,\n type AgentModelOptions,\n assertAgentOptions,\n hasLanguageModel,\n hasRuntimeModel,\n} from \"./agent-options\";\nimport { resumeAgentRun } from \"./agent-resume\";\nimport type { AgentSessionEntry, SessionHandle } from \"./agent-session-entry\";\nimport { executionHost } from \"./execution/host\";\nimport { createInMemoryExecutionHost } from \"./execution/memory\";\nimport type { AgentHost, NotificationRecord } from \"./execution/types\";\nimport { createLlm, type RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\nimport type { AgentRun } from \"./session/run\";\nimport { type AgentInput, AgentSession } from \"./session/session\";\nimport type { SessionStore } from \"./session/store/types\";\n\nexport type { AgentOptions } from \"./agent-options\";\nexport type { SessionHandle } from \"./agent-session-entry\";\nexport type { AgentHost } from \"./execution/types\";\n\nexport class Agent {\n readonly #baseTools?: ToolSet;\n readonly #llm?: RuntimeLlm;\n readonly #modelOptions?: AgentModelOptions;\n readonly #sessions = new Map<string, AgentSessionEntry>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\n readonly #host: AgentHost;\n readonly #plugins: readonly AgentPlugin[];\n readonly host: AgentHost;\n readonly namespace?: string;\n constructor(options: AgentConstructionOptions) {\n assertAgentOptions(options);\n\n this.namespace = options.namespace;\n this.#sessionNamespace = stableAgentNamespace({\n namespace: options.namespace,\n });\n this.#host = options.host ?? createInMemoryExecutionHost();\n this.host = this.#host;\n this.#store = sessionStoreForHost(this.#host);\n this.#plugins = options.plugins ?? [];\n if (hasRuntimeModel(options)) {\n this.#llm = options.model;\n } else if (hasLanguageModel(options)) {\n this.#baseTools = options.tools;\n this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n };\n }\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n async resume(runId: string): Promise<AgentRun | null> {\n const host = executionHost(this.#host);\n if (!host) {\n throw new Error(\"Agent host does not support durable run resume.\");\n }\n\n return await resumeAgentRun({\n host,\n ownerNamespace: this.#sessionNamespace,\n resumeNotification: (notification) =>\n this.#resumeNotification(notification),\n runId,\n });\n }\n\n session(key: string): SessionHandle {\n return this.#sessionEntry(key).publicHandle;\n }\n\n #sessionEntry(key: string): AgentSessionEntry {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n let session: AgentSession | undefined;\n const llm = this.#llm ?? createLlm(this.#createLlmOptionsForSession());\n session = new AgentSession(\n llm,\n { key, store: this.#store },\n this.#plugins,\n {\n executionHost: executionHost(this.#host),\n }\n );\n const publicHandle: SessionHandle = {\n delete: async () => {\n session.kill();\n this.#evictSessionHandle(key);\n await session.delete();\n },\n dispose: () => {\n session.kill();\n this.#evictSessionHandle(key);\n return Promise.resolve();\n },\n interrupt: () => session.interrupt(),\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n const entry: AgentSessionEntry = {\n notify: (input, options) => session.notify(input, options),\n publicHandle,\n };\n this.#sessions.set(key, entry);\n return entry;\n }\n\n #evictSessionHandle(key: string): void {\n this.#sessions.delete(key);\n }\n\n #resumeNotification(notification: NotificationRecord): Promise<AgentRun> {\n return this.#sessionEntry(notification.sessionKey).notify(\n notification.input,\n { observerEvents: notification.observerEvents }\n );\n }\n\n #createLlmOptionsForSession(): Parameters<typeof createLlm>[0] {\n const modelOptions = this.#modelOptions;\n if (!modelOptions) {\n throw new Error(\"Agent: missing model options.\");\n }\n\n return {\n instructions: modelOptions.instructions,\n model: modelOptions.model,\n toolChoice: modelOptions.toolChoice,\n tools: this.#baseTools,\n };\n }\n}\n"],"mappings":";;;;;;;;;AAyBA,IAAa,QAAb,MAAmB;CACjB;CACA;CACA;CACA,4BAAqB,IAAI,IAA+B;CACxD;CACA;CACA;CACA;CACA;CACA;CACA,YAAY,SAAmC;EAC7C,mBAAmB,OAAO;EAE1B,KAAK,YAAY,QAAQ;EACzB,KAAKI,oBAAoB,qBAAqB,EAC5C,WAAW,QAAQ,UACrB,CAAC;EACD,KAAKE,QAAQ,QAAQ,QAAQ,4BAA4B;EACzD,KAAK,OAAO,KAAKA;EACjB,KAAKD,SAAS,oBAAoB,KAAKC,KAAK;EAC5C,KAAKC,WAAW,QAAQ,WAAW,CAAC;EACpC,IAAI,gBAAgB,OAAO,GACzB,KAAKN,OAAO,QAAQ;OACf,IAAI,iBAAiB,OAAO,GAAG;GACpC,KAAKD,aAAa,QAAQ;GAC1B,KAAKE,gBAAgB;IACnB,cAAc,QAAQ;IACtB,OAAO,QAAQ;IACf,YAAY,QAAQ;GACtB;EACF;CACF;CAEA,KAAK,OAAsC;EACzC,OAAO,KAAK,QAAQ,SAAS,EAAE,KAAK,KAAK;CAC3C;CAEA,MAAM,OAAO,OAAyC;EACpD,MAAM,OAAO,cAAc,KAAKI,KAAK;EACrC,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,iDAAiD;EAGnE,OAAO,MAAM,eAAe;GAC1B;GACA,gBAAgB,KAAKF;GACrB,qBAAqB,iBACnB,KAAKI,oBAAoB,YAAY;GACvC;EACF,CAAC;CACH;CAEA,QAAQ,KAA4B;EAClC,OAAO,KAAKC,cAAc,GAAG,EAAE;CACjC;CAEA,cAAc,KAAgC;EAC5C,MAAM,WAAW,KAAKN,UAAU,IAAI,GAAG;EACvC,IAAI,UACF,OAAO;EAGT,IAAI;EAEJ,UAAU,IAAI,aADF,KAAKF,QAAQ,UAAU,KAAKS,4BAA4B,CAAC,GAGnE;GAAE;GAAK,OAAO,KAAKL;EAAO,GAC1B,KAAKE,UACL,EACE,eAAe,cAAc,KAAKD,KAAK,EACzC,CACF;EAgBA,MAAM,QAA2B;GAC/B,SAAS,OAAO,YAAY,QAAQ,OAAO,OAAO,OAAO;GACzD,cAAA;IAhBA,QAAQ,YAAY;KAClB,QAAQ,KAAK;KACb,KAAKK,oBAAoB,GAAG;KAC5B,MAAM,QAAQ,OAAO;IACvB;IACA,eAAe;KACb,QAAQ,KAAK;KACb,KAAKA,oBAAoB,GAAG;KAC5B,OAAO,QAAQ,QAAQ;IACzB;IACA,iBAAiB,QAAQ,UAAU;IACnC,OAAO,UAAU,QAAQ,KAAK,KAAK;IACnC,QAAQ,UAAU,QAAQ,MAAM,KAAK;GAI1B;EACb;EACA,KAAKR,UAAU,IAAI,KAAK,KAAK;EAC7B,OAAO;CACT;CAEA,oBAAoB,KAAmB;EACrC,KAAKA,UAAU,OAAO,GAAG;CAC3B;CAEA,oBAAoB,cAAqD;EACvE,OAAO,KAAKM,cAAc,aAAa,UAAU,EAAE,OACjD,aAAa,OACb,EAAE,gBAAgB,aAAa,eAAe,CAChD;CACF;CAEA,8BAA+D;EAC7D,MAAM,eAAe,KAAKP;EAC1B,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,+BAA+B;EAGjD,OAAO;GACL,cAAc,aAAa;GAC3B,OAAO,aAAa;GACpB,YAAY,aAAa;GACzB,OAAO,KAAKF;EACd;CACF;AACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ExecutionHost } from "../execution/types.js";
|
|
2
|
+
import { CloudflareAlarmDrainBudget } from "./cloudflare-alarm-budget.js";
|
|
3
|
+
import { CloudflareDurableObjectStorage } from "./cloudflare-host.js";
|
|
4
|
+
import { CloudflareAlarmAgent, CloudflareAlarmDrainSummary } from "./cloudflare-alarm-drainer.js";
|
|
5
|
+
|
|
6
|
+
//#region src/cloudflare/cloudflare-agent-context.d.ts
|
|
7
|
+
type MaybePromise<T> = Promise<T> | T;
|
|
8
|
+
interface CloudflareAgentContextFactoryOptions<Env> {
|
|
9
|
+
readonly env: Env;
|
|
10
|
+
readonly host: ExecutionHost;
|
|
11
|
+
readonly prefix: string;
|
|
12
|
+
readonly storage: CloudflareDurableObjectStorage;
|
|
13
|
+
}
|
|
14
|
+
interface CloudflareAgentContextPrefixOptions<Env> {
|
|
15
|
+
readonly env: Env;
|
|
16
|
+
readonly storage: CloudflareDurableObjectStorage;
|
|
17
|
+
}
|
|
18
|
+
interface CloudflareAgentContextOptions<Env, Agent extends CloudflareAlarmAgent> {
|
|
19
|
+
readonly createAgent: (options: CloudflareAgentContextFactoryOptions<Env>) => Agent;
|
|
20
|
+
readonly defaultPrefix?: string;
|
|
21
|
+
readonly env: Env;
|
|
22
|
+
readonly readPrefix?: (options: CloudflareAgentContextPrefixOptions<Env>) => MaybePromise<string | undefined>;
|
|
23
|
+
readonly storage: CloudflareDurableObjectStorage;
|
|
24
|
+
}
|
|
25
|
+
interface CloudflareAgentContext<Agent extends CloudflareAlarmAgent> {
|
|
26
|
+
agent(prefix?: string): Agent;
|
|
27
|
+
drainAlarm(budget?: CloudflareAlarmDrainBudget): Promise<CloudflareAlarmDrainSummary>;
|
|
28
|
+
host(prefix?: string): ExecutionHost;
|
|
29
|
+
readonly storage: CloudflareDurableObjectStorage;
|
|
30
|
+
}
|
|
31
|
+
declare function createCloudflareAgentContext<Env, Agent extends CloudflareAlarmAgent>({
|
|
32
|
+
createAgent,
|
|
33
|
+
defaultPrefix,
|
|
34
|
+
env,
|
|
35
|
+
readPrefix,
|
|
36
|
+
storage
|
|
37
|
+
}: CloudflareAgentContextOptions<Env, Agent>): CloudflareAgentContext<Agent>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { CloudflareAgentContext, CloudflareAgentContextFactoryOptions, CloudflareAgentContextOptions, CloudflareAgentContextPrefixOptions, createCloudflareAgentContext };
|
|
40
|
+
//# sourceMappingURL=cloudflare-agent-context.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createCloudflareDurableObjectHost } from "./cloudflare-host.js";
|
|
2
|
+
import { drainCloudflareAlarm } from "./cloudflare-alarm-drainer.js";
|
|
3
|
+
//#region src/cloudflare/cloudflare-agent-context.ts
|
|
4
|
+
const defaultContextPrefix = "pss-runtime";
|
|
5
|
+
function createCloudflareAgentContext({ createAgent, defaultPrefix = defaultContextPrefix, env, readPrefix, storage }) {
|
|
6
|
+
const createHost = (prefix = defaultPrefix) => createCloudflareDurableObjectHost({
|
|
7
|
+
prefix,
|
|
8
|
+
storage
|
|
9
|
+
});
|
|
10
|
+
const createContextAgent = (prefix = defaultPrefix) => createAgent({
|
|
11
|
+
env,
|
|
12
|
+
host: createHost(prefix),
|
|
13
|
+
prefix,
|
|
14
|
+
storage
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
agent: createContextAgent,
|
|
18
|
+
drainAlarm: async (budget) => {
|
|
19
|
+
const prefix = await readPrefix?.({
|
|
20
|
+
env,
|
|
21
|
+
storage
|
|
22
|
+
}) ?? defaultPrefix;
|
|
23
|
+
return await drainCloudflareAlarm({
|
|
24
|
+
agent: createContextAgent(prefix),
|
|
25
|
+
...budget,
|
|
26
|
+
prefix,
|
|
27
|
+
storage
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
host: createHost,
|
|
31
|
+
storage
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { createCloudflareAgentContext };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=cloudflare-agent-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare-agent-context.js","names":[],"sources":["../../src/cloudflare/cloudflare-agent-context.ts"],"sourcesContent":["import type { ExecutionHost } from \"../execution\";\nimport type { CloudflareAlarmDrainBudget } from \"./cloudflare-alarm-budget\";\nimport type {\n CloudflareAlarmAgent,\n CloudflareAlarmDrainSummary,\n} from \"./cloudflare-alarm-drainer\";\nimport { drainCloudflareAlarm } from \"./cloudflare-alarm-drainer\";\nimport {\n type CloudflareDurableObjectStorage,\n createCloudflareDurableObjectHost,\n} from \"./cloudflare-host\";\n\nconst defaultContextPrefix = \"pss-runtime\";\n\ntype MaybePromise<T> = Promise<T> | T;\n\nexport interface CloudflareAgentContextFactoryOptions<Env> {\n readonly env: Env;\n readonly host: ExecutionHost;\n readonly prefix: string;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport interface CloudflareAgentContextPrefixOptions<Env> {\n readonly env: Env;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport interface CloudflareAgentContextOptions<\n Env,\n Agent extends CloudflareAlarmAgent,\n> {\n readonly createAgent: (\n options: CloudflareAgentContextFactoryOptions<Env>\n ) => Agent;\n readonly defaultPrefix?: string;\n readonly env: Env;\n readonly readPrefix?: (\n options: CloudflareAgentContextPrefixOptions<Env>\n ) => MaybePromise<string | undefined>;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport interface CloudflareAgentContext<Agent extends CloudflareAlarmAgent> {\n agent(prefix?: string): Agent;\n drainAlarm(\n budget?: CloudflareAlarmDrainBudget\n ): Promise<CloudflareAlarmDrainSummary>;\n host(prefix?: string): ExecutionHost;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport function createCloudflareAgentContext<\n Env,\n Agent extends CloudflareAlarmAgent,\n>({\n createAgent,\n defaultPrefix = defaultContextPrefix,\n env,\n readPrefix,\n storage,\n}: CloudflareAgentContextOptions<Env, Agent>): CloudflareAgentContext<Agent> {\n const createHost = (prefix = defaultPrefix) =>\n createCloudflareDurableObjectHost({ prefix, storage });\n const createContextAgent = (prefix = defaultPrefix) =>\n createAgent({\n env,\n host: createHost(prefix),\n prefix,\n storage,\n });\n\n return {\n agent: createContextAgent,\n drainAlarm: async (budget) => {\n const prefix = (await readPrefix?.({ env, storage })) ?? defaultPrefix;\n return await drainCloudflareAlarm({\n agent: createContextAgent(prefix),\n ...budget,\n prefix,\n storage,\n });\n },\n host: createHost,\n storage,\n };\n}\n"],"mappings":";;;AAYA,MAAM,uBAAuB;AAwC7B,SAAgB,6BAGd,EACA,aACA,gBAAgB,sBAChB,KACA,YACA,WAC2E;CAC3E,MAAM,cAAc,SAAS,kBAC3B,kCAAkC;EAAE;EAAQ;CAAQ,CAAC;CACvD,MAAM,sBAAsB,SAAS,kBACnC,YAAY;EACV;EACA,MAAM,WAAW,MAAM;EACvB;EACA;CACF,CAAC;CAEH,OAAO;EACL,OAAO;EACP,YAAY,OAAO,WAAW;GAC5B,MAAM,SAAU,MAAM,aAAa;IAAE;IAAK;GAAQ,CAAC,KAAM;GACzD,OAAO,MAAM,qBAAqB;IAChC,OAAO,mBAAmB,MAAM;IAChC,GAAG;IACH;IACA;GACF,CAAC;EACH;EACA,MAAM;EACN;CACF;AACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/cloudflare/cloudflare-alarm-budget.d.ts
|
|
2
|
+
type CloudflareAlarmContinuationReason = "deadline" | "event-budget" | "failure" | "run-budget" | "session-prompt-budget";
|
|
3
|
+
interface CloudflareAlarmDrainBudget {
|
|
4
|
+
readonly continuationRunAfterMs?: number;
|
|
5
|
+
readonly deadlineMs?: number;
|
|
6
|
+
readonly failureRunAfterMs?: number;
|
|
7
|
+
readonly maxEvents?: number;
|
|
8
|
+
readonly maxRuns?: number;
|
|
9
|
+
readonly maxSessionPrompts?: number;
|
|
10
|
+
readonly throwOnFailure?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface FailedScheduledWork {
|
|
13
|
+
readonly error: string;
|
|
14
|
+
readonly id: string;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { CloudflareAlarmContinuationReason, CloudflareAlarmDrainBudget, FailedScheduledWork };
|
|
18
|
+
//# sourceMappingURL=cloudflare-alarm-budget.d.ts.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/cloudflare/cloudflare-alarm-budget.ts
|
|
2
|
+
const defaultAlarmDrainBudget = {
|
|
3
|
+
continuationRunAfterMs: 0,
|
|
4
|
+
deadlineMs: 3e4,
|
|
5
|
+
failureRunAfterMs: 1e3,
|
|
6
|
+
maxEvents: 1e3,
|
|
7
|
+
maxRuns: 25,
|
|
8
|
+
maxSessionPrompts: 25,
|
|
9
|
+
throwOnFailure: false
|
|
10
|
+
};
|
|
11
|
+
function createAlarmDrainState() {
|
|
12
|
+
return {
|
|
13
|
+
consumedSessionPrompts: [],
|
|
14
|
+
droppedEvents: 0,
|
|
15
|
+
events: [],
|
|
16
|
+
failedRuns: [],
|
|
17
|
+
failedSessionPrompts: [],
|
|
18
|
+
reasons: /* @__PURE__ */ new Set(),
|
|
19
|
+
resumedRuns: [],
|
|
20
|
+
runAttempts: 0,
|
|
21
|
+
sessionPromptAttempts: 0
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function normalizeAlarmDrainBudget(budget = {}) {
|
|
25
|
+
return {
|
|
26
|
+
continuationRunAfterMs: nonNegativeInteger(budget.continuationRunAfterMs ?? defaultAlarmDrainBudget.continuationRunAfterMs),
|
|
27
|
+
deadlineMs: nonNegativeInteger(budget.deadlineMs ?? defaultAlarmDrainBudget.deadlineMs),
|
|
28
|
+
failureRunAfterMs: nonNegativeInteger(budget.failureRunAfterMs ?? defaultAlarmDrainBudget.failureRunAfterMs),
|
|
29
|
+
maxEvents: nonNegativeInteger(budget.maxEvents ?? defaultAlarmDrainBudget.maxEvents),
|
|
30
|
+
maxRuns: nonNegativeInteger(budget.maxRuns ?? defaultAlarmDrainBudget.maxRuns),
|
|
31
|
+
maxSessionPrompts: nonNegativeInteger(budget.maxSessionPrompts ?? defaultAlarmDrainBudget.maxSessionPrompts),
|
|
32
|
+
startedAt: Date.now(),
|
|
33
|
+
throwOnFailure: budget.throwOnFailure ?? defaultAlarmDrainBudget.throwOnFailure
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function eventSlotsRemaining(state, budget) {
|
|
37
|
+
return Math.max(0, budget.maxEvents - state.events.length);
|
|
38
|
+
}
|
|
39
|
+
function shouldStopForDeadline(budget) {
|
|
40
|
+
return Date.now() - budget.startedAt >= budget.deadlineMs;
|
|
41
|
+
}
|
|
42
|
+
function shouldStopRuns(state, budget) {
|
|
43
|
+
if (shouldStopForDeadline(budget)) {
|
|
44
|
+
state.reasons.add("deadline");
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (shouldStopForEventBudget(state, budget)) return true;
|
|
48
|
+
if (state.runAttempts >= budget.maxRuns) {
|
|
49
|
+
state.reasons.add("run-budget");
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
function shouldStopSessionPrompts(state, budget) {
|
|
55
|
+
if (shouldStopForDeadline(budget)) {
|
|
56
|
+
state.reasons.add("deadline");
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
if (shouldStopForEventBudget(state, budget)) return true;
|
|
60
|
+
if (state.sessionPromptAttempts >= budget.maxSessionPrompts) {
|
|
61
|
+
state.reasons.add("session-prompt-budget");
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
function shouldStopForEventBudget(state, budget) {
|
|
67
|
+
if (state.events.length < budget.maxEvents) return false;
|
|
68
|
+
state.reasons.add("event-budget");
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
function nonNegativeInteger(value) {
|
|
72
|
+
return Math.max(0, Math.floor(value));
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { createAlarmDrainState, eventSlotsRemaining, normalizeAlarmDrainBudget, shouldStopRuns, shouldStopSessionPrompts };
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=cloudflare-alarm-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare-alarm-budget.js","names":[],"sources":["../../src/cloudflare/cloudflare-alarm-budget.ts"],"sourcesContent":["import type { AgentEvent } from \"../index\";\n\nexport type CloudflareAlarmContinuationReason =\n | \"deadline\"\n | \"event-budget\"\n | \"failure\"\n | \"run-budget\"\n | \"session-prompt-budget\";\n\nexport interface CloudflareAlarmDrainBudget {\n readonly continuationRunAfterMs?: number;\n readonly deadlineMs?: number;\n readonly failureRunAfterMs?: number;\n readonly maxEvents?: number;\n readonly maxRuns?: number;\n readonly maxSessionPrompts?: number;\n readonly throwOnFailure?: boolean;\n}\n\nexport interface FailedScheduledWork {\n readonly error: string;\n readonly id: string;\n}\n\nexport interface AlarmDrainState {\n readonly consumedSessionPrompts: string[];\n droppedEvents: number;\n readonly events: AgentEvent[];\n readonly failedRuns: FailedScheduledWork[];\n readonly failedSessionPrompts: FailedScheduledWork[];\n readonly reasons: Set<CloudflareAlarmContinuationReason>;\n readonly resumedRuns: string[];\n runAttempts: number;\n sessionPromptAttempts: number;\n}\n\nexport interface NormalizedAlarmDrainBudget {\n readonly continuationRunAfterMs: number;\n readonly deadlineMs: number;\n readonly failureRunAfterMs: number;\n readonly maxEvents: number;\n readonly maxRuns: number;\n readonly maxSessionPrompts: number;\n readonly startedAt: number;\n readonly throwOnFailure: boolean;\n}\n\nconst defaultAlarmDrainBudget = {\n continuationRunAfterMs: 0,\n deadlineMs: 30_000,\n failureRunAfterMs: 1000,\n maxEvents: 1000,\n maxRuns: 25,\n maxSessionPrompts: 25,\n throwOnFailure: false,\n} satisfies Required<CloudflareAlarmDrainBudget>;\n\nexport function createAlarmDrainState(): AlarmDrainState {\n return {\n consumedSessionPrompts: [],\n droppedEvents: 0,\n events: [],\n failedRuns: [],\n failedSessionPrompts: [],\n reasons: new Set<CloudflareAlarmContinuationReason>(),\n resumedRuns: [],\n runAttempts: 0,\n sessionPromptAttempts: 0,\n };\n}\n\nexport function normalizeAlarmDrainBudget(\n budget: CloudflareAlarmDrainBudget = {}\n): NormalizedAlarmDrainBudget {\n return {\n continuationRunAfterMs: nonNegativeInteger(\n budget.continuationRunAfterMs ??\n defaultAlarmDrainBudget.continuationRunAfterMs\n ),\n deadlineMs: nonNegativeInteger(\n budget.deadlineMs ?? defaultAlarmDrainBudget.deadlineMs\n ),\n failureRunAfterMs: nonNegativeInteger(\n budget.failureRunAfterMs ?? defaultAlarmDrainBudget.failureRunAfterMs\n ),\n maxEvents: nonNegativeInteger(\n budget.maxEvents ?? defaultAlarmDrainBudget.maxEvents\n ),\n maxRuns: nonNegativeInteger(\n budget.maxRuns ?? defaultAlarmDrainBudget.maxRuns\n ),\n maxSessionPrompts: nonNegativeInteger(\n budget.maxSessionPrompts ?? defaultAlarmDrainBudget.maxSessionPrompts\n ),\n startedAt: Date.now(),\n throwOnFailure:\n budget.throwOnFailure ?? defaultAlarmDrainBudget.throwOnFailure,\n };\n}\n\nexport function eventSlotsRemaining(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): number {\n return Math.max(0, budget.maxEvents - state.events.length);\n}\n\nexport function shouldStopForDeadline(\n budget: NormalizedAlarmDrainBudget\n): boolean {\n return Date.now() - budget.startedAt >= budget.deadlineMs;\n}\n\nexport function shouldStopRuns(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): boolean {\n if (shouldStopForDeadline(budget)) {\n state.reasons.add(\"deadline\");\n return true;\n }\n if (shouldStopForEventBudget(state, budget)) {\n return true;\n }\n if (state.runAttempts >= budget.maxRuns) {\n state.reasons.add(\"run-budget\");\n return true;\n }\n return false;\n}\n\nexport function shouldStopSessionPrompts(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): boolean {\n if (shouldStopForDeadline(budget)) {\n state.reasons.add(\"deadline\");\n return true;\n }\n if (shouldStopForEventBudget(state, budget)) {\n return true;\n }\n if (state.sessionPromptAttempts >= budget.maxSessionPrompts) {\n state.reasons.add(\"session-prompt-budget\");\n return true;\n }\n return false;\n}\n\nfunction shouldStopForEventBudget(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): boolean {\n if (state.events.length < budget.maxEvents) {\n return false;\n }\n state.reasons.add(\"event-budget\");\n return true;\n}\n\nfunction nonNegativeInteger(value: number): number {\n return Math.max(0, Math.floor(value));\n}\n"],"mappings":";AA+CA,MAAM,0BAA0B;CAC9B,wBAAwB;CACxB,YAAY;CACZ,mBAAmB;CACnB,WAAW;CACX,SAAS;CACT,mBAAmB;CACnB,gBAAgB;AAClB;AAEA,SAAgB,wBAAyC;CACvD,OAAO;EACL,wBAAwB,CAAC;EACzB,eAAe;EACf,QAAQ,CAAC;EACT,YAAY,CAAC;EACb,sBAAsB,CAAC;EACvB,yBAAS,IAAI,IAAuC;EACpD,aAAa,CAAC;EACd,aAAa;EACb,uBAAuB;CACzB;AACF;AAEA,SAAgB,0BACd,SAAqC,CAAC,GACV;CAC5B,OAAO;EACL,wBAAwB,mBACtB,OAAO,0BACL,wBAAwB,sBAC5B;EACA,YAAY,mBACV,OAAO,cAAc,wBAAwB,UAC/C;EACA,mBAAmB,mBACjB,OAAO,qBAAqB,wBAAwB,iBACtD;EACA,WAAW,mBACT,OAAO,aAAa,wBAAwB,SAC9C;EACA,SAAS,mBACP,OAAO,WAAW,wBAAwB,OAC5C;EACA,mBAAmB,mBACjB,OAAO,qBAAqB,wBAAwB,iBACtD;EACA,WAAW,KAAK,IAAI;EACpB,gBACE,OAAO,kBAAkB,wBAAwB;CACrD;AACF;AAEA,SAAgB,oBACd,OACA,QACQ;CACR,OAAO,KAAK,IAAI,GAAG,OAAO,YAAY,MAAM,OAAO,MAAM;AAC3D;AAEA,SAAgB,sBACd,QACS;CACT,OAAO,KAAK,IAAI,IAAI,OAAO,aAAa,OAAO;AACjD;AAEA,SAAgB,eACd,OACA,QACS;CACT,IAAI,sBAAsB,MAAM,GAAG;EACjC,MAAM,QAAQ,IAAI,UAAU;EAC5B,OAAO;CACT;CACA,IAAI,yBAAyB,OAAO,MAAM,GACxC,OAAO;CAET,IAAI,MAAM,eAAe,OAAO,SAAS;EACvC,MAAM,QAAQ,IAAI,YAAY;EAC9B,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAgB,yBACd,OACA,QACS;CACT,IAAI,sBAAsB,MAAM,GAAG;EACjC,MAAM,QAAQ,IAAI,UAAU;EAC5B,OAAO;CACT;CACA,IAAI,yBAAyB,OAAO,MAAM,GACxC,OAAO;CAET,IAAI,MAAM,yBAAyB,OAAO,mBAAmB;EAC3D,MAAM,QAAQ,IAAI,uBAAuB;EACzC,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAS,yBACP,OACA,QACS;CACT,IAAI,MAAM,OAAO,SAAS,OAAO,WAC/B,OAAO;CAET,MAAM,QAAQ,IAAI,cAAc;CAChC,OAAO;AACT;AAEA,SAAS,mBAAmB,OAAuB;CACjD,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACtC"}
|