55
66The bindings use ` schema-v2.0.0-alpha.5 ` .
77
8- The v2 runtime is separate from the stable v1 API. Its methods accept and return
9- generated request and response models directly. Install update handlers on the
10- client before opening a session because updates are independent connection
11- traffic:
8+ The v2 runtime is separate from the stable v1 API. Like v1, connection methods
9+ and agent/client handlers accept expanded, snake-case parameters. Responses and
10+ nested values (content blocks, updates, capabilities) use ` v2.schema ` models.
11+ Extra keyword arguments carry request ` _meta ` .
12+
13+ Install update handlers before opening a session because updates are independent
14+ connection traffic:
1215
1316``` python
17+ from typing import Any
1418from acp.experimental import v2
1519
16- class MyClient :
20+ class MyClient ( v2 . Client ) :
1721 async def session_update (
18- self ,
19- notification : v2.schema.UpdateSessionNotification,
22+ self , session_id : str , update : Any, ** kwargs : Any,
2023 ) -> None :
21- handle_update(notification )
24+ handle_update(session_id, update )
2225
2326
2427connection = v2.connect_to_agent(MyClient(), transport)
2528initialized = await connection.initialize(
26- v2.schema.InitializeRequest(
27- protocol_version = v2.PROTOCOL_VERSION ,
28- info = v2.schema.Implementation(name = " my-client" , version = " 1.0.0" ),
29- )
30- )
31- session = await connection.new_session(
32- v2.schema.NewSessionRequest(cwd = " /workspace" )
29+ protocol_version = v2.PROTOCOL_VERSION ,
30+ info = v2.schema.Implementation(name = " my-client" , version = " 1.0.0" ),
3331)
32+ session = await connection.new_session(cwd = " /workspace" )
3433accepted = await connection.prompt(
35- v2.schema.PromptRequest(
36- session_id = session.session_id,
37- prompt = [v2.schema.TextContentBlock(text = " Hello" )],
38- )
34+ session_id = session.session_id,
35+ prompt = [v2.schema.TextContentBlock(text = " Hello" )],
36+ )
37+ ```
38+
39+ Implement an agent with the same expanded handler style:
40+
41+ ``` python
42+ class MyAgent (v2 .Agent ):
43+ async def initialize (
44+ self ,
45+ protocol_version : int ,
46+ info : v2.schema.Implementation,
47+ capabilities : v2.schema.ClientCapabilities | None = None ,
48+ ** kwargs : Any,
49+ ) -> v2.schema.InitializeResponse:
50+ return v2.schema.InitializeResponse(
51+ protocol_version = v2.PROTOCOL_VERSION ,
52+ info = v2.schema.Implementation(name = " my-agent" , version = " 1.0.0" ),
53+ )
54+
55+ async def new_session (
56+ self ,
57+ cwd : str ,
58+ additional_directories : list[str ] | None = None ,
59+ mcp_servers : list[Any] | None = None ,
60+ ** kwargs : Any,
61+ ) -> v2.schema.NewSessionResponse:
62+ return v2.schema.NewSessionResponse(session_id = " session-1" )
63+
64+
65+ await v2.run_agent(MyAgent())
66+ ```
67+
68+ ` v2.Agent ` and ` v2.Client ` describe the v2 handler signatures; subclassing is
69+ optional. Implement only the methods you support. Unimplemented requests return
70+ method-not-found, and unimplemented notifications are ignored. The v2 protocols
71+ are separate from v1 because initialization, prompt responses, permissions, and
72+ session updates have different contracts. Both versions use ` param_model `
73+ metadata to derive their routes. V2 retains strict request/response validation
74+ and requires successful initialization before other traffic.
75+
76+ Previously, v2 methods accepted a whole request model. Replace
77+ ` connection.new_session(v2.schema.NewSessionRequest(cwd="/workspace")) ` with
78+ ` connection.new_session(cwd="/workspace") ` , and expand handler parameters likewise.
79+
80+ Union requests also use expanded parameters:
81+
82+ ``` python
83+ await connection.set_config_option(config_id = " thinking" , session_id = session.session_id, value = True )
84+ # type defaults to "boolean" for bool values and "id" otherwise.
85+ await connection.set_config_option(
86+ config_id = " vendor/limit" , session_id = session.session_id, value = 10 , type = " vendor/number" ,
87+ )
88+ await agent_connection.create_elicitation(
89+ message = " Sign in" , mode = " url" , session_id = session.session_id,
90+ elicitation_id = " sign-in-1" , url = " https://example.com/login" ,
3991)
4092```
4193
94+ For elicitation, ` session_id ` selects session scope; otherwise ` request_id `
95+ selects request scope (including ` None ` ). Pass ` requested_schema ` for form mode,
96+ or ` elicitation_id ` and ` url ` for URL mode. Handlers receive the validated
97+ branch's fields, including ` type ` for config options and ` mode ` for elicitation.
98+
4299` session/prompt ` returns after the agent inserts the user message into the ACP
43100conversation, without waiting for processing to finish. The response requires a
44101non-null ` message_id ` . Agents return ` v2.schema.PromptResponse(message_id=...) `
@@ -48,7 +105,7 @@ the same ID. That update may arrive before or after the response; use
48105and do not carry a prompt identifier.
49106
50107Agents can send ` v2.schema.SessionNotice(severity="warning", title="Context is nearly full") `
51- in an ` UpdateSessionNotification ` . V2 notices require no client capability and
108+ with ` await agent_connection.session_update(session_id=session_id, update=notice) ` . V2 notices require no client capability and
52109are live advisory events, outside retained session history. Clients may ignore
53110them. Titles must be non-empty, and severity also accepts custom or future strings.
54111
@@ -59,7 +116,7 @@ tool name, while omitting `name` leaves it unchanged. This also applies to
59116terminal updates and patch metadata. When applying received patches, use
60117` update.model_dump(by_alias=True, exclude_unset=True) ` to retain that distinction.
61118
62- Setting ` replay_from=v2.schema.ReplayFromStartVariant() ` on a ` ResumeSessionRequest `
119+ Setting ` replay_from=v2.schema.ReplayFromStartVariant() ` on ` connection.resume_session(...) `
63120requests all retained conversation history; agents need not retain every message.
64121Accepted elicitation content validates scalar values and string lists; nested
65122objects are not valid form values.
0 commit comments