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,262 @@
|
|
|
1
|
+
"""SQL session store implementation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import timedelta
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Self
|
|
7
|
+
|
|
8
|
+
from sqlalchemy import delete, select
|
|
9
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
10
|
+
from sqlmodel import SQLModel
|
|
11
|
+
|
|
12
|
+
from agentpool.log import get_logger
|
|
13
|
+
from agentpool.sessions.models import SessionData
|
|
14
|
+
from agentpool.utils.now import get_now
|
|
15
|
+
from agentpool_storage.sql_provider.models import Session
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from types import TracebackType
|
|
20
|
+
|
|
21
|
+
from sqlalchemy.ext.asyncio import AsyncEngine
|
|
22
|
+
|
|
23
|
+
from agentpool_config.storage import SQLStorageConfig
|
|
24
|
+
|
|
25
|
+
logger = get_logger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SQLSessionStore:
|
|
29
|
+
"""SQL-based session store using SQLModel.
|
|
30
|
+
|
|
31
|
+
Persists session data to a SQL database, supporting:
|
|
32
|
+
- SQLite (default)
|
|
33
|
+
- PostgreSQL
|
|
34
|
+
- MySQL
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, config: SQLStorageConfig) -> None:
|
|
38
|
+
"""Initialize SQL session store.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
config: SQL storage configuration with database URL
|
|
42
|
+
"""
|
|
43
|
+
self._config = config
|
|
44
|
+
self._engine: AsyncEngine | None = None
|
|
45
|
+
|
|
46
|
+
async def __aenter__(self) -> Self:
|
|
47
|
+
"""Initialize database connection and create tables."""
|
|
48
|
+
self._engine = self._config.get_engine()
|
|
49
|
+
|
|
50
|
+
async with self._engine.begin() as conn:
|
|
51
|
+
await conn.run_sync(SQLModel.metadata.create_all)
|
|
52
|
+
|
|
53
|
+
# Auto-migrate missing columns
|
|
54
|
+
await self._migrate_columns()
|
|
55
|
+
|
|
56
|
+
logger.debug("SQL session store initialized", url=self._config.url)
|
|
57
|
+
return self
|
|
58
|
+
|
|
59
|
+
async def _migrate_columns(self) -> None:
|
|
60
|
+
"""Add missing columns to existing tables."""
|
|
61
|
+
from agentpool_storage.sql_provider.utils import auto_migrate_columns
|
|
62
|
+
|
|
63
|
+
if self._engine is None:
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
async with self._engine.begin() as conn:
|
|
67
|
+
|
|
68
|
+
def sync_migrate(sync_conn: Any) -> None:
|
|
69
|
+
auto_migrate_columns(sync_conn, self._engine.dialect) # type: ignore[union-attr]
|
|
70
|
+
|
|
71
|
+
await conn.run_sync(sync_migrate)
|
|
72
|
+
|
|
73
|
+
async def __aexit__(
|
|
74
|
+
self,
|
|
75
|
+
exc_type: type[BaseException] | None,
|
|
76
|
+
exc_val: BaseException | None,
|
|
77
|
+
exc_tb: TracebackType | None,
|
|
78
|
+
) -> None:
|
|
79
|
+
"""Close database connection."""
|
|
80
|
+
if self._engine:
|
|
81
|
+
await self._engine.dispose()
|
|
82
|
+
self._engine = None
|
|
83
|
+
|
|
84
|
+
def _get_engine(self) -> AsyncEngine:
|
|
85
|
+
"""Get engine, raising if not initialized."""
|
|
86
|
+
if self._engine is None:
|
|
87
|
+
msg = "Session store not initialized. Use async context manager."
|
|
88
|
+
raise RuntimeError(msg)
|
|
89
|
+
return self._engine
|
|
90
|
+
|
|
91
|
+
def _to_db_model(self, data: SessionData) -> Session:
|
|
92
|
+
"""Convert SessionData to database model."""
|
|
93
|
+
return Session(
|
|
94
|
+
session_id=data.session_id,
|
|
95
|
+
agent_name=data.agent_name,
|
|
96
|
+
conversation_id=data.conversation_id,
|
|
97
|
+
pool_id=data.pool_id,
|
|
98
|
+
title=data.title,
|
|
99
|
+
cwd=data.cwd,
|
|
100
|
+
created_at=data.created_at,
|
|
101
|
+
last_active=data.last_active,
|
|
102
|
+
metadata_json=data.metadata,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def _from_db_model(self, row: Session) -> SessionData:
|
|
106
|
+
"""Convert database model to SessionData."""
|
|
107
|
+
return SessionData(
|
|
108
|
+
session_id=row.session_id,
|
|
109
|
+
agent_name=row.agent_name,
|
|
110
|
+
conversation_id=row.conversation_id,
|
|
111
|
+
pool_id=row.pool_id,
|
|
112
|
+
title=row.title,
|
|
113
|
+
cwd=row.cwd,
|
|
114
|
+
created_at=row.created_at,
|
|
115
|
+
last_active=row.last_active,
|
|
116
|
+
metadata=row.metadata_json or {},
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
async def save(self, data: SessionData) -> None:
|
|
120
|
+
"""Save or update session data.
|
|
121
|
+
|
|
122
|
+
Uses delete-then-insert for upsert semantics.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
data: Session data to persist
|
|
126
|
+
"""
|
|
127
|
+
engine = self._get_engine()
|
|
128
|
+
|
|
129
|
+
async with AsyncSession(engine) as session:
|
|
130
|
+
# Delete existing if present (upsert via delete+insert)
|
|
131
|
+
stmt = delete(Session).where(Session.session_id == data.session_id) # type: ignore[arg-type]
|
|
132
|
+
await session.execute(stmt)
|
|
133
|
+
|
|
134
|
+
# Insert new/updated
|
|
135
|
+
db_session = self._to_db_model(data)
|
|
136
|
+
session.add(db_session)
|
|
137
|
+
await session.commit()
|
|
138
|
+
logger.debug("Saved session", session_id=data.session_id)
|
|
139
|
+
|
|
140
|
+
async def load(self, session_id: str) -> SessionData | None:
|
|
141
|
+
"""Load session data by ID.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
session_id: Session identifier
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
Session data if found, None otherwise
|
|
148
|
+
"""
|
|
149
|
+
engine = self._get_engine()
|
|
150
|
+
|
|
151
|
+
async with AsyncSession(engine) as session:
|
|
152
|
+
stmt = select(Session).where(Session.session_id == session_id) # type: ignore[arg-type]
|
|
153
|
+
result = await session.execute(stmt)
|
|
154
|
+
row = result.scalars().first()
|
|
155
|
+
|
|
156
|
+
if row is None:
|
|
157
|
+
return None
|
|
158
|
+
|
|
159
|
+
return self._from_db_model(row)
|
|
160
|
+
|
|
161
|
+
async def delete(self, session_id: str) -> bool:
|
|
162
|
+
"""Delete a session.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
session_id: Session identifier
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
True if session was deleted, False if not found
|
|
169
|
+
"""
|
|
170
|
+
engine = self._get_engine()
|
|
171
|
+
|
|
172
|
+
async with AsyncSession(engine) as session:
|
|
173
|
+
stmt = delete(Session).where(Session.session_id == session_id) # type: ignore[arg-type]
|
|
174
|
+
result = await session.execute(stmt)
|
|
175
|
+
await session.commit()
|
|
176
|
+
|
|
177
|
+
deleted: bool = result.rowcount > 0 # type: ignore[attr-defined]
|
|
178
|
+
if deleted:
|
|
179
|
+
logger.debug("Deleted session", session_id=session_id)
|
|
180
|
+
return deleted
|
|
181
|
+
|
|
182
|
+
async def list_sessions(
|
|
183
|
+
self,
|
|
184
|
+
pool_id: str | None = None,
|
|
185
|
+
agent_name: str | None = None,
|
|
186
|
+
) -> list[str]:
|
|
187
|
+
"""List session IDs, optionally filtered.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
pool_id: Filter by pool/manifest ID
|
|
191
|
+
agent_name: Filter by agent name
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
List of session IDs
|
|
195
|
+
"""
|
|
196
|
+
engine = self._get_engine()
|
|
197
|
+
|
|
198
|
+
async with AsyncSession(engine) as session:
|
|
199
|
+
stmt = select(Session.session_id) # type: ignore[call-overload]
|
|
200
|
+
|
|
201
|
+
if pool_id is not None:
|
|
202
|
+
stmt = stmt.where(Session.pool_id == pool_id)
|
|
203
|
+
if agent_name is not None:
|
|
204
|
+
stmt = stmt.where(Session.agent_name == agent_name)
|
|
205
|
+
|
|
206
|
+
stmt = stmt.order_by(Session.last_active.desc()) # type: ignore[attr-defined]
|
|
207
|
+
result = await session.execute(stmt)
|
|
208
|
+
# When selecting a single column, scalars() gives us the values directly
|
|
209
|
+
return list(result.scalars().all())
|
|
210
|
+
|
|
211
|
+
async def cleanup_expired(self, max_age_hours: int = 24) -> int:
|
|
212
|
+
"""Remove sessions older than max_age.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
max_age_hours: Maximum session age in hours
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Number of sessions removed
|
|
219
|
+
"""
|
|
220
|
+
engine = self._get_engine()
|
|
221
|
+
cutoff = get_now() - timedelta(hours=max_age_hours)
|
|
222
|
+
|
|
223
|
+
async with AsyncSession(engine) as session:
|
|
224
|
+
stmt = delete(Session).where(Session.last_active < cutoff) # type: ignore[arg-type]
|
|
225
|
+
result = await session.execute(stmt)
|
|
226
|
+
await session.commit()
|
|
227
|
+
|
|
228
|
+
count = result.rowcount or 0 # type: ignore[attr-defined]
|
|
229
|
+
if count > 0:
|
|
230
|
+
logger.info("Cleaned up expired sessions", count=count)
|
|
231
|
+
return count
|
|
232
|
+
|
|
233
|
+
async def get_all(
|
|
234
|
+
self,
|
|
235
|
+
pool_id: str | None = None,
|
|
236
|
+
limit: int | None = None,
|
|
237
|
+
) -> list[SessionData]:
|
|
238
|
+
"""Get all sessions, optionally filtered.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
pool_id: Filter by pool/manifest ID
|
|
242
|
+
limit: Maximum number of sessions to return
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
List of session data objects
|
|
246
|
+
"""
|
|
247
|
+
engine = self._get_engine()
|
|
248
|
+
|
|
249
|
+
async with AsyncSession(engine) as session:
|
|
250
|
+
stmt = select(Session)
|
|
251
|
+
|
|
252
|
+
if pool_id is not None:
|
|
253
|
+
stmt = stmt.where(Session.pool_id == pool_id) # type: ignore[arg-type]
|
|
254
|
+
|
|
255
|
+
stmt = stmt.order_by(Session.last_active.desc()) # type: ignore[attr-defined]
|
|
256
|
+
|
|
257
|
+
if limit is not None:
|
|
258
|
+
stmt = stmt.limit(limit)
|
|
259
|
+
|
|
260
|
+
result = await session.execute(stmt)
|
|
261
|
+
# scalars() gives us actual Session model instances
|
|
262
|
+
return [self._from_db_model(row) for row in result.scalars().all()]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""SQL storage provider package."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from agentpool_storage.sql_provider.sql_provider import SQLModelProvider
|
|
6
|
+
from agentpool_storage.sql_provider.models import (
|
|
7
|
+
Conversation,
|
|
8
|
+
Message,
|
|
9
|
+
CommandHistory,
|
|
10
|
+
MessageLog,
|
|
11
|
+
ConversationLog,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"CommandHistory",
|
|
16
|
+
"Conversation",
|
|
17
|
+
"ConversationLog",
|
|
18
|
+
"Message",
|
|
19
|
+
"MessageLog",
|
|
20
|
+
"SQLModelProvider",
|
|
21
|
+
]
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Database migration management script for agentpool.
|
|
3
|
+
|
|
4
|
+
This script provides easy commands for managing database migrations using Alembic.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
import subprocess
|
|
12
|
+
from typing import Annotated
|
|
13
|
+
|
|
14
|
+
from rich.console import Console
|
|
15
|
+
from rich.prompt import Confirm
|
|
16
|
+
import typer
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
app = typer.Typer(
|
|
20
|
+
name="agentpool-db",
|
|
21
|
+
help="Database migration management for agentpool",
|
|
22
|
+
rich_markup_mode="rich",
|
|
23
|
+
)
|
|
24
|
+
console = Console()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def run_command(cmd: list[str], cwd: Path | None = None) -> int:
|
|
28
|
+
"""Run a command and return the exit code."""
|
|
29
|
+
console.print(f"[bold blue]Running:[/bold blue] {' '.join(cmd)}")
|
|
30
|
+
result = subprocess.run(cmd, cwd=cwd, check=False)
|
|
31
|
+
if result.returncode != 0 and cmd[0] == "alembic":
|
|
32
|
+
console.print(
|
|
33
|
+
f"[bold red]Error:[/bold red] Command {cmd[0]!r} not found. "
|
|
34
|
+
"Make sure alembic is installed."
|
|
35
|
+
)
|
|
36
|
+
return result.returncode
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_project_root() -> Path:
|
|
40
|
+
"""Get the project root directory."""
|
|
41
|
+
# Start from this file and go up to find the project root
|
|
42
|
+
# This file is in src/agentpool_storage/sql_provider/cli.py
|
|
43
|
+
return Path(__file__).parent.parent.parent.parent
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@app.command()
|
|
47
|
+
def status() -> int:
|
|
48
|
+
"""Show current migration status."""
|
|
49
|
+
project_root = get_project_root()
|
|
50
|
+
return run_command(["alembic", "current", "-v"], cwd=project_root)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@app.command()
|
|
54
|
+
def upgrade(
|
|
55
|
+
revision: Annotated[str, typer.Argument(help="Target revision")] = "head",
|
|
56
|
+
) -> int:
|
|
57
|
+
"""Upgrade database to latest migration."""
|
|
58
|
+
project_root = get_project_root()
|
|
59
|
+
return run_command(["alembic", "upgrade", revision], cwd=project_root)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@app.command()
|
|
63
|
+
def downgrade(
|
|
64
|
+
revision: Annotated[
|
|
65
|
+
str,
|
|
66
|
+
typer.Argument(help="Target revision (e.g., -1 for previous, or specific revision ID)"),
|
|
67
|
+
],
|
|
68
|
+
) -> int:
|
|
69
|
+
"""Downgrade database."""
|
|
70
|
+
project_root = get_project_root()
|
|
71
|
+
return run_command(["alembic", "downgrade", revision], cwd=project_root)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@app.command()
|
|
75
|
+
def create(
|
|
76
|
+
message: Annotated[str, typer.Argument(help="Migration message")],
|
|
77
|
+
autogenerate: Annotated[
|
|
78
|
+
bool,
|
|
79
|
+
typer.Option(
|
|
80
|
+
"--autogenerate",
|
|
81
|
+
help="Auto-generate migration based on model changes",
|
|
82
|
+
),
|
|
83
|
+
] = False,
|
|
84
|
+
) -> int:
|
|
85
|
+
"""Create a new migration."""
|
|
86
|
+
project_root = get_project_root()
|
|
87
|
+
cmd = ["alembic", "revision", "-m", message]
|
|
88
|
+
if autogenerate:
|
|
89
|
+
cmd.append("--autogenerate")
|
|
90
|
+
return run_command(cmd, cwd=project_root)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@app.command()
|
|
94
|
+
def history() -> int:
|
|
95
|
+
"""Show migration history."""
|
|
96
|
+
project_root = get_project_root()
|
|
97
|
+
return run_command(["alembic", "history", "-v"], cwd=project_root)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@app.command()
|
|
101
|
+
def current() -> int:
|
|
102
|
+
"""Show current revision."""
|
|
103
|
+
project_root = get_project_root()
|
|
104
|
+
return run_command(["alembic", "current"], cwd=project_root)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@app.command()
|
|
108
|
+
def reset(
|
|
109
|
+
force: Annotated[
|
|
110
|
+
bool,
|
|
111
|
+
typer.Option("--force", help="Force reset without confirmation"),
|
|
112
|
+
] = False,
|
|
113
|
+
) -> int:
|
|
114
|
+
"""Reset database (WARNING: destructive)."""
|
|
115
|
+
if not force and not Confirm.ask(
|
|
116
|
+
"[bold red]This will delete all data in the database. Continue?[/bold red]",
|
|
117
|
+
default=False,
|
|
118
|
+
):
|
|
119
|
+
console.print("[yellow]Aborted.[/yellow]")
|
|
120
|
+
return 0
|
|
121
|
+
|
|
122
|
+
project_root = get_project_root()
|
|
123
|
+
console.print("[bold yellow]Resetting database...[/bold yellow]")
|
|
124
|
+
|
|
125
|
+
# First, drop to base (empty database)
|
|
126
|
+
result = run_command(["alembic", "downgrade", "base"], cwd=project_root)
|
|
127
|
+
if result != 0:
|
|
128
|
+
return result
|
|
129
|
+
|
|
130
|
+
# Then upgrade to head
|
|
131
|
+
return run_command(["alembic", "upgrade", "head"], cwd=project_root)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def main() -> None:
|
|
135
|
+
"""Main entry point."""
|
|
136
|
+
# Set up environment
|
|
137
|
+
project_root = get_project_root()
|
|
138
|
+
env = os.environ.copy()
|
|
139
|
+
env["PYTHONPATH"] = str(project_root / "src")
|
|
140
|
+
os.environ.update(env)
|
|
141
|
+
|
|
142
|
+
app()
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
main()
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"""Database models for agentpool storage."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import UTC, datetime
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from uuid import uuid4
|
|
8
|
+
|
|
9
|
+
from pydantic import ConfigDict
|
|
10
|
+
from schemez import Schema
|
|
11
|
+
from sqlalchemy import Column, DateTime, Text
|
|
12
|
+
from sqlalchemy.ext.asyncio import AsyncAttrs
|
|
13
|
+
from sqlalchemy.types import TypeDecorator
|
|
14
|
+
from sqlmodel import JSON, Field, SQLModel
|
|
15
|
+
from sqlmodel.main import SQLModelConfig # type: ignore[attr-defined]
|
|
16
|
+
|
|
17
|
+
from agentpool.common_types import JsonValue
|
|
18
|
+
from agentpool.utils.now import get_now
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from sqlalchemy import Dialect
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class UTCDateTime(TypeDecorator[datetime]):
|
|
26
|
+
"""Stores DateTime as UTC."""
|
|
27
|
+
|
|
28
|
+
impl = DateTime
|
|
29
|
+
cache_ok = True
|
|
30
|
+
|
|
31
|
+
def process_bind_param(
|
|
32
|
+
self,
|
|
33
|
+
value: datetime | None,
|
|
34
|
+
dialect: Dialect,
|
|
35
|
+
) -> datetime | None:
|
|
36
|
+
if value is not None:
|
|
37
|
+
value = value.replace(tzinfo=UTC) if value.tzinfo is None else value.astimezone(UTC)
|
|
38
|
+
return value
|
|
39
|
+
|
|
40
|
+
def process_result_value(
|
|
41
|
+
self,
|
|
42
|
+
value: datetime | None,
|
|
43
|
+
dialect: Dialect,
|
|
44
|
+
) -> datetime | None:
|
|
45
|
+
if value is not None:
|
|
46
|
+
value = value.replace(tzinfo=UTC)
|
|
47
|
+
return value
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class CommandHistory(AsyncAttrs, SQLModel, table=True):
|
|
51
|
+
"""Database model for command history."""
|
|
52
|
+
|
|
53
|
+
id: int = Field(default=None, primary_key=True)
|
|
54
|
+
"""Primary key for command history entry"""
|
|
55
|
+
|
|
56
|
+
session_id: str = Field(index=True)
|
|
57
|
+
"""ID of the chat session"""
|
|
58
|
+
|
|
59
|
+
agent_name: str = Field(index=True)
|
|
60
|
+
"""Name of the agent that executed the command"""
|
|
61
|
+
|
|
62
|
+
command: str
|
|
63
|
+
"""The command that was executed"""
|
|
64
|
+
|
|
65
|
+
context_type: str | None = Field(default=None, index=True)
|
|
66
|
+
"""Type of the command context (e.g. 'AgentContext', 'PoolSupervisor', etc.)"""
|
|
67
|
+
|
|
68
|
+
context_metadata: dict[str, JsonValue] = Field(default_factory=dict, sa_column=Column(JSON))
|
|
69
|
+
"""Additional context information about command execution"""
|
|
70
|
+
|
|
71
|
+
timestamp: datetime = Field(
|
|
72
|
+
sa_column=Column(UTCDateTime, default=get_now), default_factory=get_now
|
|
73
|
+
)
|
|
74
|
+
"""When the command was executed"""
|
|
75
|
+
|
|
76
|
+
model_config = SQLModelConfig(use_attribute_docstrings=True) # pyright: ignore[reportCallIssue]
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class MessageLog(Schema):
|
|
80
|
+
"""Raw message log entry."""
|
|
81
|
+
|
|
82
|
+
timestamp: datetime
|
|
83
|
+
"""When the message was sent"""
|
|
84
|
+
|
|
85
|
+
role: str
|
|
86
|
+
"""Role of the message sender (user/assistant/system)"""
|
|
87
|
+
|
|
88
|
+
content: str
|
|
89
|
+
"""Content of the message"""
|
|
90
|
+
|
|
91
|
+
token_usage: dict[str, int] | None = None
|
|
92
|
+
"""Token usage statistics as provided by model"""
|
|
93
|
+
|
|
94
|
+
cost: float | None = None
|
|
95
|
+
"""Cost of generating this message in USD"""
|
|
96
|
+
|
|
97
|
+
model: str | None = None
|
|
98
|
+
"""Name of the model that generated this message"""
|
|
99
|
+
|
|
100
|
+
model_config = ConfigDict(frozen=True)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class ConversationLog(Schema):
|
|
104
|
+
"""Collection of messages forming a conversation."""
|
|
105
|
+
|
|
106
|
+
id: str
|
|
107
|
+
"""Unique identifier for the conversation"""
|
|
108
|
+
|
|
109
|
+
agent_name: str
|
|
110
|
+
"""Name of the agent handling the conversation"""
|
|
111
|
+
|
|
112
|
+
start_time: datetime
|
|
113
|
+
"""When the conversation started"""
|
|
114
|
+
|
|
115
|
+
messages: list[MessageLog]
|
|
116
|
+
"""List of messages in the conversation"""
|
|
117
|
+
|
|
118
|
+
model_config = ConfigDict(frozen=True)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class Message(AsyncAttrs, SQLModel, table=True):
|
|
122
|
+
"""Database model for message logs."""
|
|
123
|
+
|
|
124
|
+
id: str = Field(default_factory=lambda: str(uuid4()), primary_key=True)
|
|
125
|
+
"""Unique identifier for the message"""
|
|
126
|
+
|
|
127
|
+
conversation_id: str = Field(index=True)
|
|
128
|
+
"""ID of the conversation this message belongs to"""
|
|
129
|
+
|
|
130
|
+
timestamp: datetime = Field(
|
|
131
|
+
sa_column=Column(UTCDateTime, default=get_now), default_factory=get_now
|
|
132
|
+
)
|
|
133
|
+
"""When the message was sent"""
|
|
134
|
+
|
|
135
|
+
role: str
|
|
136
|
+
"""Role of the message sender (user/assistant/system)"""
|
|
137
|
+
|
|
138
|
+
name: str | None = Field(default=None, index=True)
|
|
139
|
+
"""Display name of the sender"""
|
|
140
|
+
|
|
141
|
+
content: str
|
|
142
|
+
"""Content of the message"""
|
|
143
|
+
|
|
144
|
+
model: str | None = None
|
|
145
|
+
"""Full model identifier (including provider)"""
|
|
146
|
+
|
|
147
|
+
model_name: str | None = Field(default=None, index=True)
|
|
148
|
+
"""Name of the model (e.g., "gpt-5")"""
|
|
149
|
+
|
|
150
|
+
model_provider: str | None = Field(default=None, index=True)
|
|
151
|
+
"""Provider of the model (e.g., "openai")"""
|
|
152
|
+
|
|
153
|
+
forwarded_from: list[str] | None = Field(default=None, sa_column=Column(JSON))
|
|
154
|
+
"""List of agent names that forwarded this message"""
|
|
155
|
+
|
|
156
|
+
total_tokens: int | None = Field(default=None, index=True)
|
|
157
|
+
"""Total number of tokens used"""
|
|
158
|
+
|
|
159
|
+
input_tokens: int | None = None
|
|
160
|
+
"""Number of tokens in the prompt"""
|
|
161
|
+
|
|
162
|
+
output_tokens: int | None = None
|
|
163
|
+
"""Number of tokens in the completion"""
|
|
164
|
+
|
|
165
|
+
cost: float | None = Field(default=None, index=True)
|
|
166
|
+
"""Cost of generating this message in USD"""
|
|
167
|
+
|
|
168
|
+
response_time: float | None = None
|
|
169
|
+
"""Time taken to generate the response in seconds"""
|
|
170
|
+
|
|
171
|
+
provider_name: str | None = Field(default=None, index=True)
|
|
172
|
+
"""Name of the LLM provider that generated the response"""
|
|
173
|
+
|
|
174
|
+
provider_response_id: str | None = None
|
|
175
|
+
"""Request ID as specified by the model provider"""
|
|
176
|
+
|
|
177
|
+
messages: str | None = None
|
|
178
|
+
"""Serialized pydantic-ai model messages"""
|
|
179
|
+
|
|
180
|
+
finish_reason: str | None = None # Literal pydantic_ai.FinishReason
|
|
181
|
+
"""Reason the model finished generating the response"""
|
|
182
|
+
|
|
183
|
+
checkpoint_data: dict[str, Any] | None = Field(default=None, sa_column=Column(JSON))
|
|
184
|
+
"""A dictionary of checkpoints (name -> metadata)."""
|
|
185
|
+
|
|
186
|
+
model_config = SQLModelConfig(use_attribute_docstrings=True) # pyright: ignore[reportCallIssue]
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class Session(AsyncAttrs, SQLModel, table=True):
|
|
190
|
+
"""Database model for session persistence."""
|
|
191
|
+
|
|
192
|
+
session_id: str = Field(primary_key=True)
|
|
193
|
+
"""Unique session identifier."""
|
|
194
|
+
|
|
195
|
+
agent_name: str = Field(index=True)
|
|
196
|
+
"""Name of the currently active agent."""
|
|
197
|
+
|
|
198
|
+
conversation_id: str = Field(index=True)
|
|
199
|
+
"""Links to conversation in message storage."""
|
|
200
|
+
|
|
201
|
+
pool_id: str | None = Field(default=None, index=True)
|
|
202
|
+
"""Optional pool/manifest identifier for multi-pool setups."""
|
|
203
|
+
|
|
204
|
+
title: str | None = Field(default=None, index=True)
|
|
205
|
+
"""AI-generated or user-provided title for the conversation."""
|
|
206
|
+
|
|
207
|
+
cwd: str | None = Field(default=None, sa_column=Column(Text))
|
|
208
|
+
"""Working directory for the session."""
|
|
209
|
+
|
|
210
|
+
created_at: datetime = Field(
|
|
211
|
+
sa_column=Column(UTCDateTime, index=True),
|
|
212
|
+
default_factory=get_now,
|
|
213
|
+
)
|
|
214
|
+
"""When the session was created."""
|
|
215
|
+
|
|
216
|
+
last_active: datetime = Field(
|
|
217
|
+
sa_column=Column(UTCDateTime, index=True),
|
|
218
|
+
default_factory=get_now,
|
|
219
|
+
)
|
|
220
|
+
"""Last activity timestamp."""
|
|
221
|
+
|
|
222
|
+
metadata_json: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
|
|
223
|
+
"""Protocol-specific or custom metadata stored as JSON."""
|
|
224
|
+
|
|
225
|
+
model_config = SQLModelConfig(use_attribute_docstrings=True) # pyright: ignore[reportCallIssue]
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
class Conversation(AsyncAttrs, SQLModel, table=True):
|
|
229
|
+
"""Database model for conversations."""
|
|
230
|
+
|
|
231
|
+
id: str = Field(primary_key=True)
|
|
232
|
+
"""Unique identifier for the conversation"""
|
|
233
|
+
|
|
234
|
+
agent_name: str = Field(index=True)
|
|
235
|
+
"""Name of the agent handling the conversation"""
|
|
236
|
+
|
|
237
|
+
title: str | None = Field(default=None, index=True)
|
|
238
|
+
"""Generated title for the conversation"""
|
|
239
|
+
|
|
240
|
+
start_time: datetime = Field(sa_column=Column(UTCDateTime, index=True), default_factory=get_now)
|
|
241
|
+
"""When the conversation started"""
|
|
242
|
+
|
|
243
|
+
total_tokens: int = 0
|
|
244
|
+
"""Total number of tokens used in this conversation"""
|
|
245
|
+
|
|
246
|
+
total_cost: float = 0.0
|
|
247
|
+
"""Total cost of this conversation in USD"""
|
|
248
|
+
|
|
249
|
+
model_config = SQLModelConfig(use_attribute_docstrings=True) # pyright: ignore[reportCallIssue]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Some pre-defined Queries."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
DELETE_AGENT_MESSAGES = """\
|
|
7
|
+
DELETE FROM message
|
|
8
|
+
WHERE conversation_id IN (
|
|
9
|
+
SELECT id FROM conversation WHERE agent_name = :agent
|
|
10
|
+
)
|
|
11
|
+
"""
|
|
12
|
+
DELETE_AGENT_CONVERSATIONS = "DELETE FROM conversation WHERE agent_name = :agent"
|
|
13
|
+
|
|
14
|
+
DELETE_ALL_MESSAGES = "DELETE FROM message"
|
|
15
|
+
DELETE_ALL_CONVERSATIONS = "DELETE FROM conversation"
|