@code-yeongyu/senpi-agent-core 2026.8.12 → 2026.8.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/README.md +13 -7
  2. package/dist/agent-loop.js +5 -1
  3. package/dist/agent-loop.js.map +1 -1
  4. package/dist/agent.d.ts +3 -1
  5. package/dist/agent.d.ts.map +1 -1
  6. package/dist/agent.js +8 -0
  7. package/dist/agent.js.map +1 -1
  8. package/dist/harness/agent-harness.d.ts +452 -96
  9. package/dist/harness/agent-harness.d.ts.map +1 -1
  10. package/dist/harness/agent-harness.js +162 -1005
  11. package/dist/harness/agent-harness.js.map +1 -1
  12. package/dist/harness/compaction/branch-summarization.d.ts +13 -6
  13. package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
  14. package/dist/harness/compaction/branch-summarization.js +10 -14
  15. package/dist/harness/compaction/branch-summarization.js.map +1 -1
  16. package/dist/harness/compaction/compaction.d.ts +14 -17
  17. package/dist/harness/compaction/compaction.d.ts.map +1 -1
  18. package/dist/harness/compaction/compaction.js +23 -36
  19. package/dist/harness/compaction/compaction.js.map +1 -1
  20. package/dist/harness/env/nodejs.d.ts +1 -0
  21. package/dist/harness/env/nodejs.d.ts.map +1 -1
  22. package/dist/harness/env/nodejs.js +23 -7
  23. package/dist/harness/env/nodejs.js.map +1 -1
  24. package/dist/harness/messages.d.ts +3 -3
  25. package/dist/harness/messages.d.ts.map +1 -1
  26. package/dist/harness/messages.js +3 -3
  27. package/dist/harness/messages.js.map +1 -1
  28. package/dist/harness/prompt-templates.d.ts.map +1 -1
  29. package/dist/harness/prompt-templates.js +4 -9
  30. package/dist/harness/prompt-templates.js.map +1 -1
  31. package/dist/harness/reducer.d.ts +100 -0
  32. package/dist/harness/reducer.d.ts.map +1 -0
  33. package/dist/harness/reducer.js +414 -0
  34. package/dist/harness/reducer.js.map +1 -0
  35. package/dist/harness/result.d.ts +40 -0
  36. package/dist/harness/result.d.ts.map +1 -0
  37. package/dist/harness/result.js +41 -0
  38. package/dist/harness/result.js.map +1 -0
  39. package/dist/harness/session/context.d.ts +22 -0
  40. package/dist/harness/session/context.d.ts.map +1 -0
  41. package/dist/harness/session/context.js +67 -0
  42. package/dist/harness/session/context.js.map +1 -0
  43. package/dist/harness/session/index.d.ts +7 -0
  44. package/dist/harness/session/index.d.ts.map +1 -0
  45. package/dist/harness/session/index.js +6 -0
  46. package/dist/harness/session/index.js.map +1 -0
  47. package/dist/harness/session/jsonl/codec.d.ts +8 -0
  48. package/dist/harness/session/jsonl/codec.d.ts.map +1 -0
  49. package/dist/harness/session/jsonl/codec.js +190 -0
  50. package/dist/harness/session/jsonl/codec.js.map +1 -0
  51. package/dist/harness/session/jsonl/errors.d.ts +5 -0
  52. package/dist/harness/session/jsonl/errors.d.ts.map +1 -0
  53. package/dist/harness/session/jsonl/errors.js +11 -0
  54. package/dist/harness/session/jsonl/errors.js.map +1 -0
  55. package/dist/harness/session/jsonl/repo.d.ts +23 -0
  56. package/dist/harness/session/jsonl/repo.d.ts.map +1 -0
  57. package/dist/harness/session/jsonl/repo.js +129 -0
  58. package/dist/harness/session/jsonl/repo.js.map +1 -0
  59. package/dist/harness/session/jsonl/storage.d.ts +43 -0
  60. package/dist/harness/session/jsonl/storage.d.ts.map +1 -0
  61. package/dist/harness/session/jsonl/storage.js +206 -0
  62. package/dist/harness/session/jsonl/storage.js.map +1 -0
  63. package/dist/harness/session/jsonl/types.d.ts +38 -0
  64. package/dist/harness/session/jsonl/types.d.ts.map +1 -0
  65. package/dist/harness/session/jsonl/types.js +2 -0
  66. package/dist/harness/session/jsonl/types.js.map +1 -0
  67. package/dist/harness/session/jsonl.d.ts +3 -0
  68. package/dist/harness/session/jsonl.d.ts.map +1 -0
  69. package/dist/harness/session/jsonl.js +2 -0
  70. package/dist/harness/session/jsonl.js.map +1 -0
  71. package/dist/harness/session/memory.d.ts +44 -0
  72. package/dist/harness/session/memory.d.ts.map +1 -0
  73. package/dist/harness/session/memory.js +142 -0
  74. package/dist/harness/session/memory.js.map +1 -0
  75. package/dist/harness/session/search.d.ts +19 -0
  76. package/dist/harness/session/search.d.ts.map +1 -0
  77. package/dist/harness/session/search.js +41 -0
  78. package/dist/harness/session/search.js.map +1 -0
  79. package/dist/harness/session/session.d.ts +43 -38
  80. package/dist/harness/session/session.d.ts.map +1 -1
  81. package/dist/harness/session/session.js +186 -304
  82. package/dist/harness/session/session.js.map +1 -1
  83. package/dist/harness/session/state.d.ts +65 -0
  84. package/dist/harness/session/state.d.ts.map +1 -0
  85. package/dist/harness/session/state.js +320 -0
  86. package/dist/harness/session/state.js.map +1 -0
  87. package/dist/harness/session/testing/conformance.d.ts +4 -0
  88. package/dist/harness/session/testing/conformance.d.ts.map +1 -0
  89. package/dist/harness/session/testing/conformance.js +743 -0
  90. package/dist/harness/session/testing/conformance.js.map +1 -0
  91. package/dist/harness/session/testing/index.d.ts +3 -0
  92. package/dist/harness/session/testing/index.d.ts.map +1 -0
  93. package/dist/harness/session/testing/index.js +2 -0
  94. package/dist/harness/session/testing/index.js.map +1 -0
  95. package/dist/harness/session/testing/types.d.ts +14 -0
  96. package/dist/harness/session/testing/types.d.ts.map +1 -0
  97. package/dist/harness/session/testing/types.js +2 -0
  98. package/dist/harness/session/testing/types.js.map +1 -0
  99. package/dist/harness/session/types.d.ts +333 -0
  100. package/dist/harness/session/types.d.ts.map +1 -0
  101. package/dist/harness/session/types.js +9 -0
  102. package/dist/harness/session/types.js.map +1 -0
  103. package/dist/harness/skills.js +21 -19
  104. package/dist/harness/skills.js.map +1 -1
  105. package/dist/harness/telemetry.d.ts +1221 -0
  106. package/dist/harness/telemetry.d.ts.map +1 -0
  107. package/dist/harness/telemetry.js +508 -0
  108. package/dist/harness/telemetry.js.map +1 -0
  109. package/dist/harness/types.d.ts +8 -485
  110. package/dist/harness/types.d.ts.map +1 -1
  111. package/dist/harness/types.js +4 -16
  112. package/dist/harness/types.js.map +1 -1
  113. package/dist/harness/utils/truncate.js.map +1 -1
  114. package/dist/index.d.ts +10 -9
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +7 -8
  117. package/dist/index.js.map +1 -1
  118. package/dist/proxy.d.ts +1 -1
  119. package/dist/proxy.d.ts.map +1 -1
  120. package/dist/proxy.js +1 -0
  121. package/dist/proxy.js.map +1 -1
  122. package/dist/types.d.ts +6 -0
  123. package/dist/types.d.ts.map +1 -1
  124. package/dist/types.js.map +1 -1
  125. package/package.json +9 -2
  126. package/dist/harness/session/array-session-reader.d.ts +0 -3
  127. package/dist/harness/session/array-session-reader.d.ts.map +0 -1
  128. package/dist/harness/session/array-session-reader.js +0 -70
  129. package/dist/harness/session/array-session-reader.js.map +0 -1
  130. package/dist/harness/session/fork.d.ts +0 -4
  131. package/dist/harness/session/fork.d.ts.map +0 -1
  132. package/dist/harness/session/fork.js +0 -22
  133. package/dist/harness/session/fork.js.map +0 -1
  134. package/dist/harness/session/jsonl-store.d.ts +0 -13
  135. package/dist/harness/session/jsonl-store.d.ts.map +0 -1
  136. package/dist/harness/session/jsonl-store.js +0 -304
  137. package/dist/harness/session/jsonl-store.js.map +0 -1
  138. package/dist/harness/session/keyed-operation-queue.d.ts +0 -17
  139. package/dist/harness/session/keyed-operation-queue.d.ts.map +0 -1
  140. package/dist/harness/session/keyed-operation-queue.js +0 -60
  141. package/dist/harness/session/keyed-operation-queue.js.map +0 -1
  142. package/dist/harness/session/memory-store.d.ts +0 -6
  143. package/dist/harness/session/memory-store.d.ts.map +0 -1
  144. package/dist/harness/session/memory-store.js +0 -107
  145. package/dist/harness/session/memory-store.js.map +0 -1
  146. package/dist/harness/session/repository.d.ts +0 -28
  147. package/dist/harness/session/repository.d.ts.map +0 -1
  148. package/dist/harness/session/repository.js +0 -61
  149. package/dist/harness/session/repository.js.map +0 -1
  150. package/dist/harness/session/search-backend.d.ts +0 -8
  151. package/dist/harness/session/search-backend.d.ts.map +0 -1
  152. package/dist/harness/session/search-backend.js +0 -22
  153. package/dist/harness/session/search-backend.js.map +0 -1
