1use agent::{ActiveThread, ContextStore, MessageSegment, TextThreadStore, ThreadStore};
2use anyhow::{Result, anyhow};
3use assistant_tool::ToolWorkingSet;
4use gpui::{AppContext, AsyncApp, Entity, Task, WeakEntity};
5use indoc::indoc;
6use languages::LanguageRegistry;
7use project::Project;
8use prompt_store::PromptBuilder;
9use std::sync::Arc;
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(indoc! {"
64 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.
65
66 Let's look at what's happening in your code:
67
68 ---
69
70 Let's check the current state of the active_thread.rs file to understand what might have changed:
71
72 ---
73
74 Looking at the implementation of `load_preview_thread_store` and understanding GPUI's async patterns, here's the issue:
75
76 1. `load_preview_thread_store` returns a `Task<anyhow::Result<Entity<ThreadStore>>>`, which means it's already a task.
77 2. When you call this function inside another `spawn` call, you're nesting tasks incorrectly.
78
79 Here's the correct way to implement this:
80
81 ---
82
83 The 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.
84
85 Here's how to fix it:
86 "}.to_string()),
87 ], cx);
88 });
89 cx.new(|cx| {
90 ActiveThread::new(
91 thread,
92 thread_store,
93 text_thread_store,
94 context_store,
95 language_registry,
96 workspace.clone(),
97 window,
98 cx,
99 )
100 })
101}