acp: Support session modes (e.g. CC plan mode) (#37632)

Adds support for [ACP session
modes](https://github.com/zed-industries/agent-client-protocol/pull/67)
enabling plan and other permission modes in CC:


https://github.com/user-attachments/assets/dea18d82-4da6-465e-983b-02b77c6dcf15


Release Notes:

- Claude Code: Add support for plan mode, and all other permission modes

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
Agus Zubiaga
2025-09-09 13:28:02 -03:00
committed by GitHub
co-authored by Bennet Bo Fenner Richard Feldman Danilo Leal
parent ad02f6b9e3
commit 5e397e85b1
26 changed files with 886 additions and 143 deletions
+6 -1
View File
@@ -805,6 +805,7 @@ pub enum AcpThreadEvent {
PromptCapabilitiesUpdated,
Refusal,
AvailableCommandsUpdated(Vec<acp::AvailableCommand>),
ModeUpdated(acp::SessionModeId),
}
impl EventEmitter<AcpThreadEvent> for AcpThread {}
@@ -1007,6 +1008,9 @@ impl AcpThread {
acp::SessionUpdate::AvailableCommandsUpdate { available_commands } => {
cx.emit(AcpThreadEvent::AvailableCommandsUpdated(available_commands))
}
acp::SessionUpdate::CurrentModeUpdate { current_mode_id } => {
cx.emit(AcpThreadEvent::ModeUpdated(current_mode_id))
}
}
Ok(())
}
@@ -1303,11 +1307,12 @@ impl AcpThread {
&mut self,
tool_call: acp::ToolCallUpdate,
options: Vec<acp::PermissionOption>,
respect_always_allow_setting: bool,
cx: &mut Context<Self>,
) -> Result<BoxFuture<'static, acp::RequestPermissionOutcome>> {
let (tx, rx) = oneshot::channel();
if AgentSettings::get_global(cx).always_allow_tool_actions {
if respect_always_allow_setting && AgentSettings::get_global(cx).always_allow_tool_actions {
// Don't use AllowAlways, because then if you were to turn off always_allow_tool_actions,
// some tools would (incorrectly) continue to auto-accept.
if let Some(allow_once_option) = options.iter().find_map(|option| {
+18
View File
@@ -75,6 +75,15 @@ pub trait AgentConnection {
fn telemetry(&self) -> Option<Rc<dyn AgentTelemetry>> {
None
}
fn session_modes(
&self,
_session_id: &acp::SessionId,
_cx: &App,
) -> Option<Rc<dyn AgentSessionModes>> {
None
}
fn into_any(self: Rc<Self>) -> Rc<dyn Any>;
}
@@ -109,6 +118,14 @@ pub trait AgentTelemetry {
) -> Task<Result<serde_json::Value>>;
}
pub trait AgentSessionModes {
fn current_mode(&self) -> acp::SessionModeId;
fn all_modes(&self) -> Vec<acp::SessionMode>;
fn set_mode(&self, mode: acp::SessionModeId, cx: &mut App) -> Task<Result<()>>;
}
#[derive(Debug)]
pub struct AuthRequired {
pub description: Option<String>,
@@ -397,6 +414,7 @@ mod test_support {
thread.request_tool_call_authorization(
tool_call.clone().into(),
options.clone(),
false,
cx,
)
})??