use std::path::Path;
use std::sync::{Arc, Mutex};
use super::actuator::ManagerActuator;
use super::chat_store::ChatStore;
use super::inference::ManagerInference;
use super::memory::PortfolioPalace;
use super::proposal::ProposalStore;
pub struct ManagerState {
palace: PortfolioPalace,
inference: ManagerInference,
conversations: ChatStore,
proposals: ProposalStore,
actuator: Mutex<Option<Arc<dyn ManagerActuator>>>,
}
impl std::fmt::Debug for ManagerState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let has_actuator = self.actuator.lock().map(|g| g.is_some()).unwrap_or(false);
f.debug_struct("ManagerState")
.field("palace", &self.palace)
.field("inference", &self.inference)
.field("conversations", &self.conversations)
.field("proposals", &self.proposals)
.field("actuator_override", &has_actuator)
.finish()
}
}
impl ManagerState {
pub fn provision(framework_root: &Path) -> Self {
Self {
palace: PortfolioPalace::provision(framework_root),
inference: ManagerInference::provision(),
conversations: ChatStore::default(),
proposals: ProposalStore::new(),
actuator: Mutex::new(None),
}
}
pub fn palace(&self) -> &PortfolioPalace {
&self.palace
}
pub fn inference(&self) -> &ManagerInference {
&self.inference
}
pub fn conversations(&self) -> &ChatStore {
&self.conversations
}
pub fn proposals(&self) -> &ProposalStore {
&self.proposals
}
pub fn actuator_override(&self) -> Option<Arc<dyn ManagerActuator>> {
self.actuator
.lock()
.unwrap_or_else(|p| p.into_inner())
.clone()
}
pub fn set_actuator(&self, actuator: Arc<dyn ManagerActuator>) {
*self.actuator.lock().unwrap_or_else(|p| p.into_inner()) = Some(actuator);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn manager_state_provisions_palace() {
let dir = tempfile::tempdir().expect("tempdir");
let state = ManagerState::provision(dir.path());
assert_eq!(state.palace().id(), super::super::PORTFOLIO_PALACE_ID);
}
}