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
1 change: 1 addition & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"protocol/file-system",
"protocol/terminals",
"protocol/agent-plan",
"protocol/session-modes",
"protocol/extensibility",
"protocol/schema"
]
Expand Down
98 changes: 68 additions & 30 deletions docs/protocol/schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ Response from loading an existing session.
Extension point for implementations
</ResponseField>
<ResponseField name="modes" type={<><span><a href="#sessionmodestate">SessionModeState</a></span><span> | null</span></>} >
**UNSTABLE**
Initial mode state if supported by the Agent

This field is not part of the spec, and may be removed or changed at any point.
See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)

</ResponseField>

Expand Down Expand Up @@ -302,9 +302,9 @@ See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol
Extension point for implementations
</ResponseField>
<ResponseField name="modes" type={<><span><a href="#sessionmodestate">SessionModeState</a></span><span> | null</span></>} >
**UNSTABLE**
Initial mode state if supported by the Agent

This field is not part of the spec, and may be removed or changed at any point.
See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)

</ResponseField>
<ResponseField name="sessionId" type={<a href="#sessionid">SessionId</a>} required>
Expand Down Expand Up @@ -386,6 +386,59 @@ See protocol docs: [Check for Completion](https://agentclientprotocol.com/protoc
Indicates why the agent stopped processing the turn.
</ResponseField>

<a id="session-set_mode"></a>
### <span class="font-mono">session/set_mode</span>

Sets the current mode for a session.

Allows switching between different agent modes (e.g., "ask", "architect", "code")
that affect system prompts, tool availability, and permission behaviors.

The mode must be one of the modes advertised in `availableModes` during session
creation or loading. Agents may also change modes autonomously and notify the
client via `current_mode_update` notifications.

This method can be called at any time during a session, whether the Agent is
idle or actively generating a response.

See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)

#### <span class="font-mono">SetSessionModeRequest</span>

Request parameters for setting a session mode.

**Type:** Object

**Properties:**

<ResponseField name="_meta" type={"object"}>
Extension point for implementations
</ResponseField>
<ResponseField
name="modeId"
type={<a href="#sessionmodeid">SessionModeId</a>}
required
>
The ID of the mode to set.
</ResponseField>
<ResponseField
name="sessionId"
type={<a href="#sessionid">SessionId</a>}
required
>
The ID of the session to set the mode for.
</ResponseField>

#### <span class="font-mono">SetSessionModeResponse</span>

Response to `session/set_mode` method.

**Type:** Object

**Properties:**

<ResponseField name="meta" type={"object"}></ResponseField>

## Client

Defines the interface that ACP-compliant clients must implement.
Expand Down Expand Up @@ -1885,9 +1938,9 @@ See protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session

## <span class="font-mono">SessionMode</span>

**UNSTABLE**
A mode the agent can operate in.

This type is not part of the spec, and may be removed or changed at any point.
See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)

**Type:** Object

Expand All @@ -1906,17 +1959,13 @@ This type is not part of the spec, and may be removed or changed at any point.

## <span class="font-mono">SessionModeId</span>

**UNSTABLE**

This type is not part of the spec, and may be removed or changed at any point.
Unique identifier for a Session Mode.

**Type:** `string`

## <span class="font-mono">SessionModeState</span>

**UNSTABLE**

This type is not part of the spec, and may be removed or changed at any point.
The set of modes and the one currently active.

**Type:** Object

Expand All @@ -1936,12 +1985,16 @@ This type is not part of the spec, and may be removed or changed at any point.
</>
}
required
></ResponseField>
>
The set of modes that the Agent can operate in
</ResponseField>
<ResponseField
name="currentModeId"
type={<a href="#sessionmodeid">SessionModeId</a>}
required
></ResponseField>
>
The current mode the Agent is in.
</ResponseField>

## <span class="font-mono">SessionUpdate</span>

Expand Down Expand Up @@ -2184,18 +2237,6 @@ The current mode of the session has changed
</Expandable>
</ResponseField>

## <span class="font-mono">SetSessionModeResponse</span>

**UNSTABLE**

This type is not part of the spec, and may be removed or changed at any point.

**Type:** Object

**Properties:**

<ResponseField name="meta" type={"object"}></ResponseField>

## <span class="font-mono">StopReason</span>

