language_model.rs

  1mod model;
  2pub mod provider;
  3mod rate_limiter;
  4mod registry;
  5mod request;
  6mod role;
  7pub mod settings;
  8
  9use anyhow::Result;
 10use client::{Client, UserStore};
 11use futures::{future::BoxFuture, stream::BoxStream};
 12use gpui::{AnyView, AppContext, AsyncAppContext, Model, SharedString, Task, WindowContext};
 13pub use model::*;
 14use project::Fs;
 15use proto::Plan;
 16pub(crate) use rate_limiter::*;
 17pub use registry::*;
 18pub use request::*;
 19pub use role::*;
 20use schemars::JsonSchema;
 21use serde::de::DeserializeOwned;
 22use std::{future::Future, sync::Arc};
 23use ui::IconName;
 24
 25pub fn init(
 26    user_store: Model<UserStore>,
 27    client: Arc<Client>,
 28    fs: Arc<dyn Fs>,
 29    cx: &mut AppContext,
 30) {
 31    settings::init(fs, cx);
 32    registry::init(user_store, client, cx);
 33}
 34
 35/// The availability of a [`LanguageModel`].
 36#[derive(Debug, PartialEq, Eq, Clone, Copy)]
 37pub enum LanguageModelAvailability {
 38    /// The language model is available to the general public.
 39    Public,
 40    /// The language model is available to users on the indicated plan.
 41    RequiresPlan(Plan),
 42}
 43
 44pub trait LanguageModel: Send + Sync {
 45    fn id(&self) -> LanguageModelId;
 46    fn name(&self) -> LanguageModelName;
 47    fn provider_id(&self) -> LanguageModelProviderId;
 48    fn provider_name(&self) -> LanguageModelProviderName;
 49    fn telemetry_id(&self) -> String;
 50
 51    /// Returns the availability of this language model.
 52    fn availability(&self) -> LanguageModelAvailability {
 53        LanguageModelAvailability::Public
 54    }
 55
 56    fn max_token_count(&self) -> usize;
 57
 58    fn count_tokens(
 59        &self,
 60        request: LanguageModelRequest,
 61        cx: &AppContext,
 62    ) -> BoxFuture<'static, Result<usize>>;
 63
 64    fn stream_completion(
 65        &self,
 66        request: LanguageModelRequest,
 67        cx: &AsyncAppContext,
 68    ) -> BoxFuture<'static, Result<BoxStream<'static, Result<String>>>>;
 69
 70    fn use_any_tool(
 71        &self,
 72        request: LanguageModelRequest,
 73        name: String,
 74        description: String,
 75        schema: serde_json::Value,
 76        cx: &AsyncAppContext,
 77    ) -> BoxFuture<'static, Result<serde_json::Value>>;
 78
 79    #[cfg(any(test, feature = "test-support"))]
 80    fn as_fake(&self) -> &provider::fake::FakeLanguageModel {
 81        unimplemented!()
 82    }
 83}
 84
 85impl dyn LanguageModel {
 86    pub fn use_tool<T: LanguageModelTool>(
 87        &self,
 88        request: LanguageModelRequest,
 89        cx: &AsyncAppContext,
 90    ) -> impl 'static + Future<Output = Result<T>> {
 91        let schema = schemars::schema_for!(T);
 92        let schema_json = serde_json::to_value(&schema).unwrap();
 93        let request = self.use_any_tool(request, T::name(), T::description(), schema_json, cx);
 94        async move {
 95            let response = request.await?;
 96            Ok(serde_json::from_value(response)?)
 97        }
 98    }
 99}
100
101pub trait LanguageModelTool: 'static + DeserializeOwned + JsonSchema {
102    fn name() -> String;
103    fn description() -> String;
104}
105
106pub trait LanguageModelProvider: 'static {
107    fn id(&self) -> LanguageModelProviderId;
108    fn name(&self) -> LanguageModelProviderName;
109    fn icon(&self) -> IconName {
110        IconName::ZedAssistant
111    }
112    fn provided_models(&self, cx: &AppContext) -> Vec<Arc<dyn LanguageModel>>;
113    fn load_model(&self, _model: Arc<dyn LanguageModel>, _cx: &AppContext) {}
114    fn is_authenticated(&self, cx: &AppContext) -> bool;
115    fn authenticate(&self, cx: &mut AppContext) -> Task<Result<()>>;
116    fn configuration_view(&self, cx: &mut WindowContext) -> AnyView;
117    fn reset_credentials(&self, cx: &mut AppContext) -> Task<Result<()>>;
118}
119
120pub trait LanguageModelProviderState: 'static {
121    type ObservableEntity;
122
123    fn observable_entity(&self) -> Option<gpui::Model<Self::ObservableEntity>>;
124
125    fn subscribe<T: 'static>(
126        &self,
127        cx: &mut gpui::ModelContext<T>,
128        callback: impl Fn(&mut T, &mut gpui::ModelContext<T>) + 'static,
129    ) -> Option<gpui::Subscription> {
130        let entity = self.observable_entity()?;
131        Some(cx.observe(&entity, move |this, _, cx| {
132            callback(this, cx);
133        }))
134    }
135}
136
137#[derive(Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
138pub struct LanguageModelId(pub SharedString);
139
140#[derive(Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
141pub struct LanguageModelName(pub SharedString);
142
143#[derive(Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
144pub struct LanguageModelProviderId(pub SharedString);
145
146#[derive(Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
147pub struct LanguageModelProviderName(pub SharedString);
148
149impl From<String> for LanguageModelId {
150    fn from(value: String) -> Self {
151        Self(SharedString::from(value))
152    }
153}
154
155impl From<String> for LanguageModelName {
156    fn from(value: String) -> Self {
157        Self(SharedString::from(value))
158    }
159}
160
161impl From<String> for LanguageModelProviderId {
162    fn from(value: String) -> Self {
163        Self(SharedString::from(value))
164    }
165}
166
167impl From<String> for LanguageModelProviderName {
168    fn from(value: String) -> Self {
169        Self(SharedString::from(value))
170    }
171}