use ratatui::style::Color;
pub use matrixcode_core::ApproveMode;
#[derive(Debug, Clone, PartialEq, Default)]
pub enum Activity {
#[default]
Idle,
Thinking,
Reading,
Writing,
Editing,
Searching,
Running,
WebSearch,
WebFetch,
Tool(String),
Asking, }
impl Activity {
pub fn label(&self) -> String {
match self {
Activity::Idle => "Ready".into(),
Activity::Thinking => "Thinking".into(),
Activity::Reading => "read".into(),
Activity::Writing => "write".into(),
Activity::Editing => "edit".into(),
Activity::Searching => "search".into(),
Activity::Running => "bash".into(),
Activity::WebSearch => "websearch".into(),
Activity::WebFetch => "webfetch".into(),
Activity::Tool(name) => name.clone(),
Activity::Asking => "AWAITING".into(),
}
}
pub fn color(&self) -> Color {
match self {
Activity::Idle => Color::Green,
Activity::Thinking => Color::Magenta,
Activity::Reading | Activity::Searching => Color::Cyan,
Activity::Writing | Activity::Editing => Color::Yellow,
Activity::Running => Color::Red,
Activity::WebSearch | Activity::WebFetch => Color::Blue,
Activity::Tool(_) => Color::Cyan,
Activity::Asking => Color::Red,
}
}
pub fn from_tool(name: &str) -> Self {
match name.to_lowercase().as_str() {
"read" => Activity::Reading,
"write" => Activity::Writing,
"edit" | "multi_edit" => Activity::Editing,
"search" | "grep" | "glob" | "ls" => Activity::Searching,
"bash" => Activity::Running,
"websearch" => Activity::WebSearch,
"webfetch" => Activity::WebFetch,
"task" | "task_create" | "task_get" | "task_list" | "task_stop" => {
Activity::Tool("task".into())
}
"enter_plan_mode" | "exit_plan_mode" => Activity::Tool("plan".into()),
"monitor" => Activity::Tool("monitor".into()),
other => Activity::Tool(other.to_string()),
}
}
}
#[derive(PartialEq)]
pub enum Role {
User,
Assistant,
Thinking,
Tool {
name: String,
detail: Option<String>,
is_error: bool,
},
System,
Ask, }
impl Role {
#[allow(dead_code)]
pub fn icon(&self) -> &'static str {
match self {
Role::User => "👤",
Role::Assistant => "🤖",
Role::Thinking => "💭",
Role::Tool { is_error, .. } => {
if *is_error {
"❌"
} else {
"✅"
}
}
Role::System => "⚠️",
Role::Ask => "⚡",
}
}
#[allow(dead_code)]
pub fn label(&self) -> String {
match self {
Role::User => "You".into(),
Role::Assistant => "Assistant".into(),
Role::Thinking => "Thinking".into(),
Role::Tool { name, .. } => name.clone(),
Role::System => "System".into(),
Role::Ask => "AWAITING".into(),
}
}
#[allow(dead_code)]
pub fn color(&self) -> Color {
match self {
Role::User => Color::Green,
Role::Assistant => Color::Blue,
Role::Thinking => Color::Magenta,
Role::Tool { is_error, .. } => {
if *is_error {
Color::Red
} else {
Color::Cyan
}
}
Role::System => Color::Yellow,
Role::Ask => Color::Yellow,
}
}
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
#[derive(Default)]
pub struct AskOption {
pub id: String,
pub label: String,
pub description: Option<String>,
pub selected: bool, pub is_submit: bool, pub is_other: bool, }
impl AskOption {
pub fn format_description(&self) -> String {
self.description
.as_ref()
.map(|d| format!(" - {}", d))
.unwrap_or_default()
}
pub fn other_option() -> Self {
Self {
id: "other".to_string(),
label: "其他 (自定义输入)".to_string(),
description: Some("输入自定义内容".to_string()),
selected: false,
is_submit: false,
is_other: true,
}
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub enum SubmitMode {
#[default]
Direct, Option, Button, }
impl SubmitMode {
pub fn from_option_count(opt_count: usize, multi_select: bool) -> Self {
if multi_select {
if opt_count <= 3 {
SubmitMode::Direct
} else if opt_count <= 10 {
SubmitMode::Option
} else {
SubmitMode::Button
}
} else {
SubmitMode::Direct
}
}
}
#[derive(Debug, Clone, Default)]
pub struct AskQuestion {
pub id: String,
pub question: String,
pub options: Vec<AskOption>,
pub multi_select: bool,
pub selected_index: usize,
pub submit_mode: SubmitMode,
pub other_input: Option<String>, }
pub struct Message {
pub role: Role,
pub content: String,
}