bikky 0.3.13 → 0.4.1

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 (362) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/CODE_OF_CONDUCT.md +80 -0
  3. package/CONTRIBUTING.md +206 -0
  4. package/README.md +94 -20
  5. package/SECURITY.md +58 -0
  6. package/SUPPORT.md +22 -0
  7. package/dist/config.d.ts +68 -1
  8. package/dist/config.js +197 -4
  9. package/dist/daemon/extraction.d.ts +12 -2
  10. package/dist/daemon/extraction.js +85 -133
  11. package/dist/daemon/loop.js +15 -1
  12. package/dist/daemon/qdrant.js +0 -1
  13. package/dist/daemon/transcript-sources.d.ts +26 -0
  14. package/dist/daemon/transcript-sources.js +193 -0
  15. package/dist/daemon/watcher.d.ts +3 -2
  16. package/dist/daemon/watcher.js +51 -2
  17. package/dist/install.d.ts +9 -1
  18. package/dist/install.js +62 -34
  19. package/dist/lib/qdrant-pool.d.ts +57 -0
  20. package/dist/lib/qdrant-pool.js +104 -0
  21. package/dist/mcp/api.d.ts +57 -19
  22. package/dist/mcp/api.js +134 -72
  23. package/dist/mcp/helpers.d.ts +0 -1
  24. package/dist/mcp/helpers.js +2 -15
  25. package/dist/mcp/index.js +29 -14
  26. package/dist/mcp/tools.d.ts +0 -7
  27. package/dist/mcp/tools.js +618 -276
  28. package/dist/mcp/types.d.ts +0 -3
  29. package/dist/routing.d.ts +53 -0
  30. package/dist/routing.js +129 -0
  31. package/dist/search-scope.d.ts +24 -0
  32. package/dist/search-scope.js +174 -0
  33. package/docs/config/fully-hosted.md +57 -0
  34. package/docs/config/hosted-models.md +50 -0
  35. package/docs/config/hosted-qdrant-local-models.md +39 -0
  36. package/docs/config/local.md +34 -0
  37. package/docs/configuration.md +403 -0
  38. package/docs/privacy-first.md +140 -0
  39. package/docs/screenshots/dashboard.png +0 -0
  40. package/docs/screenshots/graph.png +0 -0
  41. package/docs/screenshots/memory.png +0 -0
  42. package/package.json +28 -7
  43. package/dist/cli.d.ts.map +0 -1
  44. package/dist/cli.js.map +0 -1
  45. package/dist/config.d.ts.map +0 -1
  46. package/dist/config.js.map +0 -1
  47. package/dist/config.test.d.ts +0 -9
  48. package/dist/config.test.d.ts.map +0 -1
  49. package/dist/config.test.js +0 -576
  50. package/dist/config.test.js.map +0 -1
  51. package/dist/daemon/capture-policy.d.ts.map +0 -1
  52. package/dist/daemon/capture-policy.js.map +0 -1
  53. package/dist/daemon/capture-policy.test.d.ts +0 -2
  54. package/dist/daemon/capture-policy.test.d.ts.map +0 -1
  55. package/dist/daemon/capture-policy.test.js +0 -48
  56. package/dist/daemon/capture-policy.test.js.map +0 -1
  57. package/dist/daemon/consolidation.d.ts.map +0 -1
  58. package/dist/daemon/consolidation.js.map +0 -1
  59. package/dist/daemon/entity-typing.d.ts.map +0 -1
  60. package/dist/daemon/entity-typing.js.map +0 -1
  61. package/dist/daemon/entity-typing.test.d.ts +0 -2
  62. package/dist/daemon/entity-typing.test.d.ts.map +0 -1
  63. package/dist/daemon/entity-typing.test.js +0 -50
  64. package/dist/daemon/entity-typing.test.js.map +0 -1
  65. package/dist/daemon/episode-summary.d.ts.map +0 -1
  66. package/dist/daemon/episode-summary.js.map +0 -1
  67. package/dist/daemon/episode-summary.test.d.ts +0 -2
  68. package/dist/daemon/episode-summary.test.d.ts.map +0 -1
  69. package/dist/daemon/episode-summary.test.js +0 -104
  70. package/dist/daemon/episode-summary.test.js.map +0 -1
  71. package/dist/daemon/extraction-quality.test.d.ts +0 -2
  72. package/dist/daemon/extraction-quality.test.d.ts.map +0 -1
  73. package/dist/daemon/extraction-quality.test.js +0 -283
  74. package/dist/daemon/extraction-quality.test.js.map +0 -1
  75. package/dist/daemon/extraction-rules.d.ts.map +0 -1
  76. package/dist/daemon/extraction-rules.js.map +0 -1
  77. package/dist/daemon/extraction-rules.test.d.ts +0 -2
  78. package/dist/daemon/extraction-rules.test.d.ts.map +0 -1
  79. package/dist/daemon/extraction-rules.test.js +0 -203
  80. package/dist/daemon/extraction-rules.test.js.map +0 -1
  81. package/dist/daemon/extraction.d.ts.map +0 -1
  82. package/dist/daemon/extraction.js.map +0 -1
  83. package/dist/daemon/extraction.test.d.ts +0 -2
  84. package/dist/daemon/extraction.test.d.ts.map +0 -1
  85. package/dist/daemon/extraction.test.js +0 -225
  86. package/dist/daemon/extraction.test.js.map +0 -1
  87. package/dist/daemon/index.d.ts.map +0 -1
  88. package/dist/daemon/index.js.map +0 -1
  89. package/dist/daemon/loop.d.ts.map +0 -1
  90. package/dist/daemon/loop.js.map +0 -1
  91. package/dist/daemon/loop.test.d.ts +0 -2
  92. package/dist/daemon/loop.test.d.ts.map +0 -1
  93. package/dist/daemon/loop.test.js +0 -85
  94. package/dist/daemon/loop.test.js.map +0 -1
  95. package/dist/daemon/maintenance-state.d.ts.map +0 -1
  96. package/dist/daemon/maintenance-state.js.map +0 -1
  97. package/dist/daemon/maintenance-state.test.d.ts +0 -2
  98. package/dist/daemon/maintenance-state.test.d.ts.map +0 -1
  99. package/dist/daemon/maintenance-state.test.js +0 -56
  100. package/dist/daemon/maintenance-state.test.js.map +0 -1
  101. package/dist/daemon/qdrant.d.ts.map +0 -1
  102. package/dist/daemon/qdrant.js.map +0 -1
  103. package/dist/daemon/qdrant.test.d.ts +0 -8
  104. package/dist/daemon/qdrant.test.d.ts.map +0 -1
  105. package/dist/daemon/qdrant.test.js +0 -265
  106. package/dist/daemon/qdrant.test.js.map +0 -1
  107. package/dist/daemon/relations-vocab.d.ts.map +0 -1
  108. package/dist/daemon/relations-vocab.js.map +0 -1
  109. package/dist/daemon/relations-vocab.test.d.ts +0 -2
  110. package/dist/daemon/relations-vocab.test.d.ts.map +0 -1
  111. package/dist/daemon/relations-vocab.test.js +0 -69
  112. package/dist/daemon/relations-vocab.test.js.map +0 -1
  113. package/dist/daemon/relations.d.ts.map +0 -1
  114. package/dist/daemon/relations.js.map +0 -1
  115. package/dist/daemon/relations.test.d.ts +0 -2
  116. package/dist/daemon/relations.test.d.ts.map +0 -1
  117. package/dist/daemon/relations.test.js +0 -36
  118. package/dist/daemon/relations.test.js.map +0 -1
  119. package/dist/daemon/session-index.d.ts.map +0 -1
  120. package/dist/daemon/session-index.js.map +0 -1
  121. package/dist/daemon/session-index.test.d.ts +0 -2
  122. package/dist/daemon/session-index.test.d.ts.map +0 -1
  123. package/dist/daemon/session-index.test.js +0 -60
  124. package/dist/daemon/session-index.test.js.map +0 -1
  125. package/dist/daemon/session-summary.d.ts.map +0 -1
  126. package/dist/daemon/session-summary.js.map +0 -1
  127. package/dist/daemon/session-summary.test.d.ts +0 -2
  128. package/dist/daemon/session-summary.test.d.ts.map +0 -1
  129. package/dist/daemon/session-summary.test.js +0 -162
  130. package/dist/daemon/session-summary.test.js.map +0 -1
  131. package/dist/daemon/staleness.d.ts.map +0 -1
  132. package/dist/daemon/staleness.js.map +0 -1
  133. package/dist/daemon/staleness.test.d.ts +0 -7
  134. package/dist/daemon/staleness.test.d.ts.map +0 -1
  135. package/dist/daemon/staleness.test.js +0 -128
  136. package/dist/daemon/staleness.test.js.map +0 -1
  137. package/dist/daemon/watcher-health.d.ts.map +0 -1
  138. package/dist/daemon/watcher-health.js.map +0 -1
  139. package/dist/daemon/watcher-health.test.d.ts +0 -5
  140. package/dist/daemon/watcher-health.test.d.ts.map +0 -1
  141. package/dist/daemon/watcher-health.test.js +0 -119
  142. package/dist/daemon/watcher-health.test.js.map +0 -1
  143. package/dist/daemon/watcher.d.ts.map +0 -1
  144. package/dist/daemon/watcher.js.map +0 -1
  145. package/dist/daemon/watcher.test.d.ts +0 -9
  146. package/dist/daemon/watcher.test.d.ts.map +0 -1
  147. package/dist/daemon/watcher.test.js +0 -204
  148. package/dist/daemon/watcher.test.js.map +0 -1
  149. package/dist/daemon/workstream-resolver.d.ts.map +0 -1
  150. package/dist/daemon/workstream-resolver.js.map +0 -1
  151. package/dist/daemon/workstream-resolver.test.d.ts +0 -2
  152. package/dist/daemon/workstream-resolver.test.d.ts.map +0 -1
  153. package/dist/daemon/workstream-resolver.test.js +0 -128
  154. package/dist/daemon/workstream-resolver.test.js.map +0 -1
  155. package/dist/daemon/workstream-summary.d.ts.map +0 -1
  156. package/dist/daemon/workstream-summary.js.map +0 -1
  157. package/dist/daemon/workstream-summary.test.d.ts +0 -2
  158. package/dist/daemon/workstream-summary.test.d.ts.map +0 -1
  159. package/dist/daemon/workstream-summary.test.js +0 -89
  160. package/dist/daemon/workstream-summary.test.js.map +0 -1
  161. package/dist/install.d.ts.map +0 -1
  162. package/dist/install.js.map +0 -1
  163. package/dist/install.test.d.ts +0 -9
  164. package/dist/install.test.d.ts.map +0 -1
  165. package/dist/install.test.js +0 -126
  166. package/dist/install.test.js.map +0 -1
  167. package/dist/lib/qdrant-client.d.ts.map +0 -1
  168. package/dist/lib/qdrant-client.js.map +0 -1
  169. package/dist/lib/qdrant-client.test.d.ts +0 -8
  170. package/dist/lib/qdrant-client.test.d.ts.map +0 -1
  171. package/dist/lib/qdrant-client.test.js +0 -274
  172. package/dist/lib/qdrant-client.test.js.map +0 -1
  173. package/dist/lifecycle.d.ts.map +0 -1
  174. package/dist/lifecycle.js.map +0 -1
  175. package/dist/lifecycle.test.d.ts +0 -8
  176. package/dist/lifecycle.test.d.ts.map +0 -1
  177. package/dist/lifecycle.test.js +0 -74
  178. package/dist/lifecycle.test.js.map +0 -1
  179. package/dist/llm/embedding/index.d.ts.map +0 -1
  180. package/dist/llm/embedding/index.js.map +0 -1
  181. package/dist/llm/embedding/index.test.d.ts +0 -8
  182. package/dist/llm/embedding/index.test.d.ts.map +0 -1
  183. package/dist/llm/embedding/index.test.js +0 -100
  184. package/dist/llm/embedding/index.test.js.map +0 -1
  185. package/dist/llm/embedding/providers/bedrock.d.ts.map +0 -1
  186. package/dist/llm/embedding/providers/bedrock.js.map +0 -1
  187. package/dist/llm/embedding/providers/bedrock.test.d.ts +0 -2
  188. package/dist/llm/embedding/providers/bedrock.test.d.ts.map +0 -1
  189. package/dist/llm/embedding/providers/bedrock.test.js +0 -24
  190. package/dist/llm/embedding/providers/bedrock.test.js.map +0 -1
  191. package/dist/llm/embedding/providers/index.d.ts.map +0 -1
  192. package/dist/llm/embedding/providers/index.js.map +0 -1
  193. package/dist/llm/embedding/providers/ollama.d.ts.map +0 -1
  194. package/dist/llm/embedding/providers/ollama.js.map +0 -1
  195. package/dist/llm/embedding/providers/ollama.test.d.ts +0 -2
  196. package/dist/llm/embedding/providers/ollama.test.d.ts.map +0 -1
  197. package/dist/llm/embedding/providers/ollama.test.js +0 -54
  198. package/dist/llm/embedding/providers/ollama.test.js.map +0 -1
  199. package/dist/llm/embedding/providers/openai.d.ts.map +0 -1
  200. package/dist/llm/embedding/providers/openai.js.map +0 -1
  201. package/dist/llm/embedding/providers/openai.test.d.ts +0 -2
  202. package/dist/llm/embedding/providers/openai.test.d.ts.map +0 -1
  203. package/dist/llm/embedding/providers/openai.test.js +0 -48
  204. package/dist/llm/embedding/providers/openai.test.js.map +0 -1
  205. package/dist/llm/embedding/providers/portkey.d.ts.map +0 -1
  206. package/dist/llm/embedding/providers/portkey.js.map +0 -1
  207. package/dist/llm/embedding/providers/portkey.test.d.ts +0 -2
  208. package/dist/llm/embedding/providers/portkey.test.d.ts.map +0 -1
  209. package/dist/llm/embedding/providers/portkey.test.js +0 -56
  210. package/dist/llm/embedding/providers/portkey.test.js.map +0 -1
  211. package/dist/llm/embedding/registry.d.ts.map +0 -1
  212. package/dist/llm/embedding/registry.js.map +0 -1
  213. package/dist/llm/embedding/registry.test.d.ts +0 -7
  214. package/dist/llm/embedding/registry.test.d.ts.map +0 -1
  215. package/dist/llm/embedding/registry.test.js +0 -68
  216. package/dist/llm/embedding/registry.test.js.map +0 -1
  217. package/dist/llm/embedding/types.d.ts.map +0 -1
  218. package/dist/llm/embedding/types.js.map +0 -1
  219. package/dist/llm/errors.d.ts.map +0 -1
  220. package/dist/llm/errors.js.map +0 -1
  221. package/dist/llm/errors.test.d.ts +0 -2
  222. package/dist/llm/errors.test.d.ts.map +0 -1
  223. package/dist/llm/errors.test.js +0 -103
  224. package/dist/llm/errors.test.js.map +0 -1
  225. package/dist/llm/fetch.d.ts.map +0 -1
  226. package/dist/llm/fetch.js.map +0 -1
  227. package/dist/llm/index.d.ts.map +0 -1
  228. package/dist/llm/index.js.map +0 -1
  229. package/dist/llm/inference/index.d.ts.map +0 -1
  230. package/dist/llm/inference/index.js.map +0 -1
  231. package/dist/llm/inference/index.test.d.ts +0 -6
  232. package/dist/llm/inference/index.test.d.ts.map +0 -1
  233. package/dist/llm/inference/index.test.js +0 -150
  234. package/dist/llm/inference/index.test.js.map +0 -1
  235. package/dist/llm/inference/providers/bedrock.d.ts.map +0 -1
  236. package/dist/llm/inference/providers/bedrock.js.map +0 -1
  237. package/dist/llm/inference/providers/bedrock.test.d.ts +0 -2
  238. package/dist/llm/inference/providers/bedrock.test.d.ts.map +0 -1
  239. package/dist/llm/inference/providers/bedrock.test.js +0 -68
  240. package/dist/llm/inference/providers/bedrock.test.js.map +0 -1
  241. package/dist/llm/inference/providers/index.d.ts.map +0 -1
  242. package/dist/llm/inference/providers/index.js.map +0 -1
  243. package/dist/llm/inference/providers/ollama.d.ts.map +0 -1
  244. package/dist/llm/inference/providers/ollama.js.map +0 -1
  245. package/dist/llm/inference/providers/ollama.test.d.ts +0 -2
  246. package/dist/llm/inference/providers/ollama.test.d.ts.map +0 -1
  247. package/dist/llm/inference/providers/ollama.test.js +0 -57
  248. package/dist/llm/inference/providers/ollama.test.js.map +0 -1
  249. package/dist/llm/inference/providers/openai.d.ts.map +0 -1
  250. package/dist/llm/inference/providers/openai.js.map +0 -1
  251. package/dist/llm/inference/providers/openai.test.d.ts +0 -2
  252. package/dist/llm/inference/providers/openai.test.d.ts.map +0 -1
  253. package/dist/llm/inference/providers/openai.test.js +0 -82
  254. package/dist/llm/inference/providers/openai.test.js.map +0 -1
  255. package/dist/llm/inference/providers/portkey.d.ts.map +0 -1
  256. package/dist/llm/inference/providers/portkey.js.map +0 -1
  257. package/dist/llm/inference/providers/portkey.test.d.ts +0 -2
  258. package/dist/llm/inference/providers/portkey.test.d.ts.map +0 -1
  259. package/dist/llm/inference/providers/portkey.test.js +0 -48
  260. package/dist/llm/inference/providers/portkey.test.js.map +0 -1
  261. package/dist/llm/inference/registry.d.ts.map +0 -1
  262. package/dist/llm/inference/registry.js.map +0 -1
  263. package/dist/llm/inference/registry.test.d.ts +0 -6
  264. package/dist/llm/inference/registry.test.d.ts.map +0 -1
  265. package/dist/llm/inference/registry.test.js +0 -63
  266. package/dist/llm/inference/registry.test.js.map +0 -1
  267. package/dist/llm/inference/types.d.ts.map +0 -1
  268. package/dist/llm/inference/types.js.map +0 -1
  269. package/dist/llm/telemetry.d.ts.map +0 -1
  270. package/dist/llm/telemetry.js.map +0 -1
  271. package/dist/llm/telemetry.test.d.ts +0 -5
  272. package/dist/llm/telemetry.test.d.ts.map +0 -1
  273. package/dist/llm/telemetry.test.js +0 -89
  274. package/dist/llm/telemetry.test.js.map +0 -1
  275. package/dist/llm/types.d.ts.map +0 -1
  276. package/dist/llm/types.js.map +0 -1
  277. package/dist/logger.d.ts.map +0 -1
  278. package/dist/logger.js.map +0 -1
  279. package/dist/logger.test.d.ts +0 -5
  280. package/dist/logger.test.d.ts.map +0 -1
  281. package/dist/logger.test.js +0 -103
  282. package/dist/logger.test.js.map +0 -1
  283. package/dist/mcp/api.d.ts.map +0 -1
  284. package/dist/mcp/api.js.map +0 -1
  285. package/dist/mcp/api.test.d.ts +0 -6
  286. package/dist/mcp/api.test.d.ts.map +0 -1
  287. package/dist/mcp/api.test.js +0 -130
  288. package/dist/mcp/api.test.js.map +0 -1
  289. package/dist/mcp/helpers.d.ts.map +0 -1
  290. package/dist/mcp/helpers.js.map +0 -1
  291. package/dist/mcp/helpers.test.d.ts +0 -5
  292. package/dist/mcp/helpers.test.d.ts.map +0 -1
  293. package/dist/mcp/helpers.test.js +0 -548
  294. package/dist/mcp/helpers.test.js.map +0 -1
  295. package/dist/mcp/index.d.ts.map +0 -1
  296. package/dist/mcp/index.js.map +0 -1
  297. package/dist/mcp/taxonomy.d.ts.map +0 -1
  298. package/dist/mcp/taxonomy.js.map +0 -1
  299. package/dist/mcp/taxonomy.test.d.ts +0 -5
  300. package/dist/mcp/taxonomy.test.d.ts.map +0 -1
  301. package/dist/mcp/taxonomy.test.js +0 -215
  302. package/dist/mcp/taxonomy.test.js.map +0 -1
  303. package/dist/mcp/tools.d.ts.map +0 -1
  304. package/dist/mcp/tools.integration.itest.d.ts +0 -23
  305. package/dist/mcp/tools.integration.itest.d.ts.map +0 -1
  306. package/dist/mcp/tools.integration.itest.js +0 -171
  307. package/dist/mcp/tools.integration.itest.js.map +0 -1
  308. package/dist/mcp/tools.js.map +0 -1
  309. package/dist/mcp/tools.test.d.ts +0 -16
  310. package/dist/mcp/tools.test.d.ts.map +0 -1
  311. package/dist/mcp/tools.test.js +0 -908
  312. package/dist/mcp/tools.test.js.map +0 -1
  313. package/dist/mcp/types.d.ts.map +0 -1
  314. package/dist/mcp/types.js.map +0 -1
  315. package/dist/postinstall.d.ts.map +0 -1
  316. package/dist/postinstall.js.map +0 -1
  317. package/dist/privacy/redaction.d.ts.map +0 -1
  318. package/dist/privacy/redaction.js.map +0 -1
  319. package/dist/privacy/redaction.test.d.ts +0 -2
  320. package/dist/privacy/redaction.test.d.ts.map +0 -1
  321. package/dist/privacy/redaction.test.js +0 -51
  322. package/dist/privacy/redaction.test.js.map +0 -1
  323. package/dist/prompts/brief.d.ts.map +0 -1
  324. package/dist/prompts/brief.js.map +0 -1
  325. package/dist/prompts/contradiction.d.ts.map +0 -1
  326. package/dist/prompts/contradiction.js.map +0 -1
  327. package/dist/prompts/distill.d.ts.map +0 -1
  328. package/dist/prompts/distill.js.map +0 -1
  329. package/dist/prompts/entity-typing.d.ts.map +0 -1
  330. package/dist/prompts/entity-typing.js.map +0 -1
  331. package/dist/prompts/episode-summary.d.ts.map +0 -1
  332. package/dist/prompts/episode-summary.js.map +0 -1
  333. package/dist/prompts/extraction.d.ts.map +0 -1
  334. package/dist/prompts/extraction.js.map +0 -1
  335. package/dist/prompts/index.d.ts.map +0 -1
  336. package/dist/prompts/index.js.map +0 -1
  337. package/dist/prompts/prompts.test.d.ts +0 -8
  338. package/dist/prompts/prompts.test.d.ts.map +0 -1
  339. package/dist/prompts/prompts.test.js +0 -140
  340. package/dist/prompts/prompts.test.js.map +0 -1
  341. package/dist/prompts/relations.d.ts.map +0 -1
  342. package/dist/prompts/relations.js.map +0 -1
  343. package/dist/prompts/workstream-summary.d.ts.map +0 -1
  344. package/dist/prompts/workstream-summary.js.map +0 -1
  345. package/dist/provenance/actor.d.ts.map +0 -1
  346. package/dist/provenance/actor.js.map +0 -1
  347. package/dist/provenance/actor.test.d.ts +0 -2
  348. package/dist/provenance/actor.test.d.ts.map +0 -1
  349. package/dist/provenance/actor.test.js +0 -49
  350. package/dist/provenance/actor.test.js.map +0 -1
  351. package/dist/render.d.ts.map +0 -1
  352. package/dist/render.js.map +0 -1
  353. package/dist/render.test.d.ts +0 -8
  354. package/dist/render.test.d.ts.map +0 -1
  355. package/dist/render.test.js +0 -244
  356. package/dist/render.test.js.map +0 -1
  357. package/dist/status.d.ts.map +0 -1
  358. package/dist/status.js.map +0 -1
  359. package/dist/status.test.d.ts +0 -5
  360. package/dist/status.test.d.ts.map +0 -1
  361. package/dist/status.test.js +0 -203
  362. package/dist/status.test.js.map +0 -1
