@minpeter/pss-runtime 0.1.0-next.0 → 0.1.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +223 -191
- package/dist/agent-child-runs.js +16 -0
- package/dist/agent-child-runs.js.map +1 -0
- package/dist/agent-host-capabilities.js +9 -0
- package/dist/agent-host-capabilities.js.map +1 -0
- package/dist/agent-host-session-store.js +12 -0
- package/dist/agent-host-session-store.js.map +1 -0
- package/dist/agent-loop.js +59 -35
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent-namespace.js +24 -0
- package/dist/agent-namespace.js.map +1 -0
- package/dist/agent-options.d.ts +35 -0
- package/dist/agent-options.js +16 -0
- package/dist/agent-options.js.map +1 -0
- package/dist/agent-resume.js +143 -0
- package/dist/agent-resume.js.map +1 -0
- package/dist/agent-session-entry.d.ts +13 -0
- package/dist/agent-validation.js +35 -0
- package/dist/agent-validation.js.map +1 -0
- package/dist/agent.d.ts +8 -33
- package/dist/agent.js +131 -55
- package/dist/agent.js.map +1 -1
- package/dist/child-session-cleanups.js +61 -0
- package/dist/child-session-cleanups.js.map +1 -0
- package/dist/execution/host.js +14 -0
- package/dist/execution/host.js.map +1 -0
- package/dist/execution/index.d.ts +4 -0
- package/dist/execution/index.js +3 -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/run.js +55 -0
- package/dist/execution/run.js.map +1 -0
- package/dist/execution/types.d.ts +155 -0
- package/dist/index.d.ts +9 -10
- package/dist/index.js +1 -6
- 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 -9
- package/dist/llm.js.map +1 -1
- package/dist/plugins.d.ts +20 -0
- package/dist/plugins.js +14 -0
- package/dist/plugins.js.map +1 -0
- package/dist/session/events.d.ts +26 -20
- package/dist/session/input-normalization.js +66 -0
- package/dist/session/input-normalization.js.map +1 -0
- package/dist/session/input.d.ts +0 -4
- package/dist/session/mapping.js +1 -2
- package/dist/session/mapping.js.map +1 -1
- package/dist/session/run.js +1 -0
- package/dist/session/run.js.map +1 -1
- package/dist/session/runtime-input.js +20 -58
- package/dist/session/runtime-input.js.map +1 -1
- package/dist/session/session-errors.js +18 -0
- package/dist/session/session-errors.js.map +1 -0
- package/dist/session/session-events.js +59 -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-kill.js +23 -0
- package/dist/session/session-kill.js.map +1 -0
- package/dist/session/session-notification.js +58 -0
- package/dist/session/session-notification.js.map +1 -0
- package/dist/session/session-runtime-drain.js +22 -0
- package/dist/session/session-runtime-drain.js.map +1 -0
- package/dist/session/session-state.js +102 -0
- package/dist/session/session-state.js.map +1 -0
- package/dist/session/session-turn-error.js +35 -0
- package/dist/session/session-turn-error.js.map +1 -0
- package/dist/session/session-turn-processor.js +135 -0
- package/dist/session/session-turn-processor.js.map +1 -0
- package/dist/session/session.js +125 -335
- package/dist/session/session.js.map +1 -1
- package/dist/session/snapshot.js +5 -31
- package/dist/session/snapshot.js.map +1 -1
- package/dist/session/store/file.d.ts +1 -0
- package/dist/session/store/file.js +14 -0
- package/dist/session/store/file.js.map +1 -1
- package/dist/session/store/memory.d.ts +1 -0
- package/dist/session/store/memory.js +5 -0
- package/dist/session/store/memory.js.map +1 -1
- package/dist/session/store/types.d.ts +1 -0
- package/dist/subagent-background-child-run-state.js +51 -0
- package/dist/subagent-background-child-run-state.js.map +1 -0
- package/dist/subagent-background-child-run.js +103 -0
- package/dist/subagent-background-child-run.js.map +1 -0
- package/dist/subagent-background-in-process.js +98 -0
- package/dist/subagent-background-in-process.js.map +1 -0
- package/dist/subagent-background-notification-inbox.js +106 -0
- package/dist/subagent-background-notification-inbox.js.map +1 -0
- package/dist/subagent-background-notify.js +136 -0
- package/dist/subagent-background-notify.js.map +1 -0
- package/dist/subagent-background-resume-group.js +99 -0
- package/dist/subagent-background-resume-group.js.map +1 -0
- package/dist/subagent-background-runner.js +115 -0
- package/dist/subagent-background-runner.js.map +1 -0
- package/dist/subagent-background-schedule.js +43 -0
- package/dist/subagent-background-schedule.js.map +1 -0
- package/dist/subagent-child-run.js +68 -0
- package/dist/subagent-child-run.js.map +1 -0
- package/dist/subagent-job-cancel.js +84 -0
- package/dist/subagent-job-cancel.js.map +1 -0
- package/dist/subagent-job-observer.js +19 -0
- package/dist/subagent-job-observer.js.map +1 -0
- package/dist/subagent-job-output.js +87 -0
- package/dist/subagent-job-output.js.map +1 -0
- package/dist/subagent-job-state.js +66 -0
- package/dist/subagent-job-state.js.map +1 -0
- package/dist/subagent-jobs.js +96 -0
- package/dist/subagent-jobs.js.map +1 -0
- package/dist/subagent-prompt-schema.js +114 -0
- package/dist/subagent-prompt-schema.js.map +1 -0
- package/dist/subagent-run.js +111 -0
- package/dist/subagent-run.js.map +1 -0
- package/dist/subagents.js +125 -0
- package/dist/subagents.js.map +1 -0
- package/package.json +11 -6
- package/dist/plugins/compaction.d.ts +0 -15
- package/dist/plugins/compaction.js +0 -98
- package/dist/plugins/compaction.js.map +0 -1
- package/dist/plugins/index.d.ts +0 -5
- package/dist/plugins/index.js +0 -5
- package/dist/plugins/memory.d.ts +0 -11
- package/dist/plugins/memory.js +0 -146
- package/dist/plugins/memory.js.map +0 -1
- package/dist/plugins/runner.d.ts +0 -1
- package/dist/plugins/runner.js +0 -83
- package/dist/plugins/runner.js.map +0 -1
- package/dist/plugins/scope.js +0 -13
- package/dist/plugins/scope.js.map +0 -1
- package/dist/plugins/sessions.d.ts +0 -12
- package/dist/plugins/sessions.js +0 -34
- package/dist/plugins/sessions.js.map +0 -1
- package/dist/plugins/tool-hook-handlers.js +0 -77
- package/dist/plugins/tool-hook-handlers.js.map +0 -1
- package/dist/plugins/tool-hook-results.js +0 -64
- package/dist/plugins/tool-hook-results.js.map +0 -1
- package/dist/plugins/tool-hooks.js +0 -111
- package/dist/plugins/tool-hooks.js.map +0 -1
- package/dist/plugins/types.d.ts +0 -105
- package/dist/plugins/types.js +0 -20
- package/dist/plugins/types.js.map +0 -1
- package/dist/session/lifecycle.d.ts +0 -12
- package/dist/session/lifecycle.js +0 -126
- package/dist/session/lifecycle.js.map +0 -1
- package/dist/session/overlay-anchor.js +0 -151
- package/dist/session/overlay-anchor.js.map +0 -1
- package/dist/session/overlay.js +0 -141
- package/dist/session/overlay.js.map +0 -1
- package/dist/session/snapshot.d.ts +0 -1
- /package/dist/{agent-loop.d.ts → session/history.d.ts} +0 -0
- /package/dist/session/{runtime-input.d.ts → session-execution.d.ts} +0 -0
- /package/dist/{plugins/scope.d.ts → session/session-state.d.ts} +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { ToolExecutionNeedsRecoveryError } from "../llm-tool-execution.js";
|
|
2
|
+
import { closeRuntimeInput, withRuntimeInputWindow } from "./runtime-input.js";
|
|
3
|
+
import { errorMessage } from "./session-errors.js";
|
|
4
|
+
import { runAgentLoop } from "../agent-loop.js";
|
|
5
|
+
import { startSessionExecutionRun } from "./session-execution.js";
|
|
6
|
+
import { drainRuntimeInput } from "./session-runtime-drain.js";
|
|
7
|
+
import { emitTurnErrorAfterRecovery } from "./session-turn-error.js";
|
|
8
|
+
//#region src/session/session-turn-processor.ts
|
|
9
|
+
async function processQueuedInput({ activate, deactivateRun, events, execution, item, llm, release, sessionKey, state }) {
|
|
10
|
+
const activeAbort = new AbortController();
|
|
11
|
+
const { initialEvents, input, preUserRuntimeInputs, run, runtimeInput } = item;
|
|
12
|
+
const turnId = crypto.randomUUID();
|
|
13
|
+
activate({
|
|
14
|
+
abort: activeAbort,
|
|
15
|
+
run,
|
|
16
|
+
runtimeInput,
|
|
17
|
+
turnId
|
|
18
|
+
});
|
|
19
|
+
const historySnapshot = state.modelSnapshot();
|
|
20
|
+
let executionRun;
|
|
21
|
+
try {
|
|
22
|
+
executionRun = await startSessionExecutionRun({
|
|
23
|
+
executionHost: execution.executionHost,
|
|
24
|
+
sessionKey,
|
|
25
|
+
state,
|
|
26
|
+
turnId
|
|
27
|
+
});
|
|
28
|
+
for (const event of initialEvents) await events.emitRunEvent(run, event);
|
|
29
|
+
await appendRuntimeInputsToHistory(state, preUserRuntimeInputs);
|
|
30
|
+
if (input) {
|
|
31
|
+
state.appendUserInput(input);
|
|
32
|
+
await state.commit();
|
|
33
|
+
}
|
|
34
|
+
await withRuntimeInputWindow(runtimeInput, "turn-start", async () => {
|
|
35
|
+
await events.emitRunBoundaryEvent(run, { type: "turn-start" });
|
|
36
|
+
});
|
|
37
|
+
await emitPreUserRuntimeInputs(events, run, preUserRuntimeInputs);
|
|
38
|
+
await drainRuntimeInput({
|
|
39
|
+
emit: (event) => events.emitRunEvent(run, event),
|
|
40
|
+
placement: "turn-start",
|
|
41
|
+
runtimeInput,
|
|
42
|
+
state
|
|
43
|
+
});
|
|
44
|
+
const result = await runAgentLoop({
|
|
45
|
+
emit: async (event) => emitTurnEvent({
|
|
46
|
+
event,
|
|
47
|
+
events,
|
|
48
|
+
run,
|
|
49
|
+
runtimeInput,
|
|
50
|
+
state
|
|
51
|
+
}),
|
|
52
|
+
history: state.history,
|
|
53
|
+
llm,
|
|
54
|
+
captureObserverEvents: (callback) => events.captureObserverEvents(run, callback),
|
|
55
|
+
signal: activeAbort.signal,
|
|
56
|
+
toolExecution: executionRun?.toolExecution
|
|
57
|
+
});
|
|
58
|
+
await state.commit();
|
|
59
|
+
await executionRun?.complete(executionStatusForResult(result));
|
|
60
|
+
await closeSuccessfulTurn({
|
|
61
|
+
deactivateRun,
|
|
62
|
+
events,
|
|
63
|
+
result,
|
|
64
|
+
run,
|
|
65
|
+
runtimeInput
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
const turnError = error instanceof Error ? error : new Error(String(error));
|
|
69
|
+
await executionRun?.complete(executionStatusForError(turnError));
|
|
70
|
+
await emitTurnErrorAfterRecovery({
|
|
71
|
+
error: turnError,
|
|
72
|
+
historySnapshot,
|
|
73
|
+
run,
|
|
74
|
+
runtimeInput,
|
|
75
|
+
state
|
|
76
|
+
});
|
|
77
|
+
} finally {
|
|
78
|
+
closeRuntimeInput(runtimeInput);
|
|
79
|
+
release();
|
|
80
|
+
run.close(void 0, runtimeInput.closedReason);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function executionStatusForResult(result) {
|
|
84
|
+
return result === "aborted" ? "cancelled" : "completed";
|
|
85
|
+
}
|
|
86
|
+
function executionStatusForError(error) {
|
|
87
|
+
return error instanceof ToolExecutionNeedsRecoveryError ? "needs-recovery" : "error";
|
|
88
|
+
}
|
|
89
|
+
async function appendRuntimeInputsToHistory(state, runtimeInputs) {
|
|
90
|
+
for (const runtimeInput of runtimeInputs) {
|
|
91
|
+
state.appendUserInput(runtimeInput.input);
|
|
92
|
+
await state.commit();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function closeSuccessfulTurn({ deactivateRun, events, result, run, runtimeInput }) {
|
|
96
|
+
const terminalEvent = result === "aborted" ? "turn-abort" : "turn-end";
|
|
97
|
+
closeRuntimeInput(runtimeInput, terminalEvent);
|
|
98
|
+
deactivateRun();
|
|
99
|
+
try {
|
|
100
|
+
await events.emitRunEvent(run, { type: terminalEvent });
|
|
101
|
+
} catch (terminalError) {
|
|
102
|
+
run.emit({
|
|
103
|
+
type: "turn-error",
|
|
104
|
+
message: errorMessage(terminalError)
|
|
105
|
+
});
|
|
106
|
+
closeRuntimeInput(runtimeInput, "turn-error");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function emitPreUserRuntimeInputs(events, run, runtimeInputs) {
|
|
110
|
+
for (const runtimeInput of runtimeInputs) await events.emitRunEvent(run, {
|
|
111
|
+
input: runtimeInput.input,
|
|
112
|
+
placement: runtimeInput.placement,
|
|
113
|
+
type: "runtime-input"
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async function emitTurnEvent({ event, events, run, runtimeInput, state }) {
|
|
117
|
+
if (event.type !== "step-start" && event.type !== "step-end") {
|
|
118
|
+
await events.emitRunEvent(run, event);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
await withRuntimeInputWindow(runtimeInput, event.type, async () => {
|
|
122
|
+
await events.emitRunBoundaryEvent(run, event);
|
|
123
|
+
});
|
|
124
|
+
const runtimeInputAdded = await drainRuntimeInput({
|
|
125
|
+
emit: (runtimeInputEvent) => events.emitRunEvent(run, runtimeInputEvent),
|
|
126
|
+
placement: event.type,
|
|
127
|
+
runtimeInput,
|
|
128
|
+
state
|
|
129
|
+
});
|
|
130
|
+
return event.type === "step-end" ? { runtimeInputAdded } : void 0;
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
export { processQueuedInput };
|
|
134
|
+
|
|
135
|
+
//# sourceMappingURL=session-turn-processor.js.map
|
|
@@ -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 QueuedRuntimeInput,\n type RuntimeInputState,\n withRuntimeInputWindow,\n} from \"./runtime-input\";\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\";\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 await appendRuntimeInputsToHistory(state, preUserRuntimeInputs);\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 emitPreUserRuntimeInputs(events, run, preUserRuntimeInputs);\n await drainRuntimeInput({\n emit: (event) => events.emitRunEvent(run, event),\n placement: \"turn-start\",\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 appendRuntimeInputsToHistory(\n state: SessionState,\n runtimeInputs: readonly QueuedRuntimeInput[]\n): Promise<void> {\n for (const runtimeInput of runtimeInputs) {\n state.appendUserInput(runtimeInput.input);\n await state.commit();\n }\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 emitPreUserRuntimeInputs(\n events: SessionEventDispatcher,\n run: BufferedAgentRun,\n runtimeInputs: readonly QueuedRuntimeInput[]\n): Promise<void> {\n for (const runtimeInput of runtimeInputs) {\n await events.emitRunEvent(run, {\n input: runtimeInput.input,\n placement: runtimeInput.placement,\n type: \"runtime-input\",\n });\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 emit: (runtimeInputEvent) => events.emitRunEvent(run, runtimeInputEvent),\n placement: event.type,\n runtimeInput,\n state,\n });\n return event.type === \"step-end\" ? { runtimeInputAdded } : undefined;\n}\n"],"mappings":"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"}
|
package/dist/session/session.js
CHANGED
|
@@ -1,135 +1,139 @@
|
|
|
1
|
-
import { runWithAgentPluginScope } from "../plugins/scope.js";
|
|
2
|
-
import { runAgentLoop } from "../agent-loop.js";
|
|
3
|
-
import { ModelMessageHistory } from "./history.js";
|
|
4
|
-
import { createRuntimeInputStepLifecycle, runPluginAfterTurnHandlers, runPluginBeforeTurnHandlers } from "./lifecycle.js";
|
|
5
|
-
import { addRuntimeInput, closeRuntimeInput, createRuntimeInputState, normalizeAgentInput, shiftRuntimeInput } from "./runtime-input.js";
|
|
6
|
-
import { SessionOverlayState } from "./overlay.js";
|
|
7
1
|
import { BufferedAgentRun } from "./run.js";
|
|
8
|
-
import {
|
|
2
|
+
import { normalizeAgentInput } from "./input-normalization.js";
|
|
3
|
+
import { addSteeringInput, createRuntimeInputState, queueRuntimeInput } from "./runtime-input.js";
|
|
4
|
+
import { sessionKilledError, sessionTerminalError } from "./session-errors.js";
|
|
5
|
+
import { SessionEventDispatcher } from "./session-events.js";
|
|
6
|
+
import { closeKilledRuntimeInputs } from "./session-kill.js";
|
|
7
|
+
import { queueSessionNotification, startSessionQueueDrain } from "./session-notification.js";
|
|
8
|
+
import { SessionState } from "./session-state.js";
|
|
9
|
+
import { processQueuedInput } from "./session-turn-processor.js";
|
|
9
10
|
//#region src/session/session.ts
|
|
10
11
|
var AgentSession = class {
|
|
12
|
+
#events;
|
|
13
|
+
#execution;
|
|
11
14
|
#inputQueue = [];
|
|
12
|
-
#internalLlm;
|
|
13
15
|
#llm;
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
16
|
+
#pendingRuntimeInputs = [];
|
|
17
|
+
#sessionKey;
|
|
18
|
+
#state;
|
|
17
19
|
#activeAbort;
|
|
18
20
|
#activeRun;
|
|
19
21
|
#activeRuntimeInput;
|
|
20
|
-
#
|
|
22
|
+
#activeTurnId;
|
|
23
|
+
#deletePromise;
|
|
21
24
|
#killed = false;
|
|
22
|
-
#loadPromise;
|
|
23
|
-
#loaded = false;
|
|
24
|
-
#pluginState = {};
|
|
25
|
-
#compactions = [];
|
|
26
|
-
#overlays = new SessionOverlayState();
|
|
27
25
|
#running = false;
|
|
28
|
-
#
|
|
29
|
-
constructor(llm, persistence, plugins,
|
|
30
|
-
this.#internalLlm = internalLlm;
|
|
31
|
-
this.#onPluginError = onPluginError;
|
|
32
|
-
this.#persistence = persistence;
|
|
33
|
-
this.#plugins = plugins;
|
|
26
|
+
#runToCloseOnKill;
|
|
27
|
+
constructor(llm, persistence, plugins = [], execution = {}) {
|
|
34
28
|
this.#llm = llm;
|
|
29
|
+
this.#execution = execution;
|
|
30
|
+
this.#sessionKey = persistence.key;
|
|
31
|
+
this.#state = new SessionState(persistence);
|
|
32
|
+
this.#events = new SessionEventDispatcher({
|
|
33
|
+
history: () => this.#state.modelSnapshot(),
|
|
34
|
+
plugins,
|
|
35
|
+
signal: () => this.#activeAbort?.signal
|
|
36
|
+
});
|
|
35
37
|
}
|
|
36
38
|
async send(input) {
|
|
37
|
-
if (this.#killed) throw
|
|
38
|
-
await this.#ensureLoaded();
|
|
39
|
-
if (this.#killed) throw
|
|
40
|
-
const runtimeInput = createRuntimeInputState();
|
|
39
|
+
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
40
|
+
await this.#state.ensureLoaded();
|
|
41
|
+
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
42
|
+
const runtimeInput = createRuntimeInputState(this.#pendingRuntimeInputs.splice(0));
|
|
41
43
|
const acceptedInput = normalizeAgentInput(input);
|
|
42
44
|
const run = new BufferedAgentRun();
|
|
43
|
-
|
|
45
|
+
await this.#events.emitRunEvent(run, acceptedInput);
|
|
44
46
|
this.#inputQueue.push({
|
|
47
|
+
initialEvents: [],
|
|
45
48
|
input: structuredClone(acceptedInput),
|
|
49
|
+
preUserRuntimeInputs: [],
|
|
46
50
|
run,
|
|
47
51
|
runtimeInput
|
|
48
52
|
});
|
|
49
|
-
this.#drainInputQueue()
|
|
50
|
-
run.emit({
|
|
51
|
-
type: "turn-error",
|
|
52
|
-
message: errorMessage(error)
|
|
53
|
-
});
|
|
54
|
-
run.close();
|
|
55
|
-
});
|
|
53
|
+
startSessionQueueDrain(run, () => this.#drainInputQueue());
|
|
56
54
|
return run;
|
|
57
55
|
}
|
|
56
|
+
async notify(input, options = {}) {
|
|
57
|
+
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
58
|
+
await this.#state.ensureLoaded();
|
|
59
|
+
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
60
|
+
return queueSessionNotification(input, options, {
|
|
61
|
+
activeRun: this.#activeRun,
|
|
62
|
+
activeRuntimeInput: this.#activeRuntimeInput,
|
|
63
|
+
drain: () => this.#drainInputQueue(),
|
|
64
|
+
inputQueue: this.#inputQueue,
|
|
65
|
+
pendingRuntimeInputs: this.#pendingRuntimeInputs
|
|
66
|
+
});
|
|
67
|
+
}
|
|
58
68
|
async steer(input) {
|
|
59
|
-
if (this.#killed) throw
|
|
69
|
+
if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
|
|
60
70
|
const runtimeInput = this.#activeRuntimeInput;
|
|
61
71
|
const run = this.#activeRun;
|
|
62
72
|
if (!(runtimeInput && run)) return this.send(input);
|
|
63
|
-
await
|
|
64
|
-
return run;
|
|
65
|
-
}
|
|
66
|
-
async overlay(input) {
|
|
67
|
-
if (this.#killed) throw sessionKilledError();
|
|
68
|
-
await this.#ensureLoaded();
|
|
69
|
-
if (this.#killed) throw sessionKilledError();
|
|
70
|
-
const activeRun = this.#activeRun;
|
|
71
|
-
if (activeRun) {
|
|
72
|
-
const placement = this.#activeRuntimeInput?.steerPlacement ?? this.#activeRuntimeInput?.placement ?? "step-end";
|
|
73
|
-
const entry = this.#overlays.appendActiveOverlay(input, placement);
|
|
74
|
-
if (!entry) throw new Error("Active overlay frame is unavailable.");
|
|
75
|
-
activeRun.emit({
|
|
76
|
-
input: entry.summary,
|
|
77
|
-
placement: entry.placement,
|
|
78
|
-
type: "overlay-accepted"
|
|
79
|
-
});
|
|
80
|
-
return activeRun;
|
|
81
|
-
}
|
|
82
|
-
const entry = this.#overlays.appendPendingOverlay(input);
|
|
83
|
-
const run = new BufferedAgentRun();
|
|
84
|
-
run.emit({
|
|
85
|
-
input: entry.summary,
|
|
86
|
-
placement: entry.placement,
|
|
87
|
-
type: "overlay-accepted"
|
|
88
|
-
});
|
|
89
|
-
run.close();
|
|
73
|
+
await addSteeringInput(runtimeInput, input);
|
|
90
74
|
return run;
|
|
91
75
|
}
|
|
92
76
|
interrupt() {
|
|
93
77
|
this.#activeAbort?.abort();
|
|
94
78
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.#
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
item?.run.emit({
|
|
105
|
-
type: "turn-error",
|
|
106
|
-
message: sessionKilledError().message
|
|
79
|
+
currentTurnId() {
|
|
80
|
+
return this.#activeTurnId;
|
|
81
|
+
}
|
|
82
|
+
delete() {
|
|
83
|
+
if (!this.#deletePromise) {
|
|
84
|
+
this.kill();
|
|
85
|
+
this.#deletePromise = this.#state.delete().catch((error) => {
|
|
86
|
+
this.#deletePromise = void 0;
|
|
87
|
+
throw error;
|
|
107
88
|
});
|
|
108
|
-
item?.run.close(void 0, sessionKilledError().message);
|
|
109
89
|
}
|
|
90
|
+
return this.#deletePromise;
|
|
110
91
|
}
|
|
111
|
-
|
|
112
|
-
if (this.#
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
92
|
+
enqueueRuntimeInput(input, placement = "turn-start") {
|
|
93
|
+
if (this.#killed) return;
|
|
94
|
+
const runtimeInput = this.#activeRuntimeInput;
|
|
95
|
+
if (runtimeInput && !runtimeInput.closedReason) {
|
|
96
|
+
if (placement === "turn-start" && runtimeInput.placement !== placement) {
|
|
97
|
+
this.#enqueuePendingRuntimeInput({
|
|
98
|
+
input,
|
|
99
|
+
placement
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
queueRuntimeInput(runtimeInput, {
|
|
104
|
+
input,
|
|
105
|
+
placement
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
119
108
|
}
|
|
109
|
+
this.#enqueuePendingRuntimeInput({
|
|
110
|
+
input,
|
|
111
|
+
placement
|
|
112
|
+
});
|
|
120
113
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
await this.#replaceWithStoredSession();
|
|
124
|
-
this.#loaded = true;
|
|
114
|
+
emitObserverEvent(event) {
|
|
115
|
+
return this.#events.emitObserverEvent(this.#activeRun, event);
|
|
125
116
|
}
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
this.#
|
|
117
|
+
#enqueuePendingRuntimeInput(input) {
|
|
118
|
+
const queuedTurn = this.#inputQueue[0];
|
|
119
|
+
if (input.placement === "turn-start" && queuedTurn) {
|
|
120
|
+
queueRuntimeInput(queuedTurn.runtimeInput, input);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.#pendingRuntimeInputs.push(input);
|
|
124
|
+
}
|
|
125
|
+
kill() {
|
|
126
|
+
if (this.#killed) return;
|
|
127
|
+
this.#killed = true;
|
|
128
|
+
const killedError = sessionKilledError();
|
|
129
|
+
this.#pendingRuntimeInputs.length = 0;
|
|
130
|
+
this.#activeAbort?.abort();
|
|
131
|
+
closeKilledRuntimeInputs({
|
|
132
|
+
activeRuntimeInput: this.#activeRuntimeInput,
|
|
133
|
+
inputQueue: this.#inputQueue,
|
|
134
|
+
message: killedError.message,
|
|
135
|
+
runToClose: this.#runToCloseOnKill ?? this.#activeRun
|
|
136
|
+
});
|
|
133
137
|
}
|
|
134
138
|
async #drainInputQueue() {
|
|
135
139
|
if (this.#running) return;
|
|
@@ -137,250 +141,36 @@ var AgentSession = class {
|
|
|
137
141
|
try {
|
|
138
142
|
while (!this.#killed && this.#inputQueue.length > 0) {
|
|
139
143
|
const item = this.#inputQueue.shift();
|
|
140
|
-
if (item) await
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
await this.#commitHistory();
|
|
166
|
-
await this.#drainRuntimeInput(run, runtimeInput, "turn-start");
|
|
167
|
-
const result = await runAgentLoop({
|
|
168
|
-
emit: async (event) => {
|
|
169
|
-
if (event.type === "step-start" || event.type === "step-end") {
|
|
170
|
-
await this.#withRuntimeInputWindow(runtimeInput, event.type, async () => {
|
|
171
|
-
await run.emitBoundary(event);
|
|
172
|
-
});
|
|
173
|
-
const overlayInputAdded = event.type === "step-end" && this.#overlays.consumeStepEndOverlayInputAdded();
|
|
174
|
-
const runtimeInputAdded = await this.#drainRuntimeInput(run, runtimeInput, event.type);
|
|
175
|
-
if (event.type === "step-end") return {
|
|
176
|
-
overlayInputAdded,
|
|
177
|
-
runtimeInputAdded
|
|
178
|
-
};
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
run.emit(event);
|
|
182
|
-
},
|
|
183
|
-
history: this.#history,
|
|
184
|
-
stepLifecycle: createRuntimeInputStepLifecycle({
|
|
185
|
-
lifecycle: this.#pluginLifecycle(),
|
|
186
|
-
runtimeInput,
|
|
187
|
-
withSteeringPlacement: (placement, callback) => this.#withSteeringPlacement(runtimeInput, placement, callback)
|
|
188
|
-
}),
|
|
189
|
-
llm: (context) => this.#invokeLlm(context),
|
|
190
|
-
signal: activeAbort.signal
|
|
191
|
-
});
|
|
192
|
-
await this.#commitHistory();
|
|
193
|
-
const terminalEvent = result === "aborted" ? "turn-abort" : "turn-end";
|
|
194
|
-
closeRuntimeInput(runtimeInput, terminalEvent);
|
|
195
|
-
this.#expireActiveOverlays(terminalEvent);
|
|
196
|
-
this.#activeRuntimeInput = void 0;
|
|
197
|
-
this.#activeRun = void 0;
|
|
198
|
-
if (await runPluginAfterTurnHandlers(this.#pluginLifecycle(), {
|
|
199
|
-
input,
|
|
200
|
-
result,
|
|
201
|
-
signal: activeAbort.signal
|
|
202
|
-
})) await this.#commitHistory();
|
|
203
|
-
run.emit({ type: terminalEvent });
|
|
204
|
-
} catch (error) {
|
|
205
|
-
if (error instanceof SessionCommitConflictError) {
|
|
206
|
-
run.emit({
|
|
207
|
-
type: "turn-error",
|
|
208
|
-
message: error.message
|
|
144
|
+
if (item) await processQueuedInput({
|
|
145
|
+
activate: ({ abort, run, runtimeInput, turnId }) => {
|
|
146
|
+
this.#activeAbort = abort;
|
|
147
|
+
this.#activeRun = run;
|
|
148
|
+
this.#activeRuntimeInput = runtimeInput;
|
|
149
|
+
this.#activeTurnId = turnId;
|
|
150
|
+
this.#runToCloseOnKill = run;
|
|
151
|
+
},
|
|
152
|
+
deactivateRun: () => {
|
|
153
|
+
this.#activeRun = void 0;
|
|
154
|
+
this.#activeRuntimeInput = void 0;
|
|
155
|
+
},
|
|
156
|
+
events: this.#events,
|
|
157
|
+
execution: this.#execution,
|
|
158
|
+
item,
|
|
159
|
+
llm: this.#llm,
|
|
160
|
+
release: () => {
|
|
161
|
+
this.#activeAbort = void 0;
|
|
162
|
+
this.#activeRun = void 0;
|
|
163
|
+
this.#activeRuntimeInput = void 0;
|
|
164
|
+
this.#activeTurnId = void 0;
|
|
165
|
+
this.#runToCloseOnKill = void 0;
|
|
166
|
+
},
|
|
167
|
+
sessionKey: this.#sessionKey,
|
|
168
|
+
state: this.#state
|
|
209
169
|
});
|
|
210
|
-
closeRuntimeInput(runtimeInput, "a session commit conflict");
|
|
211
|
-
this.#expireActiveOverlays("turn-error");
|
|
212
|
-
this.#activeAbort = void 0;
|
|
213
|
-
return;
|
|
214
170
|
}
|
|
215
|
-
this.#history.rollback(historySnapshot);
|
|
216
|
-
try {
|
|
217
|
-
await this.#commitHistory();
|
|
218
|
-
} catch (rollbackError) {
|
|
219
|
-
run.emit({
|
|
220
|
-
type: "turn-error",
|
|
221
|
-
message: `${errorMessage(error)}; history rollback persistence failed: ${errorMessage(rollbackError)}`
|
|
222
|
-
});
|
|
223
|
-
closeRuntimeInput(runtimeInput, "turn-error");
|
|
224
|
-
this.#expireActiveOverlays("turn-error");
|
|
225
|
-
this.#activeAbort = void 0;
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
run.emit({
|
|
229
|
-
type: "turn-error",
|
|
230
|
-
message: errorMessage(error)
|
|
231
|
-
});
|
|
232
|
-
closeRuntimeInput(runtimeInput, "turn-error");
|
|
233
|
-
this.#expireActiveOverlays("turn-error");
|
|
234
|
-
} finally {
|
|
235
|
-
closeRuntimeInput(runtimeInput);
|
|
236
|
-
this.#activeAbort = void 0;
|
|
237
|
-
this.#activeRun = void 0;
|
|
238
|
-
this.#activeRuntimeInput = void 0;
|
|
239
|
-
this.#overlays.resetActiveTurn();
|
|
240
|
-
run.close(void 0, runtimeInput.closedReason);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
async #commitHistory() {
|
|
244
|
-
const result = await this.#persistence.store.commit(this.#persistence.key, { state: encodeSessionSnapshot({
|
|
245
|
-
compactions: this.#compactions,
|
|
246
|
-
history: this.#history.modelSnapshot(),
|
|
247
|
-
pluginState: this.#pluginState
|
|
248
|
-
}) }, { expectedVersion: this.#storeVersion ?? null });
|
|
249
|
-
if (!result.ok) {
|
|
250
|
-
await this.#replaceWithStoredSession();
|
|
251
|
-
throw new SessionCommitConflictError(this.#persistence.key);
|
|
252
|
-
}
|
|
253
|
-
this.#storeVersion = result.version;
|
|
254
|
-
}
|
|
255
|
-
#createPluginScope(signal) {
|
|
256
|
-
return {
|
|
257
|
-
eventHandlers: this.#plugins?.eventHandlers,
|
|
258
|
-
getCompactions: () => structuredClone(this.#compactions),
|
|
259
|
-
getPluginState: (pluginName) => this.#pluginState[pluginName],
|
|
260
|
-
history: () => this.#history.modelSnapshot(),
|
|
261
|
-
sessionKey: this.#persistence.key,
|
|
262
|
-
overlay: (input) => this.overlay(input),
|
|
263
|
-
setCompactions: (compactions) => {
|
|
264
|
-
this.#compactions = structuredClone([...compactions]);
|
|
265
|
-
},
|
|
266
|
-
setPluginState: (pluginName, state) => {
|
|
267
|
-
this.#pluginState = {
|
|
268
|
-
...this.#pluginState,
|
|
269
|
-
[pluginName]: structuredClone(state)
|
|
270
|
-
};
|
|
271
|
-
},
|
|
272
|
-
signal,
|
|
273
|
-
steer: (input) => this.steer(input),
|
|
274
|
-
summarize: (messages) => this.#summarizeForPlugins(messages, signal)
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
#pluginLifecycle() {
|
|
278
|
-
return {
|
|
279
|
-
createScope: (signal) => this.#createPluginScope(signal),
|
|
280
|
-
history: () => this.#history.modelSnapshot(),
|
|
281
|
-
onPluginError: this.#onPluginError,
|
|
282
|
-
plugins: this.#plugins,
|
|
283
|
-
sessionKey: this.#persistence.key,
|
|
284
|
-
overlaySession: (input) => this.overlay(input),
|
|
285
|
-
steerCurrentRun: async (runtimeInput, input) => {
|
|
286
|
-
await addRuntimeInput(runtimeInput, input);
|
|
287
|
-
if (!this.#activeRun) throw new Error("Agent plugin steering requires an active run.");
|
|
288
|
-
return this.#activeRun;
|
|
289
|
-
},
|
|
290
|
-
steerSession: (input) => this.steer(input)
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
#invokeLlm({ history, signal }) {
|
|
294
|
-
const activeSignal = signal ?? new AbortController().signal;
|
|
295
|
-
const invoke = async () => {
|
|
296
|
-
let transformedHistory = history;
|
|
297
|
-
for (const transform of this.#plugins?.contextTransforms ?? []) transformedHistory = await transform({
|
|
298
|
-
history: transformedHistory,
|
|
299
|
-
sessionKey: this.#persistence.key,
|
|
300
|
-
signal: activeSignal
|
|
301
|
-
});
|
|
302
|
-
const modelHistory = this.#overlays.compose(transformedHistory, history);
|
|
303
|
-
this.#overlays.markInferenceStarted();
|
|
304
|
-
return this.#llm({
|
|
305
|
-
history: modelHistory,
|
|
306
|
-
signal: activeSignal
|
|
307
|
-
});
|
|
308
|
-
};
|
|
309
|
-
return runWithAgentPluginScope(this.#createPluginScope(activeSignal), invoke);
|
|
310
|
-
}
|
|
311
|
-
async #summarizeForPlugins(messages, signal) {
|
|
312
|
-
return outputToText(await this.#internalLlm({
|
|
313
|
-
history: [{
|
|
314
|
-
content: "Summarize these earlier session messages for future model context.",
|
|
315
|
-
role: "system"
|
|
316
|
-
}, ...messages],
|
|
317
|
-
signal
|
|
318
|
-
})) || `Summarized ${messages.length} messages.`;
|
|
319
|
-
}
|
|
320
|
-
async #withRuntimeInputWindow(runtimeInput, placement, callback) {
|
|
321
|
-
const previousSteerPlacement = runtimeInput.steerPlacement;
|
|
322
|
-
runtimeInput.placement = placement;
|
|
323
|
-
runtimeInput.steerPlacement = placement;
|
|
324
|
-
try {
|
|
325
|
-
return await callback();
|
|
326
171
|
} finally {
|
|
327
|
-
|
|
328
|
-
runtimeInput.steerPlacement = previousSteerPlacement;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
async #withSteeringPlacement(runtimeInput, placement, callback) {
|
|
332
|
-
const previousSteerPlacement = runtimeInput.steerPlacement;
|
|
333
|
-
runtimeInput.steerPlacement = placement;
|
|
334
|
-
try {
|
|
335
|
-
return await callback();
|
|
336
|
-
} finally {
|
|
337
|
-
runtimeInput.steerPlacement = previousSteerPlacement;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
async #drainRuntimeInput(run, runtimeInput, placement) {
|
|
341
|
-
let added = false;
|
|
342
|
-
let next = shiftRuntimeInput(runtimeInput, placement);
|
|
343
|
-
while (next) {
|
|
344
|
-
added = true;
|
|
345
|
-
run.emit({
|
|
346
|
-
type: "runtime-input",
|
|
347
|
-
input: next.input,
|
|
348
|
-
placement
|
|
349
|
-
});
|
|
350
|
-
this.#history.appendUserInput(next.input);
|
|
351
|
-
await this.#commitHistory();
|
|
352
|
-
next = shiftRuntimeInput(runtimeInput, placement);
|
|
353
|
-
}
|
|
354
|
-
return added;
|
|
355
|
-
}
|
|
356
|
-
#expireActiveOverlays(reason) {
|
|
357
|
-
const event = this.#overlays.expireActiveFrame(reason);
|
|
358
|
-
if (!event) return;
|
|
359
|
-
this.#activeRun?.emit(event);
|
|
360
|
-
}
|
|
361
|
-
};
|
|
362
|
-
function errorMessage(error) {
|
|
363
|
-
if (error instanceof Error) return error.message;
|
|
364
|
-
return String(error);
|
|
365
|
-
}
|
|
366
|
-
function outputToText(output) {
|
|
367
|
-
const parts = [];
|
|
368
|
-
for (const message of output) {
|
|
369
|
-
if (message.role !== "assistant") continue;
|
|
370
|
-
if (typeof message.content === "string") {
|
|
371
|
-
parts.push(message.content);
|
|
372
|
-
continue;
|
|
172
|
+
this.#running = false;
|
|
373
173
|
}
|
|
374
|
-
for (const part of message.content) if (part.type === "text") parts.push(part.text);
|
|
375
|
-
}
|
|
376
|
-
return parts.join("\n").trim();
|
|
377
|
-
}
|
|
378
|
-
function sessionKilledError() {
|
|
379
|
-
return /* @__PURE__ */ new Error("Session killed");
|
|
380
|
-
}
|
|
381
|
-
var SessionCommitConflictError = class extends Error {
|
|
382
|
-
constructor(key) {
|
|
383
|
-
super(`Session ${JSON.stringify(key)} commit conflict`);
|
|
384
174
|
}
|
|
385
175
|
};
|
|
386
176
|
//#endregion
|