agentpool 2.1.9__py3-none-any.whl
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.
Potentially problematic release.
This version of agentpool might be problematic. Click here for more details.
- acp/README.md +64 -0
- acp/__init__.py +172 -0
- acp/__main__.py +10 -0
- acp/acp_requests.py +285 -0
- acp/agent/__init__.py +6 -0
- acp/agent/connection.py +256 -0
- acp/agent/implementations/__init__.py +6 -0
- acp/agent/implementations/debug_server/__init__.py +1 -0
- acp/agent/implementations/debug_server/cli.py +79 -0
- acp/agent/implementations/debug_server/debug.html +234 -0
- acp/agent/implementations/debug_server/debug_server.py +496 -0
- acp/agent/implementations/testing.py +91 -0
- acp/agent/protocol.py +65 -0
- acp/bridge/README.md +162 -0
- acp/bridge/__init__.py +6 -0
- acp/bridge/__main__.py +91 -0
- acp/bridge/bridge.py +246 -0
- acp/bridge/py.typed +0 -0
- acp/bridge/settings.py +15 -0
- acp/client/__init__.py +7 -0
- acp/client/connection.py +251 -0
- acp/client/implementations/__init__.py +7 -0
- acp/client/implementations/default_client.py +185 -0
- acp/client/implementations/headless_client.py +266 -0
- acp/client/implementations/noop_client.py +110 -0
- acp/client/protocol.py +61 -0
- acp/connection.py +280 -0
- acp/exceptions.py +46 -0
- acp/filesystem.py +524 -0
- acp/notifications.py +832 -0
- acp/py.typed +0 -0
- acp/schema/__init__.py +265 -0
- acp/schema/agent_plan.py +30 -0
- acp/schema/agent_requests.py +126 -0
- acp/schema/agent_responses.py +256 -0
- acp/schema/base.py +39 -0
- acp/schema/capabilities.py +230 -0
- acp/schema/client_requests.py +247 -0
- acp/schema/client_responses.py +96 -0
- acp/schema/common.py +81 -0
- acp/schema/content_blocks.py +188 -0
- acp/schema/mcp.py +82 -0
- acp/schema/messages.py +171 -0
- acp/schema/notifications.py +82 -0
- acp/schema/protocol_stuff.md +3 -0
- acp/schema/session_state.py +160 -0
- acp/schema/session_updates.py +419 -0
- acp/schema/slash_commands.py +51 -0
- acp/schema/terminal.py +15 -0
- acp/schema/tool_call.py +347 -0
- acp/stdio.py +250 -0
- acp/task/__init__.py +53 -0
- acp/task/debug.py +197 -0
- acp/task/dispatcher.py +93 -0
- acp/task/queue.py +69 -0
- acp/task/sender.py +82 -0
- acp/task/state.py +87 -0
- acp/task/supervisor.py +93 -0
- acp/terminal_handle.py +30 -0
- acp/tool_call_reporter.py +199 -0
- acp/tool_call_state.py +178 -0
- acp/transports.py +104 -0
- acp/utils.py +240 -0
- agentpool/__init__.py +63 -0
- agentpool/__main__.py +7 -0
- agentpool/agents/__init__.py +30 -0
- agentpool/agents/acp_agent/__init__.py +5 -0
- agentpool/agents/acp_agent/acp_agent.py +837 -0
- agentpool/agents/acp_agent/acp_converters.py +294 -0
- agentpool/agents/acp_agent/client_handler.py +317 -0
- agentpool/agents/acp_agent/session_state.py +44 -0
- agentpool/agents/agent.py +1264 -0
- agentpool/agents/agui_agent/__init__.py +19 -0
- agentpool/agents/agui_agent/agui_agent.py +677 -0
- agentpool/agents/agui_agent/agui_converters.py +423 -0
- agentpool/agents/agui_agent/chunk_transformer.py +204 -0
- agentpool/agents/agui_agent/event_types.py +83 -0
- agentpool/agents/agui_agent/helpers.py +192 -0
- agentpool/agents/architect.py +71 -0
- agentpool/agents/base_agent.py +177 -0
- agentpool/agents/claude_code_agent/__init__.py +11 -0
- agentpool/agents/claude_code_agent/claude_code_agent.py +1021 -0
- agentpool/agents/claude_code_agent/converters.py +243 -0
- agentpool/agents/context.py +105 -0
- agentpool/agents/events/__init__.py +61 -0
- agentpool/agents/events/builtin_handlers.py +129 -0
- agentpool/agents/events/event_emitter.py +320 -0
- agentpool/agents/events/events.py +561 -0
- agentpool/agents/events/tts_handlers.py +186 -0
- agentpool/agents/interactions.py +419 -0
- agentpool/agents/slashed_agent.py +244 -0
- agentpool/agents/sys_prompts.py +178 -0
- agentpool/agents/tool_wrapping.py +184 -0
- agentpool/base_provider.py +28 -0
- agentpool/common_types.py +226 -0
- agentpool/config_resources/__init__.py +16 -0
- agentpool/config_resources/acp_assistant.yml +24 -0
- agentpool/config_resources/agents.yml +109 -0
- agentpool/config_resources/agents_template.yml +18 -0
- agentpool/config_resources/agui_test.yml +18 -0
- agentpool/config_resources/claude_code_agent.yml +16 -0
- agentpool/config_resources/claude_style_subagent.md +30 -0
- agentpool/config_resources/external_acp_agents.yml +77 -0
- agentpool/config_resources/opencode_style_subagent.md +19 -0
- agentpool/config_resources/tts_test_agents.yml +78 -0
- agentpool/delegation/__init__.py +8 -0
- agentpool/delegation/base_team.py +504 -0
- agentpool/delegation/message_flow_tracker.py +39 -0
- agentpool/delegation/pool.py +1129 -0
- agentpool/delegation/team.py +325 -0
- agentpool/delegation/teamrun.py +343 -0
- agentpool/docs/__init__.py +5 -0
- agentpool/docs/gen_examples.py +42 -0
- agentpool/docs/utils.py +370 -0
- agentpool/functional/__init__.py +20 -0
- agentpool/functional/py.typed +0 -0
- agentpool/functional/run.py +80 -0
- agentpool/functional/structure.py +136 -0
- agentpool/hooks/__init__.py +20 -0
- agentpool/hooks/agent_hooks.py +247 -0
- agentpool/hooks/base.py +119 -0
- agentpool/hooks/callable.py +140 -0
- agentpool/hooks/command.py +180 -0
- agentpool/hooks/prompt.py +122 -0
- agentpool/jinja_filters.py +132 -0
- agentpool/log.py +224 -0
- agentpool/mcp_server/__init__.py +17 -0
- agentpool/mcp_server/client.py +429 -0
- agentpool/mcp_server/constants.py +32 -0
- agentpool/mcp_server/conversions.py +172 -0
- agentpool/mcp_server/helpers.py +47 -0
- agentpool/mcp_server/manager.py +232 -0
- agentpool/mcp_server/message_handler.py +164 -0
- agentpool/mcp_server/registries/__init__.py +1 -0
- agentpool/mcp_server/registries/official_registry_client.py +345 -0
- agentpool/mcp_server/registries/pulsemcp_client.py +88 -0
- agentpool/mcp_server/tool_bridge.py +548 -0
- agentpool/messaging/__init__.py +58 -0
- agentpool/messaging/compaction.py +928 -0
- agentpool/messaging/connection_manager.py +319 -0
- agentpool/messaging/context.py +66 -0
- agentpool/messaging/event_manager.py +426 -0
- agentpool/messaging/events.py +39 -0
- agentpool/messaging/message_container.py +209 -0
- agentpool/messaging/message_history.py +491 -0
- agentpool/messaging/messagenode.py +377 -0
- agentpool/messaging/messages.py +655 -0
- agentpool/messaging/processing.py +76 -0
- agentpool/mime_utils.py +95 -0
- agentpool/models/__init__.py +21 -0
- agentpool/models/acp_agents/__init__.py +22 -0
- agentpool/models/acp_agents/base.py +308 -0
- agentpool/models/acp_agents/mcp_capable.py +790 -0
- agentpool/models/acp_agents/non_mcp.py +842 -0
- agentpool/models/agents.py +450 -0
- agentpool/models/agui_agents.py +89 -0
- agentpool/models/claude_code_agents.py +238 -0
- agentpool/models/file_agents.py +116 -0
- agentpool/models/file_parsing.py +367 -0
- agentpool/models/manifest.py +658 -0
- agentpool/observability/__init__.py +9 -0
- agentpool/observability/observability_registry.py +97 -0
- agentpool/prompts/__init__.py +1 -0
- agentpool/prompts/base.py +27 -0
- agentpool/prompts/builtin_provider.py +75 -0
- agentpool/prompts/conversion_manager.py +95 -0
- agentpool/prompts/convert.py +96 -0
- agentpool/prompts/manager.py +204 -0
- agentpool/prompts/parts/zed.md +33 -0
- agentpool/prompts/prompts.py +581 -0
- agentpool/py.typed +0 -0
- agentpool/queries/tree-sitter-language-pack/README.md +7 -0
- agentpool/queries/tree-sitter-language-pack/arduino-tags.scm +5 -0
- agentpool/queries/tree-sitter-language-pack/c-tags.scm +9 -0
- agentpool/queries/tree-sitter-language-pack/chatito-tags.scm +16 -0
- agentpool/queries/tree-sitter-language-pack/clojure-tags.scm +7 -0
- agentpool/queries/tree-sitter-language-pack/commonlisp-tags.scm +122 -0
- agentpool/queries/tree-sitter-language-pack/cpp-tags.scm +15 -0
- agentpool/queries/tree-sitter-language-pack/csharp-tags.scm +26 -0
- agentpool/queries/tree-sitter-language-pack/d-tags.scm +26 -0
- agentpool/queries/tree-sitter-language-pack/dart-tags.scm +92 -0
- agentpool/queries/tree-sitter-language-pack/elisp-tags.scm +5 -0
- agentpool/queries/tree-sitter-language-pack/elixir-tags.scm +54 -0
- agentpool/queries/tree-sitter-language-pack/elm-tags.scm +19 -0
- agentpool/queries/tree-sitter-language-pack/gleam-tags.scm +41 -0
- agentpool/queries/tree-sitter-language-pack/go-tags.scm +42 -0
- agentpool/queries/tree-sitter-language-pack/java-tags.scm +20 -0
- agentpool/queries/tree-sitter-language-pack/javascript-tags.scm +88 -0
- agentpool/queries/tree-sitter-language-pack/lua-tags.scm +34 -0
- agentpool/queries/tree-sitter-language-pack/matlab-tags.scm +10 -0
- agentpool/queries/tree-sitter-language-pack/ocaml-tags.scm +115 -0
- agentpool/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +98 -0
- agentpool/queries/tree-sitter-language-pack/pony-tags.scm +39 -0
- agentpool/queries/tree-sitter-language-pack/properties-tags.scm +5 -0
- agentpool/queries/tree-sitter-language-pack/python-tags.scm +14 -0
- agentpool/queries/tree-sitter-language-pack/r-tags.scm +21 -0
- agentpool/queries/tree-sitter-language-pack/racket-tags.scm +12 -0
- agentpool/queries/tree-sitter-language-pack/ruby-tags.scm +64 -0
- agentpool/queries/tree-sitter-language-pack/rust-tags.scm +60 -0
- agentpool/queries/tree-sitter-language-pack/solidity-tags.scm +43 -0
- agentpool/queries/tree-sitter-language-pack/swift-tags.scm +51 -0
- agentpool/queries/tree-sitter-language-pack/udev-tags.scm +20 -0
- agentpool/queries/tree-sitter-languages/README.md +24 -0
- agentpool/queries/tree-sitter-languages/c-tags.scm +9 -0
- agentpool/queries/tree-sitter-languages/c_sharp-tags.scm +46 -0
- agentpool/queries/tree-sitter-languages/cpp-tags.scm +15 -0
- agentpool/queries/tree-sitter-languages/dart-tags.scm +91 -0
- agentpool/queries/tree-sitter-languages/elisp-tags.scm +8 -0
- agentpool/queries/tree-sitter-languages/elixir-tags.scm +54 -0
- agentpool/queries/tree-sitter-languages/elm-tags.scm +19 -0
- agentpool/queries/tree-sitter-languages/fortran-tags.scm +15 -0
- agentpool/queries/tree-sitter-languages/go-tags.scm +30 -0
- agentpool/queries/tree-sitter-languages/haskell-tags.scm +3 -0
- agentpool/queries/tree-sitter-languages/hcl-tags.scm +77 -0
- agentpool/queries/tree-sitter-languages/java-tags.scm +20 -0
- agentpool/queries/tree-sitter-languages/javascript-tags.scm +88 -0
- agentpool/queries/tree-sitter-languages/julia-tags.scm +60 -0
- agentpool/queries/tree-sitter-languages/kotlin-tags.scm +27 -0
- agentpool/queries/tree-sitter-languages/matlab-tags.scm +10 -0
- agentpool/queries/tree-sitter-languages/ocaml-tags.scm +115 -0
- agentpool/queries/tree-sitter-languages/ocaml_interface-tags.scm +98 -0
- agentpool/queries/tree-sitter-languages/php-tags.scm +26 -0
- agentpool/queries/tree-sitter-languages/python-tags.scm +12 -0
- agentpool/queries/tree-sitter-languages/ql-tags.scm +26 -0
- agentpool/queries/tree-sitter-languages/ruby-tags.scm +64 -0
- agentpool/queries/tree-sitter-languages/rust-tags.scm +60 -0
- agentpool/queries/tree-sitter-languages/scala-tags.scm +65 -0
- agentpool/queries/tree-sitter-languages/typescript-tags.scm +41 -0
- agentpool/queries/tree-sitter-languages/zig-tags.scm +3 -0
- agentpool/repomap.py +1231 -0
- agentpool/resource_providers/__init__.py +17 -0
- agentpool/resource_providers/aggregating.py +54 -0
- agentpool/resource_providers/base.py +172 -0
- agentpool/resource_providers/codemode/__init__.py +9 -0
- agentpool/resource_providers/codemode/code_executor.py +215 -0
- agentpool/resource_providers/codemode/default_prompt.py +19 -0
- agentpool/resource_providers/codemode/helpers.py +83 -0
- agentpool/resource_providers/codemode/progress_executor.py +212 -0
- agentpool/resource_providers/codemode/provider.py +150 -0
- agentpool/resource_providers/codemode/remote_mcp_execution.py +143 -0
- agentpool/resource_providers/codemode/remote_provider.py +171 -0
- agentpool/resource_providers/filtering.py +42 -0
- agentpool/resource_providers/mcp_provider.py +246 -0
- agentpool/resource_providers/plan_provider.py +196 -0
- agentpool/resource_providers/pool.py +69 -0
- agentpool/resource_providers/static.py +289 -0
- agentpool/running/__init__.py +20 -0
- agentpool/running/decorators.py +56 -0
- agentpool/running/discovery.py +101 -0
- agentpool/running/executor.py +284 -0
- agentpool/running/injection.py +111 -0
- agentpool/running/py.typed +0 -0
- agentpool/running/run_nodes.py +87 -0
- agentpool/server.py +122 -0
- agentpool/sessions/__init__.py +13 -0
- agentpool/sessions/manager.py +302 -0
- agentpool/sessions/models.py +71 -0
- agentpool/sessions/session.py +239 -0
- agentpool/sessions/store.py +163 -0
- agentpool/skills/__init__.py +5 -0
- agentpool/skills/manager.py +120 -0
- agentpool/skills/registry.py +210 -0
- agentpool/skills/skill.py +36 -0
- agentpool/storage/__init__.py +17 -0
- agentpool/storage/manager.py +419 -0
- agentpool/storage/serialization.py +136 -0
- agentpool/talk/__init__.py +13 -0
- agentpool/talk/registry.py +128 -0
- agentpool/talk/stats.py +159 -0
- agentpool/talk/talk.py +604 -0
- agentpool/tasks/__init__.py +20 -0
- agentpool/tasks/exceptions.py +25 -0
- agentpool/tasks/registry.py +33 -0
- agentpool/testing.py +129 -0
- agentpool/text_templates/__init__.py +39 -0
- agentpool/text_templates/system_prompt.jinja +30 -0
- agentpool/text_templates/tool_call_default.jinja +13 -0
- agentpool/text_templates/tool_call_markdown.jinja +25 -0
- agentpool/text_templates/tool_call_simple.jinja +5 -0
- agentpool/tools/__init__.py +16 -0
- agentpool/tools/base.py +269 -0
- agentpool/tools/exceptions.py +9 -0
- agentpool/tools/manager.py +255 -0
- agentpool/tools/tool_call_info.py +87 -0
- agentpool/ui/__init__.py +2 -0
- agentpool/ui/base.py +89 -0
- agentpool/ui/mock_provider.py +81 -0
- agentpool/ui/stdlib_provider.py +150 -0
- agentpool/utils/__init__.py +44 -0
- agentpool/utils/baseregistry.py +185 -0
- agentpool/utils/count_tokens.py +62 -0
- agentpool/utils/dag.py +184 -0
- agentpool/utils/importing.py +206 -0
- agentpool/utils/inspection.py +334 -0
- agentpool/utils/model_capabilities.py +25 -0
- agentpool/utils/network.py +28 -0
- agentpool/utils/now.py +22 -0
- agentpool/utils/parse_time.py +87 -0
- agentpool/utils/result_utils.py +35 -0
- agentpool/utils/signatures.py +305 -0
- agentpool/utils/streams.py +112 -0
- agentpool/utils/tasks.py +186 -0
- agentpool/vfs_registry.py +250 -0
- agentpool-2.1.9.dist-info/METADATA +336 -0
- agentpool-2.1.9.dist-info/RECORD +474 -0
- agentpool-2.1.9.dist-info/WHEEL +4 -0
- agentpool-2.1.9.dist-info/entry_points.txt +14 -0
- agentpool-2.1.9.dist-info/licenses/LICENSE +22 -0
- agentpool_cli/__init__.py +34 -0
- agentpool_cli/__main__.py +66 -0
- agentpool_cli/agent.py +175 -0
- agentpool_cli/cli_types.py +23 -0
- agentpool_cli/common.py +163 -0
- agentpool_cli/create.py +175 -0
- agentpool_cli/history.py +217 -0
- agentpool_cli/log.py +78 -0
- agentpool_cli/py.typed +0 -0
- agentpool_cli/run.py +84 -0
- agentpool_cli/serve_acp.py +177 -0
- agentpool_cli/serve_api.py +69 -0
- agentpool_cli/serve_mcp.py +74 -0
- agentpool_cli/serve_vercel.py +233 -0
- agentpool_cli/store.py +171 -0
- agentpool_cli/task.py +84 -0
- agentpool_cli/utils.py +104 -0
- agentpool_cli/watch.py +54 -0
- agentpool_commands/__init__.py +180 -0
- agentpool_commands/agents.py +199 -0
- agentpool_commands/base.py +45 -0
- agentpool_commands/commands.py +58 -0
- agentpool_commands/completers.py +110 -0
- agentpool_commands/connections.py +175 -0
- agentpool_commands/markdown_utils.py +31 -0
- agentpool_commands/models.py +62 -0
- agentpool_commands/prompts.py +78 -0
- agentpool_commands/py.typed +0 -0
- agentpool_commands/read.py +77 -0
- agentpool_commands/resources.py +210 -0
- agentpool_commands/session.py +48 -0
- agentpool_commands/tools.py +269 -0
- agentpool_commands/utils.py +189 -0
- agentpool_commands/workers.py +163 -0
- agentpool_config/__init__.py +53 -0
- agentpool_config/builtin_tools.py +265 -0
- agentpool_config/commands.py +237 -0
- agentpool_config/conditions.py +301 -0
- agentpool_config/converters.py +30 -0
- agentpool_config/durable.py +331 -0
- agentpool_config/event_handlers.py +600 -0
- agentpool_config/events.py +153 -0
- agentpool_config/forward_targets.py +251 -0
- agentpool_config/hook_conditions.py +331 -0
- agentpool_config/hooks.py +241 -0
- agentpool_config/jinja.py +206 -0
- agentpool_config/knowledge.py +41 -0
- agentpool_config/loaders.py +350 -0
- agentpool_config/mcp_server.py +243 -0
- agentpool_config/nodes.py +202 -0
- agentpool_config/observability.py +191 -0
- agentpool_config/output_types.py +55 -0
- agentpool_config/pool_server.py +267 -0
- agentpool_config/prompt_hubs.py +105 -0
- agentpool_config/prompts.py +185 -0
- agentpool_config/py.typed +0 -0
- agentpool_config/resources.py +33 -0
- agentpool_config/session.py +119 -0
- agentpool_config/skills.py +17 -0
- agentpool_config/storage.py +288 -0
- agentpool_config/system_prompts.py +190 -0
- agentpool_config/task.py +162 -0
- agentpool_config/teams.py +52 -0
- agentpool_config/tools.py +112 -0
- agentpool_config/toolsets.py +1033 -0
- agentpool_config/workers.py +86 -0
- agentpool_prompts/__init__.py +1 -0
- agentpool_prompts/braintrust_hub.py +235 -0
- agentpool_prompts/fabric.py +75 -0
- agentpool_prompts/langfuse_hub.py +79 -0
- agentpool_prompts/promptlayer_provider.py +59 -0
- agentpool_prompts/py.typed +0 -0
- agentpool_server/__init__.py +9 -0
- agentpool_server/a2a_server/__init__.py +5 -0
- agentpool_server/a2a_server/a2a_types.py +41 -0
- agentpool_server/a2a_server/server.py +190 -0
- agentpool_server/a2a_server/storage.py +81 -0
- agentpool_server/acp_server/__init__.py +22 -0
- agentpool_server/acp_server/acp_agent.py +786 -0
- agentpool_server/acp_server/acp_tools.py +43 -0
- agentpool_server/acp_server/commands/__init__.py +18 -0
- agentpool_server/acp_server/commands/acp_commands.py +594 -0
- agentpool_server/acp_server/commands/debug_commands.py +376 -0
- agentpool_server/acp_server/commands/docs_commands/__init__.py +39 -0
- agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +169 -0
- agentpool_server/acp_server/commands/docs_commands/get_schema.py +176 -0
- agentpool_server/acp_server/commands/docs_commands/get_source.py +110 -0
- agentpool_server/acp_server/commands/docs_commands/git_diff.py +111 -0
- agentpool_server/acp_server/commands/docs_commands/helpers.py +33 -0
- agentpool_server/acp_server/commands/docs_commands/url_to_markdown.py +90 -0
- agentpool_server/acp_server/commands/spawn.py +210 -0
- agentpool_server/acp_server/converters.py +235 -0
- agentpool_server/acp_server/input_provider.py +338 -0
- agentpool_server/acp_server/server.py +288 -0
- agentpool_server/acp_server/session.py +969 -0
- agentpool_server/acp_server/session_manager.py +313 -0
- agentpool_server/acp_server/syntax_detection.py +250 -0
- agentpool_server/acp_server/zed_tools.md +90 -0
- agentpool_server/aggregating_server.py +309 -0
- agentpool_server/agui_server/__init__.py +11 -0
- agentpool_server/agui_server/server.py +128 -0
- agentpool_server/base.py +189 -0
- agentpool_server/http_server.py +164 -0
- agentpool_server/mcp_server/__init__.py +6 -0
- agentpool_server/mcp_server/server.py +314 -0
- agentpool_server/mcp_server/zed_wrapper.py +110 -0
- agentpool_server/openai_api_server/__init__.py +5 -0
- agentpool_server/openai_api_server/completions/__init__.py +1 -0
- agentpool_server/openai_api_server/completions/helpers.py +81 -0
- agentpool_server/openai_api_server/completions/models.py +98 -0
- agentpool_server/openai_api_server/responses/__init__.py +1 -0
- agentpool_server/openai_api_server/responses/helpers.py +74 -0
- agentpool_server/openai_api_server/responses/models.py +96 -0
- agentpool_server/openai_api_server/server.py +242 -0
- agentpool_server/py.typed +0 -0
- agentpool_storage/__init__.py +9 -0
- agentpool_storage/base.py +310 -0
- agentpool_storage/file_provider.py +378 -0
- agentpool_storage/formatters.py +129 -0
- agentpool_storage/memory_provider.py +396 -0
- agentpool_storage/models.py +108 -0
- agentpool_storage/py.typed +0 -0
- agentpool_storage/session_store.py +262 -0
- agentpool_storage/sql_provider/__init__.py +21 -0
- agentpool_storage/sql_provider/cli.py +146 -0
- agentpool_storage/sql_provider/models.py +249 -0
- agentpool_storage/sql_provider/queries.py +15 -0
- agentpool_storage/sql_provider/sql_provider.py +444 -0
- agentpool_storage/sql_provider/utils.py +234 -0
- agentpool_storage/text_log_provider.py +275 -0
- agentpool_toolsets/__init__.py +15 -0
- agentpool_toolsets/builtin/__init__.py +33 -0
- agentpool_toolsets/builtin/agent_management.py +239 -0
- agentpool_toolsets/builtin/chain.py +288 -0
- agentpool_toolsets/builtin/code.py +398 -0
- agentpool_toolsets/builtin/debug.py +291 -0
- agentpool_toolsets/builtin/execution_environment.py +381 -0
- agentpool_toolsets/builtin/file_edit/__init__.py +11 -0
- agentpool_toolsets/builtin/file_edit/file_edit.py +747 -0
- agentpool_toolsets/builtin/file_edit/fuzzy_matcher/__init__.py +5 -0
- agentpool_toolsets/builtin/file_edit/fuzzy_matcher/example_usage.py +311 -0
- agentpool_toolsets/builtin/file_edit/fuzzy_matcher/streaming_fuzzy_matcher.py +443 -0
- agentpool_toolsets/builtin/history.py +36 -0
- agentpool_toolsets/builtin/integration.py +85 -0
- agentpool_toolsets/builtin/skills.py +77 -0
- agentpool_toolsets/builtin/subagent_tools.py +324 -0
- agentpool_toolsets/builtin/tool_management.py +90 -0
- agentpool_toolsets/builtin/user_interaction.py +52 -0
- agentpool_toolsets/builtin/workers.py +128 -0
- agentpool_toolsets/composio_toolset.py +96 -0
- agentpool_toolsets/config_creation.py +192 -0
- agentpool_toolsets/entry_points.py +47 -0
- agentpool_toolsets/fsspec_toolset/__init__.py +7 -0
- agentpool_toolsets/fsspec_toolset/diagnostics.py +115 -0
- agentpool_toolsets/fsspec_toolset/grep.py +450 -0
- agentpool_toolsets/fsspec_toolset/helpers.py +631 -0
- agentpool_toolsets/fsspec_toolset/streaming_diff_parser.py +249 -0
- agentpool_toolsets/fsspec_toolset/toolset.py +1384 -0
- agentpool_toolsets/mcp_run_toolset.py +61 -0
- agentpool_toolsets/notifications.py +146 -0
- agentpool_toolsets/openapi.py +118 -0
- agentpool_toolsets/py.typed +0 -0
- agentpool_toolsets/search_toolset.py +202 -0
- agentpool_toolsets/semantic_memory_toolset.py +536 -0
- agentpool_toolsets/streaming_tools.py +265 -0
- agentpool_toolsets/vfs_toolset.py +124 -0
agentpool/testing.py
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""Testing utilities for end-to-end ACP testing.
|
|
2
|
+
|
|
3
|
+
This module provides a lightweight test harness for running end-to-end tests
|
|
4
|
+
against the agentpool ACP server. It uses ACPAgent as the client, connecting
|
|
5
|
+
to a agentpool serve-acp subprocess.
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
```python
|
|
9
|
+
async def test_basic_prompt():
|
|
10
|
+
async with acp_test_session("tests/fixtures/simple.yml") as agent:
|
|
11
|
+
result = await agent.run("Say hello")
|
|
12
|
+
assert result.content
|
|
13
|
+
|
|
14
|
+
async def test_filesystem_tool():
|
|
15
|
+
async with acp_test_session(
|
|
16
|
+
"tests/fixtures/with_tools.yml",
|
|
17
|
+
file_access=True,
|
|
18
|
+
terminal_access=True,
|
|
19
|
+
) as agent:
|
|
20
|
+
result = await agent.run("List files in the current directory")
|
|
21
|
+
assert "pyproject.toml" in result.content
|
|
22
|
+
```
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from contextlib import asynccontextmanager
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
from typing import TYPE_CHECKING, Any
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from collections.abc import AsyncIterator, Sequence
|
|
34
|
+
|
|
35
|
+
from evented.configs import EventConfig
|
|
36
|
+
|
|
37
|
+
from agentpool.agents.acp_agent import ACPAgent
|
|
38
|
+
from agentpool.common_types import BuiltinEventHandlerType, IndividualEventHandler
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@asynccontextmanager
|
|
42
|
+
async def acp_test_session(
|
|
43
|
+
config: str | Path | None = None,
|
|
44
|
+
*,
|
|
45
|
+
file_access: bool = True,
|
|
46
|
+
terminal_access: bool = True,
|
|
47
|
+
providers: list[str] | None = None,
|
|
48
|
+
debug_messages: bool = False,
|
|
49
|
+
debug_file: str | None = None,
|
|
50
|
+
debug_commands: bool = False,
|
|
51
|
+
agent: str | None = None,
|
|
52
|
+
load_skills: bool = False,
|
|
53
|
+
cwd: str | Path | None = None,
|
|
54
|
+
event_configs: Sequence[EventConfig] | None = None,
|
|
55
|
+
event_handlers: Sequence[IndividualEventHandler | BuiltinEventHandlerType] | None = None,
|
|
56
|
+
) -> AsyncIterator[ACPAgent[Any]]:
|
|
57
|
+
"""Create an end-to-end ACP test session using agentpool as server.
|
|
58
|
+
|
|
59
|
+
This context manager starts an ACPAgent connected to a agentpool serve-acp
|
|
60
|
+
subprocess, enabling full round-trip testing of the ACP protocol.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
config: Path to agent configuration YAML file. If None, uses default config.
|
|
64
|
+
file_access: Enable file system access for agents.
|
|
65
|
+
terminal_access: Enable terminal access for agents.
|
|
66
|
+
providers: Model providers to search for models.
|
|
67
|
+
debug_messages: Save raw JSON-RPC messages to debug file.
|
|
68
|
+
debug_file: File path for JSON-RPC debug messages.
|
|
69
|
+
debug_commands: Enable debug slash commands for testing.
|
|
70
|
+
agent: Name of specific agent to use from config.
|
|
71
|
+
load_skills: Load client-side skills from .claude/skills directory.
|
|
72
|
+
cwd: Working directory for the ACP server subprocess.
|
|
73
|
+
event_configs: Event configurations for the agent.
|
|
74
|
+
event_handlers: Event handlers for the agent (e.g., ["detailed"] for logging).
|
|
75
|
+
|
|
76
|
+
Yields:
|
|
77
|
+
ACPAgent instance connected to the test server.
|
|
78
|
+
|
|
79
|
+
Example:
|
|
80
|
+
```python
|
|
81
|
+
async def test_echo():
|
|
82
|
+
async with acp_test_session("my_config.yml") as agent:
|
|
83
|
+
result = await agent.run("Hello!")
|
|
84
|
+
assert "Hello" in result.content
|
|
85
|
+
```
|
|
86
|
+
"""
|
|
87
|
+
from agentpool.agents.acp_agent import ACPAgent
|
|
88
|
+
|
|
89
|
+
# Build command line arguments
|
|
90
|
+
args = ["run", "agentpool", "serve-acp"]
|
|
91
|
+
|
|
92
|
+
if config is not None:
|
|
93
|
+
args.extend(["--config", str(config)])
|
|
94
|
+
|
|
95
|
+
if not file_access:
|
|
96
|
+
args.append("--no-file-access")
|
|
97
|
+
|
|
98
|
+
if not terminal_access:
|
|
99
|
+
args.append("--no-terminal-access")
|
|
100
|
+
|
|
101
|
+
if providers:
|
|
102
|
+
for provider in providers:
|
|
103
|
+
args.extend(["--model-provider", provider])
|
|
104
|
+
|
|
105
|
+
if debug_messages:
|
|
106
|
+
args.append("--debug-messages")
|
|
107
|
+
|
|
108
|
+
if debug_file:
|
|
109
|
+
args.extend(["--debug-file", debug_file])
|
|
110
|
+
|
|
111
|
+
if debug_commands:
|
|
112
|
+
args.append("--debug-commands")
|
|
113
|
+
|
|
114
|
+
if agent:
|
|
115
|
+
args.extend(["--agent", agent])
|
|
116
|
+
|
|
117
|
+
if not load_skills:
|
|
118
|
+
args.append("--no-skills")
|
|
119
|
+
|
|
120
|
+
working_dir = str(cwd) if cwd else str(Path.cwd())
|
|
121
|
+
|
|
122
|
+
async with ACPAgent(
|
|
123
|
+
command="uv",
|
|
124
|
+
args=args,
|
|
125
|
+
cwd=working_dir,
|
|
126
|
+
event_configs=event_configs,
|
|
127
|
+
event_handlers=event_handlers,
|
|
128
|
+
) as acp_agent:
|
|
129
|
+
yield acp_agent
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Package resources for AgentPool configuration."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import importlib.resources
|
|
6
|
+
from functools import cache
|
|
7
|
+
from typing import Final, Literal
|
|
8
|
+
|
|
9
|
+
_RESOURCES = importlib.resources.files("agentpool.text_templates")
|
|
10
|
+
|
|
11
|
+
DEFAULT_SYSTEM_PROMPT: Final[str] = str(_RESOURCES / "system_prompt.jinja")
|
|
12
|
+
"""Path to the default system prompt template."""
|
|
13
|
+
|
|
14
|
+
FormatStyle = Literal["simple", "detailed", "markdown"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@cache
|
|
18
|
+
def get_system_prompt() -> str:
|
|
19
|
+
"""Get the default system prompt template content."""
|
|
20
|
+
return (_RESOURCES / "system_prompt.jinja").read_text()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@cache
|
|
24
|
+
def get_tool_call_template(style: FormatStyle) -> str:
|
|
25
|
+
"""Get tool call template by style."""
|
|
26
|
+
files = {
|
|
27
|
+
"simple": "tool_call_simple.jinja",
|
|
28
|
+
"detailed": "tool_call_default.jinja",
|
|
29
|
+
"markdown": "tool_call_markdown.jinja",
|
|
30
|
+
}
|
|
31
|
+
return (_RESOURCES / files[style]).read_text()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
"DEFAULT_SYSTEM_PROMPT",
|
|
36
|
+
"FormatStyle",
|
|
37
|
+
"get_system_prompt",
|
|
38
|
+
"get_tool_call_template",
|
|
39
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{%- if inject_agent_info and agent.name %}You are {{ agent.name }}{% if agent.description %}. {{ agent.description }}{% endif %}.
|
|
2
|
+
|
|
3
|
+
{% endif -%}
|
|
4
|
+
{%- if inject_tools != "off" -%}
|
|
5
|
+
{%- set tools = agent.tools.get_tools("enabled") -%}
|
|
6
|
+
{%- if tools %}
|
|
7
|
+
|
|
8
|
+
{%- if tool_usage_style == "strict" %}
|
|
9
|
+
You MUST use these tools to complete your tasks:
|
|
10
|
+
{%- else %}
|
|
11
|
+
You have access to these tools:
|
|
12
|
+
{%- endif %}
|
|
13
|
+
{% for tool in tools %}
|
|
14
|
+
- {{ tool.name }}{% if tool.description %}: {{ tool.description }}{% endif %}
|
|
15
|
+
{%- endfor %}
|
|
16
|
+
|
|
17
|
+
{%- if tool_usage_style == "strict" %}
|
|
18
|
+
Do not attempt to perform tasks without using appropriate tools.
|
|
19
|
+
{%- else %}
|
|
20
|
+
Use them when appropriate to complete your tasks.
|
|
21
|
+
{%- endif %}
|
|
22
|
+
|
|
23
|
+
{% endif -%}
|
|
24
|
+
{% endif -%}
|
|
25
|
+
{%- for prompt in prompts %}
|
|
26
|
+
{{ prompt|to_prompt if dynamic else prompt }}
|
|
27
|
+
{%- if not loop.last %}
|
|
28
|
+
|
|
29
|
+
{% endif %}
|
|
30
|
+
{%- endfor %}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
### Tool Call: {{ tool_name }}
|
|
2
|
+
|
|
3
|
+
**Arguments:**
|
|
4
|
+
{% for name, value in args.items() %}
|
|
5
|
+
- {{ name }}: {{ value|repr }}
|
|
6
|
+
{%- endfor %}
|
|
7
|
+
|
|
8
|
+
{%- if error %}
|
|
9
|
+
|
|
10
|
+
**Error:** {{ error }}
|
|
11
|
+
{%- endif %}
|
|
12
|
+
{%- if result %}
|
|
13
|
+
|
|
14
|
+
**Result:**
|
|
15
|
+
```
|
|
16
|
+
{{ result }}
|
|
17
|
+
```
|
|
18
|
+
{%- endif %}
|
|
19
|
+
|
|
20
|
+
{%- if show_timing and timing %}
|
|
21
|
+
*Execution time: {{ "%.2f"|format(timing) }}s*
|
|
22
|
+
{%- endif %}
|
|
23
|
+
{%- if agent_tool_name %}
|
|
24
|
+
*Agent: {{ agent_tool_name }}*
|
|
25
|
+
{%- endif %}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Tool implementations and related classes / functions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from agentpool.tools.base import Tool
|
|
6
|
+
from agentpool.tools.manager import ToolManager, ToolError
|
|
7
|
+
from agentpool.tools.tool_call_info import ToolCallInfo
|
|
8
|
+
from agentpool.skills.registry import SkillsRegistry
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"SkillsRegistry",
|
|
12
|
+
"Tool",
|
|
13
|
+
"ToolCallInfo",
|
|
14
|
+
"ToolError",
|
|
15
|
+
"ToolManager",
|
|
16
|
+
]
|
agentpool/tools/base.py
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""Base tool classes."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
import inspect
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
8
|
+
|
|
9
|
+
import logfire
|
|
10
|
+
from pydantic_ai.tools import Tool as PydanticAiTool
|
|
11
|
+
import schemez
|
|
12
|
+
|
|
13
|
+
from agentpool.log import get_logger
|
|
14
|
+
from agentpool.utils.inspection import (
|
|
15
|
+
dataclasses_no_defaults_repr,
|
|
16
|
+
execute,
|
|
17
|
+
get_fn_name,
|
|
18
|
+
get_fn_qualname,
|
|
19
|
+
)
|
|
20
|
+
from agentpool_config.tools import ToolHints
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from collections.abc import Awaitable, Callable
|
|
25
|
+
|
|
26
|
+
from mcp.types import Tool as MCPTool
|
|
27
|
+
from schemez import FunctionSchema, Property
|
|
28
|
+
|
|
29
|
+
from agentpool.common_types import ToolSource
|
|
30
|
+
from agentpool.tools.manager import ToolState
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
logger = get_logger(__name__)
|
|
34
|
+
ToolKind = Literal[
|
|
35
|
+
"read",
|
|
36
|
+
"edit",
|
|
37
|
+
"delete",
|
|
38
|
+
"move",
|
|
39
|
+
"search",
|
|
40
|
+
"execute",
|
|
41
|
+
"think",
|
|
42
|
+
"fetch",
|
|
43
|
+
"switch_mode",
|
|
44
|
+
"other",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass
|
|
49
|
+
class Tool[TOutputType = Any]:
|
|
50
|
+
"""Information about a registered tool."""
|
|
51
|
+
|
|
52
|
+
callable: Callable[..., TOutputType]
|
|
53
|
+
"""The actual tool implementation"""
|
|
54
|
+
|
|
55
|
+
name: str
|
|
56
|
+
"""The name of the tool."""
|
|
57
|
+
|
|
58
|
+
description: str = ""
|
|
59
|
+
"""The description of the tool."""
|
|
60
|
+
|
|
61
|
+
schema_override: schemez.OpenAIFunctionDefinition | None = None
|
|
62
|
+
"""Schema override. If not set, the schema is inferred from the callable."""
|
|
63
|
+
|
|
64
|
+
hints: ToolHints = field(default_factory=ToolHints)
|
|
65
|
+
"""Hints for the tool."""
|
|
66
|
+
|
|
67
|
+
import_path: str | None = None
|
|
68
|
+
"""The import path for the tool."""
|
|
69
|
+
|
|
70
|
+
enabled: bool = True
|
|
71
|
+
"""Whether the tool is currently enabled"""
|
|
72
|
+
|
|
73
|
+
source: ToolSource | str = "dynamic"
|
|
74
|
+
"""Where the tool came from."""
|
|
75
|
+
|
|
76
|
+
requires_confirmation: bool = False
|
|
77
|
+
"""Whether tool execution needs explicit confirmation"""
|
|
78
|
+
|
|
79
|
+
agent_name: str | None = None
|
|
80
|
+
"""The agent name as an identifier for agent-as-a-tool."""
|
|
81
|
+
|
|
82
|
+
metadata: dict[str, str] = field(default_factory=dict)
|
|
83
|
+
"""Additional tool metadata"""
|
|
84
|
+
|
|
85
|
+
category: ToolKind | None = None
|
|
86
|
+
"""The category of the tool."""
|
|
87
|
+
|
|
88
|
+
__repr__ = dataclasses_no_defaults_repr
|
|
89
|
+
|
|
90
|
+
def to_pydantic_ai(self) -> PydanticAiTool:
|
|
91
|
+
"""Convert tool to Pydantic AI tool."""
|
|
92
|
+
metadata = {**self.metadata, "agent_name": self.agent_name, "category": self.category}
|
|
93
|
+
return PydanticAiTool(
|
|
94
|
+
function=self.callable,
|
|
95
|
+
name=self.name,
|
|
96
|
+
# takes_ctx=self.takes_ctx,
|
|
97
|
+
# max_retries=self.max_retries,
|
|
98
|
+
description=self.description,
|
|
99
|
+
requires_approval=self.requires_confirmation,
|
|
100
|
+
metadata=metadata,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def schema_obj(self) -> FunctionSchema:
|
|
105
|
+
"""Get the OpenAI function schema for the tool."""
|
|
106
|
+
from pydantic_ai import RunContext
|
|
107
|
+
|
|
108
|
+
from agentpool.agents.context import AgentContext
|
|
109
|
+
|
|
110
|
+
return schemez.create_schema(
|
|
111
|
+
self.callable,
|
|
112
|
+
name_override=self.name,
|
|
113
|
+
description_override=self.description,
|
|
114
|
+
exclude_types=[AgentContext, RunContext],
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def schema(self) -> schemez.OpenAIFunctionTool:
|
|
119
|
+
"""Get the OpenAI function schema for the tool."""
|
|
120
|
+
schema = self.schema_obj.model_dump_openai()
|
|
121
|
+
if self.schema_override:
|
|
122
|
+
schema["function"] = self.schema_override
|
|
123
|
+
return schema
|
|
124
|
+
|
|
125
|
+
def matches_filter(self, state: ToolState) -> bool:
|
|
126
|
+
"""Check if tool matches state filter."""
|
|
127
|
+
match state:
|
|
128
|
+
case "all":
|
|
129
|
+
return True
|
|
130
|
+
case "enabled":
|
|
131
|
+
return self.enabled
|
|
132
|
+
case "disabled":
|
|
133
|
+
return not self.enabled
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def parameters(self) -> list[ToolParameter]:
|
|
137
|
+
"""Get information about tool parameters."""
|
|
138
|
+
schema = self.schema["function"]
|
|
139
|
+
properties: dict[str, Property] = schema.get("properties", {}) # type: ignore
|
|
140
|
+
required: list[str] = schema.get("required", []) # type: ignore
|
|
141
|
+
|
|
142
|
+
return [
|
|
143
|
+
ToolParameter(
|
|
144
|
+
name=name,
|
|
145
|
+
required=name in required,
|
|
146
|
+
type_info=details.get("type"),
|
|
147
|
+
description=details.get("description"),
|
|
148
|
+
)
|
|
149
|
+
for name, details in properties.items()
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
def format_info(self, indent: str = " ") -> str:
|
|
153
|
+
"""Format complete tool information."""
|
|
154
|
+
lines = [f"{indent}→ {self.name}"]
|
|
155
|
+
if self.description:
|
|
156
|
+
lines.append(f"{indent} {self.description}")
|
|
157
|
+
if self.parameters:
|
|
158
|
+
lines.append(f"{indent} Parameters:")
|
|
159
|
+
lines.extend(f"{indent} {param}" for param in self.parameters)
|
|
160
|
+
if self.metadata:
|
|
161
|
+
lines.append(f"{indent} Metadata:")
|
|
162
|
+
lines.extend(f"{indent} {k}: {v}" for k, v in self.metadata.items())
|
|
163
|
+
return "\n".join(lines)
|
|
164
|
+
|
|
165
|
+
@logfire.instrument("Executing tool {self.name} with args={args}, kwargs={kwargs}")
|
|
166
|
+
async def execute(self, *args: Any, **kwargs: Any) -> Any:
|
|
167
|
+
"""Execute tool, handling both sync and async cases."""
|
|
168
|
+
return await execute(self.callable, *args, **kwargs, use_thread=True)
|
|
169
|
+
|
|
170
|
+
@classmethod
|
|
171
|
+
def from_code(
|
|
172
|
+
cls,
|
|
173
|
+
code: str,
|
|
174
|
+
name: str | None = None,
|
|
175
|
+
description: str | None = None,
|
|
176
|
+
) -> Tool[Any]:
|
|
177
|
+
"""Create a tool from a code string."""
|
|
178
|
+
namespace: dict[str, Any] = {}
|
|
179
|
+
exec(code, namespace)
|
|
180
|
+
func = next((v for v in namespace.values() if callable(v)), None)
|
|
181
|
+
if not func:
|
|
182
|
+
msg = "No callable found in provided code"
|
|
183
|
+
raise ValueError(msg)
|
|
184
|
+
return cls.from_callable(func, name_override=name, description_override=description) # pyright: ignore[reportArgumentType]
|
|
185
|
+
|
|
186
|
+
@classmethod
|
|
187
|
+
def from_callable(
|
|
188
|
+
cls,
|
|
189
|
+
fn: Callable[..., TOutputType | Awaitable[TOutputType]] | str,
|
|
190
|
+
*,
|
|
191
|
+
name_override: str | None = None,
|
|
192
|
+
description_override: str | None = None,
|
|
193
|
+
schema_override: schemez.OpenAIFunctionDefinition | None = None,
|
|
194
|
+
hints: ToolHints | None = None,
|
|
195
|
+
category: ToolKind | None = None,
|
|
196
|
+
enabled: bool = True,
|
|
197
|
+
source: ToolSource | str | None = None,
|
|
198
|
+
**kwargs: Any,
|
|
199
|
+
) -> Tool[TOutputType]:
|
|
200
|
+
if isinstance(fn, str):
|
|
201
|
+
import_path = fn
|
|
202
|
+
from agentpool.utils import importing
|
|
203
|
+
|
|
204
|
+
callable_obj = importing.import_callable(fn)
|
|
205
|
+
name = getattr(callable_obj, "__name__", "unknown")
|
|
206
|
+
import_path = fn
|
|
207
|
+
else:
|
|
208
|
+
callable_obj = fn
|
|
209
|
+
module = fn.__module__
|
|
210
|
+
if hasattr(fn, "__qualname__"): # Regular function
|
|
211
|
+
name = get_fn_name(fn)
|
|
212
|
+
import_path = f"{module}.{get_fn_qualname(fn)}"
|
|
213
|
+
else: # Instance with __call__ method
|
|
214
|
+
name = fn.__class__.__name__
|
|
215
|
+
import_path = f"{module}.{fn.__class__.__qualname__}"
|
|
216
|
+
|
|
217
|
+
return cls(
|
|
218
|
+
callable=callable_obj, # pyright: ignore[reportArgumentType]
|
|
219
|
+
name=name_override or name,
|
|
220
|
+
description=description_override or inspect.getdoc(callable_obj) or "",
|
|
221
|
+
import_path=import_path,
|
|
222
|
+
schema_override=schema_override,
|
|
223
|
+
category=category,
|
|
224
|
+
hints=hints or ToolHints(),
|
|
225
|
+
enabled=enabled,
|
|
226
|
+
source=source or "dynamic",
|
|
227
|
+
**kwargs,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
def to_mcp_tool(self) -> MCPTool:
|
|
231
|
+
"""Convert internal Tool to MCP Tool."""
|
|
232
|
+
schema = self.schema
|
|
233
|
+
from mcp.types import Tool as MCPTool, ToolAnnotations
|
|
234
|
+
|
|
235
|
+
return MCPTool(
|
|
236
|
+
name=schema["function"]["name"],
|
|
237
|
+
description=schema["function"]["description"],
|
|
238
|
+
inputSchema=schema["function"]["parameters"], # pyright: ignore
|
|
239
|
+
annotations=ToolAnnotations(
|
|
240
|
+
title=self.name,
|
|
241
|
+
readOnlyHint=self.hints.read_only if self.hints else None,
|
|
242
|
+
destructiveHint=self.hints.destructive if self.hints else None,
|
|
243
|
+
idempotentHint=self.hints.idempotent if self.hints else None,
|
|
244
|
+
openWorldHint=self.hints.open_world if self.hints else None,
|
|
245
|
+
),
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@dataclass
|
|
250
|
+
class ToolParameter:
|
|
251
|
+
"""Information about a tool parameter."""
|
|
252
|
+
|
|
253
|
+
name: str
|
|
254
|
+
required: bool
|
|
255
|
+
type_info: str | None = None
|
|
256
|
+
description: str | None = None
|
|
257
|
+
|
|
258
|
+
def __str__(self) -> str:
|
|
259
|
+
"""Format parameter info."""
|
|
260
|
+
req = "*" if self.required else ""
|
|
261
|
+
type_str = f": {self.type_info}" if self.type_info else ""
|
|
262
|
+
desc = f" - {self.description}" if self.description else ""
|
|
263
|
+
return f"{self.name}{req}{type_str}{desc}"
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
if __name__ == "__main__":
|
|
267
|
+
import webbrowser
|
|
268
|
+
|
|
269
|
+
t = Tool.from_callable(webbrowser.open)
|