@yugenlab/vaayu 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/chunks/{agentic-tool-loop-O3NUV7KG.js → agentic-tool-loop-NQESOBLC.js} +2 -2
  2. package/chunks/akasha-5C5Q6NMP.js +12 -0
  3. package/chunks/{chunk-7XV5ISV7.js → chunk-26K6DS6N.js} +2 -2
  4. package/chunks/chunk-5E3ZS5SW.js +529 -0
  5. package/chunks/{chunk-D46QTN3G.js → chunk-ARZCIITZ.js} +47 -18
  6. package/chunks/{chunk-ZYY6N3SP.js → chunk-FEDPZOZ5.js} +548 -389
  7. package/chunks/{chunk-3AYSJ7WB.js → chunk-GWYC7R2L.js} +13 -7
  8. package/chunks/chunk-H46F2Y6R.js +134 -0
  9. package/chunks/{chunk-QV4GPIPT.js → chunk-HXHDP2PZ.js} +8 -4
  10. package/chunks/chunk-KVQH4LE7.js +396 -0
  11. package/chunks/{chunk-Z576WVLG.js → chunk-LJCT7UYP.js} +17 -7
  12. package/chunks/{chunk-LJUEMPLG.js → chunk-M2RLX5LU.js} +32 -14
  13. package/chunks/{chunk-IGKYKEKT.js → chunk-NAQKA54E.js} +8 -2
  14. package/chunks/{chunk-F6RNEGFX.js → chunk-PZ4AQ22L.js} +78 -13
  15. package/chunks/{chunk-G2QREGXK.js → chunk-R273KC7J.js} +275 -2
  16. package/chunks/{chunk-A3HOZBC5.js → chunk-RVKTGKFD.js} +2 -2
  17. package/chunks/{chunk-VCUJES75.js → chunk-TSOQ2CT3.js} +763 -620
  18. package/chunks/{chunk-V2ZIKDN4.js → chunk-VEZ2DI2M.js} +16 -5
  19. package/chunks/{chunk-W4PVGBUH.js → chunk-XP3NIH5F.js} +7 -3
  20. package/chunks/{chunk-7AYYXHYZ.js → chunk-Y6IZH6FT.js} +19 -4
  21. package/chunks/{chunk-JZTFJE7M.js → chunk-YRTGGYJU.js} +14 -10
  22. package/chunks/{consolidation-indexer-VIWOP6VO.js → consolidation-indexer-KPXORCJ4.js} +9 -9
  23. package/chunks/database-BX3LVYXS.js +11 -0
  24. package/chunks/{day-consolidation-HMHSXIOM.js → day-consolidation-CR3TJFAL.js} +5 -5
  25. package/chunks/{dist-CY5NX2IK.js → dist-ESCM3CP5.js} +31 -21
  26. package/chunks/graphrag-73XA7LBX.js +14 -0
  27. package/chunks/hierarchical-temporal-search-GHKVKNZ6.js +8 -0
  28. package/chunks/hybrid-search-OD756RDV.js +20 -0
  29. package/chunks/{memory-store-LEERUQGL.js → memory-store-4GCBR2DZ.js} +4 -4
  30. package/chunks/periodic-consolidation-IINCHP6L.js +11 -0
  31. package/chunks/{postgres-7GZDDX77.js → postgres-YLCUNVPQ.js} +2 -2
  32. package/chunks/recall-64RROTUC.js +21 -0
  33. package/chunks/search-JVCDNTAJ.js +19 -0
  34. package/chunks/{session-store-O3TS7DUY.js → session-store-3EDQZEDS.js} +12 -6
  35. package/chunks/{sqlite-7BC4DJTN.js → sqlite-4N7YH2KK.js} +2 -2
  36. package/chunks/{src-6GVZTUH6.js → src-OPSDZEFI.js} +2 -2
  37. package/chunks/{suncalc-NOHGYHDU.js → suncalc-RM7URNUR.js} +2 -2
  38. package/chunks/{tree-RSHKDTCR.js → tree-FIUVGJ5J.js} +2 -2
  39. package/chunks/{vasana-engine-BJFHJVGM.js → vasana-engine-W4PYWT5H.js} +5 -5
  40. package/gateway.js +2358 -768
  41. package/package.json +1 -1
  42. package/pair-cli.js +2 -2
  43. package/chunks/chunk-2OBLQJYJ.js +0 -198
  44. package/chunks/chunk-67DXWEKG.js +0 -123
  45. package/chunks/graphrag-T2QWNX57.js +0 -14
  46. package/chunks/hierarchical-temporal-search-U6DG74IR.js +0 -8
  47. package/chunks/hybrid-search-BYTXCOXP.js +0 -20
  48. package/chunks/periodic-consolidation-D6SSKZ7H.js +0 -11
  49. package/chunks/recall-LNRQVATQ.js +0 -21
  50. package/chunks/search-BIODUW2P.js +0 -19
@@ -1,30 +1,41 @@
1
1
  import {
2
2
  getDayFilePath,
3
3
  listDayFiles
4
- } from "./chunk-F6RNEGFX.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-D46QTN3G.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-ZYY6N3SP.js";
21
+ } from "./chunk-FEDPZOZ5.js";
17
22
  import {
18
23
  cosineSimilarity,
19
24
  estimateTokens
20
- } from "./chunk-A3HOZBC5.js";
25
+ } from "./chunk-RVKTGKFD.js";
21
26
  import {
22
27
  DatabaseManager
23
- } from "./chunk-67DXWEKG.js";
28
+ } from "./chunk-H46F2Y6R.js";
24
29
  import {
25
30
  SessionError,
26
- getChitraguptaHome
27
- } from "./chunk-2OBLQJYJ.js";
31
+ getChitraguptaHome,
32
+ init_dist
33
+ } from "./chunk-KVQH4LE7.js";
34
+
35
+ // ../chitragupta/packages/smriti/dist/index.js
36
+ init_markdown_parser();
37
+ init_markdown_writer();
38
+ init_session_store();
28
39
 
29
40
  // ../chitragupta/packages/smriti/dist/session-export.js
