The Big Themes of v2
Moving beyond the turn
When we launched ACP v1, most agents happily emitted events only after a user-initiated message and usually stopped once they finished generating. But these days, agents are able to work longer and even orchestrate more and more work in the background. While the ACP v1 spec didn’t prohibitsession/update notifications from coming outside of the turn, it was a common point of confusion for implementers, who usually wanted to guarantee interaction patterns around the idea of a user-initiated turn, but it is clear that enforcing this actually prevents useful behavior. An agent could be ready to receive new input while background events are happening, but it still wants to provide real-time updates for those as well. If we stick with a turn-focused orientation for prompts, neither side is happy.
If we want to allow for queueing, steering, or receiving updates from work that isn’t necessarily initiated by the user, we need to make it clearer that the prompt request/response doesn’t own the entire lifecycle of work being done. Now session/update notifications can proceed freely at any point in the session, and a prompt response is the indication that the message was acknowledged by the agent, not the end of the turn. The agent will replay the user message where it inserted it, which also makes it easier for both replay and the potential for multiple clients observing the same session. The agent can indicate when it is “idle”, or ready to receive new inputs, allowing the client to indicate readiness, and agents can continue to update the session state in the meantime.
You can read more about this in the new prompt lifecycle RFD.
Updating Messages and Streaming Tool Calls
User and agent messages, tool calls, and terminal output are patched by stable IDs with uniform semantics: omitted fields stay unchanged,null clears, values replace, and chunks append. Message IDs are required as well so that messages can not only stream, but also update and replace in case of redaction or other needs.
This was a pattern that was only available for tool calls before, but now is uniformly used across these session item types to make things more consistent and flexible.
We also applied the message streaming pattern to tool call content, so that tool calls can be streamed in without buffering and resending the entire content over and over.
Diff Overhaul
TheoldText/newText diff is replaced by structured file changes. You can now express add, delete, modify, move, copy, plus binary and non-text cases. Some of these could be inferred in the old structure, but not all, so we’ve hopefully made it possible to report all changes the agent makes on the filesystem.
The agent can also provide an optional git_patch for rendering the changes. This can be shown as is, but is also structured enough for clients to do nice diff rendering for text changes as well.
More flexible permission requests
Permission prompts carry their own requiredtitle and optional description, with an extensible subject instead of a hard-wired tool call. This also allows us to provide special permission requests for terminal commands or other objects in the future. And decoupling the title and description from the tool call’s title and content makes it possible to provide more context to the user making the decision without accidentally overriding the tool call itself.
Forward compatibility by default
One of the big goals in v1 was to make ACP extensible, which has been hugely successful. So many of you have built amazing features using these mechanisms, several of which have been upstreamed to the protocol itself. v2 now makes it possible to extend at just about every layer you can think of to allow for more experimentation or extension points when building tooling on top. Enum-like values across the schema accept unknown variants with a_ prefix for implementation-specific extensions. This builds on the successful pattern we added for session config options and embeds it right in the schema. This makes sure new features don’t cause older client and agents to choke on unknown nested data, and provides patterns for extending even more parts of the protocol where needed.
Draft status
v2 is a Draft. I personally went through every single line of the schema at least once, if not more, and I think it is in a solid state to start testing. However, various pieces can, and will, change before stabilization. That is the point of the draft stage: to receive feedback before we stabilize it. As you start implementing it, gate your implementation behind the version negotiation AND feature flags. Don’t ship it by default in production until we are closer to stabilization. If we’re lucky, not much will need to change between now and then. But we also want to avoid causing pain for users while we all navigate the necessary changes. Adding v2 support should not mean dropping v1. v1-only peers will remain common for some time, so implementers should support both versions side by side. We are working on making this easier to express in the various SDKs. A majority of the types haven’t changed between versions, but if you maintain an Agent, Client, or SDK, the migration guide walks through the key changes you need to know with before/after examples.Where to start
- Read the v2 protocol docs and the migration guide.
- SDK authors can generate against the v2 JSON schemas, published in the repository releases as
v2.0.0-alphaXalongside v1. - The v2 RFD collection records the key decisions behind the larger changes.