package/dist/mcp/api.js CHANGED
@@ -1,32 +1,37 @@
1
1
  /**
2
- * External API helpers — Qdrant REST client, LLM chat, logging.
3
- * Credentials come from config (~/.bikky/config.json) or env vars.
2
+ * External API helpers — Qdrant REST client pool, LLM chat, logging.
3
+ *
4
+ * Multi-destination model: write operations resolve to one Destination
5
+ * (see ../routing.ts) and operate against that destination's QdrantClient
6
+ * via the QdrantPool (see ../lib/qdrant-pool.ts). Read/search operations may
7
+ * resolve a search scope and fan out across multiple destinations.
8
+ *
9
+ * The legacy single-Qdrant API is kept around for back-compat where call sites
10
+ * have not yet been refactored — they all route to a "default" destination
11
+ * synthesized from the top-level qdrant_url/qdrant_api_key/collection.
4
12
  */
5
13
  import fs from "node:fs";
6
14
  import path from "node:path";
7
15
  import { embed, getEmbeddingDimensions, getEmbeddingConfig, initEmbedding, chatCompletion, initLLM } from "../llm/index.js";
8
16
  export { embed, getEmbeddingDimensions, getEmbeddingConfig, initEmbedding };
9
17
  import { createLogger } from "../logger.js";
