Skip to main content

locus_sdk/domain/
ai.rs

1use anyhow::Result;
2use async_trait::async_trait;
3use locus_core_rs::domain::models::AvecState;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum AiCapability {
7    SemanticEmbedding,
8    AvecEmbedding,
9    AvecScoring,
10}
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum AiTask {
14    SemanticEmbedding,
15    AvecEmbedding,
16    AvecScoring,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum ProviderPolicy {
21    Auto,
22    Preferred,
23    Required,
24}
25
26#[derive(Debug, Clone)]
27pub struct EmbedRequest {
28    pub text: String,
29    pub task: AiTask,
30    pub provider_id: Option<String>,
31    pub model: Option<String>,
32    pub policy: ProviderPolicy,
33}
34
35#[derive(Debug, Clone)]
36pub struct ScoreAvecRequest {
37    pub text: String,
38    pub provider_id: Option<String>,
39    pub model: Option<String>,
40    pub policy: ProviderPolicy,
41}
42
43#[async_trait]
44pub trait AiProvider: Send + Sync {
45    fn provider_id(&self) -> &str;
46    fn capabilities(&self) -> &'static [AiCapability];
47
48    async fn embed_semantic(&self, request: &EmbedRequest) -> Result<Vec<f32>>;
49
50    async fn embed_avec(&self, request: &EmbedRequest) -> Result<Vec<f32>>;
51
52    async fn score_avec(&self, request: &ScoreAvecRequest) -> Result<AvecState>;
53}
54
55pub trait AiProviderRegistry: Send + Sync {
56    fn resolve(
57        &self,
58        task: AiTask,
59        provider_id: Option<&str>,
60        policy: ProviderPolicy,
61    ) -> Result<&dyn AiProvider>;
62
63    fn list_capabilities(&self) -> Vec<(String, Vec<AiCapability>)>;
64}