1use editor::MultiBuffer;
2use gpui::{AppContext, Model, ModelContext, Subscription};
3
4use crate::{assistant_panel::Conversation, LanguageModelRequestMessage, Role};
5
6#[derive(Default)]
7pub struct EmbeddedScope {
8 active_buffer: Option<Model<MultiBuffer>>,
9 active_buffer_enabled: bool,
10 active_buffer_subscription: Option<Subscription>,
11}
12
13impl EmbeddedScope {
14 pub fn new() -> Self {
15 Self {
16 active_buffer: None,
17 active_buffer_enabled: true,
18 active_buffer_subscription: None,
19 }
20 }
21
22 pub fn set_active_buffer(
23 &mut self,
24 buffer: Option<Model<MultiBuffer>>,
25 cx: &mut ModelContext<Conversation>,
26 ) {
27 self.active_buffer_subscription.take();
28
29 if let Some(active_buffer) = buffer.clone() {
30 self.active_buffer_subscription =
31 Some(cx.subscribe(&active_buffer, |conversation, _, e, cx| {
32 if let multi_buffer::Event::Edited { .. } = e {
33 conversation.count_remaining_tokens(cx)
34 }
35 }));
36 }
37
38 self.active_buffer = buffer;
39 }
40
41 pub fn active_buffer(&self) -> Option<&Model<MultiBuffer>> {
42 self.active_buffer.as_ref()
43 }
44
45 pub fn active_buffer_enabled(&self) -> bool {
46 self.active_buffer_enabled
47 }
48
49 pub fn set_active_buffer_enabled(&mut self, enabled: bool) {
50 self.active_buffer_enabled = enabled;
51 }
52
53 /// Provide a message for the language model based on the active buffer.
54 pub fn message(&self, cx: &AppContext) -> Option<LanguageModelRequestMessage> {
55 if !self.active_buffer_enabled {
56 return None;
57 }
58
59 let active_buffer = self.active_buffer.as_ref()?;
60 let buffer = active_buffer.read(cx);
61
62 if let Some(singleton) = buffer.as_singleton() {
63 let singleton = singleton.read(cx);
64
65 let filename = singleton
66 .file()
67 .map(|file| file.path().to_string_lossy())
68 .unwrap_or("Untitled".into());
69
70 let text = singleton.text();
71
72 let language = singleton
73 .language()
74 .map(|l| {
75 let name = l.code_fence_block_name();
76 name.to_string()
77 })
78 .unwrap_or_default();
79
80 let markdown =
81 format!("User's active file `{filename}`:\n\n```{language}\n{text}```\n\n");
82
83 return Some(LanguageModelRequestMessage {
84 role: Role::System,
85 content: markdown,
86 });
87 }
88
89 None
90 }
91}