assistant_example.rs

  1use anyhow::Context as _;
  2use assets::Assets;
  3use assistant2::{tools::ProjectIndexTool, AssistantPanel};
  4use assistant_tooling::ToolRegistry;
  5use client::Client;
  6use gpui::{actions, App, AppContext, KeyBinding, Task, View, WindowOptions};
  7use language::LanguageRegistry;
  8use project::Project;
  9use semantic_index::{OpenAiEmbeddingModel, OpenAiEmbeddingProvider, SemanticIndex};
 10use settings::{KeymapFile, DEFAULT_KEYMAP_PATH};
 11use std::{
 12    path::{Path, PathBuf},
 13    sync::Arc,
 14};
 15use theme::LoadThemes;
 16use ui::{div, prelude::*, Render};
 17use util::{http::HttpClientWithUrl, ResultExt as _};
 18
 19actions!(example, [Quit]);
 20
 21fn main() {
 22    let args: Vec<String> = std::env::args().collect();
 23
 24    env_logger::init();
 25    App::new().with_assets(Assets).run(|cx| {
 26        cx.bind_keys(Some(KeyBinding::new("cmd-q", Quit, None)));
 27        cx.on_action(|_: &Quit, cx: &mut AppContext| {
 28            cx.quit();
 29        });
 30
 31        if args.len() < 2 {
 32            eprintln!(
 33                "Usage: cargo run --example assistant_example -p assistant2 -- <project_path>"
 34            );
 35            cx.quit();
 36            return;
 37        }
 38
 39        settings::init(cx);
 40        language::init(cx);
 41        Project::init_settings(cx);
 42        editor::init(cx);
 43        theme::init(LoadThemes::JustBase, cx);
 44        Assets.load_fonts(cx).unwrap();
 45        KeymapFile::load_asset(DEFAULT_KEYMAP_PATH, cx).unwrap();
 46        client::init_settings(cx);
 47        release_channel::init("0.130.0", cx);
 48
 49        let client = Client::production(cx);
 50        {
 51            let client = client.clone();
 52            cx.spawn(|cx| async move { client.authenticate_and_connect(false, &cx).await })
 53                .detach_and_log_err(cx);
 54        }
 55        assistant2::init(client.clone(), cx);
 56
 57        let language_registry = Arc::new(LanguageRegistry::new(
 58            Task::ready(()),
 59            cx.background_executor().clone(),
 60        ));
 61        let node_runtime = node_runtime::RealNodeRuntime::new(client.http_client());
 62        languages::init(language_registry.clone(), node_runtime, cx);
 63
 64        let http = Arc::new(HttpClientWithUrl::new("http://localhost:11434"));
 65
 66        let api_key = std::env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY not set");
 67        let embedding_provider = OpenAiEmbeddingProvider::new(
 68            http.clone(),
 69            OpenAiEmbeddingModel::TextEmbedding3Small,
 70            open_ai::OPEN_AI_API_URL.to_string(),
 71            api_key,
 72        );
 73
 74        cx.spawn(|mut cx| async move {
 75            let mut semantic_index = SemanticIndex::new(
 76                PathBuf::from("/tmp/semantic-index-db.mdb"),
 77                Arc::new(embedding_provider),
 78                &mut cx,
 79            )
 80            .await?;
 81
 82            let project_path = Path::new(&args[1]);
 83            let project = Project::example([project_path], &mut cx).await;
 84
 85            cx.update(|cx| {
 86                let fs = project.read(cx).fs().clone();
 87
 88                let project_index = semantic_index.project_index(project.clone(), cx);
 89
 90                let mut tool_registry = ToolRegistry::new();
 91                tool_registry
 92                    .register(ProjectIndexTool::new(project_index.clone(), fs.clone()))
 93                    .context("failed to register ProjectIndexTool")
 94                    .log_err();
 95
 96                let tool_registry = Arc::new(tool_registry);
 97
 98                cx.open_window(WindowOptions::default(), |cx| {
 99                    cx.new_view(|cx| Example::new(language_registry, tool_registry, cx))
100                });
101                cx.activate(true);
102            })
103        })
104        .detach_and_log_err(cx);
105    })
106}
107
108struct Example {
109    assistant_panel: View<AssistantPanel>,
110}
111
112impl Example {
113    fn new(
114        language_registry: Arc<LanguageRegistry>,
115        tool_registry: Arc<ToolRegistry>,
116        cx: &mut ViewContext<Self>,
117    ) -> Self {
118        Self {
119            assistant_panel: cx
120                .new_view(|cx| AssistantPanel::new(language_registry, tool_registry, cx)),
121        }
122    }
123}
124
125impl Render for Example {
126    fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl ui::prelude::IntoElement {
127        div().size_full().child(self.assistant_panel.clone())
128    }
129}