10
- import { BIKKY_DIR, LOG_DIR, loadConfig } from "../config.js";
11
- import { QdrantClient } from "../lib/qdrant-client.js";
18
+ import { BIKKY_DIR, LOG_DIR, loadConfig, getEffectiveDestinations } from "../config.js";
19
+ import { QdrantPool } from "../lib/qdrant-pool.js";
20
+ import { resolveDestination, buildResolver } from "../routing.js";
12
21
  // ---------------------------------------------------------------------------
13
- // Config
22
+ // Boot dirs / log
14
23
  // ---------------------------------------------------------------------------
15
24
  export const MEMORY_DIR = BIKKY_DIR;
16
- let collectionName = "bikky";
17
- export function getCollection() { return collectionName; }
18
- export function setCollection(name) {
19
- collectionName = name;
20
- rebuildClient();
21
- }
22
25
  fs.mkdirSync(MEMORY_DIR, { recursive: true });
23
26
  fs.mkdirSync(LOG_DIR, { recursive: true });
24
- let llmInitialized = false;
27
+ export const log = createLogger("memory-mcp", path.join(LOG_DIR, "mcp.log"), {
28
+ maxSize: 2 * 1024 * 1024,
29
+ maxFiles: 3,
30
+ });
31
+ const qdrantLogAdapter = (level, msg) => log(level, msg);
25
32
  // ---------------------------------------------------------------------------
