@yugenlab/vaayu 0.1.10 → 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.
Files changed (53) hide show
  1. package/chunks/{agentic-tool-loop-2FZK72JO.js → agentic-tool-loop-NQESOBLC.js} +2 -2
  2. package/chunks/akasha-5C5Q6NMP.js +12 -0
  3. package/chunks/{chunk-JGI4SDWS.js → chunk-26K6DS6N.js} +7 -5
  4. package/chunks/chunk-5E3ZS5SW.js +529 -0
  5. package/chunks/{chunk-VJHNE47S.js → chunk-ARZCIITZ.js} +104 -94
  6. package/chunks/{chunk-PRXQW76U.js → chunk-EG37M4QL.js} +17 -6
  7. package/chunks/{chunk-HIYHTWFW.js → chunk-FEDPZOZ5.js} +572 -441
  8. package/chunks/{chunk-O4KV7TFP.js → chunk-GWYC7R2L.js} +38 -20
  9. package/chunks/chunk-H46F2Y6R.js +134 -0
  10. package/chunks/{chunk-M7THR63C.js → chunk-HXHDP2PZ.js} +78 -65
  11. package/chunks/chunk-KVQH4LE7.js +396 -0
  12. package/chunks/{chunk-TND3MU4Z.js → chunk-LJCT7UYP.js} +86 -68
  13. package/chunks/{chunk-OT4G2L46.js → chunk-M2RLX5LU.js} +229 -163
  14. package/chunks/{chunk-IGKYKEKT.js → chunk-NAQKA54E.js} +8 -2
  15. package/chunks/{chunk-77725AR7.js → chunk-PZ4AQ22L.js} +151 -57
  16. package/chunks/{chunk-C76USAC5.js → chunk-QFGAB4XD.js} +13 -5
  17. package/chunks/{chunk-MJ74G5RB.js → chunk-R273KC7J.js} +276 -3
  18. package/chunks/{chunk-JAWZ7ANC.js → chunk-RVKTGKFD.js} +12 -8
  19. package/chunks/{chunk-AGK3A7R7.js → chunk-TSOQ2CT3.js} +1430 -1173
  20. package/chunks/{chunk-YJRXLRTE.js → chunk-VEZ2DI2M.js} +24 -12
  21. package/chunks/{chunk-N22M7D4P.js → chunk-XP3NIH5F.js} +91 -98
  22. package/chunks/{chunk-6556EKOB.js → chunk-Y6IZH6FT.js} +42 -26
  23. package/chunks/{chunk-AS3DJFY3.js → chunk-YRTGGYJU.js} +45 -41
  24. package/chunks/{consolidation-indexer-VKQ6DNU3.js → consolidation-indexer-KPXORCJ4.js} +9 -9
  25. package/chunks/database-BX3LVYXS.js +11 -0
  26. package/chunks/{day-consolidation-BH3QU2SZ.js → day-consolidation-CR3TJFAL.js} +5 -5
  27. package/chunks/{src-Y3TGMINC.js → dist-ESCM3CP5.js} +31 -21
  28. package/chunks/graphrag-73XA7LBX.js +14 -0
  29. package/chunks/hierarchical-temporal-search-GHKVKNZ6.js +8 -0
  30. package/chunks/hybrid-search-OD756RDV.js +20 -0
  31. package/chunks/{memory-store-A6WOWLWC.js → memory-store-4GCBR2DZ.js} +4 -4
  32. package/chunks/periodic-consolidation-IINCHP6L.js +11 -0
  33. package/chunks/postgres-YLCUNVPQ.js +8 -0
  34. package/chunks/recall-64RROTUC.js +21 -0
  35. package/chunks/search-JVCDNTAJ.js +19 -0
  36. package/chunks/{session-store-3BRPGC6P.js → session-store-3EDQZEDS.js} +12 -6
  37. package/chunks/{sqlite-DHUQGPR5.js → sqlite-4N7YH2KK.js} +3 -3
  38. package/chunks/{src-6GVZTUH6.js → src-OPSDZEFI.js} +2 -2
  39. package/chunks/{suncalc-NOHGYHDU.js → suncalc-RM7URNUR.js} +2 -2
  40. package/chunks/{tree-RSHKDTCR.js → tree-FIUVGJ5J.js} +2 -2
  41. package/chunks/{vasana-engine-MU25OQ23.js → vasana-engine-W4PYWT5H.js} +5 -5
  42. package/gateway.js +38859 -30650
  43. package/package.json +1 -1
  44. package/pair-cli.js +2 -2
  45. package/chunks/chunk-U62ABYKD.js +0 -123
  46. package/chunks/chunk-UZ6OIVEC.js +0 -198
  47. package/chunks/graphrag-D7OXWAWD.js +0 -14
  48. package/chunks/hierarchical-temporal-search-PVHVA3NZ.js +0 -8
  49. package/chunks/hybrid-search-G2NAJKJ7.js +0 -20
  50. package/chunks/periodic-consolidation-LMYMNS4Q.js +0 -11
  51. package/chunks/postgres-WLH3D5HG.js +0 -8
  52. package/chunks/recall-ZNL4DJ2L.js +0 -21
  53. package/chunks/search-35JMSGUT.js +0 -19
@@ -1,32 +1,43 @@
1
1
  import {
2
2
  getDayFilePath,
3
3
  listDayFiles
4
- } from "./chunk-77725AR7.js";
4
+ } from "./chunk-PZ4AQ22L.js";
5
5
  import {
6
6
  PRESERVATION_RATIOS,
7
7
  RecallEngine,
8
8
  STREAM_ORDER,
9
9
  StreamManager
10
- } from "./chunk-VJHNE47S.js";
10
+ } from "./chunk-ARZCIITZ.js";
11
11
  import {
12
12
  createSession,
13
+ getAgentDb,
14
+ init_markdown_parser,
15
+ init_markdown_writer,
16
+ init_session_db,
17
+ init_session_store,
13
18
  listSessions,
14
19
  loadSession,
15
20
  saveSession
16
- } from "./chunk-HIYHTWFW.js";
21
+ } from "./chunk-FEDPZOZ5.js";
17
22
  import {
18
23
  cosineSimilarity,
19
24
  estimateTokens
20
- } from "./chunk-JAWZ7ANC.js";
25
+ } from "./chunk-RVKTGKFD.js";
21
26
  import {
22
27
  DatabaseManager
23
- } from "./chunk-U62ABYKD.js";
28
+ } from "./chunk-H46F2Y6R.js";
24
29
  import {
25
30
  SessionError,
26
- getChitraguptaHome
27
- } from "./chunk-UZ6OIVEC.js";
31
+ getChitraguptaHome,
32
+ init_dist
33
+ } from "./chunk-KVQH4LE7.js";
28
34
 
