@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
package/src/selector.ts CHANGED
@@ -135,17 +135,17 @@ export class Selector<
135
135
  }
136
136
 
137
137
  // Run the selector
138
- this.state.set('running' as any, true)
138
+ this.state.set('running' as any, true as any)
139
139
  this.emit('started' as any)
140
140
 
141
141
  let data: any
142
142
  try {
143
143
  data = await this.run(parsed, this.context)
144
- this.state.set('running' as any, false)
145
- this.state.set('lastRanAt' as any, Date.now())
144
+ this.state.set('running' as any, false as any)
145
+ this.state.set('lastRanAt' as any, Date.now() as any)
146
146
  this.emit('completed' as any, data)
147
147
  } catch (err: any) {
148
- this.state.set('running' as any, false)
148
+ this.state.set('running' as any, false as any)
149
149
  this.emit('failed' as any, err)
150
150
  throw err
151
151
  }
@@ -197,6 +197,76 @@ export class SelectorsRegistry extends Registry<Selector<any>> {
197
197
  override scope = 'selectors'
198
198
  override baseClass = Selector as any
199
199
 
200
+ /**
201
+ * Convert all registered selectors into a `{ schemas, handlers }` object
202
+ * compatible with `assistant.use()`.
203
+ *
204
+ * Each selector becomes a tool whose parameters come from the selector's
205
+ * `argsSchema` (with internal fields stripped) and whose handler dispatches
206
+ * the selector and returns the data directly (cache metadata is not exposed).
207
+ *
208
+ * @param container - The container used to instantiate and run selectors
209
+ * @param options - Optional filter/transform options
210
+ * @param options.include - Only include these selector names (default: all)
211
+ * @param options.exclude - Exclude these selector names (default: none)
212
+ * @param options.prefix - Prefix tool names (e.g. 'sel_' → 'sel_packageInfo')
213
+ */
214
+ toTools(
215
+ container: Container<any> & SelectorsInterface,
216
+ options?: { include?: string[], exclude?: string[], prefix?: string },
217
+ ): { schemas: Record<string, z.ZodType>, handlers: Record<string, Function> } {
218
+ const schemas: Record<string, z.ZodType> = {}
219
+ const handlers: Record<string, Function> = {}
220
+ const prefix = options?.prefix ?? ''
221
+ const includeSet = options?.include ? new Set(options.include) : null
222
+ const excludeSet = new Set(options?.exclude ?? [])
223
+
224
+ // Internal fields from HelperOptionsSchema and SelectorOptionsSchema
225
+ const internalFields = ['name', '_cacheKey', 'dispatchSource']
226
+
227
+ for (const name of this.available) {
228
+ if (excludeSet.has(name)) continue
229
+ if (includeSet && !includeSet.has(name)) continue
230
+
231
+ const Sel = this.lookup(name) as typeof Selector
232
+ const rawSchema = Sel.argsSchema
233
+ const description = Sel.selectorDescription || Sel.description || name
234
+
235
+ let toolSchema: z.ZodType
236
+ try {
237
+ const shape = typeof (rawSchema as any)?._def?.shape === 'function'
238
+ ? (rawSchema as any)._def.shape()
239
+ : (rawSchema as any)?._def?.shape
240
+
241
+ if (shape) {
242
+ const cleanShape: Record<string, z.ZodType> = {}
243
+ for (const [key, val] of Object.entries(shape)) {
244
+ if (internalFields.includes(key)) continue
245
+ cleanShape[key] = val as z.ZodType
246
+ }
247
+
248
+ toolSchema = Object.keys(cleanShape).length > 0
249
+ ? z.object(cleanShape).describe(description)
250
+ : z.object({}).describe(description)
251
+ } else {
252
+ toolSchema = z.object({}).describe(description)
253
+ }
254
+ } catch {
255
+ toolSchema = z.object({}).describe(description)
256
+ }
257
+
258
+ const toolName = `${prefix}${name}`
259
+ schemas[toolName] = toolSchema
260
+ handlers[toolName] = async (args: Record<string, any>) => {
261
+ const sel = (container.select as any)(name)
262
+ const result = await sel.select(args ?? {})
263
+ return result.data
264
+ }
265
+ }
266
+
267
+ return { schemas, handlers }
268
+ }
269
+
200
270
  /**
201
271
  * Discover and register selectors from a directory.
202
272
  * Detection order:
package/src/server.ts CHANGED
@@ -30,7 +30,7 @@ export class Server<T extends ServerState = ServerState, K extends ServerOptions
30
30
  static override eventsSchema = ServerEventsSchema
31
31
 
32
32
  /** Self-register a Server subclass from a static initialization block. */
33
- static register: (SubClass: typeof Server, id?: string) => typeof Server
33
+ static register: (SubClass: abstract new (options: any, context: any) => Server, id?: string) => abstract new (options: any, context: any) => Server
34
34
 
35
35
  override get initialState() : T {
36
36
  return ({
@@ -203,7 +203,7 @@ export const helperCache = new Map()
203
203
  * ```
204
204
  */
205
205
  Server.register = function registerServer(
206
- SubClass: typeof Server,
206
+ SubClass: abstract new (options: any, context: any) => Server,
207
207
  id?: string,
208
208
  ) {
209
209
  const registryId = id ?? SubClass.name[0]!.toLowerCase() + SubClass.name.slice(1)
@@ -33,9 +33,9 @@ export type MCPContext = {
33
33
  export interface RegisteredTool {
34
34
  name: string
35
35
  description?: string
36
- schema?: z.ZodObject<any>
36
+ schema?: z.ZodType
37
37
  jsonSchema?: Record<string, any>
38
- handler: (args: any, ctx: MCPContext) => any
38
+ handler: Function
39
39
  }
40
40
 
41
41
  /** A registered MCP resource with its URI, metadata, and handler. */
@@ -61,9 +61,9 @@ export type PromptMessage = {
61
61
  }
62
62
 
63
63
  type ToolRegistrationOptions = {
64
- schema?: z.ZodObject<any>
64
+ schema?: z.ZodType
65
65
  description?: string
66
- handler: (args: any, ctx: MCPContext) => any
66
+ handler?: Function | ((args: any, ctx: any) => any)
67
67
  }
68
68
 
69
69
  type ResourceRegistrationOptions = {
@@ -340,7 +340,7 @@ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
340
340
  * @param name - Unique tool name
341
341
  * @param options - Tool schema, description, and handler
342
342
  */
343
- tool(name: string, options: ToolRegistrationOptions): this {
343
+ override tool(name: string, options: ToolRegistrationOptions): this {
344
344
  let jsonSchema: Record<string, any> | undefined
345
345
 
346
346
  if (options.schema) {
@@ -357,7 +357,7 @@ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
357
357
  description: options.description,
358
358
  schema: options.schema,
359
359
  jsonSchema,
360
- handler: options.handler,
360
+ handler: options.handler ?? (() => {}),
361
361
  }
362
362
 
363
363
  this._tools.set(name, registered)
@@ -136,7 +136,7 @@ export class Helpers extends Feature<HelpersState, HelpersOptions> {
136
136
  return {}
137
137
  }
138
138
 
139
- const manifest: Manifest = await response.json()
139
+ const manifest = await response.json() as Manifest
140
140
  this._manifest = manifest
141
141
  this.state.set('manifestLoaded', true)
142
142
  this.emit('manifestLoaded' as any, manifest)
@@ -1,3 +1,4 @@
1
+ /// <reference lib="dom" />
1
2
  import { z } from 'zod'
2
3
  import { FeatureStateSchema, FeatureOptionsSchema, FeatureEventsSchema } from '../../schemas/base.js'
3
4
  import { Feature } from "../feature.js";
@@ -15,18 +15,27 @@ describe('Assistant', () => {
15
15
  expect(assistant.systemPrompt).toContain('coding assistant')
16
16
  })
17
17
 
18
- it('loads tools from tools.ts via the VM', () => {
19
- const assistant = container.feature('assistant', { folder: 'assistants/codingAssistant' })
18
+ it('loads tools from codingTools feature after start', async () => {
19
+ const assistant = container.feature('assistant', {
20
+ folder: 'assistants/codingAssistant',
21
+ local: true,
22
+ model: 'qwen/qwen3-8b',
23
+ })
24
+ await assistant.start()
20
25
  const tools = assistant.availableTools
21
26
  expect(tools).toContain('rg')
22
27
  expect(tools).toContain('ls')
23
28
  expect(tools).toContain('cat')
24
- expect(tools).toContain('pwd')
25
29
  expect(tools.length).toBeGreaterThan(0)
26
30
  })
27
31
 
28
- it('tools have descriptions and parameter schemas', () => {
29
- const assistant = container.feature('assistant', { folder: 'assistants/codingAssistant' })
32
+ it('tools have descriptions and parameter schemas', async () => {
33
+ const assistant = container.feature('assistant', {
34
+ folder: 'assistants/codingAssistant',
35
+ local: true,
36
+ model: 'qwen/qwen3-8b',
37
+ })
38
+ await assistant.start()
30
39
  const { rg, ls, cat } = assistant.tools
31
40
  expect(rg.description.length).toBeGreaterThan(0)
32
41
  expect(rg.parameters.type).toBe('object')
@@ -0,0 +1,220 @@
1
+ import { describe, it, expect, beforeEach } from 'bun:test'
2
+ import { AGIContainer } from '../src/agi/container.server'
3
+ import type { Conversation } from '../src/agi/features/conversation'
4
+
5
+ function makeConversation(opts: Record<string, any> = {}): Conversation {
6
+ const container = new AGIContainer()
7
+ return container.feature('conversation', { model: 'gpt-5', ...opts }) as Conversation
8
+ }
9
+
10
+ describe('Conversation', () => {
11
+ describe('state', () => {
12
+ it('initializes with empty messages when no history provided', () => {
13
+ const conv = makeConversation()
14
+ expect(conv.messages).toEqual([])
15
+ })
16
+
17
+ it('seeds message history from options', () => {
18
+ const history = [{ role: 'system', content: 'You are helpful.' }]
19
+ const conv = makeConversation({ history })
20
+ expect(conv.messages).toHaveLength(1)
21
+ expect(conv.messages[0]).toEqual(history[0])
22
+ })
23
+
24
+ it('uses provided model', () => {
25
+ const conv = makeConversation({ model: 'gpt-4.1' })
26
+ expect(conv.model).toBe('gpt-4.1')
27
+ })
28
+
29
+ it('isStreaming is false initially', () => {
30
+ const conv = makeConversation()
31
+ expect(conv.isStreaming).toBe(false)
32
+ })
33
+ })
34
+
35
+ describe('pushMessage', () => {
36
+ it('appends to messages', () => {
37
+ const conv = makeConversation()
38
+ conv.pushMessage({ role: 'user', content: 'hello' })
39
+ expect(conv.messages).toHaveLength(1)
40
+ expect(conv.messages[0]!.role).toBe('user')
41
+ })
42
+
43
+ it('does not mutate prior messages array', () => {
44
+ const conv = makeConversation()
45
+ const before = conv.messages
46
+ conv.pushMessage({ role: 'user', content: 'hi' })
47
+ expect(conv.messages).not.toBe(before)
48
+ })
49
+ })
50
+
51
+ describe('tools', () => {
52
+ it('starts with no tools', () => {
53
+ const conv = makeConversation()
54
+ expect(conv.availableTools).toHaveLength(0)
55
+ })
56
+
57
+ it('addTool registers a tool', () => {
58
+ const conv = makeConversation()
59
+ conv.addTool('greet', {
60
+ description: 'Says hello',
61
+ parameters: { type: 'object', properties: {} },
62
+ handler: async () => 'hello',
63
+ })
64
+ expect(conv.availableTools).toContain('greet')
65
+ })
66
+
67
+ it('removeTool deregisters a tool', () => {
68
+ const conv = makeConversation()
69
+ conv.addTool('greet', {
70
+ description: 'Says hello',
71
+ parameters: { type: 'object', properties: {} },
72
+ handler: async () => 'hello',
73
+ })
74
+ conv.removeTool('greet')
75
+ expect(conv.availableTools).not.toContain('greet')
76
+ })
77
+
78
+ it('updateTools merges without replacing unrelated tools', () => {
79
+ const conv = makeConversation()
80
+ conv.addTool('a', { description: 'A', parameters: { type: 'object', properties: {} }, handler: async () => 'a' })
81
+ conv.updateTools({ b: { description: 'B', parameters: { type: 'object', properties: {} }, handler: async () => 'b' } })
82
+ expect(conv.availableTools).toContain('a')
83
+ expect(conv.availableTools).toContain('b')
84
+ })
85
+
86
+ it('construction-time tools are available immediately', () => {
87
+ const conv = makeConversation({
88
+ tools: {
89
+ ping: { description: 'Ping', parameters: { type: 'object', properties: {} }, handler: async () => 'pong' }
90
+ }
91
+ })
92
+ expect(conv.availableTools).toContain('ping')
93
+ })
94
+ })
95
+
96
+ describe('estimateTokens', () => {
97
+ it('returns a near-zero baseline for empty messages', () => {
98
+ const conv = makeConversation()
99
+ expect(conv.estimateTokens()).toBeLessThan(10)
100
+ })
101
+
102
+ it('returns a positive number when messages exist', () => {
103
+ const conv = makeConversation({
104
+ history: [{ role: 'user', content: 'What is the capital of France?' }]
105
+ })
106
+ expect(conv.estimateTokens()).toBeGreaterThan(0)
107
+ })
108
+
109
+ it('increases as more messages are added', () => {
110
+ const conv = makeConversation()
111
+ conv.pushMessage({ role: 'user', content: 'Hello' })
112
+ const first = conv.estimateTokens()
113
+ conv.pushMessage({ role: 'assistant', content: 'Hi there, how can I help you today?' })
114
+ const second = conv.estimateTokens()
115
+ expect(second).toBeGreaterThan(first)
116
+ })
117
+ })
118
+
119
+ describe('stub()', () => {
120
+ it('exact string match returns the stub response', async () => {
121
+ const conv = makeConversation()
122
+ conv.stub('ping', 'pong')
123
+ const result = await conv.ask('ping')
124
+ expect(result).toBe('pong')
125
+ })
126
+
127
+ it('substring match triggers the stub', async () => {
128
+ const conv = makeConversation()
129
+ conv.stub('weather', 'Sunny and 72°F.')
130
+ const result = await conv.ask('what is the weather today?')
131
+ expect(result).toBe('Sunny and 72°F.')
132
+ })
133
+
134
+ it('regex match triggers the stub', async () => {
135
+ const conv = makeConversation()
136
+ conv.stub(/hello/i, 'Hey there!')
137
+ const result = await conv.ask('HELLO')
138
+ expect(result).toBe('Hey there!')
139
+ })
140
+
141
+ it('function response is called on each match', async () => {
142
+ const conv = makeConversation()
143
+ let callCount = 0
144
+ conv.stub('count', () => `call ${++callCount}`)
145
+ expect(await conv.ask('count')).toBe('call 1')
146
+ expect(await conv.ask('count')).toBe('call 2')
147
+ })
148
+
149
+ it('first matching stub wins', async () => {
150
+ const conv = makeConversation()
151
+ conv.stub('hello', 'first')
152
+ conv.stub('hello', 'second')
153
+ expect(await conv.ask('hello')).toBe('first')
154
+ })
155
+
156
+ it('appends user and assistant messages to history', async () => {
157
+ const conv = makeConversation()
158
+ conv.stub('hi', 'hello back')
159
+ await conv.ask('hi')
160
+ expect(conv.messages).toHaveLength(2)
161
+ expect(conv.messages[0]).toMatchObject({ role: 'user', content: 'hi' })
162
+ expect(conv.messages[1]).toMatchObject({ role: 'assistant', content: 'hello back' })
163
+ })
164
+
165
+ it('isStreaming is false after the call resolves', async () => {
166
+ const conv = makeConversation()
167
+ conv.stub('test', 'response')
168
+ await conv.ask('test')
169
+ expect(conv.isStreaming).toBe(false)
170
+ })
171
+
172
+ it('emits chunk events for each word', async () => {
173
+ const conv = makeConversation()
174
+ conv.stub('go', 'one two three')
175
+ const chunks: string[] = []
176
+ conv.on('chunk', (delta: string) => chunks.push(delta))
177
+ await conv.ask('go')
178
+ expect(chunks.join('')).toBe('one two three')
179
+ })
180
+
181
+ it('emits preview events with accumulating text', async () => {
182
+ const conv = makeConversation()
183
+ conv.stub('go', 'alpha beta')
184
+ const previews: string[] = []
185
+ conv.on('preview', (text: string) => previews.push(text))
186
+ await conv.ask('go')
187
+ expect(previews.at(-1)).toBe('alpha beta')
188
+ // Each preview should be longer than or equal to the previous
189
+ for (let i = 1; i < previews.length; i++) {
190
+ expect(previews[i]!.length).toBeGreaterThanOrEqual(previews[i - 1]!.length)
191
+ }
192
+ })
193
+
194
+ it('emits turnStart and turnEnd events', async () => {
195
+ const conv = makeConversation()
196
+ conv.stub('x', 'y')
197
+ const events: string[] = []
198
+ conv.on('turnStart', () => events.push('turnStart'))
199
+ conv.on('turnEnd', () => events.push('turnEnd'))
200
+ await conv.ask('x')
201
+ expect(events).toEqual(['turnStart', 'turnEnd'])
202
+ })
203
+
204
+ it('emits response event with the full text', async () => {
205
+ const conv = makeConversation()
206
+ conv.stub('question', 'the answer')
207
+ let emitted = ''
208
+ conv.on('response', (text: string) => { emitted = text })
209
+ await conv.ask('question')
210
+ expect(emitted).toBe('the answer')
211
+ })
212
+
213
+ it('stub is chainable', () => {
214
+ const conv = makeConversation()
215
+ const result = conv.stub('a', 'A').stub('b', 'B')
216
+ expect(result).toBe(conv)
217
+ expect(conv.availableTools).toHaveLength(0) // stubs don't affect tools
218
+ })
219
+ })
220
+ })
@@ -0,0 +1,204 @@
1
+ import {
2
+ requireEnv,
3
+ describeWithRequirements,
4
+ createAGIContainer,
5
+ API_TIMEOUT,
6
+ } from './helpers'
7
+ import type { AGIContainer } from '../src/agi/container.server'
8
+ import type { Memory } from '../src/agi/features/agent-memory'
9
+
10
+ const openaiKey = requireEnv('OPENAI_API_KEY')
11
+
12
+ describeWithRequirements('Memory Integration', [openaiKey], () => {
13
+ let container: AGIContainer
14
+ let mem: Memory
15
+
16
+ beforeAll(async () => {
17
+ container = createAGIContainer()
18
+ mem = container.feature('memory', { namespace: 'test-integration' }) as unknown as Memory
19
+ await mem.initDb()
20
+ await mem.wipeAll()
21
+ })
22
+
23
+ afterAll(async () => {
24
+ await mem.wipeAll()
25
+ })
26
+
27
+ describe('Feature registration', () => {
28
+ it('registers in the container', () => {
29
+ expect(container.features.available).toContain('memory')
30
+ })
31
+
32
+ it('has correct shortcut', () => {
33
+ const { Memory: MemClass } = require('../src/agi/features/agent-memory')
34
+ expect(MemClass.shortcut).toBe('features.memory')
35
+ })
36
+
37
+ it('initializes database', () => {
38
+ expect(mem.state.get('dbReady')).toBe(true)
39
+ })
40
+ })
41
+
42
+ describe('CRUD operations', () => {
43
+ it('creates and retrieves a memory', async () => {
44
+ const m = await mem.create('facts', 'Jonathan is a software engineer based in Austin')
45
+ expect(m.id).toBeGreaterThan(0)
46
+ expect(m.category).toBe('facts')
47
+ expect(m.document).toBe('Jonathan is a software engineer based in Austin')
48
+
49
+ const fetched = await mem.get('facts', m.id)
50
+ expect(fetched).not.toBeNull()
51
+ expect(fetched!.document).toBe(m.document)
52
+ }, API_TIMEOUT)
53
+
54
+ it('updates a memory', async () => {
55
+ const m = await mem.create('facts', 'Prefers dark mode')
56
+ const updated = await mem.update('facts', m.id, {
57
+ text: 'Prefers dark mode, especially Dracula theme',
58
+ metadata: { updated: 'true' },
59
+ })
60
+ expect(updated!.document).toBe('Prefers dark mode, especially Dracula theme')
61
+ expect(updated!.metadata.updated).toBe('true')
62
+ }, API_TIMEOUT)
63
+
64
+ it('deletes a memory', async () => {
65
+ const m = await mem.create('scratch', 'temporary memory')
66
+ expect(await mem.delete('scratch', m.id)).toBe(true)
67
+ expect(await mem.get('scratch', m.id)).toBeNull()
68
+ }, API_TIMEOUT)
69
+
70
+ it('lists categories', async () => {
71
+ const cats = await mem.categories()
72
+ expect(cats).toContain('facts')
73
+ })
74
+
75
+ it('counts memories', async () => {
76
+ const total = await mem.count()
77
+ expect(total).toBeGreaterThan(0)
78
+ const factCount = await mem.count('facts')
79
+ expect(factCount).toBeGreaterThan(0)
80
+ })
81
+
82
+ it('gets all memories with filtering', async () => {
83
+ await mem.create('prefs', 'Likes iterative delivery', { source: 'onboarding' })
84
+ await mem.create('prefs', 'Prefers concise responses')
85
+
86
+ const onboarding = await mem.getAll('prefs', { filterMetadata: { source: 'onboarding' } })
87
+ expect(onboarding.length).toBeGreaterThan(0)
88
+ expect(onboarding.every(m => m.metadata.source === 'onboarding')).toBe(true)
89
+ }, API_TIMEOUT)
90
+ })
91
+
92
+ describe('Semantic search', () => {
93
+ it('finds relevant memories by query', async () => {
94
+ const results = await mem.search('facts', 'Where does the user live?', 3)
95
+ expect(results.length).toBeGreaterThan(0)
96
+ expect(results[0].distance).toBeLessThan(1)
97
+ }, API_TIMEOUT)
98
+ })
99
+
100
+ describe('Deduplication', () => {
101
+ it('blocks near-duplicate memories', async () => {
102
+ const before = await mem.count('facts')
103
+ const dup = await mem.createUnique('facts', 'Jonathan is a software engineer living in Austin, TX')
104
+ const after = await mem.count('facts')
105
+ expect(dup).toBeNull()
106
+ expect(after).toBe(before)
107
+ }, API_TIMEOUT)
108
+ })
109
+
110
+ describe('Epochs and events', () => {
111
+ it('tracks epoch state', () => {
112
+ expect(mem.getEpoch()).toBe(1)
113
+ })
114
+
115
+ it('creates events and increments epoch', async () => {
116
+ await mem.createEvent('User started a new project')
117
+ await mem.incrementEpoch()
118
+ expect(mem.getEpoch()).toBe(2)
119
+
120
+ await mem.createEvent('User requested a test script')
121
+
122
+ const e1 = await mem.getEvents({ epoch: 1 })
123
+ const e2 = await mem.getEvents({ epoch: 2 })
124
+ expect(e1.length).toBeGreaterThan(0)
125
+ expect(e2.length).toBeGreaterThan(0)
126
+ }, API_TIMEOUT)
127
+ })
128
+
129
+ describe('Export and import', () => {
130
+ it('roundtrips through export/import', async () => {
131
+ const exported = await mem.exportToJson()
132
+ expect(exported.memories.length).toBeGreaterThan(0)
133
+
134
+ await mem.wipeAll()
135
+ expect(await mem.count()).toBe(0)
136
+
137
+ const imported = await mem.importFromJson(exported)
138
+ expect(imported).toBe(exported.memories.length)
139
+ expect(await mem.count()).toBe(exported.memories.length)
140
+ }, API_TIMEOUT * 3)
141
+ })
142
+
143
+ describe('Tool interface (toTools)', () => {
144
+ it('exposes tools via standard toTools() pattern', () => {
145
+ const { schemas, handlers } = mem.toTools()
146
+ expect(Object.keys(schemas)).toContain('remember')
147
+ expect(Object.keys(schemas)).toContain('recall')
148
+ expect(Object.keys(schemas)).toContain('forgetCategory')
149
+ expect(Object.keys(schemas)).toContain('listCategories')
150
+ expect(typeof handlers.remember).toBe('function')
151
+ expect(typeof handlers.recall).toBe('function')
152
+ expect(typeof handlers.forgetCategory).toBe('function')
153
+ expect(typeof handlers.listCategories).toBe('function')
154
+ })
155
+
156
+ it('toTools only/except filtering works', () => {
157
+ const { schemas: onlySchemas } = mem.toTools({ only: ['remember', 'recall'] })
158
+ expect(Object.keys(onlySchemas)).toEqual(['remember', 'recall'])
159
+
160
+ const { schemas: exceptSchemas } = mem.toTools({ except: ['forgetCategory'] })
161
+ expect(Object.keys(exceptSchemas)).not.toContain('forgetCategory')
162
+ expect(Object.keys(exceptSchemas)).toContain('remember')
163
+ })
164
+
165
+ it('remember tool stores and deduplicates', async () => {
166
+ const { handlers } = mem.toTools()
167
+ const result = await handlers.remember({ category: 'facts', text: 'Has a golden retriever named Max' })
168
+ expect(result.stored).toBe(true)
169
+
170
+ const dup = await handlers.remember({ category: 'facts', text: 'Has a golden retriever named Max' })
171
+ expect(dup.stored).toBe(false)
172
+ }, API_TIMEOUT)
173
+
174
+ it('recall tool searches memories', async () => {
175
+ const { handlers } = mem.toTools()
176
+ const results = await handlers.recall({ category: 'facts', query: 'pets and animals', n_results: 2 })
177
+ expect(results.length).toBeGreaterThan(0)
178
+ expect(results[0]).toHaveProperty('document')
179
+ expect(results[0]).toHaveProperty('distance')
180
+ }, API_TIMEOUT)
181
+
182
+ it('listCategories tool returns counts', async () => {
183
+ const { handlers } = mem.toTools()
184
+ const result = await handlers.listCategories()
185
+ expect(result.categories).toBeDefined()
186
+ expect(typeof result.categories.facts).toBe('number')
187
+ })
188
+ })
189
+
190
+ describe('Wipe operations', () => {
191
+ it('wipeCategory removes only that category', async () => {
192
+ const before = await mem.count()
193
+ const deleted = await mem.wipeCategory('scratch')
194
+ const after = await mem.count()
195
+ expect(after).toBeLessThanOrEqual(before)
196
+ })
197
+
198
+ it('wipeAll removes everything and resets epoch', async () => {
199
+ await mem.wipeAll()
200
+ expect(await mem.count()).toBe(0)
201
+ expect(mem.getEpoch()).toBe(1)
202
+ })
203
+ })
204
+ })
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": false,
5
+ "emitDeclarationOnly": true,
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "outDir": "./dist",
9
+ "rootDir": "./src"
10
+ },
11
+ "include": ["src/**/*.ts", "src/**/*.tsx"]
12
+ }
package/tsconfig.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  // Environment setup & latest features
4
- "lib": ["ESNext"],
4
+ "lib": ["ESNext", "dom", "dom.iterable"],
5
5
  "target": "ESNext",
6
6
  "module": "Preserve",
7
7
  "moduleDetection": "force",