Skip to main content

oxios_kernel/kernel_handle/
persona_api.rs

1//! Persona API — multi-persona management.
2//!
3//! `PersonaApi` is the thin public surface over `PersonaManager`.
4//! RFC-039 completion: the manager owns persistence (`StateStore`) and
5//! intent-engine re-seeding (callback) internally, so this API is a
6//! pass-through — no caller can accidentally skip persist or re-seed.
7
8use crate::persona::Persona;
9use crate::persona::PersonaManager;
10use std::sync::Arc;
11
12/// Persona management system calls.
13pub struct PersonaApi {
14    pub(crate) persona_manager: Arc<PersonaManager>,
15}
16
17impl PersonaApi {
18    /// Create a new PersonaApi.
19    pub fn new(persona_manager: Arc<PersonaManager>) -> Self {
20        Self { persona_manager }
21    }
22
23    /// Underlying `Arc<PersonaManager>` for boot-time wiring.
24    pub fn manager(&self) -> Arc<PersonaManager> {
25        Arc::clone(&self.persona_manager)
26    }
27
28    /// List all personas.
29    pub fn list(&self) -> Vec<Persona> {
30        self.persona_manager.store().list_all()
31    }
32
33    /// Get persona by ID.
34    pub fn get(&self, id: &str) -> Option<Persona> {
35        self.persona_manager.store().get(id)
36    }
37
38    /// Create a new persona (in-memory only; call `persist` after).
39    pub fn create(&self, persona: Persona) {
40        self.persona_manager.store().register(persona);
41    }
42
43    /// Update a persona (in-memory only; call `persist` after).
44    pub fn update(&self, id: &str, persona: Persona) -> anyhow::Result<()> {
45        self.persona_manager.store().update(id, persona)
46    }
47
48    /// Delete a persona (in-memory only; call `persist` after).
49    pub fn delete(&self, id: &str) -> anyhow::Result<()> {
50        self.persona_manager.store().delete(id)
51    }
52
53    /// Get active persona.
54    pub fn active(&self) -> Option<Persona> {
55        self.persona_manager.get_active_persona()
56    }
57
58    /// Get active persona ID.
59    pub fn active_id(&self) -> Option<String> {
60        self.persona_manager.active_persona_id()
61    }
62
63    /// Set active persona — persists to disk and re-seeds the intent engine
64    /// automatically (via `PersonaManager::set_active`).
65    pub async fn set_active(&self, id: &str) -> anyhow::Result<Option<String>> {
66        self.persona_manager.set_active(id).await
67    }
68
69    /// Persist the full persona registry to `StateStore`.
70    /// Call this after `create`/`update`/`delete` mutations so the in-memory
71    /// state matches the on-disk state.
72    pub async fn persist(&self) -> anyhow::Result<()> {
73        self.persona_manager.persist().await
74    }
75
76    /// Get persona count.
77    pub fn count(&self) -> usize {
78        self.persona_manager.store().len()
79    }
80
81    /// List enabled personas.
82    pub fn list_enabled(&self) -> Vec<Persona> {
83        self.persona_manager.store().list_enabled()
84    }
85}