@soederpop/luca 0.1.2 → 0.2.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 (381) hide show
  1. package/.github/workflows/release.yaml +167 -0
  2. package/CLAUDE.md +2 -0
  3. package/README.md +3 -0
  4. package/assistants/codingAssistant/ABOUT.md +3 -0
  5. package/assistants/codingAssistant/CORE.md +22 -17
  6. package/assistants/codingAssistant/hooks.ts +17 -4
  7. package/assistants/codingAssistant/tools.ts +1 -106
  8. package/assistants/inkbot/ABOUT.md +5 -0
  9. package/assistants/inkbot/CORE.md +71 -0
  10. package/assistants/inkbot/hooks.ts +14 -0
  11. package/assistants/inkbot/tools.ts +47 -0
  12. package/bun.lock +20 -4
  13. package/commands/inkbot.ts +353 -0
  14. package/commands/release.ts +75 -181
  15. package/dist/agi/container.server.d.ts +63 -0
  16. package/dist/agi/container.server.d.ts.map +1 -0
  17. package/dist/agi/endpoints/ask.d.ts +20 -0
  18. package/dist/agi/endpoints/ask.d.ts.map +1 -0
  19. package/dist/agi/endpoints/conversations/[id].d.ts +27 -0
  20. package/dist/agi/endpoints/conversations/[id].d.ts.map +1 -0
  21. package/dist/agi/endpoints/conversations.d.ts +18 -0
  22. package/dist/agi/endpoints/conversations.d.ts.map +1 -0
  23. package/dist/agi/endpoints/experts.d.ts +8 -0
  24. package/dist/agi/endpoints/experts.d.ts.map +1 -0
  25. package/dist/agi/feature.d.ts +9 -0
  26. package/dist/agi/feature.d.ts.map +1 -0
  27. package/dist/agi/features/assistant.d.ts +509 -0
  28. package/dist/agi/features/assistant.d.ts.map +1 -0
  29. package/dist/agi/features/assistants-manager.d.ts +236 -0
  30. package/dist/agi/features/assistants-manager.d.ts.map +1 -0
  31. package/dist/agi/features/autonomous-assistant.d.ts +281 -0
  32. package/dist/agi/features/autonomous-assistant.d.ts.map +1 -0
  33. package/dist/agi/features/browser-use.d.ts +479 -0
  34. package/dist/agi/features/browser-use.d.ts.map +1 -0
  35. package/dist/agi/features/claude-code.d.ts +824 -0
  36. package/dist/agi/features/claude-code.d.ts.map +1 -0
  37. package/dist/agi/features/conversation-history.d.ts +245 -0
  38. package/dist/agi/features/conversation-history.d.ts.map +1 -0
  39. package/dist/agi/features/conversation.d.ts +464 -0
  40. package/dist/agi/features/conversation.d.ts.map +1 -0
  41. package/dist/agi/features/docs-reader.d.ts +72 -0
  42. package/dist/agi/features/docs-reader.d.ts.map +1 -0
  43. package/dist/agi/features/file-tools.d.ts +110 -0
  44. package/dist/agi/features/file-tools.d.ts.map +1 -0
  45. package/dist/agi/features/luca-coder.d.ts +323 -0
  46. package/dist/agi/features/luca-coder.d.ts.map +1 -0
  47. package/dist/agi/features/openai-codex.d.ts +381 -0
  48. package/dist/agi/features/openai-codex.d.ts.map +1 -0
  49. package/dist/agi/features/openapi.d.ts +200 -0
  50. package/dist/agi/features/openapi.d.ts.map +1 -0
  51. package/dist/agi/features/skills-library.d.ts +167 -0
  52. package/dist/agi/features/skills-library.d.ts.map +1 -0
  53. package/dist/agi/index.d.ts +5 -0
  54. package/dist/agi/index.d.ts.map +1 -0
  55. package/dist/agi/lib/interceptor-chain.d.ts +44 -0
  56. package/dist/agi/lib/interceptor-chain.d.ts.map +1 -0
  57. package/dist/agi/lib/token-counter.d.ts +13 -0
  58. package/dist/agi/lib/token-counter.d.ts.map +1 -0
  59. package/dist/bootstrap/generated.d.ts +5 -0
  60. package/dist/bootstrap/generated.d.ts.map +1 -0
  61. package/dist/browser.d.ts +12 -0
  62. package/dist/browser.d.ts.map +1 -0
  63. package/dist/bus.d.ts +29 -0
  64. package/dist/bus.d.ts.map +1 -0
  65. package/dist/cli/build-info.d.ts +4 -0
  66. package/dist/cli/build-info.d.ts.map +1 -0
  67. package/dist/cli/cli.d.ts +3 -0
  68. package/dist/cli/cli.d.ts.map +1 -0
  69. package/dist/client.d.ts +60 -0
  70. package/dist/client.d.ts.map +1 -0
  71. package/dist/clients/civitai/index.d.ts +472 -0
  72. package/dist/clients/civitai/index.d.ts.map +1 -0
  73. package/dist/clients/client-template.d.ts +30 -0
  74. package/dist/clients/client-template.d.ts.map +1 -0
  75. package/dist/clients/comfyui/index.d.ts +281 -0
  76. package/dist/clients/comfyui/index.d.ts.map +1 -0
  77. package/dist/clients/elevenlabs/index.d.ts +197 -0
  78. package/dist/clients/elevenlabs/index.d.ts.map +1 -0
  79. package/dist/clients/graph.d.ts +64 -0
  80. package/dist/clients/graph.d.ts.map +1 -0
  81. package/dist/clients/openai/index.d.ts +247 -0
  82. package/dist/clients/openai/index.d.ts.map +1 -0
  83. package/dist/clients/rest.d.ts +92 -0
  84. package/dist/clients/rest.d.ts.map +1 -0
  85. package/dist/clients/supabase/index.d.ts +176 -0
  86. package/dist/clients/supabase/index.d.ts.map +1 -0
  87. package/dist/clients/websocket.d.ts +127 -0
  88. package/dist/clients/websocket.d.ts.map +1 -0
  89. package/dist/command.d.ts +163 -0
  90. package/dist/command.d.ts.map +1 -0
  91. package/dist/commands/bootstrap.d.ts +20 -0
  92. package/dist/commands/bootstrap.d.ts.map +1 -0
  93. package/dist/commands/chat.d.ts +37 -0
  94. package/dist/commands/chat.d.ts.map +1 -0
  95. package/dist/commands/code.d.ts +28 -0
  96. package/dist/commands/code.d.ts.map +1 -0
  97. package/dist/commands/console.d.ts +22 -0
  98. package/dist/commands/console.d.ts.map +1 -0
  99. package/dist/commands/describe.d.ts +50 -0
  100. package/dist/commands/describe.d.ts.map +1 -0
  101. package/dist/commands/eval.d.ts +23 -0
  102. package/dist/commands/eval.d.ts.map +1 -0
  103. package/dist/commands/help.d.ts +25 -0
  104. package/dist/commands/help.d.ts.map +1 -0
  105. package/dist/commands/index.d.ts +18 -0
  106. package/dist/commands/index.d.ts.map +1 -0
  107. package/dist/commands/introspect.d.ts +24 -0
  108. package/dist/commands/introspect.d.ts.map +1 -0
  109. package/dist/commands/mcp.d.ts +35 -0
  110. package/dist/commands/mcp.d.ts.map +1 -0
  111. package/dist/commands/prompt.d.ts +38 -0
  112. package/dist/commands/prompt.d.ts.map +1 -0
  113. package/dist/commands/run.d.ts +24 -0
  114. package/dist/commands/run.d.ts.map +1 -0
  115. package/dist/commands/sandbox-mcp.d.ts +34 -0
  116. package/dist/commands/sandbox-mcp.d.ts.map +1 -0
  117. package/dist/commands/save-api-docs.d.ts +21 -0
  118. package/dist/commands/save-api-docs.d.ts.map +1 -0
  119. package/dist/commands/scaffold.d.ts +24 -0
  120. package/dist/commands/scaffold.d.ts.map +1 -0
  121. package/dist/commands/select.d.ts +22 -0
  122. package/dist/commands/select.d.ts.map +1 -0
  123. package/dist/commands/serve.d.ts +29 -0
  124. package/dist/commands/serve.d.ts.map +1 -0
  125. package/dist/container-describer.d.ts +144 -0
  126. package/dist/container-describer.d.ts.map +1 -0
  127. package/dist/container.d.ts +451 -0
  128. package/dist/container.d.ts.map +1 -0
  129. package/dist/endpoint.d.ts +113 -0
  130. package/dist/endpoint.d.ts.map +1 -0
  131. package/dist/feature.d.ts +47 -0
  132. package/dist/feature.d.ts.map +1 -0
  133. package/dist/graft.d.ts +29 -0
  134. package/dist/graft.d.ts.map +1 -0
  135. package/dist/hash-object.d.ts +8 -0
  136. package/dist/hash-object.d.ts.map +1 -0
  137. package/dist/helper.d.ts +209 -0
  138. package/dist/helper.d.ts.map +1 -0
  139. package/dist/introspection/generated.node.d.ts +44623 -0
  140. package/dist/introspection/generated.node.d.ts.map +1 -0
  141. package/dist/introspection/generated.web.d.ts +1412 -0
  142. package/dist/introspection/generated.web.d.ts.map +1 -0
  143. package/dist/introspection/index.d.ts +156 -0
  144. package/dist/introspection/index.d.ts.map +1 -0
  145. package/dist/introspection/scan.d.ts +147 -0
  146. package/dist/introspection/scan.d.ts.map +1 -0
  147. package/dist/node/container.d.ts +256 -0
  148. package/dist/node/container.d.ts.map +1 -0
  149. package/dist/node/feature.d.ts +9 -0
  150. package/dist/node/feature.d.ts.map +1 -0
  151. package/dist/node/features/container-link.d.ts +213 -0
  152. package/dist/node/features/container-link.d.ts.map +1 -0
  153. package/dist/node/features/content-db.d.ts +354 -0
  154. package/dist/node/features/content-db.d.ts.map +1 -0
  155. package/dist/node/features/disk-cache.d.ts +236 -0
  156. package/dist/node/features/disk-cache.d.ts.map +1 -0
  157. package/dist/node/features/dns.d.ts +511 -0
  158. package/dist/node/features/dns.d.ts.map +1 -0
  159. package/dist/node/features/docker.d.ts +485 -0
  160. package/dist/node/features/docker.d.ts.map +1 -0
  161. package/dist/node/features/downloader.d.ts +73 -0
  162. package/dist/node/features/downloader.d.ts.map +1 -0
  163. package/dist/node/features/figlet-fonts.d.ts +4 -0
  164. package/dist/node/features/figlet-fonts.d.ts.map +1 -0
  165. package/dist/node/features/file-manager.d.ts +177 -0
  166. package/dist/node/features/file-manager.d.ts.map +1 -0
  167. package/dist/node/features/fs.d.ts +635 -0
  168. package/dist/node/features/fs.d.ts.map +1 -0
  169. package/dist/node/features/git.d.ts +329 -0
  170. package/dist/node/features/git.d.ts.map +1 -0
  171. package/dist/node/features/google-auth.d.ts +200 -0
  172. package/dist/node/features/google-auth.d.ts.map +1 -0
  173. package/dist/node/features/google-calendar.d.ts +194 -0
  174. package/dist/node/features/google-calendar.d.ts.map +1 -0
  175. package/dist/node/features/google-docs.d.ts +138 -0
  176. package/dist/node/features/google-docs.d.ts.map +1 -0
  177. package/dist/node/features/google-drive.d.ts +202 -0
  178. package/dist/node/features/google-drive.d.ts.map +1 -0
  179. package/dist/node/features/google-mail.d.ts +221 -0
  180. package/dist/node/features/google-mail.d.ts.map +1 -0
  181. package/dist/node/features/google-sheets.d.ts +157 -0
  182. package/dist/node/features/google-sheets.d.ts.map +1 -0
  183. package/dist/node/features/grep.d.ts +207 -0
  184. package/dist/node/features/grep.d.ts.map +1 -0
  185. package/dist/node/features/helpers.d.ts +236 -0
  186. package/dist/node/features/helpers.d.ts.map +1 -0
  187. package/dist/node/features/ink.d.ts +332 -0
  188. package/dist/node/features/ink.d.ts.map +1 -0
  189. package/dist/node/features/ipc-socket.d.ts +298 -0
  190. package/dist/node/features/ipc-socket.d.ts.map +1 -0
  191. package/dist/node/features/json-tree.d.ts +140 -0
  192. package/dist/node/features/json-tree.d.ts.map +1 -0
  193. package/dist/node/features/networking.d.ts +373 -0
  194. package/dist/node/features/networking.d.ts.map +1 -0
  195. package/dist/node/features/nlp.d.ts +125 -0
  196. package/dist/node/features/nlp.d.ts.map +1 -0
  197. package/dist/node/features/opener.d.ts +93 -0
  198. package/dist/node/features/opener.d.ts.map +1 -0
  199. package/dist/node/features/os.d.ts +168 -0
  200. package/dist/node/features/os.d.ts.map +1 -0
  201. package/dist/node/features/package-finder.d.ts +419 -0
  202. package/dist/node/features/package-finder.d.ts.map +1 -0
  203. package/dist/node/features/postgres.d.ts +173 -0
  204. package/dist/node/features/postgres.d.ts.map +1 -0
  205. package/dist/node/features/proc.d.ts +285 -0
  206. package/dist/node/features/proc.d.ts.map +1 -0
  207. package/dist/node/features/process-manager.d.ts +427 -0
  208. package/dist/node/features/process-manager.d.ts.map +1 -0
  209. package/dist/node/features/python.d.ts +477 -0
  210. package/dist/node/features/python.d.ts.map +1 -0
  211. package/dist/node/features/redis.d.ts +247 -0
  212. package/dist/node/features/redis.d.ts.map +1 -0
  213. package/dist/node/features/repl.d.ts +84 -0
  214. package/dist/node/features/repl.d.ts.map +1 -0
  215. package/dist/node/features/runpod.d.ts +527 -0
  216. package/dist/node/features/runpod.d.ts.map +1 -0
  217. package/dist/node/features/secure-shell.d.ts +145 -0
  218. package/dist/node/features/secure-shell.d.ts.map +1 -0
  219. package/dist/node/features/semantic-search.d.ts +207 -0
  220. package/dist/node/features/semantic-search.d.ts.map +1 -0
  221. package/dist/node/features/sqlite.d.ts +180 -0
  222. package/dist/node/features/sqlite.d.ts.map +1 -0
  223. package/dist/node/features/telegram.d.ts +173 -0
  224. package/dist/node/features/telegram.d.ts.map +1 -0
  225. package/dist/node/features/transpiler.d.ts +51 -0
  226. package/dist/node/features/transpiler.d.ts.map +1 -0
  227. package/dist/node/features/tts.d.ts +108 -0
  228. package/dist/node/features/tts.d.ts.map +1 -0
  229. package/dist/node/features/ui.d.ts +562 -0
  230. package/dist/node/features/ui.d.ts.map +1 -0
  231. package/dist/node/features/vault.d.ts +90 -0
  232. package/dist/node/features/vault.d.ts.map +1 -0
  233. package/dist/node/features/vm.d.ts +285 -0
  234. package/dist/node/features/vm.d.ts.map +1 -0
  235. package/dist/node/features/yaml-tree.d.ts +118 -0
  236. package/dist/node/features/yaml-tree.d.ts.map +1 -0
  237. package/dist/node/features/yaml.d.ts +127 -0
  238. package/dist/node/features/yaml.d.ts.map +1 -0
  239. package/dist/node.d.ts +67 -0
  240. package/dist/node.d.ts.map +1 -0
  241. package/dist/python/generated.d.ts +2 -0
  242. package/dist/python/generated.d.ts.map +1 -0
  243. package/dist/react/index.d.ts +36 -0
  244. package/dist/react/index.d.ts.map +1 -0
  245. package/dist/registry.d.ts +97 -0
  246. package/dist/registry.d.ts.map +1 -0
  247. package/dist/scaffolds/generated.d.ts +13 -0
  248. package/dist/scaffolds/generated.d.ts.map +1 -0
  249. package/dist/scaffolds/template.d.ts +11 -0
  250. package/dist/scaffolds/template.d.ts.map +1 -0
  251. package/dist/schemas/base.d.ts +254 -0
  252. package/dist/schemas/base.d.ts.map +1 -0
  253. package/dist/selector.d.ts +130 -0
  254. package/dist/selector.d.ts.map +1 -0
  255. package/dist/server.d.ts +89 -0
  256. package/dist/server.d.ts.map +1 -0
  257. package/dist/servers/express.d.ts +104 -0
  258. package/dist/servers/express.d.ts.map +1 -0
  259. package/dist/servers/mcp.d.ts +201 -0
  260. package/dist/servers/mcp.d.ts.map +1 -0
  261. package/dist/servers/socket.d.ts +121 -0
  262. package/dist/servers/socket.d.ts.map +1 -0
  263. package/dist/state.d.ts +24 -0
  264. package/dist/state.d.ts.map +1 -0
  265. package/dist/web/clients/socket.d.ts +37 -0
  266. package/dist/web/clients/socket.d.ts.map +1 -0
  267. package/dist/web/container.d.ts +55 -0
  268. package/dist/web/container.d.ts.map +1 -0
  269. package/dist/web/extension.d.ts +4 -0
  270. package/dist/web/extension.d.ts.map +1 -0
  271. package/dist/web/feature.d.ts +8 -0
  272. package/dist/web/feature.d.ts.map +1 -0
  273. package/dist/web/features/asset-loader.d.ts +35 -0
  274. package/dist/web/features/asset-loader.d.ts.map +1 -0
  275. package/dist/web/features/container-link.d.ts +167 -0
  276. package/dist/web/features/container-link.d.ts.map +1 -0
  277. package/dist/web/features/esbuild.d.ts +51 -0
  278. package/dist/web/features/esbuild.d.ts.map +1 -0
  279. package/dist/web/features/helpers.d.ts +140 -0
  280. package/dist/web/features/helpers.d.ts.map +1 -0
  281. package/dist/web/features/network.d.ts +69 -0
  282. package/dist/web/features/network.d.ts.map +1 -0
  283. package/dist/web/features/speech.d.ts +71 -0
  284. package/dist/web/features/speech.d.ts.map +1 -0
  285. package/dist/web/features/vault.d.ts +62 -0
  286. package/dist/web/features/vault.d.ts.map +1 -0
  287. package/dist/web/features/vm.d.ts +48 -0
  288. package/dist/web/features/vm.d.ts.map +1 -0
  289. package/dist/web/features/voice-recognition.d.ts +96 -0
  290. package/dist/web/features/voice-recognition.d.ts.map +1 -0
  291. package/dist/web/shims/isomorphic-vm.d.ts +22 -0
  292. package/dist/web/shims/isomorphic-vm.d.ts.map +1 -0
  293. package/docs/apis/features/agi/assistant.md +1 -0
  294. package/docs/apis/features/agi/assistants-manager.md +62 -2
  295. package/docs/apis/features/agi/auto-assistant.md +11 -109
  296. package/docs/apis/features/agi/claude-code.md +138 -0
  297. package/docs/apis/features/agi/conversation.md +60 -31
  298. package/docs/apis/features/agi/luca-coder.md +407 -0
  299. package/docs/apis/features/agi/openapi.md +2 -2
  300. package/docs/apis/features/agi/skills-library.md +12 -0
  301. package/docs/apis/features/node/python.md +81 -11
  302. package/docs/apis/features/node/transpiler.md +74 -0
  303. package/docs/apis/features/web/esbuild.md +0 -6
  304. package/docs/apis/servers/mcp.md +2 -2
  305. package/docs/examples/entity.md +124 -0
  306. package/docs/ideas/assistant-factory-pattern.md +142 -0
  307. package/package.json +74 -21
  308. package/src/agi/container.server.ts +10 -0
  309. package/src/agi/feature.ts +13 -0
  310. package/src/agi/features/agent-memory.ts +694 -0
  311. package/src/agi/features/assistant.ts +37 -26
  312. package/src/agi/features/assistants-manager.ts +95 -5
  313. package/src/agi/features/autonomous-assistant.ts +1 -5
  314. package/src/agi/features/browser-use.ts +32 -2
  315. package/src/agi/features/claude-code.ts +165 -1
  316. package/src/agi/features/coding-tools.ts +175 -0
  317. package/src/agi/features/conversation-history.ts +2 -6
  318. package/src/agi/features/conversation.ts +95 -3
  319. package/src/agi/features/docs-reader.ts +2 -1
  320. package/src/agi/features/file-tools.ts +35 -28
  321. package/src/agi/features/luca-coder.ts +1 -5
  322. package/src/agi/features/openai-codex.ts +1 -1
  323. package/src/agi/features/openapi.ts +3 -3
  324. package/src/agi/features/skills-library.ts +111 -13
  325. package/src/agi/lib/interceptor-chain.ts +10 -0
  326. package/src/agi/lib/token-counter.ts +1 -1
  327. package/src/bootstrap/generated.ts +126 -1
  328. package/src/bus.ts +27 -5
  329. package/src/cli/build-info.ts +2 -2
  330. package/src/client.ts +2 -2
  331. package/src/clients/elevenlabs/index.ts +5 -0
  332. package/src/clients/voicebox/index.ts +300 -0
  333. package/src/commands/bootstrap.ts +2 -1
  334. package/src/commands/chat.ts +1 -0
  335. package/src/commands/code.ts +4 -2
  336. package/src/commands/prompt.ts +34 -34
  337. package/src/commands/sandbox-mcp.ts +69 -163
  338. package/src/commands/save-api-docs.ts +10 -8
  339. package/src/commands/select.ts +8 -3
  340. package/src/container-describer.ts +70 -84
  341. package/src/container.ts +93 -3
  342. package/src/endpoint.ts +1 -1
  343. package/src/entity.ts +173 -0
  344. package/src/feature.ts +3 -3
  345. package/src/helper.ts +8 -4
  346. package/src/introspection/generated.agi.ts +3012 -1356
  347. package/src/introspection/generated.node.ts +179 -33
  348. package/src/introspection/generated.web.ts +95 -3
  349. package/src/introspection/scan.ts +1 -1
  350. package/src/node/container.ts +1 -1
  351. package/src/node/features/content-db.ts +57 -30
  352. package/src/node/features/file-manager.ts +10 -9
  353. package/src/node/features/git.ts +5 -5
  354. package/src/node/features/helpers.ts +1 -1
  355. package/src/node/features/json-tree.ts +1 -1
  356. package/src/node/features/os.ts +3 -3
  357. package/src/node/features/package-finder.ts +1 -1
  358. package/src/node/features/process-manager.ts +51 -18
  359. package/src/node/features/python.ts +3 -3
  360. package/src/node/features/redis.ts +1 -1
  361. package/src/node/features/repl.ts +2 -2
  362. package/src/node/features/transpiler.ts +2 -2
  363. package/src/node/features/ui.ts +1 -1
  364. package/src/node/features/vm.ts +3 -3
  365. package/src/node/features/yaml-tree.ts +1 -1
  366. package/src/node.ts +1 -0
  367. package/src/python/generated.ts +1 -1
  368. package/src/scaffolds/generated.ts +1 -1
  369. package/src/selector.ts +74 -4
  370. package/src/server.ts +2 -2
  371. package/src/servers/mcp.ts +6 -6
  372. package/src/web/features/helpers.ts +1 -1
  373. package/src/web/features/network.ts +1 -0
  374. package/test/assistant.test.ts +14 -5
  375. package/test/conversation.test.ts +220 -0
  376. package/test-integration/memory.test.ts +204 -0
  377. package/tsconfig.build.json +12 -0
  378. package/tsconfig.json +1 -1
  379. package/scripts/examples/telegram-ink-ui.ts +0 -302
  380. package/scripts/examples/using-openai-codex.ts +0 -23
  381. package/scripts/examples/vm-loading-esm-modules.ts +0 -16
