enya-agent 0.1.0

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 (389) hide show
  1. package/.env.example +20 -0
  2. package/.github/workflows/ci.yml +70 -0
  3. package/.github/workflows/publish.yml +250 -0
  4. package/.gitmodules +3 -0
  5. package/Cargo.lock +3584 -0
  6. package/Cargo.toml +97 -0
  7. package/crates/enact/Cargo.toml +27 -0
  8. package/crates/enact/src/lib.rs +60 -0
  9. package/crates/enact-a2a/Cargo.toml +25 -0
  10. package/crates/enact-a2a/src/lib.rs +411 -0
  11. package/crates/enact-channels/Cargo.toml +64 -0
  12. package/crates/enact-channels/examples/README.md +80 -0
  13. package/crates/enact-channels/examples/channel_bot.rs +169 -0
  14. package/crates/enact-channels/examples/telegram-echo.rs +34 -0
  15. package/crates/enact-channels/examples/whatsapp-echo.rs +142 -0
  16. package/crates/enact-channels/src/config.rs +213 -0
  17. package/crates/enact-channels/src/lib.rs +25 -0
  18. package/crates/enact-channels/src/runtime.rs +237 -0
  19. package/crates/enact-channels/src/security/mod.rs +5 -0
  20. package/crates/enact-channels/src/security/pairing.rs +205 -0
  21. package/crates/enact-channels/src/teams.rs +601 -0
  22. package/crates/enact-channels/src/telegram.rs +2833 -0
  23. package/crates/enact-channels/src/traits.rs +200 -0
  24. package/crates/enact-channels/src/webhook.rs +262 -0
  25. package/crates/enact-channels/src/whatsapp.rs +310 -0
  26. package/crates/enact-cli/Cargo.toml +40 -0
  27. package/crates/enact-cli/src/commands/doctor.rs +62 -0
  28. package/crates/enact-cli/src/commands/mod.rs +3 -0
  29. package/crates/enact-cli/src/commands/run.rs +69 -0
  30. package/crates/enact-cli/src/commands/serve.rs +81 -0
  31. package/crates/enact-cli/src/config.rs +2 -0
  32. package/crates/enact-cli/src/main.rs +79 -0
  33. package/crates/enact-config/Cargo.toml +36 -0
  34. package/crates/enact-config/ENV_VAR_MAPPING.md +135 -0
  35. package/crates/enact-config/QUICK_REFERENCE.md +92 -0
  36. package/crates/enact-config/README.md +107 -0
  37. package/crates/enact-config/TESTING.md +161 -0
  38. package/crates/enact-config/examples/test-env-vars.rs +100 -0
  39. package/crates/enact-config/src/config.rs +399 -0
  40. package/crates/enact-config/src/encrypted_store.rs +211 -0
  41. package/crates/enact-config/src/lib.rs +298 -0
  42. package/crates/enact-config/src/secrets.rs +149 -0
  43. package/crates/enact-config/src/sync.rs +260 -0
  44. package/crates/enact-config/test-env-vars.sh +34 -0
  45. package/crates/enact-config/tests/README.md +99 -0
  46. package/crates/enact-config/tests/config_integration_test.rs +202 -0
  47. package/crates/enact-config/tests/security_test.rs +140 -0
  48. package/crates/enact-context/Cargo.toml +41 -0
  49. package/crates/enact-context/src/budget.rs +314 -0
  50. package/crates/enact-context/src/calibrator.rs +535 -0
  51. package/crates/enact-context/src/compactor.rs +392 -0
  52. package/crates/enact-context/src/condenser.rs +826 -0
  53. package/crates/enact-context/src/lib.rs +94 -0
  54. package/crates/enact-context/src/segment.rs +238 -0
  55. package/crates/enact-context/src/step_context.rs +645 -0
  56. package/crates/enact-context/src/token_counter.rs +148 -0
  57. package/crates/enact-context/src/window.rs +372 -0
  58. package/crates/enact-core/Cargo.toml +42 -0
  59. package/crates/enact-core/README.md +98 -0
  60. package/crates/enact-core/src/background/executor.rs +524 -0
  61. package/crates/enact-core/src/background/mod.rs +48 -0
  62. package/crates/enact-core/src/background/target_binding.rs +390 -0
  63. package/crates/enact-core/src/background/trigger.rs +511 -0
  64. package/crates/enact-core/src/callable/callable.rs +152 -0
  65. package/crates/enact-core/src/callable/composite.rs +817 -0
  66. package/crates/enact-core/src/callable/graph.rs +104 -0
  67. package/crates/enact-core/src/callable/llm.rs +211 -0
  68. package/crates/enact-core/src/callable/mod.rs +64 -0
  69. package/crates/enact-core/src/callable/registry.rs +206 -0
  70. package/crates/enact-core/src/context/execution_context.rs +757 -0
  71. package/crates/enact-core/src/context/invocation.rs +99 -0
  72. package/crates/enact-core/src/context/mod.rs +50 -0
  73. package/crates/enact-core/src/context/tenant.rs +175 -0
  74. package/crates/enact-core/src/context/trace.rs +127 -0
  75. package/crates/enact-core/src/flow/conditional.rs +293 -0
  76. package/crates/enact-core/src/flow/mod.rs +43 -0
  77. package/crates/enact-core/src/flow/parallel.rs +437 -0
  78. package/crates/enact-core/src/flow/repeat.rs +534 -0
  79. package/crates/enact-core/src/flow/sequential.rs +248 -0
  80. package/crates/enact-core/src/graph/checkpoint.rs +79 -0
  81. package/crates/enact-core/src/graph/checkpoint_store.rs +76 -0
  82. package/crates/enact-core/src/graph/compiled.rs +189 -0
  83. package/crates/enact-core/src/graph/edge.rs +59 -0
  84. package/crates/enact-core/src/graph/graph_schema.rs +218 -0
  85. package/crates/enact-core/src/graph/loader.rs +155 -0
  86. package/crates/enact-core/src/graph/mod.rs +18 -0
  87. package/crates/enact-core/src/graph/node/function.rs +49 -0
  88. package/crates/enact-core/src/graph/node/mod.rs +48 -0
  89. package/crates/enact-core/src/graph/schema.rs +62 -0
  90. package/crates/enact-core/src/inbox/message.rs +405 -0
  91. package/crates/enact-core/src/inbox/mod.rs +31 -0
  92. package/crates/enact-core/src/inbox/store.rs +355 -0
  93. package/crates/enact-core/src/kernel/artifact/filesystem.rs +546 -0
  94. package/crates/enact-core/src/kernel/artifact/metadata.rs +283 -0
  95. package/crates/enact-core/src/kernel/artifact/mod.rs +27 -0
  96. package/crates/enact-core/src/kernel/artifact/store.rs +427 -0
  97. package/crates/enact-core/src/kernel/enforcement.rs +1315 -0
  98. package/crates/enact-core/src/kernel/error.rs +1200 -0
  99. package/crates/enact-core/src/kernel/event.rs +1394 -0
  100. package/crates/enact-core/src/kernel/execution_model.rs +831 -0
  101. package/crates/enact-core/src/kernel/execution_state.rs +189 -0
  102. package/crates/enact-core/src/kernel/execution_strategy.rs +117 -0
  103. package/crates/enact-core/src/kernel/ids.rs +2086 -0
  104. package/crates/enact-core/src/kernel/interrupt.rs +125 -0
  105. package/crates/enact-core/src/kernel/kernel.rs +1283 -0
  106. package/crates/enact-core/src/kernel/mod.rs +205 -0
  107. package/crates/enact-core/src/kernel/persistence/event_store.rs +270 -0
  108. package/crates/enact-core/src/kernel/persistence/message_store.rs +908 -0
  109. package/crates/enact-core/src/kernel/persistence/mod.rs +102 -0
  110. package/crates/enact-core/src/kernel/persistence/state_store.rs +228 -0
  111. package/crates/enact-core/src/kernel/persistence/vector_store.rs +299 -0
  112. package/crates/enact-core/src/kernel/reducer.rs +808 -0
  113. package/crates/enact-core/src/kernel/replay.rs +153 -0
  114. package/crates/enact-core/src/lib.rs +413 -0
  115. package/crates/enact-core/src/memory/episodic.rs +0 -0
  116. package/crates/enact-core/src/memory/mod.rs +6 -0
  117. package/crates/enact-core/src/memory/semantic.rs +0 -0
  118. package/crates/enact-core/src/memory/trait.rs +0 -0
  119. package/crates/enact-core/src/memory/vector_db.rs +0 -0
  120. package/crates/enact-core/src/memory/working.rs +0 -0
  121. package/crates/enact-core/src/policy/execution_policy.rs +292 -0
  122. package/crates/enact-core/src/policy/filters.rs +458 -0
  123. package/crates/enact-core/src/policy/input_processor.rs +407 -0
  124. package/crates/enact-core/src/policy/long_running.rs +134 -0
  125. package/crates/enact-core/src/policy/mod.rs +193 -0
  126. package/crates/enact-core/src/policy/pii_input.rs +274 -0
  127. package/crates/enact-core/src/policy/tenant_policy.rs +453 -0
  128. package/crates/enact-core/src/policy/tool_policy.rs +407 -0
  129. package/crates/enact-core/src/providers/mod.rs +63 -0
  130. package/crates/enact-core/src/providers/trait.rs +292 -0
  131. package/crates/enact-core/src/runner/callbacks.rs +6 -0
  132. package/crates/enact-core/src/runner/execution_runner.rs +476 -0
  133. package/crates/enact-core/src/runner/loop.rs +117 -0
  134. package/crates/enact-core/src/runner/mod.rs +58 -0
  135. package/crates/enact-core/src/runner/protected_runner.rs +280 -0
  136. package/crates/enact-core/src/signal/inmemory.rs +231 -0
  137. package/crates/enact-core/src/signal/mod.rs +108 -0
  138. package/crates/enact-core/src/streaming/event_logger.rs +195 -0
  139. package/crates/enact-core/src/streaming/event_stream.rs +1423 -0
  140. package/crates/enact-core/src/streaming/mod.rs +108 -0
  141. package/crates/enact-core/src/streaming/pause_cancel.rs +0 -0
  142. package/crates/enact-core/src/streaming/protected_emitter.rs +173 -0
  143. package/crates/enact-core/src/streaming/protection/context.rs +136 -0
  144. package/crates/enact-core/src/streaming/protection/encryption.rs +289 -0
  145. package/crates/enact-core/src/streaming/protection/mod.rs +43 -0
  146. package/crates/enact-core/src/streaming/protection/pii_protection.rs +243 -0
  147. package/crates/enact-core/src/streaming/protection/processor.rs +166 -0
  148. package/crates/enact-core/src/streaming/sse.rs +0 -0
  149. package/crates/enact-core/src/telemetry/exporter.rs +0 -0
  150. package/crates/enact-core/src/telemetry/init.rs +0 -0
  151. package/crates/enact-core/src/telemetry/mod.rs +49 -0
  152. package/crates/enact-core/src/telemetry/spans.rs +245 -0
  153. package/crates/enact-core/src/tool/agent_tool.rs +177 -0
  154. package/crates/enact-core/src/tool/browser/mod.rs +0 -0
  155. package/crates/enact-core/src/tool/browser/webdriver.rs +0 -0
  156. package/crates/enact-core/src/tool/cost.rs +247 -0
  157. package/crates/enact-core/src/tool/discovery.rs +0 -0
  158. package/crates/enact-core/src/tool/dispatcher.rs +347 -0
  159. package/crates/enact-core/src/tool/filesystem.rs +231 -0
  160. package/crates/enact-core/src/tool/function.rs +99 -0
  161. package/crates/enact-core/src/tool/git.rs +162 -0
  162. package/crates/enact-core/src/tool/http.rs +214 -0
  163. package/crates/enact-core/src/tool/mcp/client.rs +0 -0
  164. package/crates/enact-core/src/tool/mcp/mod.rs +0 -0
  165. package/crates/enact-core/src/tool/mod.rs +51 -0
  166. package/crates/enact-core/src/tool/reasoning/debugging.rs +0 -0
  167. package/crates/enact-core/src/tool/reasoning/mcts.rs +0 -0
  168. package/crates/enact-core/src/tool/reasoning/mod.rs +0 -0
  169. package/crates/enact-core/src/tool/reasoning/sequential.rs +0 -0
  170. package/crates/enact-core/src/tool/sandbox/dagger.rs +0 -0
  171. package/crates/enact-core/src/tool/sandbox/mod.rs +0 -0
  172. package/crates/enact-core/src/tool/shell.rs +147 -0
  173. package/crates/enact-core/src/tool/trait.rs +33 -0
  174. package/crates/enact-core/src/tool/web_search.rs +277 -0
  175. package/crates/enact-core/src/util/config.rs +0 -0
  176. package/crates/enact-core/src/util/errors.rs +0 -0
  177. package/crates/enact-core/src/util/mod.rs +6 -0
  178. package/crates/enact-core/tests/airgapped_e2e_test.rs +291 -0
  179. package/crates/enact-core/tests/e2e_agentic_loop.rs +119 -0
  180. package/crates/enact-core/tests/e2e_test.rs +259 -0
  181. package/crates/enact-core/tests/graph_test.rs +130 -0
  182. package/crates/enact-core/tests/stream_event_id_validation.rs +435 -0
  183. package/crates/enact-cron/Cargo.toml +28 -0
  184. package/crates/enact-cron/src/lib.rs +44 -0
  185. package/crates/enact-cron/src/schedule.rs +156 -0
  186. package/crates/enact-cron/src/store.rs +589 -0
  187. package/crates/enact-cron/src/types.rs +148 -0
  188. package/crates/enact-gateway/Cargo.toml +31 -0
  189. package/crates/enact-gateway/README.md +30 -0
  190. package/crates/enact-gateway/examples/whatsapp-gateway-runner-mock.rs +59 -0
  191. package/crates/enact-gateway/examples/whatsapp-gateway.rs +42 -0
  192. package/crates/enact-gateway/src/lib.rs +582 -0
  193. package/crates/enact-mcp/Cargo.toml +24 -0
  194. package/crates/enact-mcp/src/lib.rs +178 -0
  195. package/crates/enact-memory/Cargo.toml +25 -0
  196. package/crates/enact-memory/src/backend.rs +20 -0
  197. package/crates/enact-memory/src/chunker.rs +230 -0
  198. package/crates/enact-memory/src/embeddings.rs +221 -0
  199. package/crates/enact-memory/src/lib.rs +67 -0
  200. package/crates/enact-memory/src/markdown.rs +127 -0
  201. package/crates/enact-memory/src/none.rs +61 -0
  202. package/crates/enact-memory/src/sqlite.rs +276 -0
  203. package/crates/enact-memory/src/traits.rs +65 -0
  204. package/crates/enact-memory/src/vector.rs +198 -0
  205. package/crates/enact-oauth/Cargo.toml +27 -0
  206. package/crates/enact-oauth/src/lib.rs +584 -0
  207. package/crates/enact-observability/Cargo.toml +22 -0
  208. package/crates/enact-observability/src/lib.rs +197 -0
  209. package/crates/enact-providers/Cargo.toml +33 -0
  210. package/crates/enact-providers/examples/hello-agent.rs +33 -0
  211. package/crates/enact-providers/src/anthropic.rs +182 -0
  212. package/crates/enact-providers/src/azure.rs +96 -0
  213. package/crates/enact-providers/src/bridge.rs +221 -0
  214. package/crates/enact-providers/src/gemini.rs +227 -0
  215. package/crates/enact-providers/src/http.rs +78 -0
  216. package/crates/enact-providers/src/lib.rs +53 -0
  217. package/crates/enact-providers/src/openai_compatible.rs +167 -0
  218. package/crates/enact-providers/src/openrouter.rs +33 -0
  219. package/crates/enact-runner/Cargo.toml +24 -0
  220. package/crates/enact-runner/README.md +76 -0
  221. package/crates/enact-runner/src/compaction.rs +225 -0
  222. package/crates/enact-runner/src/config.rs +118 -0
  223. package/crates/enact-runner/src/lib.rs +63 -0
  224. package/crates/enact-runner/src/loop_driver.rs +414 -0
  225. package/crates/enact-runner/src/parser.rs +421 -0
  226. package/crates/enact-runner/src/retry.rs +262 -0
  227. package/crates/enact-runner/tests/integration.rs +278 -0
  228. package/crates/enact-security/Cargo.toml +22 -0
  229. package/crates/enact-security/src/audit.rs +375 -0
  230. package/crates/enact-security/src/lib.rs +37 -0
  231. package/crates/enact-security/src/policy.rs +406 -0
  232. package/crates/enact-skills/Cargo.toml +25 -0
  233. package/crates/enact-skills/src/lib.rs +506 -0
  234. package/crates/enact-tools/Cargo.toml +22 -0
  235. package/crates/enact-tools/src/file_read.rs +166 -0
  236. package/crates/enact-tools/src/file_write.rs +216 -0
  237. package/crates/enact-tools/src/git_operations.rs +513 -0
  238. package/crates/enact-tools/src/http_request.rs +417 -0
  239. package/crates/enact-tools/src/lib.rs +104 -0
  240. package/crates/enact-tools/src/security.rs +227 -0
  241. package/crates/enact-tools/src/shell.rs +191 -0
  242. package/crates/enact-tools/src/traits.rs +159 -0
  243. package/docs/Makefile +74 -0
  244. package/docs/config.toml +62 -0
  245. package/docs/content/_index.md +174 -0
  246. package/docs/content/a2a/_index.md +431 -0
  247. package/docs/content/api/_index.md +323 -0
  248. package/docs/content/channels/_index.md +160 -0
  249. package/docs/content/channels/teams.md +205 -0
  250. package/docs/content/channels/telegram.md +182 -0
  251. package/docs/content/channels/webhook.md +423 -0
  252. package/docs/content/channels/whatsapp.md +240 -0
  253. package/docs/content/cli/_index.md +261 -0
  254. package/docs/content/concepts/_index.md +273 -0
  255. package/docs/content/configuration/_index.md +241 -0
  256. package/docs/content/cron/_index.md +248 -0
  257. package/docs/content/developers/_index.md +278 -0
  258. package/docs/content/getting-started/_index.md +180 -0
  259. package/docs/content/installation/_index.md +186 -0
  260. package/docs/content/installation/uninstall.md +101 -0
  261. package/docs/content/installation/updating.md +120 -0
  262. package/docs/content/mcp/_index.md +215 -0
  263. package/docs/content/memory/_index.md +163 -0
  264. package/docs/content/oauth/_index.md +515 -0
  265. package/docs/content/providers/_index.md +206 -0
  266. package/docs/content/roadmap/_index.md +199 -0
  267. package/docs/content/security/_index.md +219 -0
  268. package/docs/content/skills/_index.md +228 -0
  269. package/docs/content/tools/_index.md +485 -0
  270. package/docs/content/troubleshooting/_index.md +259 -0
  271. package/docs/content/yaml-schema/_index.md +294 -0
  272. package/docs/static/giallo-dark.css +91 -0
  273. package/docs/static/giallo-light.css +91 -0
  274. package/docs/themes/tanuki/.github/workflows/deploy.yml +44 -0
  275. package/docs/themes/tanuki/LICENSE +21 -0
  276. package/docs/themes/tanuki/README.md +166 -0
  277. package/docs/themes/tanuki/examples/blog/config.toml +58 -0
  278. package/docs/themes/tanuki/examples/blog/content/_index.md +4 -0
  279. package/docs/themes/tanuki/examples/blog/content/about.md +33 -0
  280. package/docs/themes/tanuki/examples/blog/content/blog/_index.md +7 -0
  281. package/docs/themes/tanuki/examples/blog/content/blog/api-design-best-practices.md +245 -0
  282. package/docs/themes/tanuki/examples/blog/content/blog/building-accessible-websites.md +147 -0
  283. package/docs/themes/tanuki/examples/blog/content/blog/css-grid-vs-flexbox.md +165 -0
  284. package/docs/themes/tanuki/examples/blog/content/blog/customizing-catppuccin-colors.md +137 -0
  285. package/docs/themes/tanuki/examples/blog/content/blog/dark-mode-best-practices.md +82 -0
  286. package/docs/themes/tanuki/examples/blog/content/blog/docker-essentials.md +301 -0
  287. package/docs/themes/tanuki/examples/blog/content/blog/getting-started-with-zola.md +129 -0
  288. package/docs/themes/tanuki/examples/blog/content/blog/git-workflow-for-content.md +112 -0
  289. package/docs/themes/tanuki/examples/blog/content/blog/introduction-to-webassembly.md +183 -0
  290. package/docs/themes/tanuki/examples/blog/content/blog/modern-javascript-features.md +234 -0
  291. package/docs/themes/tanuki/examples/blog/content/blog/testing-strategies.md +311 -0
  292. package/docs/themes/tanuki/examples/blog/content/blog/typography-for-developers.md +104 -0
  293. package/docs/themes/tanuki/examples/blog/content/blog/welcome-to-tanuki.md +67 -0
  294. package/docs/themes/tanuki/examples/blog/content/blog/why-static-sites.md +85 -0
  295. package/docs/themes/tanuki/examples/blog/content/projects.md +64 -0
  296. package/docs/themes/tanuki/examples/book/config.toml +17 -0
  297. package/docs/themes/tanuki/examples/book/content/_index.md +12 -0
  298. package/docs/themes/tanuki/examples/book/content/chapter-1.md +90 -0
  299. package/docs/themes/tanuki/examples/book/content/chapter-2.md +143 -0
  300. package/docs/themes/tanuki/examples/book/content/chapter-3.md +217 -0
  301. package/docs/themes/tanuki/examples/book/content/chapter-4.md +224 -0
  302. package/docs/themes/tanuki/examples/book/content/chapter-5.md +297 -0
  303. package/docs/themes/tanuki/examples/book/content/print.md +6 -0
  304. package/docs/themes/tanuki/examples/docs/config.toml +28 -0
  305. package/docs/themes/tanuki/examples/docs/content/_index.md +20 -0
  306. package/docs/themes/tanuki/examples/docs/content/components.md +156 -0
  307. package/docs/themes/tanuki/examples/docs/content/configuration.md +94 -0
  308. package/docs/themes/tanuki/examples/docs/content/customization.md +202 -0
  309. package/docs/themes/tanuki/examples/docs/content/deployment.md +204 -0
  310. package/docs/themes/tanuki/examples/docs/content/installation.md +59 -0
  311. package/docs/themes/tanuki/examples/docs/content/print.md +6 -0
  312. package/docs/themes/tanuki/examples/docs/static/img/tanuki-icon.avif +0 -0
  313. package/docs/themes/tanuki/examples/index.html +2104 -0
  314. package/docs/themes/tanuki/mise.toml +108 -0
  315. package/docs/themes/tanuki/sass/base/_catppuccin.scss +164 -0
  316. package/docs/themes/tanuki/sass/base/_fonts.scss +64 -0
  317. package/docs/themes/tanuki/sass/base/_reset.scss +152 -0
  318. package/docs/themes/tanuki/sass/base/_typography.scss +523 -0
  319. package/docs/themes/tanuki/sass/components/_buttons.scss +209 -0
  320. package/docs/themes/tanuki/sass/components/_code.scss +457 -0
  321. package/docs/themes/tanuki/sass/components/_landing.scss +633 -0
  322. package/docs/themes/tanuki/sass/components/_layout.scss +294 -0
  323. package/docs/themes/tanuki/sass/components/_navigation.scss +1200 -0
  324. package/docs/themes/tanuki/sass/components/_print.scss +237 -0
  325. package/docs/themes/tanuki/sass/components/_search.scss +224 -0
  326. package/docs/themes/tanuki/sass/components/_sidebar.scss +473 -0
  327. package/docs/themes/tanuki/sass/components/_theme-toggle.scss +186 -0
  328. package/docs/themes/tanuki/sass/modes/_blog.scss +366 -0
  329. package/docs/themes/tanuki/sass/modes/_product.scss +875 -0
  330. package/docs/themes/tanuki/sass/modes/_raskell.scss +1696 -0
  331. package/docs/themes/tanuki/sass/patterns/_buttons.scss +183 -0
  332. package/docs/themes/tanuki/sass/patterns/_cards.scss +144 -0
  333. package/docs/themes/tanuki/sass/patterns/_index.scss +9 -0
  334. package/docs/themes/tanuki/sass/patterns/_lists.scss +259 -0
  335. package/docs/themes/tanuki/sass/patterns/_sections.scss +243 -0
  336. package/docs/themes/tanuki/sass/style.scss +47 -0
  337. package/docs/themes/tanuki/sass/tokens/_colors.scss +139 -0
  338. package/docs/themes/tanuki/sass/tokens/_spacing.scss +100 -0
  339. package/docs/themes/tanuki/sass/tokens/_typography.scss +186 -0
  340. package/docs/themes/tanuki/screenshot.png +0 -0
  341. package/docs/themes/tanuki/sentinel.kdl +59 -0
  342. package/docs/themes/tanuki/static/elasticlunr.min.js +10 -0
  343. package/docs/themes/tanuki/static/fonts/GEIST-LICENSE.txt +92 -0
  344. package/docs/themes/tanuki/static/fonts/Geist-Variable.woff2 +0 -0
  345. package/docs/themes/tanuki/static/fonts/GeistMono-Variable.woff2 +0 -0
  346. package/docs/themes/tanuki/static/img/tanuki-icon.avif +0 -0
  347. package/docs/themes/tanuki/static/img/tanuki-icon.png +0 -0
  348. package/docs/themes/tanuki/static/js/anchors.js +18 -0
  349. package/docs/themes/tanuki/static/js/app.js +274 -0
  350. package/docs/themes/tanuki/static/js/code.js +394 -0
  351. package/docs/themes/tanuki/static/js/navigation.js +778 -0
  352. package/docs/themes/tanuki/static/js/scroll-to-top.js +33 -0
  353. package/docs/themes/tanuki/static/js/search-raskell.js +240 -0
  354. package/docs/themes/tanuki/static/js/search.js +215 -0
  355. package/docs/themes/tanuki/static/js/theme.js +169 -0
  356. package/docs/themes/tanuki/static/syntax-dark.css +151 -0
  357. package/docs/themes/tanuki/static/syntax-light.css +151 -0
  358. package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm.js +486 -0
  359. package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm_bg.wasm +0 -0
  360. package/docs/themes/tanuki/templates/404.html +52 -0
  361. package/docs/themes/tanuki/templates/base.html +428 -0
  362. package/docs/themes/tanuki/templates/blog.html +66 -0
  363. package/docs/themes/tanuki/templates/home.html +108 -0
  364. package/docs/themes/tanuki/templates/index.html +178 -0
  365. package/docs/themes/tanuki/templates/landing.html +168 -0
  366. package/docs/themes/tanuki/templates/macros/nav.html +128 -0
  367. package/docs/themes/tanuki/templates/macros/posts.html +101 -0
  368. package/docs/themes/tanuki/templates/macros/ui.html +159 -0
  369. package/docs/themes/tanuki/templates/page.html +135 -0
  370. package/docs/themes/tanuki/templates/partials/footer.html +38 -0
  371. package/docs/themes/tanuki/templates/partials/header.html +366 -0
  372. package/docs/themes/tanuki/templates/partials/nav-buttons.html +55 -0
  373. package/docs/themes/tanuki/templates/partials/nav-overlay.html +81 -0
  374. package/docs/themes/tanuki/templates/partials/page-toc-panel.html +43 -0
  375. package/docs/themes/tanuki/templates/partials/search.html +52 -0
  376. package/docs/themes/tanuki/templates/partials/sidebar.html +107 -0
  377. package/docs/themes/tanuki/templates/partials/theme-toggle.html +35 -0
  378. package/docs/themes/tanuki/templates/partials/toc-overlay.html +146 -0
  379. package/docs/themes/tanuki/templates/partials/version-picker.html +38 -0
  380. package/docs/themes/tanuki/templates/print.html +244 -0
  381. package/docs/themes/tanuki/templates/section.html +186 -0
  382. package/docs/themes/tanuki/templates/taxonomy_list.html +18 -0
  383. package/docs/themes/tanuki/templates/taxonomy_single.html +31 -0
  384. package/docs/themes/tanuki/theme.toml +58 -0
  385. package/examples/hello-agent.rs +55 -0
  386. package/package.json +36 -0
  387. package/proto/config.proto +60 -0
  388. package/proto/events.proto +0 -0
  389. package/proto/runtime.proto +215 -0