30
41
  function exportSessionToJson(session) {
@@ -235,12 +246,14 @@ function validateExportedSession(data) {
235
246
  }
236
247
 
237
248
  // ../chitragupta/packages/smriti/dist/cross-machine-sync.js
249
+ init_dist();
238
250
  import fs2 from "node:fs";
239
251
  import os from "node:os";
240
252
  import path2 from "node:path";
241
253
  import crypto2 from "node:crypto";
242
254
 
243
255
  // ../chitragupta/packages/smriti/dist/sync-import.js
256
+ init_dist();
244
257
  import fs from "node:fs";
245
258
  import path from "node:path";
246
259
  import crypto from "node:crypto";
@@ -655,6 +668,8 @@ function getCrossMachineSyncStatus() {
655
668
  }
656
669
 
657
670
  // ../chitragupta/packages/smriti/dist/branch.js
671
+ init_dist();
672
+ init_session_store();
658
673
  function branchSession(sessionId, project, branchName, fromTurn) {
659
674
  const original = loadSession(sessionId, project);
660
675
  let turnsToKeep = original.turns;
@@ -1174,6 +1189,7 @@ function writeDeltaMarkdown(delta) {
1174
1189
  }
1175
1190
 
1176
1191
  // ../chitragupta/packages/smriti/dist/compactor.js
1192
+ init_dist();
1177
1193
  import fs3 from "fs";
1178
1194
  import path3 from "path";
1179
1195
  function getCompactionDir() {
@@ -1369,7 +1385,9 @@ var SessionCompactor = class {
1369
1385
  const filePath = path3.join(dir, `${delta.sessionId}.md`);
1370
1386
  const markdown = writeDeltaMarkdown(delta);
1371
1387
  fs3.writeFileSync(filePath, markdown, "utf-8");
1372
- } catch {
1388
+ } catch (err) {
1389
+ process.stderr.write(`[smriti:compactor] delta save failed: ${err instanceof Error ? err.message : String(err)}
1390
+ `);
1373
1391
  }
1374
1392
  }
1375
1393
  saveMixingMatrix(sessionId, mixingMatrix, signals) {
@@ -1396,7 +1414,9 @@ var SessionCompactor = class {
1396
1414
  };
1397
1415
  const filePath = path3.join(dir, `${sessionId}.json`);
1398
1416
  fs3.writeFileSync(filePath, JSON.stringify(data, null, " "), "utf-8");
1399
- } catch {
1417
+ } catch (err) {
1418
+ process.stderr.write(`[smriti:compactor] mixing matrix save failed: ${err instanceof Error ? err.message : String(err)}
1419
+ `);
1400
1420
  }
1401
1421
  }
1402
1422
  };
@@ -2235,6 +2255,7 @@ var CheckpointManager = class {
2235
2255
  };
2236
2256
 
2237
2257
  // ../chitragupta/packages/smriti/dist/consolidation.js
2258
+ init_dist();
2238
2259
  import fs5 from "fs";
2239
2260
  import path5 from "path";
2240
2261
 
@@ -2634,7 +2655,7 @@ function enforceMaxRules(rules, maxRules) {
2634
2655
  }
2635
2656
  }
2636
2657
 
