use crate::agent::core::Agent;
use crate::apis::api_client::SessionManager;
use crate::app::commands::SpecialCommand;
use crate::app::history::ConversationSummary;
use crate::app::models::ToolPermissionStatus;
use crate::app::permissions::PendingToolExecution;
use crate::app::utils::ScrollState;
use crate::models::ModelConfig;
use std::sync::mpsc;
use std::time::{Duration, Instant};
use tokio::runtime::Runtime;
use uuid::Uuid;
#[derive(Debug, PartialEq)]
pub enum AppState {
Setup,
ApiKeyInput,
Error(String),
Chat,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TaskStatus {
InProgress,
Completed {
duration: Duration,
tool_uses: u32,
input_tokens: u32,
output_tokens: u32,
},
Failed(String),
}
#[derive(Debug, Clone)]
pub struct Task {
pub id: String,
pub description: String,
pub status: TaskStatus,
pub created_at: Instant,
pub updated_at: Instant,
pub tool_count: u32,
pub input_tokens: u32,
pub output_tokens: u32,
}
impl Task {
pub fn new(description: &str) -> Self {
let now = Instant::now();
Self {
id: format!("{}", Uuid::new_v4().simple()),
description: description.to_string(),
status: TaskStatus::InProgress,
created_at: now,
updated_at: now,
tool_count: 0,
input_tokens: 0,
output_tokens: 0,
}
}
pub fn complete(&mut self, _tool_uses: u32, output_tokens: u32) {
let now = Instant::now();
let duration = now.duration_since(self.created_at);
self.output_tokens = output_tokens;
self.status = TaskStatus::Completed {
duration,
tool_uses: self.tool_count, input_tokens: self.input_tokens,
output_tokens: self.output_tokens,
};
self.updated_at = now;
}
pub fn fail(&mut self, error: &str) {
self.status = TaskStatus::Failed(error.to_string());
self.updated_at = Instant::now();
}
pub fn add_tool_use(&mut self) {
self.tool_count += 1;
self.updated_at = Instant::now();
}
pub fn add_input_tokens(&mut self, tokens: u32) {
self.input_tokens += tokens;
self.updated_at = Instant::now();
}
pub fn is_in_progress(&self) -> bool {
matches!(self.status, TaskStatus::InProgress)
}
}
use tui_textarea::TextArea;
pub struct App {
pub state: AppState,
pub textarea: TextArea<'static>, pub input: String, pub messages: Vec<String>,
pub logs: Vec<String>, pub show_logs: bool, pub selected_model: usize,
pub available_models: Vec<ModelConfig>,
pub error_message: Option<String>,
pub debug_messages: bool,
pub message_scroll: ScrollState, pub log_scroll: ScrollState, pub scroll_position: usize, pub last_query_time: Instant,
pub last_message_time: Instant, pub use_agent: bool,
pub agent: Option<Agent>,
pub tokio_runtime: Option<Runtime>,
pub agent_progress_rx: Option<mpsc::Receiver<String>>,
pub api_key: Option<String>,
pub current_working_dir: Option<String>,
pub command_mode: bool,
pub available_commands: Vec<SpecialCommand>,
pub selected_command: usize,
pub show_command_menu: bool,
pub permission_required: bool, pub pending_tool: Option<PendingToolExecution>, pub tool_permission_status: ToolPermissionStatus, pub tool_execution_in_progress: bool, pub show_intermediate_steps: bool, pub show_shortcuts_hint: bool, pub show_detailed_shortcuts: bool, pub cursor_position: usize, pub tasks: Vec<Task>,
pub current_task_id: Option<String>,
pub task_scroll: ScrollState, pub task_scroll_position: usize, pub conversation_summaries: Vec<ConversationSummary>, pub session_manager: Option<SessionManager>, pub session_id: String, }