Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion schema/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
refs/tags/v0.9.1
refs/tags/v0.10.3
5 changes: 5 additions & 0 deletions schema/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
"authenticate": "authenticate",
"initialize": "initialize",
"session_cancel": "session/cancel",
"session_fork": "session/fork",
"session_list": "session/list",
"session_load": "session/load",
"session_new": "session/new",
"session_prompt": "session/prompt",
"session_resume": "session/resume",
"session_set_mode": "session/set_mode",
"session_set_model": "session/set_model"
},
Expand All @@ -21,5 +23,8 @@
"terminal_release": "terminal/release",
"terminal_wait_for_exit": "terminal/wait_for_exit"
},
"protocolMethods": {
"cancel_request": "$/cancel_request"
},
"version": 1
}
393 changes: 389 additions & 4 deletions schema/schema.json

Large diffs are not rendered by default.

33 changes: 12 additions & 21 deletions scripts/gen_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@
)

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

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

Expand Down Expand Up @@ -417,20 +422,6 @@ def replace_block(
return content


def _normalize_stdio_model(content: str) -> str:
replacement_line = ' type: Literal["stdio"] = "stdio"'
new_content, count = STDIO_TYPE_PATTERN.subn(replacement_line, content)
if count == 0:
print("Warning: stdio type placeholder not found; no replacements made.", file=sys.stderr)
return content
if count > 1:
print(
"Warning: multiple stdio type placeholders detected; manual review required.",
file=sys.stderr,
)
return new_content


def _add_description_comments(content: str) -> str:
lines = content.splitlines()
new_lines: list[str] = []
Expand Down
4 changes: 3 additions & 1 deletion src/acp/agent/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
ReleaseTerminalResponse,
RequestPermissionRequest,
RequestPermissionResponse,
SessionInfoUpdate,
SessionNotification,
TerminalOutputRequest,
TerminalOutputResponse,
Expand Down Expand Up @@ -83,7 +84,8 @@ async def session_update(
| ToolCallProgress
| AgentPlanUpdate
| AvailableCommandsUpdate
| CurrentModeUpdate,
| CurrentModeUpdate
| SessionInfoUpdate,
**kwargs: Any,
) -> None:
await notify_model(
Expand Down
4 changes: 4 additions & 0 deletions src/acp/agent/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
from ..schema import (
AuthenticateRequest,
CancelNotification,
ForkSessionRequest,
InitializeRequest,
ListSessionsRequest,
LoadSessionRequest,
NewSessionRequest,
PromptRequest,
ResumeSessionRequest,
SetSessionModelRequest,
SetSessionModeRequest,
)
Expand Down Expand Up @@ -58,6 +60,8 @@ def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> Mes
"authenticate",
adapt_result=normalize_result,
)
router.route_request(AGENT_METHODS["session_fork"], ForkSessionRequest, agent, "fork_session", unstable=True)
router.route_request(AGENT_METHODS["session_resume"], ResumeSessionRequest, agent, "resume_session", unstable=True)

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

Expand Down
34 changes: 34 additions & 0 deletions src/acp/client/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
CancelNotification,
ClientCapabilities,
EmbeddedResourceContentBlock,
ForkSessionRequest,
ForkSessionResponse,
HttpMcpServer,
ImageContentBlock,
Implementation,
Expand All @@ -29,6 +31,8 @@
PromptRequest,
PromptResponse,
ResourceContentBlock,
ResumeSessionRequest,
ResumeSessionResponse,
SetSessionModelRequest,
SetSessionModelResponse,
SetSessionModeRequest,
Expand Down Expand Up @@ -165,6 +169,36 @@ async def prompt(
PromptResponse,
)

@param_model(ForkSessionRequest)
async def fork_session(
self,
cwd: str,
session_id: str,
mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None,
**kwargs: Any,
) -> ForkSessionResponse:
return await request_model(
self._conn,
AGENT_METHODS["session_fork"],
ForkSessionRequest(session_id=session_id, cwd=cwd, mcp_servers=mcp_servers, field_meta=kwargs or None),
ForkSessionResponse,
)

@param_model(ResumeSessionRequest)
async def resume_session(
self,
cwd: str,
session_id: str,
mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None,
**kwargs: Any,
) -> ResumeSessionResponse:
return await request_model(
self._conn,
AGENT_METHODS["session_resume"],
ResumeSessionRequest(session_id=session_id, cwd=cwd, mcp_servers=mcp_servers, field_meta=kwargs or None),
ResumeSessionResponse,
)

@param_model(CancelNotification)
async def cancel(self, session_id: str, **kwargs: Any) -> None:
await notify_model(
Expand Down
26 changes: 25 additions & 1 deletion src/acp/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
CurrentModeUpdate,
EmbeddedResourceContentBlock,
EnvVariable,
ForkSessionRequest,
ForkSessionResponse,
HttpMcpServer,
ImageContentBlock,
Implementation,
Expand All @@ -41,6 +43,9 @@
RequestPermissionRequest,
RequestPermissionResponse,
ResourceContentBlock,
ResumeSessionRequest,
ResumeSessionResponse,
SessionInfoUpdate,
SessionNotification,
SetSessionModelRequest,
SetSessionModelResponse,
Expand Down Expand Up @@ -81,7 +86,8 @@ async def session_update(
| ToolCallProgress
| AgentPlanUpdate
| AvailableCommandsUpdate
| CurrentModeUpdate,
| CurrentModeUpdate
| SessionInfoUpdate,
**kwargs: Any,
) -> None: ...

Expand Down Expand Up @@ -182,6 +188,24 @@ async def prompt(
**kwargs: Any,
) -> PromptResponse: ...

@param_model(ForkSessionRequest)
async def fork_session(
self,
cwd: str,
session_id: str,
mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None,
**kwargs: Any,
) -> ForkSessionResponse: ...

@param_model(ResumeSessionRequest)
async def resume_session(
self,
cwd: str,
session_id: str,
mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None,
**kwargs: Any,
) -> ResumeSessionResponse: ...

@param_model(CancelNotification)
async def cancel(self, session_id: str, **kwargs: Any) -> None: ...

Expand Down
4 changes: 3 additions & 1 deletion src/acp/meta.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Generated from schema/meta.json. Do not edit by hand.
# Schema ref: refs/tags/v0.9.1
# Schema ref: refs/tags/v0.10.3
AGENT_METHODS = {
"authenticate": "authenticate",
"initialize": "initialize",
"session_cancel": "session/cancel",
"session_fork": "session/fork",
"session_list": "session/list",
"session_load": "session/load",
"session_new": "session/new",
"session_prompt": "session/prompt",
"session_resume": "session/resume",
"session_set_mode": "session/set_mode",
"session_set_model": "session/set_model",
}
Expand Down
Loading