29
- // ../chitragupta/packages/smriti/src/session-export.ts
35
+ // ../chitragupta/packages/smriti/dist/index.js
36
+ init_markdown_parser();
37
+ init_markdown_writer();
38
+ init_session_store();
39
+
40
+ // ../chitragupta/packages/smriti/dist/session-export.js
30
41
  function exportSessionToJson(session) {
31
42
  const messages = session.turns.map((turn) => {
32
43
  const msg = {
@@ -34,8 +45,10 @@ function exportSessionToJson(session) {
34
45
  content: turn.content,
35
46
  turnNumber: turn.turnNumber
36
47
  };
37
- if (turn.agent) msg.agent = turn.agent;
38
- if (turn.model) msg.model = turn.model;
48
+ if (turn.agent)
49
+ msg.agent = turn.agent;
50
+ if (turn.model)
51
+ msg.model = turn.model;
39
52
  if (turn.toolCalls && turn.toolCalls.length > 0) {
40
53
  msg.toolCalls = turn.toolCalls.map((tc) => {
41
54
  const exported = {
@@ -43,7 +56,8 @@ function exportSessionToJson(session) {
43
56
  input: tc.input,
44
57
  result: tc.result
45
58
  };
46
- if (tc.isError) exported.isError = true;
59
+ if (tc.isError)
60
+ exported.isError = true;
47
61
  return exported;
48
62
  });
49
63
  }
@@ -157,8 +171,10 @@ function importSessionFromJson(data) {
157
171
  role: msg.role,
158
172
  content: msg.content
159
173
  };
160
- if (msg.agent) turn.agent = msg.agent;
161
- if (msg.model) turn.model = msg.model;
174
+ if (msg.agent)
175
+ turn.agent = msg.agent;
176
+ if (msg.model)
177
+ turn.model = msg.model;
162
178
  if (msg.toolCalls && msg.toolCalls.length > 0) {
163
179
  turn.toolCalls = msg.toolCalls.map((tc) => {
164
180
  const toolCall = {
@@ -166,7 +182,8 @@ function importSessionFromJson(data) {
166
182
  input: tc.input,
167
183
  result: tc.result
168
184
  };
169
- if (tc.isError) toolCall.isError = true;
185
+ if (tc.isError)
186
+ toolCall.isError = true;
170
187
  return toolCall;
171
188
  });
172
189
  }
@@ -228,13 +245,15 @@ function validateExportedSession(data) {
228
245
  }
229
246
  }
230
247
 
231
- // ../chitragupta/packages/smriti/src/cross-machine-sync.ts
248
+ // ../chitragupta/packages/smriti/dist/cross-machine-sync.js
249
+ init_dist();
232
250
  import fs2 from "node:fs";
233
251
  import os from "node:os";
234
252
  import path2 from "node:path";
235
253
  import crypto2 from "node:crypto";
236
254
 
237
- // ../chitragupta/packages/smriti/src/sync-import.ts
255
+ // ../chitragupta/packages/smriti/dist/sync-import.js
256
+ init_dist();
238
257
  import fs from "node:fs";
239
258
  import path from "node:path";
240
259
  import crypto from "node:crypto";
@@ -288,16 +307,21 @@ function splitMemory(content) {
288
307
  function mergeMemory(localContent, remoteContent) {
289
308
  const localTrimmed = localContent.trim();
290
309
  const remoteTrimmed = remoteContent.trim();
291
- if (!localTrimmed) return remoteTrimmed ? `${remoteTrimmed}
310
+ if (!localTrimmed)
311
+ return remoteTrimmed ? `${remoteTrimmed}
292
312
  ` : "";
293
- if (!remoteTrimmed) return localContent.endsWith("\n") ? localContent : `${localContent}
313
+ if (!remoteTrimmed)
314
+ return localContent.endsWith("\n") ? localContent : `${localContent}
294
315
  `;
295
- if (localContent === remoteContent) return localContent;
316
+ if (localContent === remoteContent)
317
+ return localContent;
296
318
  const local = splitMemory(localContent);
297
319
  const remote = splitMemory(remoteContent);
298
320
  if (local.entries.length === 0 && remote.entries.length === 0) {
299
- if (localContent.includes(remoteContent)) return localContent;
300
- if (remoteContent.includes(localContent)) return remoteContent;
321
+ if (localContent.includes(remoteContent))
322
+ return localContent;
323
+ if (remoteContent.includes(localContent))
324
+ return remoteContent;
301
325
  return `${localContent.trimEnd()}
302
326
 
303
327
  ---
@@ -310,7 +334,8 @@ ${remoteContent.trim()}
310
334
  const mergedEntries = [];
311
335
  for (const entry of [...local.entries, ...remote.entries]) {
312
336
  const key = sha256(entry.replace(/\s+/g, " ").trim().toLowerCase());
313
- if (seen.has(key)) continue;
337
+ if (seen.has(key))
338
+ continue;
314
339
  seen.add(key);
315
340
  mergedEntries.push(entry.trim());
316
341
  }
@@ -318,13 +343,15 @@ ${remoteContent.trim()}
318
343
  if (mergedEntries.length > 0) {
319
344
  merged += ENTRY_SEPARATOR + mergedEntries.join(ENTRY_SEPARATOR);
320
345
  }
321
- if (!merged.endsWith("\n")) merged += "\n";
346
+ if (!merged.endsWith("\n"))
347
+ merged += "\n";
322
348
  return merged;
323
349
  }
324
350
  function readSyncState(home) {
325
351
  const statePath = path.join(home, "sync-state.json");
326
352
  try {
327
- if (!fs.existsSync(statePath)) return {};
353
+ if (!fs.existsSync(statePath))
354
+ return {};
328
355
  const raw = fs.readFileSync(statePath, "utf-8");
329
356
  const parsed = JSON.parse(raw);
330
357
  return parsed && typeof parsed === "object" ? parsed : {};
@@ -368,7 +395,8 @@ function importCrossMachineSnapshot(source, options) {
368
395
  }
369
396
  const targetPath = resolveSnapshotPath(file.path, home);
370
397
  if (!fs.existsSync(targetPath)) {
371
- if (!dryRun) writeTextFile(targetPath, file.content);
398
+ if (!dryRun)
399
+ writeTextFile(targetPath, file.content);
372
400
  totals.created += 1;
373
401
  changedPaths.push(file.path);
374
402
  continue;
@@ -384,13 +412,15 @@ function importCrossMachineSnapshot(source, options) {
384
412
  totals.skipped += 1;
385
413
  continue;
386
414
  }
387
- if (!dryRun) writeTextFile(targetPath, merged);
415
+ if (!dryRun)
416
+ writeTextFile(targetPath, merged);
388
417
  totals.merged += 1;
389
418
  changedPaths.push(file.path);
390
419
  continue;
391
420
  }
392
421
  if (strategy === "preferRemote") {
393
- if (!dryRun) writeTextFile(targetPath, file.content);
422
+ if (!dryRun)
423
+ writeTextFile(targetPath, file.content);
394
424
  totals.updated += 1;
395
425
  changedPaths.push(file.path);
396
426
  continue;
@@ -400,7 +430,8 @@ function importCrossMachineSnapshot(source, options) {
400
430
  continue;
401
431
  }
402
432
  const conflictPath = createConflictPath(conflictRoot, file.path);
403
- if (!dryRun) writeTextFile(conflictPath, file.content);
433
+ if (!dryRun)
434
+ writeTextFile(conflictPath, file.content);
404
435
  totals.conflicts += 1;
405
436
  conflictPaths.push(toPortablePath(conflictPath, home));
406
437
  } catch {
@@ -458,7 +489,7 @@ function assertSnapshot(value) {
458
489
  }
459
490
  }
460
491
 
461
- // ../chitragupta/packages/smriti/src/cross-machine-sync.ts
492
+ // ../chitragupta/packages/smriti/dist/cross-machine-sync.js
462
493
  var SNAPSHOT_VERSION2 = 1;
463
494
  function sha2562(content) {
464
495
  return crypto2.createHash("sha256").update(content, "utf-8").digest("hex");
@@ -471,7 +502,8 @@ function toPortablePath2(absPath, home) {
471
502
  return rel.split(path2.sep).join("/");
472
503
  }
473
504
  function listMemoryFiles(memoryRoot) {
474
- if (!fs2.existsSync(memoryRoot)) return [];
505
+ if (!fs2.existsSync(memoryRoot))
506
+ return [];
475
507
  const stack = [memoryRoot];
476
508
  const files = [];
477
509
  while (stack.length > 0) {
@@ -498,7 +530,8 @@ function listMemoryFiles(memoryRoot) {
498
530
  function readSyncState2(home) {
499
531
  const statePath = path2.join(home, "sync-state.json");
500
532
  try {
501
- if (!fs2.existsSync(statePath)) return {};
533
+ if (!fs2.existsSync(statePath))
534
+ return {};
502
535
  const raw = fs2.readFileSync(statePath, "utf-8");
503
536
  const parsed = JSON.parse(raw);
504
537
  return parsed && typeof parsed === "object" ? parsed : {};
@@ -557,7 +590,8 @@ function createCrossMachineSnapshot(options) {
557
590
  }
558
591
  for (const date of dates) {
559
592
  const absPath = getDayFilePath(date);
560
- if (!fs2.existsSync(absPath)) continue;
593
+ if (!fs2.existsSync(absPath))
594
+ continue;
561
595
  try {
562
596
  const content = fs2.readFileSync(absPath, "utf-8");
563
597
  const stat = fs2.statSync(absPath);
@@ -633,16 +667,16 @@ function getCrossMachineSyncStatus() {
633
667
  };
634
668
  }
635
669
 
636
- // ../chitragupta/packages/smriti/src/branch.ts
670
+ // ../chitragupta/packages/smriti/dist/branch.js
671
+ init_dist();
672
+ init_session_store();
637
673
  function branchSession(sessionId, project, branchName, fromTurn) {
638
674
  const original = loadSession(sessionId, project);
639
675
  let turnsToKeep = original.turns;
640
676
  if (fromTurn !== void 0) {
641
677
  turnsToKeep = original.turns.filter((t) => t.turnNumber <= fromTurn);
642
678
  if (turnsToKeep.length === 0 && original.turns.length > 0) {
643
- throw new SessionError(
644
- `No turns found at or before turn ${fromTurn} in session ${sessionId}`
645
- );
679
+ throw new SessionError(`No turns found at or before turn ${fromTurn} in session ${sessionId}`);
646
680
  }
647
681
  }
648
682
  const branched = createSession({
@@ -735,7 +769,7 @@ function createSyntheticRoot(project) {
735
769
  };
736
770
  }
737
771
 
738
- // ../chitragupta/packages/smriti/src/sinkhorn-knopp.ts
772
+ // ../chitragupta/packages/smriti/dist/sinkhorn-knopp.js
739
773
  function sinkhornKnopp(matrix, maxIterations = 100, epsilon = 1e-6) {
740
774
  const n = matrix.length;
741
775
  if (n === 0) {
@@ -748,7 +782,8 @@ function sinkhornKnopp(matrix, maxIterations = 100, epsilon = 1e-6) {
748
782
  const A = matrix.map((row) => [...row]);
749
783
  for (let i = 0; i < n; i++) {
750
784
  for (let j = 0; j < m; j++) {
751
- if (A[i][j] < 0) A[i][j] = 0;
785
+ if (A[i][j] < 0)
786
+ A[i][j] = 0;
752
787
  }
753
788
  }
754
789
  for (let i = 0; i < n; i++) {
@@ -797,7 +832,8 @@ function sinkhornKnopp(matrix, maxIterations = 100, epsilon = 1e-6) {
797
832
  for (let i = 0; i < n; i++) {
798
833
  const rowSum = A[i].reduce((s, v) => s + v, 0);
799
834
  const dev = Math.abs(rowSum - 1);
800
- if (dev > maxDeviation2) maxDeviation2 = dev;
835
+ if (dev > maxDeviation2)
836
+ maxDeviation2 = dev;
801
837
  }
802
838
  for (let j = 0; j < m; j++) {
803
839
  let colSum = 0;
@@ -805,7 +841,8 @@ function sinkhornKnopp(matrix, maxIterations = 100, epsilon = 1e-6) {
805
841
  colSum += A[i][j];
806
842
  }
807
843
  const dev = Math.abs(colSum - 1);
808
- if (dev > maxDeviation2) maxDeviation2 = dev;
844
+ if (dev > maxDeviation2)
845
+ maxDeviation2 = dev;
809
846
  }
810
847
  if (maxDeviation2 < epsilon) {
811
848
  converged = true;
@@ -856,7 +893,8 @@ function buildAffinityMatrix(signals) {
856
893
  }
857
894
  function computeTokenBudgets(mixingMatrix, totalBudget, preservationRatios = PRESERVATION_RATIOS) {
858
895
  const n = mixingMatrix.length;
859
- if (n === 0) return [];
896
+ if (n === 0)
897
+ return [];
860
898
  const weights = [];
861
899
  for (let j = 0; j < n; j++) {
862
900
  let colSum = 0;
@@ -879,7 +917,8 @@ function computeTokenBudgets(mixingMatrix, totalBudget, preservationRatios = PRE
879
917
  let remainder = totalBudget - allocated;
880
918
  const sortedIndices = preservationRatios.map((r, i) => ({ ratio: r, index: i })).sort((a, b) => b.ratio - a.ratio).map((x) => x.index);
881
919
  for (const idx of sortedIndices) {
882
- if (remainder <= 0) break;
920
+ if (remainder <= 0)
921
+ break;
883
922
  budgets[idx] += 1;
884
923
  remainder -= 1;
885
924
  }
@@ -892,7 +931,7 @@ function allocateBudgets(signals, totalBudget) {
892
931
  return { budgets, mixingMatrix, converged };
893
932
  }
894
933
 
895
- // ../chitragupta/packages/smriti/src/compactor-signals.ts
934
+ // ../chitragupta/packages/smriti/dist/compactor-signals.js
896
935
  var OLLAMA_ENDPOINT = process.env.OLLAMA_HOST ?? "http://localhost:11434";
897
936
  var GENERATION_MODEL = "llama3.2";
898
937
  function configureCompactorSignals(options) {
@@ -948,7 +987,8 @@ function keywordExtractSignals(session) {
948
987
  break;
949
988
  }
950
989
  }
951
- if (matched) continue;
990
+ if (matched)
991
+ continue;
952
992
  for (const pattern of PROJECT_PATTERNS) {
953
993
  if (pattern.test(sentence)) {
954
994
  signals.projects.push(sentence.slice(0, 200));
@@ -956,7 +996,8 @@ function keywordExtractSignals(session) {
956
996
  break;
957
997
  }
958
998
  }
959
- if (matched) continue;
999
+ if (matched)
1000
+ continue;
960
1001
  for (const pattern of TASK_PATTERNS) {
961
1002
  if (pattern.test(sentence)) {
962
1003
  signals.tasks.push(sentence.slice(0, 200));
@@ -964,7 +1005,8 @@ function keywordExtractSignals(session) {
964
1005
  break;
965
1006
  }
966
1007
  }
967
- if (matched) continue;
1008
+ if (matched)
1009
+ continue;
968
1010
  for (const pattern of FLOW_PATTERNS) {
969
1011
  if (pattern.test(sentence)) {
970
1012
  signals.flow.push(sentence.slice(0, 200));
@@ -1146,7 +1188,8 @@ function writeDeltaMarkdown(delta) {
1146
1188
  return lines.join("\n");
1147
1189
  }
1148
1190
 
1149
- // ../chitragupta/packages/smriti/src/compactor.ts
1191
+ // ../chitragupta/packages/smriti/dist/compactor.js
1192
+ init_dist();
1150
1193
  import fs3 from "fs";
1151
1194
  import path3 from "path";
1152
1195
  function getCompactionDir() {
@@ -1156,12 +1199,14 @@ function getDeltaDir() {
1156
1199
  return path3.join(getChitraguptaHome(), "smriti", "deltas");
1157
1200
  }
1158
1201
  function updateIdentityStream(streamManager, signals) {
1159
- if (signals.identity.length === 0) return;
1202
+ if (signals.identity.length === 0)
1203
+ return;
1160
1204
  const entry = signals.identity.map((s) => `- ${s}`).join("\n");
1161
1205
  streamManager.append("identity", entry);
1162
1206
  }
1163
1207
  function updateProjectsStream(streamManager, signals, session) {
1164
- if (signals.projects.length === 0) return;
1208
+ if (signals.projects.length === 0)
1209
+ return;
1165
1210
  const parts = [];
1166
1211
  parts.push(`### Session: ${session.meta.title}`);
1167
1212
  parts.push("");
@@ -1171,7 +1216,8 @@ function updateProjectsStream(streamManager, signals, session) {
1171
1216
  streamManager.append("projects", parts.join("\n"));
1172
1217
  }
1173
1218
  function updateTasksStream(streamManager, signals) {
1174
- if (signals.tasks.length === 0) return;
1219
+ if (signals.tasks.length === 0)
1220
+ return;
1175
1221
  const parts = [];
1176
1222
  const newTasks = [];
1177
1223
  const completed = [];
@@ -1339,7 +1385,9 @@ var SessionCompactor = class {
1339
1385
  const filePath = path3.join(dir, `${delta.sessionId}.md`);
1340
1386
  const markdown = writeDeltaMarkdown(delta);
1341
1387
  fs3.writeFileSync(filePath, markdown, "utf-8");
1342
- } catch {
1388
+ } catch (err) {
1389
+ process.stderr.write(`[smriti:compactor] delta save failed: ${err instanceof Error ? err.message : String(err)}
1390
+ `);
1343
1391
  }
1344
1392
  }
1345
1393
  saveMixingMatrix(sessionId, mixingMatrix, signals) {
@@ -1366,16 +1414,19 @@ var SessionCompactor = class {
1366
1414
  };
1367
1415
  const filePath = path3.join(dir, `${sessionId}.json`);
1368
1416
  fs3.writeFileSync(filePath, JSON.stringify(data, null, " "), "utf-8");
1369
- } catch {
1417
+ } catch (err) {
1418
+ process.stderr.write(`[smriti:compactor] mixing matrix save failed: ${err instanceof Error ? err.message : String(err)}
1419
+ `);
1370
1420
  }
1371
1421
  }
1372
1422
  };
1373
1423
 
1374
- // ../chitragupta/packages/smriti/src/sinkhorn-budget.ts
1424
+ // ../chitragupta/packages/smriti/dist/sinkhorn-budget.js
1375
1425
  function computeTokenBudgetsMHC(chunks, totalBudget) {
1376
1426
  const result = /* @__PURE__ */ new Map();
1377
1427
  const n = chunks.length;
1378
- if (n === 0) return result;
1428
+ if (n === 0)
1429
+ return result;
1379
1430
  if (n === 1) {
1380
1431
  result.set(chunks[0].id, totalBudget);
1381
1432
  return result;
@@ -1396,7 +1447,8 @@ function computeTokenBudgetsMHC(chunks, totalBudget) {
1396
1447
  const importanceAff = Math.max(ci.importance, cj.importance);
1397
1448
  const topicBonus = ci.topic && cj.topic && ci.topic === cj.topic ? TOPIC_BONUS : 0;
1398
1449
  row[j] = W_RECENCY * recencyAff + W_RELEVANCE * relevanceAff + W_IMPORTANCE * importanceAff + W_TOPIC * topicBonus;
1399
- if (row[j] < 1e-6) row[j] = 1e-6;
1450
+ if (row[j] < 1e-6)
1451
+ row[j] = 1e-6;
1400
1452
  }
1401
1453
  affinity.push(row);
1402
1454
  }
@@ -1413,13 +1465,15 @@ function computeTokenBudgetsMHC(chunks, totalBudget) {
1413
1465
  let rawTotal = 0;
1414
1466
  for (let i = 0; i < n; i++) {
1415
1467
  let rowSum = 0;
1416
- for (let j = 0; j < n; j++) rowSum += dsMatrix[i][j];
1468
+ for (let j = 0; j < n; j++)
1469
+ rowSum += dsMatrix[i][j];
1417
1470
  rawBudgets[i] = rowSum * composites[i];
1418
1471
  rawTotal += rawBudgets[i];
1419
1472
  }
1420
1473
  if (rawTotal === 0) {
1421
1474
  const equal = Math.floor(totalBudget / n);
1422
- for (let i = 0; i < n; i++) result.set(chunks[i].id, equal);
1475
+ for (let i = 0; i < n; i++)
1476
+ result.set(chunks[i].id, equal);
1423
1477
  let rem = totalBudget - equal * n;
1424
1478
  for (let i = 0; rem > 0; i++, rem--) {
1425
1479
  result.set(chunks[i].id, (result.get(chunks[i].id) ?? 0) + 1);
@@ -1435,7 +1489,8 @@ function computeTokenBudgetsMHC(chunks, totalBudget) {
1435
1489
  let remainder = totalBudget - allocated;
1436
1490
  const sortedIndices = composites.map((c, i) => ({ composite: c, index: i })).sort((a, b) => b.composite - a.composite).map((x) => x.index);
1437
1491
  for (const idx of sortedIndices) {
1438
- if (remainder <= 0) break;
1492
+ if (remainder <= 0)
1493
+ break;
1439
1494
  const id = chunks[idx].id;
1440
1495
  result.set(id, (result.get(id) ?? 0) + 1);
1441
1496
  remainder--;
@@ -1443,15 +1498,19 @@ function computeTokenBudgetsMHC(chunks, totalBudget) {
1443
1498
  return result;
1444
1499
  }
1445
1500
 
1446
- // ../chitragupta/packages/smriti/src/sinkhorn-accelerated.ts
1501
+ // ../chitragupta/packages/smriti/dist/sinkhorn-accelerated.js
1447
1502
  function logsumexp(arr) {
1448
- if (arr.length === 0) return -Infinity;
1449
- if (arr.length === 1) return arr[0];
1503
+ if (arr.length === 0)
1504
+ return -Infinity;
1505
+ if (arr.length === 1)
1506
+ return arr[0];
1450
1507
  let maxVal = -Infinity;
1451
1508
  for (let i = 0; i < arr.length; i++) {
1452
- if (arr[i] > maxVal) maxVal = arr[i];
1509
+ if (arr[i] > maxVal)
1510
+ maxVal = arr[i];
1453
1511
  }
1454
- if (maxVal === -Infinity) return -Infinity;
1512
+ if (maxVal === -Infinity)
1513
+ return -Infinity;
1455
1514
  let sumExp = 0;
1456
1515
  for (let i = 0; i < arr.length; i++) {
1457
1516
  sumExp += Math.exp(arr[i] - maxVal);
@@ -1483,16 +1542,20 @@ function linearSKStep(A) {
1483
1542
  const m = A[0].length;
1484
1543
  for (let i = 0; i < n; i++) {
1485
1544
  let rowSum = 0;
1486
- for (let j = 0; j < m; j++) rowSum += A[i][j];
1545
+ for (let j = 0; j < m; j++)
1546
+ rowSum += A[i][j];
1487
1547
  if (rowSum > 0) {
1488
- for (let j = 0; j < m; j++) A[i][j] /= rowSum;
1548
+ for (let j = 0; j < m; j++)
1549
+ A[i][j] /= rowSum;
1489
1550
  }
1490
1551
  }
1491
1552
  for (let j = 0; j < m; j++) {
1492
1553
  let colSum = 0;
1493
- for (let i = 0; i < n; i++) colSum += A[i][j];
1554
+ for (let i = 0; i < n; i++)
1555
+ colSum += A[i][j];
1494
1556
  if (colSum > 0) {
1495
- for (let i = 0; i < n; i++) A[i][j] /= colSum;
1557
+ for (let i = 0; i < n; i++)
1558
+ A[i][j] /= colSum;
1496
1559
  }
1497
1560
  }
1498
1561
  }
@@ -1502,15 +1565,19 @@ function maxDeviation(A) {
1502
1565
  let maxDev = 0;
1503
1566
  for (let i = 0; i < n; i++) {
1504
1567
  let rowSum = 0;
1505
- for (let j = 0; j < m; j++) rowSum += A[i][j];
1568
+ for (let j = 0; j < m; j++)
1569
+ rowSum += A[i][j];
1506
1570
  const dev = Math.abs(rowSum - 1);
1507
- if (dev > maxDev) maxDev = dev;
1571
+ if (dev > maxDev)
1572
+ maxDev = dev;
1508
1573
  }
1509
1574
  for (let j = 0; j < m; j++) {
1510
1575
  let colSum = 0;
1511
- for (let i = 0; i < n; i++) colSum += A[i][j];
1576
+ for (let i = 0; i < n; i++)
1577
+ colSum += A[i][j];
1512
1578
  const dev = Math.abs(colSum - 1);
1513
- if (dev > maxDev) maxDev = dev;
1579
+ if (dev > maxDev)
1580
+ maxDev = dev;
1514
1581
  }
1515
1582
  return maxDev;
1516
1583
  }
@@ -1547,18 +1614,25 @@ function sinkhornAccelerated(matrix, opts) {
1547
1614
  const initialEps = opts?.initialEpsilon ?? 0.01;
1548
1615
  const halvingInterval = opts?.epsilonHalvingInterval ?? 10;
1549
1616
  const n = matrix.length;
1550
- if (n === 0) return { result: [], iterations: 0, converged: true };
1617
+ if (n === 0)
1618
+ return { result: [], iterations: 0, converged: true };
1551
1619
  const m = matrix[0].length;
1552
- if (m === 0) return { result: matrix.map(() => []), iterations: 0, converged: true };
1620
+ if (m === 0)
1621
+ return { result: matrix.map(() => []), iterations: 0, converged: true };
1553
1622
  const A = matrix.map((row) => row.map((v) => Math.max(v, 0)));
1554
1623
  for (let i = 0; i < n; i++) {
1555
1624
  const rowSum = A[i].reduce((s, v) => s + v, 0);
1556
- if (rowSum === 0) for (let j = 0; j < m; j++) A[i][j] = 1 / m;
1625
+ if (rowSum === 0)
1626
+ for (let j = 0; j < m; j++)
1627
+ A[i][j] = 1 / m;
1557
1628
  }
1558
1629
  for (let j = 0; j < m; j++) {
1559
1630
  let colSum = 0;
1560
- for (let i = 0; i < n; i++) colSum += A[i][j];
1561
- if (colSum === 0) for (let i = 0; i < n; i++) A[i][j] = 1 / n;
1631
+ for (let i = 0; i < n; i++)
1632
+ colSum += A[i][j];
1633
+ if (colSum === 0)
1634
+ for (let i = 0; i < n; i++)
1635
+ A[i][j] = 1 / n;
1562
1636
  }
1563
1637
  let currentEps = useAdaptiveEps ? initialEps : targetEpsilon;
1564
1638
  let iterations = 0;
@@ -1594,7 +1668,8 @@ function sinkhornAccelerated(matrix, opts) {
1594
1668
  const working = useNesterov ? nesterovExtrapolate(current, previous, k) : cloneMatrix(current);
1595
1669
  for (let i = 0; i < n; i++) {
1596
1670
  for (let j = 0; j < m; j++) {
1597
- if (working[i][j] < 1e-15) working[i][j] = 1e-15;
1671
+ if (working[i][j] < 1e-15)
1672
+ working[i][j] = 1e-15;
1598
1673
  }
1599
1674
  }
1600
1675
  previous = cloneMatrix(current);
@@ -1609,7 +1684,7 @@ function sinkhornAccelerated(matrix, opts) {
1609
1684
  return { result: current, iterations, converged };
1610
1685
  }
1611
1686
 
1612
- // ../chitragupta/packages/smriti/src/stream-extractor.ts
1687
+ // ../chitragupta/packages/smriti/dist/stream-extractor.js
1613
1688
  var IDENTITY_PATTERNS2 = [
1614
1689
  /\bi (?:prefer|like|want|hate|always|never|use)\b/i,
1615
1690
  /\b(?:my|our) (?:preference|style|convention|workflow|setup)\b/i,
@@ -1650,7 +1725,8 @@ var TASK_PATTERNS2 = [
1650
1725
  function scorePatterns(text, patterns) {
1651
1726
  let hits = 0;
1652
1727
  for (const pattern of patterns) {
1653
- if (pattern.test(text)) hits++;
1728
+ if (pattern.test(text))
1729
+ hits++;
1654
1730
  }
1655
1731
  return hits;
1656
1732
  }
@@ -1663,7 +1739,8 @@ function extractSignals(turn) {
1663
1739
  };
1664
1740
  const sentences = splitSentences(turn.content);
1665
1741
  for (const sentence of sentences) {
1666
- if (sentence.trim().length < 5) continue;
1742
+ if (sentence.trim().length < 5)
1743
+ continue;
1667
1744
  const identityScore = scorePatterns(sentence, IDENTITY_PATTERNS2);
1668
1745
  const projectScore = scorePatterns(sentence, PROJECT_PATTERNS2);
1669
1746
  const taskScore = scorePatterns(sentence, TASK_PATTERNS2);
@@ -1700,10 +1777,14 @@ function classifyContent(text) {
1700
1777
  const projectScore = scorePatterns(text, PROJECT_PATTERNS2);
1701
1778
  const taskScore = scorePatterns(text, TASK_PATTERNS2);
1702
1779
  const maxScore = Math.max(identityScore, projectScore, taskScore);
1703
- if (maxScore === 0) return "flow";
1704
- if (identityScore === maxScore) return "identity";
1705
- if (projectScore === maxScore) return "projects";
1706
- if (taskScore === maxScore) return "tasks";
1780
+ if (maxScore === 0)
1781
+ return "flow";
1782
+ if (identityScore === maxScore)
1783
+ return "identity";
1784
+ if (projectScore === maxScore)
1785
+ return "projects";
1786
+ if (taskScore === maxScore)
1787
+ return "tasks";
1707
1788
  return "flow";
1708
1789
  }
1709
1790
  function extractSignalsFromTurns(turns) {
@@ -1728,11 +1809,12 @@ function splitSentences(text) {
1728
1809
  return sentences;
1729
1810
  }
1730
1811
 
1731
- // ../chitragupta/packages/smriti/src/graphrag-adaptive-scoring.ts
1812
+ // ../chitragupta/packages/smriti/dist/graphrag-adaptive-scoring.js
1732
1813
  function sampleBeta(alpha, beta) {
1733
1814
  const x = sampleGamma(alpha);
1734
1815
  const y = sampleGamma(beta);
1735
- if (x + y === 0) return 0.5;
1816
+ if (x + y === 0)
1817
+ return 0.5;
1736
1818
  return x / (x + y);
1737
1819
  }
1738
1820
  function sampleGamma(shape) {
@@ -1752,8 +1834,10 @@ function sampleGamma(shape) {
1752
1834
  v = v * v * v;
1753
1835
  const u = Math.random();
1754
1836
  const zSq = z * z;
1755
- if (u < 1 - 0.0331 * (zSq * zSq)) return d * v;
1756
- if (Math.log(u) < 0.5 * zSq + d * (1 - v + Math.log(v))) return d * v;
1837
+ if (u < 1 - 0.0331 * (zSq * zSq))
1838
+ return d * v;
1839
+ if (Math.log(u) < 0.5 * zSq + d * (1 - v + Math.log(v)))
1840
+ return d * v;
1757
1841
  }
1758
1842
  }
1759
1843
  function gaussianRandom() {
@@ -1819,7 +1903,8 @@ var AdaptiveScorer = class {
1819
1903
  */
1820
1904
  recordFeedback(queryId, accepted) {
1821
1905
  const dominant = this.queryDominants.get(queryId);
1822
- if (!dominant) return;
1906
+ if (!dominant)
1907
+ return;
1823
1908
  const record = {
1824
1909
  timestamp: Date.now(),
1825
1910
  accepted,
@@ -1883,7 +1968,8 @@ var AdaptiveScorer = class {
1883
1968
  const rawPagerank = sampleBeta(this.pagerankAlpha, this.pagerankBeta);
1884
1969
  const rawText = sampleBeta(this.textAlpha, this.textBeta);
1885
1970
  const total = rawCosine + rawPagerank + rawText;
1886
- if (total === 0) return { ...FIXED_WEIGHTS };
1971
+ if (total === 0)
1972
+ return { ...FIXED_WEIGHTS };
1887
1973
  return {
1888
1974
  cosine: rawCosine / total,
1889
1975
  pagerank: rawPagerank / total,
@@ -1927,7 +2013,8 @@ var AdaptiveScorer = class {
1927
2013
  }
1928
2014
  };
1929
2015
  function mmrRerank(scored, lambda = 0.7, topK = 10) {
1930
- if (scored.length <= 1 || topK <= 0) return scored.slice(0, topK);
2016
+ if (scored.length <= 1 || topK <= 0)
2017
+ return scored.slice(0, topK);
1931
2018
  const k = Math.min(topK, scored.length);
1932
2019
  const selected = [];
1933
2020
  const remaining = [...scored];
@@ -1941,7 +2028,8 @@ function mmrRerank(scored, lambda = 0.7, topK = 10) {
1941
2028
  let maxSim = 0;
1942
2029
  for (const sel of selected) {
1943
2030
  const sim = computeSimilarity(candidate, sel);
1944
- if (sim > maxSim) maxSim = sim;
2031
+ if (sim > maxSim)
2032
+ maxSim = sim;
1945
2033
  }
1946
2034
  const mmr = lambda * candidate.finalScore - (1 - lambda) * maxSim;
1947
2035
  if (mmr > bestMMR) {
@@ -1962,7 +2050,7 @@ function computeSimilarity(a, b) {
1962
2050
  return Math.max(0, cosineSimilarity(vecA, vecB));
1963
2051
  }
1964
2052
 
1965
- // ../chitragupta/packages/smriti/src/checkpoint.ts
2053
+ // ../chitragupta/packages/smriti/dist/checkpoint.js
1966
2054
  import fs4 from "node:fs";
1967
2055
  import path4 from "node:path";
1968
2056
  import { randomUUID } from "node:crypto";
@@ -1971,13 +2059,16 @@ var DEFAULT_INTERVAL = 3e4;
1971
2059
  var DEFAULT_MAX_CHECKPOINTS = 5;
1972
2060
  var CHECKPOINT_EXT = ".json";
1973
2061
  function parseCheckpointFilename(filename) {
1974
- if (!filename.endsWith(CHECKPOINT_EXT)) return null;
2062
+ if (!filename.endsWith(CHECKPOINT_EXT))
2063
+ return null;
1975
2064
  const base = filename.slice(0, -CHECKPOINT_EXT.length);
1976
2065
  const dashIdx = base.indexOf("-");
1977
- if (dashIdx === -1) return null;
2066
+ if (dashIdx === -1)
2067
+ return null;
1978
2068
  const timestamp = Number(base.slice(0, dashIdx));
1979
2069
  const uuid = base.slice(dashIdx + 1);
1980
- if (Number.isNaN(timestamp) || !uuid) return null;
2070
+ if (Number.isNaN(timestamp) || !uuid)
2071
+ return null;
1981
2072
  return { timestamp, uuid };
1982
2073
  }
1983
2074
  var CheckpointManager = class {
@@ -2021,7 +2112,8 @@ var CheckpointManager = class {
2021
2112
  */
2022
2113
  async load(sessionId) {
2023
2114
  const checkpoints = this.list(sessionId);
2024
- if (checkpoints.length === 0) return null;
2115
+ if (checkpoints.length === 0)
2116
+ return null;
2025
2117
  for (const cp of checkpoints) {
2026
2118
  try {
2027
2119
  const filePath = this.checkpointPath(sessionId, cp);
@@ -2042,7 +2134,8 @@ var CheckpointManager = class {
2042
2134
  */
2043
2135
  list(sessionId) {
2044
2136
  const sessionDir = this.sessionDir(sessionId);
2045
- if (!fs4.existsSync(sessionDir)) return [];
2137
+ if (!fs4.existsSync(sessionDir))
2138
+ return [];
2046
2139
  let entries;
2047
2140
  try {
2048
2141
  entries = fs4.readdirSync(sessionDir);
@@ -2051,9 +2144,11 @@ var CheckpointManager = class {
2051
2144
  }
2052
2145
  const checkpoints = [];
2053
2146
  for (const entry of entries) {
2054
- if (entry.endsWith(".tmp")) continue;
2147
+ if (entry.endsWith(".tmp"))
2148
+ continue;
2055
2149
  const parsed = parseCheckpointFilename(entry);
2056
- if (!parsed) continue;
2150
+ if (!parsed)
2151
+ continue;
2057
2152
  const filePath = path4.join(sessionDir, entry);
2058
2153
  let size = 0;
2059
2154
  let turnCount = 0;
@@ -2097,7 +2192,8 @@ var CheckpointManager = class {
2097
2192
  */
2098
2193
  async prune(sessionId) {
2099
2194
  const all = this.list(sessionId);
2100
- if (all.length <= this.maxCheckpoints) return 0;
2195
+ if (all.length <= this.maxCheckpoints)
2196
+ return 0;
2101
2197
  const toRemove = all.slice(this.maxCheckpoints);
2102
2198
  let removed = 0;
2103
2199
  for (const cp of toRemove) {
@@ -2142,7 +2238,8 @@ var CheckpointManager = class {
2142
2238
  */
2143
2239
  async deleteAll(sessionId) {
2144
2240
  const sessionDir = this.sessionDir(sessionId);
2145
- if (!fs4.existsSync(sessionDir)) return;
2241
+ if (!fs4.existsSync(sessionDir))
2242
+ return;
2146
2243
  try {
2147
2244
  await fs4.promises.rm(sessionDir, { recursive: true, force: true });
2148
2245
  } catch {
@@ -2157,11 +2254,12 @@ var CheckpointManager = class {
2157
2254
  }
2158
2255
  };
2159
2256
 
2160
- // ../chitragupta/packages/smriti/src/consolidation.ts
2257
+ // ../chitragupta/packages/smriti/dist/consolidation.js
2258
+ init_dist();
2161
2259
  import fs5 from "fs";
2162
2260
  import path5 from "path";
2163
2261
 
2164
- // ../chitragupta/packages/smriti/src/consolidation-phases.ts
2262
+ // ../chitragupta/packages/smriti/dist/consolidation-phases.js
2165
2263
  var PREFERENCE_PATTERNS = [
2166
2264
  /\bi prefer\b/i,
2167
2265
  /\balways use\b/i,
@@ -2255,7 +2353,8 @@ function detectToolSequences(sessions, minObservations) {
2255
2353
  const ngramEvidence = /* @__PURE__ */ new Map();
2256
2354
  for (const session of sessions) {
2257
2355
  const toolSeq = extractToolSequence(session);
2258
- if (toolSeq.length < n) continue;
2356
+ if (toolSeq.length < n)
2357
+ continue;
2259
2358
  const sessionNgrams = new Set(ngrams(toolSeq, n));
2260
2359
  for (const ng of sessionNgrams) {
2261
2360
  if (!ngramSessionCount.has(ng)) {
@@ -2263,9 +2362,7 @@ function detectToolSequences(sessions, minObservations) {
2263
2362
  ngramEvidence.set(ng, []);
2264
2363
  }
2265
2364
  ngramSessionCount.get(ng).add(session.meta.id);
2266
- ngramEvidence.get(ng).push(
2267
- `Session "${session.meta.title}": ${ng}`
2268
- );
2365
+ ngramEvidence.get(ng).push(`Session "${session.meta.title}": ${ng}`);
2269
2366
  }
2270
2367
  }
2271
2368
  for (const [ng, sessionIds] of ngramSessionCount) {
@@ -2298,9 +2395,7 @@ function detectPreferences(sessions) {
2298
2395
  }
2299
2396
  const hit = preferenceHits.get(key);
2300
2397
  hit.sessions.add(session.meta.id);
2301
- hit.evidence.push(
2302
- `Session "${session.meta.title}": "${sentence}"`
2303
- );
2398
+ hit.evidence.push(`Session "${session.meta.title}": "${sentence}"`);
2304
2399
  }
2305
2400
  }
2306
2401
  }
@@ -2332,9 +2427,7 @@ function detectDecisions(sessions) {
2332
2427
  }
2333
2428
  const hit = decisionHits.get(key);
2334
2429
  hit.sessions.add(session.meta.id);
2335
- hit.evidence.push(
2336
- `Session "${session.meta.title}": "${sentence}"`
2337
- );
2430
+ hit.evidence.push(`Session "${session.meta.title}": "${sentence}"`);
2338
2431
  }
2339
2432
  }
2340
2433
  }
@@ -2366,9 +2459,7 @@ function detectCorrections(sessions) {
2366
2459
  }
2367
2460
  const hit = correctionHits.get(key);
2368
2461
  hit.sessions.add(session.meta.id);
2369
- hit.evidence.push(
2370
- `Session "${session.meta.title}": "${sentence}"`
2371
- );
2462
+ hit.evidence.push(`Session "${session.meta.title}": "${sentence}"`);
2372
2463
  }
2373
2464
  }
2374
2465
  }
@@ -2394,7 +2485,8 @@ function detectConventions(sessions, minObservations) {
2394
2485
  const fileExtCounts = /* @__PURE__ */ new Map();
2395
2486
  for (const session of sessions) {
2396
2487
  for (const turn of session.turns) {
2397
- if (!turn.toolCalls) continue;
2488
+ if (!turn.toolCalls)
2489
+ continue;
2398
2490
  for (const tc of turn.toolCalls) {
2399
2491
  const extMatch = tc.input.match(/\.([a-z]{1,5})\b/gi);
2400
2492
  if (extMatch) {
@@ -2405,9 +2497,7 @@ function detectConventions(sessions, minObservations) {
2405
2497
  }
2406
2498
  const hit = fileExtCounts.get(extLower);
2407
2499
  hit.sessions.add(session.meta.id);
2408
- hit.evidence.push(
2409
- `Session "${session.meta.title}": tool ${tc.name} used ${extLower}`
2410
- );
2500
+ hit.evidence.push(`Session "${session.meta.title}": tool ${tc.name} used ${extLower}`);
2411
2501
  }
2412
2502
  }
2413
2503
  if (tc.name === "edit" || tc.name === "write") {
@@ -2418,9 +2508,7 @@ function detectConventions(sessions, minObservations) {
2418
2508
  }
2419
2509
  const hit = conventionHits.get(importKey);
2420
2510
  hit.sessions.add(session.meta.id);
2421
- hit.evidence.push(
2422
- `Session "${session.meta.title}": ${importKey} in ${tc.name} call`
2423
- );
2511
+ hit.evidence.push(`Session "${session.meta.title}": ${importKey} in ${tc.name} call`);
2424
2512
  }
2425
2513
  }
2426
2514
  }
@@ -2440,7 +2528,7 @@ function detectConventions(sessions, minObservations) {
2440
2528
  return patterns;
2441
2529
  }
2442
2530
 
2443
- // ../chitragupta/packages/smriti/src/consolidation-scoring.ts
2531
+ // ../chitragupta/packages/smriti/dist/consolidation-scoring.js
2444
2532
  var FNV_OFFSET = 2166136261;
2445
2533
  var FNV_PRIME = 16777619;
2446
2534
  function fnv1a(input) {
@@ -2459,8 +2547,10 @@ function textSimilarity(a, b) {
2459
2547
  const normalize = (s) => s.toLowerCase().trim().replace(/\s+/g, " ");
2460
2548
  const na = normalize(a);
2461
2549
  const nb = normalize(b);
2462
- if (na === nb) return 1;
2463
- if (na.length < 2 || nb.length < 2) return 0;
2550
+ if (na === nb)
2551
+ return 1;
2552
+ if (na.length < 2 || nb.length < 2)
2553
+ return 0;
2464
2554
  const bigrams = (s) => {
2465
2555
  const map = /* @__PURE__ */ new Map();
2466
2556
  for (let i = 0; i < s.length - 1; i++) {
@@ -2496,10 +2586,7 @@ function mergeWithExisting(candidates, allPatterns, rules) {
2496
2586
  }
2497
2587
  if (bestMatch && bestSimilarity >= SIMILARITY_THRESHOLD) {
2498
2588
  bestMatch.observationCount += candidate.observationCount;
2499
- bestMatch.confidence = Math.min(
2500
- 1,
2501
- bestMatch.confidence + 0.1 * candidate.observationCount
2502
- );
2589
+ bestMatch.confidence = Math.min(1, bestMatch.confidence + 0.1 * candidate.observationCount);
2503
2590
  bestMatch.lastReinforcedAt = candidate.lastReinforcedAt;
2504
2591
  const sessionSet = /* @__PURE__ */ new Set([
2505
2592
  ...bestMatch.sourceSessionIds,
@@ -2542,9 +2629,7 @@ function patternToRule(pattern, sessions, timestamp) {
2542
2629
  };
2543
2630
  const category = categoryMap[pattern.type];
2544
2631
  const id = generateRuleId(category, pattern.description);
2545
- const sessionIds = sessions.filter(
2546
- (s) => pattern.evidence.some((e) => e.includes(s.meta.title))
2547
- ).map((s) => s.meta.id);
2632
+ const sessionIds = sessions.filter((s) => pattern.evidence.some((e) => e.includes(s.meta.title))).map((s) => s.meta.id);
2548
2633
  return {
2549
2634
  id,
2550
2635
  rule: pattern.description,
@@ -2559,11 +2644,10 @@ function patternToRule(pattern, sessions, timestamp) {
2559
2644
  };
2560
2645
  }
2561
2646
  function enforceMaxRules(rules, maxRules) {
2562
- if (rules.size <= maxRules) return;
2647
+ if (rules.size <= maxRules)
2648
+ return;
2563
2649
  const sorted = [...rules.entries()].sort(([, a], [, b]) => b.confidence - a.confidence);
2564
- const toKeep = new Set(
2565
- sorted.slice(0, maxRules).map(([id]) => id)
2566
- );
2650
+ const toKeep = new Set(sorted.slice(0, maxRules).map(([id]) => id));
2567
2651
  for (const id of rules.keys()) {
2568
2652
  if (!toKeep.has(id)) {
2569
2653
  rules.delete(id);
@@ -2571,7 +2655,7 @@ function enforceMaxRules(rules, maxRules) {
2571
2655
  }
2572
2656
  }
2573
2657
 
2574
- // ../chitragupta/packages/smriti/src/consolidation.ts
2658
+ // ../chitragupta/packages/smriti/dist/consolidation-types.js
2575
2659
  var DEFAULT_CONFIG = {
2576
2660
  minObservations: 2,
2577
2661
  decayRatePerDay: 0.01,
@@ -2589,6 +2673,8 @@ var ALL_CATEGORIES = [
2589
2673
  "domain-knowledge",
2590
2674
  "relationship"
2591
2675
  ];
2676
+
2677
+ // ../chitragupta/packages/smriti/dist/consolidation.js
2592
2678
  var ConsolidationEngine = class {
2593
2679
  config;
2594
2680
  rules = /* @__PURE__ */ new Map();
@@ -2629,6 +2715,7 @@ var ConsolidationEngine = class {
2629
2715
  const candidateRules = allPatterns.filter((p) => p.frequency >= this.config.minObservations).map((p) => patternToRule(p, sessions, timestamp));
2630
2716
  const { newRules, reinforcedRules, weakenedRules } = mergeWithExisting(candidateRules, allPatterns, this.rules);
2631
2717
  enforceMaxRules(this.rules, this.config.maxRules);
2718
+ this.decayRules();
2632
2719
  this.pruneRules();
2633
2720
  const entry = {
2634
2721
  timestamp,
@@ -2642,6 +2729,7 @@ var ConsolidationEngine = class {
2642
2729
  if (this.history.length > MAX_HISTORY_ENTRIES) {
2643
2730
  this.history = this.history.slice(-MAX_HISTORY_ENTRIES);
2644
2731
  }
2732
+ this.save();
2645
2733
  return {
2646
2734
  newRules,
2647
2735
  reinforcedRules,
@@ -2792,9 +2880,7 @@ var ConsolidationEngine = class {
2792
2880
  }
2793
2881
  if (fs5.existsSync(historyPath)) {
2794
2882
  try {
2795
- this.history = JSON.parse(
2796
- fs5.readFileSync(historyPath, "utf-8")
2797
- );
2883
+ this.history = JSON.parse(fs5.readFileSync(historyPath, "utf-8"));
2798
2884
  } catch (err) {
2799
2885
  process.stderr.write(`[consolidation] corrupted history.json, starting fresh: ${err instanceof Error ? err.message : err}
2800
2886
  `);
@@ -2834,7 +2920,7 @@ var ConsolidationEngine = class {
2834
2920
  }
2835
2921
  };
2836
2922
 
2837
- // ../chitragupta/packages/smriti/src/query-decomposition.ts
2923
+ // ../chitragupta/packages/smriti/dist/query-decomposition.js
2838
2924
  var CONJUNCTIONS = /\b(and|or|but|that|which|who|where|when|while|although)\b/i;
2839
2925
  var TEMPORAL = /\b(when|before|after|last\s+(?:time|week|month|year|day)|yesterday|recently|earlier|previously|ago|since|until)\b/i;
2840
2926
  var COMPARATIVE = /\b(vs\.?|versus|compared?\s+to|difference\s+between|between\s+\w+\s+and)\b/i;
@@ -2844,18 +2930,25 @@ var positionalWeight = (index) => Math.max(0.4, 1 - 0.2 * index);
2844
2930
  function isComplexQuery(query) {
2845
2931
  const trimmed = query.trim();
2846
2932
  const words = trimmed.split(/\s+/);
2847
- if (words.length > COMPLEXITY_WORD_THRESHOLD) return true;
2848
- if (CONJUNCTIONS.test(trimmed)) return true;
2849
- if (TEMPORAL.test(trimmed)) return true;
2850
- if (COMPARATIVE.test(trimmed)) return true;
2933
+ if (words.length > COMPLEXITY_WORD_THRESHOLD)
2934
+ return true;
2935
+ if (CONJUNCTIONS.test(trimmed))
2936
+ return true;
2937
+ if (TEMPORAL.test(trimmed))
2938
+ return true;
2939
+ if (COMPARATIVE.test(trimmed))
2940
+ return true;
2851
2941
  const quotedTerms = trimmed.match(/["'][^"']+["']/g);
2852
- if (quotedTerms && quotedTerms.length >= 2) return true;
2942
+ if (quotedTerms && quotedTerms.length >= 2)
2943
+ return true;
2853
2944
  const capitalizedWords = words.slice(1).filter((w) => /^[A-Z][a-z]/.test(w));
2854
- if (capitalizedWords.length >= 2) return true;
2945
+ if (capitalizedWords.length >= 2)
2946
+ return true;
2855
2947
  return false;
2856
2948
  }
2857
2949
  function clampSubQueries(subQueries, maxSubQueries) {
2858
- if (subQueries.length <= maxSubQueries) return subQueries;
2950
+ if (subQueries.length <= maxSubQueries)
2951
+ return subQueries;
2859
2952
  const original = subQueries[0];
2860
2953
  const rest = subQueries.slice(1).sort((a, b) => b.weight - a.weight).slice(0, maxSubQueries - 1);
2861
2954
  return [original, ...rest];
@@ -2863,7 +2956,8 @@ function clampSubQueries(subQueries, maxSubQueries) {
2863
2956
  function extractListEntities(query) {
2864
2957
  const listPattern = /([^,]+(?:,\s*[^,]+)*,?\s*(?:and|or)\s+[^,]+)/i;
2865
2958
  const match = query.match(listPattern);
2866
- if (!match) return [];
2959
+ if (!match)
2960
+ return [];
2867
2961
  const listPortion = match[1];
2868
2962
  const entities = listPortion.split(/,\s*|\s+(?:and|or)\s+/i).map((s) => s.trim()).filter((s) => s.length >= 2);
2869
2963
  return entities.length >= 2 ? entities : [];
@@ -2977,50 +3071,42 @@ function extractKeyTerms(query) {
2977
3071
  }
2978
3072
  function decomposeQuery(query, maxSubQueries) {
2979
3073
  const trimmed = query.trim();
2980
- if (!trimmed) return [];
3074
+ if (!trimmed)
3075
+ return [];
2981
3076
  const subQueries = [];
2982
3077
  subQueries.push({
2983
3078
  query: trimmed,
2984
3079
  intent: "original query",
2985
3080
  weight: 1
2986
3081
  });
2987
- if (!isComplexQuery(trimmed)) return subQueries;
2988
- const comparativeMatch = trimmed.match(
2989
- /^(.+?)\s+(?:vs\.?|versus|compared?\s+to)\s+(.+)$/i
2990
- );
3082
+ if (!isComplexQuery(trimmed))
3083
+ return subQueries;
3084
+ const comparativeMatch = trimmed.match(/^(.+?)\s+(?:vs\.?|versus|compared?\s+to)\s+(.+)$/i);
2991
3085
  if (comparativeMatch) {
2992
3086
  const [, left, right] = comparativeMatch;
2993
- subQueries.push(
2994
- {
2995
- query: left.trim(),
2996
- intent: "comparative left side",
2997
- weight: positionalWeight(subQueries.length)
2998
- },
2999
- {
3000
- query: right.trim(),
3001
- intent: "comparative right side",
3002
- weight: positionalWeight(subQueries.length + 1)
3003
- }
3004
- );
3087
+ subQueries.push({
3088
+ query: left.trim(),
3089
+ intent: "comparative left side",
3090
+ weight: positionalWeight(subQueries.length)
3091
+ }, {
3092
+ query: right.trim(),
3093
+ intent: "comparative right side",
3094
+ weight: positionalWeight(subQueries.length + 1)
3095
+ });
3005
3096
  return clampSubQueries(subQueries, maxSubQueries);
3006
3097
  }
3007
- const diffBetween = trimmed.match(
3008
- /difference\s+between\s+(.+?)\s+and\s+(.+)/i
3009
- );
3098
+ const diffBetween = trimmed.match(/difference\s+between\s+(.+?)\s+and\s+(.+)/i);
3010
3099
  if (diffBetween) {
3011
3100
  const [, left, right] = diffBetween;
3012
- subQueries.push(
3013
- {
3014
- query: left.trim(),
3015
- intent: "comparison entity A",
3016
- weight: positionalWeight(subQueries.length)
3017
- },
3018
- {
3019
- query: right.trim(),
3020
- intent: "comparison entity B",
3021
- weight: positionalWeight(subQueries.length + 1)
3022
- }
3023
- );
3101
+ subQueries.push({
3102
+ query: left.trim(),
3103
+ intent: "comparison entity A",
3104
+ weight: positionalWeight(subQueries.length)
3105
+ }, {
3106
+ query: right.trim(),
3107
+ intent: "comparison entity B",
3108
+ weight: positionalWeight(subQueries.length + 1)
3109
+ });
3024
3110
  return clampSubQueries(subQueries, maxSubQueries);
3025
3111
  }
3026
3112
  if (CAUSAL.test(trimmed)) {
@@ -3039,9 +3125,7 @@ function decomposeQuery(query, maxSubQueries) {
3039
3125
  return clampSubQueries(subQueries, maxSubQueries);
3040
3126
  }
3041
3127
  }
3042
- const listMatch = trimmed.match(
3043
- /^(.*?)(\b\w+(?:\s+\w+)?)(?:,\s*(\b\w+(?:\s+\w+)?))+(?:,?\s*and\s+(\b\w+(?:\s+\w+)?))\b(.*)$/i
3044
- );
3128
+ const listMatch = trimmed.match(/^(.*?)(\b\w+(?:\s+\w+)?)(?:,\s*(\b\w+(?:\s+\w+)?))+(?:,?\s*and\s+(\b\w+(?:\s+\w+)?))\b(.*)$/i);
3045
3129
  if (listMatch) {
3046
3130
  const entityParts = extractListEntities(trimmed);
3047
3131
  if (entityParts.length >= 2) {
@@ -3075,14 +3159,14 @@ function decomposeQuery(query, maxSubQueries) {
3075
3159
  function generateFollowUpQueries(originalQuery, currentResults, previousSubQueries, maxSubQueries) {
3076
3160
  const followUps = [];
3077
3161
  const queryTerms = extractKeyTerms(originalQuery);
3078
- const previousQueryTexts = new Set(
3079
- previousSubQueries.map((sq) => sq.query.toLowerCase())
3080
- );
3162
+ const previousQueryTexts = new Set(previousSubQueries.map((sq) => sq.query.toLowerCase()));
3081
3163
  const contentBag = currentResults.map((r) => `${r.title} ${r.content}`).join(" ").toLowerCase();
3082
3164
  for (const term of queryTerms) {
3083
3165
  const lowerTerm = term.toLowerCase();
3084
- if (previousQueryTexts.has(lowerTerm)) continue;
3085
- if (contentBag.includes(lowerTerm)) continue;
3166
+ if (previousQueryTexts.has(lowerTerm))
3167
+ continue;
3168
+ if (contentBag.includes(lowerTerm))
3169
+ continue;
3086
3170
  followUps.push({
3087
3171
  query: term,
3088
3172
  intent: `follow-up for missing concept: ${term}`,
@@ -3090,13 +3174,10 @@ function generateFollowUpQueries(originalQuery, currentResults, previousSubQueri
3090
3174
  // Follow-ups have lower weight than initial decomposition.
3091
3175
  });
3092
3176
  }
3093
- return followUps.slice(
3094
- 0,
3095
- Math.max(1, maxSubQueries - previousSubQueries.length)
3096
- );
3177
+ return followUps.slice(0, Math.max(1, maxSubQueries - previousSubQueries.length));
3097
3178
  }
3098
3179
 
3099
- // ../chitragupta/packages/smriti/src/multi-round-retrieval.ts
3180
+ // ../chitragupta/packages/smriti/dist/multi-round-retrieval.js
3100
3181
  var DEFAULT_CONFIG2 = {
3101
3182
  maxSubQueries: 4,
3102
3183
  maxRounds: 3,
@@ -3163,12 +3244,9 @@ var AnveshanaEngine = class {
3163
3244
  previousTopScore = currentFused.length > 0 ? currentFused[0].score : 0;
3164
3245
  let allPreviousSubQueries = [...subQueries];
3165
3246
  for (let round = 1; round < this.config.maxRounds; round++) {
3166
- const followUps = this.generateFollowUp(
3167
- query,
3168
- currentFused,
3169
- allPreviousSubQueries
3170
- );
3171
- if (followUps.length === 0) break;
3247
+ const followUps = this.generateFollowUp(query, currentFused, allPreviousSubQueries);
3248
+ if (followUps.length === 0)
3249
+ break;
3172
3250
  const roundResults = await this.executeRound(followUps, round);
3173
3251
  allRounds.push(...roundResults);
3174
3252
  allPreviousSubQueries = [...allPreviousSubQueries, ...followUps];
@@ -3189,10 +3267,7 @@ var AnveshanaEngine = class {
3189
3267
  previousTopScore = newTopScore;
3190
3268
  }
3191
3269
  const finalResults = currentFused.slice(0, this.config.maxResults);
3192
- const totalRawResults = allRounds.reduce(
3193
- (sum, r) => sum + r.results.length,
3194
- 0
3195
- );
3270
+ const totalRawResults = allRounds.reduce((sum, r) => sum + r.results.length, 0);
3196
3271
  this.lastStats = {
3197
3272
  totalRounds: allRounds.length > 0 ? Math.max(...allRounds.map((r) => r.round)) + 1 : 1,
3198
3273
  subQueriesGenerated: allPreviousSubQueries.length,
@@ -3238,12 +3313,7 @@ var AnveshanaEngine = class {
3238
3313
  * @returns New sub-queries targeting unrepresented concepts.
3239
3314
  */
3240
3315
  generateFollowUp(originalQuery, currentResults, previousSubQueries) {
3241
- return generateFollowUpQueries(
3242
- originalQuery,
3243
- currentResults,
3244
- previousSubQueries,
3245
- this.config.maxSubQueries
3246
- );
3316
+ return generateFollowUpQueries(originalQuery, currentResults, previousSubQueries, this.config.maxSubQueries);
3247
3317
  }
3248
3318
  /**
3249
3319
  * Fuse results from multiple rounds with weighted scoring.
@@ -3268,12 +3338,10 @@ var AnveshanaEngine = class {
3268
3338
  if (existing) {
3269
3339
  existing.weightedScore += result.score * weight;
3270
3340
  existing.foundBy.add(round.subQuery.query);
3271
- existing.roundScores.push(
3272
- ...result.roundScores.map((rs) => ({
3273
- query: rs.query,
3274
- score: rs.score * weight
3275
- }))
3276
- );
3341
+ existing.roundScores.push(...result.roundScores.map((rs) => ({
3342
+ query: rs.query,
3343
+ score: rs.score * weight
3344
+ })));
3277
3345
  if (result.content.length > existing.content.length) {
3278
3346
  existing.content = result.content;
3279
3347
  }
@@ -3324,16 +3392,14 @@ var AnveshanaEngine = class {
3324
3392
  const roundResults = [];
3325
3393
  const tasks = subQueries.map(async (sq) => {
3326
3394
  const hybridResults = await this.hybridSearch.search(sq.query);
3327
- const multiResults = hybridResults.map(
3328
- (r) => ({
3329
- id: r.id,
3330
- title: r.title,
3331
- content: r.content,
3332
- foundBy: [sq.query],
3333
- score: r.score,
3334
- roundScores: [{ query: sq.query, score: r.score }]
3335
- })
3336
- );
3395
+ const multiResults = hybridResults.map((r) => ({
3396
+ id: r.id,
3397
+ title: r.title,
3398
+ content: r.content,
3399
+ foundBy: [sq.query],
3400
+ score: r.score,
3401
+ roundScores: [{ query: sq.query, score: r.score }]
3402
+ }));
3337
3403
  roundResults.push({
3338
3404
  subQuery: sq,
3339
3405
  results: multiResults,
@@ -3345,10 +3411,11 @@ var AnveshanaEngine = class {
3345
3411
  }
3346
3412
  };
3347
3413
 
3348
- // ../chitragupta/packages/smriti/src/smaran.ts
3414
+ // ../chitragupta/packages/smriti/dist/smaran.js
3415
+ init_dist();
3349
3416
  import path7 from "path";
3350
3417
 
3351
- // ../chitragupta/packages/smriti/src/smaran-store.ts
3418
+ // ../chitragupta/packages/smriti/dist/smaran-store.js
3352
3419
  import fs6 from "fs";
3353
3420
  import path6 from "path";
3354
3421
  function fnv1a2(str) {
@@ -3359,7 +3426,7 @@ function fnv1a2(str) {
3359
3426
  }
3360
3427
  return hash;
3361
3428
  }
3362
- function tokenize2(text) {
3429
+ function tokenize(text) {
3363
3430
  return text.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((t) => t.length > 1);
3364
3431
  }
3365
3432
  function extractTags(content) {
@@ -3378,7 +3445,8 @@ function extractTags(content) {
3378
3445
  [/\bschedule\b|\bcalendar\b|\bmeeting\b|\bappointment\b/, "schedule"]
3379
3446
  ];
3380
3447
  for (const [pattern, tag] of tagPatterns) {
3381
- if (pattern.test(lower)) tags.push(tag);
3448
+ if (pattern.test(lower))
3449
+ tags.push(tag);
3382
3450
  }
3383
3451
  return tags;
3384
3452
  }
@@ -3386,9 +3454,11 @@ function parseSimpleYaml(yaml) {
3386
3454
  const result = {};
3387
3455
  for (const line of yaml.split("\n")) {
3388
3456
  const trimmed = line.trim();
3389
- if (!trimmed || trimmed.startsWith("#")) continue;
3457
+ if (!trimmed || trimmed.startsWith("#"))
3458
+ continue;
3390
3459
  const colonIdx = trimmed.indexOf(":");
3391
- if (colonIdx === -1) continue;
3460
+ if (colonIdx === -1)
3461
+ continue;
3392
3462
  const key = trimmed.slice(0, colonIdx).trim();
3393
3463
  const rawValue = trimmed.slice(colonIdx + 1).trim();
3394
3464
  if (rawValue.startsWith("[") && rawValue.endsWith("]")) {
@@ -3396,9 +3466,12 @@ function parseSimpleYaml(yaml) {
3396
3466
  result[key] = inner.trim() === "" ? [] : inner.split(",").map((s) => s.trim());
3397
3467
  continue;
3398
3468
  }
3399
- if (rawValue === "null" || rawValue === "~") result[key] = null;
3400
- else if (rawValue === "true") result[key] = true;
3401
- else if (rawValue === "false") result[key] = false;
3469
+ if (rawValue === "null" || rawValue === "~")
3470
+ result[key] = null;
3471
+ else if (rawValue === "true")
3472
+ result[key] = true;
3473
+ else if (rawValue === "false")
3474
+ result[key] = false;
3402
3475
  else {
3403
3476
  const num = Number(rawValue);
3404
3477
  result[key] = !Number.isNaN(num) && rawValue !== "" ? num : rawValue;
@@ -3407,8 +3480,10 @@ function parseSimpleYaml(yaml) {
3407
3480
  return result;
3408
3481
  }
3409
3482
  function parseTags(value) {
3410
- if (Array.isArray(value)) return value.map(String);
3411
- if (typeof value === "string") return value.split(",").map((s) => s.trim()).filter(Boolean);
3483
+ if (Array.isArray(value))
3484
+ return value.map(String);
3485
+ if (typeof value === "string")
3486
+ return value.split(",").map((s) => s.trim()).filter(Boolean);
3412
3487
  return [];
3413
3488
  }
3414
3489
  function toSmaranMarkdown(entry) {
@@ -3421,7 +3496,8 @@ function toSmaranMarkdown(entry) {
3421
3496
  lines.push(entry.tags.length > 0 ? `tags: [${entry.tags.join(", ")}]` : "tags: []");
3422
3497
  lines.push(`created: ${entry.createdAt}`);
3423
3498
  lines.push(`updated: ${entry.updatedAt}`);
3424
- if (entry.sessionId) lines.push(`session: ${entry.sessionId}`);
3499
+ if (entry.sessionId)
3500
+ lines.push(`session: ${entry.sessionId}`);
3425
3501
  lines.push(`decayHalfLifeDays: ${entry.decayHalfLifeDays}`);
3426
3502
  lines.push("---");
3427
3503
  lines.push("");
@@ -3431,12 +3507,14 @@ function toSmaranMarkdown(entry) {
3431
3507
  }
3432
3508
  function fromSmaranMarkdown(content) {
3433
3509
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
3434
- if (!fmMatch) return null;
3510
+ if (!fmMatch)
3511
+ return null;
3435
3512
  const yaml = fmMatch[1];
3436
3513
  const body = content.slice(fmMatch[0].length).trim();
3437
3514
  const meta = parseSimpleYaml(yaml);
3438
3515
  const id = String(meta.id ?? "");
3439
- if (!id || !body) return null;
3516
+ if (!id || !body)
3517
+ return null;
3440
3518
  return {
3441
3519
  id,
3442
3520
  content: body,
@@ -3452,13 +3530,15 @@ function fromSmaranMarkdown(content) {
3452
3530
  }
3453
3531
  function loadSmaranEntries(storagePath) {
3454
3532
  const entries = /* @__PURE__ */ new Map();
3455
- if (!fs6.existsSync(storagePath)) return entries;
3533
+ if (!fs6.existsSync(storagePath))
3534
+ return entries;
3456
3535
  const files = fs6.readdirSync(storagePath).filter((f) => f.endsWith(".md"));
3457
3536
  for (const file of files) {
3458
3537
  try {
3459
3538
  const content = fs6.readFileSync(path6.join(storagePath, file), "utf-8");
3460
3539
  const entry = fromSmaranMarkdown(content);
3461
- if (entry) entries.set(entry.id, entry);
3540
+ if (entry)
3541
+ entries.set(entry.id, entry);
3462
3542
  } catch {
3463
3543
  }
3464
3544
  }
@@ -3472,32 +3552,37 @@ function saveSmaranEntry(storagePath, entry) {
3472
3552
  function deleteSmaranFile(storagePath, id) {
3473
3553
  const filePath = path6.join(storagePath, `${id}.md`);
3474
3554
  try {
3475
- if (fs6.existsSync(filePath)) fs6.unlinkSync(filePath);
3555
+ if (fs6.existsSync(filePath))
3556
+ fs6.unlinkSync(filePath);
3476
3557
  } catch {
3477
3558
  }
3478
3559
  }
3479
3560
  function findSimilarEntry(content, entries) {
3480
- const queryTerms = new Set(tokenize2(content));
3481
- if (queryTerms.size === 0) return null;
3561
+ const queryTerms = new Set(tokenize(content));
3562
+ if (queryTerms.size === 0)
3563
+ return null;
3482
3564
  for (const entry of entries) {
3483
- const entryTerms = new Set(tokenize2(entry.content));
3565
+ const entryTerms = new Set(tokenize(entry.content));
3484
3566
  let overlap = 0;
3485
3567
  for (const term of queryTerms) {
3486
- if (entryTerms.has(term)) overlap++;
3568
+ if (entryTerms.has(term))
3569
+ overlap++;
3487
3570
  }
3488
3571
  const similarity = overlap / Math.max(queryTerms.size, entryTerms.size);
3489
- if (similarity > 0.8) return entry;
3572
+ if (similarity > 0.8)
3573
+ return entry;
3490
3574
  }
3491
3575
  return null;
3492
3576
  }
3493
3577
  function scoreBM25Recall(entries, query, threshold) {
3494
- const queryTerms = tokenize2(query);
3495
- if (queryTerms.length === 0) return [];
3578
+ const queryTerms = tokenize(query);
3579
+ if (queryTerms.length === 0)
3580
+ return [];
3496
3581
  const allEntries = [];
3497
3582
  const df = /* @__PURE__ */ new Map();
3498
3583
  for (const entry of entries) {
3499
3584
  allEntries.push(entry);
3500
- const terms = new Set(tokenize2(entry.content + " " + entry.tags.join(" ")));
3585
+ const terms = new Set(tokenize(entry.content + " " + entry.tags.join(" ")));
3501
3586
  for (const term of terms) {
3502
3587
  df.set(term, (df.get(term) ?? 0) + 1);
3503
3588
  }
@@ -3510,30 +3595,33 @@ function scoreBM25Recall(entries, query, threshold) {
3510
3595
  const scored = [];
3511
3596
  for (const entry of allEntries) {
3512
3597
  const docText = (entry.content + " " + entry.tags.join(" ")).toLowerCase();
3513
- const docTerms = tokenize2(docText);
3598
+ const docTerms = tokenize(docText);
3514
3599
  let bm25 = 0;
3515
3600
  for (const qt of queryTerms) {
3516
3601
  const termFreq = docTerms.filter((t) => t === qt).length;
3517
- if (termFreq === 0) continue;
3602
+ if (termFreq === 0)
3603
+ continue;
3518
3604
  const docFreq = df.get(qt) ?? 0;
3519
3605
  const idf = Math.log((N - docFreq + 0.5) / (docFreq + 0.5) + 1);
3520
3606
  const tf = termFreq * (k1 + 1) / (termFreq + k1 * (1 - b + b * docTerms.length / avgLen));
3521
3607
  bm25 += idf * tf;
3522
3608
  }
3523
- if (docText.includes(queryLower)) bm25 *= 1.5;
3609
+ if (docText.includes(queryLower))
3610
+ bm25 *= 1.5;
3524
3611
  bm25 *= 0.5 + 0.5 * entry.confidence;
3525
3612
  if (entry.decayHalfLifeDays > 0) {
3526
3613
  const ageMs = Date.now() - new Date(entry.updatedAt).getTime();
3527
3614
  const ageDays = ageMs / (1e3 * 60 * 60 * 24);
3528
3615
  bm25 *= Math.exp(-Math.LN2 * ageDays / entry.decayHalfLifeDays);
3529
3616
  }
3530
- if (bm25 >= threshold) scored.push({ entry, score: bm25 });
3617
+ if (bm25 >= threshold)
3618
+ scored.push({ entry, score: bm25 });
3531
3619
  }
3532
3620
  scored.sort((a, b2) => b2.score - a.score);
3533
3621
  return scored;
3534
3622
  }
3535
3623
 
3536
- // ../chitragupta/packages/smriti/src/smaran.ts
3624
+ // ../chitragupta/packages/smriti/dist/smaran.js
3537
3625
  var DEFAULT_CONFIG3 = {
3538
3626
  maxEntries: 1e3,
3539
3627
  defaultDecayDays: 90,
@@ -3553,14 +3641,8 @@ var SmaranStore = class {
3553
3641
  this.config = {
3554
3642
  ...DEFAULT_CONFIG3,
3555
3643
  ...config,
3556
- maxEntries: Math.min(
3557
- config?.maxEntries ?? DEFAULT_CONFIG3.maxEntries,
3558
- SMARAN_HARD_CEILINGS.maxEntries
3559
- ),
3560
- recallLimit: Math.min(
3561
- config?.recallLimit ?? DEFAULT_CONFIG3.recallLimit,
3562
- SMARAN_HARD_CEILINGS.recallLimit
3563
- )
3644
+ maxEntries: Math.min(config?.maxEntries ?? DEFAULT_CONFIG3.maxEntries, SMARAN_HARD_CEILINGS.maxEntries),
3645
+ recallLimit: Math.min(config?.recallLimit ?? DEFAULT_CONFIG3.recallLimit, SMARAN_HARD_CEILINGS.recallLimit)
3564
3646
  };
3565
3647
  this.storagePath = this.config.storagePath ?? path7.join(getChitraguptaHome(), "smaran");
3566
3648
  }
@@ -3603,7 +3685,8 @@ var SmaranStore = class {
3603
3685
  /** Delete a memory by ID. Returns true if deleted. */
3604
3686
  forget(id) {
3605
3687
  this.ensureLoaded();
3606
- if (!this.entries.has(id)) return false;
3688
+ if (!this.entries.has(id))
3689
+ return false;
3607
3690
  this.entries.delete(id);
3608
3691
  deleteSmaranFile(this.storagePath, id);
3609
3692
  return true;
@@ -3614,7 +3697,8 @@ var SmaranStore = class {
3614
3697
  const lower = query.toLowerCase();
3615
3698
  const toDelete = [];
3616
3699
  for (const [id, entry] of this.entries) {
3617
- if (entry.content.toLowerCase().includes(lower)) toDelete.push(id);
3700
+ if (entry.content.toLowerCase().includes(lower))
3701
+ toDelete.push(id);
3618
3702
  }
3619
3703
  for (const id of toDelete) {
3620
3704
  this.entries.delete(id);
@@ -3626,11 +3710,16 @@ var SmaranStore = class {
3626
3710
  update(id, updates) {
3627
3711
  this.ensureLoaded();
3628
3712
  const entry = this.entries.get(id);
3629
- if (!entry) return null;
3630
- if (updates.content !== void 0) entry.content = updates.content;
3631
- if (updates.category !== void 0) entry.category = updates.category;
3632
- if (updates.tags !== void 0) entry.tags = updates.tags;
3633
- if (updates.confidence !== void 0) entry.confidence = updates.confidence;
3713
+ if (!entry)
3714
+ return null;
3715
+ if (updates.content !== void 0)
3716
+ entry.content = updates.content;
3717
+ if (updates.category !== void 0)
3718
+ entry.category = updates.category;
3719
+ if (updates.tags !== void 0)
3720
+ entry.tags = updates.tags;
3721
+ if (updates.confidence !== void 0)
3722
+ entry.confidence = updates.confidence;
3634
3723
  entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3635
3724
  saveSmaranEntry(this.storagePath, entry);
3636
3725
  return entry;
@@ -3644,7 +3733,8 @@ var SmaranStore = class {
3644
3733
  /** Recall memories relevant to a query using BM25-like scoring. */
3645
3734
  recall(query, limit) {
3646
3735
  this.ensureLoaded();
3647
- if (this.entries.size === 0) return [];
3736
+ if (this.entries.size === 0)
3737
+ return [];
3648
3738
  const maxResults = limit ?? this.config.recallLimit;
3649
3739
  const scored = scoreBM25Recall(this.entries.values(), query, this.config.recallThreshold);
3650
3740
  return scored.slice(0, maxResults).map((s) => s.entry);
@@ -3654,16 +3744,15 @@ var SmaranStore = class {
3654
3744
  this.ensureLoaded();
3655
3745
  const results = [];
3656
3746
  for (const entry of this.entries.values()) {
3657
- if (entry.category === category) results.push(entry);
3747
+ if (entry.category === category)
3748
+ results.push(entry);
3658
3749
  }
3659
3750
  return results.sort((a, b) => b.confidence - a.confidence);
3660
3751
  }
3661
3752
  /** List all entries. */
3662
3753
  listAll() {
3663
3754
  this.ensureLoaded();
3664
- return [...this.entries.values()].sort(
3665
- (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
3666
- );
3755
+ return [...this.entries.values()].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
3667
3756
  }
3668
3757
  /** Get total count of stored memories. */
3669
3758
  get size() {
@@ -3678,9 +3767,11 @@ var SmaranStore = class {
3678
3767
  */
3679
3768
  buildContextSection(query, maxTokens = 2e3) {
3680
3769
  this.ensureLoaded();
3681
- if (this.entries.size === 0) return "";
3770
+ if (this.entries.size === 0)
3771
+ return "";
3682
3772
  const entries = query ? this.recall(query, 15) : this.listAll().slice(0, 20);
3683
- if (entries.length === 0) return "";
3773
+ if (entries.length === 0)
3774
+ return "";
3684
3775
  const sections = ["## User Memory (Smaran)", ""];
3685
3776
  const grouped = /* @__PURE__ */ new Map();
3686
3777
  for (const entry of entries) {
@@ -3697,10 +3788,12 @@ var SmaranStore = class {
3697
3788
  };
3698
3789
  let totalLen = 0;
3699
3790
  for (const [category, catEntries] of grouped) {
3700
- if (totalLen >= maxTokens) break;
3791
+ if (totalLen >= maxTokens)
3792
+ break;
3701
3793
  sections.push(`### ${labels[category]}`);
3702
3794
  for (const entry of catEntries) {
3703
- if (totalLen >= maxTokens) break;
3795
+ if (totalLen >= maxTokens)
3796
+ break;
3704
3797
  const conf = entry.source === "explicit" ? "" : ` (confidence: ${entry.confidence.toFixed(1)})`;
3705
3798
  const line = `- ${entry.content}${conf}`;
3706
3799
  sections.push(line);
@@ -3717,7 +3810,8 @@ var SmaranStore = class {
3717
3810
  const now = Date.now();
3718
3811
  let modified = false;
3719
3812
  for (const entry of this.entries.values()) {
3720
- if (entry.decayHalfLifeDays <= 0) continue;
3813
+ if (entry.decayHalfLifeDays <= 0)
3814
+ continue;
3721
3815
  const ageMs = now - new Date(entry.updatedAt).getTime();
3722
3816
  const ageDays = ageMs / (1e3 * 60 * 60 * 24);
3723
3817
  const decay = Math.exp(-Math.LN2 * ageDays / entry.decayHalfLifeDays);
@@ -3749,7 +3843,8 @@ var SmaranStore = class {
3749
3843
  }
3750
3844
  // ─── Internal ─────────────────────────────────────────────────────────
3751
3845
  ensureLoaded() {
3752
- if (this.loaded) return;
3846
+ if (this.loaded)
3847
+ return;
3753
3848
  this.entries = loadSmaranEntries(this.storagePath);
3754
3849
  this.loaded = true;
3755
3850
  }
@@ -3763,7 +3858,7 @@ var SmaranStore = class {
3763
3858
  }
3764
3859
  };
3765
3860
 
3766
- // ../chitragupta/packages/smriti/src/memory-nlu.ts
3861
+ // ../chitragupta/packages/smriti/dist/memory-nlu.js
3767
3862
  var REMEMBER_PATTERNS = [
3768
3863
  { pattern: /\bremember\s+that\s+(.+)/i, contentGroup: 1 },
3769
3864
  { pattern: /\bremember\s*:\s*(.+)/i, contentGroup: 1 },
@@ -3816,7 +3911,8 @@ var CATEGORY_PATTERNS = [
3816
3911
  ];
3817
3912
  function detectMemoryIntent(text) {
3818
3913
  const trimmed = text.trim();
3819
- if (!trimmed) return null;
3914
+ if (!trimmed)
3915
+ return null;
3820
3916
  for (const pattern of FORGET_PATTERNS) {
3821
3917
  const match = trimmed.match(pattern);
3822
3918
  if (match) {
@@ -3848,7 +3944,8 @@ function detectMemoryIntent(text) {
3848
3944
  const match = trimmed.match(pattern);
3849
3945
  if (match) {
3850
3946
  const content = contentGroup === 0 ? trimmed : (match[contentGroup] ?? "").trim();
3851
- if (!content) continue;
3947
+ if (!content)
3948
+ continue;
3852
3949
  return {
3853
3950
  action: "remember",
3854
3951
  content: cleanContent(content),
@@ -3860,7 +3957,8 @@ function detectMemoryIntent(text) {
3860
3957
  }
3861
3958
  function detectCategory(content) {
3862
3959
  for (const { pattern, category } of CATEGORY_PATTERNS) {
3863
- if (pattern.test(content)) return category;
3960
+ if (pattern.test(content))
3961
+ return category;
3864
3962
  }
3865
3963
  return "fact";
3866
3964
  }
@@ -3868,7 +3966,7 @@ function cleanContent(content) {
3868
3966
  return content.replace(/[.!?]+$/, "").replace(/\s+/g, " ").trim();
3869
3967
  }
3870
3968
 
3871
- // ../chitragupta/packages/smriti/src/identity-context.ts
3969
+ // ../chitragupta/packages/smriti/dist/identity-context.js
3872
3970
  import fs7 from "fs";
3873
3971
  import path8 from "path";
3874
3972
  import os2 from "os";
@@ -3894,7 +3992,8 @@ var IdentityContext = class {
3894
3992
  */
3895
3993
  load() {
3896
3994
  const files = this.loadFiles();
3897
- if (files.length === 0) return "";
3995
+ if (files.length === 0)
3996
+ return "";
3898
3997
  const sections = [];
3899
3998
  sections.push("## Identity & Values");
3900
3999
  sections.push("");
@@ -3918,7 +4017,8 @@ var IdentityContext = class {
3918
4017
  loadUserPreferences() {
3919
4018
  const files = this.loadFiles();
3920
4019
  const userFile = files.find((f) => f.type === "user");
3921
- if (!userFile) return "";
4020
+ if (!userFile)
4021
+ return "";
3922
4022
  const content = stripFrontmatter(userFile.content);
3923
4023
  const prefSections = [];
3924
4024
  const sectionPattern = /^##\s+(.+)$/gm;
@@ -3957,7 +4057,8 @@ var IdentityContext = class {
3957
4057
  }
3958
4058
  // ─── Internal ─────────────────────────────────────────────────────────
3959
4059
  loadFiles() {
3960
- if (this.cachedFiles) return this.cachedFiles;
4060
+ if (this.cachedFiles)
4061
+ return this.cachedFiles;
3961
4062
  const include = this.config.include ?? DEFAULT_INCLUDE;
3962
4063
  const files = [];
3963
4064
  for (const type of include) {
@@ -3973,7 +4074,8 @@ var IdentityContext = class {
3973
4074
  const explicitPath = this.config.paths?.[type];
3974
4075
  if (explicitPath) {
3975
4076
  const content = readFileSafe(explicitPath);
3976
- if (content) return { type, path: explicitPath, content };
4077
+ if (content)
4078
+ return { type, path: explicitPath, content };
3977
4079
  }
3978
4080
  const searchDirs = this.getSearchDirs();
3979
4081
  const fileNames = FILE_NAMES[type];
@@ -3981,7 +4083,8 @@ var IdentityContext = class {
3981
4083
  for (const name of fileNames) {
3982
4084
  const filePath = path8.join(dir, name);
3983
4085
  const content = readFileSafe(filePath);
3984
- if (content) return { type, path: filePath, content };
4086
+ if (content)
4087
+ return { type, path: filePath, content };
3985
4088
  }
3986
4089
  }
3987
4090
  return null;
@@ -3993,7 +4096,8 @@ var IdentityContext = class {
3993
4096
  let current = this.config.projectPath;
3994
4097
  for (let i = 0; i < 3; i++) {
3995
4098
  const parent = path8.dirname(current);
3996
- if (parent === current) break;
4099
+ if (parent === current)
4100
+ break;
3997
4101
  dirs.push(parent);
3998
4102
  current = parent;
3999
4103
  }
@@ -4020,7 +4124,8 @@ function readFileSafe(filePath) {
4020
4124
  try {
4021
4125
  if (fs7.existsSync(filePath)) {
4022
4126
  const content = fs7.readFileSync(filePath, "utf-8");
4023
- if (content.trim().length > 0) return content;
4127
+ if (content.trim().length > 0)
4128
+ return content;
4024
4129
  }
4025
4130
  } catch {
4026
4131
  }
@@ -4031,7 +4136,7 @@ function stripFrontmatter(content) {
4031
4136
  return fmMatch ? content.slice(fmMatch[0].length) : content;
4032
4137
  }
4033
4138
 
4034
- // ../chitragupta/packages/smriti/src/svapna-extraction.ts
4139
+ // ../chitragupta/packages/smriti/dist/svapna-extraction.js
4035
4140
  var FNV_OFFSET2 = 2166136261;
4036
4141
  var FNV_PRIME2 = 16777619;
4037
4142
  function fnv1a3(input) {
@@ -4043,7 +4148,8 @@ function fnv1a3(input) {
4043
4148
  return hash.toString(16).padStart(8, "0");
4044
4149
  }
4045
4150
  function parseToolCalls(json) {
4046
- if (!json) return [];
4151
+ if (!json)
4152
+ return [];
4047
4153
  try {
4048
4154
  const parsed = JSON.parse(json);
4049
4155
  return Array.isArray(parsed) ? parsed : [];
@@ -4056,20 +4162,24 @@ function toolNames(calls) {
4056
4162
  }
4057
4163
  function buildToolFingerprint(names) {
4058
4164
  const fp = /* @__PURE__ */ new Set();
4059
- if (names.length === 0) return fp;
4060
- for (const name of names) fp.add(fnv1a3(`u:${name}`));
4165
+ if (names.length === 0)
4166
+ return fp;
4167
+ for (const name of names)
4168
+ fp.add(fnv1a3(`u:${name}`));
4061
4169
  for (let i = 0; i < names.length - 1; i++) {
4062
4170
  fp.add(fnv1a3(`b:${names[i]}:${names[i + 1]}`));
4063
4171
  }
4064
4172
  return fp;
4065
4173
  }
4066
4174
  function jaccardSimilarity(a, b) {
4067
- if (a.size === 0 && b.size === 0) return 0;
4175
+ if (a.size === 0 && b.size === 0)
4176
+ return 0;
4068
4177
  let intersection = 0;
4069
4178
  const smaller = a.size <= b.size ? a : b;
4070
4179
  const larger = a.size <= b.size ? b : a;
4071
4180
  for (const elem of smaller) {
4072
- if (larger.has(elem)) intersection++;
4181
+ if (larger.has(elem))
4182
+ intersection++;
4073
4183
  }
4074
4184
  const union = a.size + b.size - intersection;
4075
4185
  return union > 0 ? intersection / union : 0;
@@ -4077,21 +4187,26 @@ function jaccardSimilarity(a, b) {
4077
4187
  async function svapnaReplay(db, config) {
4078
4188
  const start = performance.now();
4079
4189
  const agentDb = db.get("agent");
4080
- const sessions = agentDb.prepare(
4081
- `SELECT id FROM sessions WHERE project = ? ORDER BY updated_at DESC LIMIT ?`
4082
- ).all(config.project, config.maxSessionsPerCycle);
4190
+ const sessions = agentDb.prepare(`SELECT id FROM sessions WHERE project = ? ORDER BY updated_at DESC LIMIT ?`).all(config.project, config.maxSessionsPerCycle);
4083
4191
  if (sessions.length === 0) {
4084
4192
  return { allTurns: [], highSurpriseTurns: [], turnsScored: 0, highSurprise: 0, durationMs: performance.now() - start };
4085
4193
  }
4086
4194
  const sessionIds = sessions.map((s) => s.id);
4087
4195
  const placeholders = sessionIds.map(() => "?").join(",");
4088
- const turns = agentDb.prepare(
4089
- `SELECT id, session_id, turn_number, role, content, tool_calls, created_at
4090
- FROM turns WHERE session_id IN (${placeholders}) ORDER BY created_at ASC`
4091
- ).all(...sessionIds);
4196
+ const turns = agentDb.prepare(`SELECT id, session_id, turn_number, role, content, tool_calls, created_at
4197
+ FROM turns WHERE session_id IN (${placeholders}) ORDER BY created_at ASC`).all(...sessionIds);
4198
+ const realTurns = turns.filter((t) => {
4199
+ if (t.content.startsWith("[system:context]"))
4200
+ return false;
4201
+ if (t.content.startsWith("[compressed] [system:context]"))
4202
+ return false;
4203
+ if (/^\[tool:chitragupta_record_conversation\] recorded \d+/.test(t.content))
4204
+ return false;
4205
+ return true;
4206
+ });
4092
4207
  const patternCounts = /* @__PURE__ */ new Map();
4093
4208
  let totalPatterns = 0;
4094
- for (const turn of turns) {
4209
+ for (const turn of realTurns) {
4095
4210
  const calls = parseToolCalls(turn.tool_calls);
4096
4211
  for (const tc of calls) {
4097
4212
  const key = `${tc.name}:${tc.isError ? "err" : "ok"}`;
@@ -4100,7 +4215,7 @@ async function svapnaReplay(db, config) {
4100
4215
  }
4101
4216
  }
4102
4217
  const scoredTurns = [];
4103
- for (const turn of turns) {
4218
+ for (const turn of realTurns) {
4104
4219
  const calls = parseToolCalls(turn.tool_calls);
4105
4220
  let surprise = 0;
4106
4221
  if (calls.length > 0) {
@@ -4131,7 +4246,9 @@ async function svapnaReplay(db, config) {
4131
4246
  }
4132
4247
  if (scoredTurns.length > 0) {
4133
4248
  let maxSurprise = 0;
4134
- for (const st of scoredTurns) if (st.surprise > maxSurprise) maxSurprise = st.surprise;
4249
+ for (const st of scoredTurns)
4250
+ if (st.surprise > maxSurprise)
4251
+ maxSurprise = st.surprise;
4135
4252
  if (maxSurprise > 0) {
4136
4253
  for (const st of scoredTurns) {
4137
4254
  st.surprise /= maxSurprise;
@@ -4139,9 +4256,7 @@ async function svapnaReplay(db, config) {
4139
4256
  }
4140
4257
  }
4141
4258
  }
4142
- const highSurpriseTurns = scoredTurns.filter(
4143
- (st) => st.surprise >= config.surpriseThreshold
4144
- );
4259
+ const highSurpriseTurns = scoredTurns.filter((st) => st.surprise >= config.surpriseThreshold);
4145
4260
  return {
4146
4261
  allTurns: scoredTurns,
4147
4262
  highSurpriseTurns,
@@ -4159,13 +4274,12 @@ async function svapnaRecombine(db, config, highSurpriseTurns) {
4159
4274
  const sessionFingerprints = /* @__PURE__ */ new Map();
4160
4275
  const sessions = agentDb.prepare(`SELECT id FROM sessions WHERE project = ? ORDER BY updated_at DESC LIMIT ?`).all(config.project, config.maxSessionsPerCycle);
4161
4276
  for (const session of sessions) {
4162
- const turns = agentDb.prepare(
4163
- `SELECT tool_calls FROM turns
4277
+ const turns = agentDb.prepare(`SELECT tool_calls FROM turns
4164
4278
  WHERE session_id = ? AND tool_calls IS NOT NULL
4165
- ORDER BY turn_number ASC`
4166
- ).all(session.id);
4279
+ ORDER BY turn_number ASC`).all(session.id);
4167
4280
  const allNames = [];
4168
- for (const turn of turns) allNames.push(...toolNames(parseToolCalls(turn.tool_calls)));
4281
+ for (const turn of turns)
4282
+ allNames.push(...toolNames(parseToolCalls(turn.tool_calls)));
4169
4283
  if (allNames.length > 0) {
4170
4284
  const fp = buildToolFingerprint(allNames);
4171
4285
  sessionFingerprints.set(session.id, {
@@ -4179,11 +4293,13 @@ async function svapnaRecombine(db, config, highSurpriseTurns) {
4179
4293
  const MIN_SIMILARITY = 0.15;
4180
4294
  for (const st of highSurpriseTurns) {
4181
4295
  const turnToolNames = toolNames(st.toolCalls);
4182
- if (turnToolNames.length === 0) continue;
4296
+ if (turnToolNames.length === 0)
4297
+ continue;
4183
4298
  const turnFp = buildToolFingerprint(turnToolNames);
4184
4299
  const turnFpStr = [...turnFp].sort().join(",");
4185
4300
  for (const [sessionId, sessionFp] of sessionFingerprints) {
4186
- if (sessionId === st.sessionId) continue;
4301
+ if (sessionId === st.sessionId)
4302
+ continue;
4187
4303
  const sim = jaccardSimilarity(turnFp, sessionFp.fingerprint);
4188
4304
  if (sim >= MIN_SIMILARITY) {
4189
4305
  associations.push({
@@ -4202,7 +4318,7 @@ async function svapnaRecombine(db, config, highSurpriseTurns) {
4202
4318
  return { associations, crossSessions: crossSessionPairs.size, durationMs: performance.now() - start };
4203
4319
  }
4204
4320
 
4205
- // ../chitragupta/packages/smriti/src/svapna-rules.ts
4321
+ // ../chitragupta/packages/smriti/dist/svapna-rules.js
4206
4322
  var FNV_OFFSET3 = 2166136261;
4207
4323
  var FNV_PRIME3 = 16777619;
4208
4324
  function fnv1a4(input) {
@@ -4217,8 +4333,10 @@ function textSimilarity2(a, b) {
4217
4333
  const normalize = (s) => s.toLowerCase().trim().replace(/\s+/g, " ");
4218
4334
  const na = normalize(a);
4219
4335
  const nb = normalize(b);
4220
- if (na === nb) return 1;
4221
- if (na.length < 2 || nb.length < 2) return 0;
4336
+ if (na === nb)
4337
+ return 1;
4338
+ if (na.length < 2 || nb.length < 2)
4339
+ return 0;
4222
4340
  const bigrams = (s) => {
4223
4341
  const map = /* @__PURE__ */ new Map();
4224
4342
  for (let i = 0; i < s.length - 1; i++) {
@@ -4243,15 +4361,13 @@ async function svapnaCrystallize(db, config) {
4243
4361
  const agentDb = db.get("agent");
4244
4362
  let vasanasCreated = 0;
4245
4363
  let vasanasReinforced = 0;
4246
- const samskaras = agentDb.prepare(
4247
- `SELECT id, session_id, pattern_type, pattern_content,
4364
+ const samskaras = agentDb.prepare(`SELECT id, session_id, pattern_type, pattern_content,
4248
4365
  observation_count, confidence, pramana_type, project
4249
4366
  FROM samskaras
4250
4367
  WHERE (project = ? OR project IS NULL)
4251
4368
  AND observation_count >= ?
4252
4369
  AND confidence > 0.5
4253
- ORDER BY confidence DESC`
4254
- ).all(config.project, config.minPatternFrequency);
4370
+ ORDER BY confidence DESC`).all(config.project, config.minPatternFrequency);
4255
4371
  if (samskaras.length === 0) {
4256
4372
  return { vasanasCreated: 0, vasanasReinforced: 0, durationMs: performance.now() - start };
4257
4373
  }
@@ -4281,47 +4397,33 @@ async function svapnaCrystallize(db, config) {
4281
4397
  }
4282
4398
  const now = Date.now();
4283
4399
  for (const cluster of clusters) {
4284
- if (cluster.sessionIds.size < 2) continue;
4400
+ if (cluster.sessionIds.size < 2)
4401
+ continue;
4285
4402
  const tendency = slugify(cluster.representative);
4286
4403
  const vasanaId = fnv1a4(`${tendency}:${config.project}`);
4287
4404
  const existing = agentDb.prepare("SELECT id, strength, activation_count FROM vasanas WHERE name = ? AND (project = ? OR project IS NULL)").get(tendency, config.project);
4288
4405
  if (existing) {
4289
4406
  const newStrength = Math.min(1, existing.strength + 0.1);
4290
- agentDb.prepare(
4291
- `UPDATE vasanas SET strength = ?, last_activated = ?, activation_count = ?, updated_at = ?, source_samskaras = ?
4292
- WHERE id = ?`
4293
- ).run(newStrength, now, existing.activation_count + 1, now, JSON.stringify(cluster.samskaraIds), existing.id);
4407
+ agentDb.prepare(`UPDATE vasanas SET strength = ?, last_activated = ?, activation_count = ?, updated_at = ?, source_samskaras = ?
4408
+ WHERE id = ?`).run(newStrength, now, existing.activation_count + 1, now, JSON.stringify(cluster.samskaraIds), existing.id);
4294
4409
  vasanasReinforced++;
4295
4410
  } else {
4296
4411
  let valence = "neutral";
4297
- if (cluster.patternType === "correction") valence = "negative";
4412
+ if (cluster.patternType === "correction")
4413
+ valence = "negative";
4298
4414
  else if (cluster.patternType === "preference" || cluster.patternType === "convention") {
4299
4415
  valence = "positive";
4300
4416
  }
4301
- agentDb.prepare(
4302
- `INSERT INTO vasanas (name, description, valence, strength, stability,
4417
+ agentDb.prepare(`INSERT INTO vasanas (name, description, valence, strength, stability,
4303
4418
  source_samskaras, project, created_at, updated_at, last_activated, activation_count)
4304
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
4305
- ).run(
4306
- tendency,
4307
- cluster.representative,
4308
- valence,
4309
- Math.min(1, cluster.maxConfidence),
4310
- cluster.sessionIds.size / config.maxSessionsPerCycle,
4311
- JSON.stringify(cluster.samskaraIds),
4312
- config.project,
4313
- now,
4314
- now,
4315
- now,
4316
- 1
4317
- );
4419
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(tendency, cluster.representative, valence, Math.min(1, cluster.maxConfidence), cluster.sessionIds.size / config.maxSessionsPerCycle, JSON.stringify(cluster.samskaraIds), config.project, now, now, now, 1);
4318
4420
  vasanasCreated++;
4319
4421
  }
4320
4422
  }
4321
4423
  return { vasanasCreated, vasanasReinforced, durationMs: performance.now() - start };
4322
4424
  }
4323
4425
 
4324
- // ../chitragupta/packages/smriti/src/svapna-vidhi.ts
4426
+ // ../chitragupta/packages/smriti/dist/svapna-vidhi.js
4325
4427
  var FNV_OFFSET4 = 2166136261;
4326
4428
  var FNV_PRIME4 = 16777619;
4327
4429
  function fnv1a5(input) {
@@ -4344,12 +4446,14 @@ function extractNgrams(sequence, minN, maxN) {
4344
4446
  return counts;
4345
4447
  }
4346
4448
  function antiUnify(argSets) {
4347
- if (argSets.length === 0) return { template: {}, params: {} };
4449
+ if (argSets.length === 0)
4450
+ return { template: {}, params: {} };
4348
4451
  const template = {};
4349
4452
  const params = {};
4350
4453
  const allKeys = /* @__PURE__ */ new Set();
4351
4454
  for (const args of argSets) {
4352
- for (const key of Object.keys(args)) allKeys.add(key);
4455
+ for (const key of Object.keys(args))
4456
+ allKeys.add(key);
4353
4457
  }
4354
4458
  for (const key of allKeys) {
4355
4459
  const values = argSets.filter((a) => key in a).map((a) => a[key]);
@@ -4364,9 +4468,12 @@ function antiUnify(argSets) {
4364
4468
  let inferredType = "string";
4365
4469
  if (types.size === 1) {
4366
4470
  const t = [...types][0];
4367
- if (t === "number") inferredType = "number";
4368
- else if (t === "boolean") inferredType = "boolean";
4369
- else if (t === "object") inferredType = Array.isArray(values[0]) ? "array" : "object";
4471
+ if (t === "number")
4472
+ inferredType = "number";
4473
+ else if (t === "boolean")
4474
+ inferredType = "boolean";
4475
+ else if (t === "object")
4476
+ inferredType = Array.isArray(values[0]) ? "array" : "object";
4370
4477
  }
4371
4478
  params[paramName] = {
4372
4479
  name: paramName,
@@ -4380,14 +4487,15 @@ function antiUnify(argSets) {
4380
4487
  return { template, params };
4381
4488
  }
4382
4489
  function findSubsequenceStart(sequence, sub) {
4383
- if (sub.length > sequence.length) return -1;
4384
- outer:
4385
- for (let i = 0; i <= sequence.length - sub.length; i++) {
4386
- for (let j = 0; j < sub.length; j++) {
4387
- if (sequence[i + j] !== sub[j]) continue outer;
4388
- }
4389
- return i;
4490
+ if (sub.length > sequence.length)
4491
+ return -1;
4492
+ outer: for (let i = 0; i <= sequence.length - sub.length; i++) {
4493
+ for (let j = 0; j < sub.length; j++) {
4494
+ if (sequence[i + j] !== sub[j])
4495
+ continue outer;
4390
4496
  }
4497
+ return i;
4498
+ }
4391
4499
  return -1;
4392
4500
  }
4393
4501
  function generateTriggers(tools) {
@@ -4423,10 +4531,8 @@ async function svapnaProceduralize(db, config) {
4423
4531
  }
4424
4532
  const sessionToolData = [];
4425
4533
  for (const session of sessions) {
4426
- const turns = agentDb.prepare(
4427
- `SELECT tool_calls FROM turns
4428
- WHERE session_id = ? AND tool_calls IS NOT NULL ORDER BY turn_number ASC`
4429
- ).all(session.id);
4534
+ const turns = agentDb.prepare(`SELECT tool_calls FROM turns
4535
+ WHERE session_id = ? AND tool_calls IS NOT NULL ORDER BY turn_number ASC`).all(session.id);
4430
4536
  const names = [];
4431
4537
  const calls = [];
4432
4538
  let totalCalls = 0;
@@ -4437,7 +4543,8 @@ async function svapnaProceduralize(db, config) {
4437
4543
  names.push(tc.name);
4438
4544
  calls.push([tc]);
4439
4545
  totalCalls++;
4440
- if (tc.isError) errorCalls++;
4546
+ if (tc.isError)
4547
+ errorCalls++;
4441
4548
  }
4442
4549
  }
4443
4550
  if (names.length >= config.minSequenceLength) {
@@ -4470,7 +4577,8 @@ async function svapnaProceduralize(db, config) {
4470
4577
  if (startIdx >= 0) {
4471
4578
  const args = [];
4472
4579
  for (let i = 0; i < ngramToolNames.length; i++) {
4473
- if (startIdx + i >= sd.calls.length) break;
4580
+ if (startIdx + i >= sd.calls.length)
4581
+ break;
4474
4582
  const callGroup = sd.calls[startIdx + i];
4475
4583
  if (callGroup && callGroup.length > 0) {
4476
4584
  try {
@@ -4489,15 +4597,18 @@ async function svapnaProceduralize(db, config) {
4489
4597
  }
4490
4598
  const now = Date.now();
4491
4599
  for (const [ngramKey, entry] of ngramIndex) {
4492
- if (entry.sessionIds.size < 3) continue;
4600
+ if (entry.sessionIds.size < 3)
4601
+ continue;
4493
4602
  const avgSuccess = entry.successRates.reduce((s, r) => s + r, 0) / entry.successRates.length;
4494
- if (avgSuccess < config.minSuccessRate) continue;
4603
+ if (avgSuccess < config.minSuccessRate)
4604
+ continue;
4495
4605
  const steps = [];
4496
4606
  const allParams = {};
4497
4607
  for (let pos = 0; pos < entry.toolNames.length; pos++) {
4498
4608
  const posArgs = [];
4499
4609
  for (const argSet of entry.argSets) {
4500
- if (argSet[pos]) posArgs.push(argSet[pos]);
4610
+ if (argSet[pos])
4611
+ posArgs.push(argSet[pos]);
4501
4612
  }
4502
4613
  const { template, params } = antiUnify(posArgs);
4503
4614
  for (const [pName, pDef] of Object.entries(params)) {
@@ -4506,7 +4617,8 @@ async function svapnaProceduralize(db, config) {
4506
4617
  const oldRef = `\${${pName}}`;
4507
4618
  const newRef = `\${${qualifiedName}}`;
4508
4619
  for (const key of Object.keys(template)) {
4509
- if (template[key] === oldRef) template[key] = newRef;
4620
+ if (template[key] === oldRef)
4621
+ template[key] = newRef;
4510
4622
  }
4511
4623
  }
4512
4624
  steps.push({
@@ -4520,7 +4632,8 @@ async function svapnaProceduralize(db, config) {
4520
4632
  const vidhiName = slugify(ngramKey.replace(/ -> /g, "-then-"));
4521
4633
  const vidhiId = fnv1a5(`${vidhiName}:${config.project}`);
4522
4634
  const existing = agentDb.prepare("SELECT id FROM vidhis WHERE id = ?").get(vidhiId);
4523
- if (existing) continue;
4635
+ if (existing)
4636
+ continue;
4524
4637
  const vidhi = {
4525
4638
  id: vidhiId,
4526
4639
  project: config.project,
@@ -4536,33 +4649,17 @@ async function svapnaProceduralize(db, config) {
4536
4649
  createdAt: now,
4537
4650
  updatedAt: now
4538
4651
  };
4539
- agentDb.prepare(
4540
- `INSERT OR IGNORE INTO vidhis
4652
+ agentDb.prepare(`INSERT OR IGNORE INTO vidhis
4541
4653
  (id, project, name, learned_from, confidence, steps, triggers,
4542
4654
  success_rate, success_count, failure_count, parameter_schema,
4543
4655
  created_at, updated_at)
4544
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
4545
- ).run(
4546
- vidhi.id,
4547
- vidhi.project,
4548
- vidhi.name,
4549
- JSON.stringify(vidhi.learnedFrom),
4550
- vidhi.confidence,
4551
- JSON.stringify(vidhi.steps),
4552
- JSON.stringify(vidhi.triggers),
4553
- vidhi.successRate,
4554
- vidhi.successCount,
4555
- vidhi.failureCount,
4556
- JSON.stringify(vidhi.parameterSchema),
4557
- vidhi.createdAt,
4558
- vidhi.updatedAt
4559
- );
4656
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(vidhi.id, vidhi.project, vidhi.name, JSON.stringify(vidhi.learnedFrom), vidhi.confidence, JSON.stringify(vidhi.steps), JSON.stringify(vidhi.triggers), vidhi.successRate, vidhi.successCount, vidhi.failureCount, JSON.stringify(vidhi.parameterSchema), vidhi.createdAt, vidhi.updatedAt);
4560
4657
  createdVidhis.push(vidhi);
4561
4658
  }
4562
4659
  return { vidhisCreated: createdVidhis.length, vidhis: createdVidhis, durationMs: performance.now() - start };
4563
4660
  }
4564
4661
 
4565
- // ../chitragupta/packages/smriti/src/svapna-consolidation.ts
4662
+ // ../chitragupta/packages/smriti/dist/svapna-types.js
4566
4663
  var DEFAULT_CONFIG4 = {
4567
4664
  maxSessionsPerCycle: 50,
4568
4665
  surpriseThreshold: 0.7,
@@ -4579,6 +4676,8 @@ var PRAMANA_PRESERVATION = {
4579
4676
  arthapatti: 0.4,
4580
4677
  anupalabdhi: 0.25
4581
4678
  };
4679
+
4680
+ // ../chitragupta/packages/smriti/dist/svapna-consolidation.js
4582
4681
  var SvapnaConsolidation = class {
4583
4682
  config;
4584
4683
  db;
@@ -4606,54 +4705,41 @@ var SvapnaConsolidation = class {
4606
4705
  const report = onProgress ?? (() => {
4607
4706
  });
4608
4707
  this.logCycle("running");
4609
- report("REPLAY", 0);
4610
- const replayResult = await this.replay();
4611
- report("REPLAY", 1);
4612
- report("RECOMBINE", 0);
4613
- const recombineResult = await this.recombine(replayResult.highSurpriseTurns);
4614
- report("RECOMBINE", 1);
4615
- report("CRYSTALLIZE", 0);
4616
- const crystallizeResult = await this.crystallize();
4617
- report("CRYSTALLIZE", 1);
4618
- report("PROCEDURALIZE", 0);
4619
- const proceduralizeResult = await this.proceduralize();
4620
- report("PROCEDURALIZE", 1);
4621
- report("COMPRESS", 0);
4622
- const compressResult = await this.compress();
4623
- report("COMPRESS", 1);
4624
- const totalDurationMs = performance.now() - cycleStart;
4625
- const result = {
4626
- phases: {
4627
- replay: {
4628
- turnsScored: replayResult.turnsScored,
4629
- highSurprise: replayResult.highSurprise,
4630
- durationMs: replayResult.durationMs
4631
- },
4632
- recombine: {
4633
- associations: recombineResult.associations.length,
4634
- crossSessions: recombineResult.crossSessions,
4635
- durationMs: recombineResult.durationMs
4636
- },
4637
- crystallize: {
4638
- vasanasCreated: crystallizeResult.vasanasCreated,
4639
- vasanasReinforced: crystallizeResult.vasanasReinforced,
4640
- durationMs: crystallizeResult.durationMs
4641
- },
4642
- proceduralize: {
4643
- vidhisCreated: proceduralizeResult.vidhisCreated,
4644
- durationMs: proceduralizeResult.durationMs
4708
+ try {
4709
+ report("REPLAY", 0);
4710
+ const replayResult = await this.replay();
4711
+ report("REPLAY", 1);
4712
+ report("RECOMBINE", 0);
4713
+ const recombineResult = await this.recombine(replayResult.highSurpriseTurns);
4714
+ report("RECOMBINE", 1);
4715
+ report("CRYSTALLIZE", 0);
4716
+ const crystallizeResult = await this.crystallize();
4717
+ report("CRYSTALLIZE", 1);
4718
+ report("PROCEDURALIZE", 0);
4719
+ const proceduralizeResult = await this.proceduralize();
4720
+ report("PROCEDURALIZE", 1);
4721
+ report("COMPRESS", 0);
4722
+ const compressResult = await this.compress();
4723
+ report("COMPRESS", 1);
4724
+ const totalDurationMs = performance.now() - cycleStart;
4725
+ const result = {
4726
+ phases: {
4727
+ replay: { turnsScored: replayResult.turnsScored, highSurprise: replayResult.highSurprise, durationMs: replayResult.durationMs },
4728
+ recombine: { associations: recombineResult.associations.length, crossSessions: recombineResult.crossSessions, durationMs: recombineResult.durationMs },
4729
+ crystallize: { vasanasCreated: crystallizeResult.vasanasCreated, vasanasReinforced: crystallizeResult.vasanasReinforced, durationMs: crystallizeResult.durationMs },
4730
+ proceduralize: { vidhisCreated: proceduralizeResult.vidhisCreated, durationMs: proceduralizeResult.durationMs },
4731
+ compress: { tokensCompressed: compressResult.tokensCompressed, compressionRatio: compressResult.compressionRatio, durationMs: compressResult.durationMs }
4645
4732
  },
4646
- compress: {
4647
- tokensCompressed: compressResult.tokensCompressed,
4648
- compressionRatio: compressResult.compressionRatio,
4649
- durationMs: compressResult.durationMs
4650
- }
4651
- },
4652
- totalDurationMs,
4653
- cycleId: this.cycleId
4654
- };
4655
- this.logCycle("success", result);
4656
- return result;
4733
+ totalDurationMs,
4734
+ cycleId: this.cycleId
4735
+ };
4736
+ this.logCycle("success", result);
4737
+ return result;
4738
+ } catch (err) {
4739
+ const msg = err instanceof Error ? err.message : String(err);
4740
+ this.logCycle("failed");
4741
+ throw new Error(`Svapna cycle ${this.cycleId} failed: ${msg}`, { cause: err });
4742
+ }
4657
4743
  }
4658
4744
  // ── Phase Delegates ─────────────────────────────────────────────────
4659
4745
  /** Phase 1: Hippocampal replay — score turns by surprise. */
@@ -4687,10 +4773,8 @@ var SvapnaConsolidation = class {
4687
4773
  }
4688
4774
  const sessionIds = sessions.map((s) => s.id);
4689
4775
  const placeholders = sessionIds.map(() => "?").join(",");
4690
- const turns = agentDb.prepare(
4691
- `SELECT id, session_id, content, tool_calls, created_at
4692
- FROM turns WHERE session_id IN (${placeholders}) ORDER BY created_at ASC`
4693
- ).all(...sessionIds);
4776
+ const turns = agentDb.prepare(`SELECT id, session_id, content, tool_calls, created_at
4777
+ FROM turns WHERE session_id IN (${placeholders}) ORDER BY created_at ASC`).all(...sessionIds);
4694
4778
  if (turns.length === 0) {
4695
4779
  return { tokensCompressed: 0, compressionRatio: 1, durationMs: performance.now() - start };
4696
4780
  }
@@ -4699,6 +4783,8 @@ var SvapnaConsolidation = class {
4699
4783
  const maxAge = 30 * 24 * 60 * 60 * 1e3;
4700
4784
  let totalOriginalTokens = 0;
4701
4785
  for (const turn of turns) {
4786
+ if (this.isNoiseTurn(turn.content))
4787
+ continue;
4702
4788
  const tokens = estimateTokens(turn.content);
4703
4789
  totalOriginalTokens += tokens;
4704
4790
  const calls = parseToolCalls(turn.tool_calls);
@@ -4717,6 +4803,13 @@ var SvapnaConsolidation = class {
4717
4803
  if (chunks.length < 2) {
4718
4804
  return { tokensCompressed: totalOriginalTokens, compressionRatio: 1, durationMs: performance.now() - start };
4719
4805
  }
4806
+ const { compressedTotal } = this.applyCompression(chunks, turns, totalOriginalTokens);
4807
+ const compressionRatio = totalOriginalTokens > 0 ? compressedTotal / totalOriginalTokens : 1;
4808
+ return { tokensCompressed: totalOriginalTokens, compressionRatio, durationMs: performance.now() - start };
4809
+ }
4810
+ // ─── Private Helpers ──────────────────────────────────────────────────
4811
+ /** Build affinity matrix, run Sinkhorn, compute budgets, and write compressed content. */
4812
+ applyCompression(chunks, turns, totalOriginalTokens) {
4720
4813
  const n = chunks.length;
4721
4814
  const affinity = [];
4722
4815
  for (let i = 0; i < n; i++) {
@@ -4734,69 +4827,123 @@ var SvapnaConsolidation = class {
4734
4827
  const rawBudgets = new Array(n);
4735
4828
  for (let i = 0; i < n; i++) {
4736
4829
  let rowSum = 0;
4737
- for (let j = 0; j < n; j++) rowSum += dsMatrix[i][j];
4830
+ for (let j = 0; j < n; j++)
4831
+ rowSum += dsMatrix[i][j];
4738
4832
  rawBudgets[i] = rowSum * chunks[i].relevance;
4739
4833
  budgetTotal += rawBudgets[i];
4740
4834
  }
4741
4835
  const targetTokens = Math.floor(totalOriginalTokens * 0.7);
4742
4836
  let compressedTotal = 0;
4743
- if (budgetTotal > 0) {
4837
+ const agentDb = this.db.get("agent");
4838
+ const updateStmt = agentDb.prepare(`UPDATE turns SET content = ? WHERE id = ?`);
4839
+ const insertRuleStmt = agentDb.prepare(`INSERT INTO consolidation_rules
4840
+ (project, category, rule_text, source_sessions, confidence, created_at, updated_at)
4841
+ VALUES (?, 'abstraction', ?, ?, ?, ?, ?)`);
4842
+ const compressBatch = agentDb.transaction(() => {
4744
4843
  for (let i = 0; i < n; i++) {
4745
- const budget = Math.floor(rawBudgets[i] / budgetTotal * targetTokens);
4746
- compressedTotal += Math.min(budget, chunks[i].tokenCount);
4844
+ const budget = budgetTotal > 0 ? Math.floor(rawBudgets[i] / budgetTotal * targetTokens) : Math.floor(targetTokens / n);
4845
+ const turnTokens = chunks[i].tokenCount;
4846
+ const allocated = Math.min(budget, turnTokens);
4847
+ compressedTotal += allocated;
4848
+ if (turnTokens > 20 && allocated < turnTokens * 0.6) {
4849
+ const turn = turns[i];
4850
+ const gist = this.generateGist(turn.content, allocated);
4851
+ const cueAnchors = this.extractCueAnchors(turn.content);
4852
+ updateStmt.run(gist, turn.id);
4853
+ insertRuleStmt.run(this.config.project, gist, JSON.stringify([turn.session_id]), chunks[i].relevance, Date.now(), Date.now());
4854
+ if (cueAnchors.length > 0) {
4855
+ try {
4856
+ const graphDb = this.db.get("graph");
4857
+ const upsertNode = graphDb.prepare(`INSERT OR REPLACE INTO nodes (id, type, label, content, metadata) VALUES (?, 'concept', ?, ?, ?)`);
4858
+ for (const cue of cueAnchors) {
4859
+ upsertNode.run(`cue-${turn.id}-${cue.slice(0, 20)}`, cue, gist.slice(0, 200), JSON.stringify({ source: `turn:${turn.id}`, cycle: this.cycleId }));
4860
+ }
4861
+ } catch {
4862
+ }
4863
+ }
4864
+ }
4747
4865
  }
4748
- } else {
4749
- compressedTotal = targetTokens;
4866
+ });
4867
+ try {
4868
+ compressBatch();
4869
+ } catch {
4750
4870
  }
4751
- const compressionRatio = totalOriginalTokens > 0 ? compressedTotal / totalOriginalTokens : 1;
4752
- return { tokensCompressed: totalOriginalTokens, compressionRatio, durationMs: performance.now() - start };
4871
+ return { compressedTotal };
4872
+ }
4873
+ /** Generate a compressed gist (abstraction) of turn content. */
4874
+ generateGist(content, tokenBudget) {
4875
+ const sentences = content.split(/(?<=[.!?\n])\s+/).filter((s) => s.trim().length > 0);
4876
+ if (sentences.length <= 2)
4877
+ return content;
4878
+ const kept = [sentences[0]];
4879
+ const signalPattern = /\b(error|decided|created|modified|fixed|found|returned|result|output)\b/i;
4880
+ for (let i = 1; i < sentences.length - 1; i++) {
4881
+ if (signalPattern.test(sentences[i]))
4882
+ kept.push(sentences[i]);
4883
+ }
4884
+ kept.push(sentences[sentences.length - 1]);
4885
+ let gist = kept.join(" ");
4886
+ const words = gist.split(/\s+/);
4887
+ const wordBudget = Math.max(5, Math.floor(tokenBudget * 0.75));
4888
+ if (words.length > wordBudget)
4889
+ gist = words.slice(0, wordBudget).join(" ") + "...";
4890
+ return `[compressed] ${gist}`;
4891
+ }
4892
+ /** Extract cue anchors (trigger phrases) from turn content. */
4893
+ extractCueAnchors(content) {
4894
+ const anchors = [];
4895
+ const lower = content.toLowerCase();
4896
+ const voPattern = /\b(create|fix|refactor|implement|add|remove|update|debug|test|deploy|configure)\s+(\w+(?:\s+\w+)?)\b/gi;
4897
+ let match;
4898
+ while ((match = voPattern.exec(lower)) !== null)
4899
+ anchors.push(match[0].trim());
4900
+ const pathPattern = /[\w\-]+\.(?:ts|js|py|rs|go|java|tsx|jsx|json|yaml|toml)\b/gi;
4901
+ while ((match = pathPattern.exec(content)) !== null)
4902
+ anchors.push(match[0]);
4903
+ return [...new Set(anchors)].slice(0, 5);
4904
+ }
4905
+ /**
4906
+ * Detect noise turns that should be excluded from consolidation.
4907
+ * System context, compressed prompts, and meta-turns produce garbage rules.
4908
+ */
4909
+ isNoiseTurn(content) {
4910
+ if (content.startsWith("[system:context]"))
4911
+ return true;
4912
+ if (content.startsWith("[compressed] [system:context]"))
4913
+ return true;
4914
+ if (/^\[tool:chitragupta_record_conversation\] recorded \d+/.test(content))
4915
+ return true;
4916
+ return false;
4753
4917
  }
4754
- // ── Private Helpers ──────────────────────────────────────────────────
4755
4918
  /** Classify epistemological source (Pramana) of a turn's content. */
4756
4919
  classifyPramana(content, calls) {
4757
- if (calls.length > 0 && calls.some((tc) => !tc.isError && tc.result.length > 0)) {
4920
+ if (calls.length > 0 && calls.some((tc) => !tc.isError && tc.result.length > 0))
4758
4921
  return "pratyaksha";
4759
- }
4760
4922
  const lower = content.toLowerCase();
4761
- if (/\b(?:maybe|possibly|might|perhaps|could be|not sure|unsure)\b/.test(lower)) return "anupalabdhi";
4762
- if (/\b(?:must be|likely|probably|implies|therefore)\b/.test(lower)) return "arthapatti";
4763
- if (/\b(?:similar to|like|analogous|compared to|just as)\b/.test(lower)) return "upamana";
4764
- if (/\b(?:according to|documentation|docs say|reference|specification)\b/.test(lower)) return "shabda";
4923
+ if (/\b(?:maybe|possibly|might|perhaps|could be|not sure|unsure)\b/.test(lower))
4924
+ return "anupalabdhi";
4925
+ if (/\b(?:must be|likely|probably|implies|therefore)\b/.test(lower))
4926
+ return "arthapatti";
4927
+ if (/\b(?:similar to|like|analogous|compared to|just as)\b/.test(lower))
4928
+ return "upamana";
4929
+ if (/\b(?:according to|documentation|docs say|reference|specification)\b/.test(lower))
4930
+ return "shabda";
4765
4931
  return "anumana";
4766
4932
  }
4767
4933
  /** Write an entry to the consolidation_log table for audit trail. */
4768
4934
  logCycle(status, result) {
4769
4935
  const agentDb = this.db.get("agent");
4770
- agentDb.prepare(
4771
- `INSERT INTO consolidation_log
4936
+ agentDb.prepare(`INSERT INTO consolidation_log
4772
4937
  (project, cycle_type, cycle_id, phase, phase_duration_ms,
4773
4938
  vasanas_created, vidhis_created, samskaras_processed,
4774
4939
  sessions_processed, status, created_at)
4775
- VALUES (?, 'svapna', ?, ?, ?, ?, ?, ?, ?, ?, ?)`
4776
- ).run(
4777
- this.config.project,
4778
- this.cycleId,
4779
- result ? "ALL" : null,
4780
- result?.totalDurationMs ?? null,
4781
- result?.phases.crystallize.vasanasCreated ?? 0,
4782
- result?.phases.proceduralize.vidhisCreated ?? 0,
4783
- 0,
4784
- result?.phases.replay.turnsScored ?? 0,
4785
- status,
4786
- Date.now()
4787
- );
4788
- agentDb.prepare(
4789
- `UPDATE nidra_state SET consolidation_phase = ?, consolidation_progress = ?, updated_at = ?
4790
- WHERE id = 1`
4791
- ).run(
4792
- status === "running" ? "REPLAY" : null,
4793
- status === "success" ? 1 : 0,
4794
- Date.now()
4795
- );
4940
+ VALUES (?, 'svapna', ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(this.config.project, this.cycleId, result ? "ALL" : null, result?.totalDurationMs ?? null, result?.phases.crystallize.vasanasCreated ?? 0, result?.phases.proceduralize.vidhisCreated ?? 0, 0, result?.phases.replay.turnsScored ?? 0, status, Date.now());
4941
+ agentDb.prepare(`UPDATE nidra_state SET consolidation_phase = ?, consolidation_progress = ?, updated_at = ?
4942
+ WHERE id = 1`).run(status === "running" ? "REPLAY" : null, status === "success" ? 1 : 0, Date.now());
4796
4943
  }
4797
4944
  };
4798
4945
 
4799
- // ../chitragupta/packages/smriti/src/vidhi-matching.ts
4946
+ // ../chitragupta/packages/smriti/dist/vidhi-matching.js
4800
4947
  var ACTION_VERBS = /* @__PURE__ */ new Set([
4801
4948
  "add",
4802
4949
  "create",
@@ -4973,7 +5120,7 @@ var STOPWORDS = /* @__PURE__ */ new Set([
4973
5120
  "want",
4974
5121
  "like"
4975
5122
  ]);
4976
- function tokenize3(text) {
5123
+ function tokenize2(text) {
4977
5124
  const words = text.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/\s+/).filter((w) => w.length > 1 && !STOPWORDS.has(w));
4978
5125
  return new Set(words);
4979
5126
  }
@@ -4981,7 +5128,8 @@ function extractVerbObjectPhrases(message) {
4981
5128
  const words = message.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/\s+/).filter((w) => w.length > 1);
4982
5129
  const phrases = [];
4983
5130
  for (let i = 0; i < words.length; i++) {
4984
- if (!ACTION_VERBS.has(words[i])) continue;
5131
+ if (!ACTION_VERBS.has(words[i]))
5132
+ continue;
4985
5133
  if (i + 1 < words.length) {
4986
5134
  phrases.push(`${words[i]} ${words[i + 1]}`);
4987
5135
  }
@@ -4995,7 +5143,8 @@ function extractTriggers(instances) {
4995
5143
  const phraseCounts = /* @__PURE__ */ new Map();
4996
5144
  for (const instance of instances) {
4997
5145
  const msg = instance.precedingUserMessage;
4998
- if (!msg || msg.trim().length === 0) continue;
5146
+ if (!msg || msg.trim().length === 0)
5147
+ continue;
4999
5148
  const phrases = extractVerbObjectPhrases(msg);
5000
5149
  for (const phrase of phrases) {
5001
5150
  phraseCounts.set(phrase, (phraseCounts.get(phrase) ?? 0) + 1);
@@ -5025,35 +5174,42 @@ function sampleGamma2(shape) {
5025
5174
  } while (v <= 0);
5026
5175
  v = v * v * v;
5027
5176
  const u = Math.random();
5028
- if (u < 1 - 0.0331 * (x * x) * (x * x)) return d * v;
5029
- if (Math.log(u) < 0.5 * x * x + d * (1 - v + Math.log(v))) return d * v;
5177
+ if (u < 1 - 0.0331 * (x * x) * (x * x))
5178
+ return d * v;
5179
+ if (Math.log(u) < 0.5 * x * x + d * (1 - v + Math.log(v)))
5180
+ return d * v;
5030
5181
  }
5031
5182
  }
5032
5183
  function sampleBeta2(alpha, beta) {
5033
5184
  const x = sampleGamma2(alpha);
5034
5185
  const y = sampleGamma2(beta);
5035
5186
  const sum = x + y;
5036
- if (sum < 1e-300 || !isFinite(sum)) return 0.5;
5187
+ if (sum < 1e-300 || !isFinite(sum))
5188
+ return 0.5;
5037
5189
  return x / sum;
5038
5190
  }
5039
5191
  function matchVidhi(vidhis, query) {
5040
- if (vidhis.length === 0) return null;
5041
- const queryTokens = tokenize3(query);
5042
- if (queryTokens.size === 0) return null;
5192
+ if (vidhis.length === 0)
5193
+ return null;
5194
+ const queryTokens = tokenize2(query);
5195
+ if (queryTokens.size === 0)
5196
+ return null;
5043
5197
  let bestVidhi = null;
5044
5198
  let bestScore = 0;
5045
5199
  for (const vidhi of vidhis) {
5046
5200
  const triggerTokens = /* @__PURE__ */ new Set();
5047
5201
  for (const trigger of vidhi.triggers) {
5048
- for (const tok of tokenize3(trigger)) {
5202
+ for (const tok of tokenize2(trigger)) {
5049
5203
  triggerTokens.add(tok);
5050
5204
  }
5051
5205
  }
5052
- if (triggerTokens.size === 0) continue;
5206
+ if (triggerTokens.size === 0)
5207
+ continue;
5053
5208
  const intersection = new Set([...queryTokens].filter((t) => triggerTokens.has(t)));
5054
5209
  const union = /* @__PURE__ */ new Set([...queryTokens, ...triggerTokens]);
5055
5210
  const jaccard = intersection.size / union.size;
5056
- if (jaccard < 0.15) continue;
5211
+ if (jaccard < 0.15)
5212
+ continue;
5057
5213
  const alpha = vidhi.successCount + 1;
5058
5214
  const beta = vidhi.failureCount + 1;
5059
5215
  const thompsonSample = sampleBeta2(alpha, beta);
@@ -5066,7 +5222,7 @@ function matchVidhi(vidhis, query) {
5066
5222
  return bestVidhi;
5067
5223
  }
5068
5224
 
5069
- // ../chitragupta/packages/smriti/src/vidhi-extraction.ts
5225
+ // ../chitragupta/packages/smriti/dist/vidhi-extraction.js
5070
5226
  var FNV_OFFSET5 = 2166136261;
5071
5227
  var FNV_PRIME5 = 16777619;
5072
5228
  function fnv1a6(str) {
@@ -5079,11 +5235,10 @@ function fnv1a6(str) {
5079
5235
  }
5080
5236
  function loadSessionSequences(config) {
5081
5237
  const db = DatabaseManager.instance().get("agent");
5082
- const sessionRows = db.prepare(
5083
- "SELECT id FROM sessions WHERE project = ?"
5084
- ).all(config.project);
5238
+ const sessionRows = db.prepare("SELECT id FROM sessions WHERE project = ?").all(config.project);
5085
5239
  const sessionIds = new Set(sessionRows.map((r) => r.id));
5086
- if (sessionIds.size === 0) return /* @__PURE__ */ new Map();
5240
+ if (sessionIds.size === 0)
5241
+ return /* @__PURE__ */ new Map();
5087
5242
  const turnRows = db.prepare(`
5088
5243
  SELECT session_id, turn_number, role, content, tool_calls
5089
5244
  FROM turns
@@ -5097,14 +5252,16 @@ function loadSessionSequences(config) {
5097
5252
  lastUserMessage = row.content;
5098
5253
  continue;
5099
5254
  }
5100
- if (row.role !== "assistant" || !row.tool_calls) continue;
5255
+ if (row.role !== "assistant" || !row.tool_calls)
5256
+ continue;
5101
5257
  let toolCalls;
5102
5258
  try {
5103
5259
  toolCalls = JSON.parse(row.tool_calls);
5104
5260
  } catch {
5105
5261
  continue;
5106
5262
  }
5107
- if (!Array.isArray(toolCalls) || toolCalls.length === 0) continue;
5263
+ if (!Array.isArray(toolCalls) || toolCalls.length === 0)
5264
+ continue;
5108
5265
  if (!result.has(row.session_id)) {
5109
5266
  result.set(row.session_id, []);
5110
5267
  }
@@ -5122,12 +5279,14 @@ function loadSessionSequences(config) {
5122
5279
  function extractAndAggregate(sessionSequences, config) {
5123
5280
  const ngramMap = /* @__PURE__ */ new Map();
5124
5281
  for (const [sessionId, sequence] of sessionSequences) {
5125
- if (sequence.length < config.minSequenceLength) continue;
5282
+ if (sequence.length < config.minSequenceLength)
5283
+ continue;
5126
5284
  for (let n = config.minSequenceLength; n <= Math.min(config.maxSequenceLength, sequence.length); n++) {
5127
5285
  for (let i = 0; i <= sequence.length - n; i++) {
5128
5286
  const window = sequence.slice(i, i + n);
5129
5287
  const hasError = window.some((w) => w.toolCall.isError === true);
5130
- if (hasError) continue;
5288
+ if (hasError)
5289
+ continue;
5131
5290
  const key = window.map((w) => w.toolCall.name).join("|");
5132
5291
  if (!ngramMap.has(key)) {
5133
5292
  ngramMap.set(key, /* @__PURE__ */ new Map());
@@ -5145,14 +5304,14 @@ function extractAndAggregate(sessionSequences, config) {
5145
5304
  }
5146
5305
  const aggregates = [];
5147
5306
  for (const [key, sessionMap] of ngramMap) {
5148
- if (sessionMap.size < config.minSessions) continue;
5307
+ if (sessionMap.size < config.minSessions)
5308
+ continue;
5149
5309
  const instances = [...sessionMap.values()];
5150
5310
  const toolNames2 = key.split("|");
5151
- const successfulInstances = instances.filter(
5152
- (inst) => inst.toolCalls.every((tc) => !tc.isError)
5153
- );
5311
+ const successfulInstances = instances.filter((inst) => inst.toolCalls.every((tc) => !tc.isError));
5154
5312
  const successRate = instances.length > 0 ? successfulInstances.length / instances.length : 0;
5155
- if (successRate < config.minSuccessRate) continue;
5313
+ if (successRate < config.minSuccessRate)
5314
+ continue;
5156
5315
  aggregates.push({
5157
5316
  key,
5158
5317
  toolNames: toolNames2,
@@ -5266,36 +5425,45 @@ function generateName(toolNames2) {
5266
5425
  function inferType(values) {
5267
5426
  const types = /* @__PURE__ */ new Set();
5268
5427
  for (const v of values) {
5269
- if (v === null || v === void 0) continue;
5270
- if (typeof v === "string") types.add("string");
5271
- else if (typeof v === "number") types.add("number");
5272
- else if (typeof v === "boolean") types.add("boolean");
5273
- else if (Array.isArray(v)) types.add("array");
5274
- else if (typeof v === "object") types.add("object");
5275
- }
5276
- if (types.size === 0) return "string";
5277
- if (types.size === 1) return [...types][0];
5428
+ if (v === null || v === void 0)
5429
+ continue;
5430
+ if (typeof v === "string")
5431
+ types.add("string");
5432
+ else if (typeof v === "number")
5433
+ types.add("number");
5434
+ else if (typeof v === "boolean")
5435
+ types.add("boolean");
5436
+ else if (Array.isArray(v))
5437
+ types.add("array");
5438
+ else if (typeof v === "object")
5439
+ types.add("object");
5440
+ }
5441
+ if (types.size === 0)
5442
+ return "string";
5443
+ if (types.size === 1)
5444
+ return [...types][0];
5278
5445
  return "string";
5279
5446
  }
5280
5447
  function deepEqual(a, b) {
5281
- if (a === b) return true;
5282
- if (a === null || b === null) return false;
5283
- if (typeof a !== typeof b) return false;
5448
+ if (a === b)
5449
+ return true;
5450
+ if (a === null || b === null)
5451
+ return false;
5452
+ if (typeof a !== typeof b)
5453
+ return false;
5284
5454
  if (typeof a === "object") {
5285
5455
  if (Array.isArray(a) && Array.isArray(b)) {
5286
- if (a.length !== b.length) return false;
5456
+ if (a.length !== b.length)
5457
+ return false;
5287
5458
  return a.every((val, idx) => deepEqual(val, b[idx]));
5288
5459
  }
5289
- if (Array.isArray(a) !== Array.isArray(b)) return false;
5460
+ if (Array.isArray(a) !== Array.isArray(b))
5461
+ return false;
5290
5462
  const keysA = Object.keys(a);
5291
5463
  const keysB = Object.keys(b);
5292
- if (keysA.length !== keysB.length) return false;
5293
- return keysA.every(
5294
- (k) => deepEqual(
5295
- a[k],
5296
- b[k]
5297
- )
5298
- );
5464
+ if (keysA.length !== keysB.length)
5465
+ return false;
5466
+ return keysA.every((k) => deepEqual(a[k], b[k]));
5299
5467
  }
5300
5468
  return false;
5301
5469
  }
@@ -5304,15 +5472,17 @@ function uniqueExamples(values, max) {
5304
5472
  const examples = [];
5305
5473
  for (const v of values) {
5306
5474
  const key = JSON.stringify(v);
5307
- if (seen.has(key)) continue;
5475
+ if (seen.has(key))
5476
+ continue;
5308
5477
  seen.add(key);
5309
5478
  examples.push(v);
5310
- if (examples.length >= max) break;
5479
+ if (examples.length >= max)
5480
+ break;
5311
5481
  }
5312
5482
  return examples;
5313
5483
  }
5314
5484
 
5315
- // ../chitragupta/packages/smriti/src/vidhi-engine.ts
5485
+ // ../chitragupta/packages/smriti/dist/vidhi-engine.js
5316
5486
  var DEFAULT_CONFIG5 = {
5317
5487
  minSessions: 3,
5318
5488
  minSuccessRate: 0.8,
@@ -5320,7 +5490,8 @@ var DEFAULT_CONFIG5 = {
5320
5490
  maxSequenceLength: 5
5321
5491
  };
5322
5492
  function safeParse(json, fallback) {
5323
- if (!json) return fallback;
5493
+ if (!json)
5494
+ return fallback;
5324
5495
  try {
5325
5496
  return JSON.parse(json);
5326
5497
  } catch {
@@ -5359,15 +5530,13 @@ var VidhiEngine = class {
5359
5530
  for (const agg of aggregates) {
5360
5531
  const existingVidhi = existingByKey.get(agg.key);
5361
5532
  if (existingVidhi) {
5533
+ const oldSize = existingVidhi.learnedFrom.length;
5362
5534
  const mergedSessions = /* @__PURE__ */ new Set([
5363
5535
  ...existingVidhi.learnedFrom,
5364
5536
  ...agg.instances.map((i) => i.sessionId)
5365
5537
  ]);
5366
5538
  existingVidhi.learnedFrom = [...mergedSessions];
5367
- existingVidhi.confidence = Math.min(
5368
- 1,
5369
- existingVidhi.confidence + 0.05 * (mergedSessions.size - existingVidhi.learnedFrom.length)
5370
- );
5539
+ existingVidhi.confidence = Math.min(1, existingVidhi.confidence + 0.05 * (mergedSessions.size - oldSize));
5371
5540
  existingVidhi.updatedAt = Date.now();
5372
5541
  this.persist(existingVidhi);
5373
5542
  reinforced.push(existingVidhi);
@@ -5408,7 +5577,8 @@ var VidhiEngine = class {
5408
5577
  */
5409
5578
  recordOutcome(vidhiId, success) {
5410
5579
  const vidhi = this.getVidhi(vidhiId);
5411
- if (!vidhi) return;
5580
+ if (!vidhi)
5581
+ return;
5412
5582
  if (success) {
5413
5583
  vidhi.successCount += 1;
5414
5584
  } else {
@@ -5461,21 +5631,7 @@ var VidhiEngine = class {
5461
5631
  success_rate, success_count, failure_count, parameter_schema,
5462
5632
  created_at, updated_at)
5463
5633
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
5464
- `).run(
5465
- vidhi.id,
5466
- vidhi.project,
5467
- vidhi.name,
5468
- JSON.stringify(vidhi.learnedFrom),
5469
- vidhi.confidence,
5470
- JSON.stringify(vidhi.steps),
5471
- JSON.stringify(vidhi.triggers),
5472
- vidhi.successRate,
5473
- vidhi.successCount,
5474
- vidhi.failureCount,
5475
- JSON.stringify(vidhi.parameterSchema),
5476
- vidhi.createdAt,
5477
- vidhi.updatedAt
5478
- );
5634
+ `).run(vidhi.id, vidhi.project, vidhi.name, JSON.stringify(vidhi.learnedFrom), vidhi.confidence, JSON.stringify(vidhi.steps), JSON.stringify(vidhi.triggers), vidhi.successRate, vidhi.successCount, vidhi.failureCount, JSON.stringify(vidhi.parameterSchema), vidhi.createdAt, vidhi.updatedAt);
5479
5635
  }
5480
5636
  /**
5481
5637
  * Load all Vidhis for a project from SQLite.
@@ -5485,9 +5641,7 @@ var VidhiEngine = class {
5485
5641
  */
5486
5642
  loadAll(project) {
5487
5643
  const db = DatabaseManager.instance().get("agent");
5488
- const rows = db.prepare(
5489
- "SELECT * FROM vidhis WHERE project = ? ORDER BY success_rate DESC"
5490
- ).all(project);
5644
+ const rows = db.prepare("SELECT * FROM vidhis WHERE project = ? ORDER BY success_rate DESC").all(project);
5491
5645
  return rows.map((r) => this._rowToVidhi(r));
5492
5646
  }
5493
5647
  // ─── Private ──────────────────────────────────────────────────────
@@ -5509,534 +5663,14 @@ var VidhiEngine = class {
5509
5663
  successRate: row.success_rate,
5510
5664
  successCount: row.success_count,
5511
5665
  failureCount: row.failure_count,
5512
- parameterSchema: safeParse(
5513
- row.parameter_schema,
5514
- {}
5515
- ),
5666
+ parameterSchema: safeParse(row.parameter_schema, {}),
5516
5667
  createdAt: row.created_at,
5517
5668
  updatedAt: row.updated_at
5518
5669
  };
5519
5670
  }
5520
5671
  };
5521
5672
 
5522
- // ../chitragupta/packages/smriti/src/akasha-integration.ts
5523
- var CREATE_TABLE_SQL = `
5524
- CREATE TABLE IF NOT EXISTS akasha_traces (
5525
- id TEXT PRIMARY KEY,
5526
- agent_id TEXT NOT NULL,
5527
- trace_type TEXT NOT NULL,
5528
- topic TEXT NOT NULL,
5529
- content TEXT NOT NULL,
5530
- strength REAL NOT NULL,
5531
- reinforcements INTEGER NOT NULL DEFAULT 0,
5532
- metadata TEXT,
5533
- created_at INTEGER NOT NULL,
5534
- last_reinforced_at INTEGER NOT NULL
5535
- );
5536
- CREATE INDEX IF NOT EXISTS idx_akasha_topic ON akasha_traces(topic);
5537
- CREATE INDEX IF NOT EXISTS idx_akasha_strength ON akasha_traces(strength DESC);
5538
- `;
5539
- var UPSERT_SQL = `
5540
- INSERT OR REPLACE INTO akasha_traces
5541
- (id, agent_id, trace_type, topic, content, strength,
5542
- reinforcements, metadata, created_at, last_reinforced_at)
5543
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
5544
- `;
5545
- var ENSURE_TABLE_SQL = `
5546
- CREATE TABLE IF NOT EXISTS akasha_traces (
5547
- id TEXT PRIMARY KEY,
5548
- agent_id TEXT NOT NULL,
5549
- trace_type TEXT NOT NULL,
5550
- topic TEXT NOT NULL,
5551
- content TEXT NOT NULL,
5552
- strength REAL NOT NULL,
5553
- reinforcements INTEGER NOT NULL DEFAULT 0,
5554
- metadata TEXT,
5555
- created_at INTEGER NOT NULL,
5556
- last_reinforced_at INTEGER NOT NULL
5557
- );
5558
- `;
5559
- function safeParseJson(raw) {
5560
- if (!raw) return {};
5561
- try {
5562
- const parsed = JSON.parse(raw);
5563
- return typeof parsed === "object" && parsed !== null ? parsed : {};
5564
- } catch {
5565
- return {};
5566
- }
5567
- }
5568
- function persistTraces(traces, db) {
5569
- db.exec(CREATE_TABLE_SQL);
5570
- const upsert = db.prepare(UPSERT_SQL);
5571
- for (const trace of traces.values()) {
5572
- upsert.run(
5573
- trace.id,
5574
- trace.agentId,
5575
- trace.traceType,
5576
- trace.topic,
5577
- trace.content,
5578
- trace.strength,
5579
- trace.reinforcements,
5580
- JSON.stringify(trace.metadata),
5581
- trace.createdAt,
5582
- trace.lastReinforcedAt
5583
- );
5584
- }
5585
- }
5586
- function restoreTraces(db, config) {
5587
- db.exec(ENSURE_TABLE_SQL);
5588
- const rows = db.prepare("SELECT * FROM akasha_traces").all();
5589
- const traces = /* @__PURE__ */ new Map();
5590
- const reinforcedBy = /* @__PURE__ */ new Map();
5591
- for (const row of rows) {
5592
- if (row.strength < config.minStrength) continue;
5593
- const trace = {
5594
- id: row.id,
5595
- agentId: row.agent_id,
5596
- traceType: row.trace_type,
5597
- topic: row.topic,
5598
- content: row.content,
5599
- strength: row.strength,
5600
- reinforcements: row.reinforcements,
5601
- metadata: safeParseJson(row.metadata),
5602
- createdAt: row.created_at,
5603
- lastReinforcedAt: row.last_reinforced_at
5604
- };
5605
- traces.set(trace.id, trace);
5606
- reinforcedBy.set(trace.id, /* @__PURE__ */ new Set([trace.agentId]));
5607
- }
5608
- return { traces, reinforcedBy };
5609
- }
5610
- function tracesToGraphNodes(traces, minStrength) {
5611
- const nodes = [];
5612
- for (const trace of traces.values()) {
5613
- if (trace.strength < minStrength) continue;
5614
- nodes.push({
5615
- id: trace.id,
5616
- label: `[${trace.traceType}] ${trace.topic}`,
5617
- content: trace.content,
5618
- type: "akasha",
5619
- weight: trace.strength
5620
- });
5621
- }
5622
- return nodes;
5623
- }
5624
- function boostResultsWithTraces(traces, config, results, query) {
5625
- const queryTokens = new Set(tokenize4(query));
5626
- const matchingTraces = [];
5627
- if (queryTokens.size > 0) {
5628
- for (const trace of traces.values()) {
5629
- if (trace.strength < config.minStrength) continue;
5630
- const traceTokens = /* @__PURE__ */ new Set([
5631
- ...tokenize4(trace.topic),
5632
- ...tokenize4(trace.content)
5633
- ]);
5634
- const sim = jaccardSimilarity2(queryTokens, traceTokens);
5635
- if (sim > 0) {
5636
- matchingTraces.push({ trace, similarity: sim });
5637
- }
5638
- }
5639
- matchingTraces.sort((a, b) => b.similarity - a.similarity);
5640
- }
5641
- return results.map((result) => {
5642
- let traceBoost = 0;
5643
- if (queryTokens.size > 0 && matchingTraces.length > 0) {
5644
- const resultTokens = result.content ? new Set(tokenize4(result.content)) : /* @__PURE__ */ new Set();
5645
- let bestBoost = 0;
5646
- for (const { trace, similarity } of matchingTraces) {
5647
- if (result.id === trace.id) {
5648
- bestBoost = Math.max(bestBoost, trace.strength);
5649
- break;
5650
- }
5651
- if (resultTokens.size > 0) {
5652
- const traceTokens = /* @__PURE__ */ new Set([
5653
- ...tokenize4(trace.topic),
5654
- ...tokenize4(trace.content)
5655
- ]);
5656
- const resultSim = jaccardSimilarity2(resultTokens, traceTokens);
5657
- if (resultSim > 0.1) {
5658
- bestBoost = Math.max(bestBoost, similarity * trace.strength);
5659
- }
5660
- } else {
5661
- bestBoost = Math.max(bestBoost, similarity * trace.strength);
5662
- }
5663
- }
5664
- traceBoost = bestBoost * config.traceBoostFactor;
5665
- }
5666
- return {
5667
- ...result,
5668
- score: result.score * (1 + traceBoost),
5669
- traceBoost
5670
- };
5671
- });
5672
- }
5673
-
5674
- // ../chitragupta/packages/smriti/src/akasha.ts
5675
- var STOP_WORDS = /* @__PURE__ */ new Set([
5676
- "a",
5677
- "an",
5678
- "the",
5679
- "and",
5680
- "or",
5681
- "but",
5682
- "in",
5683
- "on",
5684
- "at",
5685
- "to",
5686
- "for",
5687
- "of",
5688
- "with",
5689
- "by",
5690
- "from",
5691
- "is",
5692
- "it",
5693
- "its",
5694
- "this",
5695
- "that",
5696
- "was",
5697
- "are",
5698
- "be",
5699
- "been",
5700
- "being",
5701
- "have",
5702
- "has",
5703
- "had",
5704
- "do",
5705
- "does",
5706
- "did",
5707
- "will",
5708
- "would",
5709
- "could",
5710
- "should",
5711
- "not",
5712
- "no",
5713
- "so",
5714
- "if",
5715
- "then",
5716
- "than",
5717
- "too",
5718
- "very",
5719
- "can",
5720
- "just",
5721
- "about",
5722
- "into",
5723
- "over",
5724
- "after"
5725
- ]);
5726
- var FNV_OFFSET6 = 2166136261;
5727
- var FNV_PRIME6 = 16777619;
5728
- function fnv1a7(input) {
5729
- let hash = FNV_OFFSET6;
5730
- for (let i = 0; i < input.length; i++) {
5731
- hash ^= input.charCodeAt(i);
5732
- hash = Math.imul(hash, FNV_PRIME6) >>> 0;
5733
- }
5734
- return hash.toString(16).padStart(8, "0");
5735
- }
5736
- function tokenize4(text) {
5737
- return text.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((t) => t.length >= 2 && !STOP_WORDS.has(t));
5738
- }
5739
- function jaccardSimilarity2(a, b) {
5740
- if (a.size === 0 && b.size === 0) return 1;
5741
- let intersection = 0;
5742
- for (const token of a) {
5743
- if (b.has(token)) intersection++;
5744
- }
5745
- const union = a.size + b.size - intersection;
5746
- return union === 0 ? 0 : intersection / union;
5747
- }
5748
- var DAY_MS = 864e5;
5749
- var DEFAULT_CONFIG6 = {
5750
- decayHalfLife: 7 * DAY_MS,
5751
- minStrength: 0.01,
5752
- maxTraces: 5e3,
5753
- reinforcementBoost: 0.15,
5754
- initialStrength: 0.5,
5755
- topKRetrieval: 10,
5756
- traceBoostFactor: 0.3,
5757
- diminishingAlpha: 0.3,
5758
- frequencyDecayBeta: 0.5
5759
- };
5760
- var HARD_CEILINGS = {
5761
- maxTraces: 5e4,
5762
- minDecayHalfLife: 36e5,
5763
- maxContentSize: 1e4
5764
- };
5765
- var AkashaField = class {
5766
- config;
5767
- traces = /* @__PURE__ */ new Map();
5768
- /** Tracks which agents reinforced which traces (prevents self/duplicate). */
5769
- reinforcedBy = /* @__PURE__ */ new Map();
5770
- constructor(config) {
5771
- this.config = {
5772
- ...DEFAULT_CONFIG6,
5773
- ...config,
5774
- maxTraces: Math.min(
5775
- config?.maxTraces ?? DEFAULT_CONFIG6.maxTraces,
5776
- HARD_CEILINGS.maxTraces
5777
- ),
5778
- decayHalfLife: Math.max(
5779
- config?.decayHalfLife ?? DEFAULT_CONFIG6.decayHalfLife,
5780
- HARD_CEILINGS.minDecayHalfLife
5781
- )
5782
- };
5783
- }
5784
- // ─── Leaving Traces ─────────────────────────────────────────────────
5785
- /**
5786
- * Agent leaves a stigmergic trace after solving or discovering something.
5787
- *
5788
- * @param agentId - Which agent is leaving this trace.
5789
- * @param type - The category of knowledge.
5790
- * @param topic - What the trace is about (used for matching).
5791
- * @param content - The actual knowledge or solution.
5792
- * @param metadata - Optional metadata for the trace.
5793
- * @returns The created StigmergicTrace.
5794
- */
5795
- leave(agentId, type, topic, content, metadata) {
5796
- const truncatedContent = content.length > HARD_CEILINGS.maxContentSize ? content.slice(0, HARD_CEILINGS.maxContentSize) : content;
5797
- const id = `aks-${fnv1a7(agentId + ":" + type + ":" + topic + ":" + truncatedContent)}`;
5798
- const now = Date.now();
5799
- const trace = {
5800
- id,
5801
- agentId,
5802
- traceType: type,
5803
- topic,
5804
- content: truncatedContent,
5805
- strength: this.config.initialStrength,
5806
- reinforcements: 0,
5807
- metadata: metadata ?? {},
5808
- createdAt: now,
5809
- lastReinforcedAt: now
5810
- };
5811
- this.traces.set(id, trace);
5812
- this.reinforcedBy.set(id, /* @__PURE__ */ new Set([agentId]));
5813
- if (this.traces.size > this.config.maxTraces) this.evictWeakest();
5814
- return trace;
5815
- }
5816
- /**
5817
- * Reinforce an existing trace -- another agent found it useful.
5818
- *
5819
- * @param traceId - The trace to reinforce.
5820
- * @param agentId - The agent reinforcing it.
5821
- * @returns The updated trace, or null if not found / already reinforced.
5822
- */
5823
- reinforce(traceId, agentId) {
5824
- const trace = this.traces.get(traceId);
5825
- if (!trace) return null;
5826
- const agents = this.reinforcedBy.get(traceId);
5827
- if (agents?.has(agentId)) return null;
5828
- const alpha = this.config.diminishingAlpha;
5829
- const effectiveBoost = this.config.reinforcementBoost / (1 + alpha * trace.reinforcements);
5830
- trace.strength = Math.min(1, trace.strength + effectiveBoost);
5831
- trace.reinforcements++;
5832
- trace.lastReinforcedAt = Date.now();
5833
- if (!agents) {
5834
- this.reinforcedBy.set(traceId, /* @__PURE__ */ new Set([agentId]));
5835
- } else {
5836
- agents.add(agentId);
5837
- }
5838
- return trace;
5839
- }
5840
- // ─── Following Traces ────────────────────────────────────────────────
5841
- /**
5842
- * Find relevant traces by Jaccard similarity on topic/content tokens.
5843
- *
5844
- * @param topic - The query to match against trace topics and content.
5845
- * @param opts - Optional filters: type, minStrength, limit.
5846
- * @returns Matching traces sorted by relevance score.
5847
- */
5848
- query(topic, opts) {
5849
- const queryTokens = new Set(tokenize4(topic));
5850
- if (queryTokens.size === 0) return [];
5851
- const minStr = opts?.minStrength ?? this.config.minStrength;
5852
- const limit = opts?.limit ?? this.config.topKRetrieval;
5853
- const scored = [];
5854
- for (const trace of this.traces.values()) {
5855
- if (trace.strength < minStr) continue;
5856
- if (opts?.type && trace.traceType !== opts.type) continue;
5857
- const traceTokens = /* @__PURE__ */ new Set([...tokenize4(trace.topic), ...tokenize4(trace.content)]);
5858
- const similarity = jaccardSimilarity2(queryTokens, traceTokens);
5859
- if (similarity <= 0) continue;
5860
- scored.push({ trace, score: similarity * trace.strength });
5861
- }
5862
- scored.sort((a, b) => b.score - a.score);
5863
- return scored.slice(0, limit).map((s) => s.trace);
5864
- }
5865
- /**
5866
- * Get the strongest traces overall -- the "highways" of collective knowledge.
5867
- *
5868
- * @param limit - Maximum number of traces to return.
5869
- * @returns Traces sorted by strength descending.
5870
- */
5871
- strongest(limit) {
5872
- const all = [...this.traces.values()];
5873
- all.sort((a, b) => b.strength - a.strength);
5874
- return all.slice(0, limit ?? this.config.topKRetrieval);
5875
- }
5876
- /**
5877
- * Get traces left by a specific agent.
5878
- *
5879
- * @param agentId - The agent whose traces to retrieve.
5880
- * @param limit - Maximum results.
5881
- * @returns Traces by the agent, sorted by creation time descending.
5882
- */
5883
- byAgent(agentId, limit) {
5884
- const results = [];
5885
- for (const trace of this.traces.values()) {
5886
- if (trace.agentId === agentId) results.push(trace);
5887
- }
5888
- results.sort((a, b) => b.createdAt - a.createdAt);
5889
- return results.slice(0, limit ?? this.config.topKRetrieval);
5890
- }
5891
- // ─── Decay & Maintenance ─────────────────────────────────────────────
5892
- /**
5893
- * Apply temporal decay to all traces. Traces that fall below `minStrength`
5894
- * after decay are pruned automatically.
5895
- *
5896
- * @returns Counts of decayed and pruned traces.
5897
- */
5898
- decay() {
5899
- const now = Date.now();
5900
- const baseHalfLife = this.config.decayHalfLife;
5901
- const beta = this.config.frequencyDecayBeta;
5902
- let decayed = 0;
5903
- const toPrune = [];
5904
- for (const [id, trace] of this.traces) {
5905
- const elapsed = now - trace.lastReinforcedAt;
5906
- if (elapsed <= 0) continue;
5907
- const effectiveHalfLife = baseHalfLife * (1 + beta * Math.log(1 + trace.reinforcements));
5908
- const factor = Math.exp(-Math.LN2 * elapsed / effectiveHalfLife);
5909
- const newStrength = trace.strength * factor;
5910
- if (Math.abs(newStrength - trace.strength) > 1e-10) {
5911
- trace.strength = newStrength;
5912
- decayed++;
5913
- }
5914
- if (trace.strength < this.config.minStrength) toPrune.push(id);
5915
- }
5916
- for (const id of toPrune) {
5917
- this.traces.delete(id);
5918
- this.reinforcedBy.delete(id);
5919
- }
5920
- return { decayed, pruned: toPrune.length };
5921
- }
5922
- /**
5923
- * Remove traces below the minStrength threshold.
5924
- *
5925
- * @returns The number of traces pruned.
5926
- */
5927
- prune() {
5928
- const toPrune = [];
5929
- for (const [id, trace] of this.traces) {
5930
- if (trace.strength < this.config.minStrength) toPrune.push(id);
5931
- }
5932
- for (const id of toPrune) {
5933
- this.traces.delete(id);
5934
- this.reinforcedBy.delete(id);
5935
- }
5936
- return toPrune.length;
5937
- }
5938
- // ─── Persistence (delegated to akasha-integration) ───────────────────
5939
- /**
5940
- * Persist all traces to a SQLite database.
5941
- *
5942
- * @param db - A duck-typed database handle with prepare/exec methods.
5943
- */
5944
- persist(db) {
5945
- persistTraces(this.traces, db);
5946
- }
5947
- /**
5948
- * Restore traces from a SQLite database.
5949
- *
5950
- * @param db - A duck-typed database handle with prepare/exec methods.
5951
- */
5952
- restore(db) {
5953
- const result = restoreTraces(db, this.config);
5954
- this.traces.clear();
5955
- this.reinforcedBy.clear();
5956
- for (const [k, v] of result.traces) this.traces.set(k, v);
5957
- for (const [k, v] of result.reinforcedBy) this.reinforcedBy.set(k, v);
5958
- }
5959
- // ─── GraphRAG (delegated to akasha-integration) ──────────────────────
5960
- /**
5961
- * Register traces as graph nodes suitable for GraphRAG retrieval.
5962
- *
5963
- * @returns An array of graph-compatible node objects.
5964
- */
5965
- toGraphNodes() {
5966
- return tracesToGraphNodes(this.traces, this.config.minStrength);
5967
- }
5968
- /**
5969
- * Boost graph search results that have matching stigmergic traces.
5970
- *
5971
- * @param results - The original search results with id and score.
5972
- * @param query - The search query used for topic matching.
5973
- * @returns Results with boosted scores and traceBoost metadata.
5974
- */
5975
- boostResults(results, query) {
5976
- return boostResultsWithTraces(this.traces, this.config, results, query);
5977
- }
5978
- // ─── Stats ───────────────────────────────────────────────────────────
5979
- /**
5980
- * Return statistics about the current state of the Akasha field.
5981
- *
5982
- * @returns Total/active counts, per-type breakdown, average strength,
5983
- * strongest topic, and total reinforcements.
5984
- */
5985
- stats() {
5986
- const byType = {
5987
- solution: 0,
5988
- warning: 0,
5989
- shortcut: 0,
5990
- pattern: 0,
5991
- correction: 0,
5992
- preference: 0
5993
- };
5994
- let totalStrength = 0;
5995
- let activeCount = 0;
5996
- let totalReinforcements = 0;
5997
- let strongestTrace = null;
5998
- for (const trace of this.traces.values()) {
5999
- byType[trace.traceType]++;
6000
- totalStrength += trace.strength;
6001
- totalReinforcements += trace.reinforcements;
6002
- if (trace.strength >= this.config.minStrength) activeCount++;
6003
- if (!strongestTrace || trace.strength > strongestTrace.strength) {
6004
- strongestTrace = trace;
6005
- }
6006
- }
6007
- return {
6008
- totalTraces: this.traces.size,
6009
- activeTraces: activeCount,
6010
- byType,
6011
- avgStrength: this.traces.size > 0 ? totalStrength / this.traces.size : 0,
6012
- strongestTopic: strongestTrace?.topic ?? null,
6013
- totalReinforcements
6014
- };
6015
- }
6016
- // ─── Internal Helpers ────────────────────────────────────────────────
6017
- /** Evict the weakest trace. Ties broken by oldest createdAt. */
6018
- evictWeakest() {
6019
- let weakestId = null;
6020
- let weakestStrength = Infinity;
6021
- let weakestCreatedAt = Infinity;
6022
- for (const [id, trace] of this.traces) {
6023
- if (trace.strength < weakestStrength || trace.strength === weakestStrength && trace.createdAt < weakestCreatedAt) {
6024
- weakestId = id;
6025
- weakestStrength = trace.strength;
6026
- weakestCreatedAt = trace.createdAt;
6027
- }
6028
- }
6029
- if (!weakestId && this.traces.size > 0) {
6030
- weakestId = this.traces.keys().next().value;
6031
- }
6032
- if (weakestId) {
6033
- this.traces.delete(weakestId);
6034
- this.reinforcedBy.delete(weakestId);
6035
- }
6036
- }
6037
- };
6038
-
6039
- // ../chitragupta/packages/smriti/src/temporal-context.ts
5673
+ // ../chitragupta/packages/smriti/dist/temporal-context.js
6040
5674
  var MINUTE = 6e4;
6041
5675
  var HOUR = 36e5;
6042
5676
  var DAY = 864e5;
@@ -6065,7 +5699,7 @@ var DEFAULT_SCALE_WEIGHTS = {
6065
5699
  quarter: 0.08,
6066
5700
  year: 0.07
6067
5701
  };
6068
- var HARD_CEILINGS2 = {
5702
+ var HARD_CEILINGS = {
6069
5703
  /** Minimum half-life: 1 second. Anything faster is meaningless. */
6070
5704
  minDecayRate: 1e3,
6071
5705
  /** Maximum half-life: 10 years. Beyond this, nothing decays. */
@@ -6230,7 +5864,7 @@ function buildTemporalContext(state, db, now) {
6230
5864
  };
6231
5865
  }
6232
5866
 
6233
- // ../chitragupta/packages/smriti/src/kala-chakra.ts
5867
+ // ../chitragupta/packages/smriti/dist/kala-chakra.js
6234
5868
  var TEMPORAL_SCALES = [
6235
5869
  "turn",
6236
5870
  "session",
@@ -6250,22 +5884,14 @@ var KalaChakra = class {
6250
5884
  if (config?.decayRates) {
6251
5885
  for (const scale of TEMPORAL_SCALES) {
6252
5886
  if (config.decayRates[scale] !== void 0) {
6253
- this._decayRates[scale] = clamp(
6254
- config.decayRates[scale],
6255
- HARD_CEILINGS2.minDecayRate,
6256
- HARD_CEILINGS2.maxDecayRate
6257
- );
5887
+ this._decayRates[scale] = clamp(config.decayRates[scale], HARD_CEILINGS.minDecayRate, HARD_CEILINGS.maxDecayRate);
6258
5888
  }
6259
5889
  }
6260
5890
  }
6261
5891
  if (config?.scaleWeights) {
6262
5892
  for (const scale of TEMPORAL_SCALES) {
6263
5893
  if (config.scaleWeights[scale] !== void 0) {
6264
- this._scaleWeights[scale] = clamp(
6265
- config.scaleWeights[scale],
6266
- HARD_CEILINGS2.minWeight,
6267
- HARD_CEILINGS2.maxWeight
6268
- );
5894
+ this._scaleWeights[scale] = clamp(config.scaleWeights[scale], HARD_CEILINGS.minWeight, HARD_CEILINGS.maxWeight);
6269
5895
  }
6270
5896
  }
6271
5897
  }
@@ -6346,7 +5972,8 @@ var KalaChakra = class {
6346
5972
  dominantScale(elapsedMs) {
6347
5973
  const abs = Math.abs(elapsedMs);
6348
5974
  for (const [threshold, scale] of SCALE_BOUNDARIES) {
6349
- if (abs < threshold) return scale;
5975
+ if (abs < threshold)
5976
+ return scale;
6350
5977
  }
6351
5978
  return "year";
6352
5979
  }
@@ -6402,26 +6029,19 @@ var KalaChakra = class {
6402
6029
  * @param data - Previously serialized state from `serialize()`.
6403
6030
  */
6404
6031
  restore(data) {
6405
- if (!data || typeof data !== "object") return;
6032
+ if (!data || typeof data !== "object")
6033
+ return;
6406
6034
  if (data.decayRates && typeof data.decayRates === "object") {
6407
6035
  for (const scale of TEMPORAL_SCALES) {
6408
6036
  if (typeof data.decayRates[scale] === "number") {
6409
- this._decayRates[scale] = clamp(
6410
- data.decayRates[scale],
6411
- HARD_CEILINGS2.minDecayRate,
6412
- HARD_CEILINGS2.maxDecayRate
6413
- );
6037
+ this._decayRates[scale] = clamp(data.decayRates[scale], HARD_CEILINGS.minDecayRate, HARD_CEILINGS.maxDecayRate);
6414
6038
  }
6415
6039
  }
6416
6040
  }
6417
6041
  if (data.scaleWeights && typeof data.scaleWeights === "object") {
6418
6042
  for (const scale of TEMPORAL_SCALES) {
6419
6043
  if (typeof data.scaleWeights[scale] === "number") {
6420
- this._scaleWeights[scale] = clamp(
6421
- data.scaleWeights[scale],
6422
- HARD_CEILINGS2.minWeight,
6423
- HARD_CEILINGS2.maxWeight
6424
- );
6044
+ this._scaleWeights[scale] = clamp(data.scaleWeights[scale], HARD_CEILINGS.minWeight, HARD_CEILINGS.maxWeight);
6425
6045
  }
6426
6046
  }
6427
6047
  }
@@ -6439,7 +6059,8 @@ var KalaChakra = class {
6439
6059
  /** Compute exponential decay for a given elapsed time and scale. */
6440
6060
  _decayForScale(elapsedMs, scale) {
6441
6061
  const halfLife = this._decayRates[scale];
6442
- if (halfLife <= 0) return 0;
6062
+ if (halfLife <= 0)
6063
+ return 0;
6443
6064
  return Math.exp(-LN2 * elapsedMs / halfLife);
6444
6065
  }
6445
6066
  };
@@ -6447,14 +6068,14 @@ function clamp(value, min, max) {
6447
6068
  return Math.max(min, Math.min(max, value));
6448
6069
  }
6449
6070
 
6450
- // ../chitragupta/packages/smriti/src/pancha-vritti-patterns.ts
6451
- var FNV_OFFSET7 = 2166136261;
6452
- var FNV_PRIME7 = 16777619;
6453
- function fnv1a8(input) {
6454
- let hash = FNV_OFFSET7;
6071
+ // ../chitragupta/packages/smriti/dist/pancha-vritti-patterns.js
6072
+ var FNV_OFFSET6 = 2166136261;
6073
+ var FNV_PRIME6 = 16777619;
6074
+ function fnv1a7(input) {
6075
+ let hash = FNV_OFFSET6;
6455
6076
  for (let i = 0; i < input.length; i++) {
6456
6077
  hash ^= input.charCodeAt(i);
6457
- hash = Math.imul(hash, FNV_PRIME7);
6078
+ hash = Math.imul(hash, FNV_PRIME6);
6458
6079
  }
6459
6080
  return (hash >>> 0).toString(16).padStart(8, "0");
6460
6081
  }
@@ -6580,7 +6201,7 @@ var SMRITI_TOOLS = /* @__PURE__ */ new Set([
6580
6201
  "chitragupta_memory_search"
6581
6202
  ]);
6582
6203
 
6583
- // ../chitragupta/packages/smriti/src/pancha-vritti.ts
6204
+ // ../chitragupta/packages/smriti/dist/pancha-vritti.js
6584
6205
  var VRITTI_TYPES = [
6585
6206
  "pramana",
6586
6207
  "viparyaya",
@@ -6595,13 +6216,13 @@ var VRITTI_CONFIDENCE_WEIGHTS = {
6595
6216
  vikalpa: 0.5,
6596
6217
  viparyaya: 0.3
6597
6218
  };
6598
- var DEFAULT_CONFIG7 = {
6219
+ var DEFAULT_CONFIG6 = {
6599
6220
  maxClassifications: 5e3,
6600
6221
  minConfidence: 0.4,
6601
6222
  snippetMaxLength: 200,
6602
6223
  confidenceWeights: { ...VRITTI_CONFIDENCE_WEIGHTS }
6603
6224
  };
6604
- var HARD_CEILINGS3 = {
6225
+ var HARD_CEILINGS2 = {
6605
6226
  maxClassifications: 5e4,
6606
6227
  snippetMaxLength: 1e3
6607
6228
  };
@@ -6612,24 +6233,18 @@ var PanchaVritti = class {
6612
6233
  totalReclassified = 0;
6613
6234
  constructor(config) {
6614
6235
  const merged = {
6615
- ...DEFAULT_CONFIG7,
6236
+ ...DEFAULT_CONFIG6,
6616
6237
  ...config,
6617
6238
  confidenceWeights: {
6618
- ...DEFAULT_CONFIG7.confidenceWeights,
6239
+ ...DEFAULT_CONFIG6.confidenceWeights,
6619
6240
  ...config?.confidenceWeights
6620
6241
  }
6621
6242
  };
6622
- if (typeof HARD_CEILINGS3.maxClassifications === "number") {
6623
- merged.maxClassifications = Math.min(
6624
- merged.maxClassifications,
6625
- HARD_CEILINGS3.maxClassifications
6626
- );
6627
- }
6628
- if (typeof HARD_CEILINGS3.snippetMaxLength === "number") {
6629
- merged.snippetMaxLength = Math.min(
6630
- merged.snippetMaxLength,
6631
- HARD_CEILINGS3.snippetMaxLength
6632
- );
6243
+ if (typeof HARD_CEILINGS2.maxClassifications === "number") {
6244
+ merged.maxClassifications = Math.min(merged.maxClassifications, HARD_CEILINGS2.maxClassifications);
6245
+ }
6246
+ if (typeof HARD_CEILINGS2.snippetMaxLength === "number") {
6247
+ merged.snippetMaxLength = Math.min(merged.snippetMaxLength, HARD_CEILINGS2.snippetMaxLength);
6633
6248
  }
6634
6249
  this.cfg = merged;
6635
6250
  }
@@ -6658,7 +6273,7 @@ var PanchaVritti = class {
6658
6273
  prePatterns.push("context:error-flag");
6659
6274
  }
6660
6275
  if (content.trim().length === 0) {
6661
- const id2 = fnv1a8("nidra:" + now.toString());
6276
+ const id2 = fnv1a7("nidra:" + now.toString());
6662
6277
  const classification2 = {
6663
6278
  id: id2,
6664
6279
  type: "nidra",
@@ -6682,7 +6297,7 @@ var PanchaVritti = class {
6682
6297
  if (winnerConfidence < this.cfg.minConfidence) {
6683
6298
  allPatterns.push("low-confidence");
6684
6299
  }
6685
- const id = fnv1a8(winnerType + ":" + content.slice(0, 100) + ":" + now.toString());
6300
+ const id = fnv1a7(winnerType + ":" + content.slice(0, 100) + ":" + now.toString());
6686
6301
  const classification = {
6687
6302
  id,
6688
6303
  type: winnerType,
@@ -6711,9 +6326,11 @@ var PanchaVritti = class {
6711
6326
  */
6712
6327
  reclassify(id, newType, reason) {
6713
6328
  const existing = this.classifications.get(id);
6714
- if (!existing) throw new Error(`Classification not found: ${id}`);
6329
+ if (!existing)
6330
+ throw new Error(`Classification not found: ${id}`);
6715
6331
  const oldType = existing.type;
6716
- if (oldType === newType) return;
6332
+ if (oldType === newType)
6333
+ return;
6717
6334
  existing.history.push({ from: oldType, to: newType, reason, at: Date.now() });
6718
6335
  existing.type = newType;
6719
6336
  this.totalReclassified++;
@@ -6731,7 +6348,8 @@ var PanchaVritti = class {
6731
6348
  getByType(type) {
6732
6349
  const result = [];
6733
6350
  for (const c of this.classifications.values()) {
6734
- if (c.type === type) result.push(c);
6351
+ if (c.type === type)
6352
+ result.push(c);
6735
6353
  }
6736
6354
  return result;
6737
6355
  }
@@ -6790,7 +6408,8 @@ var PanchaVritti = class {
6790
6408
  /** Restore state from a serialized snapshot. */
6791
6409
  deserialize(state) {
6792
6410
  this.classifications.clear();
6793
- for (const c of state.classifications) this.classifications.set(c.id, c);
6411
+ for (const c of state.classifications)
6412
+ this.classifications.set(c.id, c);
6794
6413
  this.totalClassified = state.totalClassified;
6795
6414
  this.totalReclassified = state.totalReclassified;
6796
6415
  }
@@ -6852,21 +6471,23 @@ var PanchaVritti = class {
6852
6471
  oldestId = id;
6853
6472
  }
6854
6473
  }
6855
- if (oldestId) this.classifications.delete(oldestId);
6474
+ if (oldestId)
6475
+ this.classifications.delete(oldestId);
6856
6476
  }
6857
6477
  }
6858
6478
  };
6859
6479
 
6860
- // ../chitragupta/packages/smriti/src/unified-recall.ts
6480
+ // ../chitragupta/packages/smriti/dist/unified-recall.js
6861
6481
  async function recall(query, options) {
6862
6482
  const limit = options?.limit ?? 5;
6863
6483
  const answers = [];
6864
- const [hybridResults, turnFallbackResults, memoryResults, dayFileResults] = await Promise.allSettled([
6484
+ const [hybridResults, turnFallbackResults, memoryResults, dayFileResults, akashaResults] = await Promise.allSettled([
6865
6485
  searchHybrid(query, options?.project, limit),
6866
6486
  // FTS5 fallback runs in parallel — used only if hybrid fails
6867
6487
  searchTurns(query, options?.project),
6868
6488
  options?.includeMemory !== false ? searchMemoryLayer(query) : Promise.resolve([]),
6869
- options?.includeDayFiles !== false ? searchDayFileLayer(query, limit) : Promise.resolve([])
6489
+ options?.includeDayFiles !== false ? searchDayFileLayer(query, limit) : Promise.resolve([]),
6490
+ options?.includeAkasha !== false ? searchAkashaLayer(query, limit) : Promise.resolve([])
6870
6491
  ]);
6871
6492
  let usedHybrid = false;
6872
6493
  if (hybridResults.status === "fulfilled" && hybridResults.value.length > 0) {
@@ -6899,43 +6520,46 @@ async function recall(query, options) {
6899
6520
  answers.push(result);
6900
6521
  }
6901
6522
  }
6523
+ if (akashaResults.status === "fulfilled") {
6524
+ for (const result of akashaResults.value.slice(0, limit)) {
6525
+ answers.push(result);
6526
+ }
6527
+ }
6902
6528
  const ranked = deduplicateAnswers(answers);
6903
6529
  ranked.sort((a, b) => b.score - a.score);
6904
6530
  return ranked.slice(0, limit);
6905
6531
  }
6906
6532
  async function searchHybrid(query, project, limit) {
6907
6533
  try {
6908
- const { HybridSearchEngine: HybridSearchEngine2 } = await import("./hybrid-search-G2NAJKJ7.js");
6534
+ const { HybridSearchEngine: HybridSearchEngine2 } = await import("./hybrid-search-OD756RDV.js");
6909
6535
  let recallEngine = null;
6910
6536
  let graphEngine = null;
6911
6537
  try {
6912
- const { RecallEngine: RecallEngine2 } = await import("./recall-ZNL4DJ2L.js");
6538
+ const { RecallEngine: RecallEngine2 } = await import("./recall-64RROTUC.js");
6913
6539
  recallEngine = new RecallEngine2();
6914
6540
  } catch {
6915
6541
  }
6916
6542
  try {
6917
- const { GraphRAGEngine: GraphRAGEngine2 } = await import("./graphrag-D7OXWAWD.js");
6543
+ const { GraphRAGEngine: GraphRAGEngine2 } = await import("./graphrag-73XA7LBX.js");
6918
6544
  graphEngine = new GraphRAGEngine2();
6919
6545
  } catch {
6920
6546
  }
6921
- const hybrid = new HybridSearchEngine2(
6922
- {
6923
- project,
6924
- topK: limit ?? 10,
6925
- enableBM25: true,
6926
- enableVector: recallEngine !== null,
6927
- enableGraphRAG: graphEngine !== null,
6928
- enablePramana: true
6929
- },
6930
- recallEngine ?? void 0,
6931
- graphEngine ?? void 0
6932
- );
6547
+ const hybrid = new HybridSearchEngine2({
6548
+ project,
6549
+ topK: limit ?? 10,
6550
+ enableBM25: true,
6551
+ enableVector: recallEngine !== null,
6552
+ enableGraphRAG: graphEngine !== null,
6553
+ enablePramana: true
6554
+ }, recallEngine ?? void 0, graphEngine ?? void 0);
6933
6555
  const results = await hybrid.search(query);
6934
6556
  return results.map((r) => {
6935
6557
  let primarySource = "hybrid";
6936
6558
  if (r.sources.length === 1) {
6937
- if (r.sources[0] === "bm25") primarySource = "turns";
6938
- else if (r.sources[0] === "graphrag") primarySource = "graph";
6559
+ if (r.sources[0] === "bm25")
6560
+ primarySource = "turns";
6561
+ else if (r.sources[0] === "graphrag")
6562
+ primarySource = "graph";
6939
6563
  }
6940
6564
  const normalizedScore = Math.min(r.score / (r.score + 0.5), 1);
6941
6565
  return {
@@ -6952,8 +6576,8 @@ async function searchHybrid(query, project, limit) {
6952
6576
  }
6953
6577
  async function searchTurns(query, project) {
6954
6578
  try {
6955
- const { searchSessions: searchSessions2 } = await import("./search-35JMSGUT.js");
6956
- const { loadSession: loadSession2 } = await import("./session-store-3BRPGC6P.js");
6579
+ const { searchSessions: searchSessions2 } = await import("./search-JVCDNTAJ.js");
6580
+ const { loadSession: loadSession2 } = await import("./session-store-3EDQZEDS.js");
6957
6581
  const metas = searchSessions2(query, project);
6958
6582
  const results = [];
6959
6583
  for (const meta of metas.slice(0, 10)) {
@@ -6966,7 +6590,8 @@ async function searchTurns(query, project) {
6966
6590
  const content = turn.content.toLowerCase();
6967
6591
  let termHits = 0;
6968
6592
  for (const term of queryTerms) {
6969
- if (term.length > 2 && content.includes(term)) termHits++;
6593
+ if (term.length > 2 && content.includes(term))
6594
+ termHits++;
6970
6595
  }
6971
6596
  const score = queryTerms.length > 0 ? termHits / queryTerms.length : 0;
6972
6597
  if (score > bestScore) {
@@ -6999,9 +6624,9 @@ async function searchTurns(query, project) {
6999
6624
  }
7000
6625
  async function searchMemoryLayer(query) {
7001
6626
  try {
7002
- const { searchMemory: searchMemory2 } = await import("./search-35JMSGUT.js");
6627
+ const { searchMemory: searchMemory2 } = await import("./search-JVCDNTAJ.js");
7003
6628
  const results = searchMemory2(query);
7004
- return results.slice(0, 5).map((r) => ({
6629
+ return results.slice(0, 5).filter((r) => !isLowValueMemoryEntry(r.content)).map((r) => ({
7005
6630
  score: Math.min((r.relevance ?? 0.5) + 0.1, 1),
7006
6631
  answer: `From memory: ${r.content.slice(0, 300)}`,
7007
6632
  primarySource: "memory",
@@ -7011,9 +6636,20 @@ async function searchMemoryLayer(query) {
7011
6636
  return [];
7012
6637
  }
7013
6638
  }
6639
+ function isLowValueMemoryEntry(content) {
6640
+ const trimmed = content.trim();
6641
+ if (/^\[(?:action|tool)\].*file\(s\)/i.test(trimmed))
6642
+ return true;
6643
+ if (/^(?:File|Created|Modified|Edited|Deleted)[:\s]+\S+\.\w+$/i.test(trimmed))
6644
+ return true;
6645
+ const bracketMatch = trimmed.match(/^\[\w+\]\s*(.*)/);
6646
+ if (bracketMatch && bracketMatch[1].length < 10)
6647
+ return true;
6648
+ return false;
6649
+ }
7014
6650
  async function searchDayFileLayer(query, limit) {
7015
6651
  try {
7016
- const { hierarchicalTemporalSearch: hierarchicalTemporalSearch2 } = await import("./hierarchical-temporal-search-PVHVA3NZ.js");
6652
+ const { hierarchicalTemporalSearch: hierarchicalTemporalSearch2 } = await import("./hierarchical-temporal-search-GHKVKNZ6.js");
7017
6653
  const results = await hierarchicalTemporalSearch2(query, { limit });
7018
6654
  if (results.length > 0) {
7019
6655
  return results.map((r) => ({
@@ -7028,7 +6664,7 @@ async function searchDayFileLayer(query, limit) {
7028
6664
  } catch {
7029
6665
  }
7030
6666
  try {
7031
- const { searchDayFiles: searchDayFiles2 } = await import("./day-consolidation-BH3QU2SZ.js");
6667
+ const { searchDayFiles: searchDayFiles2 } = await import("./day-consolidation-CR3TJFAL.js");
7032
6668
  const results = searchDayFiles2(query, { limit });
7033
6669
  return results.map((r) => ({
7034
6670
  score: 0.5,
@@ -7041,17 +6677,50 @@ async function searchDayFileLayer(query, limit) {
7041
6677
  return [];
7042
6678
  }
7043
6679
  }
6680
+ async function searchAkashaLayer(query, limit) {
6681
+ try {
6682
+ const { AkashaField: AkashaField2 } = await import("./akasha-5C5Q6NMP.js");
6683
+ const akasha = new AkashaField2();
6684
+ try {
6685
+ const { DatabaseManager: DatabaseManager2 } = await import("./database-BX3LVYXS.js");
6686
+ const dbm = DatabaseManager2.instance();
6687
+ const db = dbm.get("agent");
6688
+ if (db) {
6689
+ akasha.restore(db);
6690
+ }
6691
+ } catch {
6692
+ }
6693
+ const traces = akasha.query(query, { limit });
6694
+ if (traces.length === 0)
6695
+ return [];
6696
+ return traces.map((trace) => {
6697
+ const score = Math.min(trace.strength * 0.8 + 0.2, 1);
6698
+ const typeLabel = trace.traceType.toUpperCase();
6699
+ const snippet = trace.content.slice(0, 300);
6700
+ const answer = `[Akasha ${typeLabel}] ${trace.topic}: ${snippet}`;
6701
+ return {
6702
+ score,
6703
+ answer,
6704
+ primarySource: "akasha",
6705
+ snippet
6706
+ };
6707
+ });
6708
+ } catch {
6709
+ return [];
6710
+ }
6711
+ }
7044
6712
  function deduplicateAnswers(answers) {
7045
6713
  const seen = /* @__PURE__ */ new Set();
7046
6714
  return answers.filter((a) => {
7047
6715
  const key = a.sessionId ? `session:${a.sessionId}` : `${a.primarySource}:${a.snippet.slice(0, 50).toLowerCase()}`;
7048
- if (seen.has(key)) return false;
6716
+ if (seen.has(key))
6717
+ return false;
7049
6718
  seen.add(key);
7050
6719
  return true;
7051
6720
  });
7052
6721
  }
7053
6722
 
7054
- // ../chitragupta/packages/smriti/src/provider-bridge.ts
6723
+ // ../chitragupta/packages/smriti/dist/provider-bridge.js
7055
6724
  async function loadProviderContext(project, options) {
7056
6725
  const maxLen = options?.maxContextLength ?? 4e3;
7057
6726
  const recentLimit = options?.recentSessionLimit ?? 3;
@@ -7059,7 +6728,7 @@ async function loadProviderContext(project, options) {
7059
6728
  let projectMemory = "";
7060
6729
  let recentContext = "";
7061
6730
  try {
7062
- const { getMemory: getMemory2 } = await import("./memory-store-A6WOWLWC.js");
6731
+ const { getMemory: getMemory2 } = await import("./memory-store-4GCBR2DZ.js");
7063
6732
  globalFacts = getMemory2({ type: "global" });
7064
6733
  if (globalFacts.length > maxLen / 3) {
7065
6734
  globalFacts = globalFacts.slice(0, maxLen / 3) + "\n...(truncated)";
@@ -7068,7 +6737,7 @@ async function loadProviderContext(project, options) {
7068
6737
  }
7069
6738
  if (project) {
7070
6739
  try {
7071
- const { getMemory: getMemory2 } = await import("./memory-store-A6WOWLWC.js");
6740
+ const { getMemory: getMemory2 } = await import("./memory-store-4GCBR2DZ.js");
7072
6741
  projectMemory = getMemory2({ type: "project", path: project });
7073
6742
  if (projectMemory.length > maxLen / 3) {
7074
6743
  projectMemory = projectMemory.slice(0, maxLen / 3) + "\n...(truncated)";
@@ -7078,18 +6747,16 @@ async function loadProviderContext(project, options) {
7078
6747
  }
7079
6748
  let vasanaContext = "";
7080
6749
  try {
7081
- const { VasanaEngine: VasanaEngine2 } = await import("./vasana-engine-MU25OQ23.js");
6750
+ const { VasanaEngine: VasanaEngine2 } = await import("./vasana-engine-W4PYWT5H.js");
7082
6751
  const engine = new VasanaEngine2();
7083
6752
  const vasanas = engine.getVasanas(project ?? "__global__", 5);
7084
6753
  if (vasanas.length > 0) {
7085
- vasanaContext = vasanas.map(
7086
- (v) => `- ${v.tendency} (strength: ${(v.strength * 100).toFixed(0)}%): ${v.description}`
7087
- ).join("\n");
6754
+ vasanaContext = vasanas.map((v) => `- ${v.tendency} (strength: ${(v.strength * 100).toFixed(0)}%): ${v.description}`).join("\n");
7088
6755
  }
7089
6756
  } catch {
7090
6757
  }
7091
6758
  try {
7092
- const { listSessions: listSessions2, loadSession: loadSession2 } = await import("./session-store-3BRPGC6P.js");
6759
+ const { listSessions: listSessions2, loadSession: loadSession2 } = await import("./session-store-3EDQZEDS.js");
7093
6760
  const sessions = project ? listSessions2(project).slice(0, recentLimit) : listSessions2().slice(0, recentLimit);
7094
6761
  const summaries = [];
7095
6762
  for (const meta of sessions) {
@@ -7137,6 +6804,595 @@ async function loadProviderContext(project, options) {
7137
6804
  };
7138
6805
  }
7139
6806
 
6807
+ // ../chitragupta/packages/smriti/dist/critique-store.js
6808
+ init_session_db();
6809
+ import crypto3 from "crypto";
6810
+ var HARD_CEILINGS3 = {
6811
+ maxPerTask: 500,
6812
+ retentionDays: 365,
6813
+ dedupeWindow: 6e5
6814
+ // 10 min max
6815
+ };
6816
+ var DEFAULTS = {
6817
+ maxPerTask: 50,
6818
+ retentionDays: 90,
6819
+ dedupeWindow: 6e4
6820
+ };
6821
+ function tokenize3(text) {
6822
+ return text.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((t) => t.length > 1);
6823
+ }
6824
+ var CritiqueStore = class {
6825
+ config;
6826
+ schemaReady = false;
6827
+ constructor(config) {
6828
+ this.config = {
6829
+ maxPerTask: Math.min(config?.maxPerTask ?? DEFAULTS.maxPerTask, HARD_CEILINGS3.maxPerTask),
6830
+ retentionDays: Math.min(config?.retentionDays ?? DEFAULTS.retentionDays, HARD_CEILINGS3.retentionDays),
6831
+ dedupeWindow: Math.min(config?.dedupeWindow ?? DEFAULTS.dedupeWindow, HARD_CEILINGS3.dedupeWindow)
6832
+ };
6833
+ }
6834
+ // ─── Schema Bootstrap ────────────────────────────────────────────────
6835
+ /** Ensure the critiques table and indices exist. */
6836
+ ensureSchema() {
6837
+ const db = getAgentDb();
6838
+ if (!this.schemaReady) {
6839
+ db.exec(`
6840
+ CREATE TABLE IF NOT EXISTS critiques (
6841
+ id TEXT PRIMARY KEY,
6842
+ task_hash TEXT NOT NULL,
6843
+ severity TEXT NOT NULL,
6844
+ category TEXT NOT NULL,
6845
+ message TEXT NOT NULL,
6846
+ file TEXT,
6847
+ line INTEGER,
6848
+ metadata TEXT,
6849
+ session_id TEXT,
6850
+ created_at INTEGER NOT NULL
6851
+ );
6852
+ CREATE INDEX IF NOT EXISTS idx_critiques_task ON critiques(task_hash);
6853
+ CREATE INDEX IF NOT EXISTS idx_critiques_created ON critiques(created_at);
6854
+ `);
6855
+ this.schemaReady = true;
6856
+ }
6857
+ return db;
6858
+ }
6859
+ // ─── Core Operations ─────────────────────────────────────────────────
6860
+ /**
6861
+ * Store a critique finding with deduplication.
6862
+ *
6863
+ * Before inserting, checks whether an identical (taskHash + category + message)
6864
+ * finding exists within the configured dedupeWindow. If so, the insert is
6865
+ * suppressed and the existing finding is returned.
6866
+ *
6867
+ * When the per-task limit is reached, the oldest findings are pruned.
6868
+ *
6869
+ * @param taskHash - Hash of the task being critiqued.
6870
+ * @param finding - The finding to store (id and createdAt are auto-generated).
6871
+ * @returns The stored (or existing duplicate) CritiqueFinding.
6872
+ */
6873
+ storeCritique(taskHash, finding) {
6874
+ const db = this.ensureSchema();
6875
+ const now = Date.now();
6876
+ const cutoff = now - this.config.dedupeWindow;
6877
+ const existing = db.prepare(`
6878
+ SELECT id, task_hash, severity, category, message, file, line, metadata, session_id, created_at
6879
+ FROM critiques
6880
+ WHERE task_hash = ? AND category = ? AND message = ? AND created_at > ?
6881
+ ORDER BY created_at DESC LIMIT 1
6882
+ `).get(taskHash, finding.category, finding.message, cutoff);
6883
+ if (existing) {
6884
+ return this.rowToFinding(existing);
6885
+ }
6886
+ const id = crypto3.randomUUID();
6887
+ const metaJson = finding.metadata ? JSON.stringify(finding.metadata) : null;
6888
+ db.prepare(`
6889
+ INSERT INTO critiques (id, task_hash, severity, category, message, file, line, metadata, session_id, created_at)
6890
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
6891
+ `).run(id, taskHash, finding.severity, finding.category, finding.message, finding.file ?? null, finding.line ?? null, metaJson, finding.sessionId ?? null, now);
6892
+ this.enforceTaskLimit(db, taskHash);
6893
+ return {
6894
+ id,
6895
+ taskHash,
6896
+ severity: finding.severity,
6897
+ category: finding.category,
6898
+ message: finding.message,
6899
+ file: finding.file,
6900
+ line: finding.line,
6901
+ metadata: finding.metadata,
6902
+ sessionId: finding.sessionId,
6903
+ createdAt: now
6904
+ };
6905
+ }
6906
+ /**
6907
+ * Retrieve critique findings for a specific task hash.
6908
+ *
6909
+ * Results are ordered by creation time descending (most recent first).
6910
+ *
6911
+ * @param taskHash - The task hash to query.
6912
+ * @param k - Maximum number of results. Default: 10.
6913
+ * @returns Array of CritiqueFinding ordered by recency.
6914
+ */
6915
+ retrieveCritiques(taskHash, k = 10) {
6916
+ const db = this.ensureSchema();
6917
+ const rows = db.prepare(`
6918
+ SELECT id, task_hash, severity, category, message, file, line, metadata, session_id, created_at
6919
+ FROM critiques
6920
+ WHERE task_hash = ?
6921
+ ORDER BY created_at DESC
6922
+ LIMIT ?
6923
+ `).all(taskHash, k);
6924
+ return rows.map((r) => this.rowToFinding(r));
6925
+ }
6926
+ /**
6927
+ * BM25 text search across all critique findings.
6928
+ *
6929
+ * Searches the concatenation of category + message + file for each finding.
6930
+ *
6931
+ * @param query - Free-text search query.
6932
+ * @param limit - Maximum results. Default: 10.
6933
+ * @returns Array of CritiqueFinding sorted by BM25 relevance.
6934
+ */
6935
+ searchCritiques(query, limit = 10) {
6936
+ const db = this.ensureSchema();
6937
+ const queryTerms = tokenize3(query);
6938
+ if (queryTerms.length === 0)
6939
+ return [];
6940
+ const rows = db.prepare(`
6941
+ SELECT id, task_hash, severity, category, message, file, line, metadata, session_id, created_at
6942
+ FROM critiques
6943
+ `).all();
6944
+ if (rows.length === 0)
6945
+ return [];
6946
+ const df = /* @__PURE__ */ new Map();
6947
+ const docs = [];
6948
+ for (const row of rows) {
6949
+ const finding = this.rowToFinding(row);
6950
+ const text = `${finding.category} ${finding.message} ${finding.file ?? ""}`;
6951
+ const terms = tokenize3(text);
6952
+ docs.push({ finding, terms });
6953
+ const uniqueTerms = new Set(terms);
6954
+ for (const t of uniqueTerms) {
6955
+ df.set(t, (df.get(t) ?? 0) + 1);
6956
+ }
6957
+ }
6958
+ const N = docs.length;
6959
+ const k1 = 1.5;
6960
+ const b = 0.75;
6961
+ const avgLen = 15;
6962
+ const queryLower = query.toLowerCase();
6963
+ const scored = [];
6964
+ for (const doc of docs) {
6965
+ let bm25 = 0;
6966
+ for (const qt of queryTerms) {
6967
+ const termFreq = doc.terms.filter((t) => t === qt).length;
6968
+ if (termFreq === 0)
6969
+ continue;
6970
+ const docFreq = df.get(qt) ?? 0;
6971
+ const idf = Math.log((N - docFreq + 0.5) / (docFreq + 0.5) + 1);
6972
+ const tf = termFreq * (k1 + 1) / (termFreq + k1 * (1 - b + b * doc.terms.length / avgLen));
6973
+ bm25 += idf * tf;
6974
+ }
6975
+ const docText = `${doc.finding.category} ${doc.finding.message}`.toLowerCase();
6976
+ if (docText.includes(queryLower))
6977
+ bm25 *= 1.5;
6978
+ if (bm25 > 0)
6979
+ scored.push({ finding: doc.finding, score: bm25 });
6980
+ }
6981
+ scored.sort((a, b2) => b2.score - a.score);
6982
+ return scored.slice(0, limit).map((s) => s.finding);
6983
+ }
6984
+ /**
6985
+ * Get aggregate statistics across all stored critique findings.
6986
+ *
6987
+ * @returns Total count, unique task count, and breakdown by severity.
6988
+ */
6989
+ getStats() {
6990
+ const db = this.ensureSchema();
6991
+ const total = db.prepare("SELECT COUNT(*) as cnt FROM critiques").get();
6992
+ const tasks = db.prepare("SELECT COUNT(DISTINCT task_hash) as cnt FROM critiques").get();
6993
+ const severityRows = db.prepare("SELECT severity, COUNT(*) as cnt FROM critiques GROUP BY severity").all();
6994
+ const bySeverity = {};
6995
+ for (const row of severityRows) {
6996
+ bySeverity[row.severity] = row.cnt;
6997
+ }
6998
+ return {
6999
+ totalCritiques: total.cnt,
7000
+ uniqueTasks: tasks.cnt,
7001
+ bySeverity
7002
+ };
7003
+ }
7004
+ /**
7005
+ * Remove findings older than the configured retentionDays.
7006
+ *
7007
+ * @returns Number of expired findings removed.
7008
+ */
7009
+ purgeExpired() {
7010
+ const db = this.ensureSchema();
7011
+ const cutoff = Date.now() - this.config.retentionDays * 24 * 60 * 60 * 1e3;
7012
+ const result = db.prepare("DELETE FROM critiques WHERE created_at < ?").run(cutoff);
7013
+ return result.changes;
7014
+ }
7015
+ /**
7016
+ * Clear all findings, or only findings for a specific task hash.
7017
+ *
7018
+ * @param taskHash - If provided, only clear findings for this task. Otherwise clear all.
7019
+ */
7020
+ clear(taskHash) {
7021
+ const db = this.ensureSchema();
7022
+ if (taskHash) {
7023
+ db.prepare("DELETE FROM critiques WHERE task_hash = ?").run(taskHash);
7024
+ } else {
7025
+ db.prepare("DELETE FROM critiques").run();
7026
+ }
7027
+ }
7028
+ // ─── Internal Helpers ────────────────────────────────────────────────
7029
+ /**
7030
+ * Enforce the maxPerTask cardinality limit by pruning the oldest entries.
7031
+ *
7032
+ * @param db - The database connection.
7033
+ * @param taskHash - The task hash to enforce the limit for.
7034
+ */
7035
+ enforceTaskLimit(db, taskHash) {
7036
+ const count = db.prepare("SELECT COUNT(*) as cnt FROM critiques WHERE task_hash = ?").get(taskHash);
7037
+ if (count.cnt > this.config.maxPerTask) {
7038
+ const excess = count.cnt - this.config.maxPerTask;
7039
+ db.prepare(`
7040
+ DELETE FROM critiques WHERE id IN (
7041
+ SELECT id FROM critiques WHERE task_hash = ? ORDER BY created_at ASC LIMIT ?
7042
+ )
7043
+ `).run(taskHash, excess);
7044
+ }
7045
+ }
7046
+ /**
7047
+ * Convert a raw SQLite row into a typed CritiqueFinding.
7048
+ *
7049
+ * @param row - A record from the critiques table.
7050
+ * @returns A fully typed CritiqueFinding.
7051
+ */
7052
+ rowToFinding(row) {
7053
+ let metadata;
7054
+ try {
7055
+ metadata = row.metadata ? JSON.parse(row.metadata) : void 0;
7056
+ } catch {
7057
+ metadata = void 0;
7058
+ }
7059
+ return {
7060
+ id: row.id,
7061
+ taskHash: row.task_hash,
7062
+ severity: row.severity,
7063
+ category: row.category,
7064
+ message: row.message,
7065
+ file: row.file ?? void 0,
7066
+ line: row.line ?? void 0,
7067
+ metadata,
7068
+ sessionId: row.session_id ?? void 0,
7069
+ createdAt: row.created_at
7070
+ };
7071
+ }
7072
+ };
7073
+
7074
+ // ../chitragupta/packages/smriti/dist/orchestrator-checkpoint.js
7075
+ init_session_db();
7076
+ import { randomUUID as randomUUID2 } from "node:crypto";
7077
+ var DEFAULT_MAX_PER_TYPE = 100;
7078
+ var DEFAULT_RETENTION_DAYS = 30;
7079
+ var MS_PER_DAY = 864e5;
7080
+ var CREATE_JOBS_TABLE = `
7081
+ CREATE TABLE IF NOT EXISTS orchestrator_jobs (
7082
+ job_id TEXT PRIMARY KEY,
7083
+ job_type TEXT NOT NULL,
7084
+ status TEXT NOT NULL,
7085
+ current_step_index INTEGER NOT NULL DEFAULT 0,
7086
+ metadata TEXT,
7087
+ idempotency_key TEXT NOT NULL UNIQUE,
7088
+ created_at INTEGER NOT NULL,
7089
+ updated_at INTEGER NOT NULL
7090
+ )`;
7091
+ var CREATE_STEPS_TABLE = `
7092
+ CREATE TABLE IF NOT EXISTS orchestrator_steps (
7093
+ job_id TEXT NOT NULL,
7094
+ step_id TEXT NOT NULL,
7095
+ step_index INTEGER NOT NULL,
7096
+ status TEXT NOT NULL DEFAULT 'pending',
7097
+ input TEXT,
7098
+ output TEXT,
7099
+ error TEXT,
7100
+ started_at INTEGER,
7101
+ completed_at INTEGER,
7102
+ retry_count INTEGER NOT NULL DEFAULT 0,
7103
+ PRIMARY KEY (job_id, step_id),
7104
+ FOREIGN KEY (job_id) REFERENCES orchestrator_jobs(job_id) ON DELETE CASCADE
7105
+ )`;
7106
+ var CREATE_JOBS_TYPE_IDX = `CREATE INDEX IF NOT EXISTS idx_orch_jobs_type ON orchestrator_jobs(job_type)`;
7107
+ var CREATE_JOBS_STATUS_IDX = `CREATE INDEX IF NOT EXISTS idx_orch_jobs_status ON orchestrator_jobs(status)`;
7108
+ var CREATE_STEPS_JOB_IDX = `CREATE INDEX IF NOT EXISTS idx_orch_steps_job ON orchestrator_steps(job_id)`;
7109
+ function rowToStep(row) {
7110
+ return {
7111
+ stepId: row.step_id,
7112
+ status: row.status,
7113
+ input: row.input ? JSON.parse(row.input) : void 0,
7114
+ output: row.output ? JSON.parse(row.output) : void 0,
7115
+ error: row.error ?? void 0,
7116
+ startedAt: row.started_at ?? void 0,
7117
+ completedAt: row.completed_at ?? void 0,
7118
+ retryCount: row.retry_count ?? 0
7119
+ };
7120
+ }
7121
+ function assembleJob(jobRow, stepRows) {
7122
+ const steps = stepRows.sort((a, b) => a.step_index - b.step_index).map(rowToStep);
7123
+ return {
7124
+ jobId: jobRow.job_id,
7125
+ jobType: jobRow.job_type,
7126
+ status: jobRow.status,
7127
+ steps,
7128
+ currentStepIndex: jobRow.current_step_index,
7129
+ metadata: jobRow.metadata ? JSON.parse(jobRow.metadata) : {},
7130
+ createdAt: jobRow.created_at,
7131
+ updatedAt: jobRow.updated_at,
7132
+ idempotencyKey: jobRow.idempotency_key
7133
+ };
7134
+ }
7135
+ var OrchestratorCheckpoint = class {
7136
+ db;
7137
+ maxPerType;
7138
+ retentionDays;
7139
+ initialized = false;
7140
+ constructor(config) {
7141
+ this.db = getAgentDb();
7142
+ this.maxPerType = config?.maxPerType ?? DEFAULT_MAX_PER_TYPE;
7143
+ this.retentionDays = config?.retentionDays ?? DEFAULT_RETENTION_DAYS;
7144
+ this.ensureSchema();
7145
+ }
7146
+ /**
7147
+ * Create a new orchestration job with the given steps.
7148
+ *
7149
+ * Idempotency: throws if a job with the same key exists in a non-terminal state.
7150
+ * If the key exists but the prior job is completed or failed, allows re-creation.
7151
+ *
7152
+ * @param jobType - Category of this job (e.g. "code-review", "deploy").
7153
+ * @param steps - Ordered step definitions for the job.
7154
+ * @param idempotencyKey - Unique key to prevent duplicate execution.
7155
+ * @param metadata - Optional metadata to attach to the job.
7156
+ * @returns The newly created job checkpoint.
7157
+ */
7158
+ createJob(jobType, steps, idempotencyKey, metadata) {
7159
+ const existing = this.db.prepare("SELECT job_id, status FROM orchestrator_jobs WHERE idempotency_key = ?").get(idempotencyKey);
7160
+ if (existing && existing.status !== "completed" && existing.status !== "failed") {
7161
+ throw new Error(`Duplicate idempotency key "${idempotencyKey}": job ${existing.job_id} is still ${existing.status}`);
7162
+ }
7163
+ if (existing) {
7164
+ this.deleteJob(existing.job_id);
7165
+ }
7166
+ const jobId = `job-${randomUUID2().slice(0, 12)}`;
7167
+ const now = Date.now();
7168
+ const txn = this.db.transaction(() => {
7169
+ this.db.prepare(`
7170
+ INSERT INTO orchestrator_jobs (job_id, job_type, status, current_step_index, metadata, idempotency_key, created_at, updated_at)
7171
+ VALUES (?, ?, 'running', 0, ?, ?, ?, ?)
7172
+ `).run(jobId, jobType, metadata ? JSON.stringify(metadata) : null, idempotencyKey, now, now);
7173
+ for (let i = 0; i < steps.length; i++) {
7174
+ const step = steps[i];
7175
+ const status = i === 0 ? "running" : "pending";
7176
+ const startedAt = i === 0 ? now : null;
7177
+ this.db.prepare(`
7178
+ INSERT INTO orchestrator_steps (job_id, step_id, step_index, status, input, retry_count, started_at)
7179
+ VALUES (?, ?, ?, ?, ?, 0, ?)
7180
+ `).run(jobId, step.stepId, i, status, step.input ? JSON.stringify(step.input) : null, startedAt);
7181
+ }
7182
+ });
7183
+ txn();
7184
+ this.enforceMaxPerType(jobType);
7185
+ return this.loadJob(jobId);
7186
+ }
7187
+ /**
7188
+ * Load a job checkpoint by ID.
7189
+ * @returns The job checkpoint, or null if not found.
7190
+ */
7191
+ loadJob(jobId) {
7192
+ const jobRow = this.db.prepare("SELECT * FROM orchestrator_jobs WHERE job_id = ?").get(jobId);
7193
+ if (!jobRow)
7194
+ return null;
7195
+ const stepRows = this.db.prepare("SELECT * FROM orchestrator_steps WHERE job_id = ? ORDER BY step_index").all(jobId);
7196
+ return assembleJob(jobRow, stepRows);
7197
+ }
7198
+ /**
7199
+ * Mark the current step as completed and advance to the next step.
7200
+ * @returns The completed step checkpoint.
7201
+ */
7202
+ advanceStep(jobId, output) {
7203
+ const job = this.requireJob(jobId);
7204
+ const currentStep = job.steps[job.currentStepIndex];
7205
+ if (!currentStep)
7206
+ throw new Error(`No current step at index ${job.currentStepIndex}`);
7207
+ const now = Date.now();
7208
+ const txn = this.db.transaction(() => {
7209
+ this.db.prepare(`
7210
+ UPDATE orchestrator_steps SET status = 'completed', output = ?, completed_at = ?
7211
+ WHERE job_id = ? AND step_id = ?
7212
+ `).run(output ? JSON.stringify(output) : null, now, jobId, currentStep.stepId);
7213
+ const nextIndex = job.currentStepIndex + 1;
7214
+ if (nextIndex < job.steps.length) {
7215
+ const nextStep = job.steps[nextIndex];
7216
+ this.db.prepare(`
7217
+ UPDATE orchestrator_steps SET status = 'running', started_at = ?
7218
+ WHERE job_id = ? AND step_id = ?
7219
+ `).run(now, jobId, nextStep.stepId);
7220
+ this.db.prepare("UPDATE orchestrator_jobs SET current_step_index = ?, updated_at = ? WHERE job_id = ?").run(nextIndex, now, jobId);
7221
+ } else {
7222
+ this.db.prepare("UPDATE orchestrator_jobs SET updated_at = ? WHERE job_id = ?").run(now, jobId);
7223
+ }
7224
+ });
7225
+ txn();
7226
+ return { ...currentStep, status: "completed", output, completedAt: now };
7227
+ }
7228
+ /**
7229
+ * Mark the current step as failed and increment its retry count.
7230
+ * @returns The failed step checkpoint.
7231
+ */
7232
+ failStep(jobId, error) {
7233
+ const job = this.requireJob(jobId);
7234
+ const currentStep = job.steps[job.currentStepIndex];
7235
+ if (!currentStep)
7236
+ throw new Error(`No current step at index ${job.currentStepIndex}`);
7237
+ const now = Date.now();
7238
+ const newRetry = currentStep.retryCount + 1;
7239
+ this.db.prepare(`
7240
+ UPDATE orchestrator_steps SET status = 'failed', error = ?, retry_count = ?
7241
+ WHERE job_id = ? AND step_id = ?
7242
+ `).run(error, newRetry, jobId, currentStep.stepId);
7243
+ this.db.prepare("UPDATE orchestrator_jobs SET updated_at = ? WHERE job_id = ?").run(now, jobId);
7244
+ return { ...currentStep, status: "failed", error, retryCount: newRetry };
7245
+ }
7246
+ /**
7247
+ * Retry the current failed step (reset to running).
7248
+ * @throws If the current step is not in "failed" status.
7249
+ */
7250
+ retryStep(jobId) {
7251
+ const job = this.requireJob(jobId);
7252
+ const currentStep = job.steps[job.currentStepIndex];
7253
+ if (!currentStep)
7254
+ throw new Error(`No current step at index ${job.currentStepIndex}`);
7255
+ if (currentStep.status !== "failed") {
7256
+ throw new Error(`Cannot retry step "${currentStep.stepId}" \u2014 status is "${currentStep.status}", not "failed"`);
7257
+ }
7258
+ const now = Date.now();
7259
+ this.db.prepare(`
7260
+ UPDATE orchestrator_steps SET status = 'running', error = NULL, started_at = ?
7261
+ WHERE job_id = ? AND step_id = ?
7262
+ `).run(now, jobId, currentStep.stepId);
7263
+ this.db.prepare("UPDATE orchestrator_jobs SET status = 'running', updated_at = ? WHERE job_id = ?").run(now, jobId);
7264
+ return { ...currentStep, status: "running", error: void 0, startedAt: now };
7265
+ }
7266
+ /** Mark the entire job as completed. */
7267
+ completeJob(jobId) {
7268
+ this.requireJob(jobId);
7269
+ const now = Date.now();
7270
+ this.db.prepare("UPDATE orchestrator_jobs SET status = 'completed', updated_at = ? WHERE job_id = ?").run(now, jobId);
7271
+ return this.loadJob(jobId);
7272
+ }
7273
+ /** Mark the entire job as failed with an error message stored in metadata. */
7274
+ failJob(jobId, error) {
7275
+ const job = this.requireJob(jobId);
7276
+ const now = Date.now();
7277
+ const meta = { ...job.metadata, failureError: error };
7278
+ this.db.prepare("UPDATE orchestrator_jobs SET status = 'failed', metadata = ?, updated_at = ? WHERE job_id = ?").run(JSON.stringify(meta), now, jobId);
7279
+ return this.loadJob(jobId);
7280
+ }
7281
+ /**
7282
+ * Resume a paused or failed job from the last incomplete step.
7283
+ * @throws If the job is already completed.
7284
+ */
7285
+ resumeJob(jobId) {
7286
+ const job = this.requireJob(jobId);
7287
+ if (job.status === "completed") {
7288
+ throw new Error(`Cannot resume job ${jobId} \u2014 already completed`);
7289
+ }
7290
+ const now = Date.now();
7291
+ let resumeIndex = -1;
7292
+ for (let i = 0; i < job.steps.length; i++) {
7293
+ if (job.steps[i].status !== "completed" && job.steps[i].status !== "skipped") {
7294
+ resumeIndex = i;
7295
+ break;
7296
+ }
7297
+ }
7298
+ if (resumeIndex === -1) {
7299
+ this.db.prepare("UPDATE orchestrator_jobs SET status = 'running', updated_at = ? WHERE job_id = ?").run(now, jobId);
7300
+ return this.loadJob(jobId);
7301
+ }
7302
+ const txn = this.db.transaction(() => {
7303
+ const step = job.steps[resumeIndex];
7304
+ this.db.prepare(`
7305
+ UPDATE orchestrator_steps SET status = 'running', error = NULL, started_at = ?
7306
+ WHERE job_id = ? AND step_id = ?
7307
+ `).run(now, jobId, step.stepId);
7308
+ this.db.prepare(`
7309
+ UPDATE orchestrator_jobs SET status = 'running', current_step_index = ?, updated_at = ?
7310
+ WHERE job_id = ?
7311
+ `).run(resumeIndex, now, jobId);
7312
+ });
7313
+ txn();
7314
+ return this.loadJob(jobId);
7315
+ }
7316
+ /** List jobs with optional type and status filters. */
7317
+ listJobs(filter) {
7318
+ let sql = "SELECT * FROM orchestrator_jobs WHERE 1=1";
7319
+ const params = [];
7320
+ if (filter?.jobType) {
7321
+ sql += " AND job_type = ?";
7322
+ params.push(filter.jobType);
7323
+ }
7324
+ if (filter?.status) {
7325
+ sql += " AND status = ?";
7326
+ params.push(filter.status);
7327
+ }
7328
+ sql += " ORDER BY updated_at DESC";
7329
+ const jobRows = this.db.prepare(sql).all(...params);
7330
+ return jobRows.map((row) => {
7331
+ const stepRows = this.db.prepare("SELECT * FROM orchestrator_steps WHERE job_id = ? ORDER BY step_index").all(row.job_id);
7332
+ return assembleJob(row, stepRows);
7333
+ });
7334
+ }
7335
+ /**
7336
+ * Purge completed/failed jobs older than retentionDays.
7337
+ * @returns Number of jobs removed.
7338
+ */
7339
+ purgeOld() {
7340
+ const cutoff = Date.now() - this.retentionDays * MS_PER_DAY;
7341
+ const rows = this.db.prepare(`
7342
+ SELECT job_id FROM orchestrator_jobs
7343
+ WHERE status IN ('completed', 'failed') AND updated_at < ?
7344
+ `).all(cutoff);
7345
+ if (rows.length === 0)
7346
+ return 0;
7347
+ const txn = this.db.transaction(() => {
7348
+ for (const row of rows) {
7349
+ this.deleteJob(row.job_id);
7350
+ }
7351
+ });
7352
+ txn();
7353
+ return rows.length;
7354
+ }
7355
+ // ─── Private ──────────────────────────────────────────────────────────────
7356
+ /** Create tables if they don't exist. Idempotent. */
7357
+ ensureSchema() {
7358
+ if (this.initialized)
7359
+ return;
7360
+ this.db.exec(CREATE_JOBS_TABLE);
7361
+ this.db.exec(CREATE_STEPS_TABLE);
7362
+ this.db.exec(CREATE_JOBS_TYPE_IDX);
7363
+ this.db.exec(CREATE_JOBS_STATUS_IDX);
7364
+ this.db.exec(CREATE_STEPS_JOB_IDX);
7365
+ this.initialized = true;
7366
+ }
7367
+ /** Load a job or throw if not found. */
7368
+ requireJob(jobId) {
7369
+ const job = this.loadJob(jobId);
7370
+ if (!job)
7371
+ throw new Error(`Job not found: ${jobId}`);
7372
+ return job;
7373
+ }
7374
+ /** Delete a job and all its steps. */
7375
+ deleteJob(jobId) {
7376
+ this.db.prepare("DELETE FROM orchestrator_steps WHERE job_id = ?").run(jobId);
7377
+ this.db.prepare("DELETE FROM orchestrator_jobs WHERE job_id = ?").run(jobId);
7378
+ }
7379
+ /** Evict oldest completed/failed jobs when exceeding maxPerType. */
7380
+ enforceMaxPerType(jobType) {
7381
+ const count = this.db.prepare("SELECT COUNT(*) as cnt FROM orchestrator_jobs WHERE job_type = ?").get(jobType);
7382
+ if (count.cnt <= this.maxPerType)
7383
+ return;
7384
+ const excess = count.cnt - this.maxPerType;
7385
+ const toRemove = this.db.prepare(`
7386
+ SELECT job_id FROM orchestrator_jobs
7387
+ WHERE job_type = ? AND status IN ('completed', 'failed')
7388
+ ORDER BY updated_at ASC LIMIT ?
7389
+ `).all(jobType, excess);
7390
+ for (const row of toRemove) {
7391
+ this.deleteJob(row.job_id);
7392
+ }
7393
+ }
7394
+ };
7395
+
7140
7396
  export {
7141
7397
  exportSessionToJson,
7142
7398
  exportSessionToMarkdown,
@@ -7172,13 +7428,14 @@ export {
7172
7428
  IdentityContext,
7173
7429
  SvapnaConsolidation,
7174
7430
  VidhiEngine,
7175
- AkashaField,
7176
7431
  TEMPORAL_SCALES,
7177
7432
  KalaChakra,
7178
7433
  VRITTI_TYPES,
7179
7434
  VRITTI_CONFIDENCE_WEIGHTS,
7180
7435
  PanchaVritti,
7181
7436
  recall,
7182
- loadProviderContext
7437
+ loadProviderContext,
7438
+ CritiqueStore,
7439
+ OrchestratorCheckpoint
7183
7440
  };
7184
- //# sourceMappingURL=chunk-AGK3A7R7.js.map
7441
+ //# sourceMappingURL=chunk-TSOQ2CT3.js.map