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,407 @@
|
|
|
1
|
+
//! Input Processor - Pre-execution content validation
|
|
2
|
+
//!
|
|
3
|
+
//! Input processors run BEFORE execution to validate and transform user input.
|
|
4
|
+
//! They detect potential issues like:
|
|
5
|
+
//! - PII in prompts (may need masking or blocking)
|
|
6
|
+
//! - Prompt injection attempts
|
|
7
|
+
//! - Prohibited content
|
|
8
|
+
//!
|
|
9
|
+
//! ## Architecture
|
|
10
|
+
//!
|
|
11
|
+
//! ```text
|
|
12
|
+
//! User Input
|
|
13
|
+
//! │
|
|
14
|
+
//! ▼
|
|
15
|
+
//! ┌──────────────────────────────────────────┐
|
|
16
|
+
//! │ INPUT PROCESSOR PIPELINE │
|
|
17
|
+
//! │ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
|
|
18
|
+
//! │ │ Content │→│ Prompt │→│ PII │ │
|
|
19
|
+
//! │ │ Filter │ │ Injection│ │ Detection │ │
|
|
20
|
+
//! │ └──────────┘ └──────────┘ └───────────┘ │
|
|
21
|
+
//! │ Pass/Block/Modify │
|
|
22
|
+
//! └──────────────────────────────────────────┘
|
|
23
|
+
//! │
|
|
24
|
+
//! ▼ (if Pass)
|
|
25
|
+
//! ExecutionKernel
|
|
26
|
+
//! ```
|
|
27
|
+
//!
|
|
28
|
+
//! @see docs/TECHNICAL/17-GUARDRAILS-PROTECTION.md
|
|
29
|
+
//! @see docs/TECHNICAL/25-STREAM-PROCESSORS.md
|
|
30
|
+
|
|
31
|
+
use super::PolicyContext;
|
|
32
|
+
use async_trait::async_trait;
|
|
33
|
+
use std::sync::Arc;
|
|
34
|
+
|
|
35
|
+
/// Result of input processing
|
|
36
|
+
#[derive(Debug, Clone)]
|
|
37
|
+
pub enum InputProcessorResult {
|
|
38
|
+
/// Input is safe, proceed with execution
|
|
39
|
+
Pass,
|
|
40
|
+
|
|
41
|
+
/// Input is blocked - do not execute
|
|
42
|
+
Block {
|
|
43
|
+
reason: String,
|
|
44
|
+
/// The processor that blocked
|
|
45
|
+
processor: String,
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
/// Input was modified (sanitized) - proceed with modified input
|
|
49
|
+
Modify {
|
|
50
|
+
original: String,
|
|
51
|
+
modified: String,
|
|
52
|
+
/// What was changed
|
|
53
|
+
changes: Vec<String>,
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
impl InputProcessorResult {
|
|
58
|
+
/// Returns true if execution should proceed
|
|
59
|
+
pub fn should_proceed(&self) -> bool {
|
|
60
|
+
matches!(self, Self::Pass | Self::Modify { .. })
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/// Returns true if input was blocked
|
|
64
|
+
pub fn is_blocked(&self) -> bool {
|
|
65
|
+
matches!(self, Self::Block { .. })
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/// Get the input to use for execution (original or modified)
|
|
69
|
+
pub fn effective_input<'a>(&'a self, original: &'a str) -> &'a str {
|
|
70
|
+
match self {
|
|
71
|
+
Self::Modify { modified, .. } => modified,
|
|
72
|
+
_ => original,
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/// Input Processor trait
|
|
78
|
+
///
|
|
79
|
+
/// Processors run BEFORE execution to validate/transform user input.
|
|
80
|
+
/// They MUST NOT have side effects beyond logging.
|
|
81
|
+
#[async_trait]
|
|
82
|
+
pub trait InputProcessor: Send + Sync {
|
|
83
|
+
/// Processor name for logging/metrics
|
|
84
|
+
fn name(&self) -> &str;
|
|
85
|
+
|
|
86
|
+
/// Priority for ordering (lower = runs first)
|
|
87
|
+
fn priority(&self) -> u32 {
|
|
88
|
+
100 // Default priority
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/// Process input before execution
|
|
92
|
+
///
|
|
93
|
+
/// # Arguments
|
|
94
|
+
/// * `input` - The user input to validate
|
|
95
|
+
/// * `ctx` - Policy context (tenant, user, metadata)
|
|
96
|
+
///
|
|
97
|
+
/// # Returns
|
|
98
|
+
/// - `Pass` - Input is safe
|
|
99
|
+
/// - `Block` - Input is blocked (don't execute)
|
|
100
|
+
/// - `Modify` - Input was sanitized (use modified version)
|
|
101
|
+
async fn process(
|
|
102
|
+
&self,
|
|
103
|
+
input: &str,
|
|
104
|
+
ctx: &PolicyContext,
|
|
105
|
+
) -> anyhow::Result<InputProcessorResult>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/// Input Processor Pipeline - chains multiple processors
|
|
109
|
+
pub struct InputProcessorPipeline {
|
|
110
|
+
processors: Vec<Arc<dyn InputProcessor>>,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
impl InputProcessorPipeline {
|
|
114
|
+
/// Create a new empty pipeline
|
|
115
|
+
pub fn new() -> Self {
|
|
116
|
+
Self { processors: vec![] }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/// Add a processor to the pipeline
|
|
120
|
+
pub fn add(mut self, processor: Arc<dyn InputProcessor>) -> Self {
|
|
121
|
+
self.processors.push(processor);
|
|
122
|
+
// Sort by priority (lower = first)
|
|
123
|
+
self.processors.sort_by_key(|p| p.priority());
|
|
124
|
+
self
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/// Run all processors in sequence
|
|
128
|
+
///
|
|
129
|
+
/// Processing stops on first Block.
|
|
130
|
+
/// Modify results are chained (each processor sees the modified input).
|
|
131
|
+
pub async fn process(
|
|
132
|
+
&self,
|
|
133
|
+
input: &str,
|
|
134
|
+
ctx: &PolicyContext,
|
|
135
|
+
) -> anyhow::Result<InputProcessorResult> {
|
|
136
|
+
let mut current_input = input.to_string();
|
|
137
|
+
let mut all_changes: Vec<String> = vec![];
|
|
138
|
+
let mut was_modified = false;
|
|
139
|
+
|
|
140
|
+
for processor in &self.processors {
|
|
141
|
+
let result = processor.process(¤t_input, ctx).await?;
|
|
142
|
+
|
|
143
|
+
match result {
|
|
144
|
+
InputProcessorResult::Pass => {
|
|
145
|
+
// Continue to next processor
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
InputProcessorResult::Block { .. } => {
|
|
149
|
+
// Stop processing, return block
|
|
150
|
+
return Ok(result);
|
|
151
|
+
}
|
|
152
|
+
InputProcessorResult::Modify {
|
|
153
|
+
modified, changes, ..
|
|
154
|
+
} => {
|
|
155
|
+
// Update input and continue
|
|
156
|
+
was_modified = true;
|
|
157
|
+
all_changes.extend(changes);
|
|
158
|
+
current_input = modified;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// All processors passed
|
|
164
|
+
if was_modified {
|
|
165
|
+
Ok(InputProcessorResult::Modify {
|
|
166
|
+
original: input.to_string(),
|
|
167
|
+
modified: current_input,
|
|
168
|
+
changes: all_changes,
|
|
169
|
+
})
|
|
170
|
+
} else {
|
|
171
|
+
Ok(InputProcessorResult::Pass)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/// Check if the pipeline is empty
|
|
176
|
+
pub fn is_empty(&self) -> bool {
|
|
177
|
+
self.processors.is_empty()
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/// Get the number of processors
|
|
181
|
+
pub fn len(&self) -> usize {
|
|
182
|
+
self.processors.len()
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
impl Default for InputProcessorPipeline {
|
|
187
|
+
fn default() -> Self {
|
|
188
|
+
Self::new()
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
#[cfg(test)]
|
|
193
|
+
mod tests {
|
|
194
|
+
use super::*;
|
|
195
|
+
use crate::policy::PolicyAction;
|
|
196
|
+
use std::collections::HashMap;
|
|
197
|
+
|
|
198
|
+
// Mock processor for testing
|
|
199
|
+
struct MockPassProcessor;
|
|
200
|
+
|
|
201
|
+
#[async_trait]
|
|
202
|
+
impl InputProcessor for MockPassProcessor {
|
|
203
|
+
fn name(&self) -> &str {
|
|
204
|
+
"mock-pass"
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async fn process(
|
|
208
|
+
&self,
|
|
209
|
+
_input: &str,
|
|
210
|
+
_ctx: &PolicyContext,
|
|
211
|
+
) -> anyhow::Result<InputProcessorResult> {
|
|
212
|
+
Ok(InputProcessorResult::Pass)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
struct MockBlockProcessor {
|
|
217
|
+
reason: String,
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
#[async_trait]
|
|
221
|
+
impl InputProcessor for MockBlockProcessor {
|
|
222
|
+
fn name(&self) -> &str {
|
|
223
|
+
"mock-block"
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async fn process(
|
|
227
|
+
&self,
|
|
228
|
+
_input: &str,
|
|
229
|
+
_ctx: &PolicyContext,
|
|
230
|
+
) -> anyhow::Result<InputProcessorResult> {
|
|
231
|
+
Ok(InputProcessorResult::Block {
|
|
232
|
+
reason: self.reason.clone(),
|
|
233
|
+
processor: self.name().to_string(),
|
|
234
|
+
})
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
struct MockModifyProcessor {
|
|
239
|
+
suffix: String,
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
#[async_trait]
|
|
243
|
+
impl InputProcessor for MockModifyProcessor {
|
|
244
|
+
fn name(&self) -> &str {
|
|
245
|
+
"mock-modify"
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async fn process(
|
|
249
|
+
&self,
|
|
250
|
+
input: &str,
|
|
251
|
+
_ctx: &PolicyContext,
|
|
252
|
+
) -> anyhow::Result<InputProcessorResult> {
|
|
253
|
+
Ok(InputProcessorResult::Modify {
|
|
254
|
+
original: input.to_string(),
|
|
255
|
+
modified: format!("{}{}", input, self.suffix),
|
|
256
|
+
changes: vec![format!("Added suffix: {}", self.suffix)],
|
|
257
|
+
})
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
fn test_context() -> PolicyContext {
|
|
262
|
+
PolicyContext {
|
|
263
|
+
tenant_id: Some("test-tenant".to_string()),
|
|
264
|
+
user_id: Some("test-user".to_string()),
|
|
265
|
+
action: PolicyAction::StartExecution { graph_id: None },
|
|
266
|
+
metadata: HashMap::new(),
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
#[test]
|
|
271
|
+
fn test_input_processor_result_should_proceed() {
|
|
272
|
+
assert!(InputProcessorResult::Pass.should_proceed());
|
|
273
|
+
assert!(InputProcessorResult::Modify {
|
|
274
|
+
original: "a".to_string(),
|
|
275
|
+
modified: "b".to_string(),
|
|
276
|
+
changes: vec![],
|
|
277
|
+
}
|
|
278
|
+
.should_proceed());
|
|
279
|
+
assert!(!InputProcessorResult::Block {
|
|
280
|
+
reason: "test".to_string(),
|
|
281
|
+
processor: "test".to_string(),
|
|
282
|
+
}
|
|
283
|
+
.should_proceed());
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
#[test]
|
|
287
|
+
fn test_input_processor_result_is_blocked() {
|
|
288
|
+
assert!(!InputProcessorResult::Pass.is_blocked());
|
|
289
|
+
assert!(InputProcessorResult::Block {
|
|
290
|
+
reason: "test".to_string(),
|
|
291
|
+
processor: "test".to_string(),
|
|
292
|
+
}
|
|
293
|
+
.is_blocked());
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
#[test]
|
|
297
|
+
fn test_input_processor_result_effective_input() {
|
|
298
|
+
let original = "hello";
|
|
299
|
+
|
|
300
|
+
// Pass returns original
|
|
301
|
+
assert_eq!(
|
|
302
|
+
InputProcessorResult::Pass.effective_input(original),
|
|
303
|
+
"hello"
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
// Block returns original
|
|
307
|
+
let block = InputProcessorResult::Block {
|
|
308
|
+
reason: "blocked".to_string(),
|
|
309
|
+
processor: "test".to_string(),
|
|
310
|
+
};
|
|
311
|
+
assert_eq!(block.effective_input(original), "hello");
|
|
312
|
+
|
|
313
|
+
// Modify returns modified
|
|
314
|
+
let modify = InputProcessorResult::Modify {
|
|
315
|
+
original: "hello".to_string(),
|
|
316
|
+
modified: "hello world".to_string(),
|
|
317
|
+
changes: vec![],
|
|
318
|
+
};
|
|
319
|
+
assert_eq!(modify.effective_input(original), "hello world");
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
#[tokio::test]
|
|
323
|
+
async fn test_pipeline_empty() {
|
|
324
|
+
let pipeline = InputProcessorPipeline::new();
|
|
325
|
+
assert!(pipeline.is_empty());
|
|
326
|
+
assert_eq!(pipeline.len(), 0);
|
|
327
|
+
|
|
328
|
+
let ctx = test_context();
|
|
329
|
+
let result = pipeline.process("test input", &ctx).await.unwrap();
|
|
330
|
+
assert!(matches!(result, InputProcessorResult::Pass));
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
#[tokio::test]
|
|
334
|
+
async fn test_pipeline_pass_through() {
|
|
335
|
+
let pipeline = InputProcessorPipeline::new().add(Arc::new(MockPassProcessor));
|
|
336
|
+
|
|
337
|
+
let ctx = test_context();
|
|
338
|
+
let result = pipeline.process("test input", &ctx).await.unwrap();
|
|
339
|
+
assert!(matches!(result, InputProcessorResult::Pass));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
#[tokio::test]
|
|
343
|
+
async fn test_pipeline_block() {
|
|
344
|
+
let pipeline = InputProcessorPipeline::new()
|
|
345
|
+
.add(Arc::new(MockPassProcessor))
|
|
346
|
+
.add(Arc::new(MockBlockProcessor {
|
|
347
|
+
reason: "forbidden".to_string(),
|
|
348
|
+
}));
|
|
349
|
+
|
|
350
|
+
let ctx = test_context();
|
|
351
|
+
let result = pipeline.process("test input", &ctx).await.unwrap();
|
|
352
|
+
|
|
353
|
+
assert!(result.is_blocked());
|
|
354
|
+
if let InputProcessorResult::Block { reason, processor } = result {
|
|
355
|
+
assert_eq!(reason, "forbidden");
|
|
356
|
+
assert_eq!(processor, "mock-block");
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
#[tokio::test]
|
|
361
|
+
async fn test_pipeline_modify() {
|
|
362
|
+
let pipeline = InputProcessorPipeline::new().add(Arc::new(MockModifyProcessor {
|
|
363
|
+
suffix: " [sanitized]".to_string(),
|
|
364
|
+
}));
|
|
365
|
+
|
|
366
|
+
let ctx = test_context();
|
|
367
|
+
let result = pipeline.process("test input", &ctx).await.unwrap();
|
|
368
|
+
|
|
369
|
+
if let InputProcessorResult::Modify {
|
|
370
|
+
original,
|
|
371
|
+
modified,
|
|
372
|
+
changes,
|
|
373
|
+
} = result
|
|
374
|
+
{
|
|
375
|
+
assert_eq!(original, "test input");
|
|
376
|
+
assert_eq!(modified, "test input [sanitized]");
|
|
377
|
+
assert_eq!(changes.len(), 1);
|
|
378
|
+
} else {
|
|
379
|
+
panic!("Expected Modify result");
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
#[tokio::test]
|
|
384
|
+
async fn test_pipeline_chained_modify() {
|
|
385
|
+
let pipeline = InputProcessorPipeline::new()
|
|
386
|
+
.add(Arc::new(MockModifyProcessor {
|
|
387
|
+
suffix: " [a]".to_string(),
|
|
388
|
+
}))
|
|
389
|
+
.add(Arc::new(MockModifyProcessor {
|
|
390
|
+
suffix: " [b]".to_string(),
|
|
391
|
+
}));
|
|
392
|
+
|
|
393
|
+
let ctx = test_context();
|
|
394
|
+
let result = pipeline.process("input", &ctx).await.unwrap();
|
|
395
|
+
|
|
396
|
+
if let InputProcessorResult::Modify {
|
|
397
|
+
modified, changes, ..
|
|
398
|
+
} = result
|
|
399
|
+
{
|
|
400
|
+
// Both modifications applied in sequence
|
|
401
|
+
assert_eq!(modified, "input [a] [b]");
|
|
402
|
+
assert_eq!(changes.len(), 2);
|
|
403
|
+
} else {
|
|
404
|
+
panic!("Expected Modify result");
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
//! Long-running execution policy
|
|
2
|
+
//!
|
|
3
|
+
//! Defines policies for executions that can run for extended periods,
|
|
4
|
+
//! including checkpointing, memory management, and cost controls.
|
|
5
|
+
|
|
6
|
+
use serde::{Deserialize, Serialize};
|
|
7
|
+
|
|
8
|
+
/// Policy configuration for long-running agentic executions
|
|
9
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
10
|
+
pub struct LongRunningExecutionPolicy {
|
|
11
|
+
/// Maximum number of dynamically discovered steps before intervention
|
|
12
|
+
pub max_discovered_steps: Option<u32>,
|
|
13
|
+
/// Maximum depth of discovery chains
|
|
14
|
+
pub max_discovery_depth: Option<u32>,
|
|
15
|
+
/// Alert threshold for cumulative cost in USD
|
|
16
|
+
pub cost_alert_threshold_usd: Option<f64>,
|
|
17
|
+
/// Maximum time without activity before idle timeout (seconds)
|
|
18
|
+
pub idle_timeout_seconds: Option<u64>,
|
|
19
|
+
/// Maximum repetitions of same methodology before loop detection
|
|
20
|
+
pub max_same_step_repetitions: Option<u32>,
|
|
21
|
+
/// Checkpointing strategy
|
|
22
|
+
pub checkpointing: CheckpointPolicy,
|
|
23
|
+
/// Memory management strategy
|
|
24
|
+
pub memory: WorkingMemoryPolicy,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
impl Default for LongRunningExecutionPolicy {
|
|
28
|
+
fn default() -> Self {
|
|
29
|
+
Self::standard()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
impl LongRunningExecutionPolicy {
|
|
34
|
+
/// Standard preset
|
|
35
|
+
pub fn standard() -> Self {
|
|
36
|
+
Self {
|
|
37
|
+
max_discovered_steps: Some(50),
|
|
38
|
+
max_discovery_depth: Some(5),
|
|
39
|
+
cost_alert_threshold_usd: Some(5.0),
|
|
40
|
+
idle_timeout_seconds: Some(1800),
|
|
41
|
+
max_same_step_repetitions: Some(3),
|
|
42
|
+
checkpointing: CheckpointPolicy::default(),
|
|
43
|
+
memory: WorkingMemoryPolicy::default(),
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// Extended preset
|
|
48
|
+
pub fn extended() -> Self {
|
|
49
|
+
Self {
|
|
50
|
+
max_discovered_steps: Some(300),
|
|
51
|
+
max_discovery_depth: Some(10),
|
|
52
|
+
cost_alert_threshold_usd: Some(50.0),
|
|
53
|
+
idle_timeout_seconds: Some(14400),
|
|
54
|
+
max_same_step_repetitions: Some(5),
|
|
55
|
+
checkpointing: CheckpointPolicy {
|
|
56
|
+
interval_steps: Some(10),
|
|
57
|
+
on_discovery: true,
|
|
58
|
+
..Default::default()
|
|
59
|
+
},
|
|
60
|
+
memory: WorkingMemoryPolicy {
|
|
61
|
+
strategy: ContextStrategy::Summarize {
|
|
62
|
+
summarize_after: 50,
|
|
63
|
+
keep_recent: 10,
|
|
64
|
+
},
|
|
65
|
+
max_tokens: Some(100_000),
|
|
66
|
+
..Default::default()
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/// Policy for checkpointing execution state
|
|
73
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
74
|
+
pub struct CheckpointPolicy {
|
|
75
|
+
/// Checkpoint every N steps
|
|
76
|
+
pub interval_steps: Option<u32>,
|
|
77
|
+
/// Checkpoint every N seconds
|
|
78
|
+
pub interval_seconds: Option<u64>,
|
|
79
|
+
/// Checkpoint on every new step discovery
|
|
80
|
+
pub on_discovery: bool,
|
|
81
|
+
/// Maximum checkpoints to retain
|
|
82
|
+
pub max_checkpoints: Option<u32>,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
impl Default for CheckpointPolicy {
|
|
86
|
+
fn default() -> Self {
|
|
87
|
+
Self {
|
|
88
|
+
interval_steps: Some(10),
|
|
89
|
+
interval_seconds: Some(300),
|
|
90
|
+
on_discovery: false,
|
|
91
|
+
max_checkpoints: Some(50),
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/// Policy for working memory management
|
|
97
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
98
|
+
pub struct WorkingMemoryPolicy {
|
|
99
|
+
/// Strategy to use when context fills up
|
|
100
|
+
pub strategy: ContextStrategy,
|
|
101
|
+
/// Maximum tokens allowed in working memory
|
|
102
|
+
pub max_tokens: Option<u32>,
|
|
103
|
+
/// Whether to auto-compact when near limit
|
|
104
|
+
pub auto_compact: bool,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
impl Default for WorkingMemoryPolicy {
|
|
108
|
+
fn default() -> Self {
|
|
109
|
+
Self {
|
|
110
|
+
strategy: ContextStrategy::SlidingWindow { size: 20 },
|
|
111
|
+
max_tokens: Some(32_000),
|
|
112
|
+
auto_compact: true,
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// Strategy for managing context window
|
|
118
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
119
|
+
pub enum ContextStrategy {
|
|
120
|
+
/// Keep all history (risk of overflow)
|
|
121
|
+
KeepAll,
|
|
122
|
+
/// Keep only the last N messages
|
|
123
|
+
SlidingWindow { size: u32 },
|
|
124
|
+
/// Summarize older history, keep recent raw
|
|
125
|
+
Summarize {
|
|
126
|
+
summarize_after: u32,
|
|
127
|
+
keep_recent: u32,
|
|
128
|
+
},
|
|
129
|
+
/// Move older history to episodic memory
|
|
130
|
+
Archive {
|
|
131
|
+
archive_after: u32,
|
|
132
|
+
keep_recent: u32,
|
|
133
|
+
},
|
|
134
|
+
}
|