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,163 @@
|
|
|
1
|
+
"""Session store protocol and implementations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import abstractmethod
|
|
6
|
+
from typing import TYPE_CHECKING, Protocol, Self, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from agentpool.log import get_logger
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from types import TracebackType
|
|
13
|
+
|
|
14
|
+
from agentpool.sessions.models import SessionData
|
|
15
|
+
|
|
16
|
+
logger = get_logger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@runtime_checkable
|
|
20
|
+
class SessionStore(Protocol):
|
|
21
|
+
"""Protocol for session persistence backends.
|
|
22
|
+
|
|
23
|
+
Implementations handle storing and retrieving SessionData to/from
|
|
24
|
+
various backends (SQL, file, memory, etc.).
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
async def __aenter__(self) -> Self:
|
|
28
|
+
"""Initialize store resources."""
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
async def __aexit__(
|
|
32
|
+
self,
|
|
33
|
+
exc_type: type[BaseException] | None,
|
|
34
|
+
exc_val: BaseException | None,
|
|
35
|
+
exc_tb: TracebackType | None,
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Clean up store resources."""
|
|
38
|
+
...
|
|
39
|
+
|
|
40
|
+
@abstractmethod
|
|
41
|
+
async def save(self, data: SessionData) -> None:
|
|
42
|
+
"""Save or update session data.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
data: Session data to persist
|
|
46
|
+
"""
|
|
47
|
+
...
|
|
48
|
+
|
|
49
|
+
@abstractmethod
|
|
50
|
+
async def load(self, session_id: str) -> SessionData | None:
|
|
51
|
+
"""Load session data by ID.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
session_id: Session identifier
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Session data if found, None otherwise
|
|
58
|
+
"""
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
@abstractmethod
|
|
62
|
+
async def delete(self, session_id: str) -> bool:
|
|
63
|
+
"""Delete a session.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
session_id: Session identifier
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
True if session was deleted, False if not found
|
|
70
|
+
"""
|
|
71
|
+
...
|
|
72
|
+
|
|
73
|
+
@abstractmethod
|
|
74
|
+
async def list_sessions(
|
|
75
|
+
self,
|
|
76
|
+
pool_id: str | None = None,
|
|
77
|
+
agent_name: str | None = None,
|
|
78
|
+
) -> list[str]:
|
|
79
|
+
"""List session IDs, optionally filtered.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
pool_id: Filter by pool/manifest ID
|
|
83
|
+
agent_name: Filter by agent name
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
List of session IDs
|
|
87
|
+
"""
|
|
88
|
+
...
|
|
89
|
+
|
|
90
|
+
@abstractmethod
|
|
91
|
+
async def cleanup_expired(self, max_age_hours: int = 24) -> int:
|
|
92
|
+
"""Remove sessions older than max_age.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
max_age_hours: Maximum session age in hours
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Number of sessions removed
|
|
99
|
+
"""
|
|
100
|
+
...
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class MemorySessionStore:
|
|
104
|
+
"""In-memory session store for testing and development."""
|
|
105
|
+
|
|
106
|
+
def __init__(self) -> None:
|
|
107
|
+
self._sessions: dict[str, SessionData] = {}
|
|
108
|
+
|
|
109
|
+
async def __aenter__(self) -> Self:
|
|
110
|
+
return self
|
|
111
|
+
|
|
112
|
+
async def __aexit__(
|
|
113
|
+
self,
|
|
114
|
+
exc_type: type[BaseException] | None,
|
|
115
|
+
exc_val: BaseException | None,
|
|
116
|
+
exc_tb: TracebackType | None,
|
|
117
|
+
) -> None:
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
async def save(self, data: SessionData) -> None:
|
|
121
|
+
self._sessions[data.session_id] = data
|
|
122
|
+
logger.debug("Saved session", session_id=data.session_id)
|
|
123
|
+
|
|
124
|
+
async def load(self, session_id: str) -> SessionData | None:
|
|
125
|
+
return self._sessions.get(session_id)
|
|
126
|
+
|
|
127
|
+
async def delete(self, session_id: str) -> bool:
|
|
128
|
+
if session_id in self._sessions:
|
|
129
|
+
del self._sessions[session_id]
|
|
130
|
+
logger.debug("Deleted session", session_id=session_id)
|
|
131
|
+
return True
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
async def list_sessions(
|
|
135
|
+
self,
|
|
136
|
+
pool_id: str | None = None,
|
|
137
|
+
agent_name: str | None = None,
|
|
138
|
+
) -> list[str]:
|
|
139
|
+
result = []
|
|
140
|
+
for session_id, data in self._sessions.items():
|
|
141
|
+
if pool_id is not None and data.pool_id != pool_id:
|
|
142
|
+
continue
|
|
143
|
+
if agent_name is not None and data.agent_name != agent_name:
|
|
144
|
+
continue
|
|
145
|
+
result.append(session_id)
|
|
146
|
+
return result
|
|
147
|
+
|
|
148
|
+
async def cleanup_expired(self, max_age_hours: int = 24) -> int:
|
|
149
|
+
from agentpool.utils.now import get_now
|
|
150
|
+
|
|
151
|
+
now = get_now()
|
|
152
|
+
expired = []
|
|
153
|
+
for session_id, data in self._sessions.items():
|
|
154
|
+
age_hours = (now - data.last_active).total_seconds() / 3600
|
|
155
|
+
if age_hours > max_age_hours:
|
|
156
|
+
expired.append(session_id)
|
|
157
|
+
|
|
158
|
+
for session_id in expired:
|
|
159
|
+
del self._sessions[session_id]
|
|
160
|
+
|
|
161
|
+
if expired:
|
|
162
|
+
logger.info("Cleaned up expired sessions", count=len(expired))
|
|
163
|
+
return len(expired)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""Skills manager for pool-wide management."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Self, overload
|
|
6
|
+
|
|
7
|
+
from upathtools import to_upath
|
|
8
|
+
|
|
9
|
+
from agentpool.log import get_logger
|
|
10
|
+
from agentpool.skills.registry import SkillsRegistry
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from fsspec import AbstractFileSystem
|
|
15
|
+
from upathtools import JoinablePathLike
|
|
16
|
+
|
|
17
|
+
from agentpool.skills.skill import Skill
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
logger = get_logger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SkillsManager:
|
|
24
|
+
"""Pool-wide skills registry management.
|
|
25
|
+
|
|
26
|
+
Owns the single skills registry for the pool. Skills can be discovered
|
|
27
|
+
from multiple directories. The actual `load_skill` tool is provided
|
|
28
|
+
separately via SkillsTools toolset.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
name: str = "skills",
|
|
34
|
+
owner: str | None = None,
|
|
35
|
+
skills_dirs: list[JoinablePathLike] | None = None,
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Initialize the skills manager.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
name: Name for this manager
|
|
41
|
+
owner: Owner of this manager
|
|
42
|
+
skills_dirs: Directories to search for skills
|
|
43
|
+
"""
|
|
44
|
+
self.name = name
|
|
45
|
+
self.owner = owner
|
|
46
|
+
self.registry = SkillsRegistry(skills_dirs)
|
|
47
|
+
self._initialized = False
|
|
48
|
+
|
|
49
|
+
def __repr__(self) -> str:
|
|
50
|
+
skill_count = len(self.registry.list_items()) if self._initialized else "?"
|
|
51
|
+
return f"SkillsManager(name={self.name!r}, skills={skill_count})"
|
|
52
|
+
|
|
53
|
+
async def __aenter__(self) -> Self:
|
|
54
|
+
"""Initialize the skills manager and discover skills."""
|
|
55
|
+
try:
|
|
56
|
+
await self.registry.discover_skills()
|
|
57
|
+
self._initialized = True
|
|
58
|
+
count = len(self.registry.list_items())
|
|
59
|
+
logger.info("Skills manager initialized", name=self.name, skill_count=count)
|
|
60
|
+
except Exception as e:
|
|
61
|
+
msg = "Failed to initialize skills manager"
|
|
62
|
+
logger.exception(msg, name=self.name, error=e)
|
|
63
|
+
raise
|
|
64
|
+
return self
|
|
65
|
+
|
|
66
|
+
async def __aexit__(self, *args: object) -> None:
|
|
67
|
+
"""Clean up the skills manager."""
|
|
68
|
+
# Skills are file-based, no persistent connections to clean up
|
|
69
|
+
|
|
70
|
+
@overload
|
|
71
|
+
async def add_skills_directory(self, path: JoinablePathLike) -> None: ...
|
|
72
|
+
|
|
73
|
+
@overload
|
|
74
|
+
async def add_skills_directory(self, path: str, *, fs: AbstractFileSystem) -> None: ...
|
|
75
|
+
|
|
76
|
+
async def add_skills_directory(
|
|
77
|
+
self,
|
|
78
|
+
path: JoinablePathLike,
|
|
79
|
+
*,
|
|
80
|
+
fs: AbstractFileSystem | None = None,
|
|
81
|
+
) -> None:
|
|
82
|
+
"""Add a new skills directory and discover its skills.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
path: Path to directory containing skills.
|
|
86
|
+
fs: Optional filesystem instance. When provided, path is interpreted
|
|
87
|
+
as a path within this filesystem (e.g., ".claude/skills").
|
|
88
|
+
"""
|
|
89
|
+
if fs is not None:
|
|
90
|
+
# Pass filesystem directly to registry with the path
|
|
91
|
+
await self.registry.register_skills_from_path(fs, base_path=str(path))
|
|
92
|
+
logger.info(
|
|
93
|
+
"Added skills directory from filesystem",
|
|
94
|
+
protocol=fs.protocol,
|
|
95
|
+
path=path,
|
|
96
|
+
)
|
|
97
|
+
else:
|
|
98
|
+
upath = to_upath(path)
|
|
99
|
+
if upath not in self.registry.skills_dirs:
|
|
100
|
+
self.registry.skills_dirs.append(upath)
|
|
101
|
+
await self.registry.register_skills_from_path(upath)
|
|
102
|
+
logger.info("Added skills directory", path=str(path))
|
|
103
|
+
|
|
104
|
+
async def refresh(self) -> None:
|
|
105
|
+
"""Force rediscovery of all skills."""
|
|
106
|
+
await self.registry.discover_skills()
|
|
107
|
+
skill_count = len(self.registry.list_items())
|
|
108
|
+
logger.info("Skills refreshed", name=self.name, skill_count=skill_count)
|
|
109
|
+
|
|
110
|
+
def list_skills(self) -> list[Skill]:
|
|
111
|
+
"""Get all available skills."""
|
|
112
|
+
return [self.registry.get(name) for name in self.registry.list_items()]
|
|
113
|
+
|
|
114
|
+
def get_skill(self, name: str) -> Skill:
|
|
115
|
+
"""Get a skill by name."""
|
|
116
|
+
return self.registry.get(name)
|
|
117
|
+
|
|
118
|
+
def get_skill_instructions(self, skill_name: str) -> str:
|
|
119
|
+
"""Get full instructions for a specific skill."""
|
|
120
|
+
return self.registry.get_skill_instructions(skill_name)
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""Claude Code Skills registry with auto-discovery."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from typing import TYPE_CHECKING, Any, ClassVar
|
|
7
|
+
|
|
8
|
+
from fsspec import AbstractFileSystem
|
|
9
|
+
from fsspec.asyn import AsyncFileSystem
|
|
10
|
+
from fsspec.implementations.asyn_wrapper import (
|
|
11
|
+
AsyncFileSystemWrapper,
|
|
12
|
+
)
|
|
13
|
+
from upathtools import is_directory
|
|
14
|
+
from upathtools.helpers import to_upath, upath_to_fs
|
|
15
|
+
|
|
16
|
+
from agentpool.log import get_logger
|
|
17
|
+
from agentpool.skills.skill import Skill
|
|
18
|
+
from agentpool.tools.exceptions import ToolError
|
|
19
|
+
from agentpool.utils.baseregistry import BaseRegistry
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from collections.abc import Sequence
|
|
24
|
+
|
|
25
|
+
from upathtools import JoinablePathLike, UPath
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
SKILL_NAME_LIMIT = 64
|
|
29
|
+
SKILL_DESCRIPTION_LIMIT = 1024
|
|
30
|
+
logger = get_logger(__name__)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class SkillsRegistry(BaseRegistry[str, Skill]):
|
|
34
|
+
"""Registry for Claude Code Skills with auto-discovery."""
|
|
35
|
+
|
|
36
|
+
DEFAULT_SKILL_PATHS: ClassVar = ["~/.claude/skills/", ".claude/skills/"]
|
|
37
|
+
|
|
38
|
+
def __init__(self, skills_dirs: Sequence[JoinablePathLike] | None = None) -> None:
|
|
39
|
+
"""Initialize with custom skill directories or auto-detect."""
|
|
40
|
+
super().__init__()
|
|
41
|
+
if skills_dirs:
|
|
42
|
+
self.skills_dirs = [to_upath(i) for i in skills_dirs or []]
|
|
43
|
+
else:
|
|
44
|
+
self.skills_dirs = [to_upath(i) for i in self.DEFAULT_SKILL_PATHS or []]
|
|
45
|
+
|
|
46
|
+
async def discover_skills(self) -> None:
|
|
47
|
+
"""Scan filesystem and register all found skills.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
filesystem: Optional async filesystem to use. If None, will use upath_to_fs()
|
|
51
|
+
to get appropriate filesystem for each skills directory.
|
|
52
|
+
"""
|
|
53
|
+
for skills_dir in self.skills_dirs:
|
|
54
|
+
await self.register_skills_from_path(skills_dir)
|
|
55
|
+
|
|
56
|
+
async def register_skills_from_path(
|
|
57
|
+
self,
|
|
58
|
+
skills_dir: JoinablePathLike | AbstractFileSystem,
|
|
59
|
+
base_path: str | None = None,
|
|
60
|
+
**storage_options: Any,
|
|
61
|
+
) -> None:
|
|
62
|
+
"""Register skills from a given path.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
skills_dir: Path to the directory containing skills, or filesystem instance.
|
|
66
|
+
base_path: When skills_dir is a filesystem, the path within that filesystem
|
|
67
|
+
to look for skills. Defaults to root_marker if not specified.
|
|
68
|
+
storage_options: Additional options to pass to the filesystem.
|
|
69
|
+
"""
|
|
70
|
+
if isinstance(skills_dir, AbstractFileSystem):
|
|
71
|
+
fs = skills_dir
|
|
72
|
+
if not isinstance(fs, AsyncFileSystem):
|
|
73
|
+
fs = AsyncFileSystemWrapper(fs)
|
|
74
|
+
search_path = base_path if base_path is not None else fs.root_marker
|
|
75
|
+
else:
|
|
76
|
+
fs = upath_to_fs(skills_dir, **storage_options)
|
|
77
|
+
search_path = fs.root_marker
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
# List entries in skills directory
|
|
81
|
+
entries = await fs._ls(search_path, detail=True)
|
|
82
|
+
except FileNotFoundError:
|
|
83
|
+
logger.warning("Skills directory not found", path=search_path)
|
|
84
|
+
return
|
|
85
|
+
# Filter for directories that might contain skills
|
|
86
|
+
skill_dirs = [
|
|
87
|
+
entry
|
|
88
|
+
for entry in entries
|
|
89
|
+
if await is_directory(fs, entry["name"], entry_type=entry.get("type"))
|
|
90
|
+
]
|
|
91
|
+
if not skill_dirs:
|
|
92
|
+
logger.info("No skills found", skills_dir=search_path)
|
|
93
|
+
return
|
|
94
|
+
logger.info("Found skills", skills=skill_dirs, skills_dir=search_path)
|
|
95
|
+
for skill_entry in skill_dirs:
|
|
96
|
+
skill_name = skill_entry["name"].lstrip("./")
|
|
97
|
+
# Construct full path for skill directory
|
|
98
|
+
if search_path and search_path != fs.root_marker:
|
|
99
|
+
skill_dir_path = to_upath(f"{search_path}/{skill_name}")
|
|
100
|
+
skill_md_path = f"{search_path}/{skill_name}/SKILL.md"
|
|
101
|
+
else:
|
|
102
|
+
skill_dir_path = to_upath(skill_name)
|
|
103
|
+
skill_md_path = f"{skill_name}/SKILL.md"
|
|
104
|
+
try:
|
|
105
|
+
await fs._cat_file(skill_md_path)
|
|
106
|
+
except FileNotFoundError:
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
skill = self._parse_skill(skill_dir_path)
|
|
111
|
+
self.register(skill.name, skill, replace=True)
|
|
112
|
+
except Exception as e: # noqa: BLE001
|
|
113
|
+
# Log but don't fail discovery for one bad skill
|
|
114
|
+
print(f"Warning: Failed to parse skill at {skill_dir_path}: {e}")
|
|
115
|
+
|
|
116
|
+
def _parse_skill(self, skill_dir: JoinablePathLike) -> Skill:
|
|
117
|
+
"""Parse a SKILL.md file and extract metadata."""
|
|
118
|
+
skill_file = to_upath(skill_dir) / "SKILL.md"
|
|
119
|
+
content = skill_file.read_text("utf-8")
|
|
120
|
+
|
|
121
|
+
# Extract YAML frontmatter
|
|
122
|
+
frontmatter_match = re.match(r"^---\s*\n(.*?)\n---\s*\n", content, re.DOTALL)
|
|
123
|
+
if not frontmatter_match:
|
|
124
|
+
msg = f"No YAML frontmatter found in {skill_file}"
|
|
125
|
+
raise ToolError(msg)
|
|
126
|
+
import yamling
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
metadata = yamling.load_yaml(frontmatter_match.group(1))
|
|
130
|
+
except yamling.YAMLError as e:
|
|
131
|
+
msg = f"Invalid YAML frontmatter in {skill_file}: {e}"
|
|
132
|
+
raise ToolError(msg) from e
|
|
133
|
+
|
|
134
|
+
# Validate required fields
|
|
135
|
+
if not isinstance(metadata, dict):
|
|
136
|
+
msg = f"YAML frontmatter must be a dictionary in {skill_file}"
|
|
137
|
+
raise ToolError(msg)
|
|
138
|
+
|
|
139
|
+
name = metadata.get("name")
|
|
140
|
+
description = metadata.get("description")
|
|
141
|
+
|
|
142
|
+
if not name:
|
|
143
|
+
msg = f"Missing 'name' field in {skill_file}"
|
|
144
|
+
raise ToolError(msg)
|
|
145
|
+
if not description:
|
|
146
|
+
msg = f"Missing 'description' field in {skill_file}"
|
|
147
|
+
raise ToolError(msg)
|
|
148
|
+
|
|
149
|
+
# Validate limits
|
|
150
|
+
if len(name) > SKILL_NAME_LIMIT:
|
|
151
|
+
msg = f"{skill_file}: Skill name exceeds {SKILL_NAME_LIMIT} chars"
|
|
152
|
+
raise ToolError(msg)
|
|
153
|
+
if len(description) > SKILL_DESCRIPTION_LIMIT:
|
|
154
|
+
msg = f"{skill_file}: Skill description exceeds {SKILL_DESCRIPTION_LIMIT} chars"
|
|
155
|
+
raise ToolError(msg)
|
|
156
|
+
|
|
157
|
+
return Skill(name=name, description=description, skill_path=to_upath(skill_dir))
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def _error_class(self) -> type[ToolError]:
|
|
161
|
+
"""Error class to use for this registry."""
|
|
162
|
+
return ToolError
|
|
163
|
+
|
|
164
|
+
def _validate_item(self, item: Any) -> Skill:
|
|
165
|
+
"""Validate and possibly transform item before registration."""
|
|
166
|
+
if not isinstance(item, Skill):
|
|
167
|
+
msg = f"Expected Skill instance, got {type(item)}"
|
|
168
|
+
raise ToolError(msg)
|
|
169
|
+
return item
|
|
170
|
+
|
|
171
|
+
def get_skill_instructions(self, skill_name: str) -> str:
|
|
172
|
+
"""Lazy load full instructions for a skill."""
|
|
173
|
+
skill = self.get(skill_name)
|
|
174
|
+
return skill.load_instructions()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
if __name__ == "__main__":
|
|
178
|
+
import os
|
|
179
|
+
|
|
180
|
+
import anyio
|
|
181
|
+
from upathtools import UPath
|
|
182
|
+
|
|
183
|
+
from agentpool.log import configure_logging
|
|
184
|
+
|
|
185
|
+
configure_logging()
|
|
186
|
+
|
|
187
|
+
async def main() -> None:
|
|
188
|
+
reg = SkillsRegistry()
|
|
189
|
+
p = UPath(
|
|
190
|
+
"github://",
|
|
191
|
+
token=os.getenv("GITHUB_TOKEN"),
|
|
192
|
+
username="phil65",
|
|
193
|
+
org="anthropics",
|
|
194
|
+
repo="skills",
|
|
195
|
+
)
|
|
196
|
+
print("Repository contents:")
|
|
197
|
+
print([f.name for f in p.iterdir()][:5]) # Show first 5 items
|
|
198
|
+
|
|
199
|
+
await reg.register_skills_from_path(
|
|
200
|
+
p,
|
|
201
|
+
token=os.getenv("GITHUB_TOKEN"),
|
|
202
|
+
username="phil65",
|
|
203
|
+
org="anthropics",
|
|
204
|
+
repo="skills",
|
|
205
|
+
)
|
|
206
|
+
print(f"Found {len(reg)} skills:")
|
|
207
|
+
for name, skill in reg.items():
|
|
208
|
+
print(f" - {name}: {skill.description[:60]}...")
|
|
209
|
+
|
|
210
|
+
anyio.run(main)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Claude Code Skill."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from upathtools import UPath
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class Skill:
|
|
15
|
+
"""A Claude Code Skill with metadata and lazy-loaded instructions."""
|
|
16
|
+
|
|
17
|
+
name: str
|
|
18
|
+
description: str
|
|
19
|
+
skill_path: UPath
|
|
20
|
+
instructions: str | None = None
|
|
21
|
+
|
|
22
|
+
def load_instructions(self) -> str:
|
|
23
|
+
"""Lazy load full instructions from SKILL.md."""
|
|
24
|
+
if self.instructions is None:
|
|
25
|
+
skill_file = self.skill_path / "SKILL.md"
|
|
26
|
+
if skill_file.exists():
|
|
27
|
+
content = skill_file.read_text(encoding="utf-8")
|
|
28
|
+
# Split on first --- after frontmatter
|
|
29
|
+
parts = content.split("---", 2)
|
|
30
|
+
if len(parts) >= 3: # noqa: PLR2004
|
|
31
|
+
self.instructions = parts[2].strip()
|
|
32
|
+
else:
|
|
33
|
+
self.instructions = ""
|
|
34
|
+
else:
|
|
35
|
+
self.instructions = ""
|
|
36
|
+
return self.instructions
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Storage package."""
|
|
2
|
+
|
|
3
|
+
from agentpool.storage.manager import StorageManager
|
|
4
|
+
from agentpool.storage.serialization import (
|
|
5
|
+
deserialize_messages,
|
|
6
|
+
deserialize_parts,
|
|
7
|
+
serialize_messages,
|
|
8
|
+
serialize_parts,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"StorageManager",
|
|
13
|
+
"deserialize_messages",
|
|
14
|
+
"deserialize_parts",
|
|
15
|
+
"serialize_messages",
|
|
16
|
+
"serialize_parts",
|
|
17
|
+
]
|