@@ -1,9 +1,10 @@
1
1
  import { z } from 'zod'
2
2
  import { FeatureStateSchema, FeatureOptionsSchema, FeatureEventsSchema } from '../../schemas/base.js'
3
- import { type AvailableFeatures, Feature } from '@soederpop/luca/feature'
3
+ import { type AvailableFeatures } from '@soederpop/luca/feature'
4
+ import { Feature } from '../feature.js'
4
5
  import { parse } from 'contentbase'
5
6
  import type { DocsReader } from './docs-reader.js'
6
- import type Assistant from './assistant.js'
7
+ import Assistant from './assistant.js'
7
8
 
8
9
  declare module '@soederpop/luca/feature' {
9
10
  interface AvailableFeatures {
@@ -72,22 +73,22 @@ export class SkillsLibrary extends Feature<SkillsLibraryState, SkillsLibraryOpti
72
73
  static { Feature.register(this, 'skillsLibrary') }
73
74
 
74
75
  /** Tools for assistant integration via assistant.use(skillsLibrary). */
75
- static tools: Record<string, { schema: z.ZodType; handler?: Function }> = {
76
+ static override tools: Record<string, { schema: z.ZodType; handler?: Function }> = {
76
77
  searchAvailableSkills: {
77
78
  schema: z.object({
78
- query: z.string().optional().describe('Optional search term to filter skills by name or description'),
79
- }).describe('Search for available skills in the library. Returns matching skill names and descriptions.'),
79
+ query: z.string().optional().describe('A keyword or phrase to filter skills by name or description. Omit to list all available skills.'),
80
+ }).describe('Discover what skills are available. Call this first when you need specialized knowledge — skills are curated guides and reference material for specific domains (frameworks, tools, patterns). Returns skill names and descriptions so you can decide which to load.'),
80
81
  },
81
82
  loadSkill: {
82
83
  schema: z.object({
83
- skillName: z.string().describe('The name of the skill to load'),
84
- }).describe('Load a skill by name and return its full SKILL.md content and metadata.'),
84
+ skillName: z.string().describe('The exact skill name as returned by searchAvailableSkills'),
85
+ }).describe('Load a skill\'s full reference content (SKILL.md). This gives you detailed guidance, examples, and best practices for that domain. Load a skill before attempting work in an unfamiliar area — the content is curated to prevent common mistakes.'),
85
86
  },
