agentpool 2.2.3__py3-none-any.whl → 2.5.0__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.
- acp/__init__.py +0 -4
- acp/acp_requests.py +20 -77
- acp/agent/connection.py +8 -0
- acp/agent/implementations/debug_server/debug_server.py +6 -2
- acp/agent/protocol.py +6 -0
- acp/client/connection.py +38 -29
- acp/client/implementations/default_client.py +3 -2
- acp/client/implementations/headless_client.py +2 -2
- acp/connection.py +2 -2
- acp/notifications.py +18 -49
- acp/schema/__init__.py +2 -0
- acp/schema/agent_responses.py +21 -0
- acp/schema/client_requests.py +3 -3
- acp/schema/session_state.py +63 -29
- acp/task/supervisor.py +2 -2
- acp/utils.py +2 -2
- agentpool/__init__.py +2 -0
- agentpool/agents/acp_agent/acp_agent.py +278 -263
- agentpool/agents/acp_agent/acp_converters.py +150 -17
- agentpool/agents/acp_agent/client_handler.py +35 -24
- agentpool/agents/acp_agent/session_state.py +14 -6
- agentpool/agents/agent.py +471 -643
- agentpool/agents/agui_agent/agui_agent.py +104 -107
- agentpool/agents/agui_agent/helpers.py +3 -4
- agentpool/agents/base_agent.py +485 -32
- agentpool/agents/claude_code_agent/FORKING.md +191 -0
- agentpool/agents/claude_code_agent/__init__.py +13 -1
- agentpool/agents/claude_code_agent/claude_code_agent.py +654 -334
- agentpool/agents/claude_code_agent/converters.py +4 -141
- agentpool/agents/claude_code_agent/models.py +77 -0
- agentpool/agents/claude_code_agent/static_info.py +100 -0
- agentpool/agents/claude_code_agent/usage.py +242 -0
- agentpool/agents/events/__init__.py +22 -0
- agentpool/agents/events/builtin_handlers.py +65 -0
- agentpool/agents/events/event_emitter.py +3 -0
- agentpool/agents/events/events.py +84 -3
- agentpool/agents/events/infer_info.py +145 -0
- agentpool/agents/events/processors.py +254 -0
- agentpool/agents/interactions.py +41 -6
- agentpool/agents/modes.py +13 -0
- agentpool/agents/slashed_agent.py +5 -4
- agentpool/agents/tool_wrapping.py +18 -6
- agentpool/common_types.py +35 -21
- agentpool/config_resources/acp_assistant.yml +2 -2
- agentpool/config_resources/agents.yml +3 -0
- agentpool/config_resources/agents_template.yml +1 -0
- agentpool/config_resources/claude_code_agent.yml +9 -8
- agentpool/config_resources/external_acp_agents.yml +2 -1
- agentpool/delegation/base_team.py +4 -30
- agentpool/delegation/pool.py +104 -265
- agentpool/delegation/team.py +57 -57
- agentpool/delegation/teamrun.py +50 -55
- agentpool/functional/run.py +10 -4
- agentpool/mcp_server/client.py +73 -38
- agentpool/mcp_server/conversions.py +54 -13
- agentpool/mcp_server/manager.py +9 -23
- agentpool/mcp_server/registries/official_registry_client.py +10 -1
- agentpool/mcp_server/tool_bridge.py +114 -79
- agentpool/messaging/connection_manager.py +11 -10
- agentpool/messaging/event_manager.py +5 -5
- agentpool/messaging/message_container.py +6 -30
- agentpool/messaging/message_history.py +87 -8
- agentpool/messaging/messagenode.py +52 -14
- agentpool/messaging/messages.py +2 -26
- agentpool/messaging/processing.py +10 -22
- agentpool/models/__init__.py +1 -1
- agentpool/models/acp_agents/base.py +6 -2
- agentpool/models/acp_agents/mcp_capable.py +124 -15
- agentpool/models/acp_agents/non_mcp.py +0 -23
- agentpool/models/agents.py +66 -66
- agentpool/models/agui_agents.py +1 -1
- agentpool/models/claude_code_agents.py +111 -17
- agentpool/models/file_parsing.py +0 -1
- agentpool/models/manifest.py +70 -50
- agentpool/prompts/conversion_manager.py +1 -1
- agentpool/prompts/prompts.py +5 -2
- agentpool/resource_providers/__init__.py +2 -0
- agentpool/resource_providers/aggregating.py +4 -2
- agentpool/resource_providers/base.py +13 -3
- agentpool/resource_providers/codemode/code_executor.py +72 -5
- agentpool/resource_providers/codemode/helpers.py +2 -2
- agentpool/resource_providers/codemode/provider.py +64 -12
- agentpool/resource_providers/codemode/remote_mcp_execution.py +2 -2
- agentpool/resource_providers/codemode/remote_provider.py +9 -12
- agentpool/resource_providers/filtering.py +3 -1
- agentpool/resource_providers/mcp_provider.py +66 -12
- agentpool/resource_providers/plan_provider.py +111 -18
- agentpool/resource_providers/pool.py +5 -3
- agentpool/resource_providers/resource_info.py +111 -0
- agentpool/resource_providers/static.py +2 -2
- agentpool/sessions/__init__.py +2 -0
- agentpool/sessions/manager.py +2 -3
- agentpool/sessions/models.py +9 -6
- agentpool/sessions/protocol.py +28 -0
- agentpool/sessions/session.py +11 -55
- agentpool/storage/manager.py +361 -54
- agentpool/talk/registry.py +4 -4
- agentpool/talk/talk.py +9 -10
- agentpool/testing.py +1 -1
- agentpool/tool_impls/__init__.py +6 -0
- agentpool/tool_impls/agent_cli/__init__.py +42 -0
- agentpool/tool_impls/agent_cli/tool.py +95 -0
- agentpool/tool_impls/bash/__init__.py +64 -0
- agentpool/tool_impls/bash/helpers.py +35 -0
- agentpool/tool_impls/bash/tool.py +171 -0
- agentpool/tool_impls/delete_path/__init__.py +70 -0
- agentpool/tool_impls/delete_path/tool.py +142 -0
- agentpool/tool_impls/download_file/__init__.py +80 -0
- agentpool/tool_impls/download_file/tool.py +183 -0
- agentpool/tool_impls/execute_code/__init__.py +55 -0
- agentpool/tool_impls/execute_code/tool.py +163 -0
- agentpool/tool_impls/grep/__init__.py +80 -0
- agentpool/tool_impls/grep/tool.py +200 -0
- agentpool/tool_impls/list_directory/__init__.py +73 -0
- agentpool/tool_impls/list_directory/tool.py +197 -0
- agentpool/tool_impls/question/__init__.py +42 -0
- agentpool/tool_impls/question/tool.py +127 -0
- agentpool/tool_impls/read/__init__.py +104 -0
- agentpool/tool_impls/read/tool.py +305 -0
- agentpool/tools/__init__.py +2 -1
- agentpool/tools/base.py +114 -34
- agentpool/tools/manager.py +57 -1
- agentpool/ui/base.py +2 -2
- agentpool/ui/mock_provider.py +2 -2
- agentpool/ui/stdlib_provider.py +2 -2
- agentpool/utils/streams.py +21 -96
- agentpool/vfs_registry.py +7 -2
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/METADATA +16 -22
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/RECORD +242 -195
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/WHEEL +1 -1
- agentpool_cli/__main__.py +20 -0
- agentpool_cli/create.py +1 -1
- agentpool_cli/serve_acp.py +59 -1
- agentpool_cli/serve_opencode.py +1 -1
- agentpool_cli/ui.py +557 -0
- agentpool_commands/__init__.py +12 -5
- agentpool_commands/agents.py +1 -1
- agentpool_commands/pool.py +260 -0
- agentpool_commands/session.py +1 -1
- agentpool_commands/text_sharing/__init__.py +119 -0
- agentpool_commands/text_sharing/base.py +123 -0
- agentpool_commands/text_sharing/github_gist.py +80 -0
- agentpool_commands/text_sharing/opencode.py +462 -0
- agentpool_commands/text_sharing/paste_rs.py +59 -0
- agentpool_commands/text_sharing/pastebin.py +116 -0
- agentpool_commands/text_sharing/shittycodingagent.py +112 -0
- agentpool_commands/utils.py +31 -32
- agentpool_config/__init__.py +30 -2
- agentpool_config/agentpool_tools.py +498 -0
- agentpool_config/converters.py +1 -1
- agentpool_config/event_handlers.py +42 -0
- agentpool_config/events.py +1 -1
- agentpool_config/forward_targets.py +1 -4
- agentpool_config/jinja.py +3 -3
- agentpool_config/mcp_server.py +1 -5
- agentpool_config/nodes.py +1 -1
- agentpool_config/observability.py +44 -0
- agentpool_config/session.py +0 -3
- agentpool_config/storage.py +38 -39
- agentpool_config/task.py +3 -3
- agentpool_config/tools.py +11 -28
- agentpool_config/toolsets.py +22 -90
- agentpool_server/a2a_server/agent_worker.py +307 -0
- agentpool_server/a2a_server/server.py +23 -18
- agentpool_server/acp_server/acp_agent.py +125 -56
- agentpool_server/acp_server/commands/acp_commands.py +46 -216
- agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +8 -7
- agentpool_server/acp_server/event_converter.py +651 -0
- agentpool_server/acp_server/input_provider.py +53 -10
- agentpool_server/acp_server/server.py +1 -11
- agentpool_server/acp_server/session.py +90 -410
- agentpool_server/acp_server/session_manager.py +8 -34
- agentpool_server/agui_server/server.py +3 -1
- agentpool_server/mcp_server/server.py +5 -2
- agentpool_server/opencode_server/ENDPOINTS.md +53 -14
- agentpool_server/opencode_server/OPENCODE_UI_TOOLS_COMPLETE.md +202 -0
- agentpool_server/opencode_server/__init__.py +0 -8
- agentpool_server/opencode_server/converters.py +132 -26
- agentpool_server/opencode_server/input_provider.py +160 -8
- agentpool_server/opencode_server/models/__init__.py +42 -20
- agentpool_server/opencode_server/models/app.py +12 -0
- agentpool_server/opencode_server/models/events.py +203 -29
- agentpool_server/opencode_server/models/mcp.py +19 -0
- agentpool_server/opencode_server/models/message.py +18 -1
- agentpool_server/opencode_server/models/parts.py +134 -1
- agentpool_server/opencode_server/models/question.py +56 -0
- agentpool_server/opencode_server/models/session.py +13 -1
- agentpool_server/opencode_server/routes/__init__.py +4 -0
- agentpool_server/opencode_server/routes/agent_routes.py +33 -2
- agentpool_server/opencode_server/routes/app_routes.py +66 -3
- agentpool_server/opencode_server/routes/config_routes.py +66 -5
- agentpool_server/opencode_server/routes/file_routes.py +184 -5
- agentpool_server/opencode_server/routes/global_routes.py +1 -1
- agentpool_server/opencode_server/routes/lsp_routes.py +1 -1
- agentpool_server/opencode_server/routes/message_routes.py +122 -66
- agentpool_server/opencode_server/routes/permission_routes.py +63 -0
- agentpool_server/opencode_server/routes/pty_routes.py +23 -22
- agentpool_server/opencode_server/routes/question_routes.py +128 -0
- agentpool_server/opencode_server/routes/session_routes.py +139 -68
- agentpool_server/opencode_server/routes/tui_routes.py +1 -1
- agentpool_server/opencode_server/server.py +47 -2
- agentpool_server/opencode_server/state.py +30 -0
- agentpool_storage/__init__.py +0 -4
- agentpool_storage/base.py +81 -2
- agentpool_storage/claude_provider/ARCHITECTURE.md +433 -0
- agentpool_storage/claude_provider/__init__.py +42 -0
- agentpool_storage/{claude_provider.py → claude_provider/provider.py} +190 -8
- agentpool_storage/file_provider.py +149 -15
- agentpool_storage/memory_provider.py +132 -12
- agentpool_storage/opencode_provider/ARCHITECTURE.md +386 -0
- agentpool_storage/opencode_provider/__init__.py +16 -0
- agentpool_storage/opencode_provider/helpers.py +414 -0
- agentpool_storage/opencode_provider/provider.py +895 -0
- agentpool_storage/session_store.py +20 -6
- agentpool_storage/sql_provider/sql_provider.py +135 -2
- agentpool_storage/sql_provider/utils.py +2 -12
- agentpool_storage/zed_provider/__init__.py +16 -0
- agentpool_storage/zed_provider/helpers.py +281 -0
- agentpool_storage/zed_provider/models.py +130 -0
- agentpool_storage/zed_provider/provider.py +442 -0
- agentpool_storage/zed_provider.py +803 -0
- agentpool_toolsets/__init__.py +0 -2
- agentpool_toolsets/builtin/__init__.py +2 -4
- agentpool_toolsets/builtin/code.py +4 -4
- agentpool_toolsets/builtin/debug.py +115 -40
- agentpool_toolsets/builtin/execution_environment.py +54 -165
- agentpool_toolsets/builtin/skills.py +0 -77
- agentpool_toolsets/builtin/subagent_tools.py +64 -51
- agentpool_toolsets/builtin/workers.py +4 -2
- agentpool_toolsets/composio_toolset.py +2 -2
- agentpool_toolsets/entry_points.py +3 -1
- agentpool_toolsets/fsspec_toolset/grep.py +25 -5
- agentpool_toolsets/fsspec_toolset/helpers.py +3 -2
- agentpool_toolsets/fsspec_toolset/toolset.py +350 -66
- agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
- agentpool_toolsets/mcp_discovery/toolset.py +74 -17
- agentpool_toolsets/mcp_run_toolset.py +8 -11
- agentpool_toolsets/notifications.py +33 -33
- agentpool_toolsets/openapi.py +3 -1
- agentpool_toolsets/search_toolset.py +3 -1
- agentpool_config/resources.py +0 -33
- agentpool_server/acp_server/acp_tools.py +0 -43
- agentpool_server/acp_server/commands/spawn.py +0 -210
- agentpool_storage/opencode_provider.py +0 -730
- agentpool_storage/text_log_provider.py +0 -276
- agentpool_toolsets/builtin/chain.py +0 -288
- agentpool_toolsets/builtin/user_interaction.py +0 -52
- agentpool_toolsets/semantic_memory_toolset.py +0 -536
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/entry_points.txt +0 -0
- {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
"""Models for agentpool standalone tool configuration."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Literal
|
|
6
|
+
|
|
7
|
+
from exxec_config import ExecutionEnvironmentConfig # noqa: TC002
|
|
8
|
+
from pydantic import ConfigDict, Field
|
|
9
|
+
|
|
10
|
+
from agentpool_config.converters import ConversionConfig # noqa: TC001
|
|
11
|
+
from agentpool_config.tools import BaseToolConfig
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from agentpool.tools.base import Tool
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BashToolConfig(BaseToolConfig):
|
|
19
|
+
"""Configuration for bash command execution tool.
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
```yaml
|
|
23
|
+
tools:
|
|
24
|
+
- type: bash
|
|
25
|
+
timeout: 30.0
|
|
26
|
+
output_limit: 10000
|
|
27
|
+
requires_confirmation: true
|
|
28
|
+
environment:
|
|
29
|
+
type: mock
|
|
30
|
+
deterministic_ids: true
|
|
31
|
+
```
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
model_config = ConfigDict(title="Bash Tool")
|
|
35
|
+
|
|
36
|
+
type: Literal["bash"] = Field("bash", init=False)
|
|
37
|
+
"""Bash command execution tool."""
|
|
38
|
+
|
|
39
|
+
timeout: float | None = Field(
|
|
40
|
+
default=None,
|
|
41
|
+
examples=[30.0, 60.0, 120.0],
|
|
42
|
+
title="Command timeout",
|
|
43
|
+
)
|
|
44
|
+
"""Command timeout in seconds. None means no timeout."""
|
|
45
|
+
|
|
46
|
+
output_limit: int | None = Field(
|
|
47
|
+
default=None,
|
|
48
|
+
examples=[10000, 50000, 100000],
|
|
49
|
+
title="Output limit",
|
|
50
|
+
)
|
|
51
|
+
"""Maximum bytes of output to return."""
|
|
52
|
+
|
|
53
|
+
environment: ExecutionEnvironmentConfig | None = Field(
|
|
54
|
+
default=None,
|
|
55
|
+
title="Execution environment",
|
|
56
|
+
)
|
|
57
|
+
"""Execution environment for command execution. Falls back to agent's env if not set."""
|
|
58
|
+
|
|
59
|
+
def get_tool(self) -> Tool:
|
|
60
|
+
"""Convert config to BashTool instance."""
|
|
61
|
+
from agentpool.tool_impls.bash import create_bash_tool
|
|
62
|
+
|
|
63
|
+
env = self.environment.get_provider() if self.environment else None
|
|
64
|
+
return create_bash_tool(
|
|
65
|
+
env=env,
|
|
66
|
+
timeout=self.timeout,
|
|
67
|
+
output_limit=self.output_limit,
|
|
68
|
+
name=self.name or "bash",
|
|
69
|
+
description=self.description or "Execute a shell command and return the output.",
|
|
70
|
+
requires_confirmation=self.requires_confirmation,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class AgentCliToolConfig(BaseToolConfig):
|
|
75
|
+
"""Configuration for agent CLI tool.
|
|
76
|
+
|
|
77
|
+
Example:
|
|
78
|
+
```yaml
|
|
79
|
+
tools:
|
|
80
|
+
- type: agent_cli
|
|
81
|
+
```
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
model_config = ConfigDict(title="Agent CLI Tool")
|
|
85
|
+
|
|
86
|
+
type: Literal["agent_cli"] = Field("agent_cli", init=False)
|
|
87
|
+
"""Agent CLI tool."""
|
|
88
|
+
|
|
89
|
+
def get_tool(self) -> Tool:
|
|
90
|
+
"""Convert config to AgentCliTool instance."""
|
|
91
|
+
from agentpool.tool_impls.agent_cli import create_agent_cli_tool
|
|
92
|
+
|
|
93
|
+
return create_agent_cli_tool(
|
|
94
|
+
name=self.name or "run_agent_cli_command",
|
|
95
|
+
description=self.description or "Execute an internal agent management command.",
|
|
96
|
+
requires_confirmation=self.requires_confirmation,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class QuestionToolConfig(BaseToolConfig):
|
|
101
|
+
"""Configuration for user interaction tool.
|
|
102
|
+
|
|
103
|
+
Example:
|
|
104
|
+
```yaml
|
|
105
|
+
tools:
|
|
106
|
+
- type: question
|
|
107
|
+
```
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
model_config = ConfigDict(title="Ask User Tool")
|
|
111
|
+
|
|
112
|
+
type: Literal["question"] = Field("question", init=False)
|
|
113
|
+
"""User interaction tool."""
|
|
114
|
+
|
|
115
|
+
def get_tool(self) -> Tool:
|
|
116
|
+
"""Convert config to QuestionTool instance."""
|
|
117
|
+
from agentpool.tool_impls.question import create_question_tool
|
|
118
|
+
|
|
119
|
+
return create_question_tool(
|
|
120
|
+
name=self.name or "question",
|
|
121
|
+
description=self.description or "Ask the user a clarifying question.",
|
|
122
|
+
requires_confirmation=self.requires_confirmation,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class ExecuteCodeToolConfig(BaseToolConfig):
|
|
127
|
+
"""Configuration for Python code execution tool.
|
|
128
|
+
|
|
129
|
+
Example:
|
|
130
|
+
```yaml
|
|
131
|
+
tools:
|
|
132
|
+
- type: execute_code
|
|
133
|
+
requires_confirmation: true
|
|
134
|
+
environment:
|
|
135
|
+
type: mock
|
|
136
|
+
deterministic_ids: true
|
|
137
|
+
```
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
model_config = ConfigDict(title="Execute Code Tool")
|
|
141
|
+
|
|
142
|
+
type: Literal["execute_code"] = Field("execute_code", init=False)
|
|
143
|
+
"""Python code execution tool."""
|
|
144
|
+
|
|
145
|
+
environment: ExecutionEnvironmentConfig | None = Field(
|
|
146
|
+
default=None,
|
|
147
|
+
title="Execution environment",
|
|
148
|
+
)
|
|
149
|
+
"""Execution environment for code execution. Falls back to agent's env if not set."""
|
|
150
|
+
|
|
151
|
+
def get_tool(self) -> Tool:
|
|
152
|
+
"""Convert config to ExecuteCodeTool instance."""
|
|
153
|
+
from agentpool.tool_impls.execute_code import create_execute_code_tool
|
|
154
|
+
|
|
155
|
+
env = self.environment.get_provider() if self.environment else None
|
|
156
|
+
return create_execute_code_tool(
|
|
157
|
+
env=env,
|
|
158
|
+
name=self.name or "execute_code",
|
|
159
|
+
description=self.description or "Execute Python code and return the result.",
|
|
160
|
+
requires_confirmation=self.requires_confirmation,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class ReadToolConfig(BaseToolConfig):
|
|
165
|
+
"""Configuration for file reading tool.
|
|
166
|
+
|
|
167
|
+
Example:
|
|
168
|
+
```yaml
|
|
169
|
+
tools:
|
|
170
|
+
- type: read
|
|
171
|
+
max_file_size_kb: 128
|
|
172
|
+
max_image_size: 1500
|
|
173
|
+
large_file_tokens: 10000
|
|
174
|
+
conversion:
|
|
175
|
+
default_provider: markitdown
|
|
176
|
+
environment:
|
|
177
|
+
type: local
|
|
178
|
+
```
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
model_config = ConfigDict(title="Read Tool")
|
|
182
|
+
|
|
183
|
+
type: Literal["read"] = Field("read", init=False)
|
|
184
|
+
"""File reading tool."""
|
|
185
|
+
|
|
186
|
+
environment: ExecutionEnvironmentConfig | None = Field(
|
|
187
|
+
default=None,
|
|
188
|
+
title="Execution environment",
|
|
189
|
+
)
|
|
190
|
+
"""Execution environment for filesystem access. Falls back to agent's env if not set."""
|
|
191
|
+
|
|
192
|
+
cwd: str | None = Field(
|
|
193
|
+
default=None,
|
|
194
|
+
title="Working directory",
|
|
195
|
+
)
|
|
196
|
+
"""Working directory for resolving relative paths."""
|
|
197
|
+
|
|
198
|
+
max_file_size_kb: int = Field(
|
|
199
|
+
default=64,
|
|
200
|
+
examples=[64, 128, 256],
|
|
201
|
+
title="Max file size",
|
|
202
|
+
)
|
|
203
|
+
"""Maximum file size in KB for read operations."""
|
|
204
|
+
|
|
205
|
+
max_image_size: int | None = Field(
|
|
206
|
+
default=2000,
|
|
207
|
+
examples=[1500, 2000, 2500],
|
|
208
|
+
title="Max image dimensions",
|
|
209
|
+
)
|
|
210
|
+
"""Max width/height for images in pixels. Images are auto-resized if larger."""
|
|
211
|
+
|
|
212
|
+
max_image_bytes: int | None = Field(
|
|
213
|
+
default=None,
|
|
214
|
+
title="Max image file size",
|
|
215
|
+
)
|
|
216
|
+
"""Max file size for images in bytes. Images are compressed if larger."""
|
|
217
|
+
|
|
218
|
+
large_file_tokens: int = Field(
|
|
219
|
+
default=12_000,
|
|
220
|
+
examples=[10_000, 12_000, 15_000],
|
|
221
|
+
title="Large file threshold",
|
|
222
|
+
)
|
|
223
|
+
"""Token threshold for switching to structure map for large files."""
|
|
224
|
+
|
|
225
|
+
map_max_tokens: int = Field(
|
|
226
|
+
default=2048,
|
|
227
|
+
examples=[1024, 2048, 4096],
|
|
228
|
+
title="Structure map max tokens",
|
|
229
|
+
)
|
|
230
|
+
"""Maximum tokens for structure map output."""
|
|
231
|
+
|
|
232
|
+
conversion: ConversionConfig | None = Field(
|
|
233
|
+
default=None,
|
|
234
|
+
title="Conversion config",
|
|
235
|
+
)
|
|
236
|
+
"""Optional conversion config for binary files. If set, converts supported files to markdown."""
|
|
237
|
+
|
|
238
|
+
def get_tool(self) -> Tool:
|
|
239
|
+
"""Convert config to ReadTool instance."""
|
|
240
|
+
from agentpool.tool_impls.read import create_read_tool
|
|
241
|
+
|
|
242
|
+
env = self.environment.get_provider() if self.environment else None
|
|
243
|
+
|
|
244
|
+
# Create converter if conversion config is provided
|
|
245
|
+
converter = None
|
|
246
|
+
if self.conversion is not None:
|
|
247
|
+
try:
|
|
248
|
+
from agentpool.prompts.conversion_manager import ConversionManager
|
|
249
|
+
|
|
250
|
+
converter = ConversionManager(self.conversion)
|
|
251
|
+
except Exception: # noqa: BLE001
|
|
252
|
+
# ConversionManager not available, continue without it
|
|
253
|
+
pass
|
|
254
|
+
|
|
255
|
+
return create_read_tool(
|
|
256
|
+
env=env,
|
|
257
|
+
converter=converter,
|
|
258
|
+
cwd=self.cwd,
|
|
259
|
+
max_file_size_kb=self.max_file_size_kb,
|
|
260
|
+
max_image_size=self.max_image_size,
|
|
261
|
+
max_image_bytes=self.max_image_bytes,
|
|
262
|
+
large_file_tokens=self.large_file_tokens,
|
|
263
|
+
map_max_tokens=self.map_max_tokens,
|
|
264
|
+
name=self.name or "read",
|
|
265
|
+
description=self.description or "Read file contents with automatic format detection.",
|
|
266
|
+
requires_confirmation=self.requires_confirmation,
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class ListDirectoryToolConfig(BaseToolConfig):
|
|
271
|
+
"""Configuration for directory listing tool.
|
|
272
|
+
|
|
273
|
+
Example:
|
|
274
|
+
```yaml
|
|
275
|
+
tools:
|
|
276
|
+
- type: list_directory
|
|
277
|
+
max_items: 1000
|
|
278
|
+
environment:
|
|
279
|
+
type: local
|
|
280
|
+
```
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
model_config = ConfigDict(title="List Directory Tool")
|
|
284
|
+
|
|
285
|
+
type: Literal["list_directory"] = Field("list_directory", init=False)
|
|
286
|
+
"""Directory listing tool."""
|
|
287
|
+
|
|
288
|
+
environment: ExecutionEnvironmentConfig | None = Field(
|
|
289
|
+
default=None,
|
|
290
|
+
title="Execution environment",
|
|
291
|
+
)
|
|
292
|
+
"""Execution environment for filesystem access. Falls back to agent's env if not set."""
|
|
293
|
+
|
|
294
|
+
cwd: str | None = Field(
|
|
295
|
+
default=None,
|
|
296
|
+
title="Working directory",
|
|
297
|
+
)
|
|
298
|
+
"""Working directory for resolving relative paths."""
|
|
299
|
+
|
|
300
|
+
max_items: int = Field(
|
|
301
|
+
default=500,
|
|
302
|
+
examples=[500, 1000, 2000],
|
|
303
|
+
title="Max items",
|
|
304
|
+
)
|
|
305
|
+
"""Maximum number of items to return (safety limit)."""
|
|
306
|
+
|
|
307
|
+
def get_tool(self) -> Tool:
|
|
308
|
+
"""Convert config to ListDirectoryTool instance."""
|
|
309
|
+
from agentpool.tool_impls.list_directory import create_list_directory_tool
|
|
310
|
+
|
|
311
|
+
env = self.environment.get_provider() if self.environment else None
|
|
312
|
+
return create_list_directory_tool(
|
|
313
|
+
env=env,
|
|
314
|
+
cwd=self.cwd,
|
|
315
|
+
max_items=self.max_items,
|
|
316
|
+
name=self.name or "list_directory",
|
|
317
|
+
description=self.description or "List files in a directory with filtering support.",
|
|
318
|
+
requires_confirmation=self.requires_confirmation,
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
class GrepToolConfig(BaseToolConfig):
|
|
323
|
+
"""Configuration for grep search tool.
|
|
324
|
+
|
|
325
|
+
Example:
|
|
326
|
+
```yaml
|
|
327
|
+
tools:
|
|
328
|
+
- type: grep
|
|
329
|
+
max_output_kb: 128
|
|
330
|
+
use_subprocess_grep: true
|
|
331
|
+
environment:
|
|
332
|
+
type: local
|
|
333
|
+
```
|
|
334
|
+
"""
|
|
335
|
+
|
|
336
|
+
model_config = ConfigDict(title="Grep Tool")
|
|
337
|
+
|
|
338
|
+
type: Literal["grep"] = Field("grep", init=False)
|
|
339
|
+
"""Grep search tool."""
|
|
340
|
+
|
|
341
|
+
environment: ExecutionEnvironmentConfig | None = Field(
|
|
342
|
+
default=None,
|
|
343
|
+
title="Execution environment",
|
|
344
|
+
)
|
|
345
|
+
"""Execution environment for filesystem access. Falls back to agent's env if not set."""
|
|
346
|
+
|
|
347
|
+
cwd: str | None = Field(
|
|
348
|
+
default=None,
|
|
349
|
+
title="Working directory",
|
|
350
|
+
)
|
|
351
|
+
"""Working directory for resolving relative paths."""
|
|
352
|
+
|
|
353
|
+
max_output_kb: int = Field(
|
|
354
|
+
default=64,
|
|
355
|
+
examples=[64, 128, 256],
|
|
356
|
+
title="Max output size",
|
|
357
|
+
)
|
|
358
|
+
"""Maximum output size in KB."""
|
|
359
|
+
|
|
360
|
+
use_subprocess_grep: bool = Field(
|
|
361
|
+
default=True,
|
|
362
|
+
title="Use subprocess grep",
|
|
363
|
+
)
|
|
364
|
+
"""Use ripgrep/grep subprocess if available (faster for large codebases)."""
|
|
365
|
+
|
|
366
|
+
def get_tool(self) -> Tool:
|
|
367
|
+
"""Convert config to GrepTool instance."""
|
|
368
|
+
from agentpool.tool_impls.grep import create_grep_tool
|
|
369
|
+
|
|
370
|
+
env = self.environment.get_provider() if self.environment else None
|
|
371
|
+
return create_grep_tool(
|
|
372
|
+
env=env,
|
|
373
|
+
cwd=self.cwd,
|
|
374
|
+
max_output_kb=self.max_output_kb,
|
|
375
|
+
use_subprocess_grep=self.use_subprocess_grep,
|
|
376
|
+
name=self.name or "grep",
|
|
377
|
+
description=self.description or "Search file contents for patterns.",
|
|
378
|
+
requires_confirmation=self.requires_confirmation,
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
class DeletePathToolConfig(BaseToolConfig):
|
|
383
|
+
"""Configuration for delete path tool.
|
|
384
|
+
|
|
385
|
+
Example:
|
|
386
|
+
```yaml
|
|
387
|
+
tools:
|
|
388
|
+
- type: delete_path
|
|
389
|
+
requires_confirmation: true
|
|
390
|
+
environment:
|
|
391
|
+
type: local
|
|
392
|
+
```
|
|
393
|
+
"""
|
|
394
|
+
|
|
395
|
+
model_config = ConfigDict(title="Delete Path Tool")
|
|
396
|
+
|
|
397
|
+
type: Literal["delete_path"] = Field("delete_path", init=False)
|
|
398
|
+
"""Delete path tool."""
|
|
399
|
+
|
|
400
|
+
environment: ExecutionEnvironmentConfig | None = Field(
|
|
401
|
+
default=None,
|
|
402
|
+
title="Execution environment",
|
|
403
|
+
)
|
|
404
|
+
"""Execution environment for filesystem access. Falls back to agent's env if not set."""
|
|
405
|
+
|
|
406
|
+
cwd: str | None = Field(
|
|
407
|
+
default=None,
|
|
408
|
+
title="Working directory",
|
|
409
|
+
)
|
|
410
|
+
"""Working directory for resolving relative paths."""
|
|
411
|
+
|
|
412
|
+
def get_tool(self) -> Tool:
|
|
413
|
+
"""Convert config to DeletePathTool instance."""
|
|
414
|
+
from agentpool.tool_impls.delete_path import create_delete_path_tool
|
|
415
|
+
|
|
416
|
+
env = self.environment.get_provider() if self.environment else None
|
|
417
|
+
return create_delete_path_tool(
|
|
418
|
+
env=env,
|
|
419
|
+
cwd=self.cwd,
|
|
420
|
+
name=self.name or "delete_path",
|
|
421
|
+
description=self.description or "Delete a file or directory.",
|
|
422
|
+
requires_confirmation=self.requires_confirmation,
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
class DownloadFileToolConfig(BaseToolConfig):
|
|
427
|
+
"""Configuration for file download tool.
|
|
428
|
+
|
|
429
|
+
Example:
|
|
430
|
+
```yaml
|
|
431
|
+
tools:
|
|
432
|
+
- type: download_file
|
|
433
|
+
chunk_size: 16384
|
|
434
|
+
timeout: 60.0
|
|
435
|
+
environment:
|
|
436
|
+
type: local
|
|
437
|
+
```
|
|
438
|
+
"""
|
|
439
|
+
|
|
440
|
+
model_config = ConfigDict(title="Download File Tool")
|
|
441
|
+
|
|
442
|
+
type: Literal["download_file"] = Field("download_file", init=False)
|
|
443
|
+
"""File download tool."""
|
|
444
|
+
|
|
445
|
+
environment: ExecutionEnvironmentConfig | None = Field(
|
|
446
|
+
default=None,
|
|
447
|
+
title="Execution environment",
|
|
448
|
+
)
|
|
449
|
+
"""Execution environment for filesystem access. Falls back to agent's env if not set."""
|
|
450
|
+
|
|
451
|
+
cwd: str | None = Field(
|
|
452
|
+
default=None,
|
|
453
|
+
title="Working directory",
|
|
454
|
+
)
|
|
455
|
+
"""Working directory for resolving relative paths."""
|
|
456
|
+
|
|
457
|
+
chunk_size: int = Field(
|
|
458
|
+
default=8192,
|
|
459
|
+
examples=[8192, 16384, 32768],
|
|
460
|
+
title="Chunk size",
|
|
461
|
+
)
|
|
462
|
+
"""Size of chunks to download in bytes."""
|
|
463
|
+
|
|
464
|
+
timeout: float = Field(
|
|
465
|
+
default=30.0,
|
|
466
|
+
examples=[30.0, 60.0, 120.0],
|
|
467
|
+
title="Request timeout",
|
|
468
|
+
)
|
|
469
|
+
"""Request timeout in seconds."""
|
|
470
|
+
|
|
471
|
+
def get_tool(self) -> Tool:
|
|
472
|
+
"""Convert config to DownloadFileTool instance."""
|
|
473
|
+
from agentpool.tool_impls.download_file import create_download_file_tool
|
|
474
|
+
|
|
475
|
+
env = self.environment.get_provider() if self.environment else None
|
|
476
|
+
return create_download_file_tool(
|
|
477
|
+
env=env,
|
|
478
|
+
cwd=self.cwd,
|
|
479
|
+
chunk_size=self.chunk_size,
|
|
480
|
+
timeout=self.timeout,
|
|
481
|
+
name=self.name or "download_file",
|
|
482
|
+
description=self.description or "Download a file from a URL.",
|
|
483
|
+
requires_confirmation=self.requires_confirmation,
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
# Union type for agentpool tool configs
|
|
488
|
+
AgentpoolToolConfig = (
|
|
489
|
+
AgentCliToolConfig
|
|
490
|
+
| QuestionToolConfig
|
|
491
|
+
| BashToolConfig
|
|
492
|
+
| DeletePathToolConfig
|
|
493
|
+
| DownloadFileToolConfig
|
|
494
|
+
| ExecuteCodeToolConfig
|
|
495
|
+
| GrepToolConfig
|
|
496
|
+
| ListDirectoryToolConfig
|
|
497
|
+
| ReadToolConfig
|
|
498
|
+
)
|
agentpool_config/converters.py
CHANGED
|
@@ -392,6 +392,47 @@ class CallbackEventHandlerConfig(BaseEventHandlerConfig):
|
|
|
392
392
|
return import_callable(self.import_path)
|
|
393
393
|
|
|
394
394
|
|
|
395
|
+
class FileStreamEventHandlerConfig(BaseEventHandlerConfig):
|
|
396
|
+
"""Configuration for streaming agent output to a file."""
|
|
397
|
+
|
|
398
|
+
model_config = ConfigDict(title="File Stream Event Handler")
|
|
399
|
+
|
|
400
|
+
type: Literal["file"] = Field("file", init=False)
|
|
401
|
+
"""File stream event handler."""
|
|
402
|
+
|
|
403
|
+
path: str = Field(
|
|
404
|
+
examples=["~/agent_output.txt", "/tmp/agent.log", "./output.md"],
|
|
405
|
+
)
|
|
406
|
+
"""Path to the output file. Supports ~ expansion."""
|
|
407
|
+
|
|
408
|
+
mode: Literal["w", "a"] = Field(
|
|
409
|
+
default="a",
|
|
410
|
+
examples=["w", "a"],
|
|
411
|
+
)
|
|
412
|
+
"""File open mode.
|
|
413
|
+
|
|
414
|
+
- w: Overwrite file on each run
|
|
415
|
+
- a: Append to existing file
|
|
416
|
+
"""
|
|
417
|
+
|
|
418
|
+
include_tools: bool = Field(default=False)
|
|
419
|
+
"""Whether to include tool call and result information."""
|
|
420
|
+
|
|
421
|
+
include_thinking: bool = Field(default=False)
|
|
422
|
+
"""Whether to include thinking/reasoning content."""
|
|
423
|
+
|
|
424
|
+
def get_handler(self) -> IndividualEventHandler:
|
|
425
|
+
"""Create and return the file stream handler."""
|
|
426
|
+
from agentpool.agents.events.builtin_handlers import create_file_stream_handler
|
|
427
|
+
|
|
428
|
+
return create_file_stream_handler(
|
|
429
|
+
path=self.path,
|
|
430
|
+
mode=self.mode,
|
|
431
|
+
include_tools=self.include_tools,
|
|
432
|
+
include_thinking=self.include_thinking,
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
|
|
395
436
|
class TTSEventHandlerConfig(BaseEventHandlerConfig):
|
|
396
437
|
"""Configuration for Text-to-Speech event handler with OpenAI streaming."""
|
|
397
438
|
|
|
@@ -578,6 +619,7 @@ class EdgeTTSEventHandlerConfig(BaseEventHandlerConfig):
|
|
|
578
619
|
EventHandlerConfig = Annotated[
|
|
579
620
|
StdoutEventHandlerConfig
|
|
580
621
|
| CallbackEventHandlerConfig
|
|
622
|
+
| FileStreamEventHandlerConfig
|
|
581
623
|
| TTSEventHandlerConfig
|
|
582
624
|
| EdgeTTSEventHandlerConfig,
|
|
583
625
|
Field(discriminator="type"),
|
agentpool_config/events.py
CHANGED
|
@@ -118,9 +118,6 @@ class NodeConnectionConfig(ConnectionConfig):
|
|
|
118
118
|
|
|
119
119
|
DEFAULT_MESSAGE_TEMPLATE = """
|
|
120
120
|
[{{ message.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}] {{ message.name }}: {{ message.content }}
|
|
121
|
-
{%- if message.forwarded_from %}
|
|
122
|
-
(via: {{ message.forwarded_from|join(' -> ') }})
|
|
123
|
-
{%- endif %}
|
|
124
121
|
"""
|
|
125
122
|
|
|
126
123
|
|
|
@@ -135,7 +132,7 @@ class FileConnectionConfig(ConnectionConfig):
|
|
|
135
132
|
- role: Message role (user/assistant/system)
|
|
136
133
|
- model: Model used (if any)
|
|
137
134
|
- cost_info: Token usage and cost info
|
|
138
|
-
-
|
|
135
|
+
- parent_id: ID of parent message for tracking chains
|
|
139
136
|
"""
|
|
140
137
|
|
|
141
138
|
model_config = ConfigDict(json_schema_extra={"title": "File Connection Configuration"})
|
agentpool_config/jinja.py
CHANGED
|
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Any, Literal
|
|
|
7
7
|
from pydantic import BaseModel, ConfigDict, Field
|
|
8
8
|
from schemez import Schema
|
|
9
9
|
|
|
10
|
-
from agentpool_config
|
|
10
|
+
from agentpool_config import ToolConfig
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
@@ -141,9 +141,9 @@ class Jinja2EnvironmentConfig(Schema):
|
|
|
141
141
|
try:
|
|
142
142
|
# Convert filters - use tool name as filter name
|
|
143
143
|
tools = [cfg.get_tool() for cfg in self.filters]
|
|
144
|
-
kwargs["filters"] = {tool.name: tool.
|
|
144
|
+
kwargs["filters"] = {tool.name: tool.get_callable() for tool in tools}
|
|
145
145
|
tools = [cfg.get_tool() for cfg in self.tests]
|
|
146
|
-
kwargs["tests"] = {tool.name: tool.
|
|
146
|
+
kwargs["tests"] = {tool.name: tool.get_callable() for tool in tools}
|
|
147
147
|
|
|
148
148
|
except Exception as exc:
|
|
149
149
|
msg = f"Failed to import Jinja2 filters/tests: {exc}"
|
agentpool_config/mcp_server.py
CHANGED
|
@@ -138,11 +138,7 @@ class BaseMCPServerConfig(Schema):
|
|
|
138
138
|
return env
|
|
139
139
|
|
|
140
140
|
def to_pydantic_ai(self) -> MCPServer:
|
|
141
|
-
"""Convert to pydantic-ai MCP server instance.
|
|
142
|
-
|
|
143
|
-
Returns:
|
|
144
|
-
A pydantic-ai MCP server instance
|
|
145
|
-
"""
|
|
141
|
+
"""Convert to pydantic-ai MCP server instance."""
|
|
146
142
|
raise NotImplementedError
|
|
147
143
|
|
|
148
144
|
@property
|
agentpool_config/nodes.py
CHANGED
|
@@ -149,6 +149,49 @@ class ArizePhoenixObservabilityConfig(BaseObservabilityConfig):
|
|
|
149
149
|
object.__setattr__(self, "_headers", headers)
|
|
150
150
|
|
|
151
151
|
|
|
152
|
+
class AxiomObservabilityConfig(BaseObservabilityConfig):
|
|
153
|
+
"""Configuration for Axiom endpoint."""
|
|
154
|
+
|
|
155
|
+
model_config = ConfigDict(json_schema_extra={"x-doc-title": "Axiom"})
|
|
156
|
+
|
|
157
|
+
type: Literal["axiom"] = "axiom"
|
|
158
|
+
"""Axiom observability configuration."""
|
|
159
|
+
|
|
160
|
+
api_token: SecretStr | None = Field(default=None, title="Axiom API token")
|
|
161
|
+
"""Axiom API token with ingest permissions."""
|
|
162
|
+
|
|
163
|
+
dataset: str = Field(
|
|
164
|
+
examples=["traces", "otel-traces", "my-service-traces"],
|
|
165
|
+
title="Dataset name",
|
|
166
|
+
)
|
|
167
|
+
"""Axiom dataset name where traces are sent."""
|
|
168
|
+
|
|
169
|
+
region: Literal["us", "eu"] | None = Field(
|
|
170
|
+
default=None,
|
|
171
|
+
examples=["us", "eu"],
|
|
172
|
+
title="Region",
|
|
173
|
+
)
|
|
174
|
+
"""Axiom region. If not set, uses default cloud endpoint."""
|
|
175
|
+
|
|
176
|
+
_endpoint: str = PrivateAttr()
|
|
177
|
+
_headers: dict[str, str] = PrivateAttr(default_factory=dict)
|
|
178
|
+
|
|
179
|
+
def model_post_init(self, __context: Any, /) -> None:
|
|
180
|
+
"""Compute private attributes from user config."""
|
|
181
|
+
# Axiom uses /v1/traces endpoint for OTLP
|
|
182
|
+
if self.region == "eu":
|
|
183
|
+
endpoint = "https://api.eu.axiom.co/v1/traces"
|
|
184
|
+
else:
|
|
185
|
+
endpoint = "https://api.axiom.co/v1/traces"
|
|
186
|
+
object.__setattr__(self, "_endpoint", endpoint)
|
|
187
|
+
|
|
188
|
+
headers: dict[str, str] = {}
|
|
189
|
+
if self.api_token:
|
|
190
|
+
headers["Authorization"] = f"Bearer {self.api_token.get_secret_value()}"
|
|
191
|
+
headers["X-Axiom-Dataset"] = self.dataset
|
|
192
|
+
object.__setattr__(self, "_headers", headers)
|
|
193
|
+
|
|
194
|
+
|
|
152
195
|
class CustomObservabilityConfig(BaseObservabilityConfig):
|
|
153
196
|
"""Configuration for custom OTEL endpoint."""
|
|
154
197
|
|
|
@@ -173,6 +216,7 @@ ObservabilityProviderConfig = Annotated[
|
|
|
173
216
|
| LangsmithObservabilityConfig
|
|
174
217
|
| AgentOpsObservabilityConfig
|
|
175
218
|
| ArizePhoenixObservabilityConfig
|
|
219
|
+
| AxiomObservabilityConfig
|
|
176
220
|
| CustomObservabilityConfig,
|
|
177
221
|
Field(discriminator="type"),
|
|
178
222
|
]
|