1use imp_llm::ThinkingLevel;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct RoleDef {
7 pub model: Option<String>,
8 pub thinking: Option<ThinkingLevel>,
9 pub tools: Option<Vec<String>>,
10 #[serde(default)]
11 pub readonly: bool,
12 pub instructions: Option<String>,
13}
14
15#[derive(Debug, Clone)]
17pub struct Role {
18 pub name: String,
19 pub model: Option<String>,
20 pub thinking_level: Option<ThinkingLevel>,
21 pub tool_set: ToolSet,
22 pub readonly: bool,
23 pub instructions: Option<String>,
24}
25
26#[derive(Debug, Clone)]
27pub enum ToolSet {
28 All,
29 Only(Vec<String>),
30}
31
32impl Role {
33 pub fn from_def(name: &str, def: &RoleDef) -> Self {
35 let tool_set = match &def.tools {
36 Some(tools) => ToolSet::Only(tools.clone()),
37 None if def.readonly => ToolSet::Only(vec![
38 "read".into(),
39 "scan".into(),
40 "web".into(),
41 "recall".into(),
42 ]),
43 None => ToolSet::All,
44 };
45
46 Self {
47 name: name.to_string(),
48 model: def.model.clone(),
49 thinking_level: def.thinking,
50 tool_set,
51 readonly: def.readonly,
52 instructions: def.instructions.clone(),
53 }
54 }
55}
56
57pub fn builtin_roles() -> Vec<(&'static str, RoleDef)> {
59 vec![
60 (
61 "worker",
62 RoleDef {
63 model: None,
64 thinking: Some(ThinkingLevel::Medium),
65 tools: None,
66 readonly: false,
67 instructions: None,
68 },
69 ),
70 (
71 "explorer",
72 RoleDef {
73 model: Some("haiku".into()),
74 thinking: Some(ThinkingLevel::Off),
75 tools: Some(vec![
76 "read".into(),
77 "scan".into(),
78 "web".into(),
79 "recall".into(),
80 ]),
81 readonly: true,
82 instructions: Some("Explore and summarize. Do not modify files.".into()),
83 },
84 ),
85 (
86 "reviewer",
87 RoleDef {
88 model: Some("sonnet".into()),
89 thinking: Some(ThinkingLevel::High),
90 tools: None,
91 readonly: true,
92 instructions: None,
93 },
94 ),
95 ]
96}