Refactor IPC and DTO structures; remove unused code and streamline message handling
- Removed unused structs and methods from `response.rs`, `usage.rs`, and `client.rs`. - Simplified `Connection` handling in `conn.rs` to only support Unix sockets. - Updated `IpcServer` to exclusively use Unix sockets and removed TCP handling. - Cleaned up `editlog.rs` by removing loading and recent entry methods. - Refactored `memory.rs` to eliminate unused functions related to lesson promotion and retrospective creation. - Enhanced `search.rs` to support multiple search providers and improved error handling. - Updated chat view logic to simplify message display and improve user experience. - Removed deprecated modules and constants from various files to streamline the codebase.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
use std::collections::HashMap;
|
||||
use std::process::Command;
|
||||
use crate::app::state::rest::AppStateRest;
|
||||
use crate::app::state::runtime::TurnEvent;
|
||||
@@ -50,147 +49,6 @@ pub struct Lesson {
|
||||
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 graduated_checks: Vec<crate::tool::GraduatedCheck>,
|
||||
pub violation_window: u32,
|
||||
}
|
||||
|
||||
impl ReviewSystem {
|
||||
pub fn new() -> Self {
|
||||
ReviewSystem {
|
||||
pending: false,
|
||||
queue_capacity: 1,
|
||||
repeated_violations: HashMap::new(),
|
||||
shadow_violations: Vec::new(),
|
||||
graduated_checks: Vec::new(),
|
||||
violation_window: 10,
|
||||
}
|
||||
}
|
||||
pub fn record_shadow_hit(&mut self, pattern: &str) -> bool {
|
||||
for check in &mut self.shadow_violations {
|
||||
if check.pattern == pattern {
|
||||
check.trial_count += 1;
|
||||
check.trial_passed += 1;
|
||||
return check.trial_count >= check.trial_window;
|
||||
}
|
||||
}
|
||||
self.shadow_violations.push(ShadowCheck {
|
||||
pattern: pattern.to_string(),
|
||||
trial_window: 10,
|
||||
trial_count: 1,
|
||||
trial_passed: 1,
|
||||
status: ShadowStatus::Trial,
|
||||
});
|
||||
false
|
||||
}
|
||||
pub fn evaluate_shadow_trials(&mut self) -> Vec<String> {
|
||||
let mut graduated = Vec::new();
|
||||
let mut remaining = Vec::new();
|
||||
for mut check in self.shadow_violations.drain(..) {
|
||||
if check.trial_count < check.trial_window {
|
||||
remaining.push(check);
|
||||
continue;
|
||||
}
|
||||
let ratio = check.trial_passed as f64 / check.trial_window as f64;
|
||||
let p = check.pattern.clone();
|
||||
let tp = check.trial_passed;
|
||||
let tw = check.trial_window;
|
||||
if ratio >= 0.3 {
|
||||
self.graduated_checks.push(crate::tool::GraduatedCheck {
|
||||
name: p.clone(),
|
||||
pattern: p.clone(),
|
||||
rule: p.clone(),
|
||||
});
|
||||
graduated.push(format!("{} (graduated, fired {}/{} writes)", p, tp, tw));
|
||||
} else {
|
||||
check.status = ShadowStatus::Rejected;
|
||||
graduated.push(format!("{} (demoted, only {}/{} — below 30% threshold)", p, tp, tw));
|
||||
remaining.push(check);
|
||||
}
|
||||
}
|
||||
self.shadow_violations = remaining;
|
||||
graduated
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -451,64 +309,6 @@ pub fn trigger_review(state: &mut AppStateRest) -> anyhow::Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn record_review_outcome(
|
||||
lessons_found: usize,
|
||||
state: &mut AppStateRest,
|
||||
) -> Option<String> {
|
||||
let runtime = match &mut state.session_runtime {
|
||||
Some(ref mut r) => r,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
if lessons_found > 0 {
|
||||
runtime.consecutive_empty_reviews = 0;
|
||||
runtime.review_count += 1;
|
||||
None
|
||||
} else {
|
||||
runtime.consecutive_empty_reviews += 1;
|
||||
runtime.review_count += 1;
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn check_violation_escalation(
|
||||
pattern: &str,
|
||||
system: &mut ReviewSystem,
|
||||
) -> Option<ViolationEscalation> {
|
||||
let level = system.increment_violation(pattern);
|
||||
match level {
|
||||
ViolationEscalation::None => None,
|
||||
ViolationEscalation::Warning => Some(level),
|
||||
ViolationEscalation::Escalate => Some(level),
|
||||
ViolationEscalation::Block => Some(level),
|
||||
}
|
||||
}
|
||||
pub fn format_escalation_note(pattern: &str, level: ViolationEscalation) -> String {
|
||||
let label = match level {
|
||||
ViolationEscalation::None => "none",
|
||||
ViolationEscalation::Warning => "WARNING",
|
||||
ViolationEscalation::Escalate => "ESCALATION",
|
||||
ViolationEscalation::Block => "BLOCKED",
|
||||
};
|
||||
format!(
|
||||
"[{}] Repeated violation: '{}' has been flagged by quality review {} time(s). {}",
|
||||
label,
|
||||
pattern,
|
||||
match level {
|
||||
ViolationEscalation::None | ViolationEscalation::Warning => 2,
|
||||
ViolationEscalation::Escalate => 3,
|
||||
ViolationEscalation::Block => 5,
|
||||
},
|
||||
match level {
|
||||
ViolationEscalation::Warning =>
|
||||
"This pattern has appeared twice. Consider reviewing the related guideline.".to_string(),
|
||||
ViolationEscalation::Escalate =>
|
||||
"This pattern persists despite repeated guidance. Manual review recommended.".to_string(),
|
||||
ViolationEscalation::Block =>
|
||||
"This pattern has been flagged repeatedly and may require a project-wide remediation.".to_string(),
|
||||
_ => String::new(),
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const STALE_AFTER_DAYS: i64 = 60;
|
||||
|
||||
@@ -545,51 +345,6 @@ pub fn maybe_run_staleness_sweep(state: &mut AppStateRest) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn detect_contradiction(
|
||||
new_text: &str,
|
||||
existing_lessons: &[crate::model::memory::Memory],
|
||||
) -> Option<String> {
|
||||
let new_words: std::collections::HashSet<String> = new_text
|
||||
.to_lowercase()
|
||||
.split(|c: char| !c.is_alphanumeric())
|
||||
.filter(|w| w.len() >= 4 && !is_stop_word(w))
|
||||
.map(|w| w.to_string())
|
||||
.collect();
|
||||
let opposite_markers = ["not", "never", "avoid", "don't", "do not", "instead"];
|
||||
for existing in existing_lessons {
|
||||
let existing_lower = existing.content.to_lowercase();
|
||||
let exist_words: std::collections::HashSet<String> = existing_lower
|
||||
.split(|c: char| !c.is_alphanumeric())
|
||||
.filter(|w| w.len() >= 4 && !is_stop_word(w))
|
||||
.map(|w| w.to_string())
|
||||
.collect();
|
||||
|
||||
let shared = new_words.intersection(&exist_words).count();
|
||||
if shared >= 3 {
|
||||
let new_has_opposite = opposite_markers.iter().any(|m| new_text.to_lowercase().contains(m));
|
||||
let old_has_opposite = opposite_markers.iter().any(|m| existing_lower.contains(m));
|
||||
if new_has_opposite != old_has_opposite {
|
||||
return Some(existing.name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn is_stop_word(w: &str) -> bool {
|
||||
matches!(
|
||||
w,
|
||||
"this" | "that" | "with" | "from" | "have" | "been" | "were" | "they"
|
||||
| "which" | "what" | "when" | "where" | "would" | "could" | "should"
|
||||
| "about" | "after" | "before" | "between" | "other" | "every" | "still" | "also"
|
||||
| "than" | "then" | "into" | "over" | "such" | "only" | "more" | "very" | "just"
|
||||
| "because" | "while" | "being" | "made" | "make" | "does" | "done" | "using"
|
||||
| "used" | "uses" | "like" | "well" | "back" | "much" | "some" | "these" | "those"
|
||||
| "each" | "both" | "most" | "upon" | "here" | "down" | "your" | "its" | "our"
|
||||
| "him" | "her" | "them"
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PendingLesson {
|
||||
pub lesson: Lesson,
|
||||
@@ -611,15 +366,6 @@ pub fn save_pending_lessons(session_dir: &std::path::Path, pending: &[PendingLes
|
||||
std::fs::write(&path, data)
|
||||
}
|
||||
|
||||
pub fn add_pending_lesson(session_dir: &std::path::Path, lesson: Lesson, auto_resolve: bool) -> std::io::Result<()> {
|
||||
let mut pending = load_pending_lessons(session_dir);
|
||||
pending.push(PendingLesson {
|
||||
lesson,
|
||||
created_at: chrono::Utc::now().timestamp_millis(),
|
||||
auto_resolve,
|
||||
});
|
||||
save_pending_lessons(session_dir, &pending)
|
||||
}
|
||||
pub fn process_pending_lessons(session_dir: &std::path::Path, memory_dir: &std::path::Path) -> std::io::Result<Vec<PendingLesson>> {
|
||||
let pending = load_pending_lessons(session_dir);
|
||||
let now = chrono::Utc::now().timestamp_millis();
|
||||
|
||||
Reference in New Issue
Block a user