2637
- // ../chitragupta/packages/smriti/dist/consolidation.js
2658
+ // ../chitragupta/packages/smriti/dist/consolidation-types.js
2638
2659
  var DEFAULT_CONFIG = {
2639
2660
  minObservations: 2,
2640
2661
  decayRatePerDay: 0.01,
@@ -2652,6 +2673,8 @@ var ALL_CATEGORIES = [
2652
2673
  "domain-knowledge",
2653
2674
  "relationship"
2654
2675
  ];
2676
+
2677
+ // ../chitragupta/packages/smriti/dist/consolidation.js
2655
2678
  var ConsolidationEngine = class {
2656
2679
  config;
2657
2680
  rules = /* @__PURE__ */ new Map();
@@ -3389,6 +3412,7 @@ var AnveshanaEngine = class {
3389
3412
  };
3390
3413
 
3391
3414
  // ../chitragupta/packages/smriti/dist/smaran.js
3415
+ init_dist();
3392
3416
  import path7 from "path";
3393
3417
 
3394
3418
  // ../chitragupta/packages/smriti/dist/smaran-store.js
@@ -4171,9 +4195,18 @@ async function svapnaReplay(db, config) {
4171
4195
  const placeholders = sessionIds.map(() => "?").join(",");
4172
4196
  const turns = agentDb.prepare(`SELECT id, session_id, turn_number, role, content, tool_calls, created_at
4173
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
+ });
4174
4207
  const patternCounts = /* @__PURE__ */ new Map();
4175
4208
  let totalPatterns = 0;
4176
- for (const turn of turns) {
4209
+ for (const turn of realTurns) {
4177
4210
  const calls = parseToolCalls(turn.tool_calls);
4178
4211
  for (const tc of calls) {
4179
4212
  const key = `${tc.name}:${tc.isError ? "err" : "ok"}`;
@@ -4182,7 +4215,7 @@ async function svapnaReplay(db, config) {
4182
4215
  }
4183
4216
  }
4184
4217
  const scoredTurns = [];
4185
- for (const turn of turns) {
4218
+ for (const turn of realTurns) {
4186
4219
  const calls = parseToolCalls(turn.tool_calls);
4187
4220
  let surprise = 0;
4188
4221
  if (calls.length > 0) {
@@ -4626,7 +4659,7 @@ async function svapnaProceduralize(db, config) {
4626
4659
  return { vidhisCreated: createdVidhis.length, vidhis: createdVidhis, durationMs: performance.now() - start };
4627
4660
  }
4628
4661
 
4629
- // ../chitragupta/packages/smriti/dist/svapna-consolidation.js
4662
+ // ../chitragupta/packages/smriti/dist/svapna-types.js
4630
4663
  var DEFAULT_CONFIG4 = {
4631
4664
  maxSessionsPerCycle: 50,
4632
4665
  surpriseThreshold: 0.7,
@@ -4643,6 +4676,8 @@ var PRAMANA_PRESERVATION = {
4643
4676
  arthapatti: 0.4,
4644
4677
  anupalabdhi: 0.25
4645
4678
  };
4679
+
4680
+ // ../chitragupta/packages/smriti/dist/svapna-consolidation.js
4646
4681
  var SvapnaConsolidation = class {
4647
4682
  config;
4648
4683
  db;
@@ -4689,30 +4724,11 @@ var SvapnaConsolidation = class {
4689
4724
  const totalDurationMs = performance.now() - cycleStart;
4690
4725
  const result = {
4691
4726
  phases: {
4692
- replay: {
4693
- turnsScored: replayResult.turnsScored,
4694
- highSurprise: replayResult.highSurprise,
4695
- durationMs: replayResult.durationMs
4696
- },
4697
- recombine: {
4698
- associations: recombineResult.associations.length,
4699
- crossSessions: recombineResult.crossSessions,
4700
- durationMs: recombineResult.durationMs
4701
- },
4702
- crystallize: {
4703
- vasanasCreated: crystallizeResult.vasanasCreated,
4704
- vasanasReinforced: crystallizeResult.vasanasReinforced,
4705
- durationMs: crystallizeResult.durationMs
4706
- },
4707
- proceduralize: {
4708
- vidhisCreated: proceduralizeResult.vidhisCreated,
4709
- durationMs: proceduralizeResult.durationMs
4710
- },
4711
- compress: {
4712
- tokensCompressed: compressResult.tokensCompressed,
4713
- compressionRatio: compressResult.compressionRatio,
4714
- durationMs: compressResult.durationMs
4715
- }
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 }
4716
4732
  },
4717
4733
  totalDurationMs,
4718
4734
  cycleId: this.cycleId
@@ -4767,6 +4783,8 @@ var SvapnaConsolidation = class {
4767
4783
  const maxAge = 30 * 24 * 60 * 60 * 1e3;
4768
4784
  let totalOriginalTokens = 0;
4769
4785
  for (const turn of turns) {
4786
+ if (this.isNoiseTurn(turn.content))
4787
+ continue;
4770
4788
  const tokens = estimateTokens(turn.content);
4771
4789
  totalOriginalTokens += tokens;
4772
4790
  const calls = parseToolCalls(turn.tool_calls);
@@ -4785,6 +4803,13 @@ var SvapnaConsolidation = class {
4785
4803
  if (chunks.length < 2) {
4786
4804
  return { tokensCompressed: totalOriginalTokens, compressionRatio: 1, durationMs: performance.now() - start };
4787
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) {
4788
4813
  const n = chunks.length;
4789
4814
  const affinity = [];
4790
4815
  for (let i = 0; i < n; i++) {
@@ -4809,6 +4834,7 @@ var SvapnaConsolidation = class {
4809
4834
  }
4810
4835
  const targetTokens = Math.floor(totalOriginalTokens * 0.7);
4811
4836
  let compressedTotal = 0;
4837
+ const agentDb = this.db.get("agent");
4812
4838
  const updateStmt = agentDb.prepare(`UPDATE turns SET content = ? WHERE id = ?`);
4813
4839
  const insertRuleStmt = agentDb.prepare(`INSERT INTO consolidation_rules
4814
4840
  (project, category, rule_text, source_sessions, confidence, created_at, updated_at)
@@ -4828,8 +4854,7 @@ var SvapnaConsolidation = class {
4828
4854
  if (cueAnchors.length > 0) {
4829
4855
  try {
4830
4856
  const graphDb = this.db.get("graph");
4831
- const upsertNode = graphDb.prepare(`INSERT OR REPLACE INTO nodes (id, type, label, content, metadata)
4832
- VALUES (?, 'concept', ?, ?, ?)`);
4857
+ const upsertNode = graphDb.prepare(`INSERT OR REPLACE INTO nodes (id, type, label, content, metadata) VALUES (?, 'concept', ?, ?, ?)`);
4833
4858
  for (const cue of cueAnchors) {
4834
4859
  upsertNode.run(`cue-${turn.id}-${cue.slice(0, 20)}`, cue, gist.slice(0, 200), JSON.stringify({ source: `turn:${turn.id}`, cycle: this.cycleId }));
4835
4860
  }
@@ -4843,15 +4868,9 @@ var SvapnaConsolidation = class {
4843
4868
  compressBatch();
4844
4869
  } catch {
4845
4870
  }
4846
- const compressionRatio = totalOriginalTokens > 0 ? compressedTotal / totalOriginalTokens : 1;
4847
- return { tokensCompressed: totalOriginalTokens, compressionRatio, durationMs: performance.now() - start };
4871
+ return { compressedTotal };
4848
4872
  }
4849
- // ── Private Helpers ──────────────────────────────────────────────────
4850
- /**
4851
- * Generate a compressed gist (abstraction) of turn content.
4852
- * Uses extractive summarization: keeps the first and last sentences,
4853
- * plus any sentences containing tool calls or decisions.
4854
- */
4873
+ /** Generate a compressed gist (abstraction) of turn content. */
4855
4874
  generateGist(content, tokenBudget) {
4856
4875
  const sentences = content.split(/(?<=[.!?\n])\s+/).filter((s) => s.trim().length > 0);
4857
4876
  if (sentences.length <= 2)
@@ -4859,42 +4878,47 @@ var SvapnaConsolidation = class {
4859
4878
  const kept = [sentences[0]];
4860
4879
  const signalPattern = /\b(error|decided|created|modified|fixed|found|returned|result|output)\b/i;
4861
4880
  for (let i = 1; i < sentences.length - 1; i++) {
4862
- if (signalPattern.test(sentences[i])) {
4881
+ if (signalPattern.test(sentences[i]))
4863
4882
  kept.push(sentences[i]);
4864
- }
4865
4883
  }
4866
4884
  kept.push(sentences[sentences.length - 1]);
4867
4885
  let gist = kept.join(" ");
4868
4886
  const words = gist.split(/\s+/);
4869
4887
  const wordBudget = Math.max(5, Math.floor(tokenBudget * 0.75));
4870
- if (words.length > wordBudget) {
4871
- gist = words.slice(0, wordBudget).join(" ") + "\u2026";
4872
- }
4888
+ if (words.length > wordBudget)
4889
+ gist = words.slice(0, wordBudget).join(" ") + "...";
4873
4890
  return `[compressed] ${gist}`;
4874
4891
  }
4875
- /**
4876
- * Extract cue anchors (trigger phrases) from turn content.
4877
- * These serve as retrieval hooks in GraphRAG for finding compressed turns.
4878
- */
4892
+ /** Extract cue anchors (trigger phrases) from turn content. */
4879
4893
  extractCueAnchors(content) {
4880
4894
  const anchors = [];
4881
4895
  const lower = content.toLowerCase();
4882
4896
  const voPattern = /\b(create|fix|refactor|implement|add|remove|update|debug|test|deploy|configure)\s+(\w+(?:\s+\w+)?)\b/gi;
4883
4897
  let match;
4884
- while ((match = voPattern.exec(lower)) !== null) {
4898
+ while ((match = voPattern.exec(lower)) !== null)
4885
4899
  anchors.push(match[0].trim());
4886
- }
4887
4900
  const pathPattern = /[\w\-]+\.(?:ts|js|py|rs|go|java|tsx|jsx|json|yaml|toml)\b/gi;
4888
- while ((match = pathPattern.exec(content)) !== null) {
4901
+ while ((match = pathPattern.exec(content)) !== null)
4889
4902
  anchors.push(match[0]);
4890
- }
4891
4903
  return [...new Set(anchors)].slice(0, 5);
4892
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;
4917
+ }
4893
4918
  /** Classify epistemological source (Pramana) of a turn's content. */
4894
4919
  classifyPramana(content, calls) {
4895
- 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))
4896
4921
  return "pratyaksha";
4897
- }
4898
4922
  const lower = content.toLowerCase();
4899
4923
  if (/\b(?:maybe|possibly|might|perhaps|could be|not sure|unsure)\b/.test(lower))
4900
4924
  return "anupalabdhi";
@@ -5646,526 +5670,6 @@ var VidhiEngine = class {
5646
5670
  }
5647
5671
  };
5648
5672
 
5649
- // ../chitragupta/packages/smriti/dist/akasha-integration.js
5650
- var CREATE_TABLE_SQL = `
5651
- CREATE TABLE IF NOT EXISTS akasha_traces (
5652
- id TEXT PRIMARY KEY,
5653
- agent_id TEXT NOT NULL,
5654
- trace_type TEXT NOT NULL,
5655
- topic TEXT NOT NULL,
5656
- content TEXT NOT NULL,
5657
- strength REAL NOT NULL,
5658
- reinforcements INTEGER NOT NULL DEFAULT 0,
5659
- metadata TEXT,
5660
- created_at INTEGER NOT NULL,
5661
- last_reinforced_at INTEGER NOT NULL
5662
- );
5663
- CREATE INDEX IF NOT EXISTS idx_akasha_topic ON akasha_traces(topic);
5664
- CREATE INDEX IF NOT EXISTS idx_akasha_strength ON akasha_traces(strength DESC);
5665
- `;
5666
- var UPSERT_SQL = `
5667
- INSERT OR REPLACE INTO akasha_traces
5668
- (id, agent_id, trace_type, topic, content, strength,
5669
- reinforcements, metadata, created_at, last_reinforced_at)
5670
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
5671
- `;
5672
- var ENSURE_TABLE_SQL = `
5673
- CREATE TABLE IF NOT EXISTS akasha_traces (
5674
- id TEXT PRIMARY KEY,
5675
- agent_id TEXT NOT NULL,
5676
- trace_type TEXT NOT NULL,
5677
- topic TEXT NOT NULL,
5678
- content TEXT NOT NULL,
5679
- strength REAL NOT NULL,
5680
- reinforcements INTEGER NOT NULL DEFAULT 0,
5681
- metadata TEXT,
5682
- created_at INTEGER NOT NULL,
5683
- last_reinforced_at INTEGER NOT NULL
5684
- );
5685
- `;
5686
- function safeParseJson(raw) {
5687
- if (!raw)
5688
- return {};
5689
- try {
5690
- const parsed = JSON.parse(raw);
5691
- return typeof parsed === "object" && parsed !== null ? parsed : {};
5692
- } catch {
5693
- return {};
5694
- }
5695
- }
5696
- function persistTraces(traces, db) {
5697
- db.exec(CREATE_TABLE_SQL);
5698
- const upsert = db.prepare(UPSERT_SQL);
5699
- for (const trace of traces.values()) {
5700
- upsert.run(trace.id, trace.agentId, trace.traceType, trace.topic, trace.content, trace.strength, trace.reinforcements, JSON.stringify(trace.metadata), trace.createdAt, trace.lastReinforcedAt);
5701
- }
5702
- }
5703
- function restoreTraces(db, config) {
5704
- db.exec(ENSURE_TABLE_SQL);
5705
- const rows = db.prepare("SELECT * FROM akasha_traces").all();
5706
- const traces = /* @__PURE__ */ new Map();
5707
- const reinforcedBy = /* @__PURE__ */ new Map();
5708
- for (const row of rows) {
5709
- if (row.strength < config.minStrength)
5710
- continue;
5711
- const trace = {
5712
- id: row.id,
5713
- agentId: row.agent_id,
5714
- traceType: row.trace_type,
5715
- topic: row.topic,
5716
- content: row.content,
5717
- strength: row.strength,
5718
- reinforcements: row.reinforcements,
5719
- metadata: safeParseJson(row.metadata),
5720
- createdAt: row.created_at,
5721
- lastReinforcedAt: row.last_reinforced_at
5722
- };
5723
- traces.set(trace.id, trace);
5724
- reinforcedBy.set(trace.id, /* @__PURE__ */ new Set([trace.agentId]));
5725
- }
5726
- return { traces, reinforcedBy };
5727
- }
5728
- function tracesToGraphNodes(traces, minStrength) {
5729
- const nodes = [];
5730
- for (const trace of traces.values()) {
5731
- if (trace.strength < minStrength)
5732
- continue;
5733
- nodes.push({
5734
- id: trace.id,
5735
- label: `[${trace.traceType}] ${trace.topic}`,
5736
- content: trace.content,
5737
- type: "akasha",
5738
- weight: trace.strength
5739
- });
5740
- }
5741
- return nodes;
5742
- }
5743
- function boostResultsWithTraces(traces, config, results, query) {
5744
- const queryTokens = new Set(tokenize3(query));
5745
- const matchingTraces = [];
5746
- if (queryTokens.size > 0) {
5747
- for (const trace of traces.values()) {
5748
- if (trace.strength < config.minStrength)
5749
- continue;
5750
- const traceTokens = /* @__PURE__ */ new Set([
5751
- ...tokenize3(trace.topic),
5752
- ...tokenize3(trace.content)
5753
- ]);
5754
- const sim = jaccardSimilarity2(queryTokens, traceTokens);
5755
- if (sim > 0) {
5756
- matchingTraces.push({ trace, similarity: sim });
5757
- }
5758
- }
5759
- matchingTraces.sort((a, b) => b.similarity - a.similarity);
5760
- }
5761
- return results.map((result) => {
5762
- let traceBoost = 0;
5763
- if (queryTokens.size > 0 && matchingTraces.length > 0) {
5764
- const resultTokens = result.content ? new Set(tokenize3(result.content)) : /* @__PURE__ */ new Set();
5765
- let bestBoost = 0;
5766
- for (const { trace, similarity } of matchingTraces) {
5767
- if (result.id === trace.id) {
5768
- bestBoost = Math.max(bestBoost, trace.strength);
5769
- break;
5770
- }
5771
- if (resultTokens.size > 0) {
5772
- const traceTokens = /* @__PURE__ */ new Set([
5773
- ...tokenize3(trace.topic),
5774
- ...tokenize3(trace.content)
5775
- ]);
5776
- const resultSim = jaccardSimilarity2(resultTokens, traceTokens);
5777
- if (resultSim > 0.1) {
5778
- bestBoost = Math.max(bestBoost, similarity * trace.strength);
5779
- }
5780
- } else {
5781
- bestBoost = Math.max(bestBoost, similarity * trace.strength);
5782
- }
5783
- }
5784
- traceBoost = bestBoost * config.traceBoostFactor;
5785
- }
5786
- return {
5787
- ...result,
5788
- score: result.score * (1 + traceBoost),
5789
- traceBoost
5790
- };
5791
- });
5792
- }
5793
-
5794
- // ../chitragupta/packages/smriti/dist/akasha.js
5795
- var STOP_WORDS = /* @__PURE__ */ new Set([
5796
- "a",
5797
- "an",
5798
- "the",
5799
- "and",
5800
- "or",
5801
- "but",
5802
- "in",
5803
- "on",
5804
- "at",
5805
- "to",
5806
- "for",
5807
- "of",
5808
- "with",
5809
- "by",
5810
- "from",
5811
- "is",
5812
- "it",
5813
- "its",
5814
- "this",
5815
- "that",
5816
- "was",
5817
- "are",
5818
- "be",
5819
- "been",
5820
- "being",
5821
- "have",
5822
- "has",
5823
- "had",
5824
- "do",
5825
- "does",
5826
- "did",
5827
- "will",
5828
- "would",
5829
- "could",
5830
- "should",
5831
- "not",
5832
- "no",
5833
- "so",
5834
- "if",
5835
- "then",
5836
- "than",
5837
- "too",
5838
- "very",
5839
- "can",
5840
- "just",
5841
- "about",
5842
- "into",
5843
- "over",
5844
- "after"
5845
- ]);
5846
- var FNV_OFFSET6 = 2166136261;
5847
- var FNV_PRIME6 = 16777619;
5848
- function fnv1a7(input) {
5849
- let hash = FNV_OFFSET6;
5850
- for (let i = 0; i < input.length; i++) {
5851
- hash ^= input.charCodeAt(i);
5852
- hash = Math.imul(hash, FNV_PRIME6) >>> 0;
5853
- }
5854
- return hash.toString(16).padStart(8, "0");
5855
- }
5856
- function tokenize3(text) {
5857
- return text.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((t) => t.length >= 2 && !STOP_WORDS.has(t));
5858
- }
5859
- function jaccardSimilarity2(a, b) {
5860
- if (a.size === 0 && b.size === 0)
5861
- return 1;
5862
- let intersection = 0;
5863
- for (const token of a) {
5864
- if (b.has(token))
5865
- intersection++;
5866
- }
5867
- const union = a.size + b.size - intersection;
5868
- return union === 0 ? 0 : intersection / union;
5869
- }
5870
- var DAY_MS = 864e5;
5871
- var DEFAULT_CONFIG6 = {
5872
- decayHalfLife: 7 * DAY_MS,
5873
- minStrength: 0.01,
5874
- maxTraces: 5e3,
5875
- reinforcementBoost: 0.15,
5876
- initialStrength: 0.5,
5877
- topKRetrieval: 10,
5878
- traceBoostFactor: 0.3,
5879
- diminishingAlpha: 0.3,
5880
- frequencyDecayBeta: 0.5
5881
- };
5882
- var HARD_CEILINGS = {
5883
- maxTraces: 5e4,
5884
- minDecayHalfLife: 36e5,
5885
- maxContentSize: 1e4
5886
- };
5887
- var AkashaField = class {
5888
- config;
5889
- traces = /* @__PURE__ */ new Map();
5890
- /** Tracks which agents reinforced which traces (prevents self/duplicate). */
5891
- reinforcedBy = /* @__PURE__ */ new Map();
5892
- constructor(config) {
5893
- this.config = {
5894
- ...DEFAULT_CONFIG6,
5895
- ...config,
5896
- maxTraces: Math.min(config?.maxTraces ?? DEFAULT_CONFIG6.maxTraces, HARD_CEILINGS.maxTraces),
5897
- decayHalfLife: Math.max(config?.decayHalfLife ?? DEFAULT_CONFIG6.decayHalfLife, HARD_CEILINGS.minDecayHalfLife)
5898
- };
5899
- }
5900
- // ─── Leaving Traces ─────────────────────────────────────────────────
5901
- /**
5902
- * Agent leaves a stigmergic trace after solving or discovering something.
5903
- *
5904
- * @param agentId - Which agent is leaving this trace.
5905
- * @param type - The category of knowledge.
5906
- * @param topic - What the trace is about (used for matching).
5907
- * @param content - The actual knowledge or solution.
5908
- * @param metadata - Optional metadata for the trace.
5909
- * @returns The created StigmergicTrace.
5910
- */
5911
- leave(agentId, type, topic, content, metadata) {
5912
- const truncatedContent = content.length > HARD_CEILINGS.maxContentSize ? content.slice(0, HARD_CEILINGS.maxContentSize) : content;
5913
- const id = `aks-${fnv1a7(agentId + ":" + type + ":" + topic + ":" + truncatedContent)}`;
5914
- const now = Date.now();
5915
- const trace = {
5916
- id,
5917
- agentId,
5918
- traceType: type,
5919
- topic,
5920
- content: truncatedContent,
5921
- strength: this.config.initialStrength,
5922
- reinforcements: 0,
5923
- metadata: metadata ?? {},
5924
- createdAt: now,
5925
- lastReinforcedAt: now
5926
- };
5927
- this.traces.set(id, trace);
5928
- this.reinforcedBy.set(id, /* @__PURE__ */ new Set([agentId]));
5929
- if (this.traces.size > this.config.maxTraces)
5930
- this.evictWeakest();
5931
- return trace;
5932
- }
5933
- /**
5934
- * Reinforce an existing trace -- another agent found it useful.
5935
- *
5936
- * @param traceId - The trace to reinforce.
5937
- * @param agentId - The agent reinforcing it.
5938
- * @returns The updated trace, or null if not found / already reinforced.
5939
- */
5940
- reinforce(traceId, agentId) {
5941
- const trace = this.traces.get(traceId);
5942
- if (!trace)
5943
- return null;
5944
- const agents = this.reinforcedBy.get(traceId);
5945
- if (agents?.has(agentId))
5946
- return null;
5947
- const alpha = this.config.diminishingAlpha;
5948
- const effectiveBoost = this.config.reinforcementBoost / (1 + alpha * trace.reinforcements);
5949
- trace.strength = Math.min(1, trace.strength + effectiveBoost);
5950
- trace.reinforcements++;
5951
- trace.lastReinforcedAt = Date.now();
5952
- if (!agents) {
5953
- this.reinforcedBy.set(traceId, /* @__PURE__ */ new Set([agentId]));
5954
- } else {
5955
- agents.add(agentId);
5956
- }
5957
- return trace;
5958
- }
5959
- // ─── Following Traces ────────────────────────────────────────────────
5960
- /**
5961
- * Find relevant traces by Jaccard similarity on topic/content tokens.
5962
- *
5963
- * @param topic - The query to match against trace topics and content.
5964
- * @param opts - Optional filters: type, minStrength, limit.
5965
- * @returns Matching traces sorted by relevance score.
5966
- */
5967
- query(topic, opts) {
5968
- const queryTokens = new Set(tokenize3(topic));
5969
- if (queryTokens.size === 0)
5970
- return [];
5971
- const minStr = opts?.minStrength ?? this.config.minStrength;
5972
- const limit = opts?.limit ?? this.config.topKRetrieval;
5973
- const scored = [];
5974
- for (const trace of this.traces.values()) {
5975
- if (trace.strength < minStr)
5976
- continue;
5977
- if (opts?.type && trace.traceType !== opts.type)
5978
- continue;
5979
- const traceTokens = /* @__PURE__ */ new Set([...tokenize3(trace.topic), ...tokenize3(trace.content)]);
5980
- const similarity = jaccardSimilarity2(queryTokens, traceTokens);
5981
- if (similarity <= 0)
5982
- continue;
5983
- scored.push({ trace, score: similarity * trace.strength });
5984
- }
5985
- scored.sort((a, b) => b.score - a.score);
5986
- return scored.slice(0, limit).map((s) => s.trace);
5987
- }
5988
- /**
5989
- * Get the strongest traces overall -- the "highways" of collective knowledge.
5990
- *
5991
- * @param limit - Maximum number of traces to return.
5992
- * @returns Traces sorted by strength descending.
5993
- */
5994
- strongest(limit) {
5995
- const all = [...this.traces.values()];
5996
- all.sort((a, b) => b.strength - a.strength);
5997
- return all.slice(0, limit ?? this.config.topKRetrieval);
5998
- }
5999
- /**
6000
- * Get traces left by a specific agent.
6001
- *
6002
- * @param agentId - The agent whose traces to retrieve.
6003
- * @param limit - Maximum results.
6004
- * @returns Traces by the agent, sorted by creation time descending.
6005
- */
6006
- byAgent(agentId, limit) {
6007
- const results = [];
6008
- for (const trace of this.traces.values()) {
6009
- if (trace.agentId === agentId)
6010
- results.push(trace);
6011
- }
6012
- results.sort((a, b) => b.createdAt - a.createdAt);
6013
- return results.slice(0, limit ?? this.config.topKRetrieval);
6014
- }
6015
- // ─── Decay & Maintenance ─────────────────────────────────────────────
6016
- /**
6017
- * Apply temporal decay to all traces. Traces that fall below `minStrength`
6018
- * after decay are pruned automatically.
6019
- *
6020
- * @returns Counts of decayed and pruned traces.
6021
- */
6022
- decay() {
6023
- const now = Date.now();
6024
- const baseHalfLife = this.config.decayHalfLife;
6025
- const beta = this.config.frequencyDecayBeta;
6026
- let decayed = 0;
6027
- const toPrune = [];
6028
- for (const [id, trace] of this.traces) {
6029
- const elapsed = now - trace.lastReinforcedAt;
6030
- if (elapsed <= 0)
6031
- continue;
6032
- const effectiveHalfLife = baseHalfLife * (1 + beta * Math.log(1 + trace.reinforcements));
6033
- const factor = Math.exp(-Math.LN2 * elapsed / effectiveHalfLife);
6034
- const newStrength = trace.strength * factor;
6035
- if (Math.abs(newStrength - trace.strength) > 1e-10) {
6036
- trace.strength = newStrength;
6037
- decayed++;
6038
- }
6039
- if (trace.strength < this.config.minStrength)
6040
- toPrune.push(id);
6041
- }
6042
- for (const id of toPrune) {
6043
- this.traces.delete(id);
6044
- this.reinforcedBy.delete(id);
6045
- }
6046
- return { decayed, pruned: toPrune.length };
6047
- }
6048
- /**
6049
- * Remove traces below the minStrength threshold.
6050
- *
6051
- * @returns The number of traces pruned.
6052
- */
6053
- prune() {
6054
- const toPrune = [];
6055
- for (const [id, trace] of this.traces) {
6056
- if (trace.strength < this.config.minStrength)
6057
- toPrune.push(id);
6058
- }
6059
- for (const id of toPrune) {
6060
- this.traces.delete(id);
6061
- this.reinforcedBy.delete(id);
6062
- }
6063
- return toPrune.length;
6064
- }
6065
- // ─── Persistence (delegated to akasha-integration) ───────────────────
6066
- /**
6067
- * Persist all traces to a SQLite database.
6068
- *
6069
- * @param db - A duck-typed database handle with prepare/exec methods.
6070
- */
6071
- persist(db) {
6072
- persistTraces(this.traces, db);
6073
- }
6074
- /**
6075
- * Restore traces from a SQLite database.
6076
- *
6077
- * @param db - A duck-typed database handle with prepare/exec methods.
6078
- */
6079
- restore(db) {
6080
- const result = restoreTraces(db, this.config);
6081
- this.traces.clear();
6082
- this.reinforcedBy.clear();
6083
- for (const [k, v] of result.traces)
6084
- this.traces.set(k, v);
6085
- for (const [k, v] of result.reinforcedBy)
6086
- this.reinforcedBy.set(k, v);
6087
- }
6088
- // ─── GraphRAG (delegated to akasha-integration) ──────────────────────
6089
- /**
6090
- * Register traces as graph nodes suitable for GraphRAG retrieval.
6091
- *
6092
- * @returns An array of graph-compatible node objects.
6093
- */
6094
- toGraphNodes() {
6095
- return tracesToGraphNodes(this.traces, this.config.minStrength);
6096
- }
6097
- /**
6098
- * Boost graph search results that have matching stigmergic traces.
6099
- *
6100
- * @param results - The original search results with id and score.
6101
- * @param query - The search query used for topic matching.
6102
- * @returns Results with boosted scores and traceBoost metadata.
6103
- */
6104
- boostResults(results, query) {
6105
- return boostResultsWithTraces(this.traces, this.config, results, query);
6106
- }
6107
- // ─── Stats ───────────────────────────────────────────────────────────
6108
- /**
6109
- * Return statistics about the current state of the Akasha field.
6110
- *
6111
- * @returns Total/active counts, per-type breakdown, average strength,
6112
- * strongest topic, and total reinforcements.
6113
- */
6114
- stats() {
6115
- const byType = {
6116
- solution: 0,
6117
- warning: 0,
6118
- shortcut: 0,
6119
- pattern: 0,
6120
- correction: 0,
6121
- preference: 0
6122
- };
6123
- let totalStrength = 0;
6124
- let activeCount = 0;
6125
- let totalReinforcements = 0;
6126
- let strongestTrace = null;
6127
- for (const trace of this.traces.values()) {
6128
- byType[trace.traceType]++;
6129
- totalStrength += trace.strength;
6130
- totalReinforcements += trace.reinforcements;
6131
- if (trace.strength >= this.config.minStrength)
6132
- activeCount++;
6133
- if (!strongestTrace || trace.strength > strongestTrace.strength) {
6134
- strongestTrace = trace;
6135
- }
6136
- }
6137
- return {
6138
- totalTraces: this.traces.size,
6139
- activeTraces: activeCount,
6140
- byType,
6141
- avgStrength: this.traces.size > 0 ? totalStrength / this.traces.size : 0,
6142
- strongestTopic: strongestTrace?.topic ?? null,
6143
- totalReinforcements
6144
- };
6145
- }
6146
- // ─── Internal Helpers ────────────────────────────────────────────────
6147
- /** Evict the weakest trace. Ties broken by oldest createdAt. */
6148
- evictWeakest() {
6149
- let weakestId = null;
6150
- let weakestStrength = Infinity;
6151
- let weakestCreatedAt = Infinity;
6152
- for (const [id, trace] of this.traces) {
6153
- if (trace.strength < weakestStrength || trace.strength === weakestStrength && trace.createdAt < weakestCreatedAt) {
6154
- weakestId = id;
6155
- weakestStrength = trace.strength;
6156
- weakestCreatedAt = trace.createdAt;
6157
- }
6158
- }
6159
- if (!weakestId && this.traces.size > 0) {
6160
- weakestId = this.traces.keys().next().value;
6161
- }
6162
- if (weakestId) {
6163
- this.traces.delete(weakestId);
6164
- this.reinforcedBy.delete(weakestId);
6165
- }
6166
- }
6167
- };
6168
-
6169
5673
  // ../chitragupta/packages/smriti/dist/temporal-context.js
6170
5674
  var MINUTE = 6e4;
6171
5675
  var HOUR = 36e5;
@@ -6195,7 +5699,7 @@ var DEFAULT_SCALE_WEIGHTS = {
6195
5699
  quarter: 0.08,
6196
5700
  year: 0.07
6197
5701
  };
6198
- var HARD_CEILINGS2 = {
5702
+ var HARD_CEILINGS = {
6199
5703
  /** Minimum half-life: 1 second. Anything faster is meaningless. */
6200
5704
  minDecayRate: 1e3,
6201
5705
  /** Maximum half-life: 10 years. Beyond this, nothing decays. */
@@ -6380,14 +5884,14 @@ var KalaChakra = class {
6380
5884
  if (config?.decayRates) {
6381
5885
  for (const scale of TEMPORAL_SCALES) {
6382
5886
  if (config.decayRates[scale] !== void 0) {
6383
- this._decayRates[scale] = clamp(config.decayRates[scale], HARD_CEILINGS2.minDecayRate, HARD_CEILINGS2.maxDecayRate);
5887
+ this._decayRates[scale] = clamp(config.decayRates[scale], HARD_CEILINGS.minDecayRate, HARD_CEILINGS.maxDecayRate);
6384
5888
  }
6385
5889
  }
6386
5890
  }
6387
5891
  if (config?.scaleWeights) {
6388
5892
  for (const scale of TEMPORAL_SCALES) {
6389
5893
  if (config.scaleWeights[scale] !== void 0) {
6390
- this._scaleWeights[scale] = clamp(config.scaleWeights[scale], HARD_CEILINGS2.minWeight, HARD_CEILINGS2.maxWeight);
5894
+ this._scaleWeights[scale] = clamp(config.scaleWeights[scale], HARD_CEILINGS.minWeight, HARD_CEILINGS.maxWeight);
6391
5895
  }
6392
5896
  }
6393
5897
  }
@@ -6530,14 +6034,14 @@ var KalaChakra = class {
6530
6034
  if (data.decayRates && typeof data.decayRates === "object") {
6531
6035
  for (const scale of TEMPORAL_SCALES) {
6532
6036
  if (typeof data.decayRates[scale] === "number") {
6533
- this._decayRates[scale] = clamp(data.decayRates[scale], HARD_CEILINGS2.minDecayRate, HARD_CEILINGS2.maxDecayRate);
6037
+ this._decayRates[scale] = clamp(data.decayRates[scale], HARD_CEILINGS.minDecayRate, HARD_CEILINGS.maxDecayRate);
6534
6038
  }
6535
6039
  }
6536
6040
  }
6537
6041
  if (data.scaleWeights && typeof data.scaleWeights === "object") {
6538
6042
  for (const scale of TEMPORAL_SCALES) {
6539
6043
  if (typeof data.scaleWeights[scale] === "number") {
6540
- this._scaleWeights[scale] = clamp(data.scaleWeights[scale], HARD_CEILINGS2.minWeight, HARD_CEILINGS2.maxWeight);
6044
+ this._scaleWeights[scale] = clamp(data.scaleWeights[scale], HARD_CEILINGS.minWeight, HARD_CEILINGS.maxWeight);
6541
6045
  }
6542
6046
  }
6543
6047
  }
@@ -6565,13 +6069,13 @@ function clamp(value, min, max) {
6565
6069
  }
6566
6070
 
6567
6071
  // ../chitragupta/packages/smriti/dist/pancha-vritti-patterns.js
6568
- var FNV_OFFSET7 = 2166136261;
6569
- var FNV_PRIME7 = 16777619;
6570
- function fnv1a8(input) {
6571
- let hash = FNV_OFFSET7;
6072
+ var FNV_OFFSET6 = 2166136261;
6073
+ var FNV_PRIME6 = 16777619;
6074
+ function fnv1a7(input) {
6075
+ let hash = FNV_OFFSET6;
6572
6076
  for (let i = 0; i < input.length; i++) {
6573
6077
  hash ^= input.charCodeAt(i);
6574
- hash = Math.imul(hash, FNV_PRIME7);
6078
+ hash = Math.imul(hash, FNV_PRIME6);
6575
6079
  }
6576
6080
  return (hash >>> 0).toString(16).padStart(8, "0");
6577
6081
  }
@@ -6712,13 +6216,13 @@ var VRITTI_CONFIDENCE_WEIGHTS = {
6712
6216
  vikalpa: 0.5,
6713
6217
  viparyaya: 0.3
6714
6218
  };
6715
- var DEFAULT_CONFIG7 = {
6219
+ var DEFAULT_CONFIG6 = {
6716
6220
  maxClassifications: 5e3,
6717
6221
  minConfidence: 0.4,
6718
6222
  snippetMaxLength: 200,
6719
6223
  confidenceWeights: { ...VRITTI_CONFIDENCE_WEIGHTS }
6720
6224
  };
6721
- var HARD_CEILINGS3 = {
6225
+ var HARD_CEILINGS2 = {
6722
6226
  maxClassifications: 5e4,
6723
6227
  snippetMaxLength: 1e3
6724
6228
  };
@@ -6729,18 +6233,18 @@ var PanchaVritti = class {
6729
6233
  totalReclassified = 0;
6730
6234
  constructor(config) {
6731
6235
  const merged = {
6732
- ...DEFAULT_CONFIG7,
6236
+ ...DEFAULT_CONFIG6,
6733
6237
  ...config,
6734
6238
  confidenceWeights: {
6735
- ...DEFAULT_CONFIG7.confidenceWeights,
6239
+ ...DEFAULT_CONFIG6.confidenceWeights,
6736
6240
  ...config?.confidenceWeights
6737
6241
  }
6738
6242
  };
6739
- if (typeof HARD_CEILINGS3.maxClassifications === "number") {
6740
- merged.maxClassifications = Math.min(merged.maxClassifications, HARD_CEILINGS3.maxClassifications);
6243
+ if (typeof HARD_CEILINGS2.maxClassifications === "number") {
6244
+ merged.maxClassifications = Math.min(merged.maxClassifications, HARD_CEILINGS2.maxClassifications);
6741
6245
  }
6742
- if (typeof HARD_CEILINGS3.snippetMaxLength === "number") {
6743
- merged.snippetMaxLength = Math.min(merged.snippetMaxLength, HARD_CEILINGS3.snippetMaxLength);
6246
+ if (typeof HARD_CEILINGS2.snippetMaxLength === "number") {
6247
+ merged.snippetMaxLength = Math.min(merged.snippetMaxLength, HARD_CEILINGS2.snippetMaxLength);
6744
6248
  }
6745
6249
  this.cfg = merged;
6746
6250
  }
@@ -6769,7 +6273,7 @@ var PanchaVritti = class {
6769
6273
  prePatterns.push("context:error-flag");
6770
6274
  }
6771
6275
  if (content.trim().length === 0) {
6772
- const id2 = fnv1a8("nidra:" + now.toString());
6276
+ const id2 = fnv1a7("nidra:" + now.toString());
6773
6277
  const classification2 = {
6774
6278
  id: id2,
6775
6279
  type: "nidra",
@@ -6793,7 +6297,7 @@ var PanchaVritti = class {
6793
6297
  if (winnerConfidence < this.cfg.minConfidence) {
6794
6298
  allPatterns.push("low-confidence");
6795
6299
  }
6796
- const id = fnv1a8(winnerType + ":" + content.slice(0, 100) + ":" + now.toString());
6300
+ const id = fnv1a7(winnerType + ":" + content.slice(0, 100) + ":" + now.toString());
6797
6301
  const classification = {
6798
6302
  id,
6799
6303
  type: winnerType,
@@ -6977,12 +6481,13 @@ var PanchaVritti = class {
6977
6481
  async function recall(query, options) {
6978
6482
  const limit = options?.limit ?? 5;
6979
6483
  const answers = [];
6980
- const [hybridResults, turnFallbackResults, memoryResults, dayFileResults] = await Promise.allSettled([
6484
+ const [hybridResults, turnFallbackResults, memoryResults, dayFileResults, akashaResults] = await Promise.allSettled([
6981
6485
  searchHybrid(query, options?.project, limit),
6982
6486
  // FTS5 fallback runs in parallel — used only if hybrid fails
6983
6487
  searchTurns(query, options?.project),
6984
6488
  options?.includeMemory !== false ? searchMemoryLayer(query) : Promise.resolve([]),
6985
- 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([])
6986
6491
  ]);
6987
6492
  let usedHybrid = false;
6988
6493
  if (hybridResults.status === "fulfilled" && hybridResults.value.length > 0) {
@@ -7015,22 +6520,27 @@ async function recall(query, options) {
7015
6520
  answers.push(result);
7016
6521
  }
7017
6522
  }
6523
+ if (akashaResults.status === "fulfilled") {
6524
+ for (const result of akashaResults.value.slice(0, limit)) {
6525
+ answers.push(result);
6526
+ }
6527
+ }
7018
6528
  const ranked = deduplicateAnswers(answers);
7019
6529
  ranked.sort((a, b) => b.score - a.score);
7020
6530
  return ranked.slice(0, limit);
7021
6531
  }
7022
6532
  async function searchHybrid(query, project, limit) {
7023
6533
  try {
7024
- const { HybridSearchEngine: HybridSearchEngine2 } = await import("./hybrid-search-BYTXCOXP.js");
6534
+ const { HybridSearchEngine: HybridSearchEngine2 } = await import("./hybrid-search-OD756RDV.js");
7025
6535
  let recallEngine = null;
7026
6536
  let graphEngine = null;
7027
6537
  try {
7028
- const { RecallEngine: RecallEngine2 } = await import("./recall-LNRQVATQ.js");
6538
+ const { RecallEngine: RecallEngine2 } = await import("./recall-64RROTUC.js");
7029
6539
  recallEngine = new RecallEngine2();
7030
6540
  } catch {
7031
6541
  }
7032
6542
  try {
7033
- const { GraphRAGEngine: GraphRAGEngine2 } = await import("./graphrag-T2QWNX57.js");
6543
+ const { GraphRAGEngine: GraphRAGEngine2 } = await import("./graphrag-73XA7LBX.js");
7034
6544
  graphEngine = new GraphRAGEngine2();
7035
6545
  } catch {
7036
6546
  }
@@ -7066,8 +6576,8 @@ async function searchHybrid(query, project, limit) {
7066
6576
  }
7067
6577
  async function searchTurns(query, project) {
7068
6578
  try {
7069
- const { searchSessions: searchSessions2 } = await import("./search-BIODUW2P.js");
7070
- const { loadSession: loadSession2 } = await import("./session-store-O3TS7DUY.js");
6579
+ const { searchSessions: searchSessions2 } = await import("./search-JVCDNTAJ.js");
6580
+ const { loadSession: loadSession2 } = await import("./session-store-3EDQZEDS.js");
7071
6581
  const metas = searchSessions2(query, project);
7072
6582
  const results = [];
7073
6583
  for (const meta of metas.slice(0, 10)) {
@@ -7114,9 +6624,9 @@ async function searchTurns(query, project) {
7114
6624
  }
7115
6625
  async function searchMemoryLayer(query) {
7116
6626
  try {
7117
- const { searchMemory: searchMemory2 } = await import("./search-BIODUW2P.js");
6627
+ const { searchMemory: searchMemory2 } = await import("./search-JVCDNTAJ.js");
7118
6628
  const results = searchMemory2(query);
7119
- return results.slice(0, 5).map((r) => ({
6629
+ return results.slice(0, 5).filter((r) => !isLowValueMemoryEntry(r.content)).map((r) => ({
7120
6630
  score: Math.min((r.relevance ?? 0.5) + 0.1, 1),
7121
6631
  answer: `From memory: ${r.content.slice(0, 300)}`,
7122
6632
  primarySource: "memory",
@@ -7126,9 +6636,20 @@ async function searchMemoryLayer(query) {
7126
6636
  return [];
7127
6637
  }
7128
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
+ }
7129
6650
  async function searchDayFileLayer(query, limit) {
7130
6651
  try {
7131
- const { hierarchicalTemporalSearch: hierarchicalTemporalSearch2 } = await import("./hierarchical-temporal-search-U6DG74IR.js");
6652
+ const { hierarchicalTemporalSearch: hierarchicalTemporalSearch2 } = await import("./hierarchical-temporal-search-GHKVKNZ6.js");
7132
6653
  const results = await hierarchicalTemporalSearch2(query, { limit });
7133
6654
  if (results.length > 0) {
7134
6655
  return results.map((r) => ({
@@ -7143,7 +6664,7 @@ async function searchDayFileLayer(query, limit) {
7143
6664
  } catch {
7144
6665
  }
7145
6666
  try {
7146
- const { searchDayFiles: searchDayFiles2 } = await import("./day-consolidation-HMHSXIOM.js");
6667
+ const { searchDayFiles: searchDayFiles2 } = await import("./day-consolidation-CR3TJFAL.js");
7147
6668
  const results = searchDayFiles2(query, { limit });
7148
6669
  return results.map((r) => ({
7149
6670
  score: 0.5,
@@ -7156,6 +6677,38 @@ async function searchDayFileLayer(query, limit) {
7156
6677
  return [];
7157
6678
  }
7158
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
+ }
7159
6712
  function deduplicateAnswers(answers) {
7160
6713
  const seen = /* @__PURE__ */ new Set();
7161
6714
  return answers.filter((a) => {
@@ -7175,7 +6728,7 @@ async function loadProviderContext(project, options) {
7175
6728
  let projectMemory = "";
7176
6729
  let recentContext = "";
7177
6730
  try {
7178
- const { getMemory: getMemory2 } = await import("./memory-store-LEERUQGL.js");
6731
+ const { getMemory: getMemory2 } = await import("./memory-store-4GCBR2DZ.js");
7179
6732
  globalFacts = getMemory2({ type: "global" });
7180
6733
  if (globalFacts.length > maxLen / 3) {
7181
6734
  globalFacts = globalFacts.slice(0, maxLen / 3) + "\n...(truncated)";
@@ -7184,7 +6737,7 @@ async function loadProviderContext(project, options) {
7184
6737
  }
7185
6738
  if (project) {
7186
6739
  try {
7187
- const { getMemory: getMemory2 } = await import("./memory-store-LEERUQGL.js");
6740
+ const { getMemory: getMemory2 } = await import("./memory-store-4GCBR2DZ.js");
7188
6741
  projectMemory = getMemory2({ type: "project", path: project });
7189
6742
  if (projectMemory.length > maxLen / 3) {
7190
6743
  projectMemory = projectMemory.slice(0, maxLen / 3) + "\n...(truncated)";
@@ -7194,7 +6747,7 @@ async function loadProviderContext(project, options) {
7194
6747
  }
7195
6748
  let vasanaContext = "";
7196
6749
  try {
7197
- const { VasanaEngine: VasanaEngine2 } = await import("./vasana-engine-BJFHJVGM.js");
6750
+ const { VasanaEngine: VasanaEngine2 } = await import("./vasana-engine-W4PYWT5H.js");
7198
6751
  const engine = new VasanaEngine2();
7199
6752
  const vasanas = engine.getVasanas(project ?? "__global__", 5);
7200
6753
  if (vasanas.length > 0) {
@@ -7203,7 +6756,7 @@ async function loadProviderContext(project, options) {
7203
6756
  } catch {
7204
6757
  }
7205
6758
  try {
7206
- const { listSessions: listSessions2, loadSession: loadSession2 } = await import("./session-store-O3TS7DUY.js");
6759
+ const { listSessions: listSessions2, loadSession: loadSession2 } = await import("./session-store-3EDQZEDS.js");
7207
6760
  const sessions = project ? listSessions2(project).slice(0, recentLimit) : listSessions2().slice(0, recentLimit);
7208
6761
  const summaries = [];
7209
6762
  for (const meta of sessions) {
@@ -7251,6 +6804,595 @@ async function loadProviderContext(project, options) {
7251
6804
  };
7252
6805
  }
7253
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
+
7254
7396
  export {
7255
7397
  exportSessionToJson,
7256
7398
  exportSessionToMarkdown,
@@ -7286,13 +7428,14 @@ export {
7286
7428
  IdentityContext,
7287
7429
  SvapnaConsolidation,
7288
7430
  VidhiEngine,
7289
- AkashaField,
7290
7431
  TEMPORAL_SCALES,
7291
7432
  KalaChakra,
7292
7433
  VRITTI_TYPES,
7293
7434
  VRITTI_CONFIDENCE_WEIGHTS,
7294
7435
  PanchaVritti,
7295
7436
  recall,
7296
- loadProviderContext
7437
+ loadProviderContext,
7438
+ CritiqueStore,
7439
+ OrchestratorCheckpoint
7297
7440
  };
7298
- //# sourceMappingURL=chunk-VCUJES75.js.map
7441
+ //# sourceMappingURL=chunk-TSOQ2CT3.js.map