1use gpui::SharedString;
2use language_model::{LanguageModelRequestMessage, MessageContent};
3use serde::{Deserialize, Serialize};
4use util::post_inc;
5
6#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize)]
7pub struct ContextId(pub(crate) usize);
8
9impl ContextId {
10 pub fn post_inc(&mut self) -> Self {
11 Self(post_inc(&mut self.0))
12 }
13}
14
15/// Some context attached to a message in a thread.
16#[derive(Debug, Clone)]
17pub struct Context {
18 pub id: ContextId,
19 pub name: SharedString,
20 pub kind: ContextKind,
21 pub text: SharedString,
22}
23
24#[derive(Debug, Clone, PartialEq, Eq, Hash)]
25pub enum ContextKind {
26 File,
27 FetchedUrl,
28 Thread,
29}
30
31pub fn attach_context_to_message(
32 message: &mut LanguageModelRequestMessage,
33 context: impl IntoIterator<Item = Context>,
34) {
35 let mut file_context = String::new();
36 let mut fetch_context = String::new();
37 let mut thread_context = String::new();
38
39 for context in context.into_iter() {
40 match context.kind {
41 ContextKind::File => {
42 file_context.push_str(&context.text);
43 file_context.push('\n');
44 }
45 ContextKind::FetchedUrl => {
46 fetch_context.push_str(&context.name);
47 fetch_context.push('\n');
48 fetch_context.push_str(&context.text);
49 fetch_context.push('\n');
50 }
51 ContextKind::Thread => {
52 thread_context.push_str(&context.name);
53 thread_context.push('\n');
54 thread_context.push_str(&context.text);
55 thread_context.push('\n');
56 }
57 }
58 }
59
60 let mut context_text = String::new();
61 if !file_context.is_empty() {
62 context_text.push_str("The following files are available:\n");
63 context_text.push_str(&file_context);
64 }
65
66 if !fetch_context.is_empty() {
67 context_text.push_str("The following fetched results are available\n");
68 context_text.push_str(&fetch_context);
69 }
70
71 if !thread_context.is_empty() {
72 context_text.push_str("The following previous conversation threads are available\n");
73 context_text.push_str(&thread_context);
74 }
75
76 message.content.push(MessageContent::Text(context_text));
77}