@minpeter/pss-runtime 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +89 -101
  2. package/dist/agent-loop.d.ts +20 -12
  3. package/dist/agent-loop.js +45 -48
  4. package/dist/agent-loop.js.map +1 -1
  5. package/dist/agent.d.ts +34 -17
  6. package/dist/agent.js +50 -31
  7. package/dist/agent.js.map +1 -1
  8. package/dist/index.d.ts +8 -7
  9. package/dist/index.js +4 -5
  10. package/dist/llm.d.ts +29 -23
  11. package/dist/llm.js +15 -11
  12. package/dist/llm.js.map +1 -1
  13. package/dist/session/events.d.ts +76 -61
  14. package/dist/session/history.js +32 -30
  15. package/dist/session/history.js.map +1 -1
  16. package/dist/session/mapping.js +92 -52
  17. package/dist/session/mapping.js.map +1 -1
  18. package/dist/session/run.d.ts +9 -0
  19. package/dist/session/run.js +78 -0
  20. package/dist/session/run.js.map +1 -0
  21. package/dist/session/session.d.ts +9 -16
  22. package/dist/session/session.js +193 -320
  23. package/dist/session/session.js.map +1 -1
  24. package/dist/session/snapshot.js +20 -0
  25. package/dist/session/snapshot.js.map +1 -0
  26. package/dist/session/store/file.d.ts +14 -0
  27. package/dist/session/store/file.js +106 -0
  28. package/dist/session/store/file.js.map +1 -0
  29. package/dist/session/store/memory.d.ts +13 -0
  30. package/dist/session/store/memory.js +31 -0
  31. package/dist/session/store/memory.js.map +1 -0
  32. package/dist/session/store/types.d.ts +22 -0
  33. package/package.json +16 -2
  34. package/dist/agent-loop.d.ts.map +0 -1
  35. package/dist/agent.d.ts.map +0 -1
  36. package/dist/index.d.ts.map +0 -1
  37. package/dist/index.js.map +0 -1
  38. package/dist/llm.d.ts.map +0 -1
  39. package/dist/session/events.d.ts.map +0 -1
  40. package/dist/session/events.js +0 -2
  41. package/dist/session/events.js.map +0 -1
  42. package/dist/session/history.d.ts +0 -11
  43. package/dist/session/history.d.ts.map +0 -1
  44. package/dist/session/mapping.d.ts +0 -7
  45. package/dist/session/mapping.d.ts.map +0 -1
  46. package/dist/session/session.d.ts.map +0 -1
@@ -1,332 +1,205 @@
1
1
  import { runAgentLoop } from "../agent-loop.js";
2
2
  import { AgentModelHistory } from "./history.js";
