@runcore-sh/runcore 0.4.0 → 0.5.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 (351) hide show
  1. package/dictionary.json +2 -2
  2. package/dist/activity/log.js +2 -2
  3. package/dist/activity/log.js.map +1 -1
  4. package/dist/agents/governed-spawn.d.ts.map +1 -1
  5. package/dist/cli.js +101 -11
  6. package/dist/cli.js.map +1 -1
  7. package/dist/extensions/cache.d.ts +57 -0
  8. package/dist/extensions/cache.d.ts.map +1 -0
  9. package/dist/extensions/cache.js +173 -0
  10. package/dist/extensions/cache.js.map +1 -0
  11. package/dist/extensions/client.d.ts +55 -0
  12. package/dist/extensions/client.d.ts.map +1 -0
  13. package/dist/extensions/client.js +120 -0
  14. package/dist/extensions/client.js.map +1 -0
  15. package/dist/extensions/index.d.ts +13 -0
  16. package/dist/extensions/index.d.ts.map +1 -0
  17. package/dist/extensions/index.js +12 -0
  18. package/dist/extensions/index.js.map +1 -0
  19. package/dist/extensions/loader.d.ts +50 -0
  20. package/dist/extensions/loader.d.ts.map +1 -0
  21. package/dist/extensions/loader.js +166 -0
  22. package/dist/extensions/loader.js.map +1 -0
  23. package/dist/extensions/manifest.d.ts +38 -0
  24. package/dist/extensions/manifest.d.ts.map +1 -0
  25. package/dist/extensions/manifest.js +17 -0
  26. package/dist/extensions/manifest.js.map +1 -0
  27. package/dist/extensions/stubs.d.ts +27 -0
  28. package/dist/extensions/stubs.d.ts.map +1 -0
  29. package/dist/extensions/stubs.js +45 -0
  30. package/dist/extensions/stubs.js.map +1 -0
  31. package/dist/lib/audit.js +2 -2
  32. package/dist/lib/audit.js.map +1 -1
  33. package/dist/lib/brain-migrate.d.ts +21 -0
  34. package/dist/lib/brain-migrate.d.ts.map +1 -0
  35. package/dist/lib/brain-migrate.js +137 -0
  36. package/dist/lib/brain-migrate.js.map +1 -0
  37. package/dist/lib/paths.d.ts +27 -0
  38. package/dist/lib/paths.d.ts.map +1 -1
  39. package/dist/lib/paths.js +65 -0
  40. package/dist/lib/paths.js.map +1 -1
  41. package/dist/llm/call-log.d.ts +40 -0
  42. package/dist/llm/call-log.d.ts.map +1 -0
  43. package/dist/llm/call-log.js +35 -0
  44. package/dist/llm/call-log.js.map +1 -0
  45. package/dist/llm/complete.d.ts +6 -0
  46. package/dist/llm/complete.d.ts.map +1 -1
  47. package/dist/llm/complete.js +27 -0
  48. package/dist/llm/complete.js.map +1 -1
  49. package/dist/mcp-server.js +118 -2
  50. package/dist/mcp-server.js.map +1 -1
  51. package/dist/memory/file-backed.d.ts +4 -0
  52. package/dist/memory/file-backed.d.ts.map +1 -1
  53. package/dist/memory/file-backed.js +4 -0
  54. package/dist/memory/file-backed.js.map +1 -1
  55. package/dist/memory/vector-index.d.ts +4 -12
  56. package/dist/memory/vector-index.d.ts.map +1 -1
  57. package/dist/memory/vector-index.js +11 -93
  58. package/dist/memory/vector-index.js.map +1 -1
  59. package/dist/search/brain-docs.d.ts +17 -7
  60. package/dist/search/brain-docs.d.ts.map +1 -1
  61. package/dist/search/brain-docs.js +170 -52
  62. package/dist/search/brain-docs.js.map +1 -1
  63. package/dist/search/brain-rag.d.ts +45 -0
  64. package/dist/search/brain-rag.d.ts.map +1 -0
  65. package/dist/search/brain-rag.js +275 -0
  66. package/dist/search/brain-rag.js.map +1 -0
  67. package/dist/search/chunker.d.ts +24 -0
  68. package/dist/search/chunker.d.ts.map +1 -0
  69. package/dist/search/chunker.js +95 -0
  70. package/dist/search/chunker.js.map +1 -0
  71. package/dist/search/embedder.d.ts +16 -0
  72. package/dist/search/embedder.d.ts.map +1 -0
  73. package/dist/search/embedder.js +108 -0
  74. package/dist/search/embedder.js.map +1 -0
  75. package/dist/search/file-watcher.d.ts +11 -0
  76. package/dist/search/file-watcher.d.ts.map +1 -0
  77. package/dist/search/file-watcher.js +86 -0
  78. package/dist/search/file-watcher.js.map +1 -0
  79. package/dist/server.d.ts.map +1 -1
  80. package/dist/server.js +814 -472
  81. package/dist/server.js.map +1 -1
  82. package/dist/sessions/store.d.ts +9 -0
  83. package/dist/sessions/store.d.ts.map +1 -1
  84. package/dist/sessions/store.js.map +1 -1
  85. package/dist/settings.d.ts +26 -0
  86. package/dist/settings.d.ts.map +1 -1
  87. package/dist/settings.js +78 -2
  88. package/dist/settings.js.map +1 -1
  89. package/dist/tracing/init.d.ts +1 -1
  90. package/dist/tracing/init.d.ts.map +1 -1
  91. package/dist/utils/logger.js +2 -2
  92. package/dist/utils/logger.js.map +1 -1
  93. package/module-tiers.json +164 -0
  94. package/package.json +9 -13
  95. package/public/avatar/cache/1184385ec5522b57.mp4 +0 -0
  96. package/public/avatar/cache/1f15f6a1ebd7e439.mp4 +0 -0
  97. package/public/avatar/cache/2c7e47ff0bdeb8d1.mp4 +0 -0
  98. package/public/avatar/cache/5f308566f7abb8f2.mp4 +0 -0
  99. package/public/avatar/cache/62f9cfba848d724e.mp4 +0 -0
  100. package/public/avatar/cache/6d64e657e6bf2aab.mp4 +0 -0
  101. package/public/avatar/cache/763ad0349e0b6f26.mp4 +0 -0
  102. package/public/avatar/cache/81a516cfd461b2b9.mp4 +0 -0
  103. package/public/avatar/cache/9366de15fd6910ca.mp4 +0 -0
  104. package/public/avatar/cache/ade41a846b283895.mp4 +0 -0
  105. package/public/avatar/cache/b6066e5c65383eec.mp4 +0 -0
  106. package/public/avatar/cache/edadb75d37891fc7.mp4 +0 -0
  107. package/public/avatar/cache/f0ae159640621dd9.mp4 +0 -0
  108. package/public/avatar/cache/fc2e5419adf29d96.mp4 +0 -0
  109. package/public/index.html +379 -59
  110. package/dist/agents/autonomous.js +0 -749
  111. package/dist/agents/autonomous.js.map +0 -1
  112. package/dist/agents/commit.js +0 -113
  113. package/dist/agents/commit.js.map +0 -1
  114. package/dist/agents/continue.js +0 -158
  115. package/dist/agents/continue.js.map +0 -1
  116. package/dist/agents/cooldown.js +0 -397
  117. package/dist/agents/cooldown.js.map +0 -1
  118. package/dist/agents/dedup-guard.js +0 -131
  119. package/dist/agents/dedup-guard.js.map +0 -1
  120. package/dist/agents/feed.js +0 -176
  121. package/dist/agents/feed.js.map +0 -1
  122. package/dist/agents/governance.js +0 -292
  123. package/dist/agents/governance.js.map +0 -1
  124. package/dist/agents/governed-spawn.js +0 -192
  125. package/dist/agents/governed-spawn.js.map +0 -1
  126. package/dist/agents/heartbeat.js +0 -324
  127. package/dist/agents/heartbeat.js.map +0 -1
  128. package/dist/agents/instance-manager.js +0 -850
  129. package/dist/agents/instance-manager.js.map +0 -1
  130. package/dist/agents/issue-reporter.js +0 -123
  131. package/dist/agents/issue-reporter.js.map +0 -1
  132. package/dist/agents/issues.js +0 -141
  133. package/dist/agents/issues.js.map +0 -1
  134. package/dist/agents/locks.js +0 -234
  135. package/dist/agents/locks.js.map +0 -1
  136. package/dist/agents/memory.js +0 -93
  137. package/dist/agents/memory.js.map +0 -1
  138. package/dist/agents/monitor.js +0 -235
  139. package/dist/agents/monitor.js.map +0 -1
  140. package/dist/agents/orchestration.js +0 -715
  141. package/dist/agents/orchestration.js.map +0 -1
  142. package/dist/agents/recover.js +0 -166
  143. package/dist/agents/recover.js.map +0 -1
  144. package/dist/agents/reflection.js +0 -199
  145. package/dist/agents/reflection.js.map +0 -1
  146. package/dist/agents/runtime/bus.js +0 -174
  147. package/dist/agents/runtime/bus.js.map +0 -1
  148. package/dist/agents/runtime/config.js +0 -101
  149. package/dist/agents/runtime/config.js.map +0 -1
  150. package/dist/agents/runtime/driver.js +0 -214
  151. package/dist/agents/runtime/driver.js.map +0 -1
  152. package/dist/agents/runtime/errors.js +0 -40
  153. package/dist/agents/runtime/errors.js.map +0 -1
  154. package/dist/agents/runtime/index.js +0 -54
  155. package/dist/agents/runtime/index.js.map +0 -1
  156. package/dist/agents/runtime/lifecycle.js +0 -116
  157. package/dist/agents/runtime/lifecycle.js.map +0 -1
  158. package/dist/agents/runtime/manager.js +0 -948
  159. package/dist/agents/runtime/manager.js.map +0 -1
  160. package/dist/agents/runtime/registry.js +0 -195
  161. package/dist/agents/runtime/registry.js.map +0 -1
  162. package/dist/agents/runtime/resources.js +0 -146
  163. package/dist/agents/runtime/resources.js.map +0 -1
  164. package/dist/agents/runtime/types.js +0 -24
  165. package/dist/agents/runtime/types.js.map +0 -1
  166. package/dist/agents/spawn-policy.js +0 -202
  167. package/dist/agents/spawn-policy.js.map +0 -1
  168. package/dist/agents/spawn.js +0 -970
  169. package/dist/agents/spawn.js.map +0 -1
  170. package/dist/agents/triage.js +0 -81
  171. package/dist/agents/triage.js.map +0 -1
  172. package/dist/agents/workflow.js +0 -543
  173. package/dist/agents/workflow.js.map +0 -1
  174. package/dist/avatar/client.js +0 -172
  175. package/dist/avatar/client.js.map +0 -1
  176. package/dist/avatar/sidecar.js +0 -125
  177. package/dist/avatar/sidecar.js.map +0 -1
  178. package/dist/browser/sessions.js +0 -122
  179. package/dist/browser/sessions.js.map +0 -1
  180. package/dist/capabilities/definitions/browser.js +0 -242
  181. package/dist/capabilities/definitions/browser.js.map +0 -1
  182. package/dist/channels/whatsapp.js +0 -200
  183. package/dist/channels/whatsapp.js.map +0 -1
  184. package/dist/credentials/store.js +0 -189
  185. package/dist/credentials/store.js.map +0 -1
  186. package/dist/files/deep-index.js +0 -337
  187. package/dist/files/deep-index.js.map +0 -1
  188. package/dist/files/extract.js +0 -33
  189. package/dist/files/extract.js.map +0 -1
  190. package/dist/files/gdrive.js +0 -246
  191. package/dist/files/gdrive.js.map +0 -1
  192. package/dist/github/client.js +0 -408
  193. package/dist/github/client.js.map +0 -1
  194. package/dist/github/commit-analysis.js +0 -276
  195. package/dist/github/commit-analysis.js.map +0 -1
  196. package/dist/github/contributor-stats.js +0 -119
  197. package/dist/github/contributor-stats.js.map +0 -1
  198. package/dist/github/issue-sla.js +0 -220
  199. package/dist/github/issue-sla.js.map +0 -1
  200. package/dist/github/issue-triage.js +0 -286
  201. package/dist/github/issue-triage.js.map +0 -1
  202. package/dist/github/pr-readiness.js +0 -197
  203. package/dist/github/pr-readiness.js.map +0 -1
  204. package/dist/github/pr-review.js +0 -410
  205. package/dist/github/pr-review.js.map +0 -1
  206. package/dist/github/release-notes.js +0 -227
  207. package/dist/github/release-notes.js.map +0 -1
  208. package/dist/github/repo-health.js +0 -303
  209. package/dist/github/repo-health.js.map +0 -1
  210. package/dist/github/retry.js +0 -117
  211. package/dist/github/retry.js.map +0 -1
  212. package/dist/github/types.js +0 -8
  213. package/dist/github/types.js.map +0 -1
  214. package/dist/github/webhooks.js +0 -153
  215. package/dist/github/webhooks.js.map +0 -1
  216. package/dist/google/auth.js +0 -325
  217. package/dist/google/auth.js.map +0 -1
  218. package/dist/google/calendar-timer.js +0 -91
  219. package/dist/google/calendar-timer.js.map +0 -1
  220. package/dist/google/calendar.js +0 -270
  221. package/dist/google/calendar.js.map +0 -1
  222. package/dist/google/docs.js +0 -309
  223. package/dist/google/docs.js.map +0 -1
  224. package/dist/google/gmail-send.js +0 -219
  225. package/dist/google/gmail-send.js.map +0 -1
  226. package/dist/google/gmail-timer.js +0 -223
  227. package/dist/google/gmail-timer.js.map +0 -1
  228. package/dist/google/gmail.js +0 -470
  229. package/dist/google/gmail.js.map +0 -1
  230. package/dist/google/plugin.js +0 -169
  231. package/dist/google/plugin.js.map +0 -1
  232. package/dist/google/tasks-timer.js +0 -107
  233. package/dist/google/tasks-timer.js.map +0 -1
  234. package/dist/google/tasks.js +0 -331
  235. package/dist/google/tasks.js.map +0 -1
  236. package/dist/google/temporal.js +0 -176
  237. package/dist/google/temporal.js.map +0 -1
  238. package/dist/integrations/gate.js +0 -100
  239. package/dist/integrations/gate.js.map +0 -1
  240. package/dist/integrations/github.js +0 -331
  241. package/dist/integrations/github.js.map +0 -1
  242. package/dist/integrations/google-tasks.js +0 -432
  243. package/dist/integrations/google-tasks.js.map +0 -1
  244. package/dist/mdns.js +0 -110
  245. package/dist/mdns.js.map +0 -1
  246. package/dist/notifications/channel.js +0 -83
  247. package/dist/notifications/channel.js.map +0 -1
  248. package/dist/notifications/channels/adapter.js +0 -55
  249. package/dist/notifications/channels/adapter.js.map +0 -1
  250. package/dist/notifications/channels/index.js +0 -6
  251. package/dist/notifications/channels/index.js.map +0 -1
  252. package/dist/notifications/channels/log.js +0 -29
  253. package/dist/notifications/channels/log.js.map +0 -1
  254. package/dist/notifications/email.js +0 -72
  255. package/dist/notifications/email.js.map +0 -1
  256. package/dist/notifications/engine.js +0 -198
  257. package/dist/notifications/engine.js.map +0 -1
  258. package/dist/notifications/index.js +0 -24
  259. package/dist/notifications/index.js.map +0 -1
  260. package/dist/notifications/phone.js +0 -48
  261. package/dist/notifications/phone.js.map +0 -1
  262. package/dist/notifications/sms.js +0 -65
  263. package/dist/notifications/sms.js.map +0 -1
  264. package/dist/notifications/types.js +0 -14
  265. package/dist/notifications/types.js.map +0 -1
  266. package/dist/notifications/webhook.js +0 -65
  267. package/dist/notifications/webhook.js.map +0 -1
  268. package/dist/resend/inbox.js +0 -199
  269. package/dist/resend/inbox.js.map +0 -1
  270. package/dist/resend/webhooks.js +0 -244
  271. package/dist/resend/webhooks.js.map +0 -1
  272. package/dist/search/browse.js +0 -225
  273. package/dist/search/browse.js.map +0 -1
  274. package/dist/search/perplexity.js +0 -41
  275. package/dist/search/perplexity.js.map +0 -1
  276. package/dist/slack/channels.js +0 -277
  277. package/dist/slack/channels.js.map +0 -1
  278. package/dist/slack/client.js +0 -468
  279. package/dist/slack/client.js.map +0 -1
  280. package/dist/slack/retry.js +0 -100
  281. package/dist/slack/retry.js.map +0 -1
  282. package/dist/slack/types.js +0 -52
  283. package/dist/slack/types.js.map +0 -1
  284. package/dist/slack/webhooks.js +0 -285
  285. package/dist/slack/webhooks.js.map +0 -1
  286. package/dist/stt/client.js +0 -66
  287. package/dist/stt/client.js.map +0 -1
  288. package/dist/stt/sidecar.js +0 -115
  289. package/dist/stt/sidecar.js.map +0 -1
  290. package/dist/tracing/bridge.js +0 -70
  291. package/dist/tracing/bridge.js.map +0 -1
  292. package/dist/tracing/correlation.js +0 -49
  293. package/dist/tracing/correlation.js.map +0 -1
  294. package/dist/tracing/index.js +0 -18
  295. package/dist/tracing/index.js.map +0 -1
  296. package/dist/tracing/init.js +0 -81
  297. package/dist/tracing/init.js.map +0 -1
  298. package/dist/tracing/instrument.js +0 -145
  299. package/dist/tracing/instrument.js.map +0 -1
  300. package/dist/tracing/middleware.js +0 -69
  301. package/dist/tracing/middleware.js.map +0 -1
  302. package/dist/tracing/tracer.js +0 -327
  303. package/dist/tracing/tracer.js.map +0 -1
  304. package/dist/tts/client.js +0 -48
  305. package/dist/tts/client.js.map +0 -1
  306. package/dist/tts/sidecar.js +0 -148
  307. package/dist/tts/sidecar.js.map +0 -1
  308. package/dist/twilio/call.js +0 -79
  309. package/dist/twilio/call.js.map +0 -1
  310. package/dist/vault/matcher.js +0 -197
  311. package/dist/vault/matcher.js.map +0 -1
  312. package/dist/vault/personal.js +0 -163
  313. package/dist/vault/personal.js.map +0 -1
  314. package/dist/vault/policy.js +0 -159
  315. package/dist/vault/policy.js.map +0 -1
  316. package/dist/vault/store.js +0 -122
  317. package/dist/vault/store.js.map +0 -1
  318. package/dist/vault/transfer.js +0 -188
  319. package/dist/vault/transfer.js.map +0 -1
  320. package/dist/volumes/index.js +0 -2
  321. package/dist/volumes/index.js.map +0 -1
  322. package/dist/volumes/manager.js +0 -462
  323. package/dist/volumes/manager.js.map +0 -1
  324. package/dist/volumes/types.js +0 -8
  325. package/dist/volumes/types.js.map +0 -1
  326. package/dist/webhooks/config.js +0 -214
  327. package/dist/webhooks/config.js.map +0 -1
  328. package/dist/webhooks/event-log.js +0 -132
  329. package/dist/webhooks/event-log.js.map +0 -1
  330. package/dist/webhooks/handler.js +0 -103
  331. package/dist/webhooks/handler.js.map +0 -1
  332. package/dist/webhooks/handlers.js +0 -231
  333. package/dist/webhooks/handlers.js.map +0 -1
  334. package/dist/webhooks/index.js +0 -33
  335. package/dist/webhooks/index.js.map +0 -1
  336. package/dist/webhooks/mount.js +0 -400
  337. package/dist/webhooks/mount.js.map +0 -1
  338. package/dist/webhooks/registry.js +0 -143
  339. package/dist/webhooks/registry.js.map +0 -1
  340. package/dist/webhooks/relay.js +0 -53
  341. package/dist/webhooks/relay.js.map +0 -1
  342. package/dist/webhooks/retry.js +0 -270
  343. package/dist/webhooks/retry.js.map +0 -1
  344. package/dist/webhooks/router.js +0 -290
  345. package/dist/webhooks/router.js.map +0 -1
  346. package/dist/webhooks/twilio.js +0 -129
  347. package/dist/webhooks/twilio.js.map +0 -1
  348. package/dist/webhooks/types.js +0 -8
  349. package/dist/webhooks/types.js.map +0 -1
  350. package/dist/webhooks/verify.js +0 -154
  351. package/dist/webhooks/verify.js.map +0 -1