@@ -0,0 +1,67 @@
1
+ pub mod backend;
2
+ pub mod chunker;
3
+ pub mod embeddings;
4
+ pub mod markdown;
5
+ pub mod none;
6
+ pub mod sqlite;
7
+ pub mod traits;
8
+ pub mod vector;
9
+
10
+ pub use backend::{MemoryBackendKind, classify_memory_backend, default_memory_backend_key};
11
+ pub use chunker::{chunk_markdown, Chunk};
12
+ pub use embeddings::{create_embedding_provider, EmbeddingProvider, NoopEmbedding, OpenAiEmbedding};
13
+ pub use markdown::MarkdownMemory;
14
+ pub use none::NoneMemory;
15
+ pub use sqlite::SqliteMemory;
16
+ pub use traits::{Memory, MemoryCategory, MemoryEntry};
17
+ pub use vector::{bytes_to_vec, cosine_similarity, hybrid_merge, vec_to_bytes, ScoredResult};
18
+
19
+ use std::path::Path;
20
+
21
+ pub fn create_memory(backend: &str, workspace_dir: &Path) -> anyhow::Result<Box<dyn Memory>> {
22
+ match classify_memory_backend(backend) {
23
+ MemoryBackendKind::Sqlite => Ok(Box::new(SqliteMemory::new(workspace_dir)?)),
24
+ MemoryBackendKind::Markdown => Ok(Box::new(MarkdownMemory::new(workspace_dir))),
25
+ MemoryBackendKind::None => Ok(Box::new(NoneMemory::new())),
26
+ MemoryBackendKind::Unknown => {
27
+ tracing::warn!(
28
+ "Unknown memory backend '{}', falling back to markdown",
29
+ backend
30
+ );
31
+ Ok(Box::new(MarkdownMemory::new(workspace_dir)))
32
+ }
33
+ }
34
+ }
35
+
36
+ #[cfg(test)]
37
+ mod tests {
38
+ use super::*;
39
+
40
+ #[test]
41
+ fn factory_sqlite() {
42
+ let tmp = tempfile::TempDir::new().unwrap();
43
+ let mem = create_memory("sqlite", tmp.path()).unwrap();
44
+ assert_eq!(mem.name(), "sqlite");
45
+ }
46
+
47
+ #[test]
48
+ fn factory_markdown() {
49
+ let tmp = tempfile::TempDir::new().unwrap();
50
+ let mem = create_memory("markdown", tmp.path()).unwrap();
51
+ assert_eq!(mem.name(), "markdown");
52
+ }
53
+
54
+ #[test]
55
+ fn factory_none() {
56
+ let tmp = tempfile::TempDir::new().unwrap();
57
+ let mem = create_memory("none", tmp.path()).unwrap();
58
+ assert_eq!(mem.name(), "none");
59
+ }
60
+
61
+ #[test]
62
+ fn factory_unknown_falls_back_to_markdown() {
63
+ let tmp = tempfile::TempDir::new().unwrap();
64
+ let mem = create_memory("redis", tmp.path()).unwrap();
65
+ assert_eq!(mem.name(), "markdown");
66
+ }
67
+ }
@@ -0,0 +1,127 @@
1
+ use crate::traits::{Memory, MemoryCategory, MemoryEntry};
2
+ use async_trait::async_trait;
3
+ use chrono::Utc;
4
+ use std::path::{Path, PathBuf};
5
+
6
+ pub struct MarkdownMemory {
7
+ root: PathBuf,
8
+ }
9
+
10
+ impl MarkdownMemory {
11
+ pub fn new(workspace_dir: &Path) -> Self {
12
+ Self {
13
+ root: workspace_dir.join("memory"),
14
+ }
15
+ }
16
+
17
+ fn file_for(&self, key: &str) -> PathBuf {
18
+ let safe = key
19
+ .chars()
20
+ .map(|c| {
21
+ if c.is_ascii_alphanumeric() || matches!(c, '-' | '_') {
22
+ c
23
+ } else {
24
+ '_'
25
+ }
26
+ })
27
+ .collect::<String>();
28
+ self.root.join(format!("{safe}.md"))
29
+ }
30
+
31
+ fn parse_entry(path: &Path, content: &str) -> Option<MemoryEntry> {
32
+ let key = path.file_stem()?.to_str()?.to_string();
33
+ Some(MemoryEntry {
34
+ id: key.clone(),
35
+ key,
36
+ content: content.to_string(),
37
+ category: MemoryCategory::Conversation,
38
+ timestamp: Utc::now().to_rfc3339(),
39
+ session_id: None,
40
+ score: None,
41
+ })
42
+ }
43
+ }
44
+
45
+ #[async_trait]
46
+ impl Memory for MarkdownMemory {
47
+ fn name(&self) -> &str {
48
+ "markdown"
49
+ }
50
+
51
+ async fn store(
52
+ &self,
53
+ key: &str,
54
+ content: &str,
55
+ _category: MemoryCategory,
56
+ _session_id: Option<&str>,
57
+ ) -> anyhow::Result<()> {
58
+ tokio::fs::create_dir_all(&self.root).await?;
59
+ tokio::fs::write(self.file_for(key), content).await?;
60
+ Ok(())
61
+ }
62
+
63
+ async fn recall(
64
+ &self,
65
+ query: &str,
66
+ limit: usize,
67
+ _session_id: Option<&str>,
68
+ ) -> anyhow::Result<Vec<MemoryEntry>> {
69
+ let mut entries = self.list(None, None).await?;
70
+ let q = query.to_ascii_lowercase();
71
+ entries.retain(|e| {
72
+ e.key.to_ascii_lowercase().contains(&q) || e.content.to_ascii_lowercase().contains(&q)
73
+ });
74
+ entries.truncate(limit);
75
+ Ok(entries)
76
+ }
77
+
78
+ async fn get(&self, key: &str) -> anyhow::Result<Option<MemoryEntry>> {
79
+ let path = self.file_for(key);
80
+ if !path.exists() {
81
+ return Ok(None);
82
+ }
83
+ let content = tokio::fs::read_to_string(&path).await?;
84
+ Ok(Self::parse_entry(&path, &content))
85
+ }
86
+
87
+ async fn list(
88
+ &self,
89
+ _category: Option<&MemoryCategory>,
90
+ _session_id: Option<&str>,
91
+ ) -> anyhow::Result<Vec<MemoryEntry>> {
92
+ let mut out = Vec::new();
93
+ if !self.root.exists() {
94
+ return Ok(out);
95
+ }
96
+
97
+ let mut dir = tokio::fs::read_dir(&self.root).await?;
98
+ while let Some(entry) = dir.next_entry().await? {
99
+ let path = entry.path();
100
+ if path.extension().and_then(|e| e.to_str()) != Some("md") {
101
+ continue;
102
+ }
103
+ let content = tokio::fs::read_to_string(&path).await?;
104
+ if let Some(parsed) = Self::parse_entry(&path, &content) {
105
+ out.push(parsed);
106
+ }
107
+ }
108
+ Ok(out)
109
+ }
110
+
111
+ async fn forget(&self, key: &str) -> anyhow::Result<bool> {
112
+ let path = self.file_for(key);
113
+ if !path.exists() {
114
+ return Ok(false);
115
+ }
116
+ tokio::fs::remove_file(path).await?;
117
+ Ok(true)
118
+ }
119
+
120
+ async fn count(&self) -> anyhow::Result<usize> {
121
+ Ok(self.list(None, None).await?.len())
122
+ }
123
+
124
+ async fn health_check(&self) -> bool {
125
+ tokio::fs::create_dir_all(&self.root).await.is_ok()
126
+ }
127
+ }
@@ -0,0 +1,61 @@
1
+ use crate::traits::{Memory, MemoryCategory, MemoryEntry};
2
+ use async_trait::async_trait;
3
+
4
+ #[derive(Default)]
5
+ pub struct NoneMemory;
6
+
7
+ impl NoneMemory {
8
+ pub fn new() -> Self {
9
+ Self
10
+ }
11
+ }
12
+
13
+ #[async_trait]
14
+ impl Memory for NoneMemory {
15
+ fn name(&self) -> &str {
16
+ "none"
17
+ }
18
+
19
+ async fn store(
20
+ &self,
21
+ _key: &str,
22
+ _content: &str,
23
+ _category: MemoryCategory,
24
+ _session_id: Option<&str>,
25
+ ) -> anyhow::Result<()> {
26
+ Ok(())
27
+ }
28
+
29
+ async fn recall(
30
+ &self,
31
+ _query: &str,
32
+ _limit: usize,
33
+ _session_id: Option<&str>,
34
+ ) -> anyhow::Result<Vec<MemoryEntry>> {
35
+ Ok(vec![])
36
+ }
37
+
38
+ async fn get(&self, _key: &str) -> anyhow::Result<Option<MemoryEntry>> {
39
+ Ok(None)
40
+ }
41
+
42
+ async fn list(
43
+ &self,
44
+ _category: Option<&MemoryCategory>,
45
+ _session_id: Option<&str>,
46
+ ) -> anyhow::Result<Vec<MemoryEntry>> {
47
+ Ok(vec![])
48
+ }
49
+
50
+ async fn forget(&self, _key: &str) -> anyhow::Result<bool> {
51
+ Ok(false)
52
+ }
53
+
54
+ async fn count(&self) -> anyhow::Result<usize> {
55
+ Ok(0)
56
+ }
57
+
58
+ async fn health_check(&self) -> bool {
59
+ true
60
+ }
61
+ }
@@ -0,0 +1,276 @@
1
+ use crate::traits::{Memory, MemoryCategory, MemoryEntry};
2
+ use async_trait::async_trait;
3
+ use chrono::Utc;
4
+ use rusqlite::{Connection, params};
5
+ use std::path::{Path, PathBuf};
6
+
7
+ pub struct SqliteMemory {
8
+ db_path: PathBuf,
9
+ }
10
+
11
+ impl SqliteMemory {
12
+ pub fn new(workspace_dir: &Path) -> anyhow::Result<Self> {
13
+ let db_path = workspace_dir.join("memory").join("brain.db");
14
+ if let Some(parent) = db_path.parent() {
15
+ std::fs::create_dir_all(parent)?;
16
+ }
17
+ let this = Self { db_path };
18
+ this.init_schema()?;
19
+ Ok(this)
20
+ }
21
+
22
+ fn open(&self) -> anyhow::Result<Connection> {
23
+ Ok(Connection::open(&self.db_path)?)
24
+ }
25
+
26
+ fn init_schema(&self) -> anyhow::Result<()> {
27
+ let conn = self.open()?;
28
+ conn.execute_batch(
29
+ "
30
+ CREATE TABLE IF NOT EXISTS memory_entries (
31
+ id TEXT PRIMARY KEY,
32
+ key TEXT NOT NULL UNIQUE,
33
+ content TEXT NOT NULL,
34
+ category TEXT NOT NULL,
35
+ timestamp TEXT NOT NULL,
36
+ session_id TEXT
37
+ );
38
+ CREATE INDEX IF NOT EXISTS idx_memory_key ON memory_entries(key);
39
+ CREATE INDEX IF NOT EXISTS idx_memory_category ON memory_entries(category);
40
+ CREATE INDEX IF NOT EXISTS idx_memory_session_id ON memory_entries(session_id);
41
+ ",
42
+ )?;
43
+ Ok(())
44
+ }
45
+
46
+ fn to_category(raw: &str) -> MemoryCategory {
47
+ match raw {
48
+ "core" => MemoryCategory::Core,
49
+ "daily" => MemoryCategory::Daily,
50
+ "conversation" => MemoryCategory::Conversation,
51
+ other => MemoryCategory::Custom(other.to_string()),
52
+ }
53
+ }
54
+ }
55
+
56
+ #[async_trait]
57
+ impl Memory for SqliteMemory {
58
+ fn name(&self) -> &str {
59
+ "sqlite"
60
+ }
61
+
62
+ async fn store(
63
+ &self,
64
+ key: &str,
65
+ content: &str,
66
+ category: MemoryCategory,
67
+ session_id: Option<&str>,
68
+ ) -> anyhow::Result<()> {
69
+ let db_path = self.db_path.clone();
70
+ let key = key.to_string();
71
+ let content = content.to_string();
72
+ let category = category.to_string();
73
+ let session_id = session_id.map(|s| s.to_string());
74
+
75
+ tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
76
+ let conn = Connection::open(db_path)?;
77
+ conn.execute(
78
+ "
79
+ INSERT INTO memory_entries (id, key, content, category, timestamp, session_id)
80
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6)
81
+ ON CONFLICT(key)
82
+ DO UPDATE SET
83
+ content=excluded.content,
84
+ category=excluded.category,
85
+ timestamp=excluded.timestamp,
86
+ session_id=excluded.session_id
87
+ ",
88
+ params![
89
+ uuid::Uuid::new_v4().to_string(),
90
+ key,
91
+ content,
92
+ category,
93
+ Utc::now().to_rfc3339(),
94
+ session_id,
95
+ ],
96
+ )?;
97
+ Ok(())
98
+ })
99
+ .await??;
100
+
101
+ Ok(())
102
+ }
103
+
104
+ async fn recall(
105
+ &self,
106
+ query: &str,
107
+ limit: usize,
108
+ session_id: Option<&str>,
109
+ ) -> anyhow::Result<Vec<MemoryEntry>> {
110
+ let db_path = self.db_path.clone();
111
+ let query = query.to_string();
112
+ let session = session_id.map(|s| s.to_string());
113
+
114
+ tokio::task::spawn_blocking(move || -> anyhow::Result<Vec<MemoryEntry>> {
115
+ let conn = Connection::open(db_path)?;
116
+ let mut out = Vec::new();
117
+ let like = format!("%{}%", query);
118
+
119
+ if let Some(session_id) = session {
120
+ let mut stmt = conn.prepare(
121
+ "
122
+ SELECT id, key, content, category, timestamp, session_id
123
+ FROM memory_entries
124
+ WHERE (key LIKE ?1 OR content LIKE ?1)
125
+ AND session_id = ?2
126
+ ORDER BY timestamp DESC
127
+ LIMIT ?3
128
+ ",
129
+ )?;
130
+ let rows = stmt.query_map(params![like, session_id, limit as i64], |row| {
131
+ let category_raw: String = row.get(3)?;
132
+ Ok(MemoryEntry {
133
+ id: row.get(0)?,
134
+ key: row.get(1)?,
135
+ content: row.get(2)?,
136
+ category: Self::to_category(&category_raw),
137
+ timestamp: row.get(4)?,
138
+ session_id: row.get(5)?,
139
+ score: None,
140
+ })
141
+ })?;
142
+
143
+ for row in rows {
144
+ out.push(row?);
145
+ }
146
+ } else {
147
+ let mut stmt = conn.prepare(
148
+ "
149
+ SELECT id, key, content, category, timestamp, session_id
150
+ FROM memory_entries
151
+ WHERE key LIKE ?1 OR content LIKE ?1
152
+ ORDER BY timestamp DESC
153
+ LIMIT ?2
154
+ ",
155
+ )?;
156
+ let rows = stmt.query_map(params![like, limit as i64], |row| {
157
+ let category_raw: String = row.get(3)?;
158
+ Ok(MemoryEntry {
159
+ id: row.get(0)?,
160
+ key: row.get(1)?,
161
+ content: row.get(2)?,
162
+ category: Self::to_category(&category_raw),
163
+ timestamp: row.get(4)?,
164
+ session_id: row.get(5)?,
165
+ score: None,
166
+ })
167
+ })?;
168
+
169
+ for row in rows {
170
+ out.push(row?);
171
+ }
172
+ }
173
+
174
+ Ok(out)
175
+ })
176
+ .await?
177
+ }
178
+
179
+ async fn get(&self, key: &str) -> anyhow::Result<Option<MemoryEntry>> {
180
+ let db_path = self.db_path.clone();
181
+ let key = key.to_string();
182
+
183
+ tokio::task::spawn_blocking(move || -> anyhow::Result<Option<MemoryEntry>> {
184
+ let conn = Connection::open(db_path)?;
185
+ let mut stmt = conn.prepare(
186
+ "SELECT id, key, content, category, timestamp, session_id FROM memory_entries WHERE key = ?1",
187
+ )?;
188
+ let mut rows = stmt.query(params![key])?;
189
+ if let Some(row) = rows.next()? {
190
+ let category_raw: String = row.get(3)?;
191
+ return Ok(Some(MemoryEntry {
192
+ id: row.get(0)?,
193
+ key: row.get(1)?,
194
+ content: row.get(2)?,
195
+ category: Self::to_category(&category_raw),
196
+ timestamp: row.get(4)?,
197
+ session_id: row.get(5)?,
198
+ score: None,
199
+ }));
200
+ }
201
+ Ok(None)
202
+ })
203
+ .await?
204
+ }
205
+
206
+ async fn list(
207
+ &self,
208
+ category: Option<&MemoryCategory>,
209
+ session_id: Option<&str>,
210
+ ) -> anyhow::Result<Vec<MemoryEntry>> {
211
+ let db_path = self.db_path.clone();
212
+ let category = category.map(|c| c.to_string());
213
+ let session = session_id.map(|s| s.to_string());
214
+
215
+ tokio::task::spawn_blocking(move || -> anyhow::Result<Vec<MemoryEntry>> {
216
+ let conn = Connection::open(db_path)?;
217
+ let mut out = Vec::new();
218
+
219
+ let sql = match (category.is_some(), session.is_some()) {
220
+ (false, false) => "SELECT id, key, content, category, timestamp, session_id FROM memory_entries ORDER BY timestamp DESC",
221
+ (true, false) => "SELECT id, key, content, category, timestamp, session_id FROM memory_entries WHERE category = ?1 ORDER BY timestamp DESC",
222
+ (false, true) => "SELECT id, key, content, category, timestamp, session_id FROM memory_entries WHERE session_id = ?1 ORDER BY timestamp DESC",
223
+ (true, true) => "SELECT id, key, content, category, timestamp, session_id FROM memory_entries WHERE category = ?1 AND session_id = ?2 ORDER BY timestamp DESC",
224
+ };
225
+
226
+ let mut stmt = conn.prepare(sql)?;
227
+ let mut rows = match (category, session) {
228
+ (None, None) => stmt.query(params![] )?,
229
+ (Some(c), None) => stmt.query(params![c])?,
230
+ (None, Some(s)) => stmt.query(params![s])?,
231
+ (Some(c), Some(s)) => stmt.query(params![c, s])?,
232
+ };
233
+
234
+ while let Some(row) = rows.next()? {
235
+ let category_raw: String = row.get(3)?;
236
+ out.push(MemoryEntry {
237
+ id: row.get(0)?,
238
+ key: row.get(1)?,
239
+ content: row.get(2)?,
240
+ category: Self::to_category(&category_raw),
241
+ timestamp: row.get(4)?,
242
+ session_id: row.get(5)?,
243
+ score: None,
244
+ });
245
+ }
246
+
247
+ Ok(out)
248
+ })
249
+ .await?
250
+ }
251
+
252
+ async fn forget(&self, key: &str) -> anyhow::Result<bool> {
253
+ let db_path = self.db_path.clone();
254
+ let key = key.to_string();
255
+ tokio::task::spawn_blocking(move || -> anyhow::Result<bool> {
256
+ let conn = Connection::open(db_path)?;
257
+ let affected = conn.execute("DELETE FROM memory_entries WHERE key = ?1", params![key])?;
258
+ Ok(affected > 0)
259
+ })
260
+ .await?
261
+ }
262
+
263
+ async fn count(&self) -> anyhow::Result<usize> {
264
+ let db_path = self.db_path.clone();
265
+ tokio::task::spawn_blocking(move || -> anyhow::Result<usize> {
266
+ let conn = Connection::open(db_path)?;
267
+ let count: i64 = conn.query_row("SELECT COUNT(*) FROM memory_entries", params![], |r| r.get(0))?;
268
+ Ok(count.max(0) as usize)
269
+ })
270
+ .await?
271
+ }
272
+
273
+ async fn health_check(&self) -> bool {
274
+ self.open().is_ok()
275
+ }
276
+ }
@@ -0,0 +1,65 @@
1
+ use async_trait::async_trait;
2
+ use serde::{Deserialize, Serialize};
3
+
4
+ #[derive(Debug, Clone, Serialize, Deserialize)]
5
+ pub struct MemoryEntry {
6
+ pub id: String,
7
+ pub key: String,
8
+ pub content: String,
9
+ pub category: MemoryCategory,
10
+ pub timestamp: String,
11
+ pub session_id: Option<String>,
12
+ pub score: Option<f64>,
13
+ }
14
+
15
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
16
+ #[serde(rename_all = "snake_case")]
17
+ pub enum MemoryCategory {
18
+ Core,
19
+ Daily,
20
+ Conversation,
21
+ Custom(String),
22
+ }
23
+
24
+ impl std::fmt::Display for MemoryCategory {
25
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26
+ match self {
27
+ Self::Core => write!(f, "core"),
28
+ Self::Daily => write!(f, "daily"),
29
+ Self::Conversation => write!(f, "conversation"),
30
+ Self::Custom(name) => write!(f, "{name}"),
31
+ }
32
+ }
33
+ }
34
+
35
+ #[async_trait]
36
+ pub trait Memory: Send + Sync {
37
+ fn name(&self) -> &str;
38
+
39
+ async fn store(
40
+ &self,
41
+ key: &str,
42
+ content: &str,
43
+ category: MemoryCategory,
44
+ session_id: Option<&str>,
45
+ ) -> anyhow::Result<()>;
46
+
47
+ async fn recall(
48
+ &self,
49
+ query: &str,
50
+ limit: usize,
51
+ session_id: Option<&str>,
52
+ ) -> anyhow::Result<Vec<MemoryEntry>>;
53
+
54
+ async fn get(&self, key: &str) -> anyhow::Result<Option<MemoryEntry>>;
55
+
56
+ async fn list(
57
+ &self,
58
+ category: Option<&MemoryCategory>,
59
+ session_id: Option<&str>,
60
+ ) -> anyhow::Result<Vec<MemoryEntry>>;
61
+
62
+ async fn forget(&self, key: &str) -> anyhow::Result<bool>;
63
+ async fn count(&self) -> anyhow::Result<usize>;
64
+ async fn health_check(&self) -> bool;
65
+ }