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,450 @@
|
|
|
1
|
+
"""Grep functionality for filesystem search operations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from enum import StrEnum, auto
|
|
6
|
+
import re
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
9
|
+
import anyenv
|
|
10
|
+
|
|
11
|
+
from agentpool.log import get_logger
|
|
12
|
+
from agentpool_toolsets.fsspec_toolset.helpers import DEFAULT_MAX_SIZE
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from exxec.base import ExecutionEnvironment
|
|
17
|
+
from fsspec.asyn import AsyncFileSystem
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
logger = get_logger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class GrepBackend(StrEnum):
|
|
24
|
+
"""Available grep backends."""
|
|
25
|
+
|
|
26
|
+
RIPGREP = auto()
|
|
27
|
+
GNU_GREP = auto()
|
|
28
|
+
PYTHON = auto()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# Default patterns to exclude from grep searches
|
|
32
|
+
DEFAULT_EXCLUDE_PATTERNS = [
|
|
33
|
+
".venv/",
|
|
34
|
+
"venv/",
|
|
35
|
+
".env/",
|
|
36
|
+
"env/",
|
|
37
|
+
"node_modules/",
|
|
38
|
+
".git/",
|
|
39
|
+
"__pycache__/",
|
|
40
|
+
".pytest_cache/",
|
|
41
|
+
".mypy_cache/",
|
|
42
|
+
".tox/",
|
|
43
|
+
".nox/",
|
|
44
|
+
".coverage/",
|
|
45
|
+
"htmlcov/",
|
|
46
|
+
"dist/",
|
|
47
|
+
"build/",
|
|
48
|
+
".idea/",
|
|
49
|
+
".vscode/",
|
|
50
|
+
"*.egg-info",
|
|
51
|
+
"*.pyc",
|
|
52
|
+
"*.pyo",
|
|
53
|
+
"*.pyd",
|
|
54
|
+
".DS_Store",
|
|
55
|
+
"Thumbs.db",
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
async def detect_grep_backend(env: ExecutionEnvironment) -> GrepBackend:
|
|
60
|
+
"""Detect available grep backend in the execution environment.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
env: ExecutionEnvironment to check for available tools
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Best available backend (ripgrep > GNU grep > Python)
|
|
67
|
+
"""
|
|
68
|
+
from anyenv.os_commands import get_os_command_provider
|
|
69
|
+
|
|
70
|
+
provider = get_os_command_provider(env.os_type)
|
|
71
|
+
which_cmd = provider.get_command("which")
|
|
72
|
+
|
|
73
|
+
# Try ripgrep first
|
|
74
|
+
cmd = which_cmd.create_command("rg")
|
|
75
|
+
result = await env.execute_command(cmd)
|
|
76
|
+
if which_cmd.parse_command(result.stdout or "", result.exit_code or 0):
|
|
77
|
+
return GrepBackend.RIPGREP
|
|
78
|
+
|
|
79
|
+
# Try GNU grep
|
|
80
|
+
cmd = which_cmd.create_command("grep")
|
|
81
|
+
result = await env.execute_command(cmd)
|
|
82
|
+
if which_cmd.parse_command(result.stdout or "", result.exit_code or 0):
|
|
83
|
+
return GrepBackend.GNU_GREP
|
|
84
|
+
|
|
85
|
+
return GrepBackend.PYTHON
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
async def grep_with_subprocess(
|
|
89
|
+
env: ExecutionEnvironment,
|
|
90
|
+
pattern: str,
|
|
91
|
+
path: str,
|
|
92
|
+
*,
|
|
93
|
+
backend: GrepBackend | None = None,
|
|
94
|
+
case_sensitive: bool = False,
|
|
95
|
+
max_matches: int = 100,
|
|
96
|
+
max_output_bytes: int = DEFAULT_MAX_SIZE,
|
|
97
|
+
exclude_patterns: list[str] | None = None,
|
|
98
|
+
use_gitignore: bool = True,
|
|
99
|
+
context_lines: int = 0,
|
|
100
|
+
timeout: int = 60,
|
|
101
|
+
) -> dict[str, Any]:
|
|
102
|
+
"""Execute grep using ExecutionEnvironment (ripgrep or GNU grep).
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
env: ExecutionEnvironment to run the command in
|
|
106
|
+
pattern: Regex pattern to search for
|
|
107
|
+
path: Directory or file path to search
|
|
108
|
+
backend: Grep backend to use (auto-detected if None)
|
|
109
|
+
case_sensitive: Whether search is case-sensitive
|
|
110
|
+
max_matches: Maximum number of matches per file
|
|
111
|
+
max_output_bytes: Maximum total output bytes
|
|
112
|
+
exclude_patterns: Patterns to exclude from search
|
|
113
|
+
use_gitignore: Whether to respect .gitignore files
|
|
114
|
+
context_lines: Number of context lines before/after match
|
|
115
|
+
timeout: Command timeout in seconds
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
Dictionary with matches, match_count, and was_truncated flag
|
|
119
|
+
"""
|
|
120
|
+
if backend is None:
|
|
121
|
+
backend = await detect_grep_backend(env)
|
|
122
|
+
|
|
123
|
+
if backend == GrepBackend.PYTHON:
|
|
124
|
+
msg = "Subprocess grep requested but no grep/ripgrep found"
|
|
125
|
+
raise ValueError(msg)
|
|
126
|
+
|
|
127
|
+
exclude = exclude_patterns or DEFAULT_EXCLUDE_PATTERNS
|
|
128
|
+
|
|
129
|
+
if backend == GrepBackend.RIPGREP:
|
|
130
|
+
cmd_list = _build_ripgrep_command(
|
|
131
|
+
pattern, path, case_sensitive, max_matches, exclude, use_gitignore, context_lines
|
|
132
|
+
)
|
|
133
|
+
else:
|
|
134
|
+
cmd_list = _build_gnu_grep_command(
|
|
135
|
+
pattern, path, case_sensitive, max_matches, exclude, context_lines
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Convert list to shell command string
|
|
139
|
+
import shlex
|
|
140
|
+
|
|
141
|
+
command = " ".join(shlex.quote(arg) for arg in cmd_list)
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
result = await env.execute_command(command)
|
|
145
|
+
|
|
146
|
+
# Exit code 0 = matches found, 1 = no matches, 2+ = error
|
|
147
|
+
if result.exit_code not in {0, 1, None}:
|
|
148
|
+
error_msg = result.stderr or f"Process exited with code {result.exit_code}"
|
|
149
|
+
return {
|
|
150
|
+
"error": f"grep error: {error_msg}",
|
|
151
|
+
"matches": "",
|
|
152
|
+
"match_count": 0,
|
|
153
|
+
"was_truncated": False,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
# Use appropriate parser based on backend
|
|
157
|
+
if backend == GrepBackend.RIPGREP:
|
|
158
|
+
return _parse_ripgrep_json_output(result.stdout or "", max_output_bytes)
|
|
159
|
+
return _parse_gnu_grep_output(result.stdout or "", max_output_bytes)
|
|
160
|
+
|
|
161
|
+
except Exception as e:
|
|
162
|
+
logger.exception("Error running grep command")
|
|
163
|
+
return {
|
|
164
|
+
"error": f"Error running grep: {e}",
|
|
165
|
+
"matches": "",
|
|
166
|
+
"match_count": 0,
|
|
167
|
+
"was_truncated": False,
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _build_ripgrep_command(
|
|
172
|
+
pattern: str,
|
|
173
|
+
path: str,
|
|
174
|
+
case_sensitive: bool,
|
|
175
|
+
max_matches: int,
|
|
176
|
+
exclude_patterns: list[str],
|
|
177
|
+
use_gitignore: bool,
|
|
178
|
+
context_lines: int = 0,
|
|
179
|
+
) -> list[str]:
|
|
180
|
+
"""Build ripgrep command with JSON output."""
|
|
181
|
+
cmd = [
|
|
182
|
+
"rg",
|
|
183
|
+
"--json", # Use JSON output for robust parsing
|
|
184
|
+
"--no-binary",
|
|
185
|
+
"--max-count",
|
|
186
|
+
str(max_matches + 1), # Request one extra to detect truncation
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
if not case_sensitive:
|
|
190
|
+
cmd.append("--smart-case")
|
|
191
|
+
|
|
192
|
+
if not use_gitignore:
|
|
193
|
+
cmd.append("--no-ignore")
|
|
194
|
+
|
|
195
|
+
# Add context lines if requested
|
|
196
|
+
if context_lines > 0:
|
|
197
|
+
cmd.extend(["--context", str(context_lines)])
|
|
198
|
+
|
|
199
|
+
for pattern_exclude in exclude_patterns:
|
|
200
|
+
cmd.extend(["--glob", f"!{pattern_exclude}"])
|
|
201
|
+
|
|
202
|
+
cmd.extend(["-e", pattern, path])
|
|
203
|
+
|
|
204
|
+
return cmd
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _build_gnu_grep_command(
|
|
208
|
+
pattern: str,
|
|
209
|
+
path: str,
|
|
210
|
+
case_sensitive: bool,
|
|
211
|
+
max_matches: int,
|
|
212
|
+
exclude_patterns: list[str],
|
|
213
|
+
context_lines: int = 0,
|
|
214
|
+
) -> list[str]:
|
|
215
|
+
"""Build GNU grep command."""
|
|
216
|
+
cmd = [
|
|
217
|
+
"grep",
|
|
218
|
+
"-r",
|
|
219
|
+
"-n",
|
|
220
|
+
"-I", # Skip binary files
|
|
221
|
+
"-E", # Extended regex
|
|
222
|
+
f"--max-count={max_matches + 1}",
|
|
223
|
+
]
|
|
224
|
+
|
|
225
|
+
if not case_sensitive and pattern.islower():
|
|
226
|
+
cmd.append("-i")
|
|
227
|
+
|
|
228
|
+
# Add context lines if requested
|
|
229
|
+
if context_lines > 0:
|
|
230
|
+
cmd.append(f"--context={context_lines}")
|
|
231
|
+
|
|
232
|
+
for pattern_exclude in exclude_patterns:
|
|
233
|
+
if pattern_exclude.endswith("/"):
|
|
234
|
+
dir_pattern = pattern_exclude.rstrip("/")
|
|
235
|
+
cmd.append(f"--exclude-dir={dir_pattern}")
|
|
236
|
+
else:
|
|
237
|
+
cmd.append(f"--exclude={pattern_exclude}")
|
|
238
|
+
|
|
239
|
+
cmd.extend(["-e", pattern, path])
|
|
240
|
+
|
|
241
|
+
return cmd
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def _parse_ripgrep_json_output(stdout: str, max_output_bytes: int) -> dict[str, Any]:
|
|
245
|
+
"""Parse ripgrep JSON output and format as markdown table.
|
|
246
|
+
|
|
247
|
+
Ripgrep --json outputs one JSON object per line with type field:
|
|
248
|
+
- "match": actual match with path, line_number, lines.text
|
|
249
|
+
- "context": context lines around matches
|
|
250
|
+
- "begin"/"end": file boundaries
|
|
251
|
+
- "summary": final statistics
|
|
252
|
+
"""
|
|
253
|
+
if not stdout:
|
|
254
|
+
return {"matches": "", "match_count": 0, "was_truncated": False}
|
|
255
|
+
|
|
256
|
+
matches: list[dict[str, Any]] = []
|
|
257
|
+
total_bytes = 0
|
|
258
|
+
was_truncated = False
|
|
259
|
+
|
|
260
|
+
for line in stdout.splitlines():
|
|
261
|
+
if not line.strip():
|
|
262
|
+
continue
|
|
263
|
+
try:
|
|
264
|
+
data = anyenv.load_json(line, return_type=dict)
|
|
265
|
+
if data.get("type") == "match":
|
|
266
|
+
match_data = data.get("data", {})
|
|
267
|
+
path = match_data.get("path", {}).get("text", "")
|
|
268
|
+
line_num = match_data.get("line_number", 0)
|
|
269
|
+
content = match_data.get("lines", {}).get("text", "").rstrip("\n")
|
|
270
|
+
|
|
271
|
+
match_entry = {"path": path, "line": line_num, "content": content}
|
|
272
|
+
entry_size = len(path) + len(str(line_num)) + len(content) + 10
|
|
273
|
+
|
|
274
|
+
if total_bytes + entry_size > max_output_bytes:
|
|
275
|
+
was_truncated = True
|
|
276
|
+
break
|
|
277
|
+
|
|
278
|
+
matches.append(match_entry)
|
|
279
|
+
total_bytes += entry_size
|
|
280
|
+
except anyenv.JsonLoadError:
|
|
281
|
+
continue
|
|
282
|
+
|
|
283
|
+
# Format as markdown table
|
|
284
|
+
if not matches:
|
|
285
|
+
return {"matches": "", "match_count": 0, "was_truncated": False}
|
|
286
|
+
|
|
287
|
+
table_lines = ["| File | Line | Content |", "|------|------|---------|"]
|
|
288
|
+
for m in matches:
|
|
289
|
+
# Escape pipe characters in content for markdown table
|
|
290
|
+
content = m["content"].replace("|", "\\|")
|
|
291
|
+
# Truncate long lines for readability
|
|
292
|
+
if len(content) > 100: # noqa: PLR2004
|
|
293
|
+
content = content[:97] + "..."
|
|
294
|
+
table_lines.append(f"| {m['path']} | {m['line']} | {content} |")
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
"matches": "\n".join(table_lines),
|
|
298
|
+
"match_count": len(matches),
|
|
299
|
+
"was_truncated": was_truncated,
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def _parse_gnu_grep_output(stdout: str, max_output_bytes: int) -> dict[str, Any]:
|
|
304
|
+
"""Parse GNU grep output and format as markdown table.
|
|
305
|
+
|
|
306
|
+
GNU grep output format: `file:linenum:content`
|
|
307
|
+
"""
|
|
308
|
+
if not stdout:
|
|
309
|
+
return {"matches": "", "match_count": 0, "was_truncated": False}
|
|
310
|
+
|
|
311
|
+
matches: list[dict[str, Any]] = []
|
|
312
|
+
total_bytes = 0
|
|
313
|
+
was_truncated = False
|
|
314
|
+
# Pattern: path:line_number:content (handles most cases)
|
|
315
|
+
line_pattern = re.compile(r"^(.+?):(\d+):(.*)$")
|
|
316
|
+
|
|
317
|
+
for line in stdout.splitlines():
|
|
318
|
+
if not line.strip() or line == "--":
|
|
319
|
+
continue
|
|
320
|
+
match = line_pattern.match(line)
|
|
321
|
+
if match:
|
|
322
|
+
path, line_num, content = match.groups()
|
|
323
|
+
entry_size = len(path) + len(line_num) + len(content) + 10
|
|
324
|
+
|
|
325
|
+
if total_bytes + entry_size > max_output_bytes:
|
|
326
|
+
was_truncated = True
|
|
327
|
+
break
|
|
328
|
+
|
|
329
|
+
matches.append({"path": path, "line": int(line_num), "content": content})
|
|
330
|
+
total_bytes += entry_size
|
|
331
|
+
|
|
332
|
+
if not matches:
|
|
333
|
+
return {"matches": "", "match_count": 0, "was_truncated": False}
|
|
334
|
+
|
|
335
|
+
table_lines = ["| File | Line | Content |", "|------|------|---------|"]
|
|
336
|
+
for m in matches:
|
|
337
|
+
content = m["content"].replace("|", "\\|")
|
|
338
|
+
if len(content) > 100: # noqa: PLR2004
|
|
339
|
+
content = content[:97] + "..."
|
|
340
|
+
table_lines.append(f"| {m['path']} | {m['line']} | {content} |")
|
|
341
|
+
|
|
342
|
+
return {
|
|
343
|
+
"matches": "\n".join(table_lines),
|
|
344
|
+
"match_count": len(matches),
|
|
345
|
+
"was_truncated": was_truncated,
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
async def grep_with_fsspec(
|
|
350
|
+
fs: AsyncFileSystem,
|
|
351
|
+
pattern: str,
|
|
352
|
+
path: str,
|
|
353
|
+
*,
|
|
354
|
+
file_pattern: str = "**/*",
|
|
355
|
+
case_sensitive: bool = False,
|
|
356
|
+
max_matches: int = 100,
|
|
357
|
+
max_output_bytes: int = DEFAULT_MAX_SIZE,
|
|
358
|
+
context_lines: int = 0,
|
|
359
|
+
) -> dict[str, Any]:
|
|
360
|
+
"""Execute grep using fsspec filesystem (Python implementation).
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
fs: FSSpec filesystem instance
|
|
364
|
+
pattern: Regex pattern to search for
|
|
365
|
+
path: Base directory to search in
|
|
366
|
+
file_pattern: Glob pattern to filter files
|
|
367
|
+
case_sensitive: Whether search is case-sensitive
|
|
368
|
+
max_matches: Maximum total matches across all files
|
|
369
|
+
max_output_bytes: Maximum total output bytes
|
|
370
|
+
context_lines: Number of context lines before/after match
|
|
371
|
+
|
|
372
|
+
Returns:
|
|
373
|
+
Dictionary with matches as markdown table
|
|
374
|
+
"""
|
|
375
|
+
try:
|
|
376
|
+
flags = 0 if case_sensitive else re.IGNORECASE
|
|
377
|
+
regex = re.compile(pattern, flags)
|
|
378
|
+
except re.error as e:
|
|
379
|
+
return {"error": f"Invalid regex pattern: {e}"}
|
|
380
|
+
|
|
381
|
+
try:
|
|
382
|
+
glob_path = f"{path.rstrip('/')}/{file_pattern}"
|
|
383
|
+
file_paths = await fs._glob(glob_path)
|
|
384
|
+
|
|
385
|
+
matches: list[dict[str, Any]] = []
|
|
386
|
+
total_bytes = 0
|
|
387
|
+
was_truncated = False
|
|
388
|
+
|
|
389
|
+
for file_path in file_paths:
|
|
390
|
+
if len(matches) >= max_matches or total_bytes >= max_output_bytes:
|
|
391
|
+
was_truncated = True
|
|
392
|
+
break
|
|
393
|
+
|
|
394
|
+
# Skip directories
|
|
395
|
+
if await fs._isdir(file_path):
|
|
396
|
+
continue
|
|
397
|
+
|
|
398
|
+
try:
|
|
399
|
+
content = await fs._cat_file(file_path)
|
|
400
|
+
# Skip binary files
|
|
401
|
+
if b"\x00" in content[:8192]:
|
|
402
|
+
continue
|
|
403
|
+
|
|
404
|
+
text = content.decode("utf-8", errors="replace")
|
|
405
|
+
lines = text.splitlines()
|
|
406
|
+
|
|
407
|
+
for line_num, line in enumerate(lines, 1):
|
|
408
|
+
if len(matches) >= max_matches or total_bytes >= max_output_bytes:
|
|
409
|
+
was_truncated = True
|
|
410
|
+
break
|
|
411
|
+
|
|
412
|
+
if regex.search(line):
|
|
413
|
+
line_content = line.rstrip()
|
|
414
|
+
entry_size = len(file_path) + len(str(line_num)) + len(line_content) + 10
|
|
415
|
+
|
|
416
|
+
if total_bytes + entry_size > max_output_bytes:
|
|
417
|
+
was_truncated = True
|
|
418
|
+
break
|
|
419
|
+
|
|
420
|
+
matches.append({
|
|
421
|
+
"path": file_path,
|
|
422
|
+
"line": line_num,
|
|
423
|
+
"content": line_content,
|
|
424
|
+
})
|
|
425
|
+
total_bytes += entry_size
|
|
426
|
+
|
|
427
|
+
except Exception as e: # noqa: BLE001
|
|
428
|
+
logger.debug("Error reading file during grep", file=file_path, error=str(e))
|
|
429
|
+
continue
|
|
430
|
+
|
|
431
|
+
except Exception as e:
|
|
432
|
+
logger.exception("Error in fsspec grep")
|
|
433
|
+
return {"error": f"Grep failed: {e}"}
|
|
434
|
+
|
|
435
|
+
# Format as markdown table
|
|
436
|
+
if not matches:
|
|
437
|
+
return {"matches": "", "match_count": 0, "was_truncated": False}
|
|
438
|
+
|
|
439
|
+
table_lines = ["| File | Line | Content |", "|------|------|---------|"]
|
|
440
|
+
for m in matches:
|
|
441
|
+
content = m["content"].replace("|", "\\|")
|
|
442
|
+
if len(content) > 100: # noqa: PLR2004
|
|
443
|
+
content = content[:97] + "..."
|
|
444
|
+
table_lines.append(f"| {m['path']} | {m['line']} | {content} |")
|
|
445
|
+
|
|
446
|
+
return {
|
|
447
|
+
"matches": "\n".join(table_lines),
|
|
448
|
+
"match_count": len(matches),
|
|
449
|
+
"was_truncated": was_truncated,
|
|
450
|
+
}
|