Skip to main content

oxios_kernel/
persona.rs

1//! Persona system: multiple AI characters with distinct voices.
2//!
3//! Personas allow different AI "characters" to participate in conversations,
4//! each with their own system prompt, role, and personality traits.
5//! This foundation supports future multi-agent chat scenarios.
6
7use serde::{Deserialize, Serialize};
8
9/// A persona is an AI character with its own voice and specialization.
10/// Multiple personas can be active simultaneously (future multi-agent chat support).
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct Persona {
13    /// Unique identifier.
14    pub id: String,
15    /// Display name.
16    pub name: String,
17    /// Role or archetype (developer, qa, architect, researcher...).
18    pub role: String,
19    /// Brief description of this persona.
20    pub description: String,
21    /// The persona's character definition (system prompt).
22    pub system_prompt: String,
23    /// Whether this persona is enabled for use.
24    pub enabled: bool,
25    /// Optional model override for this persona.
26    pub model: Option<String>,
27    /// Personality traits (curious, skeptical, creative...).
28    pub personality_traits: Vec<String>,
29}
30
31impl Default for Persona {
32    fn default() -> Self {
33        Self {
34            id: uuid::Uuid::new_v4().to_string(),
35            name: "Default".to_string(),
36            role: "assistant".to_string(),
37            description: "Default AI assistant persona".to_string(),
38            system_prompt: "You are a helpful AI assistant.".to_string(),
39            enabled: true,
40            model: None,
41            personality_traits: vec![],
42        }
43    }
44}
45
46impl Persona {
47    /// Creates a new persona with the given parameters.
48    pub fn new(name: &str, role: &str, description: &str, system_prompt: &str) -> Self {
49        Self {
50            id: uuid::Uuid::new_v4().to_string(),
51            name: name.to_string(),
52            role: role.to_string(),
53            description: description.to_string(),
54            system_prompt: system_prompt.to_string(),
55            enabled: true,
56            model: None,
57            personality_traits: vec![],
58        }
59    }
60
61    /// Creates a persona with the given ID (used when loading from storage).
62    pub fn with_id(
63        id: &str,
64        name: &str,
65        role: &str,
66        description: &str,
67        system_prompt: &str,
68    ) -> Self {
69        Self {
70            id: id.to_string(),
71            name: name.to_string(),
72            role: role.to_string(),
73            description: description.to_string(),
74            system_prompt: system_prompt.to_string(),
75            enabled: true,
76            model: None,
77            personality_traits: vec![],
78        }
79    }
80}
81
82/// Creates the three default personas for Oxios.
83pub fn default_personas() -> Vec<Persona> {
84    vec![
85        Persona {
86            id: "dev".to_string(),
87            name: "Dev".to_string(),
88            role: "developer".to_string(),
89            description: "Pragmatic developer focused on implementation".to_string(),
90            system_prompt: "You are Dev, a pragmatic software developer. You focus on \
91                implementing working solutions quickly. You value clean code, \
92                but prioritize shipping over perfection. When asked to build something, \
93                you consider: what is the minimal viable approach? You suggest \
94                practical solutions using proven tools and patterns."
95                .to_string(),
96            enabled: true,
97            model: None,
98            personality_traits: vec![
99                "pragmatic".to_string(),
100                "action-oriented".to_string(),
101                "practical".to_string(),
102            ],
103        },
104        Persona {
105            id: "review".to_string(),
106            name: "Review".to_string(),
107            role: "qa".to_string(),
108            description: "Quality-focused reviewer with skepticism for assumptions".to_string(),
109            system_prompt: "You are Review, a quality assurance and architecture \
110                specialist. You are skeptical of assumptions and eager to find \
111                edge cases, bugs, and design flaws. You question whether the \
112                approach scales and whether error conditions are handled. When \
113                reviewing code or specs, you identify potential problems before \
114                they become production issues."
115                .to_string(),
116            enabled: true,
117            model: None,
118            personality_traits: vec![
119                "skeptical".to_string(),
120                "thorough".to_string(),
121                "quality-focused".to_string(),
122            ],
123        },
124        Persona {
125            id: "research".to_string(),
126            name: "Research".to_string(),
127            role: "researcher".to_string(),
128            description: "Curious researcher focused on understanding and evidence".to_string(),
129            system_prompt: "You are Research, a curious researcher. You explore \
130                topics deeply, seeking to understand why things work the way they do. \
131                You look for evidence, benchmarks, and best practices before \
132                recommending approaches. You ask clarifying questions and \
133                consider edge cases thoroughly. You prefer well-reasoned \
134                arguments backed by data."
135                .to_string(),
136            enabled: true,
137            model: None,
138            personality_traits: vec![
139                "curious".to_string(),
140                "analytical".to_string(),
141                "evidence-focused".to_string(),
142            ],
143        },
144    ]
145}