agentpool 2.1.9__py3-none-any.whl → 2.2.3__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 +13 -0
- acp/bridge/README.md +15 -2
- acp/bridge/__init__.py +3 -2
- acp/bridge/__main__.py +60 -19
- acp/bridge/ws_server.py +173 -0
- acp/bridge/ws_server_cli.py +89 -0
- acp/notifications.py +2 -1
- acp/stdio.py +39 -9
- acp/transports.py +362 -2
- acp/utils.py +15 -2
- agentpool/__init__.py +4 -1
- agentpool/agents/__init__.py +2 -0
- agentpool/agents/acp_agent/acp_agent.py +203 -88
- agentpool/agents/acp_agent/acp_converters.py +46 -21
- agentpool/agents/acp_agent/client_handler.py +157 -3
- agentpool/agents/acp_agent/session_state.py +4 -1
- agentpool/agents/agent.py +314 -107
- agentpool/agents/agui_agent/__init__.py +0 -2
- agentpool/agents/agui_agent/agui_agent.py +90 -21
- agentpool/agents/agui_agent/agui_converters.py +0 -131
- agentpool/agents/base_agent.py +163 -1
- agentpool/agents/claude_code_agent/claude_code_agent.py +626 -179
- agentpool/agents/claude_code_agent/converters.py +71 -3
- agentpool/agents/claude_code_agent/history.py +474 -0
- agentpool/agents/context.py +40 -0
- agentpool/agents/events/__init__.py +2 -0
- agentpool/agents/events/builtin_handlers.py +2 -1
- agentpool/agents/events/event_emitter.py +29 -2
- agentpool/agents/events/events.py +20 -0
- agentpool/agents/modes.py +54 -0
- agentpool/agents/tool_call_accumulator.py +213 -0
- agentpool/common_types.py +21 -0
- agentpool/config_resources/__init__.py +38 -1
- agentpool/config_resources/claude_code_agent.yml +3 -0
- agentpool/delegation/pool.py +37 -29
- agentpool/delegation/team.py +1 -0
- agentpool/delegation/teamrun.py +1 -0
- agentpool/diagnostics/__init__.py +53 -0
- agentpool/diagnostics/lsp_manager.py +1593 -0
- agentpool/diagnostics/lsp_proxy.py +41 -0
- agentpool/diagnostics/lsp_proxy_script.py +229 -0
- agentpool/diagnostics/models.py +398 -0
- agentpool/mcp_server/__init__.py +0 -2
- agentpool/mcp_server/client.py +12 -3
- agentpool/mcp_server/manager.py +25 -31
- agentpool/mcp_server/registries/official_registry_client.py +25 -0
- agentpool/mcp_server/tool_bridge.py +78 -66
- agentpool/messaging/__init__.py +0 -2
- agentpool/messaging/compaction.py +72 -197
- agentpool/messaging/message_history.py +12 -0
- agentpool/messaging/messages.py +52 -9
- agentpool/messaging/processing.py +3 -1
- agentpool/models/acp_agents/base.py +0 -22
- agentpool/models/acp_agents/mcp_capable.py +8 -148
- agentpool/models/acp_agents/non_mcp.py +129 -72
- agentpool/models/agents.py +35 -13
- agentpool/models/claude_code_agents.py +33 -2
- agentpool/models/manifest.py +43 -0
- agentpool/repomap.py +1 -1
- agentpool/resource_providers/__init__.py +9 -1
- agentpool/resource_providers/aggregating.py +52 -3
- agentpool/resource_providers/base.py +57 -1
- agentpool/resource_providers/mcp_provider.py +23 -0
- agentpool/resource_providers/plan_provider.py +130 -41
- agentpool/resource_providers/pool.py +2 -0
- agentpool/resource_providers/static.py +2 -0
- agentpool/sessions/__init__.py +2 -1
- agentpool/sessions/manager.py +31 -2
- agentpool/sessions/models.py +50 -0
- agentpool/skills/registry.py +13 -8
- agentpool/storage/manager.py +217 -1
- agentpool/testing.py +537 -19
- agentpool/utils/file_watcher.py +269 -0
- agentpool/utils/identifiers.py +121 -0
- agentpool/utils/pydantic_ai_helpers.py +46 -0
- agentpool/utils/streams.py +690 -1
- agentpool/utils/subprocess_utils.py +155 -0
- agentpool/utils/token_breakdown.py +461 -0
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/METADATA +27 -7
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/RECORD +170 -112
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/WHEEL +1 -1
- agentpool_cli/__main__.py +4 -0
- agentpool_cli/serve_acp.py +41 -20
- agentpool_cli/serve_agui.py +87 -0
- agentpool_cli/serve_opencode.py +119 -0
- agentpool_commands/__init__.py +30 -0
- agentpool_commands/agents.py +74 -1
- agentpool_commands/history.py +62 -0
- agentpool_commands/mcp.py +176 -0
- agentpool_commands/models.py +56 -3
- agentpool_commands/tools.py +57 -0
- agentpool_commands/utils.py +51 -0
- agentpool_config/builtin_tools.py +77 -22
- agentpool_config/commands.py +24 -1
- agentpool_config/compaction.py +258 -0
- agentpool_config/mcp_server.py +131 -1
- agentpool_config/storage.py +46 -1
- agentpool_config/tools.py +7 -1
- agentpool_config/toolsets.py +92 -148
- agentpool_server/acp_server/acp_agent.py +134 -150
- agentpool_server/acp_server/commands/acp_commands.py +216 -51
- agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +10 -10
- agentpool_server/acp_server/server.py +23 -79
- agentpool_server/acp_server/session.py +181 -19
- agentpool_server/opencode_server/.rules +95 -0
- agentpool_server/opencode_server/ENDPOINTS.md +362 -0
- agentpool_server/opencode_server/__init__.py +27 -0
- agentpool_server/opencode_server/command_validation.py +172 -0
- agentpool_server/opencode_server/converters.py +869 -0
- agentpool_server/opencode_server/dependencies.py +24 -0
- agentpool_server/opencode_server/input_provider.py +269 -0
- agentpool_server/opencode_server/models/__init__.py +228 -0
- agentpool_server/opencode_server/models/agent.py +53 -0
- agentpool_server/opencode_server/models/app.py +60 -0
- agentpool_server/opencode_server/models/base.py +26 -0
- agentpool_server/opencode_server/models/common.py +23 -0
- agentpool_server/opencode_server/models/config.py +37 -0
- agentpool_server/opencode_server/models/events.py +647 -0
- agentpool_server/opencode_server/models/file.py +88 -0
- agentpool_server/opencode_server/models/mcp.py +25 -0
- agentpool_server/opencode_server/models/message.py +162 -0
- agentpool_server/opencode_server/models/parts.py +190 -0
- agentpool_server/opencode_server/models/provider.py +81 -0
- agentpool_server/opencode_server/models/pty.py +43 -0
- agentpool_server/opencode_server/models/session.py +99 -0
- agentpool_server/opencode_server/routes/__init__.py +25 -0
- agentpool_server/opencode_server/routes/agent_routes.py +442 -0
- agentpool_server/opencode_server/routes/app_routes.py +139 -0
- agentpool_server/opencode_server/routes/config_routes.py +241 -0
- agentpool_server/opencode_server/routes/file_routes.py +392 -0
- agentpool_server/opencode_server/routes/global_routes.py +94 -0
- agentpool_server/opencode_server/routes/lsp_routes.py +319 -0
- agentpool_server/opencode_server/routes/message_routes.py +705 -0
- agentpool_server/opencode_server/routes/pty_routes.py +299 -0
- agentpool_server/opencode_server/routes/session_routes.py +1205 -0
- agentpool_server/opencode_server/routes/tui_routes.py +139 -0
- agentpool_server/opencode_server/server.py +430 -0
- agentpool_server/opencode_server/state.py +121 -0
- agentpool_server/opencode_server/time_utils.py +8 -0
- agentpool_storage/__init__.py +16 -0
- agentpool_storage/base.py +103 -0
- agentpool_storage/claude_provider.py +907 -0
- agentpool_storage/file_provider.py +129 -0
- agentpool_storage/memory_provider.py +61 -0
- agentpool_storage/models.py +3 -0
- agentpool_storage/opencode_provider.py +730 -0
- agentpool_storage/project_store.py +325 -0
- agentpool_storage/session_store.py +6 -0
- agentpool_storage/sql_provider/__init__.py +4 -2
- agentpool_storage/sql_provider/models.py +48 -0
- agentpool_storage/sql_provider/sql_provider.py +134 -1
- agentpool_storage/sql_provider/utils.py +10 -1
- agentpool_storage/text_log_provider.py +1 -0
- agentpool_toolsets/builtin/__init__.py +0 -8
- agentpool_toolsets/builtin/code.py +95 -56
- agentpool_toolsets/builtin/debug.py +16 -21
- agentpool_toolsets/builtin/execution_environment.py +99 -103
- agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
- agentpool_toolsets/builtin/skills.py +86 -4
- agentpool_toolsets/fsspec_toolset/__init__.py +13 -1
- agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
- agentpool_toolsets/fsspec_toolset/grep.py +74 -2
- agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
- agentpool_toolsets/fsspec_toolset/toolset.py +159 -38
- agentpool_toolsets/mcp_discovery/__init__.py +5 -0
- agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
- agentpool_toolsets/mcp_discovery/toolset.py +454 -0
- agentpool_toolsets/mcp_run_toolset.py +84 -6
- agentpool_toolsets/builtin/agent_management.py +0 -239
- agentpool_toolsets/builtin/history.py +0 -36
- agentpool_toolsets/builtin/integration.py +0 -85
- agentpool_toolsets/builtin/tool_management.py +0 -90
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/entry_points.txt +0 -0
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,7 +5,6 @@ from __future__ import annotations
|
|
|
5
5
|
from typing import TYPE_CHECKING, Literal
|
|
6
6
|
|
|
7
7
|
from pydantic import ConfigDict, Field
|
|
8
|
-
from tokonomics.model_discovery import ProviderType # noqa: TC002
|
|
9
8
|
|
|
10
9
|
from agentpool.models.acp_agents.base import BaseACPAgentConfig
|
|
11
10
|
|
|
@@ -67,6 +66,12 @@ class CodexACPAgentConfig(BaseACPAgentConfig):
|
|
|
67
66
|
)
|
|
68
67
|
"""Model override."""
|
|
69
68
|
|
|
69
|
+
auto_approve: bool = Field(
|
|
70
|
+
default=False,
|
|
71
|
+
title="Auto Approve",
|
|
72
|
+
)
|
|
73
|
+
"""Automatically accept all actions (YOLO mode)."""
|
|
74
|
+
|
|
70
75
|
sandbox_permissions: list[str] | None = Field(
|
|
71
76
|
default=None,
|
|
72
77
|
title="Sandbox Permissions",
|
|
@@ -85,11 +90,6 @@ class CodexACPAgentConfig(BaseACPAgentConfig):
|
|
|
85
90
|
"""Get the command to spawn the ACP server."""
|
|
86
91
|
return "npx"
|
|
87
92
|
|
|
88
|
-
@property
|
|
89
|
-
def model_providers(self) -> list[ProviderType]:
|
|
90
|
-
"""Codex uses OpenAI models."""
|
|
91
|
-
return ["openai"]
|
|
92
|
-
|
|
93
93
|
async def get_args(self, prompt_manager: PromptManager | None = None) -> list[str]:
|
|
94
94
|
"""Build command arguments from settings."""
|
|
95
95
|
args: list[str] = ["@zed-industries/codex-acp"]
|
|
@@ -105,6 +105,8 @@ class CodexACPAgentConfig(BaseACPAgentConfig):
|
|
|
105
105
|
"-c",
|
|
106
106
|
f"shell_environment_policy.inherit={self.shell_environment_policy_inherit}",
|
|
107
107
|
])
|
|
108
|
+
if self.auto_approve:
|
|
109
|
+
args.extend(["-c", "approval_mode=yolo"])
|
|
108
110
|
|
|
109
111
|
return args
|
|
110
112
|
|
|
@@ -142,11 +144,6 @@ class OpenCodeACPAgentConfig(BaseACPAgentConfig):
|
|
|
142
144
|
args.extend(["--cwd", self.cwd])
|
|
143
145
|
return args
|
|
144
146
|
|
|
145
|
-
@property
|
|
146
|
-
def model_providers(self) -> list[ProviderType]:
|
|
147
|
-
"""OpenCode supports multiple providers."""
|
|
148
|
-
return ["openai", "anthropic", "gemini", "openrouter"]
|
|
149
|
-
|
|
150
147
|
|
|
151
148
|
class GooseACPAgentConfig(BaseACPAgentConfig):
|
|
152
149
|
"""Configuration for Goose via ACP.
|
|
@@ -176,11 +173,6 @@ class GooseACPAgentConfig(BaseACPAgentConfig):
|
|
|
176
173
|
"""Build command arguments from settings."""
|
|
177
174
|
return ["acp"]
|
|
178
175
|
|
|
179
|
-
@property
|
|
180
|
-
def model_providers(self) -> list[ProviderType]:
|
|
181
|
-
"""Goose supports multiple providers."""
|
|
182
|
-
return ["openai", "anthropic", "gemini", "openrouter"]
|
|
183
|
-
|
|
184
176
|
|
|
185
177
|
class MistralACPAgentConfig(BaseACPAgentConfig):
|
|
186
178
|
"""Configuration for Mistral Agent via ACP.
|
|
@@ -208,11 +200,6 @@ class MistralACPAgentConfig(BaseACPAgentConfig):
|
|
|
208
200
|
"""Build command arguments from settings."""
|
|
209
201
|
return []
|
|
210
202
|
|
|
211
|
-
@property
|
|
212
|
-
def model_providers(self) -> list[ProviderType]:
|
|
213
|
-
"""Goose supports multiple providers."""
|
|
214
|
-
return ["mistral"]
|
|
215
|
-
|
|
216
203
|
|
|
217
204
|
class OpenHandsACPAgentConfig(BaseACPAgentConfig):
|
|
218
205
|
"""Configuration for OpenHands via ACP.
|
|
@@ -242,11 +229,6 @@ class OpenHandsACPAgentConfig(BaseACPAgentConfig):
|
|
|
242
229
|
"""Build command arguments from settings."""
|
|
243
230
|
return ["acp"]
|
|
244
231
|
|
|
245
|
-
@property
|
|
246
|
-
def model_providers(self) -> list[ProviderType]:
|
|
247
|
-
"""OpenHands supports multiple providers."""
|
|
248
|
-
return ["openai", "anthropic", "gemini", "openrouter"]
|
|
249
|
-
|
|
250
232
|
|
|
251
233
|
class AmpACPAgentConfig(BaseACPAgentConfig):
|
|
252
234
|
"""Configuration for Amp (AmpCode) via ACP.
|
|
@@ -292,11 +274,6 @@ class AmpACPAgentConfig(BaseACPAgentConfig):
|
|
|
292
274
|
"""Build command arguments for amp-acp bridge."""
|
|
293
275
|
return ["-y", "amp-acp"]
|
|
294
276
|
|
|
295
|
-
@property
|
|
296
|
-
def model_providers(self) -> list[ProviderType]:
|
|
297
|
-
"""Amp supports multiple providers."""
|
|
298
|
-
return ["openai", "anthropic", "gemini"]
|
|
299
|
-
|
|
300
277
|
|
|
301
278
|
class CagentACPAgentConfig(BaseACPAgentConfig):
|
|
302
279
|
"""Configuration for Docker cagent via ACP.
|
|
@@ -393,11 +370,6 @@ class CagentACPAgentConfig(BaseACPAgentConfig):
|
|
|
393
370
|
|
|
394
371
|
return args
|
|
395
372
|
|
|
396
|
-
@property
|
|
397
|
-
def model_providers(self) -> list[ProviderType]:
|
|
398
|
-
"""Cagent supports multiple providers via MCP."""
|
|
399
|
-
return ["openai", "anthropic", "gemini"]
|
|
400
|
-
|
|
401
373
|
|
|
402
374
|
class StakpakACPAgentConfig(BaseACPAgentConfig):
|
|
403
375
|
"""Configuration for Stakpak Agent via ACP.
|
|
@@ -538,11 +510,6 @@ class StakpakACPAgentConfig(BaseACPAgentConfig):
|
|
|
538
510
|
|
|
539
511
|
return args
|
|
540
512
|
|
|
541
|
-
@property
|
|
542
|
-
def model_providers(self) -> list[ProviderType]:
|
|
543
|
-
"""Stakpak supports multiple providers."""
|
|
544
|
-
return ["openai", "anthropic", "gemini"]
|
|
545
|
-
|
|
546
513
|
|
|
547
514
|
class VTCodeACPAgentConfig(BaseACPAgentConfig):
|
|
548
515
|
"""Configuration for VT Code via ACP.
|
|
@@ -644,7 +611,7 @@ class VTCodeACPAgentConfig(BaseACPAgentConfig):
|
|
|
644
611
|
)
|
|
645
612
|
"""Configuration file path."""
|
|
646
613
|
|
|
647
|
-
|
|
614
|
+
auto_approve: bool = Field(default=False, title="Auto Approve")
|
|
648
615
|
"""Skip safety confirmations."""
|
|
649
616
|
|
|
650
617
|
full_auto: bool = Field(default=False, title="Full Auto")
|
|
@@ -684,18 +651,13 @@ class VTCodeACPAgentConfig(BaseACPAgentConfig):
|
|
|
684
651
|
args.extend(["--max-tool-calls", str(self.max_tool_calls)])
|
|
685
652
|
if self.config:
|
|
686
653
|
args.extend(["--config", self.config])
|
|
687
|
-
if self.
|
|
654
|
+
if self.auto_approve:
|
|
688
655
|
args.append("--skip-confirmations")
|
|
689
656
|
if self.full_auto:
|
|
690
657
|
args.append("--full-auto")
|
|
691
658
|
|
|
692
659
|
return args
|
|
693
660
|
|
|
694
|
-
@property
|
|
695
|
-
def model_providers(self) -> list[ProviderType]:
|
|
696
|
-
"""VT Code supports multiple providers."""
|
|
697
|
-
return ["openai", "anthropic", "gemini"]
|
|
698
|
-
|
|
699
661
|
|
|
700
662
|
class CursorACPAgentConfig(BaseACPAgentConfig):
|
|
701
663
|
"""Configuration for Cursor via ACP.
|
|
@@ -748,25 +710,13 @@ class CursorACPAgentConfig(BaseACPAgentConfig):
|
|
|
748
710
|
)
|
|
749
711
|
"""Session storage directory (default: ~/.cursor-sessions)."""
|
|
750
712
|
|
|
751
|
-
timeout: int | None = Field(
|
|
752
|
-
default=None,
|
|
753
|
-
title="Timeout",
|
|
754
|
-
examples=[30000, 60000],
|
|
755
|
-
)
|
|
713
|
+
timeout: int | None = Field(default=None, title="Timeout", examples=[30000, 60000])
|
|
756
714
|
"""Cursor-agent timeout in milliseconds (default: 30000)."""
|
|
757
715
|
|
|
758
|
-
retries: int | None = Field(
|
|
759
|
-
default=None,
|
|
760
|
-
title="Retries",
|
|
761
|
-
examples=[3, 5],
|
|
762
|
-
)
|
|
716
|
+
retries: int | None = Field(default=None, title="Retries", examples=[3, 5])
|
|
763
717
|
"""Number of retries for cursor-agent commands (default: 3)."""
|
|
764
718
|
|
|
765
|
-
max_sessions: int | None = Field(
|
|
766
|
-
default=None,
|
|
767
|
-
title="Max Sessions",
|
|
768
|
-
examples=[100, 200],
|
|
769
|
-
)
|
|
719
|
+
max_sessions: int | None = Field(default=None, title="Max Sessions", examples=[100, 200])
|
|
770
720
|
"""Maximum number of concurrent sessions (default: 100)."""
|
|
771
721
|
|
|
772
722
|
session_timeout: int | None = Field(
|
|
@@ -782,11 +732,7 @@ class CursorACPAgentConfig(BaseACPAgentConfig):
|
|
|
782
732
|
no_terminal: bool = Field(default=False, title="No Terminal")
|
|
783
733
|
"""Disable terminal tools."""
|
|
784
734
|
|
|
785
|
-
max_processes: int | None = Field(
|
|
786
|
-
default=None,
|
|
787
|
-
title="Max Processes",
|
|
788
|
-
examples=[5, 10],
|
|
789
|
-
)
|
|
735
|
+
max_processes: int | None = Field(default=None, title="Max Processes", examples=[5, 10])
|
|
790
736
|
"""Maximum number of terminal processes (default: 5)."""
|
|
791
737
|
|
|
792
738
|
def get_command(self) -> str:
|
|
@@ -821,10 +767,120 @@ class CursorACPAgentConfig(BaseACPAgentConfig):
|
|
|
821
767
|
args.extend(["--max-processes", str(self.max_processes)])
|
|
822
768
|
return args
|
|
823
769
|
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
770
|
+
|
|
771
|
+
class GeminiACPAgentConfig(BaseACPAgentConfig):
|
|
772
|
+
"""Configuration for Gemini CLI via ACP.
|
|
773
|
+
|
|
774
|
+
Provides typed settings for the gemini CLI with ACP support.
|
|
775
|
+
|
|
776
|
+
Note:
|
|
777
|
+
Gemini CLI does not support runtime MCP server injection via config.
|
|
778
|
+
MCP servers must be pre-configured using `gemini mcp add` command.
|
|
779
|
+
|
|
780
|
+
Example:
|
|
781
|
+
```yaml
|
|
782
|
+
agents:
|
|
783
|
+
coder:
|
|
784
|
+
type: acp
|
|
785
|
+
provider: gemini
|
|
786
|
+
cwd: /path/to/project
|
|
787
|
+
model: gemini-2.5-pro
|
|
788
|
+
approval_mode: auto_edit
|
|
789
|
+
allowed_tools:
|
|
790
|
+
- read_file
|
|
791
|
+
- write_file
|
|
792
|
+
- terminal
|
|
793
|
+
```
|
|
794
|
+
"""
|
|
795
|
+
|
|
796
|
+
model_config = ConfigDict(json_schema_extra={"title": "Gemini ACP Agent Configuration"})
|
|
797
|
+
|
|
798
|
+
provider: Literal["gemini"] = Field("gemini", init=False)
|
|
799
|
+
"""Discriminator for Gemini ACP agent."""
|
|
800
|
+
|
|
801
|
+
model: str | None = Field(
|
|
802
|
+
default=None,
|
|
803
|
+
title="Model",
|
|
804
|
+
examples=["gemini-2.5-pro", "gemini-2.5-flash"],
|
|
805
|
+
)
|
|
806
|
+
"""Model override."""
|
|
807
|
+
|
|
808
|
+
approval_mode: Literal["default", "auto_edit", "yolo"] | None = Field(
|
|
809
|
+
default=None,
|
|
810
|
+
title="Approval Mode",
|
|
811
|
+
examples=["auto_edit", "yolo"],
|
|
812
|
+
)
|
|
813
|
+
"""Approval mode for tool execution."""
|
|
814
|
+
|
|
815
|
+
sandbox: bool = Field(default=False, title="Sandbox")
|
|
816
|
+
"""Run in sandbox mode."""
|
|
817
|
+
|
|
818
|
+
auto_approve: bool = Field(default=False, title="Auto Approve")
|
|
819
|
+
"""Automatically accept all actions."""
|
|
820
|
+
|
|
821
|
+
allowed_tools: list[str] | None = Field(
|
|
822
|
+
default=None,
|
|
823
|
+
title="Allowed Tools",
|
|
824
|
+
examples=[["read_file", "write_file", "terminal"], ["search"]],
|
|
825
|
+
)
|
|
826
|
+
"""Tools allowed to run without confirmation."""
|
|
827
|
+
|
|
828
|
+
allowed_mcp_server_names: list[str] | None = Field(
|
|
829
|
+
default=None,
|
|
830
|
+
title="Allowed MCP Server Names",
|
|
831
|
+
examples=[["filesystem", "github"], ["slack"]],
|
|
832
|
+
)
|
|
833
|
+
"""Allowed MCP server names."""
|
|
834
|
+
|
|
835
|
+
extensions: list[str] | None = Field(
|
|
836
|
+
default=None,
|
|
837
|
+
title="Extensions",
|
|
838
|
+
examples=[["python", "typescript"], ["rust", "go"]],
|
|
839
|
+
)
|
|
840
|
+
"""List of extensions to use. If not provided, all are used."""
|
|
841
|
+
|
|
842
|
+
include_directories: list[str] | None = Field(
|
|
843
|
+
default=None,
|
|
844
|
+
title="Include Directories",
|
|
845
|
+
examples=[["/path/to/lib", "/path/to/shared"], ["./vendor"]],
|
|
846
|
+
)
|
|
847
|
+
"""Additional directories to include in the workspace."""
|
|
848
|
+
|
|
849
|
+
output_format: Literal["text", "json", "stream-json"] | None = Field(
|
|
850
|
+
default=None,
|
|
851
|
+
title="Output Format",
|
|
852
|
+
examples=["json", "stream-json"],
|
|
853
|
+
)
|
|
854
|
+
"""Output format."""
|
|
855
|
+
|
|
856
|
+
def get_command(self) -> str:
|
|
857
|
+
"""Get the command to spawn the ACP server."""
|
|
858
|
+
return "gemini"
|
|
859
|
+
|
|
860
|
+
async def get_args(self, prompt_manager: PromptManager | None = None) -> list[str]:
|
|
861
|
+
"""Build command arguments from settings."""
|
|
862
|
+
args: list[str] = ["--experimental-acp"]
|
|
863
|
+
|
|
864
|
+
if self.model:
|
|
865
|
+
args.extend(["--model", self.model])
|
|
866
|
+
if self.approval_mode:
|
|
867
|
+
args.extend(["--approval-mode", self.approval_mode])
|
|
868
|
+
if self.sandbox:
|
|
869
|
+
args.append("--sandbox")
|
|
870
|
+
if self.auto_approve:
|
|
871
|
+
args.append("--yolo")
|
|
872
|
+
if self.allowed_tools:
|
|
873
|
+
args.extend(["--allowed-tools", *self.allowed_tools])
|
|
874
|
+
if self.allowed_mcp_server_names:
|
|
875
|
+
args.extend(["--allowed-mcp-server-names", *self.allowed_mcp_server_names])
|
|
876
|
+
if self.extensions:
|
|
877
|
+
args.extend(["--extensions", *self.extensions])
|
|
878
|
+
if self.include_directories:
|
|
879
|
+
args.extend(["--include-directories", *self.include_directories])
|
|
880
|
+
if self.output_format:
|
|
881
|
+
args.extend(["--output-format", self.output_format])
|
|
882
|
+
|
|
883
|
+
return args
|
|
828
884
|
|
|
829
885
|
|
|
830
886
|
# Union of all ACP agent config types
|
|
@@ -839,4 +895,5 @@ RegularACPAgentConfigTypes = (
|
|
|
839
895
|
| MistralACPAgentConfig
|
|
840
896
|
| VTCodeACPAgentConfig
|
|
841
897
|
| CursorACPAgentConfig
|
|
898
|
+
| GeminiACPAgentConfig
|
|
842
899
|
)
|
agentpool/models/agents.py
CHANGED
|
@@ -12,6 +12,7 @@ from llmling_models.configs import AnyModelConfig # noqa: TC002
|
|
|
12
12
|
from pydantic import ConfigDict, Field, model_validator
|
|
13
13
|
from pydantic_ai import UsageLimits # noqa: TC002
|
|
14
14
|
from schemez import InlineSchemaDef
|
|
15
|
+
from tokonomics.model_discovery import ProviderType # noqa: TC002
|
|
15
16
|
from tokonomics.model_names import ModelId # noqa: TC002
|
|
16
17
|
from toprompt import render_prompt
|
|
17
18
|
|
|
@@ -19,6 +20,7 @@ from agentpool import log
|
|
|
19
20
|
from agentpool.common_types import EndStrategy # noqa: TC001
|
|
20
21
|
from agentpool.prompts.prompts import PromptMessage, StaticPrompt
|
|
21
22
|
from agentpool.resource_providers import StaticResourceProvider
|
|
23
|
+
from agentpool_config.builtin_tools import BaseBuiltinToolConfig
|
|
22
24
|
from agentpool_config.hooks import HooksConfig # noqa: TC001
|
|
23
25
|
from agentpool_config.knowledge import Knowledge # noqa: TC001
|
|
24
26
|
from agentpool_config.nodes import BaseAgentConfig
|
|
@@ -37,7 +39,6 @@ if TYPE_CHECKING:
|
|
|
37
39
|
|
|
38
40
|
|
|
39
41
|
ToolMode = Literal["codemode"]
|
|
40
|
-
AutoCache = Literal["off", "5m", "1h"]
|
|
41
42
|
|
|
42
43
|
logger = log.get_logger(__name__)
|
|
43
44
|
|
|
@@ -230,6 +231,18 @@ class NativeAgentConfig(BaseAgentConfig):
|
|
|
230
231
|
usage_limits: UsageLimits | None = Field(default=None, title="Usage limits")
|
|
231
232
|
"""Usage limits for this agent."""
|
|
232
233
|
|
|
234
|
+
model_providers: list[ProviderType] | None = Field(
|
|
235
|
+
default=None,
|
|
236
|
+
examples=[["models.dev"], ["anthropic", "openai"]],
|
|
237
|
+
title="Model providers",
|
|
238
|
+
)
|
|
239
|
+
"""List of model providers to use for model discovery.
|
|
240
|
+
|
|
241
|
+
When set, the agent's get_available_models() will return models from these
|
|
242
|
+
providers. Common values: "openai", "anthropic", "gemini", "mistral", etc.
|
|
243
|
+
If not set, defaults to ["models.dev"].
|
|
244
|
+
"""
|
|
245
|
+
|
|
233
246
|
tool_mode: ToolMode | None = Field(
|
|
234
247
|
default=None,
|
|
235
248
|
examples=["codemode"],
|
|
@@ -240,17 +253,6 @@ class NativeAgentConfig(BaseAgentConfig):
|
|
|
240
253
|
- "codemode": Tools are wrapped in a Python execution environment
|
|
241
254
|
"""
|
|
242
255
|
|
|
243
|
-
auto_cache: AutoCache = Field(
|
|
244
|
-
default="off",
|
|
245
|
-
examples=["off", "5m", "1h"],
|
|
246
|
-
title="Automatic caching",
|
|
247
|
-
)
|
|
248
|
-
"""Automatic prompt caching configuration:
|
|
249
|
-
- "off": No automatic caching
|
|
250
|
-
- "5m": Add cache point with 5 minute TTL
|
|
251
|
-
- "1h": Add cache point with 1 hour TTL
|
|
252
|
-
"""
|
|
253
|
-
|
|
254
256
|
hooks: HooksConfig | None = Field(
|
|
255
257
|
default=None,
|
|
256
258
|
title="Lifecycle hooks",
|
|
@@ -312,7 +314,7 @@ class NativeAgentConfig(BaseAgentConfig):
|
|
|
312
314
|
return providers
|
|
313
315
|
|
|
314
316
|
def get_tool_provider(self) -> ResourceProvider | None:
|
|
315
|
-
"""Get tool provider for this agent."""
|
|
317
|
+
"""Get tool provider for this agent (excludes builtin tools)."""
|
|
316
318
|
from agentpool.tools.base import Tool
|
|
317
319
|
|
|
318
320
|
# Create provider for static tools
|
|
@@ -320,6 +322,9 @@ class NativeAgentConfig(BaseAgentConfig):
|
|
|
320
322
|
return None
|
|
321
323
|
static_tools: list[Tool] = []
|
|
322
324
|
for tool_config in self.tools:
|
|
325
|
+
# Skip builtin tools - they're handled via get_builtin_tools()
|
|
326
|
+
if isinstance(tool_config, BaseBuiltinToolConfig):
|
|
327
|
+
continue
|
|
323
328
|
try:
|
|
324
329
|
match tool_config:
|
|
325
330
|
case str():
|
|
@@ -331,8 +336,25 @@ class NativeAgentConfig(BaseAgentConfig):
|
|
|
331
336
|
logger.exception("Failed to load tool", config=tool_config)
|
|
332
337
|
continue
|
|
333
338
|
|
|
339
|
+
if not static_tools:
|
|
340
|
+
return None
|
|
334
341
|
return StaticResourceProvider(name="builtin", tools=static_tools)
|
|
335
342
|
|
|
343
|
+
def get_builtin_tools(self) -> list[Any]:
|
|
344
|
+
"""Get pydantic-ai builtin tools from config.
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
List of AbstractBuiltinTool instances (WebSearchTool, etc.)
|
|
348
|
+
"""
|
|
349
|
+
builtin_tools: list[Any] = []
|
|
350
|
+
for tool_config in self.tools:
|
|
351
|
+
if isinstance(tool_config, BaseBuiltinToolConfig):
|
|
352
|
+
try:
|
|
353
|
+
builtin_tools.append(tool_config.get_builtin_tool())
|
|
354
|
+
except Exception:
|
|
355
|
+
logger.exception("Failed to load builtin tool", config=tool_config)
|
|
356
|
+
return builtin_tools
|
|
357
|
+
|
|
336
358
|
def get_session_config(self) -> MemoryConfig:
|
|
337
359
|
"""Get resolved memory configuration."""
|
|
338
360
|
match self.session:
|
|
@@ -18,6 +18,26 @@ if TYPE_CHECKING:
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
PermissionMode = Literal["default", "acceptEdits", "plan", "bypassPermissions"]
|
|
21
|
+
ToolName = Literal[
|
|
22
|
+
"Task",
|
|
23
|
+
"TaskOutput",
|
|
24
|
+
"Bash",
|
|
25
|
+
"Glob",
|
|
26
|
+
"Grep",
|
|
27
|
+
"ExitPlanMode",
|
|
28
|
+
"Read",
|
|
29
|
+
"Edit",
|
|
30
|
+
"Write",
|
|
31
|
+
"NotebookEdit",
|
|
32
|
+
"WebFetch",
|
|
33
|
+
"TodoWrite",
|
|
34
|
+
"WebSearch",
|
|
35
|
+
"KillShell",
|
|
36
|
+
"AskUserQuestion",
|
|
37
|
+
"Skill",
|
|
38
|
+
"EnterPlanMode",
|
|
39
|
+
"LSP",
|
|
40
|
+
]
|
|
21
41
|
|
|
22
42
|
|
|
23
43
|
class ClaudeCodeAgentConfig(BaseAgentConfig):
|
|
@@ -74,7 +94,7 @@ class ClaudeCodeAgentConfig(BaseAgentConfig):
|
|
|
74
94
|
)
|
|
75
95
|
"""Model to use for this agent. Defaults to Claude's default model."""
|
|
76
96
|
|
|
77
|
-
allowed_tools: list[str] | None = Field(
|
|
97
|
+
allowed_tools: list[ToolName | str] | None = Field(
|
|
78
98
|
default=None,
|
|
79
99
|
title="Allowed Tools",
|
|
80
100
|
examples=[["Read", "Write", "Bash"], ["Read", "Grep", "Glob"]],
|
|
@@ -85,7 +105,7 @@ class ClaudeCodeAgentConfig(BaseAgentConfig):
|
|
|
85
105
|
Common tools: Read, Write, Edit, Bash, Glob, Grep, Task, WebFetch, etc.
|
|
86
106
|
"""
|
|
87
107
|
|
|
88
|
-
disallowed_tools: list[str] | None = Field(
|
|
108
|
+
disallowed_tools: list[ToolName | str] | None = Field(
|
|
89
109
|
default=None,
|
|
90
110
|
title="Disallowed Tools",
|
|
91
111
|
examples=[["Bash", "Write"], ["Task"]],
|
|
@@ -132,6 +152,17 @@ class ClaudeCodeAgentConfig(BaseAgentConfig):
|
|
|
132
152
|
)
|
|
133
153
|
"""Maximum number of conversation turns before stopping."""
|
|
134
154
|
|
|
155
|
+
max_budget_usd: float | None = Field(
|
|
156
|
+
default=None,
|
|
157
|
+
title="Max Budget (USD)",
|
|
158
|
+
ge=0.0,
|
|
159
|
+
examples=[1.0, 5.0, 10.0],
|
|
160
|
+
)
|
|
161
|
+
"""Maximum budget in USD before stopping.
|
|
162
|
+
|
|
163
|
+
When set, the agent will stop once the estimated cost exceeds this limit.
|
|
164
|
+
"""
|
|
165
|
+
|
|
135
166
|
max_thinking_tokens: int | None = Field(
|
|
136
167
|
default=None,
|
|
137
168
|
title="Max Thinking Tokens",
|
agentpool/models/manifest.py
CHANGED
|
@@ -17,6 +17,7 @@ from agentpool.models.agui_agents import AGUIAgentConfig
|
|
|
17
17
|
from agentpool.models.claude_code_agents import ClaudeCodeAgentConfig
|
|
18
18
|
from agentpool.models.file_agents import FileAgentConfig
|
|
19
19
|
from agentpool_config.commands import CommandConfig, StaticCommandConfig
|
|
20
|
+
from agentpool_config.compaction import CompactionConfig
|
|
20
21
|
from agentpool_config.converters import ConversionConfig
|
|
21
22
|
from agentpool_config.mcp_server import BaseMCPServerConfig, MCPServerConfig
|
|
22
23
|
from agentpool_config.observability import ObservabilityConfig
|
|
@@ -38,6 +39,7 @@ from agentpool_config.workers import (
|
|
|
38
39
|
if TYPE_CHECKING:
|
|
39
40
|
from upathtools import JoinablePathLike
|
|
40
41
|
|
|
42
|
+
from agentpool.messaging.compaction import CompactionPipeline
|
|
41
43
|
from agentpool.models.acp_agents import BaseACPAgentConfig
|
|
42
44
|
from agentpool.prompts.manager import PromptManager
|
|
43
45
|
from agentpool.vfs_registry import VFSRegistry
|
|
@@ -77,6 +79,12 @@ class AgentsManifest(Schema):
|
|
|
77
79
|
INHERIT: str | list[str] | None = None
|
|
78
80
|
"""Inheritance references."""
|
|
79
81
|
|
|
82
|
+
name: str | None = None
|
|
83
|
+
"""Optional name for this manifest.
|
|
84
|
+
|
|
85
|
+
Useful for identification when working with multiple configurations.
|
|
86
|
+
"""
|
|
87
|
+
|
|
80
88
|
resources: dict[str, ResourceConfig] = Field(
|
|
81
89
|
default_factory=dict,
|
|
82
90
|
examples=[
|
|
@@ -272,6 +280,30 @@ class AgentsManifest(Schema):
|
|
|
272
280
|
path: "./prompts/analysis.md"
|
|
273
281
|
"""
|
|
274
282
|
|
|
283
|
+
compaction: CompactionConfig | None = None
|
|
284
|
+
"""Compaction configuration for message history management.
|
|
285
|
+
|
|
286
|
+
Controls how conversation history is compacted/summarized to manage context size.
|
|
287
|
+
Can use a preset or define custom steps:
|
|
288
|
+
compaction:
|
|
289
|
+
preset: balanced # or: minimal, summarizing
|
|
290
|
+
|
|
291
|
+
Or custom steps:
|
|
292
|
+
compaction:
|
|
293
|
+
steps:
|
|
294
|
+
- type: filter_thinking
|
|
295
|
+
- type: summarize
|
|
296
|
+
model: openai:gpt-4o-mini
|
|
297
|
+
threshold: 15
|
|
298
|
+
"""
|
|
299
|
+
|
|
300
|
+
config_file_path: str | None = Field(default=None, exclude=True)
|
|
301
|
+
"""Path to the configuration file this manifest was loaded from.
|
|
302
|
+
|
|
303
|
+
Set automatically by `from_file()`. Used for resolving relative paths.
|
|
304
|
+
Excluded from serialization.
|
|
305
|
+
"""
|
|
306
|
+
|
|
275
307
|
model_config = ConfigDict(
|
|
276
308
|
json_schema_extra={
|
|
277
309
|
"x-icon": "octicon:file-code-16",
|
|
@@ -583,6 +615,16 @@ class AgentsManifest(Schema):
|
|
|
583
615
|
|
|
584
616
|
return PromptManager(self.prompts)
|
|
585
617
|
|
|
618
|
+
def get_compaction_pipeline(self) -> CompactionPipeline | None:
|
|
619
|
+
"""Get the configured compaction pipeline, if any.
|
|
620
|
+
|
|
621
|
+
Returns:
|
|
622
|
+
CompactionPipeline instance or None if not configured
|
|
623
|
+
"""
|
|
624
|
+
if self.compaction is None:
|
|
625
|
+
return None
|
|
626
|
+
return self.compaction.build()
|
|
627
|
+
|
|
586
628
|
# @model_validator(mode="after")
|
|
587
629
|
# def validate_response_types(self) -> AgentsManifest:
|
|
588
630
|
# """Ensure all agent output_types exist in responses or are inline."""
|
|
@@ -623,6 +665,7 @@ class AgentsManifest(Schema):
|
|
|
623
665
|
|
|
624
666
|
return agent_def.model_copy(
|
|
625
667
|
update={
|
|
668
|
+
"config_file_path": path_str,
|
|
626
669
|
"agents": update_with_path(agent_def.agents),
|
|
627
670
|
"teams": update_with_path(agent_def.teams),
|
|
628
671
|
}
|
agentpool/repomap.py
CHANGED
|
@@ -1109,7 +1109,7 @@ def get_file_map_from_content( # noqa: PLR0915
|
|
|
1109
1109
|
|
|
1110
1110
|
header = (
|
|
1111
1111
|
f"# File: {filename} ({lines} lines)\n"
|
|
1112
|
-
f"# Structure map (~{tokens_approx} tokens). Use
|
|
1112
|
+
f"# Structure map (~{tokens_approx} tokens). Use read with line/limit for details.\n\n"
|
|
1113
1113
|
)
|
|
1114
1114
|
|
|
1115
1115
|
result = header + f"{filename}:\n" + tree_output
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"""Resource provider implementations."""
|
|
2
2
|
|
|
3
|
-
from agentpool.resource_providers.base import
|
|
3
|
+
from agentpool.resource_providers.base import (
|
|
4
|
+
ProviderKind,
|
|
5
|
+
ResourceChangeEvent,
|
|
6
|
+
ResourceProvider,
|
|
7
|
+
ResourceType,
|
|
8
|
+
)
|
|
4
9
|
from agentpool.resource_providers.static import StaticResourceProvider
|
|
5
10
|
from agentpool.resource_providers.filtering import FilteringResourceProvider
|
|
6
11
|
from agentpool.resource_providers.aggregating import AggregatingResourceProvider
|
|
@@ -12,6 +17,9 @@ __all__ = [
|
|
|
12
17
|
"FilteringResourceProvider",
|
|
13
18
|
"MCPResourceProvider",
|
|
14
19
|
"PlanProvider",
|
|
20
|
+
"ProviderKind",
|
|
21
|
+
"ResourceChangeEvent",
|
|
15
22
|
"ResourceProvider",
|
|
23
|
+
"ResourceType",
|
|
16
24
|
"StaticResourceProvider",
|
|
17
25
|
]
|
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from agentpool.resource_providers import ResourceProvider
|
|
7
|
+
from agentpool.resource_providers.base import ResourceChangeEvent, ResourceProvider
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
@@ -14,9 +14,17 @@ if TYPE_CHECKING:
|
|
|
14
14
|
from agentpool.tools.base import Tool
|
|
15
15
|
from agentpool_config.resources import ResourceInfo
|
|
16
16
|
|
|
17
|
+
_ = ResourceChangeEvent # Used at runtime in method signatures
|
|
18
|
+
|
|
17
19
|
|
|
18
20
|
class AggregatingResourceProvider(ResourceProvider):
|
|
19
|
-
"""Provider that combines resources from multiple providers.
|
|
21
|
+
"""Provider that combines resources from multiple providers.
|
|
22
|
+
|
|
23
|
+
Automatically forwards change signals from child providers.
|
|
24
|
+
When a child emits tools_changed, this provider re-emits it.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
kind = "aggregating"
|
|
20
28
|
|
|
21
29
|
def __init__(self, providers: list[ResourceProvider], name: str = "aggregating") -> None:
|
|
22
30
|
"""Initialize provider with list of providers to aggregate.
|
|
@@ -26,9 +34,50 @@ class AggregatingResourceProvider(ResourceProvider):
|
|
|
26
34
|
name: Name for this provider
|
|
27
35
|
"""
|
|
28
36
|
super().__init__(name=name)
|
|
29
|
-
|
|
37
|
+
self._providers: list[ResourceProvider] = []
|
|
38
|
+
# Use property setter to set up signal forwarding
|
|
30
39
|
self.providers = providers
|
|
31
40
|
|
|
41
|
+
@property
|
|
42
|
+
def providers(self) -> list[ResourceProvider]:
|
|
43
|
+
"""Get the list of child providers."""
|
|
44
|
+
return self._providers
|
|
45
|
+
|
|
46
|
+
@providers.setter
|
|
47
|
+
def providers(self, value: list[ResourceProvider]) -> None:
|
|
48
|
+
"""Set the list of child providers and set up signal forwarding."""
|
|
49
|
+
# Disconnect from old providers
|
|
50
|
+
for provider in self._providers:
|
|
51
|
+
provider.tools_changed.disconnect(self._forward_tools_changed)
|
|
52
|
+
provider.prompts_changed.disconnect(self._forward_prompts_changed)
|
|
53
|
+
provider.resources_changed.disconnect(self._forward_resources_changed)
|
|
54
|
+
provider.skills_changed.disconnect(self._forward_skills_changed)
|
|
55
|
+
|
|
56
|
+
self._providers = value
|
|
57
|
+
|
|
58
|
+
# Connect to new providers
|
|
59
|
+
for provider in self._providers:
|
|
60
|
+
provider.tools_changed.connect(self._forward_tools_changed)
|
|
61
|
+
provider.prompts_changed.connect(self._forward_prompts_changed)
|
|
62
|
+
provider.resources_changed.connect(self._forward_resources_changed)
|
|
63
|
+
provider.skills_changed.connect(self._forward_skills_changed)
|
|
64
|
+
|
|
65
|
+
async def _forward_tools_changed(self, event: ResourceChangeEvent) -> None:
|
|
66
|
+
"""Forward tools_changed signal from child provider."""
|
|
67
|
+
await self.tools_changed.emit(event)
|
|
68
|
+
|
|
69
|
+
async def _forward_prompts_changed(self, event: ResourceChangeEvent) -> None:
|
|
70
|
+
"""Forward prompts_changed signal from child provider."""
|
|
71
|
+
await self.prompts_changed.emit(event)
|
|
72
|
+
|
|
73
|
+
async def _forward_resources_changed(self, event: ResourceChangeEvent) -> None:
|
|
74
|
+
"""Forward resources_changed signal from child provider."""
|
|
75
|
+
await self.resources_changed.emit(event)
|
|
76
|
+
|
|
77
|
+
async def _forward_skills_changed(self, event: ResourceChangeEvent) -> None:
|
|
78
|
+
"""Forward skills_changed signal from child provider."""
|
|
79
|
+
await self.skills_changed.emit(event)
|
|
80
|
+
|
|
32
81
|
async def get_tools(self) -> list[Tool]:
|
|
33
82
|
"""Get tools from all providers."""
|
|
34
83
|
return [t for provider in self.providers for t in await provider.get_tools()]
|