@@ -2,49 +2,135 @@
2
2
  * Brain document finder — auto-detects document references in user messages
3
3
  * and resolves them to actual brain files.
4
4
  *
5
- * Parallels how calendar/email/board keywords trigger context injection.
6
- * Scans brain/content/drafts, brain/knowledge/notes, brain/knowledge/research,
7
- * and brain/knowledge/protocols for matching filenames.
5
+ * Three search modes (in priority order):
6
+ * 1. RAG semantic search — fast, uses pre-computed embeddings
7
+ * 2. Filename/path match keyword scoring on filenames and directories
8
+ * 3. Keyword content scan — REMOVED (replaced by RAG)
9
+ *
10
+ * Returns best matching file + sibling listing (option B from spec).
8
11
  */
9
12
  import { readdir } from "node:fs/promises";
10
- import { join, basename } from "node:path";
13
+ import { join, basename, dirname } from "node:path";
11
14
  import { readBrainFile } from "../lib/brain-io.js";
12
- import { BRAIN_DIR } from "../lib/paths.js";
13
- /** Directories to scan for documents the user might reference by description. */
14
- const DOC_DIRS = [
15
- join(BRAIN_DIR, "content", "drafts"),
16
- join(BRAIN_DIR, "knowledge", "notes"),
17
- join(BRAIN_DIR, "knowledge", "research"),
18
- join(BRAIN_DIR, "knowledge", "protocols"),
19
- ];
20
- /** Does the message reference a document, paper, draft, note, or similar? */
21
- const DOC_REF_PATTERN = /\b(read|show|open|pull up|find|get|load|look at|check)\b.*\b(paper|draft|doc|document|note|post|thread|whitepaper|positioning|writeup|write-?up|article|research|report)\b/i;
22
- /**
23
- * Tokenize a user message into searchable keywords.
24
- * Strips common verbs/articles, returns lowercase stems.
25
- */
15
+ import { createLogger } from "../utils/logger.js";
16
+ const log = createLogger("brain-docs");
17
+ // ── Module-level RAG reference (set during server init) ──────────────────────
18
+ let _rag = null;
19
+ /** Wire the BrainRAG instance. Called once during server startup. */
20
+ export function setBrainRAG(rag) {
21
+ _rag = rag;
22
+ }
23
+ // ── Patterns ─────────────────────────────────────────────────────────────────
24
+ /** Explicit document reference — "read my paper", "show the draft", etc. */
25
+ const DOC_REF_PATTERN = /\b(read|show|open|pull up|find|get|load|look at|check)\b.*\b(paper|draft|doc|document|note|post|thread|whitepaper|positioning|writeup|write-?up|article|research|report|book|chapter|spec)\b/i;
26
+ /** Question about brain knowledge "which book", "what does X say", "where is the" */
27
+ const KNOWLEDGE_QUESTION_PATTERN = /\b(which|what|where|how|did|does|do|have|is|are|tell me|remind me)\b.*\b(book|chapter|spec|paper|draft|note|plan|goal|roadmap|decision|protocol|template|principle|identity|series|write|wrote|writing|document|research|finance|govern)\b/i;
28
+ // ── Keyword extraction ───────────────────────────────────────────────────────
26
29
  function extractKeywords(message) {
27
30
  const stopWords = new Set([
28
31
  "the", "a", "an", "my", "our", "that", "this", "it", "its",
29
32
  "read", "show", "open", "pull", "up", "find", "get", "load",
30
33
  "look", "at", "check", "can", "you", "me", "for", "about",
31
34
  "please", "and", "or", "in", "on", "to", "of", "with",
35
+ "which", "what", "where", "how", "did", "does", "have",
36
+ "is", "are", "tell", "remind", "we", "were", "was", "been",
37
+ "do", "not", "but", "from", "who", "they",
32
38
  ]);
33
- return message
39
+ const tokens = message
34
40
  .toLowerCase()
35
41
  .replace(/[^a-z0-9\s-]/g, " ")
36
42
  .split(/\s+/)
37
- .filter((w) => w.length > 2 && !stopWords.has(w));
43
+ .filter(Boolean);
44
+ const keywords = [];
45
+ for (let i = 0; i < tokens.length; i++) {
46
+ const t = tokens[i];
47
+ if (/^\d+$/.test(t)) {
48
+ keywords.push(t);
49
+ if (i > 0 && keywords.length >= 2) {
50
+ const prev = keywords[keywords.length - 2];
51
+ if (!/^\d+$/.test(prev)) {
52
+ keywords.push(prev + t);
53
+ }
54
+ }
55
+ }
56
+ else if (t.length > 2 && !stopWords.has(t)) {
57
+ keywords.push(t);
58
+ }
59
+ }
60
+ return keywords;
38
61
  }
