- `language_model` no longer depends on provider-specific crates such as `anthropic` and `open_ai` (inverted dependency) - `language_model_core` was extracted from `language_model` which contains the types for the provider-specific crates to convert to/from. - `gpui::SharedString` has been extracted into its own crate (still exposed by `gpui`), so `language_model_core` and provider API crates don't have to depend on `gpui`. - Removes some unnecessary `&'static str` | `SharedString` -> `String` -> `SharedString` conversions across the codebase. - Extracts the core logic of the cloud `LanguageModelProvider` into its own crate with simpler dependencies. Release Notes: - N/A --------- Co-authored-by: John Tur <john-tur@outlook.com>
75 lines
2.2 KiB
Rust
75 lines
2.2 KiB
Rust
use std::sync::Arc;
|
|
|
|
use cloud_api_types::OrganizationId;
|
|
use smol::lock::{RwLock, RwLockUpgradableReadGuard, RwLockWriteGuard};
|
|
|
|
use crate::{ClientApiError, CloudApiClient};
|
|
|
|
#[derive(Clone, Default)]
|
|
pub struct LlmApiToken(Arc<RwLock<Option<String>>>);
|
|
|
|
impl LlmApiToken {
|
|
pub async fn acquire(
|
|
&self,
|
|
client: &CloudApiClient,
|
|
system_id: Option<String>,
|
|
organization_id: Option<OrganizationId>,
|
|
) -> Result<String, ClientApiError> {
|
|
let lock = self.0.upgradable_read().await;
|
|
if let Some(token) = lock.as_ref() {
|
|
Ok(token.to_string())
|
|
} else {
|
|
Self::fetch(
|
|
RwLockUpgradableReadGuard::upgrade(lock).await,
|
|
client,
|
|
system_id,
|
|
organization_id,
|
|
)
|
|
.await
|
|
}
|
|
}
|
|
|
|
pub async fn refresh(
|
|
&self,
|
|
client: &CloudApiClient,
|
|
system_id: Option<String>,
|
|
organization_id: Option<OrganizationId>,
|
|
) -> Result<String, ClientApiError> {
|
|
Self::fetch(self.0.write().await, client, system_id, organization_id).await
|
|
}
|
|
|
|
/// Clears the existing token before attempting to fetch a new one.
|
|
///
|
|
/// Used when switching organizations so that a failed refresh doesn't
|
|
/// leave a token for the wrong organization.
|
|
pub async fn clear_and_refresh(
|
|
&self,
|
|
client: &CloudApiClient,
|
|
system_id: Option<String>,
|
|
organization_id: Option<OrganizationId>,
|
|
) -> Result<String, ClientApiError> {
|
|
let mut lock = self.0.write().await;
|
|
*lock = None;
|
|
Self::fetch(lock, client, system_id, organization_id).await
|
|
}
|
|
|
|
async fn fetch(
|
|
mut lock: RwLockWriteGuard<'_, Option<String>>,
|
|
client: &CloudApiClient,
|
|
system_id: Option<String>,
|
|
organization_id: Option<OrganizationId>,
|
|
) -> Result<String, ClientApiError> {
|
|
let result = client.create_llm_token(system_id, organization_id).await;
|
|
match result {
|
|
Ok(response) => {
|
|
*lock = Some(response.token.0.clone());
|
|
Ok(response.token.0)
|
|
}
|
|
Err(err) => {
|
|
*lock = None;
|
|
Err(err)
|
|
}
|
|
}
|
|
}
|
|
}
|