active_thread.rs

 1use languages::LanguageRegistry;
 2use project::Project;
 3use std::sync::Arc;
 4
 5use agent::{ActiveThread, ContextStore, MessageSegment, TextThreadStore, ThreadStore};
 6use anyhow::{Result, anyhow};
 7use assistant_tool::ToolWorkingSet;
 8use gpui::{AppContext, AsyncApp, Entity, Task, WeakEntity};
 9use prompt_store::PromptBuilder;
10use ui::{App, Window};
11use workspace::Workspace;
12
13pub fn load_preview_thread_store(
14    workspace: WeakEntity<Workspace>,
15    project: Entity<Project>,
16    cx: &mut AsyncApp,
17) -> Task<Result<Entity<ThreadStore>>> {
18    workspace
19        .update(cx, |_, cx| {
20            ThreadStore::load(
21                project.clone(),
22                cx.new(|_| ToolWorkingSet::default()),
23                None,
24                Arc::new(PromptBuilder::new(None).unwrap()),
25                cx,
26            )
27        })
28        .unwrap_or(Task::ready(Err(anyhow!("workspace dropped"))))
29}
30
31pub fn load_preview_text_thread_store(
32    workspace: WeakEntity<Workspace>,
33    project: Entity<Project>,
34    cx: &mut AsyncApp,
35) -> Task<Result<Entity<TextThreadStore>>> {
36    workspace
37        .update(cx, |_, cx| {
38            TextThreadStore::new(
39                project.clone(),
40                Arc::new(PromptBuilder::new(None).unwrap()),
41                Default::default(),
42                cx,
43            )
44        })
45        .unwrap_or(Task::ready(Err(anyhow!("workspace dropped"))))
46}
47
48pub fn static_active_thread(
49    workspace: WeakEntity<Workspace>,
50    project: Entity<Project>,
51    language_registry: Arc<LanguageRegistry>,
52    thread_store: Entity<ThreadStore>,
53    text_thread_store: Entity<TextThreadStore>,
54    window: &mut Window,
55    cx: &mut App,
56) -> Entity<ActiveThread> {
57    let context_store =
58        cx.new(|_| ContextStore::new(project.downgrade(), Some(thread_store.downgrade())));
59
60    let thread = thread_store.update(cx, |thread_store, cx| thread_store.create_thread(cx));
61    thread.update(cx, |thread, cx| {
62        thread.insert_assistant_message(vec![
63            MessageSegment::Text("I'll help you fix the lifetime error in your `cx.spawn` call. When working with async operations in GPUI, there are specific patterns to follow for proper lifetime management.".to_string()),
64            MessageSegment::Text("\n\nLet's look at what's happening in your code:".to_string()),
65            MessageSegment::Text("\n\n---\n\nLet's check the current state of the active_thread.rs file to understand what might have changed:".to_string()),
66            MessageSegment::Text("\n\n---\n\nLooking at the implementation of `load_preview_thread_store` and understanding GPUI's async patterns, here's the issue:".to_string()),
67            MessageSegment::Text("\n\n1. `load_preview_thread_store` returns a `Task<anyhow::Result<Entity<ThreadStore>>>`, which means it's already a task".to_string()),
68            MessageSegment::Text("\n2. When you call this function inside another `spawn` call, you're nesting tasks incorrectly".to_string()),
69            MessageSegment::Text("\n3. The `this` parameter you're trying to use in your closure has the wrong context".to_string()),
70            MessageSegment::Text("\n\nHere's the correct way to implement this:".to_string()),
71            MessageSegment::Text("\n\n---\n\nThe problem is in how you're setting up the async closure and trying to reference variables like `window` and `language_registry` that aren't accessible in that scope.".to_string()),
72            MessageSegment::Text("\n\nHere's how to fix it:".to_string()),
73        ], cx);
74    });
75    cx.new(|cx| {
76        ActiveThread::new(
77            thread,
78            thread_store,
79            text_thread_store,
80            context_store,
81            language_registry,
82            workspace.clone(),
83            window,
84            cx,
85        )
86    })
87}