use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
use crate::error::RerankError;
use crate::types::{RerankCandidate, RerankConfig, RerankResult};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RerankerBackendType {
Local,
Remote,
Plugin,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RerankerInfo {
pub name: String,
pub display_name: String,
pub backend_type: RerankerBackendType,
pub supports_batch: bool,
pub max_candidates: Option<usize>,
pub pricing: Option<RerankerPricing>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RerankerPricing {
pub cost_per_search: f64,
}
#[async_trait]
pub trait Reranker: Send + Sync + Debug {
async fn rerank(
&self,
query: &str,
candidates: Vec<RerankCandidate>,
config: &RerankConfig,
) -> Result<RerankResult, RerankError>;
async fn rerank_default(
&self,
query: &str,
candidates: Vec<RerankCandidate>,
) -> Result<RerankResult, RerankError> {
self.rerank(query, candidates, &RerankConfig::default()).await
}
fn reranker_info(&self) -> &RerankerInfo;
}
#[async_trait]
pub trait SignalPlugin: Send + Sync + Debug {
fn name(&self) -> &str;
fn weight_key(&self) -> &'static str;
async fn score(&self, query: &str, candidate: &RerankCandidate) -> Result<f32, RerankError>;
async fn score_batch(
&self,
query: &str,
candidates: &[RerankCandidate],
) -> Result<Vec<f32>, RerankError> {
use futures::future::join_all;
let futures: Vec<_> =
candidates.iter().map(|candidate| self.score(query, candidate)).collect();
let results = join_all(futures).await;
let mut scores = Vec::with_capacity(results.len());
for result in results {
scores.push(result?);
}
Ok(scores)
}
}