86
87
  askSkillBasedQuestion: {
87
88
  schema: z.object({
88
- skillName: z.string().describe('The name of the skill to query'),
89
- question: z.string().describe('The question to ask about the skill'),
90
- }).describe('Ask a question about a specific skill using AI-assisted document reading.'),
89
+ skillName: z.string().describe('The exact skill name to query'),
90
+ question: z.string().describe('A specific question about the skill\'s domain. Be precise — "how do I add a new feature to the container?" is better than "tell me about features".'),
91
+ }).describe('Ask a focused question about a skill\'s domain using AI-assisted document reading. Use this when you need a specific answer from a skill rather than reading the whole thing. More efficient than loadSkill for targeted lookups.'),
91
92
  },
92
93
  }
93
94
 
@@ -102,9 +103,61 @@ export class SkillsLibrary extends Feature<SkillsLibraryState, SkillsLibraryOpti
102
103
  }
103
104
  }
104
105
 
105
- override setupToolsConsumer(assistant: Assistant) {
106
- console.log('setting up tools consumer', assistant.uuid)
107
- assistant.state.set('toolsSetup', true)
106
+ override setupToolsConsumer(assistant: Feature) {
107
+ if (!(assistant instanceof Assistant)) {
108
+ throw new Error('Skills library tools require an Assistant instance (including subclasses).')
109
+ }
110
+
111
+ const a : Assistant = assistant as Assistant
112
+
113
+ a.addSystemPromptExtension('skillsLibrary', [
114
+ '## Skills Library',
115
+ '',
116
+ 'You have access to a library of curated skills — domain-specific reference guides with examples, patterns, and best practices.',
117
+ '',
118
+ '**When to use skills:**',
119
+ '- When working in an unfamiliar domain or framework — load the skill before writing code',
120
+ '- When the user asks about a topic that might have a matching skill — search first',
121
+ '- When you see "Required Skills" in a message — load those skills immediately with `loadSkill` before answering',
122
+ '',
123
+ '**Workflow:** `searchAvailableSkills` → find relevant skill → `loadSkill` to get the full guide → follow its patterns. Use `askSkillBasedQuestion` for targeted lookups when you don\'t need the whole guide.',
124
+ '',
125
+ '**Skills are authoritative.** When a loaded skill contradicts your general knowledge, follow the skill — it reflects project-specific conventions and decisions.',
126
+ ].join('\n'))
127
+
128
+ const { container } = a
129
+
130
+ const skillsLibrary = this
131
+
132
+ const preloadSkills : string[] = []
133
+ if (a.meta.skills) {
134
+ if (Array.isArray(a.meta.skills)) {
135
+ preloadSkills.push(...a.meta.skills)
136
+ } else {
137
+ preloadSkills.push(a.meta.skills)
138
+ }
139
+ }
140
+
141
+ async function beforeAskCheckIfWeNeedSkills(ctx: any, next: any) {
142
+ const { question } = ctx
143
+ const skills = await skillsLibrary.findRelevantSkillsForAssistant(a, question as string)
144
+
145
+ const allSkillsToLoad : string[] = container.utils.lodash.uniq([
146
+ ...skills,
147
+ ...preloadSkills,
148
+ ])
149
+
150
+ if (allSkillsToLoad.length) {
151
+ ctx.question = `${ctx.question} \n\n## Required Skills\nYou will need to load the following skills to answer this question: ${skills.join(', ')}`
152
+ }
153
+
154
+ a.interceptors.beforeAsk.remove(beforeAskCheckIfWeNeedSkills)
155
+
156
+ await next()
157
+ }
158
+
159
+ assistant.intercept('beforeAsk', beforeAskCheckIfWeNeedSkills as any)
160
+
108
161
  return assistant
109
162
  }
110
163
 
@@ -375,6 +428,51 @@ export class SkillsLibrary extends Feature<SkillsLibraryState, SkillsLibraryOpti
375
428
  const answer = await reader.ask(question)
376
429
  return answer
377
430
  }
