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,218 @@
1
+ //! StateGraph - builder for creating graphs
2
+ //!
3
+ //! Includes cycle detection to prevent infinite loops (DAG invariant).
4
+
5
+ use super::edge::{ConditionalEdge, Edge, EdgeTarget};
6
+ use super::node::{DynNode, FunctionNode, Node, NodeState};
7
+ use super::CompiledGraph;
8
+ use std::collections::{HashMap, HashSet};
9
+ use std::future::Future;
10
+ use std::sync::Arc;
11
+
12
+ /// StateGraph - fluent builder for creating DAGs
13
+ pub struct StateGraph {
14
+ nodes: HashMap<String, DynNode>,
15
+ edges: Vec<Edge>,
16
+ conditional_edges: Vec<ConditionalEdge>,
17
+ entry_point: Option<String>,
18
+ }
19
+
20
+ impl StateGraph {
21
+ /// Create a new empty graph
22
+ pub fn new() -> Self {
23
+ Self {
24
+ nodes: HashMap::new(),
25
+ edges: Vec::new(),
26
+ conditional_edges: Vec::new(),
27
+ entry_point: None,
28
+ }
29
+ }
30
+
31
+ /// Add a node with a function
32
+ pub fn add_node<F, Fut>(mut self, name: impl Into<String>, func: F) -> Self
33
+ where
34
+ F: Fn(NodeState) -> Fut + Send + Sync + 'static,
35
+ Fut: Future<Output = anyhow::Result<NodeState>> + Send + 'static,
36
+ {
37
+ let name = name.into();
38
+ let node = Arc::new(FunctionNode::new(name.clone(), func));
39
+ self.nodes.insert(name, node);
40
+ self
41
+ }
42
+
43
+ /// Add a pre-built node
44
+ pub fn add_node_impl(mut self, node: impl Node + 'static) -> Self {
45
+ let name = node.name().to_string();
46
+ self.nodes.insert(name, Arc::new(node));
47
+ self
48
+ }
49
+
50
+ /// Add a direct edge between two nodes
51
+ pub fn add_edge(mut self, from: impl Into<String>, to: impl Into<String>) -> Self {
52
+ self.edges.push(Edge::new(from, EdgeTarget::node(to)));
53
+ self
54
+ }
55
+
56
+ /// Add an edge to END
57
+ pub fn add_edge_to_end(mut self, from: impl Into<String>) -> Self {
58
+ self.edges.push(Edge::new(from, EdgeTarget::End));
59
+ self
60
+ }
61
+
62
+ /// Add a conditional edge with a router function
63
+ pub fn add_conditional_edge<F>(mut self, from: impl Into<String>, router: F) -> Self
64
+ where
65
+ F: Fn(&str) -> EdgeTarget + Send + Sync + 'static,
66
+ {
67
+ self.conditional_edges.push(ConditionalEdge {
68
+ from: from.into(),
69
+ router: Arc::new(router),
70
+ });
71
+ self
72
+ }
73
+
74
+ /// Set the entry point node
75
+ pub fn set_entry_point(mut self, name: impl Into<String>) -> Self {
76
+ self.entry_point = Some(name.into());
77
+ self
78
+ }
79
+
80
+ /// Compile the graph for execution
81
+ pub fn compile(self) -> anyhow::Result<CompiledGraph> {
82
+ // Validate: must have at least one node
83
+ if self.nodes.is_empty() {
84
+ anyhow::bail!("Graph must have at least one node");
85
+ }
86
+
87
+ // Determine entry point
88
+ let entry_point = self.entry_point.clone().or_else(|| {
89
+ // If no entry point set, use first node added
90
+ self.nodes.keys().next().cloned()
91
+ });
92
+
93
+ let entry_point = entry_point.ok_or_else(|| anyhow::anyhow!("No entry point defined"))?;
94
+
95
+ // Validate: entry point must exist
96
+ if !self.nodes.contains_key(&entry_point) {
97
+ anyhow::bail!("Entry point '{}' does not exist", entry_point);
98
+ }
99
+
100
+ // Validate: all edge sources/targets exist
101
+ for edge in &self.edges {
102
+ if !self.nodes.contains_key(&edge.from) {
103
+ anyhow::bail!("Edge source '{}' does not exist", edge.from);
104
+ }
105
+ if let EdgeTarget::Node(ref target) = edge.to {
106
+ if !self.nodes.contains_key(target) {
107
+ anyhow::bail!("Edge target '{}' does not exist", target);
108
+ }
109
+ }
110
+ }
111
+
112
+ // Validate: no cycles (DAG invariant)
113
+ // Build adjacency list from edges
114
+ let adjacency = self.build_adjacency_list();
115
+ if let Some(cycle) = self.detect_cycle(&adjacency, &entry_point) {
116
+ anyhow::bail!(
117
+ "Graph contains a cycle: {} -> ... -> {}. Cycles are not allowed in DAGs.",
118
+ cycle.first().unwrap_or(&"?".to_string()),
119
+ cycle.last().unwrap_or(&"?".to_string())
120
+ );
121
+ }
122
+
123
+ Ok(CompiledGraph {
124
+ nodes: self.nodes,
125
+ edges: self.edges,
126
+ conditional_edges: self.conditional_edges,
127
+ entry_point,
128
+ })
129
+ }
130
+
131
+ /// Build adjacency list from edges
132
+ fn build_adjacency_list(&self) -> HashMap<String, Vec<String>> {
133
+ let mut adjacency: HashMap<String, Vec<String>> = HashMap::new();
134
+
135
+ // Initialize all nodes with empty neighbor lists
136
+ for node_name in self.nodes.keys() {
137
+ adjacency.entry(node_name.clone()).or_default();
138
+ }
139
+
140
+ // Add edges
141
+ for edge in &self.edges {
142
+ if let EdgeTarget::Node(ref target) = edge.to {
143
+ adjacency
144
+ .entry(edge.from.clone())
145
+ .or_default()
146
+ .push(target.clone());
147
+ }
148
+ }
149
+
150
+ adjacency
151
+ }
152
+
153
+ /// Detect cycle using DFS
154
+ /// Returns Some(cycle_path) if a cycle is found, None otherwise
155
+ fn detect_cycle(
156
+ &self,
157
+ adjacency: &HashMap<String, Vec<String>>,
158
+ entry_point: &str,
159
+ ) -> Option<Vec<String>> {
160
+ let mut visited = HashSet::new();
161
+ let mut rec_stack = HashSet::new();
162
+ let mut path = Vec::new();
163
+
164
+ if self.dfs_cycle_detect(entry_point, adjacency, &mut visited, &mut rec_stack, &mut path) {
165
+ return Some(path);
166
+ }
167
+
168
+ // Also check from all nodes in case graph has disconnected components
169
+ for node in self.nodes.keys() {
170
+ if !visited.contains(node) {
171
+ path.clear();
172
+ if self.dfs_cycle_detect(node, adjacency, &mut visited, &mut rec_stack, &mut path) {
173
+ return Some(path);
174
+ }
175
+ }
176
+ }
177
+
178
+ None
179
+ }
180
+
181
+ /// DFS helper for cycle detection
182
+ fn dfs_cycle_detect(
183
+ &self,
184
+ node: &str,
185
+ adjacency: &HashMap<String, Vec<String>>,
186
+ visited: &mut HashSet<String>,
187
+ rec_stack: &mut HashSet<String>,
188
+ path: &mut Vec<String>,
189
+ ) -> bool {
190
+ visited.insert(node.to_string());
191
+ rec_stack.insert(node.to_string());
192
+ path.push(node.to_string());
193
+
194
+ if let Some(neighbors) = adjacency.get(node) {
195
+ for neighbor in neighbors {
196
+ if !visited.contains(neighbor) {
197
+ if self.dfs_cycle_detect(neighbor, adjacency, visited, rec_stack, path) {
198
+ return true;
199
+ }
200
+ } else if rec_stack.contains(neighbor) {
201
+ // Found a cycle
202
+ path.push(neighbor.clone());
203
+ return true;
204
+ }
205
+ }
206
+ }
207
+
208
+ rec_stack.remove(node);
209
+ path.pop();
210
+ false
211
+ }
212
+ }
213
+
214
+ impl Default for StateGraph {
215
+ fn default() -> Self {
216
+ Self::new()
217
+ }
218
+ }
@@ -0,0 +1,155 @@
1
+ use super::schema::{GraphDefinition, NodeDefinition};
2
+ use super::{EdgeTarget, NodeState, StateGraph};
3
+ use anyhow::{anyhow, Context, Result};
4
+
5
+ pub struct GraphLoader;
6
+
7
+ impl GraphLoader {
8
+ pub fn load_from_str(yaml: &str) -> Result<StateGraph> {
9
+ let def: GraphDefinition =
10
+ serde_yaml::from_str(yaml).context("Failed to parse graph definition YAML")?;
11
+
12
+ let mut graph = StateGraph::new();
13
+
14
+ // 1. Add all nodes
15
+ for (name, node_def) in &def.nodes {
16
+ match node_def {
17
+ NodeDefinition::Llm {
18
+ model,
19
+ system_prompt,
20
+ ..
21
+ } => {
22
+ // Placeholder for LLM node
23
+ let name_clone = name.clone();
24
+ let model = model.clone().unwrap_or_else(|| "default".to_string());
25
+ let prompt = system_prompt.clone();
26
+
27
+ graph = graph.add_node(name, move |state: NodeState| {
28
+ let n = name_clone.clone();
29
+ let m = model.clone();
30
+ let p = prompt.clone();
31
+ async move {
32
+ println!("🤖 [LLM Node: {}] Model: {}, Prompt: {:.30}...", n, m, p);
33
+ // In a real implementation, this would call LlmCallable
34
+ Ok(state)
35
+ }
36
+ });
37
+ }
38
+ NodeDefinition::Function { action, .. } => {
39
+ let name_clone = name.clone();
40
+ let action = action.clone();
41
+
42
+ graph = graph.add_node(name, move |state: NodeState| {
43
+ let n = name_clone.clone();
44
+ let a = action.clone();
45
+ async move {
46
+ println!("⚙️ [Function Node: {}] Action: {}", n, a);
47
+ // In a real implementation, this would execute the actionCommand
48
+ // For now, allow simple "echo" for testing
49
+ if a.starts_with("echo ") {
50
+ let output = a.trim_start_matches("echo ").to_string();
51
+ return Ok(NodeState::from_str(&output));
52
+ }
53
+ Ok(state)
54
+ }
55
+ });
56
+ }
57
+ NodeDefinition::Condition { expr, .. } => {
58
+ let name_clone = name.clone();
59
+ let expr = expr.clone();
60
+
61
+ // Condition node evaluates expression and returns the result key
62
+ // (which matches an edge key)
63
+ graph = graph.add_node(name, move |state: NodeState| {
64
+ let n = name_clone.clone();
65
+ let e = expr.clone();
66
+ async move {
67
+ println!("❓ [Condition Node: {}] Expr: {}", n, e);
68
+ // Simple mock evaluation
69
+ // If input contains "error", return "error", else "ok"
70
+ let input = state.as_str().unwrap_or("");
71
+ if e.contains("contains('error')") {
72
+ if input.contains("error") {
73
+ return Ok(NodeState::from_str("error"));
74
+ } else {
75
+ return Ok(NodeState::from_str("ok"));
76
+ }
77
+ }
78
+ Ok(NodeState::from_str("default"))
79
+ }
80
+ });
81
+ }
82
+ _ => {
83
+ return Err(anyhow!("Unsupported node type in yaml"));
84
+ }
85
+ }
86
+ }
87
+
88
+ // 2. Add edges
89
+ for (name, node_def) in &def.nodes {
90
+ let edges = node_def.edges();
91
+
92
+ // Check if this is a conditional node (router)
93
+ // If it has multiple edges with keys other than "_default",
94
+ // valid keys are the outputs of the previous node.
95
+
96
+ // For Llm/Function nodes, usually they have a single "_default" edge
97
+ // or specific keys if they return structured data?
98
+ // The schema implies simple string matching on output.
99
+
100
+ let is_conditional = matches!(node_def, NodeDefinition::Condition { .. });
101
+
102
+ if is_conditional {
103
+ // Conditional edges based on node output
104
+ let edges_clone = edges.clone();
105
+ let router = move |output: &str| -> EdgeTarget {
106
+ if let Some(target) = edges_clone.get(output) {
107
+ if target == "END" {
108
+ EdgeTarget::End
109
+ } else {
110
+ EdgeTarget::Node(target.clone())
111
+ }
112
+ } else if let Some(default) = edges_clone.get("_default") {
113
+ if default == "END" {
114
+ EdgeTarget::End
115
+ } else {
116
+ EdgeTarget::Node(default.clone())
117
+ }
118
+ } else {
119
+ EdgeTarget::End
120
+ }
121
+ };
122
+
123
+ graph = graph.add_conditional_edge(name, router);
124
+ } else {
125
+ // Standard edges
126
+ // TODO: Support branching from non-condition nodes?
127
+ // For now, assume "_default" is the main edge
128
+ if let Some(target) = edges.get("_default") {
129
+ if target == "END" {
130
+ graph = graph.add_edge_to_end(name);
131
+ } else {
132
+ graph = graph.add_edge(name, target);
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ // 3. Set entry point
139
+ // Ideally schema allows defining it, or we use first node?
140
+ // Current StateGraph defaults to first node if not set.
141
+ // We could look for "start" or "input" node?
142
+ // The implementation_plan example didn't specify entry point explicitly.
143
+ // Let's assume the first defined node in YAML (but HashMap is unordered).
144
+ // Use "start" or "input" if present, else random?
145
+ // Better: require `triggers` or look for a node named "start".
146
+
147
+ if def.nodes.contains_key("start") {
148
+ graph = graph.set_entry_point("start");
149
+ } else if def.nodes.contains_key("input") {
150
+ graph = graph.set_entry_point("input");
151
+ }
152
+
153
+ Ok(graph)
154
+ }
155
+ }
@@ -0,0 +1,18 @@
1
+ //! Graph module - DAG execution engine and flow semantics
2
+
3
+ mod checkpoint;
4
+ mod checkpoint_store;
5
+ mod compiled;
6
+ mod edge;
7
+ mod graph_schema;
8
+ pub mod loader;
9
+ pub mod schema;
10
+
11
+ pub mod node;
12
+
13
+ pub use checkpoint::Checkpoint;
14
+ pub use checkpoint_store::{CheckpointStore, InMemoryCheckpointStore};
15
+ pub use compiled::CompiledGraph;
16
+ pub use edge::{Edge, EdgeTarget};
17
+ pub use graph_schema::StateGraph;
18
+ pub use node::{FunctionNode, Node, NodeState};
@@ -0,0 +1,49 @@
1
+ //! Function node - wraps an async function as a node
2
+
3
+ use super::{Node, NodeState};
4
+ use async_trait::async_trait;
5
+ use std::future::Future;
6
+ use std::pin::Pin;
7
+ use std::sync::Arc;
8
+
9
+ /// Type alias for async node functions
10
+ pub type NodeFn = Arc<
11
+ dyn Fn(NodeState) -> Pin<Box<dyn Future<Output = anyhow::Result<NodeState>> + Send>>
12
+ + Send
13
+ + Sync,
14
+ >;
15
+
16
+ /// Function node - wraps an async closure
17
+ pub struct FunctionNode {
18
+ name: String,
19
+ func: NodeFn,
20
+ }
21
+
22
+ impl FunctionNode {
23
+ pub fn new<F, Fut>(name: impl Into<String>, func: F) -> Self
24
+ where
25
+ F: Fn(NodeState) -> Fut + Send + Sync + 'static,
26
+ Fut: Future<Output = anyhow::Result<NodeState>> + Send + 'static,
27
+ {
28
+ let func = Arc::new(move |state: NodeState| {
29
+ let fut = func(state);
30
+ Box::pin(fut) as Pin<Box<dyn Future<Output = anyhow::Result<NodeState>> + Send>>
31
+ });
32
+
33
+ Self {
34
+ name: name.into(),
35
+ func,
36
+ }
37
+ }
38
+ }
39
+
40
+ #[async_trait]
41
+ impl Node for FunctionNode {
42
+ fn name(&self) -> &str {
43
+ &self.name
44
+ }
45
+
46
+ async fn execute(&self, state: NodeState) -> anyhow::Result<NodeState> {
47
+ (self.func)(state).await
48
+ }
49
+ }
@@ -0,0 +1,48 @@
1
+ //! Node module - units of execution in a graph
2
+
3
+ mod function;
4
+
5
+ use async_trait::async_trait;
6
+ use serde_json::Value;
7
+ use std::sync::Arc;
8
+
9
+ pub use function::FunctionNode;
10
+
11
+ /// Node state - input/output passed between nodes
12
+ #[derive(Debug, Clone, Default)]
13
+ pub struct NodeState {
14
+ pub data: Value,
15
+ }
16
+
17
+ impl NodeState {
18
+ pub fn new() -> Self {
19
+ Self { data: Value::Null }
20
+ }
21
+
22
+ pub fn from_value(data: Value) -> Self {
23
+ Self { data }
24
+ }
25
+
26
+ pub fn from_str(s: &str) -> Self {
27
+ Self {
28
+ data: Value::String(s.to_string()),
29
+ }
30
+ }
31
+
32
+ pub fn as_str(&self) -> Option<&str> {
33
+ self.data.as_str()
34
+ }
35
+ }
36
+
37
+ /// Node trait - a single step in a graph
38
+ #[async_trait]
39
+ pub trait Node: Send + Sync {
40
+ /// Node name (unique within graph)
41
+ fn name(&self) -> &str;
42
+
43
+ /// Execute the node
44
+ async fn execute(&self, state: NodeState) -> anyhow::Result<NodeState>;
45
+ }
46
+
47
+ /// Boxed node for dynamic dispatch
48
+ pub type DynNode = Arc<dyn Node>;
@@ -0,0 +1,62 @@
1
+ use serde::{Deserialize, Serialize};
2
+ use std::collections::HashMap;
3
+
4
+ #[derive(Debug, Clone, Serialize, Deserialize)]
5
+ pub struct GraphDefinition {
6
+ pub name: String,
7
+ #[serde(default = "default_version")]
8
+ pub version: String,
9
+ pub description: Option<String>,
10
+ #[serde(default)]
11
+ pub triggers: Vec<String>, // "manual", "cron:...", etc.
12
+ #[serde(default)]
13
+ pub inputs: HashMap<String, String>, // name -> description or type
14
+ pub nodes: HashMap<String, NodeDefinition>,
15
+ }
16
+
17
+ fn default_version() -> String {
18
+ "1.0".to_string()
19
+ }
20
+
21
+ #[derive(Debug, Clone, Serialize, Deserialize)]
22
+ #[serde(tag = "type", rename_all = "snake_case")]
23
+ pub enum NodeDefinition {
24
+ /// LLM-based agent node
25
+ Llm {
26
+ #[serde(default)]
27
+ model: Option<String>, // e.g., "gpt-4o"
28
+ system_prompt: String,
29
+ #[serde(default)]
30
+ tools: Vec<String>, // tool names
31
+ #[serde(default)]
32
+ edges: HashMap<String, String>, // output matching -> target node
33
+ },
34
+ /// Function execution node (e.g., shell command, script)
35
+ Function {
36
+ action: String, // e.g., "scripts/check_style.sh"
37
+ #[serde(default)]
38
+ edges: HashMap<String, String>,
39
+ },
40
+ /// Conditional branching node (no LLM, just logic)
41
+ Condition {
42
+ expr: String, // e.g. "input.contains('error')"
43
+ edges: HashMap<String, String>, // "true" -> nodeA, "false" -> nodeB
44
+ },
45
+ /// Sub-graph execution
46
+ Graph {
47
+ graph_name: String,
48
+ #[serde(default)]
49
+ edges: HashMap<String, String>,
50
+ },
51
+ }
52
+
53
+ impl NodeDefinition {
54
+ pub fn edges(&self) -> &HashMap<String, String> {
55
+ match self {
56
+ NodeDefinition::Llm { edges, .. } => edges,
57
+ NodeDefinition::Function { edges, .. } => edges,
58
+ NodeDefinition::Condition { edges, .. } => edges,
59
+ NodeDefinition::Graph { edges, .. } => edges,
60
+ }
61
+ }
62
+ }