1use crate::mention_set::Mention;
2use gpui::{AppContext as _, Entity, Task};
3use language_model::{LanguageModelImage, LanguageModelRequestMessage, MessageContent};
4use ui::App;
5use util::ResultExt as _;
6
7use crate::mention_set::MentionSet;
8
9#[derive(Debug, Clone, Default)]
10pub struct LoadedContext {
11 pub text: String,
12 pub images: Vec<LanguageModelImage>,
13}
14
15impl LoadedContext {
16 pub fn add_to_request_message(&self, request_message: &mut LanguageModelRequestMessage) {
17 if !self.text.is_empty() {
18 request_message
19 .content
20 .push(MessageContent::Text(self.text.to_string()));
21 }
22
23 if !self.images.is_empty() {
24 // Some providers only support image parts after an initial text part
25 if request_message.content.is_empty() {
26 request_message
27 .content
28 .push(MessageContent::Text("Images attached by user:".to_string()));
29 }
30
31 for image in &self.images {
32 request_message
33 .content
34 .push(MessageContent::Image(image.clone()))
35 }
36 }
37 }
38}
39
40/// Loads and formats a collection of contexts.
41pub fn load_context(mention_set: &Entity<MentionSet>, cx: &mut App) -> Task<Option<LoadedContext>> {
42 let task = mention_set.update(cx, |mention_set, cx| mention_set.contents(true, cx));
43 cx.background_spawn(async move {
44 let mentions = task.await.log_err()?;
45 let mut loaded_context = LoadedContext::default();
46 loaded_context
47 .text
48 .push_str("The following items were attached by the user.\n");
49 for (_, (_, mention)) in mentions {
50 match mention {
51 Mention::Text { content, .. } => {
52 loaded_context.text.push_str(&content);
53 }
54 Mention::Image(mention_image) => loaded_context.images.push(LanguageModelImage {
55 source: mention_image.data,
56 ..LanguageModelImage::empty()
57 }),
58 Mention::Link => {}
59 }
60 }
61 Some(loaded_context)
62 })
63}