Skip to content

Commit 4cc2dfd

Browse files
authored
feat: Update schema to v0.10.2, support fork_session and resume_session unstable API (#48)
Signed-off-by: Frost Ming <me@frostming.com>
1 parent a09e090 commit 4cc2dfd

File tree

13 files changed

+863
-131
lines changed

13 files changed

+863
-131
lines changed

schema/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
refs/tags/v0.9.1
1+
refs/tags/v0.10.3

schema/meta.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
"authenticate": "authenticate",
44
"initialize": "initialize",
55
"session_cancel": "session/cancel",
6+
"session_fork": "session/fork",
67
"session_list": "session/list",
78
"session_load": "session/load",
89
"session_new": "session/new",
910
"session_prompt": "session/prompt",
11+
"session_resume": "session/resume",
1012
"session_set_mode": "session/set_mode",
1113
"session_set_model": "session/set_model"
1214
},
@@ -21,5 +23,8 @@
2123
"terminal_release": "terminal/release",
2224
"terminal_wait_for_exit": "terminal/wait_for_exit"
2325
},
26+
"protocolMethods": {
27+
"cancel_request": "$/cancel_request"
28+
},
2429
"version": 1
2530
}

schema/schema.json

Lines changed: 389 additions & 4 deletions
Large diffs are not rendered by default.

scripts/gen_schema.py

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@
2727
)
2828

2929
STDIO_TYPE_LITERAL = 'Literal["2#-datamodel-code-generator-#-object-#-special-#"]'
30-
STDIO_TYPE_PATTERN = re.compile(
31-
r"^ type:\s*Literal\[['\"]McpServerStdio['\"]\]"
32-
r"(?:\s*=\s*['\"][^'\"]+['\"])?\s*$",
33-
re.MULTILINE,
34-
)
35-
MODELS_TO_REMOVE = ["Model1", "Model2", "Model3", "Model4", "Model5", "Model6", "Model"]
30+
MODELS_TO_REMOVE = [
31+
"AgentClientProtocol",
32+
"AgentClientProtocol1",
33+
"AgentClientProtocol2",
34+
"AgentClientProtocol3",
35+
"AgentClientProtocol4",
36+
"AgentClientProtocol5",
37+
"AgentClientProtocol6",
38+
]
3639

3740
# Map of numbered classes produced by datamodel-code-generator to descriptive names.
3841
# Keep this in sync with the Rust/TypeScript SDK nomenclature.
@@ -58,6 +61,7 @@
5861
"SessionUpdate6": "AgentPlanUpdate",
5962
"SessionUpdate7": "AvailableCommandsUpdate",
6063
"SessionUpdate8": "CurrentModeUpdate",
64+
"SessionUpdate9": "SessionInfoUpdate",
6165
"ToolCallContent1": "ContentToolCallContent",
6266
"ToolCallContent2": "FileEditToolCallContent",
6367
"ToolCallContent3": "TerminalToolCallContent",
@@ -175,7 +179,6 @@ def postprocess_generated_schema(output_path: Path) -> list[str]:
175179
processing_steps: tuple[_ProcessingStep, ...] = (
176180
_ProcessingStep("apply field overrides", _apply_field_overrides),
177181
_ProcessingStep("apply default overrides", _apply_default_overrides),
178-
_ProcessingStep("normalize stdio literal", _normalize_stdio_model),
179182
_ProcessingStep("attach description comments", _add_description_comments),
180183
_ProcessingStep("ensure custom BaseModel", _ensure_custom_base_model),
181184
)
@@ -242,6 +245,8 @@ def _remove_backcompat_block(content: str) -> str:
242245
def _rename_numbered_models(content: str) -> tuple[str, list[str]]:
243246
renamed = content
244247
for old, new in sorted(RENAME_MAP.items(), key=lambda item: len(item[0]), reverse=True):
248+
if re.search(rf"\b{re.escape(new)}\b", renamed) is not None:
249+
renamed = re.sub(rf"\b{re.escape(new)}\b", f"_{new}", renamed)
245250
pattern = re.compile(rf"\b{re.escape(old)}\b")
246251
renamed = pattern.sub(new, renamed)
247252