62
+ // ── Main search ──────────────────────────────────────────────────────────────
39
63
  /**
40
- * Score how well a filename matches a set of keywords.
41
- * Filename is split on hyphens/underscores/dots and compared to keywords.
64
+ * Search brain files for the best match to the user's message.
65
+ *
66
+ * Priority:
67
+ * 1. RAG semantic search (if available and indexed)
68
+ * 2. Keyword filename match (fallback)
42
69
  */
43
- function scoreMatch(filename, keywords) {
70
+ export async function findBrainDocument(message) {
71
+ const keywords = extractKeywords(message);
72
+ const docMatch = DOC_REF_PATTERN.test(message);
73
+ const knowledgeMatch = KNOWLEDGE_QUESTION_PATTERN.test(message);
74
+ log.info(`findBrainDocument: keywords=[${keywords.join(",")}] docRef=${docMatch} knowledgeQ=${knowledgeMatch}`);
75
+ if (!docMatch && !knowledgeMatch) {
76
+ log.info("No pattern matched — skipping brain doc search");
77
+ return null;
78
+ }
79
+ // ── Mode 1: RAG semantic search ──────────────────────────────────────────
80
+ if (_rag && _rag.ready) {
81
+ try {
82
+ log.info("Trying RAG semantic search...");
83
+ const results = await _rag.query(message, 5);
84
+ if (results.length > 0) {
85
+ const best = results[0];
86
+ log.info(`RAG hit: ${best.filePath} (score: ${best.score.toFixed(3)})${best.siblings ? `, ${best.siblings.length} siblings` : ""}`);
87
+ const content = await readBrainFile(best.fullPath);
88
+ const filename = basename(best.filePath);
89
+ // Build sibling listing
90
+ let siblings;
91
+ if (best.siblings && best.siblings.length > 0) {
92
+ siblings = best.siblings;
93
+ }
94
+ return { path: best.fullPath, filename, content, siblings };
95
+ }
96
+ log.info("RAG returned no results above threshold");
97
+ }
98
+ catch (err) {
99
+ log.error("RAG search failed, falling back to keyword match", {
100
+ error: err instanceof Error ? err.message : String(err),
101
+ });
102
+ }
103
+ }
104
+ else {
105
+ log.info("RAG not available, using keyword fallback");
106
+ }
107
+ // ── Mode 2: Keyword filename match (fallback) ───────────────────────────
108
+ if (keywords.length === 0)
109
+ return null;
110
+ return keywordFilenameSearch(keywords);
111
+ }
112
+ // ── Keyword filename fallback ────────────────────────────────────────────────
113
+ import { stat as fsStat } from "node:fs/promises";
114
+ import { FILES_DIR, resolveBrainDir } from "../lib/paths.js";
115
+ const DOC_DIRS = [
116
+ FILES_DIR,
117
+ resolveBrainDir("content"),
118
+ resolveBrainDir("knowledge"),
119
+ resolveBrainDir("identity"),
120
+ resolveBrainDir("operations"),
121
+ resolveBrainDir("skills"),
122
+ resolveBrainDir("templates"),
123
+ ];
124
+ const SEARCHABLE_EXTS = new Set([".md", ".yaml", ".yml", ".txt", ".json"]);
125
+ const SKIP_DIRS = new Set([
126
+ "node_modules", ".git", ".obsidian", "logs", "tasks",
127
+ "daily", "hourly", "memory", "ops", "metrics", "ledger",
128
+ ]);
129
+ function scoreFilename(filename, keywords) {
44
130
  const parts = basename(filename, ".md")
45
131
  .toLowerCase()
46
132
  .split(/[-_.]/)
47
- .filter((p) => p.length > 2);
133
+ .filter((p) => p.length > 0);
48
134
  let score = 0;
49
135
  for (const kw of keywords) {
50
136
  for (const part of parts) {
@@ -54,46 +140,78 @@ function scoreMatch(filename, keywords) {
54
140
  }
55
141
  return score;
56
142
  }
57
- /**
58
- * Search brain document directories for files matching the user's message.
59
- * Returns the best match (if any) with its content loaded.
60
- */
61
- export async function findBrainDocument(message) {
62
- // Only trigger on messages that reference a document
63
- if (!DOC_REF_PATTERN.test(message))
64
- return null;
65
- const keywords = extractKeywords(message);
66
- if (keywords.length === 0)
67
- return null;
68
- // Scan all doc directories, collect candidates
69
- const candidates = [];
70
- for (const dir of DOC_DIRS) {
143
+ async function collectFiles(dir) {
144
+ const results = [];
145
+ async function walk(d) {
146
+ let entries;
71
147
  try {
72
- const files = await readdir(dir);
73
- for (const file of files) {
74
- if (!file.endsWith(".md"))
75
- continue;
76
- const score = scoreMatch(file, keywords);
77
- if (score > 0) {
78
- candidates.push({ path: join(dir, file), filename: file, score });
148
+ entries = await readdir(d);
149
+ }
150
+ catch {
151
+ return;
152
+ }
153
+ for (const name of entries) {
154
+ if (name.startsWith(".") && name !== ".config")
155
+ continue;
156
+ if (SKIP_DIRS.has(name))
157
+ continue;
158
+ const full = join(d, name);
159
+ try {
160
+ const s = await fsStat(full);
161
+ if (s.isDirectory()) {
162
+ await walk(full);
163
+ }
164
+ else {
165
+ const ext = name.substring(name.lastIndexOf(".")).toLowerCase();
166
+ if (SEARCHABLE_EXTS.has(ext) && s.size < 500_000) {
167
+ results.push({ path: full, filename: name });
168
+ }
79
169
  }
80
170
  }
171
+ catch {
172
+ continue;
173
+ }
81
174
  }
82
- catch {
83
- // Directory might not exist — skip
175
+ }
176
+ await walk(dir);
177
+ return results;
178
+ }
179
+ async function keywordFilenameSearch(keywords) {
180
+ const candidates = [];
181
+ const seen = new Set();
182
+ for (const dir of DOC_DIRS) {
183
+ if (seen.has(dir))
184
+ continue;
185
+ seen.add(dir);
186
+ const files = await collectFiles(dir);
187
+ for (const file of files) {
188
+ const parentDir = basename(dirname(file.path));
189
+ const score = scoreFilename(file.filename, keywords) + scoreFilename(parentDir, keywords);
190
+ if (score > 0) {
191
+ candidates.push({ ...file, score });
192
+ }
84
193
  }
85
194
  }
86
195
  if (candidates.length === 0)
87
196
  return null;
88
- // Sort by score descending, take the best match
89
197
  candidates.sort((a, b) => b.score - a.score);
90
- const best = candidates[0];
91
- // Require at least 2 keyword hits to avoid false positives
92
- if (best.score < 2)
198
+ log.info(`Keyword fallback: ${candidates.length} candidates, best: ${candidates[0].filename} (score: ${candidates[0].score})`);
199
+ if (candidates[0].score < 2)
93
200
  return null;
94
201
  try {
202
+ const best = candidates[0];
95
203
  const content = await readBrainFile(best.path);
96
- return { path: best.path, filename: best.filename, content };
204
+ // Sibling listing
205
+ const dir = dirname(best.path);
206
+ let siblings;
207
+ try {
208
+ const entries = await readdir(dir);
209
+ const sibs = entries.filter((e) => e !== best.filename);
210
+ if (sibs.length > 0)
211
+ siblings = sibs;
212
+ }
213
+ catch { /* ignore */ }
214
+ return { path: best.path, filename: best.filename, content, siblings };
97
215
  }
98
216
  catch {
99
217
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"brain-docs.js","sourceRoot":"","sources":["../../src/search/brain-docs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"brain-docs.js","sourceRoot":"","sources":["../../src/search/brain-docs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Brain RAG — semantic retrieval for brain files.
3
+ *
4
+ * Indexes brain files into chunks with Ollama embeddings.
5
+ * Stores in brain/memory/file-embeddings.jsonl (append-only).
6
+ * In-memory cosine similarity search over chunk vectors.
7
+ *
8
+ * The vector index is a derived cache. Delete the file, re-index from brain.
9
+ */
10
+ export interface RAGResult {
11
+ filePath: string;
12
+ heading: string;
13
+ chunk: string;
14
+ score: number;
15
+ fullPath: string;
16
+ /** Other files in the same directory (sibling listing for option B) */
17
+ siblings?: string[];
18
+ }
19
+ export declare class BrainRAG {
20
+ private chunks;
21
+ /** Track mtime per file so we know what's stale */
22
+ private fileMtimes;
23
+ private embeddingsPath;
24
+ private _ready;
25
+ constructor();
26
+ get ready(): boolean;
27
+ /** Load existing embeddings from disk. Fast — no Ollama needed. */
28
+ load(): Promise<void>;
29
+ /** Full index: scan all brain files, chunk and embed anything new or changed. */
30
+ indexAll(): Promise<{
31
+ indexed: number;
32
+ skipped: number;
33
+ errors: number;
34
+ }>;
35
+ /** Read file content, handling PDFs (text and scanned) specially. */
36
+ private readFileContent;
37
+ /** Index a single file: chunk, embed, persist. */
38
+ indexFile(filePath: string): Promise<void>;
39
+ /** Semantic search: embed query, return top-k file chunks with scores. */
40
+ query(text: string, topK?: number): Promise<RAGResult[]>;
41
+ /** Force re-index: clear in-memory state and rebuild from files. */
42
+ reindex(): Promise<void>;
43
+ private collectFiles;
44
+ }
45
+ //# sourceMappingURL=brain-rag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain-rag.d.ts","sourceRoot":"","sources":["../../src/search/brain-rag.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA4DH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAID,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAkC;IAChD,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,MAAM,CAAS;;IAMvB,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,mEAAmE;IAC7D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B3B,iFAAiF;IAC3E,QAAQ,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA0C/E,qEAAqE;YACvD,eAAe;IAsB7B,kDAAkD;IAC5C,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4ChD,0EAA0E;IACpE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAoDzD,oEAAoE;IAC9D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAQhB,YAAY;CA2B3B"}
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Brain RAG — semantic retrieval for brain files.
3
+ *
4
+ * Indexes brain files into chunks with Ollama embeddings.
5
+ * Stores in brain/memory/file-embeddings.jsonl (append-only).
6
+ * In-memory cosine similarity search over chunk vectors.
7
+ *
8
+ * The vector index is a derived cache. Delete the file, re-index from brain.
9
+ */
10
+ import { join, relative, basename, dirname } from "node:path";
11
+ import { readdir, stat } from "node:fs/promises";
12
+ import { createLogger } from "../utils/logger.js";
13
+ import { readBrainFile, readBrainLines, appendBrainLine } from "../lib/brain-io.js";
14
+ import { BRAIN_DIR, FILES_DIR, resolveBrainDir } from "../lib/paths.js";
15
+ import { embed, embedBatch, isOllamaAvailable, cosine } from "./embedder.js";
16
+ import { chunkMarkdown } from "./chunker.js";
17
+ import { readFile } from "node:fs/promises";
18
+ import { extractPdfText, extractImageText } from "../files/extract.js";
19
+ const log = createLogger("brain-rag");
20
+ const FILE_EMBEDDINGS = "file-embeddings.jsonl";
21
+ const BATCH_SIZE = 10;
22
+ const SEARCHABLE_EXTS = new Set([".md", ".yaml", ".yml", ".txt", ".pdf"]);
23
+ const SKIP_DIRS = new Set([
24
+ "node_modules", ".git", ".obsidian", "logs", "tasks",
25
+ "daily", "hourly", "memory", "ops", "metrics", "ledger",
26
+ ".config",
27
+ ]);
28
+ const MAX_FILE_SIZE = 500_000; // 500KB
29
+ /** Directories to scan for brain files. */
30
+ const SCAN_DIRS = [
31
+ FILES_DIR,
32
+ resolveBrainDir("content"),
33
+ resolveBrainDir("knowledge"),
34
+ resolveBrainDir("identity"),
35
+ resolveBrainDir("operations"),
36
+ resolveBrainDir("skills"),
37
+ resolveBrainDir("templates"),
38
+ ];
39
+ // ── BrainRAG class ───────────────────────────────────────────────────────────
40
+ export class BrainRAG {
41
+ chunks = new Map();
42
+ /** Track mtime per file so we know what's stale */
43
+ fileMtimes = new Map();
44
+ embeddingsPath;
45
+ _ready = false;
46
+ constructor() {
47
+ this.embeddingsPath = join(BRAIN_DIR, "memory", FILE_EMBEDDINGS);
48
+ }
49
+ get ready() {
50
+ return this._ready;
51
+ }
52
+ /** Load existing embeddings from disk. Fast — no Ollama needed. */
53
+ async load() {
54
+ const lines = await readBrainLines(this.embeddingsPath);
55
+ let loaded = 0;
56
+ for (const line of lines) {
57
+ try {
58
+ const entry = JSON.parse(line);
59
+ if (!entry.id || !entry.v)
60
+ continue;
61
+ // Last-write-wins: later lines for same ID supersede earlier
62
+ this.chunks.set(entry.id, {
63
+ id: entry.id,
64
+ filePath: entry.filePath,
65
+ heading: entry.heading,
66
+ index: entry.index,
67
+ mtime: entry.mtime,
68
+ vec: new Float32Array(entry.v),
69
+ });
70
+ // Track highest mtime per file
71
+ const existing = this.fileMtimes.get(entry.filePath) ?? 0;
72
+ if (entry.mtime > existing)
73
+ this.fileMtimes.set(entry.filePath, entry.mtime);
74
+ loaded++;
75
+ }
76
+ catch {
77
+ continue;
78
+ }
79
+ }
80
+ this._ready = true;
81
+ if (loaded > 0)
82
+ log.info(`Loaded ${this.chunks.size} chunk embeddings from disk`);
83
+ }
84
+ /** Full index: scan all brain files, chunk and embed anything new or changed. */
85
+ async indexAll() {
86
+ const available = await isOllamaAvailable();
87
+ if (!available) {
88
+ log.info("Ollama unavailable — skipping file indexing");
89
+ return { indexed: 0, skipped: 0, errors: 0 };
90
+ }
91
+ let indexed = 0;
92
+ let skipped = 0;
93
+ let errors = 0;
94
+ const seen = new Set();
95
+ for (const dir of SCAN_DIRS) {
96
+ if (seen.has(dir))
97
+ continue;
98
+ seen.add(dir);
99
+ const files = await this.collectFiles(dir);
100
+ for (const file of files) {
101
+ try {
102
+ const relPath = relative(BRAIN_DIR, file.path).replace(/\\/g, "/");
103
+ const existingMtime = this.fileMtimes.get(relPath) ?? 0;
104
+ if (file.mtime <= existingMtime) {
105
+ skipped++;
106
+ continue;
107
+ }
108
+ await this.indexFile(file.path);
109
+ indexed++;
110
+ }
111
+ catch (err) {
112
+ errors++;
113
+ log.error(`Failed to index ${file.path}`, {
114
+ error: err instanceof Error ? err.message : String(err),
115
+ });
116
+ }
117
+ }
118
+ }
119
+ log.info(`Index complete: ${indexed} indexed, ${skipped} skipped, ${errors} errors (${this.chunks.size} total chunks)`);
120
+ return { indexed, skipped, errors };
121
+ }
122
+ /** Read file content, handling PDFs (text and scanned) specially. */
123
+ async readFileContent(filePath) {
124
+ const ext = filePath.substring(filePath.lastIndexOf(".")).toLowerCase();
125
+ if (ext === ".pdf") {
126
+ const buffer = Buffer.from(await readFile(filePath));
127
+ // Try text extraction first
128
+ let text = await extractPdfText(buffer);
129
+ // If PDF is scanned (no extractable text), fall back to OCR
130
+ if (!text.trim() || text.trim().length < 50) {
131
+ try {
132
+ log.info(`PDF appears scanned, trying OCR: ${basename(filePath)}`);
133
+ text = await extractImageText(buffer);
134
+ }
135
+ catch (err) {
136
+ log.warn(`OCR failed for ${basename(filePath)}`, {
137
+ error: err instanceof Error ? err.message : String(err),
138
+ });
139
+ }
140
+ }
141
+ return text;
142
+ }
143
+ return readBrainFile(filePath);
144
+ }
145
+ /** Index a single file: chunk, embed, persist. */
146
+ async indexFile(filePath) {
147
+ const relPath = relative(BRAIN_DIR, filePath).replace(/\\/g, "/");
148
+ const content = await this.readFileContent(filePath);
149
+ const fileStat = await stat(filePath);
150
+ const mtime = fileStat.mtimeMs;
151
+ const fileChunks = chunkMarkdown(relPath, content);
152
+ if (fileChunks.length === 0)
153
+ return;
154
+ // Embed in batches
155
+ for (let i = 0; i < fileChunks.length; i += BATCH_SIZE) {
156
+ const batch = fileChunks.slice(i, i + BATCH_SIZE);
157
+ const texts = batch.map((c) => c.text);
158
+ const vecs = await embedBatch(texts);
159
+ for (let j = 0; j < batch.length; j++) {
160
+ const chunk = batch[j];
161
+ const record = {
162
+ id: chunk.id,
163
+ filePath: relPath,
164
+ heading: chunk.heading,
165
+ index: chunk.index,
166
+ mtime,
167
+ vec: vecs[j],
168
+ };
169
+ this.chunks.set(chunk.id, record);
170
+ // Persist
171
+ const line = {
172
+ id: chunk.id,
173
+ filePath: relPath,
174
+ heading: chunk.heading,
175
+ index: chunk.index,
176
+ mtime,
177
+ v: Array.from(vecs[j]),
178
+ };
179
+ await appendBrainLine(this.embeddingsPath, JSON.stringify(line));
180
+ }
181
+ }
182
+ this.fileMtimes.set(relPath, mtime);
183
+ log.info(`Indexed ${relPath}: ${fileChunks.length} chunks`);
184
+ }
185
+ /** Semantic search: embed query, return top-k file chunks with scores. */
186
+ async query(text, topK = 5) {
187
+ if (this.chunks.size === 0)
188
+ return [];
189
+ const queryVec = await embed(text);
190
+ const scored = [];
191
+ for (const record of this.chunks.values()) {
192
+ const score = cosine(queryVec, record.vec);
193
+ scored.push({ record, score });
194
+ }
195
+ scored.sort((a, b) => b.score - a.score);
196
+ const topResults = scored.slice(0, topK);
197
+ const results = [];
198
+ for (const { record, score } of topResults) {
199
+ if (score < 0.3)
200
+ continue; // threshold
201
+ const fullPath = join(BRAIN_DIR, record.filePath);
202
+ // Option B: sibling listing
203
+ const dir = dirname(fullPath);
204
+ let siblings;
205
+ try {
206
+ const entries = await readdir(dir);
207
+ const sibs = entries.filter((e) => e !== basename(record.filePath));
208
+ if (sibs.length > 0)
209
+ siblings = sibs;
210
+ }
211
+ catch { /* ignore */ }
212
+ results.push({
213
+ filePath: record.filePath,
214
+ heading: record.heading,
215
+ chunk: "", // caller reads full file; chunk text not persisted
216
+ score,
217
+ fullPath,
218
+ siblings,
219
+ });
220
+ }
221
+ // Deduplicate by filePath — keep highest score per file
222
+ const byFile = new Map();
223
+ for (const r of results) {
224
+ const existing = byFile.get(r.filePath);
225
+ if (!existing || r.score > existing.score) {
226
+ byFile.set(r.filePath, r);
227
+ }
228
+ }
229
+ return Array.from(byFile.values()).sort((a, b) => b.score - a.score);
230
+ }
231
+ /** Force re-index: clear in-memory state and rebuild from files. */
232
+ async reindex() {
233
+ this.chunks.clear();
234
+ this.fileMtimes.clear();
235
+ await this.indexAll();
236
+ }
237
+ // ── File collection ──────────────────────────────────────────────────────
238
+ async collectFiles(dir) {
239
+ const results = [];
240
+ const walk = async (d) => {
241
+ let entries;
242
+ try {
243
+ entries = await readdir(d);
244
+ }
245
+ catch {
246
+ return;
247
+ }
248
+ for (const name of entries) {
249
+ if (name.startsWith("."))
250
+ continue;
251
+ if (SKIP_DIRS.has(name))
252
+ continue;
253
+ const full = join(d, name);
254
+ try {
255
+ const s = await stat(full);
256
+ if (s.isDirectory()) {
257
+ await walk(full);
258
+ }
259
+ else {
260
+ const ext = name.substring(name.lastIndexOf(".")).toLowerCase();
261
+ if (SEARCHABLE_EXTS.has(ext) && s.size < MAX_FILE_SIZE) {
262
+ results.push({ path: full, mtime: s.mtimeMs });
263
+ }
264
+ }
265
+ }
266
+ catch {
267
+ continue;
268
+ }
269
+ }
270
+ };
271
+ await walk(dir);
272
+ return results;
273
+ }
274
+ }
275
+ //# sourceMappingURL=brain-rag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain-rag.js","sourceRoot":"","sources":["../../src/search/brain-rag.ts"],"names":[],"mappings":"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"}