@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-turn-processor.js","names":[],"sources":["../../src/session/session-turn-processor.ts"],"sourcesContent":["import { runAgentLoop } from \"../agent-loop\";\nimport type { RuntimeLlm } from \"../llm\";\nimport { ToolExecutionNeedsRecoveryError } from \"../llm-tool-execution\";\nimport type { AgentEvent } from \"./events\";\nimport type { BufferedAgentRun } from \"./run\";\nimport {\n closeRuntimeInput,\n type QueuedInput,\n type RuntimeInputState,\n withRuntimeInputWindow,\n} from \"./runtime-input\";\nimport {\n commitPreUserRuntimeInputs,\n emitCommittedRuntimeInputs,\n} from \"./runtime-input-emit\";\nimport { errorMessage } from \"./session-errors\";\nimport type { SessionEventDispatcher } from \"./session-events\";\nimport {\n type SessionExecutionOptions,\n type SessionExecutionRun,\n type SessionExecutionTerminalStatus,\n startSessionExecutionRun,\n} from \"./session-execution\";\nimport { drainRuntimeInput } from \"./session-runtime-drain\";\n\nimport type { SessionState } from \"./session-state\";\nimport { emitTurnErrorAfterRecovery } from \"./session-turn-error\";\n\ninterface ActiveTurn {\n readonly abort: AbortController;\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n readonly turnId: string;\n}\n\ninterface ProcessQueuedInputOptions {\n readonly activate: (turn: ActiveTurn) => void;\n readonly deactivateRun: () => void;\n readonly events: SessionEventDispatcher;\n readonly execution: SessionExecutionOptions;\n readonly item: QueuedInput;\n readonly llm: RuntimeLlm;\n readonly release: () => void;\n readonly sessionKey: string;\n readonly state: SessionState;\n}\n\nexport async function processQueuedInput({\n activate,\n deactivateRun,\n events,\n execution,\n item,\n llm,\n release,\n sessionKey,\n state,\n}: ProcessQueuedInputOptions): Promise<void> {\n const activeAbort = new AbortController();\n const { initialEvents, input, preUserRuntimeInputs, run, runtimeInput } =\n item;\n const turnId = crypto.randomUUID();\n activate({\n abort: activeAbort,\n run,\n runtimeInput,\n turnId,\n });\n const historySnapshot = state.modelSnapshot();\n let executionRun: SessionExecutionRun | undefined;\n\n try {\n executionRun = await startSessionExecutionRun({\n executionHost: execution.executionHost,\n sessionKey,\n state,\n turnId,\n });\n for (const event of initialEvents) {\n await events.emitRunEvent(run, event);\n }\n const committedPreUser = await commitPreUserRuntimeInputs(\n events,\n state,\n preUserRuntimeInputs\n );\n if (input) {\n state.appendUserInput(input);\n await state.commit();\n }\n await withRuntimeInputWindow(runtimeInput, \"turn-start\", async () => {\n await events.emitRunBoundaryEvent(run, { type: \"turn-start\" });\n });\n await emitCommittedRuntimeInputs(events, run, committedPreUser);\n await drainRuntimeInput({\n events,\n placement: \"turn-start\",\n run,\n runtimeInput,\n state,\n });\n\n const result = await runAgentLoop({\n emit: async (event) =>\n emitTurnEvent({\n event,\n events,\n run,\n runtimeInput,\n state,\n }),\n history: state.history,\n llm,\n captureObserverEvents: (callback) =>\n events.captureObserverEvents(run, callback),\n signal: activeAbort.signal,\n toolExecution: executionRun?.toolExecution,\n });\n\n await state.commit();\n await executionRun?.complete(executionStatusForResult(result));\n await closeSuccessfulTurn({\n deactivateRun,\n events,\n result,\n run,\n runtimeInput,\n });\n } catch (error) {\n const turnError = error instanceof Error ? error : new Error(String(error));\n await executionRun?.complete(executionStatusForError(turnError));\n await emitTurnErrorAfterRecovery({\n error: turnError,\n historySnapshot,\n run,\n runtimeInput,\n state,\n });\n } finally {\n closeRuntimeInput(runtimeInput);\n release();\n run.close(undefined, runtimeInput.closedReason);\n }\n}\n\nfunction executionStatusForResult(\n result: \"aborted\" | \"completed\"\n): SessionExecutionTerminalStatus {\n return result === \"aborted\" ? \"cancelled\" : \"completed\";\n}\n\nfunction executionStatusForError(error: Error): SessionExecutionTerminalStatus {\n return error instanceof ToolExecutionNeedsRecoveryError\n ? \"needs-recovery\"\n : \"error\";\n}\n\nasync function closeSuccessfulTurn({\n deactivateRun,\n events,\n result,\n run,\n runtimeInput,\n}: {\n readonly deactivateRun: () => void;\n readonly events: SessionEventDispatcher;\n readonly result: \"aborted\" | \"completed\";\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n}): Promise<void> {\n const terminalEvent = result === \"aborted\" ? \"turn-abort\" : \"turn-end\";\n closeRuntimeInput(runtimeInput, terminalEvent);\n deactivateRun();\n try {\n await events.emitRunEvent(run, { type: terminalEvent });\n } catch (terminalError) {\n run.emit({ type: \"turn-error\", message: errorMessage(terminalError) });\n closeRuntimeInput(runtimeInput, \"turn-error\");\n }\n}\n\nasync function emitTurnEvent({\n event,\n events,\n run,\n runtimeInput,\n state,\n}: {\n readonly event: AgentEvent;\n readonly events: SessionEventDispatcher;\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n readonly state: SessionState;\n}): Promise<{ readonly runtimeInputAdded: boolean } | undefined> {\n if (event.type !== \"step-start\" && event.type !== \"step-end\") {\n await events.emitRunEvent(run, event);\n return;\n }\n\n await withRuntimeInputWindow(runtimeInput, event.type, async () => {\n await events.emitRunBoundaryEvent(run, event);\n });\n const runtimeInputAdded = await drainRuntimeInput({\n events,\n placement: event.type,\n run,\n runtimeInput,\n state,\n });\n return event.type === \"step-end\" ? { runtimeInputAdded } : undefined;\n}\n"],"mappings":";;;;;;;;;AA+CA,eAAsB,mBAAmB,EACvC,UACA,eACA,QACA,WACA,MACA,KACA,SACA,YACA,SAC2C;CAC3C,MAAM,cAAc,IAAI,gBAAgB;CACxC,MAAM,EAAE,eAAe,OAAO,sBAAsB,KAAK,iBACvD;CACF,MAAM,SAAS,OAAO,WAAW;CACjC,SAAS;EACP,OAAO;EACP;EACA;EACA;CACF,CAAC;CACD,MAAM,kBAAkB,MAAM,cAAc;CAC5C,IAAI;CAEJ,IAAI;EACF,eAAe,MAAM,yBAAyB;GAC5C,eAAe,UAAU;GACzB;GACA;GACA;EACF,CAAC;EACD,KAAK,MAAM,SAAS,eAClB,MAAM,OAAO,aAAa,KAAK,KAAK;EAEtC,MAAM,mBAAmB,MAAM,2BAC7B,QACA,OACA,oBACF;EACA,IAAI,OAAO;GACT,MAAM,gBAAgB,KAAK;GAC3B,MAAM,MAAM,OAAO;EACrB;EACA,MAAM,uBAAuB,cAAc,cAAc,YAAY;GACnE,MAAM,OAAO,qBAAqB,KAAK,EAAE,MAAM,aAAa,CAAC;EAC/D,CAAC;EACD,MAAM,2BAA2B,QAAQ,KAAK,gBAAgB;EAC9D,MAAM,kBAAkB;GACtB;GACA,WAAW;GACX;GACA;GACA;EACF,CAAC;EAED,MAAM,SAAS,MAAM,aAAa;GAChC,MAAM,OAAO,UACX,cAAc;IACZ;IACA;IACA;IACA;IACA;GACF,CAAC;GACH,SAAS,MAAM;GACf;GACA,wBAAwB,aACtB,OAAO,sBAAsB,KAAK,QAAQ;GAC5C,QAAQ,YAAY;GACpB,eAAe,cAAc;EAC/B,CAAC;EAED,MAAM,MAAM,OAAO;EACnB,MAAM,cAAc,SAAS,yBAAyB,MAAM,CAAC;EAC7D,MAAM,oBAAoB;GACxB;GACA;GACA;GACA;GACA;EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,YAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;EAC1E,MAAM,cAAc,SAAS,wBAAwB,SAAS,CAAC;EAC/D,MAAM,2BAA2B;GAC/B,OAAO;GACP;GACA;GACA;GACA;EACF,CAAC;CACH,UAAU;EACR,kBAAkB,YAAY;EAC9B,QAAQ;EACR,IAAI,MAAM,KAAA,GAAW,aAAa,YAAY;CAChD;AACF;AAEA,SAAS,yBACP,QACgC;CAChC,OAAO,WAAW,YAAY,cAAc;AAC9C;AAEA,SAAS,wBAAwB,OAA8C;CAC7E,OAAO,iBAAiB,kCACpB,mBACA;AACN;AAEA,eAAe,oBAAoB,EACjC,eACA,QACA,QACA,KACA,gBAOgB;CAChB,MAAM,gBAAgB,WAAW,YAAY,eAAe;CAC5D,kBAAkB,cAAc,aAAa;CAC7C,cAAc;CACd,IAAI;EACF,MAAM,OAAO,aAAa,KAAK,EAAE,MAAM,cAAc,CAAC;CACxD,SAAS,eAAe;EACtB,IAAI,KAAK;GAAE,MAAM;GAAc,SAAS,aAAa,aAAa;EAAE,CAAC;EACrE,kBAAkB,cAAc,YAAY;CAC9C;AACF;AAEA,eAAe,cAAc,EAC3B,OACA,QACA,KACA,cACA,SAO+D;CAC/D,IAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,YAAY;EAC5D,MAAM,OAAO,aAAa,KAAK,KAAK;EACpC;CACF;CAEA,MAAM,uBAAuB,cAAc,MAAM,MAAM,YAAY;EACjE,MAAM,OAAO,qBAAqB,KAAK,KAAK;CAC9C,CAAC;CACD,MAAM,oBAAoB,MAAM,kBAAkB;EAChD;EACA,WAAW,MAAM;EACjB;EACA;EACA;CACF,CAAC;CACD,OAAO,MAAM,SAAS,aAAa,EAAE,kBAAkB,IAAI,KAAA;AAC7D"}
|
package/dist/session/session.js
CHANGED
|
@@ -1,53 +1,77 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { attachInputMeta, userInputFromEvent } from "./input-meta.js";
|
|
2
2
|
import { normalizeAgentInput } from "./input-normalization.js";
|
|
3
3
|
import { BufferedAgentRun } from "./run.js";
|
|
4
|
-
import { addSteeringInput,
|
|
5
|
-
import {
|
|
4
|
+
import { addSteeringInput, createRuntimeInputState, queueRuntimeInput } from "./runtime-input.js";
|
|
5
|
+
import { sessionKilledError, sessionTerminalError } from "./session-errors.js";
|
|
6
|
+
import { SessionEventDispatcher } from "./session-events.js";
|
|
6
7
|
import { closeKilledRuntimeInputs } from "./session-kill.js";
|
|
7
|
-
import {
|
|
8
|
+
import { queueSessionNotification, startSessionQueueDrain } from "./session-notification.js";
|
|
8
9
|
import { SessionState } from "./session-state.js";
|
|
9
|
-
import {
|
|
10
|
+
import { processQueuedInput } from "./session-turn-processor.js";
|
|
10
11
|
//#region src/session/session.ts
|
|
11
12
|
var AgentSession = class {
|
|
12
|
-
#
|
|
13
|
+
#events;
|
|
14
|
+
#execution;
|
|
13
15
|
#inputQueue = [];
|
|
14
16
|
#llm;
|
|
15
17
|
#pendingRuntimeInputs = [];
|
|
18
|
+
#sessionKey;
|
|
16
19
|
#state;
|
|
17
20
|
#activeAbort;
|
|
18
21
|
#activeRun;
|
|
19
22
|
#activeRuntimeInput;
|
|
23
|
+
#activeTurnId;
|
|
20
24
|
#deletePromise;
|
|
21
25
|
#killed = false;
|
|
22
26
|
#running = false;
|
|
23
27
|
#runToCloseOnKill;
|
|
24
|
-
constructor(llm, persistence,
|
|
25
|
-
this.#hooks = hooks;
|
|
28
|
+
constructor(llm, persistence, plugins = [], execution = {}) {
|
|
26
29
|
this.#llm = llm;
|
|
30
|
+
this.#execution = execution;
|
|
31
|
+
this.#sessionKey = persistence.key;
|
|
27
32
|
this.#state = new SessionState(persistence);
|
|
33
|
+
this.#events = new SessionEventDispatcher({
|
|
34
|
+
history: () => this.#state.modelSnapshot(),
|
|
35
|
+
plugins,
|
|
36
|
+
signal: () => this.#activeAbort?.signal
|
|
37
|
+
});
|
|
28
38
|
}
|
|
29
39
|
async send(input) {
|
|
30
40
|
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
31
41
|
await this.#state.ensureLoaded();
|
|
32
42
|
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
33
43
|
const runtimeInput = createRuntimeInputState(this.#pendingRuntimeInputs.splice(0));
|
|
34
|
-
const
|
|
44
|
+
const normalized = normalizeAgentInput(input);
|
|
45
|
+
const acceptedInput = normalized.meta === void 0 ? attachInputMeta(normalized, { source: "send" }) : normalized;
|
|
35
46
|
const run = new BufferedAgentRun();
|
|
36
|
-
|
|
47
|
+
const emitted = await this.#events.emitRunEvent(run, acceptedInput);
|
|
48
|
+
if (emitted === "handled") {
|
|
49
|
+
run.close();
|
|
50
|
+
return run;
|
|
51
|
+
}
|
|
52
|
+
const queuedInput = userInputFromEvent(emitted.type === "user-text" || emitted.type === "user-message" ? emitted : acceptedInput);
|
|
37
53
|
this.#inputQueue.push({
|
|
38
|
-
|
|
54
|
+
initialEvents: [],
|
|
55
|
+
input: structuredClone(queuedInput),
|
|
56
|
+
preUserRuntimeInputs: [],
|
|
39
57
|
run,
|
|
40
58
|
runtimeInput
|
|
41
59
|
});
|
|
42
|
-
this.#drainInputQueue()
|
|
43
|
-
run.emit({
|
|
44
|
-
type: "turn-error",
|
|
45
|
-
message: errorMessage(error)
|
|
46
|
-
});
|
|
47
|
-
run.close();
|
|
48
|
-
});
|
|
60
|
+
startSessionQueueDrain(run, () => this.#drainInputQueue());
|
|
49
61
|
return run;
|
|
50
62
|
}
|
|
63
|
+
async notify(input, options = {}) {
|
|
64
|
+
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
65
|
+
await this.#state.ensureLoaded();
|
|
66
|
+
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
67
|
+
return queueSessionNotification(input, options, {
|
|
68
|
+
activeRun: this.#activeRun,
|
|
69
|
+
activeRuntimeInput: this.#activeRuntimeInput,
|
|
70
|
+
drain: () => this.#drainInputQueue(),
|
|
71
|
+
inputQueue: this.#inputQueue,
|
|
72
|
+
pendingRuntimeInputs: this.#pendingRuntimeInputs
|
|
73
|
+
});
|
|
74
|
+
}
|
|
51
75
|
async steer(input) {
|
|
52
76
|
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
53
77
|
const runtimeInput = this.#activeRuntimeInput;
|
|
@@ -59,11 +83,17 @@ var AgentSession = class {
|
|
|
59
83
|
interrupt() {
|
|
60
84
|
this.#activeAbort?.abort();
|
|
61
85
|
}
|
|
86
|
+
currentTurnId() {
|
|
87
|
+
return this.#activeTurnId;
|
|
88
|
+
}
|
|
62
89
|
delete() {
|
|
63
|
-
this.#deletePromise
|
|
64
|
-
this
|
|
65
|
-
|
|
66
|
-
|
|
90
|
+
if (!this.#deletePromise) {
|
|
91
|
+
this.kill();
|
|
92
|
+
this.#deletePromise = this.#state.delete().catch((error) => {
|
|
93
|
+
this.#deletePromise = void 0;
|
|
94
|
+
throw error;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
67
97
|
return this.#deletePromise;
|
|
68
98
|
}
|
|
69
99
|
enqueueRuntimeInput(input, placement = "turn-start") {
|
|
@@ -77,7 +107,7 @@ var AgentSession = class {
|
|
|
77
107
|
});
|
|
78
108
|
return;
|
|
79
109
|
}
|
|
80
|
-
runtimeInput
|
|
110
|
+
queueRuntimeInput(runtimeInput, {
|
|
81
111
|
input,
|
|
82
112
|
placement
|
|
83
113
|
});
|
|
@@ -89,12 +119,12 @@ var AgentSession = class {
|
|
|
89
119
|
});
|
|
90
120
|
}
|
|
91
121
|
emitObserverEvent(event) {
|
|
92
|
-
this.#activeRun
|
|
122
|
+
return this.#events.emitObserverEvent(this.#activeRun, event);
|
|
93
123
|
}
|
|
94
124
|
#enqueuePendingRuntimeInput(input) {
|
|
95
125
|
const queuedTurn = this.#inputQueue[0];
|
|
96
126
|
if (input.placement === "turn-start" && queuedTurn) {
|
|
97
|
-
queuedTurn.runtimeInput
|
|
127
|
+
queueRuntimeInput(queuedTurn.runtimeInput, input);
|
|
98
128
|
return;
|
|
99
129
|
}
|
|
100
130
|
this.#pendingRuntimeInputs.push(input);
|
|
@@ -118,88 +148,37 @@ var AgentSession = class {
|
|
|
118
148
|
try {
|
|
119
149
|
while (!this.#killed && this.#inputQueue.length > 0) {
|
|
120
150
|
const item = this.#inputQueue.shift();
|
|
121
|
-
if (item) await
|
|
151
|
+
if (item) await processQueuedInput({
|
|
152
|
+
activate: ({ abort, run, runtimeInput, turnId }) => {
|
|
153
|
+
this.#activeAbort = abort;
|
|
154
|
+
this.#activeRun = run;
|
|
155
|
+
this.#activeRuntimeInput = runtimeInput;
|
|
156
|
+
this.#activeTurnId = turnId;
|
|
157
|
+
this.#runToCloseOnKill = run;
|
|
158
|
+
},
|
|
159
|
+
deactivateRun: () => {
|
|
160
|
+
this.#activeRun = void 0;
|
|
161
|
+
this.#activeRuntimeInput = void 0;
|
|
162
|
+
},
|
|
163
|
+
events: this.#events,
|
|
164
|
+
execution: this.#execution,
|
|
165
|
+
item,
|
|
166
|
+
llm: this.#llm,
|
|
167
|
+
release: () => {
|
|
168
|
+
this.#activeAbort = void 0;
|
|
169
|
+
this.#activeRun = void 0;
|
|
170
|
+
this.#activeRuntimeInput = void 0;
|
|
171
|
+
this.#activeTurnId = void 0;
|
|
172
|
+
this.#runToCloseOnKill = void 0;
|
|
173
|
+
},
|
|
174
|
+
sessionKey: this.#sessionKey,
|
|
175
|
+
state: this.#state
|
|
176
|
+
});
|
|
122
177
|
}
|
|
123
178
|
} finally {
|
|
124
179
|
this.#running = false;
|
|
125
180
|
}
|
|
126
181
|
}
|
|
127
|
-
async #processQueuedInput({ input, run, runtimeInput }) {
|
|
128
|
-
const activeAbort = new AbortController();
|
|
129
|
-
this.#activeAbort = activeAbort;
|
|
130
|
-
this.#activeRun = run;
|
|
131
|
-
this.#activeRuntimeInput = runtimeInput;
|
|
132
|
-
this.#runToCloseOnKill = run;
|
|
133
|
-
const historySnapshot = this.#state.modelSnapshot();
|
|
134
|
-
try {
|
|
135
|
-
await withSteeringPlacement(runtimeInput, "turn-start", async () => {
|
|
136
|
-
await this.#hooks?.beforeTurn?.({
|
|
137
|
-
history: this.#state.modelSnapshot(),
|
|
138
|
-
input,
|
|
139
|
-
signal: activeAbort.signal
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
await withRuntimeInputWindow(runtimeInput, "turn-start", async () => {
|
|
143
|
-
await run.emitBoundary({ type: "turn-start" });
|
|
144
|
-
});
|
|
145
|
-
this.#state.appendUserInput(input);
|
|
146
|
-
await this.#state.commit();
|
|
147
|
-
await drainRuntimeInput({
|
|
148
|
-
placement: "turn-start",
|
|
149
|
-
run,
|
|
150
|
-
runtimeInput,
|
|
151
|
-
state: this.#state
|
|
152
|
-
});
|
|
153
|
-
const result = await runAgentLoop({
|
|
154
|
-
emit: async (event) => {
|
|
155
|
-
if (event.type === "step-start" || event.type === "step-end") {
|
|
156
|
-
await withRuntimeInputWindow(runtimeInput, event.type, async () => {
|
|
157
|
-
await run.emitBoundary(event);
|
|
158
|
-
});
|
|
159
|
-
const runtimeInputAdded = await drainRuntimeInput({
|
|
160
|
-
placement: event.type,
|
|
161
|
-
run,
|
|
162
|
-
runtimeInput,
|
|
163
|
-
state: this.#state
|
|
164
|
-
});
|
|
165
|
-
return event.type === "step-end" ? { runtimeInputAdded } : void 0;
|
|
166
|
-
}
|
|
167
|
-
run.emit(event);
|
|
168
|
-
},
|
|
169
|
-
history: this.#state.history,
|
|
170
|
-
hooks: hooksForRuntimeInput(this.#hooks, runtimeInput),
|
|
171
|
-
llm: this.#llm,
|
|
172
|
-
signal: activeAbort.signal
|
|
173
|
-
});
|
|
174
|
-
await this.#state.commit();
|
|
175
|
-
const terminalEvent = result === "aborted" ? "turn-abort" : "turn-end";
|
|
176
|
-
closeRuntimeInput(runtimeInput, terminalEvent);
|
|
177
|
-
this.#activeRuntimeInput = void 0;
|
|
178
|
-
this.#activeRun = void 0;
|
|
179
|
-
await runAfterTurnHook(this.#hooks, {
|
|
180
|
-
history: this.#state.modelSnapshot(),
|
|
181
|
-
input,
|
|
182
|
-
result,
|
|
183
|
-
signal: activeAbort.signal
|
|
184
|
-
});
|
|
185
|
-
run.emit({ type: terminalEvent });
|
|
186
|
-
} catch (error) {
|
|
187
|
-
await emitTurnErrorAfterRecovery({
|
|
188
|
-
error: error instanceof Error ? error : new Error(String(error)),
|
|
189
|
-
historySnapshot,
|
|
190
|
-
run,
|
|
191
|
-
runtimeInput,
|
|
192
|
-
state: this.#state
|
|
193
|
-
});
|
|
194
|
-
} finally {
|
|
195
|
-
closeRuntimeInput(runtimeInput);
|
|
196
|
-
this.#activeAbort = void 0;
|
|
197
|
-
this.#activeRun = void 0;
|
|
198
|
-
this.#activeRuntimeInput = void 0;
|
|
199
|
-
this.#runToCloseOnKill = void 0;
|
|
200
|
-
run.close(void 0, runtimeInput.closedReason);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
182
|
};
|
|
204
183
|
//#endregion
|
|
205
184
|
export { AgentSession };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","names":["#hooks","#inputQueue","#llm","#pendingRuntimeInputs","#state","#killed","#deletePromise","#drainInputQueue","#activeRuntimeInput","#activeRun","#activeAbort","#enqueuePendingRuntimeInput","#runToCloseOnKill","#running","#processQueuedInput"],"sources":["../../src/session/session.ts"],"sourcesContent":["import { runAgentLoop } from \"../agent-loop\";\nimport type { AgentHooks } from \"../hooks\";\nimport type { Llm } from \"../llm\";\nimport type { AgentEvent } from \"./events\";\nimport type { AgentInput, UserInput } from \"./input\";\nimport { normalizeAgentInput } from \"./input-normalization\";\nimport { type AgentRun, BufferedAgentRun } from \"./run\";\nimport {\n addSteeringInput,\n closeRuntimeInput,\n createRuntimeInputState,\n hooksForRuntimeInput,\n type QueuedInput,\n type QueuedRuntimeInput,\n type RuntimeInputPlacement,\n type RuntimeInputState,\n withRuntimeInputWindow,\n withSteeringPlacement,\n} from \"./runtime-input\";\nimport {\n errorMessage,\n runAfterTurnHook,\n sessionKilledError,\n sessionTerminalError,\n} from \"./session-errors\";\nimport { closeKilledRuntimeInputs } from \"./session-kill\";\nimport { drainRuntimeInput } from \"./session-runtime-drain\";\nimport { type SessionPersistenceOptions, SessionState } from \"./session-state\";\nimport { emitTurnErrorAfterRecovery } from \"./session-turn-error\";\n\nexport type { AgentInput, SessionInput, UserInput } from \"./input\";\nexport type { AgentRun } from \"./run\";\n\nexport class AgentSession {\n readonly #hooks?: AgentHooks;\n readonly #inputQueue: QueuedInput[] = [];\n readonly #llm: Llm;\n readonly #pendingRuntimeInputs: QueuedRuntimeInput[] = [];\n readonly #state: SessionState;\n #activeAbort?: AbortController;\n #activeRun?: BufferedAgentRun;\n #activeRuntimeInput?: RuntimeInputState;\n #deletePromise?: Promise<void>;\n #killed = false;\n #running = false;\n #runToCloseOnKill?: BufferedAgentRun;\n\n constructor(\n llm: Llm,\n persistence: SessionPersistenceOptions,\n hooks?: AgentHooks\n ) {\n this.#hooks = hooks;\n this.#llm = llm;\n this.#state = new SessionState(persistence);\n }\n\n async send(input: AgentInput): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n await this.#state.ensureLoaded();\n\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n const runtimeInput = createRuntimeInputState(\n this.#pendingRuntimeInputs.splice(0)\n );\n const acceptedInput = normalizeAgentInput(input);\n const run = new BufferedAgentRun();\n run.emit(acceptedInput);\n this.#inputQueue.push({\n input: structuredClone(acceptedInput),\n run,\n runtimeInput,\n });\n this.#drainInputQueue().catch((error: unknown) => {\n run.emit({ type: \"turn-error\", message: errorMessage(error) });\n run.close();\n });\n return run;\n }\n\n async steer(input: AgentInput): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n const runtimeInput = this.#activeRuntimeInput;\n const run = this.#activeRun;\n if (!(runtimeInput && run)) {\n return this.send(input);\n }\n\n await addSteeringInput(runtimeInput, input);\n return run;\n }\n\n interrupt(): void {\n this.#activeAbort?.abort();\n }\n\n delete(): Promise<void> {\n this.#deletePromise ??= this.#state.delete().then(\n () => this.kill(),\n (error: unknown) => {\n this.#deletePromise = undefined;\n throw error;\n }\n );\n return this.#deletePromise;\n }\n\n enqueueRuntimeInput(\n input: UserInput,\n placement: RuntimeInputPlacement = \"turn-start\"\n ): void {\n if (this.#killed) {\n return;\n }\n\n const runtimeInput = this.#activeRuntimeInput;\n if (runtimeInput && !runtimeInput.closedReason) {\n if (placement === \"turn-start\" && runtimeInput.placement !== placement) {\n this.#enqueuePendingRuntimeInput({ input, placement });\n return;\n }\n\n runtimeInput.queue.push({ input, placement });\n return;\n }\n\n this.#enqueuePendingRuntimeInput({ input, placement });\n }\n\n emitObserverEvent(event: AgentEvent): void {\n this.#activeRun?.emit(event);\n }\n\n #enqueuePendingRuntimeInput(input: QueuedRuntimeInput): void {\n const queuedTurn = this.#inputQueue[0];\n if (input.placement === \"turn-start\" && queuedTurn) {\n queuedTurn.runtimeInput.queue.push(input);\n return;\n }\n\n this.#pendingRuntimeInputs.push(input);\n }\n\n kill(): void {\n if (this.#killed) {\n return;\n }\n\n this.#killed = true;\n const killedError = sessionKilledError();\n this.#pendingRuntimeInputs.length = 0;\n this.#activeAbort?.abort();\n closeKilledRuntimeInputs({\n activeRuntimeInput: this.#activeRuntimeInput,\n inputQueue: this.#inputQueue,\n message: killedError.message,\n runToClose: this.#runToCloseOnKill ?? this.#activeRun,\n });\n }\n\n async #drainInputQueue(): Promise<void> {\n if (this.#running) {\n return;\n }\n\n this.#running = true;\n try {\n while (!this.#killed && this.#inputQueue.length > 0) {\n const item = this.#inputQueue.shift();\n if (item) {\n await this.#processQueuedInput(item);\n }\n }\n } finally {\n this.#running = false;\n }\n }\n\n async #processQueuedInput({\n input,\n run,\n runtimeInput,\n }: QueuedInput): Promise<void> {\n const activeAbort = new AbortController();\n this.#activeAbort = activeAbort;\n this.#activeRun = run;\n this.#activeRuntimeInput = runtimeInput;\n this.#runToCloseOnKill = run;\n const historySnapshot = this.#state.modelSnapshot();\n\n try {\n await withSteeringPlacement(runtimeInput, \"turn-start\", async () => {\n await this.#hooks?.beforeTurn?.({\n history: this.#state.modelSnapshot(),\n input,\n signal: activeAbort.signal,\n });\n });\n await withRuntimeInputWindow(runtimeInput, \"turn-start\", async () => {\n await run.emitBoundary({ type: \"turn-start\" });\n });\n this.#state.appendUserInput(input);\n await this.#state.commit();\n await drainRuntimeInput({\n placement: \"turn-start\",\n run,\n runtimeInput,\n state: this.#state,\n });\n\n const result = await runAgentLoop({\n emit: async (event) => {\n if (event.type === \"step-start\" || event.type === \"step-end\") {\n await withRuntimeInputWindow(runtimeInput, event.type, async () => {\n await run.emitBoundary(event);\n });\n const runtimeInputAdded = await drainRuntimeInput({\n placement: event.type,\n run,\n runtimeInput,\n state: this.#state,\n });\n\n return event.type === \"step-end\"\n ? { runtimeInputAdded }\n : undefined;\n }\n\n run.emit(event);\n },\n history: this.#state.history,\n hooks: hooksForRuntimeInput(this.#hooks, runtimeInput),\n llm: this.#llm,\n signal: activeAbort.signal,\n });\n\n await this.#state.commit();\n const terminalEvent = result === \"aborted\" ? \"turn-abort\" : \"turn-end\";\n closeRuntimeInput(runtimeInput, terminalEvent);\n this.#activeRuntimeInput = undefined;\n this.#activeRun = undefined;\n await runAfterTurnHook(this.#hooks, {\n history: this.#state.modelSnapshot(),\n input,\n result,\n signal: activeAbort.signal,\n });\n run.emit({ type: terminalEvent });\n } catch (error) {\n const turnError =\n error instanceof Error ? error : new Error(String(error));\n await emitTurnErrorAfterRecovery({\n error: turnError,\n historySnapshot,\n run,\n runtimeInput,\n state: this.#state,\n });\n } finally {\n closeRuntimeInput(runtimeInput);\n this.#activeAbort = undefined;\n this.#activeRun = undefined;\n this.#activeRuntimeInput = undefined;\n this.#runToCloseOnKill = undefined;\n run.close(undefined, runtimeInput.closedReason);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session.js","names":["#events","#execution","#inputQueue","#llm","#pendingRuntimeInputs","#sessionKey","#state","#activeAbort","#killed","#deletePromise","#drainInputQueue","#activeRun","#activeRuntimeInput","#activeTurnId","#enqueuePendingRuntimeInput","#runToCloseOnKill","#running"],"sources":["../../src/session/session.ts"],"sourcesContent":["import type { RuntimeLlm } from \"../llm\";\nimport type { AgentPlugin } from \"../plugins\";\nimport type { AgentEvent } from \"./events\";\nimport type { AgentInput, UserInput } from \"./input\";\nimport { attachInputMeta, userInputFromEvent } from \"./input-meta\";\nimport { normalizeAgentInput } from \"./input-normalization\";\nimport { type AgentRun, BufferedAgentRun } from \"./run\";\nimport {\n addSteeringInput,\n createRuntimeInputState,\n type QueuedInput,\n type QueuedRuntimeInput,\n queueRuntimeInput,\n type RuntimeInputPlacement,\n type RuntimeInputState,\n} from \"./runtime-input\";\nimport { sessionKilledError, sessionTerminalError } from \"./session-errors\";\nimport { SessionEventDispatcher } from \"./session-events\";\nimport type { SessionExecutionOptions } from \"./session-execution\";\nimport { closeKilledRuntimeInputs } from \"./session-kill\";\nimport {\n type NotifyOptions,\n queueSessionNotification,\n startSessionQueueDrain,\n} from \"./session-notification\";\nimport { type SessionPersistenceOptions, SessionState } from \"./session-state\";\nimport { processQueuedInput } from \"./session-turn-processor\";\n\nexport type { AgentInput, SessionInput, UserInput } from \"./input\";\nexport type { AgentRun } from \"./run\";\nexport type { NotifyOptions } from \"./session-notification\";\n\nexport class AgentSession {\n readonly #events: SessionEventDispatcher;\n readonly #execution: SessionExecutionOptions;\n readonly #inputQueue: QueuedInput[] = [];\n readonly #llm: RuntimeLlm;\n readonly #pendingRuntimeInputs: QueuedRuntimeInput[] = [];\n readonly #sessionKey: string;\n readonly #state: SessionState;\n #activeAbort?: AbortController;\n #activeRun?: BufferedAgentRun;\n #activeRuntimeInput?: RuntimeInputState;\n #activeTurnId?: string;\n #deletePromise?: Promise<void>;\n #killed = false;\n #running = false;\n #runToCloseOnKill?: BufferedAgentRun;\n\n constructor(\n llm: RuntimeLlm,\n persistence: SessionPersistenceOptions,\n plugins: readonly AgentPlugin[] = [],\n execution: SessionExecutionOptions = {}\n ) {\n this.#llm = llm;\n this.#execution = execution;\n this.#sessionKey = persistence.key;\n this.#state = new SessionState(persistence);\n this.#events = new SessionEventDispatcher({\n history: () => this.#state.modelSnapshot(),\n plugins,\n signal: () => this.#activeAbort?.signal,\n });\n }\n\n async send(input: AgentInput): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n await this.#state.ensureLoaded();\n\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n const runtimeInput = createRuntimeInputState(\n this.#pendingRuntimeInputs.splice(0)\n );\n const normalized = normalizeAgentInput(input);\n const acceptedInput =\n normalized.meta === undefined\n ? attachInputMeta(normalized, { source: \"send\" })\n : normalized;\n const run = new BufferedAgentRun();\n const emitted = await this.#events.emitRunEvent(run, acceptedInput);\n if (emitted === \"handled\") {\n run.close();\n return run;\n }\n\n const queuedInput = userInputFromEvent(\n emitted.type === \"user-text\" || emitted.type === \"user-message\"\n ? emitted\n : acceptedInput\n );\n this.#inputQueue.push({\n initialEvents: [],\n input: structuredClone(queuedInput),\n preUserRuntimeInputs: [],\n run,\n runtimeInput,\n });\n startSessionQueueDrain(run, () => this.#drainInputQueue());\n return run;\n }\n\n async notify(\n input: AgentInput,\n options: NotifyOptions = {}\n ): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n await this.#state.ensureLoaded();\n\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n return queueSessionNotification(input, options, {\n activeRun: this.#activeRun,\n activeRuntimeInput: this.#activeRuntimeInput,\n drain: () => this.#drainInputQueue(),\n inputQueue: this.#inputQueue,\n pendingRuntimeInputs: this.#pendingRuntimeInputs,\n });\n }\n\n async steer(input: AgentInput): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n const runtimeInput = this.#activeRuntimeInput;\n const run = this.#activeRun;\n if (!(runtimeInput && run)) {\n return this.send(input);\n }\n\n await addSteeringInput(runtimeInput, input);\n return run;\n }\n\n interrupt(): void {\n this.#activeAbort?.abort();\n }\n\n currentTurnId(): string | undefined {\n return this.#activeTurnId;\n }\n\n delete(): Promise<void> {\n if (!this.#deletePromise) {\n this.kill();\n this.#deletePromise = this.#state.delete().catch((error: unknown) => {\n this.#deletePromise = undefined;\n throw error;\n });\n }\n return this.#deletePromise;\n }\n\n enqueueRuntimeInput(\n input: UserInput,\n placement: RuntimeInputPlacement = \"turn-start\"\n ): void {\n if (this.#killed) {\n return;\n }\n\n const runtimeInput = this.#activeRuntimeInput;\n if (runtimeInput && !runtimeInput.closedReason) {\n if (placement === \"turn-start\" && runtimeInput.placement !== placement) {\n this.#enqueuePendingRuntimeInput({ input, placement });\n return;\n }\n\n queueRuntimeInput(runtimeInput, { input, placement });\n return;\n }\n\n this.#enqueuePendingRuntimeInput({ input, placement });\n }\n\n emitObserverEvent(event: AgentEvent): Promise<void> {\n return this.#events.emitObserverEvent(this.#activeRun, event);\n }\n\n #enqueuePendingRuntimeInput(input: QueuedRuntimeInput): void {\n const queuedTurn = this.#inputQueue[0];\n if (input.placement === \"turn-start\" && queuedTurn) {\n queueRuntimeInput(queuedTurn.runtimeInput, input);\n return;\n }\n\n this.#pendingRuntimeInputs.push(input);\n }\n\n kill(): void {\n if (this.#killed) {\n return;\n }\n\n this.#killed = true;\n const killedError = sessionKilledError();\n this.#pendingRuntimeInputs.length = 0;\n this.#activeAbort?.abort();\n closeKilledRuntimeInputs({\n activeRuntimeInput: this.#activeRuntimeInput,\n inputQueue: this.#inputQueue,\n message: killedError.message,\n runToClose: this.#runToCloseOnKill ?? this.#activeRun,\n });\n }\n\n async #drainInputQueue(): Promise<void> {\n if (this.#running) {\n return;\n }\n\n this.#running = true;\n try {\n while (!this.#killed && this.#inputQueue.length > 0) {\n const item = this.#inputQueue.shift();\n if (item) {\n await processQueuedInput({\n activate: ({ abort, run, runtimeInput, turnId }) => {\n this.#activeAbort = abort;\n this.#activeRun = run;\n this.#activeRuntimeInput = runtimeInput;\n this.#activeTurnId = turnId;\n this.#runToCloseOnKill = run;\n },\n deactivateRun: () => {\n this.#activeRun = undefined;\n this.#activeRuntimeInput = undefined;\n },\n events: this.#events,\n execution: this.#execution,\n item,\n llm: this.#llm,\n release: () => {\n this.#activeAbort = undefined;\n this.#activeRun = undefined;\n this.#activeRuntimeInput = undefined;\n this.#activeTurnId = undefined;\n this.#runToCloseOnKill = undefined;\n },\n sessionKey: this.#sessionKey,\n state: this.#state,\n });\n }\n }\n } finally {\n this.#running = false;\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","names":[],"sources":["../../src/session/snapshot.ts"],"sourcesContent":["import type { ModelMessage } from \"ai\";\nimport type { StoredSession } from \"./store/types\";\n\nexport interface AgentSessionSnapshotV1 {\n readonly history: ModelMessage[];\n readonly schemaVersion: 1;\n}\n\nexport
|
|
1
|
+
{"version":3,"file":"snapshot.js","names":[],"sources":["../../src/session/snapshot.ts"],"sourcesContent":["import type { ModelMessage } from \"ai\";\nimport type { StoredSession } from \"./store/types\";\n\nexport interface AgentSessionSnapshotV1 {\n readonly history: ModelMessage[];\n readonly schemaVersion: 1;\n}\n\nexport function encodeSessionSnapshot(\n history: ModelMessage[]\n): AgentSessionSnapshotV1 {\n return { schemaVersion: 1, history: structuredClone(history) };\n}\n\nexport function decodeStoredSessionSnapshot(\n stored: StoredSession | null\n): ModelMessage[] {\n if (!stored) {\n return [];\n }\n\n const snapshot = stored.state;\n if (isSessionSnapshotV1(snapshot)) {\n return structuredClone(snapshot.history);\n }\n\n throw new Error(\"Unsupported stored session state\");\n}\n\nfunction isSessionSnapshotV1(value: unknown): value is AgentSessionSnapshotV1 {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"schemaVersion\" in value &&\n value.schemaVersion === 1 &&\n \"history\" in value &&\n Array.isArray(value.history)\n );\n}\n"],"mappings":";AAQA,SAAgB,sBACd,SACwB;CACxB,OAAO;EAAE,eAAe;EAAG,SAAS,gBAAgB,OAAO;CAAE;AAC/D;AAEA,SAAgB,4BACd,QACgB;CAChB,IAAI,CAAC,QACH,OAAO,CAAC;CAGV,MAAM,WAAW,OAAO;CACxB,IAAI,oBAAoB,QAAQ,GAC9B,OAAO,gBAAgB,SAAS,OAAO;CAGzC,MAAM,IAAI,MAAM,kCAAkC;AACpD;AAEA,SAAS,oBAAoB,OAAiD;CAC5E,OACE,UAAU,QACV,OAAO,UAAU,YACjB,mBAAmB,SACnB,MAAM,kBAAkB,KACxB,aAAa,SACb,MAAM,QAAQ,MAAM,OAAO;AAE/B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@minpeter/pss-runtime",
|
|
3
|
-
"version": "0.1.0-next.
|
|
3
|
+
"version": "0.1.0-next.3",
|
|
4
4
|
"description": "Generic agent runtime for sessions, model loops, and synchronized run events.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,6 +20,21 @@
|
|
|
20
20
|
"@minpeter/pss-source": "./src/session/store/file.ts",
|
|
21
21
|
"types": "./dist/session/store/file.d.ts",
|
|
22
22
|
"import": "./dist/session/store/file.js"
|
|
23
|
+
},
|
|
24
|
+
"./cloudflare": {
|
|
25
|
+
"@minpeter/pss-source": "./src/cloudflare/index.ts",
|
|
26
|
+
"types": "./dist/cloudflare/index.d.ts",
|
|
27
|
+
"import": "./dist/cloudflare/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./execution": {
|
|
30
|
+
"@minpeter/pss-source": "./src/execution/index.ts",
|
|
31
|
+
"types": "./dist/execution/index.d.ts",
|
|
32
|
+
"import": "./dist/execution/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./execution/memory": {
|
|
35
|
+
"@minpeter/pss-source": "./src/execution/memory.ts",
|
|
36
|
+
"types": "./dist/execution/memory.d.ts",
|
|
37
|
+
"import": "./dist/execution/memory.js"
|
|
23
38
|
}
|
|
24
39
|
},
|
|
25
40
|
"files": [
|
package/dist/agent-validation.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
//#region src/agent-validation.ts
|
|
2
|
-
const subagentNamePattern = /^[a-z][a-z0-9_-]{0,51}$/;
|
|
3
|
-
function assertSubagents(options, agentClass, hasCustomLlm) {
|
|
4
|
-
if (!("subagents" in options) || options.subagents === void 0) return;
|
|
5
|
-
if (hasCustomLlm) throw new TypeError("Agent: subagents require options.model.");
|
|
6
|
-
if (!Array.isArray(options.subagents)) throw new TypeError("Agent: subagents must be an array.");
|
|
7
|
-
assertSubagentTools(options.subagents, agentClass, options.tools ?? {});
|
|
8
|
-
}
|
|
9
|
-
function assertSubagentTools(subagents, agentClass, tools) {
|
|
10
|
-
const toolNames = new Set(Object.keys(tools));
|
|
11
|
-
const generatedToolNames = /* @__PURE__ */ new Set();
|
|
12
|
-
for (const [index, subagent] of subagents.entries()) {
|
|
13
|
-
const toolName = `delegate_to_${assertSubagentMetadata(subagent, index, agentClass).replaceAll("-", "_")}`;
|
|
14
|
-
if (toolNames.has(toolName)) throw new TypeError(`Agent: subagent tool ${toolName} collides with an existing tool.`);
|
|
15
|
-
if (generatedToolNames.has(toolName)) throw new TypeError(`Agent: duplicate subagent tool name ${toolName}.`);
|
|
16
|
-
generatedToolNames.add(toolName);
|
|
17
|
-
}
|
|
18
|
-
for (const reservedToolName of ["background_output", "background_cancel"]) if (toolNames.has(reservedToolName)) throw new TypeError(`Agent: ${reservedToolName} collides with a reserved subagent tool.`);
|
|
19
|
-
}
|
|
20
|
-
function assertSubagentMetadata(subagent, index, agentClass) {
|
|
21
|
-
if (!(subagent instanceof agentClass)) throw new TypeError(`Agent: subagents[${index}] must be an Agent.`);
|
|
22
|
-
if (!isValidSubagentName(subagent.name)) throw new TypeError(`Agent: subagents[${index}].name is required or too long.`);
|
|
23
|
-
if (!isNonEmptyText(subagent.description)) throw new TypeError(`Agent: subagents[${index}].description is required.`);
|
|
24
|
-
return subagent.name;
|
|
25
|
-
}
|
|
26
|
-
function isNonEmptyText(value) {
|
|
27
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
28
|
-
}
|
|
29
|
-
function isValidSubagentName(value) {
|
|
30
|
-
return typeof value === "string" && subagentNamePattern.test(value);
|
|
31
|
-
}
|
|
32
|
-
//#endregion
|
|
33
|
-
export { assertSubagents };
|
|
34
|
-
|
|
35
|
-
//# sourceMappingURL=agent-validation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-validation.js","names":[],"sources":["../src/agent-validation.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport type { Agent, AgentOptions } from \"./agent\";\n\nconst subagentNamePattern = /^[a-z][a-z0-9_-]{0,51}$/;\n\nexport function assertSubagents(\n options: AgentOptions,\n agentClass: new (options: AgentOptions) => Agent,\n hasCustomLlm: boolean\n): void {\n if (!(\"subagents\" in options) || options.subagents === undefined) {\n return;\n }\n\n if (hasCustomLlm) {\n throw new TypeError(\"Agent: subagents require options.model.\");\n }\n\n if (!Array.isArray(options.subagents)) {\n throw new TypeError(\"Agent: subagents must be an array.\");\n }\n\n assertSubagentTools(options.subagents, agentClass, options.tools ?? {});\n}\n\nfunction assertSubagentTools(\n subagents: readonly Agent[],\n agentClass: new (options: AgentOptions) => Agent,\n tools: ToolSet\n): void {\n const toolNames = new Set(Object.keys(tools));\n const generatedToolNames = new Set<string>();\n for (const [index, subagent] of subagents.entries()) {\n const name = assertSubagentMetadata(subagent, index, agentClass);\n const toolName = `delegate_to_${name.replaceAll(\"-\", \"_\")}`;\n if (toolNames.has(toolName)) {\n throw new TypeError(\n `Agent: subagent tool ${toolName} collides with an existing tool.`\n );\n }\n\n if (generatedToolNames.has(toolName)) {\n throw new TypeError(`Agent: duplicate subagent tool name ${toolName}.`);\n }\n\n generatedToolNames.add(toolName);\n }\n\n for (const reservedToolName of [\"background_output\", \"background_cancel\"]) {\n if (toolNames.has(reservedToolName)) {\n throw new TypeError(\n `Agent: ${reservedToolName} collides with a reserved subagent tool.`\n );\n }\n }\n}\n\nfunction assertSubagentMetadata(\n subagent: Agent,\n index: number,\n agentClass: new (options: AgentOptions) => Agent\n): string {\n if (!(subagent instanceof agentClass)) {\n throw new TypeError(`Agent: subagents[${index}] must be an Agent.`);\n }\n\n if (!isValidSubagentName(subagent.name)) {\n throw new TypeError(\n `Agent: subagents[${index}].name is required or too long.`\n );\n }\n\n if (!isNonEmptyText(subagent.description)) {\n throw new TypeError(`Agent: subagents[${index}].description is required.`);\n }\n\n return subagent.name;\n}\n\nfunction isNonEmptyText(value: string | undefined): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction isValidSubagentName(value: string | undefined): value is string {\n return typeof value === \"string\" && subagentNamePattern.test(value);\n}\n"],"mappings":";AAGA,MAAM,sBAAsB;AAE5B,SAAgB,gBACd,SACA,YACA,cACM;CACN,IAAI,EAAE,eAAe,YAAY,QAAQ,cAAc,KAAA,GACrD;CAGF,IAAI,cACF,MAAM,IAAI,UAAU,yCAAyC;CAG/D,IAAI,CAAC,MAAM,QAAQ,QAAQ,SAAS,GAClC,MAAM,IAAI,UAAU,oCAAoC;CAG1D,oBAAoB,QAAQ,WAAW,YAAY,QAAQ,SAAS,CAAC,CAAC;AACxE;AAEA,SAAS,oBACP,WACA,YACA,OACM;CACN,MAAM,YAAY,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC;CAC5C,MAAM,qCAAqB,IAAI,IAAY;CAC3C,KAAK,MAAM,CAAC,OAAO,aAAa,UAAU,QAAQ,GAAG;EAEnD,MAAM,WAAW,eADJ,uBAAuB,UAAU,OAAO,UAClB,EAAE,WAAW,KAAK,GAAG;EACxD,IAAI,UAAU,IAAI,QAAQ,GACxB,MAAM,IAAI,UACR,wBAAwB,SAAS,iCACnC;EAGF,IAAI,mBAAmB,IAAI,QAAQ,GACjC,MAAM,IAAI,UAAU,uCAAuC,SAAS,EAAE;EAGxE,mBAAmB,IAAI,QAAQ;CACjC;CAEA,KAAK,MAAM,oBAAoB,CAAC,qBAAqB,mBAAmB,GACtE,IAAI,UAAU,IAAI,gBAAgB,GAChC,MAAM,IAAI,UACR,UAAU,iBAAiB,yCAC7B;AAGN;AAEA,SAAS,uBACP,UACA,OACA,YACQ;CACR,IAAI,EAAE,oBAAoB,aACxB,MAAM,IAAI,UAAU,oBAAoB,MAAM,oBAAoB;CAGpE,IAAI,CAAC,oBAAoB,SAAS,IAAI,GACpC,MAAM,IAAI,UACR,oBAAoB,MAAM,gCAC5B;CAGF,IAAI,CAAC,eAAe,SAAS,WAAW,GACtC,MAAM,IAAI,UAAU,oBAAoB,MAAM,2BAA2B;CAG3E,OAAO,SAAS;AAClB;AAEA,SAAS,eAAe,OAA4C;CAClE,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS;AAC5D;AAEA,SAAS,oBAAoB,OAA4C;CACvE,OAAO,OAAO,UAAU,YAAY,oBAAoB,KAAK,KAAK;AACpE"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
//#region src/child-session-cleanups.ts
|
|
2
|
-
var ChildSessionCleanups = class {
|
|
3
|
-
#byParentSession = /* @__PURE__ */ new Map();
|
|
4
|
-
async delete(parentSessionKey) {
|
|
5
|
-
const cleanups = this.#byParentSession.get(parentSessionKey);
|
|
6
|
-
if (!cleanups) return;
|
|
7
|
-
this.#byParentSession.delete(parentSessionKey);
|
|
8
|
-
const results = await Promise.all([...cleanups].map(runCleanup));
|
|
9
|
-
const failedCleanups = [];
|
|
10
|
-
let firstError;
|
|
11
|
-
for (const result of results) {
|
|
12
|
-
if (result.ok) continue;
|
|
13
|
-
firstError ??= result.error;
|
|
14
|
-
failedCleanups.push(result.cleanup);
|
|
15
|
-
}
|
|
16
|
-
if (failedCleanups.length === 0) return;
|
|
17
|
-
this.#restore(parentSessionKey, failedCleanups);
|
|
18
|
-
throw firstError instanceof Error ? firstError : new Error(String(firstError));
|
|
19
|
-
}
|
|
20
|
-
register(parentSessionKey, cleanup) {
|
|
21
|
-
const existing = this.#byParentSession.get(parentSessionKey);
|
|
22
|
-
if (existing) {
|
|
23
|
-
existing.add(cleanup);
|
|
24
|
-
return () => this.#unregister(parentSessionKey, existing, cleanup);
|
|
25
|
-
}
|
|
26
|
-
const cleanups = new Set([cleanup]);
|
|
27
|
-
this.#byParentSession.set(parentSessionKey, cleanups);
|
|
28
|
-
return () => this.#unregister(parentSessionKey, cleanups, cleanup);
|
|
29
|
-
}
|
|
30
|
-
#unregister(parentSessionKey, cleanups, cleanup) {
|
|
31
|
-
cleanups.delete(cleanup);
|
|
32
|
-
if (cleanups.size === 0 && this.#byParentSession.get(parentSessionKey) === cleanups) this.#byParentSession.delete(parentSessionKey);
|
|
33
|
-
}
|
|
34
|
-
#restore(parentSessionKey, failedCleanups) {
|
|
35
|
-
const current = this.#byParentSession.get(parentSessionKey);
|
|
36
|
-
if (current) {
|
|
37
|
-
for (const cleanup of failedCleanups) current.add(cleanup);
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
this.#byParentSession.set(parentSessionKey, new Set(failedCleanups));
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
async function runCleanup(cleanup) {
|
|
44
|
-
try {
|
|
45
|
-
await cleanup();
|
|
46
|
-
return {
|
|
47
|
-
cleanup,
|
|
48
|
-
ok: true
|
|
49
|
-
};
|
|
50
|
-
} catch (error) {
|
|
51
|
-
return {
|
|
52
|
-
cleanup,
|
|
53
|
-
error,
|
|
54
|
-
ok: false
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
//#endregion
|
|
59
|
-
export { ChildSessionCleanups };
|
|
60
|
-
|
|
61
|
-
//# sourceMappingURL=child-session-cleanups.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"child-session-cleanups.js","names":["#byParentSession","#restore","#unregister"],"sources":["../src/child-session-cleanups.ts"],"sourcesContent":["type ChildSessionCleanup = () => Promise<void>;\n\ntype CleanupResult =\n | { readonly cleanup: ChildSessionCleanup; readonly ok: true }\n | {\n readonly cleanup: ChildSessionCleanup;\n readonly error: unknown;\n readonly ok: false;\n };\n\nexport class ChildSessionCleanups {\n readonly #byParentSession = new Map<string, Set<ChildSessionCleanup>>();\n\n async delete(parentSessionKey: string): Promise<void> {\n const cleanups = this.#byParentSession.get(parentSessionKey);\n if (!cleanups) {\n return;\n }\n\n this.#byParentSession.delete(parentSessionKey);\n const results = await Promise.all([...cleanups].map(runCleanup));\n const failedCleanups: ChildSessionCleanup[] = [];\n let firstError: unknown;\n for (const result of results) {\n if (result.ok) {\n continue;\n }\n\n firstError ??= result.error;\n failedCleanups.push(result.cleanup);\n }\n\n if (failedCleanups.length === 0) {\n return;\n }\n\n this.#restore(parentSessionKey, failedCleanups);\n throw firstError instanceof Error\n ? firstError\n : new Error(String(firstError));\n }\n\n register(parentSessionKey: string, cleanup: ChildSessionCleanup): () => void {\n const existing = this.#byParentSession.get(parentSessionKey);\n if (existing) {\n existing.add(cleanup);\n return () => this.#unregister(parentSessionKey, existing, cleanup);\n }\n\n const cleanups = new Set([cleanup]);\n this.#byParentSession.set(parentSessionKey, cleanups);\n return () => this.#unregister(parentSessionKey, cleanups, cleanup);\n }\n\n #unregister(\n parentSessionKey: string,\n cleanups: Set<ChildSessionCleanup>,\n cleanup: ChildSessionCleanup\n ): void {\n cleanups.delete(cleanup);\n if (\n cleanups.size === 0 &&\n this.#byParentSession.get(parentSessionKey) === cleanups\n ) {\n this.#byParentSession.delete(parentSessionKey);\n }\n }\n\n #restore(\n parentSessionKey: string,\n failedCleanups: readonly ChildSessionCleanup[]\n ): void {\n const current = this.#byParentSession.get(parentSessionKey);\n if (current) {\n for (const cleanup of failedCleanups) {\n current.add(cleanup);\n }\n return;\n }\n\n this.#byParentSession.set(parentSessionKey, new Set(failedCleanups));\n }\n}\n\nasync function runCleanup(\n cleanup: ChildSessionCleanup\n): Promise<CleanupResult> {\n try {\n await cleanup();\n return { cleanup, ok: true };\n } catch (error) {\n return { cleanup, error, ok: false };\n }\n}\n"],"mappings":";AAUA,IAAa,uBAAb,MAAkC;CAChC,mCAA4B,IAAI,IAAsC;CAEtE,MAAM,OAAO,kBAAyC;EACpD,MAAM,WAAW,KAAKA,iBAAiB,IAAI,gBAAgB;EAC3D,IAAI,CAAC,UACH;EAGF,KAAKA,iBAAiB,OAAO,gBAAgB;EAC7C,MAAM,UAAU,MAAM,QAAQ,IAAI,CAAC,GAAG,QAAQ,EAAE,IAAI,UAAU,CAAC;EAC/D,MAAM,iBAAwC,CAAC;EAC/C,IAAI;EACJ,KAAK,MAAM,UAAU,SAAS;GAC5B,IAAI,OAAO,IACT;GAGF,eAAe,OAAO;GACtB,eAAe,KAAK,OAAO,OAAO;EACpC;EAEA,IAAI,eAAe,WAAW,GAC5B;EAGF,KAAKC,SAAS,kBAAkB,cAAc;EAC9C,MAAM,sBAAsB,QACxB,aACA,IAAI,MAAM,OAAO,UAAU,CAAC;CAClC;CAEA,SAAS,kBAA0B,SAA0C;EAC3E,MAAM,WAAW,KAAKD,iBAAiB,IAAI,gBAAgB;EAC3D,IAAI,UAAU;GACZ,SAAS,IAAI,OAAO;GACpB,aAAa,KAAKE,YAAY,kBAAkB,UAAU,OAAO;EACnE;EAEA,MAAM,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC;EAClC,KAAKF,iBAAiB,IAAI,kBAAkB,QAAQ;EACpD,aAAa,KAAKE,YAAY,kBAAkB,UAAU,OAAO;CACnE;CAEA,YACE,kBACA,UACA,SACM;EACN,SAAS,OAAO,OAAO;EACvB,IACE,SAAS,SAAS,KAClB,KAAKF,iBAAiB,IAAI,gBAAgB,MAAM,UAEhD,KAAKA,iBAAiB,OAAO,gBAAgB;CAEjD;CAEA,SACE,kBACA,gBACM;EACN,MAAM,UAAU,KAAKA,iBAAiB,IAAI,gBAAgB;EAC1D,IAAI,SAAS;GACX,KAAK,MAAM,WAAW,gBACpB,QAAQ,IAAI,OAAO;GAErB;EACF;EAEA,KAAKA,iBAAiB,IAAI,kBAAkB,IAAI,IAAI,cAAc,CAAC;CACrE;AACF;AAEA,eAAe,WACb,SACwB;CACxB,IAAI;EACF,MAAM,QAAQ;EACd,OAAO;GAAE;GAAS,IAAI;EAAK;CAC7B,SAAS,OAAO;EACd,OAAO;GAAE;GAAS;GAAO,IAAI;EAAM;CACrC;AACF"}
|
package/dist/hooks.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { RuntimeLlmContext } from "./llm.js";
|
|
2
|
-
import { UserInput } from "./session/input.js";
|
|
3
|
-
|
|
4
|
-
//#region src/hooks.d.ts
|
|
5
|
-
type AgentTurnResult = "aborted" | "completed";
|
|
6
|
-
type AgentStepResult = "completed" | "continue";
|
|
7
|
-
type MaybePromise<T> = PromiseLike<T> | T;
|
|
8
|
-
interface AgentBeforeTurnContext {
|
|
9
|
-
readonly history: RuntimeLlmContext["history"];
|
|
10
|
-
readonly input: UserInput;
|
|
11
|
-
readonly signal: AbortSignal;
|
|
12
|
-
}
|
|
13
|
-
interface AgentAfterTurnContext extends AgentBeforeTurnContext {
|
|
14
|
-
readonly result: AgentTurnResult;
|
|
15
|
-
}
|
|
16
|
-
interface AgentBeforeStepContext {
|
|
17
|
-
readonly history: RuntimeLlmContext["history"];
|
|
18
|
-
readonly signal: AbortSignal;
|
|
19
|
-
readonly stepIndex: number;
|
|
20
|
-
}
|
|
21
|
-
interface AgentAfterStepContext extends AgentBeforeStepContext {
|
|
22
|
-
readonly result: AgentStepResult;
|
|
23
|
-
}
|
|
24
|
-
interface AgentHooks {
|
|
25
|
-
afterStep?(context: AgentAfterStepContext): MaybePromise<void>;
|
|
26
|
-
afterTurn?(context: AgentAfterTurnContext): MaybePromise<void>;
|
|
27
|
-
beforeStep?(context: AgentBeforeStepContext): MaybePromise<void>;
|
|
28
|
-
beforeTurn?(context: AgentBeforeTurnContext): MaybePromise<void>;
|
|
29
|
-
}
|
|
30
|
-
//#endregion
|
|
31
|
-
export { AgentAfterStepContext, AgentAfterTurnContext, AgentBeforeStepContext, AgentBeforeTurnContext, AgentHooks, AgentStepResult, AgentTurnResult };
|
|
32
|
-
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { assertBackgroundTaskId, cancelJob, isActiveJob } from "./subagent-jobs.js";
|
|
2
|
-
import { jsonSchema, tool } from "ai";
|
|
3
|
-
//#region src/subagent-job-cancel.ts
|
|
4
|
-
function createBackgroundCancelTool(jobs) {
|
|
5
|
-
return tool({
|
|
6
|
-
description: "Cancel an active background subagent job.",
|
|
7
|
-
execute: (input) => {
|
|
8
|
-
assertBackgroundTaskId(input.task_id, "background_cancel");
|
|
9
|
-
const job = jobs.get(input.task_id);
|
|
10
|
-
if (!job) throw new Error(`Unknown background subagent task ${input.task_id}.`);
|
|
11
|
-
if (isActiveJob(job.status)) cancelJob(job);
|
|
12
|
-
return {
|
|
13
|
-
status: job.status,
|
|
14
|
-
task_id: job.id
|
|
15
|
-
};
|
|
16
|
-
},
|
|
17
|
-
inputSchema: jsonSchema({
|
|
18
|
-
additionalProperties: false,
|
|
19
|
-
properties: { task_id: { type: "string" } },
|
|
20
|
-
required: ["task_id"],
|
|
21
|
-
type: "object"
|
|
22
|
-
})
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
//#endregion
|
|
26
|
-
export { createBackgroundCancelTool };
|
|
27
|
-
|
|
28
|
-
//# sourceMappingURL=subagent-job-cancel.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"subagent-job-cancel.js","names":[],"sources":["../src/subagent-job-cancel.ts"],"sourcesContent":["import { jsonSchema, tool } from \"ai\";\nimport {\n assertBackgroundTaskId,\n cancelJob,\n isActiveJob,\n} from \"./subagent-jobs\";\nimport type { BackgroundCancelInput, SubagentJob } from \"./subagent-types\";\n\nexport function createBackgroundCancelTool(jobs: Map<string, SubagentJob>) {\n return tool<BackgroundCancelInput, unknown, Record<string, unknown>>({\n description: \"Cancel an active background subagent job.\",\n execute: (input: BackgroundCancelInput) => {\n assertBackgroundTaskId(input.task_id, \"background_cancel\");\n const job = jobs.get(input.task_id);\n if (!job) {\n throw new Error(`Unknown background subagent task ${input.task_id}.`);\n }\n\n if (isActiveJob(job.status)) {\n cancelJob(job);\n }\n\n return {\n status: job.status,\n task_id: job.id,\n };\n },\n inputSchema: jsonSchema<BackgroundCancelInput>({\n additionalProperties: false,\n properties: {\n task_id: { type: \"string\" },\n },\n required: [\"task_id\"],\n type: \"object\",\n }),\n });\n}\n"],"mappings":";;;AAQA,SAAgB,2BAA2B,MAAgC;CACzE,OAAO,KAA8D;EACnE,aAAa;EACb,UAAU,UAAiC;GACzC,uBAAuB,MAAM,SAAS,mBAAmB;GACzD,MAAM,MAAM,KAAK,IAAI,MAAM,OAAO;GAClC,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,oCAAoC,MAAM,QAAQ,EAAE;GAGtE,IAAI,YAAY,IAAI,MAAM,GACxB,UAAU,GAAG;GAGf,OAAO;IACL,QAAQ,IAAI;IACZ,SAAS,IAAI;GACf;EACF;EACA,aAAa,WAAkC;GAC7C,sBAAsB;GACtB,YAAY,EACV,SAAS,EAAE,MAAM,SAAS,EAC5B;GACA,UAAU,CAAC,SAAS;GACpB,MAAM;EACR,CAAC;CACH,CAAC;AACH"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { assertBackgroundTaskId, cleanupJob, isActiveJob } from "./subagent-jobs.js";
|
|
2
|
-
import { jsonSchema, tool } from "ai";
|
|
3
|
-
//#region src/subagent-job-output.ts
|
|
4
|
-
function createBackgroundOutputTool(jobs) {
|
|
5
|
-
return tool({
|
|
6
|
-
description: "Retrieve compact output for a background subagent job.",
|
|
7
|
-
execute: async (input, { abortSignal }) => {
|
|
8
|
-
assertBackgroundTaskId(input.task_id, "background_output");
|
|
9
|
-
const job = jobs.get(input.task_id);
|
|
10
|
-
if (!job) throw new Error(`Unknown background subagent task ${input.task_id}.`);
|
|
11
|
-
if (input.block === true && isActiveJob(job.status)) await waitForJob(job, input.timeout, abortSignal);
|
|
12
|
-
const output = {
|
|
13
|
-
result: job.result,
|
|
14
|
-
status: job.status,
|
|
15
|
-
subagent: job.subagent,
|
|
16
|
-
task_id: job.id
|
|
17
|
-
};
|
|
18
|
-
if (!(isActiveJob(job.status) || !job.settled)) {
|
|
19
|
-
if (await cleanupJob(job).then(() => true, () => false)) jobs.delete(job.id);
|
|
20
|
-
}
|
|
21
|
-
return output;
|
|
22
|
-
},
|
|
23
|
-
inputSchema: jsonSchema({
|
|
24
|
-
additionalProperties: false,
|
|
25
|
-
properties: {
|
|
26
|
-
block: { type: "boolean" },
|
|
27
|
-
task_id: { type: "string" },
|
|
28
|
-
timeout: {
|
|
29
|
-
minimum: 0,
|
|
30
|
-
type: "number"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
required: ["task_id"],
|
|
34
|
-
type: "object"
|
|
35
|
-
})
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
async function waitForJob(job, timeout, abortSignal) {
|
|
39
|
-
if (abortSignal?.aborted) return;
|
|
40
|
-
const timeoutMs = Math.min(timeout ?? 6e4, 6e5);
|
|
41
|
-
let timeoutId;
|
|
42
|
-
let abortListener;
|
|
43
|
-
const abortPromise = abortSignal ? new Promise((resolve) => {
|
|
44
|
-
abortListener = resolve;
|
|
45
|
-
abortSignal.addEventListener("abort", abortListener, { once: true });
|
|
46
|
-
}) : void 0;
|
|
47
|
-
try {
|
|
48
|
-
await Promise.race([
|
|
49
|
-
job.promise,
|
|
50
|
-
...abortPromise ? [abortPromise] : [],
|
|
51
|
-
new Promise((resolve) => {
|
|
52
|
-
timeoutId = setTimeout(resolve, timeoutMs);
|
|
53
|
-
})
|
|
54
|
-
]);
|
|
55
|
-
} finally {
|
|
56
|
-
if (timeoutId) clearTimeout(timeoutId);
|
|
57
|
-
if (abortListener) abortSignal?.removeEventListener("abort", abortListener);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
//#endregion
|
|
61
|
-
export { createBackgroundOutputTool };
|
|
62
|
-
|
|
63
|
-
//# sourceMappingURL=subagent-job-output.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"subagent-job-output.js","names":[],"sources":["../src/subagent-job-output.ts"],"sourcesContent":["import { jsonSchema, tool } from \"ai\";\nimport {\n assertBackgroundTaskId,\n cleanupJob,\n isActiveJob,\n} from \"./subagent-jobs\";\nimport type { BackgroundOutputInput, SubagentJob } from \"./subagent-types\";\n\nexport function createBackgroundOutputTool(jobs: Map<string, SubagentJob>) {\n return tool<BackgroundOutputInput, unknown, Record<string, unknown>>({\n description: \"Retrieve compact output for a background subagent job.\",\n execute: async (input: BackgroundOutputInput, { abortSignal }) => {\n assertBackgroundTaskId(input.task_id, \"background_output\");\n const job = jobs.get(input.task_id);\n if (!job) {\n throw new Error(`Unknown background subagent task ${input.task_id}.`);\n }\n\n if (input.block === true && isActiveJob(job.status)) {\n await waitForJob(job, input.timeout, abortSignal);\n }\n\n const output = {\n result: job.result,\n status: job.status,\n subagent: job.subagent,\n task_id: job.id,\n };\n if (!(isActiveJob(job.status) || !job.settled)) {\n const cleaned = await cleanupJob(job).then(\n () => true,\n () => false\n );\n if (cleaned) {\n jobs.delete(job.id);\n }\n }\n\n return output;\n },\n inputSchema: jsonSchema<BackgroundOutputInput>({\n additionalProperties: false,\n properties: {\n block: { type: \"boolean\" },\n task_id: { type: \"string\" },\n timeout: { minimum: 0, type: \"number\" },\n },\n required: [\"task_id\"],\n type: \"object\",\n }),\n });\n}\n\nasync function waitForJob(\n job: SubagentJob,\n timeout: number | undefined,\n abortSignal: AbortSignal | undefined\n) {\n if (abortSignal?.aborted) {\n return;\n }\n\n const timeoutMs = Math.min(timeout ?? 60_000, 600_000);\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n let abortListener: (() => void) | undefined;\n const abortPromise = abortSignal\n ? new Promise<void>((resolve) => {\n abortListener = resolve;\n abortSignal.addEventListener(\"abort\", abortListener, { once: true });\n })\n : undefined;\n try {\n await Promise.race([\n job.promise,\n ...(abortPromise ? [abortPromise] : []),\n new Promise<void>((resolve) => {\n timeoutId = setTimeout(resolve, timeoutMs);\n }),\n ]);\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n if (abortListener) {\n abortSignal?.removeEventListener(\"abort\", abortListener);\n }\n }\n}\n"],"mappings":";;;AAQA,SAAgB,2BAA2B,MAAgC;CACzE,OAAO,KAA8D;EACnE,aAAa;EACb,SAAS,OAAO,OAA8B,EAAE,kBAAkB;GAChE,uBAAuB,MAAM,SAAS,mBAAmB;GACzD,MAAM,MAAM,KAAK,IAAI,MAAM,OAAO;GAClC,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,oCAAoC,MAAM,QAAQ,EAAE;GAGtE,IAAI,MAAM,UAAU,QAAQ,YAAY,IAAI,MAAM,GAChD,MAAM,WAAW,KAAK,MAAM,SAAS,WAAW;GAGlD,MAAM,SAAS;IACb,QAAQ,IAAI;IACZ,QAAQ,IAAI;IACZ,UAAU,IAAI;IACd,SAAS,IAAI;GACf;GACA,IAAI,EAAE,YAAY,IAAI,MAAM,KAAK,CAAC,IAAI;QAKhC,MAJkB,WAAW,GAAG,EAAE,WAC9B,YACA,KACR,GAEE,KAAK,OAAO,IAAI,EAAE;GAAA;GAItB,OAAO;EACT;EACA,aAAa,WAAkC;GAC7C,sBAAsB;GACtB,YAAY;IACV,OAAO,EAAE,MAAM,UAAU;IACzB,SAAS,EAAE,MAAM,SAAS;IAC1B,SAAS;KAAE,SAAS;KAAG,MAAM;IAAS;GACxC;GACA,UAAU,CAAC,SAAS;GACpB,MAAM;EACR,CAAC;CACH,CAAC;AACH;AAEA,eAAe,WACb,KACA,SACA,aACA;CACA,IAAI,aAAa,SACf;CAGF,MAAM,YAAY,KAAK,IAAI,WAAW,KAAQ,GAAO;CACrD,IAAI;CACJ,IAAI;CACJ,MAAM,eAAe,cACjB,IAAI,SAAe,YAAY;EAC7B,gBAAgB;EAChB,YAAY,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;CACrE,CAAC,IACD,KAAA;CACJ,IAAI;EACF,MAAM,QAAQ,KAAK;GACjB,IAAI;GACJ,GAAI,eAAe,CAAC,YAAY,IAAI,CAAC;GACrC,IAAI,SAAe,YAAY;IAC7B,YAAY,WAAW,SAAS,SAAS;GAC3C,CAAC;EACH,CAAC;CACH,UAAU;EACR,IAAI,WACF,aAAa,SAAS;EAExB,IAAI,eACF,aAAa,oBAAoB,SAAS,aAAa;CAE3D;AACF"}
|