context.rs

 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    Directory,
28    FetchedUrl,
29    Thread,
30}
31
32pub fn attach_context_to_message(
33    message: &mut LanguageModelRequestMessage,
34    context: impl IntoIterator<Item = Context>,
35) {
36    let mut file_context = String::new();
37    let mut directory_context = String::new();
38    let mut fetch_context = String::new();
39    let mut thread_context = String::new();
40
41    for context in context.into_iter() {
42        match context.kind {
43            ContextKind::File => {
44                file_context.push_str(&context.text);
45                file_context.push('\n');
46            }
47            ContextKind::Directory => {
48                directory_context.push_str(&context.text);
49                directory_context.push('\n');
50            }
51            ContextKind::FetchedUrl => {
52                fetch_context.push_str(&context.name);
53                fetch_context.push('\n');
54                fetch_context.push_str(&context.text);
55                fetch_context.push('\n');
56            }
57            ContextKind::Thread => {
58                thread_context.push_str(&context.name);
59                thread_context.push('\n');
60                thread_context.push_str(&context.text);
61                thread_context.push('\n');
62            }
63        }
64    }
65
66    let mut context_text = String::new();
67    if !file_context.is_empty() {
68        context_text.push_str("The following files are available:\n");
69        context_text.push_str(&file_context);
70    }
71
72    if !directory_context.is_empty() {
73        context_text.push_str("The following directories are available:\n");
74        context_text.push_str(&directory_context);
75    }
76
77    if !fetch_context.is_empty() {
78        context_text.push_str("The following fetched results are available\n");
79        context_text.push_str(&fetch_context);
80    }
81
82    if !thread_context.is_empty() {
83        context_text.push_str("The following previous conversation threads are available\n");
84        context_text.push_str(&thread_context);
85    }
86
87    if !context_text.is_empty() {
88        message.content.push(MessageContent::Text(context_text));
89    }
90}