@soederpop/luca 0.0.2

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 (358) hide show
  1. package/CLAUDE.md +71 -0
  2. package/README.md +78 -0
  3. package/bun.lock +2928 -0
  4. package/bunfig.toml +3 -0
  5. package/commands/audit-docs.ts +740 -0
  6. package/commands/build-scaffolds.ts +154 -0
  7. package/commands/generate-api-docs.ts +114 -0
  8. package/commands/update-introspection.ts +67 -0
  9. package/docs/CLI.md +335 -0
  10. package/docs/README.md +88 -0
  11. package/docs/TABLE-OF-CONTENTS.md +157 -0
  12. package/docs/apis/clients/elevenlabs.md +84 -0
  13. package/docs/apis/clients/graph.md +56 -0
  14. package/docs/apis/clients/openai.md +69 -0
  15. package/docs/apis/clients/rest.md +41 -0
  16. package/docs/apis/clients/websocket.md +107 -0
  17. package/docs/apis/features/agi/assistant.md +471 -0
  18. package/docs/apis/features/agi/assistants-manager.md +154 -0
  19. package/docs/apis/features/agi/claude-code.md +602 -0
  20. package/docs/apis/features/agi/conversation-history.md +352 -0
  21. package/docs/apis/features/agi/conversation.md +333 -0
  22. package/docs/apis/features/agi/docs-reader.md +121 -0
  23. package/docs/apis/features/agi/openai-codex.md +318 -0
  24. package/docs/apis/features/agi/openapi.md +138 -0
  25. package/docs/apis/features/agi/semantic-search.md +387 -0
  26. package/docs/apis/features/agi/skills-library.md +216 -0
  27. package/docs/apis/features/node/container-link.md +133 -0
  28. package/docs/apis/features/node/content-db.md +313 -0
  29. package/docs/apis/features/node/disk-cache.md +379 -0
  30. package/docs/apis/features/node/dns.md +651 -0
  31. package/docs/apis/features/node/docker.md +705 -0
  32. package/docs/apis/features/node/downloader.md +81 -0
  33. package/docs/apis/features/node/esbuild.md +59 -0
  34. package/docs/apis/features/node/file-manager.md +182 -0
  35. package/docs/apis/features/node/fs.md +581 -0
  36. package/docs/apis/features/node/git.md +330 -0
  37. package/docs/apis/features/node/google-auth.md +174 -0
  38. package/docs/apis/features/node/google-calendar.md +187 -0
  39. package/docs/apis/features/node/google-docs.md +151 -0
  40. package/docs/apis/features/node/google-drive.md +225 -0
  41. package/docs/apis/features/node/google-sheets.md +179 -0
  42. package/docs/apis/features/node/grep.md +290 -0
  43. package/docs/apis/features/node/helpers.md +135 -0
  44. package/docs/apis/features/node/ink.md +334 -0
  45. package/docs/apis/features/node/ipc-socket.md +260 -0
  46. package/docs/apis/features/node/json-tree.md +86 -0
  47. package/docs/apis/features/node/launcher-app-command-listener.md +145 -0
  48. package/docs/apis/features/node/networking.md +281 -0
  49. package/docs/apis/features/node/nlp.md +133 -0
  50. package/docs/apis/features/node/opener.md +97 -0
  51. package/docs/apis/features/node/os.md +118 -0
  52. package/docs/apis/features/node/package-finder.md +402 -0
  53. package/docs/apis/features/node/postgres.md +212 -0
  54. package/docs/apis/features/node/proc.md +430 -0
  55. package/docs/apis/features/node/process-manager.md +210 -0
  56. package/docs/apis/features/node/python.md +278 -0
  57. package/docs/apis/features/node/repl.md +88 -0
  58. package/docs/apis/features/node/runpod.md +673 -0
  59. package/docs/apis/features/node/secure-shell.md +169 -0
  60. package/docs/apis/features/node/semantic-search.md +401 -0
  61. package/docs/apis/features/node/sqlite.md +211 -0
  62. package/docs/apis/features/node/telegram.md +254 -0
  63. package/docs/apis/features/node/tts.md +118 -0
  64. package/docs/apis/features/node/ui.md +703 -0
  65. package/docs/apis/features/node/vault.md +64 -0
  66. package/docs/apis/features/node/vm.md +84 -0
  67. package/docs/apis/features/node/window-manager.md +337 -0
  68. package/docs/apis/features/node/yaml-tree.md +85 -0
  69. package/docs/apis/features/node/yaml.md +176 -0
  70. package/docs/apis/features/web/asset-loader.md +47 -0
  71. package/docs/apis/features/web/container-link.md +133 -0
  72. package/docs/apis/features/web/esbuild.md +59 -0
  73. package/docs/apis/features/web/helpers.md +135 -0
  74. package/docs/apis/features/web/network.md +30 -0
  75. package/docs/apis/features/web/speech.md +55 -0
  76. package/docs/apis/features/web/vault.md +64 -0
  77. package/docs/apis/features/web/vm.md +84 -0
  78. package/docs/apis/features/web/voice.md +67 -0
  79. package/docs/apis/servers/express.md +127 -0
  80. package/docs/apis/servers/mcp.md +213 -0
  81. package/docs/apis/servers/websocket.md +99 -0
  82. package/docs/documentation-audit.md +134 -0
  83. package/docs/examples/content-db.md +77 -0
  84. package/docs/examples/disk-cache.md +83 -0
  85. package/docs/examples/docker.md +101 -0
  86. package/docs/examples/downloader.md +70 -0
  87. package/docs/examples/esbuild.md +80 -0
  88. package/docs/examples/file-manager.md +82 -0
  89. package/docs/examples/fs.md +83 -0
  90. package/docs/examples/git.md +85 -0
  91. package/docs/examples/google-auth.md +88 -0
  92. package/docs/examples/google-calendar.md +94 -0
  93. package/docs/examples/google-docs.md +82 -0
  94. package/docs/examples/google-drive.md +96 -0
  95. package/docs/examples/google-sheets.md +95 -0
  96. package/docs/examples/grep.md +85 -0
  97. package/docs/examples/ink-blocks.md +75 -0
  98. package/docs/examples/ink-renderer.md +41 -0
  99. package/docs/examples/ink.md +103 -0
  100. package/docs/examples/ipc-socket.md +103 -0
  101. package/docs/examples/json-tree.md +91 -0
  102. package/docs/examples/launcher-app-command-listener.md +120 -0
  103. package/docs/examples/networking.md +58 -0
  104. package/docs/examples/nlp.md +91 -0
  105. package/docs/examples/opener.md +78 -0
  106. package/docs/examples/os.md +72 -0
  107. package/docs/examples/package-finder.md +89 -0
  108. package/docs/examples/port-exposer.md +89 -0
  109. package/docs/examples/postgres.md +91 -0
  110. package/docs/examples/proc.md +81 -0
  111. package/docs/examples/process-manager.md +79 -0
  112. package/docs/examples/python.md +91 -0
  113. package/docs/examples/repl.md +93 -0
  114. package/docs/examples/runpod.md +119 -0
  115. package/docs/examples/secure-shell.md +92 -0
  116. package/docs/examples/sqlite.md +86 -0
  117. package/docs/examples/telegram.md +77 -0
  118. package/docs/examples/tts.md +86 -0
  119. package/docs/examples/ui.md +80 -0
  120. package/docs/examples/vault.md +70 -0
  121. package/docs/examples/vm.md +86 -0
  122. package/docs/examples/window-manager.md +125 -0
  123. package/docs/examples/yaml-tree.md +93 -0
  124. package/docs/examples/yaml.md +104 -0
  125. package/docs/ideas/class-registration-refactor-possibilities.md +197 -0
  126. package/docs/ideas/container-use-api.md +9 -0
  127. package/docs/ideas/easy-auth-for-express-servers-and-luca-serve.md +0 -0
  128. package/docs/ideas/feature-stacks.md +22 -0
  129. package/docs/ideas/luca-cli-self-sufficiency-demo.md +23 -0
  130. package/docs/ideas/mcp-design.md +9 -0
  131. package/docs/ideas/web-container-debugging-feature.md +13 -0
  132. package/docs/introspection-audit.md +49 -0
  133. package/docs/introspection.md +154 -0
  134. package/docs/mcp/readme.md +162 -0
  135. package/docs/models.ts +38 -0
  136. package/docs/philosophy.md +85 -0
  137. package/docs/principles.md +7 -0
  138. package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +34 -0
  139. package/docs/prompts/mcp-test-easy-command.md +27 -0
  140. package/docs/reports/assistant-bugs.md +38 -0
  141. package/docs/reports/attach-pattern-usage.md +18 -0
  142. package/docs/reports/code-audit-results.md +391 -0
  143. package/docs/reports/introspection-audit-tasks.md +378 -0
  144. package/docs/reports/luca-mcp-improvements.md +128 -0
  145. package/docs/scaffolds/client.md +140 -0
  146. package/docs/scaffolds/command.md +106 -0
  147. package/docs/scaffolds/endpoint.md +176 -0
  148. package/docs/scaffolds/feature.md +148 -0
  149. package/docs/scaffolds/server.md +187 -0
  150. package/docs/tasks/web-container-helper-discovery.md +71 -0
  151. package/docs/todos.md +1 -0
  152. package/docs/tutorials/01-getting-started.md +106 -0
  153. package/docs/tutorials/02-container.md +210 -0
  154. package/docs/tutorials/03-scripts.md +194 -0
  155. package/docs/tutorials/04-features-overview.md +196 -0
  156. package/docs/tutorials/05-state-and-events.md +171 -0
  157. package/docs/tutorials/06-servers.md +157 -0
  158. package/docs/tutorials/07-endpoints.md +198 -0
  159. package/docs/tutorials/08-commands.md +171 -0
  160. package/docs/tutorials/09-clients.md +162 -0
  161. package/docs/tutorials/10-creating-features.md +198 -0
  162. package/docs/tutorials/11-contentbase.md +191 -0
  163. package/docs/tutorials/12-assistants.md +215 -0
  164. package/docs/tutorials/13-introspection.md +147 -0
  165. package/docs/tutorials/14-type-system.md +174 -0
  166. package/docs/tutorials/15-project-patterns.md +222 -0
  167. package/docs/tutorials/16-google-features.md +534 -0
  168. package/docs/tutorials/17-tui-blocks.md +530 -0
  169. package/docs/tutorials/18-semantic-search.md +334 -0
  170. package/index.ts +1 -0
  171. package/luca.console.ts +9 -0
  172. package/main.py +6 -0
  173. package/package.json +154 -0
  174. package/pyproject.toml +7 -0
  175. package/scripts/animations/chrome-glitch.ts +55 -0
  176. package/scripts/animations/index.ts +16 -0
  177. package/scripts/animations/neon-pulse.ts +64 -0
  178. package/scripts/animations/types.ts +6 -0
  179. package/scripts/build-web.ts +28 -0
  180. package/scripts/examples/ask-luca-expert.ts +42 -0
  181. package/scripts/examples/assistant-questions.ts +12 -0
  182. package/scripts/examples/excalidraw-expert.ts +75 -0
  183. package/scripts/examples/expert-chat.ts +0 -0
  184. package/scripts/examples/file-manager.ts +14 -0
  185. package/scripts/examples/ideas.ts +12 -0
  186. package/scripts/examples/interactive-chat.ts +20 -0
  187. package/scripts/examples/openai-tool-calls.ts +113 -0
  188. package/scripts/examples/opening-a-web-browser.ts +5 -0
  189. package/scripts/examples/telegram-bot.ts +79 -0
  190. package/scripts/examples/telegram-ink-ui.ts +302 -0
  191. package/scripts/examples/using-assistant-with-mcp.ts +560 -0
  192. package/scripts/examples/using-claude-code.ts +10 -0
  193. package/scripts/examples/using-contentdb.ts +35 -0
  194. package/scripts/examples/using-conversations.ts +35 -0
  195. package/scripts/examples/using-disk-cache.ts +10 -0
  196. package/scripts/examples/using-docker-shell.ts +75 -0
  197. package/scripts/examples/using-elevenlabs.ts +25 -0
  198. package/scripts/examples/using-google-calendar.ts +57 -0
  199. package/scripts/examples/using-google-docs.ts +74 -0
  200. package/scripts/examples/using-google-drive.ts +74 -0
  201. package/scripts/examples/using-google-sheets.ts +89 -0
  202. package/scripts/examples/using-nlp.ts +55 -0
  203. package/scripts/examples/using-ollama.ts +10 -0
  204. package/scripts/examples/using-openai-codex.ts +23 -0
  205. package/scripts/examples/using-postgres.ts +55 -0
  206. package/scripts/examples/using-runpod.ts +32 -0
  207. package/scripts/examples/using-tts.ts +40 -0
  208. package/scripts/examples/vm-loading-esm-modules.ts +16 -0
  209. package/scripts/scaffold.ts +391 -0
  210. package/scripts/scratch.ts +15 -0
  211. package/scripts/test-command-listener.ts +123 -0
  212. package/scripts/test-window-manager-lifecycle.ts +86 -0
  213. package/scripts/test-window-manager.ts +43 -0
  214. package/scripts/update-introspection-data.ts +58 -0
  215. package/src/agi/README.md +14 -0
  216. package/src/agi/container.server.ts +114 -0
  217. package/src/agi/endpoints/ask.ts +60 -0
  218. package/src/agi/endpoints/conversations/[id].ts +45 -0
  219. package/src/agi/endpoints/conversations.ts +31 -0
  220. package/src/agi/endpoints/experts.ts +37 -0
  221. package/src/agi/features/assistant.ts +767 -0
  222. package/src/agi/features/assistants-manager.ts +260 -0
  223. package/src/agi/features/claude-code.ts +1111 -0
  224. package/src/agi/features/conversation-history.ts +497 -0
  225. package/src/agi/features/conversation.ts +799 -0
  226. package/src/agi/features/openai-codex.ts +631 -0
  227. package/src/agi/features/openapi.ts +438 -0
  228. package/src/agi/features/skills-library.ts +425 -0
  229. package/src/agi/index.ts +6 -0
  230. package/src/agi/lib/token-counter.ts +122 -0
  231. package/src/browser.ts +25 -0
  232. package/src/bus.ts +100 -0
  233. package/src/cli/cli.ts +70 -0
  234. package/src/client.ts +461 -0
  235. package/src/clients/civitai/index.ts +541 -0
  236. package/src/clients/client-template.ts +41 -0
  237. package/src/clients/comfyui/index.ts +597 -0
  238. package/src/clients/elevenlabs/index.ts +291 -0
  239. package/src/clients/openai/index.ts +451 -0
  240. package/src/clients/supabase/index.ts +366 -0
  241. package/src/command.ts +164 -0
  242. package/src/commands/chat.ts +182 -0
  243. package/src/commands/console.ts +192 -0
  244. package/src/commands/describe.ts +433 -0
  245. package/src/commands/eval.ts +116 -0
  246. package/src/commands/help.ts +214 -0
  247. package/src/commands/index.ts +14 -0
  248. package/src/commands/mcp.ts +64 -0
  249. package/src/commands/prompt.ts +807 -0
  250. package/src/commands/run.ts +257 -0
  251. package/src/commands/sandbox-mcp.ts +439 -0
  252. package/src/commands/scaffold.ts +79 -0
  253. package/src/commands/serve.ts +172 -0
  254. package/src/container.ts +781 -0
  255. package/src/endpoint.ts +340 -0
  256. package/src/feature.ts +75 -0
  257. package/src/hash-object.ts +97 -0
  258. package/src/helper.ts +543 -0
  259. package/src/introspection/generated.agi.ts +23388 -0
  260. package/src/introspection/generated.node.ts +18899 -0
  261. package/src/introspection/generated.web.ts +2021 -0
  262. package/src/introspection/index.ts +256 -0
  263. package/src/introspection/scan.ts +912 -0
  264. package/src/node/container.ts +354 -0
  265. package/src/node/feature.ts +13 -0
  266. package/src/node/features/container-link.ts +558 -0
  267. package/src/node/features/content-db.ts +475 -0
  268. package/src/node/features/disk-cache.ts +382 -0
  269. package/src/node/features/dns.ts +655 -0
  270. package/src/node/features/docker.ts +912 -0
  271. package/src/node/features/downloader.ts +92 -0
  272. package/src/node/features/esbuild.ts +68 -0
  273. package/src/node/features/file-manager.ts +357 -0
  274. package/src/node/features/fs.ts +534 -0
  275. package/src/node/features/git.ts +492 -0
  276. package/src/node/features/google-auth.ts +502 -0
  277. package/src/node/features/google-calendar.ts +300 -0
  278. package/src/node/features/google-docs.ts +404 -0
  279. package/src/node/features/google-drive.ts +339 -0
  280. package/src/node/features/google-sheets.ts +279 -0
  281. package/src/node/features/grep.ts +406 -0
  282. package/src/node/features/helpers.ts +374 -0
  283. package/src/node/features/ink.ts +490 -0
  284. package/src/node/features/ipc-socket.ts +459 -0
  285. package/src/node/features/json-tree.ts +188 -0
  286. package/src/node/features/launcher-app-command-listener.ts +388 -0
  287. package/src/node/features/networking.ts +925 -0
  288. package/src/node/features/nlp.ts +211 -0
  289. package/src/node/features/opener.ts +166 -0
  290. package/src/node/features/os.ts +157 -0
  291. package/src/node/features/package-finder.ts +539 -0
  292. package/src/node/features/port-exposer.ts +342 -0
  293. package/src/node/features/postgres.ts +273 -0
  294. package/src/node/features/proc.ts +502 -0
  295. package/src/node/features/process-manager.ts +542 -0
  296. package/src/node/features/python.ts +444 -0
  297. package/src/node/features/repl.ts +194 -0
  298. package/src/node/features/runpod.ts +802 -0
  299. package/src/node/features/secure-shell.ts +248 -0
  300. package/src/node/features/semantic-search.ts +924 -0
  301. package/src/node/features/sqlite.ts +289 -0
  302. package/src/node/features/telegram.ts +342 -0
  303. package/src/node/features/tts.ts +184 -0
  304. package/src/node/features/ui.ts +857 -0
  305. package/src/node/features/vault.ts +164 -0
  306. package/src/node/features/vm.ts +312 -0
  307. package/src/node/features/window-manager.ts +804 -0
  308. package/src/node/features/yaml-tree.ts +149 -0
  309. package/src/node/features/yaml.ts +132 -0
  310. package/src/node.ts +70 -0
  311. package/src/react/index.ts +175 -0
  312. package/src/registry.ts +199 -0
  313. package/src/scaffolds/generated.ts +1613 -0
  314. package/src/scaffolds/template.ts +37 -0
  315. package/src/schemas/base.ts +255 -0
  316. package/src/server.ts +135 -0
  317. package/src/servers/express.ts +209 -0
  318. package/src/servers/mcp.ts +805 -0
  319. package/src/servers/socket.ts +120 -0
  320. package/src/state.ts +101 -0
  321. package/src/web/clients/socket.ts +82 -0
  322. package/src/web/container.ts +74 -0
  323. package/src/web/extension.ts +30 -0
  324. package/src/web/feature.ts +12 -0
  325. package/src/web/features/asset-loader.ts +64 -0
  326. package/src/web/features/container-link.ts +385 -0
  327. package/src/web/features/esbuild.ts +79 -0
  328. package/src/web/features/helpers.ts +267 -0
  329. package/src/web/features/network.ts +61 -0
  330. package/src/web/features/speech.ts +87 -0
  331. package/src/web/features/vault.ts +189 -0
  332. package/src/web/features/vm.ts +78 -0
  333. package/src/web/features/voice-recognition.ts +129 -0
  334. package/src/web/shims/isomorphic-vm.ts +149 -0
  335. package/test/bus.test.ts +134 -0
  336. package/test/clients-servers.test.ts +216 -0
  337. package/test/container-link.test.ts +274 -0
  338. package/test/features.test.ts +160 -0
  339. package/test/integration.test.ts +787 -0
  340. package/test/node-container.test.ts +121 -0
  341. package/test/rate-limit.test.ts +272 -0
  342. package/test/semantic-search.test.ts +550 -0
  343. package/test/state.test.ts +121 -0
  344. package/test-integration/assistant.test.ts +138 -0
  345. package/test-integration/assistants-manager.test.ts +123 -0
  346. package/test-integration/claude-code.test.ts +98 -0
  347. package/test-integration/conversation-history.test.ts +205 -0
  348. package/test-integration/conversation.test.ts +137 -0
  349. package/test-integration/elevenlabs.test.ts +55 -0
  350. package/test-integration/google-services.test.ts +80 -0
  351. package/test-integration/helpers.ts +89 -0
  352. package/test-integration/openai-codex.test.ts +93 -0
  353. package/test-integration/runpod.test.ts +58 -0
  354. package/test-integration/server-endpoints.test.ts +97 -0
  355. package/test-integration/skills-library.test.ts +157 -0
  356. package/test-integration/telegram.test.ts +46 -0
  357. package/tsconfig.json +58 -0
  358. package/uv.lock +8 -0
