Implement chat and markdown views, enhance status bar, and add workflow panel

- Added `chat.rs` for rendering chat messages with timestamps and roles.
- Introduced `markdown.rs` for rendering markdown content with styling.
- Created `status.rs` to display the application status bar with session and message counts.
- Developed `workflow.rs` to show the current workflow status, including tool calls and active jobs.
- Established a `theme.rs` for centralized color management across the UI.
- Updated `mod.rs` to include new modules and manage rendering logic.
This commit is contained in:
asepharyana
2026-07-11 13:16:10 +07:00
parent 7cb4ae6708
commit cc03bd79b6
131 changed files with 10994 additions and 0 deletions
+172
View File
@@ -0,0 +1,172 @@
use std::collections::HashMap;
use crate::app::state::rest::AppStateRest;
use crate::app::state::types::{AgentMode, Origin, Toast, ToastKind};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum Confidence {
Human,
Verified,
Unverified,
Auto,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum LessonLifecycle {
New,
Active,
Stale,
Contradicted,
Superseded,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum LessonScope {
Project,
Global,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Provenance {
pub session_turn: String,
pub session_id: String,
pub reviewer: Origin,
}
#[derive(Debug, Clone)]
pub struct Lesson {
pub name: String,
pub content: String,
pub confidence: Confidence,
pub outcome: Option<String>,
pub lifecycle: LessonLifecycle,
pub scope: LessonScope,
pub contradiction_with: Option<String>,
pub provenance: Provenance,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ViolationEscalation {
None,
Warning,
Escalate,
Block,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ShadowStatus {
Trial,
Graduated,
Rejected,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ShadowCheck {
pub pattern: String,
pub trial_window: u32,
pub trial_count: u32,
pub trial_passed: u32,
pub status: ShadowStatus,
}
pub struct ReviewSystem {
pub pending: bool,
pub queue_capacity: usize,
pub repeated_violations: HashMap<String, u32>,
pub shadow_violations: Vec<ShadowCheck>,
pub violation_window: u32,
}
impl ReviewSystem {
pub fn new() -> Self {
ReviewSystem {
pending: false,
queue_capacity: 1,
repeated_violations: HashMap::new(),
shadow_violations: Vec::new(),
violation_window: 10,
}
}
pub fn reset(&mut self) {
self.pending = false;
}
pub fn check_escalation(&self, pattern: &str) -> ViolationEscalation {
let count = self.repeated_violations.get(pattern).copied().unwrap_or(0);
match count {
0 | 1 => ViolationEscalation::None,
2 => ViolationEscalation::Warning,
3 | 4 => ViolationEscalation::Escalate,
_ => ViolationEscalation::Block,
}
}
pub fn increment_violation(&mut self, pattern: &str) -> ViolationEscalation {
let entry = self.repeated_violations.entry(pattern.to_string()).or_insert(0);
*entry += 1;
self.check_escalation(pattern)
}
pub fn should_skip_review(consecutive_empty: u32) -> bool {
consecutive_empty >= 3
}
}
pub fn create_pending_lesson(name: &str, content: &str, provenance: Provenance) -> Lesson {
Lesson {
name: name.to_string(),
content: content.to_string(),
confidence: Confidence::Unverified,
outcome: None,
lifecycle: LessonLifecycle::New,
scope: LessonScope::Project,
contradiction_with: None,
provenance,
}
}
pub fn apply_lesson_calibration(state: &mut AppStateRest, lesson: &Lesson) {
if lesson.confidence != Confidence::Unverified {
return;
}
if state.mode.auto_approve() {
return;
}
state.push_toast(Toast::new(
ToastKind::Lesson,
format!("Lesson '{}' is pending review. Keep or discard?", lesson.name),
));
}
pub fn should_trigger_review(state: &AppStateRest, origin: Origin) -> bool {
if state.mode == AgentMode::Plan {
return false;
}
if origin != Origin::Main {
return false;
}
let runtime = match &state.session_runtime {
Some(r) => r,
None => return false,
};
if !state.settings.review_enabled {
return false;
}
if runtime.edit_count > 0 && runtime.edit_count % 5 == 0 {
return true;
}
if runtime.consecutive_empty_reviews >= state.settings.adaptive_review_max_skip {
return true;
}
false
}
pub fn trigger_review(state: &mut AppStateRest) -> anyhow::Result<()> {
let _origin = Origin::Reviewer;
state.push_transcript(crate::app::state::rest::ChatMessageDisplay::new(
crate::dto::chat::message::Role::System,
"review triggered".to_string(),
));
Ok(())
}