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,228 @@
|
|
|
1
|
+
+++
|
|
2
|
+
title = "Skills System"
|
|
3
|
+
weight = 7
|
|
4
|
+
sort_by = "weight"
|
|
5
|
+
+++
|
|
6
|
+
|
|
7
|
+
# Skills System
|
|
8
|
+
|
|
9
|
+
The Skills System allows you to extend Enact with custom capabilities through TOML manifests or simple Markdown files.
|
|
10
|
+
|
|
11
|
+
## Status
|
|
12
|
+
|
|
13
|
+
| Feature | Status |
|
|
14
|
+
|---------|--------|
|
|
15
|
+
| TOML skill manifests (`SKILL.toml`) | ✅ Complete |
|
|
16
|
+
| Markdown skill format (`SKILL.md`) | ✅ Complete |
|
|
17
|
+
| Tool definitions (shell, http, script) | ✅ Complete |
|
|
18
|
+
| Open-skills repo integration | ✅ Complete |
|
|
19
|
+
| Load skills from workspace directory | ✅ Complete |
|
|
20
|
+
| Convert skills to prompts | ✅ Complete |
|
|
21
|
+
| 15+ comprehensive tests | ✅ Complete |
|
|
22
|
+
|
|
23
|
+
## Skill Locations
|
|
24
|
+
|
|
25
|
+
Skills can be loaded from two locations:
|
|
26
|
+
|
|
27
|
+
1. **Workspace directory**: `./skills/<skill-name>/`
|
|
28
|
+
2. **Open-skills repository**: Auto-synced from [besoeasy/open-skills](https://github.com/besoeasy/open-skills)
|
|
29
|
+
|
|
30
|
+
## SKILL.toml Format
|
|
31
|
+
|
|
32
|
+
The structured format for skills with tool definitions:
|
|
33
|
+
|
|
34
|
+
```toml
|
|
35
|
+
[skill]
|
|
36
|
+
name = "my-skill"
|
|
37
|
+
description = "What this skill does"
|
|
38
|
+
version = "0.1.0"
|
|
39
|
+
author = "your-name"
|
|
40
|
+
tags = ["productivity", "automation"]
|
|
41
|
+
|
|
42
|
+
[[tools]]
|
|
43
|
+
name = "my_tool"
|
|
44
|
+
description = "What this tool does"
|
|
45
|
+
kind = "shell"
|
|
46
|
+
command = "echo hello"
|
|
47
|
+
|
|
48
|
+
[[tools]]
|
|
49
|
+
name = "http_tool"
|
|
50
|
+
description = "Makes an HTTP request"
|
|
51
|
+
kind = "http"
|
|
52
|
+
command = "https://api.example.com/endpoint"
|
|
53
|
+
|
|
54
|
+
[tools.args]
|
|
55
|
+
method = "GET"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Skill Metadata
|
|
59
|
+
|
|
60
|
+
| Field | Required | Description |
|
|
61
|
+
|-------|----------|-------------|
|
|
62
|
+
| `name` | Yes | Unique skill identifier |
|
|
63
|
+
| `description` | Yes | What the skill does |
|
|
64
|
+
| `version` | No | Semantic version (default: "0.1.0") |
|
|
65
|
+
| `author` | No | Skill author |
|
|
66
|
+
| `tags` | No | Categorization tags |
|
|
67
|
+
|
|
68
|
+
### Tool Types
|
|
69
|
+
|
|
70
|
+
| Kind | Description |
|
|
71
|
+
|------|-------------|
|
|
72
|
+
| `shell` | Execute a shell command |
|
|
73
|
+
| `http` | Make an HTTP request |
|
|
74
|
+
| `script` | Run a script file |
|
|
75
|
+
|
|
76
|
+
## SKILL.md Format
|
|
77
|
+
|
|
78
|
+
A simpler format for prompt-based skills:
|
|
79
|
+
|
|
80
|
+
```markdown
|
|
81
|
+
# My Skill
|
|
82
|
+
|
|
83
|
+
Instructions for the agent to follow.
|
|
84
|
+
|
|
85
|
+
When the user asks about X, do Y.
|
|
86
|
+
|
|
87
|
+
## Examples
|
|
88
|
+
|
|
89
|
+
- If user says "hello", respond warmly
|
|
90
|
+
- If user asks for help, provide guidance
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The entire markdown content becomes the skill's prompt.
|
|
94
|
+
|
|
95
|
+
## Loading Skills
|
|
96
|
+
|
|
97
|
+
### Programmatic Usage
|
|
98
|
+
|
|
99
|
+
```rust
|
|
100
|
+
use enact_skills::{load_skills, skills_to_prompt};
|
|
101
|
+
use std::path::Path;
|
|
102
|
+
|
|
103
|
+
// Load all skills from workspace
|
|
104
|
+
let skills = load_skills(Path::new("."));
|
|
105
|
+
|
|
106
|
+
// Convert to system prompt addition
|
|
107
|
+
let prompt_addition = skills_to_prompt(&skills);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Skill Directory Structure
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
my-project/
|
|
114
|
+
├── skills/
|
|
115
|
+
│ ├── greeting/
|
|
116
|
+
│ │ └── SKILL.toml
|
|
117
|
+
│ ├── code-review/
|
|
118
|
+
│ │ └── SKILL.md
|
|
119
|
+
│ └── README.md
|
|
120
|
+
└── agents/
|
|
121
|
+
└── my-agent.yaml
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Open-Skills Integration
|
|
125
|
+
|
|
126
|
+
Enact automatically syncs with the open-skills community repository:
|
|
127
|
+
|
|
128
|
+
- **Repository**: [besoeasy/open-skills](https://github.com/besoeasy/open-skills)
|
|
129
|
+
- **Location**: `~/open-skills/`
|
|
130
|
+
- **Sync interval**: Weekly (7 days)
|
|
131
|
+
- **Format**: Markdown files
|
|
132
|
+
|
|
133
|
+
### Configuration
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Disable open-skills
|
|
137
|
+
export ENACT_OPEN_SKILLS_ENABLED=false
|
|
138
|
+
|
|
139
|
+
# Custom open-skills directory
|
|
140
|
+
export ENACT_OPEN_SKILLS_DIR=/path/to/skills
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Initialize Skills Directory
|
|
144
|
+
|
|
145
|
+
```rust
|
|
146
|
+
use enact_skills::init_skills_dir;
|
|
147
|
+
use std::path::Path;
|
|
148
|
+
|
|
149
|
+
// Creates ./skills/ with a README.md
|
|
150
|
+
init_skills_dir(Path::new("."))?;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Rust API
|
|
154
|
+
|
|
155
|
+
### Skill Struct
|
|
156
|
+
|
|
157
|
+
```rust
|
|
158
|
+
pub struct Skill {
|
|
159
|
+
pub name: String,
|
|
160
|
+
pub description: String,
|
|
161
|
+
pub version: String,
|
|
162
|
+
pub author: Option<String>,
|
|
163
|
+
pub tags: Vec<String>,
|
|
164
|
+
pub tools: Vec<SkillTool>,
|
|
165
|
+
pub prompts: Vec<String>,
|
|
166
|
+
pub location: Option<PathBuf>,
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### SkillTool Struct
|
|
171
|
+
|
|
172
|
+
```rust
|
|
173
|
+
pub struct SkillTool {
|
|
174
|
+
pub name: String,
|
|
175
|
+
pub description: String,
|
|
176
|
+
pub kind: String, // "shell", "http", "script"
|
|
177
|
+
pub command: String,
|
|
178
|
+
pub args: HashMap<String, String>,
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Functions
|
|
183
|
+
|
|
184
|
+
| Function | Description |
|
|
185
|
+
|----------|-------------|
|
|
186
|
+
| `load_skills(workspace_dir)` | Load all skills from workspace and open-skills |
|
|
187
|
+
| `skills_to_prompt(skills)` | Convert skills to system prompt addition |
|
|
188
|
+
| `skills_dir(workspace_dir)` | Get the skills directory path |
|
|
189
|
+
| `init_skills_dir(workspace_dir)` | Initialize skills directory with README |
|
|
190
|
+
|
|
191
|
+
## Example Skills
|
|
192
|
+
|
|
193
|
+
### Shell Tool Skill
|
|
194
|
+
|
|
195
|
+
```toml
|
|
196
|
+
[skill]
|
|
197
|
+
name = "git-helper"
|
|
198
|
+
description = "Git operations helper"
|
|
199
|
+
version = "1.0.0"
|
|
200
|
+
tags = ["git", "vcs"]
|
|
201
|
+
|
|
202
|
+
[[tools]]
|
|
203
|
+
name = "git_status"
|
|
204
|
+
description = "Show git status"
|
|
205
|
+
kind = "shell"
|
|
206
|
+
command = "git status"
|
|
207
|
+
|
|
208
|
+
[[tools]]
|
|
209
|
+
name = "git_log"
|
|
210
|
+
description = "Show recent commits"
|
|
211
|
+
kind = "shell"
|
|
212
|
+
command = "git log --oneline -10"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Prompt-Based Skill
|
|
216
|
+
|
|
217
|
+
```markdown
|
|
218
|
+
# Code Reviewer
|
|
219
|
+
|
|
220
|
+
You are a code review assistant. When reviewing code:
|
|
221
|
+
|
|
222
|
+
1. Check for bugs and logic errors
|
|
223
|
+
2. Suggest performance improvements
|
|
224
|
+
3. Ensure code follows best practices
|
|
225
|
+
4. Be constructive and specific
|
|
226
|
+
|
|
227
|
+
Always explain your reasoning.
|
|
228
|
+
```
|
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
+++
|
|
2
|
+
title = "Tools"
|
|
3
|
+
weight = 12
|
|
4
|
+
+++
|
|
5
|
+
|
|
6
|
+
# Built-in Tools
|
|
7
|
+
|
|
8
|
+
Enact provides **7 production-ready tools** for agents with security sandboxing and policy enforcement. These tools enable agents to interact with the filesystem, execute commands, search the web, make API calls, and track costs.
|
|
9
|
+
|
|
10
|
+
## Available Tools
|
|
11
|
+
|
|
12
|
+
| Tool | Description | Network Required | Risk Level |
|
|
13
|
+
|------|-------------|------------------|------------|
|
|
14
|
+
| `file_read` | Read file contents securely | ❌ No | Low |
|
|
15
|
+
| `file_write` | Write/create files | ❌ No | Medium |
|
|
16
|
+
| `shell` | Execute shell commands | ❌ No* | Medium-High |
|
|
17
|
+
| `git` | Git repository operations | ✅ Yes | Low-Medium |
|
|
18
|
+
| `web_search` | Web search (DuckDuckGo/Brave) | ✅ Yes | Low |
|
|
19
|
+
| `http_request` | Make HTTP requests | ✅ Yes | Medium |
|
|
20
|
+
| `cost` | Track API costs & usage | ❌ No | Low |
|
|
21
|
+
|
|
22
|
+
\* Shell commands themselves may require network access
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```rust
|
|
29
|
+
use enact_core::tool::{
|
|
30
|
+
FileReadTool, FileWriteTool, ShellTool, GitTool,
|
|
31
|
+
WebSearchTool, HttpRequestTool, CostTracker, CostTool
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Read a file
|
|
35
|
+
let tool = FileReadTool::new();
|
|
36
|
+
let result = tool.execute(json!({"path": "README.md"})).await?;
|
|
37
|
+
|
|
38
|
+
// Search the web
|
|
39
|
+
let tool = WebSearchTool::new("duckduckgo");
|
|
40
|
+
let result = tool.execute(json!({"query": "Rust async patterns"})).await?;
|
|
41
|
+
|
|
42
|
+
// Run a shell command
|
|
43
|
+
let tool = ShellTool::new();
|
|
44
|
+
let result = tool.execute(json!({"command": "cargo test"})).await?;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## File Read Tool
|
|
50
|
+
|
|
51
|
+
Read file contents with path traversal protection:
|
|
52
|
+
|
|
53
|
+
```rust
|
|
54
|
+
use enact_core::tool::FileReadTool;
|
|
55
|
+
|
|
56
|
+
let tool = FileReadTool::new();
|
|
57
|
+
|
|
58
|
+
let result = tool.execute(serde_json::json!({
|
|
59
|
+
"path": "src/main.rs"
|
|
60
|
+
})).await?;
|
|
61
|
+
|
|
62
|
+
// Returns:
|
|
63
|
+
// {
|
|
64
|
+
// "success": true,
|
|
65
|
+
// "content": "file contents...",
|
|
66
|
+
// "path": "src/main.rs",
|
|
67
|
+
// "size": 1234
|
|
68
|
+
// }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Parameters
|
|
72
|
+
|
|
73
|
+
| Parameter | Type | Required | Description |
|
|
74
|
+
|-----------|------|----------|-------------|
|
|
75
|
+
| `path` | string | Yes | Relative path to file |
|
|
76
|
+
|
|
77
|
+
### Security Features
|
|
78
|
+
|
|
79
|
+
- ✅ Path traversal attacks blocked (`../etc/passwd`)
|
|
80
|
+
- ✅ Maximum file size: 10MB
|
|
81
|
+
- ✅ Only regular files (not directories)
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## File Write Tool
|
|
86
|
+
|
|
87
|
+
Write or create files with automatic parent directory creation:
|
|
88
|
+
|
|
89
|
+
```rust
|
|
90
|
+
use enact_core::tool::FileWriteTool;
|
|
91
|
+
|
|
92
|
+
let tool = FileWriteTool::new();
|
|
93
|
+
|
|
94
|
+
let result = tool.execute(serde_json::json!({
|
|
95
|
+
"path": "output/results.txt",
|
|
96
|
+
"content": "Hello, World!"
|
|
97
|
+
})).await?;
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Parameters
|
|
101
|
+
|
|
102
|
+
| Parameter | Type | Required | Description |
|
|
103
|
+
|-----------|------|----------|-------------|
|
|
104
|
+
| `path` | string | Yes | Relative path to file |
|
|
105
|
+
| `content` | string | Yes | Content to write |
|
|
106
|
+
|
|
107
|
+
### Security Features
|
|
108
|
+
|
|
109
|
+
- ✅ Path traversal prevention
|
|
110
|
+
- ✅ Parent directories created automatically
|
|
111
|
+
- ✅ Works within workspace boundaries
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Shell Tool
|
|
116
|
+
|
|
117
|
+
Execute shell commands with timeout protection:
|
|
118
|
+
|
|
119
|
+
```rust
|
|
120
|
+
use enact_core::tool::ShellTool;
|
|
121
|
+
|
|
122
|
+
let tool = ShellTool::new();
|
|
123
|
+
|
|
124
|
+
// Basic command
|
|
125
|
+
let result = tool.execute(serde_json::json!({
|
|
126
|
+
"command": "ls -la"
|
|
127
|
+
})).await?;
|
|
128
|
+
|
|
129
|
+
// With timeout
|
|
130
|
+
let result = tool.execute(serde_json::json!({
|
|
131
|
+
"command": "cargo build",
|
|
132
|
+
"timeout": 120 // seconds
|
|
133
|
+
})).await?;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Parameters
|
|
137
|
+
|
|
138
|
+
| Parameter | Type | Required | Description |
|
|
139
|
+
|-----------|------|----------|-------------|
|
|
140
|
+
| `command` | string | Yes | Shell command to execute |
|
|
141
|
+
| `timeout` | number | No | Timeout in seconds (default: 60, max: 300) |
|
|
142
|
+
|
|
143
|
+
### Output
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"success": true,
|
|
148
|
+
"stdout": "command output...",
|
|
149
|
+
"stderr": "error output...",
|
|
150
|
+
"exit_code": 0,
|
|
151
|
+
"command": "ls -la"
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Security Features
|
|
156
|
+
|
|
157
|
+
- ⏱️ Timeout protection (prevents hanging)
|
|
158
|
+
- 📏 Max output: 1MB (truncated with notice)
|
|
159
|
+
- 🔒 Runs through `sh -c` for compatibility
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Git Tool
|
|
164
|
+
|
|
165
|
+
Perform Git operations on repositories:
|
|
166
|
+
|
|
167
|
+
```rust
|
|
168
|
+
use enact_core::tool::GitTool;
|
|
169
|
+
|
|
170
|
+
let tool = GitTool::new();
|
|
171
|
+
|
|
172
|
+
// Check status
|
|
173
|
+
let result = tool.execute(serde_json::json!({
|
|
174
|
+
"operation": "status"
|
|
175
|
+
})).await?;
|
|
176
|
+
|
|
177
|
+
// Clone a repository
|
|
178
|
+
let result = tool.execute(serde_json::json!({
|
|
179
|
+
"operation": "clone",
|
|
180
|
+
"repo_url": "https://github.com/user/repo.git",
|
|
181
|
+
"directory": "./cloned-repo"
|
|
182
|
+
})).await?;
|
|
183
|
+
|
|
184
|
+
// Create a commit
|
|
185
|
+
let result = tool.execute(serde_json::json!({
|
|
186
|
+
"operation": "commit",
|
|
187
|
+
"message": "Add new feature",
|
|
188
|
+
"directory": "./my-project"
|
|
189
|
+
})).await?;
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Operations
|
|
193
|
+
|
|
194
|
+
| Operation | Parameters | Description |
|
|
195
|
+
|-----------|------------|-------------|
|
|
196
|
+
| `clone` | `repo_url`, `directory` | Clone a repository |
|
|
197
|
+
| `status` | `directory` | Show working tree status |
|
|
198
|
+
| `add` | `args` | Stage files |
|
|
199
|
+
| `commit` | `message` | Create a commit |
|
|
200
|
+
| `push` | `args` | Push to remote |
|
|
201
|
+
| `pull` | `args` | Pull from remote |
|
|
202
|
+
| `branch` | - | List branches |
|
|
203
|
+
| `checkout` | `args` | Switch branches |
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Web Search Tool
|
|
208
|
+
|
|
209
|
+
Search the web using DuckDuckGo (free) or Brave API:
|
|
210
|
+
|
|
211
|
+
```rust
|
|
212
|
+
use enact_core::tool::WebSearchTool;
|
|
213
|
+
|
|
214
|
+
// Using DuckDuckGo (free, no API key)
|
|
215
|
+
let tool = WebSearchTool::new("duckduckgo");
|
|
216
|
+
|
|
217
|
+
let result = tool.execute(serde_json::json!({
|
|
218
|
+
"query": "Rust async programming",
|
|
219
|
+
"max_results": 5
|
|
220
|
+
})).await?;
|
|
221
|
+
|
|
222
|
+
// Using Brave (requires API key)
|
|
223
|
+
let tool = WebSearchTool::new("brave")
|
|
224
|
+
.with_brave_key("your-api-key");
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Parameters
|
|
228
|
+
|
|
229
|
+
| Parameter | Type | Required | Description |
|
|
230
|
+
|-----------|------|----------|-------------|
|
|
231
|
+
| `query` | string | Yes | Search query |
|
|
232
|
+
| `max_results` | number | No | Max results 1-10 (default: 5) |
|
|
233
|
+
|
|
234
|
+
### Output
|
|
235
|
+
|
|
236
|
+
```json
|
|
237
|
+
{
|
|
238
|
+
"success": true,
|
|
239
|
+
"query": "Rust async programming",
|
|
240
|
+
"provider": "duckduckgo",
|
|
241
|
+
"results": [
|
|
242
|
+
{
|
|
243
|
+
"title": "Asynchronous Programming in Rust",
|
|
244
|
+
"url": "https://rust-lang.github.io/async-book/",
|
|
245
|
+
"snippet": "..."
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
"count": 5
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Providers
|
|
253
|
+
|
|
254
|
+
- **DuckDuckGo**: Free, no API key required
|
|
255
|
+
- **Brave**: Requires API key, better results
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## HTTP Request Tool
|
|
260
|
+
|
|
261
|
+
Make HTTP requests to APIs and web services:
|
|
262
|
+
|
|
263
|
+
```rust
|
|
264
|
+
use enact_core::tool::HttpRequestTool;
|
|
265
|
+
|
|
266
|
+
let tool = HttpRequestTool::new();
|
|
267
|
+
|
|
268
|
+
// GET request
|
|
269
|
+
let result = tool.execute(serde_json::json!({
|
|
270
|
+
"url": "https://api.example.com/data",
|
|
271
|
+
"method": "GET"
|
|
272
|
+
})).await?;
|
|
273
|
+
|
|
274
|
+
// POST request with JSON body
|
|
275
|
+
let result = tool.execute(serde_json::json!({
|
|
276
|
+
"url": "https://api.example.com/users",
|
|
277
|
+
"method": "POST",
|
|
278
|
+
"headers": {
|
|
279
|
+
"Content-Type": "application/json",
|
|
280
|
+
"Authorization": "Bearer token123"
|
|
281
|
+
},
|
|
282
|
+
"body": {
|
|
283
|
+
"name": "John",
|
|
284
|
+
"email": "john@example.com"
|
|
285
|
+
}
|
|
286
|
+
})).await?;
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Parameters
|
|
290
|
+
|
|
291
|
+
| Parameter | Type | Required | Description |
|
|
292
|
+
|-----------|------|----------|-------------|
|
|
293
|
+
| `url` | string | Yes | Request URL |
|
|
294
|
+
| `method` | string | No | HTTP method (default: GET) |
|
|
295
|
+
| `headers` | object | No | Request headers |
|
|
296
|
+
| `body` | string/object | No | Request body |
|
|
297
|
+
| `timeout` | number | No | Timeout in seconds (default: 30) |
|
|
298
|
+
|
|
299
|
+
### Supported Methods
|
|
300
|
+
|
|
301
|
+
`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`, `OPTIONS`
|
|
302
|
+
|
|
303
|
+
### Output
|
|
304
|
+
|
|
305
|
+
```json
|
|
306
|
+
{
|
|
307
|
+
"success": true,
|
|
308
|
+
"status_code": 200,
|
|
309
|
+
"status_text": "OK",
|
|
310
|
+
"headers": { "content-type": "application/json" },
|
|
311
|
+
"body": { "data": "..." },
|
|
312
|
+
"url": "https://api.example.com/data",
|
|
313
|
+
"method": "GET"
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Security Features
|
|
318
|
+
|
|
319
|
+
- 📏 Max response size: 10MB
|
|
320
|
+
- ⏱️ Configurable timeout
|
|
321
|
+
- 🔒 Automatic JSON parsing for JSON responses
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Cost Tracking Tool
|
|
326
|
+
|
|
327
|
+
Track API costs and usage for budget management:
|
|
328
|
+
|
|
329
|
+
```rust
|
|
330
|
+
use enact_core::tool::{CostTool, CostTracker};
|
|
331
|
+
use std::sync::Arc;
|
|
332
|
+
|
|
333
|
+
// Create tracker
|
|
334
|
+
let tracker = Arc::new(CostTracker::new());
|
|
335
|
+
|
|
336
|
+
// Track a request
|
|
337
|
+
tracker.track_request("gpt-4o-mini", 1000, 500);
|
|
338
|
+
|
|
339
|
+
// Query costs
|
|
340
|
+
let tool = CostTool::new(tracker.clone());
|
|
341
|
+
let result = tool.execute(serde_json::json!({
|
|
342
|
+
"action": "get"
|
|
343
|
+
})).await?;
|
|
344
|
+
|
|
345
|
+
// Reset metrics
|
|
346
|
+
let result = tool.execute(serde_json::json!({
|
|
347
|
+
"action": "reset"
|
|
348
|
+
})).await?;
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Parameters
|
|
352
|
+
|
|
353
|
+
| Parameter | Type | Required | Description |
|
|
354
|
+
|-----------|------|----------|-------------|
|
|
355
|
+
| `action` | string | No | `"get"` or `"reset"` (default: get) |
|
|
356
|
+
|
|
357
|
+
### Output
|
|
358
|
+
|
|
359
|
+
```json
|
|
360
|
+
{
|
|
361
|
+
"success": true,
|
|
362
|
+
"metrics": {
|
|
363
|
+
"total_requests": 42,
|
|
364
|
+
"total_input_tokens": 15000,
|
|
365
|
+
"total_output_tokens": 8000,
|
|
366
|
+
"total_cost_usd": 0.045,
|
|
367
|
+
"requests_by_model": {
|
|
368
|
+
"gpt-4o-mini": 40,
|
|
369
|
+
"claude-3-sonnet": 2
|
|
370
|
+
},
|
|
371
|
+
"cost_by_model": {
|
|
372
|
+
"gpt-4o-mini": 0.015,
|
|
373
|
+
"claude-3-sonnet": 0.030
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Supported Models
|
|
380
|
+
|
|
381
|
+
Pricing is built-in for:
|
|
382
|
+
- OpenAI: `gpt-4o`, `gpt-4o-mini`, `gpt-4-turbo`
|
|
383
|
+
- Anthropic: `claude-3-opus`, `claude-3-sonnet`
|
|
384
|
+
- Google: `gemini-pro`
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## Tool Trait
|
|
389
|
+
|
|
390
|
+
All tools implement the `Tool` trait:
|
|
391
|
+
|
|
392
|
+
```rust
|
|
393
|
+
use enact_core::tool::Tool;
|
|
394
|
+
use async_trait::async_trait;
|
|
395
|
+
use serde_json::Value;
|
|
396
|
+
|
|
397
|
+
#[async_trait]
|
|
398
|
+
pub trait Tool: Send + Sync {
|
|
399
|
+
/// Tool name (used by LLM to invoke)
|
|
400
|
+
fn name(&self) -> &str;
|
|
401
|
+
|
|
402
|
+
/// Description (shown to LLM)
|
|
403
|
+
fn description(&self) -> &str;
|
|
404
|
+
|
|
405
|
+
/// JSON Schema for parameters
|
|
406
|
+
fn parameters_schema(&self) -> Value;
|
|
407
|
+
|
|
408
|
+
/// Whether tool needs network
|
|
409
|
+
fn requires_network(&self) -> bool { true }
|
|
410
|
+
|
|
411
|
+
/// Execute the tool
|
|
412
|
+
async fn execute(&self, args: Value) -> anyhow::Result<Value>;
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## Error Handling
|
|
419
|
+
|
|
420
|
+
All tools return structured errors:
|
|
421
|
+
|
|
422
|
+
```rust
|
|
423
|
+
match tool.execute(args).await {
|
|
424
|
+
Ok(result) => {
|
|
425
|
+
if result["success"].as_bool().unwrap_or(false) {
|
|
426
|
+
// Tool executed successfully
|
|
427
|
+
println!("Output: {}", result["stdout"]);
|
|
428
|
+
} else {
|
|
429
|
+
// Tool executed but operation failed
|
|
430
|
+
eprintln!("Error: {}", result["error"]);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
Err(e) => {
|
|
434
|
+
// Tool execution failed
|
|
435
|
+
eprintln!("Tool error: {}", e);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Security Best Practices
|
|
443
|
+
|
|
444
|
+
1. **Path Validation**: All file tools prevent directory traversal
|
|
445
|
+
2. **Timeouts**: Shell and HTTP tools have timeouts to prevent hangs
|
|
446
|
+
3. **Size Limits**: File reads limited to 10MB, HTTP responses to 10MB
|
|
447
|
+
4. **Workspace Boundaries**: Tools operate within workspace directory
|
|
448
|
+
5. **No Secrets**: Tools don't log or expose sensitive data
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## Testing
|
|
453
|
+
|
|
454
|
+
All tools have comprehensive tests:
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
# Run tool tests
|
|
458
|
+
cargo test -p enact-core filesystem
|
|
459
|
+
cargo test -p enact-core shell
|
|
460
|
+
cargo test -p enact-core git
|
|
461
|
+
cargo test -p enact-core web_search
|
|
462
|
+
cargo test -p enact-core http
|
|
463
|
+
cargo test -p enact-core cost
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
**Total: 694 tests passing** ✅
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## MCP vs Built-in Tools
|
|
471
|
+
|
|
472
|
+
**Use Built-in Tools for:**
|
|
473
|
+
- ✅ File system operations (file_read, file_write)
|
|
474
|
+
- ✅ Shell commands
|
|
475
|
+
- ✅ Git operations
|
|
476
|
+
- ✅ Cost tracking
|
|
477
|
+
- ✅ Memory operations (via enact-memory crate)
|
|
478
|
+
- ✅ Cron jobs (via enact-cron crate)
|
|
479
|
+
|
|
480
|
+
**Use MCP Tools for:**
|
|
481
|
+
- 🔗 External APIs (GitHub, Slack, Notion)
|
|
482
|
+
- 🔗 Third-party services
|
|
483
|
+
- 🔗 Non-Enact integrations
|
|
484
|
+
|
|
485
|
+
**Built-in tools are faster, more secure, and don't require external dependencies!**
|