Reasons why an agent stops processing a prompt turn.
Expand Down Expand Up @@ -2576,10 +2617,7 @@ See protocol docs: [Creating](https://agentclientprotocol.com/protocol/tool-call
<ResponseField name="fetch">Retrieving external data.</ResponseField>

<ResponseField name="switch_mode">
**UNSTABLE**

This tool kind is not part of the spec and may be removed at any point.

Switching the current session mode.
</ResponseField>

<ResponseField name="other">Other tool types (default).</ResponseField>
167 changes: 167 additions & 0 deletions docs/protocol/session-modes.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
---
title: "Session Modes"
description: "How agents can operate in different modes"
---

Agents can provide a set of modes they can operate in. Modes often affect the system prompts used, the availability of tools, and whether they request permission before running.

## Initial state

During [Session Setup](./session-setup) the Agent **MAY** return a list of modes it can operate in and the currently active mode:

```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"sessionId": "sess_abc123def456",
"modes": {
"currentModeId": "ask",
"availableModes": [
{
"id": "ask",
"name": "Ask",
"description": "Request permission before making any changes"
},
{
"id": "architect",
"name": "Architect",
"description": "Design and plan software systems without implementation"
},
{
"id": "code",
"name": "Code",
"description": "Write and modify code with full tool access"
}
]
}
}
}
```

<ResponseField name="modes" type="SessionModeState">
The current mode state for the session
</ResponseField>

### SessionModeState

<ResponseField name="currentModeId" type="SessionModeId" required>
The ID of the mode that is currently active
</ResponseField>

<ResponseField name="availableModes" type="SessionMode[]" required>
The set of modes that the Agent can operate in
</ResponseField>

### SessionMode

<ResponseField name="id" type="SessionModeId" required>
Unique identifier for this mode
</ResponseField>

<ResponseField name="name" type="string" required>
Human-readable name of the mode
</ResponseField>

<ResponseField name="description" type="string">
Optional description providing more details about what this mode does
</ResponseField>

## Setting the current mode

The current mode can be changed at any point during a session, whether the Agent is idle or generating a response.

### From the Client

Typically, Clients display the available modes to the user and allow them to change the current one, which they can do by calling the [`session/set_mode`](./schema#session%2Fset-mode) method.

```json
{
"jsonrpc": "2.0",
"id": 2,
"method": "session/set_mode",
"params": {
"sessionId": "sess_abc123def456",
"modeId": "code"
}
}
```

<ParamField path="sessionId" type="SessionId" required>
The ID of the session to set the mode for
</ParamField>

<ParamField path="modeId" type="SessionModeId" required>
The ID of the mode to switch to. Must be one of the modes listed in
`availableModes`
</ParamField>

### From the Agent

The Agent can also change its own mode and let the Client know by sending the `current_mode_update` session notification:

```json
{
"jsonrpc": "2.0",
"method": "session/update",
"params": {
"sessionId": "sess_abc123def456",
"update": {
"sessionUpdate": "current_mode_update",
"modeId": "code"
}
}
}
```

#### Exiting plan modes

A common case where an Agent might switch modes is from within a special "exit mode" tool that can be provided to the language model during plan/architect modes. The language model can call this tool when it determines it's ready to start implementing a solution.

This "switch mode" tool will usually request permission before running, which it can do just like any other tool:

```json
{
"jsonrpc": "2.0",
"id": 3,
"method": "session/request_permission",
"params": {
"sessionId": "sess_abc123def456",
"toolCall": {
"toolCallId": "call_switch_mode_001",
"title": "Ready for implementation",
"kind": "switch_mode",
"status": "pending",
"content": [
{
"type": "text",
"text": "## Implementation Plan..."
}
]
},
"options": [
{
"optionId": "code",
"name": "Yes, and auto-accept all actions",
"kind": "allow_always"
},
{
"optionId": "ask",
"name": "Yes, and manually accept actions",
"kind": "allow_once"
},
{
"optionId": "reject",
"name": "No, stay in architect mode",
"kind": "reject_once"
}
]
}
}
```

When an option is chosen, the tool runs, setting the mode and sending the `current_mode_update` notification mentioned above.

<Card icon="shield-check" horizontal href="./tool-calls#requesting-permission">
Learn more about permission requests
</Card>
3 changes: 0 additions & 3 deletions rust/acp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ impl Agent for ClientSideConnection {
.map(|value| value.unwrap_or_default())
}

#[cfg(feature = "unstable")]
async fn set_session_mode(
&self,
arguments: SetSessionModeRequest,
Expand Down Expand Up @@ -619,7 +618,6 @@ impl Side for AgentSide {
SESSION_LOAD_METHOD_NAME => serde_json::from_str(params.get())
.map(ClientRequest::LoadSessionRequest)
.map_err(Into::into),
#[cfg(feature = "unstable")]
SESSION_SET_MODE_METHOD_NAME => serde_json::from_str(params.get())
.map(ClientRequest::SetSessionModeRequest)
.map_err(Into::into),
Expand Down Expand Up @@ -686,7 +684,6 @@ impl<T: Agent> MessageHandler<AgentSide> for T {
let response = self.prompt(args).await?;
Ok(AgentResponse::PromptResponse(response))
}
#[cfg(feature = "unstable")]
ClientRequest::SetSessionModeRequest(args) => {
let response = self.set_session_mode(args).await?;
Ok(AgentResponse::SetSessionModeResponse(response))
Expand Down
Loading