@yugenlab/vaayu 0.1.11 → 0.1.12
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/chunks/{agentic-tool-loop-O3NUV7KG.js → agentic-tool-loop-NQESOBLC.js} +2 -2
- package/chunks/akasha-5C5Q6NMP.js +12 -0
- package/chunks/{chunk-7XV5ISV7.js → chunk-26K6DS6N.js} +2 -2
- package/chunks/chunk-5E3ZS5SW.js +529 -0
- package/chunks/{chunk-D46QTN3G.js → chunk-ARZCIITZ.js} +47 -18
- package/chunks/{chunk-ZYY6N3SP.js → chunk-FEDPZOZ5.js} +548 -389
- package/chunks/{chunk-3AYSJ7WB.js → chunk-GWYC7R2L.js} +13 -7
- package/chunks/chunk-H46F2Y6R.js +134 -0
- package/chunks/{chunk-QV4GPIPT.js → chunk-HXHDP2PZ.js} +8 -4
- package/chunks/chunk-KVQH4LE7.js +396 -0
- package/chunks/{chunk-Z576WVLG.js → chunk-LJCT7UYP.js} +17 -7
- package/chunks/{chunk-LJUEMPLG.js → chunk-M2RLX5LU.js} +32 -14
- package/chunks/{chunk-IGKYKEKT.js → chunk-NAQKA54E.js} +8 -2
- package/chunks/{chunk-F6RNEGFX.js → chunk-PZ4AQ22L.js} +78 -13
- package/chunks/{chunk-G2QREGXK.js → chunk-R273KC7J.js} +275 -2
- package/chunks/{chunk-A3HOZBC5.js → chunk-RVKTGKFD.js} +2 -2
- package/chunks/{chunk-VCUJES75.js → chunk-TSOQ2CT3.js} +763 -620
- package/chunks/{chunk-V2ZIKDN4.js → chunk-VEZ2DI2M.js} +16 -5
- package/chunks/{chunk-W4PVGBUH.js → chunk-XP3NIH5F.js} +7 -3
- package/chunks/{chunk-7AYYXHYZ.js → chunk-Y6IZH6FT.js} +19 -4
- package/chunks/{chunk-JZTFJE7M.js → chunk-YRTGGYJU.js} +14 -10
- package/chunks/{consolidation-indexer-VIWOP6VO.js → consolidation-indexer-KPXORCJ4.js} +9 -9
- package/chunks/database-BX3LVYXS.js +11 -0
- package/chunks/{day-consolidation-HMHSXIOM.js → day-consolidation-CR3TJFAL.js} +5 -5
- package/chunks/{dist-CY5NX2IK.js → dist-ESCM3CP5.js} +31 -21
- package/chunks/graphrag-73XA7LBX.js +14 -0
- package/chunks/hierarchical-temporal-search-GHKVKNZ6.js +8 -0
- package/chunks/hybrid-search-OD756RDV.js +20 -0
- package/chunks/{memory-store-LEERUQGL.js → memory-store-4GCBR2DZ.js} +4 -4
- package/chunks/periodic-consolidation-IINCHP6L.js +11 -0
- package/chunks/{postgres-7GZDDX77.js → postgres-YLCUNVPQ.js} +2 -2
- package/chunks/recall-64RROTUC.js +21 -0
- package/chunks/search-JVCDNTAJ.js +19 -0
- package/chunks/{session-store-O3TS7DUY.js → session-store-3EDQZEDS.js} +12 -6
- package/chunks/{sqlite-7BC4DJTN.js → sqlite-4N7YH2KK.js} +2 -2
- package/chunks/{src-6GVZTUH6.js → src-OPSDZEFI.js} +2 -2
- package/chunks/{suncalc-NOHGYHDU.js → suncalc-RM7URNUR.js} +2 -2
- package/chunks/{tree-RSHKDTCR.js → tree-FIUVGJ5J.js} +2 -2
- package/chunks/{vasana-engine-BJFHJVGM.js → vasana-engine-W4PYWT5H.js} +5 -5
- package/gateway.js +2358 -768
- package/package.json +1 -1
- package/pair-cli.js +2 -2
- package/chunks/chunk-2OBLQJYJ.js +0 -198
- package/chunks/chunk-67DXWEKG.js +0 -123
- package/chunks/graphrag-T2QWNX57.js +0 -14
- package/chunks/hierarchical-temporal-search-U6DG74IR.js +0 -8
- package/chunks/hybrid-search-BYTXCOXP.js +0 -20
- package/chunks/periodic-consolidation-D6SSKZ7H.js +0 -11
- package/chunks/recall-LNRQVATQ.js +0 -21
- package/chunks/search-BIODUW2P.js +0 -19
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
-
initAgentSchema
|
|
3
|
-
|
|
2
|
+
initAgentSchema,
|
|
3
|
+
init_schema
|
|
4
|
+
} from "./chunk-VEZ2DI2M.js";
|
|
4
5
|
import {
|
|
5
|
-
DatabaseManager
|
|
6
|
-
|
|
6
|
+
DatabaseManager,
|
|
7
|
+
init_database
|
|
8
|
+
} from "./chunk-H46F2Y6R.js";
|
|
7
9
|
import {
|
|
8
10
|
SessionError,
|
|
9
|
-
getChitraguptaHome
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
getChitraguptaHome,
|
|
12
|
+
init_dist
|
|
13
|
+
} from "./chunk-KVQH4LE7.js";
|
|
14
|
+
import {
|
|
15
|
+
__esm,
|
|
16
|
+
__export,
|
|
17
|
+
__toCommonJS
|
|
18
|
+
} from "./chunk-NAQKA54E.js";
|
|
17
19
|
|
|
18
20
|
// ../chitragupta/packages/smriti/dist/markdown-parser.js
|
|
19
21
|
function parseFrontmatter(yaml) {
|
|
@@ -209,6 +211,12 @@ function parseToolCallSection(name, section) {
|
|
|
209
211
|
toolCall.isError = true;
|
|
210
212
|
return toolCall;
|
|
211
213
|
}
|
|
214
|
+
var init_markdown_parser = __esm({
|
|
215
|
+
"../chitragupta/packages/smriti/dist/markdown-parser.js"() {
|
|
216
|
+
"use strict";
|
|
217
|
+
init_dist();
|
|
218
|
+
}
|
|
219
|
+
});
|
|
212
220
|
|
|
213
221
|
// ../chitragupta/packages/smriti/dist/markdown-writer.js
|
|
214
222
|
function writeFrontmatter(meta) {
|
|
@@ -302,147 +310,24 @@ function writeSessionMarkdown(session) {
|
|
|
302
310
|
function writeTurnMarkdown(turn) {
|
|
303
311
|
return writeTurn(turn);
|
|
304
312
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
try {
|
|
309
|
-
nodeRenameSync(tmpPath, targetPath);
|
|
310
|
-
} catch {
|
|
311
|
-
fs.writeFileSync(targetPath, fs.readFileSync(tmpPath, "utf-8"), "utf-8");
|
|
312
|
-
try {
|
|
313
|
-
fs.unlinkSync(tmpPath);
|
|
314
|
-
} catch {
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
var SESSION_CACHE_MAX = 500;
|
|
319
|
-
var SESSION_CACHE_MAX_BYTES = 25 * 1024 * 1024;
|
|
320
|
-
var sessionCache = /* @__PURE__ */ new Map();
|
|
321
|
-
var sessionCacheSizes = /* @__PURE__ */ new Map();
|
|
322
|
-
var sessionCacheBytes = 0;
|
|
323
|
-
function estimateSessionBytes(session) {
|
|
324
|
-
let bytes = 200;
|
|
325
|
-
for (const turn of session.turns) {
|
|
326
|
-
bytes += Buffer.byteLength(turn.content, "utf-8") + 50;
|
|
327
|
-
}
|
|
328
|
-
return bytes;
|
|
329
|
-
}
|
|
330
|
-
function cacheKey(id, project) {
|
|
331
|
-
return `${id}:${project}`;
|
|
332
|
-
}
|
|
333
|
-
function cacheGet(id, project) {
|
|
334
|
-
const key = cacheKey(id, project);
|
|
335
|
-
const entry = sessionCache.get(key);
|
|
336
|
-
if (!entry)
|
|
337
|
-
return void 0;
|
|
338
|
-
const size = sessionCacheSizes.get(key) ?? 0;
|
|
339
|
-
sessionCache.delete(key);
|
|
340
|
-
sessionCacheSizes.delete(key);
|
|
341
|
-
sessionCache.set(key, entry);
|
|
342
|
-
sessionCacheSizes.set(key, size);
|
|
343
|
-
return entry;
|
|
344
|
-
}
|
|
345
|
-
function cachePut(id, project, session) {
|
|
346
|
-
const key = cacheKey(id, project);
|
|
347
|
-
const existingSize = sessionCacheSizes.get(key) ?? 0;
|
|
348
|
-
sessionCache.delete(key);
|
|
349
|
-
sessionCacheSizes.delete(key);
|
|
350
|
-
sessionCacheBytes -= existingSize;
|
|
351
|
-
const newSize = estimateSessionBytes(session);
|
|
352
|
-
while ((sessionCache.size >= SESSION_CACHE_MAX || sessionCacheBytes + newSize > SESSION_CACHE_MAX_BYTES) && sessionCache.size > 0) {
|
|
353
|
-
const oldest = sessionCache.keys().next().value;
|
|
354
|
-
if (oldest === void 0)
|
|
355
|
-
break;
|
|
356
|
-
const evictedSize = sessionCacheSizes.get(oldest) ?? 0;
|
|
357
|
-
sessionCache.delete(oldest);
|
|
358
|
-
sessionCacheSizes.delete(oldest);
|
|
359
|
-
sessionCacheBytes -= evictedSize;
|
|
313
|
+
var init_markdown_writer = __esm({
|
|
314
|
+
"../chitragupta/packages/smriti/dist/markdown-writer.js"() {
|
|
315
|
+
"use strict";
|
|
360
316
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
const key = cacheKey(id, project);
|
|
367
|
-
const size = sessionCacheSizes.get(key) ?? 0;
|
|
368
|
-
sessionCache.delete(key);
|
|
369
|
-
sessionCacheSizes.delete(key);
|
|
370
|
-
sessionCacheBytes -= size;
|
|
371
|
-
}
|
|
372
|
-
function _resetSessionCache() {
|
|
373
|
-
sessionCache.clear();
|
|
374
|
-
sessionCacheSizes.clear();
|
|
375
|
-
sessionCacheBytes = 0;
|
|
376
|
-
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// ../chitragupta/packages/smriti/dist/session-db.js
|
|
320
|
+
import path from "path";
|
|
321
|
+
import crypto from "crypto";
|
|
377
322
|
function hashProject(project) {
|
|
378
323
|
return crypto.createHash("sha256").update(project).digest("hex").slice(0, 12);
|
|
379
324
|
}
|
|
380
|
-
function generateSessionId(project) {
|
|
381
|
-
const now = /* @__PURE__ */ new Date();
|
|
382
|
-
const yyyy = now.getFullYear().toString();
|
|
383
|
-
const mm = (now.getMonth() + 1).toString().padStart(2, "0");
|
|
384
|
-
const dd = now.getDate().toString().padStart(2, "0");
|
|
385
|
-
const dateStr = `${yyyy}-${mm}-${dd}`;
|
|
386
|
-
const projHash = hashProject(project).slice(0, 8);
|
|
387
|
-
const baseId = `session-${dateStr}-${projHash}`;
|
|
388
|
-
const projectDir = getProjectSessionDir(project);
|
|
389
|
-
const yearMonthDir = path.join(projectDir, yyyy, mm);
|
|
390
|
-
fs.mkdirSync(yearMonthDir, { recursive: true });
|
|
391
|
-
const basePath = path.join(yearMonthDir, `${baseId}.md`);
|
|
392
|
-
if (!fs.existsSync(basePath)) {
|
|
393
|
-
return {
|
|
394
|
-
id: baseId,
|
|
395
|
-
filePath: path.join("sessions", hashProject(project), yyyy, mm, `${baseId}.md`)
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
let counter = 2;
|
|
399
|
-
while (fs.existsSync(path.join(yearMonthDir, `${baseId}-${counter}.md`))) {
|
|
400
|
-
counter++;
|
|
401
|
-
}
|
|
402
|
-
const id = `${baseId}-${counter}`;
|
|
403
|
-
return {
|
|
404
|
-
id,
|
|
405
|
-
filePath: path.join("sessions", hashProject(project), yyyy, mm, `${id}.md`)
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
325
|
function getSessionsRoot() {
|
|
409
326
|
return path.join(getChitraguptaHome(), "sessions");
|
|
410
327
|
}
|
|
411
328
|
function getProjectSessionDir(project) {
|
|
412
329
|
return path.join(getSessionsRoot(), hashProject(project));
|
|
413
330
|
}
|
|
414
|
-
function resolveSessionPath(id, project) {
|
|
415
|
-
const projectDir = getProjectSessionDir(project);
|
|
416
|
-
const dateMatch = id.match(/^session-(\d{4})-(\d{2})-\d{2}/);
|
|
417
|
-
if (dateMatch) {
|
|
418
|
-
const newPath = path.join(projectDir, dateMatch[1], dateMatch[2], `${id}.md`);
|
|
419
|
-
if (fs.existsSync(newPath))
|
|
420
|
-
return newPath;
|
|
421
|
-
}
|
|
422
|
-
const oldPath = path.join(projectDir, `${id}.md`);
|
|
423
|
-
if (fs.existsSync(oldPath))
|
|
424
|
-
return oldPath;
|
|
425
|
-
if (dateMatch) {
|
|
426
|
-
return path.join(projectDir, dateMatch[1], dateMatch[2], `${id}.md`);
|
|
427
|
-
}
|
|
428
|
-
return oldPath;
|
|
429
|
-
}
|
|
430
|
-
function patchFrontmatterUpdated(content, updatedIso) {
|
|
431
|
-
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
432
|
-
if (!fmMatch)
|
|
433
|
-
return content;
|
|
434
|
-
const frontmatter = fmMatch[1];
|
|
435
|
-
if (!/^updated:\s/m.test(frontmatter))
|
|
436
|
-
return content;
|
|
437
|
-
const patchedFrontmatter = frontmatter.replace(/^updated:\s.*$/m, `updated: ${updatedIso}`);
|
|
438
|
-
if (patchedFrontmatter === frontmatter)
|
|
439
|
-
return content;
|
|
440
|
-
return `---
|
|
441
|
-
${patchedFrontmatter}
|
|
442
|
-
---${content.slice(fmMatch[0].length)}`;
|
|
443
|
-
}
|
|
444
|
-
var _dbInitialized = false;
|
|
445
|
-
var _dbInitError = null;
|
|
446
331
|
function getAgentDb() {
|
|
447
332
|
const dbm = DatabaseManager.instance();
|
|
448
333
|
if (!_dbInitialized) {
|
|
@@ -553,8 +438,8 @@ function seedSessionRowForTurn(sessionId, project, filePath) {
|
|
|
553
438
|
function insertTurnToDb(sessionId, turn, context) {
|
|
554
439
|
try {
|
|
555
440
|
const db = getAgentDb();
|
|
441
|
+
const now = Date.now();
|
|
556
442
|
const writeTurn2 = db.transaction(() => {
|
|
557
|
-
const now = Date.now();
|
|
558
443
|
const result = db.prepare(`
|
|
559
444
|
INSERT OR IGNORE INTO turns (session_id, turn_number, role, content, agent, model, tool_calls, created_at)
|
|
560
445
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
@@ -581,153 +466,97 @@ function insertTurnToDb(sessionId, turn, context) {
|
|
|
581
466
|
`);
|
|
582
467
|
}
|
|
583
468
|
}
|
|
584
|
-
function
|
|
585
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
586
|
-
const { id, filePath } = generateSessionId(opts.project);
|
|
587
|
-
const meta = {
|
|
588
|
-
id,
|
|
589
|
-
title: opts.title ?? "New Session",
|
|
590
|
-
created: now,
|
|
591
|
-
updated: now,
|
|
592
|
-
agent: opts.agent ?? "chitragupta",
|
|
593
|
-
model: opts.model ?? "unknown",
|
|
594
|
-
provider: opts.provider,
|
|
595
|
-
project: opts.project,
|
|
596
|
-
parent: opts.parentSessionId ?? null,
|
|
597
|
-
branch: opts.branch ?? null,
|
|
598
|
-
tags: opts.tags ?? [],
|
|
599
|
-
totalCost: 0,
|
|
600
|
-
totalTokens: 0,
|
|
601
|
-
metadata: opts.metadata
|
|
602
|
-
};
|
|
603
|
-
if (opts.provider) {
|
|
604
|
-
meta.metadata = { ...meta.metadata, provider: opts.provider };
|
|
605
|
-
}
|
|
606
|
-
const session = { meta, turns: [] };
|
|
607
|
-
saveSession(session);
|
|
608
|
-
upsertSessionToDb(meta, filePath);
|
|
609
|
-
return session;
|
|
610
|
-
}
|
|
611
|
-
function saveSession(session) {
|
|
612
|
-
const filePath = resolveSessionPath(session.meta.id, session.meta.project);
|
|
613
|
-
const dir = path.dirname(filePath);
|
|
469
|
+
function getMaxTurnNumber(sessionId) {
|
|
614
470
|
try {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
atomicRename(tmpPath, filePath);
|
|
621
|
-
cachePut(session.meta.id, session.meta.project, session);
|
|
622
|
-
} catch (err) {
|
|
623
|
-
throw new SessionError(`Failed to save session ${session.meta.id} at ${filePath}: ${err.message}`);
|
|
471
|
+
const db = getAgentDb();
|
|
472
|
+
const row = db.prepare("SELECT MAX(turn_number) as max_turn FROM turns WHERE session_id = ?").get(sessionId);
|
|
473
|
+
return row?.max_turn ?? 0;
|
|
474
|
+
} catch {
|
|
475
|
+
return 0;
|
|
624
476
|
}
|
|
625
477
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
478
|
+
var _dbInitialized, _dbInitError;
|
|
479
|
+
var init_session_db = __esm({
|
|
480
|
+
"../chitragupta/packages/smriti/dist/session-db.js"() {
|
|
481
|
+
"use strict";
|
|
482
|
+
init_dist();
|
|
483
|
+
init_database();
|
|
484
|
+
init_schema();
|
|
485
|
+
_dbInitialized = false;
|
|
486
|
+
_dbInitError = null;
|
|
633
487
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
throw err;
|
|
642
|
-
throw new SessionError(`Failed to load session ${id}: ${err.message}`);
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
// ../chitragupta/packages/smriti/dist/session-store-cache.js
|
|
491
|
+
function estimateSessionBytes(session) {
|
|
492
|
+
let bytes = 200;
|
|
493
|
+
for (const turn of session.turns) {
|
|
494
|
+
bytes += Buffer.byteLength(turn.content, "utf-8") + 50;
|
|
643
495
|
}
|
|
496
|
+
return bytes;
|
|
644
497
|
}
|
|
645
|
-
function
|
|
646
|
-
|
|
647
|
-
const db = getAgentDb();
|
|
648
|
-
let rows;
|
|
649
|
-
if (project) {
|
|
650
|
-
rows = db.prepare("SELECT * FROM sessions WHERE project = ? ORDER BY updated_at DESC").all(project);
|
|
651
|
-
} else {
|
|
652
|
-
rows = db.prepare("SELECT * FROM sessions ORDER BY updated_at DESC").all();
|
|
653
|
-
}
|
|
654
|
-
if (rows.length > 0) {
|
|
655
|
-
return rows.map(rowToSessionMeta);
|
|
656
|
-
}
|
|
657
|
-
} catch (err) {
|
|
658
|
-
process.stderr.write(`[chitragupta] listSessions SQLite failed, falling back to filesystem: ${err instanceof Error ? err.message : err}
|
|
659
|
-
`);
|
|
660
|
-
}
|
|
661
|
-
return listSessionsFromFilesystem(project);
|
|
498
|
+
function cacheKey(id, project) {
|
|
499
|
+
return `${id}:${project}`;
|
|
662
500
|
}
|
|
663
|
-
function
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
|
|
501
|
+
function cacheGet(id, project) {
|
|
502
|
+
const key = cacheKey(id, project);
|
|
503
|
+
const entry = sessionCache.get(key);
|
|
504
|
+
if (!entry)
|
|
505
|
+
return void 0;
|
|
506
|
+
const size = sessionCacheSizes.get(key) ?? 0;
|
|
507
|
+
sessionCache.delete(key);
|
|
508
|
+
sessionCacheSizes.delete(key);
|
|
509
|
+
sessionCache.set(key, entry);
|
|
510
|
+
sessionCacheSizes.set(key, size);
|
|
511
|
+
return entry;
|
|
671
512
|
}
|
|
672
|
-
function
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
if (
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
return allSessions.filter((s) => {
|
|
688
|
-
const created = new Date(s.created).getTime();
|
|
689
|
-
return created >= startMs && created < endMs;
|
|
690
|
-
});
|
|
691
|
-
}
|
|
692
|
-
function listSessionDates(project) {
|
|
693
|
-
try {
|
|
694
|
-
const db = getAgentDb();
|
|
695
|
-
let rows;
|
|
696
|
-
if (project) {
|
|
697
|
-
rows = db.prepare(`SELECT DISTINCT date(created_at / 1000, 'unixepoch') as session_date
|
|
698
|
-
FROM sessions WHERE project = ?
|
|
699
|
-
ORDER BY session_date DESC`).all(project);
|
|
700
|
-
} else {
|
|
701
|
-
rows = db.prepare(`SELECT DISTINCT date(created_at / 1000, 'unixepoch') as session_date
|
|
702
|
-
FROM sessions
|
|
703
|
-
ORDER BY session_date DESC`).all();
|
|
704
|
-
}
|
|
705
|
-
return rows.map((r) => r.session_date).filter(Boolean);
|
|
706
|
-
} catch {
|
|
707
|
-
const allSessions = listSessionsFromFilesystem(project);
|
|
708
|
-
const dates = /* @__PURE__ */ new Set();
|
|
709
|
-
for (const s of allSessions) {
|
|
710
|
-
dates.add(s.created.slice(0, 10));
|
|
711
|
-
}
|
|
712
|
-
return [...dates].sort().reverse();
|
|
513
|
+
function cachePut(id, project, session) {
|
|
514
|
+
const key = cacheKey(id, project);
|
|
515
|
+
const existingSize = sessionCacheSizes.get(key) ?? 0;
|
|
516
|
+
sessionCache.delete(key);
|
|
517
|
+
sessionCacheSizes.delete(key);
|
|
518
|
+
sessionCacheBytes -= existingSize;
|
|
519
|
+
const newSize = estimateSessionBytes(session);
|
|
520
|
+
while ((sessionCache.size >= SESSION_CACHE_MAX || sessionCacheBytes + newSize > SESSION_CACHE_MAX_BYTES) && sessionCache.size > 0) {
|
|
521
|
+
const oldest = sessionCache.keys().next().value;
|
|
522
|
+
if (oldest === void 0)
|
|
523
|
+
break;
|
|
524
|
+
const evictedSize = sessionCacheSizes.get(oldest) ?? 0;
|
|
525
|
+
sessionCache.delete(oldest);
|
|
526
|
+
sessionCacheSizes.delete(oldest);
|
|
527
|
+
sessionCacheBytes -= evictedSize;
|
|
713
528
|
}
|
|
529
|
+
sessionCache.set(key, session);
|
|
530
|
+
sessionCacheSizes.set(key, newSize);
|
|
531
|
+
sessionCacheBytes += newSize;
|
|
714
532
|
}
|
|
715
|
-
function
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
}));
|
|
727
|
-
} catch {
|
|
728
|
-
return [];
|
|
729
|
-
}
|
|
533
|
+
function cacheInvalidate(id, project) {
|
|
534
|
+
const key = cacheKey(id, project);
|
|
535
|
+
const size = sessionCacheSizes.get(key) ?? 0;
|
|
536
|
+
sessionCache.delete(key);
|
|
537
|
+
sessionCacheSizes.delete(key);
|
|
538
|
+
sessionCacheBytes -= size;
|
|
539
|
+
}
|
|
540
|
+
function _resetSessionCache() {
|
|
541
|
+
sessionCache.clear();
|
|
542
|
+
sessionCacheSizes.clear();
|
|
543
|
+
sessionCacheBytes = 0;
|
|
730
544
|
}
|
|
545
|
+
var SESSION_CACHE_MAX, SESSION_CACHE_MAX_BYTES, sessionCache, sessionCacheSizes, sessionCacheBytes;
|
|
546
|
+
var init_session_store_cache = __esm({
|
|
547
|
+
"../chitragupta/packages/smriti/dist/session-store-cache.js"() {
|
|
548
|
+
"use strict";
|
|
549
|
+
SESSION_CACHE_MAX = 500;
|
|
550
|
+
SESSION_CACHE_MAX_BYTES = 25 * 1024 * 1024;
|
|
551
|
+
sessionCache = /* @__PURE__ */ new Map();
|
|
552
|
+
sessionCacheSizes = /* @__PURE__ */ new Map();
|
|
553
|
+
sessionCacheBytes = 0;
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
// ../chitragupta/packages/smriti/dist/session-queries.js
|
|
558
|
+
import fs from "fs";
|
|
559
|
+
import path2 from "path";
|
|
731
560
|
function listSessionsFromFilesystem(project) {
|
|
732
561
|
const sessionsRoot = getSessionsRoot();
|
|
733
562
|
if (!fs.existsSync(sessionsRoot))
|
|
@@ -742,7 +571,7 @@ function listSessionsFromFilesystem(project) {
|
|
|
742
571
|
const projectDirs = fs.readdirSync(sessionsRoot, { withFileTypes: true });
|
|
743
572
|
for (const entry of projectDirs) {
|
|
744
573
|
if (entry.isDirectory()) {
|
|
745
|
-
results.push(...scanDirRecursive(
|
|
574
|
+
results.push(...scanDirRecursive(path2.join(sessionsRoot, entry.name)));
|
|
746
575
|
}
|
|
747
576
|
}
|
|
748
577
|
}
|
|
@@ -754,7 +583,7 @@ function scanDirRecursive(dir) {
|
|
|
754
583
|
try {
|
|
755
584
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
756
585
|
for (const entry of entries) {
|
|
757
|
-
const fullPath =
|
|
586
|
+
const fullPath = path2.join(dir, entry.name);
|
|
758
587
|
if (entry.isDirectory()) {
|
|
759
588
|
metas.push(...scanDirRecursive(fullPath));
|
|
760
589
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -762,85 +591,109 @@ function scanDirRecursive(dir) {
|
|
|
762
591
|
const content = fs.readFileSync(fullPath, "utf-8");
|
|
763
592
|
const session = parseSessionMarkdown(content);
|
|
764
593
|
metas.push(session.meta);
|
|
765
|
-
} catch {
|
|
594
|
+
} catch (err) {
|
|
595
|
+
process.stderr.write(`[smriti:session-queries] skip unparseable file ${fullPath}: ${err instanceof Error ? err.message : String(err)}
|
|
596
|
+
`);
|
|
766
597
|
}
|
|
767
598
|
}
|
|
768
599
|
}
|
|
769
|
-
} catch {
|
|
600
|
+
} catch (err) {
|
|
601
|
+
process.stderr.write(`[smriti:session-queries] directory scan failed for ${dir}: ${err instanceof Error ? err.message : String(err)}
|
|
602
|
+
`);
|
|
770
603
|
}
|
|
771
604
|
return metas;
|
|
772
605
|
}
|
|
773
|
-
function
|
|
774
|
-
const filePath = resolveSessionPath(id, project);
|
|
775
|
-
if (!fs.existsSync(filePath)) {
|
|
776
|
-
throw new SessionError(`Session not found: ${id} (project: ${project})`);
|
|
777
|
-
}
|
|
778
|
-
fs.unlinkSync(filePath);
|
|
779
|
-
cacheInvalidate(id, project);
|
|
780
|
-
let dir = path.dirname(filePath);
|
|
781
|
-
const sessionsRoot = getSessionsRoot();
|
|
782
|
-
while (dir !== sessionsRoot && dir.length > sessionsRoot.length) {
|
|
783
|
-
try {
|
|
784
|
-
const remaining = fs.readdirSync(dir);
|
|
785
|
-
if (remaining.length === 0) {
|
|
786
|
-
fs.rmdirSync(dir);
|
|
787
|
-
dir = path.dirname(dir);
|
|
788
|
-
} else {
|
|
789
|
-
break;
|
|
790
|
-
}
|
|
791
|
-
} catch {
|
|
792
|
-
break;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
606
|
+
function listSessions(project) {
|
|
795
607
|
try {
|
|
796
608
|
const db = getAgentDb();
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
db.prepare("
|
|
609
|
+
let rows;
|
|
610
|
+
if (project) {
|
|
611
|
+
rows = db.prepare("SELECT * FROM sessions WHERE project = ? ORDER BY updated_at DESC").all(project);
|
|
612
|
+
} else {
|
|
613
|
+
rows = db.prepare("SELECT * FROM sessions ORDER BY updated_at DESC").all();
|
|
800
614
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
615
|
+
if (rows.length > 0) {
|
|
616
|
+
return rows.map(rowToSessionMeta);
|
|
617
|
+
}
|
|
618
|
+
} catch (err) {
|
|
619
|
+
process.stderr.write(`[chitragupta] listSessions SQLite failed, falling back to filesystem: ${err instanceof Error ? err.message : err}
|
|
620
|
+
`);
|
|
804
621
|
}
|
|
622
|
+
return listSessionsFromFilesystem(project);
|
|
805
623
|
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
624
|
+
function listSessionsByDate(date, project) {
|
|
625
|
+
const dateMatch = date.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
626
|
+
if (!dateMatch) {
|
|
627
|
+
throw new SessionError(`Invalid date format: ${date}. Expected YYYY-MM-DD.`);
|
|
628
|
+
}
|
|
629
|
+
const startOfDay = (/* @__PURE__ */ new Date(`${date}T00:00:00.000Z`)).getTime();
|
|
630
|
+
const endOfDay = startOfDay + 864e5;
|
|
631
|
+
return listSessionsByDateRange(startOfDay, endOfDay, project);
|
|
632
|
+
}
|
|
633
|
+
function listSessionsByDateRange(startMs, endMs, project) {
|
|
634
|
+
try {
|
|
635
|
+
const db = getAgentDb();
|
|
636
|
+
let rows;
|
|
637
|
+
if (project) {
|
|
638
|
+
rows = db.prepare("SELECT * FROM sessions WHERE project = ? AND created_at >= ? AND created_at < ? ORDER BY created_at ASC").all(project, startMs, endMs);
|
|
639
|
+
} else {
|
|
640
|
+
rows = db.prepare("SELECT * FROM sessions WHERE created_at >= ? AND created_at < ? ORDER BY created_at ASC").all(startMs, endMs);
|
|
814
641
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
try {
|
|
818
|
-
const session = parseSessionMarkdown(fileContent);
|
|
819
|
-
turn.turnNumber = session.turns.length + 1;
|
|
820
|
-
} catch {
|
|
821
|
-
turn.turnNumber = getMaxTurnNumber(sessionId) + 1;
|
|
822
|
-
}
|
|
642
|
+
if (rows.length > 0) {
|
|
643
|
+
return rows.map(rowToSessionMeta);
|
|
823
644
|
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
645
|
+
} catch (err) {
|
|
646
|
+
process.stderr.write(`[smriti:session-queries] listSessionsByDateRange SQLite failed: ${err instanceof Error ? err.message : String(err)}
|
|
647
|
+
`);
|
|
648
|
+
}
|
|
649
|
+
const allSessions = listSessionsFromFilesystem(project);
|
|
650
|
+
return allSessions.filter((s) => {
|
|
651
|
+
const created = new Date(s.created).getTime();
|
|
652
|
+
return created >= startMs && created < endMs;
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
function listSessionDates(project) {
|
|
656
|
+
try {
|
|
657
|
+
const db = getAgentDb();
|
|
658
|
+
let rows;
|
|
659
|
+
if (project) {
|
|
660
|
+
rows = db.prepare(`SELECT DISTINCT date(created_at / 1000, 'unixepoch') as session_date
|
|
661
|
+
FROM sessions WHERE project = ?
|
|
662
|
+
ORDER BY session_date DESC`).all(project);
|
|
663
|
+
} else {
|
|
664
|
+
rows = db.prepare(`SELECT DISTINCT date(created_at / 1000, 'unixepoch') as session_date
|
|
665
|
+
FROM sessions
|
|
666
|
+
ORDER BY session_date DESC`).all();
|
|
828
667
|
}
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
${
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
}).finally(() => {
|
|
838
|
-
if (sessionWriteQueues.get(key) === next) {
|
|
839
|
-
sessionWriteQueues.delete(key);
|
|
668
|
+
return rows.map((r) => r.session_date).filter(Boolean);
|
|
669
|
+
} catch (err) {
|
|
670
|
+
process.stderr.write(`[smriti:session-queries] listSessionDates SQLite failed: ${err instanceof Error ? err.message : String(err)}
|
|
671
|
+
`);
|
|
672
|
+
const allSessions = listSessionsFromFilesystem(project);
|
|
673
|
+
const dates = /* @__PURE__ */ new Set();
|
|
674
|
+
for (const s of allSessions) {
|
|
675
|
+
dates.add(s.created.slice(0, 10));
|
|
840
676
|
}
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
677
|
+
return [...dates].sort().reverse();
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
function listSessionProjects() {
|
|
681
|
+
try {
|
|
682
|
+
const db = getAgentDb();
|
|
683
|
+
const rows = db.prepare(`SELECT project, COUNT(*) as count, MAX(updated_at) as last_active
|
|
684
|
+
FROM sessions
|
|
685
|
+
GROUP BY project
|
|
686
|
+
ORDER BY last_active DESC`).all();
|
|
687
|
+
return rows.map((r) => ({
|
|
688
|
+
project: r.project,
|
|
689
|
+
sessionCount: r.count,
|
|
690
|
+
lastActive: new Date(r.last_active).toISOString()
|
|
691
|
+
}));
|
|
692
|
+
} catch (err) {
|
|
693
|
+
process.stderr.write(`[smriti:session-queries] listSessionProjects SQLite failed: ${err instanceof Error ? err.message : String(err)}
|
|
694
|
+
`);
|
|
695
|
+
return [];
|
|
696
|
+
}
|
|
844
697
|
}
|
|
845
698
|
function listTurnsWithTimestamps(sessionId, project) {
|
|
846
699
|
try {
|
|
@@ -857,17 +710,67 @@ function listTurnsWithTimestamps(sessionId, project) {
|
|
|
857
710
|
createdAt: row.created_at
|
|
858
711
|
}));
|
|
859
712
|
}
|
|
860
|
-
} catch {
|
|
713
|
+
} catch (err) {
|
|
714
|
+
process.stderr.write(`[smriti:session-queries] listTurnsWithTimestamps SQLite failed: ${err instanceof Error ? err.message : String(err)}
|
|
715
|
+
`);
|
|
861
716
|
}
|
|
862
717
|
try {
|
|
863
|
-
const
|
|
718
|
+
const { loadSession: loadSession2 } = (init_session_store(), __toCommonJS(session_store_exports));
|
|
719
|
+
const session = loadSession2(sessionId, project);
|
|
864
720
|
const baseTime = new Date(session.meta.created).getTime();
|
|
865
721
|
return session.turns.map((turn, i) => ({
|
|
866
722
|
...turn,
|
|
867
723
|
createdAt: baseTime + i * 1e3
|
|
868
724
|
// 1-second spacing
|
|
869
725
|
}));
|
|
870
|
-
} catch {
|
|
726
|
+
} catch (err) {
|
|
727
|
+
process.stderr.write(`[smriti:session-queries] listTurnsWithTimestamps markdown fallback failed: ${err instanceof Error ? err.message : String(err)}
|
|
728
|
+
`);
|
|
729
|
+
return [];
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
function findSessionByMetadata(key, value, project) {
|
|
733
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
|
|
734
|
+
return void 0;
|
|
735
|
+
}
|
|
736
|
+
try {
|
|
737
|
+
const db = getAgentDb();
|
|
738
|
+
const sql = project ? "SELECT * FROM sessions WHERE project = ? AND json_extract(metadata, ?) = ? LIMIT 1" : "SELECT * FROM sessions WHERE json_extract(metadata, ?) = ? LIMIT 1";
|
|
739
|
+
const params = project ? [project, `$.${key}`, value] : [`$.${key}`, value];
|
|
740
|
+
const row = db.prepare(sql).get(...params);
|
|
741
|
+
return row ? rowToSessionMeta(row) : void 0;
|
|
742
|
+
} catch (err) {
|
|
743
|
+
process.stderr.write(`[smriti:session-queries] findSessionByMetadata failed: ${err instanceof Error ? err.message : String(err)}
|
|
744
|
+
`);
|
|
745
|
+
return void 0;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
function getTurnsSince(sessionId, sinceTurnNumber) {
|
|
749
|
+
try {
|
|
750
|
+
const db = getAgentDb();
|
|
751
|
+
const rows = db.prepare("SELECT turn_number, role, content, agent, model, tool_calls FROM turns WHERE session_id = ? AND turn_number > ? ORDER BY turn_number ASC").all(sessionId, sinceTurnNumber);
|
|
752
|
+
return rows.map((row) => ({
|
|
753
|
+
turnNumber: row.turn_number,
|
|
754
|
+
role: row.role,
|
|
755
|
+
content: row.content,
|
|
756
|
+
agent: row.agent ?? void 0,
|
|
757
|
+
model: row.model ?? void 0,
|
|
758
|
+
toolCalls: row.tool_calls ? JSON.parse(row.tool_calls) : void 0
|
|
759
|
+
}));
|
|
760
|
+
} catch (err) {
|
|
761
|
+
process.stderr.write(`[smriti:session-queries] getTurnsSince SQLite failed: ${err instanceof Error ? err.message : String(err)}
|
|
762
|
+
`);
|
|
763
|
+
return [];
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
function getSessionsModifiedSince(project, sinceMs) {
|
|
767
|
+
try {
|
|
768
|
+
const db = getAgentDb();
|
|
769
|
+
const rows = db.prepare("SELECT * FROM sessions WHERE project = ? AND updated_at > ? ORDER BY updated_at ASC").all(project, sinceMs);
|
|
770
|
+
return rows.map(rowToSessionMeta);
|
|
771
|
+
} catch (err) {
|
|
772
|
+
process.stderr.write(`[smriti:session-queries] getSessionsModifiedSince SQLite failed: ${err instanceof Error ? err.message : String(err)}
|
|
773
|
+
`);
|
|
871
774
|
return [];
|
|
872
775
|
}
|
|
873
776
|
}
|
|
@@ -897,40 +800,32 @@ function updateSessionMeta(sessionId, updates) {
|
|
|
897
800
|
sets.push("updated_at = @updated_at");
|
|
898
801
|
params.updated_at = Date.now();
|
|
899
802
|
db.prepare(`UPDATE sessions SET ${sets.join(", ")} WHERE id = @id`).run(params);
|
|
900
|
-
} catch {
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
function getMaxTurnNumber(sessionId) {
|
|
904
|
-
try {
|
|
905
|
-
const db = getAgentDb();
|
|
906
|
-
const row = db.prepare("SELECT MAX(turn_number) as max_turn FROM turns WHERE session_id = ?").get(sessionId);
|
|
907
|
-
return row?.max_turn ?? 0;
|
|
908
|
-
} catch {
|
|
909
|
-
return 0;
|
|
803
|
+
} catch (err) {
|
|
804
|
+
process.stderr.write(`[smriti:session-queries] updateSessionMeta failed for ${sessionId}: ${err instanceof Error ? err.message : String(err)}
|
|
805
|
+
`);
|
|
910
806
|
}
|
|
911
807
|
}
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
808
|
+
var init_session_queries = __esm({
|
|
809
|
+
"../chitragupta/packages/smriti/dist/session-queries.js"() {
|
|
810
|
+
"use strict";
|
|
811
|
+
init_dist();
|
|
812
|
+
init_markdown_parser();
|
|
813
|
+
init_session_db();
|
|
814
|
+
init_session_db();
|
|
915
815
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
return row ? rowToSessionMeta(row) : void 0;
|
|
922
|
-
} catch {
|
|
923
|
-
return void 0;
|
|
924
|
-
}
|
|
925
|
-
}
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
// ../chitragupta/packages/smriti/dist/session-store-migration.js
|
|
819
|
+
import fs2 from "fs";
|
|
820
|
+
import path3 from "path";
|
|
926
821
|
function migrateExistingSessions(project) {
|
|
927
822
|
const db = getAgentDb();
|
|
928
823
|
const sessionsRoot = getSessionsRoot();
|
|
929
|
-
if (!
|
|
824
|
+
if (!fs2.existsSync(sessionsRoot))
|
|
930
825
|
return { migrated: 0, skipped: 0 };
|
|
931
826
|
let migrated = 0;
|
|
932
827
|
let skipped = 0;
|
|
933
|
-
const dirs = project ? [getProjectSessionDir(project)] :
|
|
828
|
+
const dirs = project ? [getProjectSessionDir(project)] : fs2.readdirSync(sessionsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path3.join(sessionsRoot, e.name));
|
|
934
829
|
const insertSession = db.prepare(`
|
|
935
830
|
INSERT OR IGNORE INTO sessions (id, project, title, created_at, updated_at, turn_count, model, agent, cost, tokens, tags, file_path, parent_id, branch, metadata)
|
|
936
831
|
VALUES (@id, @project, @title, @created_at, @updated_at, @turn_count, @model, @agent, @cost, @tokens, @tags, @file_path, @parent_id, @branch, @metadata)
|
|
@@ -942,7 +837,7 @@ function migrateExistingSessions(project) {
|
|
|
942
837
|
const insertFts = db.prepare("INSERT INTO turns_fts (rowid, content) VALUES (?, ?)");
|
|
943
838
|
const migrateFile = (mdPath, relativePath) => {
|
|
944
839
|
try {
|
|
945
|
-
const content =
|
|
840
|
+
const content = fs2.readFileSync(mdPath, "utf-8");
|
|
946
841
|
const session = parseSessionMarkdown(content);
|
|
947
842
|
const existing = db.prepare("SELECT id FROM sessions WHERE id = ?").get(session.meta.id);
|
|
948
843
|
if (existing) {
|
|
@@ -965,7 +860,7 @@ function migrateExistingSessions(project) {
|
|
|
965
860
|
};
|
|
966
861
|
const runMigration = db.transaction(() => {
|
|
967
862
|
for (const dir of dirs) {
|
|
968
|
-
if (!
|
|
863
|
+
if (!fs2.existsSync(dir))
|
|
969
864
|
continue;
|
|
970
865
|
walkMdFiles(dir, sessionsRoot, migrateFile);
|
|
971
866
|
}
|
|
@@ -975,41 +870,305 @@ function migrateExistingSessions(project) {
|
|
|
975
870
|
}
|
|
976
871
|
function walkMdFiles(dir, sessionsRoot, callback) {
|
|
977
872
|
try {
|
|
978
|
-
const entries =
|
|
873
|
+
const entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
979
874
|
for (const entry of entries) {
|
|
980
|
-
const fullPath =
|
|
875
|
+
const fullPath = path3.join(dir, entry.name);
|
|
981
876
|
if (entry.isDirectory()) {
|
|
982
877
|
walkMdFiles(fullPath, sessionsRoot, callback);
|
|
983
878
|
} else if (entry.name.endsWith(".md")) {
|
|
984
|
-
const relativePath =
|
|
879
|
+
const relativePath = path3.relative(path3.dirname(sessionsRoot), fullPath);
|
|
985
880
|
callback(fullPath, relativePath);
|
|
986
881
|
}
|
|
987
882
|
}
|
|
988
883
|
} catch {
|
|
989
884
|
}
|
|
990
885
|
}
|
|
886
|
+
var init_session_store_migration = __esm({
|
|
887
|
+
"../chitragupta/packages/smriti/dist/session-store-migration.js"() {
|
|
888
|
+
"use strict";
|
|
889
|
+
init_markdown_parser();
|
|
890
|
+
init_session_db();
|
|
891
|
+
}
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
// ../chitragupta/packages/smriti/dist/session-store.js
|
|
895
|
+
var session_store_exports = {};
|
|
896
|
+
__export(session_store_exports, {
|
|
897
|
+
_getDbStatus: () => _getDbStatus,
|
|
898
|
+
_resetDbInit: () => _resetDbInit,
|
|
899
|
+
_resetSessionCache: () => _resetSessionCache,
|
|
900
|
+
addTurn: () => addTurn,
|
|
901
|
+
createSession: () => createSession,
|
|
902
|
+
deleteSession: () => deleteSession,
|
|
903
|
+
findSessionByMetadata: () => findSessionByMetadata,
|
|
904
|
+
getMaxTurnNumber: () => getMaxTurnNumber,
|
|
905
|
+
getSessionsModifiedSince: () => getSessionsModifiedSince,
|
|
906
|
+
getTurnsSince: () => getTurnsSince,
|
|
907
|
+
listSessionDates: () => listSessionDates,
|
|
908
|
+
listSessionProjects: () => listSessionProjects,
|
|
909
|
+
listSessions: () => listSessions,
|
|
910
|
+
listSessionsByDate: () => listSessionsByDate,
|
|
911
|
+
listSessionsByDateRange: () => listSessionsByDateRange,
|
|
912
|
+
listTurnsWithTimestamps: () => listTurnsWithTimestamps,
|
|
913
|
+
loadSession: () => loadSession,
|
|
914
|
+
migrateExistingSessions: () => migrateExistingSessions,
|
|
915
|
+
saveSession: () => saveSession,
|
|
916
|
+
updateSessionMeta: () => updateSessionMeta
|
|
917
|
+
});
|
|
918
|
+
import fs3 from "fs";
|
|
919
|
+
import { renameSync as nodeRenameSync } from "node:fs";
|
|
920
|
+
import path4 from "path";
|
|
921
|
+
function atomicRename(tmpPath, targetPath) {
|
|
922
|
+
try {
|
|
923
|
+
nodeRenameSync(tmpPath, targetPath);
|
|
924
|
+
} catch (err) {
|
|
925
|
+
if (!process.env.VITEST) {
|
|
926
|
+
process.stderr.write(`[smriti:session-store] atomic rename failed, using direct write: ${err instanceof Error ? err.message : String(err)}
|
|
927
|
+
`);
|
|
928
|
+
}
|
|
929
|
+
fs3.writeFileSync(targetPath, fs3.readFileSync(tmpPath, "utf-8"), "utf-8");
|
|
930
|
+
try {
|
|
931
|
+
fs3.unlinkSync(tmpPath);
|
|
932
|
+
} catch {
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
function generateSessionId(project) {
|
|
937
|
+
const now = /* @__PURE__ */ new Date();
|
|
938
|
+
const yyyy = now.getFullYear().toString();
|
|
939
|
+
const mm = (now.getMonth() + 1).toString().padStart(2, "0");
|
|
940
|
+
const dd = now.getDate().toString().padStart(2, "0");
|
|
941
|
+
const dateStr = `${yyyy}-${mm}-${dd}`;
|
|
942
|
+
const projHash = hashProject(project).slice(0, 8);
|
|
943
|
+
const baseId = `session-${dateStr}-${projHash}`;
|
|
944
|
+
const projectDir = getProjectSessionDir(project);
|
|
945
|
+
const yearMonthDir = path4.join(projectDir, yyyy, mm);
|
|
946
|
+
fs3.mkdirSync(yearMonthDir, { recursive: true });
|
|
947
|
+
const basePath = path4.join(yearMonthDir, `${baseId}.md`);
|
|
948
|
+
if (!fs3.existsSync(basePath)) {
|
|
949
|
+
return {
|
|
950
|
+
id: baseId,
|
|
951
|
+
filePath: path4.join("sessions", hashProject(project), yyyy, mm, `${baseId}.md`)
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
let counter = 2;
|
|
955
|
+
while (fs3.existsSync(path4.join(yearMonthDir, `${baseId}-${counter}.md`))) {
|
|
956
|
+
counter++;
|
|
957
|
+
}
|
|
958
|
+
const id = `${baseId}-${counter}`;
|
|
959
|
+
return {
|
|
960
|
+
id,
|
|
961
|
+
filePath: path4.join("sessions", hashProject(project), yyyy, mm, `${id}.md`)
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
function resolveSessionPath(id, project) {
|
|
965
|
+
const projectDir = getProjectSessionDir(project);
|
|
966
|
+
const dateMatch = id.match(/^session-(\d{4})-(\d{2})-\d{2}/);
|
|
967
|
+
if (dateMatch) {
|
|
968
|
+
const newPath = path4.join(projectDir, dateMatch[1], dateMatch[2], `${id}.md`);
|
|
969
|
+
if (fs3.existsSync(newPath))
|
|
970
|
+
return newPath;
|
|
971
|
+
}
|
|
972
|
+
const oldPath = path4.join(projectDir, `${id}.md`);
|
|
973
|
+
if (fs3.existsSync(oldPath))
|
|
974
|
+
return oldPath;
|
|
975
|
+
if (dateMatch) {
|
|
976
|
+
return path4.join(projectDir, dateMatch[1], dateMatch[2], `${id}.md`);
|
|
977
|
+
}
|
|
978
|
+
return oldPath;
|
|
979
|
+
}
|
|
980
|
+
function patchFrontmatterUpdated(content, updatedIso) {
|
|
981
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
982
|
+
if (!fmMatch)
|
|
983
|
+
return content;
|
|
984
|
+
const frontmatter = fmMatch[1];
|
|
985
|
+
if (!/^updated:\s/m.test(frontmatter))
|
|
986
|
+
return content;
|
|
987
|
+
const patchedFrontmatter = frontmatter.replace(/^updated:\s.*$/m, `updated: ${updatedIso}`);
|
|
988
|
+
if (patchedFrontmatter === frontmatter)
|
|
989
|
+
return content;
|
|
990
|
+
return `---
|
|
991
|
+
${patchedFrontmatter}
|
|
992
|
+
---${content.slice(fmMatch[0].length)}`;
|
|
993
|
+
}
|
|
994
|
+
function createSession(opts) {
|
|
995
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
996
|
+
const { id, filePath } = generateSessionId(opts.project);
|
|
997
|
+
const meta = {
|
|
998
|
+
id,
|
|
999
|
+
title: opts.title ?? "New Session",
|
|
1000
|
+
created: now,
|
|
1001
|
+
updated: now,
|
|
1002
|
+
agent: opts.agent ?? "chitragupta",
|
|
1003
|
+
model: opts.model ?? "unknown",
|
|
1004
|
+
provider: opts.provider,
|
|
1005
|
+
project: opts.project,
|
|
1006
|
+
parent: opts.parentSessionId ?? null,
|
|
1007
|
+
branch: opts.branch ?? null,
|
|
1008
|
+
tags: opts.tags ?? [],
|
|
1009
|
+
totalCost: 0,
|
|
1010
|
+
totalTokens: 0,
|
|
1011
|
+
metadata: opts.metadata
|
|
1012
|
+
};
|
|
1013
|
+
if (opts.provider) {
|
|
1014
|
+
meta.metadata = { ...meta.metadata, provider: opts.provider };
|
|
1015
|
+
}
|
|
1016
|
+
const session = { meta, turns: [] };
|
|
1017
|
+
saveSession(session);
|
|
1018
|
+
upsertSessionToDb(meta, filePath);
|
|
1019
|
+
return session;
|
|
1020
|
+
}
|
|
1021
|
+
function saveSession(session) {
|
|
1022
|
+
const filePath = resolveSessionPath(session.meta.id, session.meta.project);
|
|
1023
|
+
const dir = path4.dirname(filePath);
|
|
1024
|
+
try {
|
|
1025
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
1026
|
+
session.meta.updated = (/* @__PURE__ */ new Date()).toISOString();
|
|
1027
|
+
const markdown = writeSessionMarkdown(session);
|
|
1028
|
+
const tmpPath = `${filePath}.tmp.${process.pid}`;
|
|
1029
|
+
fs3.writeFileSync(tmpPath, markdown, "utf-8");
|
|
1030
|
+
atomicRename(tmpPath, filePath);
|
|
1031
|
+
cachePut(session.meta.id, session.meta.project, session);
|
|
1032
|
+
} catch (err) {
|
|
1033
|
+
throw new SessionError(`Failed to save session ${session.meta.id} at ${filePath}: ${err.message}`);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
function loadSession(id, project) {
|
|
1037
|
+
const cached = cacheGet(id, project);
|
|
1038
|
+
if (cached)
|
|
1039
|
+
return cached;
|
|
1040
|
+
const filePath = resolveSessionPath(id, project);
|
|
1041
|
+
if (!fs3.existsSync(filePath)) {
|
|
1042
|
+
throw new SessionError(`Session not found: ${id} (project: ${project})`);
|
|
1043
|
+
}
|
|
1044
|
+
try {
|
|
1045
|
+
const content = fs3.readFileSync(filePath, "utf-8");
|
|
1046
|
+
const session = parseSessionMarkdown(content);
|
|
1047
|
+
cachePut(id, project, session);
|
|
1048
|
+
return session;
|
|
1049
|
+
} catch (err) {
|
|
1050
|
+
if (err instanceof SessionError)
|
|
1051
|
+
throw err;
|
|
1052
|
+
throw new SessionError(`Failed to load session ${id}: ${err.message}`);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
function deleteSession(id, project) {
|
|
1056
|
+
const filePath = resolveSessionPath(id, project);
|
|
1057
|
+
if (!fs3.existsSync(filePath)) {
|
|
1058
|
+
throw new SessionError(`Session not found: ${id} (project: ${project})`);
|
|
1059
|
+
}
|
|
1060
|
+
fs3.unlinkSync(filePath);
|
|
1061
|
+
cacheInvalidate(id, project);
|
|
1062
|
+
let dir = path4.dirname(filePath);
|
|
1063
|
+
const sessionsRoot = getSessionsRoot();
|
|
1064
|
+
while (dir !== sessionsRoot && dir.length > sessionsRoot.length) {
|
|
1065
|
+
try {
|
|
1066
|
+
const remaining = fs3.readdirSync(dir);
|
|
1067
|
+
if (remaining.length === 0) {
|
|
1068
|
+
fs3.rmdirSync(dir);
|
|
1069
|
+
dir = path4.dirname(dir);
|
|
1070
|
+
} else {
|
|
1071
|
+
break;
|
|
1072
|
+
}
|
|
1073
|
+
} catch {
|
|
1074
|
+
break;
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
try {
|
|
1078
|
+
const db = getAgentDb();
|
|
1079
|
+
const turns = db.prepare("SELECT id FROM turns WHERE session_id = ?").all(id);
|
|
1080
|
+
for (const t of turns) {
|
|
1081
|
+
db.prepare("DELETE FROM turns_fts WHERE rowid = ?").run(t.id);
|
|
1082
|
+
}
|
|
1083
|
+
db.prepare("DELETE FROM turns WHERE session_id = ?").run(id);
|
|
1084
|
+
db.prepare("DELETE FROM sessions WHERE id = ?").run(id);
|
|
1085
|
+
} catch (err) {
|
|
1086
|
+
process.stderr.write(`[smriti:session-store] deleteSession SQLite cleanup failed for ${id}: ${err instanceof Error ? err.message : String(err)}
|
|
1087
|
+
`);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
function addTurn(sessionId, project, turn) {
|
|
1091
|
+
const key = `${sessionId}:${project}`;
|
|
1092
|
+
const prev = sessionWriteQueues.get(key) ?? Promise.resolve();
|
|
1093
|
+
const next = prev.then(() => {
|
|
1094
|
+
const filePath = resolveSessionPath(sessionId, project);
|
|
1095
|
+
if (!fs3.existsSync(filePath)) {
|
|
1096
|
+
throw new SessionError(`Session not found: ${sessionId} (project: ${project})`);
|
|
1097
|
+
}
|
|
1098
|
+
const fileContent = fs3.readFileSync(filePath, "utf-8");
|
|
1099
|
+
if (!turn.turnNumber) {
|
|
1100
|
+
try {
|
|
1101
|
+
const session = parseSessionMarkdown(fileContent);
|
|
1102
|
+
turn.turnNumber = session.turns.length + 1;
|
|
1103
|
+
} catch {
|
|
1104
|
+
turn.turnNumber = getMaxTurnNumber(sessionId) + 1;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
const updatedIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
1108
|
+
const patchedContent = patchFrontmatterUpdated(fileContent, updatedIso);
|
|
1109
|
+
if (patchedContent !== fileContent) {
|
|
1110
|
+
fs3.writeFileSync(filePath, patchedContent, "utf-8");
|
|
1111
|
+
}
|
|
1112
|
+
const turnMd = writeTurnMarkdown(turn);
|
|
1113
|
+
fs3.appendFileSync(filePath, `
|
|
1114
|
+
${turnMd}
|
|
1115
|
+
`, "utf-8");
|
|
1116
|
+
cacheInvalidate(sessionId, project);
|
|
1117
|
+
insertTurnToDb(sessionId, turn, { project, filePath });
|
|
1118
|
+
}).catch((err) => {
|
|
1119
|
+
throw err;
|
|
1120
|
+
}).finally(() => {
|
|
1121
|
+
if (sessionWriteQueues.get(key) === next) {
|
|
1122
|
+
sessionWriteQueues.delete(key);
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
sessionWriteQueues.set(key, next);
|
|
1126
|
+
return next;
|
|
1127
|
+
}
|
|
1128
|
+
var sessionWriteQueues;
|
|
1129
|
+
var init_session_store = __esm({
|
|
1130
|
+
"../chitragupta/packages/smriti/dist/session-store.js"() {
|
|
1131
|
+
init_dist();
|
|
1132
|
+
init_markdown_parser();
|
|
1133
|
+
init_markdown_writer();
|
|
1134
|
+
init_session_db();
|
|
1135
|
+
init_session_store_cache();
|
|
1136
|
+
init_session_store_cache();
|
|
1137
|
+
init_session_db();
|
|
1138
|
+
init_session_queries();
|
|
1139
|
+
init_session_store_migration();
|
|
1140
|
+
sessionWriteQueues = /* @__PURE__ */ new Map();
|
|
1141
|
+
}
|
|
1142
|
+
});
|
|
991
1143
|
|
|
992
1144
|
export {
|
|
993
1145
|
parseSessionMarkdown,
|
|
1146
|
+
init_markdown_parser,
|
|
994
1147
|
writeSessionMarkdown,
|
|
995
1148
|
writeTurnMarkdown,
|
|
996
|
-
|
|
1149
|
+
init_markdown_writer,
|
|
1150
|
+
getAgentDb,
|
|
997
1151
|
_resetDbInit,
|
|
998
1152
|
_getDbStatus,
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1153
|
+
getMaxTurnNumber,
|
|
1154
|
+
init_session_db,
|
|
1155
|
+
_resetSessionCache,
|
|
1002
1156
|
listSessions,
|
|
1003
1157
|
listSessionsByDate,
|
|
1004
1158
|
listSessionsByDateRange,
|
|
1005
1159
|
listSessionDates,
|
|
1006
1160
|
listSessionProjects,
|
|
1007
|
-
deleteSession,
|
|
1008
|
-
addTurn,
|
|
1009
1161
|
listTurnsWithTimestamps,
|
|
1010
|
-
updateSessionMeta,
|
|
1011
|
-
getMaxTurnNumber,
|
|
1012
1162
|
findSessionByMetadata,
|
|
1013
|
-
|
|
1163
|
+
getTurnsSince,
|
|
1164
|
+
getSessionsModifiedSince,
|
|
1165
|
+
updateSessionMeta,
|
|
1166
|
+
migrateExistingSessions,
|
|
1167
|
+
createSession,
|
|
1168
|
+
saveSession,
|
|
1169
|
+
loadSession,
|
|
1170
|
+
deleteSession,
|
|
1171
|
+
addTurn,
|
|
1172
|
+
init_session_store
|
|
1014
1173
|
};
|
|
1015
|
-
//# sourceMappingURL=chunk-
|
|
1174
|
+
//# sourceMappingURL=chunk-FEDPZOZ5.js.map
|