431
+
432
+ /**
433
+ * Fork the given assistant and ask it which skills (if any) are relevant
434
+ * to the user's query. Returns an array of skill names that should be loaded
435
+ * before the real question is answered.
436
+ *
437
+ * The fork is ephemeral (historyMode: 'none') and uses structured output so
438
+ * the result is always a clean string array — never free text.
439
+ *
440
+ * @param assistant - The assistant instance to fork
441
+ * @param userQuery - The user's original question
442
+ * @returns Array of skill names relevant to the query (may be empty)
443
+ */
444
+ async findRelevantSkillsForAssistant(assistant: Assistant, userQuery: string): Promise<string[]> {
445
+ if (!this.isStarted) await this.start()
446
+
447
+ const skills = this.list()
448
+ if (skills.length === 0) return []
449
+
450
+ const responseSchema = z.object({
451
+ skills: z.array(z.string()).describe('Names of skills relevant to the query. Empty array if none apply.'),
452
+ })
453
+
454
+ const skillsDescription = Object.entries(this.skillsTable)
455
+ .map(([title,description]) => `- **${title}**: ${description}`)
456
+ .join("\n")
457
+
458
+ const prompt = this.container.ui.endent(`You are a routing assistant. Given a user query and a list of available skills, determine which skills (if any) should be loaded to help answer the query.
459
+ Available skills:
460
+ -------
461
+ ${skillsDescription}
462
+
463
+ User query: ${userQuery}
464
+
465
+ Return only the skill names that are directly relevant. Return an empty array if none apply. Do not load skills speculatively — only include ones that would materially help answer this specific query.`)
466
+
467
+ const fork = assistant.conversation.fork()
468
+ const result = await fork.ask(prompt, { schema: responseSchema }) as unknown as { skills: string[] }
469
+
470
+ const found = result.skills.filter(name => this.find(name) !== undefined)
471
+
472
+ this.emit('foundSkills', found, assistant, userQuery)
473
+
474
+ return found
475
+ }
378
476
  }
