use crate::pty::vte::VteParser;
use crate::core::types::CliTool;
use super::traits::{MessageClass, OutputParser, ParsedMessage};
pub struct ClassificationPipeline {
vte_parser: VteParser,
cli_parser: Box<dyn OutputParser>,
turn_counter: u32,
in_response: bool,
}
impl ClassificationPipeline {
pub fn new(cli_parser: Box<dyn OutputParser>) -> Self {
Self {
vte_parser: VteParser::new(),
cli_parser,
turn_counter: 0,
in_response: false,
}
}
pub fn process(&mut self, raw: &str) -> Vec<ParsedMessage> {
let cleaned = self.vte_parser.parse(raw);
self.cli_parser.feed(&cleaned);
let mut messages = self.cli_parser.parse();
for msg in &mut messages {
match msg.class {
MessageClass::AiResponse => {
self.in_response = true;
msg.metadata.turn = Some(self.turn_counter);
}
MessageClass::PromptReady => {
if self.in_response {
self.turn_counter += 1;
self.in_response = false;
}
msg.metadata.turn = Some(self.turn_counter);
}
_ => {
msg.metadata.turn = Some(self.turn_counter);
}
}
}
messages
}
pub fn turn_count(&self) -> u32 {
self.turn_counter
}
pub fn in_response(&self) -> bool {
self.in_response
}
pub fn tool(&self) -> CliTool {
self.cli_parser.tool()
}
pub fn extract_ai_text(&self, raw_cleaned: &str) -> String {
self.cli_parser.extract_ai_text(raw_cleaned)
}
pub fn classify(&self, text: &str) -> MessageClass {
self.cli_parser.classify(text)
}
pub fn clear(&mut self) {
self.cli_parser.clear();
}
}