@@ -1,45 +1,50 @@
1
- import { type ImageContent, type TextContent, type Usage } from "@earendil-works/pi-ai";
2
1
  import type { AgentMessage } from "../../types.ts";
3
- import type { CustomEntry, SessionContext, SessionEntryCursorOptions, SessionMetadata, SessionReader, SessionStats, SessionStore, SessionTreeEntry } from "../types.ts";
4
- export type ContextEntryTransform = (entries: readonly SessionTreeEntry[]) => readonly SessionTreeEntry[];
5
- export type CustomEntryContextMessageProjector = (entry: CustomEntry, index: number, entries: readonly SessionTreeEntry[]) => readonly AgentMessage[] | undefined;
6
- export interface SessionContextBuildOptions {
7
- /** Additional entry transforms applied after the default compaction transform. */
8
- entryTransforms?: readonly ContextEntryTransform[];
9
- /** Optional custom-entry projectors. Custom entries are omitted from model context by default. */
10
- entryProjectors?: Readonly<Record<string, CustomEntryContextMessageProjector>>;
11
- }
12
- export declare function defaultContextEntryTransform(pathEntries: readonly SessionTreeEntry[]): SessionTreeEntry[];
13
- export declare function buildContextEntries(pathEntries: readonly SessionTreeEntry[], options?: SessionContextBuildOptions): SessionTreeEntry[];
14
- export declare function sessionEntryToContextMessages(entry: SessionTreeEntry, index: number, entries: readonly SessionTreeEntry[], options?: SessionContextBuildOptions): AgentMessage[];
15
- export declare function buildSessionContext(pathEntries: readonly SessionTreeEntry[], options?: SessionContextBuildOptions): SessionContext;
16
- export interface Session<TMetadata extends SessionMetadata = SessionMetadata> {
2
+ import type { BranchBounds, Entry, EntryQuery, IdGenerator, LanePointer, LaneRecord, LogItem, LogOptions, NewRecord, OperationStartedRecord, ProvisionedEntry, RecordBase, RecordQuery, SessionMetadata, SessionStats, SessionStorage, SessionTree } from "./types.ts";
3
+ export declare function assertJsonSerializable(value: unknown): void;
4
+ export declare class Session<TMetadata extends SessionMetadata = SessionMetadata> implements SessionTree {
5
+ private readonly storage;
6
+ readonly idGenerator: IdGenerator;
7
+ constructor(storage: SessionStorage<TMetadata>, options?: {
8
+ idGenerator?: IdGenerator;
9
+ });
17
10
  getMetadata(): Promise<TMetadata>;
11
+ view(lane: string): SessionTree;
18
12
  getLeafId(): Promise<string | null>;
19
- getEntry(id: string): Promise<SessionTreeEntry | undefined>;
20
- getEntries(options?: SessionEntryCursorOptions): Promise<SessionTreeEntry[]>;
21
- getBranch(fromId?: string | null): Promise<SessionTreeEntry[]>;
22
- buildContextEntries(options?: SessionContextBuildOptions): Promise<SessionTreeEntry[]>;
23
- buildContext(options?: SessionContextBuildOptions): Promise<SessionContext>;
24
- getLabel(id: string): Promise<string | undefined>;
25
- getSessionStats(): Promise<SessionStats>;
26
- getSessionName(): Promise<string | undefined>;
13
+ getEntry(id: string): Promise<Entry | undefined>;
14
+ getStats(): Promise<SessionStats>;
15
+ getName(): Promise<string | undefined>;
16
+ setName(name: string): Promise<void>;
17
+ getLabel(targetId: string): Promise<string | undefined>;
18
+ setLabel(targetId: string, label: string | undefined): Promise<void>;
19
+ findEntries(query?: EntryQuery): Promise<Entry[]>;
20
+ findEntry(query?: EntryQuery): Promise<Entry | undefined>;
21
+ findEntriesOnBranch(query?: EntryQuery & BranchBounds): Promise<Entry[]>;
22
+ findEntryOnBranch(query?: EntryQuery & BranchBounds): Promise<Entry | undefined>;
27
23
  appendMessage(message: AgentMessage): Promise<string>;
28
- appendThinkingLevelChange(thinkingLevel: string): Promise<string>;
29
- appendModelChange(provider: string, modelId: string): Promise<string>;
30
- appendActiveToolsChange(activeToolNames: string[]): Promise<string>;
31
- appendCompaction<T = unknown>(summary: string, firstKeptEntryId: string | undefined, tokensBefore: number, details?: T, fromHook?: boolean, usage?: Usage, retainedTail?: AgentMessage[]): Promise<string>;
32
24
  appendCustomEntry(customType: string, data?: unknown): Promise<string>;
33
- appendCustomMessageEntry<T = unknown>(customType: string, content: string | (TextContent | ImageContent)[], display: boolean, details?: T): Promise<string>;
34
- appendLabel(targetId: string, label: string | undefined): Promise<string>;
35
- appendSessionName(name: string): Promise<string>;
36
- moveTo(entryId: string | null, summary?: {
37
- summary: string;
38
- details?: unknown;
39
- usage?: Usage;
40
- fromHook?: boolean;
41
- }): Promise<string | undefined>;
25
+ getLanes(): Promise<LanePointer[]>;
26
+ createLane(lane: string, at: string | null): Promise<void>;
27
+ moveLane(lane: string, to: string | null): Promise<void>;
28
+ appendEntry<TEntry extends Entry>(entry: ProvisionedEntry<TEntry>, lane: string): Promise<TEntry>;
29
+ appendRecord<TNewRecord extends NewRecord>(record: TNewRecord): Promise<TNewRecord & Pick<RecordBase, "seq" | "timestamp">>;
30
+ findRecords<K extends LaneRecord["type"]>(query: RecordQuery & {
31
+ type: K;
32
+ }): Promise<Extract<LaneRecord, {
33
+ type: K;
34
+ }>[]>;
35
+ findRecords(query?: RecordQuery): Promise<LaneRecord[]>;
36
+ findOpenOperations(lane: string, options?: {
37
+ limit?: number;
38
+ }): Promise<OperationStartedRecord[]>;
39
+ getLog(options?: LogOptions): Promise<LogItem[]>;
40
+ private getLeafIdForLane;
41
+ private queryEntries;
42
+ private queryBranchEntries;
43
+ private queryRecords;
44
+ private queryLog;
45
+ private appendMessageToLane;
46
+ private appendCustomEntryToLane;
47
+ private commitEntry;
48
+ private commitRecord;
42
49
  }
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>>;
45
50
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/harness/session/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/harness/session/session.ts"],"names":[],"mappings":"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"}
@@ -1,338 +1,220 @@
1
1
  import { uuidv7 } from "@earendil-works/pi-ai";
2
- import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage } from "../messages.js";
3
- import { SessionError } from "../types.js";
4
- function deriveSessionContextState(pathEntries) {
5
- let thinkingLevel = "off";
6
- let model = null;
7
- let activeToolNames = null;
8
- for (const entry of pathEntries) {
9
- if (entry.type === "thinking_level_change") {
10
- thinkingLevel = entry.thinkingLevel;
2
+ import { SessionError } from "./types.js";
3
+ function invalidPayload(reason) {
4
+ throw new SessionError("invalid_payload", `Durable payload ${reason}`);
5
+ }
6
+ function assertValidLimit(limit) {
7
+ if (limit !== undefined && (!Number.isInteger(limit) || limit <= 0)) {
8
+ throw new SessionError("invalid_query", "limit must be a positive integer");
9
+ }
10
+ }
11
+ function assertValidCursor(afterSeq) {
12
+ if (afterSeq !== undefined && (!Number.isInteger(afterSeq) || afterSeq < 0)) {
13
+ throw new SessionError("invalid_query", "cursor sequence must be a non-negative integer");
14
+ }
15
+ }
16
+ export function assertJsonSerializable(value) {
17
+ const active = new WeakSet();
18
+ const stack = [{ value }];
19
+ while (stack.length > 0) {
20
+ const frame = stack.pop();
21
+ if ("exit" in frame) {
22
+ active.delete(frame.exit);
23
+ continue;
11
24
  }
12
- else if (entry.type === "model_change") {
13
- model = { provider: entry.provider, modelId: entry.modelId };
25
+ const candidate = frame.value;
26
+ if (candidate === null || typeof candidate === "string" || typeof candidate === "boolean") {
27
+ continue;
14
28
  }
15
- else if (entry.type === "message" && entry.message.role === "assistant") {
16
- model = { provider: entry.message.provider, modelId: entry.message.model };
29
+ if (typeof candidate === "number") {
30
+ if (!Number.isFinite(candidate))
31
+ invalidPayload("contains a non-finite number");
32
+ continue;
17
33
  }
18
- else if (entry.type === "active_tools_change") {
19
- activeToolNames = [...entry.activeToolNames];
34
+ if (typeof candidate !== "object")
35
+ invalidPayload(`contains ${typeof candidate}`);
36
+ if (active.has(candidate))
37
+ invalidPayload("contains a cycle");
38
+ active.add(candidate);
39
+ stack.push({ exit: candidate });
40
+ if (Array.isArray(candidate)) {
41
+ if (Object.getPrototypeOf(candidate) !== Array.prototype) {
42
+ invalidPayload("contains a non-standard array");
43
+ }
44
+ if (Object.getOwnPropertySymbols(candidate).length > 0 ||
45
+ Object.getOwnPropertyNames(candidate).length !== candidate.length + 1) {
46
+ invalidPayload("contains an array with unsupported properties");
47
+ }
48
+ for (let index = candidate.length - 1; index >= 0; index--) {
49
+ if (!Object.hasOwn(candidate, index))
50
+ invalidPayload("contains a sparse array");
51
+ const descriptor = Object.getOwnPropertyDescriptor(candidate, index);
52
+ if (!("value" in descriptor))
53
+ invalidPayload("contains an array accessor");
54
+ stack.push({ value: descriptor.value });
55
+ }
56
+ continue;
20
57
  }
21
- }
22
- return { thinkingLevel, model, activeToolNames };
23
- }
24
- export function defaultContextEntryTransform(pathEntries) {
25
- let compaction = null;
26
- for (const entry of pathEntries) {
27
- if (entry.type === "compaction") {
28
- compaction = entry;
58
+ const prototype = Object.getPrototypeOf(candidate);
59
+ if (prototype !== Object.prototype && prototype !== null) {
60
+ invalidPayload("contains a non-plain object");
29
61
  }
30
- }
31
- if (!compaction) {
32
- return [...pathEntries];
33
- }
34
- const entries = [compaction];
35
- const compactionIdx = pathEntries.findIndex((entry) => entry.type === "compaction" && entry.id === compaction.id);
36
- if (compaction.retainedTail) {
37
- for (let i = compactionIdx + 1; i < pathEntries.length; i++) {
38
- entries.push(pathEntries[i]);
62
+ if (Object.getOwnPropertySymbols(candidate).length > 0) {
63
+ invalidPayload("contains a symbol-keyed property");
39
64
  }
40
- return entries;
41
- }
42
- if (compaction.firstKeptEntryId) {
43
- let foundFirstKept = false;
44
- for (let i = 0; i < compactionIdx; i++) {
45
- const entry = pathEntries[i];
46
- if (entry.id === compaction.firstKeptEntryId)
47
- foundFirstKept = true;
48
- if (foundFirstKept)
49
- entries.push(entry);
65
+ const keys = Object.keys(candidate);
66
+ if (Object.getOwnPropertyNames(candidate).length !== keys.length) {
67
+ invalidPayload("contains a non-enumerable property");
50
68
  }
51
- }
52
- for (let i = compactionIdx + 1; i < pathEntries.length; i++) {
53
- entries.push(pathEntries[i]);
54
- }
55
- return entries;
56
- }
57
- export function buildContextEntries(pathEntries, options = {}) {
58
- let entries = defaultContextEntryTransform(pathEntries);
59
- for (const transform of options.entryTransforms ?? []) {
60
- entries = [...transform(entries)];
61
- }
62
- return entries;
63
- }
64
- export function sessionEntryToContextMessages(entry, index, entries, options = {}) {
65
- if (entry.type === "message") {
66
- return [entry.message];
67
- }
68
- if (entry.type === "custom_message") {
69
- return [
70
- createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp),
71
- ];
72
- }
73
- if (entry.type === "compaction") {
74
- return [
75
- createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp),
76
- ...(entry.retainedTail ?? []),
77
- ];
78
- }
79
- if (entry.type === "branch_summary" && entry.summary) {
80
- return [createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp)];
81
- }
82
- if (entry.type === "custom") {
83
- return [...(options.entryProjectors?.[entry.customType]?.(entry, index, entries) ?? [])];
84
- }
85
- return [];
86
- }
87
- export function buildSessionContext(pathEntries, options = {}) {
88
- const state = deriveSessionContextState(pathEntries);
89
- const contextEntries = buildContextEntries(pathEntries, options);
90
- const messages = contextEntries.flatMap((entry, index) => sessionEntryToContextMessages(entry, index, contextEntries, options));
91
- return { ...state, messages };
92
- }
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;
69
+ for (let index = keys.length - 1; index >= 0; index--) {
70
+ const descriptor = Object.getOwnPropertyDescriptor(candidate, keys[index]);
71
+ if (!("value" in descriptor))
72
+ invalidPayload("contains an accessor");
73
+ stack.push({ value: descriptor.value });
138
74
  }
139
- return { messageCount, cachedTokens, uncachedTokens, totalTokens, costTotal };
140
- }
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);
149
75
  }
150
76
  }
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;
77
+ export class Session {
78
+ constructor(storage, options = {}) {
79
+ this.storage = storage;
80
+ this.idGenerator = options.idGenerator ?? { next: () => uuidv7() };
159
81
  }
160
82
  async getMetadata() {
161
- return this.metadata;
83
+ return this.storage.getMetadata();
84
+ }
85
+ view(lane) {
86
+ if (lane === "main")
87
+ return this;
88
+ return {
89
+ getLeafId: () => this.getLeafIdForLane(lane),
90
+ getEntry: (id) => this.getEntry(id),
91
+ getStats: () => this.getStats(),
92
+ getName: () => this.getName(),
93
+ setName: (name) => this.setName(name),
94
+ getLabel: (targetId) => this.getLabel(targetId),
95
+ setLabel: (targetId, label) => this.setLabel(targetId, label),
96
+ findEntries: (query) => this.queryEntries(query),
97
+ findEntry: async (query = {}) => (await this.queryEntries(query, 1))[0],
98
+ findEntriesOnBranch: (query) => this.queryBranchEntries(lane, query),
99
+ findEntryOnBranch: async (query = {}) => (await this.queryBranchEntries(lane, query, 1))[0],
100
+ appendMessage: (message) => this.appendMessageToLane(lane, message),
101
+ appendCustomEntry: (customType, data) => this.appendCustomEntryToLane(lane, customType, data),
102
+ };
162
103
  }
163
104
  async getLeafId() {
164
- return this.leafId;
105
+ return this.getLeafIdForLane("main");
165
106
  }
166
107
  async getEntry(id) {
167
- return this.reader.readEntry(id);
108
+ return this.storage.getEntry(id);
168
109
  }
169
- async getEntries(options) {
170
- return [...(await this.reader.readEntries(options))];
110
+ async getStats() {
111
+ return this.storage.getStats();
171
112
  }
172
- async getBranch(fromId) {
173
- return [...(await this.reader.readPathToRootOrCompaction(fromId === undefined ? this.leafId : fromId))];
113
+ async getName() {
114
+ return this.storage.getName();
174
115
  }
175
- async buildContextEntries(options = {}) {
176
- return buildContextEntries(await this.getBranch(), this.mergeContextBuildOptions(options));
116
+ async setName(name) {
117
+ await this.storage.setName(name);
177
118
  }
178
- async buildContext(options = {}) {
179
- return buildSessionContext(await this.getBranch(), this.mergeContextBuildOptions(options));
119
+ async getLabel(targetId) {
120
+ return this.storage.getLabel(targetId);
180
121
  }
181
- mergeContextBuildOptions(options) {
182
- return {
183
- entryTransforms: [...(this.contextBuildOptions.entryTransforms ?? []), ...(options.entryTransforms ?? [])],
184
- entryProjectors: {
185
- ...(this.contextBuildOptions.entryProjectors ?? {}),
186
- ...(options.entryProjectors ?? {}),
187
- },
188
- };
122
+ async setLabel(targetId, label) {
123
+ await this.storage.setLabel(targetId, label);
189
124
  }
190
- async getLabel(id) {
191
- return (await this.getHydratedState()).getLabel(id);
125
+ async findEntries(query) {
126
+ return this.queryEntries(query);
192
127
  }
193
- async getSessionStats() {
194
- return (await this.getHydratedState()).getSessionStats();
128
+ async findEntry(query = {}) {
129
+ return (await this.queryEntries(query, 1))[0];
195
130
  }
196
- async getSessionName() {
197
- return (await this.getHydratedState()).getSessionName();
131
+ async findEntriesOnBranch(query) {
132
+ return this.queryBranchEntries("main", query);
198
133
  }
199
- async getHydratedState() {
200
- this.hydratedStatePromise ??= this.reader.readEntries().then((entries) => new HydratedSessionState(entries));
201
- return this.hydratedStatePromise;
202
- }
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;
134
+ async findEntryOnBranch(query = {}) {
135
+ return (await this.queryBranchEntries("main", query, 1))[0];
236
136
  }
237
137
  async appendMessage(message) {
238
- return this.appendTypedEntry((base) => ({
239
- ...base,
240
- type: "message",
241
- message,
242
- }));
243
- }
244
- async appendThinkingLevelChange(thinkingLevel) {
245
- return this.appendTypedEntry((base) => ({
246
- ...base,
247
- type: "thinking_level_change",
248
- thinkingLevel,
249
- }));
250
- }
251
- async appendModelChange(provider, modelId) {
252
- return this.appendTypedEntry((base) => ({
253
- ...base,
254
- type: "model_change",
255
- provider,
256
- modelId,
257
- }));
258
- }
259
- async appendActiveToolsChange(activeToolNames) {
260
- return this.appendTypedEntry((base) => ({
261
- ...base,
262
- type: "active_tools_change",
263
- activeToolNames: [...activeToolNames],
264
- }));
265
- }
266
- async appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook, usage, retainedTail) {
267
- return this.appendTypedEntry((base) => ({
268
- ...base,
269
- type: "compaction",
270
- summary,
271
- firstKeptEntryId,
272
- tokensBefore,
273
- retainedTail,
274
- details,
275
- usage,
276
- fromHook,
277
- }));
138
+ return this.appendMessageToLane("main", message);
278
139
  }
279
140
  async appendCustomEntry(customType, data) {
280
- return this.appendTypedEntry((base) => ({
281
- ...base,
282
- type: "custom",
283
- customType,
284
- data,
285
- }));
286
- }
287
- async appendCustomMessageEntry(customType, content, display, details) {
288
- return this.appendTypedEntry((base) => ({
289
- ...base,
290
- type: "custom_message",
291
- customType,
292
- content,
293
- display,
294
- details,
295
- }));
296
- }
297
- async appendLabel(targetId, label) {
298
- if (!(await this.getEntry(targetId))) {
299
- throw new SessionError("not_found", `Entry ${targetId} not found`);
300
- }
301
- return this.appendTypedEntry((base) => ({
302
- ...base,
303
- type: "label",
304
- targetId,
305
- label,
306
- }));
307
- }
308
- async appendSessionName(name) {
309
- const sanitizedName = name.replace(/[\r\n]+/g, " ").trim();
310
- return this.appendTypedEntry((base) => ({
311
- ...base,
312
- type: "session_info",
313
- name: sanitizedName,
314
- }));
315
- }
316
- async moveTo(entryId, summary) {
317
- if (entryId !== null && !(await this.getEntry(entryId))) {
318
- throw new SessionError("not_found", `Entry ${entryId} not found`);
141
+ return this.appendCustomEntryToLane("main", customType, data);
142
+ }
143
+ async getLanes() {
144
+ return this.storage.getLanes();
145
+ }
146
+ async createLane(lane, at) {
147
+ await this.storage.createLane(lane, at);
148
+ }
149
+ async moveLane(lane, to) {
150
+ await this.storage.moveLane(lane, to);
151
+ }
152
+ async appendEntry(entry, lane) {
153
+ return this.commitEntry(entry, lane);
154
+ }
155
+ async appendRecord(record) {
156
+ return this.commitRecord(record);
157
+ }
158
+ async findRecords(query) {
159
+ return this.queryRecords(query);
160
+ }
161
+ async findOpenOperations(lane, options) {
162
+ assertValidLimit(options?.limit);
163
+ return this.storage.findOpenOperations(lane, options);
164
+ }
165
+ async getLog(options) {
166
+ return this.queryLog(options);
167
+ }
168
+ async getLeafIdForLane(lane) {
169
+ const pointer = (await this.getLanes()).find((candidate) => candidate.lane === lane);
170
+ if (!pointer)
171
+ throw new SessionError("invalid_lane", `Lane not found: ${lane}`);
172
+ return pointer.leafId;
173
+ }
174
+ async queryEntries(query = {}, resultLimit = query.limit) {
175
+ assertValidLimit(query.limit);
176
+ assertValidCursor(query.cursor?.afterSeq);
177
+ return this.storage.findEntries(resultLimit === query.limit ? query : { ...query, limit: resultLimit });
178
+ }
179
+ async queryBranchEntries(lane, query = {}, resultLimit = query.limit) {
180
+ assertValidLimit(query.limit);
181
+ assertValidCursor(query.cursor?.afterSeq);
182
+ const start = query.start ?? (await this.getLeafIdForLane(lane));
183
+ if (start === null)
184
+ return [];
185
+ const storageQuery = resultLimit === query.limit ? query : { ...query, limit: resultLimit };
186
+ return this.storage.findEntriesOnBranch({ ...storageQuery, start });
187
+ }
188
+ async queryRecords(query = {}) {
189
+ assertValidLimit(query.limit);
190
+ assertValidCursor(query.afterSeq);
191
+ if (query.operationKind !== undefined && query.type !== "operation_started") {
192
+ throw new SessionError("invalid_query", 'operationKind requires type "operation_started"');
319
193
  }
320
- await this.setLeafId(entryId);
321
- if (!summary)
322
- return undefined;
323
- return this.appendTypedEntry((base) => ({
324
- ...base,
325
- type: "branch_summary",
326
- fromId: entryId ?? "root",
327
- summary: summary.summary,
328
- details: summary.details,
329
- usage: summary.usage,
330
- fromHook: summary.fromHook,
331
- }));
194
+ return this.storage.findRecords(query);
195
+ }
196
+ async queryLog(options = {}) {
197
+ assertValidLimit(options.limit);
198
+ assertValidCursor(options.afterSeq);
199
+ return this.storage.getLog(options);
200
+ }
201
+ async appendMessageToLane(lane, message) {
202
+ const entry = await this.commitEntry({ type: "message", id: this.idGenerator.next(), message }, lane);
203
+ return entry.id;
204
+ }
205
+ async appendCustomEntryToLane(lane, customType, data) {
206
+ const entry = await this.commitEntry(data === undefined
207
+ ? { type: "custom", id: this.idGenerator.next(), customType }
208
+ : { type: "custom", id: this.idGenerator.next(), customType, data }, lane);
209
+ return entry.id;
210
+ }
211
+ async commitEntry(entry, lane) {
212
+ assertJsonSerializable(entry);
213
+ return this.storage.appendEntry(entry, lane);
214
+ }
215
+ async commitRecord(record) {
216
+ assertJsonSerializable(record);
217
+ return this.storage.appendRecord(record);
332
218
  }
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
219
  }
338
220
  //# sourceMappingURL=session.js.map