subx_cli/services/ai/
mod.rs1use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5
6#[async_trait]
8pub trait AIProvider: Send + Sync {
9 async fn analyze_content(&self, request: AnalysisRequest) -> crate::Result<MatchResult>;
11 async fn verify_match(
13 &self,
14 verification: VerificationRequest,
15 ) -> crate::Result<ConfidenceScore>;
16}
17
18#[derive(Debug, Serialize, Clone, PartialEq, Eq)]
20pub struct AnalysisRequest {
21 pub video_files: Vec<String>,
22 pub subtitle_files: Vec<String>,
23 pub content_samples: Vec<ContentSample>,
24}
25
26#[derive(Debug, Serialize, Clone, PartialEq, Eq)]
28pub struct ContentSample {
29 pub filename: String,
30 pub content_preview: String,
31 pub file_size: u64,
32}
33
34#[derive(Debug, Deserialize, Clone, PartialEq)]
36pub struct MatchResult {
37 pub matches: Vec<FileMatch>,
38 pub confidence: f32,
39 pub reasoning: String,
40}
41
42#[derive(Debug, Deserialize, Clone, PartialEq)]
44pub struct FileMatch {
45 pub video_file: String,
46 pub subtitle_file: String,
47 pub confidence: f32,
48 pub match_factors: Vec<String>,
49}
50
51#[derive(Debug, Deserialize, Clone, PartialEq)]
53pub struct ConfidenceScore {
54 pub score: f32,
55 pub factors: Vec<String>,
56}
57
58#[derive(Debug, Serialize, Clone, PartialEq, Eq)]
60pub struct VerificationRequest {
61 pub video_file: String,
62 pub subtitle_file: String,
63 pub match_factors: Vec<String>,
64}
65
66#[derive(Debug, Clone)]
68pub struct AiUsageStats {
69 pub model: String,
71 pub prompt_tokens: u32,
73 pub completion_tokens: u32,
75 pub total_tokens: u32,
77}
78
79#[derive(Debug, Clone)]
81pub struct AiResponse {
82 pub content: String,
84 pub usage: Option<AiUsageStats>,
86}
87
88pub mod cache;
89pub mod factory;
90pub mod openai;
91pub mod prompts;
92pub mod retry;
93
94pub use cache::AICache;
95pub use factory::AIClientFactory;
96pub use openai::OpenAIClient;
97pub use retry::{RetryConfig, retry_with_backoff};