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,476 @@
1
+ //! Runner - executes callables and graphs with flow features
2
+
3
+ use crate::callable::Callable;
4
+ use crate::graph::{Checkpoint, CheckpointStore, CompiledGraph, NodeState};
5
+ use crate::kernel::{ExecutionError, ExecutionId, StepId, StepType};
6
+ use crate::streaming::{EventEmitter, StreamEvent};
7
+ use std::sync::Arc;
8
+ use std::time::Instant;
9
+ use tokio_util::sync::CancellationToken;
10
+
11
+ /// Runner - executes agents/graphs with abort, pause, and event streaming
12
+ pub struct Runner<S: CheckpointStore> {
13
+ execution_id: ExecutionId,
14
+ cancellation_token: CancellationToken,
15
+ checkpoint_store: Arc<S>,
16
+ emitter: EventEmitter,
17
+ paused: std::sync::atomic::AtomicBool,
18
+ start_time: Option<Instant>,
19
+ }
20
+
21
+ impl<S: CheckpointStore> Runner<S> {
22
+ /// Create a new runner
23
+ pub fn new(checkpoint_store: Arc<S>) -> Self {
24
+ Self {
25
+ execution_id: ExecutionId::new(),
26
+ cancellation_token: CancellationToken::new(),
27
+ checkpoint_store,
28
+ emitter: EventEmitter::new(),
29
+ paused: std::sync::atomic::AtomicBool::new(false),
30
+ start_time: None,
31
+ }
32
+ }
33
+
34
+ /// Get the execution ID
35
+ pub fn execution_id(&self) -> &ExecutionId {
36
+ &self.execution_id
37
+ }
38
+
39
+ /// Backward compatibility alias
40
+ #[deprecated(note = "Use execution_id() instead")]
41
+ pub fn run_id(&self) -> &ExecutionId {
42
+ &self.execution_id
43
+ }
44
+
45
+ /// Get the event emitter
46
+ pub fn emitter(&self) -> &EventEmitter {
47
+ &self.emitter
48
+ }
49
+
50
+ /// Cancel the run (abort signal)
51
+ pub fn cancel(&self) {
52
+ self.cancellation_token.cancel();
53
+ self.emitter.emit(StreamEvent::execution_cancelled(
54
+ &self.execution_id,
55
+ "Run cancelled by user",
56
+ ));
57
+ }
58
+
59
+ /// Check if cancelled
60
+ pub fn is_cancelled(&self) -> bool {
61
+ self.cancellation_token.is_cancelled()
62
+ }
63
+
64
+ /// Pause the run
65
+ pub async fn pause(&self) -> anyhow::Result<()> {
66
+ self.paused.store(true, std::sync::atomic::Ordering::SeqCst);
67
+ self.emitter.emit(StreamEvent::execution_paused(
68
+ &self.execution_id,
69
+ "Paused by user",
70
+ ));
71
+ Ok(())
72
+ }
73
+
74
+ /// Resume the run
75
+ pub fn resume(&self) {
76
+ self.paused.store(false, std::sync::atomic::Ordering::SeqCst);
77
+ self.emitter.emit(StreamEvent::execution_resumed(&self.execution_id));
78
+ }
79
+
80
+ /// Check if paused
81
+ pub fn is_paused(&self) -> bool {
82
+ self.paused.load(std::sync::atomic::Ordering::SeqCst)
83
+ }
84
+
85
+ /// Save checkpoint
86
+ pub async fn save_checkpoint(&self, state: NodeState, node: Option<&str>) -> anyhow::Result<Checkpoint> {
87
+ let mut checkpoint = Checkpoint::new(self.execution_id.clone())
88
+ .with_state(state.data);
89
+
90
+ if let Some(n) = node {
91
+ checkpoint = checkpoint.with_node(n);
92
+ }
93
+
94
+ self.checkpoint_store.save(checkpoint.clone()).await?;
95
+ Ok(checkpoint)
96
+ }
97
+
98
+ /// Load latest checkpoint
99
+ pub async fn load_checkpoint(&self) -> anyhow::Result<Option<Checkpoint>> {
100
+ self.checkpoint_store.load_latest(self.execution_id.as_str()).await
101
+ }
102
+
103
+ /// Run a callable with event streaming
104
+ pub async fn run_callable<A: Callable + ?Sized>(&mut self, callable: &A, input: &str) -> anyhow::Result<String> {
105
+ self.start_time = Some(Instant::now());
106
+ self.emitter.emit(StreamEvent::execution_start(&self.execution_id));
107
+
108
+ // Check for cancellation before running
109
+ if self.is_cancelled() {
110
+ anyhow::bail!("Run cancelled");
111
+ }
112
+
113
+ let result = callable.run(input).await;
114
+ let duration_ms = self.start_time.map(|t| t.elapsed().as_millis() as u64).unwrap_or(0);
115
+
116
+ match &result {
117
+ Ok(output) => {
118
+ self.emitter.emit(StreamEvent::execution_end(
119
+ &self.execution_id,
120
+ Some(output.clone()),
121
+ duration_ms,
122
+ ));
123
+ }
124
+ Err(e) => {
125
+ let error = ExecutionError::kernel_internal(e.to_string());
126
+ self.emitter.emit(StreamEvent::execution_failed(
127
+ &self.execution_id,
128
+ error,
129
+ ));
130
+ }
131
+ }
132
+
133
+ result
134
+ }
135
+
136
+ /// Run a compiled graph with event streaming
137
+ pub async fn run_graph(&mut self, graph: &CompiledGraph, input: &str) -> anyhow::Result<NodeState> {
138
+ self.start_time = Some(Instant::now());
139
+ self.emitter.emit(StreamEvent::execution_start(&self.execution_id));
140
+
141
+ let mut state = NodeState::from_str(input);
142
+ let mut current_node = graph.entry_point().to_string();
143
+
144
+ loop {
145
+ // Check for cancellation
146
+ if self.is_cancelled() {
147
+ anyhow::bail!("Run cancelled");
148
+ }
149
+
150
+ // Check for pause - wait until resumed
151
+ while self.is_paused() {
152
+ tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
153
+ if self.is_cancelled() {
154
+ anyhow::bail!("Run cancelled while paused");
155
+ }
156
+ }
157
+
158
+ // Get the node
159
+ let node = graph
160
+ .get_node(&current_node)
161
+ .ok_or_else(|| anyhow::anyhow!("Node '{}' not found", current_node))?;
162
+
163
+ // Create step ID for this node execution
164
+ let step_id = StepId::new();
165
+ let step_start = Instant::now();
166
+
167
+ // Emit step started
168
+ self.emitter.emit(StreamEvent::step_start(
169
+ &self.execution_id,
170
+ &step_id,
171
+ StepType::FunctionNode, // Graph nodes are function nodes by default
172
+ current_node.clone(),
173
+ ));
174
+
175
+ // Execute node
176
+ state = node.execute(state).await?;
177
+
178
+ // Emit step completed
179
+ let step_duration = step_start.elapsed().as_millis() as u64;
180
+ self.emitter.emit(StreamEvent::step_end(
181
+ &self.execution_id,
182
+ &step_id,
183
+ Some(state.as_str().unwrap_or_default().to_string()),
184
+ step_duration,
185
+ ));
186
+
187
+ // Get next nodes
188
+ let output = state.as_str().unwrap_or_default();
189
+ let next = graph.get_next(&current_node, output);
190
+
191
+ if next.is_empty() {
192
+ break;
193
+ }
194
+
195
+ match &next[0] {
196
+ crate::graph::EdgeTarget::End => break,
197
+ crate::graph::EdgeTarget::Node(n) => {
198
+ current_node = n.clone();
199
+ }
200
+ }
201
+ }
202
+
203
+ let duration_ms = self.start_time.map(|t| t.elapsed().as_millis() as u64).unwrap_or(0);
204
+ self.emitter.emit(StreamEvent::execution_end(
205
+ &self.execution_id,
206
+ Some(state.as_str().unwrap_or_default().to_string()),
207
+ duration_ms,
208
+ ));
209
+
210
+ Ok(state)
211
+ }
212
+ }
213
+
214
+ /// Runner with in-memory checkpoint store (default)
215
+ pub type DefaultRunner = Runner<crate::graph::InMemoryCheckpointStore>;
216
+
217
+ impl DefaultRunner {
218
+ /// Create a new runner with in-memory checkpoint store
219
+ pub fn default_new() -> Self {
220
+ Self::new(Arc::new(crate::graph::InMemoryCheckpointStore::new()))
221
+ }
222
+ }
223
+
224
+ #[cfg(test)]
225
+ mod tests {
226
+ use super::*;
227
+ use async_trait::async_trait;
228
+ use crate::graph::InMemoryCheckpointStore;
229
+
230
+ /// Mock callable for testing
231
+ struct MockCallable {
232
+ name: String,
233
+ response: Result<String, String>,
234
+ delay_ms: Option<u64>,
235
+ }
236
+
237
+ impl MockCallable {
238
+ fn success(name: &str, response: &str) -> Self {
239
+ Self {
240
+ name: name.to_string(),
241
+ response: Ok(response.to_string()),
242
+ delay_ms: None,
243
+ }
244
+ }
245
+
246
+ fn failing(name: &str, error: &str) -> Self {
247
+ Self {
248
+ name: name.to_string(),
249
+ response: Err(error.to_string()),
250
+ delay_ms: None,
251
+ }
252
+ }
253
+ }
254
+
255
+ #[async_trait]
256
+ impl Callable for MockCallable {
257
+ fn name(&self) -> &str {
258
+ &self.name
259
+ }
260
+
261
+ async fn run(&self, input: &str) -> anyhow::Result<String> {
262
+ if let Some(delay) = self.delay_ms {
263
+ tokio::time::sleep(tokio::time::Duration::from_millis(delay)).await;
264
+ }
265
+ match &self.response {
266
+ Ok(r) => Ok(format!("{}:{}", r, input)),
267
+ Err(e) => anyhow::bail!("{}", e),
268
+ }
269
+ }
270
+ }
271
+
272
+ // ============ Construction Tests ============
273
+
274
+ #[test]
275
+ fn test_runner_new() {
276
+ let store = Arc::new(InMemoryCheckpointStore::new());
277
+ let runner = Runner::new(store);
278
+
279
+ // Should have a valid execution ID
280
+ assert!(!runner.execution_id().as_str().is_empty());
281
+ // Should not be cancelled initially
282
+ assert!(!runner.is_cancelled());
283
+ // Should not be paused initially
284
+ assert!(!runner.is_paused());
285
+ }
286
+
287
+ #[test]
288
+ fn test_default_runner_new() {
289
+ let runner = DefaultRunner::default_new();
290
+ assert!(!runner.execution_id().as_str().is_empty());
291
+ }
292
+
293
+ #[test]
294
+ fn test_runner_execution_id_unique() {
295
+ let store = Arc::new(InMemoryCheckpointStore::new());
296
+ let runner1 = Runner::new(store.clone());
297
+ let runner2 = Runner::new(store);
298
+
299
+ // Each runner should have unique execution ID
300
+ assert_ne!(runner1.execution_id().as_str(), runner2.execution_id().as_str());
301
+ }
302
+
303
+ // ============ Cancellation Tests ============
304
+
305
+ #[test]
306
+ fn test_runner_cancel() {
307
+ let runner = DefaultRunner::default_new();
308
+
309
+ assert!(!runner.is_cancelled());
310
+ runner.cancel();
311
+ assert!(runner.is_cancelled());
312
+ }
313
+
314
+ #[tokio::test]
315
+ async fn test_runner_callable_checks_cancellation_before_run() {
316
+ let mut runner = DefaultRunner::default_new();
317
+ let callable = MockCallable::success("test", "response");
318
+
319
+ // Cancel before running
320
+ runner.cancel();
321
+
322
+ let result = runner.run_callable(&callable, "input").await;
323
+ assert!(result.is_err());
324
+ assert!(result.unwrap_err().to_string().contains("cancelled"));
325
+ }
326
+
327
+ // ============ Pause/Resume Tests ============
328
+
329
+ #[tokio::test]
330
+ async fn test_runner_pause_resume() {
331
+ let runner = DefaultRunner::default_new();
332
+
333
+ assert!(!runner.is_paused());
334
+
335
+ runner.pause().await.unwrap();
336
+ assert!(runner.is_paused());
337
+
338
+ runner.resume();
339
+ assert!(!runner.is_paused());
340
+ }
341
+
342
+ // ============ Run Callable Tests ============
343
+
344
+ #[tokio::test]
345
+ async fn test_run_callable_success() {
346
+ let mut runner = DefaultRunner::default_new();
347
+ let callable = MockCallable::success("test", "hello");
348
+
349
+ let result = runner.run_callable(&callable, "world").await;
350
+ assert!(result.is_ok());
351
+ assert_eq!(result.unwrap(), "hello:world");
352
+ }
353
+
354
+ #[tokio::test]
355
+ async fn test_run_callable_failure() {
356
+ let mut runner = DefaultRunner::default_new();
357
+ let callable = MockCallable::failing("test", "Something went wrong");
358
+
359
+ let result = runner.run_callable(&callable, "input").await;
360
+ assert!(result.is_err());
361
+ assert!(result.unwrap_err().to_string().contains("Something went wrong"));
362
+ }
363
+
364
+ #[tokio::test]
365
+ async fn test_run_callable_emits_events() {
366
+ let mut runner = DefaultRunner::default_new();
367
+ let callable = MockCallable::success("test", "response");
368
+
369
+ runner.run_callable(&callable, "input").await.unwrap();
370
+
371
+ // Drain and check collected events
372
+ let events = runner.emitter().drain();
373
+
374
+ // Should have execution start and end events
375
+ assert!(events.len() >= 2);
376
+
377
+ // First event should be execution start
378
+ let first = &events[0];
379
+ assert!(matches!(first, StreamEvent::ExecutionStart { .. }));
380
+
381
+ // Last event should be execution end
382
+ let last = &events[events.len() - 1];
383
+ assert!(matches!(last, StreamEvent::ExecutionEnd { .. }));
384
+ }
385
+
386
+ #[tokio::test]
387
+ async fn test_run_callable_failure_emits_failed_event() {
388
+ let mut runner = DefaultRunner::default_new();
389
+ let callable = MockCallable::failing("test", "error message");
390
+
391
+ let _ = runner.run_callable(&callable, "input").await;
392
+
393
+ // Drain and check collected events
394
+ let events = runner.emitter().drain();
395
+
396
+ // Should have execution start and failed events
397
+ assert!(events.len() >= 2);
398
+
399
+ // Last event should be execution failed
400
+ let last = &events[events.len() - 1];
401
+ assert!(matches!(last, StreamEvent::ExecutionFailed { .. }));
402
+ }
403
+
404
+ // ============ Checkpoint Tests ============
405
+
406
+ #[tokio::test]
407
+ async fn test_runner_save_and_load_checkpoint() {
408
+ let runner = DefaultRunner::default_new();
409
+
410
+ // Save a checkpoint
411
+ let state = NodeState::from_str("test state data");
412
+ let checkpoint = runner.save_checkpoint(state, Some("node1")).await.unwrap();
413
+
414
+ assert_eq!(checkpoint.current_node.as_ref().unwrap(), "node1");
415
+
416
+ // Load the checkpoint
417
+ let loaded = runner.load_checkpoint().await.unwrap();
418
+ assert!(loaded.is_some());
419
+
420
+ let loaded = loaded.unwrap();
421
+ assert_eq!(loaded.state, serde_json::Value::String("test state data".to_string()));
422
+ }
423
+
424
+ #[tokio::test]
425
+ async fn test_runner_checkpoint_without_node() {
426
+ let runner = DefaultRunner::default_new();
427
+
428
+ let state = NodeState::from_str("some data");
429
+ let checkpoint = runner.save_checkpoint(state, None).await.unwrap();
430
+
431
+ assert!(checkpoint.current_node.is_none());
432
+ }
433
+
434
+ #[tokio::test]
435
+ async fn test_runner_load_checkpoint_no_data() {
436
+ let runner = DefaultRunner::default_new();
437
+
438
+ // Without saving, load should return None
439
+ let loaded = runner.load_checkpoint().await.unwrap();
440
+ assert!(loaded.is_none());
441
+ }
442
+
443
+ // ============ Emitter Tests ============
444
+
445
+ #[test]
446
+ fn test_runner_emitter_access() {
447
+ let runner = DefaultRunner::default_new();
448
+ let emitter = runner.emitter();
449
+
450
+ // Should be able to emit and drain events
451
+ emitter.emit(StreamEvent::execution_start(runner.execution_id()));
452
+ let events = emitter.drain();
453
+ assert_eq!(events.len(), 1);
454
+ }
455
+
456
+ #[test]
457
+ fn test_emitter_mode() {
458
+ use crate::streaming::StreamMode;
459
+
460
+ let runner = DefaultRunner::default_new();
461
+ let emitter = runner.emitter();
462
+
463
+ // Default mode should be Full
464
+ assert_eq!(emitter.mode(), StreamMode::Full);
465
+ }
466
+
467
+ // ============ Deprecated API Tests ============
468
+
469
+ #[test]
470
+ #[allow(deprecated)]
471
+ fn test_runner_run_id_deprecated() {
472
+ let runner = DefaultRunner::default_new();
473
+ // run_id should return same as execution_id
474
+ assert_eq!(runner.run_id().as_str(), runner.execution_id().as_str());
475
+ }
476
+ }
@@ -0,0 +1,117 @@
1
+ //! Agentic Loop implementation
2
+ //!
3
+ //! The core loop that drives long-running executions.
4
+ //! It handles the "Discovery -> Execute -> Repeat" cycle.
5
+
6
+ use crate::callable::{Callable, DynCallable};
7
+ use crate::graph::CheckpointStore;
8
+ use crate::policy::LongRunningExecutionPolicy;
9
+ use crate::runner::Runner;
10
+ use crate::streaming::StreamEvent;
11
+ use std::time::{Duration, Instant};
12
+
13
+ /// The agentic loop driver
14
+ #[allow(dead_code)]
15
+ pub struct AgenticLoop;
16
+
17
+ #[allow(dead_code)]
18
+ impl AgenticLoop {
19
+ /// Run the agentic loop for a callable
20
+ pub async fn run<S: CheckpointStore>(
21
+ runner: &mut Runner<S>,
22
+ callable: DynCallable,
23
+ input: String,
24
+ policy: LongRunningExecutionPolicy,
25
+ ) -> anyhow::Result<String> {
26
+ // Initial setup
27
+ let start_time = Instant::now();
28
+ let mut steps_executed = 0;
29
+ let mut _tokens_used = 0;
30
+ let mut history: Vec<String> = Vec::new();
31
+
32
+ // Push initial input
33
+ history.push(format!("User: {}", input));
34
+
35
+ // Initial execution
36
+ let current_input = input.clone();
37
+ let current_callable = callable;
38
+
39
+ // Main Loop
40
+ loop {
41
+ // 1. Check Limits (simplified for now, full enforcement in kernel/enforcement.rs)
42
+ if let Some(max_steps) = policy.max_discovered_steps {
43
+ if steps_executed > max_steps {
44
+ runner.emitter().emit(StreamEvent::execution_failed(
45
+ runner.execution_id(),
46
+ crate::kernel::ExecutionError::quota_exceeded("Max steps exceeded"),
47
+ ));
48
+ anyhow::bail!("Max steps exceeded");
49
+ }
50
+ }
51
+
52
+ if let Some(timeout) = policy.idle_timeout_seconds {
53
+ if start_time.elapsed() > Duration::from_secs(timeout) {
54
+ runner.emitter().emit(StreamEvent::execution_failed(
55
+ runner.execution_id(),
56
+ crate::kernel::ExecutionError::timeout(format!(
57
+ "Idle timeout after {}s",
58
+ timeout
59
+ )),
60
+ ));
61
+ anyhow::bail!("Idle timeout");
62
+ }
63
+ }
64
+
65
+ // 2. Execute Step
66
+ let result = runner
67
+ .run_callable(current_callable.as_ref() as &dyn Callable, &current_input)
68
+ .await;
69
+
70
+ match result {
71
+ Ok(output) => {
72
+ history.push(format!("Assistant: {}", output));
73
+ steps_executed += 1;
74
+
75
+ // 3. Check for Checkpoint
76
+ if policy.checkpointing.on_discovery
77
+ || policy
78
+ .checkpointing
79
+ .interval_steps
80
+ .map_or(false, |i| steps_executed % i == 0)
81
+ {
82
+ // Create a checkpoint state (simplified)
83
+ let state = crate::graph::NodeState::from_str(&output);
84
+ if let Err(e) = runner
85
+ .save_checkpoint(state, Some(current_callable.name()))
86
+ .await
87
+ {
88
+ // Log warning but continue?
89
+ eprintln!("Failed to save checkpoint: {}", e);
90
+ }
91
+ }
92
+
93
+ // 4. Determine Next Step (Discovery)
94
+ // In a real agentic DAG, the output might contain instructions to run more tools
95
+ // or discover new steps. For this v0 implementation, we check if the callable
96
+ // returned a "DONE" signal or if it's a single-shot callable.
97
+
98
+ // TODO: Parse output for discovered steps if this is a DiscoveryAgent
99
+ // For now, we assume simple single-turn or limited loop
100
+
101
+ // IF output suggests more work, continue.
102
+ // IF output suggests completion, break.
103
+
104
+ // Simple heuristic for now: if it's just a generic callable, run once.
105
+ // If we want a loop, we'd need a "LoopCallable" wrapper or parsing logic.
106
+ // Given the prompt asks for "loop for long running executions", we implement
107
+ // the framework here but defaults to single pass unless discovered steps are found.
108
+
109
+ // (Placeholder for proper Discovery logic which would be in the Callable result)
110
+
111
+ return Ok(output);
112
+ }
113
+ Err(e) => return Err(e),
114
+ }
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,58 @@
1
+ //! Runner module - thin execution shell
2
+ //!
3
+ //! The runner is a thin orchestration layer that:
4
+ //! - Accepts invocations
5
+ //! - Passes to Kernel
6
+ //! - Wires callbacks
7
+ //! - Returns streams
8
+ //!
9
+ //! Core execution logic lives in the kernel module.
10
+ //! Context types are in the context module.
11
+ //!
12
+ //! ## CRITICAL INVARIANT: Runner Never Mutates State
13
+ //!
14
+ //! Runner is a thin orchestration shell. All execution semantics live in kernel/.
15
+ //!
16
+ //! Runner MUST NOT:
17
+ //! - Mutate execution state directly
18
+ //! - Retry steps (kernel handles retries)
19
+ //! - Handle backoff (kernel handles backoff)
20
+ //! - Skip nodes (kernel handles node execution)
21
+ //!
22
+ //! If Runner starts doing these things → duplicated kernel logic (architectural leak).
23
+ //!
24
+ //! **What Runner Does:**
25
+ //! - Wires services (session, memory, artifacts)
26
+ //! - Handles callbacks (before/after hooks)
27
+ //! - Delegates execution to ExecutionKernel
28
+ //! - Streams events to clients
29
+ //!
30
+ //! **What Runner Does NOT Do:**
31
+ //! - Mutate execution state directly
32
+ //! - Implement execution semantics
33
+ //! - Make policy decisions
34
+ //!
35
+ //! @see docs/TECHNICAL/01-EXECUTION-TELEMETRY.md
36
+ //! @see docs/TECHNICAL/25-STREAM-PROCESSORS.md
37
+
38
+ mod callbacks;
39
+ mod execution_runner;
40
+ mod r#loop;
41
+ mod protected_runner;
42
+
43
+ // Runner types
44
+ pub use execution_runner::{DefaultRunner, Runner};
45
+
46
+ // Protected runner (feat-09: Guardrails)
47
+ pub use protected_runner::{DefaultProtectedRunner, InputBlockedError, ProtectedRunner};
48
+
49
+ // Re-export from kernel (kernel owns parallel/interrupt logic)
50
+ pub use crate::kernel::{
51
+ run_parallel, InterruptDecision, InterruptReason, InterruptableRunner, ParallelResult,
52
+ };
53
+
54
+ // Re-export from context
55
+ pub use crate::context::{
56
+ InvocationContext, InvocationServices, ResourceLimits, RuntimeContext, RuntimeContextBuilder,
57
+ SessionContext, TraceContext,
58
+ };