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.
- package/.env.example +20 -0
- package/.github/workflows/ci.yml +70 -0
- package/.github/workflows/publish.yml +250 -0
- package/.gitmodules +3 -0
- package/Cargo.lock +3584 -0
- package/Cargo.toml +97 -0
- package/crates/enact/Cargo.toml +27 -0
- package/crates/enact/src/lib.rs +60 -0
- package/crates/enact-a2a/Cargo.toml +25 -0
- package/crates/enact-a2a/src/lib.rs +411 -0
- package/crates/enact-channels/Cargo.toml +64 -0
- package/crates/enact-channels/examples/README.md +80 -0
- package/crates/enact-channels/examples/channel_bot.rs +169 -0
- package/crates/enact-channels/examples/telegram-echo.rs +34 -0
- package/crates/enact-channels/examples/whatsapp-echo.rs +142 -0
- package/crates/enact-channels/src/config.rs +213 -0
- package/crates/enact-channels/src/lib.rs +25 -0
- package/crates/enact-channels/src/runtime.rs +237 -0
- package/crates/enact-channels/src/security/mod.rs +5 -0
- package/crates/enact-channels/src/security/pairing.rs +205 -0
- package/crates/enact-channels/src/teams.rs +601 -0
- package/crates/enact-channels/src/telegram.rs +2833 -0
- package/crates/enact-channels/src/traits.rs +200 -0
- package/crates/enact-channels/src/webhook.rs +262 -0
- package/crates/enact-channels/src/whatsapp.rs +310 -0
- package/crates/enact-cli/Cargo.toml +40 -0
- package/crates/enact-cli/src/commands/doctor.rs +62 -0
- package/crates/enact-cli/src/commands/mod.rs +3 -0
- package/crates/enact-cli/src/commands/run.rs +69 -0
- package/crates/enact-cli/src/commands/serve.rs +81 -0
- package/crates/enact-cli/src/config.rs +2 -0
- package/crates/enact-cli/src/main.rs +79 -0
- package/crates/enact-config/Cargo.toml +36 -0
- package/crates/enact-config/ENV_VAR_MAPPING.md +135 -0
- package/crates/enact-config/QUICK_REFERENCE.md +92 -0
- package/crates/enact-config/README.md +107 -0
- package/crates/enact-config/TESTING.md +161 -0
- package/crates/enact-config/examples/test-env-vars.rs +100 -0
- package/crates/enact-config/src/config.rs +399 -0
- package/crates/enact-config/src/encrypted_store.rs +211 -0
- package/crates/enact-config/src/lib.rs +298 -0
- package/crates/enact-config/src/secrets.rs +149 -0
- package/crates/enact-config/src/sync.rs +260 -0
- package/crates/enact-config/test-env-vars.sh +34 -0
- package/crates/enact-config/tests/README.md +99 -0
- package/crates/enact-config/tests/config_integration_test.rs +202 -0
- package/crates/enact-config/tests/security_test.rs +140 -0
- package/crates/enact-context/Cargo.toml +41 -0
- package/crates/enact-context/src/budget.rs +314 -0
- package/crates/enact-context/src/calibrator.rs +535 -0
- package/crates/enact-context/src/compactor.rs +392 -0
- package/crates/enact-context/src/condenser.rs +826 -0
- package/crates/enact-context/src/lib.rs +94 -0
- package/crates/enact-context/src/segment.rs +238 -0
- package/crates/enact-context/src/step_context.rs +645 -0
- package/crates/enact-context/src/token_counter.rs +148 -0
- package/crates/enact-context/src/window.rs +372 -0
- package/crates/enact-core/Cargo.toml +42 -0
- package/crates/enact-core/README.md +98 -0
- package/crates/enact-core/src/background/executor.rs +524 -0
- package/crates/enact-core/src/background/mod.rs +48 -0
- package/crates/enact-core/src/background/target_binding.rs +390 -0
- package/crates/enact-core/src/background/trigger.rs +511 -0
- package/crates/enact-core/src/callable/callable.rs +152 -0
- package/crates/enact-core/src/callable/composite.rs +817 -0
- package/crates/enact-core/src/callable/graph.rs +104 -0
- package/crates/enact-core/src/callable/llm.rs +211 -0
- package/crates/enact-core/src/callable/mod.rs +64 -0
- package/crates/enact-core/src/callable/registry.rs +206 -0
- package/crates/enact-core/src/context/execution_context.rs +757 -0
- package/crates/enact-core/src/context/invocation.rs +99 -0
- package/crates/enact-core/src/context/mod.rs +50 -0
- package/crates/enact-core/src/context/tenant.rs +175 -0
- package/crates/enact-core/src/context/trace.rs +127 -0
- package/crates/enact-core/src/flow/conditional.rs +293 -0
- package/crates/enact-core/src/flow/mod.rs +43 -0
- package/crates/enact-core/src/flow/parallel.rs +437 -0
- package/crates/enact-core/src/flow/repeat.rs +534 -0
- package/crates/enact-core/src/flow/sequential.rs +248 -0
- package/crates/enact-core/src/graph/checkpoint.rs +79 -0
- package/crates/enact-core/src/graph/checkpoint_store.rs +76 -0
- package/crates/enact-core/src/graph/compiled.rs +189 -0
- package/crates/enact-core/src/graph/edge.rs +59 -0
- package/crates/enact-core/src/graph/graph_schema.rs +218 -0
- package/crates/enact-core/src/graph/loader.rs +155 -0
- package/crates/enact-core/src/graph/mod.rs +18 -0
- package/crates/enact-core/src/graph/node/function.rs +49 -0
- package/crates/enact-core/src/graph/node/mod.rs +48 -0
- package/crates/enact-core/src/graph/schema.rs +62 -0
- package/crates/enact-core/src/inbox/message.rs +405 -0
- package/crates/enact-core/src/inbox/mod.rs +31 -0
- package/crates/enact-core/src/inbox/store.rs +355 -0
- package/crates/enact-core/src/kernel/artifact/filesystem.rs +546 -0
- package/crates/enact-core/src/kernel/artifact/metadata.rs +283 -0
- package/crates/enact-core/src/kernel/artifact/mod.rs +27 -0
- package/crates/enact-core/src/kernel/artifact/store.rs +427 -0
- package/crates/enact-core/src/kernel/enforcement.rs +1315 -0
- package/crates/enact-core/src/kernel/error.rs +1200 -0
- package/crates/enact-core/src/kernel/event.rs +1394 -0
- package/crates/enact-core/src/kernel/execution_model.rs +831 -0
- package/crates/enact-core/src/kernel/execution_state.rs +189 -0
- package/crates/enact-core/src/kernel/execution_strategy.rs +117 -0
- package/crates/enact-core/src/kernel/ids.rs +2086 -0
- package/crates/enact-core/src/kernel/interrupt.rs +125 -0
- package/crates/enact-core/src/kernel/kernel.rs +1283 -0
- package/crates/enact-core/src/kernel/mod.rs +205 -0
- package/crates/enact-core/src/kernel/persistence/event_store.rs +270 -0
- package/crates/enact-core/src/kernel/persistence/message_store.rs +908 -0
- package/crates/enact-core/src/kernel/persistence/mod.rs +102 -0
- package/crates/enact-core/src/kernel/persistence/state_store.rs +228 -0
- package/crates/enact-core/src/kernel/persistence/vector_store.rs +299 -0
- package/crates/enact-core/src/kernel/reducer.rs +808 -0
- package/crates/enact-core/src/kernel/replay.rs +153 -0
- package/crates/enact-core/src/lib.rs +413 -0
- package/crates/enact-core/src/memory/episodic.rs +0 -0
- package/crates/enact-core/src/memory/mod.rs +6 -0
- package/crates/enact-core/src/memory/semantic.rs +0 -0
- package/crates/enact-core/src/memory/trait.rs +0 -0
- package/crates/enact-core/src/memory/vector_db.rs +0 -0
- package/crates/enact-core/src/memory/working.rs +0 -0
- package/crates/enact-core/src/policy/execution_policy.rs +292 -0
- package/crates/enact-core/src/policy/filters.rs +458 -0
- package/crates/enact-core/src/policy/input_processor.rs +407 -0
- package/crates/enact-core/src/policy/long_running.rs +134 -0
- package/crates/enact-core/src/policy/mod.rs +193 -0
- package/crates/enact-core/src/policy/pii_input.rs +274 -0
- package/crates/enact-core/src/policy/tenant_policy.rs +453 -0
- package/crates/enact-core/src/policy/tool_policy.rs +407 -0
- package/crates/enact-core/src/providers/mod.rs +63 -0
- package/crates/enact-core/src/providers/trait.rs +292 -0
- package/crates/enact-core/src/runner/callbacks.rs +6 -0
- package/crates/enact-core/src/runner/execution_runner.rs +476 -0
- package/crates/enact-core/src/runner/loop.rs +117 -0
- package/crates/enact-core/src/runner/mod.rs +58 -0
- package/crates/enact-core/src/runner/protected_runner.rs +280 -0
- package/crates/enact-core/src/signal/inmemory.rs +231 -0
- package/crates/enact-core/src/signal/mod.rs +108 -0
- package/crates/enact-core/src/streaming/event_logger.rs +195 -0
- package/crates/enact-core/src/streaming/event_stream.rs +1423 -0
- package/crates/enact-core/src/streaming/mod.rs +108 -0
- package/crates/enact-core/src/streaming/pause_cancel.rs +0 -0
- package/crates/enact-core/src/streaming/protected_emitter.rs +173 -0
- package/crates/enact-core/src/streaming/protection/context.rs +136 -0
- package/crates/enact-core/src/streaming/protection/encryption.rs +289 -0
- package/crates/enact-core/src/streaming/protection/mod.rs +43 -0
- package/crates/enact-core/src/streaming/protection/pii_protection.rs +243 -0
- package/crates/enact-core/src/streaming/protection/processor.rs +166 -0
- package/crates/enact-core/src/streaming/sse.rs +0 -0
- package/crates/enact-core/src/telemetry/exporter.rs +0 -0
- package/crates/enact-core/src/telemetry/init.rs +0 -0
- package/crates/enact-core/src/telemetry/mod.rs +49 -0
- package/crates/enact-core/src/telemetry/spans.rs +245 -0
- package/crates/enact-core/src/tool/agent_tool.rs +177 -0
- package/crates/enact-core/src/tool/browser/mod.rs +0 -0
- package/crates/enact-core/src/tool/browser/webdriver.rs +0 -0
- package/crates/enact-core/src/tool/cost.rs +247 -0
- package/crates/enact-core/src/tool/discovery.rs +0 -0
- package/crates/enact-core/src/tool/dispatcher.rs +347 -0
- package/crates/enact-core/src/tool/filesystem.rs +231 -0
- package/crates/enact-core/src/tool/function.rs +99 -0
- package/crates/enact-core/src/tool/git.rs +162 -0
- package/crates/enact-core/src/tool/http.rs +214 -0
- package/crates/enact-core/src/tool/mcp/client.rs +0 -0
- package/crates/enact-core/src/tool/mcp/mod.rs +0 -0
- package/crates/enact-core/src/tool/mod.rs +51 -0
- package/crates/enact-core/src/tool/reasoning/debugging.rs +0 -0
- package/crates/enact-core/src/tool/reasoning/mcts.rs +0 -0
- package/crates/enact-core/src/tool/reasoning/mod.rs +0 -0
- package/crates/enact-core/src/tool/reasoning/sequential.rs +0 -0
- package/crates/enact-core/src/tool/sandbox/dagger.rs +0 -0
- package/crates/enact-core/src/tool/sandbox/mod.rs +0 -0
- package/crates/enact-core/src/tool/shell.rs +147 -0
- package/crates/enact-core/src/tool/trait.rs +33 -0
- package/crates/enact-core/src/tool/web_search.rs +277 -0
- package/crates/enact-core/src/util/config.rs +0 -0
- package/crates/enact-core/src/util/errors.rs +0 -0
- package/crates/enact-core/src/util/mod.rs +6 -0
- package/crates/enact-core/tests/airgapped_e2e_test.rs +291 -0
- package/crates/enact-core/tests/e2e_agentic_loop.rs +119 -0
- package/crates/enact-core/tests/e2e_test.rs +259 -0
- package/crates/enact-core/tests/graph_test.rs +130 -0
- package/crates/enact-core/tests/stream_event_id_validation.rs +435 -0
- package/crates/enact-cron/Cargo.toml +28 -0
- package/crates/enact-cron/src/lib.rs +44 -0
- package/crates/enact-cron/src/schedule.rs +156 -0
- package/crates/enact-cron/src/store.rs +589 -0
- package/crates/enact-cron/src/types.rs +148 -0
- package/crates/enact-gateway/Cargo.toml +31 -0
- package/crates/enact-gateway/README.md +30 -0
- package/crates/enact-gateway/examples/whatsapp-gateway-runner-mock.rs +59 -0
- package/crates/enact-gateway/examples/whatsapp-gateway.rs +42 -0
- package/crates/enact-gateway/src/lib.rs +582 -0
- package/crates/enact-mcp/Cargo.toml +24 -0
- package/crates/enact-mcp/src/lib.rs +178 -0
- package/crates/enact-memory/Cargo.toml +25 -0
- package/crates/enact-memory/src/backend.rs +20 -0
- package/crates/enact-memory/src/chunker.rs +230 -0
- package/crates/enact-memory/src/embeddings.rs +221 -0
- package/crates/enact-memory/src/lib.rs +67 -0
- package/crates/enact-memory/src/markdown.rs +127 -0
- package/crates/enact-memory/src/none.rs +61 -0
- package/crates/enact-memory/src/sqlite.rs +276 -0
- package/crates/enact-memory/src/traits.rs +65 -0
- package/crates/enact-memory/src/vector.rs +198 -0
- package/crates/enact-oauth/Cargo.toml +27 -0
- package/crates/enact-oauth/src/lib.rs +584 -0
- package/crates/enact-observability/Cargo.toml +22 -0
- package/crates/enact-observability/src/lib.rs +197 -0
- package/crates/enact-providers/Cargo.toml +33 -0
- package/crates/enact-providers/examples/hello-agent.rs +33 -0
- package/crates/enact-providers/src/anthropic.rs +182 -0
- package/crates/enact-providers/src/azure.rs +96 -0
- package/crates/enact-providers/src/bridge.rs +221 -0
- package/crates/enact-providers/src/gemini.rs +227 -0
- package/crates/enact-providers/src/http.rs +78 -0
- package/crates/enact-providers/src/lib.rs +53 -0
- package/crates/enact-providers/src/openai_compatible.rs +167 -0
- package/crates/enact-providers/src/openrouter.rs +33 -0
- package/crates/enact-runner/Cargo.toml +24 -0
- package/crates/enact-runner/README.md +76 -0
- package/crates/enact-runner/src/compaction.rs +225 -0
- package/crates/enact-runner/src/config.rs +118 -0
- package/crates/enact-runner/src/lib.rs +63 -0
- package/crates/enact-runner/src/loop_driver.rs +414 -0
- package/crates/enact-runner/src/parser.rs +421 -0
- package/crates/enact-runner/src/retry.rs +262 -0
- package/crates/enact-runner/tests/integration.rs +278 -0
- package/crates/enact-security/Cargo.toml +22 -0
- package/crates/enact-security/src/audit.rs +375 -0
- package/crates/enact-security/src/lib.rs +37 -0
- package/crates/enact-security/src/policy.rs +406 -0
- package/crates/enact-skills/Cargo.toml +25 -0
- package/crates/enact-skills/src/lib.rs +506 -0
- package/crates/enact-tools/Cargo.toml +22 -0
- package/crates/enact-tools/src/file_read.rs +166 -0
- package/crates/enact-tools/src/file_write.rs +216 -0
- package/crates/enact-tools/src/git_operations.rs +513 -0
- package/crates/enact-tools/src/http_request.rs +417 -0
- package/crates/enact-tools/src/lib.rs +104 -0
- package/crates/enact-tools/src/security.rs +227 -0
- package/crates/enact-tools/src/shell.rs +191 -0
- package/crates/enact-tools/src/traits.rs +159 -0
- package/docs/Makefile +74 -0
- package/docs/config.toml +62 -0
- package/docs/content/_index.md +174 -0
- package/docs/content/a2a/_index.md +431 -0
- package/docs/content/api/_index.md +323 -0
- package/docs/content/channels/_index.md +160 -0
- package/docs/content/channels/teams.md +205 -0
- package/docs/content/channels/telegram.md +182 -0
- package/docs/content/channels/webhook.md +423 -0
- package/docs/content/channels/whatsapp.md +240 -0
- package/docs/content/cli/_index.md +261 -0
- package/docs/content/concepts/_index.md +273 -0
- package/docs/content/configuration/_index.md +241 -0
- package/docs/content/cron/_index.md +248 -0
- package/docs/content/developers/_index.md +278 -0
- package/docs/content/getting-started/_index.md +180 -0
- package/docs/content/installation/_index.md +186 -0
- package/docs/content/installation/uninstall.md +101 -0
- package/docs/content/installation/updating.md +120 -0
- package/docs/content/mcp/_index.md +215 -0
- package/docs/content/memory/_index.md +163 -0
- package/docs/content/oauth/_index.md +515 -0
- package/docs/content/providers/_index.md +206 -0
- package/docs/content/roadmap/_index.md +199 -0
- package/docs/content/security/_index.md +219 -0
- package/docs/content/skills/_index.md +228 -0
- package/docs/content/tools/_index.md +485 -0
- package/docs/content/troubleshooting/_index.md +259 -0
- package/docs/content/yaml-schema/_index.md +294 -0
- package/docs/static/giallo-dark.css +91 -0
- package/docs/static/giallo-light.css +91 -0
- package/docs/themes/tanuki/.github/workflows/deploy.yml +44 -0
- package/docs/themes/tanuki/LICENSE +21 -0
- package/docs/themes/tanuki/README.md +166 -0
- package/docs/themes/tanuki/examples/blog/config.toml +58 -0
- package/docs/themes/tanuki/examples/blog/content/_index.md +4 -0
- package/docs/themes/tanuki/examples/blog/content/about.md +33 -0
- package/docs/themes/tanuki/examples/blog/content/blog/_index.md +7 -0
- package/docs/themes/tanuki/examples/blog/content/blog/api-design-best-practices.md +245 -0
- package/docs/themes/tanuki/examples/blog/content/blog/building-accessible-websites.md +147 -0
- package/docs/themes/tanuki/examples/blog/content/blog/css-grid-vs-flexbox.md +165 -0
- package/docs/themes/tanuki/examples/blog/content/blog/customizing-catppuccin-colors.md +137 -0
- package/docs/themes/tanuki/examples/blog/content/blog/dark-mode-best-practices.md +82 -0
- package/docs/themes/tanuki/examples/blog/content/blog/docker-essentials.md +301 -0
- package/docs/themes/tanuki/examples/blog/content/blog/getting-started-with-zola.md +129 -0
- package/docs/themes/tanuki/examples/blog/content/blog/git-workflow-for-content.md +112 -0
- package/docs/themes/tanuki/examples/blog/content/blog/introduction-to-webassembly.md +183 -0
- package/docs/themes/tanuki/examples/blog/content/blog/modern-javascript-features.md +234 -0
- package/docs/themes/tanuki/examples/blog/content/blog/testing-strategies.md +311 -0
- package/docs/themes/tanuki/examples/blog/content/blog/typography-for-developers.md +104 -0
- package/docs/themes/tanuki/examples/blog/content/blog/welcome-to-tanuki.md +67 -0
- package/docs/themes/tanuki/examples/blog/content/blog/why-static-sites.md +85 -0
- package/docs/themes/tanuki/examples/blog/content/projects.md +64 -0
- package/docs/themes/tanuki/examples/book/config.toml +17 -0
- package/docs/themes/tanuki/examples/book/content/_index.md +12 -0
- package/docs/themes/tanuki/examples/book/content/chapter-1.md +90 -0
- package/docs/themes/tanuki/examples/book/content/chapter-2.md +143 -0
- package/docs/themes/tanuki/examples/book/content/chapter-3.md +217 -0
- package/docs/themes/tanuki/examples/book/content/chapter-4.md +224 -0
- package/docs/themes/tanuki/examples/book/content/chapter-5.md +297 -0
- package/docs/themes/tanuki/examples/book/content/print.md +6 -0
- package/docs/themes/tanuki/examples/docs/config.toml +28 -0
- package/docs/themes/tanuki/examples/docs/content/_index.md +20 -0
- package/docs/themes/tanuki/examples/docs/content/components.md +156 -0
- package/docs/themes/tanuki/examples/docs/content/configuration.md +94 -0
- package/docs/themes/tanuki/examples/docs/content/customization.md +202 -0
- package/docs/themes/tanuki/examples/docs/content/deployment.md +204 -0
- package/docs/themes/tanuki/examples/docs/content/installation.md +59 -0
- package/docs/themes/tanuki/examples/docs/content/print.md +6 -0
- package/docs/themes/tanuki/examples/docs/static/img/tanuki-icon.avif +0 -0
- package/docs/themes/tanuki/examples/index.html +2104 -0
- package/docs/themes/tanuki/mise.toml +108 -0
- package/docs/themes/tanuki/sass/base/_catppuccin.scss +164 -0
- package/docs/themes/tanuki/sass/base/_fonts.scss +64 -0
- package/docs/themes/tanuki/sass/base/_reset.scss +152 -0
- package/docs/themes/tanuki/sass/base/_typography.scss +523 -0
- package/docs/themes/tanuki/sass/components/_buttons.scss +209 -0
- package/docs/themes/tanuki/sass/components/_code.scss +457 -0
- package/docs/themes/tanuki/sass/components/_landing.scss +633 -0
- package/docs/themes/tanuki/sass/components/_layout.scss +294 -0
- package/docs/themes/tanuki/sass/components/_navigation.scss +1200 -0
- package/docs/themes/tanuki/sass/components/_print.scss +237 -0
- package/docs/themes/tanuki/sass/components/_search.scss +224 -0
- package/docs/themes/tanuki/sass/components/_sidebar.scss +473 -0
- package/docs/themes/tanuki/sass/components/_theme-toggle.scss +186 -0
- package/docs/themes/tanuki/sass/modes/_blog.scss +366 -0
- package/docs/themes/tanuki/sass/modes/_product.scss +875 -0
- package/docs/themes/tanuki/sass/modes/_raskell.scss +1696 -0
- package/docs/themes/tanuki/sass/patterns/_buttons.scss +183 -0
- package/docs/themes/tanuki/sass/patterns/_cards.scss +144 -0
- package/docs/themes/tanuki/sass/patterns/_index.scss +9 -0
- package/docs/themes/tanuki/sass/patterns/_lists.scss +259 -0
- package/docs/themes/tanuki/sass/patterns/_sections.scss +243 -0
- package/docs/themes/tanuki/sass/style.scss +47 -0
- package/docs/themes/tanuki/sass/tokens/_colors.scss +139 -0
- package/docs/themes/tanuki/sass/tokens/_spacing.scss +100 -0
- package/docs/themes/tanuki/sass/tokens/_typography.scss +186 -0
- package/docs/themes/tanuki/screenshot.png +0 -0
- package/docs/themes/tanuki/sentinel.kdl +59 -0
- package/docs/themes/tanuki/static/elasticlunr.min.js +10 -0
- package/docs/themes/tanuki/static/fonts/GEIST-LICENSE.txt +92 -0
- package/docs/themes/tanuki/static/fonts/Geist-Variable.woff2 +0 -0
- package/docs/themes/tanuki/static/fonts/GeistMono-Variable.woff2 +0 -0
- package/docs/themes/tanuki/static/img/tanuki-icon.avif +0 -0
- package/docs/themes/tanuki/static/img/tanuki-icon.png +0 -0
- package/docs/themes/tanuki/static/js/anchors.js +18 -0
- package/docs/themes/tanuki/static/js/app.js +274 -0
- package/docs/themes/tanuki/static/js/code.js +394 -0
- package/docs/themes/tanuki/static/js/navigation.js +778 -0
- package/docs/themes/tanuki/static/js/scroll-to-top.js +33 -0
- package/docs/themes/tanuki/static/js/search-raskell.js +240 -0
- package/docs/themes/tanuki/static/js/search.js +215 -0
- package/docs/themes/tanuki/static/js/theme.js +169 -0
- package/docs/themes/tanuki/static/syntax-dark.css +151 -0
- package/docs/themes/tanuki/static/syntax-light.css +151 -0
- package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm.js +486 -0
- package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm_bg.wasm +0 -0
- package/docs/themes/tanuki/templates/404.html +52 -0
- package/docs/themes/tanuki/templates/base.html +428 -0
- package/docs/themes/tanuki/templates/blog.html +66 -0
- package/docs/themes/tanuki/templates/home.html +108 -0
- package/docs/themes/tanuki/templates/index.html +178 -0
- package/docs/themes/tanuki/templates/landing.html +168 -0
- package/docs/themes/tanuki/templates/macros/nav.html +128 -0
- package/docs/themes/tanuki/templates/macros/posts.html +101 -0
- package/docs/themes/tanuki/templates/macros/ui.html +159 -0
- package/docs/themes/tanuki/templates/page.html +135 -0
- package/docs/themes/tanuki/templates/partials/footer.html +38 -0
- package/docs/themes/tanuki/templates/partials/header.html +366 -0
- package/docs/themes/tanuki/templates/partials/nav-buttons.html +55 -0
- package/docs/themes/tanuki/templates/partials/nav-overlay.html +81 -0
- package/docs/themes/tanuki/templates/partials/page-toc-panel.html +43 -0
- package/docs/themes/tanuki/templates/partials/search.html +52 -0
- package/docs/themes/tanuki/templates/partials/sidebar.html +107 -0
- package/docs/themes/tanuki/templates/partials/theme-toggle.html +35 -0
- package/docs/themes/tanuki/templates/partials/toc-overlay.html +146 -0
- package/docs/themes/tanuki/templates/partials/version-picker.html +38 -0
- package/docs/themes/tanuki/templates/print.html +244 -0
- package/docs/themes/tanuki/templates/section.html +186 -0
- package/docs/themes/tanuki/templates/taxonomy_list.html +18 -0
- package/docs/themes/tanuki/templates/taxonomy_single.html +31 -0
- package/docs/themes/tanuki/theme.toml +58 -0
- package/examples/hello-agent.rs +55 -0
- package/package.json +36 -0
- package/proto/config.proto +60 -0
- package/proto/events.proto +0 -0
- package/proto/runtime.proto +215 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//! enact-runner — The Robust Agent Loop for Enact
|
|
2
|
+
//!
|
|
3
|
+
//! This crate fills the gap between `enact-core`'s deterministic kernel and the
|
|
4
|
+
//! applications (CLI, API) that assume the Rust layer handles retries, context
|
|
5
|
+
//! compaction, and multi-format tool call parsing.
|
|
6
|
+
//!
|
|
7
|
+
//! ## Architecture
|
|
8
|
+
//!
|
|
9
|
+
//! ```text
|
|
10
|
+
//! ┌─────────────────────────────────────────────────────┐
|
|
11
|
+
//! │ CLI / API / Web (thin clients) │
|
|
12
|
+
//! └──────────────────────┬──────────────────────────────┘
|
|
13
|
+
//! │ Execution Intent
|
|
14
|
+
//! ▼
|
|
15
|
+
//! ┌─────────────────────────────────────────────────────┐
|
|
16
|
+
//! │ enact-runner (THIS CRATE) │
|
|
17
|
+
//! │ ┌─────────────────────────────────────────────┐ │
|
|
18
|
+
//! │ │ AgentRunner::run() │ │
|
|
19
|
+
//! │ │ • Multi-iteration tool call loop │ │
|
|
20
|
+
//! │ │ • Retry with exponential backoff │ │
|
|
21
|
+
//! │ │ • Auto context compaction │ │
|
|
22
|
+
//! │ │ • Multi-format parsing (JSON/XML/MD) │ │
|
|
23
|
+
//! │ │ • Checkpoint at intervals │ │
|
|
24
|
+
//! │ │ • Stream event emission │ │
|
|
25
|
+
//! │ └─────────────────────────────────────────────┘ │
|
|
26
|
+
//! └──────────────────────┬──────────────────────────────┘
|
|
27
|
+
//! │ Callable::run()
|
|
28
|
+
//! ▼
|
|
29
|
+
//! ┌─────────────────────────────────────────────────────┐
|
|
30
|
+
//! │ enact-core kernel (deterministic DAG engine) │
|
|
31
|
+
//! └─────────────────────────────────────────────────────┘
|
|
32
|
+
//! ```
|
|
33
|
+
//!
|
|
34
|
+
//! ## Quick Start
|
|
35
|
+
//!
|
|
36
|
+
//! ```rust,no_run
|
|
37
|
+
//! use enact_runner::{AgentRunner, RunnerConfig, DefaultAgentRunner};
|
|
38
|
+
//!
|
|
39
|
+
//! # async fn example() -> anyhow::Result<()> {
|
|
40
|
+
//! // Create runner with default config
|
|
41
|
+
//! let mut runner = DefaultAgentRunner::default_new();
|
|
42
|
+
//!
|
|
43
|
+
//! // Or configure for long-running tasks
|
|
44
|
+
//! let mut runner = DefaultAgentRunner::with_config(RunnerConfig::long_running());
|
|
45
|
+
//!
|
|
46
|
+
//! // Run an agent through the robust loop
|
|
47
|
+
//! // let outcome = runner.run(&my_callable, "user input").await?;
|
|
48
|
+
//! # Ok(())
|
|
49
|
+
//! # }
|
|
50
|
+
//! ```
|
|
51
|
+
|
|
52
|
+
pub mod compaction;
|
|
53
|
+
pub mod config;
|
|
54
|
+
pub mod loop_driver;
|
|
55
|
+
pub mod parser;
|
|
56
|
+
pub mod retry;
|
|
57
|
+
|
|
58
|
+
// Re-exports for convenient access
|
|
59
|
+
pub use compaction::HistoryMessage;
|
|
60
|
+
pub use config::{RetryConfig, RunnerConfig};
|
|
61
|
+
pub use loop_driver::{AgentRunner, DefaultAgentRunner, LoopOutcome};
|
|
62
|
+
pub use parser::{ParseResult, ParsedToolCall, ToolCallFormat};
|
|
63
|
+
pub use retry::{classify_error, ErrorKind, RetryHandler};
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
//! Core agent loop driver
|
|
2
|
+
//!
|
|
3
|
+
//! `AgentRunner` is the "missing middle" — the robust loop that sits between
|
|
4
|
+
//! the apps (CLI, API) and the `enact-core` kernel. It implements:
|
|
5
|
+
//!
|
|
6
|
+
//! - Multi-iteration tool call loop (ported from zeroclaw's `run_tool_call_loop`)
|
|
7
|
+
//! - Multi-format tool call parsing (JSON, XML, Markdown)
|
|
8
|
+
//! - Auto context compaction when history grows too large
|
|
9
|
+
//! - Retry with exponential backoff for transient errors
|
|
10
|
+
//! - Checkpoint saving at configured intervals
|
|
11
|
+
//! - Stream event emission throughout
|
|
12
|
+
//!
|
|
13
|
+
//! This fulfills the mandate from `28-TS-RUST-INTEGRATION.md`:
|
|
14
|
+
//! "Rust handles retries/fallbacks" and `27-LONG-RUNNING-EXECUTIONS.md`:
|
|
15
|
+
//! "Unified long-running agentic loop".
|
|
16
|
+
|
|
17
|
+
use crate::compaction::{self, HistoryMessage};
|
|
18
|
+
use crate::config::RunnerConfig;
|
|
19
|
+
use crate::parser;
|
|
20
|
+
use crate::retry::RetryHandler;
|
|
21
|
+
|
|
22
|
+
use enact_core::callable::Callable;
|
|
23
|
+
use enact_core::graph::CheckpointStore;
|
|
24
|
+
use enact_core::kernel::{ExecutionError, StepId, StepType};
|
|
25
|
+
use enact_core::runner::Runner;
|
|
26
|
+
use enact_core::streaming::StreamEvent;
|
|
27
|
+
use enact_core::tool::Tool;
|
|
28
|
+
|
|
29
|
+
use std::sync::Arc;
|
|
30
|
+
use std::time::Instant;
|
|
31
|
+
|
|
32
|
+
/// Outcome of a runner loop execution.
|
|
33
|
+
#[derive(Debug)]
|
|
34
|
+
pub enum LoopOutcome {
|
|
35
|
+
/// The agent produced a final response (no more tool calls).
|
|
36
|
+
Completed(String),
|
|
37
|
+
/// The loop hit the maximum iteration limit.
|
|
38
|
+
MaxIterationsReached {
|
|
39
|
+
last_output: String,
|
|
40
|
+
iterations: usize,
|
|
41
|
+
},
|
|
42
|
+
/// The execution was cancelled externally.
|
|
43
|
+
Cancelled,
|
|
44
|
+
/// The execution exceeded the configured timeout.
|
|
45
|
+
TimedOut {
|
|
46
|
+
elapsed_secs: u64,
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
impl LoopOutcome {
|
|
51
|
+
/// Whether the outcome represents a successful completion.
|
|
52
|
+
pub fn is_completed(&self) -> bool {
|
|
53
|
+
matches!(self, LoopOutcome::Completed(_))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/// Get the final output text, if any.
|
|
57
|
+
pub fn output(&self) -> Option<&str> {
|
|
58
|
+
match self {
|
|
59
|
+
LoopOutcome::Completed(s) => Some(s),
|
|
60
|
+
LoopOutcome::MaxIterationsReached { last_output, .. } => Some(last_output),
|
|
61
|
+
_ => None,
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/// The robust agent runner — drives the tool call loop with retries,
|
|
67
|
+
/// compaction, and multi-format parsing.
|
|
68
|
+
pub struct AgentRunner<S: CheckpointStore> {
|
|
69
|
+
/// The underlying enact-core runner (provides cancel/pause/checkpoint/events)
|
|
70
|
+
runner: Runner<S>,
|
|
71
|
+
/// Configuration for iteration limits, compaction, retries
|
|
72
|
+
config: RunnerConfig,
|
|
73
|
+
/// Registered tools available to the agent
|
|
74
|
+
tools: Vec<Arc<dyn Tool>>,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
impl<S: CheckpointStore> AgentRunner<S> {
|
|
78
|
+
/// Create a new `AgentRunner` wrapping an existing `Runner`.
|
|
79
|
+
pub fn new(runner: Runner<S>, config: RunnerConfig) -> Self {
|
|
80
|
+
Self {
|
|
81
|
+
runner,
|
|
82
|
+
config,
|
|
83
|
+
tools: Vec::new(),
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// Register a tool for use in the loop.
|
|
88
|
+
pub fn add_tool(mut self, tool: impl Tool + 'static) -> Self {
|
|
89
|
+
self.tools.push(Arc::new(tool));
|
|
90
|
+
self
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// Register multiple tools at once.
|
|
94
|
+
pub fn add_tools(mut self, tools: Vec<Arc<dyn Tool>>) -> Self {
|
|
95
|
+
self.tools.extend(tools);
|
|
96
|
+
self
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/// Access the underlying runner.
|
|
100
|
+
pub fn inner(&self) -> &Runner<S> {
|
|
101
|
+
&self.runner
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/// Access the underlying runner mutably.
|
|
105
|
+
pub fn inner_mut(&mut self) -> &mut Runner<S> {
|
|
106
|
+
&mut self.runner
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/// Run the robust agent loop.
|
|
110
|
+
///
|
|
111
|
+
/// This is the core method — it replaces both `AgenticLoop::run` (which was
|
|
112
|
+
/// a skeleton) and `LlmCallable::run` (which had a basic loop but no
|
|
113
|
+
/// retries, compaction, or multi-format parsing).
|
|
114
|
+
///
|
|
115
|
+
/// # Flow
|
|
116
|
+
///
|
|
117
|
+
/// 1. Call the callable with current input
|
|
118
|
+
/// 2. Parse the response for tool calls (JSON → XML → Markdown)
|
|
119
|
+
/// 3. If tool calls found: execute them, append results to history, loop
|
|
120
|
+
/// 4. If no tool calls: return the final response
|
|
121
|
+
/// 5. Throughout: check limits, retry on errors, compact history, checkpoint
|
|
122
|
+
pub async fn run(
|
|
123
|
+
&mut self,
|
|
124
|
+
callable: &dyn Callable,
|
|
125
|
+
input: &str,
|
|
126
|
+
) -> anyhow::Result<LoopOutcome> {
|
|
127
|
+
let start_time = Instant::now();
|
|
128
|
+
let mut retry_handler = RetryHandler::new(self.config.retry.clone());
|
|
129
|
+
|
|
130
|
+
// Build initial history
|
|
131
|
+
let mut history = vec![
|
|
132
|
+
HistoryMessage::user(input),
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
// Emit execution start
|
|
136
|
+
if self.config.emit_events {
|
|
137
|
+
self.runner.emitter().emit(StreamEvent::execution_start(
|
|
138
|
+
self.runner.execution_id(),
|
|
139
|
+
));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
tracing::info!(
|
|
143
|
+
execution_id = %self.runner.execution_id(),
|
|
144
|
+
callable = callable.name(),
|
|
145
|
+
max_iterations = self.config.max_iterations,
|
|
146
|
+
"Starting robust agent loop"
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
let mut last_output = String::new();
|
|
150
|
+
|
|
151
|
+
for iteration in 0..self.config.max_iterations {
|
|
152
|
+
// ── Check cancellation ──
|
|
153
|
+
if self.runner.is_cancelled() {
|
|
154
|
+
tracing::info!("Execution cancelled");
|
|
155
|
+
return Ok(LoopOutcome::Cancelled);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ── Check timeout ──
|
|
159
|
+
let elapsed = start_time.elapsed();
|
|
160
|
+
if elapsed > self.config.max_duration {
|
|
161
|
+
tracing::warn!(
|
|
162
|
+
elapsed_secs = elapsed.as_secs(),
|
|
163
|
+
"Execution timed out"
|
|
164
|
+
);
|
|
165
|
+
return Ok(LoopOutcome::TimedOut {
|
|
166
|
+
elapsed_secs: elapsed.as_secs(),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// ── Wait if paused ──
|
|
171
|
+
while self.runner.is_paused() {
|
|
172
|
+
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
|
173
|
+
if self.runner.is_cancelled() {
|
|
174
|
+
return Ok(LoopOutcome::Cancelled);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ── Build input for this iteration ──
|
|
179
|
+
let current_input = self.build_iteration_input(&history);
|
|
180
|
+
let step_id = StepId::new();
|
|
181
|
+
let step_start = Instant::now();
|
|
182
|
+
|
|
183
|
+
if self.config.emit_events {
|
|
184
|
+
self.runner.emitter().emit(StreamEvent::step_start(
|
|
185
|
+
self.runner.execution_id(),
|
|
186
|
+
&step_id,
|
|
187
|
+
StepType::LlmNode,
|
|
188
|
+
format!("iteration_{}", iteration),
|
|
189
|
+
));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
tracing::debug!(iteration, "Running callable");
|
|
193
|
+
|
|
194
|
+
// ── Call the LLM ──
|
|
195
|
+
let response = match callable.run(¤t_input).await {
|
|
196
|
+
Ok(output) => {
|
|
197
|
+
retry_handler.reset();
|
|
198
|
+
output
|
|
199
|
+
}
|
|
200
|
+
Err(e) => {
|
|
201
|
+
let err_msg = e.to_string();
|
|
202
|
+
tracing::warn!(iteration, error = %err_msg, "Callable error");
|
|
203
|
+
|
|
204
|
+
// Check if we should retry
|
|
205
|
+
if let Some(delay) = retry_handler.should_retry(&err_msg) {
|
|
206
|
+
if self.config.emit_events {
|
|
207
|
+
self.runner.emitter().emit(StreamEvent::step_end(
|
|
208
|
+
self.runner.execution_id(),
|
|
209
|
+
&step_id,
|
|
210
|
+
Some(format!("Retrying after error: {}", err_msg)),
|
|
211
|
+
step_start.elapsed().as_millis() as u64,
|
|
212
|
+
));
|
|
213
|
+
}
|
|
214
|
+
tokio::time::sleep(delay).await;
|
|
215
|
+
continue; // Retry this iteration
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Non-retryable or max retries exceeded
|
|
219
|
+
let exec_error = ExecutionError::kernel_internal(err_msg);
|
|
220
|
+
if self.config.emit_events {
|
|
221
|
+
self.runner.emitter().emit(StreamEvent::execution_failed(
|
|
222
|
+
self.runner.execution_id(),
|
|
223
|
+
exec_error,
|
|
224
|
+
));
|
|
225
|
+
}
|
|
226
|
+
return Err(e);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// ── Parse for tool calls ──
|
|
231
|
+
let parse_result = parser::parse(&response);
|
|
232
|
+
|
|
233
|
+
if parse_result.tool_calls.is_empty() {
|
|
234
|
+
// No tool calls — this is the final response
|
|
235
|
+
last_output = if parse_result.text.is_empty() {
|
|
236
|
+
response.clone()
|
|
237
|
+
} else {
|
|
238
|
+
parse_result.text.clone()
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
let step_duration = step_start.elapsed().as_millis() as u64;
|
|
242
|
+
if self.config.emit_events {
|
|
243
|
+
self.runner.emitter().emit(StreamEvent::step_end(
|
|
244
|
+
self.runner.execution_id(),
|
|
245
|
+
&step_id,
|
|
246
|
+
Some(last_output.clone()),
|
|
247
|
+
step_duration,
|
|
248
|
+
));
|
|
249
|
+
let total_duration = start_time.elapsed().as_millis() as u64;
|
|
250
|
+
self.runner.emitter().emit(StreamEvent::execution_end(
|
|
251
|
+
self.runner.execution_id(),
|
|
252
|
+
Some(last_output.clone()),
|
|
253
|
+
total_duration,
|
|
254
|
+
));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
tracing::info!(
|
|
258
|
+
iteration,
|
|
259
|
+
output_len = last_output.len(),
|
|
260
|
+
"Agent loop completed with final response"
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
return Ok(LoopOutcome::Completed(last_output));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ── Execute tool calls ──
|
|
267
|
+
history.push(HistoryMessage::assistant(&response));
|
|
268
|
+
|
|
269
|
+
for tool_call in &parse_result.tool_calls {
|
|
270
|
+
tracing::debug!(
|
|
271
|
+
tool = %tool_call.name,
|
|
272
|
+
format = ?tool_call.format,
|
|
273
|
+
"Executing tool call"
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
// Find the tool in our registry
|
|
277
|
+
let tool = self.tools.iter().find(|t| t.name() == tool_call.name);
|
|
278
|
+
|
|
279
|
+
let tool_result = match tool {
|
|
280
|
+
Some(t) => {
|
|
281
|
+
match t.execute(tool_call.arguments.clone()).await {
|
|
282
|
+
Ok(result) => serde_json::to_string(&result)
|
|
283
|
+
.unwrap_or_else(|_| format!("{:?}", result)),
|
|
284
|
+
Err(e) => format!("Tool error: {}", e),
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
None => {
|
|
288
|
+
format!(
|
|
289
|
+
"Error: Tool '{}' not found. Available tools: {:?}",
|
|
290
|
+
tool_call.name,
|
|
291
|
+
self.tools.iter().map(|t| t.name()).collect::<Vec<_>>()
|
|
292
|
+
)
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
history.push(HistoryMessage::tool_result(&tool_call.name, &tool_result));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
let step_duration = step_start.elapsed().as_millis() as u64;
|
|
300
|
+
if self.config.emit_events {
|
|
301
|
+
self.runner.emitter().emit(StreamEvent::step_end(
|
|
302
|
+
self.runner.execution_id(),
|
|
303
|
+
&step_id,
|
|
304
|
+
Some(format!(
|
|
305
|
+
"Executed {} tool(s)",
|
|
306
|
+
parse_result.tool_calls.len()
|
|
307
|
+
)),
|
|
308
|
+
step_duration,
|
|
309
|
+
));
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
last_output = response;
|
|
313
|
+
|
|
314
|
+
// ── Auto-compact history if needed ──
|
|
315
|
+
if compaction::needs_compaction(&history, self.config.compaction_threshold) {
|
|
316
|
+
tracing::info!(
|
|
317
|
+
history_len = history.len(),
|
|
318
|
+
threshold = self.config.compaction_threshold,
|
|
319
|
+
"Triggering auto-compaction"
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
match compaction::compact_history(
|
|
323
|
+
&mut history,
|
|
324
|
+
callable,
|
|
325
|
+
self.config.compaction_keep_recent,
|
|
326
|
+
)
|
|
327
|
+
.await
|
|
328
|
+
{
|
|
329
|
+
Ok(true) => {
|
|
330
|
+
tracing::info!(
|
|
331
|
+
new_len = history.len(),
|
|
332
|
+
"History compacted successfully"
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
Ok(false) => {
|
|
336
|
+
tracing::debug!("Compaction skipped (not enough messages)");
|
|
337
|
+
}
|
|
338
|
+
Err(e) => {
|
|
339
|
+
// Compaction failure is non-fatal — log and continue
|
|
340
|
+
tracing::warn!(error = %e, "History compaction failed, continuing");
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// ── Checkpoint at intervals ──
|
|
346
|
+
if let Some(interval) = self.config.checkpoint_interval {
|
|
347
|
+
if (iteration + 1) % interval == 0 {
|
|
348
|
+
let state = enact_core::graph::NodeState::from_str(&last_output);
|
|
349
|
+
if let Err(e) = self
|
|
350
|
+
.runner
|
|
351
|
+
.save_checkpoint(state, Some(callable.name()))
|
|
352
|
+
.await
|
|
353
|
+
{
|
|
354
|
+
tracing::warn!(error = %e, "Failed to save checkpoint, continuing");
|
|
355
|
+
} else {
|
|
356
|
+
tracing::debug!(iteration, "Checkpoint saved");
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Max iterations reached
|
|
363
|
+
tracing::warn!(
|
|
364
|
+
max = self.config.max_iterations,
|
|
365
|
+
"Max iterations reached"
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
if self.config.emit_events {
|
|
369
|
+
let duration = start_time.elapsed().as_millis() as u64;
|
|
370
|
+
self.runner.emitter().emit(StreamEvent::execution_end(
|
|
371
|
+
self.runner.execution_id(),
|
|
372
|
+
Some(last_output.clone()),
|
|
373
|
+
duration,
|
|
374
|
+
));
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
Ok(LoopOutcome::MaxIterationsReached {
|
|
378
|
+
last_output,
|
|
379
|
+
iterations: self.config.max_iterations,
|
|
380
|
+
})
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/// Build the input string for a given iteration from history.
|
|
384
|
+
///
|
|
385
|
+
/// Concatenates all history messages into a single prompt string.
|
|
386
|
+
fn build_iteration_input(&self, history: &[HistoryMessage]) -> String {
|
|
387
|
+
history
|
|
388
|
+
.iter()
|
|
389
|
+
.map(|m| format!("{}: {}", m.role, m.content))
|
|
390
|
+
.collect::<Vec<_>>()
|
|
391
|
+
.join("\n\n")
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/// Convenience: create an `AgentRunner` with default in-memory checkpoint store.
|
|
396
|
+
pub type DefaultAgentRunner = AgentRunner<enact_core::graph::InMemoryCheckpointStore>;
|
|
397
|
+
|
|
398
|
+
impl DefaultAgentRunner {
|
|
399
|
+
/// Create a new `AgentRunner` with default in-memory store and default config.
|
|
400
|
+
pub fn default_new() -> Self {
|
|
401
|
+
Self::new(
|
|
402
|
+
enact_core::runner::DefaultRunner::default_new(),
|
|
403
|
+
RunnerConfig::default(),
|
|
404
|
+
)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/// Create with a specific config.
|
|
408
|
+
pub fn with_config(config: RunnerConfig) -> Self {
|
|
409
|
+
Self::new(
|
|
410
|
+
enact_core::runner::DefaultRunner::default_new(),
|
|
411
|
+
config,
|
|
412
|
+
)
|
|
413
|
+
}
|
|
414
|
+
}
|