collab: Add usages table to LLM database (#15884)

This PR adds a `usages` table to the LLM database.

We'll use this to track usage for rate-limiting purposes.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-08-06 18:40:10 -04:00 committed by GitHub
parent 4f69336024
commit a54e16b7ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 165 additions and 1 deletions

View file

@ -0,0 +1,57 @@
use rpc::LanguageModelProvider;
use super::*;
impl LlmDatabase {
pub async fn find_or_create_usage(
&self,
user_id: i32,
provider: LanguageModelProvider,
model_name: &str,
) -> Result<usage::Model> {
self.transaction(|tx| async move {
let provider_name = match provider {
LanguageModelProvider::Anthropic => "anthropic",
LanguageModelProvider::OpenAi => "open_ai",
LanguageModelProvider::Google => "google",
LanguageModelProvider::Zed => "zed",
};
let model = model::Entity::find()
.inner_join(provider::Entity)
.filter(
provider::Column::Name
.eq(provider_name)
.and(model::Column::Name.eq(model_name)),
)
.one(&*tx)
.await?
// TODO: Create the model, if one doesn't exist.
.ok_or_else(|| anyhow!("no model found for {provider_name}:{model_name}"))?;
let model_id = model.id;
let existing_usage = usage::Entity::find()
.filter(
usage::Column::UserId
.eq(user_id)
.and(usage::Column::ModelId.eq(model_id)),
)
.one(&*tx)
.await?;
if let Some(usage) = existing_usage {
return Ok(usage);
}
let usage = usage::Entity::insert(usage::ActiveModel {
user_id: ActiveValue::set(user_id),
model_id: ActiveValue::set(model_id),
..Default::default()
})
.exec_with_returning(&*tx)
.await?;
Ok(usage)
})
.await
}
}