3
- export class AgentSession {
4
- #listeners = new Set();
5
- #llm;
6
- #history;
7
- #onHistoryChange;
8
- #inputQueue = [];
9
- #running = false;
10
- #activeAbort;
11
- #killAbort = new AbortController();
12
- #interruptAbort = new AbortController();
13
- #killed = false;
14
- #historyPromiseChain = Promise.resolve();
15
- #pendingWrites = new Set();
16
- #settledWriteErrors = new Set();
17
- #turnErrorEmitted = false;
18
- constructor(llm, options) {
19
- this.#llm = llm;
20
- const { history, onHistoryChange } = options ?? {};
21
- this.#onHistoryChange = onHistoryChange;
22
- this.#history = new AgentModelHistory(history, onHistoryChange
23
- ? (snapshot) => this.#enqueueHistoryChange(snapshot, onHistoryChange)
24
- : undefined);
25
- }
26
- getHistory() {
27
- return this.#history.modelSnapshot();
28
- }
29
- subscribe(listener) {
30
- this.#listeners.add(listener);
31
- return () => this.#listeners.delete(listener);
32
- }
33
- submit(input) {
34
- if (this.#killed) {
35
- return Promise.reject(sessionKilledError());
36
- }
37
- const acceptedInput = structuredClone(input);
38
- this.#emit(acceptedInput);
39
- if (this.#killed) {
40
- return Promise.reject(sessionKilledError());
41
- }
42
- const queued = new Promise((resolve, reject) => {
43
- this.#inputQueue.push({
44
- input: structuredClone(acceptedInput),
45
- resolve,
46
- reject,
47
- });
48
- });
49
- this.#drainInputQueue().catch((error) => {
50
- this.#emitTurnError(error);
51
- });
52
- return queued;
53
- }
54
- interrupt() {
55
- if (!this.#activeAbort) {
56
- return;
57
- }
58
- this.#activeAbort.abort();
59
- this.#interruptAbort.abort();
60
- }
61
- kill() {
62
- if (this.#killed) {
63
- return;
64
- }
65
- this.#killed = true;
66
- this.#killAbort.abort();
67
- this.#activeAbort?.abort();
68
- while (this.#inputQueue.length > 0) {
69
- this.#inputQueue.shift()?.reject(sessionKilledError());
70
- }
71
- }
72
- async #drainInputQueue() {
73
- if (this.#running) {
74
- return;
75
- }
76
- this.#running = true;
77
- try {
78
- while (!this.#killed && this.#inputQueue.length > 0) {
79
- const item = this.#inputQueue.shift();
80
- if (item) {
81
- await this.#processQueuedInput(item);
82
- }
83
- }
84
- }
85
- finally {
86
- this.#running = false;
87
- this.#interruptAbort = new AbortController();
88
- }
89
- }
90
- async #processQueuedInput(item) {
91
- this.#activeAbort = new AbortController();
92
- const historySnapshot = this.#history.modelSnapshot();
93
- this.#pendingWrites.clear();
94
- this.#settledWriteErrors.clear();
95
- try {
96
- this.#turnErrorEmitted = false;
97
- this.#emit({ type: "turn-start" });
98
- this.#history.appendUserInput(item.input);
99
- const userHistoryWrite = this.#pendingHistoryWrites({
100
- unblockOnKill: true,
101
- unblockOnInterrupt: true,
102
- });
103
- if (userHistoryWrite) {
104
- await userHistoryWrite;
105
- }
106
- const result = await runAgentLoop({
107
- emit: (event) => this.#emit(event),
108
- history: this.#history,
109
- llm: this.#llm,
110
- signal: this.#activeAbort.signal,
111
- });
112
- const turnHistoryWrites = this.#pendingHistoryWrites({
113
- unblockOnKill: true,
114
- unblockOnInterrupt: true,
115
- });
116
- if (turnHistoryWrites) {
117
- await turnHistoryWrites;
118
- }
119
- const interrupted = result === "aborted";
120
- this.#emit({ type: interrupted ? "turn-abort" : "turn-end" });
121
- if (interrupted) {
122
- this.#interruptAbort = new AbortController();
123
- }
124
- item.resolve();
125
- }
126
- catch (error) {
127
- if (this.#killed && isSessionKilledError(error)) {
128
- this.#history.rollback(historySnapshot);
129
- this.#emit({ type: "turn-abort" });
130
- item.resolve();
131
- return;
132
- }
133
- if (isSessionInterruptedError(error)) {
134
- this.#repairHistoryPersistenceAfterInterruptedWait();
135
- this.#pendingWrites.clear();
136
- this.#interruptAbort = new AbortController();
137
- this.#emit({ type: "turn-abort" });
138
- item.resolve();
139
- return;
140
- }
141
- await this.#rollbackAndRejectInput(item, historySnapshot, error);
142
- }
143
- finally {
144
- this.#pendingWrites.clear();
145
- this.#activeAbort = undefined;
146
- }
147
- }
148
- async #rollbackAndRejectInput(item, historySnapshot, error) {
149
- this.#history.rollback(historySnapshot);
150
- let rejectionError = error;
151
- try {
152
- const rollbackHistoryWrite = this.#pendingHistoryWrites({
153
- unblockOnKill: true,
154
- });
155
- if (rollbackHistoryWrite) {
156
- await rollbackHistoryWrite;
157
- }
158
- }
159
- catch (rollbackOrWriteError) {
160
- rejectionError = mergeTurnAndPersistenceErrors(error, rollbackOrWriteError);
161
- }
162
- this.#emitTurnError(rejectionError);
163
- item.reject(rejectionError);
164
- }
165
- #enqueueHistoryChange(snapshot, onHistoryChange) {
166
- const writePromise = this.#historyPromiseChain.then(async () => {
167
- try {
168
- await onHistoryChange(structuredClone(snapshot));
169
- }
170
- catch (error) {
171
- throw createPersistenceError(error);
172
- }
173
- });
174
- this.#historyPromiseChain = writePromise.catch(() => {
175
- // Keep later history writes sequenced even if this write fails.
176
- });
177
- this.#pendingWrites.add(writePromise);
178
- writePromise.then(() => this.#pendingWrites.delete(writePromise), (error) => {
179
- this.#settledWriteErrors.add(error);
180
- this.#pendingWrites.delete(writePromise);
181
- });
182
- }
183
- #repairHistoryPersistenceAfterInterruptedWait() {
184
- const onHistoryChange = this.#onHistoryChange;
185
- if (!onHistoryChange) {
186
- return;
187
- }
188
- const abandonedChain = this.#historyPromiseChain;
189
- this.#historyPromiseChain = Promise.resolve();
190
- abandonedChain.then(() => {
191
- if (this.#killed) {
192
- return;
193
- }
194
- this.#enqueueHistoryChange(this.#history.modelSnapshot(), onHistoryChange);
195
- });
196
- }
197
- async #awaitPendingHistoryWrites(options) {
198
- const errors = [];
199
- while (this.#pendingWrites.size > 0) {
200
- const writes = [...this.#pendingWrites];
201
- const settledWrites = Promise.allSettled(writes);
202
- const results = await this.#settleHistoryWrites(settledWrites, options);
203
- for (const result of results) {
204
- if (result.status === "rejected") {
205
- errors.push(result.reason);
206
- }
207
- }
208
- this.#settledWriteErrors.clear();
209
- }
210
- if (errors.length > 0) {
211
- throw combinePersistenceErrors(errors);
212
- }
213
- }
214
- #pendingHistoryWrites(options) {
215
- if (this.#pendingWrites.size === 0) {
216
- return;
217
- }
218
- return this.#awaitPendingHistoryWrites(options);
219
- }
220
- async #settleHistoryWrites(writes, options) {
221
- if (!(options?.unblockOnKill || options?.unblockOnInterrupt)) {
222
- return writes;
223
- }
224
- let interruptibleWrites = writes;
225
- if (options.unblockOnKill) {
226
- interruptibleWrites = rejectOnKill(interruptibleWrites, this.#killAbort.signal);
227
- }
228
- if (options.unblockOnInterrupt) {
229
- interruptibleWrites = rejectOnInterrupt(interruptibleWrites, this.#interruptAbort.signal);
230
- }
231
- try {
232
- return await interruptibleWrites;
233
- }
234
- catch (error) {
235
- if (isSessionKilledError(error) || isSessionInterruptedError(error)) {
236
- await waitForAbortRaceSettlements();
237
- if (this.#settledWriteErrors.size > 0) {
238
- const settledErrors = [...this.#settledWriteErrors];
239
- this.#settledWriteErrors.clear();
240
- throw combinePersistenceErrors(settledErrors);
241
- }
242
- }
243
- throw error;
244
- }
245
- }
246
- #emitTurnError(error) {
247
- if (this.#turnErrorEmitted) {
248
- return;
249
- }
250
- this.#turnErrorEmitted = true;
251
- this.#emit({ type: "turn-error", message: errorMessage(error) });
252
- }
253
- #emit(event) {
254
- for (const listener of this.#listeners) {
255
- listener(event);
256
- }
257
- }
3
+ import { BufferedAgentRun } from "./run.js";
4
+ import { decodeStoredSessionSnapshot, encodeSessionSnapshot } from "./snapshot.js";
5
+ //#region src/session/session.ts
6
+ var AgentSession = class {
7
+ #inputQueue = [];
8
+ #llm;
9
+ #persistence;
10
+ #activeAbort;
11
+ #history = new AgentModelHistory();
12
+ #killed = false;
13
+ #loadPromise;
14
+ #loaded = false;
15
+ #running = false;
16
+ #storeVersion;
17
+ constructor(llm, persistence) {
18
+ this.#llm = llm;
19
+ this.#persistence = persistence;
20
+ }
21
+ async send(input) {
22
+ if (this.#killed) throw sessionKilledError();
23
+ await this.#ensureLoaded();
24
+ if (this.#killed) throw sessionKilledError();
25
+ const acceptedInput = normalizeAgentInput(input);
26
+ const run = new BufferedAgentRun();
27
+ run.emit(acceptedInput);
28
+ this.#inputQueue.push({
29
+ input: structuredClone(acceptedInput),
30
+ run
31
+ });
32
+ this.#drainInputQueue().catch((error) => {
33
+ run.emit({
34
+ type: "turn-error",
35
+ message: errorMessage(error)
36
+ });
37
+ run.close();
38
+ });
39
+ return run;
40
+ }
41
+ interrupt() {
42
+ this.#activeAbort?.abort();
43
+ }
44
+ kill() {
45
+ if (this.#killed) return;
46
+ this.#killed = true;
47
+ this.#activeAbort?.abort();
48
+ while (this.#inputQueue.length > 0) {
49
+ const item = this.#inputQueue.shift();
50
+ item?.run.emit({
51
+ type: "turn-error",
52
+ message: sessionKilledError().message
53
+ });
54
+ item?.run.close();
55
+ }
56
+ }
57
+ async #ensureLoaded() {
58
+ if (this.#loaded) return;
59
+ this.#loadPromise ??= this.#loadSessionState();
60
+ try {
61
+ await this.#loadPromise;
62
+ } catch (error) {
63
+ this.#loadPromise = void 0;
64
+ throw error;
65
+ }
66
+ }
67
+ async #loadSessionState() {
68
+ if (this.#loaded) return;
69
+ await this.#replaceWithStoredSession();
70
+ this.#loaded = true;
71
+ }
72
+ async #replaceWithStoredSession() {
73
+ const stored = await this.#persistence.store.load(this.#persistence.key);
74
+ this.#storeVersion = stored?.version;
75
+ this.#history = new AgentModelHistory(decodeStoredSessionSnapshot(stored));
76
+ }
77
+ async #drainInputQueue() {
78
+ if (this.#running) return;
79
+ this.#running = true;
80
+ try {
81
+ while (!this.#killed && this.#inputQueue.length > 0) {
82
+ const item = this.#inputQueue.shift();
83
+ if (item) await this.#processQueuedInput(item);
84
+ }
85
+ } finally {
86
+ this.#running = false;
87
+ }
88
+ }
89
+ async #processQueuedInput({ input, run }) {
90
+ this.#activeAbort = new AbortController();
91
+ const historySnapshot = this.#history.modelSnapshot();
92
+ try {
93
+ run.emit({ type: "turn-start" });
94
+ this.#history.appendUserInput(input);
95
+ await this.#commitHistory();
96
+ const result = await runAgentLoop({
97
+ emit: (event) => run.emit(event),
98
+ history: this.#history,
99
+ llm: this.#llm,
100
+ signal: this.#activeAbort.signal
101
+ });
102
+ await this.#commitHistory();
103
+ run.emit({ type: result === "aborted" ? "turn-abort" : "turn-end" });
104
+ } catch (error) {
105
+ if (error instanceof SessionCommitConflictError) {
106
+ run.emit({
107
+ type: "turn-error",
108
+ message: error.message
109
+ });
110
+ return;
111
+ }
112
+ this.#history.rollback(historySnapshot);
113
+ try {
114
+ await this.#commitHistory();
115
+ } catch (rollbackError) {
116
+ run.emit({
117
+ type: "turn-error",
118
+ message: `${errorMessage(error)}; history rollback persistence failed: ${errorMessage(rollbackError)}`
119
+ });
120
+ return;
121
+ }
122
+ run.emit({
123
+ type: "turn-error",
124
+ message: errorMessage(error)
125
+ });
126
+ } finally {
127
+ run.close();
128
+ this.#activeAbort = void 0;
129
+ }
130
+ }
131
+ async #commitHistory() {
132
+ const result = await this.#persistence.store.commit(this.#persistence.key, {
133
+ state: encodeSessionSnapshot(this.#history.modelSnapshot()),
134
+ version: this.#storeVersion
135
+ }, { expectedVersion: this.#storeVersion ?? null });
136
+ if (!result.ok) {
137
+ await this.#replaceWithStoredSession();
138
+ throw new SessionCommitConflictError(this.#persistence.key);
139
+ }
140
+ this.#storeVersion = result.version;
141
+ }
142
+ };
143
+ function normalizeAgentInput(input) {
144
+ if (typeof input === "string") return {
145
+ type: "user-text",
146
+ text: input
147
+ };
148
+ if (isStringArrayInput(input)) return {
149
+ type: "user-text",
150
+ text: structuredClone(input)
151
+ };
152
+ if (isArrayInput(input)) {
153
+ assertUserMessageContent(input);
154
+ return {
155
+ type: "user-message",
156
+ content: structuredClone(input)
157
+ };
158
+ }
159
+ if (isUserMessage(input)) assertUserMessageContent(input.content);
160
+ return structuredClone(input);
258
161
  }
