@planu/cli 0.27.0 → 0.29.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 (273) hide show
  1. package/dist/config/model-routing-rules.json +98 -0
  2. package/dist/config/tool-groups.json +140 -0
  3. package/dist/engine/ai-cost-estimator/core.d.ts +1 -1
  4. package/dist/engine/ai-cost-estimator/core.d.ts.map +1 -1
  5. package/dist/engine/ai-cost-estimator/core.js +3 -167
  6. package/dist/engine/ai-cost-estimator/core.js.map +1 -1
  7. package/dist/engine/ai-cost-estimator/recommender.d.ts +8 -0
  8. package/dist/engine/ai-cost-estimator/recommender.d.ts.map +1 -0
  9. package/dist/engine/ai-cost-estimator/recommender.js +94 -0
  10. package/dist/engine/ai-cost-estimator/recommender.js.map +1 -0
  11. package/dist/engine/ai-cost-estimator/spec-loader.d.ts +13 -0
  12. package/dist/engine/ai-cost-estimator/spec-loader.d.ts.map +1 -0
  13. package/dist/engine/ai-cost-estimator/spec-loader.js +102 -0
  14. package/dist/engine/ai-cost-estimator/spec-loader.js.map +1 -0
  15. package/dist/engine/code-transforms/transform-engine.d.ts +7 -0
  16. package/dist/engine/code-transforms/transform-engine.d.ts.map +1 -0
  17. package/dist/engine/code-transforms/transform-engine.js +67 -0
  18. package/dist/engine/code-transforms/transform-engine.js.map +1 -0
  19. package/dist/engine/code-transforms/typescript/add-error-handling.d.ts +6 -0
  20. package/dist/engine/code-transforms/typescript/add-error-handling.d.ts.map +1 -0
  21. package/dist/engine/code-transforms/typescript/add-error-handling.js +92 -0
  22. package/dist/engine/code-transforms/typescript/add-error-handling.js.map +1 -0
  23. package/dist/engine/code-transforms/typescript/add-jsdoc.d.ts +6 -0
  24. package/dist/engine/code-transforms/typescript/add-jsdoc.d.ts.map +1 -0
  25. package/dist/engine/code-transforms/typescript/add-jsdoc.js +83 -0
  26. package/dist/engine/code-transforms/typescript/add-jsdoc.js.map +1 -0
  27. package/dist/engine/code-transforms/typescript/add-types.d.ts +3 -0
  28. package/dist/engine/code-transforms/typescript/add-types.d.ts.map +1 -0
  29. package/dist/engine/code-transforms/typescript/add-types.js +182 -0
  30. package/dist/engine/code-transforms/typescript/add-types.js.map +1 -0
  31. package/dist/engine/code-transforms/typescript/ast-utils.d.ts +38 -0
  32. package/dist/engine/code-transforms/typescript/ast-utils.d.ts.map +1 -0
  33. package/dist/engine/code-transforms/typescript/ast-utils.js +90 -0
  34. package/dist/engine/code-transforms/typescript/ast-utils.js.map +1 -0
  35. package/dist/engine/code-transforms/typescript/extract-interface.d.ts +6 -0
  36. package/dist/engine/code-transforms/typescript/extract-interface.d.ts.map +1 -0
  37. package/dist/engine/code-transforms/typescript/extract-interface.js +103 -0
  38. package/dist/engine/code-transforms/typescript/extract-interface.js.map +1 -0
  39. package/dist/engine/code-transforms/typescript/modernize-syntax.d.ts +3 -0
  40. package/dist/engine/code-transforms/typescript/modernize-syntax.d.ts.map +1 -0
  41. package/dist/engine/code-transforms/typescript/modernize-syntax.js +213 -0
  42. package/dist/engine/code-transforms/typescript/modernize-syntax.js.map +1 -0
  43. package/dist/engine/code-transforms/typescript/rename-symbol.d.ts +8 -0
  44. package/dist/engine/code-transforms/typescript/rename-symbol.d.ts.map +1 -0
  45. package/dist/engine/code-transforms/typescript/rename-symbol.js +40 -0
  46. package/dist/engine/code-transforms/typescript/rename-symbol.js.map +1 -0
  47. package/dist/engine/focus-tracker.d.ts.map +1 -1
  48. package/dist/engine/focus-tracker.js +1 -0
  49. package/dist/engine/focus-tracker.js.map +1 -1
  50. package/dist/engine/mermaid/core.d.ts +18 -0
  51. package/dist/engine/mermaid/core.d.ts.map +1 -0
  52. package/dist/engine/mermaid/core.js +88 -0
  53. package/dist/engine/mermaid/core.js.map +1 -0
  54. package/dist/engine/mermaid/diagram-generators.d.ts +22 -0
  55. package/dist/engine/mermaid/diagram-generators.d.ts.map +1 -0
  56. package/dist/engine/mermaid/diagram-generators.js +139 -0
  57. package/dist/engine/mermaid/diagram-generators.js.map +1 -0
  58. package/dist/engine/mermaid/helpers.d.ts +8 -0
  59. package/dist/engine/mermaid/helpers.d.ts.map +1 -0
  60. package/dist/engine/mermaid/helpers.js +61 -0
  61. package/dist/engine/mermaid/helpers.js.map +1 -0
  62. package/dist/engine/mermaid-generator.d.ts +2 -37
  63. package/dist/engine/mermaid-generator.d.ts.map +1 -1
  64. package/dist/engine/mermaid-generator.js +4 -276
  65. package/dist/engine/mermaid-generator.js.map +1 -1
  66. package/dist/engine/model-router/complexity-analyzer.d.ts +26 -0
  67. package/dist/engine/model-router/complexity-analyzer.d.ts.map +1 -0
  68. package/dist/engine/model-router/complexity-analyzer.js +182 -0
  69. package/dist/engine/model-router/complexity-analyzer.js.map +1 -0
  70. package/dist/engine/model-router/cost-estimator.d.ts +6 -0
  71. package/dist/engine/model-router/cost-estimator.d.ts.map +1 -0
  72. package/dist/engine/model-router/cost-estimator.js +60 -0
  73. package/dist/engine/model-router/cost-estimator.js.map +1 -0
  74. package/dist/engine/model-router/historical-learner.d.ts +26 -0
  75. package/dist/engine/model-router/historical-learner.d.ts.map +1 -0
  76. package/dist/engine/model-router/historical-learner.js +91 -0
  77. package/dist/engine/model-router/historical-learner.js.map +1 -0
  78. package/dist/engine/model-router/rules-engine.d.ts +13 -0
  79. package/dist/engine/model-router/rules-engine.d.ts.map +1 -0
  80. package/dist/engine/model-router/rules-engine.js +142 -0
  81. package/dist/engine/model-router/rules-engine.js.map +1 -0
  82. package/dist/engine/planu-config-writer.d.ts +2 -2
  83. package/dist/engine/planu-config-writer.d.ts.map +1 -1
  84. package/dist/engine/planu-config-writer.js +4 -6
  85. package/dist/engine/planu-config-writer.js.map +1 -1
  86. package/dist/engine/spec-coverage/criteria-mapper.d.ts +1 -2
  87. package/dist/engine/spec-coverage/criteria-mapper.d.ts.map +1 -1
  88. package/dist/engine/spec-coverage/criteria-mapper.js +4 -203
  89. package/dist/engine/spec-coverage/criteria-mapper.js.map +1 -1
  90. package/dist/engine/spec-coverage/keyword-extractor.d.ts +10 -0
  91. package/dist/engine/spec-coverage/keyword-extractor.d.ts.map +1 -0
  92. package/dist/engine/spec-coverage/keyword-extractor.js +147 -0
  93. package/dist/engine/spec-coverage/keyword-extractor.js.map +1 -0
  94. package/dist/engine/spec-coverage/test-matchers.d.ts +9 -0
  95. package/dist/engine/spec-coverage/test-matchers.d.ts.map +1 -0
  96. package/dist/engine/spec-coverage/test-matchers.js +59 -0
  97. package/dist/engine/spec-coverage/test-matchers.js.map +1 -0
  98. package/dist/engine/spec-migrator.d.ts +17 -0
  99. package/dist/engine/spec-migrator.d.ts.map +1 -0
  100. package/dist/engine/spec-migrator.js +119 -0
  101. package/dist/engine/spec-migrator.js.map +1 -0
  102. package/dist/engine/spec-templates/catalog-extra.d.ts +1 -1
  103. package/dist/engine/spec-templates/catalog-extra.d.ts.map +1 -1
  104. package/dist/engine/spec-templates/catalog-extra.js +8 -363
  105. package/dist/engine/spec-templates/catalog-extra.js.map +1 -1
  106. package/dist/engine/spec-templates/catalog.d.ts.map +1 -1
  107. package/dist/engine/spec-templates/catalog.js +10 -381
  108. package/dist/engine/spec-templates/catalog.js.map +1 -1
  109. package/dist/engine/spec-templates/templates-api-ui.d.ts +6 -0
  110. package/dist/engine/spec-templates/templates-api-ui.d.ts.map +1 -0
  111. package/dist/engine/spec-templates/templates-api-ui.js +188 -0
  112. package/dist/engine/spec-templates/templates-api-ui.js.map +1 -0
  113. package/dist/engine/spec-templates/templates-auth-crud.d.ts +6 -0
  114. package/dist/engine/spec-templates/templates-auth-crud.d.ts.map +1 -0
  115. package/dist/engine/spec-templates/templates-auth-crud.js +198 -0
  116. package/dist/engine/spec-templates/templates-auth-crud.js.map +1 -0
  117. package/dist/engine/spec-templates/templates-data-security.d.ts +6 -0
  118. package/dist/engine/spec-templates/templates-data-security.d.ts.map +1 -0
  119. package/dist/engine/spec-templates/templates-data-security.js +172 -0
  120. package/dist/engine/spec-templates/templates-data-security.js.map +1 -0
  121. package/dist/engine/spec-templates/templates-perf-integration.d.ts +6 -0
  122. package/dist/engine/spec-templates/templates-perf-integration.d.ts.map +1 -0
  123. package/dist/engine/spec-templates/templates-perf-integration.js +199 -0
  124. package/dist/engine/spec-templates/templates-perf-integration.js.map +1 -0
  125. package/dist/engine/tool-groups/context-analyzer.d.ts +11 -0
  126. package/dist/engine/tool-groups/context-analyzer.d.ts.map +1 -0
  127. package/dist/engine/tool-groups/context-analyzer.js +40 -0
  128. package/dist/engine/tool-groups/context-analyzer.js.map +1 -0
  129. package/dist/engine/tool-groups/group-manager.d.ts +35 -0
  130. package/dist/engine/tool-groups/group-manager.d.ts.map +1 -0
  131. package/dist/engine/tool-groups/group-manager.js +201 -0
  132. package/dist/engine/tool-groups/group-manager.js.map +1 -0
  133. package/dist/engine/vector-store/hnsw.d.ts +37 -0
  134. package/dist/engine/vector-store/hnsw.d.ts.map +1 -0
  135. package/dist/engine/vector-store/hnsw.js +294 -0
  136. package/dist/engine/vector-store/hnsw.js.map +1 -0
  137. package/dist/engine/vector-store/similarity.d.ts +21 -0
  138. package/dist/engine/vector-store/similarity.d.ts.map +1 -0
  139. package/dist/engine/vector-store/similarity.js +86 -0
  140. package/dist/engine/vector-store/similarity.js.map +1 -0
  141. package/dist/engine/vector-store/tfidf.d.ts +35 -0
  142. package/dist/engine/vector-store/tfidf.d.ts.map +1 -0
  143. package/dist/engine/vector-store/tfidf.js +255 -0
  144. package/dist/engine/vector-store/tfidf.js.map +1 -0
  145. package/dist/engine/web-fetcher/registry-loader.d.ts.map +1 -1
  146. package/dist/engine/web-fetcher/registry-loader.js +2 -0
  147. package/dist/engine/web-fetcher/registry-loader.js.map +1 -1
  148. package/dist/index.js +19 -0
  149. package/dist/index.js.map +1 -1
  150. package/dist/storage/vector-store/backend-factory.d.ts +9 -0
  151. package/dist/storage/vector-store/backend-factory.d.ts.map +1 -0
  152. package/dist/storage/vector-store/backend-factory.js +33 -0
  153. package/dist/storage/vector-store/backend-factory.js.map +1 -0
  154. package/dist/storage/vector-store/json-fallback.d.ts +21 -0
  155. package/dist/storage/vector-store/json-fallback.d.ts.map +1 -0
  156. package/dist/storage/vector-store/json-fallback.js +85 -0
  157. package/dist/storage/vector-store/json-fallback.js.map +1 -0
  158. package/dist/storage/vector-store/migrator.d.ts +10 -0
  159. package/dist/storage/vector-store/migrator.d.ts.map +1 -0
  160. package/dist/storage/vector-store/migrator.js +139 -0
  161. package/dist/storage/vector-store/migrator.js.map +1 -0
  162. package/dist/storage/vector-store/sqlite-adapter.d.ts +28 -0
  163. package/dist/storage/vector-store/sqlite-adapter.d.ts.map +1 -0
  164. package/dist/storage/vector-store/sqlite-adapter.js +142 -0
  165. package/dist/storage/vector-store/sqlite-adapter.js.map +1 -0
  166. package/dist/tools/create-spec/constitution-validator.d.ts +4 -0
  167. package/dist/tools/create-spec/constitution-validator.d.ts.map +1 -0
  168. package/dist/tools/create-spec/constitution-validator.js +37 -0
  169. package/dist/tools/create-spec/constitution-validator.js.map +1 -0
  170. package/dist/tools/create-spec/post-creation.d.ts +11 -0
  171. package/dist/tools/create-spec/post-creation.d.ts.map +1 -0
  172. package/dist/tools/create-spec/post-creation.js +48 -0
  173. package/dist/tools/create-spec/post-creation.js.map +1 -0
  174. package/dist/tools/create-spec/spec-builder.d.ts +14 -0
  175. package/dist/tools/create-spec/spec-builder.d.ts.map +1 -0
  176. package/dist/tools/create-spec/spec-builder.js +131 -0
  177. package/dist/tools/create-spec/spec-builder.js.map +1 -0
  178. package/dist/tools/create-spec.d.ts.map +1 -1
  179. package/dist/tools/create-spec.js +42 -172
  180. package/dist/tools/create-spec.js.map +1 -1
  181. package/dist/tools/data-governance/audit-handler.d.ts.map +1 -1
  182. package/dist/tools/data-governance/audit-handler.js +1 -0
  183. package/dist/tools/data-governance/audit-handler.js.map +1 -1
  184. package/dist/tools/design-schema.d.ts.map +1 -1
  185. package/dist/tools/design-schema.js +1 -0
  186. package/dist/tools/design-schema.js.map +1 -1
  187. package/dist/tools/init-project/handler.d.ts.map +1 -1
  188. package/dist/tools/init-project/handler.js +48 -14
  189. package/dist/tools/init-project/handler.js.map +1 -1
  190. package/dist/tools/recommend-model-handler.d.ts +8 -0
  191. package/dist/tools/recommend-model-handler.d.ts.map +1 -0
  192. package/dist/tools/recommend-model-handler.js +65 -0
  193. package/dist/tools/recommend-model-handler.js.map +1 -0
  194. package/dist/tools/register-ai-cost-tools.js +1 -1
  195. package/dist/tools/register-ai-cost-tools.js.map +1 -1
  196. package/dist/tools/register-model-tools.d.ts +3 -0
  197. package/dist/tools/register-model-tools.d.ts.map +1 -0
  198. package/dist/tools/register-model-tools.js +50 -0
  199. package/dist/tools/register-model-tools.js.map +1 -0
  200. package/dist/tools/register-search-tools.d.ts +7 -0
  201. package/dist/tools/register-search-tools.d.ts.map +1 -0
  202. package/dist/tools/register-search-tools.js +34 -0
  203. package/dist/tools/register-search-tools.js.map +1 -0
  204. package/dist/tools/register-spec-tools/core-spec-tools.d.ts.map +1 -1
  205. package/dist/tools/register-spec-tools/core-spec-tools.js +0 -4
  206. package/dist/tools/register-spec-tools/core-spec-tools.js.map +1 -1
  207. package/dist/tools/register-tool-groups.d.ts +7 -0
  208. package/dist/tools/register-tool-groups.d.ts.map +1 -0
  209. package/dist/tools/register-tool-groups.js +39 -0
  210. package/dist/tools/register-tool-groups.js.map +1 -0
  211. package/dist/tools/register-transform-tools.d.ts +3 -0
  212. package/dist/tools/register-transform-tools.d.ts.map +1 -0
  213. package/dist/tools/register-transform-tools.js +29 -0
  214. package/dist/tools/register-transform-tools.js.map +1 -0
  215. package/dist/tools/semantic-search-handler.d.ts +7 -0
  216. package/dist/tools/semantic-search-handler.d.ts.map +1 -0
  217. package/dist/tools/semantic-search-handler.js +72 -0
  218. package/dist/tools/semantic-search-handler.js.map +1 -0
  219. package/dist/tools/suggest-tooling/orchestration-generator.js +1 -1
  220. package/dist/tools/suggest-tooling/orchestration-generator.js.map +1 -1
  221. package/dist/tools/tool-group-handler.d.ts +9 -0
  222. package/dist/tools/tool-group-handler.d.ts.map +1 -0
  223. package/dist/tools/tool-group-handler.js +82 -0
  224. package/dist/tools/tool-group-handler.js.map +1 -0
  225. package/dist/tools/transform-code-handler.d.ts +7 -0
  226. package/dist/tools/transform-code-handler.d.ts.map +1 -0
  227. package/dist/tools/transform-code-handler.js +58 -0
  228. package/dist/tools/transform-code-handler.js.map +1 -0
  229. package/dist/types/advanced-framework.d.ts +47 -0
  230. package/dist/types/advanced-framework.d.ts.map +1 -0
  231. package/dist/types/advanced-framework.js +3 -0
  232. package/dist/types/advanced-framework.js.map +1 -0
  233. package/dist/types/code-transforms.d.ts +114 -0
  234. package/dist/types/code-transforms.d.ts.map +1 -0
  235. package/dist/types/code-transforms.js +11 -0
  236. package/dist/types/code-transforms.js.map +1 -0
  237. package/dist/types/css-framework.d.ts +110 -0
  238. package/dist/types/css-framework.d.ts.map +1 -0
  239. package/dist/types/css-framework.js +3 -0
  240. package/dist/types/css-framework.js.map +1 -0
  241. package/dist/types/dashboard.d.ts +77 -0
  242. package/dist/types/dashboard.d.ts.map +1 -0
  243. package/dist/types/dashboard.js +2 -0
  244. package/dist/types/dashboard.js.map +1 -0
  245. package/dist/types/index.d.ts +4 -0
  246. package/dist/types/index.d.ts.map +1 -1
  247. package/dist/types/index.js +4 -0
  248. package/dist/types/index.js.map +1 -1
  249. package/dist/types/model-routing.d.ts +127 -0
  250. package/dist/types/model-routing.d.ts.map +1 -0
  251. package/dist/types/model-routing.js +3 -0
  252. package/dist/types/model-routing.js.map +1 -0
  253. package/dist/types/project/inputs.d.ts +0 -1
  254. package/dist/types/project/inputs.d.ts.map +1 -1
  255. package/dist/types/spec/core.d.ts +28 -1
  256. package/dist/types/spec/core.d.ts.map +1 -1
  257. package/dist/types/spec/inputs.d.ts +9 -6
  258. package/dist/types/spec/inputs.d.ts.map +1 -1
  259. package/dist/types/tool-groups.d.ts +57 -0
  260. package/dist/types/tool-groups.d.ts.map +1 -0
  261. package/dist/types/tool-groups.js +3 -0
  262. package/dist/types/tool-groups.js.map +1 -0
  263. package/dist/types/ui.d.ts +3 -231
  264. package/dist/types/ui.d.ts.map +1 -1
  265. package/dist/types/ui.js +7 -1
  266. package/dist/types/ui.js.map +1 -1
  267. package/dist/types/vector-store.d.ts +137 -0
  268. package/dist/types/vector-store.d.ts.map +1 -0
  269. package/dist/types/vector-store.js +3 -0
  270. package/dist/types/vector-store.js.map +1 -0
  271. package/package.json +1 -1
  272. package/src/config/model-routing-rules.json +98 -0
  273. package/src/config/tool-groups.json +140 -0
