@code-yeongyu/senpi-agent-core 2026.8.1 → 2026.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/harness/agent-harness.d.ts +14 -3
- package/dist/harness/agent-harness.d.ts.map +1 -1
- package/dist/harness/agent-harness.js +156 -67
- package/dist/harness/agent-harness.js.map +1 -1
- package/dist/harness/session/array-session-reader.d.ts +3 -0
- package/dist/harness/session/array-session-reader.d.ts.map +1 -0
- package/dist/harness/session/array-session-reader.js +70 -0
- package/dist/harness/session/array-session-reader.js.map +1 -0
- package/dist/harness/session/fork.d.ts +4 -0
- package/dist/harness/session/fork.d.ts.map +1 -0
- package/dist/harness/session/fork.js +22 -0
- package/dist/harness/session/fork.js.map +1 -0
- package/dist/harness/session/jsonl-store.d.ts +13 -0
- package/dist/harness/session/jsonl-store.d.ts.map +1 -0
- package/dist/harness/session/jsonl-store.js +304 -0
- package/dist/harness/session/jsonl-store.js.map +1 -0
- package/dist/harness/session/keyed-operation-queue.d.ts +17 -0
- package/dist/harness/session/keyed-operation-queue.d.ts.map +1 -0
- package/dist/harness/session/keyed-operation-queue.js +60 -0
- package/dist/harness/session/keyed-operation-queue.js.map +1 -0
- package/dist/harness/session/memory-store.d.ts +6 -0
- package/dist/harness/session/memory-store.d.ts.map +1 -0
- package/dist/harness/session/memory-store.js +107 -0
- package/dist/harness/session/memory-store.js.map +1 -0
- package/dist/harness/session/repository.d.ts +28 -0
- package/dist/harness/session/repository.d.ts.map +1 -0
- package/dist/harness/session/repository.js +61 -0
- package/dist/harness/session/repository.js.map +1 -0
- package/dist/harness/session/search-backend.d.ts +8 -0
- package/dist/harness/session/search-backend.d.ts.map +1 -0
- package/dist/harness/session/search-backend.js +22 -0
- package/dist/harness/session/search-backend.js.map +1 -0
- package/dist/harness/session/session.d.ts +6 -10
- package/dist/harness/session/session.d.ts.map +1 -1
- package/dist/harness/session/session.js +154 -77
- package/dist/harness/session/session.js.map +1 -1
- package/dist/harness/types.d.ts +49 -23
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/proxy.js +1 -1
- package/dist/proxy.js.map +1 -1
- package/package.json +4 -4
- package/dist/harness/session/jsonl-repo.d.ts +0 -26
- package/dist/harness/session/jsonl-repo.d.ts.map +0 -1
- package/dist/harness/session/jsonl-repo.js +0 -100
- package/dist/harness/session/jsonl-repo.js.map +0 -1
- package/dist/harness/session/jsonl-storage.d.ts +0 -42
- package/dist/harness/session/jsonl-storage.d.ts.map +0 -1
- package/dist/harness/session/jsonl-storage.js +0 -286
- package/dist/harness/session/jsonl-storage.js.map +0 -1
- package/dist/harness/session/memory-repo.d.ts +0 -18
- package/dist/harness/session/memory-repo.d.ts.map +0 -1
- package/dist/harness/session/memory-repo.js +0 -44
- package/dist/harness/session/memory-repo.js.map +0 -1
- package/dist/harness/session/memory-storage.d.ts +0 -33
- package/dist/harness/session/memory-storage.d.ts.map +0 -1
- package/dist/harness/session/memory-storage.js +0 -163
- package/dist/harness/session/memory-storage.js.map +0 -1
- package/dist/harness/session/repo-utils.d.ts +0 -11
- package/dist/harness/session/repo-utils.d.ts.map +0 -1
- package/dist/harness/session/repo-utils.js +0 -39
- package/dist/harness/session/repo-utils.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../src/harness/session/repository.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,oBAAoB,EAEzB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,MAAM,aAAa,CAAC;AAErB,OAAO,EAA2B,KAAK,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAEtG,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,qBAAa,iBAAiB,CAC7B,SAAS,SAAS,eAAe,GAAG,eAAe,EACnD,cAAc,SAAS,oBAAoB,GAAG,oBAAoB,EAClE,YAAY,GAAG,IAAI;IAEnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwD;IAC9E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6B;IAEjE,YAAY,OAAO,EAAE;QACpB,KAAK,EAAE,YAAY,CAAC,SAAS,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;QAC7D,MAAM,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QACzC,mBAAmB,CAAC,EAAE,0BAA0B,CAAC;KACjD,EAIA;IAEK,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAEjE;IAEK,IAAI,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAE3D;IAEK,IAAI,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAEvD;IAEK,MAAM,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;IAEK,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,GAAG,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAUvG;IAEK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAAC,CAE/G;CACD;AAED,wBAAgB,uBAAuB,CACtC,SAAS,SAAS,eAAe,GAAG,eAAe,EACnD,cAAc,SAAS,oBAAoB,GAAG,oBAAoB,EAClE,YAAY,GAAG,IAAI,EAClB,OAAO,EAAE;IACV,KAAK,EAAE,YAAY,CAAC,SAAS,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IAC7D,MAAM,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IACzC,mBAAmB,CAAC,EAAE,0BAA0B,CAAC;CACjD,GAAG,iBAAiB,CAAC,SAAS,EAAE,cAAc,EAAE,YAAY,CAAC,CAE7D;AAED,wBAAgB,uBAAuB,CAAC,SAAS,SAAS,eAAe,EACxE,QAAQ,EAAE,SAAS,EACnB,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,IAAI,EAAE,MAAM,GACV,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAQ/B;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAM7G"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { uuidv7 } from "@earendil-works/pi-ai";
|
|
2
|
+
import { SessionError, } from "../types.js";
|
|
3
|
+
import { createSessionForkSelection } from "./fork.js";
|
|
4
|
+
import { createSessionFromReader } from "./session.js";
|
|
5
|
+
export function createSessionId() {
|
|
6
|
+
return uuidv7();
|
|
7
|
+
}
|
|
8
|
+
export function createTimestamp() {
|
|
9
|
+
return new Date().toISOString();
|
|
10
|
+
}
|
|
11
|
+
export class SessionRepository {
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this.store = options.store;
|
|
14
|
+
this.searchStore = options.search ?? null;
|
|
15
|
+
this.contextBuildOptions = options.contextBuildOptions ?? {};
|
|
16
|
+
}
|
|
17
|
+
async create(options) {
|
|
18
|
+
return createSessionFromReader(this.store, await this.store.create(options), this.contextBuildOptions);
|
|
19
|
+
}
|
|
20
|
+
async open(metadata) {
|
|
21
|
+
return createSessionFromReader(this.store, await this.store.load(metadata), this.contextBuildOptions);
|
|
22
|
+
}
|
|
23
|
+
async list(options) {
|
|
24
|
+
return await this.store.list(options);
|
|
25
|
+
}
|
|
26
|
+
async delete(metadata) {
|
|
27
|
+
await this.store.delete(metadata);
|
|
28
|
+
}
|
|
29
|
+
async fork(source, options) {
|
|
30
|
+
const selection = createSessionForkSelection(options);
|
|
31
|
+
const createOptions = { ...options };
|
|
32
|
+
delete createOptions.entryId;
|
|
33
|
+
delete createOptions.position;
|
|
34
|
+
return createSessionFromReader(this.store, await this.store.fork(source, createOptions, selection), this.contextBuildOptions);
|
|
35
|
+
}
|
|
36
|
+
async search(options) {
|
|
37
|
+
return this.searchStore ? await this.searchStore.search(options) : [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function createSessionRepository(options) {
|
|
41
|
+
return new SessionRepository(options);
|
|
42
|
+
}
|
|
43
|
+
export function findSessionEntryMatches(metadata, entries, text) {
|
|
44
|
+
const normalizedText = text.trim().toLowerCase();
|
|
45
|
+
if (!normalizedText)
|
|
46
|
+
return [];
|
|
47
|
+
return entries.flatMap((entry) => {
|
|
48
|
+
const payload = JSON.stringify(entry);
|
|
49
|
+
if (!payload.toLowerCase().includes(normalizedText))
|
|
50
|
+
return [];
|
|
51
|
+
return [{ metadata, entryId: entry.id, timestamp: entry.timestamp, snippet: payload }];
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export function getFileSystemResultOrThrow(result, message) {
|
|
55
|
+
if (!result.ok) {
|
|
56
|
+
const code = result.error.code === "not_found" ? "not_found" : "storage";
|
|
57
|
+
throw new SessionError(code, `${message}: ${result.error.message}`, result.error);
|
|
58
|
+
}
|
|
59
|
+
return result.value;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/harness/session/repository.ts"],"names":[],"mappings":"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","sourcesContent":["import { uuidv7 } from \"@earendil-works/pi-ai\";\nimport {\n\ttype FileError,\n\ttype Result,\n\ttype SessionCreateOptions,\n\tSessionError,\n\ttype SessionForkOptions,\n\ttype SessionMetadata,\n\ttype SessionSearch,\n\ttype SessionSearchHit,\n\ttype SessionStore,\n\ttype SessionTreeEntry,\n} from \"../types.ts\";\nimport { createSessionForkSelection } from \"./fork.ts\";\nimport { createSessionFromReader, type Session, type SessionContextBuildOptions } from \"./session.ts\";\n\nexport function createSessionId(): string {\n\treturn uuidv7();\n}\n\nexport function createTimestamp(): string {\n\treturn new Date().toISOString();\n}\n\nexport class SessionRepository<\n\tTMetadata extends SessionMetadata = SessionMetadata,\n\tTCreateOptions extends SessionCreateOptions = SessionCreateOptions,\n\tTListOptions = void,\n> {\n\tprivate readonly store: SessionStore<TMetadata, TCreateOptions, TListOptions>;\n\tprivate readonly searchStore: SessionSearch<TMetadata> | null;\n\tprivate readonly contextBuildOptions: SessionContextBuildOptions;\n\n\tconstructor(options: {\n\t\tstore: SessionStore<TMetadata, TCreateOptions, TListOptions>;\n\t\tsearch?: SessionSearch<TMetadata> | null;\n\t\tcontextBuildOptions?: SessionContextBuildOptions;\n\t}) {\n\t\tthis.store = options.store;\n\t\tthis.searchStore = options.search ?? null;\n\t\tthis.contextBuildOptions = options.contextBuildOptions ?? {};\n\t}\n\n\tasync create(options: TCreateOptions): Promise<Session<TMetadata>> {\n\t\treturn createSessionFromReader(this.store, await this.store.create(options), this.contextBuildOptions);\n\t}\n\n\tasync open(metadata: TMetadata): Promise<Session<TMetadata>> {\n\t\treturn createSessionFromReader(this.store, await this.store.load(metadata), this.contextBuildOptions);\n\t}\n\n\tasync list(options?: TListOptions): Promise<TMetadata[]> {\n\t\treturn await this.store.list(options);\n\t}\n\n\tasync delete(metadata: TMetadata): Promise<void> {\n\t\tawait this.store.delete(metadata);\n\t}\n\n\tasync fork(source: TMetadata, options: SessionForkOptions & TCreateOptions): Promise<Session<TMetadata>> {\n\t\tconst selection = createSessionForkSelection(options);\n\t\tconst createOptions = { ...options };\n\t\tdelete createOptions.entryId;\n\t\tdelete createOptions.position;\n\t\treturn createSessionFromReader(\n\t\t\tthis.store,\n\t\t\tawait this.store.fork(source, createOptions, selection),\n\t\t\tthis.contextBuildOptions,\n\t\t);\n\t}\n\n\tasync search(options: Parameters<SessionSearch<TMetadata>[\"search\"]>[0]): Promise<SessionSearchHit<TMetadata>[]> {\n\t\treturn this.searchStore ? await this.searchStore.search(options) : [];\n\t}\n}\n\nexport function createSessionRepository<\n\tTMetadata extends SessionMetadata = SessionMetadata,\n\tTCreateOptions extends SessionCreateOptions = SessionCreateOptions,\n\tTListOptions = void,\n>(options: {\n\tstore: SessionStore<TMetadata, TCreateOptions, TListOptions>;\n\tsearch?: SessionSearch<TMetadata> | null;\n\tcontextBuildOptions?: SessionContextBuildOptions;\n}): SessionRepository<TMetadata, TCreateOptions, TListOptions> {\n\treturn new SessionRepository(options);\n}\n\nexport function findSessionEntryMatches<TMetadata extends SessionMetadata>(\n\tmetadata: TMetadata,\n\tentries: readonly SessionTreeEntry[],\n\ttext: string,\n): SessionSearchHit<TMetadata>[] {\n\tconst normalizedText = text.trim().toLowerCase();\n\tif (!normalizedText) return [];\n\treturn entries.flatMap((entry) => {\n\t\tconst payload = JSON.stringify(entry);\n\t\tif (!payload.toLowerCase().includes(normalizedText)) return [];\n\t\treturn [{ metadata, entryId: entry.id, timestamp: entry.timestamp, snippet: payload }];\n\t});\n}\n\nexport function getFileSystemResultOrThrow<TValue>(result: Result<TValue, FileError>, message: string): TValue {\n\tif (!result.ok) {\n\t\tconst code = result.error.code === \"not_found\" ? \"not_found\" : \"storage\";\n\t\tthrow new SessionError(code, `${message}: ${result.error.message}`, result.error);\n\t}\n\treturn result.value;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SessionMetadata, SessionReader, SessionSearch } from "../types.ts";
|
|
2
|
+
type SessionSearchSource<TMetadata extends SessionMetadata> = {
|
|
3
|
+
load(metadata: TMetadata): Promise<SessionReader<TMetadata>>;
|
|
4
|
+
list(): Promise<TMetadata[]>;
|
|
5
|
+
};
|
|
6
|
+
export declare function createScanningSessionSearch<TMetadata extends SessionMetadata>(source: SessionSearchSource<TMetadata>): SessionSearch<TMetadata>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=search-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-backend.d.ts","sourceRoot":"","sources":["../../../src/harness/session/search-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EACf,aAAa,EACb,aAAa,EAGb,MAAM,aAAa,CAAC;AAGrB,KAAK,mBAAmB,CAAC,SAAS,SAAS,eAAe,IAAI;IAC7D,IAAI,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7D,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;CAC7B,CAAC;AAsBF,wBAAgB,2BAA2B,CAAC,SAAS,SAAS,eAAe,EAC5E,MAAM,EAAE,mBAAmB,CAAC,SAAS,CAAC,GACpC,aAAa,CAAC,SAAS,CAAC,CAE1B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { findSessionEntryMatches } from "./repository.js";
|
|
2
|
+
/** Searches canonical sessions directly and therefore has no index to maintain. */
|
|
3
|
+
class ScanningSessionSearch {
|
|
4
|
+
constructor(source) {
|
|
5
|
+
this.source = source;
|
|
6
|
+
}
|
|
7
|
+
async search(options) {
|
|
8
|
+
const hits = [];
|
|
9
|
+
for (const metadata of await this.source.list()) {
|
|
10
|
+
const cwd = metadata.cwd;
|
|
11
|
+
if (options.cwd !== undefined && cwd !== options.cwd)
|
|
12
|
+
continue;
|
|
13
|
+
const reader = await this.source.load(metadata);
|
|
14
|
+
hits.push(...findSessionEntryMatches(reader.metadata, await reader.readEntries(), options.text));
|
|
15
|
+
}
|
|
16
|
+
return hits;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function createScanningSessionSearch(source) {
|
|
20
|
+
return new ScanningSessionSearch(source);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=search-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-backend.js","sourceRoot":"","sources":["../../../src/harness/session/search-backend.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAO1D,mFAAmF;AACnF,MAAM,qBAAqB;IAG1B,YAAY,MAAsC;QACjD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAA6B;QACzC,MAAM,IAAI,GAAkC,EAAE,CAAC;QAC/C,KAAK,MAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACjD,MAAM,GAAG,GAAI,QAA8B,CAAC,GAAG,CAAC;YAChD,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG;gBAAE,SAAS;YAC/D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,MAAM,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAClG,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;CACD;AAED,MAAM,UAAU,2BAA2B,CAC1C,MAAsC;IAEtC,OAAO,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["import type {\n\tSessionMetadata,\n\tSessionReader,\n\tSessionSearch,\n\tSessionSearchHit,\n\tSessionSearchOptions,\n} from \"../types.ts\";\nimport { findSessionEntryMatches } from \"./repository.ts\";\n\ntype SessionSearchSource<TMetadata extends SessionMetadata> = {\n\tload(metadata: TMetadata): Promise<SessionReader<TMetadata>>;\n\tlist(): Promise<TMetadata[]>;\n};\n\n/** Searches canonical sessions directly and therefore has no index to maintain. */\nclass ScanningSessionSearch<TMetadata extends SessionMetadata = SessionMetadata> implements SessionSearch<TMetadata> {\n\tprivate readonly source: SessionSearchSource<TMetadata>;\n\n\tconstructor(source: SessionSearchSource<TMetadata>) {\n\t\tthis.source = source;\n\t}\n\n\tasync search(options: SessionSearchOptions): Promise<SessionSearchHit<TMetadata>[]> {\n\t\tconst hits: SessionSearchHit<TMetadata>[] = [];\n\t\tfor (const metadata of await this.source.list()) {\n\t\t\tconst cwd = (metadata as { cwd?: unknown }).cwd;\n\t\t\tif (options.cwd !== undefined && cwd !== options.cwd) continue;\n\t\t\tconst reader = await this.source.load(metadata);\n\t\t\thits.push(...findSessionEntryMatches(reader.metadata, await reader.readEntries(), options.text));\n\t\t}\n\t\treturn hits;\n\t}\n}\n\nexport function createScanningSessionSearch<TMetadata extends SessionMetadata>(\n\tsource: SessionSearchSource<TMetadata>,\n): SessionSearch<TMetadata> {\n\treturn new ScanningSessionSearch(source);\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ImageContent, type TextContent, type Usage } from "@earendil-works/pi-ai";
|
|
2
2
|
import type { AgentMessage } from "../../types.ts";
|
|
3
|
-
import type { CustomEntry, SessionContext, SessionEntryCursorOptions, SessionMetadata, SessionStats,
|
|
3
|
+
import type { CustomEntry, SessionContext, SessionEntryCursorOptions, SessionMetadata, SessionReader, SessionStats, SessionStore, SessionTreeEntry } from "../types.ts";
|
|
4
4
|
export type ContextEntryTransform = (entries: readonly SessionTreeEntry[]) => readonly SessionTreeEntry[];
|
|
5
5
|
export type CustomEntryContextMessageProjector = (entry: CustomEntry, index: number, entries: readonly SessionTreeEntry[]) => readonly AgentMessage[] | undefined;
|
|
6
6
|
export interface SessionContextBuildOptions {
|
|
@@ -13,23 +13,17 @@ export declare function defaultContextEntryTransform(pathEntries: readonly Sessi
|
|
|
13
13
|
export declare function buildContextEntries(pathEntries: readonly SessionTreeEntry[], options?: SessionContextBuildOptions): SessionTreeEntry[];
|
|
14
14
|
export declare function sessionEntryToContextMessages(entry: SessionTreeEntry, index: number, entries: readonly SessionTreeEntry[], options?: SessionContextBuildOptions): AgentMessage[];
|
|
15
15
|
export declare function buildSessionContext(pathEntries: readonly SessionTreeEntry[], options?: SessionContextBuildOptions): SessionContext;
|
|
16
|
-
export
|
|
17
|
-
private storage;
|
|
18
|
-
private contextBuildOptions;
|
|
19
|
-
constructor(storage: SessionStorage<TMetadata>, contextBuildOptions?: SessionContextBuildOptions);
|
|
16
|
+
export interface Session<TMetadata extends SessionMetadata = SessionMetadata> {
|
|
20
17
|
getMetadata(): Promise<TMetadata>;
|
|
21
|
-
getStorage(): SessionStorage<TMetadata>;
|
|
22
18
|
getLeafId(): Promise<string | null>;
|
|
23
19
|
getEntry(id: string): Promise<SessionTreeEntry | undefined>;
|
|
24
20
|
getEntries(options?: SessionEntryCursorOptions): Promise<SessionTreeEntry[]>;
|
|
25
|
-
getBranch(fromId?: string): Promise<SessionTreeEntry[]>;
|
|
21
|
+
getBranch(fromId?: string | null): Promise<SessionTreeEntry[]>;
|
|
26
22
|
buildContextEntries(options?: SessionContextBuildOptions): Promise<SessionTreeEntry[]>;
|
|
27
23
|
buildContext(options?: SessionContextBuildOptions): Promise<SessionContext>;
|
|
28
|
-
private mergeContextBuildOptions;
|
|
29
24
|
getLabel(id: string): Promise<string | undefined>;
|
|
30
25
|
getSessionStats(): Promise<SessionStats>;
|
|
31
26
|
getSessionName(): Promise<string | undefined>;
|
|
32
|
-
private appendTypedEntry;
|
|
33
27
|
appendMessage(message: AgentMessage): Promise<string>;
|
|
34
28
|
appendThinkingLevelChange(thinkingLevel: string): Promise<string>;
|
|
35
29
|
appendModelChange(provider: string, modelId: string): Promise<string>;
|
|
@@ -46,4 +40,6 @@ export declare class Session<TMetadata extends SessionMetadata = SessionMetadata
|
|
|
46
40
|
fromHook?: boolean;
|
|
47
41
|
}): Promise<string | undefined>;
|
|
48
42
|
}
|
|
43
|
+
/** @internal Construct sessions only through SessionRepository. */
|
|
44
|
+
export declare function createSessionFromReader<TMetadata extends SessionMetadata>(store: Pick<SessionStore<TMetadata>, "appendEntry">, reader: SessionReader<TMetadata>, contextBuildOptions?: SessionContextBuildOptions): Promise<Session<TMetadata>>;
|
|
49
45
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/harness/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/harness/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAU,MAAM,uBAAuB,CAAC;AAChG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,KAAK,EAIX,WAAW,EAMX,cAAc,EACd,yBAAyB,EAEzB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAEhB,MAAM,aAAa,CAAC;AAGrB,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,KAAK,SAAS,gBAAgB,EAAE,CAAC;AAE1G,MAAM,MAAM,kCAAkC,GAAG,CAChD,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,gBAAgB,EAAE,KAChC,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;AAEzC,MAAM,WAAW,0BAA0B;IAC1C,kFAAkF;IAClF,eAAe,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,kGAAkG;IAClG,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kCAAkC,CAAC,CAAC,CAAC;CAC/E;AAsBD,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CA+BzG;AAED,wBAAgB,mBAAmB,CAClC,WAAW,EAAE,SAAS,gBAAgB,EAAE,EACxC,OAAO,GAAE,0BAA+B,GACtC,gBAAgB,EAAE,CAMpB;AAED,wBAAgB,6BAA6B,CAC5C,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,OAAO,GAAE,0BAA+B,GACtC,YAAY,EAAE,CA4BhB;AAED,wBAAgB,mBAAmB,CAClC,WAAW,EAAE,SAAS,gBAAgB,EAAE,EACxC,OAAO,GAAE,0BAA+B,GACtC,cAAc,CAOhB;AAgED,MAAM,WAAW,OAAO,CAAC,SAAS,SAAS,eAAe,GAAG,eAAe;IAC3E,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IAC5D,UAAU,CAAC,OAAO,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC7E,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC/D,mBAAmB,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACvF,YAAY,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IACzC,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC9C,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtE,uBAAuB,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpE,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAC3B,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,CAAC,EACX,QAAQ,CAAC,EAAE,OAAO,EAClB,KAAK,CAAC,EAAE,KAAK,EACb,YAAY,CAAC,EAAE,YAAY,EAAE,GAC3B,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvE,wBAAwB,CAAC,CAAC,GAAG,OAAO,EACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,CAAC,GACT,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,CACL,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GACjF,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CAC/B;AA8QD,mEAAmE;AACnE,wBAAsB,uBAAuB,CAAC,SAAS,SAAS,eAAe,EAC9E,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,EACnD,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,EAChC,mBAAmB,GAAE,0BAA+B,GAClD,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAE7B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { uuidv7 } from "@earendil-works/pi-ai";
|
|
1
2
|
import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage } from "../messages.js";
|
|
2
3
|
import { SessionError } from "../types.js";
|
|
3
4
|
function deriveSessionContextState(pathEntries) {
|
|
@@ -89,29 +90,87 @@ export function buildSessionContext(pathEntries, options = {}) {
|
|
|
89
90
|
const messages = contextEntries.flatMap((entry, index) => sessionEntryToContextMessages(entry, index, contextEntries, options));
|
|
90
91
|
return { ...state, messages };
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
-
constructor(
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
93
|
+
class HydratedSessionState {
|
|
94
|
+
constructor(entries) {
|
|
95
|
+
this.labelsById = new Map();
|
|
96
|
+
this.entries = [...entries];
|
|
97
|
+
for (const entry of this.entries)
|
|
98
|
+
this.applyProjection(entry);
|
|
99
|
+
}
|
|
100
|
+
getLabel(id) {
|
|
101
|
+
return this.labelsById.get(id);
|
|
102
|
+
}
|
|
103
|
+
getSessionName() {
|
|
104
|
+
for (let i = this.entries.length - 1; i >= 0; i--) {
|
|
105
|
+
const entry = this.entries[i];
|
|
106
|
+
if (entry.type === "session_info")
|
|
107
|
+
return entry.name?.trim() || undefined;
|
|
108
|
+
}
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
getSessionStats() {
|
|
112
|
+
let messageCount = 0;
|
|
113
|
+
let cachedTokens = 0;
|
|
114
|
+
let uncachedTokens = 0;
|
|
115
|
+
let totalTokens = 0;
|
|
116
|
+
let costTotal = 0;
|
|
117
|
+
for (const entry of this.entries) {
|
|
118
|
+
if (entry.type === "message")
|
|
119
|
+
messageCount += 1;
|
|
120
|
+
const usage = entry.type === "message"
|
|
121
|
+
? entry.message.role === "assistant"
|
|
122
|
+
? entry.message.usage
|
|
123
|
+
: undefined
|
|
124
|
+
: entry.type === "compaction" || entry.type === "branch_summary"
|
|
125
|
+
? entry.usage
|
|
126
|
+
: undefined;
|
|
127
|
+
if (!usage ||
|
|
128
|
+
typeof usage.input !== "number" ||
|
|
129
|
+
typeof usage.output !== "number" ||
|
|
130
|
+
typeof usage.cacheRead !== "number" ||
|
|
131
|
+
typeof usage.cacheWrite !== "number" ||
|
|
132
|
+
typeof usage.cost?.total !== "number")
|
|
133
|
+
continue;
|
|
134
|
+
cachedTokens += usage.cacheRead;
|
|
135
|
+
uncachedTokens += usage.input + usage.cacheWrite;
|
|
136
|
+
totalTokens += usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
137
|
+
costTotal += usage.cost.total;
|
|
138
|
+
}
|
|
139
|
+
return { messageCount, cachedTokens, uncachedTokens, totalTokens, costTotal };
|
|
96
140
|
}
|
|
97
|
-
|
|
98
|
-
|
|
141
|
+
applyProjection(entry) {
|
|
142
|
+
if (entry.type !== "label")
|
|
143
|
+
return;
|
|
144
|
+
const label = entry.label?.trim();
|
|
145
|
+
if (label)
|
|
146
|
+
this.labelsById.set(entry.targetId, label);
|
|
147
|
+
else
|
|
148
|
+
this.labelsById.delete(entry.targetId);
|
|
99
149
|
}
|
|
100
|
-
|
|
101
|
-
|
|
150
|
+
}
|
|
151
|
+
class StoreSession {
|
|
152
|
+
constructor(store, reader, leafId, contextBuildOptions = {}) {
|
|
153
|
+
this.appendTail = Promise.resolve();
|
|
154
|
+
this.store = store;
|
|
155
|
+
this.reader = reader;
|
|
156
|
+
this.metadata = reader.metadata;
|
|
157
|
+
this.leafId = leafId;
|
|
158
|
+
this.contextBuildOptions = contextBuildOptions;
|
|
102
159
|
}
|
|
103
|
-
|
|
104
|
-
return this.
|
|
160
|
+
async getMetadata() {
|
|
161
|
+
return this.metadata;
|
|
105
162
|
}
|
|
106
|
-
|
|
107
|
-
return this.
|
|
163
|
+
async getLeafId() {
|
|
164
|
+
return this.leafId;
|
|
108
165
|
}
|
|
109
|
-
|
|
110
|
-
return this.
|
|
166
|
+
async getEntry(id) {
|
|
167
|
+
return this.reader.readEntry(id);
|
|
168
|
+
}
|
|
169
|
+
async getEntries(options) {
|
|
170
|
+
return [...(await this.reader.readEntries(options))];
|
|
111
171
|
}
|
|
112
172
|
async getBranch(fromId) {
|
|
113
|
-
|
|
114
|
-
return this.storage.getPathToRootOrCompaction(leafId);
|
|
173
|
+
return [...(await this.reader.readPathToRootOrCompaction(fromId === undefined ? this.leafId : fromId))];
|
|
115
174
|
}
|
|
116
175
|
async buildContextEntries(options = {}) {
|
|
117
176
|
return buildContextEntries(await this.getBranch(), this.mergeContextBuildOptions(options));
|
|
@@ -128,62 +187,86 @@ export class Session {
|
|
|
128
187
|
},
|
|
129
188
|
};
|
|
130
189
|
}
|
|
131
|
-
getLabel(id) {
|
|
132
|
-
return this.
|
|
190
|
+
async getLabel(id) {
|
|
191
|
+
return (await this.getHydratedState()).getLabel(id);
|
|
133
192
|
}
|
|
134
|
-
getSessionStats() {
|
|
135
|
-
return this.
|
|
193
|
+
async getSessionStats() {
|
|
194
|
+
return (await this.getHydratedState()).getSessionStats();
|
|
136
195
|
}
|
|
137
196
|
async getSessionName() {
|
|
138
|
-
return this.
|
|
197
|
+
return (await this.getHydratedState()).getSessionName();
|
|
198
|
+
}
|
|
199
|
+
async getHydratedState() {
|
|
200
|
+
this.hydratedStatePromise ??= this.reader.readEntries().then((entries) => new HydratedSessionState(entries));
|
|
201
|
+
return this.hydratedStatePromise;
|
|
139
202
|
}
|
|
140
|
-
async
|
|
141
|
-
|
|
142
|
-
|
|
203
|
+
async createEntryId() {
|
|
204
|
+
for (let i = 0; i < 100; i++) {
|
|
205
|
+
const id = uuidv7().slice(-8);
|
|
206
|
+
if (!(await this.getEntry(id)))
|
|
207
|
+
return id;
|
|
208
|
+
}
|
|
209
|
+
return uuidv7();
|
|
210
|
+
}
|
|
211
|
+
enqueueAppend(createEntry) {
|
|
212
|
+
const operation = this.appendTail.then(async () => {
|
|
213
|
+
const entry = createEntry({
|
|
214
|
+
id: await this.createEntryId(),
|
|
215
|
+
parentId: this.leafId,
|
|
216
|
+
timestamp: new Date().toISOString(),
|
|
217
|
+
});
|
|
218
|
+
await this.store.appendEntry(this.metadata, entry);
|
|
219
|
+
this.leafId = entry.type === "leaf" ? entry.targetId : entry.id;
|
|
220
|
+
this.hydratedStatePromise = undefined;
|
|
221
|
+
return entry;
|
|
222
|
+
});
|
|
223
|
+
this.appendTail = operation.then(() => undefined, () => undefined);
|
|
224
|
+
return operation;
|
|
225
|
+
}
|
|
226
|
+
async setLeafId(leafId) {
|
|
227
|
+
if (leafId !== null && !(await this.getEntry(leafId))) {
|
|
228
|
+
throw new SessionError("not_found", `Entry ${leafId} not found`);
|
|
229
|
+
}
|
|
230
|
+
return this.enqueueAppend((base) => {
|
|
231
|
+
return { ...base, type: "leaf", targetId: leafId };
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
async appendTypedEntry(createEntry) {
|
|
235
|
+
return (await this.enqueueAppend(createEntry)).id;
|
|
143
236
|
}
|
|
144
237
|
async appendMessage(message) {
|
|
145
|
-
return this.appendTypedEntry({
|
|
238
|
+
return this.appendTypedEntry((base) => ({
|
|
239
|
+
...base,
|
|
146
240
|
type: "message",
|
|
147
|
-
id: await this.storage.createEntryId(),
|
|
148
|
-
parentId: await this.storage.getLeafId(),
|
|
149
|
-
timestamp: new Date().toISOString(),
|
|
150
241
|
message,
|
|
151
|
-
});
|
|
242
|
+
}));
|
|
152
243
|
}
|
|
153
244
|
async appendThinkingLevelChange(thinkingLevel) {
|
|
154
|
-
return this.appendTypedEntry({
|
|
245
|
+
return this.appendTypedEntry((base) => ({
|
|
246
|
+
...base,
|
|
155
247
|
type: "thinking_level_change",
|
|
156
|
-
id: await this.storage.createEntryId(),
|
|
157
|
-
parentId: await this.storage.getLeafId(),
|
|
158
|
-
timestamp: new Date().toISOString(),
|
|
159
248
|
thinkingLevel,
|
|
160
|
-
});
|
|
249
|
+
}));
|
|
161
250
|
}
|
|
162
251
|
async appendModelChange(provider, modelId) {
|
|
163
|
-
return this.appendTypedEntry({
|
|
252
|
+
return this.appendTypedEntry((base) => ({
|
|
253
|
+
...base,
|
|
164
254
|
type: "model_change",
|
|
165
|
-
id: await this.storage.createEntryId(),
|
|
166
|
-
parentId: await this.storage.getLeafId(),
|
|
167
|
-
timestamp: new Date().toISOString(),
|
|
168
255
|
provider,
|
|
169
256
|
modelId,
|
|
170
|
-
});
|
|
257
|
+
}));
|
|
171
258
|
}
|
|
172
259
|
async appendActiveToolsChange(activeToolNames) {
|
|
173
|
-
return this.appendTypedEntry({
|
|
260
|
+
return this.appendTypedEntry((base) => ({
|
|
261
|
+
...base,
|
|
174
262
|
type: "active_tools_change",
|
|
175
|
-
id: await this.storage.createEntryId(),
|
|
176
|
-
parentId: await this.storage.getLeafId(),
|
|
177
|
-
timestamp: new Date().toISOString(),
|
|
178
263
|
activeToolNames: [...activeToolNames],
|
|
179
|
-
});
|
|
264
|
+
}));
|
|
180
265
|
}
|
|
181
266
|
async appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook, usage, retainedTail) {
|
|
182
|
-
return this.appendTypedEntry({
|
|
267
|
+
return this.appendTypedEntry((base) => ({
|
|
268
|
+
...base,
|
|
183
269
|
type: "compaction",
|
|
184
|
-
id: await this.storage.createEntryId(),
|
|
185
|
-
parentId: await this.storage.getLeafId(),
|
|
186
|
-
timestamp: new Date().toISOString(),
|
|
187
270
|
summary,
|
|
188
271
|
firstKeptEntryId,
|
|
189
272
|
tokensBefore,
|
|
@@ -191,71 +274,65 @@ export class Session {
|
|
|
191
274
|
details,
|
|
192
275
|
usage,
|
|
193
276
|
fromHook,
|
|
194
|
-
});
|
|
277
|
+
}));
|
|
195
278
|
}
|
|
196
279
|
async appendCustomEntry(customType, data) {
|
|
197
|
-
return this.appendTypedEntry({
|
|
280
|
+
return this.appendTypedEntry((base) => ({
|
|
281
|
+
...base,
|
|
198
282
|
type: "custom",
|
|
199
|
-
id: await this.storage.createEntryId(),
|
|
200
|
-
parentId: await this.storage.getLeafId(),
|
|
201
|
-
timestamp: new Date().toISOString(),
|
|
202
283
|
customType,
|
|
203
284
|
data,
|
|
204
|
-
});
|
|
285
|
+
}));
|
|
205
286
|
}
|
|
206
287
|
async appendCustomMessageEntry(customType, content, display, details) {
|
|
207
|
-
return this.appendTypedEntry({
|
|
288
|
+
return this.appendTypedEntry((base) => ({
|
|
289
|
+
...base,
|
|
208
290
|
type: "custom_message",
|
|
209
|
-
id: await this.storage.createEntryId(),
|
|
210
|
-
parentId: await this.storage.getLeafId(),
|
|
211
|
-
timestamp: new Date().toISOString(),
|
|
212
291
|
customType,
|
|
213
292
|
content,
|
|
214
293
|
display,
|
|
215
294
|
details,
|
|
216
|
-
});
|
|
295
|
+
}));
|
|
217
296
|
}
|
|
218
297
|
async appendLabel(targetId, label) {
|
|
219
|
-
if (!(await this.
|
|
298
|
+
if (!(await this.getEntry(targetId))) {
|
|
220
299
|
throw new SessionError("not_found", `Entry ${targetId} not found`);
|
|
221
300
|
}
|
|
222
|
-
return this.appendTypedEntry({
|
|
301
|
+
return this.appendTypedEntry((base) => ({
|
|
302
|
+
...base,
|
|
223
303
|
type: "label",
|
|
224
|
-
id: await this.storage.createEntryId(),
|
|
225
|
-
parentId: await this.storage.getLeafId(),
|
|
226
|
-
timestamp: new Date().toISOString(),
|
|
227
304
|
targetId,
|
|
228
305
|
label,
|
|
229
|
-
});
|
|
306
|
+
}));
|
|
230
307
|
}
|
|
231
308
|
async appendSessionName(name) {
|
|
232
309
|
const sanitizedName = name.replace(/[\r\n]+/g, " ").trim();
|
|
233
|
-
return this.appendTypedEntry({
|
|
310
|
+
return this.appendTypedEntry((base) => ({
|
|
311
|
+
...base,
|
|
234
312
|
type: "session_info",
|
|
235
|
-
id: await this.storage.createEntryId(),
|
|
236
|
-
parentId: await this.storage.getLeafId(),
|
|
237
|
-
timestamp: new Date().toISOString(),
|
|
238
313
|
name: sanitizedName,
|
|
239
|
-
});
|
|
314
|
+
}));
|
|
240
315
|
}
|
|
241
316
|
async moveTo(entryId, summary) {
|
|
242
|
-
if (entryId !== null && !(await this.
|
|
317
|
+
if (entryId !== null && !(await this.getEntry(entryId))) {
|
|
243
318
|
throw new SessionError("not_found", `Entry ${entryId} not found`);
|
|
244
319
|
}
|
|
245
|
-
await this.
|
|
320
|
+
await this.setLeafId(entryId);
|
|
246
321
|
if (!summary)
|
|
247
322
|
return undefined;
|
|
248
|
-
return this.appendTypedEntry({
|
|
323
|
+
return this.appendTypedEntry((base) => ({
|
|
324
|
+
...base,
|
|
249
325
|
type: "branch_summary",
|
|
250
|
-
id: await this.storage.createEntryId(),
|
|
251
|
-
parentId: entryId,
|
|
252
|
-
timestamp: new Date().toISOString(),
|
|
253
326
|
fromId: entryId ?? "root",
|
|
254
327
|
summary: summary.summary,
|
|
255
328
|
details: summary.details,
|
|
256
329
|
usage: summary.usage,
|
|
257
330
|
fromHook: summary.fromHook,
|
|
258
|
-
});
|
|
331
|
+
}));
|
|
259
332
|
}
|
|
260
333
|
}
|
|
334
|
+
/** @internal Construct sessions only through SessionRepository. */
|
|
335
|
+
export async function createSessionFromReader(store, reader, contextBuildOptions = {}) {
|
|
336
|
+
return new StoreSession(store, reader, (await reader.readHead()).leafId, contextBuildOptions);
|
|
337
|
+
}
|
|
261
338
|
//# sourceMappingURL=session.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/harness/session/session.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent, Usage } from \"@earendil-works/pi-ai\";\nimport type { AgentMessage } from \"../../types.ts\";\nimport { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage } from \"../messages.ts\";\nimport type {\n\tActiveToolsChangeEntry,\n\tBranchSummaryEntry,\n\tCompactionEntry,\n\tCustomEntry,\n\tCustomMessageEntry,\n\tLabelEntry,\n\tMessageEntry,\n\tModelChangeEntry,\n\tSessionContext,\n\tSessionEntryCursorOptions,\n\tSessionInfoEntry,\n\tSessionMetadata,\n\tSessionStats,\n\tSessionStorage,\n\tSessionTreeEntry,\n\tThinkingLevelChangeEntry,\n} from \"../types.ts\";\nimport { SessionError } from \"../types.ts\";\n\nexport type ContextEntryTransform = (entries: readonly SessionTreeEntry[]) => readonly SessionTreeEntry[];\n\nexport type CustomEntryContextMessageProjector = (\n\tentry: CustomEntry,\n\tindex: number,\n\tentries: readonly SessionTreeEntry[],\n) => readonly AgentMessage[] | undefined;\n\nexport interface SessionContextBuildOptions {\n\t/** Additional entry transforms applied after the default compaction transform. */\n\tentryTransforms?: readonly ContextEntryTransform[];\n\t/** Optional custom-entry projectors. Custom entries are omitted from model context by default. */\n\tentryProjectors?: Readonly<Record<string, CustomEntryContextMessageProjector>>;\n}\n\nfunction deriveSessionContextState(pathEntries: readonly SessionTreeEntry[]): Omit<SessionContext, \"messages\"> {\n\tlet thinkingLevel = \"off\";\n\tlet model: { provider: string; modelId: string } | null = null;\n\tlet activeToolNames: string[] | null = null;\n\n\tfor (const entry of pathEntries) {\n\t\tif (entry.type === \"thinking_level_change\") {\n\t\t\tthinkingLevel = entry.thinkingLevel;\n\t\t} else if (entry.type === \"model_change\") {\n\t\t\tmodel = { provider: entry.provider, modelId: entry.modelId };\n\t\t} else if (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tmodel = { provider: entry.message.provider, modelId: entry.message.model };\n\t\t} else if (entry.type === \"active_tools_change\") {\n\t\t\tactiveToolNames = [...entry.activeToolNames];\n\t\t}\n\t}\n\n\treturn { thinkingLevel, model, activeToolNames };\n}\n\nexport function defaultContextEntryTransform(pathEntries: readonly SessionTreeEntry[]): SessionTreeEntry[] {\n\tlet compaction: CompactionEntry | null = null;\n\tfor (const entry of pathEntries) {\n\t\tif (entry.type === \"compaction\") {\n\t\t\tcompaction = entry;\n\t\t}\n\t}\n\tif (!compaction) {\n\t\treturn [...pathEntries];\n\t}\n\n\tconst entries: SessionTreeEntry[] = [compaction];\n\tconst compactionIdx = pathEntries.findIndex((entry) => entry.type === \"compaction\" && entry.id === compaction.id);\n\tif (compaction.retainedTail) {\n\t\tfor (let i = compactionIdx + 1; i < pathEntries.length; i++) {\n\t\t\tentries.push(pathEntries[i]!);\n\t\t}\n\t\treturn entries;\n\t}\n\tif (compaction.firstKeptEntryId) {\n\t\tlet foundFirstKept = false;\n\t\tfor (let i = 0; i < compactionIdx; i++) {\n\t\t\tconst entry = pathEntries[i]!;\n\t\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\t\tif (foundFirstKept) entries.push(entry);\n\t\t}\n\t}\n\tfor (let i = compactionIdx + 1; i < pathEntries.length; i++) {\n\t\tentries.push(pathEntries[i]!);\n\t}\n\treturn entries;\n}\n\nexport function buildContextEntries(\n\tpathEntries: readonly SessionTreeEntry[],\n\toptions: SessionContextBuildOptions = {},\n): SessionTreeEntry[] {\n\tlet entries = defaultContextEntryTransform(pathEntries);\n\tfor (const transform of options.entryTransforms ?? []) {\n\t\tentries = [...transform(entries)];\n\t}\n\treturn entries;\n}\n\nexport function sessionEntryToContextMessages(\n\tentry: SessionTreeEntry,\n\tindex: number,\n\tentries: readonly SessionTreeEntry[],\n\toptions: SessionContextBuildOptions = {},\n): AgentMessage[] {\n\tif (entry.type === \"message\") {\n\t\treturn [entry.message as AgentMessage];\n\t}\n\tif (entry.type === \"custom_message\") {\n\t\treturn [\n\t\t\tcreateCustomMessage(\n\t\t\t\tentry.customType,\n\t\t\t\tentry.content as string | (TextContent | ImageContent)[],\n\t\t\t\tentry.display,\n\t\t\t\tentry.details,\n\t\t\t\tentry.timestamp,\n\t\t\t),\n\t\t];\n\t}\n\tif (entry.type === \"compaction\") {\n\t\treturn [\n\t\t\tcreateCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp),\n\t\t\t...(entry.retainedTail ?? []),\n\t\t];\n\t}\n\tif (entry.type === \"branch_summary\" && entry.summary) {\n\t\treturn [createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp)];\n\t}\n\tif (entry.type === \"custom\") {\n\t\treturn [...(options.entryProjectors?.[entry.customType]?.(entry, index, entries) ?? [])];\n\t}\n\treturn [];\n}\n\nexport function buildSessionContext(\n\tpathEntries: readonly SessionTreeEntry[],\n\toptions: SessionContextBuildOptions = {},\n): SessionContext {\n\tconst state = deriveSessionContextState(pathEntries);\n\tconst contextEntries = buildContextEntries(pathEntries, options);\n\tconst messages = contextEntries.flatMap((entry, index) =>\n\t\tsessionEntryToContextMessages(entry, index, contextEntries, options),\n\t);\n\treturn { ...state, messages };\n}\n\nexport class Session<TMetadata extends SessionMetadata = SessionMetadata> {\n\tprivate storage: SessionStorage<TMetadata>;\n\tprivate contextBuildOptions: SessionContextBuildOptions;\n\n\tconstructor(storage: SessionStorage<TMetadata>, contextBuildOptions: SessionContextBuildOptions = {}) {\n\t\tthis.storage = storage;\n\t\tthis.contextBuildOptions = contextBuildOptions;\n\t}\n\n\tgetMetadata(): Promise<TMetadata> {\n\t\treturn this.storage.getMetadata();\n\t}\n\n\tgetStorage(): SessionStorage<TMetadata> {\n\t\treturn this.storage;\n\t}\n\n\tgetLeafId(): Promise<string | null> {\n\t\treturn this.storage.getLeafId();\n\t}\n\n\tgetEntry(id: string): Promise<SessionTreeEntry | undefined> {\n\t\treturn this.storage.getEntry(id);\n\t}\n\n\tgetEntries(options?: SessionEntryCursorOptions): Promise<SessionTreeEntry[]> {\n\t\treturn this.storage.getEntries(options);\n\t}\n\n\tasync getBranch(fromId?: string): Promise<SessionTreeEntry[]> {\n\t\tconst leafId = fromId ?? (await this.storage.getLeafId());\n\t\treturn this.storage.getPathToRootOrCompaction(leafId);\n\t}\n\n\tasync buildContextEntries(options: SessionContextBuildOptions = {}): Promise<SessionTreeEntry[]> {\n\t\treturn buildContextEntries(await this.getBranch(), this.mergeContextBuildOptions(options));\n\t}\n\n\tasync buildContext(options: SessionContextBuildOptions = {}): Promise<SessionContext> {\n\t\treturn buildSessionContext(await this.getBranch(), this.mergeContextBuildOptions(options));\n\t}\n\n\tprivate mergeContextBuildOptions(options: SessionContextBuildOptions): SessionContextBuildOptions {\n\t\treturn {\n\t\t\tentryTransforms: [...(this.contextBuildOptions.entryTransforms ?? []), ...(options.entryTransforms ?? [])],\n\t\t\tentryProjectors: {\n\t\t\t\t...(this.contextBuildOptions.entryProjectors ?? {}),\n\t\t\t\t...(options.entryProjectors ?? {}),\n\t\t\t},\n\t\t};\n\t}\n\n\tgetLabel(id: string): Promise<string | undefined> {\n\t\treturn this.storage.getLabel(id);\n\t}\n\n\tgetSessionStats(): Promise<SessionStats> {\n\t\treturn this.storage.getSessionStats();\n\t}\n\n\tasync getSessionName(): Promise<string | undefined> {\n\t\treturn this.storage.getSessionName();\n\t}\n\n\tprivate async appendTypedEntry<TEntry extends SessionTreeEntry>(entry: TEntry): Promise<string> {\n\t\tawait this.storage.appendEntry(entry);\n\t\treturn entry.id;\n\t}\n\n\tasync appendMessage(message: AgentMessage): Promise<string> {\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"message\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: await this.storage.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tmessage,\n\t\t} satisfies MessageEntry);\n\t}\n\n\tasync appendThinkingLevelChange(thinkingLevel: string): Promise<string> {\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"thinking_level_change\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: await this.storage.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tthinkingLevel,\n\t\t} satisfies ThinkingLevelChangeEntry);\n\t}\n\n\tasync appendModelChange(provider: string, modelId: string): Promise<string> {\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"model_change\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: await this.storage.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t} satisfies ModelChangeEntry);\n\t}\n\n\tasync appendActiveToolsChange(activeToolNames: string[]): Promise<string> {\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"active_tools_change\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: await this.storage.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tactiveToolNames: [...activeToolNames],\n\t\t} satisfies ActiveToolsChangeEntry);\n\t}\n\n\tasync appendCompaction<T = unknown>(\n\t\tsummary: string,\n\t\tfirstKeptEntryId: string | undefined,\n\t\ttokensBefore: number,\n\t\tdetails?: T,\n\t\tfromHook?: boolean,\n\t\tusage?: Usage,\n\t\tretainedTail?: AgentMessage[],\n\t): Promise<string> {\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"compaction\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: await this.storage.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsummary,\n\t\t\tfirstKeptEntryId,\n\t\t\ttokensBefore,\n\t\t\tretainedTail,\n\t\t\tdetails,\n\t\t\tusage,\n\t\t\tfromHook,\n\t\t} satisfies CompactionEntry<T>);\n\t}\n\n\tasync appendCustomEntry(customType: string, data?: unknown): Promise<string> {\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"custom\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: await this.storage.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcustomType,\n\t\t\tdata,\n\t\t} satisfies CustomEntry);\n\t}\n\n\tasync appendCustomMessageEntry<T = unknown>(\n\t\tcustomType: string,\n\t\tcontent: string | (TextContent | ImageContent)[],\n\t\tdisplay: boolean,\n\t\tdetails?: T,\n\t): Promise<string> {\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"custom_message\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: await this.storage.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcustomType,\n\t\t\tcontent,\n\t\t\tdisplay,\n\t\t\tdetails,\n\t\t} satisfies CustomMessageEntry<T>);\n\t}\n\n\tasync appendLabel(targetId: string, label: string | undefined): Promise<string> {\n\t\tif (!(await this.storage.getEntry(targetId))) {\n\t\t\tthrow new SessionError(\"not_found\", `Entry ${targetId} not found`);\n\t\t}\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"label\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: await this.storage.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\ttargetId,\n\t\t\tlabel,\n\t\t} satisfies LabelEntry);\n\t}\n\n\tasync appendSessionName(name: string): Promise<string> {\n\t\tconst sanitizedName = name.replace(/[\\r\\n]+/g, \" \").trim();\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"session_info\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: await this.storage.getLeafId(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tname: sanitizedName,\n\t\t} satisfies SessionInfoEntry);\n\t}\n\n\tasync moveTo(\n\t\tentryId: string | null,\n\t\tsummary?: { summary: string; details?: unknown; usage?: Usage; fromHook?: boolean },\n\t): Promise<string | undefined> {\n\t\tif (entryId !== null && !(await this.storage.getEntry(entryId))) {\n\t\t\tthrow new SessionError(\"not_found\", `Entry ${entryId} not found`);\n\t\t}\n\t\tawait this.storage.setLeafId(entryId);\n\t\tif (!summary) return undefined;\n\t\treturn this.appendTypedEntry({\n\t\t\ttype: \"branch_summary\",\n\t\t\tid: await this.storage.createEntryId(),\n\t\t\tparentId: entryId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tfromId: entryId ?? \"root\",\n\t\t\tsummary: summary.summary,\n\t\t\tdetails: summary.details,\n\t\t\tusage: summary.usage,\n\t\t\tfromHook: summary.fromHook,\n\t\t} satisfies BranchSummaryEntry);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/harness/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmD,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEhG,OAAO,EAAE,0BAA0B,EAAE,8BAA8B,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAqBjH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiB3C,SAAS,yBAAyB,CAAC,WAAwC;IAC1E,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,KAAK,GAAiD,IAAI,CAAC;IAC/D,IAAI,eAAe,GAAoB,IAAI,CAAC;IAE5C,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,IAAI,KAAK,uBAAuB,EAAE,CAAC;YAC5C,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;QACrC,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAC1C,KAAK,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9D,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC3E,KAAK,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC5E,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;YACjD,eAAe,GAAG,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;QAC9C,CAAC;IACF,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,WAAwC;IACpF,IAAI,UAAU,GAA2B,IAAI,CAAC;IAC9C,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACjC,UAAU,GAAG,KAAK,CAAC;QACpB,CAAC;IACF,CAAC;IACD,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,OAAO,GAAuB,CAAC,UAAU,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,EAAE,KAAK,UAAU,CAAC,EAAE,CAAC,CAAC;IAClH,IAAI,UAAU,CAAC,YAAY,EAAE,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,aAAa,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,IAAI,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACjC,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAE,CAAC;YAC9B,IAAI,KAAK,CAAC,EAAE,KAAK,UAAU,CAAC,gBAAgB;gBAAE,cAAc,GAAG,IAAI,CAAC;YACpE,IAAI,cAAc;gBAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;IACF,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,aAAa,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAClC,WAAwC,EACxC,OAAO,GAA+B,EAAE;IAExC,IAAI,OAAO,GAAG,4BAA4B,CAAC,WAAW,CAAC,CAAC;IACxD,KAAK,MAAM,SAAS,IAAI,OAAO,CAAC,eAAe,IAAI,EAAE,EAAE,CAAC;QACvD,OAAO,GAAG,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC5C,KAAuB,EACvB,KAAa,EACb,OAAoC,EACpC,OAAO,GAA+B,EAAE;IAExC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,OAAuB,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,OAAO;YACN,mBAAmB,CAClB,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,OAAkD,EACxD,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,SAAS,CACf;SACD,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACjC,OAAO;YACN,8BAA8B,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC;YAClF,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC;SAC7B,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACtD,OAAO,CAAC,0BAA0B,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC;AAED,MAAM,UAAU,mBAAmB,CAClC,WAAwC,EACxC,OAAO,GAA+B,EAAE;IAExC,MAAM,KAAK,GAAG,yBAAyB,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,cAAc,GAAG,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACxD,6BAA6B,CAAC,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,CAAC,CACpE,CAAC;IACF,OAAO,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,oBAAoB;IAIzB,YAAY,OAAoC;QAF/B,eAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;QAGvD,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED,QAAQ,CAAC,EAAU;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,cAAc;QACb,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC;YAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;gBAAE,OAAO,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;QAC3E,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,eAAe;QACd,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;gBAAE,YAAY,IAAI,CAAC,CAAC;YAChD,MAAM,KAAK,GACV,KAAK,CAAC,IAAI,KAAK,SAAS;gBACvB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW;oBACnC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK;oBACrB,CAAC,CAAC,SAAS;gBACZ,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB;oBAC/D,CAAC,CAAC,KAAK,CAAC,KAAK;oBACb,CAAC,CAAC,SAAS,CAAC;YACf,IACC,CAAC,KAAK;gBACN,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;gBAC/B,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;gBAChC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;gBACnC,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;gBACpC,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,KAAK,QAAQ;gBAErC,SAAS;YACV,YAAY,IAAI,KAAK,CAAC,SAAS,CAAC;YAChC,cAAc,IAAI,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC;YACjD,WAAW,IAAI,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC;YAC/E,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/B,CAAC;QACD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;IAC/E,CAAC;IAEO,eAAe,CAAC,KAAuB;QAC9C,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;QAClC,IAAI,KAAK;YAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;;YACjD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;CACD;AAyCD,MAAM,YAAY;IASjB,YACC,KAAmD,EACnD,MAAgC,EAChC,MAAqB,EACrB,mBAAmB,GAA+B,EAAE;QAN7C,eAAU,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;QAQrD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,WAAW;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IACD,KAAK,CAAC,SAAS;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IACD,KAAK,CAAC,QAAQ,CAAC,EAAU;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,OAAmC;QACnD,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAsB;QACrC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,0BAA0B,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACzG,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,OAAO,GAA+B,EAAE;QACjE,OAAO,mBAAmB,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAO,GAA+B,EAAE;QAC1D,OAAO,mBAAmB,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5F,CAAC;IAEO,wBAAwB,CAAC,OAAmC;QACnE,OAAO;YACN,eAAe,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;YAC1G,eAAe,EAAE;gBAChB,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,IAAI,EAAE,CAAC;gBACnD,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;aAClC;SACD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,EAAU;QACxB,OAAO,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,KAAK,CAAC,eAAe;QACpB,OAAO,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,eAAe,EAAE,CAAC;IAC1D,CAAC;IACD,KAAK,CAAC,cAAc;QACnB,OAAO,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC;IACzD,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC7B,IAAI,CAAC,oBAAoB,KAAK,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7G,OAAO,IAAI,CAAC,oBAAoB,CAAC;IAClC,CAAC;IAEO,KAAK,CAAC,aAAa;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBAAE,OAAO,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO,MAAM,EAAE,CAAC;IACjB,CAAC;IAEO,aAAa,CACpB,WAAsF;QAEtF,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACjD,MAAM,KAAK,GAAG,WAAW,CAAC;gBACzB,EAAE,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE;gBAC9B,QAAQ,EAAE,IAAI,CAAC,MAAM;gBACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACnC,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACnD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC;YACtC,OAAO,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,IAAI,CAC/B,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,OAAO,SAAS,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,MAAqB;QAC5C,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,YAAY,CAAC,WAAW,EAAE,SAAS,MAAM,YAAY,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE;YAClC,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QACpD,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC7B,WAAsF;QAEtF,OAAO,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAqB;QACxC,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,SAAS;YACf,OAAO;SACP,CAAwB,CAC1B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,aAAqB;QACpD,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,uBAAuB;YAC7B,aAAa;SACb,CAAoC,CACtC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAAgB,EAAE,OAAe;QACxD,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,cAAc;YACpB,QAAQ;YACR,OAAO;SACP,CAA4B,CAC9B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,eAAyB;QACtD,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,qBAAqB;YAC3B,eAAe,EAAE,CAAC,GAAG,eAAe,CAAC;SACrC,CAAkC,CACpC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CACrB,OAAe,EACf,gBAAoC,EACpC,YAAoB,EACpB,OAAW,EACX,QAAkB,EAClB,KAAa,EACb,YAA6B;QAE7B,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,YAAY;YAClB,OAAO;YACP,gBAAgB;YAChB,YAAY;YACZ,YAAY;YACZ,OAAO;YACP,KAAK;YACL,QAAQ;SACR,CAA8B,CAChC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,UAAkB,EAAE,IAAc;QACzD,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,QAAQ;YACd,UAAU;YACV,IAAI;SACJ,CAAuB,CACzB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,wBAAwB,CAC7B,UAAkB,EAClB,OAAgD,EAChD,OAAgB,EAChB,OAAW;QAEX,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,gBAAgB;YACtB,UAAU;YACV,OAAO;YACP,OAAO;YACP,OAAO;SACP,CAAiC,CACnC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,KAAyB;QAC5D,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,YAAY,CAAC,WAAW,EAAE,SAAS,QAAQ,YAAY,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,OAAO;YACb,QAAQ;YACR,KAAK;SACL,CAAsB,CACxB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,IAAY;QACnC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,cAAc;YACpB,IAAI,EAAE,aAAa;SACnB,CAA4B,CAC9B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CACX,OAAsB,EACtB,OAAmF;QAEnF,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,YAAY,CAAC,WAAW,EAAE,SAAS,OAAO,YAAY,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAC/B,OAAO,IAAI,CAAC,gBAAgB,CAC3B,CAAC,IAAI,EAAE,EAAE,CACR,CAAC;YACA,GAAG,IAAI;YACP,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,OAAO,IAAI,MAAM;YACzB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC1B,CAA8B,CAChC,CAAC;IACH,CAAC;CACD;AAED,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,KAAmD,EACnD,MAAgC,EAChC,mBAAmB,GAA+B,EAAE;IAEpD,OAAO,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAC/F,CAAC","sourcesContent":["import { type ImageContent, type TextContent, type Usage, uuidv7 } from \"@earendil-works/pi-ai\";\nimport type { AgentMessage } from \"../../types.ts\";\nimport { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage } from \"../messages.ts\";\nimport type {\n\tActiveToolsChangeEntry,\n\tBranchSummaryEntry,\n\tCompactionEntry,\n\tCustomEntry,\n\tCustomMessageEntry,\n\tLabelEntry,\n\tLeafEntry,\n\tMessageEntry,\n\tModelChangeEntry,\n\tSessionContext,\n\tSessionEntryCursorOptions,\n\tSessionInfoEntry,\n\tSessionMetadata,\n\tSessionReader,\n\tSessionStats,\n\tSessionStore,\n\tSessionTreeEntry,\n\tThinkingLevelChangeEntry,\n} from \"../types.ts\";\nimport { SessionError } from \"../types.ts\";\n\nexport type ContextEntryTransform = (entries: readonly SessionTreeEntry[]) => readonly SessionTreeEntry[];\n\nexport type CustomEntryContextMessageProjector = (\n\tentry: CustomEntry,\n\tindex: number,\n\tentries: readonly SessionTreeEntry[],\n) => readonly AgentMessage[] | undefined;\n\nexport interface SessionContextBuildOptions {\n\t/** Additional entry transforms applied after the default compaction transform. */\n\tentryTransforms?: readonly ContextEntryTransform[];\n\t/** Optional custom-entry projectors. Custom entries are omitted from model context by default. */\n\tentryProjectors?: Readonly<Record<string, CustomEntryContextMessageProjector>>;\n}\n\nfunction deriveSessionContextState(pathEntries: readonly SessionTreeEntry[]): Omit<SessionContext, \"messages\"> {\n\tlet thinkingLevel = \"off\";\n\tlet model: { provider: string; modelId: string } | null = null;\n\tlet activeToolNames: string[] | null = null;\n\n\tfor (const entry of pathEntries) {\n\t\tif (entry.type === \"thinking_level_change\") {\n\t\t\tthinkingLevel = entry.thinkingLevel;\n\t\t} else if (entry.type === \"model_change\") {\n\t\t\tmodel = { provider: entry.provider, modelId: entry.modelId };\n\t\t} else if (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tmodel = { provider: entry.message.provider, modelId: entry.message.model };\n\t\t} else if (entry.type === \"active_tools_change\") {\n\t\t\tactiveToolNames = [...entry.activeToolNames];\n\t\t}\n\t}\n\n\treturn { thinkingLevel, model, activeToolNames };\n}\n\nexport function defaultContextEntryTransform(pathEntries: readonly SessionTreeEntry[]): SessionTreeEntry[] {\n\tlet compaction: CompactionEntry | null = null;\n\tfor (const entry of pathEntries) {\n\t\tif (entry.type === \"compaction\") {\n\t\t\tcompaction = entry;\n\t\t}\n\t}\n\tif (!compaction) {\n\t\treturn [...pathEntries];\n\t}\n\n\tconst entries: SessionTreeEntry[] = [compaction];\n\tconst compactionIdx = pathEntries.findIndex((entry) => entry.type === \"compaction\" && entry.id === compaction.id);\n\tif (compaction.retainedTail) {\n\t\tfor (let i = compactionIdx + 1; i < pathEntries.length; i++) {\n\t\t\tentries.push(pathEntries[i]!);\n\t\t}\n\t\treturn entries;\n\t}\n\tif (compaction.firstKeptEntryId) {\n\t\tlet foundFirstKept = false;\n\t\tfor (let i = 0; i < compactionIdx; i++) {\n\t\t\tconst entry = pathEntries[i]!;\n\t\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\t\tif (foundFirstKept) entries.push(entry);\n\t\t}\n\t}\n\tfor (let i = compactionIdx + 1; i < pathEntries.length; i++) {\n\t\tentries.push(pathEntries[i]!);\n\t}\n\treturn entries;\n}\n\nexport function buildContextEntries(\n\tpathEntries: readonly SessionTreeEntry[],\n\toptions: SessionContextBuildOptions = {},\n): SessionTreeEntry[] {\n\tlet entries = defaultContextEntryTransform(pathEntries);\n\tfor (const transform of options.entryTransforms ?? []) {\n\t\tentries = [...transform(entries)];\n\t}\n\treturn entries;\n}\n\nexport function sessionEntryToContextMessages(\n\tentry: SessionTreeEntry,\n\tindex: number,\n\tentries: readonly SessionTreeEntry[],\n\toptions: SessionContextBuildOptions = {},\n): AgentMessage[] {\n\tif (entry.type === \"message\") {\n\t\treturn [entry.message as AgentMessage];\n\t}\n\tif (entry.type === \"custom_message\") {\n\t\treturn [\n\t\t\tcreateCustomMessage(\n\t\t\t\tentry.customType,\n\t\t\t\tentry.content as string | (TextContent | ImageContent)[],\n\t\t\t\tentry.display,\n\t\t\t\tentry.details,\n\t\t\t\tentry.timestamp,\n\t\t\t),\n\t\t];\n\t}\n\tif (entry.type === \"compaction\") {\n\t\treturn [\n\t\t\tcreateCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp),\n\t\t\t...(entry.retainedTail ?? []),\n\t\t];\n\t}\n\tif (entry.type === \"branch_summary\" && entry.summary) {\n\t\treturn [createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp)];\n\t}\n\tif (entry.type === \"custom\") {\n\t\treturn [...(options.entryProjectors?.[entry.customType]?.(entry, index, entries) ?? [])];\n\t}\n\treturn [];\n}\n\nexport function buildSessionContext(\n\tpathEntries: readonly SessionTreeEntry[],\n\toptions: SessionContextBuildOptions = {},\n): SessionContext {\n\tconst state = deriveSessionContextState(pathEntries);\n\tconst contextEntries = buildContextEntries(pathEntries, options);\n\tconst messages = contextEntries.flatMap((entry, index) =>\n\t\tsessionEntryToContextMessages(entry, index, contextEntries, options),\n\t);\n\treturn { ...state, messages };\n}\n\nclass HydratedSessionState {\n\tprivate readonly entries: SessionTreeEntry[];\n\tprivate readonly labelsById = new Map<string, string>();\n\n\tconstructor(entries: readonly SessionTreeEntry[]) {\n\t\tthis.entries = [...entries];\n\t\tfor (const entry of this.entries) this.applyProjection(entry);\n\t}\n\n\tgetLabel(id: string): string | undefined {\n\t\treturn this.labelsById.get(id);\n\t}\n\n\tgetSessionName(): string | undefined {\n\t\tfor (let i = this.entries.length - 1; i >= 0; i--) {\n\t\t\tconst entry = this.entries[i]!;\n\t\t\tif (entry.type === \"session_info\") return entry.name?.trim() || undefined;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tgetSessionStats(): SessionStats {\n\t\tlet messageCount = 0;\n\t\tlet cachedTokens = 0;\n\t\tlet uncachedTokens = 0;\n\t\tlet totalTokens = 0;\n\t\tlet costTotal = 0;\n\t\tfor (const entry of this.entries) {\n\t\t\tif (entry.type === \"message\") messageCount += 1;\n\t\t\tconst usage =\n\t\t\t\tentry.type === \"message\"\n\t\t\t\t\t? entry.message.role === \"assistant\"\n\t\t\t\t\t\t? entry.message.usage\n\t\t\t\t\t\t: undefined\n\t\t\t\t\t: entry.type === \"compaction\" || entry.type === \"branch_summary\"\n\t\t\t\t\t\t? entry.usage\n\t\t\t\t\t\t: undefined;\n\t\t\tif (\n\t\t\t\t!usage ||\n\t\t\t\ttypeof usage.input !== \"number\" ||\n\t\t\t\ttypeof usage.output !== \"number\" ||\n\t\t\t\ttypeof usage.cacheRead !== \"number\" ||\n\t\t\t\ttypeof usage.cacheWrite !== \"number\" ||\n\t\t\t\ttypeof usage.cost?.total !== \"number\"\n\t\t\t)\n\t\t\t\tcontinue;\n\t\t\tcachedTokens += usage.cacheRead;\n\t\t\tuncachedTokens += usage.input + usage.cacheWrite;\n\t\t\ttotalTokens += usage.input + usage.output + usage.cacheRead + usage.cacheWrite;\n\t\t\tcostTotal += usage.cost.total;\n\t\t}\n\t\treturn { messageCount, cachedTokens, uncachedTokens, totalTokens, costTotal };\n\t}\n\n\tprivate applyProjection(entry: SessionTreeEntry): void {\n\t\tif (entry.type !== \"label\") return;\n\t\tconst label = entry.label?.trim();\n\t\tif (label) this.labelsById.set(entry.targetId, label);\n\t\telse this.labelsById.delete(entry.targetId);\n\t}\n}\n\nexport interface Session<TMetadata extends SessionMetadata = SessionMetadata> {\n\tgetMetadata(): Promise<TMetadata>;\n\tgetLeafId(): Promise<string | null>;\n\tgetEntry(id: string): Promise<SessionTreeEntry | undefined>;\n\tgetEntries(options?: SessionEntryCursorOptions): Promise<SessionTreeEntry[]>;\n\tgetBranch(fromId?: string | null): Promise<SessionTreeEntry[]>;\n\tbuildContextEntries(options?: SessionContextBuildOptions): Promise<SessionTreeEntry[]>;\n\tbuildContext(options?: SessionContextBuildOptions): Promise<SessionContext>;\n\tgetLabel(id: string): Promise<string | undefined>;\n\tgetSessionStats(): Promise<SessionStats>;\n\tgetSessionName(): Promise<string | undefined>;\n\tappendMessage(message: AgentMessage): Promise<string>;\n\tappendThinkingLevelChange(thinkingLevel: string): Promise<string>;\n\tappendModelChange(provider: string, modelId: string): Promise<string>;\n\tappendActiveToolsChange(activeToolNames: string[]): Promise<string>;\n\tappendCompaction<T = unknown>(\n\t\tsummary: string,\n\t\tfirstKeptEntryId: string | undefined,\n\t\ttokensBefore: number,\n\t\tdetails?: T,\n\t\tfromHook?: boolean,\n\t\tusage?: Usage,\n\t\tretainedTail?: AgentMessage[],\n\t): Promise<string>;\n\tappendCustomEntry(customType: string, data?: unknown): Promise<string>;\n\tappendCustomMessageEntry<T = unknown>(\n\t\tcustomType: string,\n\t\tcontent: string | (TextContent | ImageContent)[],\n\t\tdisplay: boolean,\n\t\tdetails?: T,\n\t): Promise<string>;\n\tappendLabel(targetId: string, label: string | undefined): Promise<string>;\n\tappendSessionName(name: string): Promise<string>;\n\tmoveTo(\n\t\tentryId: string | null,\n\t\tsummary?: { summary: string; details?: unknown; usage?: Usage; fromHook?: boolean },\n\t): Promise<string | undefined>;\n}\n\nclass StoreSession<TMetadata extends SessionMetadata = SessionMetadata> implements Session<TMetadata> {\n\tprivate readonly store: Pick<SessionStore<TMetadata>, \"appendEntry\">;\n\tprivate readonly reader: SessionReader<TMetadata>;\n\tprivate readonly metadata: TMetadata;\n\tprivate hydratedStatePromise: Promise<HydratedSessionState> | undefined;\n\tprivate leafId: string | null;\n\tprivate readonly contextBuildOptions: SessionContextBuildOptions;\n\tprivate appendTail: Promise<void> = Promise.resolve();\n\n\tconstructor(\n\t\tstore: Pick<SessionStore<TMetadata>, \"appendEntry\">,\n\t\treader: SessionReader<TMetadata>,\n\t\tleafId: string | null,\n\t\tcontextBuildOptions: SessionContextBuildOptions = {},\n\t) {\n\t\tthis.store = store;\n\t\tthis.reader = reader;\n\t\tthis.metadata = reader.metadata;\n\t\tthis.leafId = leafId;\n\t\tthis.contextBuildOptions = contextBuildOptions;\n\t}\n\n\tasync getMetadata(): Promise<TMetadata> {\n\t\treturn this.metadata;\n\t}\n\tasync getLeafId(): Promise<string | null> {\n\t\treturn this.leafId;\n\t}\n\tasync getEntry(id: string): Promise<SessionTreeEntry | undefined> {\n\t\treturn this.reader.readEntry(id);\n\t}\n\tasync getEntries(options?: SessionEntryCursorOptions): Promise<SessionTreeEntry[]> {\n\t\treturn [...(await this.reader.readEntries(options))];\n\t}\n\n\tasync getBranch(fromId?: string | null): Promise<SessionTreeEntry[]> {\n\t\treturn [...(await this.reader.readPathToRootOrCompaction(fromId === undefined ? this.leafId : fromId))];\n\t}\n\n\tasync buildContextEntries(options: SessionContextBuildOptions = {}): Promise<SessionTreeEntry[]> {\n\t\treturn buildContextEntries(await this.getBranch(), this.mergeContextBuildOptions(options));\n\t}\n\n\tasync buildContext(options: SessionContextBuildOptions = {}): Promise<SessionContext> {\n\t\treturn buildSessionContext(await this.getBranch(), this.mergeContextBuildOptions(options));\n\t}\n\n\tprivate mergeContextBuildOptions(options: SessionContextBuildOptions): SessionContextBuildOptions {\n\t\treturn {\n\t\t\tentryTransforms: [...(this.contextBuildOptions.entryTransforms ?? []), ...(options.entryTransforms ?? [])],\n\t\t\tentryProjectors: {\n\t\t\t\t...(this.contextBuildOptions.entryProjectors ?? {}),\n\t\t\t\t...(options.entryProjectors ?? {}),\n\t\t\t},\n\t\t};\n\t}\n\n\tasync getLabel(id: string): Promise<string | undefined> {\n\t\treturn (await this.getHydratedState()).getLabel(id);\n\t}\n\tasync getSessionStats(): Promise<SessionStats> {\n\t\treturn (await this.getHydratedState()).getSessionStats();\n\t}\n\tasync getSessionName(): Promise<string | undefined> {\n\t\treturn (await this.getHydratedState()).getSessionName();\n\t}\n\n\tprivate async getHydratedState(): Promise<HydratedSessionState> {\n\t\tthis.hydratedStatePromise ??= this.reader.readEntries().then((entries) => new HydratedSessionState(entries));\n\t\treturn this.hydratedStatePromise;\n\t}\n\n\tprivate async createEntryId(): Promise<string> {\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tconst id = uuidv7().slice(-8);\n\t\t\tif (!(await this.getEntry(id))) return id;\n\t\t}\n\t\treturn uuidv7();\n\t}\n\n\tprivate enqueueAppend<TEntry extends SessionTreeEntry>(\n\t\tcreateEntry: (base: Pick<SessionTreeEntry, \"id\" | \"parentId\" | \"timestamp\">) => TEntry,\n\t): Promise<TEntry> {\n\t\tconst operation = this.appendTail.then(async () => {\n\t\t\tconst entry = createEntry({\n\t\t\t\tid: await this.createEntryId(),\n\t\t\t\tparentId: this.leafId,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tawait this.store.appendEntry(this.metadata, entry);\n\t\t\tthis.leafId = entry.type === \"leaf\" ? entry.targetId : entry.id;\n\t\t\tthis.hydratedStatePromise = undefined;\n\t\t\treturn entry;\n\t\t});\n\t\tthis.appendTail = operation.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn operation;\n\t}\n\n\tprivate async setLeafId(leafId: string | null): Promise<LeafEntry> {\n\t\tif (leafId !== null && !(await this.getEntry(leafId))) {\n\t\t\tthrow new SessionError(\"not_found\", `Entry ${leafId} not found`);\n\t\t}\n\t\treturn this.enqueueAppend((base) => {\n\t\t\treturn { ...base, type: \"leaf\", targetId: leafId };\n\t\t});\n\t}\n\n\tprivate async appendTypedEntry<TEntry extends SessionTreeEntry>(\n\t\tcreateEntry: (base: Pick<SessionTreeEntry, \"id\" | \"parentId\" | \"timestamp\">) => TEntry,\n\t): Promise<string> {\n\t\treturn (await this.enqueueAppend(createEntry)).id;\n\t}\n\n\tasync appendMessage(message: AgentMessage): Promise<string> {\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"message\",\n\t\t\t\t\tmessage,\n\t\t\t\t}) satisfies MessageEntry,\n\t\t);\n\t}\n\n\tasync appendThinkingLevelChange(thinkingLevel: string): Promise<string> {\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"thinking_level_change\",\n\t\t\t\t\tthinkingLevel,\n\t\t\t\t}) satisfies ThinkingLevelChangeEntry,\n\t\t);\n\t}\n\n\tasync appendModelChange(provider: string, modelId: string): Promise<string> {\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"model_change\",\n\t\t\t\t\tprovider,\n\t\t\t\t\tmodelId,\n\t\t\t\t}) satisfies ModelChangeEntry,\n\t\t);\n\t}\n\n\tasync appendActiveToolsChange(activeToolNames: string[]): Promise<string> {\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"active_tools_change\",\n\t\t\t\t\tactiveToolNames: [...activeToolNames],\n\t\t\t\t}) satisfies ActiveToolsChangeEntry,\n\t\t);\n\t}\n\n\tasync appendCompaction<T = unknown>(\n\t\tsummary: string,\n\t\tfirstKeptEntryId: string | undefined,\n\t\ttokensBefore: number,\n\t\tdetails?: T,\n\t\tfromHook?: boolean,\n\t\tusage?: Usage,\n\t\tretainedTail?: AgentMessage[],\n\t): Promise<string> {\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"compaction\",\n\t\t\t\t\tsummary,\n\t\t\t\t\tfirstKeptEntryId,\n\t\t\t\t\ttokensBefore,\n\t\t\t\t\tretainedTail,\n\t\t\t\t\tdetails,\n\t\t\t\t\tusage,\n\t\t\t\t\tfromHook,\n\t\t\t\t}) satisfies CompactionEntry<T>,\n\t\t);\n\t}\n\n\tasync appendCustomEntry(customType: string, data?: unknown): Promise<string> {\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"custom\",\n\t\t\t\t\tcustomType,\n\t\t\t\t\tdata,\n\t\t\t\t}) satisfies CustomEntry,\n\t\t);\n\t}\n\n\tasync appendCustomMessageEntry<T = unknown>(\n\t\tcustomType: string,\n\t\tcontent: string | (TextContent | ImageContent)[],\n\t\tdisplay: boolean,\n\t\tdetails?: T,\n\t): Promise<string> {\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"custom_message\",\n\t\t\t\t\tcustomType,\n\t\t\t\t\tcontent,\n\t\t\t\t\tdisplay,\n\t\t\t\t\tdetails,\n\t\t\t\t}) satisfies CustomMessageEntry<T>,\n\t\t);\n\t}\n\n\tasync appendLabel(targetId: string, label: string | undefined): Promise<string> {\n\t\tif (!(await this.getEntry(targetId))) {\n\t\t\tthrow new SessionError(\"not_found\", `Entry ${targetId} not found`);\n\t\t}\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"label\",\n\t\t\t\t\ttargetId,\n\t\t\t\t\tlabel,\n\t\t\t\t}) satisfies LabelEntry,\n\t\t);\n\t}\n\n\tasync appendSessionName(name: string): Promise<string> {\n\t\tconst sanitizedName = name.replace(/[\\r\\n]+/g, \" \").trim();\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"session_info\",\n\t\t\t\t\tname: sanitizedName,\n\t\t\t\t}) satisfies SessionInfoEntry,\n\t\t);\n\t}\n\n\tasync moveTo(\n\t\tentryId: string | null,\n\t\tsummary?: { summary: string; details?: unknown; usage?: Usage; fromHook?: boolean },\n\t): Promise<string | undefined> {\n\t\tif (entryId !== null && !(await this.getEntry(entryId))) {\n\t\t\tthrow new SessionError(\"not_found\", `Entry ${entryId} not found`);\n\t\t}\n\t\tawait this.setLeafId(entryId);\n\t\tif (!summary) return undefined;\n\t\treturn this.appendTypedEntry(\n\t\t\t(base) =>\n\t\t\t\t({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: \"branch_summary\",\n\t\t\t\t\tfromId: entryId ?? \"root\",\n\t\t\t\t\tsummary: summary.summary,\n\t\t\t\t\tdetails: summary.details,\n\t\t\t\t\tusage: summary.usage,\n\t\t\t\t\tfromHook: summary.fromHook,\n\t\t\t\t}) satisfies BranchSummaryEntry,\n\t\t);\n\t}\n}\n\n/** @internal Construct sessions only through SessionRepository. */\nexport async function createSessionFromReader<TMetadata extends SessionMetadata>(\n\tstore: Pick<SessionStore<TMetadata>, \"appendEntry\">,\n\treader: SessionReader<TMetadata>,\n\tcontextBuildOptions: SessionContextBuildOptions = {},\n): Promise<Session<TMetadata>> {\n\treturn new StoreSession(store, reader, (await reader.readHead()).leafId, contextBuildOptions);\n}\n"]}
|