@miller-tech/uap 1.8.1 → 1.10.0

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 (202) hide show
  1. package/README.md +285 -642
  2. package/config/chat_template.jinja +76 -0
  3. package/config/lora-finetune.yaml +82 -0
  4. package/config/model-profiles/claude-haiku-3.5.json +62 -0
  5. package/config/model-profiles/claude-opus-4.6.json +63 -0
  6. package/config/model-profiles/claude-sonnet-4.6.json +63 -0
  7. package/config/model-profiles/gemini-2.5-flash.json +62 -0
  8. package/config/model-profiles/gemini-2.5-pro.json +62 -0
  9. package/config/model-profiles/generic.json +54 -0
  10. package/config/model-profiles/glm-5.json +61 -0
  11. package/config/model-profiles/gpt-4.1.json +64 -0
  12. package/config/model-profiles/gpt-4o.json +64 -0
  13. package/config/model-profiles/gpt-o3.json +61 -0
  14. package/config/model-profiles/kimi-k2.5.json +70 -0
  15. package/config/model-profiles/llama.json +86 -0
  16. package/config/model-profiles/qwen35.json +218 -0
  17. package/dist/.tsbuildinfo +1 -1
  18. package/dist/bin/cli.js +78 -9
  19. package/dist/bin/cli.js.map +1 -1
  20. package/dist/bin/llama-server-optimize.js +0 -10
  21. package/dist/bin/llama-server-optimize.js.map +1 -1
  22. package/dist/bin/policy.js +11 -195
  23. package/dist/bin/policy.js.map +1 -1
  24. package/dist/cli/dashboard.d.ts.map +1 -1
  25. package/dist/cli/dashboard.js +14 -14
  26. package/dist/cli/dashboard.js.map +1 -1
  27. package/dist/cli/generate.d.ts +0 -7
  28. package/dist/cli/generate.d.ts.map +1 -1
  29. package/dist/cli/generate.js +10 -22
  30. package/dist/cli/generate.js.map +1 -1
  31. package/dist/cli/hooks.d.ts +1 -1
  32. package/dist/cli/hooks.d.ts.map +1 -1
  33. package/dist/cli/hooks.js +371 -0
  34. package/dist/cli/hooks.js.map +1 -1
  35. package/dist/cli/init.d.ts.map +1 -1
  36. package/dist/cli/init.js +120 -3
  37. package/dist/cli/init.js.map +1 -1
  38. package/dist/cli/memory.d.ts.map +1 -1
  39. package/dist/cli/memory.js +43 -109
  40. package/dist/cli/memory.js.map +1 -1
  41. package/dist/cli/model.d.ts.map +1 -1
  42. package/dist/cli/model.js +8 -25
  43. package/dist/cli/model.js.map +1 -1
  44. package/dist/cli/patterns.d.ts.map +1 -1
  45. package/dist/cli/patterns.js +11 -9
  46. package/dist/cli/patterns.js.map +1 -1
  47. package/dist/cli/policy.d.ts.map +1 -1
  48. package/dist/cli/policy.js +165 -1
  49. package/dist/cli/policy.js.map +1 -1
  50. package/dist/cli/rtk-validation.d.ts +0 -4
  51. package/dist/cli/rtk-validation.d.ts.map +1 -1
  52. package/dist/cli/rtk-validation.js +5 -23
  53. package/dist/cli/rtk-validation.js.map +1 -1
  54. package/dist/cli/schema-diff.d.ts.map +1 -1
  55. package/dist/cli/schema-diff.js +25 -16
  56. package/dist/cli/schema-diff.js.map +1 -1
  57. package/dist/cli/setup-wizard.d.ts.map +1 -1
  58. package/dist/cli/setup-wizard.js +13 -9
  59. package/dist/cli/setup-wizard.js.map +1 -1
  60. package/dist/cli/setup.d.ts.map +1 -1
  61. package/dist/cli/setup.js +3 -4
  62. package/dist/cli/setup.js.map +1 -1
  63. package/dist/cli/visualize.d.ts +6 -13
  64. package/dist/cli/visualize.d.ts.map +1 -1
  65. package/dist/cli/visualize.js +35 -64
  66. package/dist/cli/visualize.js.map +1 -1
  67. package/dist/cli/worktree.d.ts.map +1 -1
  68. package/dist/cli/worktree.js +12 -13
  69. package/dist/cli/worktree.js.map +1 -1
  70. package/dist/coordination/adaptive-patterns.d.ts.map +1 -1
  71. package/dist/coordination/adaptive-patterns.js +7 -3
  72. package/dist/coordination/adaptive-patterns.js.map +1 -1
  73. package/dist/coordination/deploy-batcher.d.ts.map +1 -1
  74. package/dist/coordination/deploy-batcher.js +8 -8
  75. package/dist/coordination/deploy-batcher.js.map +1 -1
  76. package/dist/dashboard/data-service.d.ts.map +1 -1
  77. package/dist/dashboard/data-service.js +12 -13
  78. package/dist/dashboard/data-service.js.map +1 -1
  79. package/dist/dashboard/server.d.ts.map +1 -1
  80. package/dist/dashboard/server.js +23 -8
  81. package/dist/dashboard/server.js.map +1 -1
  82. package/dist/index.d.ts +4 -4
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +3 -3
  85. package/dist/index.js.map +1 -1
  86. package/dist/mcp-router/executor/client.d.ts +0 -6
  87. package/dist/mcp-router/executor/client.d.ts.map +1 -1
  88. package/dist/mcp-router/executor/client.js +1 -27
  89. package/dist/mcp-router/executor/client.js.map +1 -1
  90. package/dist/mcp-router/index.d.ts +1 -1
  91. package/dist/mcp-router/index.d.ts.map +1 -1
  92. package/dist/mcp-router/index.js.map +1 -1
  93. package/dist/mcp-router/output-compressor.js +114 -112
  94. package/dist/mcp-router/output-compressor.js.map +1 -1
  95. package/dist/mcp-router/types.d.ts +0 -5
  96. package/dist/mcp-router/types.d.ts.map +1 -1
  97. package/dist/memory/backends/github.d.ts.map +1 -1
  98. package/dist/memory/backends/github.js +21 -13
  99. package/dist/memory/backends/github.js.map +1 -1
  100. package/dist/memory/context-pruner.d.ts +2 -9
  101. package/dist/memory/context-pruner.d.ts.map +1 -1
  102. package/dist/memory/context-pruner.js +5 -22
  103. package/dist/memory/context-pruner.js.map +1 -1
  104. package/dist/memory/correction-propagator.d.ts.map +1 -1
  105. package/dist/memory/correction-propagator.js +19 -19
  106. package/dist/memory/correction-propagator.js.map +1 -1
  107. package/dist/memory/dynamic-retrieval.d.ts.map +1 -1
  108. package/dist/memory/dynamic-retrieval.js +263 -132
  109. package/dist/memory/dynamic-retrieval.js.map +1 -1
  110. package/dist/memory/embeddings.d.ts.map +1 -1
  111. package/dist/memory/embeddings.js +2 -15
  112. package/dist/memory/embeddings.js.map +1 -1
  113. package/dist/memory/hierarchical-memory.d.ts.map +1 -1
  114. package/dist/memory/hierarchical-memory.js +6 -0
  115. package/dist/memory/hierarchical-memory.js.map +1 -1
  116. package/dist/memory/knowledge-graph.d.ts.map +1 -1
  117. package/dist/memory/knowledge-graph.js +2 -1
  118. package/dist/memory/knowledge-graph.js.map +1 -1
  119. package/dist/memory/memory-consolidator.d.ts +1 -0
  120. package/dist/memory/memory-consolidator.d.ts.map +1 -1
  121. package/dist/memory/memory-consolidator.js +27 -3
  122. package/dist/memory/memory-consolidator.js.map +1 -1
  123. package/dist/memory/predictive-memory.d.ts +9 -1
  124. package/dist/memory/predictive-memory.d.ts.map +1 -1
  125. package/dist/memory/predictive-memory.js +77 -1
  126. package/dist/memory/predictive-memory.js.map +1 -1
  127. package/dist/memory/serverless-qdrant.d.ts +1 -0
  128. package/dist/memory/serverless-qdrant.d.ts.map +1 -1
  129. package/dist/memory/serverless-qdrant.js +3 -9
  130. package/dist/memory/serverless-qdrant.js.map +1 -1
  131. package/dist/memory/short-term/schema.d.ts.map +1 -1
  132. package/dist/memory/short-term/schema.js +44 -6
  133. package/dist/memory/short-term/schema.js.map +1 -1
  134. package/dist/memory/short-term/sqlite.d.ts +4 -3
  135. package/dist/memory/short-term/sqlite.d.ts.map +1 -1
  136. package/dist/memory/short-term/sqlite.js +3 -12
  137. package/dist/memory/short-term/sqlite.js.map +1 -1
  138. package/dist/memory/speculative-cache.js +2 -2
  139. package/dist/memory/speculative-cache.js.map +1 -1
  140. package/dist/models/executor.d.ts +21 -0
  141. package/dist/models/executor.d.ts.map +1 -1
  142. package/dist/models/executor.js +116 -4
  143. package/dist/models/executor.js.map +1 -1
  144. package/dist/models/planner.d.ts +1 -0
  145. package/dist/models/planner.d.ts.map +1 -1
  146. package/dist/models/planner.js +13 -1
  147. package/dist/models/planner.js.map +1 -1
  148. package/dist/policies/enforced-tool-router.d.ts +3 -1
  149. package/dist/policies/enforced-tool-router.d.ts.map +1 -1
  150. package/dist/policies/enforced-tool-router.js.map +1 -1
  151. package/dist/tasks/service.d.ts +1 -0
  152. package/dist/tasks/service.d.ts.map +1 -1
  153. package/dist/tasks/service.js +10 -6
  154. package/dist/tasks/service.js.map +1 -1
  155. package/dist/telemetry/session-telemetry.d.ts.map +1 -1
  156. package/dist/telemetry/session-telemetry.js +73 -17
  157. package/dist/telemetry/session-telemetry.js.map +1 -1
  158. package/dist/types/config.d.ts +377 -263
  159. package/dist/types/config.d.ts.map +1 -1
  160. package/dist/types/config.js +13 -67
  161. package/dist/types/config.js.map +1 -1
  162. package/dist/utils/config-loader.d.ts +34 -0
  163. package/dist/utils/config-loader.d.ts.map +1 -0
  164. package/dist/utils/config-loader.js +93 -0
  165. package/dist/utils/config-loader.js.map +1 -0
  166. package/dist/utils/lazy-imports.d.ts +18 -0
  167. package/dist/utils/lazy-imports.d.ts.map +1 -0
  168. package/dist/utils/lazy-imports.js +39 -0
  169. package/dist/utils/lazy-imports.js.map +1 -0
  170. package/dist/utils/stopwords.d.ts +12 -0
  171. package/dist/utils/stopwords.d.ts.map +1 -0
  172. package/dist/utils/stopwords.js +196 -0
  173. package/dist/utils/stopwords.js.map +1 -0
  174. package/dist/utils/string-similarity.d.ts +10 -3
  175. package/dist/utils/string-similarity.d.ts.map +1 -1
  176. package/dist/utils/string-similarity.js +49 -25
  177. package/dist/utils/string-similarity.js.map +1 -1
  178. package/docs/INDEX.md +35 -34
  179. package/package.json +13 -14
  180. package/scripts/maintenance/publish-npm.sh +82 -0
  181. package/scripts/maintenance/publish.sh +29 -0
  182. package/scripts/maintenance/update-droids.py +93 -0
  183. package/scripts/maintenance/update-skills.py +148 -0
  184. package/scripts/maintenance/update-uap-compliance.sh +45 -0
  185. package/scripts/maintenance/validate-skills.py +83 -0
  186. package/scripts/maintenance/verify-compliance.sh +117 -0
  187. package/scripts/setup/install-cloakbrowser.ts +14 -0
  188. package/scripts/setup/install-desktop.sh +105 -0
  189. package/scripts/setup/install-rtk.sh +184 -0
  190. package/scripts/setup/install-web.sh +73 -0
  191. package/scripts/setup/setup.sh +375 -0
  192. package/scripts/validate-build.sh +62 -0
  193. package/scripts/version-bump.sh +130 -0
  194. package/tools/agents/scripts/migrate_memory_to_qdrant.py +1 -1
  195. /package/docs/{BENCHMARK_GAPS_AND_PLAN.md → archive/BENCHMARK_GAPS_AND_PLAN.md} +0 -0
  196. /package/docs/{MODEL_ROUTING_IMPLEMENTATION_SUMMARY.md → archive/MODEL_ROUTING_IMPLEMENTATION_SUMMARY.md} +0 -0
  197. /package/docs/{MODEL_ROUTING_OPTIMIZATION_PLAN.md → archive/MODEL_ROUTING_OPTIMIZATION_PLAN.md} +0 -0
  198. /package/docs/{PARALLELISM_GAPS_AND_OPTIONS.md → archive/PARALLELISM_GAPS_AND_OPTIONS.md} +0 -0
  199. /package/docs/{POLICY_GATE_IMPLEMENTATION.md → archive/POLICY_GATE_IMPLEMENTATION.md} +0 -0
  200. /package/docs/{UAP_OPTIMIZATION_PLAN.md → archive/UAP_OPTIMIZATION_PLAN.md} +0 -0
  201. /package/docs/{opencode-integration-guide.md → archive/opencode-integration-guide.md} +0 -0
  202. /package/docs/{opencode-integration-quickref.md → archive/opencode-integration-quickref.md} +0 -0
