use super::Orchestrator;
use crate::app::events::AppEvent;
#[derive(Default)]
pub(super) struct ModelDiscovery {
epoch: u64,
pending: bool,
answered: bool,
known: Option<String>,
}
impl ModelDiscovery {
fn invalidate(&mut self) {
self.epoch += 1;
self.pending = false;
self.answered = false;
self.known = None;
}
#[cfg(test)]
pub(super) fn epoch(&self) -> u64 {
self.epoch
}
#[cfg(test)]
pub(super) fn pending(&self) -> bool {
self.pending
}
fn apply(&mut self, epoch: u64, name: Option<String>) -> bool {
if epoch != self.epoch {
return false;
}
self.pending = false;
self.answered = true;
self.known = name;
true
}
}
impl Orchestrator {
pub(super) fn effective_model_name(&self) -> Option<String> {
self.config
.engine
.active_model_name()
.or_else(|| self.model.known.clone())
}
pub(super) fn refresh_model_name(&mut self) {
self.model.invalidate();
self.emit_model_name();
if self.config.engine.active_model_name().is_some() {
return;
}
let Some(backend) = self.engines.backend.clone() else {
return;
};
self.model.pending = true;
let epoch = self.model.epoch;
let tx = self.model_tx.clone();
tokio::spawn(async move {
let _ = tx.send((epoch, backend.model_id().await));
});
}
pub(super) fn handle_model_result(&mut self, epoch: u64, name: Option<String>) {
if !self.model.apply(epoch, name) {
return;
}
if let Some(name) = &self.model.known {
tracing::info!(model = %name, "engine reported the model it is running");
}
self.emit_model_name();
}
fn emit_model_name(&self) {
let _ = self
.evt_tx
.send(AppEvent::EngineModel(self.model.known.clone()));
}
}