@@ -0,0 +1,334 @@
1
+ ---
2
+ title: Semantic Search
3
+ tags: [semantic-search, embeddings, vector-search, bm25, hybrid-search, sqlite, contentdb]
4
+ ---
5
+
6
+ # Semantic Search
7
+
8
+ Luca's `semanticSearch` feature provides BM25 keyword search, vector similarity search, and hybrid search with Reciprocal Rank Fusion -- all backed by SQLite. It chunks documents intelligently, generates embeddings via OpenAI or a local GGUF model, and stores everything in a single `.sqlite` file.
9
+
10
+ ## Quick Start with ContentDb
11
+
12
+ The fastest way to use semantic search is through the `contentDb` feature, which handles indexing and querying automatically:
13
+
14
+ ```typescript
15
+ import container from '@soederpop/luca'
16
+
17
+ const db = container.feature('contentDb', { rootPath: './docs' })
18
+ await db.load()
19
+
20
+ // Build the search index (generates embeddings for all documents)
21
+ await db.buildSearchIndex({
22
+ onProgress: (indexed, total) => console.log(`${indexed}/${total}`)
23
+ })
24
+
25
+ // Search your documents
26
+ const results = await db.hybridSearch('how does authentication work')
27
+ for (const r of results) {
28
+ console.log(`${r.title} (score: ${r.score.toFixed(3)})`)
29
+ console.log(` ${r.snippet}`)
30
+ }
31
+ ```
32
+
33
+ ContentDb provides three search methods that delegate to the underlying semanticSearch feature:
34
+
35
+ ```typescript
36
+ // BM25 keyword search -- best for exact term matching
37
+ await db.search('OAuth2 token refresh')
38
+
39
+ // Vector similarity search -- finds conceptually related documents
40
+ await db.vectorSearch('how do users log in')
41
+
42
+ // Hybrid search -- combines both via Reciprocal Rank Fusion (recommended)
43
+ await db.hybridSearch('authentication flow', { limit: 5 })
44
+ ```
45
+
46
+ ## Using SemanticSearch Directly
47
+
48
+ For more control, use the `semanticSearch` feature directly:
49
+
50
+ ```typescript
51
+ import container from '@soederpop/luca'
52
+ import { SemanticSearch } from '@soederpop/luca/node/features/semantic-search'
53
+
54
+ // Attach the feature to the container
55
+ SemanticSearch.attach(container)
56
+
57
+ const search = container.feature('semanticSearch', {
58
+ dbPath: '.contentbase/search.sqlite',
59
+ embeddingProvider: 'openai', // or 'local'
60
+ embeddingModel: 'text-embedding-3-small',
61
+ chunkStrategy: 'section', // 'section' | 'fixed' | 'document'
62
+ chunkSize: 900,
63
+ })
64
+
65
+ await search.initDb()
66
+ ```
67
+
68
+ ## Indexing Documents
69
+
70
+ Documents are represented as `DocumentInput` objects with optional section metadata:
71
+
72
+ ```typescript
73
+ await search.indexDocuments([
74
+ {
75
+ pathId: 'guides/auth',
76
+ model: 'Guide',
77
+ title: 'Authentication Guide',
78
+ meta: { status: 'published', category: 'security' },
79
+ content: 'Full document content here...',
80
+ sections: [
81
+ {
82
+ heading: 'OAuth2 Flow',
83
+ headingPath: 'Authentication Guide > OAuth2 Flow',
84
+ content: 'OAuth2 uses authorization codes and tokens...',
85
+ level: 2,
86
+ },
87
+ {
88
+ heading: 'Session Management',
89
+ headingPath: 'Authentication Guide > Session Management',
90
+ content: 'Sessions are stored server-side with a cookie...',
91
+ level: 2,
92
+ },
93
+ ],
94
+ },
95
+ {
96
+ pathId: 'guides/deployment',
97
+ title: 'Deployment Guide',
98
+ content: 'How to deploy your application...',
99
+ },
100
+ ])
101
+ ```
102
+
103
+ The `indexDocuments` method:
104
+ 1. Stores documents in SQLite with FTS5 full-text indexing
105
+ 2. Chunks each document based on the configured strategy
106
+ 3. Generates embeddings for every chunk
107
+ 4. Stores embeddings as BLOBs alongside the chunk text
108
+
109
+ ## Chunking Strategies
110
+
111
+ The feature splits documents into chunks before embedding. Choose a strategy based on your content:
112
+
113
+ ### Section (default)
114
+
115
+ Splits at heading boundaries (`## H2`, `### H3`). Each section becomes a chunk, prefixed with the heading path for context. Falls back to fixed chunking if the document has no sections.
116
+
117
+ ```typescript
118
+ const search = container.feature('semanticSearch', {
119
+ chunkStrategy: 'section',
120
+ chunkSize: 900, // max tokens per chunk (sections exceeding this are split at paragraphs)
121
+ })
122
+ ```
123
+
124
+ Best for: structured documents with clear heading hierarchies.
125
+
126
+ ### Fixed
127
+
128
+ Splits by word count with configurable overlap between chunks:
129
+
130
+ ```typescript
131
+ const search = container.feature('semanticSearch', {
132
+ chunkStrategy: 'fixed',
133
+ chunkSize: 900,
134
+ chunkOverlap: 0.15, // 15% overlap between adjacent chunks
135
+ })
136
+ ```
137
+
138
+ Best for: unstructured prose, logs, or transcripts.
139
+
140
+ ### Document
141
+
142
+ One chunk per document -- no splitting:
143
+
144
+ ```typescript
145
+ const search = container.feature('semanticSearch', {
146
+ chunkStrategy: 'document',
147
+ })
148
+ ```
149
+
150
+ Best for: short documents where splitting would lose context.
151
+
152
+ ## Search Methods
153
+
154
+ ### BM25 Keyword Search
155
+
156
+ Uses SQLite FTS5 with Porter stemming for traditional keyword matching:
157
+
158
+ ```typescript
159
+ const results = await search.search('authentication tokens', {
160
+ limit: 10,
161
+ model: 'Guide', // filter by document model
162
+ where: { status: 'published' }, // filter by metadata fields
163
+ })
164
+ ```
165
+
166
+ Returns results ranked by BM25 relevance with highlighted snippets.
167
+
168
+ ### Vector Similarity Search
169
+
170
+ Embeds the query and computes cosine similarity against all stored chunk embeddings:
171
+
172
+ ```typescript
173
+ const results = await search.vectorSearch('how do users prove their identity', {
174
+ limit: 10,
175
+ })
176
+ ```
177
+
178
+ Finds conceptually related content even without keyword overlap. Results are deduplicated by document, keeping the best-scoring chunk per document.
179
+
180
+ ### Hybrid Search (Recommended)
181
+
182
+ Runs both BM25 and vector search in parallel, then fuses results using Reciprocal Rank Fusion:
183
+
184
+ ```typescript
185
+ const results = await search.hybridSearch('authentication flow', {
186
+ limit: 10,
187
+ model: 'Guide',
188
+ where: { category: 'security' },
189
+ })
190
+ ```
191
+
192
+ This gives the best results for most queries -- keyword precision combined with semantic recall.
193
+
194
+ ## Search Results
195
+
196
+ All search methods return `SearchResult[]`:
197
+
198
+ ```typescript
199
+ interface SearchResult {
200
+ pathId: string // document identifier
201
+ model: string // content model name
202
+ title: string // document title
203
+ meta: Record<string, any> // document metadata
204
+ score: number // relevance score
205
+ snippet: string // matched text excerpt
206
+ matchedSection?: string // section heading where the match occurred
207
+ headingPath?: string // full heading breadcrumb (e.g. "Auth > OAuth2 > Tokens")
208
+ }
209
+ ```
210
+
211
+ ## Embedding Providers
212
+
213
+ ### OpenAI (default)
214
+
215
+ Uses the OpenAI embeddings API. Requires an `openai` client registered in the container.
216
+
217
+ ```typescript
218
+ const search = container.feature('semanticSearch', {
219
+ embeddingProvider: 'openai',
220
+ embeddingModel: 'text-embedding-3-small', // 1536 dimensions
221
+ // also available: 'text-embedding-3-large' (3072 dimensions)
222
+ })
223
+ ```
224
+
225
+ ### Local (GGUF)
226
+
227
+ Runs embeddings locally using `node-llama-cpp` with a GGUF model file:
228
+
229
+ ```typescript
230
+ const search = container.feature('semanticSearch', {
231
+ embeddingProvider: 'local',
232
+ embeddingModel: 'embedding-gemma-300M-Q8_0', // 768 dimensions
233
+ })
234
+
235
+ // Install the dependency if needed
236
+ await search.installLocalEmbeddings(process.cwd())
237
+ ```
238
+
239
+ Local models are loaded from `~/.cache/luca/models/` or `~/.cache/qmd/models/`. The model is kept in memory and automatically disposed after 5 minutes of inactivity.
240
+
241
+ ## Index Management
242
+
243
+ ### Incremental Updates
244
+
245
+ The feature tracks content hashes to avoid re-embedding unchanged documents:
246
+
247
+ ```typescript
248
+ // Check if a document needs re-indexing
249
+ if (search.needsReindex(doc)) {
250
+ search.removeDocument(doc.pathId)
251
+ await search.indexDocuments([doc])
252
+ }
253
+ ```
254
+
255
+ ### Remove Stale Documents
256
+
257
+ Clean up documents that no longer exist in your collection:
258
+
259
+ ```typescript
260
+ const currentIds = ['guides/auth', 'guides/deployment']
261
+ search.removeStale(currentIds) // deletes any indexed docs not in this list
262
+ ```
263
+
264
+ ### Full Reindex
265
+
266
+ Clear everything and start fresh:
267
+
268
+ ```typescript
269
+ await search.reindex() // clears all data
270
+ await search.indexDocuments(allDocs) // re-index everything
271
+ ```
272
+
273
+ ### Index Status
274
+
275
+ ```typescript
276
+ const stats = search.getStats()
277
+ // {
278
+ // documentCount: 42,
279
+ // chunkCount: 187,
280
+ // embeddingCount: 187,
281
+ // lastIndexedAt: '2026-03-06T...',
282
+ // provider: 'openai',
283
+ // model: 'text-embedding-3-small',
284
+ // dimensions: 1536,
285
+ // dbSizeBytes: 2457600,
286
+ // }
287
+ ```
288
+
289
+ ## Database Scoping
290
+
291
+ Each provider/model combination gets its own SQLite file. If you configure `dbPath: '.contentbase/search.sqlite'` with the OpenAI provider and `text-embedding-3-small` model, the actual file will be `.contentbase/search.openai-text-embedding-3-small.sqlite`. This prevents dimension mismatches if you switch providers.
292
+
293
+ ## ContentDb Integration Details
294
+
295
+ When using `contentDb.buildSearchIndex()`, the feature automatically:
296
+
297
+ - Extracts sections from your markdown documents at H2 boundaries
298
+ - Converts each document to a `DocumentInput` with pathId, title, meta, and sections
299
+ - Skips unchanged documents (incremental by default)
300
+ - Removes documents that no longer exist in the collection
301
+
302
+ ```typescript
303
+ const db = container.feature('contentDb', { rootPath: './docs' })
304
+ await db.load()
305
+
306
+ // Incremental update (default)
307
+ const { indexed, total } = await db.buildSearchIndex()
308
+ console.log(`Indexed ${indexed} of ${total} documents`)
309
+
310
+ // Force full rebuild
311
+ await db.rebuildSearchIndex()
312
+
313
+ // Check index health
314
+ console.log(db.searchIndexStatus)
315
+ ```
316
+
317
+ ## Lifecycle
318
+
319
+ Always close the feature when done to release the SQLite connection and any loaded models:
320
+
321
+ ```typescript
322
+ await search.close()
323
+ ```
324
+
325
+ The feature emits events you can listen to:
326
+
327
+ ```typescript
328
+ search.on('dbReady', () => console.log('Database initialized'))
329
+ search.on('indexed', ({ documents, chunks }) => {
330
+ console.log(`Indexed ${documents} docs (${chunks} chunks)`)
331
+ })
332
+ search.on('modelLoaded', () => console.log('Local embedding model loaded'))
333
+ search.on('modelDisposed', () => console.log('Local embedding model released'))
334
+ ```
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ console.log("Hello via Bun!");
@@ -0,0 +1,9 @@
1
+ import type { AGIContainer } from '@soederpop/luca/agi'
2
+
3
+ declare global {
4
+ var container: AGIContainer
5
+ }
6
+
7
+ export const ass = container.feature('assistant', {
8
+ folder: 'assistants/project-owner',
9
+ })
package/main.py ADDED
@@ -0,0 +1,6 @@
1
+ def main():
2
+ print("Hello from luca2!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
package/package.json ADDED
@@ -0,0 +1,154 @@
1
+ {
2
+ "name": "@soederpop/luca",
3
+ "version": "0.0.2",
4
+ "private": false,
5
+ "description": "lightweight universal conversational architecture",
6
+ "author": "jon soeder <jon@soederpop.com>",
7
+ "type": "module",
8
+ "repository": "https://github.com/soederpop/luca",
9
+ "license": "MIT",
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "keywords": [
14
+ "conversational",
15
+ "architecture"
16
+ ],
17
+ "main": "./src/node.ts",
18
+ "types": "./src/node.ts",
19
+ "browser": "./src/browser.ts",
20
+ "exports": {
21
+ ".": "./src/node.ts",
22
+ "./node": "./src/node.ts",
23
+ "./node/*": "./src/node/*",
24
+ "./web": "./src/browser.ts",
25
+ "./web/*": "./src/web/*",
26
+ "./agi": "./src/agi/index.ts",
27
+ "./agi/*": "./src/agi/*",
28
+ "./schemas": "./src/schemas/base.ts",
29
+ "./schemas/*": "./src/schemas/*",
30
+ "./container": "./src/container.ts",
31
+ "./client": "./src/client.ts",
32
+ "./clients/*": "./src/clients/*",
33
+ "./feature": "./src/feature.ts",
34
+ "./react": "./src/react/index.ts"
35
+ },
36
+ "bin": {
37
+ "luca": "./src/cli/cli.ts"
38
+ },
39
+ "scripts": {
40
+ "serve": "bun build:web && luca serve --any-port",
41
+ "console": "ts-node --esm scripts/console.ts",
42
+ "lint": "eslint src/ --ext .js,.jsx,.ts,.tsx",
43
+ "clean": "rm -rf dist build package",
44
+ "build:web": "bun run scripts/build-web.ts",
45
+ "build:introspection": "bun run src/cli/cli.ts update-introspection",
46
+ "compile": "bun build ./src/cli/cli.ts --compile --outfile dist/luca --external node-llama-cpp",
47
+ "typecheck": "tsc -p tsconfig.json --noEmit",
48
+ "build:scaffolds": "bun run src/cli/cli.ts build-scaffolds",
49
+ "test": "bun test test/*.test.ts",
50
+ "update-all-docs": "bun run test && bun run build:introspection && bun run src/cli/cli.ts generate-api-docs && bun run build:scaffolds",
51
+ "precommit": "bun run update-all-docs && git add docs/apis/ src/introspection/generated.*.ts src/scaffolds/generated.ts && bun compile",
52
+ "test:integration": "bun test ./test-integration/"
53
+ },
54
+ "devDependencies": {
55
+ "@types/cacache": "^15.0.1",
56
+ "@types/chalk": "^2.2.0",
57
+ "@types/child-process-promise": "^2.2.2",
58
+ "@types/chokidar": "^2.1.3",
59
+ "@types/cors": "^2.8.13",
60
+ "@types/detect-port": "^1.3.2",
61
+ "@types/dotenv": "^8.2.0",
62
+ "@types/express": "^4.17.17",
63
+ "@types/figlet": "^1.5.5",
64
+ "@types/glob": "^8.1.0",
65
+ "@types/inquirer": "^9.0.3",
66
+ "@types/jest": "^27.4.1",
67
+ "@types/js-yaml": "^4.0.5",
68
+ "@types/lodash-es": "^4.17.7",
69
+ "@types/micromatch": "^4.0.2",
70
+ "@types/minimist": "^1.2.2",
71
+ "@types/node": "^18.15.11",
72
+ "@types/node-uuid": "^0.0.29",
73
+ "@types/object-hash": "^3.0.2",
74
+ "@types/react": "^18.2.0",
75
+ "@types/uuid": "^9.0.1",
76
+ "@types/ws": "^8.5.4",
77
+ "@typescript-eslint/eslint-plugin": "^5.20.0",
78
+ "@typescript-eslint/parser": "^5.20.0",
79
+ "eslint": "^8.14.0",
80
+ "mkdist": "^1.3.0",
81
+ "prettier": "^2.8.7",
82
+ "ts-node": "^11.0.0-beta.1"
83
+ },
84
+ "dependencies": {
85
+ "@modelcontextprotocol/sdk": "^1.12.1",
86
+ "@ngrok/ngrok": "^1.5.1",
87
+ "@openai/codex": "^0.99.0",
88
+ "@resvg/resvg-js": "^2.6.2",
89
+ "@supabase/supabase-js": "^2.95.3",
90
+ "@types/marked": "^6.0.0",
91
+ "@types/marked-terminal": "^6.1.1",
92
+ "axios": "^1.3.5",
93
+ "cacache": "^17.0.7",
94
+ "chalk": "^5.2.0",
95
+ "child-process-promise": "^2.2.1",
96
+ "chokidar": "^3.5.3",
97
+ "cli-markdown": "^3.5.0",
98
+ "compromise": "^14.14.5",
99
+ "contentbase": "",
100
+ "cors": "^2.8.5",
101
+ "cross-fetch": "^4.1.0",
102
+ "detect-port": "^1.5.1",
103
+ "dotenv": "^17.2.4",
104
+ "endent": "^2.1.0",
105
+ "esbuild-wasm": "0.17.18",
106
+ "excalidraw-to-svg": "^3.1.0",
107
+ "express": "^4.18.2",
108
+ "figlet": "^1.6.0",
109
+ "glob": "^11.0.2",
110
+ "googleapis": "^171.4.0",
111
+ "grammy": "^1.40.0",
112
+ "inflect": "^0.5.0",
113
+ "ink": "^6.7.0",
114
+ "inquirer": "^9.1.5",
115
+ "isomorphic-vm": "^0.0.1",
116
+ "isomorphic-ws": "^5.0.0",
117
+ "js-tiktoken": "^1.0.21",
118
+ "js-yaml": "^4.1.0",
119
+ "lodash-es": "^4.17.21",
120
+ "marked": "^15.0.12",
121
+ "marked-terminal": "^7.3.0",
122
+ "mdast-util-to-markdown": "^1.5.0",
123
+ "mdast-util-to-string": "^3.2.0",
124
+ "micromatch": "^4.0.5",
125
+ "minimist": "^1.2.8",
126
+ "node-uuid": "^1.4.8",
127
+ "object-hash": "^3.0.0",
128
+ "openai": "^5.1.1",
129
+ "opener": "^1.5.2",
130
+ "react": "^19.2.4",
131
+ "react-devtools-core": "^7.0.1",
132
+ "react-dom": "^19.2.4",
133
+ "react-reconciler": "^0.33.0",
134
+ "remark-gfm": "^3.0.1",
135
+ "rimraf": "^5.0.0",
136
+ "typescript": "^5.9.3",
137
+ "unist-util-find-after": "^4.0.1",
138
+ "unist-util-find-all-after": "^4.0.1",
139
+ "unist-util-find-all-before": "^4.0.1",
140
+ "unist-util-find-before": "^3.0.1",
141
+ "unist-util-select": "^4.0.3",
142
+ "unist-util-visit": "^4.1.2",
143
+ "wink-eng-lite-web-model": "^1.8.1",
144
+ "wink-nlp": "^2.4.0",
145
+ "ws": "^8.13.0",
146
+ "zod": "^4.0.0"
147
+ },
148
+ "optionalDependencies": {
149
+ "node-llama-cpp": "^3.17.1"
150
+ },
151
+ "luca": {
152
+ "aliases": ["luca", "framework", "container", "runtime"]
153
+ }
154
+ }
package/pyproject.toml ADDED
@@ -0,0 +1,7 @@
1
+ [project]
2
+ name = "luca2"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ dependencies = []
@@ -0,0 +1,55 @@
1
+ import type { AsciiAnimation } from './types'
2
+
3
+ const frames = [
4
+ String.raw`
5
+ ###### ###### ########
6
+ ## ## ## ## ##
7
+ ###### ## ## ##
8
+ ## ## ## ## ##
9
+ ## ## ###### ##
10
+ ## ## ###### ##
11
+
12
+ [o_o] channel-open
13
+ /|\ packet-sync
14
+ / \ pulse: 71%
15
+
16
+ <<..................>>
17
+ `,
18
+ String.raw`
19
+ ###### ###### ########
20
+ ## ## ## ## ##
21
+ ###### ## ## ##
22
+ ## ## ## ## ##
23
+ ## ## ###### ##
24
+ ## ## ###### ##
25
+
26
+ [0_0] channel-open
27
+ /|\ packet-sync
28
+ / \ pulse: 84%
29
+
30
+ <<##..##..##..##..##..>>
31
+ `,
32
+ String.raw`
33
+ ###### ###### ########
34
+ ## ## ## ## ##
35
+ ###### ## ## ##
36
+ ## ## ## ## ##
37
+ ## ## ###### ##
38
+ ## ## ###### ##
39
+
40
+ [O_O] channel-open
41
+ /|\ packet-sync
42
+ / \ pulse: 96%
43
+
44
+ <<##################>>
45
+ `,
46
+ ]
47
+
48
+ const chromeGlitch: AsciiAnimation = {
49
+ id: 'chromeGlitch',
50
+ name: 'Chrome Glitch Totem',
51
+ fps: 5,
52
+ frames,
53
+ }
54
+
55
+ export default chromeGlitch
@@ -0,0 +1,16 @@
1
+ import type { AsciiAnimation } from './types'
2
+ import neonPulse from './neon-pulse'
3
+ import chromeGlitch from './chrome-glitch'
4
+
5
+ const animations: AsciiAnimation[] = [neonPulse, chromeGlitch]
6
+
7
+ export function listAnimations(): AsciiAnimation[] {
8
+ return animations
9
+ }
10
+
11
+ export function resolveAnimation(id: string): AsciiAnimation {
12
+ const match = animations.find((animation) => animation.id.toLowerCase() === id.toLowerCase())
13
+ if (match) return match
14
+ if (!animations[0]) throw new Error('No animations are registered.')
15
+ return animations[0]
16
+ }
@@ -0,0 +1,64 @@
1
+ import type { AsciiAnimation } from './types'
2
+
3
+ const frames = [
4
+ String.raw`
5
+ .-""-.
6
+ .' .--. '.
7
+ / / \ \
8
+ | | 0 0 | |
9
+ | | __ | |
10
+ | | /__\ | |
11
+ | | \__/ | |
12
+ | | | |
13
+ /| '.__.' |\
14
+ .' | /::\ | '.
15
+ / | |::::| | \
16
+ /____|__|::::|__|____\
17
+ /_/ |::| \_\
18
+ /____\
19
+ ~ ~ ~ SIGNAL: STABLE ~ ~ ~
20
+ `,
21
+ String.raw`
22
+ .-""-.
23
+ .' .--. '.
24
+ / / /\ \ \
25
+ | | ^ ^ | |
26
+ | | -- | |
27
+ | | /__\ | |
28
+ | | \__/ | |
29
+ | | /\ | |
30
+ /| '.__.' |\
31
+ .' | _/::\_ | '.
32
+ / | |::::::| | \
33
+ /____|_|::::::|_|____\
34
+ /_/ |::| \_\
35
+ /____\
36
+ ~ ~ ~ SIGNAL: BREATHING ~ ~ ~
37
+ `,
38
+ String.raw`
39
+ .-""-.
40
+ .' .--. '.
41
+ / / __ \ \
42
+ | | o o | |
43
+ | | .. | |
44
+ | | /__\ | |
45
+ | | \__/ | |
46
+ | | .--. | |
47
+ /| '.__.' |\
48
+ .' | /::\ | '.
49
+ / | |::::| | \
50
+ /____|__|::::|__|____\
51
+ /_/ |::| \_\
52
+ /____\
53
+ ~ ~ ~ SIGNAL: SCANNING ~ ~ ~
54
+ `,
55
+ ]
56
+
57
+ const neonPulse: AsciiAnimation = {
58
+ id: 'neonPulse',
59
+ name: 'Neon Pulse Bot',
60
+ fps: 4,
61
+ frames,
62
+ }
63
+
64
+ export default neonPulse
@@ -0,0 +1,6 @@
1
+ export interface AsciiAnimation {
2
+ id: string
3
+ name: string
4
+ fps: number
5
+ frames: string[]
6
+ }
@@ -0,0 +1,28 @@
1
+ // @ts-nocheck
2
+ import path from "path"
3
+
4
+ const result = await Bun.build({
5
+ entrypoints: [path.resolve(import.meta.dir, "../src/browser.ts")],
6
+ outdir: path.resolve(import.meta.dir, "../dist"),
7
+ target: "browser",
8
+ format: "esm",
9
+ naming: "browser.js",
10
+ external: [
11
+ "react",
12
+ "react-dom",
13
+ ],
14
+ define: {
15
+ "process.env.NODE_ENV": JSON.stringify("production"),
16
+ "process.env.NODE_DEBUG": JSON.stringify(""),
17
+ },
18
+ })
19
+
20
+ if (!result.success) {
21
+ console.error("Build failed:")
22
+ for (const log of result.logs) {
23
+ console.error(log)
24
+ }
25
+ process.exit(1)
26
+ }
27
+
28
+ console.log(`Built browser bundle: dist/browser.js (${(result.outputs[0].size / 1024).toFixed(1)}KB)`)