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.
Files changed (90) hide show
  1. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/PKG-INFO +1 -1
  2. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/client.py +2 -4
  3. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/echo_agent.py +6 -0
  4. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/gemini.py +5 -7
  5. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/pyproject.toml +1 -1
  6. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/__init__.py +8 -4
  7. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/agent/connection.py +6 -8
  8. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/agent/router.py +49 -3
  9. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/client/connection.py +49 -2
  10. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/client/router.py +2 -2
  11. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/interfaces.py +19 -7
  12. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/meta.py +2 -1
  13. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/router.py +31 -21
  14. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/schema.py +365 -39
  15. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/utils.py +99 -5
  16. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/conftest.py +25 -3
  17. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/initialize_response.json +2 -1
  18. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_compatibility.py +43 -0
  19. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_golden.py +2 -2
  20. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_rpc.py +44 -0
  21. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_unstable.py +9 -2
  22. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_utils.py +40 -1
  23. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/LICENSE +0 -0
  24. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/README.md +0 -0
  25. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/agent.py +0 -0
  26. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/examples/duet.py +0 -0
  27. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/agent/__init__.py +0 -0
  28. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/client/__init__.py +0 -0
  29. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/connection.py +0 -0
  30. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/contrib/__init__.py +0 -0
  31. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/contrib/permissions.py +0 -0
  32. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/contrib/session_state.py +0 -0
  33. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/contrib/tool_calls.py +0 -0
  34. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/core.py +0 -0
  35. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/exceptions.py +0 -0
  36. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/helpers.py +0 -0
  37. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/py.typed +0 -0
  38. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/stdio.py +0 -0
  39. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/__init__.py +0 -0
  40. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/dispatcher.py +0 -0
  41. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/queue.py +0 -0
  42. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/sender.py +0 -0
  43. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/state.py +0 -0
  44. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/task/supervisor.py +0 -0
  45. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/telemetry.py +0 -0
  46. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/src/acp/transports.py +0 -0
  47. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/contrib/test_contrib_permissions.py +0 -0
  48. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/contrib/test_contrib_session_state.py +0 -0
  49. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/contrib/test_contrib_tool_calls.py +0 -0
  50. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/cancel_notification.json +0 -0
  51. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_audio.json +0 -0
  52. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_image.json +0 -0
  53. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_resource_blob.json +0 -0
  54. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_resource_link.json +0 -0
  55. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_resource_text.json +0 -0
  56. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/content_text.json +0 -0
  57. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/fs_read_text_file_request.json +0 -0
  58. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/fs_read_text_file_response.json +0 -0
  59. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/fs_write_text_file_request.json +0 -0
  60. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/initialize_request.json +0 -0
  61. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/new_session_request.json +0 -0
  62. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/new_session_response.json +0 -0
  63. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/permission_outcome_cancelled.json +0 -0
  64. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/permission_outcome_selected.json +0 -0
  65. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/prompt_request.json +0 -0
  66. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/request_permission_request.json +0 -0
  67. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/request_permission_response_selected.json +0 -0
  68. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_agent_message_chunk.json +0 -0
  69. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_agent_thought_chunk.json +0 -0
  70. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_config_option_update.json +0 -0
  71. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_plan.json +0 -0
  72. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call.json +0 -0
  73. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_edit.json +0 -0
  74. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_locations_rawinput.json +0 -0
  75. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_read.json +0 -0
  76. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_update_content.json +0 -0
  77. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_tool_call_update_more_fields.json +0 -0
  78. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/session_update_user_message_chunk.json +0 -0
  79. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/set_session_config_option_request.json +0 -0
  80. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/set_session_config_option_response.json +0 -0
  81. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/tool_content_content_text.json +0 -0
  82. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/tool_content_diff.json +0 -0
  83. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/tool_content_diff_no_old.json +0 -0
  84. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/golden/tool_content_terminal.json +0 -0
  85. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/__init__.py +0 -0
  86. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/test_cancel_prompt_flow.py +0 -0
  87. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/test_mcp_servers_optional.py +0 -0
  88. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/test_permission_flow.py +0 -0
  89. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/real_user/test_stdio_limits.py +0 -0
  90. {agent_client_protocol-0.8.0 → agent_client_protocol-0.9.0}/tests/test_gemini_example.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: agent-client-protocol
3
- Version: 0.8.0
3
+ Version: 0.9.0
4
4
  Summary: A Python implement of Agent Client Protocol (ACP, by Zed Industries)
5
5
  Keywords: python
6
6
  Author-Email: Chojan Shang <psiace@apache.org>, Frost Ming <me@frostming.com>
@@ -28,7 +28,7 @@ from acp.schema import (
28
28
  EnvVariable,
29
29
  ImageContentBlock,
30
30
  Implementation,
31
- KillTerminalCommandResponse,
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(
@@ -1,3 +1,9 @@
1
+ # /// script
2
+ # requires-python = ">=3.10,<3.15"
3
+ # dependencies = [
4
+ # "agent-client-protocol",
5
+ # ]
6
+ # ///
1
7
  import asyncio
2
8
  from typing import Any
3
9
  from uuid import uuid4
@@ -33,8 +33,8 @@ from acp.schema import (
33
33
  EmbeddedResourceContentBlock,
34
34
  EnvVariable,
35
35
  FileEditToolCallContent,
36
- FileSystemCapability,
37
- KillTerminalCommandResponse,
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 KillTerminalCommandResponse()
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=FileSystemCapability(read_text_file=True, write_text_file=True),
321
+ fs=FileSystemCapabilities(read_text_file=True, write_text_file=True),
324
322
  terminal=True,
325
323
  ),
326
324
  )
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agent-client-protocol"
3
- version = "0.8.0"
3
+ version = "0.9.0"
4
4
  description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)"
5
5
  authors = [
6
6
  { name = "Chojan Shang", email = "psiace@apache.org" },
@@ -45,8 +45,8 @@ from .schema import (
45
45
  CreateTerminalResponse,
46
46
  InitializeRequest,
47
47
  InitializeResponse,
48
- KillTerminalCommandRequest,
49
- KillTerminalCommandResponse,
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
- "KillTerminalCommandRequest",
126
- "KillTerminalCommandResponse",
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
- KillTerminalCommandRequest,
21
- KillTerminalCommandResponse,
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(KillTerminalCommandRequest)
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
- KillTerminalCommandRequest(session_id=session_id, terminal_id=terminal_id, field_meta=kwargs or None),
202
- KillTerminalCommandResponse,
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", unstable=True)
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(prompt=prompt, session_id=session_id, field_meta=kwargs or None),
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
- KillTerminalCommandRequest,
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
- KillTerminalCommandRequest,
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
- KillTerminalCommandRequest,
29
- KillTerminalCommandResponse,
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(KillTerminalCommandRequest)
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.10.8
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 = False
67
- func = getattr(obj, attr, None)
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
- warnings.warn(
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]