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,97 @@
|
|
|
1
|
+
"""Simplified observability registry using Logfire with single backend."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
import logfire
|
|
9
|
+
|
|
10
|
+
from agentpool.log import get_logger
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from agentpool_config.observability import BaseObservabilityConfig, ObservabilityConfig
|
|
15
|
+
|
|
16
|
+
logger = get_logger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ObservabilityRegistry:
|
|
20
|
+
"""Simplified registry that configures Logfire for single backend export."""
|
|
21
|
+
|
|
22
|
+
def __init__(self) -> None:
|
|
23
|
+
self._configured = False
|
|
24
|
+
|
|
25
|
+
def configure_observability(self, observability_config: ObservabilityConfig) -> None:
|
|
26
|
+
"""Configure Logfire for single backend export.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
observability_config: Configuration for observability
|
|
30
|
+
"""
|
|
31
|
+
if not observability_config.enabled or not observability_config.provider:
|
|
32
|
+
logger.debug("Observability disabled or no provider configured")
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
if self._configured:
|
|
36
|
+
logger.warning("Observability already configured, skipping")
|
|
37
|
+
return
|
|
38
|
+
|
|
39
|
+
config = observability_config.provider
|
|
40
|
+
if not config.enabled:
|
|
41
|
+
logger.debug("Provider is disabled", provider=config.type)
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
_setup_otel_environment(config) # Configure OTEL env variables based on provider
|
|
45
|
+
logfire.configure(
|
|
46
|
+
service_name=config.service_name,
|
|
47
|
+
environment=config.environment,
|
|
48
|
+
console=False,
|
|
49
|
+
send_to_logfire=(config.type == "logfire"),
|
|
50
|
+
)
|
|
51
|
+
logfire.instrument_pydantic_ai()
|
|
52
|
+
logfire.instrument_mcp()
|
|
53
|
+
# Note: structlog logs are captured via StructlogProcessor in log.py
|
|
54
|
+
|
|
55
|
+
self._configured = True
|
|
56
|
+
logger.info("Configured observability", provider=config.type)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _setup_otel_environment(config: BaseObservabilityConfig) -> None:
|
|
60
|
+
"""Set up OTEL environment variables for the configured backend."""
|
|
61
|
+
# Get endpoint and headers from config
|
|
62
|
+
endpoint = getattr(config, "_endpoint", getattr(config, "endpoint", None))
|
|
63
|
+
headers = getattr(config, "_headers", getattr(config, "headers", {}))
|
|
64
|
+
|
|
65
|
+
if not endpoint:
|
|
66
|
+
logger.warning("No endpoint found", provider=config.type)
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
# Set standard OTEL environment variables
|
|
70
|
+
os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = endpoint
|
|
71
|
+
os.environ["OTEL_EXPORTER_OTLP_PROTOCOL"] = config.protocol
|
|
72
|
+
|
|
73
|
+
# Set headers if available
|
|
74
|
+
if headers:
|
|
75
|
+
header_str = ",".join(f"{k}={v}" for k, v in headers.items())
|
|
76
|
+
os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = header_str
|
|
77
|
+
|
|
78
|
+
# Set resource attributes
|
|
79
|
+
resource_attrs = []
|
|
80
|
+
if config.service_name:
|
|
81
|
+
resource_attrs.append(f"service.name={config.service_name}")
|
|
82
|
+
if config.environment:
|
|
83
|
+
resource_attrs.append(f"deployment.environment.name={config.environment}")
|
|
84
|
+
|
|
85
|
+
if resource_attrs:
|
|
86
|
+
os.environ["OTEL_RESOURCE_ATTRIBUTES"] = ",".join(resource_attrs)
|
|
87
|
+
|
|
88
|
+
logger.debug(
|
|
89
|
+
"Set OTEL environment",
|
|
90
|
+
endpoint=endpoint,
|
|
91
|
+
protocol=config.protocol,
|
|
92
|
+
headers=headers,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# Global registry instance
|
|
97
|
+
registry = ObservabilityRegistry()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Prompt template management."""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Prompt models for agent configuration."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from typing import Any, ClassVar
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BasePromptProvider(ABC):
|
|
10
|
+
"""Base class for external prompt providers."""
|
|
11
|
+
|
|
12
|
+
name: ClassVar[str]
|
|
13
|
+
supports_versions: ClassVar[bool] = False
|
|
14
|
+
supports_variables: ClassVar[bool] = False
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
async def get_prompt(
|
|
18
|
+
self,
|
|
19
|
+
name: str,
|
|
20
|
+
version: str | None = None,
|
|
21
|
+
variables: dict[str, Any] | None = None,
|
|
22
|
+
) -> str:
|
|
23
|
+
"""Get a prompt by ID."""
|
|
24
|
+
|
|
25
|
+
async def list_prompts(self) -> list[str]:
|
|
26
|
+
"""List available prompts."""
|
|
27
|
+
return [] # Default implementation returns empty list
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Builtin prompt provider."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
from agentpool.prompts.base import BasePromptProvider
|
|
8
|
+
from agentpool_config.system_prompts import StaticPromptConfig
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from agentpool_config.system_prompts import StaticPromptConfig
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BuiltinPromptProvider(BasePromptProvider):
|
|
16
|
+
"""Default provider using system prompts."""
|
|
17
|
+
|
|
18
|
+
supports_variables = True
|
|
19
|
+
name = "builtin"
|
|
20
|
+
|
|
21
|
+
def __init__(self, manifest_prompts: dict[str, StaticPromptConfig]) -> None:
|
|
22
|
+
from jinjarope import Environment
|
|
23
|
+
|
|
24
|
+
self.prompts = manifest_prompts
|
|
25
|
+
self.env = Environment(autoescape=False, enable_async=True)
|
|
26
|
+
|
|
27
|
+
async def get_prompt(
|
|
28
|
+
self,
|
|
29
|
+
name: str,
|
|
30
|
+
version: str | None = None,
|
|
31
|
+
variables: dict[str, Any] | None = None,
|
|
32
|
+
) -> str:
|
|
33
|
+
"""Get prompt content as string."""
|
|
34
|
+
from jinja2 import Template, meta
|
|
35
|
+
|
|
36
|
+
if name not in self.prompts:
|
|
37
|
+
msg = f"Prompt not found: {name}"
|
|
38
|
+
raise KeyError(msg)
|
|
39
|
+
|
|
40
|
+
prompt = self.prompts[name]
|
|
41
|
+
content = prompt.content
|
|
42
|
+
|
|
43
|
+
# Parse template to find required variables
|
|
44
|
+
ast = self.env.parse(content)
|
|
45
|
+
required_vars = meta.find_undeclared_variables(ast)
|
|
46
|
+
if variables and (unknown_vars := (set(variables) - required_vars)):
|
|
47
|
+
vars_ = ", ".join(unknown_vars)
|
|
48
|
+
msg = f"Unknown variables for prompt {name}: {vars_}"
|
|
49
|
+
raise KeyError(msg)
|
|
50
|
+
|
|
51
|
+
if required_vars:
|
|
52
|
+
if not variables:
|
|
53
|
+
req = ", ".join(required_vars)
|
|
54
|
+
msg = f"Prompt {name} requires variables: {req}"
|
|
55
|
+
raise KeyError(msg)
|
|
56
|
+
|
|
57
|
+
# Check for missing required variables
|
|
58
|
+
missing_vars = required_vars - set(variables or {})
|
|
59
|
+
if missing_vars:
|
|
60
|
+
vars_ = ", ".join(missing_vars)
|
|
61
|
+
msg = f"Missing required variables for prompt {name}: {vars_}"
|
|
62
|
+
raise KeyError(msg)
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
template = Template(content, enable_async=True)
|
|
66
|
+
content = await template.render_async(**variables)
|
|
67
|
+
except Exception as e:
|
|
68
|
+
msg = f"Failed to render prompt {name}: {e}"
|
|
69
|
+
raise ValueError(msg) from e
|
|
70
|
+
|
|
71
|
+
return content
|
|
72
|
+
|
|
73
|
+
async def list_prompts(self) -> list[str]:
|
|
74
|
+
"""List available prompt identifiers."""
|
|
75
|
+
return list(self.prompts.keys())
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
from agentpool.mime_utils import guess_type
|
|
8
|
+
from agentpool_config.converters import ConversionConfig
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from docler.converters.base import DocumentConverter
|
|
13
|
+
from upathtools import JoinablePathLike
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ConversionManager:
|
|
17
|
+
"""Manages document conversion using configured providers.
|
|
18
|
+
|
|
19
|
+
In order to not make things super complex, all Converters will be implemented as sync.
|
|
20
|
+
The manager will handle async I/O and thread pooling.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, config: ConversionConfig | list[DocumentConverter]) -> None:
|
|
24
|
+
if isinstance(config, list):
|
|
25
|
+
self.config = ConversionConfig()
|
|
26
|
+
self._converters = config
|
|
27
|
+
else:
|
|
28
|
+
self.config = config
|
|
29
|
+
self._converters = self._setup_converters()
|
|
30
|
+
self._executor = ThreadPoolExecutor(max_workers=3)
|
|
31
|
+
|
|
32
|
+
def __del__(self) -> None:
|
|
33
|
+
self._executor.shutdown(wait=False)
|
|
34
|
+
|
|
35
|
+
def supports_file(self, path: JoinablePathLike) -> bool:
|
|
36
|
+
"""Check if any converter supports the file."""
|
|
37
|
+
mime_type = guess_type(str(path)) or "application/octet-stream"
|
|
38
|
+
return any(c.supports_mime_type(mime_type) for c in self._converters)
|
|
39
|
+
|
|
40
|
+
def supports_content(self, content: Any, mime_type: str | None = None) -> bool:
|
|
41
|
+
"""Check if any converter supports the file."""
|
|
42
|
+
return any(c.supports_mime_type(content) for c in self._converters)
|
|
43
|
+
|
|
44
|
+
def _setup_converters(self) -> list[DocumentConverter]:
|
|
45
|
+
"""Create converter instances from config."""
|
|
46
|
+
return [i.get_provider() for i in self.config.providers or []]
|
|
47
|
+
# Always add PlainConverter as fallback
|
|
48
|
+
# if it gets configured by user, that one gets preference.
|
|
49
|
+
|
|
50
|
+
async def convert_file(self, path: JoinablePathLike) -> str:
|
|
51
|
+
"""Convert file using first supporting converter."""
|
|
52
|
+
loop = asyncio.get_running_loop()
|
|
53
|
+
mime_type = guess_type(str(path)) or "text/plain"
|
|
54
|
+
|
|
55
|
+
for converter in self._converters:
|
|
56
|
+
# Run support check in thread pool
|
|
57
|
+
supports = await loop.run_in_executor(
|
|
58
|
+
self._executor, converter.supports_mime_type, mime_type
|
|
59
|
+
)
|
|
60
|
+
if not supports:
|
|
61
|
+
continue
|
|
62
|
+
# Run conversion in thread pool
|
|
63
|
+
|
|
64
|
+
content = await loop.run_in_executor(
|
|
65
|
+
self._executor,
|
|
66
|
+
converter.convert_file,
|
|
67
|
+
path,
|
|
68
|
+
)
|
|
69
|
+
return str(content)
|
|
70
|
+
|
|
71
|
+
async def convert_content(self, content: Any, mime_type: str | None = None) -> str:
|
|
72
|
+
"""Convert content using first supporting converter."""
|
|
73
|
+
loop = asyncio.get_running_loop()
|
|
74
|
+
|
|
75
|
+
for converter in self._converters:
|
|
76
|
+
# Run support check in thread pool
|
|
77
|
+
supports = await loop.run_in_executor(
|
|
78
|
+
self._executor, converter.supports_mime_type, mime_type or "text/plain"
|
|
79
|
+
)
|
|
80
|
+
if not supports:
|
|
81
|
+
continue
|
|
82
|
+
|
|
83
|
+
doc = await converter.convert_content(content, mime_type or "text/plain")
|
|
84
|
+
return doc.content
|
|
85
|
+
|
|
86
|
+
return str(content) # Fallback for unsupported content
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
if __name__ == "__main__":
|
|
90
|
+
from docler.configs.converter_configs import MarkItDownConfig
|
|
91
|
+
|
|
92
|
+
from agentpool_config.converters import ConversionConfig
|
|
93
|
+
|
|
94
|
+
config = ConversionConfig(providers=[MarkItDownConfig()])
|
|
95
|
+
manager = ConversionManager(config)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""The main Agent. Can do all sort of crazy things."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from pydantic_ai import AudioUrl, BinaryContent, BinaryImage, DocumentUrl, ImageUrl, VideoUrl
|
|
9
|
+
from toprompt import to_prompt
|
|
10
|
+
from upathtools import UPath, read_path, to_upath
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from collections.abc import Sequence
|
|
15
|
+
|
|
16
|
+
from pydantic_ai import UserContent
|
|
17
|
+
|
|
18
|
+
from agentpool.common_types import PromptCompatible
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async def convert_prompts(
|
|
22
|
+
prompts: Sequence[PromptCompatible],
|
|
23
|
+
) -> list[UserContent]:
|
|
24
|
+
"""Convert prompts to pydantic-ai UserContent format.
|
|
25
|
+
|
|
26
|
+
Handles:
|
|
27
|
+
- PIL Images -> BinaryImage
|
|
28
|
+
- UPath/PathLike -> Auto-detect and convert to appropriate Content
|
|
29
|
+
- Regular prompts -> str via to_prompt
|
|
30
|
+
- pydantic-ai content objects -> pass through
|
|
31
|
+
"""
|
|
32
|
+
result: list[UserContent] = []
|
|
33
|
+
for p in prompts:
|
|
34
|
+
match p:
|
|
35
|
+
case os.PathLike() | UPath():
|
|
36
|
+
from agentpool.mime_utils import guess_type
|
|
37
|
+
|
|
38
|
+
path_obj = to_upath(p)
|
|
39
|
+
mime_type = guess_type(str(path_obj))
|
|
40
|
+
|
|
41
|
+
match mime_type:
|
|
42
|
+
case "application/pdf":
|
|
43
|
+
# For http(s) URLs, use DocumentUrl; otherwise read binary
|
|
44
|
+
if path_obj.protocol in {"http", "https"}:
|
|
45
|
+
result.append(DocumentUrl(url=str(path_obj)))
|
|
46
|
+
else:
|
|
47
|
+
data = await read_path(path_obj, mode="rb")
|
|
48
|
+
result.append(BinaryContent(data=data, media_type="application/pdf"))
|
|
49
|
+
case str() if mime_type.startswith("image/"):
|
|
50
|
+
if path_obj.protocol in {"http", "https"}:
|
|
51
|
+
result.append(ImageUrl(url=str(path_obj)))
|
|
52
|
+
else:
|
|
53
|
+
data = await read_path(path_obj, mode="rb")
|
|
54
|
+
result.append(BinaryImage(data=data, media_type=mime_type))
|
|
55
|
+
case str() if mime_type.startswith("audio/"):
|
|
56
|
+
if path_obj.protocol in {"http", "https"}:
|
|
57
|
+
result.append(AudioUrl(url=str(path_obj)))
|
|
58
|
+
else:
|
|
59
|
+
data = await read_path(path_obj, mode="rb")
|
|
60
|
+
result.append(BinaryContent(data=data, media_type=mime_type))
|
|
61
|
+
case str() if mime_type.startswith("video/"):
|
|
62
|
+
if path_obj.protocol in {"http", "https"}:
|
|
63
|
+
result.append(VideoUrl(url=str(path_obj)))
|
|
64
|
+
else:
|
|
65
|
+
# Video as binary content
|
|
66
|
+
data = await read_path(path_obj, mode="rb")
|
|
67
|
+
result.append(BinaryContent(data=data, media_type=mime_type))
|
|
68
|
+
case _:
|
|
69
|
+
# Non-media or unknown type - read as text
|
|
70
|
+
text = await read_path(path_obj)
|
|
71
|
+
result.append(text)
|
|
72
|
+
|
|
73
|
+
case (
|
|
74
|
+
str()
|
|
75
|
+
| ImageUrl()
|
|
76
|
+
| AudioUrl()
|
|
77
|
+
| DocumentUrl()
|
|
78
|
+
| VideoUrl()
|
|
79
|
+
| BinaryContent()
|
|
80
|
+
| BinaryImage()
|
|
81
|
+
):
|
|
82
|
+
# Already a valid UserContent type
|
|
83
|
+
result.append(p)
|
|
84
|
+
|
|
85
|
+
case _:
|
|
86
|
+
# Use to_prompt for anything else (PIL images, pydantic models, etc.)
|
|
87
|
+
result.append(await to_prompt(p))
|
|
88
|
+
return result
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
async def format_prompts(prompts: Sequence[UserContent]) -> str:
|
|
92
|
+
"""Format prompts for human readability using to_prompt."""
|
|
93
|
+
from toprompt import to_prompt
|
|
94
|
+
|
|
95
|
+
parts = [await to_prompt(p) for p in prompts]
|
|
96
|
+
return "\n\n".join(parts)
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""Prompt Manager."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
|
|
8
|
+
from anyenv import method_spawner
|
|
9
|
+
|
|
10
|
+
from agentpool.log import get_logger
|
|
11
|
+
from agentpool.prompts.builtin_provider import BuiltinPromptProvider
|
|
12
|
+
from agentpool.utils.tasks import TaskManager
|
|
13
|
+
from agentpool_config.prompt_hubs import (
|
|
14
|
+
BraintrustConfig,
|
|
15
|
+
FabricConfig,
|
|
16
|
+
LangfuseConfig,
|
|
17
|
+
PromptLayerConfig,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from agentpool.prompts.base import BasePromptProvider
|
|
23
|
+
from agentpool_config.system_prompts import PromptLibraryConfig
|
|
24
|
+
|
|
25
|
+
logger = get_logger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def parse_prompt_reference(reference: str) -> tuple[str, str, str | None, dict[str, str]]:
|
|
29
|
+
"""Parse a prompt reference string.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
reference: Format [provider:]name[@version][?var1=val1,var2=val2]
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Tuple of (provider, identifier, version, variables)
|
|
36
|
+
Provider defaults to "builtin" if not specified
|
|
37
|
+
"""
|
|
38
|
+
provider = "builtin"
|
|
39
|
+
version = None
|
|
40
|
+
variables: dict[str, str] = {}
|
|
41
|
+
|
|
42
|
+
# Split provider and rest
|
|
43
|
+
if ":" in reference:
|
|
44
|
+
provider, identifier = reference.split(":", 1)
|
|
45
|
+
else:
|
|
46
|
+
identifier = reference
|
|
47
|
+
|
|
48
|
+
# Handle version
|
|
49
|
+
if "@" in identifier:
|
|
50
|
+
identifier, version = identifier.split("@", 1)
|
|
51
|
+
|
|
52
|
+
# Handle query parameters
|
|
53
|
+
if "?" in identifier:
|
|
54
|
+
identifier, query = identifier.split("?", 1)
|
|
55
|
+
for pair in query.split(","):
|
|
56
|
+
if "=" not in pair:
|
|
57
|
+
continue
|
|
58
|
+
key, value = pair.split("=", 1)
|
|
59
|
+
variables[key.strip()] = value.strip()
|
|
60
|
+
|
|
61
|
+
return provider, identifier.strip(), version, variables
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class PromptManager:
|
|
65
|
+
"""Manages multiple prompt providers.
|
|
66
|
+
|
|
67
|
+
Handles:
|
|
68
|
+
- Provider initialization and cleanup
|
|
69
|
+
- Prompt reference parsing and resolution
|
|
70
|
+
- Access to prompts from different sources
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
def __init__(self, config: PromptLibraryConfig) -> None:
|
|
74
|
+
"""Initialize prompt manager.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
config: Prompt configuration including providers
|
|
78
|
+
"""
|
|
79
|
+
super().__init__()
|
|
80
|
+
self.config = config
|
|
81
|
+
self.task_manager = TaskManager()
|
|
82
|
+
self.providers: dict[str, BasePromptProvider] = {}
|
|
83
|
+
|
|
84
|
+
# Always register builtin provider
|
|
85
|
+
self.providers["builtin"] = BuiltinPromptProvider(config.system_prompts)
|
|
86
|
+
|
|
87
|
+
# Register configured providers
|
|
88
|
+
for provider_config in config.providers:
|
|
89
|
+
match provider_config:
|
|
90
|
+
case LangfuseConfig():
|
|
91
|
+
from agentpool_prompts.langfuse_hub import LangfusePromptHub
|
|
92
|
+
|
|
93
|
+
self.providers["langfuse"] = LangfusePromptHub(provider_config)
|
|
94
|
+
|
|
95
|
+
case FabricConfig():
|
|
96
|
+
from agentpool_prompts.fabric import FabricPromptHub
|
|
97
|
+
|
|
98
|
+
self.providers["fabric"] = FabricPromptHub(provider_config)
|
|
99
|
+
|
|
100
|
+
case BraintrustConfig():
|
|
101
|
+
from agentpool_prompts.braintrust_hub import BraintrustPromptHub
|
|
102
|
+
|
|
103
|
+
self.providers["braintrust"] = BraintrustPromptHub(provider_config)
|
|
104
|
+
|
|
105
|
+
case PromptLayerConfig():
|
|
106
|
+
from agentpool_prompts.promptlayer_provider import (
|
|
107
|
+
PromptLayerProvider,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
self.providers["promptlayer"] = PromptLayerProvider(provider_config)
|
|
111
|
+
|
|
112
|
+
async def get_from(
|
|
113
|
+
self,
|
|
114
|
+
identifier: str,
|
|
115
|
+
*,
|
|
116
|
+
provider: str | None = None,
|
|
117
|
+
version: str | None = None,
|
|
118
|
+
variables: dict[str, Any] | None = None,
|
|
119
|
+
) -> str:
|
|
120
|
+
"""Get a prompt.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
identifier: Prompt identifier/name
|
|
124
|
+
provider: Provider name (None = builtin)
|
|
125
|
+
version: Optional version string
|
|
126
|
+
variables: Optional template variables
|
|
127
|
+
|
|
128
|
+
Examples:
|
|
129
|
+
await prompts.get_from("code_review", variables={"language": "python"})
|
|
130
|
+
await prompts.get_from(
|
|
131
|
+
"expert",
|
|
132
|
+
provider="langfuse",
|
|
133
|
+
version="v2",
|
|
134
|
+
variables={"domain": "ML"}
|
|
135
|
+
)
|
|
136
|
+
"""
|
|
137
|
+
provider_name = provider or "builtin"
|
|
138
|
+
if provider_name not in self.providers:
|
|
139
|
+
msg = f"Unknown prompt provider: {provider_name}"
|
|
140
|
+
raise KeyError(msg)
|
|
141
|
+
|
|
142
|
+
provider_instance = self.providers[provider_name]
|
|
143
|
+
try:
|
|
144
|
+
kwargs: dict[str, Any] = {}
|
|
145
|
+
if provider_instance.supports_versions and version:
|
|
146
|
+
kwargs["version"] = version
|
|
147
|
+
if provider_instance.supports_variables and variables:
|
|
148
|
+
kwargs["variables"] = variables
|
|
149
|
+
|
|
150
|
+
return await provider_instance.get_prompt(identifier, **kwargs)
|
|
151
|
+
except Exception as e:
|
|
152
|
+
msg = f"Failed to get prompt {identifier!r} from {provider_name}"
|
|
153
|
+
raise RuntimeError(msg) from e
|
|
154
|
+
|
|
155
|
+
@method_spawner
|
|
156
|
+
async def get(self, reference: str) -> str:
|
|
157
|
+
"""Get a prompt using identifier syntax.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
reference: Prompt identifier in format:
|
|
161
|
+
[provider:]name[@version][?var1=val1,var2=val2]
|
|
162
|
+
|
|
163
|
+
Examples:
|
|
164
|
+
await prompts.get("error_handler") # Builtin prompt
|
|
165
|
+
await prompts.get("langfuse:code_review@v2?style=detailed")
|
|
166
|
+
"""
|
|
167
|
+
provider_name, id_, version, vars_ = parse_prompt_reference(reference)
|
|
168
|
+
prov = provider_name if provider_name != "builtin" else None
|
|
169
|
+
return await self.get_from(id_, provider=prov, version=version, variables=vars_)
|
|
170
|
+
|
|
171
|
+
async def list_prompts(self, provider: str | None = None) -> dict[str, list[str]]:
|
|
172
|
+
"""List available prompts.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
provider: Optional provider name to filter by
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
Dict mapping provider names to their available prompts
|
|
179
|
+
"""
|
|
180
|
+
providers = {provider: self.providers[provider]} if provider else self.providers
|
|
181
|
+
|
|
182
|
+
if not providers:
|
|
183
|
+
return {}
|
|
184
|
+
# Get prompts from providers concurrently
|
|
185
|
+
result = {}
|
|
186
|
+
coros = [p.list_prompts() for p in providers.values()]
|
|
187
|
+
gathered_results = await asyncio.gather(*coros, return_exceptions=True)
|
|
188
|
+
for (name, _), prompts in zip(providers.items(), gathered_results, strict=False):
|
|
189
|
+
if isinstance(prompts, BaseException):
|
|
190
|
+
logger.exception("Failed to list prompts", source=name)
|
|
191
|
+
continue
|
|
192
|
+
result[name] = prompts
|
|
193
|
+
return result
|
|
194
|
+
|
|
195
|
+
def cleanup(self) -> None:
|
|
196
|
+
"""Clean up providers."""
|
|
197
|
+
self.providers.clear()
|
|
198
|
+
|
|
199
|
+
def get_default_provider(self) -> str:
|
|
200
|
+
"""Get default provider name.
|
|
201
|
+
|
|
202
|
+
Returns configured default or "builtin"
|
|
203
|
+
"""
|
|
204
|
+
return "builtin"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## Code References
|
|
2
|
+
|
|
3
|
+
When referencing code locations in responses, use markdown links with `file://` URLs:
|
|
4
|
+
|
|
5
|
+
- **File**: `[filename](file:///absolute/path/to/file.py)`
|
|
6
|
+
- **Line range**: `[filename#L10-25](file:///absolute/path/to/file.py#L10:25)`
|
|
7
|
+
- **Single line**: `[filename#L10](file:///absolute/path/to/file.py#L10:10)`
|
|
8
|
+
- **Directory**: `[dirname/](file:///absolute/path/to/dir/)`
|
|
9
|
+
|
|
10
|
+
Line range format is `#L<start>:<end>` (1-based, inclusive).
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
- [toolset.py](file:///home/phil65/dev/oss/agentpool/src/agentpool_toolsets/openapi/toolset.py)
|
|
14
|
+
- [OpenAPITools class](file:///home/phil65/dev/oss/agentpool/src/agentpool_toolsets/openapi/toolset.py#L19:80)
|
|
15
|
+
|
|
16
|
+
Use these clickable references when pointing to specific code locations. For showing actual code content, still use fenced code blocks with the path-based syntax.
|
|
17
|
+
|
|
18
|
+
## Zed-specific URLs
|
|
19
|
+
|
|
20
|
+
In addition to `file://` URLs, these `zed://` URLs work in the agent context:
|
|
21
|
+
|
|
22
|
+
- **File reference**: `[text](zed:///agent/file?path=/absolute/path/to/file.py)`
|
|
23
|
+
- **Selection**: `[text](zed:///agent/selection?path=/absolute/path/to/file.py#L10:25)`
|
|
24
|
+
- **Symbol**: `[text](zed:///agent/symbol/function_name?path=/absolute/path/to/file.py#L10:25)`
|
|
25
|
+
- **Directory**: `[text](zed:///agent/directory?path=/absolute/path/to/dir)`
|
|
26
|
+
|
|
27
|
+
These may require existing context to work:
|
|
28
|
+
- **Thread reference**: `[text](zed:///agent/thread/SESSION_ID?name=Thread%20Name)`
|
|
29
|
+
- **Rule reference**: `[text](zed:///agent/rule/UUID?name=Rule%20Name)`
|
|
30
|
+
- **Pasted image**: `[text](zed:///agent/pasted-image)`
|
|
31
|
+
- **Untitled buffer**: `[text](zed:///agent/untitled-buffer#L10:20)`
|
|
32
|
+
|
|
33
|
+
Query params must be URL-encoded (spaces → `%20`). Paths must be absolute.
|