259
- function createPersistenceError(error) {
260
- return new Error(`onHistoryChange failed: ${errorMessage(error)}`);
162
+ function isStringArrayInput(input) {
163
+ return isArrayInput(input) && input.every((part) => typeof part === "string");
261
164
  }
262
- function combinePersistenceErrors(errors) {
263
- if (errors.length === 1) {
264
- return errors[0];
265
- }
266
- const messages = [...new Set(errors.map((error) => errorMessage(error)))];
267
- return new Error(`Multiple onHistoryChange failures: ${messages.join("; ")}`);
165
+ function isArrayInput(input) {
166
+ return Array.isArray(input);
268
167
  }
269
- function mergeTurnAndPersistenceErrors(turnError, persistenceError) {
270
- return new Error(`${errorMessage(turnError)}; history rollback persistence failed: ${errorMessage(persistenceError)}`);
168
+ function isUserMessage(input) {
169
+ return input.type === "user-message";
271
170
  }
272
- function errorMessage(error) {
273
- if (error instanceof Error) {
274
- return error.message;
275
- }
276
- return String(error);
277
- }
278
- function sessionKilledError() {
279
- return new Error("Session killed");
280
- }
281
- function isSessionKilledError(error) {
282
- return error instanceof Error && error.message === "Session killed";
171
+ function assertUserMessageContent(input) {
172
+ for (const part of input) if (!isUserMessageContentPart(part)) throw new TypeError("Agent input content parts must be { type: \"text\", text }, { type: \"image\", image }, or { type: \"file\", data, mediaType }.");
283
173
  }
284
- function sessionInterruptedError() {
285
- return new Error("Session interrupted");
174
+ function isUserMessageContentPart(part) {
175
+ if (part === null || typeof part !== "object" || !("type" in part)) return false;
176
+ if (part.type === "text") return "text" in part && typeof part.text === "string";
177
+ if (part.type === "image") return "image" in part && typeof part.image === "string" && (!("mediaType" in part) || typeof part.mediaType === "string");
178
+ if (part.type === "file") return "data" in part && isUserMessageFileData(part.data) && "mediaType" in part && typeof part.mediaType === "string" && (!("filename" in part) || typeof part.filename === "string");
179
+ return false;
286
180
  }
287
- function isSessionInterruptedError(error) {
288
- return error instanceof Error && error.message === "Session interrupted";
181
+ function isUserMessageFileData(data) {
182
+ if (typeof data === "string") return true;
183
+ if (data === null || typeof data !== "object" || !("type" in data)) return false;
184
+ if (data.type === "data") return "data" in data && typeof data.data === "string";
185
+ if (data.type === "reference") return "reference" in data && data.reference !== null && typeof data.reference === "object" && Object.values(data.reference).every((value) => typeof value === "string");
186
+ if (data.type === "text") return "text" in data && typeof data.text === "string";
187
+ if (data.type === "url") return "url" in data && typeof data.url === "string";
188
+ return false;
289
189
  }
290
- async function waitForAbortRaceSettlements() {
291
- await new Promise((resolve) => {
292
- setTimeout(resolve, 0);
293
- });
294
- }
295
- function rejectOnKill(promise, signal) {
296
- return rejectOnSignal(promise, signal, sessionKilledError);
297
- }
298
- function rejectOnInterrupt(promise, signal) {
299
- return rejectOnSignal(promise, signal, sessionInterruptedError);
190
+ function errorMessage(error) {
191
+ if (error instanceof Error) return error.message;
192
+ return String(error);
300
193
  }
301
- function rejectOnSignal(promise, signal, createError) {
302
- if (signal.aborted) {
303
- return new Promise((_, reject) => {
304
- setTimeout(() => reject(createError()), 0);
305
- });
306
- }
307
- return new Promise((resolve, reject) => {
308
- let abortTimeout;
309
- const cleanup = () => {
310
- signal.removeEventListener("abort", onAbort);
311
- if (abortTimeout) {
312
- clearTimeout(abortTimeout);
313
- }
314
- };
315
- const onAbort = () => {
316
- signal.removeEventListener("abort", onAbort);
317
- abortTimeout = setTimeout(() => {
318
- abortTimeout = undefined;
319
- reject(createError());
320
- }, 0);
321
- };
322
- signal.addEventListener("abort", onAbort, { once: true });
323
- promise.then((value) => {
324
- cleanup();
325
- resolve(value);
326
- }, (error) => {
327
- cleanup();
328
- reject(error);
329
- });
330
- });
194
+ function sessionKilledError() {
195
+ return /* @__PURE__ */ new Error("Session killed");
331
196
  }
197
+ var SessionCommitConflictError = class extends Error {
198
+ constructor(key) {
199
+ super(`Session ${JSON.stringify(key)} commit conflict`);
200
+ }
201
+ };
202
+ //#endregion
203
+ export { AgentSession };
204
+
332
205
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","names":["#inputQueue","#llm","#persistence","#killed","#ensureLoaded","#drainInputQueue","#activeAbort","#loaded","#loadPromise","#loadSessionState","#replaceWithStoredSession","#storeVersion","#history","#running","#processQueuedInput","#commitHistory"],"sources":["../../src/session/session.ts"],"sourcesContent":["import { runAgentLoop } from \"../agent-loop\";\nimport type { Llm } from \"../llm\";\nimport type { UserMessage, UserMessageContentPart, UserText } from \"./events\";\nimport { AgentModelHistory } from \"./history\";\nimport type { AgentRun } from \"./run\";\nimport { BufferedAgentRun } from \"./run\";\nimport { decodeStoredSessionSnapshot, encodeSessionSnapshot } from \"./snapshot\";\nimport type { SessionStore } from \"./store/types\";\n\nexport type UserInput = UserMessage | UserText;\nexport type AgentInput =\n | readonly string[]\n | readonly UserMessageContentPart[]\n | string\n | UserInput;\nexport type SessionInput = AgentInput;\nexport type { AgentRun } from \"./run\";\n\ninterface SessionPersistenceOptions {\n readonly key: string;\n readonly store: SessionStore;\n}\n\ninterface QueuedInput {\n readonly input: UserInput;\n readonly run: BufferedAgentRun;\n}\n\nexport class AgentSession {\n readonly #inputQueue: QueuedInput[] = [];\n readonly #llm: Llm;\n readonly #persistence: SessionPersistenceOptions;\n #activeAbort?: AbortController;\n #history = new AgentModelHistory();\n #killed = false;\n #loadPromise?: Promise<void>;\n #loaded = false;\n #running = false;\n #storeVersion: string | undefined;\n\n constructor(llm: Llm, persistence: SessionPersistenceOptions) {\n this.#llm = llm;\n this.#persistence = persistence;\n }\n\n async send(input: AgentInput): Promise<AgentRun> {\n if (this.#killed) {\n throw sessionKilledError();\n }\n\n await this.#ensureLoaded();\n\n if (this.#killed) {\n throw sessionKilledError();\n }\n\n const acceptedInput = normalizeAgentInput(input);\n const run = new BufferedAgentRun();\n run.emit(acceptedInput);\n this.#inputQueue.push({ input: structuredClone(acceptedInput), run });\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 interrupt(): void {\n this.#activeAbort?.abort();\n }\n\n kill(): void {\n if (this.#killed) {\n return;\n }\n\n this.#killed = true;\n this.#activeAbort?.abort();\n\n while (this.#inputQueue.length > 0) {\n const item = this.#inputQueue.shift();\n item?.run.emit({\n type: \"turn-error\",\n message: sessionKilledError().message,\n });\n item?.run.close();\n }\n }\n\n async #ensureLoaded(): Promise<void> {\n if (this.#loaded) {\n return;\n }\n\n this.#loadPromise ??= this.#loadSessionState();\n try {\n await this.#loadPromise;\n } catch (error) {\n this.#loadPromise = undefined;\n throw error;\n }\n }\n\n async #loadSessionState(): Promise<void> {\n if (this.#loaded) {\n return;\n }\n\n await this.#replaceWithStoredSession();\n this.#loaded = true;\n }\n\n async #replaceWithStoredSession(): Promise<void> {\n const stored = await this.#persistence.store.load(this.#persistence.key);\n this.#storeVersion = stored?.version;\n this.#history = new AgentModelHistory(decodeStoredSessionSnapshot(stored));\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({ input, run }: QueuedInput): Promise<void> {\n this.#activeAbort = new AbortController();\n const historySnapshot = this.#history.modelSnapshot();\n\n try {\n run.emit({ type: \"turn-start\" });\n this.#history.appendUserInput(input);\n await this.#commitHistory();\n\n const result = await runAgentLoop({\n emit: (event) => run.emit(event),\n history: this.#history,\n llm: this.#llm,\n signal: this.#activeAbort.signal,\n });\n\n await this.#commitHistory();\n run.emit({ type: result === \"aborted\" ? \"turn-abort\" : \"turn-end\" });\n } catch (error) {\n if (error instanceof SessionCommitConflictError) {\n run.emit({ type: \"turn-error\", message: error.message });\n return;\n }\n\n this.#history.rollback(historySnapshot);\n try {\n await this.#commitHistory();\n } catch (rollbackError) {\n run.emit({\n type: \"turn-error\",\n message: `${errorMessage(error)}; history rollback persistence failed: ${errorMessage(\n rollbackError\n )}`,\n });\n return;\n }\n run.emit({ type: \"turn-error\", message: errorMessage(error) });\n } finally {\n run.close();\n this.#activeAbort = undefined;\n }\n }\n\n async #commitHistory(): Promise<void> {\n const result = await this.#persistence.store.commit(\n this.#persistence.key,\n {\n state: encodeSessionSnapshot(this.#history.modelSnapshot()),\n version: this.#storeVersion,\n },\n { expectedVersion: this.#storeVersion ?? null }\n );\n\n if (!result.ok) {\n await this.#replaceWithStoredSession();\n throw new SessionCommitConflictError(this.#persistence.key);\n }\n\n this.#storeVersion = result.version;\n }\n}\n\nexport function normalizeAgentInput(input: AgentInput): UserInput {\n if (typeof input === \"string\") {\n return {\n type: \"user-text\",\n text: input,\n };\n }\n\n if (isStringArrayInput(input)) {\n return {\n type: \"user-text\",\n text: structuredClone(input) as readonly string[],\n };\n }\n\n if (isArrayInput(input)) {\n assertUserMessageContent(input);\n return {\n type: \"user-message\",\n content: structuredClone(input) as readonly UserMessageContentPart[],\n };\n }\n\n if (isUserMessage(input)) {\n assertUserMessageContent(input.content);\n }\n\n return structuredClone(input);\n}\n\nfunction isStringArrayInput(input: AgentInput): input is readonly string[] {\n return isArrayInput(input) && input.every((part) => typeof part === \"string\");\n}\n\nfunction isArrayInput(\n input: AgentInput\n): input is readonly string[] | readonly UserMessageContentPart[] {\n return Array.isArray(input);\n}\n\nfunction isUserMessage(input: UserInput): input is UserMessage {\n return input.type === \"user-message\";\n}\n\nfunction assertUserMessageContent(\n input: readonly unknown[]\n): asserts input is readonly UserMessageContentPart[] {\n for (const part of input) {\n if (!isUserMessageContentPart(part)) {\n throw new TypeError(\n 'Agent input content parts must be { type: \"text\", text }, { type: \"image\", image }, or { type: \"file\", data, mediaType }.'\n );\n }\n }\n}\n\nfunction isUserMessageContentPart(\n part: unknown\n): part is UserMessageContentPart {\n if (part === null || typeof part !== \"object\" || !(\"type\" in part)) {\n return false;\n }\n\n if (part.type === \"text\") {\n return \"text\" in part && typeof part.text === \"string\";\n }\n\n if (part.type === \"image\") {\n return (\n \"image\" in part &&\n typeof part.image === \"string\" &&\n (!(\"mediaType\" in part) || typeof part.mediaType === \"string\")\n );\n }\n\n if (part.type === \"file\") {\n return (\n \"data\" in part &&\n isUserMessageFileData(part.data) &&\n \"mediaType\" in part &&\n typeof part.mediaType === \"string\" &&\n (!(\"filename\" in part) || typeof part.filename === \"string\")\n );\n }\n\n return false;\n}\n\nfunction isUserMessageFileData(data: unknown): boolean {\n if (typeof data === \"string\") {\n return true;\n }\n\n if (data === null || typeof data !== \"object\" || !(\"type\" in data)) {\n return false;\n }\n\n if (data.type === \"data\") {\n return \"data\" in data && typeof data.data === \"string\";\n }\n\n if (data.type === \"reference\") {\n return (\n \"reference\" in data &&\n data.reference !== null &&\n typeof data.reference === \"object\" &&\n Object.values(data.reference).every((value) => typeof value === \"string\")\n );\n }\n\n if (data.type === \"text\") {\n return \"text\" in data && typeof data.text === \"string\";\n }\n\n if (data.type === \"url\") {\n return \"url\" in data && typeof data.url === \"string\";\n }\n\n return false;\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n return String(error);\n}\n\nfunction sessionKilledError(): Error {\n return new Error(\"Session killed\");\n}\n\nclass SessionCommitConflictError extends Error {\n constructor(key: string) {\n super(`Session ${JSON.stringify(key)} commit conflict`);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ //#region src/session/snapshot.ts
2
+ function encodeSessionSnapshot(history) {
3
+ return {
4
+ schemaVersion: 1,
5
+ history: structuredClone(history)
6
+ };
7
+ }
8
+ function decodeStoredSessionSnapshot(stored) {
9
+ if (!stored) return [];
10
+ const snapshot = stored.state;
11
+ if (isSessionSnapshotV1(snapshot)) return structuredClone(snapshot.history);
12
+ throw new Error("Unsupported stored session state");
13
+ }
14
+ function isSessionSnapshotV1(value) {
15
+ return value !== null && typeof value === "object" && "schemaVersion" in value && value.schemaVersion === 1 && "history" in value && Array.isArray(value.history);
16
+ }
17
+ //#endregion
18
+ export { decodeStoredSessionSnapshot, encodeSessionSnapshot };
19
+
20
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","names":[],"sources":["../../src/session/snapshot.ts"],"sourcesContent":["import type { AgentMessage } from \"../llm\";\nimport type { StoredSession } from \"./store/types\";\n\nexport interface AgentSessionSnapshotV1 {\n readonly history: AgentMessage[];\n readonly schemaVersion: 1;\n}\n\nexport type AgentSessionSnapshot = AgentSessionSnapshotV1;\n\nexport function encodeSessionSnapshot(\n history: AgentMessage[]\n): AgentSessionSnapshot {\n return { schemaVersion: 1, history: structuredClone(history) };\n}\n\nexport function decodeStoredSessionSnapshot(\n stored: StoredSession | null\n): AgentMessage[] {\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":";AAUA,SAAgB,sBACd,SACsB;CACtB,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"}
@@ -0,0 +1,14 @@
1
+ import { CommitResult, SessionStore, StoredSession } from "./types.js";
2
+
3
+ //#region src/session/store/file.d.ts
4
+ declare class FileSessionStore implements SessionStore {
5
+ #private;
6
+ constructor(directory: string);
7
+ load(key: string): Promise<StoredSession | null>;
8
+ commit(key: string, next: StoredSession, options?: {
9
+ expectedVersion?: string | null;
10
+ }): Promise<CommitResult>;
11
+ }
12
+ //#endregion
13
+ export { FileSessionStore };
14
+ //# sourceMappingURL=file.d.ts.map