@devxiyang/agent-kernel 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +525 -0
  2. package/dist/core/agent/agent.d.ts +132 -0
  3. package/dist/core/agent/agent.d.ts.map +1 -0
  4. package/dist/core/agent/agent.js +301 -0
  5. package/dist/core/agent/agent.js.map +1 -0
  6. package/dist/core/agent/index.d.ts +13 -0
  7. package/dist/core/agent/index.d.ts.map +1 -0
  8. package/dist/core/agent/index.js +10 -0
  9. package/dist/core/agent/index.js.map +1 -0
  10. package/dist/core/agent/loop.d.ts +30 -0
  11. package/dist/core/agent/loop.d.ts.map +1 -0
  12. package/dist/core/agent/loop.js +378 -0
  13. package/dist/core/agent/loop.js.map +1 -0
  14. package/dist/core/agent/types.d.ts +231 -0
  15. package/dist/core/agent/types.d.ts.map +1 -0
  16. package/dist/core/agent/types.js +9 -0
  17. package/dist/core/agent/types.js.map +1 -0
  18. package/dist/core/agent/wrap-tool.d.ts +12 -0
  19. package/dist/core/agent/wrap-tool.d.ts.map +1 -0
  20. package/dist/core/agent/wrap-tool.js +37 -0
  21. package/dist/core/agent/wrap-tool.js.map +1 -0
  22. package/dist/core/kernel/index.d.ts +12 -0
  23. package/dist/core/kernel/index.d.ts.map +1 -0
  24. package/dist/core/kernel/index.js +10 -0
  25. package/dist/core/kernel/index.js.map +1 -0
  26. package/dist/core/kernel/kernel.d.ts +15 -0
  27. package/dist/core/kernel/kernel.d.ts.map +1 -0
  28. package/dist/core/kernel/kernel.js +320 -0
  29. package/dist/core/kernel/kernel.js.map +1 -0
  30. package/dist/core/kernel/session-store.d.ts +24 -0
  31. package/dist/core/kernel/session-store.d.ts.map +1 -0
  32. package/dist/core/kernel/session-store.js +90 -0
  33. package/dist/core/kernel/session-store.js.map +1 -0
  34. package/dist/core/kernel/types.d.ts +215 -0
  35. package/dist/core/kernel/types.d.ts.map +1 -0
  36. package/dist/core/kernel/types.js +11 -0
  37. package/dist/core/kernel/types.js.map +1 -0
  38. package/dist/event-stream.d.ts +25 -0
  39. package/dist/event-stream.d.ts.map +1 -0
  40. package/dist/event-stream.js +58 -0
  41. package/dist/event-stream.js.map +1 -0
  42. package/dist/index.d.ts +12 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +12 -0
  45. package/dist/index.js.map +1 -0
  46. package/package.json +57 -0