379
477
 
380
478
  export default SkillsLibrary
@@ -26,6 +26,16 @@ export class InterceptorChain<T> {
26
26
  return this.fns.length
27
27
  }
28
28
 
29
+ clear(): void {
30
+ this.fns = []
31
+ }
32
+
33
+ clone(): InterceptorChain<T> {
34
+ const copy = new InterceptorChain<T>()
35
+ for (const fn of this.fns) copy.add(fn)
36
+ return copy
37
+ }
38
+
29
39
  async run(ctx: T, final: () => Promise<void>): Promise<void> {
30
40
  let index = 0
31
41
  const fns = this.fns
@@ -39,7 +39,7 @@ export function getContextWindow(model: string): number {
39
39
  }
40
40
  }
41
41
 
42
- return best ? MODEL_CONTEXT_WINDOWS[best] : DEFAULT_CONTEXT_WINDOW
42
+ return best ? MODEL_CONTEXT_WINDOWS[best] ?? DEFAULT_CONTEXT_WINDOW : DEFAULT_CONTEXT_WINDOW
43
43
  }
44
44
 
45
45
  /** Get a cached tiktoken encoder for a model (falls back to o200k_base). */
@@ -1,5 +1,5 @@
1
1
  // Auto-generated bootstrap content
2
- // Generated at: 2026-03-30T06:52:56.930Z
2
+ // Generated at: 2026-04-05T06:58:07.990Z
3
3
  // Source: docs/bootstrap/*.md, docs/bootstrap/templates/*, docs/examples/*.md, docs/tutorials/*.md
