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    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}