@@ -848,6 +848,9 @@ too_many_arguments = "allow"
# We often have large enum variants yet we rarely actually bother with splitting them up.
large_enum_variant = "allow"
+# Boolean expressions can be hard to read, requiring only the minimal form gets in the way
+nonminimal_bol = "allow"
+
[workspace.metadata.cargo-machete]
ignored = [
"bindgen",
@@ -8,7 +8,7 @@ use action_log::ActionLog;
use agent_client_protocol::{self as acp, PromptCapabilities};
use agent_servers::{AgentServer, AgentServerDelegate, ClaudeCode};
use agent_settings::{AgentProfileId, AgentSettings, CompletionMode, NotifyWhenAgentWaiting};
-use agent2::{DbThreadMetadata, HistoryEntry, HistoryEntryId, HistoryStore};
+use agent2::{DbThreadMetadata, HistoryEntry, HistoryEntryId, HistoryStore, NativeAgentServer};
use anyhow::{Context as _, Result, anyhow, bail};
use audio::{Audio, Sound};
use buffer_diff::BufferDiff;
@@ -418,6 +418,13 @@ impl AcpThreadView {
window: &mut Window,
cx: &mut Context<Self>,
) -> ThreadState {
+ if project.read(cx).is_via_collab()
+ && agent.clone().downcast::<NativeAgentServer>().is_none()
+ {
+ return ThreadState::LoadError(LoadError::Other(
+ "External agents are not yet supported for remote projects.".into(),
+ ));
+ }
let root_dir = project
.read(cx)
.visible_worktrees(cx)
@@ -1091,6 +1091,7 @@ impl AgentPanel {
let workspace = self.workspace.clone();
let project = self.project.clone();
let fs = self.fs.clone();
+ let is_via_collab = self.project.read(cx).is_via_collab();
const LAST_USED_EXTERNAL_AGENT_KEY: &str = "agent_panel__last_used_external_agent";
@@ -1122,17 +1123,21 @@ impl AgentPanel {
agent
}
None => {
- cx.background_spawn(async move {
- KEY_VALUE_STORE.read_kvp(LAST_USED_EXTERNAL_AGENT_KEY)
- })
- .await
- .log_err()
- .flatten()
- .and_then(|value| {
- serde_json::from_str::<LastUsedExternalAgent>(&value).log_err()
- })
- .unwrap_or_default()
- .agent
+ if is_via_collab {
+ ExternalAgent::NativeAgent
+ } else {
+ cx.background_spawn(async move {
+ KEY_VALUE_STORE.read_kvp(LAST_USED_EXTERNAL_AGENT_KEY)
+ })
+ .await
+ .log_err()
+ .flatten()
+ .and_then(|value| {
+ serde_json::from_str::<LastUsedExternalAgent>(&value).log_err()
+ })
+ .unwrap_or_default()
+ .agent
+ }
}
};
@@ -2527,6 +2532,11 @@ impl AgentPanel {
.with_handle(self.new_thread_menu_handle.clone())
.menu({
let workspace = self.workspace.clone();
+ let is_via_collab = workspace
+ .update(cx, |workspace, cx| {
+ workspace.project().read(cx).is_via_collab()
+ })
+ .unwrap_or_default();
move |window, cx| {
telemetry::event!("New Thread Clicked");
@@ -2617,6 +2627,7 @@ impl AgentPanel {
ContextMenuEntry::new("New Gemini CLI Thread")
.icon(IconName::AiGemini)
.icon_color(Color::Muted)
+ .disabled(is_via_collab)
.handler({
let workspace = workspace.clone();
move |window, cx| {
@@ -2643,6 +2654,7 @@ impl AgentPanel {
menu.item(
ContextMenuEntry::new("New Claude Code Thread")
.icon(IconName::AiClaude)
+ .disabled(is_via_collab)
.icon_color(Color::Muted)
.handler({
let workspace = workspace.clone();
@@ -2675,6 +2687,7 @@ impl AgentPanel {
ContextMenuEntry::new(format!("New {} Thread", agent_name))
.icon(IconName::Terminal)
.icon_color(Color::Muted)
+ .disabled(is_via_collab)
.handler({
let workspace = workspace.clone();
let agent_name = agent_name.clone();