4
4
  //
5
5
  // Do not edit manually. Run: luca build-bootstrap
@@ -1253,6 +1253,131 @@ console.log('Running after killAll:', remaining.length)
1253
1253
  ## Summary
1254
1254
 
1255
1255
  This demo covered the \`processManager\` feature: spawning processes that return handles immediately, tracking them by ID or tag, listing all tracked processes, and killing them individually or all at once. It is the right tool for orchestrating background services, dev servers, and any scenario where you need non-blocking process management with lifecycle events.
1256
+ `,
1257
+ "entity.md": `---
1258
+ title: "Entity"
1259
+ tags: [entity, state, events, tools, core]
1260
+ lastTested: null
1261
+ lastTestPassed: null
1262
+ ---
1263
+
1264
+ # entity
1265
+
1266
+ Lightweight, composable objects with observable state, a typed event bus, and an optional tool interface.
1267
+
1268
+ ## Overview
1269
+
1270
+ An entity is a plain object — not a class — created via \`container.entity(id, options?)\`. Same id + options always returns the same underlying state and bus instance. Entities are designed to be extended with methods and getters via \`.extend()\`, and can expose those methods as AI tools via \`.expose()\`.
1271
+
1272
+ ## Basic Entity with Observable State
1273
+
1274
+ Create an entity and read/write state through the observable \`state\` property.
1275
+
1276
+ \`\`\`ts
1277
+ const counter = container.entity<{ count: number }>('counter')
1278
+ counter.setState({ count: 0 })
1279
+
1280
+ counter.state.observe((next) => {
1281
+ console.log('count changed to', next.count)
1282
+ })
1283
+
1284
+ counter.setState(s => ({ count: s.count + 1 }))
1285
+ counter.setState(s => ({ count: s.count + 1 }))
1286
+ console.log('final count:', counter.state.get('count'))
1287
+ \`\`\`
1288
+
1289
+ \`setState\` accepts either a partial object or a function that receives the current state. Observers fire synchronously after each change.
1290
+
1291
+ ## Typed Event Bus
1292
+
1293
+ Every entity has a built-in event bus. Declare the event map as the third type parameter.
1294
+
1295
+ \`\`\`ts
1296
+ type TimerEvents = {
1297
+ tick: [elapsed: number]
1298
+ done: []
1299
+ }
1300
+
1301
+ const timer = container.entity<{}, {}, TimerEvents>('timer')
1302
+
1303
+ timer.on('tick', (elapsed) => {
1304
+ console.log('tick at', elapsed, 'ms')
1305
+ })
1306
+
1307
+ timer.once('done', () => {
1308
+ console.log('timer finished')
1309
+ })
1310
+
1311
+ timer.emit('tick', 100)
1312
+ timer.emit('tick', 200)
1313
+ timer.emit('done')
1314
+ \`\`\`
1315
+
1316
+ \`once\` auto-detaches after the first fire. \`waitFor\` returns a promise that resolves on the next emit of that event.
1317
+
1318
+ ## Extending with Methods
1319
+
1320
+ Use \`.extend()\` to graft methods and getters onto an entity. All base properties — \`state\`, \`options\`, \`container\`, and the event methods — are available via \`this\`.
1321
+
1322
+ \`\`\`ts
1323
+ const session = container.entity('session', { userId: '42' })
1324
+ .extend({
1325
+ greet() {
1326
+ return \`Hello user \${this.options.userId}\`
1327
+ },
1328
+ get label() {
1329
+ return \`Session \${this.id} (user \${this.options.userId})\`
1330
+ },
1331
+ bump() {
1332
+ const visits = (this.state.get('visits') ?? 0) + 1
1333
+ this.setState({ visits })
1334
+ this.emit('visited', visits)
1335
+ return visits
1336
+ },
1337
+ })
1338
+
1339
+ console.log(session.greet())
1340
+ console.log(session.label)
1341
+ console.log('visits:', session.bump())
1342
+ console.log('visits:', session.bump())
1343
+ \`\`\`
1344
+
1345
+ Extensions are chained via prototype delegation — each layer can see everything below it.
1346
+
1347
+ ## Exposing Methods as AI Tools
1348
+
1349
+ Use \`.expose(methodName, zodSchema)\` to register methods as tools. \`.toTools()\` returns \`{ schemas, handlers }\` compatible with \`assistant.addTools()\`.
1350
+
1351
+ \`\`\`ts
1352
+ const search = container.entity('search', {})
1353
+ .extend({
1354
+ async lookup({ query }: { query: string }) {
1355
+ return \`Results for: \${query}\`
1356
+ },
1357
+ async summarize({ text, maxWords }: { text: string; maxWords: number }) {
1358
+ return text.split(' ').slice(0, maxWords).join(' ')
1359
+ },
1360
+ })
1361
+ .expose('lookup', z.object({
1362
+ query: z.string().describe('The search query'),
1363
+ }))
1364
+ .expose('summarize', z.object({
1365
+ text: z.string().describe('Text to summarize'),
1366
+ maxWords: z.number().describe('Maximum words in summary'),
1367
+ }))
1368
+
1369
+ const { schemas, handlers } = search.toTools()
1370
+ console.log('registered tools:', Object.keys(schemas))
1371
+
1372
+ // Pass directly to an assistant
1373
+ // assistant.addTools(search)
1374
+ \`\`\`
1375
+
1376
+ \`.expose()\` is chainable and returns \`this\`, so you can stack as many as you need.
1377
+
1378
+ ## Summary
1379
+
1380
+ Entities give you observable state, a typed event bus, and prototype-safe method extension — all as a plain object with no class overhead. The \`.expose()\` / \`.toTools()\` interface makes it straightforward to surface entity methods as AI tools.
1256
1381
  `,
