use crate::benchmarks::BenchmarkStore;
use std::process::Command;
use tracing::info;
#[derive(Debug, Clone, Default)]
pub struct ThegentAdapterConfig {
pub thegent_path: Option<String>,
pub enabled: bool,
}
pub struct ThegentAdapter {
config: ThegentAdapterConfig,
}
impl ThegentAdapter {
pub fn new(config: ThegentAdapterConfig) -> Self {
Self { config }
}
pub fn is_available(&self) -> bool {
if !self.config.enabled {
return false;
}
if let Some(ref path) = self.config.thegent_path {
return std::path::Path::new(path).exists();
}
Command::new("which")
.arg("thegent")
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
pub fn get_quality_indices(&self) -> Result<Vec<ThegentQualityIndex>, ThegentError> {
if !self.is_available() {
return Err(ThegentError::NotAvailable);
}
info!("Thegent quality indices requested but adapter not fully implemented");
Err(ThegentError::NotImplemented)
}
pub fn get_speed_indices(&self) -> Result<Vec<ThegentSpeedIndex>, ThegentError> {
if !self.is_available() {
return Err(ThegentError::NotAvailable);
}
info!("Thegent speed indices requested but adapter not fully implemented");
Err(ThegentError::NotImplemented)
}
pub fn get_cost_values(&self) -> Result<Vec<ThegentCostValue>, ThegentError> {
if !self.is_available() {
return Err(ThegentError::NotAvailable);
}
info!("Thegent cost values requested but adapter not fully implemented");
Err(ThegentError::NotImplemented)
}
pub async fn fetch_and_store(&self, _store: &BenchmarkStore) -> Result<usize, ThegentError> {
if !self.is_available() {
return Err(ThegentError::NotAvailable);
}
info!("Thegent adapter fetch_and_store not fully implemented");
Err(ThegentError::NotImplemented)
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ThegentQualityIndex {
pub model_id: String,
pub provider: String,
pub quality_index: f64,
pub task_type: Option<String>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ThegentSpeedIndex {
pub model_id: String,
pub provider: String,
pub speed_index: f64,
pub tps: Option<f64>,
pub latency_ms: Option<f64>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ThegentCostValue {
pub model_id: String,
pub provider: String,
pub cost_per_1k: f64,
}
#[derive(Debug, thiserror::Error)]
pub enum ThegentError {
#[error("Thegent is not available")]
NotAvailable,
#[error("Thegent adapter not implemented")]
NotImplemented,
#[error("Failed to execute thegent: {0}")]
ExecutionError(String),
#[error("Failed to parse thegent output: {0}")]
ParseError(String),
}
impl From<std::io::Error> for ThegentError {
fn from(e: std::io::Error) -> Self {
ThegentError::ExecutionError(e.to_string())
}
}
impl From<serde_json::Error> for ThegentError {
fn from(e: serde_json::Error) -> Self {
ThegentError::ParseError(e.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_adapter_disabled_by_default() {
let config = ThegentAdapterConfig::default();
let adapter = ThegentAdapter::new(config);
assert!(!adapter.is_available());
}
}