pub mod codex_compat;
use crate::errors::AppError;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ExtractionHints {
pub memory_name: Option<String>,
pub memory_type: Option<String>,
pub existing_entities: Vec<String>,
pub skip_relations: bool,
pub seed: Option<u64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ExtractedEntity {
pub name: String,
pub entity_type: String,
pub description: Option<String>,
pub confidence: Option<f32>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ExtractedRelationship {
pub source: String,
pub target: String,
pub relation: String,
pub strength: f32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ExtractionOutput {
pub entities: Vec<ExtractedEntity>,
pub relationships: Vec<ExtractedRelationship>,
pub embedding: Option<Vec<f32>>,
pub backend: String,
pub elapsed_ms: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum BackendKind {
Llm,
Embedding,
None,
Composite,
}
impl BackendKind {
pub fn as_str(self) -> &'static str {
match self {
BackendKind::Llm => "llm",
BackendKind::Embedding => "embedding",
BackendKind::None => "none",
BackendKind::Composite => "composite",
}
}
pub fn parse(s: &str) -> Option<Self> {
match s.to_ascii_lowercase().as_str() {
"llm" => Some(BackendKind::Llm),
"embedding" => Some(BackendKind::Embedding),
"none" => Some(BackendKind::None),
"both" | "composite" => Some(BackendKind::Composite),
_ => None,
}
}
}
#[async_trait]
pub trait ExtractionBackend: Send + Sync {
fn kind(&self) -> BackendKind;
fn model_name(&self) -> String;
async fn extract(
&self,
content: &str,
hints: &ExtractionHints,
) -> Result<ExtractionOutput, AppError>;
async fn health(&self) -> Result<BackendHealth, AppError>;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BackendHealth {
pub kind: BackendKind,
pub healthy: bool,
pub model_name: String,
pub message: String,
}
pub type SharedBackend = Arc<dyn ExtractionBackend>;
pub mod composite_backend;
pub mod embedding_backend;
pub mod llm_backend;
pub mod llm_embedding;
pub mod none_backend;
pub use composite_backend::{backend_from_kind, default_backend, CompositeBackend};
pub use embedding_backend::EmbeddingBackend;
pub use llm_backend::{LlmBackend, LlmExtractorConfig};
pub use llm_embedding::{EmbeddingFlavour, LlmEmbedding};
pub use none_backend::NoneBackend;