@minpeter/pss-runtime 0.1.0-next.2 → 0.1.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +172 -85
- package/dist/agent-host-session-store.js +2 -4
- package/dist/agent-host-session-store.js.map +1 -1
- package/dist/agent-loop.js +9 -8
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent-namespace.js +3 -7
- package/dist/agent-namespace.js.map +1 -1
- package/dist/agent-options.d.ts +4 -19
- package/dist/agent-options.js +2 -8
- package/dist/agent-options.js.map +1 -1
- package/dist/agent-resume.js +2 -82
- package/dist/agent-resume.js.map +1 -1
- package/dist/agent-session-entry.d.ts +1 -1
- package/dist/agent.d.ts +4 -4
- package/dist/agent.js +19 -89
- 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 +49 -1
- package/dist/execution/host.js.map +1 -1
- package/dist/execution/index.d.ts +3 -1
- package/dist/execution/index.js +2 -1
- package/dist/execution/memory.js +1 -1
- package/dist/execution/memory.js.map +1 -1
- package/dist/execution/types.d.ts +5 -10
- package/dist/index.d.ts +9 -5
- package/dist/index.js +6 -2
- package/dist/llm-tool-execution.js.map +1 -1
- package/dist/llm.d.ts +1 -21
- package/dist/llm.js +12 -14
- package/dist/llm.js.map +1 -1
- package/dist/plugins.d.ts +27 -5
- package/dist/plugins.js +35 -6
- package/dist/plugins.js.map +1 -1
- 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 -25
- 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 +5 -1
- package/dist/session/runtime-input.js.map +1 -1
- package/dist/session/session-events.js +20 -6
- package/dist/session/session-events.js.map +1 -1
- package/dist/session/session-notification.js +3 -2
- package/dist/session/session-notification.js.map +1 -1
- 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 +10 -20
- package/dist/session/session-turn-processor.js.map +1 -1
- package/dist/session/session.js +15 -8
- package/dist/session/session.js.map +1 -1
- package/package.json +6 -1
- package/dist/agent-child-runs.js +0 -16
- package/dist/agent-child-runs.js.map +0 -1
- package/dist/agent-host-capabilities.js +0 -9
- package/dist/agent-host-capabilities.js.map +0 -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/execution/run.js +0 -55
- package/dist/execution/run.js.map +0 -1
- package/dist/subagent-background-child-run-state.js +0 -51
- package/dist/subagent-background-child-run-state.js.map +0 -1
- package/dist/subagent-background-child-run.js +0 -103
- package/dist/subagent-background-child-run.js.map +0 -1
- package/dist/subagent-background-in-process.js +0 -98
- package/dist/subagent-background-in-process.js.map +0 -1
- package/dist/subagent-background-notification-inbox.js +0 -106
- package/dist/subagent-background-notification-inbox.js.map +0 -1
- package/dist/subagent-background-notify.js +0 -136
- package/dist/subagent-background-notify.js.map +0 -1
- package/dist/subagent-background-resume-group.js +0 -99
- package/dist/subagent-background-resume-group.js.map +0 -1
- package/dist/subagent-background-runner.js +0 -115
- package/dist/subagent-background-runner.js.map +0 -1
- package/dist/subagent-background-schedule.js +0 -43
- package/dist/subagent-background-schedule.js.map +0 -1
- package/dist/subagent-child-run.js +0 -68
- package/dist/subagent-child-run.js.map +0 -1
- package/dist/subagent-job-cancel.js +0 -84
- package/dist/subagent-job-cancel.js.map +0 -1
- package/dist/subagent-job-observer.js +0 -19
- package/dist/subagent-job-observer.js.map +0 -1
- package/dist/subagent-job-output.js +0 -87
- package/dist/subagent-job-output.js.map +0 -1
- package/dist/subagent-job-state.js +0 -66
- package/dist/subagent-job-state.js.map +0 -1
- package/dist/subagent-jobs.js +0 -96
- 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 -125
- package/dist/subagents.js.map +0 -1
package/dist/agent-resume.js
CHANGED
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
import { readDurableBackgroundChildRunState } from "./subagent-background-child-run-state.js";
|
|
2
1
|
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
2
|
//#region src/agent-resume.ts
|
|
8
|
-
|
|
9
|
-
async function resumeAgentRun({ host, ownerNamespace, resumeNotification, runId, subagents }) {
|
|
3
|
+
async function resumeAgentRun({ host, ownerNamespace, resumeNotification, runId }) {
|
|
10
4
|
const run = await host.store.runs.get(runId);
|
|
11
5
|
if (!run) return null;
|
|
12
6
|
if (!canAccessRun(run, ownerNamespace)) return null;
|
|
13
|
-
if (run.kind === "background-subagent") return await resumeBackgroundSubagentRun({
|
|
14
|
-
host,
|
|
15
|
-
run,
|
|
16
|
-
subagents
|
|
17
|
-
});
|
|
18
7
|
if (run.kind === "notification" && run.dedupeKey) {
|
|
19
8
|
const idempotencyKey = run.dedupeKey;
|
|
20
9
|
const claimed = await claimRun(host, run);
|
|
@@ -59,84 +48,15 @@ async function completeNotificationRun(host, runId) {
|
|
|
59
48
|
status: "completed"
|
|
60
49
|
});
|
|
61
50
|
}
|
|
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
51
|
async function claimRun(host, run) {
|
|
114
52
|
const claim = await host.store.runs.claim(run.runId, {
|
|
115
53
|
attempt: (run.lease?.attempt ?? 0) + 1,
|
|
116
54
|
leaseId: crypto.randomUUID(),
|
|
117
|
-
leaseMs:
|
|
55
|
+
leaseMs: 3e5,
|
|
118
56
|
nowMs: Date.now()
|
|
119
57
|
});
|
|
120
58
|
return claim.ok ? claim.record : null;
|
|
121
59
|
}
|
|
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
60
|
//#endregion
|
|
141
61
|
export { resumeAgentRun };
|
|
142
62
|
|
package/dist/agent-resume.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-resume.js","names":[],"sources":["../src/agent-resume.ts"],"sourcesContent":["import { ownsAgentNamespace } from \"./agent-namespace\";\nimport
|
|
1
|
+
{"version":3,"file":"agent-resume.js","names":[],"sources":["../src/agent-resume.ts"],"sourcesContent":["import { ownsAgentNamespace } from \"./agent-namespace\";\nimport type {\n ExecutionHost,\n NotificationRecord,\n RunRecord,\n} from \"./execution/types\";\nimport type { AgentRun } from \"./session/run\";\n\ninterface ResumeAgentRunInput {\n readonly host: ExecutionHost;\n readonly ownerNamespace: string;\n resumeNotification(notification: NotificationRecord): Promise<AgentRun>;\n readonly runId: string;\n}\n\nexport async function resumeAgentRun({\n host,\n ownerNamespace,\n resumeNotification,\n runId,\n}: ResumeAgentRunInput): Promise<AgentRun | null> {\n const run = await host.store.runs.get(runId);\n if (!run) {\n return null;\n }\n if (!canAccessRun(run, ownerNamespace)) {\n return null;\n }\n\n if (run.kind === \"notification\" && run.dedupeKey) {\n const idempotencyKey = run.dedupeKey;\n const claimed = await claimRun(host, run);\n if (!claimed) {\n return null;\n }\n\n const notification = await claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n });\n if (!notification) {\n return null;\n }\n\n try {\n const notificationRun = await resumeNotification(notification);\n await completeNotificationRun(host, claimed.runId);\n return notificationRun;\n } catch (error) {\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n throw error;\n }\n }\n\n return null;\n}\n\nasync function claimNotificationForRun({\n host,\n idempotencyKey,\n ownerNamespace,\n}: {\n readonly host: ExecutionHost;\n readonly idempotencyKey: string;\n readonly ownerNamespace: string;\n}): Promise<NotificationRecord | null> {\n const current =\n await host.store.notifications.getByIdempotencyKey(idempotencyKey);\n if (!ownsAgentNamespace(current?.ownerNamespace, ownerNamespace)) {\n return null;\n }\n\n const claim =\n await host.store.notifications.claimByIdempotencyKey(idempotencyKey);\n if (claim.ok) {\n if (ownsAgentNamespace(claim.record.ownerNamespace, ownerNamespace)) {\n return claim.record;\n }\n await host.store.notifications.releaseByIdempotencyKey(idempotencyKey);\n return null;\n }\n\n if (\n claim.reason === \"already-claimed\" &&\n ownsAgentNamespace(claim.record?.ownerNamespace, ownerNamespace)\n ) {\n return claim.record ?? null;\n }\n\n return null;\n}\n\nfunction canAccessRun(run: RunRecord, ownerNamespace: string): boolean {\n if (run.ownerNamespace) {\n return ownsAgentNamespace(run.ownerNamespace, ownerNamespace);\n }\n\n return (\n run.sessionKey.startsWith(`parent:${ownerNamespace}:`) ||\n run.parentRunId?.startsWith(`${ownerNamespace}:session:`) === true\n );\n}\n\nexport async function completeNotificationRun(\n host: ExecutionHost,\n runId: string\n): Promise<void> {\n const run = await host.store.runs.get(runId);\n if (run?.kind !== \"notification\" || run.status === \"completed\") {\n return;\n }\n\n await host.store.runs.update({ ...run, status: \"completed\" });\n}\n\nasync function claimRun(\n host: ExecutionHost,\n run: RunRecord\n): Promise<RunRecord | null> {\n const claim = await host.store.runs.claim(run.runId, {\n attempt: (run.lease?.attempt ?? 0) + 1,\n leaseId: crypto.randomUUID(),\n leaseMs: 300_000,\n nowMs: Date.now(),\n });\n return claim.ok ? claim.record : null;\n}\n"],"mappings":";;AAeA,eAAsB,eAAe,EACnC,MACA,gBACA,oBACA,SACgD;CAChD,MAAM,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,KAAK;CAC3C,IAAI,CAAC,KACH,OAAO;CAET,IAAI,CAAC,aAAa,KAAK,cAAc,GACnC,OAAO;CAGT,IAAI,IAAI,SAAS,kBAAkB,IAAI,WAAW;EAChD,MAAM,iBAAiB,IAAI;EAC3B,MAAM,UAAU,MAAM,SAAS,MAAM,GAAG;EACxC,IAAI,CAAC,SACH,OAAO;EAGT,MAAM,eAAe,MAAM,wBAAwB;GACjD;GACA;GACA;EACF,CAAC;EACD,IAAI,CAAC,cACH,OAAO;EAGT,IAAI;GACF,MAAM,kBAAkB,MAAM,mBAAmB,YAAY;GAC7D,MAAM,wBAAwB,MAAM,QAAQ,KAAK;GACjD,OAAO;EACT,SAAS,OAAO;GACd,MAAM,KAAK,MAAM,cAAc,wBAAwB,cAAc;GACrE,MAAM;EACR;CACF;CAEA,OAAO;AACT;AAEA,eAAe,wBAAwB,EACrC,MACA,gBACA,kBAKqC;CAGrC,IAAI,CAAC,oBAAmB,MADhB,KAAK,MAAM,cAAc,oBAAoB,cAAc,IAClC,gBAAgB,cAAc,GAC7D,OAAO;CAGT,MAAM,QACJ,MAAM,KAAK,MAAM,cAAc,sBAAsB,cAAc;CACrE,IAAI,MAAM,IAAI;EACZ,IAAI,mBAAmB,MAAM,OAAO,gBAAgB,cAAc,GAChE,OAAO,MAAM;EAEf,MAAM,KAAK,MAAM,cAAc,wBAAwB,cAAc;EACrE,OAAO;CACT;CAEA,IACE,MAAM,WAAW,qBACjB,mBAAmB,MAAM,QAAQ,gBAAgB,cAAc,GAE/D,OAAO,MAAM,UAAU;CAGzB,OAAO;AACT;AAEA,SAAS,aAAa,KAAgB,gBAAiC;CACrE,IAAI,IAAI,gBACN,OAAO,mBAAmB,IAAI,gBAAgB,cAAc;CAG9D,OACE,IAAI,WAAW,WAAW,UAAU,eAAe,EAAE,KACrD,IAAI,aAAa,WAAW,GAAG,eAAe,UAAU,MAAM;AAElE;AAEA,eAAsB,wBACpB,MACA,OACe;CACf,MAAM,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,KAAK;CAC3C,IAAI,KAAK,SAAS,kBAAkB,IAAI,WAAW,aACjD;CAGF,MAAM,KAAK,MAAM,KAAK,OAAO;EAAE,GAAG;EAAK,QAAQ;CAAY,CAAC;AAC9D;AAEA,eAAe,SACb,MACA,KAC2B;CAC3B,MAAM,QAAQ,MAAM,KAAK,MAAM,KAAK,MAAM,IAAI,OAAO;EACnD,UAAU,IAAI,OAAO,WAAW,KAAK;EACrC,SAAS,OAAO,WAAW;EAC3B,SAAS;EACT,OAAO,KAAK,IAAI;CAClB,CAAC;CACD,OAAO,MAAM,KAAK,MAAM,SAAS;AACnC"}
|
|
@@ -3,8 +3,8 @@ import { AgentRun } from "./session/run.js";
|
|
|
3
3
|
//#region src/agent-session-entry.d.ts
|
|
4
4
|
interface SessionHandle {
|
|
5
5
|
delete(): Promise<void>;
|
|
6
|
+
dispose(): Promise<void>;
|
|
6
7
|
interrupt(): void;
|
|
7
|
-
kill(): Promise<void>;
|
|
8
8
|
send(input: AgentInput): Promise<AgentRun>;
|
|
9
9
|
steer(input: AgentInput): Promise<AgentRun>;
|
|
10
10
|
}
|
package/dist/agent.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { AgentInput } from "./session/input.js";
|
|
2
2
|
import { AgentHost } from "./execution/types.js";
|
|
3
|
-
import { AgentOptions } from "./agent-options.js";
|
|
3
|
+
import { AgentConstructionOptions, AgentOptions } from "./agent-options.js";
|
|
4
4
|
import { AgentRun } from "./session/run.js";
|
|
5
5
|
import { SessionHandle } from "./agent-session-entry.js";
|
|
6
6
|
|
|
7
7
|
//#region src/agent.d.ts
|
|
8
8
|
declare class Agent {
|
|
9
9
|
#private;
|
|
10
|
-
readonly
|
|
11
|
-
readonly
|
|
12
|
-
constructor(options:
|
|
10
|
+
readonly host: AgentHost;
|
|
11
|
+
readonly namespace?: string;
|
|
12
|
+
constructor(options: AgentConstructionOptions);
|
|
13
13
|
send(input: AgentInput): Promise<AgentRun>;
|
|
14
14
|
resume(runId: string): Promise<AgentRun | null>;
|
|
15
15
|
session(key: string): SessionHandle;
|
package/dist/agent.js
CHANGED
|
@@ -1,53 +1,34 @@
|
|
|
1
1
|
import { executionHost } from "./execution/host.js";
|
|
2
|
-
import { cancelDurableChildRuns } from "./agent-child-runs.js";
|
|
3
|
-
import { supportsBackgroundSubagents } from "./agent-host-capabilities.js";
|
|
4
2
|
import { sessionStoreForHost } from "./agent-host-session-store.js";
|
|
5
|
-
import {
|
|
6
|
-
import { assertAgentOptions
|
|
3
|
+
import { stableAgentNamespace } from "./agent-namespace.js";
|
|
4
|
+
import { assertAgentOptions } from "./agent-options.js";
|
|
7
5
|
import { resumeAgentRun } from "./agent-resume.js";
|
|
8
|
-
import { assertSubagents } from "./agent-validation.js";
|
|
9
|
-
import { ChildSessionCleanups } from "./child-session-cleanups.js";
|
|
10
6
|
import { createInMemoryExecutionHost } from "./execution/memory.js";
|
|
11
|
-
import { createLlm } from "./llm.js";
|
|
12
7
|
import { AgentSession } from "./session/session.js";
|
|
13
|
-
import { createSubagentTools } from "./subagents.js";
|
|
14
8
|
//#region src/agent.ts
|
|
15
|
-
var Agent = class
|
|
16
|
-
#baseTools;
|
|
17
|
-
#llm;
|
|
9
|
+
var Agent = class {
|
|
18
10
|
#modelOptions;
|
|
19
|
-
#childSessionCleanups = new ChildSessionCleanups();
|
|
20
|
-
#sessionGenerations = /* @__PURE__ */ new Map();
|
|
21
11
|
#sessions = /* @__PURE__ */ new Map();
|
|
22
12
|
#sessionNamespace;
|
|
23
13
|
#store;
|
|
24
14
|
#host;
|
|
25
15
|
#plugins;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
name;
|
|
16
|
+
host;
|
|
17
|
+
namespace;
|
|
29
18
|
constructor(options) {
|
|
30
19
|
assertAgentOptions(options);
|
|
31
|
-
this.
|
|
32
|
-
this
|
|
33
|
-
this.#sessionNamespace = stableAgentNamespace({
|
|
34
|
-
name: options.name,
|
|
35
|
-
namespace: options.namespace
|
|
36
|
-
});
|
|
20
|
+
this.namespace = options.namespace;
|
|
21
|
+
this.#sessionNamespace = stableAgentNamespace({ namespace: options.namespace });
|
|
37
22
|
this.#host = options.host ?? createInMemoryExecutionHost();
|
|
23
|
+
this.host = this.#host;
|
|
38
24
|
this.#store = sessionStoreForHost(this.#host);
|
|
39
25
|
this.#plugins = options.plugins ?? [];
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
instructions: options.instructions,
|
|
47
|
-
model: options.model,
|
|
48
|
-
toolChoice: options.toolChoice
|
|
49
|
-
};
|
|
50
|
-
}
|
|
26
|
+
this.#modelOptions = {
|
|
27
|
+
instructions: options.instructions,
|
|
28
|
+
model: options.model,
|
|
29
|
+
toolChoice: options.toolChoice,
|
|
30
|
+
tools: options.tools
|
|
31
|
+
};
|
|
51
32
|
}
|
|
52
33
|
send(input) {
|
|
53
34
|
return this.session("default").send(input);
|
|
@@ -59,8 +40,7 @@ var Agent = class Agent {
|
|
|
59
40
|
host,
|
|
60
41
|
ownerNamespace: this.#sessionNamespace,
|
|
61
42
|
resumeNotification: (notification) => this.#resumeNotification(notification),
|
|
62
|
-
runId
|
|
63
|
-
subagents: this.#subagents
|
|
43
|
+
runId
|
|
64
44
|
});
|
|
65
45
|
}
|
|
66
46
|
session(key) {
|
|
@@ -70,16 +50,7 @@ var Agent = class Agent {
|
|
|
70
50
|
const existing = this.#sessions.get(key);
|
|
71
51
|
if (existing) return existing;
|
|
72
52
|
let session;
|
|
73
|
-
|
|
74
|
-
if (!session) throw new Error("Agent session is not initialized.");
|
|
75
|
-
return session;
|
|
76
|
-
};
|
|
77
|
-
const parentAgentNamespace = parentSessionNamespace({
|
|
78
|
-
generation: this.#sessionGenerations.get(key) ?? 0,
|
|
79
|
-
sessionKey: key,
|
|
80
|
-
sessionNamespace: this.#sessionNamespace
|
|
81
|
-
});
|
|
82
|
-
session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession(key, parentAgentNamespace, (input, placement) => getSession().enqueueRuntimeInput(input, placement), (event) => getSession().emitObserverEvent(event), (input, options) => getSession().notify(input, options), () => getSession().currentTurnId(), () => parentAgentNamespace)), {
|
|
53
|
+
session = new AgentSession(this.#modelOptions, {
|
|
83
54
|
key,
|
|
84
55
|
store: this.#store
|
|
85
56
|
}, this.#plugins, { executionHost: executionHost(this.#host) });
|
|
@@ -88,18 +59,15 @@ var Agent = class Agent {
|
|
|
88
59
|
publicHandle: {
|
|
89
60
|
delete: async () => {
|
|
90
61
|
session.kill();
|
|
91
|
-
await this.#cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace);
|
|
92
62
|
this.#evictSessionHandle(key);
|
|
93
63
|
await session.delete();
|
|
94
|
-
await this.#childSessionCleanups.delete(key);
|
|
95
64
|
},
|
|
96
|
-
|
|
97
|
-
kill: async () => {
|
|
65
|
+
dispose: () => {
|
|
98
66
|
session.kill();
|
|
99
|
-
await this.#cancelDurableChildRunsBeforeLocalCleanup(key, parentAgentNamespace);
|
|
100
67
|
this.#evictSessionHandle(key);
|
|
101
|
-
|
|
68
|
+
return Promise.resolve();
|
|
102
69
|
},
|
|
70
|
+
interrupt: () => session.interrupt(),
|
|
103
71
|
send: (input) => session.send(input),
|
|
104
72
|
steer: (input) => session.steer(input)
|
|
105
73
|
}
|
|
@@ -107,50 +75,12 @@ var Agent = class Agent {
|
|
|
107
75
|
this.#sessions.set(key, entry);
|
|
108
76
|
return entry;
|
|
109
77
|
}
|
|
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
78
|
#evictSessionHandle(key) {
|
|
119
79
|
this.#sessions.delete(key);
|
|
120
|
-
this.#sessionGenerations.set(key, (this.#sessionGenerations.get(key) ?? 0) + 1);
|
|
121
80
|
}
|
|
122
81
|
#resumeNotification(notification) {
|
|
123
82
|
return this.#sessionEntry(notification.sessionKey).notify(notification.input, { observerEvents: notification.observerEvents });
|
|
124
83
|
}
|
|
125
|
-
#createLlmOptionsForSession(key, parentAgentNamespace, enqueueRuntimeInput, emitObserverEvent, notify, currentBackgroundGroupId, currentRunId) {
|
|
126
|
-
const modelOptions = this.#modelOptions;
|
|
127
|
-
if (!modelOptions) throw new Error("Agent: missing model options.");
|
|
128
|
-
const hostExecution = executionHost(this.#host);
|
|
129
|
-
const tools = this.#subagents.length === 0 ? this.#baseTools : {
|
|
130
|
-
...this.#baseTools,
|
|
131
|
-
...createSubagentTools({
|
|
132
|
-
backgroundSubagents: supportsBackgroundSubagents(this.#host, hostExecution),
|
|
133
|
-
executionHost: hostExecution,
|
|
134
|
-
parentAgentNamespace,
|
|
135
|
-
parentSession: {
|
|
136
|
-
currentBackgroundGroupId,
|
|
137
|
-
currentRunId,
|
|
138
|
-
emitObserverEvent,
|
|
139
|
-
enqueueRuntimeInput,
|
|
140
|
-
notify
|
|
141
|
-
},
|
|
142
|
-
parentSessionKey: key,
|
|
143
|
-
registerChildSession: (sessionKey, cleanup) => this.#childSessionCleanups.register(sessionKey, cleanup),
|
|
144
|
-
subagents: this.#subagents
|
|
145
|
-
})
|
|
146
|
-
};
|
|
147
|
-
return {
|
|
148
|
-
instructions: modelOptions.instructions,
|
|
149
|
-
model: modelOptions.model,
|
|
150
|
-
toolChoice: modelOptions.toolChoice,
|
|
151
|
-
tools
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
84
|
};
|
|
155
85
|
//#endregion
|
|
156
86
|
export { Agent };
|
package/dist/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","names":["#baseTools","#llm","#modelOptions","#childSessionCleanups","#sessionGenerations","#sessions","#sessionNamespace","#store","#host","#plugins","#subagents","#resumeNotification","#sessionEntry","#createLlmOptionsForSession","#cancelDurableChildRunsBeforeLocalCleanup","#evictSessionHandle"],"sources":["../src/agent.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport { cancelDurableChildRuns } from \"./agent-child-runs\";\nimport { supportsBackgroundSubagents } from \"./agent-host-capabilities\";\nimport { sessionStoreForHost } from \"./agent-host-session-store\";\nimport {\n parentSessionNamespace,\n stableAgentNamespace,\n} from \"./agent-namespace\";\nimport {\n type AgentModelOptions,\n type AgentOptions,\n assertAgentOptions,\n hasRuntimeModel,\n} from \"./agent-options\";\nimport { resumeAgentRun } from \"./agent-resume\";\nimport type { AgentSessionEntry, SessionHandle } from \"./agent-session-entry\";\nimport { assertSubagents } from \"./agent-validation\";\nimport { ChildSessionCleanups } from \"./child-session-cleanups\";\nimport { executionHost } from \"./execution/host\";\nimport { createInMemoryExecutionHost } from \"./execution/memory\";\nimport type { AgentHost, NotificationRecord } from \"./execution/types\";\nimport { createLlm, type RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\nimport type { UserInput } from \"./session/events\";\nimport type { AgentRun } from \"./session/run\";\nimport {\n type AgentInput,\n AgentSession,\n type NotifyOptions,\n} from \"./session/session\";\nimport type { SessionStore } from \"./session/store/types\";\nimport { createSubagentTools } from \"./subagents\";\n\nexport type { AgentOptions } from \"./agent-options\";\nexport type { SessionHandle } from \"./agent-session-entry\";\nexport type { AgentHost } from \"./execution/types\";\n\nexport class Agent {\n readonly #baseTools?: ToolSet;\n readonly #llm?: RuntimeLlm;\n readonly #modelOptions?: AgentModelOptions;\n readonly #childSessionCleanups = new ChildSessionCleanups();\n readonly #sessionGenerations = new Map<string, number>();\n readonly #sessions = new Map<string, AgentSessionEntry>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\n readonly #host: AgentHost;\n readonly #plugins: readonly AgentPlugin[];\n readonly #subagents: readonly Agent[];\n readonly description?: string;\n readonly name?: string;\n\n constructor(options: AgentOptions) {\n assertAgentOptions(options);\n\n this.description = options.description;\n this.name = options.name;\n this.#sessionNamespace = stableAgentNamespace({\n name: options.name,\n namespace: options.namespace,\n });\n this.#host = options.host ?? createInMemoryExecutionHost();\n this.#store = sessionStoreForHost(this.#host);\n this.#plugins = options.plugins ?? [];\n assertSubagents(options, Agent, hasRuntimeModel(options));\n this.#subagents = hasRuntimeModel(options) ? [] : (options.subagents ?? []);\n if (hasRuntimeModel(options)) {\n this.#llm = options.model;\n } else {\n this.#baseTools = options.tools;\n this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n };\n }\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n async resume(runId: string): Promise<AgentRun | null> {\n const host = executionHost(this.#host);\n if (!host) {\n throw new Error(\"Agent host does not support durable run resume.\");\n }\n\n return await resumeAgentRun({\n host,\n ownerNamespace: this.#sessionNamespace,\n resumeNotification: (notification) =>\n this.#resumeNotification(notification),\n runId,\n subagents: this.#subagents,\n });\n }\n\n session(key: string): SessionHandle {\n return this.#sessionEntry(key).publicHandle;\n }\n\n #sessionEntry(key: string): AgentSessionEntry {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n let session: AgentSession | undefined;\n const getSession = () => {\n if (!session) {\n throw new Error(\"Agent session is not initialized.\");\n }\n return session;\n };\n const parentAgentNamespace = parentSessionNamespace({\n generation: this.#sessionGenerations.get(key) ?? 0,\n sessionKey: key,\n sessionNamespace: this.#sessionNamespace,\n });\n const llm =\n this.#llm ??\n createLlm(\n this.#createLlmOptionsForSession(\n key,\n parentAgentNamespace,\n (input: UserInput, placement?: \"turn-start\") =>\n getSession().enqueueRuntimeInput(input, placement),\n (event) => getSession().emitObserverEvent(event),\n (input: UserInput, options?: NotifyOptions) =>\n getSession().notify(input, options),\n () => getSession().currentTurnId(),\n () => parentAgentNamespace\n )\n );\n session = new AgentSession(\n llm,\n { key, store: this.#store },\n this.#plugins,\n {\n executionHost: executionHost(this.#host),\n }\n );\n const publicHandle: SessionHandle = {\n delete: async () => {\n session.kill();\n await this.#cancelDurableChildRunsBeforeLocalCleanup(\n key,\n parentAgentNamespace\n );\n this.#evictSessionHandle(key);\n await session.delete();\n await this.#childSessionCleanups.delete(key);\n },\n interrupt: () => session.interrupt(),\n kill: async () => {\n session.kill();\n await this.#cancelDurableChildRunsBeforeLocalCleanup(\n key,\n parentAgentNamespace\n );\n this.#evictSessionHandle(key);\n await this.#childSessionCleanups.delete(key);\n },\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n const entry: AgentSessionEntry = {\n notify: (input, options) => session.notify(input, options),\n publicHandle,\n };\n this.#sessions.set(key, entry);\n return entry;\n }\n\n async #cancelDurableChildRunsBeforeLocalCleanup(\n key: string,\n parentAgentNamespace: string\n ): Promise<void> {\n try {\n await cancelDurableChildRuns(this.#host, parentAgentNamespace);\n } catch (error) {\n this.#evictSessionHandle(key);\n throw error;\n }\n }\n\n #evictSessionHandle(key: string): void {\n this.#sessions.delete(key);\n this.#sessionGenerations.set(\n key,\n (this.#sessionGenerations.get(key) ?? 0) + 1\n );\n }\n\n #resumeNotification(notification: NotificationRecord): Promise<AgentRun> {\n return this.#sessionEntry(notification.sessionKey).notify(\n notification.input,\n { observerEvents: notification.observerEvents }\n );\n }\n\n #createLlmOptionsForSession(\n key: string,\n parentAgentNamespace: string,\n enqueueRuntimeInput: AgentSession[\"enqueueRuntimeInput\"],\n emitObserverEvent: AgentSession[\"emitObserverEvent\"],\n notify: (input: UserInput, options?: NotifyOptions) => Promise<AgentRun>,\n currentBackgroundGroupId: () => string | undefined,\n currentRunId: () => string | undefined\n ): Parameters<typeof createLlm>[0] {\n const modelOptions = this.#modelOptions;\n if (!modelOptions) {\n throw new Error(\"Agent: missing model options.\");\n }\n const hostExecution = executionHost(this.#host);\n const tools =\n this.#subagents.length === 0\n ? this.#baseTools\n : {\n ...this.#baseTools,\n ...createSubagentTools({\n backgroundSubagents: supportsBackgroundSubagents(\n this.#host,\n hostExecution\n ),\n executionHost: hostExecution,\n parentAgentNamespace,\n parentSession: {\n currentBackgroundGroupId,\n currentRunId,\n emitObserverEvent,\n enqueueRuntimeInput,\n notify,\n },\n parentSessionKey: key,\n registerChildSession: (sessionKey, cleanup) =>\n this.#childSessionCleanups.register(sessionKey, cleanup),\n subagents: this.#subagents,\n }),\n };\n\n return {\n instructions: modelOptions.instructions,\n model: modelOptions.model,\n toolChoice: modelOptions.toolChoice,\n tools,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent.js","names":["#modelOptions","#sessions","#sessionNamespace","#store","#host","#plugins","#resumeNotification","#sessionEntry","#evictSessionHandle"],"sources":["../src/agent.ts"],"sourcesContent":["import { sessionStoreForHost } from \"./agent-host-session-store\";\nimport { stableAgentNamespace } from \"./agent-namespace\";\nimport {\n type AgentConstructionOptions,\n type AgentModelOptions,\n assertAgentOptions,\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 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 #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 this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n tools: options.tools,\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 session = new AgentSession(\n this.#modelOptions,\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"],"mappings":";;;;;;;;AAqBA,IAAa,QAAb,MAAmB;CACjB;CACA,4BAAqB,IAAI,IAA+B;CACxD;CACA;CACA;CACA;CACA;CACA;CACA,YAAY,SAAmC;EAC7C,mBAAmB,OAAO;EAE1B,KAAK,YAAY,QAAQ;EACzB,KAAKE,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,KAAKL,gBAAgB;GACnB,cAAc,QAAQ;GACtB,OAAO,QAAQ;GACf,YAAY,QAAQ;GACpB,OAAO,QAAQ;EACjB;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;EACJ,UAAU,IAAI,aACZ,KAAKD,eACL;GAAE;GAAK,OAAO,KAAKG;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,KAAKI,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,KAAKP,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;AACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ExecutionHost } from "../execution/types.js";
|
|
2
|
+
import { CloudflareAlarmDrainBudget } from "./cloudflare-alarm-budget.js";
|
|
3
|
+
import { CloudflareDurableObjectStorage } from "./cloudflare-host.js";
|
|
4
|
+
import { CloudflareAlarmAgent, CloudflareAlarmDrainSummary } from "./cloudflare-alarm-drainer.js";
|
|
5
|
+
|
|
6
|
+
//#region src/cloudflare/cloudflare-agent-context.d.ts
|
|
7
|
+
type MaybePromise<T> = Promise<T> | T;
|
|
8
|
+
interface CloudflareAgentContextFactoryOptions<Env> {
|
|
9
|
+
readonly env: Env;
|
|
10
|
+
readonly host: ExecutionHost;
|
|
11
|
+
readonly prefix: string;
|
|
12
|
+
readonly storage: CloudflareDurableObjectStorage;
|
|
13
|
+
}
|
|
14
|
+
interface CloudflareAgentContextPrefixOptions<Env> {
|
|
15
|
+
readonly env: Env;
|
|
16
|
+
readonly storage: CloudflareDurableObjectStorage;
|
|
17
|
+
}
|
|
18
|
+
interface CloudflareAgentContextOptions<Env, Agent extends CloudflareAlarmAgent> {
|
|
19
|
+
readonly createAgent: (options: CloudflareAgentContextFactoryOptions<Env>) => Agent;
|
|
20
|
+
readonly defaultPrefix?: string;
|
|
21
|
+
readonly env: Env;
|
|
22
|
+
readonly readPrefix?: (options: CloudflareAgentContextPrefixOptions<Env>) => MaybePromise<string | undefined>;
|
|
23
|
+
readonly storage: CloudflareDurableObjectStorage;
|
|
24
|
+
}
|
|
25
|
+
interface CloudflareAgentContext<Agent extends CloudflareAlarmAgent> {
|
|
26
|
+
agent(prefix?: string): Agent;
|
|
27
|
+
drainAlarm(budget?: CloudflareAlarmDrainBudget): Promise<CloudflareAlarmDrainSummary>;
|
|
28
|
+
host(prefix?: string): ExecutionHost;
|
|
29
|
+
readonly storage: CloudflareDurableObjectStorage;
|
|
30
|
+
}
|
|
31
|
+
declare function createCloudflareAgentContext<Env, Agent extends CloudflareAlarmAgent>({
|
|
32
|
+
createAgent,
|
|
33
|
+
defaultPrefix,
|
|
34
|
+
env,
|
|
35
|
+
readPrefix,
|
|
36
|
+
storage
|
|
37
|
+
}: CloudflareAgentContextOptions<Env, Agent>): CloudflareAgentContext<Agent>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { CloudflareAgentContext, CloudflareAgentContextFactoryOptions, CloudflareAgentContextOptions, CloudflareAgentContextPrefixOptions, createCloudflareAgentContext };
|
|
40
|
+
//# sourceMappingURL=cloudflare-agent-context.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createCloudflareDurableObjectHost } from "./cloudflare-host.js";
|
|
2
|
+
import { drainCloudflareAlarm } from "./cloudflare-alarm-drainer.js";
|
|
3
|
+
//#region src/cloudflare/cloudflare-agent-context.ts
|
|
4
|
+
const defaultContextPrefix = "pss-runtime";
|
|
5
|
+
function createCloudflareAgentContext({ createAgent, defaultPrefix = defaultContextPrefix, env, readPrefix, storage }) {
|
|
6
|
+
const createHost = (prefix = defaultPrefix) => createCloudflareDurableObjectHost({
|
|
7
|
+
prefix,
|
|
8
|
+
storage
|
|
9
|
+
});
|
|
10
|
+
const createContextAgent = (prefix = defaultPrefix) => createAgent({
|
|
11
|
+
env,
|
|
12
|
+
host: createHost(prefix),
|
|
13
|
+
prefix,
|
|
14
|
+
storage
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
agent: createContextAgent,
|
|
18
|
+
drainAlarm: async (budget) => {
|
|
19
|
+
const prefix = await readPrefix?.({
|
|
20
|
+
env,
|
|
21
|
+
storage
|
|
22
|
+
}) ?? defaultPrefix;
|
|
23
|
+
return await drainCloudflareAlarm({
|
|
24
|
+
agent: createContextAgent(prefix),
|
|
25
|
+
...budget,
|
|
26
|
+
prefix,
|
|
27
|
+
storage
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
host: createHost,
|
|
31
|
+
storage
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { createCloudflareAgentContext };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=cloudflare-agent-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare-agent-context.js","names":[],"sources":["../../src/cloudflare/cloudflare-agent-context.ts"],"sourcesContent":["import type { ExecutionHost } from \"../execution\";\nimport type { CloudflareAlarmDrainBudget } from \"./cloudflare-alarm-budget\";\nimport type {\n CloudflareAlarmAgent,\n CloudflareAlarmDrainSummary,\n} from \"./cloudflare-alarm-drainer\";\nimport { drainCloudflareAlarm } from \"./cloudflare-alarm-drainer\";\nimport {\n type CloudflareDurableObjectStorage,\n createCloudflareDurableObjectHost,\n} from \"./cloudflare-host\";\n\nconst defaultContextPrefix = \"pss-runtime\";\n\ntype MaybePromise<T> = Promise<T> | T;\n\nexport interface CloudflareAgentContextFactoryOptions<Env> {\n readonly env: Env;\n readonly host: ExecutionHost;\n readonly prefix: string;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport interface CloudflareAgentContextPrefixOptions<Env> {\n readonly env: Env;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport interface CloudflareAgentContextOptions<\n Env,\n Agent extends CloudflareAlarmAgent,\n> {\n readonly createAgent: (\n options: CloudflareAgentContextFactoryOptions<Env>\n ) => Agent;\n readonly defaultPrefix?: string;\n readonly env: Env;\n readonly readPrefix?: (\n options: CloudflareAgentContextPrefixOptions<Env>\n ) => MaybePromise<string | undefined>;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport interface CloudflareAgentContext<Agent extends CloudflareAlarmAgent> {\n agent(prefix?: string): Agent;\n drainAlarm(\n budget?: CloudflareAlarmDrainBudget\n ): Promise<CloudflareAlarmDrainSummary>;\n host(prefix?: string): ExecutionHost;\n readonly storage: CloudflareDurableObjectStorage;\n}\n\nexport function createCloudflareAgentContext<\n Env,\n Agent extends CloudflareAlarmAgent,\n>({\n createAgent,\n defaultPrefix = defaultContextPrefix,\n env,\n readPrefix,\n storage,\n}: CloudflareAgentContextOptions<Env, Agent>): CloudflareAgentContext<Agent> {\n const createHost = (prefix = defaultPrefix) =>\n createCloudflareDurableObjectHost({ prefix, storage });\n const createContextAgent = (prefix = defaultPrefix) =>\n createAgent({\n env,\n host: createHost(prefix),\n prefix,\n storage,\n });\n\n return {\n agent: createContextAgent,\n drainAlarm: async (budget) => {\n const prefix = (await readPrefix?.({ env, storage })) ?? defaultPrefix;\n return await drainCloudflareAlarm({\n agent: createContextAgent(prefix),\n ...budget,\n prefix,\n storage,\n });\n },\n host: createHost,\n storage,\n };\n}\n"],"mappings":";;;AAYA,MAAM,uBAAuB;AAwC7B,SAAgB,6BAGd,EACA,aACA,gBAAgB,sBAChB,KACA,YACA,WAC2E;CAC3E,MAAM,cAAc,SAAS,kBAC3B,kCAAkC;EAAE;EAAQ;CAAQ,CAAC;CACvD,MAAM,sBAAsB,SAAS,kBACnC,YAAY;EACV;EACA,MAAM,WAAW,MAAM;EACvB;EACA;CACF,CAAC;CAEH,OAAO;EACL,OAAO;EACP,YAAY,OAAO,WAAW;GAC5B,MAAM,SAAU,MAAM,aAAa;IAAE;IAAK;GAAQ,CAAC,KAAM;GACzD,OAAO,MAAM,qBAAqB;IAChC,OAAO,mBAAmB,MAAM;IAChC,GAAG;IACH;IACA;GACF,CAAC;EACH;EACA,MAAM;EACN;CACF;AACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/cloudflare/cloudflare-alarm-budget.d.ts
|
|
2
|
+
type CloudflareAlarmContinuationReason = "deadline" | "event-budget" | "failure" | "run-budget" | "session-prompt-budget";
|
|
3
|
+
interface CloudflareAlarmDrainBudget {
|
|
4
|
+
readonly continuationRunAfterMs?: number;
|
|
5
|
+
readonly deadlineMs?: number;
|
|
6
|
+
readonly failureRunAfterMs?: number;
|
|
7
|
+
readonly maxEvents?: number;
|
|
8
|
+
readonly maxRuns?: number;
|
|
9
|
+
readonly maxSessionPrompts?: number;
|
|
10
|
+
readonly throwOnFailure?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface FailedScheduledWork {
|
|
13
|
+
readonly error: string;
|
|
14
|
+
readonly id: string;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { CloudflareAlarmContinuationReason, CloudflareAlarmDrainBudget, FailedScheduledWork };
|
|
18
|
+
//# sourceMappingURL=cloudflare-alarm-budget.d.ts.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/cloudflare/cloudflare-alarm-budget.ts
|
|
2
|
+
const defaultAlarmDrainBudget = {
|
|
3
|
+
continuationRunAfterMs: 0,
|
|
4
|
+
deadlineMs: 3e4,
|
|
5
|
+
failureRunAfterMs: 1e3,
|
|
6
|
+
maxEvents: 1e3,
|
|
7
|
+
maxRuns: 25,
|
|
8
|
+
maxSessionPrompts: 25,
|
|
9
|
+
throwOnFailure: false
|
|
10
|
+
};
|
|
11
|
+
function createAlarmDrainState() {
|
|
12
|
+
return {
|
|
13
|
+
consumedSessionPrompts: [],
|
|
14
|
+
droppedEvents: 0,
|
|
15
|
+
events: [],
|
|
16
|
+
failedRuns: [],
|
|
17
|
+
failedSessionPrompts: [],
|
|
18
|
+
reasons: /* @__PURE__ */ new Set(),
|
|
19
|
+
resumedRuns: [],
|
|
20
|
+
runAttempts: 0,
|
|
21
|
+
sessionPromptAttempts: 0
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function normalizeAlarmDrainBudget(budget = {}) {
|
|
25
|
+
return {
|
|
26
|
+
continuationRunAfterMs: nonNegativeInteger(budget.continuationRunAfterMs ?? defaultAlarmDrainBudget.continuationRunAfterMs),
|
|
27
|
+
deadlineMs: nonNegativeInteger(budget.deadlineMs ?? defaultAlarmDrainBudget.deadlineMs),
|
|
28
|
+
failureRunAfterMs: nonNegativeInteger(budget.failureRunAfterMs ?? defaultAlarmDrainBudget.failureRunAfterMs),
|
|
29
|
+
maxEvents: nonNegativeInteger(budget.maxEvents ?? defaultAlarmDrainBudget.maxEvents),
|
|
30
|
+
maxRuns: nonNegativeInteger(budget.maxRuns ?? defaultAlarmDrainBudget.maxRuns),
|
|
31
|
+
maxSessionPrompts: nonNegativeInteger(budget.maxSessionPrompts ?? defaultAlarmDrainBudget.maxSessionPrompts),
|
|
32
|
+
startedAt: Date.now(),
|
|
33
|
+
throwOnFailure: budget.throwOnFailure ?? defaultAlarmDrainBudget.throwOnFailure
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function eventSlotsRemaining(state, budget) {
|
|
37
|
+
return Math.max(0, budget.maxEvents - state.events.length);
|
|
38
|
+
}
|
|
39
|
+
function shouldStopForDeadline(budget) {
|
|
40
|
+
return Date.now() - budget.startedAt >= budget.deadlineMs;
|
|
41
|
+
}
|
|
42
|
+
function shouldStopRuns(state, budget) {
|
|
43
|
+
if (shouldStopForDeadline(budget)) {
|
|
44
|
+
state.reasons.add("deadline");
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (shouldStopForEventBudget(state, budget)) return true;
|
|
48
|
+
if (state.runAttempts >= budget.maxRuns) {
|
|
49
|
+
state.reasons.add("run-budget");
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
function shouldStopSessionPrompts(state, budget) {
|
|
55
|
+
if (shouldStopForDeadline(budget)) {
|
|
56
|
+
state.reasons.add("deadline");
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
if (shouldStopForEventBudget(state, budget)) return true;
|
|
60
|
+
if (state.sessionPromptAttempts >= budget.maxSessionPrompts) {
|
|
61
|
+
state.reasons.add("session-prompt-budget");
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
function shouldStopForEventBudget(state, budget) {
|
|
67
|
+
if (state.events.length < budget.maxEvents) return false;
|
|
68
|
+
state.reasons.add("event-budget");
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
function nonNegativeInteger(value) {
|
|
72
|
+
return Math.max(0, Math.floor(value));
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { createAlarmDrainState, eventSlotsRemaining, normalizeAlarmDrainBudget, shouldStopRuns, shouldStopSessionPrompts };
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=cloudflare-alarm-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare-alarm-budget.js","names":[],"sources":["../../src/cloudflare/cloudflare-alarm-budget.ts"],"sourcesContent":["import type { AgentEvent } from \"../index\";\n\nexport type CloudflareAlarmContinuationReason =\n | \"deadline\"\n | \"event-budget\"\n | \"failure\"\n | \"run-budget\"\n | \"session-prompt-budget\";\n\nexport interface CloudflareAlarmDrainBudget {\n readonly continuationRunAfterMs?: number;\n readonly deadlineMs?: number;\n readonly failureRunAfterMs?: number;\n readonly maxEvents?: number;\n readonly maxRuns?: number;\n readonly maxSessionPrompts?: number;\n readonly throwOnFailure?: boolean;\n}\n\nexport interface FailedScheduledWork {\n readonly error: string;\n readonly id: string;\n}\n\nexport interface AlarmDrainState {\n readonly consumedSessionPrompts: string[];\n droppedEvents: number;\n readonly events: AgentEvent[];\n readonly failedRuns: FailedScheduledWork[];\n readonly failedSessionPrompts: FailedScheduledWork[];\n readonly reasons: Set<CloudflareAlarmContinuationReason>;\n readonly resumedRuns: string[];\n runAttempts: number;\n sessionPromptAttempts: number;\n}\n\nexport interface NormalizedAlarmDrainBudget {\n readonly continuationRunAfterMs: number;\n readonly deadlineMs: number;\n readonly failureRunAfterMs: number;\n readonly maxEvents: number;\n readonly maxRuns: number;\n readonly maxSessionPrompts: number;\n readonly startedAt: number;\n readonly throwOnFailure: boolean;\n}\n\nconst defaultAlarmDrainBudget = {\n continuationRunAfterMs: 0,\n deadlineMs: 30_000,\n failureRunAfterMs: 1000,\n maxEvents: 1000,\n maxRuns: 25,\n maxSessionPrompts: 25,\n throwOnFailure: false,\n} satisfies Required<CloudflareAlarmDrainBudget>;\n\nexport function createAlarmDrainState(): AlarmDrainState {\n return {\n consumedSessionPrompts: [],\n droppedEvents: 0,\n events: [],\n failedRuns: [],\n failedSessionPrompts: [],\n reasons: new Set<CloudflareAlarmContinuationReason>(),\n resumedRuns: [],\n runAttempts: 0,\n sessionPromptAttempts: 0,\n };\n}\n\nexport function normalizeAlarmDrainBudget(\n budget: CloudflareAlarmDrainBudget = {}\n): NormalizedAlarmDrainBudget {\n return {\n continuationRunAfterMs: nonNegativeInteger(\n budget.continuationRunAfterMs ??\n defaultAlarmDrainBudget.continuationRunAfterMs\n ),\n deadlineMs: nonNegativeInteger(\n budget.deadlineMs ?? defaultAlarmDrainBudget.deadlineMs\n ),\n failureRunAfterMs: nonNegativeInteger(\n budget.failureRunAfterMs ?? defaultAlarmDrainBudget.failureRunAfterMs\n ),\n maxEvents: nonNegativeInteger(\n budget.maxEvents ?? defaultAlarmDrainBudget.maxEvents\n ),\n maxRuns: nonNegativeInteger(\n budget.maxRuns ?? defaultAlarmDrainBudget.maxRuns\n ),\n maxSessionPrompts: nonNegativeInteger(\n budget.maxSessionPrompts ?? defaultAlarmDrainBudget.maxSessionPrompts\n ),\n startedAt: Date.now(),\n throwOnFailure:\n budget.throwOnFailure ?? defaultAlarmDrainBudget.throwOnFailure,\n };\n}\n\nexport function eventSlotsRemaining(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): number {\n return Math.max(0, budget.maxEvents - state.events.length);\n}\n\nexport function shouldStopForDeadline(\n budget: NormalizedAlarmDrainBudget\n): boolean {\n return Date.now() - budget.startedAt >= budget.deadlineMs;\n}\n\nexport function shouldStopRuns(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): boolean {\n if (shouldStopForDeadline(budget)) {\n state.reasons.add(\"deadline\");\n return true;\n }\n if (shouldStopForEventBudget(state, budget)) {\n return true;\n }\n if (state.runAttempts >= budget.maxRuns) {\n state.reasons.add(\"run-budget\");\n return true;\n }\n return false;\n}\n\nexport function shouldStopSessionPrompts(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): boolean {\n if (shouldStopForDeadline(budget)) {\n state.reasons.add(\"deadline\");\n return true;\n }\n if (shouldStopForEventBudget(state, budget)) {\n return true;\n }\n if (state.sessionPromptAttempts >= budget.maxSessionPrompts) {\n state.reasons.add(\"session-prompt-budget\");\n return true;\n }\n return false;\n}\n\nfunction shouldStopForEventBudget(\n state: AlarmDrainState,\n budget: NormalizedAlarmDrainBudget\n): boolean {\n if (state.events.length < budget.maxEvents) {\n return false;\n }\n state.reasons.add(\"event-budget\");\n return true;\n}\n\nfunction nonNegativeInteger(value: number): number {\n return Math.max(0, Math.floor(value));\n}\n"],"mappings":";AA+CA,MAAM,0BAA0B;CAC9B,wBAAwB;CACxB,YAAY;CACZ,mBAAmB;CACnB,WAAW;CACX,SAAS;CACT,mBAAmB;CACnB,gBAAgB;AAClB;AAEA,SAAgB,wBAAyC;CACvD,OAAO;EACL,wBAAwB,CAAC;EACzB,eAAe;EACf,QAAQ,CAAC;EACT,YAAY,CAAC;EACb,sBAAsB,CAAC;EACvB,yBAAS,IAAI,IAAuC;EACpD,aAAa,CAAC;EACd,aAAa;EACb,uBAAuB;CACzB;AACF;AAEA,SAAgB,0BACd,SAAqC,CAAC,GACV;CAC5B,OAAO;EACL,wBAAwB,mBACtB,OAAO,0BACL,wBAAwB,sBAC5B;EACA,YAAY,mBACV,OAAO,cAAc,wBAAwB,UAC/C;EACA,mBAAmB,mBACjB,OAAO,qBAAqB,wBAAwB,iBACtD;EACA,WAAW,mBACT,OAAO,aAAa,wBAAwB,SAC9C;EACA,SAAS,mBACP,OAAO,WAAW,wBAAwB,OAC5C;EACA,mBAAmB,mBACjB,OAAO,qBAAqB,wBAAwB,iBACtD;EACA,WAAW,KAAK,IAAI;EACpB,gBACE,OAAO,kBAAkB,wBAAwB;CACrD;AACF;AAEA,SAAgB,oBACd,OACA,QACQ;CACR,OAAO,KAAK,IAAI,GAAG,OAAO,YAAY,MAAM,OAAO,MAAM;AAC3D;AAEA,SAAgB,sBACd,QACS;CACT,OAAO,KAAK,IAAI,IAAI,OAAO,aAAa,OAAO;AACjD;AAEA,SAAgB,eACd,OACA,QACS;CACT,IAAI,sBAAsB,MAAM,GAAG;EACjC,MAAM,QAAQ,IAAI,UAAU;EAC5B,OAAO;CACT;CACA,IAAI,yBAAyB,OAAO,MAAM,GACxC,OAAO;CAET,IAAI,MAAM,eAAe,OAAO,SAAS;EACvC,MAAM,QAAQ,IAAI,YAAY;EAC9B,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAgB,yBACd,OACA,QACS;CACT,IAAI,sBAAsB,MAAM,GAAG;EACjC,MAAM,QAAQ,IAAI,UAAU;EAC5B,OAAO;CACT;CACA,IAAI,yBAAyB,OAAO,MAAM,GACxC,OAAO;CAET,IAAI,MAAM,yBAAyB,OAAO,mBAAmB;EAC3D,MAAM,QAAQ,IAAI,uBAAuB;EACzC,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAS,yBACP,OACA,QACS;CACT,IAAI,MAAM,OAAO,SAAS,OAAO,WAC/B,OAAO;CAET,MAAM,QAAQ,IAAI,cAAc;CAChC,OAAO;AACT;AAEA,SAAS,mBAAmB,OAAuB;CACjD,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACtC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AgentEvent } from "../session/events.js";
|
|
2
|
+
import { AgentRun } from "../session/run.js";
|
|
3
|
+
import { CloudflareAlarmContinuationReason, CloudflareAlarmDrainBudget, FailedScheduledWork } from "./cloudflare-alarm-budget.js";
|
|
4
|
+
import { CloudflareDurableObjectStorage } from "./cloudflare-host.js";
|
|
5
|
+
|
|
6
|
+
//#region src/cloudflare/cloudflare-alarm-drainer.d.ts
|
|
7
|
+
interface CloudflareAlarmDrainSummary {
|
|
8
|
+
readonly consumedSessionPrompts: readonly string[];
|
|
9
|
+
readonly continuationReasons: readonly CloudflareAlarmContinuationReason[];
|
|
10
|
+
readonly continuationScheduled: boolean;
|
|
11
|
+
readonly droppedEvents: number;
|
|
12
|
+
readonly events: readonly AgentEvent[];
|
|
13
|
+
readonly failedRuns: readonly FailedScheduledWork[];
|
|
14
|
+
readonly failedSessionPrompts: readonly FailedScheduledWork[];
|
|
15
|
+
readonly markers: readonly string[];
|
|
16
|
+
readonly remainingRuns: number;
|
|
17
|
+
readonly remainingSessionPrompts: number;
|
|
18
|
+
readonly resumedRuns: readonly string[];
|
|
19
|
+
}
|
|
20
|
+
interface CloudflareAlarmAgent {
|
|
21
|
+
resume(runId: string): Promise<AgentRun | null>;
|
|
22
|
+
}
|
|
23
|
+
declare class CloudflareAlarmDrainFailureError extends Error {
|
|
24
|
+
readonly summary: CloudflareAlarmDrainSummary;
|
|
25
|
+
constructor(summary: CloudflareAlarmDrainSummary);
|
|
26
|
+
}
|
|
27
|
+
declare function drainCloudflareAlarm({
|
|
28
|
+
agent,
|
|
29
|
+
continuationRunAfterMs,
|
|
30
|
+
deadlineMs,
|
|
31
|
+
failureRunAfterMs,
|
|
32
|
+
maxEvents,
|
|
33
|
+
maxRuns,
|
|
34
|
+
maxSessionPrompts,
|
|
35
|
+
prefix,
|
|
36
|
+
storage,
|
|
37
|
+
throwOnFailure
|
|
38
|
+
}: {
|
|
39
|
+
readonly agent: CloudflareAlarmAgent;
|
|
40
|
+
readonly prefix: string;
|
|
41
|
+
readonly storage: CloudflareDurableObjectStorage;
|
|
42
|
+
} & CloudflareAlarmDrainBudget): Promise<CloudflareAlarmDrainSummary>;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { CloudflareAlarmAgent, CloudflareAlarmDrainFailureError, CloudflareAlarmDrainSummary, drainCloudflareAlarm };
|
|
45
|
+
//# sourceMappingURL=cloudflare-alarm-drainer.d.ts.map
|