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
|
@@ -477,6 +477,18 @@ class MessageHistory:
|
|
|
477
477
|
# Use cost_info if available
|
|
478
478
|
return self.chat_messages.get_history_tokens()
|
|
479
479
|
|
|
480
|
+
def get_last_message_id(self) -> str | None:
|
|
481
|
+
"""Get the message_id of the last message in history.
|
|
482
|
+
|
|
483
|
+
Used for setting parent_id on new messages to build the message tree.
|
|
484
|
+
|
|
485
|
+
Returns:
|
|
486
|
+
The message_id of the last message, or None if history is empty.
|
|
487
|
+
"""
|
|
488
|
+
if not self.chat_messages:
|
|
489
|
+
return None
|
|
490
|
+
return self.chat_messages[-1].message_id
|
|
491
|
+
|
|
480
492
|
|
|
481
493
|
if __name__ == "__main__":
|
|
482
494
|
from agentpool import Agent
|
agentpool/messaging/messages.py
CHANGED
|
@@ -30,6 +30,7 @@ from agentpool.common_types import MessageRole, SimpleJsonType # noqa: TC001
|
|
|
30
30
|
from agentpool.log import get_logger
|
|
31
31
|
from agentpool.utils.inspection import dataclasses_no_defaults_repr
|
|
32
32
|
from agentpool.utils.now import get_now
|
|
33
|
+
from agentpool.utils.pydantic_ai_helpers import safe_args_as_dict
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
if TYPE_CHECKING:
|
|
@@ -198,6 +199,14 @@ class ChatMessage[TContent]:
|
|
|
198
199
|
conversation_id: str | None = None
|
|
199
200
|
"""ID of the conversation this message belongs to."""
|
|
200
201
|
|
|
202
|
+
parent_id: str | None = None
|
|
203
|
+
"""ID of the parent message for tree-structured conversations.
|
|
204
|
+
|
|
205
|
+
This enables branching conversations where each message knows its predecessor.
|
|
206
|
+
For user messages, this typically points to the previous assistant response.
|
|
207
|
+
For assistant responses, this points to the user message being responded to.
|
|
208
|
+
"""
|
|
209
|
+
|
|
201
210
|
response_time: float | None = None
|
|
202
211
|
"""Time it took the LLM to respond."""
|
|
203
212
|
|
|
@@ -295,12 +304,29 @@ class ChatMessage[TContent]:
|
|
|
295
304
|
message: TPromptContent,
|
|
296
305
|
conversation_id: str | None = None,
|
|
297
306
|
instructions: str | None = None,
|
|
307
|
+
parent_id: str | None = None,
|
|
298
308
|
) -> ChatMessage[TPromptContent]:
|
|
299
|
-
"""Create a user prompt message.
|
|
309
|
+
"""Create a user prompt message.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
message: The prompt content
|
|
313
|
+
conversation_id: ID of the conversation
|
|
314
|
+
instructions: Optional instructions for the model
|
|
315
|
+
parent_id: ID of the parent message (typically the previous assistant response)
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
A ChatMessage representing the user prompt
|
|
319
|
+
"""
|
|
300
320
|
part = UserPromptPart(content=message)
|
|
301
321
|
request = ModelRequest(parts=[part], instructions=instructions)
|
|
302
322
|
id_ = conversation_id or str(uuid4())
|
|
303
|
-
return ChatMessage(
|
|
323
|
+
return ChatMessage(
|
|
324
|
+
messages=[request],
|
|
325
|
+
role="user",
|
|
326
|
+
content=message,
|
|
327
|
+
conversation_id=id_,
|
|
328
|
+
parent_id=parent_id,
|
|
329
|
+
)
|
|
304
330
|
|
|
305
331
|
@classmethod
|
|
306
332
|
def from_pydantic_ai[TContentType](
|
|
@@ -310,6 +336,7 @@ class ChatMessage[TContent]:
|
|
|
310
336
|
conversation_id: str | None = None,
|
|
311
337
|
name: str | None = None,
|
|
312
338
|
forwarded_from: list[str] | None = None,
|
|
339
|
+
parent_id: str | None = None,
|
|
313
340
|
) -> ChatMessage[TContentType]:
|
|
314
341
|
"""Convert a Pydantic model to a ChatMessage."""
|
|
315
342
|
match message:
|
|
@@ -322,6 +349,7 @@ class ChatMessage[TContent]:
|
|
|
322
349
|
# instructions=instructions,
|
|
323
350
|
forwarded_from=forwarded_from or [],
|
|
324
351
|
name=name,
|
|
352
|
+
parent_id=parent_id,
|
|
325
353
|
)
|
|
326
354
|
case ModelResponse(
|
|
327
355
|
usage=usage,
|
|
@@ -348,6 +376,7 @@ class ChatMessage[TContent]:
|
|
|
348
376
|
provider_response_id=provider_response_id,
|
|
349
377
|
name=name,
|
|
350
378
|
forwarded_from=forwarded_from or [],
|
|
379
|
+
parent_id=parent_id,
|
|
351
380
|
)
|
|
352
381
|
case _ as unreachable:
|
|
353
382
|
assert_never(unreachable)
|
|
@@ -360,7 +389,9 @@ class ChatMessage[TContent]:
|
|
|
360
389
|
agent_name: str | None = None,
|
|
361
390
|
message_id: str | None = None,
|
|
362
391
|
conversation_id: str | None = None,
|
|
392
|
+
parent_id: str | None = None,
|
|
363
393
|
response_time: float,
|
|
394
|
+
metadata: SimpleJsonType | None = None,
|
|
364
395
|
) -> ChatMessage[OutputDataT]:
|
|
365
396
|
"""Create a ChatMessage from a PydanticAI run result.
|
|
366
397
|
|
|
@@ -369,19 +400,29 @@ class ChatMessage[TContent]:
|
|
|
369
400
|
agent_name: Name of the agent that generated this response
|
|
370
401
|
message_id: Unique message identifier
|
|
371
402
|
conversation_id: Conversation identifier
|
|
403
|
+
parent_id: ID of the parent message (typically the user message)
|
|
372
404
|
response_time: Total time taken for the response
|
|
405
|
+
metadata: Optional metadata to attach to the message
|
|
373
406
|
|
|
374
407
|
Returns:
|
|
375
408
|
A ChatMessage with all fields populated from the result
|
|
376
409
|
"""
|
|
377
|
-
# Calculate costs
|
|
410
|
+
# Calculate costs - prefer provider-reported cost if available
|
|
378
411
|
run_usage = result.usage()
|
|
379
412
|
usage = result.response.usage
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
413
|
+
provider_cost = (result.response.provider_details or {}).get("cost")
|
|
414
|
+
if provider_cost is not None:
|
|
415
|
+
# Use actual cost from provider (e.g., OpenRouter returns this)
|
|
416
|
+
cost_info: TokenCost | None = TokenCost(
|
|
417
|
+
token_usage=run_usage, total_cost=Decimal(str(provider_cost))
|
|
418
|
+
)
|
|
419
|
+
else:
|
|
420
|
+
# Fall back to calculated cost
|
|
421
|
+
cost_info = await TokenCost.from_usage(
|
|
422
|
+
model=result.response.model_name or "",
|
|
423
|
+
usage=run_usage,
|
|
424
|
+
provider=result.response.provider_name,
|
|
425
|
+
)
|
|
385
426
|
|
|
386
427
|
return ChatMessage[OutputDataT](
|
|
387
428
|
content=result.output,
|
|
@@ -395,9 +436,11 @@ class ChatMessage[TContent]:
|
|
|
395
436
|
provider_name=result.response.provider_name,
|
|
396
437
|
message_id=message_id or str(uuid4()),
|
|
397
438
|
conversation_id=conversation_id,
|
|
439
|
+
parent_id=parent_id,
|
|
398
440
|
cost_info=cost_info,
|
|
399
441
|
response_time=response_time,
|
|
400
442
|
provider_details={},
|
|
443
|
+
metadata=metadata or {},
|
|
401
444
|
)
|
|
402
445
|
|
|
403
446
|
def forwarded(self, previous_message: ChatMessage[Any]) -> Self:
|
|
@@ -509,7 +552,7 @@ class ChatMessage[TContent]:
|
|
|
509
552
|
call_part = call_parts[part.tool_call_id]
|
|
510
553
|
tool_info = ToolCallInfo(
|
|
511
554
|
tool_name=call_part.tool_name,
|
|
512
|
-
args=call_part
|
|
555
|
+
args=safe_args_as_dict(call_part),
|
|
513
556
|
agent_name=agent_name or "UNSET",
|
|
514
557
|
result=part.content,
|
|
515
558
|
tool_call_id=call_part.tool_call_id or str(uuid4()),
|
|
@@ -18,6 +18,7 @@ if TYPE_CHECKING:
|
|
|
18
18
|
|
|
19
19
|
async def prepare_prompts(
|
|
20
20
|
*prompt: PromptCompatible | ChatMessage[Any],
|
|
21
|
+
parent_id: str | None = None,
|
|
21
22
|
) -> tuple[ChatMessage[Any], list[UserContent], ChatMessage[Any] | None]:
|
|
22
23
|
"""Prepare prompts for processing.
|
|
23
24
|
|
|
@@ -25,6 +26,7 @@ async def prepare_prompts(
|
|
|
25
26
|
|
|
26
27
|
Args:
|
|
27
28
|
*prompt: The prompt(s) to prepare.
|
|
29
|
+
parent_id: Optional ID of the parent message (typically the previous response).
|
|
28
30
|
|
|
29
31
|
Returns:
|
|
30
32
|
A tuple of:
|
|
@@ -41,7 +43,7 @@ async def prepare_prompts(
|
|
|
41
43
|
# clear cost info to avoid double-counting
|
|
42
44
|
return user_msg, prompts, original_msg
|
|
43
45
|
prompts = await convert_prompts(prompt)
|
|
44
|
-
user_msg = ChatMessage.user_prompt(message=prompts)
|
|
46
|
+
user_msg = ChatMessage.user_prompt(message=prompts, parent_id=parent_id)
|
|
45
47
|
return user_msg, prompts, None
|
|
46
48
|
|
|
47
49
|
|
|
@@ -13,7 +13,6 @@ from exxec.configs import (
|
|
|
13
13
|
ExecutionEnvironmentConfig, # noqa: TC002
|
|
14
14
|
)
|
|
15
15
|
from pydantic import ConfigDict, Field
|
|
16
|
-
from tokonomics.model_discovery import ProviderType # noqa: TC002
|
|
17
16
|
|
|
18
17
|
from agentpool_config.nodes import NodeConfig
|
|
19
18
|
from agentpool_config.system_prompts import PromptConfig # noqa: TC001
|
|
@@ -239,15 +238,6 @@ class BaseACPAgentConfig(NodeConfig):
|
|
|
239
238
|
return get_environment(self.client_execution_environment)
|
|
240
239
|
return self.client_execution_environment.get_provider()
|
|
241
240
|
|
|
242
|
-
@property
|
|
243
|
-
def model_providers(self) -> list[ProviderType]:
|
|
244
|
-
"""Return the model providers used by this ACP agent.
|
|
245
|
-
|
|
246
|
-
Override in subclasses to specify which providers the agent uses.
|
|
247
|
-
Used for intelligent model discovery and fallback configuration.
|
|
248
|
-
"""
|
|
249
|
-
return []
|
|
250
|
-
|
|
251
241
|
|
|
252
242
|
class ACPAgentConfig(BaseACPAgentConfig):
|
|
253
243
|
"""Configuration for a custom ACP agent with explicit command.
|
|
@@ -286,18 +276,6 @@ class ACPAgentConfig(BaseACPAgentConfig):
|
|
|
286
276
|
)
|
|
287
277
|
"""Arguments to pass to the command."""
|
|
288
278
|
|
|
289
|
-
providers: list[ProviderType] = Field(
|
|
290
|
-
default_factory=list,
|
|
291
|
-
title="Providers",
|
|
292
|
-
examples=[["openai", "anthropic"], ["gemini"]],
|
|
293
|
-
)
|
|
294
|
-
"""Model providers this agent can use."""
|
|
295
|
-
|
|
296
|
-
@property
|
|
297
|
-
def model_providers(self) -> list[ProviderType]:
|
|
298
|
-
"""Return configured providers for custom ACP agents."""
|
|
299
|
-
return list(self.providers)
|
|
300
|
-
|
|
301
279
|
def get_command(self) -> str:
|
|
302
280
|
"""Get the command to spawn the ACP server."""
|
|
303
281
|
return self.command
|
|
@@ -5,8 +5,8 @@ from __future__ import annotations
|
|
|
5
5
|
import json
|
|
6
6
|
from typing import TYPE_CHECKING, Any, Literal, assert_never, cast
|
|
7
7
|
|
|
8
|
+
import anyenv
|
|
8
9
|
from pydantic import BaseModel, ConfigDict, Field
|
|
9
|
-
from tokonomics.model_discovery import ProviderType # noqa: TC002
|
|
10
10
|
|
|
11
11
|
from agentpool.models.acp_agents.base import BaseACPAgentConfig
|
|
12
12
|
from agentpool_config.output_types import StructuredResponseConfig # noqa: TC001
|
|
@@ -211,9 +211,9 @@ class ClaudeACPAgentConfig(MCPCapableACPAgentConfig):
|
|
|
211
211
|
)
|
|
212
212
|
"""Fallback model when default is overloaded."""
|
|
213
213
|
|
|
214
|
-
|
|
214
|
+
auto_approve: bool = Field(
|
|
215
215
|
default=False,
|
|
216
|
-
title="
|
|
216
|
+
title="Auto Approve",
|
|
217
217
|
)
|
|
218
218
|
"""Bypass all permission checks. Only for sandboxed environments."""
|
|
219
219
|
|
|
@@ -267,7 +267,7 @@ class ClaudeACPAgentConfig(MCPCapableACPAgentConfig):
|
|
|
267
267
|
args.extend(["--tools", ""])
|
|
268
268
|
if self.fallback_model:
|
|
269
269
|
args.extend(["--fallback-model", self.fallback_model])
|
|
270
|
-
if self.
|
|
270
|
+
if self.auto_approve:
|
|
271
271
|
args.append("--dangerously-skip-permissions")
|
|
272
272
|
if self.output_type:
|
|
273
273
|
args.extend(["--output-format", "json"])
|
|
@@ -286,128 +286,7 @@ class ClaudeACPAgentConfig(MCPCapableACPAgentConfig):
|
|
|
286
286
|
return None
|
|
287
287
|
# StructuredResponseConfig - resolve schema via get_schema()
|
|
288
288
|
model_cls = cast(type[BaseModel], self.output_type.response_schema.get_schema())
|
|
289
|
-
return
|
|
290
|
-
|
|
291
|
-
@property
|
|
292
|
-
def model_providers(self) -> list[ProviderType]:
|
|
293
|
-
"""Claude Code uses Anthropic models."""
|
|
294
|
-
return ["anthropic"]
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
class GeminiACPAgentConfig(MCPCapableACPAgentConfig):
|
|
298
|
-
"""Configuration for Gemini CLI via ACP.
|
|
299
|
-
|
|
300
|
-
Provides typed settings for the gemini CLI with ACP support.
|
|
301
|
-
|
|
302
|
-
Example:
|
|
303
|
-
```yaml
|
|
304
|
-
agents:
|
|
305
|
-
coder:
|
|
306
|
-
type: acp
|
|
307
|
-
provider: gemini
|
|
308
|
-
cwd: /path/to/project
|
|
309
|
-
model: gemini-2.5-pro
|
|
310
|
-
approval_mode: auto_edit
|
|
311
|
-
allowed_tools:
|
|
312
|
-
- read_file
|
|
313
|
-
- write_file
|
|
314
|
-
- terminal
|
|
315
|
-
```
|
|
316
|
-
"""
|
|
317
|
-
|
|
318
|
-
model_config = ConfigDict(json_schema_extra={"title": "Gemini ACP Agent Configuration"})
|
|
319
|
-
|
|
320
|
-
provider: Literal["gemini"] = Field("gemini", init=False)
|
|
321
|
-
"""Discriminator for Gemini ACP agent."""
|
|
322
|
-
|
|
323
|
-
model: str | None = Field(
|
|
324
|
-
default=None,
|
|
325
|
-
title="Model",
|
|
326
|
-
examples=["gemini-2.5-pro", "gemini-2.5-flash"],
|
|
327
|
-
)
|
|
328
|
-
"""Model override."""
|
|
329
|
-
|
|
330
|
-
approval_mode: Literal["default", "auto_edit", "yolo"] | None = Field(
|
|
331
|
-
default=None,
|
|
332
|
-
title="Approval Mode",
|
|
333
|
-
examples=["auto_edit", "yolo"],
|
|
334
|
-
)
|
|
335
|
-
"""Approval mode for tool execution."""
|
|
336
|
-
|
|
337
|
-
sandbox: bool = Field(default=False, title="Sandbox")
|
|
338
|
-
"""Run in sandbox mode."""
|
|
339
|
-
|
|
340
|
-
yolo: bool = Field(default=False, title="YOLO")
|
|
341
|
-
"""Automatically accept all actions."""
|
|
342
|
-
|
|
343
|
-
allowed_tools: list[str] | None = Field(
|
|
344
|
-
default=None,
|
|
345
|
-
title="Allowed Tools",
|
|
346
|
-
examples=[["read_file", "write_file", "terminal"], ["search"]],
|
|
347
|
-
)
|
|
348
|
-
"""Tools allowed to run without confirmation."""
|
|
349
|
-
|
|
350
|
-
allowed_mcp_server_names: list[str] | None = Field(
|
|
351
|
-
default=None,
|
|
352
|
-
title="Allowed MCP Server Names",
|
|
353
|
-
examples=[["filesystem", "github"], ["slack"]],
|
|
354
|
-
)
|
|
355
|
-
"""Allowed MCP server names."""
|
|
356
|
-
|
|
357
|
-
extensions: list[str] | None = Field(
|
|
358
|
-
default=None,
|
|
359
|
-
title="Extensions",
|
|
360
|
-
examples=[["python", "typescript"], ["rust", "go"]],
|
|
361
|
-
)
|
|
362
|
-
"""List of extensions to use. If not provided, all are used."""
|
|
363
|
-
|
|
364
|
-
include_directories: list[str] | None = Field(
|
|
365
|
-
default=None,
|
|
366
|
-
title="Include Directories",
|
|
367
|
-
examples=[["/path/to/lib", "/path/to/shared"], ["./vendor"]],
|
|
368
|
-
)
|
|
369
|
-
"""Additional directories to include in the workspace."""
|
|
370
|
-
|
|
371
|
-
output_format: Literal["text", "json", "stream-json"] | None = Field(
|
|
372
|
-
default=None,
|
|
373
|
-
title="Output Format",
|
|
374
|
-
examples=["json", "stream-json"],
|
|
375
|
-
)
|
|
376
|
-
"""Output format."""
|
|
377
|
-
|
|
378
|
-
def get_command(self) -> str:
|
|
379
|
-
"""Get the command to spawn the ACP server."""
|
|
380
|
-
return "gemini"
|
|
381
|
-
|
|
382
|
-
@property
|
|
383
|
-
def model_providers(self) -> list[ProviderType]:
|
|
384
|
-
"""Gemini CLI uses Google Gemini models."""
|
|
385
|
-
return ["gemini"]
|
|
386
|
-
|
|
387
|
-
async def get_args(self, prompt_manager: PromptManager | None = None) -> list[str]:
|
|
388
|
-
"""Build command arguments from settings."""
|
|
389
|
-
args: list[str] = ["--experimental-acp"]
|
|
390
|
-
|
|
391
|
-
if self.model:
|
|
392
|
-
args.extend(["--model", self.model])
|
|
393
|
-
if self.approval_mode:
|
|
394
|
-
args.extend(["--approval-mode", self.approval_mode])
|
|
395
|
-
if self.sandbox:
|
|
396
|
-
args.append("--sandbox")
|
|
397
|
-
if self.yolo:
|
|
398
|
-
args.append("--yolo")
|
|
399
|
-
if self.allowed_tools:
|
|
400
|
-
args.extend(["--allowed-tools", *self.allowed_tools])
|
|
401
|
-
if self.allowed_mcp_server_names:
|
|
402
|
-
args.extend(["--allowed-mcp-server-names", *self.allowed_mcp_server_names])
|
|
403
|
-
if self.extensions:
|
|
404
|
-
args.extend(["--extensions", *self.extensions])
|
|
405
|
-
if self.include_directories:
|
|
406
|
-
args.extend(["--include-directories", *self.include_directories])
|
|
407
|
-
if self.output_format:
|
|
408
|
-
args.extend(["--output-format", self.output_format])
|
|
409
|
-
|
|
410
|
-
return args
|
|
289
|
+
return anyenv.dump_json(model_cls.model_json_schema())
|
|
411
290
|
|
|
412
291
|
|
|
413
292
|
class FastAgentACPAgentConfig(MCPCapableACPAgentConfig):
|
|
@@ -513,11 +392,6 @@ class FastAgentACPAgentConfig(MCPCapableACPAgentConfig):
|
|
|
513
392
|
|
|
514
393
|
return args
|
|
515
394
|
|
|
516
|
-
@property
|
|
517
|
-
def model_providers(self) -> list[ProviderType]:
|
|
518
|
-
"""fast-agent supports multiple providers."""
|
|
519
|
-
return ["openai", "anthropic", "gemini", "openrouter"]
|
|
520
|
-
|
|
521
395
|
|
|
522
396
|
class AuggieACPAgentConfig(MCPCapableACPAgentConfig):
|
|
523
397
|
"""Configuration for Auggie (Augment Code) via ACP.
|
|
@@ -681,11 +555,6 @@ class AuggieACPAgentConfig(MCPCapableACPAgentConfig):
|
|
|
681
555
|
|
|
682
556
|
return args
|
|
683
557
|
|
|
684
|
-
@property
|
|
685
|
-
def model_providers(self) -> list[ProviderType]:
|
|
686
|
-
"""Auggie uses Augment Code's models."""
|
|
687
|
-
return []
|
|
688
|
-
|
|
689
558
|
|
|
690
559
|
class KimiACPAgentConfig(MCPCapableACPAgentConfig):
|
|
691
560
|
"""Configuration for Kimi CLI via ACP.
|
|
@@ -737,7 +606,7 @@ class KimiACPAgentConfig(MCPCapableACPAgentConfig):
|
|
|
737
606
|
)
|
|
738
607
|
"""Working directory for the agent."""
|
|
739
608
|
|
|
740
|
-
|
|
609
|
+
auto_approve: bool = Field(default=False, title="Auto Approve")
|
|
741
610
|
"""Automatically approve all actions."""
|
|
742
611
|
|
|
743
612
|
thinking: bool | None = Field(default=None, title="Thinking")
|
|
@@ -767,24 +636,15 @@ class KimiACPAgentConfig(MCPCapableACPAgentConfig):
|
|
|
767
636
|
if mcp_json:
|
|
768
637
|
args.extend(["--mcp-config", mcp_json])
|
|
769
638
|
|
|
770
|
-
if self.
|
|
639
|
+
if self.auto_approve:
|
|
771
640
|
args.append("--yolo")
|
|
772
641
|
if self.thinking is not None and self.thinking:
|
|
773
642
|
args.append("--thinking")
|
|
774
643
|
|
|
775
644
|
return args
|
|
776
645
|
|
|
777
|
-
@property
|
|
778
|
-
def model_providers(self) -> list[ProviderType]:
|
|
779
|
-
"""Kimi uses Moonshot AI's models."""
|
|
780
|
-
return []
|
|
781
|
-
|
|
782
646
|
|
|
783
647
|
# Union of all ACP agent config types
|
|
784
648
|
MCPCapableACPAgentConfigTypes = (
|
|
785
|
-
ClaudeACPAgentConfig
|
|
786
|
-
| GeminiACPAgentConfig
|
|
787
|
-
| FastAgentACPAgentConfig
|
|
788
|
-
| AuggieACPAgentConfig
|
|
789
|
-
| KimiACPAgentConfig
|
|
649
|
+
ClaudeACPAgentConfig | FastAgentACPAgentConfig | AuggieACPAgentConfig | KimiACPAgentConfig
|
|
790
650
|
)
|