@@ -0,0 +1,35 @@
1
+ import type { ToolSlot, GroupStatus, GroupActivationResult } from '../../types/index.js';
2
+ export declare class GroupManager {
3
+ private readonly groups;
4
+ private readonly enabledState;
5
+ private readonly toolMap;
6
+ private readonly notifyChanged;
7
+ constructor(toolMap: Map<string, ToolSlot>, notifyChanged: () => void);
8
+ /** Load groups from config, restore persisted state, apply to toolMap. */
9
+ init(): Promise<void>;
10
+ /** Enable all tools in a group. */
11
+ enableGroup(groupId: string): GroupActivationResult;
12
+ /** Disable all tools in a group. */
13
+ disableGroup(groupId: string): GroupActivationResult;
14
+ /** Toggle a group based on its current state. */
15
+ toggleGroup(groupId: string): GroupActivationResult;
16
+ /** Return runtime status for all groups, including a virtual 'ungrouped' group. */
17
+ getGroupStatus(): GroupStatus[];
18
+ /** Return the group ID that contains the given tool, or undefined. */
19
+ getToolGroup(toolName: string): string | undefined;
20
+ /** Count of tools currently enabled in toolMap. */
21
+ getActiveToolCount(): number;
22
+ /** Total tools registered in toolMap. */
23
+ getTotalToolCount(): number;
24
+ /** Load persisted group states from disk. */
25
+ private loadPersistedState;
26
+ /** Write current group states to disk. */
27
+ private persistState;
28
+ /** Apply enabled/disabled state to all tools in a group via toolMap. */
29
+ private applyGroupState;
30
+ /** Build a successful GroupActivationResult for a given group and action. */
31
+ private buildActivationResult;
32
+ /** Build a failed GroupActivationResult (group not found or locked). */
33
+ private buildErrorResult;
34
+ }
35
+ //# sourceMappingURL=group-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-manager.d.ts","sourceRoot":"","sources":["../../../src/engine/tool-groups/group-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,QAAQ,EACR,WAAW,EACX,qBAAqB,EAGtB,MAAM,kBAAkB,CAAC;AAQ1B,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAa;gBAE/B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,EAAE,MAAM,IAAI;IAOrE,0EAA0E;IACpE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB3B,mCAAmC;IACnC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB;IAcnD,oCAAoC;IACpC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB;IAqBpD,iDAAiD;IACjD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB;IAuBnD,mFAAmF;IACnF,cAAc,IAAI,WAAW,EAAE;IAwC/B,sEAAsE;IACtE,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IASlD,mDAAmD;IACnD,kBAAkB,IAAI,MAAM;IAU5B,yCAAyC;IACzC,iBAAiB,IAAI,MAAM;IAI3B,6CAA6C;YAC/B,kBAAkB;IAUhC,0CAA0C;YAC5B,YAAY;IAY1B,wEAAwE;IACxE,OAAO,CAAC,eAAe;IAoBvB,6EAA6E;IAC7E,OAAO,CAAC,qBAAqB;IAgB7B,wEAAwE;IACxE,OAAO,CAAC,gBAAgB;CAezB"}
@@ -0,0 +1,201 @@
1
+ import { readJson, writeJson } from '../../storage/base-store.js';
2
+ import toolGroupsConfigJson from '../../config/tool-groups.json' with { type: 'json' };
3
+ const STATE_PATH = 'data/global/tool-group-state.json';
4
+ const toolGroupsConfig = toolGroupsConfigJson;
5
+ export class GroupManager {
6
+ groups;
7
+ enabledState;
8
+ toolMap;
9
+ notifyChanged;
10
+ constructor(toolMap, notifyChanged) {
11
+ this.toolMap = toolMap;
12
+ this.notifyChanged = notifyChanged;
13
+ this.groups = new Map();
14
+ this.enabledState = new Map();
15
+ }
16
+ /** Load groups from config, restore persisted state, apply to toolMap. */
17
+ async init() {
18
+ for (const def of toolGroupsConfig.groups) {
19
+ this.groups.set(def.id, def);
20
+ this.enabledState.set(def.id, def.defaultEnabled);
21
+ }
22
+ const persisted = await this.loadPersistedState();
23
+ for (const [groupId, enabled] of persisted) {
24
+ if (this.groups.has(groupId)) {
25
+ this.enabledState.set(groupId, enabled);
26
+ }
27
+ }
28
+ for (const [groupId, enabled] of this.enabledState) {
29
+ this.applyGroupState(groupId, enabled);
30
+ }
31
+ }
32
+ /** Enable all tools in a group. */
33
+ enableGroup(groupId) {
34
+ const group = this.groups.get(groupId);
35
+ if (!group) {
36
+ return this.buildErrorResult(groupId, 'enable', `Group '${groupId}' does not exist.`);
37
+ }
38
+ this.enabledState.set(groupId, true);
39
+ this.applyGroupState(groupId, true);
40
+ void this.persistState();
41
+ this.notifyChanged();
42
+ return this.buildActivationResult(groupId, 'enable');
43
+ }
44
+ /** Disable all tools in a group. */
45
+ disableGroup(groupId) {
46
+ const group = this.groups.get(groupId);
47
+ if (!group) {
48
+ return this.buildErrorResult(groupId, 'disable', `Group '${groupId}' does not exist.`);
49
+ }
50
+ if (group.locked) {
51
+ return this.buildErrorResult(groupId, 'disable', `Group '${groupId}' is locked and cannot be disabled.`);
52
+ }
53
+ this.enabledState.set(groupId, false);
54
+ this.applyGroupState(groupId, false);
55
+ void this.persistState();
56
+ this.notifyChanged();
57
+ return this.buildActivationResult(groupId, 'disable');
58
+ }
59
+ /** Toggle a group based on its current state. */
60
+ toggleGroup(groupId) {
61
+ const group = this.groups.get(groupId);
62
+ if (!group) {
63
+ return this.buildErrorResult(groupId, 'toggle', `Group '${groupId}' does not exist.`);
64
+ }
65
+ const currentlyEnabled = this.enabledState.get(groupId) ?? group.defaultEnabled;
66
+ if (!currentlyEnabled) {
67
+ return this.enableGroup(groupId);
68
+ }
69
+ if (group.locked) {
70
+ return this.buildErrorResult(groupId, 'toggle', `Group '${groupId}' is locked and cannot be disabled.`);
71
+ }
72
+ return this.disableGroup(groupId);
73
+ }
74
+ /** Return runtime status for all groups, including a virtual 'ungrouped' group. */
75
+ getGroupStatus() {
76
+ const statuses = [];
77
+ const groupedTools = new Set();
78
+ for (const [groupId, def] of this.groups) {
79
+ for (const tool of def.tools) {
80
+ groupedTools.add(tool);
81
+ }
82
+ const enabled = this.enabledState.get(groupId) ?? def.defaultEnabled;
83
+ statuses.push({
84
+ id: groupId,
85
+ name: def.name,
86
+ description: def.description,
87
+ enabled,
88
+ tools: [...def.tools],
89
+ toolCount: def.tools.length,
90
+ });
91
+ }
92
+ const ungroupedTools = [];
93
+ for (const toolName of this.toolMap.keys()) {
94
+ if (!groupedTools.has(toolName)) {
95
+ ungroupedTools.push(toolName);
96
+ }
97
+ }
98
+ if (ungroupedTools.length > 0) {
99
+ statuses.push({
100
+ id: 'ungrouped',
101
+ name: 'Ungrouped',
102
+ description: 'Tools not assigned to any defined group.',
103
+ enabled: true,
104
+ tools: ungroupedTools,
105
+ toolCount: ungroupedTools.length,
106
+ });
107
+ }
108
+ return statuses;
109
+ }
110
+ /** Return the group ID that contains the given tool, or undefined. */
111
+ getToolGroup(toolName) {
112
+ for (const [groupId, def] of this.groups) {
113
+ if (def.tools.includes(toolName)) {
114
+ return groupId;
115
+ }
116
+ }
117
+ return undefined;
118
+ }
119
+ /** Count of tools currently enabled in toolMap. */
120
+ getActiveToolCount() {
121
+ let count = 0;
122
+ for (const slot of this.toolMap.values()) {
123
+ if (slot.enabled) {
124
+ count++;
125
+ }
126
+ }
127
+ return count;
128
+ }
129
+ /** Total tools registered in toolMap. */
130
+ getTotalToolCount() {
131
+ return this.toolMap.size;
132
+ }
133
+ /** Load persisted group states from disk. */
134
+ async loadPersistedState() {
135
+ const defaultState = { states: [], updatedAt: '' };
136
+ const persisted = await readJson(STATE_PATH, defaultState);
137
+ const result = new Map();
138
+ for (const entry of persisted.states) {
139
+ result.set(entry.groupId, entry.enabled);
140
+ }
141
+ return result;
142
+ }
143
+ /** Write current group states to disk. */
144
+ async persistState() {
145
+ const states = [];
146
+ for (const [groupId, enabled] of this.enabledState) {
147
+ states.push({ groupId, enabled, lastChanged: new Date().toISOString() });
148
+ }
149
+ const payload = {
150
+ states,
151
+ updatedAt: new Date().toISOString(),
152
+ };
153
+ await writeJson(STATE_PATH, payload);
154
+ }
155
+ /** Apply enabled/disabled state to all tools in a group via toolMap. */
156
+ applyGroupState(groupId, enabled) {
157
+ const def = this.groups.get(groupId);
158
+ /* v8 ignore next 3 */
159
+ if (!def) {
160
+ return;
161
+ }
162
+ for (const toolName of def.tools) {
163
+ const slot = this.toolMap.get(toolName);
164
+ if (!slot) {
165
+ continue;
166
+ }
167
+ if (enabled) {
168
+ slot.enable();
169
+ }
170
+ else {
171
+ slot.disable();
172
+ }
173
+ }
174
+ }
175
+ /** Build a successful GroupActivationResult for a given group and action. */
176
+ buildActivationResult(groupId, action) {
177
+ const newState = this.enabledState.get(groupId) ?? false;
178
+ return {
179
+ success: true,
180
+ group: groupId,
181
+ action,
182
+ newState,
183
+ allGroups: this.getGroupStatus(),
184
+ totalActiveTools: this.getActiveToolCount(),
185
+ totalTools: this.getTotalToolCount(),
186
+ };
187
+ }
188
+ /** Build a failed GroupActivationResult (group not found or locked). */
189
+ buildErrorResult(groupId, action, _message) {
190
+ return {
191
+ success: false,
192
+ group: groupId,
193
+ action,
194
+ newState: this.enabledState.get(groupId) ?? false,
195
+ allGroups: this.getGroupStatus(),
196
+ totalActiveTools: this.getActiveToolCount(),
197
+ totalTools: this.getTotalToolCount(),
198
+ };
199
+ }
200
+ }
201
+ //# sourceMappingURL=group-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-manager.js","sourceRoot":"","sources":["../../../src/engine/tool-groups/group-manager.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,oBAAoB,MAAM,+BAA+B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEvF,MAAM,UAAU,GAAG,mCAAmC,CAAC;AAEvD,MAAM,gBAAgB,GAAG,oBAAwC,CAAC;AAElE,MAAM,OAAO,YAAY;IACN,MAAM,CAAmC;IACzC,YAAY,CAAuB;IACnC,OAAO,CAAwB;IAC/B,aAAa,CAAa;IAE3C,YAAY,OAA8B,EAAE,aAAyB;QACnE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;IAChC,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,IAAI;QACR,KAAK,MAAM,GAAG,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAClD,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACnD,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,WAAW,CAAC,OAAe;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,OAAO,mBAAmB,CAAC,CAAC;QACxF,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpC,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,OAAO,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvD,CAAC;IAED,oCAAoC;IACpC,YAAY,CAAC,OAAe;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,OAAO,mBAAmB,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,gBAAgB,CAC1B,OAAO,EACP,SAAS,EACT,UAAU,OAAO,qCAAqC,CACvD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACrC,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,OAAO,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACxD,CAAC;IAED,iDAAiD;IACjD,WAAW,CAAC,OAAe;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,OAAO,mBAAmB,CAAC,CAAC;QACxF,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC;QAEhF,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,gBAAgB,CAC1B,OAAO,EACP,QAAQ,EACR,UAAU,OAAO,qCAAqC,CACvD,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,mFAAmF;IACnF,cAAc;QACZ,MAAM,QAAQ,GAAkB,EAAE,CAAC;QACnC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;QAEvC,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACzC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBAC7B,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC;YACrE,QAAQ,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,OAAO;gBACX,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,OAAO;gBACP,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC;gBACrB,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM;aAC5B,CAAC,CAAC;QACL,CAAC;QAED,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAChC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,WAAW;gBACf,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,0CAA0C;gBACvD,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,cAAc;gBACrB,SAAS,EAAE,cAAc,CAAC,MAAM;aACjC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,sEAAsE;IACtE,YAAY,CAAC,QAAgB;QAC3B,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACzC,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjC,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,mDAAmD;IACnD,kBAAkB;QAChB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,KAAK,EAAE,CAAC;YACV,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yCAAyC;IACzC,iBAAiB;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,6CAA6C;IACrC,KAAK,CAAC,kBAAkB;QAC9B,MAAM,YAAY,GAA4B,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QAC5E,MAAM,SAAS,GAAG,MAAM,QAAQ,CAA0B,UAAU,EAAE,YAAY,CAAC,CAAC;QACpF,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmB,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,0CAA0C;IAClC,KAAK,CAAC,YAAY;QACxB,MAAM,MAAM,GAAqB,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACnD,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,OAAO,GAA4B;YACvC,MAAM;YACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,wEAAwE;IAChE,eAAe,CAAC,OAAe,EAAE,OAAgB;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,sBAAsB;QACtB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,SAAS;YACX,CAAC;YACD,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,6EAA6E;IACrE,qBAAqB,CAC3B,OAAe,EACf,MAAuC;QAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;QACzD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,OAAO;YACd,MAAM;YACN,QAAQ;YACR,SAAS,EAAE,IAAI,CAAC,cAAc,EAAE;YAChC,gBAAgB,EAAE,IAAI,CAAC,kBAAkB,EAAE;YAC3C,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE;SACrC,CAAC;IACJ,CAAC;IAED,wEAAwE;IAChE,gBAAgB,CACtB,OAAe,EACf,MAAuC,EACvC,QAAgB;QAEhB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,OAAO;YACd,MAAM;YACN,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK;YACjD,SAAS,EAAE,IAAI,CAAC,cAAc,EAAE;YAChC,gBAAgB,EAAE,IAAI,CAAC,kBAAkB,EAAE;YAC3C,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE;SACrC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ import type { HNSWConfig, HNSWSearchCandidate, HNSWSerializedState } from '../../types/index.js';
2
+ /**
3
+ * HNSW (Hierarchical Navigable Small World) index.
4
+ * For corpus < flatSearchThreshold, delegates to brute-force flat search.
5
+ */
6
+ export declare class HNSWIndex {
7
+ private readonly config;
8
+ private readonly nodes;
9
+ private entryPoint;
10
+ private maxLayer;
11
+ constructor(config?: Partial<HNSWConfig>);
12
+ /** Number of indexed vectors. */
13
+ get size(): number;
14
+ /** Insert a vector into the index. */
15
+ insert(id: string, vector: number[]): void;
16
+ /** Remove a vector from the index. */
17
+ remove(id: string): boolean;
18
+ /** Search for the top-K nearest neighbors. Uses flat search for small corpus. */
19
+ search(query: number[], topK: number): HNSWSearchCandidate[];
20
+ /** Brute-force flat search -- guaranteed recall = 1.0. */
21
+ private flatSearch;
22
+ /** HNSW graph search -- approximate, O(log n). */
23
+ private hnswSearch;
24
+ /** Greedy walk to the closest node in a given layer. */
25
+ private greedyClosest;
26
+ /** Search a single layer, returning ef closest candidates. */
27
+ private searchLayer;
28
+ /** Prune connections to keep at most M neighbors. */
29
+ private pruneConnections;
30
+ /** Random level for a new node (geometric distribution). */
31
+ private randomLevel;
32
+ /** Export the index for serialization. */
33
+ exportState(): HNSWSerializedState;
34
+ /** Import the index from serialized form. */
35
+ importState(state: HNSWSerializedState): void;
36
+ }
37
+ //# sourceMappingURL=hnsw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hnsw.d.ts","sourceRoot":"","sources":["../../../src/engine/vector-store/hnsw.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,UAAU,EAEV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AAG9B;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IACrD,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,QAAQ,CAAK;gBAET,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC;IASxC,iCAAiC;IACjC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,sCAAsC;IACtC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IA8D1C,sCAAsC;IACtC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IA2C3B,iFAAiF;IACjF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAa5D,0DAA0D;IAC1D,OAAO,CAAC,UAAU;IASlB,kDAAkD;IAClD,OAAO,CAAC,UAAU;IAelB,wDAAwD;IACxD,OAAO,CAAC,aAAa;IA6CrB,8DAA8D;IAC9D,OAAO,CAAC,WAAW;IAuEnB,qDAAqD;IACrD,OAAO,CAAC,gBAAgB;IAexB,4DAA4D;IAC5D,OAAO,CAAC,WAAW;IASnB,0CAA0C;IAC1C,WAAW,IAAI,mBAAmB;IASlC,6CAA6C;IAC7C,WAAW,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;CAS9C"}
@@ -0,0 +1,294 @@
1
+ // engine/vector-store/hnsw.ts — HNSW index for approximate nearest neighbor search.
2
+ // SPEC-075 AC-02: Pure TypeScript, O(log n), recall > 0.9.
3
+ import { cosineSimilarity } from './similarity.js';
4
+ /**
5
+ * HNSW (Hierarchical Navigable Small World) index.
6
+ * For corpus < flatSearchThreshold, delegates to brute-force flat search.
7
+ */
8
+ export class HNSWIndex {
9
+ config;
10
+ nodes = new Map();
11
+ entryPoint = null;
12
+ maxLayer = 0;
13
+ constructor(config) {
14
+ this.config = {
15
+ M: config?.M ?? 16,
16
+ efConstruction: config?.efConstruction ?? 200,
17
+ efSearch: config?.efSearch ?? 50,
18
+ flatSearchThreshold: config?.flatSearchThreshold ?? 1000,
19
+ };
20
+ }
21
+ /** Number of indexed vectors. */
22
+ get size() {
23
+ return this.nodes.size;
24
+ }
25
+ /** Insert a vector into the index. */
26
+ insert(id, vector) {
27
+ const level = this.randomLevel();
28
+ const layers = [];
29
+ for (let i = 0; i <= level; i++) {
30
+ layers.push(new Map());
31
+ }
32
+ const node = { id, vector, layers };
33
+ if (this.nodes.size === 0) {
34
+ this.nodes.set(id, node);
35
+ this.entryPoint = id;
36
+ this.maxLayer = level;
37
+ return;
38
+ }
39
+ // Navigate from top to insertion level
40
+ /* v8 ignore start -- entryPoint always set when nodes.size > 0 */
41
+ let currentId = this.entryPoint ?? id;
42
+ /* v8 ignore stop */
43
+ for (let lc = this.maxLayer; lc > level; lc--) {
44
+ currentId = this.greedyClosest(currentId, vector, lc);
45
+ }
46
+ // Insert at each layer from level down to 0
47
+ for (let lc = Math.min(level, this.maxLayer); lc >= 0; lc--) {
48
+ const neighbors = this.searchLayer(currentId, vector, this.config.efConstruction, lc);
49
+ const selected = neighbors.slice(0, this.config.M);
50
+ for (const nb of selected) {
51
+ const sim = nb.similarity;
52
+ node.layers[lc]?.set(nb.id, sim);
53
+ const nbNode = this.nodes.get(nb.id);
54
+ /* v8 ignore start -- neighbor always exists and has layers at lc */
55
+ if (nbNode && lc < nbNode.layers.length) {
56
+ /* v8 ignore stop */
57
+ nbNode.layers[lc]?.set(id, sim);
58
+ // Prune if too many connections
59
+ /* v8 ignore start -- lc always within nbNode.layers bounds */
60
+ if ((nbNode.layers[lc]?.size ?? 0) > this.config.M * 2) {
61
+ /* v8 ignore stop */
62
+ this.pruneConnections(nbNode, lc);
63
+ }
64
+ }
65
+ }
66
+ const first = selected[0];
67
+ /* v8 ignore start -- searchLayer always returns at least one result */
68
+ if (first) {
69
+ /* v8 ignore stop */
70
+ currentId = first.id;
71
+ }
72
+ }
73
+ this.nodes.set(id, node);
74
+ if (level > this.maxLayer) {
75
+ this.maxLayer = level;
76
+ this.entryPoint = id;
77
+ }
78
+ }
79
+ /** Remove a vector from the index. */
80
+ remove(id) {
81
+ const node = this.nodes.get(id);
82
+ if (!node) {
83
+ return false;
84
+ }
85
+ // Remove references from neighbors
86
+ for (let lc = 0; lc < node.layers.length; lc++) {
87
+ const layer = node.layers[lc];
88
+ /* v8 ignore start -- defensive: layers always exist within bounds */
89
+ if (!layer) {
90
+ continue;
91
+ }
92
+ /* v8 ignore stop */
93
+ for (const neighborId of layer.keys()) {
94
+ const neighbor = this.nodes.get(neighborId);
95
+ /* v8 ignore start -- neighbor always exists in graph */
96
+ if (neighbor && lc < neighbor.layers.length) {
97
+ /* v8 ignore stop */
98
+ neighbor.layers[lc]?.delete(id);
99
+ }
100
+ }
101
+ }
102
+ this.nodes.delete(id);
103
+ // Update entry point if needed
104
+ if (this.entryPoint === id) {
105
+ /* v8 ignore start -- Map.keys().next().value always defined when size > 0 */
106
+ this.entryPoint = this.nodes.size > 0 ? (this.nodes.keys().next().value ?? null) : null;
107
+ /* v8 ignore stop */
108
+ this.maxLayer = 0;
109
+ for (const n of this.nodes.values()) {
110
+ if (n.layers.length - 1 > this.maxLayer) {
111
+ this.maxLayer = n.layers.length - 1;
112
+ this.entryPoint = n.id;
113
+ }
114
+ }
115
+ }
116
+ return true;
117
+ }
118
+ /** Search for the top-K nearest neighbors. Uses flat search for small corpus. */
119
+ search(query, topK) {
120
+ if (this.nodes.size === 0) {
121
+ return [];
122
+ }
123
+ // Flat search for small corpus
124
+ if (this.nodes.size < this.config.flatSearchThreshold) {
125
+ return this.flatSearch(query, topK);
126
+ }
127
+ return this.hnswSearch(query, topK);
128
+ }
129
+ /** Brute-force flat search -- guaranteed recall = 1.0. */
130
+ flatSearch(query, topK) {
131
+ const results = [];
132
+ for (const node of this.nodes.values()) {
133
+ results.push({ id: node.id, similarity: cosineSimilarity(query, node.vector) });
134
+ }
135
+ results.sort((a, b) => b.similarity - a.similarity);
136
+ return results.slice(0, topK);
137
+ }
138
+ /** HNSW graph search -- approximate, O(log n). */
139
+ hnswSearch(query, topK) {
140
+ /* v8 ignore start -- entryPoint always set when called (size > 0) */
141
+ let currentId = this.entryPoint ?? '';
142
+ /* v8 ignore stop */
143
+ // Traverse from top layer to layer 1
144
+ for (let lc = this.maxLayer; lc > 0; lc--) {
145
+ currentId = this.greedyClosest(currentId, query, lc);
146
+ }
147
+ // Search at layer 0 with efSearch candidates
148
+ const candidates = this.searchLayer(currentId, query, this.config.efSearch, 0);
149
+ return candidates.slice(0, topK);
150
+ }
151
+ /** Greedy walk to the closest node in a given layer. */
152
+ greedyClosest(startId, query, layer) {
153
+ let bestId = startId;
154
+ const startNode = this.nodes.get(startId);
155
+ /* v8 ignore start -- defensive: startId always valid when called internally */
156
+ if (!startNode) {
157
+ return bestId;
158
+ }
159
+ /* v8 ignore stop */
160
+ let bestSim = cosineSimilarity(query, startNode.vector);
161
+ let improved = true;
162
+ while (improved) {
163
+ improved = false;
164
+ const node = this.nodes.get(bestId);
165
+ /* v8 ignore start -- defensive: bestId always valid in walk */
166
+ if (!node || layer >= node.layers.length) {
167
+ break;
168
+ }
169
+ /* v8 ignore stop */
170
+ const neighbors = node.layers[layer];
171
+ /* v8 ignore start -- defensive: layer within bounds */
172
+ if (!neighbors) {
173
+ break;
174
+ }
175
+ /* v8 ignore stop */
176
+ for (const neighborId of neighbors.keys()) {
177
+ const neighbor = this.nodes.get(neighborId);
178
+ /* v8 ignore start -- defensive: neighbor always valid in graph */
179
+ if (!neighbor) {
180
+ continue;
181
+ }
182
+ /* v8 ignore stop */
183
+ const sim = cosineSimilarity(query, neighbor.vector);
184
+ if (sim > bestSim) {
185
+ bestSim = sim;
186
+ bestId = neighborId;
187
+ improved = true;
188
+ }
189
+ }
190
+ }
191
+ return bestId;
192
+ }
193
+ /** Search a single layer, returning ef closest candidates. */
194
+ searchLayer(startId, query, ef, layer) {
195
+ const visited = new Set([startId]);
196
+ const startNode = this.nodes.get(startId);
197
+ /* v8 ignore start -- defensive: startId always valid */
198
+ if (!startNode) {
199
+ return [];
200
+ }
201
+ /* v8 ignore stop */
202
+ const candidates = [
203
+ { id: startId, similarity: cosineSimilarity(query, startNode.vector) },
204
+ ];
205
+ const queue = [startId];
206
+ while (queue.length > 0) {
207
+ const currentId = queue.shift();
208
+ /* v8 ignore start -- defensive: queue checked non-empty */
209
+ if (!currentId) {
210
+ continue;
211
+ }
212
+ /* v8 ignore stop */
213
+ const current = this.nodes.get(currentId);
214
+ /* v8 ignore start -- defensive: currentId always valid */
215
+ if (!current || layer >= current.layers.length) {
216
+ continue;
217
+ }
218
+ /* v8 ignore stop */
219
+ const neighbors = current.layers[layer];
220
+ /* v8 ignore start -- defensive: layer within bounds */
221
+ if (!neighbors) {
222
+ continue;
223
+ }
224
+ /* v8 ignore stop */
225
+ for (const neighborId of neighbors.keys()) {
226
+ if (visited.has(neighborId)) {
227
+ continue;
228
+ }
229
+ visited.add(neighborId);
230
+ const neighbor = this.nodes.get(neighborId);
231
+ /* v8 ignore start -- defensive: neighbor always in graph */
232
+ if (!neighbor) {
233
+ continue;
234
+ }
235
+ /* v8 ignore stop */
236
+ const sim = cosineSimilarity(query, neighbor.vector);
237
+ candidates.push({ id: neighborId, similarity: sim });
238
+ queue.push(neighborId);
239
+ // Keep candidate list bounded
240
+ /* v8 ignore start -- requires corpus > ef*2 neighbors from a single node */
241
+ if (candidates.length > ef * 2) {
242
+ candidates.sort((a, b) => b.similarity - a.similarity);
243
+ candidates.length = ef;
244
+ }
245
+ /* v8 ignore stop */
246
+ }
247
+ }
248
+ candidates.sort((a, b) => b.similarity - a.similarity);
249
+ return candidates.slice(0, ef);
250
+ }
251
+ /** Prune connections to keep at most M neighbors. */
252
+ pruneConnections(node, layer) {
253
+ const layerMap = node.layers[layer];
254
+ /* v8 ignore start -- defensive: layer always valid when called */
255
+ if (!layerMap) {
256
+ return;
257
+ }
258
+ /* v8 ignore stop */
259
+ const entries = [...layerMap.entries()].sort((a, b) => b[1] - a[1]);
260
+ layerMap.clear();
261
+ for (const [id, sim] of entries.slice(0, this.config.M)) {
262
+ layerMap.set(id, sim);
263
+ }
264
+ }
265
+ /** Random level for a new node (geometric distribution). */
266
+ randomLevel() {
267
+ const ml = 1 / Math.log(this.config.M);
268
+ let level = 0;
269
+ while (Math.random() < ml && level < 16) {
270
+ level++;
271
+ }
272
+ return level;
273
+ }
274
+ /** Export the index for serialization. */
275
+ exportState() {
276
+ const nodes = [...this.nodes.values()].map((n) => ({
277
+ id: n.id,
278
+ vector: n.vector,
279
+ layers: n.layers.map((l) => [...l.entries()]),
280
+ }));
281
+ return { nodes, entryPoint: this.entryPoint, maxLayer: this.maxLayer };
282
+ }
283
+ /** Import the index from serialized form. */
284
+ importState(state) {
285
+ this.nodes.clear();
286
+ for (const n of state.nodes) {
287
+ const layers = n.layers.map((l) => new Map(l));
288
+ this.nodes.set(n.id, { id: n.id, vector: n.vector, layers });
289
+ }
290
+ this.entryPoint = state.entryPoint;
291
+ this.maxLayer = state.maxLayer;
292
+ }
293
+ }
294
+ //# sourceMappingURL=hnsw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hnsw.js","sourceRoot":"","sources":["../../../src/engine/vector-store/hnsw.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Compute cosine similarity between two vectors.
3
+ * Returns a value in [0, 1] where 1 means identical direction.
4
+ */
5
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
6
+ /**
7
+ * Compute Jaccard similarity between two binary-ish vectors.
8
+ * Treats non-zero values as "present". Returns value in [0, 1].
9
+ */
10
+ export declare function jaccardSimilarity(a: number[], b: number[]): number;
11
+ /**
12
+ * Combined similarity: weighted average of cosine and jaccard.
13
+ * Default weights: 0.8 cosine + 0.2 jaccard.
14
+ */
15
+ export declare function combinedSimilarity(a: number[], b: number[], cosineWeight?: number): number;
16
+ /**
17
+ * Normalize a vector to unit length (L2 norm).
18
+ * Returns a new array. If the vector is zero, returns a zero vector.
19
+ */
20
+ export declare function normalizeVector(v: number[]): number[];
21
+ //# sourceMappingURL=similarity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"similarity.d.ts","sourceRoot":"","sources":["../../../src/engine/vector-store/similarity.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CA2BjE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CA4BlE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,YAAY,SAAM,GAAG,MAAM,CAIvF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAUrD"}