@@ -417,20 +422,6 @@ def replace_block(
417422
return content
418423

419424

420-
def _normalize_stdio_model(content: str) -> str:
421-
replacement_line = ' type: Literal["stdio"] = "stdio"'
422-
new_content, count = STDIO_TYPE_PATTERN.subn(replacement_line, content)
423-
if count == 0:
424-
print("Warning: stdio type placeholder not found; no replacements made.", file=sys.stderr)
425-
return content
426-
if count > 1:
427-
print(
428-
"Warning: multiple stdio type placeholders detected; manual review required.",
429-
file=sys.stderr,
430-
)
431-
return new_content
432-
433-
434425
def _add_description_comments(content: str) -> str:
435426
lines = content.splitlines()
436427
new_lines: list[str] = []

src/acp/agent/connection.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
ReleaseTerminalResponse,
2626
RequestPermissionRequest,
2727
RequestPermissionResponse,
28+
SessionInfoUpdate,
2829
SessionNotification,
2930
TerminalOutputRequest,
3031
TerminalOutputResponse,
@@ -83,7 +84,8 @@ async def session_update(
8384
| ToolCallProgress
8485
| AgentPlanUpdate
8586
| AvailableCommandsUpdate
86-
| CurrentModeUpdate,
87+
| CurrentModeUpdate
88+
| SessionInfoUpdate,
8789
**kwargs: Any,
8890
) -> None:
8991
await notify_model(

src/acp/agent/router.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
from ..schema import (
1010
AuthenticateRequest,
1111
CancelNotification,
12+
ForkSessionRequest,
1213
InitializeRequest,
1314
ListSessionsRequest,
1415
LoadSessionRequest,
1516
NewSessionRequest,
1617
PromptRequest,
18+
ResumeSessionRequest,
1719
SetSessionModelRequest,
1820
SetSessionModeRequest,
1921
)
@@ -58,6 +60,8 @@ def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> Mes
5860
"authenticate",
5961
adapt_result=normalize_result,
6062
)
63+
router.route_request(AGENT_METHODS["session_fork"], ForkSessionRequest, agent, "fork_session", unstable=True)
64+
router.route_request(AGENT_METHODS["session_resume"], ResumeSessionRequest, agent, "resume_session", unstable=True)
6165

6266
router.route_notification(AGENT_METHODS["session_cancel"], CancelNotification, agent, "cancel")
6367

src/acp/client/connection.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
CancelNotification,
1515
ClientCapabilities,
1616
EmbeddedResourceContentBlock,
17+
ForkSessionRequest,
18+
ForkSessionResponse,
1719
HttpMcpServer,
1820
ImageContentBlock,
1921
Implementation,
@@ -29,6 +31,8 @@
2931
PromptRequest,
3032
PromptResponse,
3133
ResourceContentBlock,
34+
ResumeSessionRequest,
35+
ResumeSessionResponse,
3236
SetSessionModelRequest,
3337
SetSessionModelResponse,
3438
SetSessionModeRequest,
@@ -165,6 +169,36 @@ async def prompt(
165169
PromptResponse,
166170
)
167171

172+
@param_model(ForkSessionRequest)
173+
async def fork_session(
174+
self,
175+
cwd: str,
176+
session_id: str,
177+
mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None,
178+
**kwargs: Any,
179+
) -> ForkSessionResponse:
180+
return await request_model(
181+
self._conn,
182+
AGENT_METHODS["session_fork"],
183+
ForkSessionRequest(session_id=session_id, cwd=cwd, mcp_servers=mcp_servers, field_meta=kwargs or None),
184+
ForkSessionResponse,
185+
)
186+
187+
@param_model(ResumeSessionRequest)
188+
async def resume_session(
189+
self,
190+
cwd: str,
191+
session_id: str,
192+
mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None,
193+
**kwargs: Any,
194+
) -> ResumeSessionResponse:
195+
return await request_model(
196+
self._conn,
197+
AGENT_METHODS["session_resume"],
198+
ResumeSessionRequest(session_id=session_id, cwd=cwd, mcp_servers=mcp_servers, field_meta=kwargs or None),
199+
ResumeSessionResponse,
200+
)
201+
168202
@param_model(CancelNotification)
169203
async def cancel(self, session_id: str, **kwargs: Any) -> None:
170204
await notify_model(

src/acp/interfaces.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
CurrentModeUpdate,
1818
EmbeddedResourceContentBlock,
1919
EnvVariable,
20+
ForkSessionRequest,
21+
ForkSessionResponse,
2022
HttpMcpServer,
2123
ImageContentBlock,
2224
Implementation,
@@ -41,6 +43,9 @@
4143
RequestPermissionRequest,
4244
RequestPermissionResponse,
4345
ResourceContentBlock,
46+
ResumeSessionRequest,
47+
ResumeSessionResponse,
48+
SessionInfoUpdate,
4449
SessionNotification,
4550
SetSessionModelRequest,
4651
SetSessionModelResponse,
@@ -81,7 +86,8 @@ async def session_update(
8186
| ToolCallProgress
8287
| AgentPlanUpdate
8388
| AvailableCommandsUpdate
84-
| CurrentModeUpdate,
89+
| CurrentModeUpdate
90+
| SessionInfoUpdate,
8591
**kwargs: Any,
8692
) -> None: ...
8793

@@ -182,6 +188,24 @@ async def prompt(
182188
**kwargs: Any,
183189
) -> PromptResponse: ...
184190

191+
@param_model(ForkSessionRequest)
192+
async def fork_session(
193+
self,
194+
cwd: str,
195+
session_id: str,
196+
mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None,
197+
**kwargs: Any,
198+
) -> ForkSessionResponse: ...
199+
200+
@param_model(ResumeSessionRequest)
201+
async def resume_session(
202+
self,
203+
cwd: str,
204+
session_id: str,
205+
mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None,
206+
**kwargs: Any,
207+
) -> ResumeSessionResponse: ...
208+
185209
@param_model(CancelNotification)
186210
async def cancel(self, session_id: str, **kwargs: Any) -> None: ...
187211

src/acp/meta.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# Generated from schema/meta.json. Do not edit by hand.
2-
# Schema ref: refs/tags/v0.9.1
2+
# Schema ref: refs/tags/v0.10.3
33
AGENT_METHODS = {
44
"authenticate": "authenticate",
55
"initialize": "initialize",
66
"session_cancel": "session/cancel",
7+
"session_fork": "session/fork",
78
"session_list": "session/list",
89
"session_load": "session/load",
910
"session_new": "session/new",
1011
"session_prompt": "session/prompt",
12+
"session_resume": "session/resume",
1113
"session_set_mode": "session/set_mode",
1214
"session_set_model": "session/set_model",
1315
}

0 commit comments

Comments
 (0)