active_thread.rs

 1use languages::LanguageRegistry;
 2use project::Project;
 3use std::sync::Arc;
 4
 5use agent::{ActiveThread, ContextStore, MessageSegment, ThreadStore};
 6use assistant_tool::ToolWorkingSet;
 7use gpui::{AppContext, AsyncApp, Entity, Task, WeakEntity};
 8use prompt_store::PromptBuilder;
 9use ui::{App, Window};
10use workspace::Workspace;
11
12pub async fn load_preview_thread_store(
13    workspace: WeakEntity<Workspace>,
14    project: Entity<Project>,
15    cx: &mut AsyncApp,
16) -> Task<anyhow::Result<Entity<ThreadStore>>> {
17    cx.spawn(async move |cx| {
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            .await
29    })
30}
31
32pub fn static_active_thread(
33    workspace: WeakEntity<Workspace>,
34    project: Entity<Project>,
35    language_registry: Arc<LanguageRegistry>,
36    thread_store: Entity<ThreadStore>,
37    window: &mut Window,
38    cx: &mut App,
39) -> Entity<ActiveThread> {
40    let context_store =
41        cx.new(|_| ContextStore::new(project.downgrade(), Some(thread_store.downgrade())));
42
43    let thread = thread_store.update(cx, |thread_store, cx| thread_store.create_thread(cx));
44    thread.update(cx, |thread, cx| {
45        thread.insert_assistant_message(vec![
46            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()),
47            MessageSegment::Text("\n\nLet's look at what's happening in your code:".to_string()),
48            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()),
49            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()),
50            MessageSegment::Text("\n\n1. `load_preview_thread_store` returns a `Task<anyhow::Result<Entity<ThreadStore>>>`, which means it's already a task".to_string()),
51            MessageSegment::Text("\n2. When you call this function inside another `spawn` call, you're nesting tasks incorrectly".to_string()),
52            MessageSegment::Text("\n3. The `this` parameter you're trying to use in your closure has the wrong context".to_string()),
53            MessageSegment::Text("\n\nHere's the correct way to implement this:".to_string()),
54            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()),
55            MessageSegment::Text("\n\nHere's how to fix it:".to_string()),
56        ], cx);
57    });
58    cx.new(|cx| {
59        ActiveThread::new(
60            thread,
61            thread_store,
62            context_store,
63            language_registry,
64            workspace.clone(),
65            window,
66            cx,
67        )
68    })
69}