26
33
  // Runtime state — populated at startup
27
34
  // ---------------------------------------------------------------------------
28
- export let qdrantUrl = null;
29
- export let qdrantApiKey = null;
30
35
  export let ready = false;
31
36
  /**
32
37
  * Reason the system is not ready, when known. Set by `setSetupError` from the
@@ -35,45 +40,69 @@ export let ready = false;
35
40
  * instead of a generic "setup_required".
36
41
  */
37
42
  export let setupError = null;
38
- let client = null;
39
- export function setQdrantUrl(v) {
40
- qdrantUrl = v ? v.replace(/\/+$/, "") : v;
41
- rebuildClient();
42
- }
43
- export function setQdrantApiKey(v) {
44
- qdrantApiKey = v;
45
- rebuildClient();
46
- }
43
+ let pool = null;
44
+ let llmInitialized = false;
47
45
  export function setReady(v) { ready = v; }
48
46
  export function setSetupError(v) { setupError = v; }
49
47
  // ---------------------------------------------------------------------------
50
- // Logging (to file only — stdout/stderr are MCP stdio transport)
48
+ // Pool lifecycle
51
49
  // ---------------------------------------------------------------------------
52
- export const log = createLogger("memory-mcp", path.join(LOG_DIR, "mcp.log"), {
53
- maxSize: 2 * 1024 * 1024,
54
- maxFiles: 3,
55
- });
56
- // Adapter to bridge QdrantClient's QdrantLogFn signature to our file logger.
57
- const qdrantLogAdapter = (level, msg) => log(level, msg);
58
- function rebuildClient() {
59
- if (qdrantUrl && collectionName) {
60
- const cfg = loadConfig();
61
- client = new QdrantClient({
62
- url: qdrantUrl,
63
- apiKey: qdrantApiKey,
64
- collection: collectionName,
65
- timeoutMs: cfg.qdrant_client.timeout_ms,
66
- retries: cfg.qdrant_client.retries,
67
- retryBaseDelayMs: cfg.qdrant_client.retry_base_delay_ms,
68
- log: qdrantLogAdapter,
69
- });
50
+ /**
51
+ * (Re)build the destination pool from the current config. Idempotent — safe
52
+ * to call after configure_credentials updates the on-disk config.
53
+ */
54
+ export function rebuildPool() {
55
+ const cfg = loadConfig();
56
+ const destinations = getEffectiveDestinations(cfg);
57
+ if (destinations.length === 0) {
58
+ pool = null;
59
+ return;
60
+ }
61
+ pool = new QdrantPool(destinations, {
62
+ client: cfg.qdrant_client,
63
+ log: qdrantLogAdapter,
64
+ });
65
+ }
66
+ export function getPool() {
67
+ if (!pool) {
68
+ throw new Error("Qdrant pool not initialized — no destinations configured. " +
69
+ "Use configure_credentials or set QDRANT_URL " +
70
+ "(QDRANT_API_KEY is optional for local / self-hosted instances).");
70
71
  }
71
- else {
72
- client = null;
72
+ return pool;
73
+ }
74
+ /** Whether at least one destination is configured. */
75
+ export function hasPool() {
76
+ return pool !== null;
77
+ }
78
+ /** All destination names currently in the pool, in registration order. */
79
+ export function destinationNames() {
80
+ return pool?.names() ?? [];
81
+ }
82
+ /** All Destination objects in the pool. */
83
+ export function listDestinations() {
84
+ return pool?.destinations() ?? [];
85
+ }
86
+ /** True if any destination's collection is confirmed ready. */
87
+ export function anyCollectionReady() {
88
+ if (!pool)
89
+ return false;
90
+ for (const name of pool.names()) {
91
+ if (pool.isCollectionReady(name))
92
+ return true;
73
93
  }
94
+ return false;
95
+ }
96
+ /** Resolve a destination from caller input. Throws if not configured/found. */
97
+ export function resolveDest(input) {
98
+ return resolveDestination(input, listDestinations());
99
+ }
100
+ /** Build a resolver closure from the current pool's destinations. */
101
+ export function makeResolver() {
102
+ return buildResolver(listDestinations());
74
103
  }
75
104
  // ---------------------------------------------------------------------------
76
- // LLM Chat Completion (for distillation)
105
+ // LLM Chat Completion (unchanged — single global LLM config)
77
106
  // ---------------------------------------------------------------------------
78
107
  export async function chatComplete(systemPrompt, userPrompt) {
79
108
  ensureLLMInitialized();
@@ -89,10 +118,6 @@ export async function chatComplete(systemPrompt, userPrompt) {
89
118
  throw new Error("LLM chat completion failed");
90
119
  return result;
91
120
  }
92
- /**
93
- * Run a pre-rendered prompt (from src/prompts/*) through the LLM. The
94
- * RenderedPrompt already carries messages, response_format, temperature, etc.
95
- */
96
121
  export async function chatCompleteRendered(opts) {
97
122
  ensureLLMInitialized();
98
123
  const result = await chatCompletion(opts);
@@ -121,53 +146,90 @@ function ensureLLMInitialized() {
121
146
  llmInitialized = true;
122
147
  }
123
148
  // ---------------------------------------------------------------------------
124
- // Qdrant REST Client
149
+ // Qdrant REST helpers — destination-scoped
125
150
  // ---------------------------------------------------------------------------
126
- function getClient() {
127
- if (!client) {
128
- throw new Error("Qdrant client not initialized — URL missing. " +
129
- "Use configure_credentials or set QDRANT_URL " +
130
- "(QDRANT_API_KEY is optional for local / self-hosted instances).");
131
- }
132
- return client;
151
+ export async function qdrantReq(destination, method, urlPath, body) {
152
+ return getPool().client(destination.name).request(method, urlPath, body);
133
153
  }
134
- export async function qdrantReq(method, urlPath, body) {
135
- return getClient().request(method, urlPath, body);
154
+ export async function ensureCollection(destination, indexes) {
155
+ await getPool().ensureCollection(destination.name, getEmbeddingDimensions(), indexes);
156
+ log("INFO", `Collection '${destination.collection}' (destination '${destination.name}') ready (vector size ${getEmbeddingDimensions()}, ${indexes.length} indexes)`);
136
157
  }
137
- export async function ensureCollection(indexes) {
138
- await getClient().ensureCollection(getEmbeddingDimensions(), indexes);
139
- log("INFO", `Collection '${getCollection()}' ready (vector size ${getEmbeddingDimensions()}, ${indexes.length} indexes)`);
158
+ /** Run ensureCollection for every destination in the pool. Failures don't stop the loop. */
159
+ export async function ensureCollectionsAll(indexes) {
160
+ const p = getPool();
161
+ const results = [];
162
+ for (const dest of p.destinations()) {
163
+ try {
164
+ await p.ensureCollection(dest.name, getEmbeddingDimensions(), indexes);
165
+ log("INFO", `Collection '${dest.collection}' (destination '${dest.name}') ready`);
166
+ results.push({ destination: dest, ok: true, error: null });
167
+ }
168
+ catch (e) {
169
+ const msg = e instanceof Error ? e.message : String(e);
170
+ log("WARN", `ensureCollection failed for destination '${dest.name}': ${msg}`);
171
+ results.push({ destination: dest, ok: false, error: msg });
172
+ }
173
+ }
174
+ return results;
140
175
  }
141
- export async function qdrantUpsert(id, vector, payload) {
142
- return qdrantReq("PUT", `/collections/${getCollection()}/points`, {
176
+ export async function qdrantUpsert(destination, id, vector, payload) {
177
+ return qdrantReq(destination, "PUT", `/collections/${destination.collection}/points`, {
143
178
  points: [{ id, vector, payload }],
144
179
  });
145
180
  }
146
- export async function qdrantSearch(vector, filter, limit = 5) {
147
- return qdrantReq("POST", `/collections/${getCollection()}/points/search`, {
181
+ export async function qdrantSearch(destination, vector, filter, limit = 5) {
182
+ return qdrantReq(destination, "POST", `/collections/${destination.collection}/points/search`, {
148
183
  vector,
149
184
  filter: filter ?? undefined,
150
185
  limit,
151
186
  with_payload: true,
152
187
  });
153
188
  }
154
- export async function qdrantScroll(filter, limit = 10) {
155
- return qdrantReq("POST", `/collections/${getCollection()}/points/scroll`, {
189
+ export async function qdrantScroll(destination, filter, limit = 10) {
190
+ return qdrantReq(destination, "POST", `/collections/${destination.collection}/points/scroll`, {
156
191
  filter,
157
192
  limit,
158
193
  with_payload: true,
159
194
  });
160
195
  }
161
- export async function qdrantSetPayload(ids, payload) {
162
- return qdrantReq("POST", `/collections/${getCollection()}/points/payload`, {
196
+ export async function qdrantSetPayload(destination, ids, payload) {
197
+ return qdrantReq(destination, "POST", `/collections/${destination.collection}/points/payload`, {
163
198
  points: ids,
164
199
  payload,
165
200
  });
166
201
  }
167
- export async function qdrantGetPoints(ids) {
168
- return qdrantReq("POST", `/collections/${getCollection()}/points`, {
202
+ export async function qdrantGetPoints(destination, ids) {
203
+ return qdrantReq(destination, "POST", `/collections/${destination.collection}/points`, {
169
204
  ids,
170
205
  with_payload: true,
171
206
  });
172
207
  }
208
+ // ---------------------------------------------------------------------------
209
+ // Cross-destination fan-out helpers
210
+ // ---------------------------------------------------------------------------
211
+ /**
212
+ * Look up a point by ID across every destination. Returns the first hit found
213
+ * (and which destination it lives in), or null. Used by `memory_forget`,
214
+ * `memory_verify`, `memory_report_outcome`, and any other ID-based op where
215
+ * the caller doesn't know upfront which destination owns the ID.
216
+ */
217
+ export async function findPointById(id) {
218
+ const p = getPool();
219
+ // Sequential rather than parallel: most lookups will hit the first / default
220
+ // destination, so we'd waste round-trips by always fanning out.
221
+ for (const dest of p.destinations()) {
222
+ try {
223
+ const res = await qdrantGetPoints(dest, [id]);
224
+ const point = res.result?.[0];
225
+ if (point)
226
+ return { destination: dest, point };
227
+ }
228
+ catch {
229
+ // Destination may be down; keep scanning.
230
+ continue;
231
+ }
232
+ }
233
+ return null;
234
+ }
173
235
  //# sourceMappingURL=api.js.map
@@ -11,7 +11,6 @@ export interface StructuredFact {
11
11
  domain?: string;
12
12
  kind?: string;
13
13
  memory_subtype?: string | null;
14
- workspace_id?: string;
15
14
  actor_id?: string;
16
15
  source?: string;
17
16
  entities: string[];
@@ -97,10 +97,9 @@ export function isStale(payload) {
97
97
  export const MEMORY_RECALL_EXCLUDED_KINDS = ["telemetry"];
98
98
  /** Build a Qdrant filter object from optional params. */
99
99
  export function buildFilter(params = {}) {
100
- const { category, domain, kind, memory_subtype, workspace_id, includeLegacyWorkspace = false, actor_id, entity, session_id, episode_id, workstream_key, task_key, repo, branch, review_status, since, until, excludeSuperseded = true, excludeKinds = [], metadata, } = params;
100
+ const { category, domain, kind, memory_subtype, actor_id, entity, session_id, episode_id, workstream_key, task_key, repo, branch, review_status, since, until, excludeSuperseded = true, excludeKinds = [], metadata, } = params;
101
101
  const must = [];
102
102
  const must_not = [];
103
- const should = [];
104
103
  if (excludeSuperseded) {
105
104
  must.push({ is_null: { key: "superseded_by" } });
106
105
  }
@@ -116,14 +115,6 @@ export function buildFilter(params = {}) {
116
115
  if (memory_subtype) {
117
116
  must.push({ key: "memory_subtype", match: { value: memory_subtype } });
118
117
  }
119
- if (workspace_id) {
120
- if (includeLegacyWorkspace) {
121
- should.push({ key: "workspace_id", match: { value: workspace_id } }, { is_empty: { key: "workspace_id" } });
122
- }
123
- else {
124
- must.push({ key: "workspace_id", match: { value: workspace_id } });
125
- }
126
- }
127
118
  if (actor_id) {
128
119
  must.push({ key: "actor_id", match: { value: actor_id } });
129
120
  }
@@ -160,11 +151,10 @@ export function buildFilter(params = {}) {
160
151
  for (const excludedKind of excludeKinds) {
161
152
  must_not.push({ key: "kind", match: { value: excludedKind } });
162
153
  }
163
- if (must.length === 0 && should.length === 0 && must_not.length === 0)
154
+ if (must.length === 0 && must_not.length === 0)
164
155
  return undefined;
165
156
  return {
166
157
  must,
167
- ...(should.length > 0 ? { should } : {}),
168
158
  ...(must_not.length > 0 ? { must_not } : {}),
169
159
  };
170
160
  }
@@ -183,8 +173,6 @@ export function formatFact(point) {
183
173
  parts.push(`kind: ${p.kind}`);
184
174
  if (p.memory_subtype)
185
175
  parts.push(`subtype: ${p.memory_subtype}`);
186
- if (p.workspace_id && p.workspace_id !== "default")
187
- parts.push(`workspace: ${p.workspace_id}`);
188
176
  if (p.actor_id)
189
177
  parts.push(`actor: ${p.actor_id}`);
190
178
  if (p.workstream_key)
@@ -246,7 +234,6 @@ export function structuredFact(point) {
246
234
  ...(p.domain ? { domain: p.domain } : {}),
247
235
  ...(p.kind ? { kind: p.kind } : {}),
248
236
  ...(p.memory_subtype ? { memory_subtype: p.memory_subtype } : {}),
249
- ...(p.workspace_id ? { workspace_id: p.workspace_id } : {}),
250
237
  ...(p.actor_id ? { actor_id: p.actor_id } : {}),
251
238
  ...(p.source ? { source: p.source } : {}),
252
239
  entities: p.entities ?? [],
package/dist/mcp/index.js CHANGED
@@ -14,18 +14,12 @@
14
14
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
15
15
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
16
16
  import { QDRANT_INDEXES } from "./taxonomy.js";
17
- import { log, setQdrantUrl, setQdrantApiKey, setReady, setCollection, setSetupError, ensureCollection, initEmbedding, } from "./api.js";
17
+ import { log, rebuildPool, hasPool, setReady, setSetupError, ensureCollectionsAll, initEmbedding, } from "./api.js";
18
18
  import { registerTools } from "./tools.js";
19
- import { loadConfig } from "../config.js";
19
+ import { loadConfig, getEffectiveDestinations } from "../config.js";
20
20
  export async function startMcpServer() {
21
21
  log("INFO", `Starting bikky MCP server (PID ${process.pid})`);
22
22
  const cfg = loadConfig();
23
- // Resolve credentials from config (which already merges env vars)
24
- const qUrl = cfg.qdrant_url?.replace(/\/+$/, "") || null;
25
- const qKey = cfg.qdrant_api_key || null;
26
- setQdrantUrl(qUrl);
27
- setQdrantApiKey(qKey);
28
- setCollection(cfg.collection);
29
23
  // Initialize embedding provider — wrapped so an unknown provider name or
30
24
  // misconfiguration produces a setup_required status instead of crashing the
31
25
  // MCP stdio transport. The server always comes up; tools degrade via
@@ -50,20 +44,41 @@ export async function startMcpServer() {
50
44
  log("ERROR", `Embedding init failed: ${msg}`);
51
45
  // Continue — server will report setup_required for memory tools.
52
46
  }
53
- if (qUrl) {
47
+ // Build the destination pool from config. Each destination is its own
48
+ // QdrantClient; missing destinations leave the server in setup_required.
49
+ try {
50
+ rebuildPool();
51
+ }
52
+ catch (e) {
53
+ const msg = e instanceof Error ? e.message : String(e);
54
+ setSetupError(`Destination pool init failed: ${msg}`);
55
+ log("ERROR", `Destination pool init failed: ${msg}`);
56
+ }
57
+ if (hasPool()) {
54
58
  try {
55
- await ensureCollection(QDRANT_INDEXES);
56
- setReady(true);
57
- log("INFO", `Memory system ready ✓ (Qdrant ${qKey ? "with" : "without"} api-key auth)`);
59
+ const results = await ensureCollectionsAll(QDRANT_INDEXES);
60
+ const ok = results.filter((r) => r.ok);
61
+ const failed = results.filter((r) => !r.ok);
62
+ for (const r of ok) {
63
+ log("INFO", `Destination '${r.destination.name}' ready ✓ (${r.destination.collection})`);
64
+ }
65
+ for (const r of failed) {
66
+ log("ERROR", `Destination '${r.destination.name}' failed: ${r.error}`);
67
+ }
68
+ setReady(ok.length > 0);
69
+ if (failed.length > 0 && ok.length === 0) {
70
+ setSetupError(`All destinations failed to initialize. First error: ${failed[0]?.error ?? "(none)"}`);
71
+ }
58
72
  }
59
73
  catch (e) {
60
74
  const msg = e instanceof Error ? e.message : String(e);
61
75
  setSetupError(`Qdrant initialization failed: ${msg}`);
62
- log("ERROR", `Failed to initialize collection: ${msg}`);
76
+ log("ERROR", `Failed to initialize collections: ${msg}`);
63
77
  }
64
78
  }
65
79
  else {
66
- log("INFO", "Memory not configured — missing: qdrant-url. Use get_setup_status + configure_credentials.");
80
+ const dests = getEffectiveDestinations(cfg);
81
+ log("INFO", `Memory not configured — no destinations (got ${dests.length}). Use get_setup_status + configure_credentials.`);
67
82
  }
68
83
  const mcp = new McpServer({
69
84
  name: "bikky",
@@ -2,12 +2,5 @@
2
2
  * MCP tool definitions for memory.
3
3
  */
4
4
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
- interface WorkspaceScope {
6
- workspaceId?: string;
7
- actorId?: string;
8
- includeLegacy: boolean;
9
- }
10
- export declare function resolveScope(workspaceId?: string, includeLegacyWorkspace?: boolean, actorId?: string): WorkspaceScope;
11
5
  export declare function registerTools(mcp: McpServer): void;
12
- export {};
13
6
  //# sourceMappingURL=tools.d.ts.map