@di-code/coding-agent 0.1.9 → 0.2.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 +7 -0
- package/compositions/base.yml +3 -0
- package/dist/compositions.d.ts.map +1 -1
- package/dist/compositions.js +2 -0
- package/dist/compositions.js.map +1 -1
- package/dist/core/image-input.d.ts +1 -1
- package/dist/core/image-input.d.ts.map +1 -1
- package/dist/core/image-input.js +15 -4
- package/dist/core/image-input.js.map +1 -1
- package/dist/core/session/session-manager.d.ts +18 -1
- package/dist/core/session/session-manager.d.ts.map +1 -1
- package/dist/core/session/session-manager.js +90 -1
- package/dist/core/session/session-manager.js.map +1 -1
- package/dist/core/session/session-storage.d.ts +2 -0
- package/dist/core/session/session-storage.d.ts.map +1 -1
- package/dist/core/session/session-storage.js +34 -2
- package/dist/core/session/session-storage.js.map +1 -1
- package/dist/core/session/types.d.ts +16 -1
- package/dist/core/session/types.d.ts.map +1 -1
- package/dist/core/session/types.js.map +1 -1
- package/dist/core/session.d.ts +27 -2
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +59 -0
- package/dist/core/session.js.map +1 -1
- package/dist/entry.js +1 -1
- package/dist/entry.js.map +1 -1
- package/dist/i18n.js +4 -4
- package/dist/i18n.js.map +1 -1
- package/dist/interactive-host-entry.d.ts.map +1 -1
- package/dist/interactive-host-entry.js +107 -12
- package/dist/interactive-host-entry.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +8 -1
- package/dist/main.js.map +1 -1
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +19 -0
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp-command-entry.d.ts +8 -0
- package/dist/mcp-command-entry.d.ts.map +1 -0
- package/dist/mcp-command-entry.js +56 -0
- package/dist/mcp-command-entry.js.map +1 -0
- package/dist/modes/interactive-components.d.ts +8 -0
- package/dist/modes/interactive-components.d.ts.map +1 -1
- package/dist/modes/interactive-components.js +7 -2
- package/dist/modes/interactive-components.js.map +1 -1
- package/dist/modes/interactive-state.d.ts.map +1 -1
- package/dist/modes/interactive-state.js +1 -4
- package/dist/modes/interactive-state.js.map +1 -1
- package/dist/modes/interactive.d.ts +4 -0
- package/dist/modes/interactive.d.ts.map +1 -1
- package/dist/modes/interactive.js +69 -0
- package/dist/modes/interactive.js.map +1 -1
- package/dist/modes/tree-selector.d.ts.map +1 -1
- package/dist/modes/tree-selector.js +5 -4
- package/dist/modes/tree-selector.js.map +1 -1
- package/dist/rpc/client.d.ts +2 -0
- package/dist/rpc/client.d.ts.map +1 -1
- package/dist/rpc/client.js +3 -0
- package/dist/rpc/client.js.map +1 -1
- package/dist/rpc/dispatcher.d.ts +14 -0
- package/dist/rpc/dispatcher.d.ts.map +1 -1
- package/dist/rpc/dispatcher.js +222 -7
- package/dist/rpc/dispatcher.js.map +1 -1
- package/dist/rpc/protocol.d.ts +12 -5
- package/dist/rpc/protocol.d.ts.map +1 -1
- package/dist/rpc/protocol.js +56 -0
- package/dist/rpc/protocol.js.map +1 -1
- package/dist/rpc/server.d.ts +5 -0
- package/dist/rpc/server.d.ts.map +1 -1
- package/dist/rpc/server.js +4 -0
- package/dist/rpc/server.js.map +1 -1
- package/dist/rpc-server-entry.d.ts.map +1 -1
- package/dist/rpc-server-entry.js +15 -1
- package/dist/rpc-server-entry.js.map +1 -1
- package/dist/runtime/product-host.d.ts +7 -0
- package/dist/runtime/product-host.d.ts.map +1 -1
- package/dist/runtime/product-host.js +29 -9
- package/dist/runtime/product-host.js.map +1 -1
- package/dist/runtime/session-factory.d.ts +18 -2
- package/dist/runtime/session-factory.d.ts.map +1 -1
- package/dist/runtime/session-factory.js +286 -23
- package/dist/runtime/session-factory.js.map +1 -1
- package/dist/runtime/session-host.d.ts +46 -1
- package/dist/runtime/session-host.d.ts.map +1 -1
- package/dist/runtime/session-host.js +38 -6
- package/dist/runtime/session-host.js.map +1 -1
- package/dist/ui-host.d.ts.map +1 -1
- package/dist/ui-host.js +3 -0
- package/dist/ui-host.js.map +1 -1
- package/dist/web/assets/index-C2SOU925.css +1 -0
- package/dist/web/assets/index-knXkInvO.js +41 -0
- package/dist/web/assets/index-knXkInvO.js.map +1 -0
- package/dist/web/index.html +2 -2
- package/dist/web-command.d.ts.map +1 -1
- package/dist/web-command.js +8 -1
- package/dist/web-command.js.map +1 -1
- package/dist/webui-entry.js +9 -1
- package/dist/webui-entry.js.map +1 -1
- package/dist/webui.d.ts +10 -0
- package/dist/webui.d.ts.map +1 -1
- package/dist/webui.js +21 -0
- package/dist/webui.js.map +1 -1
- package/package.json +11 -9
- package/dist/web/assets/index-BwfuGMvv.css +0 -1
- package/dist/web/assets/index-DPUaJqFJ.js +0 -41
- package/dist/web/assets/index-DPUaJqFJ.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-storage.d.ts","sourceRoot":"","sources":["../../../src/core/session/session-storage.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,aAAa,EAElB,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"session-storage.d.ts","sourceRoot":"","sources":["../../../src/core/session/session-storage.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,aAAa,EAElB,KAAK,YAAY,EAEjB,KAAK,aAAa,EAMlB,MAAM,YAAY,CAAC;AAIpB,eAAO,MAAM,+BAA+B,QAAa,CAAC;AAwP1D,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAiF9E;AAkBD,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAaD,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB9F;AAsDD,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,oBAAyB,GAChC,OAAO,CAAC,IAAI,CAAC,CAqFf"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { appendFile, mkdir, open, readFile, unlink } from "node:fs/promises";
|
|
2
2
|
import { dirname, posix, win32 } from "node:path";
|
|
3
3
|
import { SESSION_FORMAT_VERSION, SessionLoadError, SessionWriteError, } from "./types.js";
|
|
4
|
+
const MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
5
|
+
export const MAX_SESSION_EVENT_PAYLOAD_BYTES = 256 * 1024;
|
|
4
6
|
function isObject(value) {
|
|
5
7
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
8
|
}
|
|
@@ -34,11 +36,22 @@ function isJsonValue(value) {
|
|
|
34
36
|
return value.every(isJsonValue);
|
|
35
37
|
return isObject(value) && Object.values(value).every(isJsonValue);
|
|
36
38
|
}
|
|
39
|
+
function isBoundedJsonValue(value) {
|
|
40
|
+
return isJsonValue(value) && Buffer.byteLength(JSON.stringify(value), "utf8") <= MAX_SESSION_EVENT_PAYLOAD_BYTES;
|
|
41
|
+
}
|
|
37
42
|
function isProviderReplay(value) {
|
|
38
43
|
return isObject(value) && isNonEmptyString(value.api) && isJsonValue(value.data);
|
|
39
44
|
}
|
|
40
45
|
function isImageContent(value) {
|
|
41
|
-
|
|
46
|
+
if (!isObject(value) || value.type !== "image" || typeof value.data !== "string" || !isNonEmptyString(value.mimeType))
|
|
47
|
+
return false;
|
|
48
|
+
const padding = value.data.endsWith("==") ? 2 : value.data.endsWith("=") ? 1 : 0;
|
|
49
|
+
const decodedBytes = Math.floor((value.data.length * 3) / 4) - padding;
|
|
50
|
+
return (value.data.length % 4 === 0 &&
|
|
51
|
+
/^[A-Za-z0-9+/]*={0,2}$/.test(value.data) &&
|
|
52
|
+
decodedBytes > 0 &&
|
|
53
|
+
decodedBytes <= MAX_IMAGE_BYTES &&
|
|
54
|
+
/^image\/[A-Za-z0-9.+-]+$/.test(value.mimeType));
|
|
42
55
|
}
|
|
43
56
|
function isTextContent(value) {
|
|
44
57
|
return isObject(value) && value.type === "text" && typeof value.text === "string";
|
|
@@ -54,6 +67,8 @@ function isAssistantContent(value) {
|
|
|
54
67
|
return typeof value.text === "string";
|
|
55
68
|
case "thinking":
|
|
56
69
|
return typeof value.thinking === "string";
|
|
70
|
+
case "image":
|
|
71
|
+
return isImageContent(value);
|
|
57
72
|
case "tool_call":
|
|
58
73
|
return (isNonEmptyString(value.id) &&
|
|
59
74
|
isNonEmptyString(value.name) &&
|
|
@@ -143,7 +158,8 @@ function decodeHeader(value, filePath) {
|
|
|
143
158
|
return value;
|
|
144
159
|
}
|
|
145
160
|
function decodeSessionEntry(value) {
|
|
146
|
-
if (!isObject(value) ||
|
|
161
|
+
if (!isObject(value) ||
|
|
162
|
+
(value.type !== "message" && value.type !== "summary" && value.type !== "plugin" && value.type !== "event")) {
|
|
147
163
|
return { reason: 'record type must be "message", "summary", or "plugin"' };
|
|
148
164
|
}
|
|
149
165
|
if (value.version !== SESSION_FORMAT_VERSION)
|
|
@@ -171,6 +187,18 @@ function decodeSessionEntry(value) {
|
|
|
171
187
|
return { reason: "record plugin fields are invalid" };
|
|
172
188
|
return { entry: value };
|
|
173
189
|
}
|
|
190
|
+
if (value.type === "event") {
|
|
191
|
+
if (typeof value.namespace !== "string" ||
|
|
192
|
+
!/^[a-z0-9][a-z0-9._-]*$/.test(value.namespace) ||
|
|
193
|
+
typeof value.eventName !== "string" ||
|
|
194
|
+
!/^[a-z0-9][a-z0-9._-]*$/.test(value.eventName) ||
|
|
195
|
+
typeof value.schemaVersion !== "number" ||
|
|
196
|
+
!Number.isSafeInteger(value.schemaVersion) ||
|
|
197
|
+
value.schemaVersion < 0 ||
|
|
198
|
+
!isBoundedJsonValue(value.payload))
|
|
199
|
+
return { reason: "record event fields are invalid or payload exceeds the limit" };
|
|
200
|
+
return { entry: value };
|
|
201
|
+
}
|
|
174
202
|
if (typeof value.summary !== "string" || value.summary.trim().length === 0) {
|
|
175
203
|
return { reason: "record summary must be a non-empty string" };
|
|
176
204
|
}
|
|
@@ -316,6 +344,8 @@ async function acquireLock(filePath, options) {
|
|
|
316
344
|
const sleep = options.sleep ?? delay;
|
|
317
345
|
const startedAt = now();
|
|
318
346
|
while (true) {
|
|
347
|
+
if (options.signal?.aborted)
|
|
348
|
+
throw options.signal.reason ?? new DOMException("The operation was aborted", "AbortError");
|
|
319
349
|
try {
|
|
320
350
|
return { handle: await open(lockPath, "wx"), lockPath };
|
|
321
351
|
}
|
|
@@ -358,6 +388,8 @@ async function releaseLock(handle, lockPath) {
|
|
|
358
388
|
throw closeError;
|
|
359
389
|
}
|
|
360
390
|
export async function appendSessionEntry(filePath, entry, expectedParentId, options = {}) {
|
|
391
|
+
if (options.signal?.aborted)
|
|
392
|
+
throw options.signal.reason ?? new DOMException("The operation was aborted", "AbortError");
|
|
361
393
|
const entrySnapshot = structuredClone(entry);
|
|
362
394
|
const decodedEntry = decodeSessionEntry(entrySnapshot);
|
|
363
395
|
if (!decodedEntry.entry) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-storage.js","sourceRoot":"","sources":["../../../src/core/session/session-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFile, mkdir, open, readFile, unlink } from \"node:fs/promises\";\nimport { dirname, posix, win32 } from \"node:path\";\nimport type { AssistantContent, AssistantMessage, Message, ToolResultContent, Usage, UserContent } from \"@di-code/ai\";\nimport {\n\ttype LoadedSession,\n\tSESSION_FORMAT_VERSION,\n\ttype SessionEntry,\n\ttype SessionHeader,\n\tSessionLoadError,\n\ttype SessionMessageEntry,\n\ttype SessionPluginEntry,\n\ttype SessionSummaryEntry,\n\tSessionWriteError,\n} from \"./types.ts\";\n\ntype JsonObject = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n\treturn typeof value === \"string\" && value.length > 0;\n}\n\nfunction isNonNegativeNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nfunction isTimestamp(value: unknown): value is number {\n\treturn Number.isSafeInteger(value) && isNonNegativeNumber(value);\n}\n\nfunction isIsoTimestamp(value: unknown): value is string {\n\tif (typeof value !== \"string\") return false;\n\tconst milliseconds = Date.parse(value);\n\treturn Number.isFinite(milliseconds) && new Date(milliseconds).toISOString() === value;\n}\n\nfunction isRecordId(value: unknown): value is string {\n\treturn typeof value === \"string\" && /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(value);\n}\n\nfunction isAbsolutePath(value: unknown): value is string {\n\treturn typeof value === \"string\" && (win32.isAbsolute(value) || posix.isAbsolute(value));\n}\n\nfunction isJsonValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonValue);\n\treturn isObject(value) && Object.values(value).every(isJsonValue);\n}\n\nfunction isProviderReplay(value: unknown): boolean {\n\treturn isObject(value) && isNonEmptyString(value.api) && isJsonValue(value.data);\n}\n\nfunction isImageContent(value: unknown): value is Extract<UserContent | ToolResultContent, { type: \"image\" }> {\n\treturn (\n\t\tisObject(value) && value.type === \"image\" && typeof value.data === \"string\" && isNonEmptyString(value.mimeType)\n\t);\n}\n\nfunction isTextContent(value: unknown): value is Extract<UserContent, { type: \"text\" }> {\n\treturn isObject(value) && value.type === \"text\" && typeof value.text === \"string\";\n}\n\nfunction isUserContent(value: unknown): value is UserContent {\n\treturn isTextContent(value) || isImageContent(value);\n}\n\nfunction isAssistantContent(value: unknown): value is AssistantContent {\n\tif (!isObject(value)) return false;\n\tswitch (value.type) {\n\t\tcase \"text\":\n\t\t\treturn typeof value.text === \"string\";\n\t\tcase \"thinking\":\n\t\t\treturn typeof value.thinking === \"string\";\n\t\tcase \"tool_call\":\n\t\t\treturn (\n\t\t\t\tisNonEmptyString(value.id) &&\n\t\t\t\tisNonEmptyString(value.name) &&\n\t\t\t\tisObject(value.arguments) &&\n\t\t\t\tisJsonValue(value.arguments)\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction isToolResultContent(value: unknown): value is ToolResultContent {\n\treturn isTextContent(value) || isImageContent(value);\n}\n\nfunction isUsage(value: unknown): value is Usage {\n\tif (!isObject(value) || !isObject(value.cost)) return false;\n\treturn (\n\t\tisNonNegativeNumber(value.input) &&\n\t\tisNonNegativeNumber(value.output) &&\n\t\tisNonNegativeNumber(value.cacheRead) &&\n\t\tisNonNegativeNumber(value.cacheWrite) &&\n\t\tisNonNegativeNumber(value.totalTokens) &&\n\t\tisNonNegativeNumber(value.cost.input) &&\n\t\tisNonNegativeNumber(value.cost.output) &&\n\t\tisNonNegativeNumber(value.cost.cacheRead) &&\n\t\tisNonNegativeNumber(value.cost.cacheWrite) &&\n\t\tisNonNegativeNumber(value.cost.total)\n\t);\n}\n\nfunction isAssistantMessage(value: JsonObject): value is JsonObject & AssistantMessage {\n\tif (\n\t\tvalue.role !== \"assistant\" ||\n\t\t!Array.isArray(value.content) ||\n\t\t!value.content.every(isAssistantContent) ||\n\t\t!isNonEmptyString(value.provider) ||\n\t\t!isNonEmptyString(value.model) ||\n\t\t(value.providerReplay !== undefined && !isProviderReplay(value.providerReplay)) ||\n\t\t!isUsage(value.usage) ||\n\t\t!isTimestamp(value.timestamp)\n\t) {\n\t\treturn false;\n\t}\n\n\tif (value.stopReason === \"stop\" || value.stopReason === \"length\" || value.stopReason === \"tool_use\") {\n\t\treturn value.errorMessage === undefined;\n\t}\n\tif (value.stopReason === \"error\" || value.stopReason === \"aborted\") {\n\t\treturn typeof value.errorMessage === \"string\";\n\t}\n\treturn false;\n}\n\nfunction isMessage(value: unknown): value is Message {\n\tif (!isObject(value) || !isTimestamp(value.timestamp)) return false;\n\n\tswitch (value.role) {\n\t\tcase \"user\":\n\t\t\treturn Array.isArray(value.content) && value.content.every(isUserContent);\n\t\tcase \"assistant\":\n\t\t\treturn isAssistantMessage(value);\n\t\tcase \"tool_result\":\n\t\t\treturn (\n\t\t\t\tisNonEmptyString(value.toolCallId) &&\n\t\t\t\tisNonEmptyString(value.toolName) &&\n\t\t\t\tArray.isArray(value.content) &&\n\t\t\t\tvalue.content.every(isToolResultContent) &&\n\t\t\t\t(value.details === undefined || isJsonValue(value.details)) &&\n\t\t\t\ttypeof value.isError === \"boolean\"\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction decodeHeader(value: unknown, filePath: string): SessionHeader {\n\tif (!isObject(value) || value.type !== \"session\") {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Invalid session header in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\tif (!(\"version\" in value)) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session header has no version in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\tif (value.version !== SESSION_FORMAT_VERSION) {\n\t\tthrow new SessionLoadError(\n\t\t\t\"UNSUPPORTED_VERSION\",\n\t\t\tfilePath,\n\t\t\t`Unsupported session version ${JSON.stringify(value.version)} in \"${filePath}\".`,\n\t\t\t{ lineNumber: 1 },\n\t\t);\n\t}\n\tif (\n\t\t!isRecordId(value.id) ||\n\t\tvalue.parentId !== null ||\n\t\t!isIsoTimestamp(value.timestamp) ||\n\t\t!isAbsolutePath(value.cwd)\n\t) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Invalid session header fields in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\treturn value as unknown as SessionHeader;\n}\n\nfunction decodeSessionEntry(value: unknown): { readonly entry?: SessionEntry; readonly reason?: string } {\n\tif (!isObject(value) || (value.type !== \"message\" && value.type !== \"summary\" && value.type !== \"plugin\")) {\n\t\treturn { reason: 'record type must be \"message\", \"summary\", or \"plugin\"' };\n\t}\n\tif (value.version !== SESSION_FORMAT_VERSION) return { reason: `record version must be ${SESSION_FORMAT_VERSION}` };\n\tif (!isRecordId(value.id)) return { reason: \"record id is invalid\" };\n\tif (!isRecordId(value.parentId)) return { reason: \"record parentId is invalid\" };\n\tif (!isIsoTimestamp(value.timestamp)) return { reason: \"record timestamp is not canonical ISO 8601 UTC\" };\n\tif (value.type === \"message\") {\n\t\tif (!isMessage(value.message)) return { reason: \"record message does not match the Message contract\" };\n\t\treturn { entry: value as unknown as SessionMessageEntry };\n\t}\n\tif (value.type === \"plugin\") {\n\t\tif (\n\t\t\ttypeof value.pluginId !== \"string\" ||\n\t\t\tvalue.pluginId.length === 0 ||\n\t\t\ttypeof value.pluginVersion !== \"string\" ||\n\t\t\tvalue.pluginVersion.length === 0 ||\n\t\t\ttypeof value.schemaVersion !== \"number\" ||\n\t\t\t!Number.isSafeInteger(value.schemaVersion) ||\n\t\t\tvalue.schemaVersion < 0 ||\n\t\t\t!isJsonValue(value.data)\n\t\t)\n\t\t\treturn { reason: \"record plugin fields are invalid\" };\n\t\treturn { entry: value as unknown as SessionPluginEntry };\n\t}\n\tif (typeof value.summary !== \"string\" || value.summary.trim().length === 0) {\n\t\treturn { reason: \"record summary must be a non-empty string\" };\n\t}\n\tif (!isRecordId(value.firstKeptEntryId)) return { reason: \"record firstKeptEntryId is invalid\" };\n\tif (!Number.isSafeInteger(value.tokensBefore) || !isNonNegativeNumber(value.tokensBefore)) {\n\t\treturn { reason: \"record tokensBefore must be a non-negative safe integer\" };\n\t}\n\treturn { entry: value as unknown as SessionSummaryEntry };\n}\n\nfunction withoutTrailingCarriageReturn(line: string): string {\n\treturn line.endsWith(\"\\r\") ? line.slice(0, -1) : line;\n}\n\nfunction errorText(cause: unknown): string {\n\treturn cause instanceof Error ? cause.message : String(cause);\n}\n\nexport async function loadSessionFile(filePath: string): Promise<LoadedSession> {\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(filePath, \"utf8\");\n\t} catch (cause) {\n\t\tthrow new SessionLoadError(\"READ_FAILED\", filePath, `Failed to read session file \"${filePath}\".`, { cause });\n\t}\n\n\tconst physicalLines = content.split(\"\\n\");\n\tlet partialLineNumber: number | undefined;\n\tif (content.endsWith(\"\\n\")) {\n\t\tphysicalLines.pop();\n\t} else {\n\t\tphysicalLines.pop();\n\t\tpartialLineNumber = physicalLines.length + 1;\n\t}\n\n\tif (physicalLines.length === 0) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session file has no committed header: \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\n\tlet headerValue: unknown;\n\ttry {\n\t\theaderValue = JSON.parse(withoutTrailingCarriageReturn(physicalLines[0] ?? \"\")) as unknown;\n\t} catch (cause) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session header is not valid JSON in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t\tcause,\n\t\t});\n\t}\n\n\tconst header = decodeHeader(headerValue, filePath);\n\tconst entries: SessionEntry[] = [];\n\tconst diagnostics: LoadedSession[\"diagnostics\"][number][] = [];\n\tconst seenIds = new Set<string>([header.id]);\n\tconst entriesById = new Map<string, SessionEntry>();\n\n\tfor (let index = 1; index < physicalLines.length; index++) {\n\t\tconst lineNumber = index + 1;\n\t\ttry {\n\t\t\tconst value = JSON.parse(withoutTrailingCarriageReturn(physicalLines[index] ?? \"\")) as unknown;\n\t\t\tconst decoded = decodeSessionEntry(value);\n\t\t\tif (!decoded.entry) throw new Error(decoded.reason ?? \"Invalid session message record.\");\n\t\t\tif (seenIds.has(decoded.entry.id)) throw new Error(\"record id is duplicated\");\n\t\t\tif (!seenIds.has(decoded.entry.parentId)) throw new Error(\"record parentId must reference an earlier record\");\n\t\t\tif (decoded.entry.type === \"summary\") {\n\t\t\t\tconst firstKept = entriesById.get(decoded.entry.firstKeptEntryId);\n\t\t\t\tif (\n\t\t\t\t\tfirstKept?.type !== \"message\" ||\n\t\t\t\t\t!isAncestor(decoded.entry.parentId, firstKept.id, entriesById, header.id)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"record firstKeptEntryId must reference an earlier message on the summary branch\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tentries.push(decoded.entry);\n\t\t\tseenIds.add(decoded.entry.id);\n\t\t\tentriesById.set(decoded.entry.id, decoded.entry);\n\t\t} catch (cause) {\n\t\t\tdiagnostics.push({ kind: \"corrupt_record\", lineNumber, reason: errorText(cause) });\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (diagnostics.length === 0 && partialLineNumber !== undefined) {\n\t\tdiagnostics.push({\n\t\t\tkind: \"trailing_partial_line\",\n\t\t\tlineNumber: partialLineNumber,\n\t\t\treason: \"final line has no newline commit marker\",\n\t\t});\n\t}\n\n\treturn {\n\t\theader,\n\t\tentries,\n\t\tmessages: entries\n\t\t\t.filter((entry): entry is SessionMessageEntry => entry.type === \"message\")\n\t\t\t.map((entry) => entry.message),\n\t\tdiagnostics,\n\t};\n}\n\nfunction isAncestor(\n\tleafId: string,\n\tancestorId: string,\n\tentriesById: ReadonlyMap<string, SessionEntry>,\n\theaderId: string,\n): boolean {\n\tlet currentId = leafId;\n\twhile (currentId !== headerId) {\n\t\tif (currentId === ancestorId) return true;\n\t\tconst current = entriesById.get(currentId);\n\t\tif (!current) return false;\n\t\tcurrentId = current.parentId;\n\t}\n\treturn false;\n}\n\nexport interface SessionAppendOptions {\n\treadonly lockTimeoutMs?: number;\n\treadonly lockRetryMs?: number;\n\treadonly now?: () => number;\n\treadonly sleep?: (milliseconds: number) => Promise<void>;\n}\n\nconst DEFAULT_LOCK_TIMEOUT_MS = 5_000;\nconst DEFAULT_LOCK_RETRY_MS = 25;\n\nfunction isNodeError(cause: unknown): cause is NodeJS.ErrnoException {\n\treturn cause instanceof Error && \"code\" in cause;\n}\n\nfunction delay(milliseconds: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\nexport async function createSessionFile(filePath: string, header: SessionHeader): Promise<void> {\n\tconst headerSnapshot = structuredClone(header);\n\ttry {\n\t\tdecodeHeader(headerSnapshot, filePath);\n\t\tawait mkdir(dirname(filePath), { recursive: true });\n\t\tconst handle = await open(filePath, \"wx\");\n\t\ttry {\n\t\t\tawait handle.writeFile(`${JSON.stringify(headerSnapshot)}\\n`, \"utf8\");\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t} catch (cause) {\n\t\tif (cause instanceof SessionWriteError) throw cause;\n\t\tthrow new SessionWriteError(\"CREATE_FAILED\", filePath, `Failed to create session file \"${filePath}\".`, {\n\t\t\tcause,\n\t\t});\n\t}\n}\n\nasync function acquireLock(filePath: string, options: SessionAppendOptions) {\n\tconst lockPath = `${filePath}.lock`;\n\tconst timeout = options.lockTimeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS;\n\tconst retry = options.lockRetryMs ?? DEFAULT_LOCK_RETRY_MS;\n\tconst now = options.now ?? Date.now;\n\tconst sleep = options.sleep ?? delay;\n\tconst startedAt = now();\n\n\twhile (true) {\n\t\ttry {\n\t\t\treturn { handle: await open(lockPath, \"wx\"), lockPath };\n\t\t} catch (cause) {\n\t\t\t// Windows can report EPERM/EACCES while another process closes or removes the lock file.\n\t\t\t// Treat that brief transition as contention so a writer does not fail merely because the lock vanished.\n\t\t\tconst lockBusy =\n\t\t\t\tisNodeError(cause) &&\n\t\t\t\t(cause.code === \"EEXIST\" ||\n\t\t\t\t\t(process.platform === \"win32\" && (cause.code === \"EPERM\" || cause.code === \"EACCES\")));\n\t\t\tif (!lockBusy) {\n\t\t\t\tthrow new SessionWriteError(\"APPEND_FAILED\", filePath, `Failed to acquire session lock for \"${filePath}\".`, {\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (now() - startedAt >= timeout) {\n\t\t\t\tthrow new SessionWriteError(\"LOCK_TIMEOUT\", filePath, `Timed out waiting for session lock \"${lockPath}\".`, {\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t}\n\t\t\tawait sleep(retry);\n\t\t}\n\t}\n}\n\nasync function releaseLock(handle: Awaited<ReturnType<typeof open>>, lockPath: string): Promise<void> {\n\tlet closeError: unknown;\n\ttry {\n\t\tawait handle.close();\n\t} catch (cause) {\n\t\tcloseError = cause;\n\t}\n\n\ttry {\n\t\tawait unlink(lockPath);\n\t} catch (cause) {\n\t\tif (!isNodeError(cause) || cause.code !== \"ENOENT\") throw cause;\n\t}\n\n\tif (closeError !== undefined) throw closeError;\n}\n\nexport async function appendSessionEntry(\n\tfilePath: string,\n\tentry: SessionEntry,\n\texpectedParentId: string,\n\toptions: SessionAppendOptions = {},\n): Promise<void> {\n\tconst entrySnapshot = structuredClone(entry);\n\tconst decodedEntry = decodeSessionEntry(entrySnapshot);\n\tif (!decodedEntry.entry) {\n\t\tthrow new SessionWriteError(\n\t\t\t\"APPEND_FAILED\",\n\t\t\tfilePath,\n\t\t\t`Refusing to append an invalid session entry to \"${filePath}\": ${decodedEntry.reason ?? \"invalid record\"}.`,\n\t\t);\n\t}\n\tconst { handle, lockPath } = await acquireLock(filePath, options);\n\tlet operationError: unknown;\n\ttry {\n\t\tconst loaded = await loadSessionFile(filePath);\n\t\tif (loaded.diagnostics.length > 0) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"CORRUPT_SESSION\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append to a session with recovery diagnostics: \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\n\t\tconst entriesById = new Map(loaded.entries.map((existing) => [existing.id, existing] as const));\n\t\tif (\n\t\t\tentrySnapshot.type === \"summary\" &&\n\t\t\t(entriesById.get(entrySnapshot.firstKeptEntryId)?.type !== \"message\" ||\n\t\t\t\t!isAncestor(expectedParentId, entrySnapshot.firstKeptEntryId, entriesById, loaded.header.id))\n\t\t) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append a summary with an invalid firstKeptEntryId to \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\t\tif (loaded.header.id === entrySnapshot.id || loaded.entries.some((existing) => existing.id === entrySnapshot.id)) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append a duplicate session record id to \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tentrySnapshot.parentId !== expectedParentId ||\n\t\t\t(expectedParentId !== loaded.header.id && !entriesById.has(expectedParentId))\n\t\t) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"CONCURRENT_MODIFICATION\",\n\t\t\t\tfilePath,\n\t\t\t\t`Session parent is no longer available in \"${filePath}\".`,\n\t\t\t\t{ expectedParentId },\n\t\t\t);\n\t\t}\n\n\t\tawait appendFile(filePath, `${JSON.stringify(entrySnapshot)}\\n`, \"utf8\");\n\t} catch (cause) {\n\t\toperationError = cause;\n\t} finally {\n\t\ttry {\n\t\t\tawait releaseLock(handle, lockPath);\n\t\t} catch (cause) {\n\t\t\toperationError ??= new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Failed to release session lock for \"${filePath}\".`,\n\t\t\t\t{ cause },\n\t\t\t);\n\t\t}\n\t}\n\n\tif (operationError !== undefined) {\n\t\tif (operationError instanceof SessionWriteError) {\n\t\t\tthrow operationError;\n\t\t}\n\t\tif (operationError instanceof SessionLoadError) {\n\t\t\tconst code = operationError.code === \"READ_FAILED\" ? \"APPEND_FAILED\" : \"CORRUPT_SESSION\";\n\t\t\tthrow new SessionWriteError(code, filePath, `Unable to load session before append: \"${filePath}\".`, {\n\t\t\t\tcause: operationError,\n\t\t\t});\n\t\t}\n\t\tthrow new SessionWriteError(\"APPEND_FAILED\", filePath, `Failed to append session entry to \"${filePath}\".`, {\n\t\t\tcause: operationError,\n\t\t});\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-storage.js","sourceRoot":"","sources":["../../../src/core/session/session-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFile, mkdir, open, readFile, unlink } from \"node:fs/promises\";\nimport { dirname, posix, win32 } from \"node:path\";\nimport type { AssistantContent, AssistantMessage, Message, ToolResultContent, Usage, UserContent } from \"@di-code/ai\";\nimport {\n\ttype LoadedSession,\n\tSESSION_FORMAT_VERSION,\n\ttype SessionEntry,\n\ttype SessionEventEntry,\n\ttype SessionHeader,\n\tSessionLoadError,\n\ttype SessionMessageEntry,\n\ttype SessionPluginEntry,\n\ttype SessionSummaryEntry,\n\tSessionWriteError,\n} from \"./types.ts\";\n\ntype JsonObject = Record<string, unknown>;\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\nexport const MAX_SESSION_EVENT_PAYLOAD_BYTES = 256 * 1024;\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n\treturn typeof value === \"string\" && value.length > 0;\n}\n\nfunction isNonNegativeNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nfunction isTimestamp(value: unknown): value is number {\n\treturn Number.isSafeInteger(value) && isNonNegativeNumber(value);\n}\n\nfunction isIsoTimestamp(value: unknown): value is string {\n\tif (typeof value !== \"string\") return false;\n\tconst milliseconds = Date.parse(value);\n\treturn Number.isFinite(milliseconds) && new Date(milliseconds).toISOString() === value;\n}\n\nfunction isRecordId(value: unknown): value is string {\n\treturn typeof value === \"string\" && /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(value);\n}\n\nfunction isAbsolutePath(value: unknown): value is string {\n\treturn typeof value === \"string\" && (win32.isAbsolute(value) || posix.isAbsolute(value));\n}\n\nfunction isJsonValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonValue);\n\treturn isObject(value) && Object.values(value).every(isJsonValue);\n}\n\nfunction isBoundedJsonValue(value: unknown): value is import(\"@di-code/ai\").JsonValue {\n\treturn isJsonValue(value) && Buffer.byteLength(JSON.stringify(value), \"utf8\") <= MAX_SESSION_EVENT_PAYLOAD_BYTES;\n}\n\nfunction isProviderReplay(value: unknown): boolean {\n\treturn isObject(value) && isNonEmptyString(value.api) && isJsonValue(value.data);\n}\n\nfunction isImageContent(value: unknown): value is Extract<UserContent | ToolResultContent, { type: \"image\" }> {\n\tif (!isObject(value) || value.type !== \"image\" || typeof value.data !== \"string\" || !isNonEmptyString(value.mimeType))\n\t\treturn false;\n\tconst padding = value.data.endsWith(\"==\") ? 2 : value.data.endsWith(\"=\") ? 1 : 0;\n\tconst decodedBytes = Math.floor((value.data.length * 3) / 4) - padding;\n\treturn (\n\t\tvalue.data.length % 4 === 0 &&\n\t\t/^[A-Za-z0-9+/]*={0,2}$/.test(value.data) &&\n\t\tdecodedBytes > 0 &&\n\t\tdecodedBytes <= MAX_IMAGE_BYTES &&\n\t\t/^image\\/[A-Za-z0-9.+-]+$/.test(value.mimeType)\n\t);\n}\n\nfunction isTextContent(value: unknown): value is Extract<UserContent, { type: \"text\" }> {\n\treturn isObject(value) && value.type === \"text\" && typeof value.text === \"string\";\n}\n\nfunction isUserContent(value: unknown): value is UserContent {\n\treturn isTextContent(value) || isImageContent(value);\n}\n\nfunction isAssistantContent(value: unknown): value is AssistantContent {\n\tif (!isObject(value)) return false;\n\tswitch (value.type) {\n\t\tcase \"text\":\n\t\t\treturn typeof value.text === \"string\";\n\t\tcase \"thinking\":\n\t\t\treturn typeof value.thinking === \"string\";\n\t\tcase \"image\":\n\t\t\treturn isImageContent(value);\n\t\tcase \"tool_call\":\n\t\t\treturn (\n\t\t\t\tisNonEmptyString(value.id) &&\n\t\t\t\tisNonEmptyString(value.name) &&\n\t\t\t\tisObject(value.arguments) &&\n\t\t\t\tisJsonValue(value.arguments)\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction isToolResultContent(value: unknown): value is ToolResultContent {\n\treturn isTextContent(value) || isImageContent(value);\n}\n\nfunction isUsage(value: unknown): value is Usage {\n\tif (!isObject(value) || !isObject(value.cost)) return false;\n\treturn (\n\t\tisNonNegativeNumber(value.input) &&\n\t\tisNonNegativeNumber(value.output) &&\n\t\tisNonNegativeNumber(value.cacheRead) &&\n\t\tisNonNegativeNumber(value.cacheWrite) &&\n\t\tisNonNegativeNumber(value.totalTokens) &&\n\t\tisNonNegativeNumber(value.cost.input) &&\n\t\tisNonNegativeNumber(value.cost.output) &&\n\t\tisNonNegativeNumber(value.cost.cacheRead) &&\n\t\tisNonNegativeNumber(value.cost.cacheWrite) &&\n\t\tisNonNegativeNumber(value.cost.total)\n\t);\n}\n\nfunction isAssistantMessage(value: JsonObject): value is JsonObject & AssistantMessage {\n\tif (\n\t\tvalue.role !== \"assistant\" ||\n\t\t!Array.isArray(value.content) ||\n\t\t!value.content.every(isAssistantContent) ||\n\t\t!isNonEmptyString(value.provider) ||\n\t\t!isNonEmptyString(value.model) ||\n\t\t(value.providerReplay !== undefined && !isProviderReplay(value.providerReplay)) ||\n\t\t!isUsage(value.usage) ||\n\t\t!isTimestamp(value.timestamp)\n\t) {\n\t\treturn false;\n\t}\n\n\tif (value.stopReason === \"stop\" || value.stopReason === \"length\" || value.stopReason === \"tool_use\") {\n\t\treturn value.errorMessage === undefined;\n\t}\n\tif (value.stopReason === \"error\" || value.stopReason === \"aborted\") {\n\t\treturn typeof value.errorMessage === \"string\";\n\t}\n\treturn false;\n}\n\nfunction isMessage(value: unknown): value is Message {\n\tif (!isObject(value) || !isTimestamp(value.timestamp)) return false;\n\n\tswitch (value.role) {\n\t\tcase \"user\":\n\t\t\treturn Array.isArray(value.content) && value.content.every(isUserContent);\n\t\tcase \"assistant\":\n\t\t\treturn isAssistantMessage(value);\n\t\tcase \"tool_result\":\n\t\t\treturn (\n\t\t\t\tisNonEmptyString(value.toolCallId) &&\n\t\t\t\tisNonEmptyString(value.toolName) &&\n\t\t\t\tArray.isArray(value.content) &&\n\t\t\t\tvalue.content.every(isToolResultContent) &&\n\t\t\t\t(value.details === undefined || isJsonValue(value.details)) &&\n\t\t\t\ttypeof value.isError === \"boolean\"\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction decodeHeader(value: unknown, filePath: string): SessionHeader {\n\tif (!isObject(value) || value.type !== \"session\") {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Invalid session header in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\tif (!(\"version\" in value)) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session header has no version in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\tif (value.version !== SESSION_FORMAT_VERSION) {\n\t\tthrow new SessionLoadError(\n\t\t\t\"UNSUPPORTED_VERSION\",\n\t\t\tfilePath,\n\t\t\t`Unsupported session version ${JSON.stringify(value.version)} in \"${filePath}\".`,\n\t\t\t{ lineNumber: 1 },\n\t\t);\n\t}\n\tif (\n\t\t!isRecordId(value.id) ||\n\t\tvalue.parentId !== null ||\n\t\t!isIsoTimestamp(value.timestamp) ||\n\t\t!isAbsolutePath(value.cwd)\n\t) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Invalid session header fields in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\treturn value as unknown as SessionHeader;\n}\n\nfunction decodeSessionEntry(value: unknown): { readonly entry?: SessionEntry; readonly reason?: string } {\n\tif (\n\t\t!isObject(value) ||\n\t\t(value.type !== \"message\" && value.type !== \"summary\" && value.type !== \"plugin\" && value.type !== \"event\")\n\t) {\n\t\treturn { reason: 'record type must be \"message\", \"summary\", or \"plugin\"' };\n\t}\n\tif (value.version !== SESSION_FORMAT_VERSION) return { reason: `record version must be ${SESSION_FORMAT_VERSION}` };\n\tif (!isRecordId(value.id)) return { reason: \"record id is invalid\" };\n\tif (!isRecordId(value.parentId)) return { reason: \"record parentId is invalid\" };\n\tif (!isIsoTimestamp(value.timestamp)) return { reason: \"record timestamp is not canonical ISO 8601 UTC\" };\n\tif (value.type === \"message\") {\n\t\tif (!isMessage(value.message)) return { reason: \"record message does not match the Message contract\" };\n\t\treturn { entry: value as unknown as SessionMessageEntry };\n\t}\n\tif (value.type === \"plugin\") {\n\t\tif (\n\t\t\ttypeof value.pluginId !== \"string\" ||\n\t\t\tvalue.pluginId.length === 0 ||\n\t\t\ttypeof value.pluginVersion !== \"string\" ||\n\t\t\tvalue.pluginVersion.length === 0 ||\n\t\t\ttypeof value.schemaVersion !== \"number\" ||\n\t\t\t!Number.isSafeInteger(value.schemaVersion) ||\n\t\t\tvalue.schemaVersion < 0 ||\n\t\t\t!isJsonValue(value.data)\n\t\t)\n\t\t\treturn { reason: \"record plugin fields are invalid\" };\n\t\treturn { entry: value as unknown as SessionPluginEntry };\n\t}\n\tif (value.type === \"event\") {\n\t\tif (\n\t\t\ttypeof value.namespace !== \"string\" ||\n\t\t\t!/^[a-z0-9][a-z0-9._-]*$/.test(value.namespace) ||\n\t\t\ttypeof value.eventName !== \"string\" ||\n\t\t\t!/^[a-z0-9][a-z0-9._-]*$/.test(value.eventName) ||\n\t\t\ttypeof value.schemaVersion !== \"number\" ||\n\t\t\t!Number.isSafeInteger(value.schemaVersion) ||\n\t\t\tvalue.schemaVersion < 0 ||\n\t\t\t!isBoundedJsonValue(value.payload)\n\t\t)\n\t\t\treturn { reason: \"record event fields are invalid or payload exceeds the limit\" };\n\t\treturn { entry: value as unknown as SessionEventEntry };\n\t}\n\tif (typeof value.summary !== \"string\" || value.summary.trim().length === 0) {\n\t\treturn { reason: \"record summary must be a non-empty string\" };\n\t}\n\tif (!isRecordId(value.firstKeptEntryId)) return { reason: \"record firstKeptEntryId is invalid\" };\n\tif (!Number.isSafeInteger(value.tokensBefore) || !isNonNegativeNumber(value.tokensBefore)) {\n\t\treturn { reason: \"record tokensBefore must be a non-negative safe integer\" };\n\t}\n\treturn { entry: value as unknown as SessionSummaryEntry };\n}\n\nfunction withoutTrailingCarriageReturn(line: string): string {\n\treturn line.endsWith(\"\\r\") ? line.slice(0, -1) : line;\n}\n\nfunction errorText(cause: unknown): string {\n\treturn cause instanceof Error ? cause.message : String(cause);\n}\n\nexport async function loadSessionFile(filePath: string): Promise<LoadedSession> {\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(filePath, \"utf8\");\n\t} catch (cause) {\n\t\tthrow new SessionLoadError(\"READ_FAILED\", filePath, `Failed to read session file \"${filePath}\".`, { cause });\n\t}\n\n\tconst physicalLines = content.split(\"\\n\");\n\tlet partialLineNumber: number | undefined;\n\tif (content.endsWith(\"\\n\")) {\n\t\tphysicalLines.pop();\n\t} else {\n\t\tphysicalLines.pop();\n\t\tpartialLineNumber = physicalLines.length + 1;\n\t}\n\n\tif (physicalLines.length === 0) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session file has no committed header: \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\n\tlet headerValue: unknown;\n\ttry {\n\t\theaderValue = JSON.parse(withoutTrailingCarriageReturn(physicalLines[0] ?? \"\")) as unknown;\n\t} catch (cause) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session header is not valid JSON in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t\tcause,\n\t\t});\n\t}\n\n\tconst header = decodeHeader(headerValue, filePath);\n\tconst entries: SessionEntry[] = [];\n\tconst diagnostics: LoadedSession[\"diagnostics\"][number][] = [];\n\tconst seenIds = new Set<string>([header.id]);\n\tconst entriesById = new Map<string, SessionEntry>();\n\n\tfor (let index = 1; index < physicalLines.length; index++) {\n\t\tconst lineNumber = index + 1;\n\t\ttry {\n\t\t\tconst value = JSON.parse(withoutTrailingCarriageReturn(physicalLines[index] ?? \"\")) as unknown;\n\t\t\tconst decoded = decodeSessionEntry(value);\n\t\t\tif (!decoded.entry) throw new Error(decoded.reason ?? \"Invalid session message record.\");\n\t\t\tif (seenIds.has(decoded.entry.id)) throw new Error(\"record id is duplicated\");\n\t\t\tif (!seenIds.has(decoded.entry.parentId)) throw new Error(\"record parentId must reference an earlier record\");\n\t\t\tif (decoded.entry.type === \"summary\") {\n\t\t\t\tconst firstKept = entriesById.get(decoded.entry.firstKeptEntryId);\n\t\t\t\tif (\n\t\t\t\t\tfirstKept?.type !== \"message\" ||\n\t\t\t\t\t!isAncestor(decoded.entry.parentId, firstKept.id, entriesById, header.id)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"record firstKeptEntryId must reference an earlier message on the summary branch\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tentries.push(decoded.entry);\n\t\t\tseenIds.add(decoded.entry.id);\n\t\t\tentriesById.set(decoded.entry.id, decoded.entry);\n\t\t} catch (cause) {\n\t\t\tdiagnostics.push({ kind: \"corrupt_record\", lineNumber, reason: errorText(cause) });\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (diagnostics.length === 0 && partialLineNumber !== undefined) {\n\t\tdiagnostics.push({\n\t\t\tkind: \"trailing_partial_line\",\n\t\t\tlineNumber: partialLineNumber,\n\t\t\treason: \"final line has no newline commit marker\",\n\t\t});\n\t}\n\n\treturn {\n\t\theader,\n\t\tentries,\n\t\tmessages: entries\n\t\t\t.filter((entry): entry is SessionMessageEntry => entry.type === \"message\")\n\t\t\t.map((entry) => entry.message),\n\t\tdiagnostics,\n\t};\n}\n\nfunction isAncestor(\n\tleafId: string,\n\tancestorId: string,\n\tentriesById: ReadonlyMap<string, SessionEntry>,\n\theaderId: string,\n): boolean {\n\tlet currentId = leafId;\n\twhile (currentId !== headerId) {\n\t\tif (currentId === ancestorId) return true;\n\t\tconst current = entriesById.get(currentId);\n\t\tif (!current) return false;\n\t\tcurrentId = current.parentId;\n\t}\n\treturn false;\n}\n\nexport interface SessionAppendOptions {\n\treadonly lockTimeoutMs?: number;\n\treadonly lockRetryMs?: number;\n\treadonly now?: () => number;\n\treadonly sleep?: (milliseconds: number) => Promise<void>;\n\treadonly signal?: AbortSignal;\n}\n\nconst DEFAULT_LOCK_TIMEOUT_MS = 5_000;\nconst DEFAULT_LOCK_RETRY_MS = 25;\n\nfunction isNodeError(cause: unknown): cause is NodeJS.ErrnoException {\n\treturn cause instanceof Error && \"code\" in cause;\n}\n\nfunction delay(milliseconds: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\nexport async function createSessionFile(filePath: string, header: SessionHeader): Promise<void> {\n\tconst headerSnapshot = structuredClone(header);\n\ttry {\n\t\tdecodeHeader(headerSnapshot, filePath);\n\t\tawait mkdir(dirname(filePath), { recursive: true });\n\t\tconst handle = await open(filePath, \"wx\");\n\t\ttry {\n\t\t\tawait handle.writeFile(`${JSON.stringify(headerSnapshot)}\\n`, \"utf8\");\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t} catch (cause) {\n\t\tif (cause instanceof SessionWriteError) throw cause;\n\t\tthrow new SessionWriteError(\"CREATE_FAILED\", filePath, `Failed to create session file \"${filePath}\".`, {\n\t\t\tcause,\n\t\t});\n\t}\n}\n\nasync function acquireLock(filePath: string, options: SessionAppendOptions) {\n\tconst lockPath = `${filePath}.lock`;\n\tconst timeout = options.lockTimeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS;\n\tconst retry = options.lockRetryMs ?? DEFAULT_LOCK_RETRY_MS;\n\tconst now = options.now ?? Date.now;\n\tconst sleep = options.sleep ?? delay;\n\tconst startedAt = now();\n\n\twhile (true) {\n\t\tif (options.signal?.aborted)\n\t\t\tthrow options.signal.reason ?? new DOMException(\"The operation was aborted\", \"AbortError\");\n\t\ttry {\n\t\t\treturn { handle: await open(lockPath, \"wx\"), lockPath };\n\t\t} catch (cause) {\n\t\t\t// Windows can report EPERM/EACCES while another process closes or removes the lock file.\n\t\t\t// Treat that brief transition as contention so a writer does not fail merely because the lock vanished.\n\t\t\tconst lockBusy =\n\t\t\t\tisNodeError(cause) &&\n\t\t\t\t(cause.code === \"EEXIST\" ||\n\t\t\t\t\t(process.platform === \"win32\" && (cause.code === \"EPERM\" || cause.code === \"EACCES\")));\n\t\t\tif (!lockBusy) {\n\t\t\t\tthrow new SessionWriteError(\"APPEND_FAILED\", filePath, `Failed to acquire session lock for \"${filePath}\".`, {\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (now() - startedAt >= timeout) {\n\t\t\t\tthrow new SessionWriteError(\"LOCK_TIMEOUT\", filePath, `Timed out waiting for session lock \"${lockPath}\".`, {\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t}\n\t\t\tawait sleep(retry);\n\t\t}\n\t}\n}\n\nasync function releaseLock(handle: Awaited<ReturnType<typeof open>>, lockPath: string): Promise<void> {\n\tlet closeError: unknown;\n\ttry {\n\t\tawait handle.close();\n\t} catch (cause) {\n\t\tcloseError = cause;\n\t}\n\n\ttry {\n\t\tawait unlink(lockPath);\n\t} catch (cause) {\n\t\tif (!isNodeError(cause) || cause.code !== \"ENOENT\") throw cause;\n\t}\n\n\tif (closeError !== undefined) throw closeError;\n}\n\nexport async function appendSessionEntry(\n\tfilePath: string,\n\tentry: SessionEntry,\n\texpectedParentId: string,\n\toptions: SessionAppendOptions = {},\n): Promise<void> {\n\tif (options.signal?.aborted)\n\t\tthrow options.signal.reason ?? new DOMException(\"The operation was aborted\", \"AbortError\");\n\tconst entrySnapshot = structuredClone(entry);\n\tconst decodedEntry = decodeSessionEntry(entrySnapshot);\n\tif (!decodedEntry.entry) {\n\t\tthrow new SessionWriteError(\n\t\t\t\"APPEND_FAILED\",\n\t\t\tfilePath,\n\t\t\t`Refusing to append an invalid session entry to \"${filePath}\": ${decodedEntry.reason ?? \"invalid record\"}.`,\n\t\t);\n\t}\n\tconst { handle, lockPath } = await acquireLock(filePath, options);\n\tlet operationError: unknown;\n\ttry {\n\t\tconst loaded = await loadSessionFile(filePath);\n\t\tif (loaded.diagnostics.length > 0) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"CORRUPT_SESSION\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append to a session with recovery diagnostics: \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\n\t\tconst entriesById = new Map(loaded.entries.map((existing) => [existing.id, existing] as const));\n\t\tif (\n\t\t\tentrySnapshot.type === \"summary\" &&\n\t\t\t(entriesById.get(entrySnapshot.firstKeptEntryId)?.type !== \"message\" ||\n\t\t\t\t!isAncestor(expectedParentId, entrySnapshot.firstKeptEntryId, entriesById, loaded.header.id))\n\t\t) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append a summary with an invalid firstKeptEntryId to \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\t\tif (loaded.header.id === entrySnapshot.id || loaded.entries.some((existing) => existing.id === entrySnapshot.id)) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append a duplicate session record id to \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tentrySnapshot.parentId !== expectedParentId ||\n\t\t\t(expectedParentId !== loaded.header.id && !entriesById.has(expectedParentId))\n\t\t) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"CONCURRENT_MODIFICATION\",\n\t\t\t\tfilePath,\n\t\t\t\t`Session parent is no longer available in \"${filePath}\".`,\n\t\t\t\t{ expectedParentId },\n\t\t\t);\n\t\t}\n\n\t\tawait appendFile(filePath, `${JSON.stringify(entrySnapshot)}\\n`, \"utf8\");\n\t} catch (cause) {\n\t\toperationError = cause;\n\t} finally {\n\t\ttry {\n\t\t\tawait releaseLock(handle, lockPath);\n\t\t} catch (cause) {\n\t\t\toperationError ??= new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Failed to release session lock for \"${filePath}\".`,\n\t\t\t\t{ cause },\n\t\t\t);\n\t\t}\n\t}\n\n\tif (operationError !== undefined) {\n\t\tif (operationError instanceof SessionWriteError) {\n\t\t\tthrow operationError;\n\t\t}\n\t\tif (operationError instanceof SessionLoadError) {\n\t\t\tconst code = operationError.code === \"READ_FAILED\" ? \"APPEND_FAILED\" : \"CORRUPT_SESSION\";\n\t\t\tthrow new SessionWriteError(code, filePath, `Unable to load session before append: \"${filePath}\".`, {\n\t\t\t\tcause: operationError,\n\t\t\t});\n\t\t}\n\t\tthrow new SessionWriteError(\"APPEND_FAILED\", filePath, `Failed to append session entry to \"${filePath}\".`, {\n\t\t\tcause: operationError,\n\t\t});\n\t}\n}\n"]}
|
|
@@ -32,7 +32,16 @@ export interface SessionPluginEntry extends SessionRecordBase {
|
|
|
32
32
|
readonly schemaVersion: number;
|
|
33
33
|
readonly data: JsonValue;
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
/** Versioned extension event retained even when its plugin is unavailable. */
|
|
36
|
+
export interface SessionEventEntry extends SessionRecordBase {
|
|
37
|
+
readonly type: "event";
|
|
38
|
+
readonly parentId: string;
|
|
39
|
+
readonly namespace: string;
|
|
40
|
+
readonly eventName: string;
|
|
41
|
+
readonly schemaVersion: number;
|
|
42
|
+
readonly payload: JsonValue;
|
|
43
|
+
}
|
|
44
|
+
export type SessionEntry = SessionMessageEntry | SessionSummaryEntry | SessionPluginEntry | SessionEventEntry;
|
|
36
45
|
/** An immutable entry snapshot with its append-ordered descendants. */
|
|
37
46
|
export interface SessionTreeNode {
|
|
38
47
|
readonly entry: SessionEntry;
|
|
@@ -47,6 +56,12 @@ export type SessionDiagnostic = {
|
|
|
47
56
|
readonly kind: "corrupt_record";
|
|
48
57
|
readonly lineNumber: number;
|
|
49
58
|
readonly reason: string;
|
|
59
|
+
} | {
|
|
60
|
+
readonly kind: "event_validation";
|
|
61
|
+
readonly namespace: string;
|
|
62
|
+
readonly eventName: string;
|
|
63
|
+
readonly schemaVersion: number;
|
|
64
|
+
readonly reason: string;
|
|
50
65
|
};
|
|
51
66
|
export interface LoadedSession {
|
|
52
67
|
readonly header: SessionHeader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/session/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtD,eAAO,MAAM,sBAAsB,EAAG,CAAU,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,OAAO,sBAAsB,CAAC;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACvD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC7D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC7D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC9B;AAED,2FAA2F;AAC3F,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC5D,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CACzB;AAED,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/session/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtD,eAAO,MAAM,sBAAsB,EAAG,CAAU,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,OAAO,sBAAsB,CAAC;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACvD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC7D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC7D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC9B;AAED,2FAA2F;AAC3F,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC5D,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CACzB;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC3D,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;CAC5B;AAED,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAE9G,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;CAC9C;AAED,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,YAAY,CAAC;AAEzD,MAAM,MAAM,iBAAiB,GAC1B;IACA,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACvB,GACD;IACA,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACvB,GACD;IACA,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACvB,CAAC;AAEL,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACnD;AAED,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,qBAAqB,GAAG,aAAa,CAAC;AAE5F,qBAAa,gBAAiB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAG5B,IAAI,EAAE,oBAAoB,EAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAQrE;AAED,MAAM,MAAM,qBAAqB,GAC9B,eAAe,GACf,eAAe,GACf,cAAc,GACd,yBAAyB,GACzB,iBAAiB,CAAC;AAErB,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;gBAGhC,IAAI,EAAE,qBAAqB,EAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACT,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QACzB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;KACjC;CASF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/session/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/session/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAU,CAAC;AAuFjD,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACjC,IAAI,CAAuB;IAC3B,QAAQ,CAAS;IACjB,UAAU,CAAU;IAE7B,YACC,IAA0B,EAC1B,QAAgB,EAChB,OAAe,EACf,OAAoE;QAEpE,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,UAAU,CAAC;IACvC,CAAC;CACD;AASD,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAClC,IAAI,CAAwB;IAC5B,QAAQ,CAAS;IACjB,gBAAgB,CAAU;IAC1B,cAAc,CAAU;IAEjC,YACC,IAA2B,EAC3B,QAAgB,EAChB,OAAe,EACf,OAIC;QAED,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,gBAAgB,GAAG,OAAO,EAAE,gBAAgB,CAAC;QAClD,IAAI,CAAC,cAAc,GAAG,OAAO,EAAE,cAAc,CAAC;IAC/C,CAAC;CACD","sourcesContent":["import type { JsonValue, Message } from \"@di-code/ai\";\n\nexport const SESSION_FORMAT_VERSION = 2 as const;\n\nexport interface SessionRecordBase {\n\treadonly version: typeof SESSION_FORMAT_VERSION;\n\treadonly id: string;\n\treadonly parentId: string | null;\n\treadonly timestamp: string;\n}\n\nexport interface SessionHeader extends SessionRecordBase {\n\treadonly type: \"session\";\n\treadonly parentId: null;\n\treadonly cwd: string;\n}\n\nexport interface SessionMessageEntry extends SessionRecordBase {\n\treadonly type: \"message\";\n\treadonly parentId: string;\n\treadonly message: Message;\n}\n\nexport interface SessionSummaryEntry extends SessionRecordBase {\n\treadonly type: \"summary\";\n\treadonly parentId: string;\n\treadonly summary: string;\n\treadonly firstKeptEntryId: string;\n\treadonly tokensBefore: number;\n}\n\n/** Plugin-private records are retained verbatim so newer plugins survive older readers. */\nexport interface SessionPluginEntry extends SessionRecordBase {\n\treadonly type: \"plugin\";\n\treadonly parentId: string;\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly schemaVersion: number;\n\treadonly data: JsonValue;\n}\n\n/** Versioned extension event retained even when its plugin is unavailable. */\nexport interface SessionEventEntry extends SessionRecordBase {\n\treadonly type: \"event\";\n\treadonly parentId: string;\n\treadonly namespace: string;\n\treadonly eventName: string;\n\treadonly schemaVersion: number;\n\treadonly payload: JsonValue;\n}\n\nexport type SessionEntry = SessionMessageEntry | SessionSummaryEntry | SessionPluginEntry | SessionEventEntry;\n\n/** An immutable entry snapshot with its append-ordered descendants. */\nexport interface SessionTreeNode {\n\treadonly entry: SessionEntry;\n\treadonly children: readonly SessionTreeNode[];\n}\n\nexport type SessionRecord = SessionHeader | SessionEntry;\n\nexport type SessionDiagnostic =\n\t| {\n\t\t\treadonly kind: \"trailing_partial_line\";\n\t\t\treadonly lineNumber: number;\n\t\t\treadonly reason: string;\n\t }\n\t| {\n\t\t\treadonly kind: \"corrupt_record\";\n\t\t\treadonly lineNumber: number;\n\t\t\treadonly reason: string;\n\t }\n\t| {\n\t\t\treadonly kind: \"event_validation\";\n\t\t\treadonly namespace: string;\n\t\t\treadonly eventName: string;\n\t\t\treadonly schemaVersion: number;\n\t\t\treadonly reason: string;\n\t };\n\nexport interface LoadedSession {\n\treadonly header: SessionHeader;\n\treadonly entries: readonly SessionEntry[];\n\treadonly messages: readonly Message[];\n\treadonly diagnostics: readonly SessionDiagnostic[];\n}\n\nexport type SessionLoadErrorCode = \"INVALID_HEADER\" | \"UNSUPPORTED_VERSION\" | \"READ_FAILED\";\n\nexport class SessionLoadError extends Error {\n\treadonly code: SessionLoadErrorCode;\n\treadonly filePath: string;\n\treadonly lineNumber?: number;\n\n\tconstructor(\n\t\tcode: SessionLoadErrorCode,\n\t\tfilePath: string,\n\t\tmessage: string,\n\t\toptions?: { readonly lineNumber?: number; readonly cause?: unknown },\n\t) {\n\t\tsuper(message, { cause: options?.cause });\n\t\tthis.name = \"SessionLoadError\";\n\t\tthis.code = code;\n\t\tthis.filePath = filePath;\n\t\tthis.lineNumber = options?.lineNumber;\n\t}\n}\n\nexport type SessionWriteErrorCode =\n\t| \"CREATE_FAILED\"\n\t| \"APPEND_FAILED\"\n\t| \"LOCK_TIMEOUT\"\n\t| \"CONCURRENT_MODIFICATION\"\n\t| \"CORRUPT_SESSION\";\n\nexport class SessionWriteError extends Error {\n\treadonly code: SessionWriteErrorCode;\n\treadonly filePath: string;\n\treadonly expectedParentId?: string;\n\treadonly actualParentId?: string;\n\n\tconstructor(\n\t\tcode: SessionWriteErrorCode,\n\t\tfilePath: string,\n\t\tmessage: string,\n\t\toptions?: {\n\t\t\treadonly cause?: unknown;\n\t\t\treadonly expectedParentId?: string;\n\t\t\treadonly actualParentId?: string;\n\t\t},\n\t) {\n\t\tsuper(message, { cause: options?.cause });\n\t\tthis.name = \"SessionWriteError\";\n\t\tthis.code = code;\n\t\tthis.filePath = filePath;\n\t\tthis.expectedParentId = options?.expectedParentId;\n\t\tthis.actualParentId = options?.actualParentId;\n\t}\n}\n"]}
|
package/dist/core/session.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type { AgentTool, AgentToolResult } from "@di-code/agent";
|
|
2
|
-
import { type AgentListener } from "@di-code/agent";
|
|
1
|
+
import type { AgentHookRegistration, AgentTool, AgentToolResult } from "@di-code/agent";
|
|
2
|
+
import { type AgentListener, type PromptSectionRegistry } from "@di-code/agent";
|
|
3
3
|
import type { AssistantMessage, ImageContent, Message, Model, Provider, ThinkingLevel, TSchema, Usage } from "@di-code/ai";
|
|
4
|
+
import type { ToolPolicyCapability, ToolPolicyMode, ToolPolicySnapshot } from "@di-code/builtins";
|
|
5
|
+
import type { PlanModeController, PlanModeProjection } from "@di-code/plan-mode";
|
|
6
|
+
import type { SessionExtensionFacade, SessionProjectionRegistry } from "@di-code/plugin-sdk";
|
|
4
7
|
import type { SkillResource } from "./resources/types.ts";
|
|
5
8
|
import type { SessionManager } from "./session/session-manager.ts";
|
|
6
9
|
import type { SessionDiagnostic, SessionTreeNode } from "./session/types.ts";
|
|
@@ -33,10 +36,18 @@ export interface AgentSessionOptions {
|
|
|
33
36
|
/** Valid initial override for the selected model's thinking level. */
|
|
34
37
|
readonly thinkingLevel?: ThinkingLevel;
|
|
35
38
|
readonly systemPrompt?: string;
|
|
39
|
+
readonly promptSections?: PromptSectionRegistry;
|
|
40
|
+
/** Returns an immutable, session-owned snapshot for dynamic prompt generators. */
|
|
41
|
+
readonly getPromptSnapshot?: () => unknown;
|
|
36
42
|
readonly skills?: readonly SkillResource[];
|
|
37
43
|
readonly now?: () => number;
|
|
38
44
|
readonly sessionManager?: SessionManager;
|
|
39
45
|
readonly compaction?: AgentSessionCompactionOptions;
|
|
46
|
+
readonly toolPolicy?: ToolPolicyCapability;
|
|
47
|
+
readonly hooks?: readonly AgentHookRegistration[];
|
|
48
|
+
readonly planMode?: PlanModeController;
|
|
49
|
+
readonly projectionRegistry?: SessionProjectionRegistry;
|
|
50
|
+
readonly extensionFacade?: SessionExtensionFacade;
|
|
40
51
|
/** Called once when the owning product host releases this session scope. */
|
|
41
52
|
readonly onDispose?: () => void | Promise<void>;
|
|
42
53
|
}
|
|
@@ -90,6 +101,10 @@ export declare class AgentSession {
|
|
|
90
101
|
private readonly sessionListeners;
|
|
91
102
|
private readonly agentUnsubscribers;
|
|
92
103
|
private readonly onDispose?;
|
|
104
|
+
private readonly toolPolicy?;
|
|
105
|
+
private readonly planModeController?;
|
|
106
|
+
private readonly projectionRegistry?;
|
|
107
|
+
private readonly extensionFacade?;
|
|
93
108
|
private disposed;
|
|
94
109
|
constructor(options: AgentSessionOptions);
|
|
95
110
|
/** Releases listeners and the isolated product scope. Repeated calls are harmless. */
|
|
@@ -114,6 +129,14 @@ export declare class AgentSession {
|
|
|
114
129
|
get sessionDiagnostics(): readonly SessionDiagnostic[];
|
|
115
130
|
get sessionTree(): readonly SessionTreeNode[];
|
|
116
131
|
get sessionLeafId(): string | undefined;
|
|
132
|
+
get toolPolicySnapshot(): ToolPolicySnapshot | undefined;
|
|
133
|
+
get planModeProjection(): PlanModeProjection | undefined;
|
|
134
|
+
planModeCommand(args: string): Promise<string>;
|
|
135
|
+
planCommand(args: string): Promise<string>;
|
|
136
|
+
planMode(): PlanModeProjection | undefined;
|
|
137
|
+
projections(): readonly import("@di-code/plugin-sdk").SessionProjectionSnapshot[];
|
|
138
|
+
extensions(): SessionExtensionFacade | undefined;
|
|
139
|
+
setToolPolicyMode(mode: ToolPolicyMode, signal?: AbortSignal): Promise<ToolPolicySnapshot>;
|
|
117
140
|
get usage(): SessionUsage;
|
|
118
141
|
prompt(text: string, signal?: AbortSignal): Promise<AssistantMessage>;
|
|
119
142
|
/** Queues an instruction for the next provider request while this Session is running. */
|
|
@@ -126,6 +149,8 @@ export declare class AgentSession {
|
|
|
126
149
|
/** Changes the active persisted branch and replaces the next-request model context. */
|
|
127
150
|
navigateTree(entryId: string): Promise<TreeNavigationResult>;
|
|
128
151
|
subscribe(listener: AgentListener): () => void;
|
|
152
|
+
/** Adds a lifecycle hook to the live Agent and returns an idempotent disposer. */
|
|
153
|
+
addHook(hook: AgentHookRegistration): () => void;
|
|
129
154
|
subscribeSession(listener: AgentSessionListener): () => void;
|
|
130
155
|
private emitSession;
|
|
131
156
|
private emitQueueUpdate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"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"}
|
package/dist/core/session.js
CHANGED
|
@@ -36,10 +36,18 @@ export class AgentSession {
|
|
|
36
36
|
sessionListeners = new Set();
|
|
37
37
|
agentUnsubscribers = [];
|
|
38
38
|
onDispose;
|
|
39
|
+
toolPolicy;
|
|
40
|
+
planModeController;
|
|
41
|
+
projectionRegistry;
|
|
42
|
+
extensionFacade;
|
|
39
43
|
disposed = false;
|
|
40
44
|
constructor(options) {
|
|
41
45
|
this.allowedRootValue = options.allowedRoot;
|
|
42
46
|
this.onDispose = options.onDispose;
|
|
47
|
+
this.toolPolicy = options.toolPolicy;
|
|
48
|
+
this.planModeController = options.planMode;
|
|
49
|
+
this.projectionRegistry = options.projectionRegistry;
|
|
50
|
+
this.extensionFacade = options.extensionFacade;
|
|
43
51
|
this.sessionManager = options.sessionManager;
|
|
44
52
|
this.provider = options.provider;
|
|
45
53
|
this.skills = structuredClone([...(options.skills ?? [])].map((skill) => ({
|
|
@@ -97,6 +105,9 @@ export class AgentSession {
|
|
|
97
105
|
now: this.now,
|
|
98
106
|
initialMessages: options.sessionManager?.messages,
|
|
99
107
|
initialContextMessages: initialContext?.messages,
|
|
108
|
+
promptSections: options.promptSections,
|
|
109
|
+
getPromptSnapshot: options.getPromptSnapshot,
|
|
110
|
+
hooks: options.hooks,
|
|
100
111
|
});
|
|
101
112
|
this.agentUnsubscribers.push(this.agent.subscribe(async (event) => {
|
|
102
113
|
if (event.type !== "message_end" || this.sessionManager === undefined || this.persistenceError !== undefined) {
|
|
@@ -132,6 +143,8 @@ export class AgentSession {
|
|
|
132
143
|
if (this.disposed)
|
|
133
144
|
return;
|
|
134
145
|
this.disposed = true;
|
|
146
|
+
this.toolPolicy?.dispose?.();
|
|
147
|
+
await this.planModeController?.dispose();
|
|
135
148
|
for (const unsubscribe of this.agentUnsubscribers.splice(0))
|
|
136
149
|
unsubscribe();
|
|
137
150
|
this.sessionListeners.clear();
|
|
@@ -253,6 +266,48 @@ export class AgentSession {
|
|
|
253
266
|
get sessionLeafId() {
|
|
254
267
|
return this.sessionManager?.leafId;
|
|
255
268
|
}
|
|
269
|
+
get toolPolicySnapshot() {
|
|
270
|
+
return this.toolPolicy?.snapshot?.();
|
|
271
|
+
}
|
|
272
|
+
get planModeProjection() {
|
|
273
|
+
return this.planModeController?.get();
|
|
274
|
+
}
|
|
275
|
+
planModeCommand(args) {
|
|
276
|
+
if (!this.planModeController)
|
|
277
|
+
return Promise.reject(new Error("Plan mode is unavailable."));
|
|
278
|
+
return this.planModeController.command(args, async (message) => {
|
|
279
|
+
if (this.promptActive) {
|
|
280
|
+
await this.steer(message);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
await this.prompt(message);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
planCommand(args) {
|
|
287
|
+
return this.planModeCommand(args);
|
|
288
|
+
}
|
|
289
|
+
planMode() {
|
|
290
|
+
return this.planModeProjection;
|
|
291
|
+
}
|
|
292
|
+
projections() {
|
|
293
|
+
if (!this.projectionRegistry || !this.sessionManager)
|
|
294
|
+
return [];
|
|
295
|
+
return this.projectionRegistry.replay(this.sessionManager.events.map((event) => ({
|
|
296
|
+
namespace: event.namespace,
|
|
297
|
+
eventName: event.eventName,
|
|
298
|
+
schemaVersion: event.schemaVersion,
|
|
299
|
+
payload: event.payload,
|
|
300
|
+
})));
|
|
301
|
+
}
|
|
302
|
+
extensions() {
|
|
303
|
+
return this.extensionFacade;
|
|
304
|
+
}
|
|
305
|
+
async setToolPolicyMode(mode, signal) {
|
|
306
|
+
this.assertNotDisposed();
|
|
307
|
+
if (!this.toolPolicy?.setMode)
|
|
308
|
+
throw new Error("Session tool policy is not dynamic.");
|
|
309
|
+
return await this.toolPolicy.setMode(mode, signal);
|
|
310
|
+
}
|
|
256
311
|
get usage() {
|
|
257
312
|
return {
|
|
258
313
|
...this.usageTotals,
|
|
@@ -366,6 +421,10 @@ export class AgentSession {
|
|
|
366
421
|
subscribe(listener) {
|
|
367
422
|
return this.agent.subscribe(listener);
|
|
368
423
|
}
|
|
424
|
+
/** Adds a lifecycle hook to the live Agent and returns an idempotent disposer. */
|
|
425
|
+
addHook(hook) {
|
|
426
|
+
return this.agent.addHook(hook);
|
|
427
|
+
}
|
|
369
428
|
subscribeSession(listener) {
|
|
370
429
|
this.sessionListeners.add(listener);
|
|
371
430
|
return () => this.sessionListeners.delete(listener);
|