1257
1382
  "assistant-with-process-manager.md": `---
1258
1383
  title: "Assistant with ProcessManager Tools"
package/src/bus.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export type EventMap = Record<string, any[]>;
2
2
 
3
3
  type Listener<Args extends any[] = any[]> = (...args: Args) => void;
4
+ type WildcardListener = (event: string, ...args: any[]) => void;
4
5
 
5
6
  export interface EventStats {
6
7
  event: string;
@@ -12,10 +13,12 @@ export interface EventStats {
12
13
 
13
14
  export class Bus<T extends EventMap = EventMap> {
14
15
  private events: Map<string, Listener[]>;
16
+ private wildcardListeners: WildcardListener[];
15
17
  private stats: Map<string, { fireCount: number; lastFiredAt: number | null; timestamps: number[] }>;
16
18
 
17
19
  constructor() {
18
20
  this.events = new Map();
21
+ this.wildcardListeners = [];
19
22
  this.stats = new Map();
20
23
  }
21
24
 
@@ -64,12 +67,19 @@ export class Bus<T extends EventMap = EventMap> {
64
67
  emit<E extends string & keyof T>(event: E, ...args: T[E]): void {
65
68
  this.recordEmit(event);
66
69
  const listeners = this.events.get(event);
67
- if (!listeners) return;
68
-
69
- listeners.forEach(listener => listener(...args));
70
+ if (listeners) {
71
+ listeners.forEach(listener => listener(...args));
72
+ }
73
+ this.wildcardListeners.forEach(listener => listener(event, ...args));
70
74
  }
71
75
 
72
- on<E extends string & keyof T>(event: E, listener: (...args: T[E]) => void): void {
76
+ on(event: '*', listener: WildcardListener): void
77
+ on<E extends string & keyof T>(event: E, listener: (...args: T[E]) => void): void
78
+ on<E extends string & keyof T>(event: E | '*', listener: any): void {
79
+ if (event === '*') {
80
+ this.wildcardListeners.push(listener);
81
+ return;
82
+ }
73
83
  const listeners = this.events.get(event) || [];
74
84
  listeners.push(listener as Listener);
75
85
  this.events.set(event, listeners);
@@ -83,7 +93,19 @@ export class Bus<T extends EventMap = EventMap> {
83
93
  this.on(event, onceListener as any);
84
94
  }
85
95
 
86
- off<E extends string & keyof T>(event: E, listener?: (...args: T[E]) => void): void {
96
+ off(event: '*', listener?: WildcardListener): void
97
+ off<E extends string & keyof T>(event: E, listener?: (...args: T[E]) => void): void
98
+ off<E extends string & keyof T>(event: E | '*', listener?: any): void {
99
+ if (event === '*') {
100
+ if (!listener) {
101
+ this.wildcardListeners = [];
102
+ return;
103
+ }
104
+ const index = this.wildcardListeners.indexOf(listener);
105
+ if (index !== -1) this.wildcardListeners.splice(index, 1);
106
+ return;
107
+ }
108
+
87
109
  const listeners = this.events.get(event);
88
110
  if (!listeners) return;
89
111
 
@@ -1,4 +1,4 @@
1
1
  // Generated at compile time — do not edit manually
2
- export const BUILD_SHA = 'e1b45a8'
2
+ export const BUILD_SHA = '8323521'
3
3
  export const BUILD_BRANCH = 'main'
4
- export const BUILD_DATE = '2026-03-30T06:52:57Z'
4
+ export const BUILD_DATE = '2026-04-05T06:58:08Z'
package/src/client.ts CHANGED
@@ -46,7 +46,7 @@ export class Client<
46
46
  static override eventsSchema = ClientEventsSchema
47
47
 
48
48
  /** Self-register a Client subclass from a static initialization block. */
49
- static register: (SubClass: typeof Client, id?: string) => typeof Client
49
+ static register: (SubClass: abstract new (options: any, context: any) => Client, id?: string) => abstract new (options: any, context: any) => Client
50
50
 
51
51
  static attach(container: Container & ClientsInterface): any {
52
52
  Object.assign(container, {
@@ -141,7 +141,7 @@ export const helperCache = new Map();
141
141
  * ```
