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
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Utils for documentation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import ast
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Literal
|
|
8
|
+
|
|
9
|
+
import mknodes as mk
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
DocStyle = Literal["simple", "full"]
|
|
13
|
+
EXAMPLES_DIR = Path("src/agentpool_docs/examples")
|
|
14
|
+
|
|
15
|
+
def create_example_doc(name: str, *, style: DocStyle = "full") -> mk.MkContainer:
|
|
16
|
+
"""Create documentation for an example file.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
name: Name of example file (e.g. "download_agents.py")
|
|
20
|
+
examples_dir: Directory containing examples (default: examples/)
|
|
21
|
+
style: Documentation style:
|
|
22
|
+
- simple: Just the code
|
|
23
|
+
- full: Title, description from docstring, code, etc.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Container with all documentation elements
|
|
27
|
+
"""
|
|
28
|
+
path = EXAMPLES_DIR / name
|
|
29
|
+
if not path.exists():
|
|
30
|
+
raise FileNotFoundError(f"Example {name} not found")
|
|
31
|
+
|
|
32
|
+
container = mk.MkContainer()
|
|
33
|
+
if style == "full":
|
|
34
|
+
# Extract title/description from example's docstring
|
|
35
|
+
title = path.stem.replace("_", " ").title()
|
|
36
|
+
container += mk.MkHeader(title, level=2)
|
|
37
|
+
# Add description from docstring if available
|
|
38
|
+
if docstring := ast.get_docstring(ast.parse(path.read_text(encoding="utf-8"))):
|
|
39
|
+
container += docstring
|
|
40
|
+
# Add the code itself
|
|
41
|
+
container += mk.MkCode(path.read_text(encoding="utf-8"), language="python")
|
|
42
|
+
return container
|
agentpool/docs/utils.py
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
"""Helper functions for running examples in different environments."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import types
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import TYPE_CHECKING, Annotated, Any, Self, Union, get_args, get_origin
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from collections.abc import Awaitable, Iterator
|
|
14
|
+
|
|
15
|
+
from agentpool.resource_providers import ResourceProvider
|
|
16
|
+
from agentpool.tools.base import Tool
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
EXAMPLES_DIR = Path("src/agentpool_docs/examples")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def is_pyodide() -> bool:
|
|
23
|
+
"""Check if code is running in a Pyodide environment."""
|
|
24
|
+
try:
|
|
25
|
+
from js import Object # type: ignore[import-not-found] # noqa: F401
|
|
26
|
+
|
|
27
|
+
return True # noqa: TRY300
|
|
28
|
+
except ImportError:
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_config_path(module_path: str | None = None, filename: str = "config.yml") -> Path:
|
|
33
|
+
"""Get the configuration file path based on environment.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
module_path: Optional __file__ from the calling module (ignored in Pyodide)
|
|
37
|
+
filename: Name of the config file (default: config.yml)
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Path to the configuration file
|
|
41
|
+
"""
|
|
42
|
+
if is_pyodide():
|
|
43
|
+
return Path(filename)
|
|
44
|
+
if module_path is None:
|
|
45
|
+
raise ValueError("module_path is required in non-Pyodide environment")
|
|
46
|
+
return Path(module_path).parent / filename
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def run[T](coro: Awaitable[T]) -> T:
|
|
50
|
+
"""Run a coroutine in both normal Python and Pyodide environments."""
|
|
51
|
+
try:
|
|
52
|
+
# Check if we're in an event loop
|
|
53
|
+
asyncio.get_running_loop()
|
|
54
|
+
# If we are, run until complete
|
|
55
|
+
return asyncio.get_event_loop().run_until_complete(coro)
|
|
56
|
+
except RuntimeError:
|
|
57
|
+
# No running event loop, create one
|
|
58
|
+
return asyncio.run(coro) # type: ignore
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass
|
|
62
|
+
class Example:
|
|
63
|
+
"""Represents a AgentPool example with its metadata."""
|
|
64
|
+
|
|
65
|
+
name: str
|
|
66
|
+
path: Path
|
|
67
|
+
title: str
|
|
68
|
+
description: str
|
|
69
|
+
icon: str = "octicon:code-16"
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def files(self) -> list[Path]:
|
|
73
|
+
"""Get all Python and YAML files (excluding __init__.py)."""
|
|
74
|
+
return [
|
|
75
|
+
f
|
|
76
|
+
for f in self.path.glob("**/*.*")
|
|
77
|
+
if f.suffix in {".py", ".yml"} and not f.name.startswith("__")
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def docs(self) -> Path | None:
|
|
82
|
+
"""Get docs.md file if it exists."""
|
|
83
|
+
docs = self.path / "docs.md"
|
|
84
|
+
return docs if docs.exists() else None
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def from_directory(cls, path: Path) -> Self | None:
|
|
88
|
+
"""Create Example from directory if it's a valid example."""
|
|
89
|
+
if not path.is_dir() or path.name.startswith("__"):
|
|
90
|
+
return None
|
|
91
|
+
|
|
92
|
+
init_file = path / "__init__.py"
|
|
93
|
+
if not init_file.exists():
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
# Load the module to get variables
|
|
97
|
+
namespace: dict[str, str] = {}
|
|
98
|
+
with init_file.open() as f:
|
|
99
|
+
exec(f.read(), namespace)
|
|
100
|
+
|
|
101
|
+
# Get metadata with defaults
|
|
102
|
+
title = namespace.get("TITLE", path.name.replace("_", " ").title())
|
|
103
|
+
icon = namespace.get("ICON", "octicon:code-16")
|
|
104
|
+
description = namespace.get("__doc__", "")
|
|
105
|
+
|
|
106
|
+
return cls(
|
|
107
|
+
name=path.name,
|
|
108
|
+
path=path,
|
|
109
|
+
title=title,
|
|
110
|
+
description=description,
|
|
111
|
+
icon=icon,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def iter_examples(root: Path | str | None = None) -> Iterator[Example]:
|
|
116
|
+
"""Iterate over all available examples.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
root: Optional root directory (defaults to agentpool_docs/examples)
|
|
120
|
+
"""
|
|
121
|
+
root = Path(root) if root else EXAMPLES_DIR
|
|
122
|
+
|
|
123
|
+
for path in sorted(root.iterdir()):
|
|
124
|
+
if example := Example.from_directory(path):
|
|
125
|
+
yield example
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def get_example(name: str, root: Path | str | None = None) -> Example:
|
|
129
|
+
"""Get a specific example by name."""
|
|
130
|
+
for example in iter_examples(root):
|
|
131
|
+
if example.name == name:
|
|
132
|
+
return example
|
|
133
|
+
raise KeyError(f"Example {name!r} not found")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def get_discriminator_values(union_type: Any) -> dict[str, type]:
|
|
137
|
+
"""Extract discriminator values from a discriminated union.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
union_type: A Union type (possibly wrapped in Annotated)
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
Dict mapping discriminator values to their model classes
|
|
144
|
+
"""
|
|
145
|
+
# Unwrap Annotated if present
|
|
146
|
+
origin = get_origin(union_type)
|
|
147
|
+
if origin is Annotated:
|
|
148
|
+
union_type = get_args(union_type)[0]
|
|
149
|
+
origin = get_origin(union_type)
|
|
150
|
+
|
|
151
|
+
# Verify it's a Union
|
|
152
|
+
if origin not in (Union, types.UnionType):
|
|
153
|
+
msg = f"Expected Union type, got: {union_type}"
|
|
154
|
+
raise TypeError(msg)
|
|
155
|
+
|
|
156
|
+
# Get all types in the union
|
|
157
|
+
union_args = get_args(union_type)
|
|
158
|
+
|
|
159
|
+
# Extract discriminator values from each model
|
|
160
|
+
result: dict[str, type] = {}
|
|
161
|
+
for model_cls in union_args:
|
|
162
|
+
if model_cls is type(None):
|
|
163
|
+
continue
|
|
164
|
+
|
|
165
|
+
# Get the 'type' field which serves as discriminator
|
|
166
|
+
if hasattr(model_cls, "model_fields") and "type" in model_cls.model_fields:
|
|
167
|
+
field = model_cls.model_fields["type"]
|
|
168
|
+
if field.default is not None:
|
|
169
|
+
result[field.default] = model_cls
|
|
170
|
+
|
|
171
|
+
return result
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def discriminator_to_filename(discriminator: str) -> str:
|
|
175
|
+
"""Convert discriminator value to expected doc filename.
|
|
176
|
+
|
|
177
|
+
Examples:
|
|
178
|
+
"file_access" -> "file-access"
|
|
179
|
+
"vfs" -> "vfs"
|
|
180
|
+
"agent_management" -> "agent-management"
|
|
181
|
+
"""
|
|
182
|
+
return discriminator.replace("_", "-")
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def check_docs_for_union(
|
|
186
|
+
union_type: Any,
|
|
187
|
+
docs_dir: Path | str,
|
|
188
|
+
*,
|
|
189
|
+
index_filename: str = "index",
|
|
190
|
+
) -> tuple[dict[str, type], set[str]]:
|
|
191
|
+
"""Check that all union members have corresponding doc files.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
union_type: A discriminated Union type
|
|
195
|
+
docs_dir: Directory containing the doc files
|
|
196
|
+
index_filename: Filename to ignore (default: "index")
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
Tuple of (missing_docs, extra_docs) where:
|
|
200
|
+
- missing_docs: Dict of discriminator -> model class for undocumented types
|
|
201
|
+
- extra_docs: Set of doc filenames without corresponding union member
|
|
202
|
+
|
|
203
|
+
Example:
|
|
204
|
+
```python
|
|
205
|
+
from agentpool_config.toolsets import ToolsetConfig
|
|
206
|
+
missing, extra = check_docs_for_union(
|
|
207
|
+
ToolsetConfig,
|
|
208
|
+
Path("docs/configuration/toolsets"),
|
|
209
|
+
)
|
|
210
|
+
```
|
|
211
|
+
"""
|
|
212
|
+
docs_dir = Path(docs_dir)
|
|
213
|
+
|
|
214
|
+
# Get discriminator values from union
|
|
215
|
+
discriminators = get_discriminator_values(union_type)
|
|
216
|
+
|
|
217
|
+
# Get doc files (filename without .md, excluding index)
|
|
218
|
+
doc_files = {f.stem for f in docs_dir.glob("*.md") if f.stem != index_filename}
|
|
219
|
+
|
|
220
|
+
# Convert discriminators to expected filenames
|
|
221
|
+
expected_files = {discriminator_to_filename(d): d for d in discriminators}
|
|
222
|
+
|
|
223
|
+
# Find mismatches
|
|
224
|
+
missing_docs = {
|
|
225
|
+
orig_discriminator: discriminators[orig_discriminator]
|
|
226
|
+
for filename, orig_discriminator in expected_files.items()
|
|
227
|
+
if filename not in doc_files
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
extra_docs = doc_files - set(expected_files.keys())
|
|
231
|
+
|
|
232
|
+
return missing_docs, extra_docs
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _strip_docstring_sections(description: str) -> str:
|
|
236
|
+
"""Strip Args/Returns/Raises sections from a docstring, keeping only the summary.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
description: The full docstring
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Just the summary/description part without parameter documentation
|
|
243
|
+
"""
|
|
244
|
+
lines = description.split("\n")
|
|
245
|
+
result = []
|
|
246
|
+
in_section = False
|
|
247
|
+
|
|
248
|
+
for line in lines:
|
|
249
|
+
stripped = line.strip()
|
|
250
|
+
# Check if we're entering a standard docstring section
|
|
251
|
+
if stripped in ("Args:", "Arguments:", "Returns:", "Raises:", "Yields:", "Note:"):
|
|
252
|
+
in_section = True
|
|
253
|
+
continue
|
|
254
|
+
# Check if we're in a section (indented content after section header)
|
|
255
|
+
if in_section:
|
|
256
|
+
# If line is empty or still indented, skip it
|
|
257
|
+
if not stripped or line.startswith(" ") or line.startswith("\t"):
|
|
258
|
+
continue
|
|
259
|
+
# Non-indented non-empty line means new content
|
|
260
|
+
in_section = False
|
|
261
|
+
result.append(line)
|
|
262
|
+
|
|
263
|
+
# Clean up trailing empty lines
|
|
264
|
+
while result and not result[-1].strip():
|
|
265
|
+
result.pop()
|
|
266
|
+
|
|
267
|
+
return "\n".join(result)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def tool_to_markdown(tool: Tool) -> str:
|
|
271
|
+
"""Generate markdown documentation for a single tool.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
tool: The tool to document
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
Markdown formatted documentation string
|
|
278
|
+
"""
|
|
279
|
+
lines = [f"### `{tool.name}`", ""]
|
|
280
|
+
|
|
281
|
+
if tool.description:
|
|
282
|
+
# Strip Args/Returns sections since we have a parameters table
|
|
283
|
+
desc = _strip_docstring_sections(tool.description)
|
|
284
|
+
if desc:
|
|
285
|
+
lines.append(desc)
|
|
286
|
+
lines.append("")
|
|
287
|
+
|
|
288
|
+
# Get parameters from schema
|
|
289
|
+
schema = tool.schema["function"]
|
|
290
|
+
params_schema = schema.get("parameters", {})
|
|
291
|
+
properties = params_schema.get("properties", {})
|
|
292
|
+
required = params_schema.get("required", [])
|
|
293
|
+
|
|
294
|
+
if properties:
|
|
295
|
+
lines.append("**Parameters:**")
|
|
296
|
+
lines.append("")
|
|
297
|
+
lines.append("| Name | Type | Required | Description |")
|
|
298
|
+
lines.append("|------|------|----------|-------------|")
|
|
299
|
+
for name, details in properties.items():
|
|
300
|
+
req = "✓" if name in required else ""
|
|
301
|
+
type_info = details.get("type", "-")
|
|
302
|
+
desc = details.get("description", "-")
|
|
303
|
+
# Escape pipe characters in description
|
|
304
|
+
desc = desc.replace("|", "\\|").replace("\n", " ")
|
|
305
|
+
lines.append(f"| `{name}` | {type_info} | {req} | {desc} |")
|
|
306
|
+
lines.append("")
|
|
307
|
+
|
|
308
|
+
# Add hints if any are set
|
|
309
|
+
hints = []
|
|
310
|
+
if tool.hints.read_only:
|
|
311
|
+
hints.append("read-only")
|
|
312
|
+
if tool.hints.destructive:
|
|
313
|
+
hints.append("destructive")
|
|
314
|
+
if tool.hints.idempotent:
|
|
315
|
+
hints.append("idempotent")
|
|
316
|
+
if tool.hints.open_world:
|
|
317
|
+
hints.append("open-world")
|
|
318
|
+
|
|
319
|
+
if hints:
|
|
320
|
+
lines.append(f"**Hints:** {', '.join(hints)}")
|
|
321
|
+
lines.append("")
|
|
322
|
+
|
|
323
|
+
if tool.category:
|
|
324
|
+
lines.append(f"**Category:** {tool.category}")
|
|
325
|
+
lines.append("")
|
|
326
|
+
|
|
327
|
+
return "\n".join(lines)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def generate_tool_docs(toolset: ResourceProvider) -> str:
|
|
331
|
+
"""Generate markdown documentation for all tools in a toolset.
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
toolset: A ResourceProvider that provides tools
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
Markdown formatted documentation for all tools
|
|
338
|
+
|
|
339
|
+
Example:
|
|
340
|
+
```python exec="true"
|
|
341
|
+
from agentpool_toolsets.builtin.code import CodeTools
|
|
342
|
+
from agentpool.docs.utils import generate_tool_docs
|
|
343
|
+
|
|
344
|
+
toolset = CodeTools()
|
|
345
|
+
print(generate_tool_docs(toolset))
|
|
346
|
+
```
|
|
347
|
+
"""
|
|
348
|
+
# Get tools (handle async)
|
|
349
|
+
tools = run(toolset.get_tools())
|
|
350
|
+
|
|
351
|
+
if not tools:
|
|
352
|
+
return "*No tools available.*"
|
|
353
|
+
|
|
354
|
+
lines = [f"## {toolset.name.replace('_', ' ').title()} Tools", ""]
|
|
355
|
+
|
|
356
|
+
for tool in tools:
|
|
357
|
+
lines.append(tool_to_markdown(tool))
|
|
358
|
+
|
|
359
|
+
return "\n".join(lines)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
if __name__ == "__main__":
|
|
363
|
+
# Example usage:
|
|
364
|
+
for ex in iter_examples():
|
|
365
|
+
print(f"\n{ex.title} ({ex.name})")
|
|
366
|
+
print(f"Icon: {ex.icon}")
|
|
367
|
+
print(f"Files: {len(ex.files)}")
|
|
368
|
+
if ex.docs:
|
|
369
|
+
print("Has docs.md")
|
|
370
|
+
print(f"Description: {ex.description.splitlines()[0]}")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""High-level functional interfaces for AgentPool."""
|
|
2
|
+
|
|
3
|
+
from agentpool.functional.run import (
|
|
4
|
+
run_agent,
|
|
5
|
+
run_agent_sync,
|
|
6
|
+
)
|
|
7
|
+
from agentpool.functional.structure import (
|
|
8
|
+
get_structured,
|
|
9
|
+
get_structured_multiple,
|
|
10
|
+
pick_one,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"auto_callable",
|
|
15
|
+
"get_structured",
|
|
16
|
+
"get_structured_multiple",
|
|
17
|
+
"pick_one",
|
|
18
|
+
"run_agent",
|
|
19
|
+
"run_agent_sync",
|
|
20
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Functional wrappers for Agent usage."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Unpack, overload
|
|
6
|
+
|
|
7
|
+
from anyenv import run_sync
|
|
8
|
+
from pydantic_ai import ImageUrl
|
|
9
|
+
|
|
10
|
+
from agentpool import Agent
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from agentpool.agents.agent import AgentKwargs
|
|
15
|
+
from agentpool.common_types import PromptCompatible
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@overload
|
|
19
|
+
async def run_agent[TResult](
|
|
20
|
+
prompt: PromptCompatible,
|
|
21
|
+
image_url: str | None = None,
|
|
22
|
+
*,
|
|
23
|
+
output_type: type[TResult],
|
|
24
|
+
**kwargs: Unpack[AgentKwargs],
|
|
25
|
+
) -> TResult: ...
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@overload
|
|
29
|
+
async def run_agent(
|
|
30
|
+
prompt: PromptCompatible,
|
|
31
|
+
image_url: str | None = None,
|
|
32
|
+
**kwargs: Unpack[AgentKwargs],
|
|
33
|
+
) -> str: ...
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async def run_agent(
|
|
37
|
+
prompt: PromptCompatible,
|
|
38
|
+
image_url: str | None = None,
|
|
39
|
+
*,
|
|
40
|
+
output_type: type[Any] | None = None,
|
|
41
|
+
**kwargs: Unpack[AgentKwargs],
|
|
42
|
+
) -> Any:
|
|
43
|
+
"""Run prompt through agent and return result."""
|
|
44
|
+
async with Agent[Any, str](**kwargs) as agent:
|
|
45
|
+
if image_url:
|
|
46
|
+
image = ImageUrl(url=image_url)
|
|
47
|
+
result = await agent.run(prompt, image, output_type=output_type)
|
|
48
|
+
else:
|
|
49
|
+
result = await agent.run(prompt, output_type=output_type)
|
|
50
|
+
return result.content
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@overload
|
|
54
|
+
def run_agent_sync[TResult](
|
|
55
|
+
prompt: PromptCompatible,
|
|
56
|
+
image_url: str | None = None,
|
|
57
|
+
*,
|
|
58
|
+
output_type: type[TResult],
|
|
59
|
+
**kwargs: Unpack[AgentKwargs],
|
|
60
|
+
) -> TResult: ...
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@overload
|
|
64
|
+
def run_agent_sync(
|
|
65
|
+
prompt: PromptCompatible,
|
|
66
|
+
image_url: str | None = None,
|
|
67
|
+
**kwargs: Unpack[AgentKwargs],
|
|
68
|
+
) -> str: ...
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def run_agent_sync(
|
|
72
|
+
prompt: PromptCompatible,
|
|
73
|
+
image_url: str | None = None,
|
|
74
|
+
*,
|
|
75
|
+
output_type: type[Any] | None = None,
|
|
76
|
+
**kwargs: Unpack[AgentKwargs],
|
|
77
|
+
) -> Any:
|
|
78
|
+
"""Sync wrapper for run_agent."""
|
|
79
|
+
coro = run_agent(prompt, image_url, output_type=output_type, **kwargs) # type: ignore
|
|
80
|
+
return run_sync(coro)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""High-level pipeline functions for agent execution."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from enum import Enum
|
|
6
|
+
from typing import TYPE_CHECKING, Literal, get_args
|
|
7
|
+
|
|
8
|
+
from agentpool.agents.agent import Agent
|
|
9
|
+
from agentpool.log import get_logger
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from collections.abc import Callable
|
|
14
|
+
|
|
15
|
+
from agentpool.common_types import ModelType
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
logger = get_logger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async def get_structured[T](
|
|
22
|
+
prompt: str,
|
|
23
|
+
response_type: type[T],
|
|
24
|
+
model: ModelType,
|
|
25
|
+
*,
|
|
26
|
+
system_prompt: str | None = None,
|
|
27
|
+
max_retries: int = 3,
|
|
28
|
+
error_handler: Callable[[Exception], T | None] | None = None,
|
|
29
|
+
) -> T:
|
|
30
|
+
"""Get structured output from LLM using function calling.
|
|
31
|
+
|
|
32
|
+
This function creates a temporary agent that uses the class constructor
|
|
33
|
+
as a tool to generate structured output. It handles:
|
|
34
|
+
- Type conversion from Python types to JSON schema
|
|
35
|
+
- Constructor parameter validation
|
|
36
|
+
- Error handling with optional recovery
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
prompt: The prompt to send to the LLM
|
|
40
|
+
response_type: The type to create (class with typed constructor)
|
|
41
|
+
model: model to use
|
|
42
|
+
system_prompt: Optional system instructions
|
|
43
|
+
max_retries: Max attempts for parsing (default: 3)
|
|
44
|
+
error_handler: Optional error handler for recovery
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
Instance of response_type
|
|
48
|
+
|
|
49
|
+
Example:
|
|
50
|
+
```python
|
|
51
|
+
class TaskResult:
|
|
52
|
+
'''Analysis result for a task.'''
|
|
53
|
+
def __init__(
|
|
54
|
+
self,
|
|
55
|
+
success: bool,
|
|
56
|
+
message: str,
|
|
57
|
+
due_date: datetime | None = None
|
|
58
|
+
):
|
|
59
|
+
self.success = success
|
|
60
|
+
self.message = message
|
|
61
|
+
self.due_date = due_date
|
|
62
|
+
|
|
63
|
+
result = await get_structured(
|
|
64
|
+
"Analyze task: Deploy monitoring",
|
|
65
|
+
TaskResult,
|
|
66
|
+
system_prompt="You analyze task success"
|
|
67
|
+
)
|
|
68
|
+
print(f"Success: {result.success}")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
TypeError: If response_type is not a valid type
|
|
73
|
+
ValueError: If constructor schema cannot be created
|
|
74
|
+
Exception: If LLM call fails and no error_handler recovers
|
|
75
|
+
"""
|
|
76
|
+
"""Get structured output from LLM using function calling."""
|
|
77
|
+
async with Agent(
|
|
78
|
+
model=model,
|
|
79
|
+
system_prompt=system_prompt or [],
|
|
80
|
+
name="structured",
|
|
81
|
+
retries=max_retries,
|
|
82
|
+
) as agent:
|
|
83
|
+
try:
|
|
84
|
+
return await agent.talk.extract(prompt, response_type)
|
|
85
|
+
except Exception as e:
|
|
86
|
+
if error_handler and (err_result := error_handler(e)):
|
|
87
|
+
return err_result
|
|
88
|
+
raise
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
async def get_structured_multiple[T](
|
|
92
|
+
prompt: str,
|
|
93
|
+
target: type[T],
|
|
94
|
+
model: ModelType,
|
|
95
|
+
) -> list[T]:
|
|
96
|
+
"""Extract multiple structured instances from text."""
|
|
97
|
+
async with Agent(model=model, name="structured") as agent:
|
|
98
|
+
return await agent.talk.extract_multiple(prompt, target)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
async def pick_one[T](
|
|
102
|
+
prompt: str,
|
|
103
|
+
options: type[T | Enum] | list[T],
|
|
104
|
+
model: ModelType,
|
|
105
|
+
) -> T:
|
|
106
|
+
"""Pick one option from a list of choices."""
|
|
107
|
+
instances: dict[str, T] = {}
|
|
108
|
+
|
|
109
|
+
# Create mapping and descriptions
|
|
110
|
+
if isinstance(options, type):
|
|
111
|
+
if issubclass(options, Enum):
|
|
112
|
+
choices = {e.name: (e.value, str(e.value)) for e in options}
|
|
113
|
+
else:
|
|
114
|
+
literal_opts = get_args(options)
|
|
115
|
+
choices = {str(opt): (opt, str(opt)) for opt in literal_opts}
|
|
116
|
+
else: # List
|
|
117
|
+
choices = {str(i): (opt, repr(opt)) for i, opt in enumerate(options)}
|
|
118
|
+
|
|
119
|
+
async def select_option(option: Literal[tuple(choices.keys())]) -> str: # type: ignore
|
|
120
|
+
"""Pick one of the available options.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
option: Which option to pick
|
|
124
|
+
"""
|
|
125
|
+
instances["selected"] = choices[option][0]
|
|
126
|
+
return f"Selected: {option}"
|
|
127
|
+
|
|
128
|
+
# Add options to docstring
|
|
129
|
+
docs = "\n".join(f"- {k}: {desc}" for k, (_, desc) in choices.items())
|
|
130
|
+
assert select_option.__doc__
|
|
131
|
+
select_option.__doc__ += f"\nOptions:\n{docs}"
|
|
132
|
+
sys_prompt = "Select the most appropriate option based on the context."
|
|
133
|
+
async with Agent(model=model, system_prompt=sys_prompt) as agent:
|
|
134
|
+
agent.tools.register_tool(select_option, enabled=True)
|
|
135
|
+
await agent.run(prompt)
|
|
136
|
+
return instances["selected"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Runtime hook classes for agent lifecycle events."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from agentpool.hooks.agent_hooks import AgentHooks
|
|
6
|
+
from agentpool.hooks.base import Hook, HookEvent, HookInput, HookResult
|
|
7
|
+
from agentpool.hooks.callable import CallableHook
|
|
8
|
+
from agentpool.hooks.command import CommandHook
|
|
9
|
+
from agentpool.hooks.prompt import PromptHook
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"AgentHooks",
|
|
13
|
+
"CallableHook",
|
|
14
|
+
"CommandHook",
|
|
15
|
+
"Hook",
|
|
16
|
+
"HookEvent",
|
|
17
|
+
"HookInput",
|
|
18
|
+
"HookResult",
|
|
19
|
+
"PromptHook",
|
|
20
|
+
]
|