agent-client-protocol 0.8.0__tar.gz → 0.9.0__tar.gz
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.
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/PKG-INFO +1 -1
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/client.py +2 -4
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/echo_agent.py +6 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/gemini.py +5 -7
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/pyproject.toml +1 -1
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/__init__.py +8 -4
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/agent/connection.py +6 -8
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/agent/router.py +49 -3
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/client/connection.py +49 -2
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/client/router.py +2 -2
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/interfaces.py +19 -7
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/meta.py +2 -1
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/router.py +31 -21
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/schema.py +365 -39
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/utils.py +99 -5
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/conftest.py +25 -3
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/initialize_response.json +2 -1
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_compatibility.py +43 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_golden.py +2 -2
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_rpc.py +44 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_unstable.py +9 -2
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_utils.py +40 -1
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/LICENSE +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/README.md +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/agent.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/duet.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/agent/__init__.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/client/__init__.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/connection.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/contrib/__init__.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/contrib/permissions.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/contrib/session_state.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/contrib/tool_calls.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/core.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/exceptions.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/helpers.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/py.typed +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/stdio.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/__init__.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/dispatcher.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/queue.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/sender.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/state.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/supervisor.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/telemetry.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/transports.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/contrib/test_contrib_permissions.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/contrib/test_contrib_session_state.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/contrib/test_contrib_tool_calls.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/cancel_notification.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_audio.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_image.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_resource_blob.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_resource_link.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_resource_text.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_text.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/fs_read_text_file_request.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/fs_read_text_file_response.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/fs_write_text_file_request.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/initialize_request.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/new_session_request.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/new_session_response.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/permission_outcome_cancelled.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/permission_outcome_selected.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/prompt_request.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/request_permission_request.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/request_permission_response_selected.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_agent_message_chunk.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_agent_thought_chunk.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_config_option_update.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_plan.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_edit.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_locations_rawinput.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_read.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_update_content.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_update_more_fields.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_user_message_chunk.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/set_session_config_option_request.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/set_session_config_option_response.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/tool_content_content_text.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/tool_content_diff.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/tool_content_diff_no_old.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/tool_content_terminal.json +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/__init__.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/test_cancel_prompt_flow.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/test_mcp_servers_optional.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/test_permission_flow.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/test_stdio_limits.py +0 -0
- {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_gemini_example.py +0 -0
|
@@ -28,7 +28,7 @@ from acp.schema import (
|
|
|
28
28
|
EnvVariable,
|
|
29
29
|
ImageContentBlock,
|
|
30
30
|
Implementation,
|
|
31
|
-
|
|
31
|
+
KillTerminalResponse,
|
|
32
32
|
PermissionOption,
|
|
33
33
|
ReadTextFileResponse,
|
|
34
34
|
ReleaseTerminalResponse,
|
|
@@ -86,9 +86,7 @@ class ExampleClient(Client):
|
|
|
86
86
|
) -> WaitForTerminalExitResponse:
|
|
87
87
|
raise RequestError.method_not_found("terminal/wait_for_exit")
|
|
88
88
|
|
|
89
|
-
async def kill_terminal(
|
|
90
|
-
self, session_id: str, terminal_id: str, **kwargs: Any
|
|
91
|
-
) -> KillTerminalCommandResponse | None:
|
|
89
|
+
async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None:
|
|
92
90
|
raise RequestError.method_not_found("terminal/kill")
|
|
93
91
|
|
|
94
92
|
async def session_update(
|
|
@@ -33,8 +33,8 @@ from acp.schema import (
|
|
|
33
33
|
EmbeddedResourceContentBlock,
|
|
34
34
|
EnvVariable,
|
|
35
35
|
FileEditToolCallContent,
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
FileSystemCapabilities,
|
|
37
|
+
KillTerminalResponse,
|
|
38
38
|
PermissionOption,
|
|
39
39
|
ReadTextFileResponse,
|
|
40
40
|
ReleaseTerminalResponse,
|
|
@@ -183,11 +183,9 @@ class GeminiClient(Client):
|
|
|
183
183
|
print(f"[Client] waitForTerminalExit: {session_id} {terminal_id}")
|
|
184
184
|
return WaitForTerminalExitResponse()
|
|
185
185
|
|
|
186
|
-
async def kill_terminal(
|
|
187
|
-
self, session_id: str, terminal_id: str, **kwargs: Any
|
|
188
|
-
) -> KillTerminalCommandResponse | None:
|
|
186
|
+
async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None:
|
|
189
187
|
print(f"[Client] killTerminal: {session_id} {terminal_id}")
|
|
190
|
-
return
|
|
188
|
+
return KillTerminalResponse()
|
|
191
189
|
|
|
192
190
|
|
|
193
191
|
def _pick_preferred_option(options: Iterable[PermissionOption]) -> PermissionOption | None:
|
|
@@ -320,7 +318,7 @@ async def run(argv: list[str]) -> int: # noqa: C901
|
|
|
320
318
|
init_resp = await conn.initialize(
|
|
321
319
|
protocol_version=PROTOCOL_VERSION,
|
|
322
320
|
client_capabilities=ClientCapabilities(
|
|
323
|
-
fs=
|
|
321
|
+
fs=FileSystemCapabilities(read_text_file=True, write_text_file=True),
|
|
324
322
|
terminal=True,
|
|
325
323
|
),
|
|
326
324
|
)
|
|
@@ -45,8 +45,8 @@ from .schema import (
|
|
|
45
45
|
CreateTerminalResponse,
|
|
46
46
|
InitializeRequest,
|
|
47
47
|
InitializeResponse,
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
KillTerminalRequest,
|
|
49
|
+
KillTerminalResponse,
|
|
50
50
|
LoadSessionRequest,
|
|
51
51
|
LoadSessionResponse,
|
|
52
52
|
NewSessionRequest,
|
|
@@ -60,6 +60,8 @@ from .schema import (
|
|
|
60
60
|
RequestPermissionRequest,
|
|
61
61
|
RequestPermissionResponse,
|
|
62
62
|
SessionNotification,
|
|
63
|
+
SetSessionConfigOptionResponse,
|
|
64
|
+
SetSessionConfigOptionSelectRequest,
|
|
63
65
|
SetSessionModelRequest,
|
|
64
66
|
SetSessionModelResponse,
|
|
65
67
|
SetSessionModeRequest,
|
|
@@ -115,6 +117,8 @@ __all__ = [ # noqa: RUF022
|
|
|
115
117
|
"SetSessionModeResponse",
|
|
116
118
|
"SetSessionModelRequest",
|
|
117
119
|
"SetSessionModelResponse",
|
|
120
|
+
"SetSessionConfigOptionSelectRequest",
|
|
121
|
+
"SetSessionConfigOptionResponse",
|
|
118
122
|
# terminal types
|
|
119
123
|
"CreateTerminalRequest",
|
|
120
124
|
"CreateTerminalResponse",
|
|
@@ -122,8 +126,8 @@ __all__ = [ # noqa: RUF022
|
|
|
122
126
|
"TerminalOutputResponse",
|
|
123
127
|
"WaitForTerminalExitRequest",
|
|
124
128
|
"WaitForTerminalExitResponse",
|
|
125
|
-
"
|
|
126
|
-
"
|
|
129
|
+
"KillTerminalRequest",
|
|
130
|
+
"KillTerminalResponse",
|
|
127
131
|
"ReleaseTerminalRequest",
|
|
128
132
|
"ReleaseTerminalResponse",
|
|
129
133
|
# core
|
|
@@ -17,8 +17,8 @@ from ..schema import (
|
|
|
17
17
|
CreateTerminalResponse,
|
|
18
18
|
CurrentModeUpdate,
|
|
19
19
|
EnvVariable,
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
KillTerminalRequest,
|
|
21
|
+
KillTerminalResponse,
|
|
22
22
|
PermissionOption,
|
|
23
23
|
ReadTextFileRequest,
|
|
24
24
|
ReadTextFileResponse,
|
|
@@ -191,15 +191,13 @@ class AgentSideConnection:
|
|
|
191
191
|
WaitForTerminalExitResponse,
|
|
192
192
|
)
|
|
193
193
|
|
|
194
|
-
@param_model(
|
|
195
|
-
async def kill_terminal(
|
|
196
|
-
self, session_id: str, terminal_id: str, **kwargs: Any
|
|
197
|
-
) -> KillTerminalCommandResponse | None:
|
|
194
|
+
@param_model(KillTerminalRequest)
|
|
195
|
+
async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None:
|
|
198
196
|
return await request_optional_model(
|
|
199
197
|
self._conn,
|
|
200
198
|
CLIENT_METHODS["terminal_kill"],
|
|
201
|
-
|
|
202
|
-
|
|
199
|
+
KillTerminalRequest(session_id=session_id, terminal_id=terminal_id, field_meta=kwargs or None),
|
|
200
|
+
KillTerminalResponse,
|
|
203
201
|
)
|
|
204
202
|
|
|
205
203
|
async def ext_method(self, method: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
@@ -2,13 +2,16 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
5
7
|
from ..exceptions import RequestError
|
|
6
8
|
from ..interfaces import Agent
|
|
7
9
|
from ..meta import AGENT_METHODS
|
|
8
|
-
from ..router import MessageRouter
|
|
10
|
+
from ..router import MessageRouter, Route, _resolve_handler, _warn_legacy_handler
|
|
9
11
|
from ..schema import (
|
|
10
12
|
AuthenticateRequest,
|
|
11
13
|
CancelNotification,
|
|
14
|
+
CloseSessionRequest,
|
|
12
15
|
ForkSessionRequest,
|
|
13
16
|
InitializeRequest,
|
|
14
17
|
ListSessionsRequest,
|
|
@@ -16,14 +19,41 @@ from ..schema import (
|
|
|
16
19
|
NewSessionRequest,
|
|
17
20
|
PromptRequest,
|
|
18
21
|
ResumeSessionRequest,
|
|
22
|
+
SetSessionConfigOptionBooleanRequest,
|
|
23
|
+
SetSessionConfigOptionSelectRequest,
|
|
19
24
|
SetSessionModelRequest,
|
|
20
25
|
SetSessionModeRequest,
|
|
21
26
|
)
|
|
22
|
-
from ..utils import normalize_result
|
|
27
|
+
from ..utils import model_to_kwargs, normalize_result
|
|
23
28
|
|
|
24
29
|
__all__ = ["build_agent_router"]
|
|
25
30
|
|
|
26
31
|
|
|
32
|
+
_SET_CONFIG_OPTION_MODELS = (SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _validate_set_config_option_request(params: Any) -> BaseModel:
|
|
36
|
+
if isinstance(params, dict) and params.get("type") == "boolean":
|
|
37
|
+
return SetSessionConfigOptionBooleanRequest.model_validate(params)
|
|
38
|
+
return SetSessionConfigOptionSelectRequest.model_validate(params)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _make_set_config_option_handler(agent: Agent) -> Any:
|
|
42
|
+
func, attr, legacy_api = _resolve_handler(agent, "set_config_option")
|
|
43
|
+
if func is None:
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
async def wrapper(params: Any) -> Any:
|
|
47
|
+
if legacy_api:
|
|
48
|
+
_warn_legacy_handler(agent, attr)
|
|
49
|
+
request = _validate_set_config_option_request(params)
|
|
50
|
+
if legacy_api:
|
|
51
|
+
return await func(request)
|
|
52
|
+
return await func(**model_to_kwargs(request, _SET_CONFIG_OPTION_MODELS))
|
|
53
|
+
|
|
54
|
+
return wrapper
|
|
55
|
+
|
|
56
|
+
|
|
27
57
|
def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> MessageRouter:
|
|
28
58
|
router = MessageRouter(use_unstable_protocol=use_unstable_protocol)
|
|
29
59
|
|
|
@@ -36,7 +66,15 @@ def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> Mes
|
|
|
36
66
|
"load_session",
|
|
37
67
|
adapt_result=normalize_result,
|
|
38
68
|
)
|
|
39
|
-
router.route_request(AGENT_METHODS["session_list"], ListSessionsRequest, agent, "list_sessions"
|
|
69
|
+
router.route_request(AGENT_METHODS["session_list"], ListSessionsRequest, agent, "list_sessions")
|
|
70
|
+
router.route_request(
|
|
71
|
+
AGENT_METHODS["session_close"],
|
|
72
|
+
CloseSessionRequest,
|
|
73
|
+
agent,
|
|
74
|
+
"close_session",
|
|
75
|
+
adapt_result=normalize_result,
|
|
76
|
+
unstable=True,
|
|
77
|
+
)
|
|
40
78
|
router.route_request(
|
|
41
79
|
AGENT_METHODS["session_set_mode"],
|
|
42
80
|
SetSessionModeRequest,
|
|
@@ -53,6 +91,14 @@ def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> Mes
|
|
|
53
91
|
adapt_result=normalize_result,
|
|
54
92
|
unstable=True,
|
|
55
93
|
)
|
|
94
|
+
router.add_route(
|
|
95
|
+
Route(
|
|
96
|
+
method=AGENT_METHODS["session_set_config_option"],
|
|
97
|
+
func=_make_set_config_option_handler(agent),
|
|
98
|
+
kind="request",
|
|
99
|
+
adapt_result=normalize_result,
|
|
100
|
+
)
|
|
101
|
+
)
|
|
56
102
|
router.route_request(
|
|
57
103
|
AGENT_METHODS["authenticate"],
|
|
58
104
|
AuthenticateRequest,
|
|
@@ -13,6 +13,8 @@ from ..schema import (
|
|
|
13
13
|
AuthenticateResponse,
|
|
14
14
|
CancelNotification,
|
|
15
15
|
ClientCapabilities,
|
|
16
|
+
CloseSessionRequest,
|
|
17
|
+
CloseSessionResponse,
|
|
16
18
|
EmbeddedResourceContentBlock,
|
|
17
19
|
ForkSessionRequest,
|
|
18
20
|
ForkSessionResponse,
|
|
@@ -33,6 +35,9 @@ from ..schema import (
|
|
|
33
35
|
ResourceContentBlock,
|
|
34
36
|
ResumeSessionRequest,
|
|
35
37
|
ResumeSessionResponse,
|
|
38
|
+
SetSessionConfigOptionBooleanRequest,
|
|
39
|
+
SetSessionConfigOptionResponse,
|
|
40
|
+
SetSessionConfigOptionSelectRequest,
|
|
36
41
|
SetSessionModelRequest,
|
|
37
42
|
SetSessionModelResponse,
|
|
38
43
|
SetSessionModeRequest,
|
|
@@ -40,7 +45,7 @@ from ..schema import (
|
|
|
40
45
|
SseMcpServer,
|
|
41
46
|
TextContentBlock,
|
|
42
47
|
)
|
|
43
|
-
from ..utils import compatible_class, notify_model, param_model, request_model, request_model_from_dict
|
|
48
|
+
from ..utils import compatible_class, notify_model, param_model, param_models, request_model, request_model_from_dict
|
|
44
49
|
from .router import build_client_router
|
|
45
50
|
|
|
46
51
|
__all__ = ["ClientSideConnection"]
|
|
@@ -150,6 +155,33 @@ class ClientSideConnection:
|
|
|
150
155
|
SetSessionModelResponse,
|
|
151
156
|
)
|
|
152
157
|
|
|
158
|
+
@param_models(SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest)
|
|
159
|
+
async def set_config_option(
|
|
160
|
+
self, config_id: str, session_id: str, value: str | bool, **kwargs: Any
|
|
161
|
+
) -> SetSessionConfigOptionResponse:
|
|
162
|
+
request = (
|
|
163
|
+
SetSessionConfigOptionBooleanRequest(
|
|
164
|
+
config_id=config_id,
|
|
165
|
+
session_id=session_id,
|
|
166
|
+
type="boolean",
|
|
167
|
+
value=value,
|
|
168
|
+
field_meta=kwargs or None,
|
|
169
|
+
)
|
|
170
|
+
if isinstance(value, bool)
|
|
171
|
+
else SetSessionConfigOptionSelectRequest(
|
|
172
|
+
config_id=config_id,
|
|
173
|
+
session_id=session_id,
|
|
174
|
+
value=value,
|
|
175
|
+
field_meta=kwargs or None,
|
|
176
|
+
)
|
|
177
|
+
)
|
|
178
|
+
return await request_model_from_dict(
|
|
179
|
+
self._conn,
|
|
180
|
+
AGENT_METHODS["session_set_config_option"],
|
|
181
|
+
request,
|
|
182
|
+
SetSessionConfigOptionResponse,
|
|
183
|
+
)
|
|
184
|
+
|
|
153
185
|
@param_model(AuthenticateRequest)
|
|
154
186
|
async def authenticate(self, method_id: str, **kwargs: Any) -> AuthenticateResponse:
|
|
155
187
|
return await request_model_from_dict(
|
|
@@ -170,12 +202,18 @@ class ClientSideConnection:
|
|
|
170
202
|
| EmbeddedResourceContentBlock
|
|
171
203
|
],
|
|
172
204
|
session_id: str,
|
|
205
|
+
message_id: str | None = None,
|
|
173
206
|
**kwargs: Any,
|
|
174
207
|
) -> PromptResponse:
|
|
175
208
|
return await request_model(
|
|
176
209
|
self._conn,
|
|
177
210
|
AGENT_METHODS["session_prompt"],
|
|
178
|
-
PromptRequest(
|
|
211
|
+
PromptRequest(
|
|
212
|
+
prompt=prompt,
|
|
213
|
+
session_id=session_id,
|
|
214
|
+
message_id=message_id,
|
|
215
|
+
field_meta=kwargs or None,
|
|
216
|
+
),
|
|
179
217
|
PromptResponse,
|
|
180
218
|
)
|
|
181
219
|
|
|
@@ -209,6 +247,15 @@ class ClientSideConnection:
|
|
|
209
247
|
ResumeSessionResponse,
|
|
210
248
|
)
|
|
211
249
|
|
|
250
|
+
@param_model(CloseSessionRequest)
|
|
251
|
+
async def close_session(self, session_id: str, **kwargs: Any) -> CloseSessionResponse | None:
|
|
252
|
+
return await request_model_from_dict(
|
|
253
|
+
self._conn,
|
|
254
|
+
AGENT_METHODS["session_close"],
|
|
255
|
+
CloseSessionRequest(session_id=session_id, field_meta=kwargs or None),
|
|
256
|
+
CloseSessionResponse,
|
|
257
|
+
)
|
|
258
|
+
|
|
212
259
|
@param_model(CancelNotification)
|
|
213
260
|
async def cancel(self, session_id: str, **kwargs: Any) -> None:
|
|
214
261
|
await notify_model(
|
|
@@ -8,7 +8,7 @@ from ..meta import CLIENT_METHODS
|
|
|
8
8
|
from ..router import MessageRouter
|
|
9
9
|
from ..schema import (
|
|
10
10
|
CreateTerminalRequest,
|
|
11
|
-
|
|
11
|
+
KillTerminalRequest,
|
|
12
12
|
ReadTextFileRequest,
|
|
13
13
|
ReleaseTerminalRequest,
|
|
14
14
|
RequestPermissionRequest,
|
|
@@ -68,7 +68,7 @@ def build_client_router(client: Client, use_unstable_protocol: bool = False) ->
|
|
|
68
68
|
)
|
|
69
69
|
router.route_request(
|
|
70
70
|
CLIENT_METHODS["terminal_kill"],
|
|
71
|
-
|
|
71
|
+
KillTerminalRequest,
|
|
72
72
|
client,
|
|
73
73
|
"kill_terminal",
|
|
74
74
|
optional=True,
|
|
@@ -12,6 +12,8 @@ from .schema import (
|
|
|
12
12
|
AvailableCommandsUpdate,
|
|
13
13
|
CancelNotification,
|
|
14
14
|
ClientCapabilities,
|
|
15
|
+
CloseSessionRequest,
|
|
16
|
+
CloseSessionResponse,
|
|
15
17
|
ConfigOptionUpdate,
|
|
16
18
|
CreateTerminalRequest,
|
|
17
19
|
CreateTerminalResponse,
|
|
@@ -25,8 +27,8 @@ from .schema import (
|
|
|
25
27
|
Implementation,
|
|
26
28
|
InitializeRequest,
|
|
27
29
|
InitializeResponse,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
KillTerminalRequest,
|
|
31
|
+
KillTerminalResponse,
|
|
30
32
|
ListSessionsRequest,
|
|
31
33
|
ListSessionsResponse,
|
|
32
34
|
LoadSessionRequest,
|
|
@@ -48,6 +50,9 @@ from .schema import (
|
|
|
48
50
|
ResumeSessionResponse,
|
|
49
51
|
SessionInfoUpdate,
|
|
50
52
|
SessionNotification,
|
|
53
|
+
SetSessionConfigOptionBooleanRequest,
|
|
54
|
+
SetSessionConfigOptionResponse,
|
|
55
|
+
SetSessionConfigOptionSelectRequest,
|
|
51
56
|
SetSessionModelRequest,
|
|
52
57
|
SetSessionModelResponse,
|
|
53
58
|
SetSessionModeRequest,
|
|
@@ -66,7 +71,7 @@ from .schema import (
|
|
|
66
71
|
WriteTextFileRequest,
|
|
67
72
|
WriteTextFileResponse,
|
|
68
73
|
)
|
|
69
|
-
from .utils import param_model
|
|
74
|
+
from .utils import param_model, param_models
|
|
70
75
|
|
|
71
76
|
__all__ = ["Agent", "Client"]
|
|
72
77
|
|
|
@@ -130,10 +135,8 @@ class Client(Protocol):
|
|
|
130
135
|
self, session_id: str, terminal_id: str, **kwargs: Any
|
|
131
136
|
) -> WaitForTerminalExitResponse: ...
|
|
132
137
|
|
|
133
|
-
@param_model(
|
|
134
|
-
async def kill_terminal(
|
|
135
|
-
self, session_id: str, terminal_id: str, **kwargs: Any
|
|
136
|
-
) -> KillTerminalCommandResponse | None: ...
|
|
138
|
+
@param_model(KillTerminalRequest)
|
|
139
|
+
async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None: ...
|
|
137
140
|
|
|
138
141
|
async def ext_method(self, method: str, params: dict[str, Any]) -> dict[str, Any]: ...
|
|
139
142
|
|
|
@@ -179,6 +182,11 @@ class Agent(Protocol):
|
|
|
179
182
|
self, model_id: str, session_id: str, **kwargs: Any
|
|
180
183
|
) -> SetSessionModelResponse | None: ...
|
|
181
184
|
|
|
185
|
+
@param_models(SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest)
|
|
186
|
+
async def set_config_option(
|
|
187
|
+
self, config_id: str, session_id: str, value: str | bool, **kwargs: Any
|
|
188
|
+
) -> SetSessionConfigOptionResponse | None: ...
|
|
189
|
+
|
|
182
190
|
@param_model(AuthenticateRequest)
|
|
183
191
|
async def authenticate(self, method_id: str, **kwargs: Any) -> AuthenticateResponse | None: ...
|
|
184
192
|
|
|
@@ -193,6 +201,7 @@ class Agent(Protocol):
|
|
|
193
201
|
| EmbeddedResourceContentBlock
|
|
194
202
|
],
|
|
195
203
|
session_id: str,
|
|
204
|
+
message_id: str | None = None,
|
|
196
205
|
**kwargs: Any,
|
|
197
206
|
) -> PromptResponse: ...
|
|
198
207
|
|
|
@@ -214,6 +223,9 @@ class Agent(Protocol):
|
|
|
214
223
|
**kwargs: Any,
|
|
215
224
|
) -> ResumeSessionResponse: ...
|
|
216
225
|
|
|
226
|
+
@param_model(CloseSessionRequest)
|
|
227
|
+
async def close_session(self, session_id: str, **kwargs: Any) -> CloseSessionResponse | None: ...
|
|
228
|
+
|
|
217
229
|
@param_model(CancelNotification)
|
|
218
230
|
async def cancel(self, session_id: str, **kwargs: Any) -> None: ...
|
|
219
231
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Generated from schema/meta.json. Do not edit by hand.
|
|
2
|
-
# Schema ref: refs/tags/v0.
|
|
2
|
+
# Schema ref: refs/tags/v0.11.2
|
|
3
3
|
AGENT_METHODS = {
|
|
4
4
|
"authenticate": "authenticate",
|
|
5
5
|
"initialize": "initialize",
|
|
6
6
|
"session_cancel": "session/cancel",
|
|
7
|
+
"session_close": "session/close",
|
|
7
8
|
"session_fork": "session/fork",
|
|
8
9
|
"session_list": "session/list",
|
|
9
10
|
"session_load": "session/load",
|
|
@@ -20,6 +20,34 @@ RequestHandler = Callable[[str, dict[str, Any]], Awaitable[Any]]
|
|
|
20
20
|
HandlerT = TypeVar("HandlerT", bound=RequestHandler)
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
def _warn_legacy_handler(obj: Any, attr: str) -> None:
|
|
24
|
+
warnings.warn(
|
|
25
|
+
f"The old style method {type(obj).__name__}.{attr} is deprecated, please update to the snake-cased form.",
|
|
26
|
+
DeprecationWarning,
|
|
27
|
+
stacklevel=3,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _resolve_handler(obj: Any, attr: str) -> tuple[AsyncHandler | None, str, bool]:
|
|
32
|
+
legacy_api = False
|
|
33
|
+
func = getattr(obj, attr, None)
|
|
34
|
+
if func is None and "_" in attr:
|
|
35
|
+
attr = to_camel_case(attr)
|
|
36
|
+
func = getattr(obj, attr, None)
|
|
37
|
+
legacy_api = True
|
|
38
|
+
elif callable(func) and "_" not in attr:
|
|
39
|
+
original_func = func
|
|
40
|
+
if hasattr(func, "__func__"):
|
|
41
|
+
original_func = func.__func__
|
|
42
|
+
parameters = inspect.signature(original_func).parameters
|
|
43
|
+
if len(parameters) == 2 and "params" in parameters:
|
|
44
|
+
legacy_api = True
|
|
45
|
+
|
|
46
|
+
if func is None or not callable(func):
|
|
47
|
+
return None, attr, legacy_api
|
|
48
|
+
return func, attr, legacy_api
|
|
49
|
+
|
|
50
|
+
|
|
23
51
|
@dataclass(slots=True)
|
|
24
52
|
class Route:
|
|
25
53
|
method: str
|
|
@@ -63,31 +91,13 @@ class MessageRouter:
|
|
|
63
91
|
self._notifications[route.method] = route
|
|
64
92
|
|
|
65
93
|
def _make_func(self, model: type[BaseModel], obj: Any, attr: str) -> AsyncHandler | None:
|
|
66
|
-
legacy_api =
|
|
67
|
-
func
|
|
68
|
-
if func is None and "_" in attr:
|
|
69
|
-
attr = to_camel_case(attr)
|
|
70
|
-
func = getattr(obj, attr, None)
|
|
71
|
-
legacy_api = True
|
|
72
|
-
elif callable(func) and "_" not in attr:
|
|
73
|
-
original_func = func
|
|
74
|
-
if hasattr(func, "__func__"):
|
|
75
|
-
original_func = func.__func__
|
|
76
|
-
parameters = inspect.signature(original_func).parameters
|
|
77
|
-
if len(parameters) == 2 and "params" in parameters:
|
|
78
|
-
legacy_api = True
|
|
79
|
-
|
|
80
|
-
if func is None or not callable(func):
|
|
94
|
+
func, attr, legacy_api = _resolve_handler(obj, attr)
|
|
95
|
+
if func is None:
|
|
81
96
|
return None
|
|
82
97
|
|
|
83
98
|
async def wrapper(params: Any) -> Any:
|
|
84
99
|
if legacy_api:
|
|
85
|
-
|
|
86
|
-
f"The old style method {type(obj).__name__}.{attr} is deprecated, "
|
|
87
|
-
"please update to the snake-cased form.",
|
|
88
|
-
DeprecationWarning,
|
|
89
|
-
stacklevel=3,
|
|
90
|
-
)
|
|
100
|
+
_warn_legacy_handler(obj, attr)
|
|
91
101
|
model_obj = model.model_validate(params)
|
|
92
102
|
if legacy_api:
|
|
93
103
|
return await func(model_obj) # type: ignore[arg-type]
|