@@ -0,0 +1,12 @@
1
+ import type { TObject } from '@sinclair/typebox';
2
+ import type { AgentTool, ToolWrapHooks } from './types';
3
+ /**
4
+ * Wrap an AgentTool with before/after hooks.
5
+ *
6
+ * - `before`: can block, modify input, or replace the result entirely
7
+ * - `after`: can partially override content, isError, and/or details
8
+ *
9
+ * Hooks are transparent to the agent loop — the loop only sees a plain AgentTool.
10
+ */
11
+ export declare function wrapTool<TSchema extends TObject = TObject, TDetails = unknown>(tool: AgentTool<TSchema, TDetails>, hooks: ToolWrapHooks): AgentTool<TSchema, TDetails>;
12
+ //# sourceMappingURL=wrap-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap-tool.d.ts","sourceRoot":"","sources":["../../../src/core/agent/wrap-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,EACV,SAAS,EAGT,aAAa,EACd,MAAM,SAAS,CAAA;AAEhB;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,OAAO,SAAU,OAAO,GAAG,OAAO,EAClC,QAAQ,GAAG,OAAO,EAElB,IAAI,EAAG,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,EACnC,KAAK,EAAE,aAAa,GACnB,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CA8B9B"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Wrap an AgentTool with before/after hooks.
3
+ *
4
+ * - `before`: can block, modify input, or replace the result entirely
5
+ * - `after`: can partially override content, isError, and/or details
6
+ *
7
+ * Hooks are transparent to the agent loop — the loop only sees a plain AgentTool.
8
+ */
9
+ export function wrapTool(tool, hooks) {
10
+ return {
11
+ ...tool,
12
+ execute: async (toolCallId, input, signal, onUpdate) => {
13
+ // ── before hook ──────────────────────────────────────────────────────
14
+ if (hooks.before) {
15
+ const before = await hooks.before(toolCallId, tool.name, input);
16
+ if (before?.action === 'block') {
17
+ return { content: before.reason, isError: true };
18
+ }
19
+ }
20
+ // ── execute ──────────────────────────────────────────────────────────
21
+ let result = await tool.execute(toolCallId, input, signal, onUpdate);
22
+ // ── after hook ───────────────────────────────────────────────────────
23
+ if (hooks.after) {
24
+ const after = await hooks.after(toolCallId, tool.name, result);
25
+ if (after) {
26
+ result = {
27
+ content: after.content !== undefined ? after.content : result.content,
28
+ isError: after.isError !== undefined ? after.isError : result.isError,
29
+ details: after.details !== undefined ? after.details : result.details,
30
+ };
31
+ }
32
+ }
33
+ return result;
34
+ },
35
+ };
36
+ }
37
+ //# sourceMappingURL=wrap-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap-tool.js","sourceRoot":"","sources":["../../../src/core/agent/wrap-tool.ts"],"names":[],"mappings":"AAQA;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAItB,IAAmC,EACnC,KAAoB;IAEpB,OAAO;QACL,GAAG,IAAI;QACP,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;YACrD,wEAAwE;YACxE,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;gBAC/D,IAAI,MAAM,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC;oBAC/B,OAAO,EAAE,OAAO,EAAG,MAAsB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAA0B,CAAA;gBAC3F,CAAC;YACH,CAAC;YAED,wEAAwE;YACxE,IAAI,MAAM,GAAyB,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;YAE1F,wEAAwE;YACxE,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;gBAC9D,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,GAAG;wBACP,OAAO,EAAG,KAAK,CAAC,OAAO,KAAM,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC,CAAC,MAAM,CAAC,OAAO;wBACpF,OAAO,EAAG,KAAK,CAAC,OAAO,KAAM,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC,CAAC,MAAM,CAAC,OAAO;wBACpF,OAAO,EAAG,KAAK,CAAC,OAAO,KAAM,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAmB,CAAE,CAAC,CAAC,MAAM,CAAC,OAAO;qBACrF,CAAA;gBACH,CAAC;YACH,CAAC;YAED,OAAO,MAAM,CAAA;QACf,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @module agent-kernel/kernel
3
+ *
4
+ * Public surface of the Kernel module. Exports all types, the createKernel factory,
5
+ * and session management utilities (listSessions, deleteSession, updateSessionMeta).
6
+ */
7
+ export type { Usage, DataContent, TextPart, ImagePart, AudioPart, VideoPart, FilePart, ContentPart, ImageMediaType, AudioMediaType, VideoMediaType, FileMediaType, StopReason, ToolCallInfo, AgentEntry, AgentMessage, StoredEntry, AppendResult, CompactionEntry, TokenBudget, AgentKernel, KernelOptions, SessionMeta, } from './types';
8
+ export { COMPACTION_TYPE } from './types';
9
+ export { createKernel } from './kernel';
10
+ export type { SessionInfo } from './session-store';
11
+ export { listSessions, deleteSession, updateSessionMeta } from './session-store';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/kernel/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EACV,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,eAAe,EACf,WAAW,EACX,WAAW,EACX,aAAa,EACb,WAAW,GACZ,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @module agent-kernel/kernel
3
+ *
4
+ * Public surface of the Kernel module. Exports all types, the createKernel factory,
5
+ * and session management utilities (listSessions, deleteSession, updateSessionMeta).
6
+ */
7
+ export { COMPACTION_TYPE } from './types';
8
+ export { createKernel } from './kernel';
9
+ export { listSessions, deleteSession, updateSessionMeta } from './session-store';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/kernel/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAGvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,15 @@
1
+ import type { AgentKernel, KernelOptions } from './types';
2
+ /**
3
+ * Kernel — conversation state manager and optional JSONL persistence layer.
4
+ *
5
+ * Maintains a linked tree of StoredEntry nodes (parentId → id) that models the
6
+ * full conversation history including branches and compaction. The "current branch"
7
+ * is the path from the root to _leafId.
8
+ *
9
+ * Two files are written per session:
10
+ * - kernel.jsonl — current branch only (rewritten on compact)
11
+ * - log.jsonl — append-only full history (never compacted); for UI display
12
+ */
13
+ /** Create a kernel. Pass options for file-backed persistence; omit for in-memory (tests). */
14
+ export declare function createKernel(options?: KernelOptions): AgentKernel;
15
+ //# sourceMappingURL=kernel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel.d.ts","sourceRoot":"","sources":["../../../src/core/kernel/kernel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,WAAW,EAKX,aAAa,EAId,MAAM,SAAS,CAAA;AAGhB;;;;;;;;;;GAUG;AAIH,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,WAAW,CAEjE"}
@@ -0,0 +1,320 @@
1
+ import { readFileSync, appendFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { COMPACTION_TYPE } from './types';
4
+ /**
5
+ * Kernel — conversation state manager and optional JSONL persistence layer.
6
+ *
7
+ * Maintains a linked tree of StoredEntry nodes (parentId → id) that models the
8
+ * full conversation history including branches and compaction. The "current branch"
9
+ * is the path from the root to _leafId.
10
+ *
11
+ * Two files are written per session:
12
+ * - kernel.jsonl — current branch only (rewritten on compact)
13
+ * - log.jsonl — append-only full history (never compacted); for UI display
14
+ */
15
+ // ─── Factory ──────────────────────────────────────────────────────────────────
16
+ /** Create a kernel. Pass options for file-backed persistence; omit for in-memory (tests). */
17
+ export function createKernel(options) {
18
+ return new Kernel(options);
19
+ }
20
+ // ─── Kernel implementation ────────────────────────────────────────────────────
21
+ class Kernel {
22
+ /** All stored entries indexed by id — the in-memory conversation tree. */
23
+ byId = new Map();
24
+ /** Next id to assign on append. */
25
+ nextId = 0;
26
+ /** Input tokens from the most recent assistant entry (tracks context window usage). */
27
+ tokenUsed = 0;
28
+ /** Configurable context size cap; Infinity until the caller sets budget.set(). */
29
+ tokenLimit = Number.POSITIVE_INFINITY;
30
+ /** Absolute path to kernel.jsonl, or undefined when running in-memory. */
31
+ kernelPath;
32
+ /** Absolute path to log.jsonl, or undefined when running in-memory. */
33
+ logPath;
34
+ /** The id of the most recent entry on the current branch (the "tip"). */
35
+ _leafId = null;
36
+ budget;
37
+ constructor(options) {
38
+ if (options) {
39
+ const sessionDir = join(options.dir, options.sessionId);
40
+ mkdirSync(sessionDir, { recursive: true });
41
+ this.kernelPath = join(sessionDir, 'kernel.jsonl');
42
+ this.logPath = join(sessionDir, 'log.jsonl');
43
+ const metaPath = join(sessionDir, 'meta.json');
44
+ if (!existsSync(metaPath)) {
45
+ const meta = { createdAt: Date.now(), ...options.meta };
46
+ writeFileSync(metaPath, JSON.stringify(meta));
47
+ }
48
+ else if (options.meta && Object.keys(options.meta).length > 0) {
49
+ const existing = JSON.parse(readFileSync(metaPath, 'utf-8'));
50
+ writeFileSync(metaPath, JSON.stringify({ ...existing, ...options.meta }));
51
+ }
52
+ }
53
+ const kernel = this;
54
+ this.budget = {
55
+ get used() { return kernel.tokenUsed; },
56
+ get limit() { return kernel.tokenLimit; },
57
+ set(limit) { kernel.tokenLimit = limit; },
58
+ };
59
+ if (this.kernelPath && existsSync(this.kernelPath)) {
60
+ this.loadFromFile(this.kernelPath);
61
+ }
62
+ }
63
+ // ─── Log ──────────────────────────────────────────────────────────────────
64
+ /**
65
+ * Write an entry to the in-memory tree and (if configured) to both
66
+ * kernel.jsonl and log.jsonl. Advances the leaf pointer.
67
+ */
68
+ append(entry) {
69
+ const result = this.write(entry);
70
+ if (result.ok && this.logPath) {
71
+ appendFileSync(this.logPath, JSON.stringify(entry) + '\n');
72
+ }
73
+ return result;
74
+ }
75
+ /** Return all entries on the current branch in chronological order (root → leaf). */
76
+ read() {
77
+ if (this._leafId === null)
78
+ return [];
79
+ return this.walkBranch(this._leafId);
80
+ }
81
+ // ─── Compaction ──────────────────────────────────────────────────────────
82
+ /**
83
+ * Replace entries [fromId, toId] with a single summary entry.
84
+ * Writes a compaction marker to kernel.jsonl, materialises the summary in memory,
85
+ * then rewrites kernel.jsonl to contain only the current branch (no markers).
86
+ * Also appends the summary to log.jsonl as a divider.
87
+ */
88
+ compact(fromId, toId, summaryText) {
89
+ const summaryEntry = { type: 'summary', payload: { text: summaryText } };
90
+ const compactionEntry = {
91
+ type: COMPACTION_TYPE,
92
+ payload: { fromId, toId, summary: summaryEntry },
93
+ };
94
+ const result = this.writeCompaction(compactionEntry);
95
+ if (result.ok) {
96
+ this.materialize(fromId, toId, summaryEntry);
97
+ // Append summary divider to conversation log
98
+ if (this.logPath) {
99
+ appendFileSync(this.logPath, JSON.stringify(summaryEntry) + '\n');
100
+ }
101
+ }
102
+ return result;
103
+ }
104
+ // ─── Context size ─────────────────────────────────────────────────────────
105
+ get contextSize() {
106
+ const last = this.peek();
107
+ return last?.type === 'assistant' ? (last.usage?.input ?? 0) : 0;
108
+ }
109
+ // ─── Branch ───────────────────────────────────────────────────────────────
110
+ get leafId() {
111
+ return this._leafId;
112
+ }
113
+ peek() {
114
+ if (this._leafId === null)
115
+ return null;
116
+ return this.byId.get(this._leafId) ?? null;
117
+ }
118
+ branch(toId) {
119
+ if (!this.byId.has(toId)) {
120
+ throw new Error(`Entry ${toId} not found`);
121
+ }
122
+ this._leafId = toId;
123
+ }
124
+ // ─── Messages ─────────────────────────────────────────────────────────────
125
+ buildMessages() {
126
+ const messages = [];
127
+ for (const entry of this.read()) {
128
+ messages.push(...entryToMessages(entry));
129
+ }
130
+ return messages;
131
+ }
132
+ // ─── Conversation log ─────────────────────────────────────────────────────
133
+ readLog() {
134
+ if (!this.logPath || !existsSync(this.logPath))
135
+ return [];
136
+ const content = readFileSync(this.logPath, 'utf-8');
137
+ return content
138
+ .split('\n')
139
+ .filter(line => line.trim() !== '')
140
+ .map(line => JSON.parse(line));
141
+ }
142
+ // ─── Private ──────────────────────────────────────────────────────────────
143
+ /** Internal: assign id/parentId/timestamp, update byId and leafId, persist to kernel.jsonl. */
144
+ write(entry) {
145
+ const record = {
146
+ ...normalizeEntry(entry),
147
+ id: this.nextId++,
148
+ parentId: this._leafId,
149
+ timestamp: Date.now(),
150
+ };
151
+ this.byId.set(record.id, record);
152
+ this._leafId = record.id;
153
+ if (record.type === 'assistant' && record.usage?.input) {
154
+ this.tokenUsed = record.usage.input;
155
+ }
156
+ if (this.kernelPath) {
157
+ appendFileSync(this.kernelPath, JSON.stringify(record) + '\n');
158
+ }
159
+ return { ok: true, id: record.id };
160
+ }
161
+ /** Write a raw compaction marker record to kernel.jsonl and advance leafId. */
162
+ writeCompaction(entry) {
163
+ const record = {
164
+ ...entry,
165
+ id: this.nextId++,
166
+ parentId: this._leafId,
167
+ timestamp: Date.now(),
168
+ };
169
+ this._leafId = record.id;
170
+ if (this.kernelPath) {
171
+ appendFileSync(this.kernelPath, JSON.stringify(record) + '\n');
172
+ }
173
+ return { ok: true, id: record.id };
174
+ }
175
+ /**
176
+ * Apply a compaction in-memory: delete the compacted range from byId,
177
+ * insert the summary at the compaction slot, and rewrite kernel.jsonl
178
+ * to hold only the clean current branch.
179
+ */
180
+ materialize(fromId, toId, summary) {
181
+ const compactionId = this._leafId;
182
+ // The summary takes the place of the compacted range in the tree:
183
+ // its parentId is the parentId of the first compacted entry (fromId).
184
+ const rangeStartParentId = this.byId.get(fromId)?.parentId ?? null;
185
+ // Remove compacted entries from byId first
186
+ for (const [id] of this.byId) {
187
+ if (id >= fromId && id <= toId) {
188
+ this.byId.delete(id);
189
+ }
190
+ }
191
+ // Insert summary entry at compactionId, linking to what preceded the range
192
+ const compactionRecord = {
193
+ ...summary,
194
+ id: compactionId,
195
+ parentId: rangeStartParentId,
196
+ timestamp: Date.now(),
197
+ };
198
+ this.byId.set(compactionId, compactionRecord);
199
+ // Rewrite kernel file with current branch (clean, no compaction markers)
200
+ if (this.kernelPath) {
201
+ const branchPath = this.read();
202
+ writeFileSync(this.kernelPath, branchPath.map(e => JSON.stringify(e)).join('\n') + '\n');
203
+ }
204
+ }
205
+ /** Walk the parentId chain from `fromId` back to the root, returning entries root-first. */
206
+ walkBranch(fromId) {
207
+ const path = [];
208
+ let current = this.byId.get(fromId);
209
+ while (current) {
210
+ path.unshift(current);
211
+ current = current.parentId !== null ? this.byId.get(current.parentId) : undefined;
212
+ }
213
+ return path;
214
+ }
215
+ /** Replay kernel.jsonl on startup to restore the in-memory tree and leafId. */
216
+ loadFromFile(filePath) {
217
+ const content = readFileSync(filePath, 'utf-8');
218
+ const lines = content.split('\n').filter(line => line.trim() !== '');
219
+ for (const line of lines) {
220
+ const record = JSON.parse(line);
221
+ this.byId.set(record.id, record);
222
+ this._leafId = record.id;
223
+ if (record.type === 'assistant' && record.usage?.input) {
224
+ this.tokenUsed = record.usage.input;
225
+ }
226
+ if (record.id >= this.nextId) {
227
+ this.nextId = record.id + 1;
228
+ }
229
+ }
230
+ }
231
+ }
232
+ // ─── entryToMessages ──────────────────────────────────────────────────────────
233
+ /**
234
+ * Convert a single AgentEntry to zero or more provider-agnostic AgentMessages.
235
+ * Summary entries become user messages with a "[Context Summary]" prefix.
236
+ */
237
+ function entryToMessages(entry) {
238
+ switch (entry.type) {
239
+ case 'user': {
240
+ const { parts } = entry.payload;
241
+ // Shorthand: single text part → string content
242
+ if (parts.length === 1 && parts[0].type === 'text') {
243
+ return [{ role: 'user', content: parts[0].text }];
244
+ }
245
+ return [{ role: 'user', content: parts }];
246
+ }
247
+ case 'assistant': {
248
+ const { text, reasoning, toolCalls } = entry.payload;
249
+ if (!reasoning && toolCalls.length === 0) {
250
+ return [{ role: 'assistant', content: text }];
251
+ }
252
+ const parts = [];
253
+ if (reasoning)
254
+ parts.push({ type: 'reasoning', text: reasoning });
255
+ if (text)
256
+ parts.push({ type: 'text', text });
257
+ for (const tc of toolCalls) {
258
+ parts.push({ type: 'tool-call', toolCallId: tc.toolCallId, toolName: tc.toolName, input: tc.input });
259
+ }
260
+ return [{ role: 'assistant', content: parts }];
261
+ }
262
+ case 'tool_result':
263
+ return [{
264
+ role: 'tool',
265
+ content: [{
266
+ type: 'tool-result',
267
+ toolCallId: entry.payload.toolCallId,
268
+ toolName: entry.payload.toolName,
269
+ content: entry.payload.content,
270
+ isError: entry.payload.isError,
271
+ }],
272
+ }];
273
+ case 'summary':
274
+ return [{ role: 'user', content: `[Context Summary]\n${entry.payload.text}` }];
275
+ default:
276
+ return [];
277
+ }
278
+ }
279
+ // ─── Serialization helpers ────────────────────────────────────────────────────
280
+ /**
281
+ * Normalize a ContentPart for JSONL storage.
282
+ * Uint8Array / ArrayBuffer → base64 string. URL → href string.
283
+ */
284
+ function normalizeContentPart(part) {
285
+ if (part.type === 'text')
286
+ return part;
287
+ if ('url' in part)
288
+ return part; // URL string stored as-is
289
+ return { ...part, data: normalizeData(part.data) };
290
+ }
291
+ /** Convert Uint8Array to base64; pass through strings unchanged. */
292
+ function normalizeData(value) {
293
+ if (value instanceof Uint8Array)
294
+ return bufferToBase64(value);
295
+ return value; // already a base64 string
296
+ }
297
+ /** Encode raw bytes to a base64 string for JSONL storage. */
298
+ function bufferToBase64(bytes) {
299
+ let binary = '';
300
+ for (let i = 0; i < bytes.byteLength; i++) {
301
+ binary += String.fromCharCode(bytes[i]);
302
+ }
303
+ return btoa(binary);
304
+ }
305
+ /**
306
+ * Normalize all ContentParts in a user or tool_result entry before persisting.
307
+ */
308
+ function normalizeEntry(entry) {
309
+ if (entry.type === 'user') {
310
+ return { ...entry, payload: { parts: entry.payload.parts.map(normalizeContentPart) } };
311
+ }
312
+ if (entry.type === 'tool_result' && Array.isArray(entry.payload.content)) {
313
+ return {
314
+ ...entry,
315
+ payload: { ...entry.payload, content: entry.payload.content.map(normalizeContentPart) },
316
+ };
317
+ }
318
+ return entry;
319
+ }
320
+ //# sourceMappingURL=kernel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel.js","sourceRoot":"","sources":["../../../src/core/kernel/kernel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { SessionMeta } from './types';
2
+ export type SessionInfo = {
3
+ sessionId: string;
4
+ updatedAt: number;
5
+ messageCount: number;
6
+ meta: SessionMeta | null;
7
+ };
8
+ /**
9
+ * List all sessions under `dir`, sorted by most recently updated first.
10
+ * Returns [] if `dir` does not exist or contains no sessions.
11
+ */
12
+ export declare function listSessions(dir: string): SessionInfo[];
13
+ /**
14
+ * Merge metadata fields into an existing session's meta.json.
15
+ * `createdAt` is protected and cannot be overwritten.
16
+ * Silent no-op if the session does not have a meta.json yet.
17
+ */
18
+ export declare function updateSessionMeta(dir: string, sessionId: string, meta: Partial<Omit<SessionMeta, 'createdAt'>>): void;
19
+ /**
20
+ * Delete a session directory and all its contents.
21
+ * Silent no-op if `dir` or `sessionId` does not exist.
22
+ */
23
+ export declare function deleteSession(dir: string, sessionId: string): void;
24
+ //# sourceMappingURL=session-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../../src/core/kernel/session-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAI1C,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,EAAK,MAAM,CAAA;IACpB,SAAS,EAAK,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAU,WAAW,GAAG,IAAI,CAAA;CACjC,CAAA;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CAyDvD;AAID;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAQ,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAO,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,GACjD,IAAI,CAKN;AAID;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAIlE"}
@@ -0,0 +1,90 @@
1
+ import { readdirSync, statSync, readFileSync, writeFileSync, rmSync, existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ // ─── listSessions ─────────────────────────────────────────────────────────────
4
+ /**
5
+ * List all sessions under `dir`, sorted by most recently updated first.
6
+ * Returns [] if `dir` does not exist or contains no sessions.
7
+ */
8
+ export function listSessions(dir) {
9
+ if (!existsSync(dir))
10
+ return [];
11
+ let entries;
12
+ try {
13
+ entries = readdirSync(dir);
14
+ }
15
+ catch {
16
+ return [];
17
+ }
18
+ const sessions = [];
19
+ for (const sessionId of entries) {
20
+ const sessionDir = join(dir, sessionId);
21
+ const logPath = join(sessionDir, 'log.jsonl');
22
+ let stat;
23
+ try {
24
+ stat = statSync(sessionDir);
25
+ if (!stat.isDirectory())
26
+ continue;
27
+ }
28
+ catch {
29
+ continue;
30
+ }
31
+ if (!existsSync(logPath)) {
32
+ let meta = null;
33
+ const metaPath = join(sessionDir, 'meta.json');
34
+ if (existsSync(metaPath)) {
35
+ try {
36
+ meta = JSON.parse(readFileSync(metaPath, 'utf-8'));
37
+ }
38
+ catch { }
39
+ }
40
+ sessions.push({ sessionId, updatedAt: stat.mtimeMs, messageCount: 0, meta });
41
+ continue;
42
+ }
43
+ let updatedAt = stat.mtimeMs;
44
+ let messageCount = 0;
45
+ try {
46
+ const logStat = statSync(logPath);
47
+ updatedAt = logStat.mtimeMs;
48
+ const content = readFileSync(logPath, 'utf-8');
49
+ messageCount = content.split('\n').filter(l => l.trim() !== '').length;
50
+ }
51
+ catch {
52
+ // Malformed log — still include the session with what we have
53
+ }
54
+ let meta = null;
55
+ const metaPath = join(sessionDir, 'meta.json');
56
+ if (existsSync(metaPath)) {
57
+ try {
58
+ meta = JSON.parse(readFileSync(metaPath, 'utf-8'));
59
+ }
60
+ catch { }
61
+ }
62
+ sessions.push({ sessionId, updatedAt, messageCount, meta });
63
+ }
64
+ return sessions.sort((a, b) => b.updatedAt - a.updatedAt);
65
+ }
66
+ // ─── updateSessionMeta ────────────────────────────────────────────────────────
67
+ /**
68
+ * Merge metadata fields into an existing session's meta.json.
69
+ * `createdAt` is protected and cannot be overwritten.
70
+ * Silent no-op if the session does not have a meta.json yet.
71
+ */
72
+ export function updateSessionMeta(dir, sessionId, meta) {
73
+ const metaPath = join(dir, sessionId, 'meta.json');
74
+ if (!existsSync(metaPath))
75
+ return;
76
+ const existing = JSON.parse(readFileSync(metaPath, 'utf-8'));
77
+ writeFileSync(metaPath, JSON.stringify({ ...existing, ...meta }));
78
+ }
79
+ // ─── deleteSession ────────────────────────────────────────────────────────────
80
+ /**
81
+ * Delete a session directory and all its contents.
82
+ * Silent no-op if `dir` or `sessionId` does not exist.
83
+ */
84
+ export function deleteSession(dir, sessionId) {
85
+ const sessionDir = join(dir, sessionId);
86
+ if (!existsSync(sessionDir))
87
+ return;
88
+ rmSync(sessionDir, { recursive: true, force: true });
89
+ }
90
+ //# sourceMappingURL=session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../../../src/core/kernel/session-store.ts"],"names":[],"mappings":"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"}