agentpool 2.1.9__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 +13 -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/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/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 +20 -50
- 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/stdio.py +39 -9
- acp/task/supervisor.py +2 -2
- acp/transports.py +362 -2
- acp/utils.py +17 -4
- agentpool/__init__.py +6 -1
- agentpool/agents/__init__.py +2 -0
- agentpool/agents/acp_agent/acp_agent.py +407 -277
- agentpool/agents/acp_agent/acp_converters.py +196 -38
- agentpool/agents/acp_agent/client_handler.py +191 -26
- agentpool/agents/acp_agent/session_state.py +17 -6
- agentpool/agents/agent.py +607 -572
- agentpool/agents/agui_agent/__init__.py +0 -2
- agentpool/agents/agui_agent/agui_agent.py +176 -110
- agentpool/agents/agui_agent/agui_converters.py +0 -131
- agentpool/agents/agui_agent/helpers.py +3 -4
- agentpool/agents/base_agent.py +632 -17
- 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 +1058 -291
- agentpool/agents/claude_code_agent/converters.py +74 -143
- agentpool/agents/claude_code_agent/history.py +474 -0
- 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/context.py +40 -0
- agentpool/agents/events/__init__.py +24 -0
- agentpool/agents/events/builtin_handlers.py +67 -1
- agentpool/agents/events/event_emitter.py +32 -2
- agentpool/agents/events/events.py +104 -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 +67 -0
- agentpool/agents/slashed_agent.py +5 -4
- agentpool/agents/tool_call_accumulator.py +213 -0
- agentpool/agents/tool_wrapping.py +18 -6
- agentpool/common_types.py +56 -21
- agentpool/config_resources/__init__.py +38 -1
- 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 +10 -6
- agentpool/config_resources/external_acp_agents.yml +2 -1
- agentpool/delegation/base_team.py +4 -30
- agentpool/delegation/pool.py +136 -289
- agentpool/delegation/team.py +58 -57
- agentpool/delegation/teamrun.py +51 -55
- 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/functional/run.py +10 -4
- agentpool/mcp_server/__init__.py +0 -2
- agentpool/mcp_server/client.py +76 -32
- agentpool/mcp_server/conversions.py +54 -13
- agentpool/mcp_server/manager.py +34 -54
- agentpool/mcp_server/registries/official_registry_client.py +35 -1
- agentpool/mcp_server/tool_bridge.py +186 -139
- agentpool/messaging/__init__.py +0 -2
- agentpool/messaging/compaction.py +72 -197
- 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 +99 -8
- agentpool/messaging/messagenode.py +52 -14
- agentpool/messaging/messages.py +54 -35
- agentpool/messaging/processing.py +12 -22
- agentpool/models/__init__.py +1 -1
- agentpool/models/acp_agents/base.py +6 -24
- agentpool/models/acp_agents/mcp_capable.py +126 -157
- agentpool/models/acp_agents/non_mcp.py +129 -95
- agentpool/models/agents.py +98 -76
- agentpool/models/agui_agents.py +1 -1
- agentpool/models/claude_code_agents.py +144 -19
- agentpool/models/file_parsing.py +0 -1
- agentpool/models/manifest.py +113 -50
- agentpool/prompts/conversion_manager.py +1 -1
- agentpool/prompts/prompts.py +5 -2
- agentpool/repomap.py +1 -1
- agentpool/resource_providers/__init__.py +11 -1
- agentpool/resource_providers/aggregating.py +56 -5
- agentpool/resource_providers/base.py +70 -4
- 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 +89 -12
- agentpool/resource_providers/plan_provider.py +228 -46
- agentpool/resource_providers/pool.py +7 -3
- agentpool/resource_providers/resource_info.py +111 -0
- agentpool/resource_providers/static.py +4 -2
- agentpool/sessions/__init__.py +4 -1
- agentpool/sessions/manager.py +33 -5
- agentpool/sessions/models.py +59 -6
- agentpool/sessions/protocol.py +28 -0
- agentpool/sessions/session.py +11 -55
- agentpool/skills/registry.py +13 -8
- agentpool/storage/manager.py +572 -49
- agentpool/talk/registry.py +4 -4
- agentpool/talk/talk.py +9 -10
- agentpool/testing.py +538 -20
- 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/file_watcher.py +269 -0
- agentpool/utils/identifiers.py +121 -0
- agentpool/utils/pydantic_ai_helpers.py +46 -0
- agentpool/utils/streams.py +616 -2
- agentpool/utils/subprocess_utils.py +155 -0
- agentpool/utils/token_breakdown.py +461 -0
- agentpool/vfs_registry.py +7 -2
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/METADATA +41 -27
- agentpool-2.5.0.dist-info/RECORD +579 -0
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/WHEEL +1 -1
- agentpool_cli/__main__.py +24 -0
- agentpool_cli/create.py +1 -1
- agentpool_cli/serve_acp.py +100 -21
- agentpool_cli/serve_agui.py +87 -0
- agentpool_cli/serve_opencode.py +119 -0
- agentpool_cli/ui.py +557 -0
- agentpool_commands/__init__.py +42 -5
- agentpool_commands/agents.py +75 -2
- agentpool_commands/history.py +62 -0
- agentpool_commands/mcp.py +176 -0
- agentpool_commands/models.py +56 -3
- 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/tools.py +57 -0
- agentpool_commands/utils.py +80 -30
- agentpool_config/__init__.py +30 -2
- agentpool_config/agentpool_tools.py +498 -0
- agentpool_config/builtin_tools.py +77 -22
- agentpool_config/commands.py +24 -1
- agentpool_config/compaction.py +258 -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 +132 -6
- agentpool_config/nodes.py +1 -1
- agentpool_config/observability.py +44 -0
- agentpool_config/session.py +0 -3
- agentpool_config/storage.py +82 -38
- agentpool_config/task.py +3 -3
- agentpool_config/tools.py +11 -22
- agentpool_config/toolsets.py +109 -233
- agentpool_server/a2a_server/agent_worker.py +307 -0
- agentpool_server/a2a_server/server.py +23 -18
- agentpool_server/acp_server/acp_agent.py +234 -181
- agentpool_server/acp_server/commands/acp_commands.py +151 -156
- agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +18 -17
- agentpool_server/acp_server/event_converter.py +651 -0
- agentpool_server/acp_server/input_provider.py +53 -10
- agentpool_server/acp_server/server.py +24 -90
- agentpool_server/acp_server/session.py +173 -331
- 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/.rules +95 -0
- agentpool_server/opencode_server/ENDPOINTS.md +401 -0
- agentpool_server/opencode_server/OPENCODE_UI_TOOLS_COMPLETE.md +202 -0
- agentpool_server/opencode_server/__init__.py +19 -0
- agentpool_server/opencode_server/command_validation.py +172 -0
- agentpool_server/opencode_server/converters.py +975 -0
- agentpool_server/opencode_server/dependencies.py +24 -0
- agentpool_server/opencode_server/input_provider.py +421 -0
- agentpool_server/opencode_server/models/__init__.py +250 -0
- agentpool_server/opencode_server/models/agent.py +53 -0
- agentpool_server/opencode_server/models/app.py +72 -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 +821 -0
- agentpool_server/opencode_server/models/file.py +88 -0
- agentpool_server/opencode_server/models/mcp.py +44 -0
- agentpool_server/opencode_server/models/message.py +179 -0
- agentpool_server/opencode_server/models/parts.py +323 -0
- agentpool_server/opencode_server/models/provider.py +81 -0
- agentpool_server/opencode_server/models/pty.py +43 -0
- agentpool_server/opencode_server/models/question.py +56 -0
- agentpool_server/opencode_server/models/session.py +111 -0
- agentpool_server/opencode_server/routes/__init__.py +29 -0
- agentpool_server/opencode_server/routes/agent_routes.py +473 -0
- agentpool_server/opencode_server/routes/app_routes.py +202 -0
- agentpool_server/opencode_server/routes/config_routes.py +302 -0
- agentpool_server/opencode_server/routes/file_routes.py +571 -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 +761 -0
- agentpool_server/opencode_server/routes/permission_routes.py +63 -0
- agentpool_server/opencode_server/routes/pty_routes.py +300 -0
- agentpool_server/opencode_server/routes/question_routes.py +128 -0
- agentpool_server/opencode_server/routes/session_routes.py +1276 -0
- agentpool_server/opencode_server/routes/tui_routes.py +139 -0
- agentpool_server/opencode_server/server.py +475 -0
- agentpool_server/opencode_server/state.py +151 -0
- agentpool_server/opencode_server/time_utils.py +8 -0
- agentpool_storage/__init__.py +12 -0
- agentpool_storage/base.py +184 -2
- agentpool_storage/claude_provider/ARCHITECTURE.md +433 -0
- agentpool_storage/claude_provider/__init__.py +42 -0
- agentpool_storage/claude_provider/provider.py +1089 -0
- agentpool_storage/file_provider.py +278 -15
- agentpool_storage/memory_provider.py +193 -12
- agentpool_storage/models.py +3 -0
- 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/project_store.py +325 -0
- agentpool_storage/session_store.py +26 -6
- agentpool_storage/sql_provider/__init__.py +4 -2
- agentpool_storage/sql_provider/models.py +48 -0
- agentpool_storage/sql_provider/sql_provider.py +269 -3
- agentpool_storage/sql_provider/utils.py +12 -13
- 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 -12
- agentpool_toolsets/builtin/code.py +96 -57
- agentpool_toolsets/builtin/debug.py +118 -48
- agentpool_toolsets/builtin/execution_environment.py +115 -230
- agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
- agentpool_toolsets/builtin/skills.py +9 -4
- 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/__init__.py +13 -1
- agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
- agentpool_toolsets/fsspec_toolset/grep.py +99 -7
- agentpool_toolsets/fsspec_toolset/helpers.py +3 -2
- agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
- agentpool_toolsets/fsspec_toolset/toolset.py +500 -95
- agentpool_toolsets/mcp_discovery/__init__.py +5 -0
- agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
- agentpool_toolsets/mcp_discovery/toolset.py +511 -0
- agentpool_toolsets/mcp_run_toolset.py +87 -12
- agentpool_toolsets/notifications.py +33 -33
- agentpool_toolsets/openapi.py +3 -1
- agentpool_toolsets/search_toolset.py +3 -1
- agentpool-2.1.9.dist-info/RECORD +0 -474
- 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/text_log_provider.py +0 -275
- agentpool_toolsets/builtin/agent_management.py +0 -239
- agentpool_toolsets/builtin/chain.py +0 -288
- agentpool_toolsets/builtin/history.py +0 -36
- agentpool_toolsets/builtin/integration.py +0 -85
- agentpool_toolsets/builtin/tool_management.py +0 -90
- agentpool_toolsets/builtin/user_interaction.py +0 -52
- agentpool_toolsets/semantic_memory_toolset.py +0 -536
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/entry_points.txt +0 -0
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -16,31 +16,27 @@ from acp.schema import (
|
|
|
16
16
|
NewSessionResponse,
|
|
17
17
|
PromptResponse,
|
|
18
18
|
ResumeSessionResponse,
|
|
19
|
+
SessionConfigOption,
|
|
20
|
+
SessionConfigSelectOption,
|
|
19
21
|
SessionInfo,
|
|
22
|
+
SessionMode,
|
|
20
23
|
SessionModelState,
|
|
21
24
|
SessionModeState,
|
|
25
|
+
SetSessionConfigOptionResponse,
|
|
22
26
|
SetSessionModelRequest,
|
|
23
27
|
SetSessionModelResponse,
|
|
24
28
|
SetSessionModeRequest,
|
|
25
29
|
SetSessionModeResponse,
|
|
26
30
|
)
|
|
27
|
-
from agentpool import Agent
|
|
28
31
|
from agentpool.log import get_logger
|
|
29
32
|
from agentpool.utils.tasks import TaskManager
|
|
30
|
-
from agentpool_server.acp_server.converters import (
|
|
31
|
-
# agent_to_mode, # TODO: Re-enable when supporting agent switching via modes
|
|
32
|
-
get_confirmation_modes,
|
|
33
|
-
mode_id_to_confirmation_mode,
|
|
34
|
-
)
|
|
35
33
|
from agentpool_server.acp_server.session_manager import ACPSessionManager
|
|
36
34
|
|
|
37
35
|
|
|
38
36
|
if TYPE_CHECKING:
|
|
39
|
-
from collections.abc import Sequence
|
|
40
|
-
|
|
41
37
|
from pydantic_ai import ModelRequest, ModelResponse
|
|
42
38
|
|
|
43
|
-
from acp import
|
|
39
|
+
from acp import Client
|
|
44
40
|
from acp.schema import (
|
|
45
41
|
AuthenticateRequest,
|
|
46
42
|
CancelNotification,
|
|
@@ -53,6 +49,7 @@ if TYPE_CHECKING:
|
|
|
53
49
|
NewSessionRequest,
|
|
54
50
|
PromptRequest,
|
|
55
51
|
ResumeSessionRequest,
|
|
52
|
+
SetSessionConfigOptionRequest,
|
|
56
53
|
SetSessionModelRequest,
|
|
57
54
|
SetSessionModeRequest,
|
|
58
55
|
)
|
|
@@ -63,62 +60,155 @@ if TYPE_CHECKING:
|
|
|
63
60
|
logger = get_logger(__name__)
|
|
64
61
|
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
),
|
|
73
|
-
ACPModelInfo(
|
|
74
|
-
model_id="sonnet",
|
|
75
|
-
name="Claude Sonnet",
|
|
76
|
-
description="Claude Sonnet - balanced performance and speed",
|
|
77
|
-
),
|
|
78
|
-
ACPModelInfo(
|
|
79
|
-
model_id="haiku",
|
|
80
|
-
name="Claude Haiku",
|
|
81
|
-
description="Claude Haiku - fast and cost-effective",
|
|
82
|
-
),
|
|
83
|
-
]
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def create_claude_code_model_state(current_model: str | None = None) -> SessionModelState:
|
|
87
|
-
"""Create SessionModelState for Claude Code agents.
|
|
63
|
+
async def get_session_model_state(
|
|
64
|
+
agent: Any, current_model: str | None = None
|
|
65
|
+
) -> SessionModelState | None:
|
|
66
|
+
"""Get SessionModelState from an agent using its get_available_models() method.
|
|
67
|
+
|
|
68
|
+
Converts tokonomics ModelInfo to ACP ModelInfo format.
|
|
88
69
|
|
|
89
70
|
Args:
|
|
90
|
-
|
|
71
|
+
agent: Any agent with get_available_models() method
|
|
72
|
+
current_model: Currently active model ID (defaults to first available)
|
|
91
73
|
|
|
92
74
|
Returns:
|
|
93
|
-
SessionModelState with
|
|
75
|
+
SessionModelState with all available models, None if no models available
|
|
94
76
|
"""
|
|
95
|
-
|
|
96
|
-
current = current_model if current_model in model_ids else "sonnet"
|
|
97
|
-
return SessionModelState(available_models=CLAUDE_CODE_MODELS, current_model_id=current)
|
|
77
|
+
from agentpool.agents.base_agent import BaseAgent
|
|
98
78
|
|
|
79
|
+
if not isinstance(agent, BaseAgent):
|
|
80
|
+
return None
|
|
99
81
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
82
|
+
try:
|
|
83
|
+
toko_models = await agent.get_available_models()
|
|
84
|
+
except Exception:
|
|
85
|
+
logger.exception("Failed to get available models from agent")
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
if not toko_models:
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
# Convert tokonomics ModelInfo to ACP ModelInfo
|
|
92
|
+
acp_models: list[ACPModelInfo] = []
|
|
93
|
+
for toko in toko_models:
|
|
94
|
+
# Use id_override if set (e.g., "opus" for Claude Code), otherwise use id
|
|
95
|
+
model_id = toko.id_override if toko.id_override else toko.id
|
|
96
|
+
info = ACPModelInfo(model_id=model_id, name=toko.name, description=toko.description or "")
|
|
97
|
+
acp_models.append(info)
|
|
98
|
+
if not acp_models:
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
# Ensure current model is in the list
|
|
102
|
+
all_ids = [model.model_id for model in acp_models]
|
|
103
|
+
if current_model and current_model not in all_ids:
|
|
104
|
+
# Add current model to the list so the UI shows it
|
|
105
|
+
desc = "Currently configured model"
|
|
106
|
+
model_info = ACPModelInfo(model_id=current_model, name=current_model, description=desc)
|
|
107
|
+
acp_models.insert(0, model_info)
|
|
108
|
+
current_model_id = current_model
|
|
109
|
+
else:
|
|
110
|
+
current_model_id = current_model if current_model in all_ids else all_ids[0]
|
|
111
|
+
|
|
112
|
+
return SessionModelState(available_models=acp_models, current_model_id=current_model_id)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
async def get_session_mode_state(agent: Any) -> SessionModeState | None:
|
|
116
|
+
"""Get SessionModeState from an agent using its get_modes() method.
|
|
117
|
+
|
|
118
|
+
Converts agentpool ModeCategory to ACP SessionModeState format.
|
|
119
|
+
Uses the first category that looks like permissions (not model).
|
|
104
120
|
|
|
105
121
|
Args:
|
|
106
|
-
|
|
107
|
-
current_model: The currently active model (defaults to first available)
|
|
122
|
+
agent: Any agent with get_modes() method
|
|
108
123
|
|
|
109
124
|
Returns:
|
|
110
|
-
|
|
125
|
+
SessionModeState from agent's modes, None if no modes available
|
|
111
126
|
"""
|
|
112
|
-
|
|
127
|
+
from agentpool.agents.base_agent import BaseAgent
|
|
128
|
+
|
|
129
|
+
if not isinstance(agent, BaseAgent):
|
|
130
|
+
return None
|
|
131
|
+
|
|
132
|
+
try:
|
|
133
|
+
mode_categories = await agent.get_modes()
|
|
134
|
+
except Exception:
|
|
135
|
+
logger.exception("Failed to get modes from agent")
|
|
136
|
+
return None
|
|
137
|
+
|
|
138
|
+
if not mode_categories:
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
# Find the permissions category (not model)
|
|
142
|
+
category = next((c for c in mode_categories if c.id != "model"), None)
|
|
143
|
+
if not category:
|
|
113
144
|
return None
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
145
|
+
|
|
146
|
+
# Convert ModeInfo to ACP SessionMode
|
|
147
|
+
acp_modes = [
|
|
148
|
+
SessionMode(
|
|
149
|
+
id=mode.id,
|
|
150
|
+
name=mode.name,
|
|
151
|
+
description=mode.description,
|
|
152
|
+
)
|
|
153
|
+
for mode in category.available_modes
|
|
154
|
+
]
|
|
155
|
+
|
|
156
|
+
return SessionModeState(
|
|
157
|
+
available_modes=acp_modes,
|
|
158
|
+
current_mode_id=category.current_mode_id,
|
|
119
159
|
)
|
|
120
160
|
|
|
121
161
|
|
|
162
|
+
async def get_session_config_options(agent: Any) -> list[SessionConfigOption]:
|
|
163
|
+
"""Get SessionConfigOptions from an agent using its get_modes() method.
|
|
164
|
+
|
|
165
|
+
Converts all agentpool ModeCategories to ACP SessionConfigOption format.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
agent: Any agent with get_modes() method
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
List of SessionConfigOption from agent's mode categories
|
|
172
|
+
"""
|
|
173
|
+
from agentpool.agents.base_agent import BaseAgent
|
|
174
|
+
|
|
175
|
+
if not isinstance(agent, BaseAgent):
|
|
176
|
+
return []
|
|
177
|
+
|
|
178
|
+
try:
|
|
179
|
+
mode_categories = await agent.get_modes()
|
|
180
|
+
except Exception:
|
|
181
|
+
logger.exception("Failed to get modes from agent")
|
|
182
|
+
return []
|
|
183
|
+
|
|
184
|
+
if not mode_categories:
|
|
185
|
+
return []
|
|
186
|
+
|
|
187
|
+
# Convert each ModeCategory to a SessionConfigOption
|
|
188
|
+
config_options: list[SessionConfigOption] = []
|
|
189
|
+
for category in mode_categories:
|
|
190
|
+
options = [
|
|
191
|
+
SessionConfigSelectOption(
|
|
192
|
+
value=mode.id,
|
|
193
|
+
name=mode.name,
|
|
194
|
+
description=mode.description,
|
|
195
|
+
)
|
|
196
|
+
for mode in category.available_modes
|
|
197
|
+
]
|
|
198
|
+
config_options.append(
|
|
199
|
+
SessionConfigOption(
|
|
200
|
+
id=category.id,
|
|
201
|
+
name=category.name,
|
|
202
|
+
description=None,
|
|
203
|
+
category=category.category,
|
|
204
|
+
current_value=category.current_mode_id,
|
|
205
|
+
options=options,
|
|
206
|
+
)
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
return config_options
|
|
210
|
+
|
|
211
|
+
|
|
122
212
|
@dataclass
|
|
123
213
|
class AgentPoolACPAgent(ACPAgent):
|
|
124
214
|
"""Implementation of ACP Agent protocol interface for AgentPool.
|
|
@@ -129,7 +219,7 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
129
219
|
|
|
130
220
|
PROTOCOL_VERSION: ClassVar = 1
|
|
131
221
|
|
|
132
|
-
|
|
222
|
+
client: Client
|
|
133
223
|
"""ACP connection for client communication."""
|
|
134
224
|
|
|
135
225
|
agent_pool: AgentPool[Any]
|
|
@@ -137,9 +227,6 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
137
227
|
|
|
138
228
|
_: KW_ONLY
|
|
139
229
|
|
|
140
|
-
available_models: Sequence[ACPModelInfo] = field(default_factory=list)
|
|
141
|
-
"""List of available ACP ModelInfo objects (converted from tokonomics at startup)."""
|
|
142
|
-
|
|
143
230
|
file_access: bool = True
|
|
144
231
|
"""Whether agent can access filesystem."""
|
|
145
232
|
|
|
@@ -160,7 +247,6 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
160
247
|
|
|
161
248
|
def __post_init__(self) -> None:
|
|
162
249
|
"""Initialize derived attributes and setup after field assignment."""
|
|
163
|
-
self.client: Client = self.connection
|
|
164
250
|
self.client_capabilities: ClientCapabilities | None = None
|
|
165
251
|
self.client_info: Implementation | None = None
|
|
166
252
|
self.session_manager = ACPSessionManager(pool=self.agent_pool)
|
|
@@ -176,17 +262,12 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
176
262
|
|
|
177
263
|
async def initialize(self, params: InitializeRequest) -> InitializeResponse:
|
|
178
264
|
"""Initialize the agent and negotiate capabilities."""
|
|
179
|
-
logger.info("Initializing ACP agent implementation")
|
|
180
265
|
version = min(params.protocol_version, self.PROTOCOL_VERSION)
|
|
181
266
|
self.client_capabilities = params.client_capabilities
|
|
182
267
|
self.client_info = params.client_info
|
|
183
|
-
logger.info(
|
|
184
|
-
"Client capabilities",
|
|
185
|
-
capabilities=self.client_capabilities,
|
|
186
|
-
client_info=self.client_info,
|
|
187
|
-
)
|
|
268
|
+
logger.info("Client info", request=params.model_dump_json())
|
|
188
269
|
self._initialized = True
|
|
189
|
-
|
|
270
|
+
return InitializeResponse.create(
|
|
190
271
|
protocol_version=version,
|
|
191
272
|
name="agentpool",
|
|
192
273
|
title="AgentPool",
|
|
@@ -199,10 +280,8 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
199
280
|
embedded_context_prompts=True,
|
|
200
281
|
image_prompts=True,
|
|
201
282
|
)
|
|
202
|
-
logger.info("ACP agent initialized successfully", response=response)
|
|
203
|
-
return response
|
|
204
283
|
|
|
205
|
-
async def new_session(self, params: NewSessionRequest) -> NewSessionResponse:
|
|
284
|
+
async def new_session(self, params: NewSessionRequest) -> NewSessionResponse:
|
|
206
285
|
"""Create a new session."""
|
|
207
286
|
if not self._initialized:
|
|
208
287
|
raise RuntimeError("Agent not initialized")
|
|
@@ -230,48 +309,26 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
230
309
|
client_info=self.client_info,
|
|
231
310
|
)
|
|
232
311
|
|
|
233
|
-
# Get mode
|
|
312
|
+
# Get mode and model information from the agent
|
|
234
313
|
from agentpool.agents.acp_agent import ACPAgent as ACPAgentClient
|
|
235
314
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if session.agent._state and session.agent._state.modes:
|
|
240
|
-
state = session.agent._state.modes
|
|
241
|
-
modes = state.available_modes
|
|
242
|
-
else:
|
|
243
|
-
# Fallback to our confirmation modes if nested agent has none
|
|
244
|
-
modes = get_confirmation_modes()
|
|
245
|
-
state = SessionModeState(current_mode_id="default", available_modes=modes)
|
|
246
|
-
else:
|
|
247
|
-
# Native Agent - use our tool confirmation modes
|
|
248
|
-
modes = get_confirmation_modes()
|
|
249
|
-
state = SessionModeState(current_mode_id="default", available_modes=modes)
|
|
250
|
-
else:
|
|
251
|
-
modes = get_confirmation_modes()
|
|
252
|
-
state = SessionModeState(current_mode_id="default", available_modes=modes)
|
|
253
|
-
# TODO: Re-enable agent switching via modes when needed:
|
|
254
|
-
# modes = [agent_to_mode(agent) for agent in self.agent_pool.all_agents.values()]
|
|
255
|
-
# state = SessionModeState(current_mode_id=default_name, available_modes=modes)
|
|
315
|
+
state: SessionModeState | None = None
|
|
316
|
+
models: SessionModelState | None = None
|
|
317
|
+
config_options: list[SessionConfigOption] = []
|
|
256
318
|
|
|
257
|
-
# Get model information from the default agent
|
|
258
319
|
if session := self.session_manager.get_session(session_id):
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
# Claude Code uses simple model IDs (sonnet, opus, haiku)
|
|
263
|
-
models = create_claude_code_model_state(session.agent.model_name)
|
|
264
|
-
elif isinstance(session.agent, ACPAgentClient):
|
|
265
|
-
# Nested ACP agent - pass through its model state directly
|
|
266
|
-
if session.agent._state and session.agent._state.models:
|
|
320
|
+
if isinstance(session.agent, ACPAgentClient):
|
|
321
|
+
# Nested ACP agent - pass through its state directly
|
|
322
|
+
if session.agent._state:
|
|
267
323
|
models = session.agent._state.models
|
|
268
|
-
|
|
269
|
-
|
|
324
|
+
state = session.agent._state.modes
|
|
325
|
+
# Also get config_options from nested agent
|
|
326
|
+
config_options = await get_session_config_options(session.agent)
|
|
270
327
|
else:
|
|
271
|
-
|
|
272
|
-
models =
|
|
273
|
-
|
|
274
|
-
|
|
328
|
+
# Use unified helpers for all other agents
|
|
329
|
+
models = await get_session_model_state(session.agent, session.agent.model_name)
|
|
330
|
+
state = await get_session_mode_state(session.agent)
|
|
331
|
+
config_options = await get_session_config_options(session.agent)
|
|
275
332
|
except Exception:
|
|
276
333
|
logger.exception("Failed to create new session")
|
|
277
334
|
raise
|
|
@@ -285,8 +342,14 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
285
342
|
if self.load_skills:
|
|
286
343
|
coro_4 = session.init_client_skills()
|
|
287
344
|
self.tasks.create_task(coro_4, name=f"init_client_skills_{session_id}")
|
|
288
|
-
logger.info("Created session", session_id=session_id
|
|
289
|
-
|
|
345
|
+
logger.info("Created session", session_id=session_id)
|
|
346
|
+
|
|
347
|
+
return NewSessionResponse(
|
|
348
|
+
session_id=session_id,
|
|
349
|
+
modes=state,
|
|
350
|
+
models=models,
|
|
351
|
+
config_options=config_options if config_options else None,
|
|
352
|
+
)
|
|
290
353
|
|
|
291
354
|
async def load_session(self, params: LoadSessionRequest) -> LoadSessionResponse:
|
|
292
355
|
"""Load an existing session from storage.
|
|
@@ -298,13 +361,14 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
298
361
|
4. Replay conversation history via ACP notifications
|
|
299
362
|
5. Return session state (modes, models)
|
|
300
363
|
"""
|
|
364
|
+
from agentpool.agents.acp_agent import ACPAgent as ACPAgentClient
|
|
365
|
+
|
|
301
366
|
if not self._initialized:
|
|
302
367
|
raise RuntimeError("Agent not initialized")
|
|
303
368
|
|
|
304
369
|
try:
|
|
305
370
|
# First check if session is already active
|
|
306
371
|
session = self.session_manager.get_session(params.session_id)
|
|
307
|
-
|
|
308
372
|
if not session:
|
|
309
373
|
# Try to resume from storage
|
|
310
374
|
msg = "Attempting to resume session from storage"
|
|
@@ -331,46 +395,30 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
331
395
|
session.mcp_servers = params.mcp_servers
|
|
332
396
|
await session.initialize_mcp_servers()
|
|
333
397
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
398
|
+
mode_state: SessionModeState | None = None
|
|
399
|
+
models: SessionModelState | None = None
|
|
400
|
+
config_opts: list[SessionConfigOption] = []
|
|
337
401
|
|
|
338
402
|
if isinstance(session.agent, ACPAgentClient):
|
|
339
|
-
#
|
|
340
|
-
if session.agent._state
|
|
403
|
+
# Nested ACP agent - pass through its state directly
|
|
404
|
+
if session.agent._state:
|
|
341
405
|
mode_state = session.agent._state.modes
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
mode_state = SessionModeState(current_mode_id="default", available_modes=modes)
|
|
350
|
-
# TODO: Re-enable agent switching via modes when needed:
|
|
351
|
-
# modes = [agent_to_mode(agent) for agent in self.agent_pool.all_agents.values()]
|
|
352
|
-
# mode_state = SessionModeState(
|
|
353
|
-
# current_mode_id=session.current_agent_name,
|
|
354
|
-
# available_modes=modes,
|
|
355
|
-
# )
|
|
356
|
-
|
|
357
|
-
# Get model information based on agent type
|
|
358
|
-
from agentpool.agents.claude_code_agent import ClaudeCodeAgent
|
|
359
|
-
|
|
360
|
-
models: SessionModelState | None
|
|
361
|
-
if session.agent and isinstance(session.agent, ClaudeCodeAgent):
|
|
362
|
-
# Claude Code uses simple model IDs (sonnet, opus, haiku)
|
|
363
|
-
models = create_claude_code_model_state(session.agent.model_name)
|
|
406
|
+
models = session.agent._state.models
|
|
407
|
+
config_opts = await get_session_config_options(session.agent)
|
|
408
|
+
elif session.agent:
|
|
409
|
+
# Use unified helpers for all other agents
|
|
410
|
+
mode_state = await get_session_mode_state(session.agent)
|
|
411
|
+
models = await get_session_model_state(session.agent, session.agent.model_name)
|
|
412
|
+
config_opts = await get_session_config_options(session.agent)
|
|
364
413
|
else:
|
|
365
|
-
|
|
366
|
-
models = create_session_model_state(self.available_models, current_model)
|
|
414
|
+
models = None
|
|
367
415
|
# Schedule post-load initialization tasks
|
|
368
416
|
self.tasks.create_task(session.send_available_commands_update())
|
|
369
417
|
self.tasks.create_task(session.init_project_context())
|
|
370
418
|
# Replay conversation history via ACP notifications
|
|
371
419
|
self.tasks.create_task(self._replay_conversation_history(session))
|
|
372
420
|
logger.info("Session loaded successfully", agent=session.current_agent_name)
|
|
373
|
-
return LoadSessionResponse(models=models, modes=mode_state)
|
|
421
|
+
return LoadSessionResponse(models=models, modes=mode_state, config_options=config_opts)
|
|
374
422
|
|
|
375
423
|
except Exception:
|
|
376
424
|
logger.exception("Failed to load session", session_id=params.session_id)
|
|
@@ -629,14 +677,8 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
629
677
|
) -> SetSessionModeResponse | None:
|
|
630
678
|
"""Set the session mode (change tool confirmation level).
|
|
631
679
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
- Agent/AGUIAgent: Updates local confirmation mode
|
|
635
|
-
- ACPAgent: Updates local mode AND forwards to remote ACP server
|
|
636
|
-
|
|
637
|
-
Mode mappings:
|
|
638
|
-
- "default": per_tool (confirm tools marked as requiring it)
|
|
639
|
-
- "acceptEdits": never (auto-approve all tool calls)
|
|
680
|
+
Calls set_mode directly on the agent with the mode_id, allowing the agent
|
|
681
|
+
to handle mode-specific logic (e.g., acceptEdits auto-allowing edit tools).
|
|
640
682
|
"""
|
|
641
683
|
from agentpool.agents.acp_agent import ACPAgent as ACPAgentClient
|
|
642
684
|
|
|
@@ -646,15 +688,8 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
646
688
|
logger.warning("Session not found for mode switch", session_id=params.session_id)
|
|
647
689
|
return None
|
|
648
690
|
|
|
649
|
-
#
|
|
650
|
-
|
|
651
|
-
if not confirmation_mode:
|
|
652
|
-
logger.error("Invalid mode_id", mode_id=params.mode_id)
|
|
653
|
-
return None
|
|
654
|
-
|
|
655
|
-
# All agent types support set_tool_confirmation_mode
|
|
656
|
-
# ACPAgent handles forwarding to remote server internally
|
|
657
|
-
await session.agent.set_tool_confirmation_mode(confirmation_mode)
|
|
691
|
+
# Call set_mode directly - agent handles mode-specific logic
|
|
692
|
+
await session.agent.set_mode(params.mode_id)
|
|
658
693
|
|
|
659
694
|
# Update stored mode state for ACPAgent
|
|
660
695
|
if (
|
|
@@ -665,9 +700,8 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
665
700
|
session.agent._state.modes.current_mode_id = params.mode_id
|
|
666
701
|
|
|
667
702
|
logger.info(
|
|
668
|
-
"Set
|
|
703
|
+
"Set mode",
|
|
669
704
|
mode_id=params.mode_id,
|
|
670
|
-
confirmation_mode=confirmation_mode,
|
|
671
705
|
session_id=params.session_id,
|
|
672
706
|
agent_type=type(session.agent).__name__,
|
|
673
707
|
)
|
|
@@ -677,19 +711,15 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
677
711
|
logger.exception("Failed to set session mode", session_id=params.session_id)
|
|
678
712
|
return None
|
|
679
713
|
|
|
680
|
-
async def set_session_model(
|
|
714
|
+
async def set_session_model(
|
|
681
715
|
self, params: SetSessionModelRequest
|
|
682
716
|
) -> SetSessionModelResponse | None:
|
|
683
717
|
"""Set the session model.
|
|
684
718
|
|
|
685
719
|
Changes the model for the active agent in the session.
|
|
686
|
-
Validates that the requested model is
|
|
687
|
-
- For ClaudeCodeAgent: validates against Claude Code models (sonnet, opus, haiku)
|
|
688
|
-
- For native Agent: validates against server's available_models
|
|
689
|
-
- For ACPAgent: validates against the nested agent's model list
|
|
720
|
+
Validates that the requested model is available via agent.get_available_models().
|
|
690
721
|
"""
|
|
691
722
|
from agentpool.agents.acp_agent import ACPAgent as ACPAgentClient
|
|
692
|
-
from agentpool.agents.claude_code_agent import ClaudeCodeAgent
|
|
693
723
|
|
|
694
724
|
try:
|
|
695
725
|
session = self.session_manager.get_session(params.session_id)
|
|
@@ -698,23 +728,8 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
698
728
|
logger.warning(msg, session_id=params.session_id)
|
|
699
729
|
return None
|
|
700
730
|
|
|
701
|
-
#
|
|
702
|
-
if isinstance(session.agent, ClaudeCodeAgent):
|
|
703
|
-
# For ClaudeCodeAgent, validate against our hardcoded models
|
|
704
|
-
available_ids = [m.model_id for m in CLAUDE_CODE_MODELS]
|
|
705
|
-
if params.model_id not in available_ids:
|
|
706
|
-
logger.warning(
|
|
707
|
-
"Model not in Claude Code available models",
|
|
708
|
-
model_id=params.model_id,
|
|
709
|
-
available=available_ids,
|
|
710
|
-
)
|
|
711
|
-
return None
|
|
712
|
-
await session.agent.set_model(params.model_id)
|
|
713
|
-
logger.info("Set model", model_id=params.model_id, session_id=params.session_id)
|
|
714
|
-
return SetSessionModelResponse()
|
|
715
|
-
|
|
731
|
+
# Handle ACPAgent specially - pass through to nested agent's model state
|
|
716
732
|
if isinstance(session.agent, ACPAgentClient):
|
|
717
|
-
# For ACPAgent, validate against nested agent's model list
|
|
718
733
|
if session.agent._state and session.agent._state.models:
|
|
719
734
|
available_ids = [
|
|
720
735
|
m.model_id for m in session.agent._state.models.available_models
|
|
@@ -727,28 +742,66 @@ class AgentPoolACPAgent(ACPAgent):
|
|
|
727
742
|
)
|
|
728
743
|
return None
|
|
729
744
|
# TODO: Use ACP protocol once set_session_model stabilizes
|
|
730
|
-
# For now, we can't actually change the model on ACPAgent
|
|
731
745
|
logger.warning(
|
|
732
746
|
"Model change for ACPAgent not yet supported (ACP protocol UNSTABLE)",
|
|
733
747
|
model_id=params.model_id,
|
|
734
748
|
)
|
|
735
749
|
return None
|
|
736
750
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
751
|
+
# Get available models from agent and validate
|
|
752
|
+
toko_models = await session.agent.get_available_models()
|
|
753
|
+
if toko_models:
|
|
754
|
+
# Build list of valid model IDs (using id_override if set)
|
|
755
|
+
available_ids = [m.id_override if m.id_override else m.id for m in toko_models]
|
|
740
756
|
if params.model_id not in available_ids:
|
|
741
|
-
|
|
742
|
-
|
|
757
|
+
logger.warning(
|
|
758
|
+
"Model not in available models",
|
|
759
|
+
model_id=params.model_id,
|
|
760
|
+
available=available_ids,
|
|
761
|
+
)
|
|
743
762
|
return None
|
|
744
|
-
session.agent.set_model(params.model_id)
|
|
745
763
|
|
|
764
|
+
# Set the model on the agent (all agents now have async set_model)
|
|
765
|
+
await session.agent.set_model(params.model_id)
|
|
746
766
|
logger.info("Set model", model_id=params.model_id, session_id=params.session_id)
|
|
747
767
|
return SetSessionModelResponse()
|
|
748
768
|
except Exception:
|
|
749
769
|
logger.exception("Failed to set session model", session_id=params.session_id)
|
|
750
770
|
return None
|
|
751
771
|
|
|
772
|
+
async def set_session_config_option(
|
|
773
|
+
self, params: SetSessionConfigOptionRequest
|
|
774
|
+
) -> SetSessionConfigOptionResponse | None:
|
|
775
|
+
"""Set a session config option.
|
|
776
|
+
|
|
777
|
+
Forwards the config option change to the agent's set_mode method
|
|
778
|
+
and returns the updated config options.
|
|
779
|
+
"""
|
|
780
|
+
try:
|
|
781
|
+
session = self.session_manager.get_session(params.session_id)
|
|
782
|
+
if not session or not session.agent:
|
|
783
|
+
msg = "Session not found for config option change"
|
|
784
|
+
logger.warning(msg, session_id=params.session_id)
|
|
785
|
+
return None
|
|
786
|
+
|
|
787
|
+
logger.info(
|
|
788
|
+
"Set config option",
|
|
789
|
+
config_id=params.config_id,
|
|
790
|
+
value=params.value,
|
|
791
|
+
session_id=params.session_id,
|
|
792
|
+
)
|
|
793
|
+
|
|
794
|
+
# Forward to agent's set_mode method
|
|
795
|
+
# config_id maps to category_id, value maps to mode_id
|
|
796
|
+
await session.agent.set_mode(params.value, category_id=params.config_id)
|
|
797
|
+
|
|
798
|
+
# Return updated config options
|
|
799
|
+
config_options = await get_session_config_options(session.agent)
|
|
800
|
+
return SetSessionConfigOptionResponse(config_options=config_options)
|
|
801
|
+
except Exception:
|
|
802
|
+
logger.exception("Failed to set session config option", session_id=params.session_id)
|
|
803
|
+
return None
|
|
804
|
+
|
|
752
805
|
async def swap_pool(self, config_path: str, agent: str | None = None) -> list[str]:
|
|
753
806
|
"""Swap the agent pool with a new one from configuration.
|
|
754
807
|
|