@@ -52,12 +52,14 @@ export function propagateCorrection(dbPath, searchContent, correctedContent, rea
52
52
  const searchLower = searchContent.toLowerCase();
53
53
  try {
54
54
  // 1. Search in memories (working memory / L1)
55
- const memRows = db.prepare(`
55
+ const memRows = db
56
+ .prepare(`
56
57
  SELECT id, content FROM memories
57
58
  WHERE LOWER(content) LIKE ?
58
59
  ORDER BY id DESC
59
60
  LIMIT 5
60
- `).all(`%${searchLower}%`);
61
+ `)
62
+ .all(`%${searchLower}%`);
61
63
  for (const row of memRows) {
62
64
  result.originalFound = true;
63
65
  result.originalId = result.originalId || row.id;
@@ -77,12 +79,14 @@ export function propagateCorrection(dbPath, searchContent, correctedContent, rea
77
79
  result.tiersUpdated.push('memories');
78
80
  }
79
81
  // 2. Search in session_memories (L2)
80
- const sessRows = db.prepare(`
82
+ const sessRows = db
83
+ .prepare(`
81
84
  SELECT id, content FROM session_memories
82
85
  WHERE LOWER(content) LIKE ?
83
86
  ORDER BY id DESC
84
87
  LIMIT 5
85
- `).all(`%${searchLower}%`);
88
+ `)
89
+ .all(`%${searchLower}%`);
86
90
  for (const row of sessRows) {
87
91
  result.originalFound = true;
88
92
  db.prepare(`
@@ -104,21 +108,15 @@ export function propagateCorrection(dbPath, searchContent, correctedContent, rea
104
108
  `).run(today, now, `[CORRECTION] ${reason}: ${correctedContent}`);
105
109
  result.tiersUpdated.push('daily_log');
106
110
  // 4. Write corrected version as new working memory entry
107
- const insertResult = db.prepare(`
111
+ const insertResult = db
112
+ .prepare(`
108
113
  INSERT INTO memories (timestamp, type, content, project_id, importance)
109
114
  VALUES (?, 'observation', ?, 'default', 8)
110
- `).run(now, correctedContent);
115
+ `)
116
+ .run(now, correctedContent);
111
117
  result.correctedEntryId = Number(insertResult.lastInsertRowid);
112
- // Update FTS if available
113
- try {
114
- db.prepare(`
115
- INSERT INTO memories_fts(rowid, content, type)
116
- VALUES (?, ?, 'observation')
117
- `).run(result.correctedEntryId, correctedContent);
118
- }
119
- catch {
120
- // FTS not available
121
- }
118
+ // FTS5 index is automatically updated via AFTER INSERT trigger in schema.ts
119
+ // (no manual insert needed — the trigger handles synchronization)
122
120
  }
123
121
  finally {
124
122
  db.close();
@@ -134,13 +132,15 @@ export function getSupersededHistory(dbPath, limit = 20) {
134
132
  const db = new Database(dbPath);
135
133
  ensureSupersededSchema(db);
136
134
  try {
137
- const rows = db.prepare(`
135
+ const rows = db
136
+ .prepare(`
138
137
  SELECT id, tier, original_entry_id, original_content, superseded_date, reason
139
138
  FROM superseded_entries
140
139
  ORDER BY id DESC
141
140
  LIMIT ?
142
- `).all(limit);
143
- return rows.map(r => ({
141
+ `)
142
+ .all(limit);
143
+ return rows.map((r) => ({
144
144
  id: r.id,
145
145
  tier: r.tier,
146
146
  originalContent: r.original_content,
@@ -1 +1 @@
1
- {"version":3,"file":"correction-propagator.js","sourceRoot":"","sources":["../../src/memory/correction-propagator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"correction-propagator.js","sourceRoot":"","sources":["../../src/memory/correction-propagator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAoBtD;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAqB;IAC1D,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;GAWP,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,aAAqB,EACrB,gBAAwB,EACxB,SAAiB,iBAAiB;IAElC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;IACxE,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAC3B,oBAAoB,CAAC,EAAE,CAAC,CAAC;IAEzB,MAAM,MAAM,GAAqB;QAC/B,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,EAAE;QAChB,eAAe,EAAE,CAAC;KACnB,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,WAAW,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;IAEhD,IAAI,CAAC;QACH,8CAA8C;QAC9C,MAAM,OAAO,GAAG,EAAE;aACf,OAAO,CACN;;;;;KAKH,CACE;aACA,GAAG,CAAC,IAAI,WAAW,GAAG,CAA2C,CAAC;QAErE,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC;YAC5B,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,CAAC;YAChD,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,GAAG,CAAC,OAAO,CAAC;YAE/D,0BAA0B;YAC1B,EAAE,CAAC,OAAO,CACR;;;OAGD,CACA,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YAE1D,0DAA0D;YAC1D,EAAE,CAAC,OAAO,CACR;;OAED,CACA,CAAC,GAAG,CAAC,cAAc,KAAK,KAAK,gBAAgB,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAE1D,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QAED,qCAAqC;QACrC,MAAM,QAAQ,GAAG,EAAE;aAChB,OAAO,CACN;;;;;KAKH,CACE;aACA,GAAG,CAAC,IAAI,WAAW,GAAG,CAA2C,CAAC;QAErE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC;YAE5B,EAAE,CAAC,OAAO,CACR;;;OAGD,CACA,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YAE1D,EAAE,CAAC,OAAO,CACR;;OAED,CACA,CAAC,GAAG,CAAC,cAAc,KAAK,KAAK,gBAAgB,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAE1D,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/C,CAAC;QAED,kDAAkD;QAClD,EAAE,CAAC,OAAO,CACR;;;KAGD,CACA,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,gBAAgB,MAAM,KAAK,gBAAgB,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAEtC,yDAAyD;QACzD,MAAM,YAAY,GAAG,EAAE;aACpB,OAAO,CACN;;;KAGH,CACE;aACA,GAAG,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAC9B,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QAE/D,4EAA4E;QAC5E,kEAAkE;IACpE,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,QAAgB,EAAE;IACrE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAE3B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE;aACZ,OAAO,CACN;;;;;KAKH,CACE;aACA,GAAG,CAAC,KAAK,CAOV,CAAC;QAEH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,eAAe,EAAE,CAAC,CAAC,gBAAgB;YACnC,cAAc,EAAE,CAAC,CAAC,eAAe;YACjC,YAAY,EAAE,EAAE,EAAE,4CAA4C;YAC9D,MAAM,EAAE,CAAC,CAAC,MAAM;SACjB,CAAC,CAAC,CAAC;IACN,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-retrieval.d.ts","sourceRoot":"","sources":["../../src/memory/dynamic-retrieval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAYjC;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,QAAQ,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACxF,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACxF;AAQD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAmDrE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,eAAe,EAC3B,MAAM,GAAE,oBAA+C,GACtD;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAE/E;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,kBAAkB,CAAC;IACnC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,gBAAgB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;IACrF,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,CAChD,eAAe,EAAE,MAAM,EACvB,WAAW,GAAE,MAAsB,EACnC,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;CACxB,GACL,OAAO,CAAC,oBAAoB,CAAC,CA0O/B;AAivBD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAmC7D"}
1
+ {"version":3,"file":"dynamic-retrieval.d.ts","sourceRoot":"","sources":["../../src/memory/dynamic-retrieval.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ import { existsSync, readFileSync, statSync } from 'fs';
13
13
  import { join } from 'path';
14
14
  import Database from 'better-sqlite3';
15
15
  import { classifyTask, extractTaskEntities, getSuggestedMemoryQueries, } from './task-classifier.js';
16
- import { ContextBudget } from './context-compressor.js';
16
+ import { ContextBudget, DynamicCompressor, estimateTokens } from './context-compressor.js';
17
17
  import { compressToSemanticUnits } from './semantic-compression.js';
18
18
  import { decideContextLevel, recordOutcome, } from './adaptive-context.js';
19
19
  import { getRelevantKnowledge, recordKnowledgeOutcome } from './terminal-bench-knowledge.js';
@@ -23,8 +23,70 @@ import { getSpeculativeCache } from './speculative-cache.js';
23
23
  import { contentHash, jaccardSimilarity } from '../utils/string-similarity.js';
24
24
  import { getPerformanceMonitor } from '../utils/performance-monitor.js';
25
25
  import { detectAmbiguity, formatAmbiguityForContext, } from './ambiguity-detector.js';
26
+ import { getMemoryConsolidator } from './memory-consolidator.js';
27
+ import { KnowledgeGraph } from './knowledge-graph.js';
28
+ // Singleton KnowledgeGraph to avoid open/close per retrieval call
29
+ let _knowledgeGraph = null;
30
+ let _knowledgeGraphPath = null;
31
+ function getOrCreateKnowledgeGraph(dbPath) {
32
+ if (!_knowledgeGraph || _knowledgeGraphPath !== dbPath) {
33
+ if (_knowledgeGraph)
34
+ try {
35
+ _knowledgeGraph.close();
36
+ }
37
+ catch {
38
+ /* ignore */
39
+ }
40
+ _knowledgeGraph = new KnowledgeGraph(dbPath);
41
+ _knowledgeGraphPath = dbPath;
42
+ }
43
+ return _knowledgeGraph;
44
+ }
26
45
  const FILE_CACHE_TTL = 60_000; // 1 minute TTL
46
+ const FILE_CACHE_MAX = 20; // Maximum cached files (prevents unbounded growth)
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
48
  const fileReadCache = new Map();
49
+ // Evict oldest entries if cache exceeds max size (runs on cleanup interval)
50
+ function trimFileCache() {
51
+ while (fileReadCache.size > FILE_CACHE_MAX) {
52
+ const firstKey = fileReadCache.keys().next().value;
53
+ if (firstKey)
54
+ fileReadCache.delete(firstKey);
55
+ else
56
+ break;
57
+ }
58
+ }
59
+ // ── Shared readonly DB connection pool (avoids N+1 connection opens per retrieval) ──
60
+ const readonlyDbPool = new Map();
61
+ const DB_POOL_TTL = 30_000; // Close idle connections after 30s
62
+ function getReadonlyDb(dbPath) {
63
+ const existing = readonlyDbPool.get(dbPath);
64
+ if (existing) {
65
+ existing.lastUsed = Date.now();
66
+ return existing.db;
67
+ }
68
+ const db = new Database(dbPath, { readonly: true });
69
+ readonlyDbPool.set(dbPath, { db, lastUsed: Date.now() });
70
+ return db;
71
+ }
72
+ // Periodic cleanup of idle connections (runs every 60s, unref'd so it doesn't block exit)
73
+ const dbPoolCleanupInterval = setInterval(() => {
74
+ const now = Date.now();
75
+ for (const [path, entry] of readonlyDbPool) {
76
+ if (now - entry.lastUsed > DB_POOL_TTL) {
77
+ try {
78
+ entry.db.close();
79
+ }
80
+ catch {
81
+ /* ignore */
82
+ }
83
+ readonlyDbPool.delete(path);
84
+ }
85
+ }
86
+ // Also trim file cache
87
+ trimFileCache();
88
+ }, 60_000);
89
+ dbPoolCleanupInterval.unref();
28
90
  const DEFAULT_RETRIEVAL_DEPTHS = {
29
91
  simple: { shortTerm: 3, sessionMem: 2, longTerm: 5, patterns: 3 },
30
92
  moderate: { shortTerm: 6, sessionMem: 5, longTerm: 8, patterns: 5 },
@@ -96,15 +158,11 @@ export async function retrieveDynamicMemoryContext(taskInstruction, projectRoot
96
158
  // T5: Read token budget from config if available, fall back to parameter or default
97
159
  let configMaxTokens = 2000;
98
160
  try {
99
- const { existsSync: fsExists, readFileSync: fsRead } = await import('fs');
100
- const { join: pathJoin } = await import('path');
101
- const configPath = pathJoin(projectRoot, '.uap.json');
102
- if (fsExists(configPath)) {
103
- const config = JSON.parse(fsRead(configPath, 'utf-8'));
104
- const budgetFromConfig = config?.costOptimization?.tokenBudget?.maxContextTokens;
105
- if (typeof budgetFromConfig === 'number' && budgetFromConfig > 0) {
106
- configMaxTokens = budgetFromConfig;
107
- }
161
+ const { loadUapConfig: loadCfg } = await import('../utils/config-loader.js');
162
+ const cfg = loadCfg(projectRoot);
163
+ const budgetFromConfig = cfg?.costOptimization?.tokenBudget?.maxContextTokens;
164
+ if (typeof budgetFromConfig === 'number' && budgetFromConfig > 0) {
165
+ configMaxTokens = budgetFromConfig;
108
166
  }
109
167
  }
110
168
  catch {
@@ -140,6 +198,39 @@ export async function retrieveDynamicMemoryContext(taskInstruction, projectRoot
140
198
  const budget = new ContextBudget(effectiveMaxTokens);
141
199
  // Step 4: Extract entities from task
142
200
  const entities = extractTaskEntities(taskInstruction);
201
+ // Step 4b: Enrich entities with knowledge graph relationships
202
+ // Uses a singleton KnowledgeGraph to avoid open/close per retrieval call
203
+ try {
204
+ const kgDbPath = join(projectRoot, 'agents/data/memory/short_term.db');
205
+ if (existsSync(kgDbPath)) {
206
+ const kg = getOrCreateKnowledgeGraph(kgDbPath);
207
+ // Query knowledge graph for each extracted entity to find related concepts
208
+ for (const tech of entities.technologies.slice(0, 3)) {
209
+ const result = kg.queryEntityGraph('technology', tech);
210
+ if (result) {
211
+ for (const rel of result.relationships.slice(0, 3)) {
212
+ if (!entities.technologies.includes(rel.relatedEntity.name)) {
213
+ entities.technologies.push(rel.relatedEntity.name);
214
+ }
215
+ }
216
+ }
217
+ }
218
+ for (const file of entities.files.slice(0, 2)) {
219
+ const result = kg.queryEntityGraph('file', file);
220
+ if (result) {
221
+ for (const rel of result.relationships.slice(0, 2)) {
222
+ if (!entities.files.includes(rel.relatedEntity.name)) {
223
+ entities.files.push(rel.relatedEntity.name);
224
+ }
225
+ }
226
+ }
227
+ }
228
+ // Don't close — singleton is reused across calls
229
+ }
230
+ }
231
+ catch {
232
+ // Knowledge graph enrichment is non-fatal
233
+ }
143
234
  // Step 5: Get suggested memory queries (enhanced with predictive prefetch)
144
235
  const suggestedQueries = getSuggestedMemoryQueries(classification);
145
236
  // Step 5b: Predictive memory prefetch - predict additional queries based on task history
@@ -216,7 +307,23 @@ export async function retrieveDynamicMemoryContext(taskInstruction, projectRoot
216
307
  })));
217
308
  }
218
309
  }
219
- // Step 7b: Prune memories to fit token budget using ContextPruner
310
+ // Step 7b: Apply budget-aware dynamic compression to individual memories
311
+ // Track consumed tokens so each memory sees a decreasing budget
312
+ let compressorConsumedTokens = 0;
313
+ try {
314
+ const dynamicCompressor = new DynamicCompressor();
315
+ processedMemories = processedMemories.map((m) => {
316
+ const budgetRemaining = Math.max(0, budget.remaining() - compressorConsumedTokens);
317
+ const { compressed } = dynamicCompressor.compressDynamic(m.content, budgetRemaining, effectiveMaxTokens);
318
+ compressorConsumedTokens += estimateTokens(compressed);
319
+ return { ...m, content: compressed };
320
+ });
321
+ }
322
+ catch {
323
+ // DynamicCompressor failure is non-fatal
324
+ }
325
+ // Step 7c: Prune memories to fit token budget using ContextPruner
326
+ // Subtract tokens already consumed by compression from the available budget
220
327
  try {
221
328
  const pruner = new ContextPruner();
222
329
  const prunableMemories = processedMemories.map((m, i) => ({
@@ -225,7 +332,8 @@ export async function retrieveDynamicMemoryContext(taskInstruction, projectRoot
225
332
  age: i, // Use index as age proxy (older = higher index)
226
333
  accessCount: 1,
227
334
  }));
228
- const pruned = pruner.prune(prunableMemories, budget.remaining());
335
+ const adjustedBudget = Math.max(0, budget.remaining() - compressorConsumedTokens);
336
+ const pruned = pruner.prune(prunableMemories, adjustedBudget);
229
337
  if (pruned.length < processedMemories.length) {
230
338
  // Map pruned back to processed memories by content match
231
339
  const prunedContents = new Set(pruned.map((p) => p.content));
@@ -263,11 +371,67 @@ export async function retrieveDynamicMemoryContext(taskInstruction, projectRoot
263
371
  // Record access for predictive memory learning
264
372
  try {
265
373
  const predictive = getPredictiveMemoryService();
266
- predictive.recordAccess(taskInstruction, processedMemories.map(m => m.source).filter((v, i, a) => a.indexOf(v) === i));
374
+ predictive.recordAccess(taskInstruction, processedMemories.map((m) => m.source).filter((v, i, a) => a.indexOf(v) === i));
267
375
  }
268
376
  catch {
269
377
  // Non-fatal
270
378
  }
379
+ // Record memory access for quality scoring (enables access-pattern learning)
380
+ try {
381
+ const consolidator = getMemoryConsolidator();
382
+ for (const mem of processedMemories) {
383
+ // Use content hash as memory ID for quality tracking
384
+ const memId = contentHash(mem.content);
385
+ consolidator.recordAccess(memId);
386
+ }
387
+ }
388
+ catch {
389
+ // Non-fatal — quality scoring is an optimization, not a requirement
390
+ }
391
+ // Pre-warm speculative cache for predicted next queries (async, non-blocking)
392
+ try {
393
+ const speculativeCache = getSpeculativeCache();
394
+ // Fire-and-forget: pre-warm cache with a real fetcher that queries short-term memory
395
+ void speculativeCache.preWarm(taskInstruction, async (query) => {
396
+ const stDbPath = join(projectRoot, 'agents/data/memory/short_term.db');
397
+ if (!existsSync(stDbPath))
398
+ return [];
399
+ try {
400
+ const db = getReadonlyDb(stDbPath);
401
+ const rows = db
402
+ .prepare(`
403
+ SELECT type, content FROM memories
404
+ WHERE content LIKE ?
405
+ ORDER BY id DESC LIMIT 5
406
+ `)
407
+ .all(`%${query.slice(0, 50)}%`);
408
+ return rows;
409
+ }
410
+ catch {
411
+ return [];
412
+ }
413
+ });
414
+ }
415
+ catch {
416
+ // Non-fatal
417
+ }
418
+ // Periodically persist learned data (fire-and-forget, every ~10th call)
419
+ if (Math.random() < 0.1) {
420
+ try {
421
+ const predictive = getPredictiveMemoryService();
422
+ predictive.saveToDb('./agents/data/memory/predictive.db');
423
+ }
424
+ catch {
425
+ /* non-fatal */
426
+ }
427
+ try {
428
+ const { saveHierarchicalMemory } = await import('./hierarchical-memory.js');
429
+ saveHierarchicalMemory(join(projectRoot, 'agents/data/memory/hierarchical.db'));
430
+ }
431
+ catch {
432
+ /* non-fatal */
433
+ }
434
+ }
271
435
  return {
272
436
  classification,
273
437
  relevantMemories: processedMemories,
@@ -296,12 +460,38 @@ export async function retrieveDynamicMemoryContext(taskInstruction, projectRoot
296
460
  */
297
461
  async function queryAllMemorySources(taskInstruction, classification, entities, suggestedQueries, projectRoot, depth, maxTokens) {
298
462
  const memories = [];
299
- // Source 1: Short-term SQLite memory (limited by depth)
300
- const shortTermMemories = await queryShortTermMemory(classification, entities, projectRoot, depth.shortTerm);
301
- memories.push(...shortTermMemories);
302
- // Source 2: Session memories (limited by depth)
303
- const sessionMemories = await querySessionMemory(taskInstruction, projectRoot, depth.sessionMem);
304
- memories.push(...sessionMemories);
463
+ // Source 1+2: Hierarchical tiered memory (replaces flat short-term + session queries)
464
+ // Uses hot/warm/cold tiering with automatic promotion/demotion and semantic search
465
+ try {
466
+ const { getHierarchicalMemoryManager } = await import('./hierarchical-memory.js');
467
+ const stDbPath = join(projectRoot, 'agents/data/memory/short_term.db');
468
+ const hmm = getHierarchicalMemoryManager(undefined, existsSync(stDbPath) ? stDbPath : undefined);
469
+ // Run tier maintenance periodically (~every 5th retrieval)
470
+ if (Math.random() < 0.2) {
471
+ hmm.pruneStale();
472
+ hmm.enforceTokenBudget();
473
+ }
474
+ const tieredResults = await hmm.query(taskInstruction, depth.shortTerm + depth.sessionMem);
475
+ for (const entry of tieredResults) {
476
+ memories.push({
477
+ content: entry.compressed || entry.content,
478
+ type: entry.type === 'observation'
479
+ ? 'lesson'
480
+ : entry.type === 'action' || entry.type === 'goal'
481
+ ? 'context'
482
+ : 'pattern',
483
+ relevance: Math.min(0.95, entry.importance / 10 + (entry.tier === 'hot' ? 0.2 : entry.tier === 'warm' ? 0.1 : 0)),
484
+ source: `hierarchical-${entry.tier}`,
485
+ });
486
+ }
487
+ }
488
+ catch {
489
+ // Fallback to flat queries if hierarchical memory fails
490
+ const shortTermMemories = await queryShortTermMemory(classification, entities, projectRoot, depth.shortTerm);
491
+ memories.push(...shortTermMemories);
492
+ const sessionMemories = await querySessionMemory(taskInstruction, projectRoot, depth.sessionMem);
493
+ memories.push(...sessionMemories);
494
+ }
305
495
  // Source 3: Long-term prepopulated memory (limited by depth)
306
496
  const longTermMemories = await queryLongTermMemory(suggestedQueries, projectRoot, depth.longTerm);
307
497
  memories.push(...longTermMemories);
@@ -331,7 +521,7 @@ async function queryAllMemorySources(taskInstruction, classification, entities,
331
521
  const budgeted = [];
332
522
  let usedTokens = 0;
333
523
  for (const mem of uniqueMemories) {
334
- const memTokens = Math.ceil(mem.content.length / 4);
524
+ const memTokens = estimateTokens(mem.content);
335
525
  if (usedTokens + memTokens > effectiveBudget && budgeted.length > 0)
336
526
  break;
337
527
  budgeted.push(mem);
@@ -349,9 +539,8 @@ async function queryShortTermMemory(classification, entities, projectRoot, limit
349
539
  return [];
350
540
  const memories = [];
351
541
  const perKeywordLimit = Math.max(1, Math.ceil(limit / 3));
352
- let db = null;
353
542
  try {
354
- db = new Database(dbPath, { readonly: true });
543
+ const db = getReadonlyDb(dbPath);
355
544
  // Check if FTS5 index exists
356
545
  const hasFts = db
357
546
  .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='memories_fts'")
@@ -452,140 +641,82 @@ async function queryShortTermMemory(classification, entities, projectRoot, limit
452
641
  }
453
642
  }
454
643
  catch {
455
- // Ignore query errors
456
- }
457
- finally {
458
- db?.close();
644
+ // Ignore query errors — pooled connection stays open for reuse
459
645
  }
460
646
  return memories;
461
647
  }
462
648
  /**
463
- * Query session memories for recent decisions using parameterized queries (secure)
649
+ * Query session memories for recent decisions using parameterized queries (secure).
650
+ * Uses FTS5 full-text search when a task instruction is provided for content-aware recall,
651
+ * falling back to importance-based recency query.
464
652
  */
465
- async function querySessionMemory(_taskInstruction, projectRoot, limit = 5) {
653
+ async function querySessionMemory(taskInstruction, projectRoot, limit = 5) {
466
654
  const dbPath = join(projectRoot, 'agents/data/memory/short_term.db');
467
655
  if (!existsSync(dbPath))
468
656
  return [];
469
657
  const memories = [];
470
- let db = null;
471
658
  try {
472
- db = new Database(dbPath, { readonly: true });
473
- const stmt = db.prepare(`
474
- SELECT type, content FROM session_memories
475
- WHERE importance >= 7
476
- ORDER BY id DESC
477
- LIMIT ?
478
- `);
479
- const rows = stmt.all(limit);
659
+ const db = getReadonlyDb(dbPath);
660
+ // Try FTS5 content-aware search first if we have a task instruction
661
+ let rows = [];
662
+ if (taskInstruction && taskInstruction.trim().length > 3) {
663
+ try {
664
+ // Extract key terms from task instruction for FTS5 query
665
+ // Quote each word to prevent FTS5 reserved words (AND, OR, NOT, NEAR) from being
666
+ // interpreted as operators — matches the sanitization pattern in sqlite.ts:186-194
667
+ const FTS5_RESERVED = new Set(['and', 'or', 'not', 'near']);
668
+ const ftsQuery = taskInstruction
669
+ .replace(/[^\w\s]/g, ' ')
670
+ .split(/\s+/)
671
+ .filter((w) => w.length > 2 && !FTS5_RESERVED.has(w.toLowerCase()))
672
+ .slice(0, 8)
673
+ .map((w) => '"' + w.replace(/"/g, '""') + '"')
674
+ .join(' OR ');
675
+ if (ftsQuery.length > 0) {
676
+ const ftsStmt = db.prepare(`
677
+ SELECT sm.type, sm.content, fts.rank
678
+ FROM session_memories_fts fts
679
+ JOIN session_memories sm ON sm.id = fts.rowid
680
+ WHERE session_memories_fts MATCH ?
681
+ ORDER BY fts.rank
682
+ LIMIT ?
683
+ `);
684
+ rows = ftsStmt.all(ftsQuery, limit);
685
+ }
686
+ }
687
+ catch {
688
+ // FTS5 table may not exist yet or query may fail — fall through to fallback
689
+ rows = [];
690
+ }
691
+ }
692
+ // Fallback: importance-based recency query
693
+ if (rows.length === 0) {
694
+ const stmt = db.prepare(`
695
+ SELECT type, content FROM session_memories
696
+ WHERE importance >= 7
697
+ ORDER BY id DESC
698
+ LIMIT ?
699
+ `);
700
+ rows = stmt.all(limit);
701
+ }
480
702
  for (const row of rows) {
481
703
  if (row.content) {
482
704
  memories.push({
483
705
  content: row.content.slice(0, 500),
484
706
  type: row.type === 'lesson' ? 'lesson' : row.type === 'decision' ? 'context' : 'pattern',
485
- relevance: 0.8,
707
+ relevance: row.rank ? Math.min(0.95, 0.8 + Math.abs(row.rank) * 0.01) : 0.8,
486
708
  source: 'session-memory',
487
709
  });
488
710
  }
489
711
  }
490
712
  }
491
713
  catch {
492
- // Ignore query errors
493
- }
494
- finally {
495
- db?.close();
714
+ // Ignore query errors — pooled connection stays open for reuse
496
715
  }
497
716
  return memories;
498
717
  }
499
- // OPTIMIZATION 9: Stopwords to filter from long-term memory queries
500
- // These words match nearly everything and reduce query precision
501
- const QUERY_STOPWORDS = new Set([
502
- 'a',
503
- 'an',
504
- 'the',
505
- 'is',
506
- 'are',
507
- 'was',
508
- 'were',
509
- 'be',
510
- 'been',
511
- 'being',
512
- 'have',
513
- 'has',
514
- 'had',
515
- 'do',
516
- 'does',
517
- 'did',
518
- 'will',
519
- 'would',
520
- 'could',
521
- 'should',
522
- 'may',
523
- 'might',
524
- 'shall',
525
- 'can',
526
- 'need',
527
- 'must',
528
- 'to',
529
- 'of',
530
- 'in',
531
- 'for',
532
- 'on',
533
- 'with',
534
- 'at',
535
- 'by',
536
- 'from',
537
- 'as',
538
- 'into',
539
- 'through',
540
- 'during',
541
- 'before',
542
- 'after',
543
- 'above',
544
- 'below',
545
- 'and',
546
- 'but',
547
- 'or',
548
- 'nor',
549
- 'not',
550
- 'so',
551
- 'yet',
552
- 'both',
553
- 'either',
554
- 'this',
555
- 'that',
556
- 'these',
557
- 'those',
558
- 'it',
559
- 'its',
560
- 'best',
561
- 'most',
562
- 'very',
563
- 'good',
564
- 'great',
565
- 'well',
566
- 'new',
567
- 'more',
568
- 'common',
569
- 'general',
570
- 'basic',
571
- 'simple',
572
- 'all',
573
- 'any',
574
- 'some',
575
- 'how',
576
- 'what',
577
- 'when',
578
- 'where',
579
- 'which',
580
- 'who',
581
- 'why',
582
- 'practices',
583
- 'tips',
584
- 'implementation',
585
- 'gotchas',
586
- 'mistakes',
587
- 'patterns',
588
- ]);
718
+ // OPTIMIZATION 9: Stopwords from shared utility (replaces 88-line inline set)
719
+ import { QUERY_STOPWORDS } from '../utils/stopwords.js';
589
720
  /**
590
721
  * Query long-term prepopulated memory
591
722
  * OPTIMIZATION 9: Added stopword filtering for better query precision