usages.rs

 1use rpc::LanguageModelProvider;
 2
 3use super::*;
 4
 5impl LlmDatabase {
 6    pub async fn find_or_create_usage(
 7        &self,
 8        user_id: i32,
 9        provider: LanguageModelProvider,
10        model_name: &str,
11    ) -> Result<usage::Model> {
12        self.transaction(|tx| async move {
13            let provider_name = match provider {
14                LanguageModelProvider::Anthropic => "anthropic",
15                LanguageModelProvider::OpenAi => "open_ai",
16                LanguageModelProvider::Google => "google",
17                LanguageModelProvider::Zed => "zed",
18            };
19
20            let model = model::Entity::find()
21                .inner_join(provider::Entity)
22                .filter(
23                    provider::Column::Name
24                        .eq(provider_name)
25                        .and(model::Column::Name.eq(model_name)),
26                )
27                .one(&*tx)
28                .await?
29                // TODO: Create the model, if one doesn't exist.
30                .ok_or_else(|| anyhow!("no model found for {provider_name}:{model_name}"))?;
31            let model_id = model.id;
32
33            let existing_usage = usage::Entity::find()
34                .filter(
35                    usage::Column::UserId
36                        .eq(user_id)
37                        .and(usage::Column::ModelId.eq(model_id)),
38                )
39                .one(&*tx)
40                .await?;
41            if let Some(usage) = existing_usage {
42                return Ok(usage);
43            }
44
45            let usage = usage::Entity::insert(usage::ActiveModel {
46                user_id: ActiveValue::set(user_id),
47                model_id: ActiveValue::set(model_id),
48                ..Default::default()
49            })
50            .exec_with_returning(&*tx)
51            .await?;
52
53            Ok(usage)
54        })
55        .await
56    }
57}