acp: Use ResourceLink for agents that don't support embedded context (#36687)

The completion provider was already limiting the mention kinds according
to `acp::PromptCapabilities`. However, it was still using
`ContentBlock::EmbeddedResource` when
`acp::PromptCapabilities::embedded_context` was `false`. We will now use
`ResourceLink` in that case making it more complaint with the
specification.

Release Notes:

- N/A
This commit is contained in:
Agus Zubiaga 2025-08-21 11:57:46 -03:00 committed by GitHub
parent f23314bef4
commit 4bee06e507
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -709,9 +709,13 @@ impl MessageEditor {
window: &mut Window,
cx: &mut Context<Self>,
) -> Task<Result<(Vec<acp::ContentBlock>, Vec<Entity<Buffer>>)>> {
let contents =
self.mention_set
.contents(&self.project, self.prompt_store.as_ref(), window, cx);
let contents = self.mention_set.contents(
&self.project,
self.prompt_store.as_ref(),
&self.prompt_capabilities.get(),
window,
cx,
);
let editor = self.editor.clone();
let prevent_slash_commands = self.prevent_slash_commands;
@ -776,6 +780,17 @@ impl MessageEditor {
.map(|path| format!("file://{}", path.display())),
})
}
Mention::UriOnly(uri) => {
acp::ContentBlock::ResourceLink(acp::ResourceLink {
name: uri.name(),
uri: uri.to_uri().to_string(),
annotations: None,
description: None,
mime_type: None,
size: None,
title: None,
})
}
};
chunks.push(chunk);
ix = crease_range.end;
@ -1418,6 +1433,7 @@ pub enum Mention {
tracked_buffers: Vec<Entity<Buffer>>,
},
Image(MentionImage),
UriOnly(MentionUri),
}
#[derive(Clone, Debug, Eq, PartialEq)]
@ -1481,9 +1497,20 @@ impl MentionSet {
&self,
project: &Entity<Project>,
prompt_store: Option<&Entity<PromptStore>>,
prompt_capabilities: &acp::PromptCapabilities,
_window: &mut Window,
cx: &mut App,
) -> Task<Result<HashMap<CreaseId, Mention>>> {
if !prompt_capabilities.embedded_context {
let mentions = self
.uri_by_crease_id
.iter()
.map(|(crease_id, uri)| (*crease_id, Mention::UriOnly(uri.clone())))
.collect();
return Task::ready(Ok(mentions));
}
let mut processed_image_creases = HashSet::default();
let mut contents = self
@ -2180,11 +2207,21 @@ mod tests {
assert_eq!(fold_ranges(editor, cx).len(), 1);
});
let all_prompt_capabilities = acp::PromptCapabilities {
image: true,
audio: true,
embedded_context: true,
};
let contents = message_editor
.update_in(&mut cx, |message_editor, window, cx| {
message_editor
.mention_set()
.contents(&project, None, window, cx)
message_editor.mention_set().contents(
&project,
None,
&all_prompt_capabilities,
window,
cx,
)
})
.await
.unwrap()
@ -2199,6 +2236,28 @@ mod tests {
pretty_assertions::assert_eq!(uri, &url_one.parse::<MentionUri>().unwrap());
}
let contents = message_editor
.update_in(&mut cx, |message_editor, window, cx| {
message_editor.mention_set().contents(
&project,
None,
&acp::PromptCapabilities::default(),
window,
cx,
)
})
.await
.unwrap()
.into_values()
.collect::<Vec<_>>();
{
let [Mention::UriOnly(uri)] = contents.as_slice() else {
panic!("Unexpected mentions");
};
pretty_assertions::assert_eq!(uri, &url_one.parse::<MentionUri>().unwrap());
}
cx.simulate_input(" ");
editor.update(&mut cx, |editor, cx| {
@ -2234,9 +2293,13 @@ mod tests {
let contents = message_editor
.update_in(&mut cx, |message_editor, window, cx| {
message_editor
.mention_set()
.contents(&project, None, window, cx)
message_editor.mention_set().contents(
&project,
None,
&all_prompt_capabilities,
window,
cx,
)
})
.await
.unwrap()
@ -2344,9 +2407,13 @@ mod tests {
let contents = message_editor
.update_in(&mut cx, |message_editor, window, cx| {
message_editor
.mention_set()
.contents(&project, None, window, cx)
message_editor.mention_set().contents(
&project,
None,
&all_prompt_capabilities,
window,
cx,
)
})
.await
.unwrap()