use std::sync::Arc;
use bevy_ecs::entity::Entity;
use leviath_providers::{InferenceRequest, Provider, ProviderError};
use tokio::sync::Notify;
use tokio::sync::mpsc::UnboundedSender;
use crate::inference_pool::InferencePermit;
pub struct TitleJob {
pub entity: Entity,
pub provider: Arc<dyn Provider>,
pub provider_name: String,
pub model: String,
pub request: InferenceRequest,
pub permit: InferencePermit,
}
pub struct TitleOutcome {
pub entity: Entity,
pub result: Result<String, ProviderError>,
pub usage: Option<leviath_providers::TokenUsage>,
pub provider_name: String,
pub model: String,
}
pub async fn run_title_job(
job: TitleJob,
deadline: std::time::Duration,
results: UnboundedSender<TitleOutcome>,
wake: Arc<Notify>,
) {
let TitleJob {
entity,
provider,
provider_name,
model,
request,
permit,
} = job;
let (result, usage) = match tokio::time::timeout(deadline, provider.infer(&request)).await {
Ok(Ok(r)) => (Ok(r.content), Some(r.tokens_used)),
Ok(Err(e)) => (Err(e), None),
Err(_) => (
Err(leviath_providers::ProviderError::Other(format!(
"title generation exceeded the {}s deadline and was aborted to free the pool slot",
deadline.as_secs()
))),
None,
),
};
drop(permit);
let _ = results.send(TitleOutcome {
entity,
result,
usage,
provider_name,
model,
});
wake.notify_one();
}