142
142
  */
143
143
  Client.register = function registerClient(
144
- SubClass: typeof Client,
144
+ SubClass: abstract new (options: any, context: any) => Client,
145
145
  id?: string,
146
146
  ) {
147
147
  const registryId = id ?? SubClass.name[0]!.toLowerCase() + SubClass.name.slice(1)
@@ -3,6 +3,7 @@ import { ClientStateSchema, ClientOptionsSchema, ClientEventsSchema } from '@soe
3
3
  import { Client } from "@soederpop/luca/client";
4
4
  import { RestClient } from "../rest";
5
5
  import type { ContainerContext } from "@soederpop/luca/container";
6
+ import type { NodeContainer } from "../../node/container.js";
6
7
  import type { AxiosRequestConfig } from 'axios'
7
8
 
8
9
  declare module "@soederpop/luca/client" {
@@ -92,6 +93,10 @@ export class ElevenLabsClient extends RestClient<ElevenLabsClientState, ElevenLa
92
93
  super(options, context)
93
94
  }
94
95
 
96
+ override get container(): NodeContainer {
97
+ return super.container as unknown as NodeContainer
98
+ }
99
+
95
100
  /** The resolved API key from options or environment. */
96
101
  get apiKey(): string {
97
102
  return this.options.apiKey || process.env.ELEVENLABS_API_KEY || ''