Skip to content

Commit 14a50e2

Browse files
agu-zJosephTLyons
authored andcommitted
acp: Fix MessageEditor::set_message for sent messages (#36715)
The `PromptCapabilities` introduced in previous PRs were only getting set on the main message editor and not for the editors in user messages. This caused a bug where mentions would disappear after resending the message, and for the completion provider to be limited to files. Release Notes: - N/A
1 parent 3d80be6 commit 14a50e2

File tree

3 files changed

+35
-24
lines changed

3 files changed

+35
-24
lines changed

crates/agent_ui/src/acp/entry_view_state.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use std::ops::Range;
1+
use std::{cell::Cell, ops::Range, rc::Rc};
22

33
use acp_thread::{AcpThread, AgentThreadEntry};
4-
use agent_client_protocol::ToolCallId;
4+
use agent_client_protocol::{PromptCapabilities, ToolCallId};
55
use agent2::HistoryStore;
66
use collections::HashMap;
77
use editor::{Editor, EditorMode, MinimapVisibility};
@@ -27,6 +27,7 @@ pub struct EntryViewState {
2727
prompt_store: Option<Entity<PromptStore>>,
2828
entries: Vec<Entry>,
2929
prevent_slash_commands: bool,
30+
prompt_capabilities: Rc<Cell<PromptCapabilities>>,
3031
}
3132

3233
impl EntryViewState {
@@ -35,6 +36,7 @@ impl EntryViewState {
3536
project: Entity<Project>,
3637
history_store: Entity<HistoryStore>,
3738
prompt_store: Option<Entity<PromptStore>>,
39+
prompt_capabilities: Rc<Cell<PromptCapabilities>>,
3840
prevent_slash_commands: bool,
3941
) -> Self {
4042
Self {
@@ -44,6 +46,7 @@ impl EntryViewState {
4446
prompt_store,
4547
entries: Vec::new(),
4648
prevent_slash_commands,
49+
prompt_capabilities,
4750
}
4851
}
4952

@@ -81,6 +84,7 @@ impl EntryViewState {
8184
self.project.clone(),
8285
self.history_store.clone(),
8386
self.prompt_store.clone(),
87+
self.prompt_capabilities.clone(),
8488
"Edit message - @ to include context",
8589
self.prevent_slash_commands,
8690
editor::EditorMode::AutoHeight {
@@ -403,6 +407,7 @@ mod tests {
403407
project.clone(),
404408
history_store,
405409
None,
410+
Default::default(),
406411
false,
407412
)
408413
});

crates/agent_ui/src/acp/message_editor.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ impl MessageEditor {
8787
project: Entity<Project>,
8888
history_store: Entity<HistoryStore>,
8989
prompt_store: Option<Entity<PromptStore>>,
90+
prompt_capabilities: Rc<Cell<acp::PromptCapabilities>>,
9091
placeholder: impl Into<Arc<str>>,
9192
prevent_slash_commands: bool,
9293
mode: EditorMode,
@@ -100,7 +101,6 @@ impl MessageEditor {
100101
},
101102
None,
102103
);
103-
let prompt_capabilities = Rc::new(Cell::new(acp::PromptCapabilities::default()));
104104
let completion_provider = ContextPickerCompletionProvider::new(
105105
cx.weak_entity(),
106106
workspace.clone(),
@@ -203,10 +203,6 @@ impl MessageEditor {
203203
.detach();
204204
}
205205

206-
pub fn set_prompt_capabilities(&mut self, capabilities: acp::PromptCapabilities) {
207-
self.prompt_capabilities.set(capabilities);
208-
}
209-
210206
#[cfg(test)]
211207
pub(crate) fn editor(&self) -> &Entity<Editor> {
212208
&self.editor
@@ -1095,15 +1091,21 @@ impl MessageEditor {
10951091
mentions.push((start..end, mention_uri, resource.text));
10961092
}
10971093
}
1094+
acp::ContentBlock::ResourceLink(resource) => {
1095+
if let Some(mention_uri) = MentionUri::parse(&resource.uri).log_err() {
1096+
let start = text.len();
1097+
write!(&mut text, "{}", mention_uri.as_link()).ok();
1098+
let end = text.len();
1099+
mentions.push((start..end, mention_uri, resource.uri));
1100+
}
1101+
}
10981102
acp::ContentBlock::Image(content) => {
10991103
let start = text.len();
11001104
text.push_str("image");
11011105
let end = text.len();
11021106
images.push((start..end, content));
11031107
}
1104-
acp::ContentBlock::Audio(_)
1105-
| acp::ContentBlock::Resource(_)
1106-
| acp::ContentBlock::ResourceLink(_) => {}
1108+
acp::ContentBlock::Audio(_) | acp::ContentBlock::Resource(_) => {}
11071109
}
11081110
}
11091111

@@ -1850,7 +1852,7 @@ impl Addon for MessageEditorAddon {
18501852

18511853
#[cfg(test)]
18521854
mod tests {
1853-
use std::{ops::Range, path::Path, sync::Arc};
1855+
use std::{cell::Cell, ops::Range, path::Path, rc::Rc, sync::Arc};
18541856

18551857
use acp_thread::MentionUri;
18561858
use agent_client_protocol as acp;
@@ -1896,6 +1898,7 @@ mod tests {
18961898
project.clone(),
18971899
history_store.clone(),
18981900
None,
1901+
Default::default(),
18991902
"Test",
19001903
false,
19011904
EditorMode::AutoHeight {
@@ -2086,6 +2089,7 @@ mod tests {
20862089

20872090
let context_store = cx.new(|cx| ContextStore::fake(project.clone(), cx));
20882091
let history_store = cx.new(|cx| HistoryStore::new(context_store, cx));
2092+
let prompt_capabilities = Rc::new(Cell::new(acp::PromptCapabilities::default()));
20892093

20902094
let (message_editor, editor) = workspace.update_in(&mut cx, |workspace, window, cx| {
20912095
let workspace_handle = cx.weak_entity();
@@ -2095,6 +2099,7 @@ mod tests {
20952099
project.clone(),
20962100
history_store.clone(),
20972101
None,
2102+
prompt_capabilities.clone(),
20982103
"Test",
20992104
false,
21002105
EditorMode::AutoHeight {
@@ -2139,13 +2144,10 @@ mod tests {
21392144
editor.set_text("", window, cx);
21402145
});
21412146

2142-
message_editor.update(&mut cx, |editor, _cx| {
2143-
// Enable all prompt capabilities
2144-
editor.set_prompt_capabilities(acp::PromptCapabilities {
2145-
image: true,
2146-
audio: true,
2147-
embedded_context: true,
2148-
});
2147+
prompt_capabilities.set(acp::PromptCapabilities {
2148+
image: true,
2149+
audio: true,
2150+
embedded_context: true,
21492151
});
21502152

21512153
cx.simulate_input("Lorem ");

crates/agent_ui/src/acp/thread_view.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use acp_thread::{
55
};
66
use acp_thread::{AgentConnection, Plan};
77
use action_log::ActionLog;
8-
use agent_client_protocol::{self as acp};
8+
use agent_client_protocol::{self as acp, PromptCapabilities};
99
use agent_servers::{AgentServer, ClaudeCode};
1010
use agent_settings::{AgentProfileId, AgentSettings, CompletionMode, NotifyWhenAgentWaiting};
1111
use agent2::{DbThreadMetadata, HistoryEntry, HistoryEntryId, HistoryStore};
@@ -34,6 +34,7 @@ use project::{Project, ProjectEntryId};
3434
use prompt_store::{PromptId, PromptStore};
3535
use rope::Point;
3636
use settings::{Settings as _, SettingsStore};
37+
use std::cell::Cell;
3738
use std::sync::Arc;
3839
use std::time::Instant;
3940
use std::{collections::BTreeMap, rc::Rc, time::Duration};
@@ -271,6 +272,7 @@ pub struct AcpThreadView {
271272
plan_expanded: bool,
272273
editor_expanded: bool,
273274
editing_message: Option<usize>,
275+
prompt_capabilities: Rc<Cell<PromptCapabilities>>,
274276
_cancel_task: Option<Task<()>>,
275277
_subscriptions: [Subscription; 3],
276278
}
@@ -306,13 +308,15 @@ impl AcpThreadView {
306308
window: &mut Window,
307309
cx: &mut Context<Self>,
308310
) -> Self {
311+
let prompt_capabilities = Rc::new(Cell::new(acp::PromptCapabilities::default()));
309312
let prevent_slash_commands = agent.clone().downcast::<ClaudeCode>().is_some();
310313
let message_editor = cx.new(|cx| {
311314
let mut editor = MessageEditor::new(
312315
workspace.clone(),
313316
project.clone(),
314317
history_store.clone(),
315318
prompt_store.clone(),
319+
prompt_capabilities.clone(),
316320
"Message the agent — @ to include context",
317321
prevent_slash_commands,
318322
editor::EditorMode::AutoHeight {
@@ -336,6 +340,7 @@ impl AcpThreadView {
336340
project.clone(),
337341
history_store.clone(),
338342
prompt_store.clone(),
343+
prompt_capabilities.clone(),
339344
prevent_slash_commands,
340345
)
341346
});
@@ -371,6 +376,7 @@ impl AcpThreadView {
371376
editor_expanded: false,
372377
history_store,
373378
hovered_recent_history_item: None,
379+
prompt_capabilities,
374380
_subscriptions: subscriptions,
375381
_cancel_task: None,
376382
}
@@ -448,6 +454,9 @@ impl AcpThreadView {
448454
Ok(thread) => {
449455
let action_log = thread.read(cx).action_log().clone();
450456

457+
this.prompt_capabilities
458+
.set(connection.prompt_capabilities());
459+
451460
let count = thread.read(cx).entries().len();
452461
this.list_state.splice(0..0, count);
453462
this.entry_view_state.update(cx, |view_state, cx| {
@@ -523,11 +532,6 @@ impl AcpThreadView {
523532
})
524533
});
525534

526-
this.message_editor.update(cx, |message_editor, _cx| {
527-
message_editor
528-
.set_prompt_capabilities(connection.prompt_capabilities());
529-
});
530-
531535
cx.notify();
532536
}
533537
Err(err) => {

0 commit comments

Comments
 (0)