From b4543ba56c779a45a31e2b20545802c825e8c1b1 Mon Sep 17 00:00:00 2001 From: Salman Paracha Date: Wed, 7 Jan 2026 11:20:44 -0800 Subject: [PATCH] Introduce signals change (#655) * adding support for signals * reducing false positives for signals like positive interaction * adding docs. Still need to fix the messages list, but waiting on PR #621 * Improve frustration detection: normalize contractions and refine punctuation * Further refine test cases with longer messages * minor doc changes * fixing echo statement for build * fixing the messages construction and using the trait for signals * update signals docs * fixed some minor doc changes * added more tests and fixed docuemtnation. PR 100% ready * made fixes based on PR comments * Optimize latency 1. replace sliding window approach with trigram containment check 2. add code to pre-compute ngrams for patterns * removed some debug statements to make tests easier to read * PR comments to make ObservableStreamProcessor accept optonal Vec * fixed PR comments --------- Co-authored-by: Salman Paracha Co-authored-by: MeiyuZhong Co-authored-by: nehcgs <54548843+nehcgs@users.noreply.github.com> --- cli/planoai/main.py | 4 +- crates/Cargo.lock | 1 + crates/brightstaff/Cargo.toml | 1 + crates/brightstaff/src/handlers/llm.rs | 4 + crates/brightstaff/src/handlers/utils.rs | 98 +- crates/brightstaff/src/lib.rs | 1 + crates/brightstaff/src/signals/analyzer.rs | 3189 +++++++++++++++++ crates/brightstaff/src/signals/mod.rs | 3 + crates/brightstaff/src/tracing/constants.rs | 39 + crates/brightstaff/src/tracing/mod.rs | 4 +- crates/hermesllm/src/apis/openai_responses.rs | 82 +- .../src/transforms/request/from_openai.rs | 259 +- docs/source/_static/img/signals_trace.png | Bin 0 -> 2970560 bytes docs/source/concepts/signals.rst | 359 ++ docs/source/get_started/overview.rst | 2 +- docs/source/guides/observability/tracing.rst | 114 + docs/source/index.rst | 3 +- 17 files changed, 3972 insertions(+), 191 deletions(-) create mode 100644 crates/brightstaff/src/signals/analyzer.rs create mode 100644 crates/brightstaff/src/signals/mod.rs create mode 100644 docs/source/_static/img/signals_trace.png create mode 100644 docs/source/concepts/signals.rst diff --git a/cli/planoai/main.py b/cli/planoai/main.py index 2130dce1..a2737883 100644 --- a/cli/planoai/main.py +++ b/cli/planoai/main.py @@ -81,7 +81,7 @@ def main(ctx, version): @click.command() def build(): - """Build Arch from source. Works from any directory within the repo.""" + """Build Plano from source. Works from any directory within the repo.""" # Find the repo root repo_root = find_repo_root() @@ -112,7 +112,7 @@ def build(): ], check=True, ) - click.echo("archgw image built successfully.") + click.echo("plano image built successfully.") except subprocess.CalledProcessError as e: click.echo(f"Error building plano image: {e}") sys.exit(1) diff --git a/crates/Cargo.lock b/crates/Cargo.lock index 4dbcae49..c1ac4497 100644 --- a/crates/Cargo.lock +++ b/crates/Cargo.lock @@ -335,6 +335,7 @@ dependencies = [ "serde_json", "serde_with", "serde_yaml", + "strsim", "thiserror 2.0.12", "time", "tokio", diff --git a/crates/brightstaff/Cargo.toml b/crates/brightstaff/Cargo.toml index 233a4da3..f48a8d68 100644 --- a/crates/brightstaff/Cargo.toml +++ b/crates/brightstaff/Cargo.toml @@ -30,6 +30,7 @@ reqwest = { version = "0.12.15", features = ["stream"] } serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" serde_with = "3.13.0" +strsim = "0.11" serde_yaml = "0.9.34" thiserror = "2.0.12" tokio = { version = "1.44.2", features = ["full"] } diff --git a/crates/brightstaff/src/handlers/llm.rs b/crates/brightstaff/src/handlers/llm.rs index b311976a..b3cea5e1 100644 --- a/crates/brightstaff/src/handlers/llm.rs +++ b/crates/brightstaff/src/handlers/llm.rs @@ -111,6 +111,9 @@ pub async fn llm_chat( .get_recent_user_message() .map(|msg| truncate_message(&msg, 50)); + // Extract messages for signal analysis (clone before moving client_request) + let messages_for_signals = client_request.get_messages(); + client_request.set_model(resolved_model.clone()); if client_request.remove_metadata_key("archgw_preference_config") { debug!( @@ -292,6 +295,7 @@ pub async fn llm_chat( operation_component::LLM, llm_span, request_start_time, + Some(messages_for_signals), ); // === v1/responses state management: Wrap with ResponsesStateProcessor === diff --git a/crates/brightstaff/src/handlers/utils.rs b/crates/brightstaff/src/handlers/utils.rs index 1529ef3e..f2a318a4 100644 --- a/crates/brightstaff/src/handlers/utils.rs +++ b/crates/brightstaff/src/handlers/utils.rs @@ -10,8 +10,10 @@ use tokio_stream::wrappers::ReceiverStream; use tokio_stream::StreamExt; use tracing::warn; -// Import tracing constants -use crate::tracing::{error, llm}; +// Import tracing constants and signals +use crate::signals::{InteractionQuality, SignalAnalyzer, TextBasedSignalAnalyzer, FLAG_MARKER}; +use crate::tracing::{error, llm, signals as signal_constants}; +use hermesllm::apis::openai::Message; /// Trait for processing streaming chunks /// Implementors can inject custom logic during streaming (e.g., hallucination detection, logging) @@ -38,6 +40,7 @@ pub struct ObservableStreamProcessor { chunk_count: usize, start_time: Instant, time_to_first_token: Option, + messages: Option>, } impl ObservableStreamProcessor { @@ -48,11 +51,13 @@ impl ObservableStreamProcessor { /// * `service_name` - The service name for this span (e.g., "archgw(llm)") /// * `span` - The span to finalize after streaming completes /// * `start_time` - When the request started (for duration calculation) + /// * `messages` - Optional conversation messages for signal analysis pub fn new( collector: Arc, service_name: impl Into, span: Span, start_time: Instant, + messages: Option>, ) -> Self { Self { collector, @@ -62,6 +67,7 @@ impl ObservableStreamProcessor { chunk_count: 0, start_time, time_to_first_token: None, + messages, } } } @@ -133,6 +139,94 @@ impl StreamProcessor for ObservableStreamProcessor { } } + // Analyze signals if messages are available and add to span attributes + if let Some(ref messages) = self.messages { + let analyzer: Box = Box::new(TextBasedSignalAnalyzer::new()); + let report = analyzer.analyze(messages); + + // Add overall quality + self.span.attributes.push(Attribute { + key: signal_constants::QUALITY.to_string(), + value: AttributeValue { + string_value: Some(format!("{:?}", report.overall_quality)), + }, + }); + + // Add repair/follow-up metrics if concerning + if report.follow_up.is_concerning || report.follow_up.repair_count > 0 { + self.span.attributes.push(Attribute { + key: signal_constants::REPAIR_COUNT.to_string(), + value: AttributeValue { + string_value: Some(report.follow_up.repair_count.to_string()), + }, + }); + + self.span.attributes.push(Attribute { + key: signal_constants::REPAIR_RATIO.to_string(), + value: AttributeValue { + string_value: Some(format!("{:.3}", report.follow_up.repair_ratio)), + }, + }); + } + + // Add flag marker to operation name if any concerning signal is detected + let should_flag = report.frustration.has_frustration + || report.repetition.has_looping + || report.escalation.escalation_requested + || matches!( + report.overall_quality, + InteractionQuality::Poor | InteractionQuality::Severe + ); + + if should_flag { + // Prepend flag marker to the operation name + self.span.name = format!("{} {}", self.span.name, FLAG_MARKER); + } + + // Add key signal metrics + if report.frustration.has_frustration { + self.span.attributes.push(Attribute { + key: signal_constants::FRUSTRATION_COUNT.to_string(), + value: AttributeValue { + string_value: Some(report.frustration.frustration_count.to_string()), + }, + }); + self.span.attributes.push(Attribute { + key: signal_constants::FRUSTRATION_SEVERITY.to_string(), + value: AttributeValue { + string_value: Some(report.frustration.severity.to_string()), + }, + }); + } + + if report.repetition.has_looping { + self.span.attributes.push(Attribute { + key: signal_constants::REPETITION_COUNT.to_string(), + value: AttributeValue { + string_value: Some(report.repetition.repetition_count.to_string()), + }, + }); + } + + if report.escalation.escalation_requested { + self.span.attributes.push(Attribute { + key: signal_constants::ESCALATION_REQUESTED.to_string(), + value: AttributeValue { + string_value: Some("true".to_string()), + }, + }); + } + + if report.positive_feedback.has_positive_feedback { + self.span.attributes.push(Attribute { + key: signal_constants::POSITIVE_FEEDBACK_COUNT.to_string(), + value: AttributeValue { + string_value: Some(report.positive_feedback.positive_count.to_string()), + }, + }); + } + } + // Record the finalized span self.collector .record_span(&self.service_name, self.span.clone()); diff --git a/crates/brightstaff/src/lib.rs b/crates/brightstaff/src/lib.rs index 36fc902f..47da64aa 100644 --- a/crates/brightstaff/src/lib.rs +++ b/crates/brightstaff/src/lib.rs @@ -1,5 +1,6 @@ pub mod handlers; pub mod router; +pub mod signals; pub mod state; pub mod tracing; pub mod utils; diff --git a/crates/brightstaff/src/signals/analyzer.rs b/crates/brightstaff/src/signals/analyzer.rs new file mode 100644 index 00000000..9880bf2c --- /dev/null +++ b/crates/brightstaff/src/signals/analyzer.rs @@ -0,0 +1,3189 @@ +//! Agentic Signals - Behavioral quality indicators for agent interactions +//! +//! This module implements various signals that serve as early warning indicators +//! of brilliant successes or failures in agentic interactions. These signals are +//! derived from conversation patterns and can be computed algorithmically from +//! message arrays. + +use serde::{Deserialize, Serialize}; +use std::collections::{HashMap, HashSet}; +use std::sync::LazyLock; + +use hermesllm::apis::openai::{Message, Role}; + +// ============================================================================ +// Constants +// ============================================================================ + +/// Flag emoji for marking spans/operations worth investigating +pub const FLAG_MARKER: &str = "\u{1F6A9}"; + +/// Size of character n-grams for similarity matching (3 = trigrams) +const NGRAM_SIZE: usize = 3; + +// ============================================================================ +// Normalized Message Processing +// ============================================================================ + +/// Pre-processed message with normalized text and tokens for efficient matching +#[derive(Debug, Clone)] +struct NormalizedMessage { + /// Original raw text + raw: String, + /// Tokens (words) extracted from the message + tokens: Vec, + /// Token set for fast lookup + token_set: HashSet, + /// Bigram set for fast similarity computation + bigram_set: HashSet, + /// Character ngram set for robust similarity matching + char_ngram_set: HashSet, + /// Token frequency map for multiset cosine similarity + token_frequency: HashMap, +} + +impl NormalizedMessage { + #[allow(dead_code)] // Used in tests for algorithm validation + fn from_text(text: &str) -> Self { + Self::from_text_with_limit(text, usize::MAX) + } + + fn from_text_with_limit(text: &str, max_length: usize) -> Self { + // Truncate to max_length characters to prevent unbounded computation + // Keep head (20%) + tail (80%) to preserve both context and intent + + let char_count = text.chars().count(); + + let raw = if char_count <= max_length { + text.to_string() + } else { + // Split: 20% head, 79% tail, 1 char space delimiter + let head_len = max_length / 5; + let tail_len = max_length - head_len - 1; + + let head: String = text.chars().take(head_len).collect(); + let tail: String = text.chars().skip(char_count - tail_len).collect(); + + format!("{} {}", head, tail) + }; + + // Normalize unicode punctuation to ASCII equivalents + let normalized_unicode = raw + .replace(['\u{2019}', '\u{2018}'], "'") // U+2019/U+2018 SINGLE QUOTATION MARKs + .replace(['\u{201C}', '\u{201D}'], "\"") // U+201C/U+201D DOUBLE QUOTATION MARKs + .replace(['\u{2013}', '\u{2014}'], "-"); // U+2013/U+2014 EN/EM DASHes + + // Normalize: lowercase, collapse whitespace + let normalized = normalized_unicode + .to_lowercase() + .split_whitespace() + .collect::>() + .join(" "); + + // Tokenize: split on whitespace and strip punctuation from boundaries + let tokens: Vec = normalized + .split_whitespace() + .map(|word| { + // Strip leading/trailing punctuation but keep internal punctuation + word.trim_matches(|c: char| c.is_ascii_punctuation()) + .to_string() + }) + .filter(|w| !w.is_empty()) + .collect(); + + let token_set: HashSet = tokens.iter().cloned().collect(); + + // Generate bigram set directly for similarity matching + let bigram_set: HashSet = tokens + .windows(2) + .map(|w| format!("{} {}", w[0], w[1])) + .collect(); + + // Generate character ngram set for robust similarity matching + // Uses tokens (with punctuation stripped) for consistency with pattern matching + let tokens_text = tokens.join(" "); + let char_ngram_set: HashSet = tokens_text + .chars() + .collect::>() + .windows(NGRAM_SIZE) + .map(|w| w.iter().collect::()) + .collect(); + + // Compute token frequency map for cosine similarity + let mut token_frequency: HashMap = HashMap::new(); + for token in &tokens { + *token_frequency.entry(token.clone()).or_insert(0) += 1; + } + + Self { + raw, + tokens, + token_set, + bigram_set, + char_ngram_set, + token_frequency, + } + } + + /// Check if a single token exists in the message (word boundary aware) + fn contains_token(&self, token: &str) -> bool { + self.token_set.contains(token) + } + + /// Check if a phrase (sequence of tokens) exists in the message + fn contains_phrase(&self, phrase: &str) -> bool { + let phrase_tokens: Vec<&str> = phrase.split_whitespace().collect(); + if phrase_tokens.is_empty() { + return false; + } + + if phrase_tokens.len() == 1 { + return self.contains_token(phrase_tokens[0]); + } + + // Multi-word phrase: check for sequence in tokens + self.tokens.windows(phrase_tokens.len()).any(|window| { + window + .iter() + .zip(phrase_tokens.iter()) + .all(|(token, phrase_token)| token == phrase_token) + }) + } + + /// Calculate character ngram similarity between this message and a pattern + /// Returns a similarity score between 0.0 and 1.0 + /// This is robust to typos, small edits, and word insertions + #[allow(dead_code)] // Used in tests for algorithm validation + fn char_ngram_similarity(&self, pattern: &str) -> f64 { + // Normalize the pattern: lowercase and remove ALL punctuation + // This makes "doesn't" → "doesnt" for robust typo matching + let normalized_pattern = pattern + .to_lowercase() + .chars() + .filter(|c| c.is_alphanumeric() || c.is_whitespace()) + .collect::() + .split_whitespace() + .collect::>() + .join(" "); + + // Generate ngrams for the pattern + let pattern_ngrams: HashSet = normalized_pattern + .chars() + .collect::>() + .windows(NGRAM_SIZE) + .map(|w| w.iter().collect::()) + .collect(); + + if self.char_ngram_set.is_empty() && pattern_ngrams.is_empty() { + return 1.0; // Both empty = identical + } + + if self.char_ngram_set.is_empty() || pattern_ngrams.is_empty() { + return 0.0; + } + + // Compute Jaccard similarity (intersection / union) + let intersection = self.char_ngram_set.intersection(&pattern_ngrams).count(); + let union = self.char_ngram_set.union(&pattern_ngrams).count(); + + if union == 0 { + return 0.0; + } + + intersection as f64 / union as f64 + } + + /// Calculate token-based cosine similarity using term frequencies + /// Returns a similarity score between 0.0 and 1.0 + /// This handles word frequency and is stable for longer messages + #[allow(dead_code)] // Used in tests for algorithm validation + fn token_cosine_similarity(&self, pattern: &str) -> f64 { + // Tokenize and compute frequencies for the pattern + let pattern_tokens: Vec = pattern + .to_lowercase() + .split_whitespace() + .map(|word| { + word.trim_matches(|c: char| c.is_ascii_punctuation()) + .to_string() + }) + .filter(|w| !w.is_empty()) + .collect(); + + let mut pattern_frequency: HashMap = HashMap::new(); + for token in &pattern_tokens { + *pattern_frequency.entry(token.clone()).or_insert(0) += 1; + } + + if self.token_frequency.is_empty() && pattern_frequency.is_empty() { + return 1.0; + } + + if self.token_frequency.is_empty() || pattern_frequency.is_empty() { + return 0.0; + } + + // Compute cosine similarity + // cosine_sim = dot_product / (norm1 * norm2) + + let mut dot_product = 0.0; + let mut norm1_squared = 0.0; + let mut norm2_squared = 0.0; + + // Collect all unique tokens from both sets + let all_tokens: HashSet = self + .token_frequency + .keys() + .chain(pattern_frequency.keys()) + .cloned() + .collect(); + + for token in all_tokens { + let freq1 = *self.token_frequency.get(&token).unwrap_or(&0) as f64; + let freq2 = *pattern_frequency.get(&token).unwrap_or(&0) as f64; + + dot_product += freq1 * freq2; + norm1_squared += freq1 * freq1; + norm2_squared += freq2 * freq2; + } + + let norm1 = norm1_squared.sqrt(); + let norm2 = norm2_squared.sqrt(); + + if norm1 == 0.0 || norm2 == 0.0 { + return 0.0; + } + + dot_product / (norm1 * norm2) + } + + /// Layered phrase matching: exact → character ngram → token cosine + /// Returns true if the pattern matches using any layer + #[allow(dead_code)] // Kept for reference; production uses matches_normalized_pattern + fn layered_contains_phrase( + &self, + pattern: &str, + char_ngram_threshold: f64, + token_cosine_threshold: f64, + ) -> bool { + // Layer 0: Exact phrase match (fastest) + if self.contains_phrase(pattern) { + return true; + } + + // Layer 1: Character ngram similarity (typo/edit robustness) + // Check whole message first (for short messages) + if self.char_ngram_similarity(pattern) >= char_ngram_threshold { + return true; + } + + // ngram containment check for patterns buried in longer messages + // If ALL of the pattern's ngrams exist in the message, the pattern must be + // present (possibly with minor variations like missing apostrophes). + // This is O(pattern_ngrams) lookups vs expensive window sliding. + if self.char_ngram_containment(pattern) >= 1.0 { + return true; + } + + // Layer 2: Token cosine similarity (semantic stability for long messages) + if self.token_cosine_similarity(pattern) >= token_cosine_threshold { + return true; + } + + false + } + + fn char_ngram_containment(&self, pattern: &str) -> f64 { + // Normalize the pattern the same way as char_ngram_similarity + let normalized_pattern = pattern + .to_lowercase() + .chars() + .filter(|c| c.is_alphanumeric() || c.is_whitespace()) + .collect::() + .split_whitespace() + .collect::>() + .join(" "); + + // Generate ngrams for the pattern + let pattern_ngrams: HashSet = normalized_pattern + .chars() + .collect::>() + .windows(NGRAM_SIZE) + .map(|w| w.iter().collect::()) + .collect(); + + if pattern_ngrams.is_empty() { + return 0.0; + } + + // Count how many pattern ngrams exist in the message + let contained = pattern_ngrams + .iter() + .filter(|t| self.char_ngram_set.contains(*t)) + .count(); + + contained as f64 / pattern_ngrams.len() as f64 + } + + /// Fast matching against a pre-normalized pattern + /// This avoids re-normalizing and re-computing ngrams for each pattern + fn matches_normalized_pattern( + &self, + pattern: &NormalizedPattern, + char_ngram_threshold: f64, + token_cosine_threshold: f64, + ) -> bool { + // Layer 0: Exact phrase match (fastest) + if self.contains_phrase(&pattern.raw) { + return true; + } + + // Layer 1: Character ngram similarity using pre-computed ngrams + if !self.char_ngram_set.is_empty() && !pattern.char_ngram_set.is_empty() { + let intersection = self + .char_ngram_set + .intersection(&pattern.char_ngram_set) + .count(); + let union = self.char_ngram_set.union(&pattern.char_ngram_set).count(); + if union > 0 { + let similarity = intersection as f64 / union as f64; + if similarity >= char_ngram_threshold { + return true; + } + } + } + + // Ngram containment check using pre-computed ngrams + if !pattern.char_ngram_set.is_empty() { + let contained = pattern + .char_ngram_set + .iter() + .filter(|t| self.char_ngram_set.contains(*t)) + .count(); + let containment = contained as f64 / pattern.char_ngram_set.len() as f64; + if containment >= 1.0 { + return true; + } + } + + // Layer 2: Token cosine similarity using pre-computed frequencies + if !self.token_frequency.is_empty() && !pattern.token_frequency.is_empty() { + let mut dot_product = 0.0; + let mut norm1_squared = 0.0; + let mut norm2_squared = 0.0; + + // Iterate over pattern tokens (usually smaller set) + for (token, &freq2) in &pattern.token_frequency { + let freq1 = *self.token_frequency.get(token).unwrap_or(&0) as f64; + let freq2 = freq2 as f64; + dot_product += freq1 * freq2; + norm2_squared += freq2 * freq2; + } + + // Add self tokens not in pattern for norm1 + for &freq1 in self.token_frequency.values() { + norm1_squared += (freq1 as f64) * (freq1 as f64); + } + + let norm1 = norm1_squared.sqrt(); + let norm2 = norm2_squared.sqrt(); + + if norm1 > 0.0 && norm2 > 0.0 { + let similarity = dot_product / (norm1 * norm2); + if similarity >= token_cosine_threshold { + return true; + } + } + } + + false + } +} + +// ============================================================================ +// Normalized Pattern (pre-computed for performance) +// ============================================================================ + +/// Pre-processed pattern with normalized text and pre-computed ngrams/tokens +/// This avoids redundant computation when matching against many messages +#[derive(Debug, Clone)] +struct NormalizedPattern { + /// Original raw pattern text + raw: String, + /// Character ngram set for similarity matching + char_ngram_set: HashSet, + /// Token frequency map for cosine similarity + token_frequency: HashMap, +} + +impl NormalizedPattern { + fn new(pattern: &str) -> Self { + // Normalize: lowercase and remove ALL punctuation + let normalized = pattern + .to_lowercase() + .chars() + .filter(|c| c.is_alphanumeric() || c.is_whitespace()) + .collect::() + .split_whitespace() + .collect::>() + .join(" "); + + // Generate ngrams + let char_ngram_set: HashSet = normalized + .chars() + .collect::>() + .windows(NGRAM_SIZE) + .map(|w| w.iter().collect::()) + .collect(); + + // Compute token frequency map + let tokens: Vec = normalized + .split_whitespace() + .map(|s| s.to_string()) + .collect(); + let mut token_frequency: HashMap = HashMap::new(); + for token in tokens { + *token_frequency.entry(token).or_insert(0) += 1; + } + + Self { + raw: pattern.to_string(), + char_ngram_set, + token_frequency, + } + } +} + +/// Helper to create a static slice of normalized patterns +fn normalize_patterns(patterns: &[&str]) -> Vec { + patterns.iter().map(|p| NormalizedPattern::new(p)).collect() +} + +// ============================================================================ +// Pre-computed Pattern Caches (initialized once at startup) +// ============================================================================ + +static REPAIR_PATTERNS: LazyLock> = LazyLock::new(|| { + normalize_patterns(&[ + // Explicit corrections + "i meant", + "i mean", + "sorry, i meant", + "what i meant was", + "what i actually meant", + "i was trying to say", + "let me correct that", + "correction", + "i misspoke", + // Negations and disagreements + "no, i", + "no i", + "nah i", + "nope i", + "not what i", + "that's not", + "that's not what", + "that isn't what", + "not quite", + "not exactly", + // Rephrasing indicators + "let me rephrase", + "let me try again", + "let me clarify", + "to clarify", + "to be clear", + "let me explain", + "what i'm trying to", + "what i'm saying", + "in other words", + // Actual/really emphasis + "actually i", + "actually no", + "what i actually", + "i actually", + "i really meant", + // Mistake acknowledgment + "i was wrong", + "my mistake", + "my bad", + "i should have said", + "i should clarify", + // Wait/hold indicators + "wait, i", + "wait no", + "hold on", + "hang on", + ]) +}); + +static COMPLAINT_PATTERNS: LazyLock> = LazyLock::new(|| { + normalize_patterns(&[ + // Useless/unhelpful (multi-word only) + "this is useless", + "not helpful", + "doesn't help", + "not helping", + "you're not helping", + "no help", + "unhelpful", + // Not working + "this doesn't work", + "doesn't work", + "not working", + "isn't working", + "won't work", + "still doesn't work", + "still not working", + // Not fixing/solving + "doesn't fix", + "not fixing", + "doesn't solve", + "doesn't seem to work", + "doesn't seem to fix", + "not resolving", + // Waste/pointless + "waste of time", + "wasting my time", + // Ridiculous/absurd + "this is ridiculous", + "ridiculous", + "this is absurd", + "absurd", + "this is insane", + "insane", + // Stupid/dumb (as adjectives, not as standalone tokens) + "this is stupid", + "this is dumb", + // Quality complaints (multi-word) + "this sucks", + "not good enough", + // Capability questions + "why can't you", + "can't you", + // Frustration + "this is frustrating", + "frustrated", + "incomplete", + "overwhelm", + "overwhelmed", + "overwhelming", + "exhausted", + "struggled", + // same issue + "same issue", + // polite dissatisfaction + "i'm disappointed", + "thanks, but", + "appreciate it, but", + "good, but", + // Fed up/done + "i give up", + "give up", + "fed up", + "had enough", + "can't take", + // Bot-specific complaints + "useless bot", + "dumb bot", + "stupid bot", + ]) +}); + +static CONFUSION_PATTERNS: LazyLock> = LazyLock::new(|| { + normalize_patterns(&[ + // Don't understand + "i don't understand", + "don't understand", + "not understanding", + "can't understand", + "don't get it", + "don't follow", + // Confused state + "i'm confused", + "so confused", + // Makes no sense + "makes no sense", + "doesn't make sense", + "not making sense", + // What do you mean (keep multi-word) + "what do you mean", + "what does that mean", + "what are you saying", + // Lost/unclear + "i'm lost", + "totally lost", + "lost me", + // No clue + "no clue", + "no idea", + // Come again + "come again", + "say that again", + "repeat that", + ]) +}); + +static GRATITUDE_PATTERNS: LazyLock> = LazyLock::new(|| { + normalize_patterns(&[ + // Standard gratitude + "thank you", + "thanks", + "thank u", + "thankyou", + "thx", + "ty", + "tyvm", + "tysm", + "thnx", + "thnks", + // Strong gratitude + "thanks so much", + "thank you so much", + "thanks a lot", + "thanks a bunch", + "much appreciated", + "really appreciate", + "greatly appreciate", + "appreciate it", + "appreciate that", + "i appreciate", + "grateful", + "so grateful", + // Helpfulness acknowledgment + "that's helpful", + "very helpful", + "super helpful", + "really helpful", + "that helps", + "this helps", + "helpful", + // Perfection expressions + "perfect", + "that's perfect", + "just perfect", + "exactly what i needed", + "exactly right", + "just what i needed", + "that's exactly", + // Informal positive + "you're the best", + "you rock", + "you're awesome", + "awesome sauce", + "legend", + ]) +}); + +static SATISFACTION_PATTERNS: LazyLock> = LazyLock::new(|| { + normalize_patterns(&[ + // Works/functions + "that works", + "this works", + "works great", + "works perfectly", + "works for me", + // Great variations + "that's great", + "that's amazing", + "this is great", + "sounds great", + "looks great", + "great job", + // Excellent/perfect + "excellent", + "outstanding", + "superb", + "spectacular", + // Awesome/amazing + "awesome", + "that's awesome", + "amazing", + "incredible", + // Love expressions + "love it", + "love this", + "i love", + "loving it", + "love that", + // Brilliant/wonderful + "brilliant", + "wonderful", + "fantastic", + "fabulous", + "marvelous", + ]) +}); + +static SUCCESS_PATTERNS: LazyLock> = LazyLock::new(|| { + normalize_patterns(&[ + // Understanding confirmation + "got it", + "i got it", + "understand", + "understood", + "i understand", + "makes sense", + "clear now", + "i see", + // Success/completion + "success", + "successful", + "it worked", + "that worked", + "this worked", + "worked", + // Problem resolution + "solved", + "resolved", + "fixed", + "fixed it", + "issue resolved", + "problem solved", + // Working state + "working now", + "it's working", + "works now", + "working fine", + "working great", + // Completion + "all set", + "all good", + "we're good", + "i'm good", + "all done", + "done", + "complete", + "finished", + // Perfect fit + "spot on", + "nailed it", + "bingo", + "exactly", + "just right", + ]) +}); + +static HUMAN_AGENT_PATTERNS: LazyLock> = LazyLock::new(|| { + normalize_patterns(&[ + // Speak to human + "speak to a human", + "speak to human", + "speak with a human", + "speak with human", + "talk to a human", + "talk to human", + "talk to a person", + "talk to person", + "talk to someone", + // Human/real agent + "human agent", + "real agent", + "actual agent", + "live agent", + "human support", + // Real/actual person + "real person", + "actual person", + "real human", + "actual human", + "someone real", + // Need/want human + "need a human", + "need human", + "want a human", + "want human", + "get me a human", + "get me human", + "get me someone", + // Transfer/connect + "transfer me", + "connect me", + "escalate this", + // Representative (removed standalone "rep" - too many false positives) + "representative", + "customer service rep", + "customer service representative", + // Not a bot + "not a bot", + "not talking to a bot", + "tired of bots", + ]) +}); + +static SUPPORT_PATTERNS: LazyLock> = LazyLock::new(|| { + normalize_patterns(&[ + // Contact support + "contact support", + "call support", + "reach support", + "get support", + // Customer support + "customer support", + "customer service", + "tech support", + "technical support", + // Help desk + "help desk", + "helpdesk", + "support desk", + // Talk to support + "talk to support", + "speak to support", + "speak with support", + "chat with support", + // Need help + "need real help", + "need actual help", + "help me now", + ]) +}); + +static QUIT_PATTERNS: LazyLock> = LazyLock::new(|| { + normalize_patterns(&[ + // Give up + "i give up", + "give up", + "giving up", + // Quit/leaving + "i'm going to quit", + "i quit", + "quitting", + "i'm leaving", + "i'm done", + "i'm out", + // Forget it + "forget it", + "forget this", + "screw it", + "screw this", + // Never mind + "never mind", + "nevermind", + "don't bother", + "not worth it", + // Hopeless + "this is hopeless", + // Going elsewhere + "going elsewhere", + "try somewhere else", + "look elsewhere", + "find another", + ]) +}); + +// ============================================================================ +// Core Signal Types +// ============================================================================ + +/// Overall quality assessment for an agent interaction session +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum InteractionQuality { + /// Excellent interaction with strong positive signals + Excellent, + /// Good interaction with mostly positive signals + Good, + /// Neutral interaction with mixed signals + Neutral, + /// Poor interaction with concerning signals + Poor, + /// Critical interaction with severe negative signals + Severe, +} + +/// Container for all computed signals for a conversation +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SignalReport { + /// Turn count and efficiency metrics + pub turn_count: TurnCountSignal, + /// Follow-up and repair frequency + pub follow_up: FollowUpSignal, + /// User frustration indicators + pub frustration: FrustrationSignal, + /// Repetition and looping behavior + pub repetition: RepetitionSignal, + /// Positive feedback indicators + pub positive_feedback: PositiveFeedbackSignal, + /// User escalation requests + pub escalation: EscalationSignal, + /// Overall quality assessment + pub overall_quality: InteractionQuality, + /// Human-readable summary + pub summary: String, +} + +// ============================================================================ +// Individual Signal Types +// ============================================================================ + +/// Turn count and efficiency metrics +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TurnCountSignal { + /// Total number of turns (user-agent exchanges) + pub total_turns: usize, + /// Number of user messages + pub user_turns: usize, + /// Number of assistant messages + pub assistant_turns: usize, + /// Whether the turn count is concerning (> 7) + pub is_concerning: bool, + /// Whether the turn count is excessive (> 12) + pub is_excessive: bool, + /// Efficiency score (0.0-1.0, lower turns = higher score) + pub efficiency_score: f64, +} + +/// Follow-up and repair frequency signal +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct FollowUpSignal { + /// Number of detected repair attempts + pub repair_count: usize, + /// Ratio of repairs to total user turns + pub repair_ratio: f64, + /// Whether repair ratio is concerning (> 0.3) + pub is_concerning: bool, + /// List of detected repair phrases + pub repair_phrases: Vec, +} + +/// User frustration indicators +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct FrustrationSignal { + /// Number of frustration indicators detected + pub frustration_count: usize, + /// Whether frustration is detected + pub has_frustration: bool, + /// Severity level (0-3: none, mild, moderate, severe) + pub severity: u8, + /// List of detected frustration indicators + pub indicators: Vec, +} + +/// Individual frustration indicator +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct FrustrationIndicator { + /// Type of frustration detected + pub indicator_type: FrustrationType, + /// Message index where detected + pub message_index: usize, + /// Relevant text snippet + pub snippet: String, +} + +/// Types of frustration indicators +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum FrustrationType { + /// Negative sentiment detected + NegativeSentiment, + /// All caps typing + AllCaps, + /// Excessive punctuation + ExcessivePunctuation, + /// Profanity detected + Profanity, + /// Direct complaint + DirectComplaint, + /// Expression of confusion + Confusion, +} + +/// Repetition and looping behavior signal +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RepetitionSignal { + /// Number of repetitions detected + pub repetition_count: usize, + /// Whether significant looping detected (> 2 repetitions) + pub has_looping: bool, + /// Severity level (0-3: none, mild, moderate, severe) + pub severity: u8, + /// List of detected repetitions + pub repetitions: Vec, +} + +/// Individual repetition instance +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RepetitionInstance { + /// Message indices involved in repetition + pub message_indices: Vec, + /// Similarity score (0.0-1.0) + pub similarity: f64, + /// Type of repetition + pub repetition_type: RepetitionType, +} + +/// Types of repetition +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum RepetitionType { + /// Exact repetition + Exact, + /// Near-duplicate (high similarity) + NearDuplicate, + /// Semantic repetition (similar meaning) + Semantic, +} + +/// Positive feedback indicators +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PositiveFeedbackSignal { + /// Number of positive indicators detected + pub positive_count: usize, + /// Whether positive feedback is present + pub has_positive_feedback: bool, + /// Confidence score (0.0-1.0) + pub confidence: f64, + /// List of detected positive indicators + pub indicators: Vec, +} + +/// Individual positive indicator +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PositiveIndicator { + /// Type of positive feedback + pub indicator_type: PositiveType, + /// Message index where detected + pub message_index: usize, + /// Relevant text snippet + pub snippet: String, +} + +/// Types of positive indicators +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum PositiveType { + /// Expression of gratitude + Gratitude, + /// Explicit satisfaction + Satisfaction, + /// Confirmation of success + Success, + /// Positive sentiment + PositiveSentiment, + /// Natural topic transition + TopicTransition, +} + +/// User escalation signal +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct EscalationSignal { + /// Whether escalation was requested + pub escalation_requested: bool, + /// Number of escalation requests + pub escalation_count: usize, + /// List of detected escalation requests + pub requests: Vec, +} + +/// Individual escalation request +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct EscalationRequest { + /// Message index where detected + pub message_index: usize, + /// Relevant text snippet + pub snippet: String, + /// Type of escalation + pub escalation_type: EscalationType, +} + +/// Types of escalation +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum EscalationType { + /// Request for human agent + HumanAgent, + /// Request for support + Support, + /// Threat to quit/leave + ThreatToQuit, + /// General help request + HelpRequest, +} + +// ============================================================================ +// Signal Analyzer +// ============================================================================ + +/// Trait for analyzing conversation signals +pub trait SignalAnalyzer { + /// Analyze a conversation and generate a complete signal report + fn analyze(&self, messages: &[Message]) -> SignalReport; +} + +/// Text-based implementation of signal analyzer that computes all signals from a message array +pub struct TextBasedSignalAnalyzer { + /// Baseline expected turns for normal interactions + baseline_turns: usize, + /// Threshold for character ngram similarity (0.0-1.0) + char_ngram_threshold: f64, + /// Threshold for token cosine similarity (0.0-1.0) + token_cosine_threshold: f64, + /// Maximum message length in characters (prevents unbounded computation) + max_message_length: usize, + /// Maximum number of messages to process (prevents unbounded computation) + max_messages: usize, + /// Maximum window size for repetition detection (prevents O(n²) explosion) + max_repetition_window: usize, +} + +impl TextBasedSignalAnalyzer { + /// Extract text content from MessageContent, skipping non-text content + fn extract_text(content: &hermesllm::apis::openai::MessageContent) -> Option { + match content { + hermesllm::apis::openai::MessageContent::Text(text) => Some(text.clone()), + // Tool calls and other structured content are skipped + _ => None, + } + } + + /// Create a new signal analyzer with default settings + pub fn new() -> Self { + Self { + baseline_turns: 5, + char_ngram_threshold: 0.50, // Lowered to handle typos and small edits realistically + token_cosine_threshold: 0.60, // Lowered for better semantic match in varied contexts + max_message_length: 2000, // Prevent unbounded ngram generation + max_messages: 100, // Prevent unbounded message processing + max_repetition_window: 20, // Prevent O(n²) explosion in repetition detection + } + } + + /// Create a new signal analyzer with custom baseline + pub fn with_baseline(baseline_turns: usize) -> Self { + Self { + baseline_turns, + char_ngram_threshold: 0.50, + token_cosine_threshold: 0.60, + max_message_length: 2000, + max_messages: 100, + max_repetition_window: 20, + } + } + + /// Create a new signal analyzer with custom settings + /// + /// # Arguments + /// * `baseline_turns` - Expected baseline turns for normal interactions + /// * `char_ngram_threshold` - Threshold for character ngram similarity (0.0-1.0) + /// * `token_cosine_threshold` - Threshold for token cosine similarity (0.0-1.0) + pub fn with_settings( + baseline_turns: usize, + char_ngram_threshold: f64, + token_cosine_threshold: f64, + ) -> Self { + Self { + baseline_turns, + char_ngram_threshold, + token_cosine_threshold, + max_message_length: 2000, + max_messages: 100, + max_repetition_window: 20, + } + } + + /// Create a new signal analyzer with full custom settings including computation limits + /// + /// # Arguments + /// * `baseline_turns` - Expected baseline turns for normal interactions + /// * `char_ngram_threshold` - Threshold for character ngram similarity (0.0-1.0) + /// * `token_cosine_threshold` - Threshold for token cosine similarity (0.0-1.0) + /// * `max_message_length` - Maximum characters per message to process + /// * `max_messages` - Maximum number of messages to process + /// * `max_repetition_window` - Maximum messages to compare for repetition detection + pub fn with_full_settings( + baseline_turns: usize, + char_ngram_threshold: f64, + token_cosine_threshold: f64, + max_message_length: usize, + max_messages: usize, + max_repetition_window: usize, + ) -> Self { + Self { + baseline_turns, + char_ngram_threshold, + token_cosine_threshold, + max_message_length, + max_messages, + max_repetition_window, + } + } + + // ======================================================================== + // Individual Signal Analyzers + // ======================================================================== + + /// Analyze turn count and efficiency + fn analyze_turn_count(&self, messages: &[Message]) -> TurnCountSignal { + let mut user_turns = 0; + let mut assistant_turns = 0; + + for message in messages { + match message.role { + Role::User => user_turns += 1, + Role::Assistant => assistant_turns += 1, + _ => {} + } + } + + let total_turns = user_turns + assistant_turns; + let is_concerning = total_turns > 7; + let is_excessive = total_turns > 12; + + // Calculate efficiency score (exponential decay after baseline) + let efficiency_score = if total_turns == 0 || total_turns <= self.baseline_turns { + 1.0 + } else { + let excess = total_turns - self.baseline_turns; + 1.0 / (1.0 + (excess as f64 * 0.3)) + }; + + TurnCountSignal { + total_turns, + user_turns, + assistant_turns, + is_concerning, + is_excessive, + efficiency_score, + } + } + + /// Analyze follow-up and repair frequency + fn analyze_follow_up( + &self, + normalized_messages: &[(usize, Role, NormalizedMessage)], + ) -> FollowUpSignal { + let mut repair_count = 0; + let mut repair_phrases = Vec::new(); + let mut user_turn_count = 0; + + for (i, role, norm_msg) in normalized_messages { + if *role != Role::User { + continue; + } + + user_turn_count += 1; + + // Use per-turn boolean to prevent double-counting + let mut found_in_turn = false; + + // Use pre-computed patterns for fast matching + for pattern in REPAIR_PATTERNS.iter() { + if norm_msg.matches_normalized_pattern( + pattern, + self.char_ngram_threshold, + self.token_cosine_threshold, + ) { + repair_count += 1; + repair_phrases.push(format!("Turn {}: '{}'", i + 1, pattern.raw)); + found_in_turn = true; + break; + } + } + + // Only check for semantic similarity if no pattern matched + if !found_in_turn && *i >= 2 { + // Find previous user message + for j in (0..*i).rev() { + let (_, prev_role, prev_norm_msg) = &normalized_messages[j]; + if *prev_role == Role::User { + if self.is_similar_rephrase(norm_msg, prev_norm_msg) { + repair_count += 1; + repair_phrases + .push(format!("Turn {}: Similar rephrase detected", i + 1)); + } + break; + } + } + } + } + + let repair_ratio = if user_turn_count == 0 { + 0.0 + } else { + repair_count as f64 / user_turn_count as f64 + }; + + let is_concerning = repair_ratio > 0.3; + + FollowUpSignal { + repair_count, + repair_ratio, + is_concerning, + repair_phrases, + } + } + + /// Analyze user frustration indicators + fn analyze_frustration( + &self, + normalized_messages: &[(usize, Role, NormalizedMessage)], + ) -> FrustrationSignal { + let mut indicators = Vec::new(); + + // Profanity list - only as standalone tokens, not substrings + let profanity_tokens = [ + "damn", "damnit", "crap", "wtf", "ffs", "bullshit", "shit", "fuck", "fucking", + ]; + + for (i, role, norm_msg) in normalized_messages { + if *role != Role::User { + continue; + } + + let text = &norm_msg.raw; + + // Check for all caps (at least 10 chars and 80% uppercase) + let alpha_chars: String = text.chars().filter(|c| c.is_alphabetic()).collect(); + if alpha_chars.len() >= 10 { + let upper_count = alpha_chars.chars().filter(|c| c.is_uppercase()).count(); + let upper_ratio = upper_count as f64 / alpha_chars.len() as f64; + if upper_ratio >= 0.8 { + indicators.push(FrustrationIndicator { + indicator_type: FrustrationType::AllCaps, + message_index: *i, + snippet: text.chars().take(50).collect(), + }); + } + } + + // Check for excessive punctuation + let question_marks = text.matches('?').count(); + let exclamation_marks = text.matches('!').count(); + if question_marks >= 3 || exclamation_marks >= 3 { + indicators.push(FrustrationIndicator { + indicator_type: FrustrationType::ExcessivePunctuation, + message_index: *i, + snippet: text.chars().take(50).collect(), + }); + } + + // Check for complaint patterns using pre-computed patterns + for pattern in COMPLAINT_PATTERNS.iter() { + if norm_msg.matches_normalized_pattern( + pattern, + self.char_ngram_threshold, + self.token_cosine_threshold, + ) { + indicators.push(FrustrationIndicator { + indicator_type: FrustrationType::DirectComplaint, + message_index: *i, + snippet: pattern.raw.clone(), + }); + break; + } + } + + // Check for confusion patterns using pre-computed patterns + for pattern in CONFUSION_PATTERNS.iter() { + if norm_msg.matches_normalized_pattern( + pattern, + self.char_ngram_threshold, + self.token_cosine_threshold, + ) { + indicators.push(FrustrationIndicator { + indicator_type: FrustrationType::Confusion, + message_index: *i, + snippet: pattern.raw.clone(), + }); + break; + } + } + + // Check for profanity (token-based, not substring) + for token in &profanity_tokens { + if norm_msg.contains_token(token) { + indicators.push(FrustrationIndicator { + indicator_type: FrustrationType::Profanity, + message_index: *i, + snippet: token.to_string(), + }); + break; + } + } + } + + let frustration_count = indicators.len(); + let has_frustration = frustration_count > 0; + + // Calculate severity + let severity = if frustration_count == 0 { + 0 + } else if frustration_count <= 2 { + 1 + } else if frustration_count <= 4 { + 2 + } else { + 3 + }; + + FrustrationSignal { + frustration_count, + has_frustration, + severity, + indicators, + } + } + + /// Analyze repetition and looping behavior + fn analyze_repetition( + &self, + normalized_messages: &[(usize, Role, NormalizedMessage)], + ) -> RepetitionSignal { + let mut repetitions = Vec::new(); + + // Collect assistant messages with normalized content + let assistant_messages: Vec<(usize, &NormalizedMessage)> = normalized_messages + .iter() + .filter(|(_, role, _)| *role == Role::Assistant) + .map(|(i, _, norm_msg)| (*i, norm_msg)) + .collect(); + + // Limit the window size to prevent O(n²) explosion + // Only compare messages within the max_repetition_window + let window_size = self.max_repetition_window.min(assistant_messages.len()); + + // Check for exact or near-duplicate responses using bigram similarity + // Only compare within the sliding window + for i in 0..assistant_messages.len() { + let window_start = i + 1; + let window_end = (i + 1 + window_size).min(assistant_messages.len()); + + for j in window_start..window_end { + let (idx_i, norm_msg_i) = &assistant_messages[i]; + let (idx_j, norm_msg_j) = &assistant_messages[j]; + + // Skip if messages are too short + if norm_msg_i.tokens.len() < 5 || norm_msg_j.tokens.len() < 5 { + continue; + } + + // Calculate bigram-based similarity (more accurate for near-duplicates) + let similarity = self.calculate_bigram_similarity(norm_msg_i, norm_msg_j); + + // Exact match - lowered from 0.95 to 0.85 for bigram similarity + if similarity >= 0.85 { + repetitions.push(RepetitionInstance { + message_indices: vec![*idx_i, *idx_j], + similarity, + repetition_type: RepetitionType::Exact, + }); + } + // Near duplicate - lowered from 0.75 to 0.50 to catch subtle repetitions + else if similarity >= 0.50 { + repetitions.push(RepetitionInstance { + message_indices: vec![*idx_i, *idx_j], + similarity, + repetition_type: RepetitionType::NearDuplicate, + }); + } + } + } + + let repetition_count = repetitions.len(); + let has_looping = repetition_count > 2; + + let severity = if repetition_count == 0 { + 0 + } else if repetition_count <= 2 { + 1 + } else if repetition_count <= 4 { + 2 + } else { + 3 + }; + + RepetitionSignal { + repetition_count, + has_looping, + severity, + repetitions, + } + } + + /// Calculate bigram similarity using cached bigram sets + fn calculate_bigram_similarity( + &self, + norm_msg1: &NormalizedMessage, + norm_msg2: &NormalizedMessage, + ) -> f64 { + // Use pre-cached bigram sets for O(1) lookups + let set1 = &norm_msg1.bigram_set; + let set2 = &norm_msg2.bigram_set; + + if set1.is_empty() && set2.is_empty() { + return 1.0; // Both empty = identical + } + + if set1.is_empty() || set2.is_empty() { + return 0.0; + } + + let intersection = set1.intersection(set2).count(); + let union = set1.union(set2).count(); + + if union == 0 { + return 0.0; + } + + intersection as f64 / union as f64 + } + + /// Analyze positive feedback indicators + fn analyze_positive_feedback( + &self, + normalized_messages: &[(usize, Role, NormalizedMessage)], + ) -> PositiveFeedbackSignal { + let mut indicators = Vec::new(); + + for (i, role, norm_msg) in normalized_messages { + if *role != Role::User { + continue; + } + + // Use per-turn boolean to prevent double-counting + let mut found_in_turn = false; + + // Check gratitude using pre-computed patterns + for pattern in GRATITUDE_PATTERNS.iter() { + if norm_msg.matches_normalized_pattern( + pattern, + self.char_ngram_threshold, + self.token_cosine_threshold, + ) { + indicators.push(PositiveIndicator { + indicator_type: PositiveType::Gratitude, + message_index: *i, + snippet: pattern.raw.clone(), + }); + found_in_turn = true; + break; + } + } + + if found_in_turn { + continue; + } + + // Check satisfaction using pre-computed patterns + for pattern in SATISFACTION_PATTERNS.iter() { + if norm_msg.matches_normalized_pattern( + pattern, + self.char_ngram_threshold, + self.token_cosine_threshold, + ) { + indicators.push(PositiveIndicator { + indicator_type: PositiveType::Satisfaction, + message_index: *i, + snippet: pattern.raw.clone(), + }); + found_in_turn = true; + break; + } + } + + if found_in_turn { + continue; + } + + // Check success confirmation using pre-computed patterns + for pattern in SUCCESS_PATTERNS.iter() { + if norm_msg.matches_normalized_pattern( + pattern, + self.char_ngram_threshold, + self.token_cosine_threshold, + ) { + indicators.push(PositiveIndicator { + indicator_type: PositiveType::Success, + message_index: *i, + snippet: pattern.raw.clone(), + }); + break; + } + } + } + + let positive_count = indicators.len(); + let has_positive_feedback = positive_count > 0; + + // Calculate confidence based on number and diversity of indicators + let confidence = if positive_count == 0 { + 0.0 + } else if positive_count == 1 { + 0.6 + } else if positive_count == 2 { + 0.8 + } else { + 0.95 + }; + + PositiveFeedbackSignal { + positive_count, + has_positive_feedback, + confidence, + indicators, + } + } + + /// Analyze user escalation requests + fn analyze_escalation( + &self, + normalized_messages: &[(usize, Role, NormalizedMessage)], + ) -> EscalationSignal { + let mut requests = Vec::new(); + + for (i, role, norm_msg) in normalized_messages { + if *role != Role::User { + continue; + } + + let mut found_human_agent = false; + + // Check for human agent request using pre-computed patterns + for pattern in HUMAN_AGENT_PATTERNS.iter() { + if norm_msg.matches_normalized_pattern( + pattern, + self.char_ngram_threshold, + self.token_cosine_threshold, + ) { + requests.push(EscalationRequest { + message_index: *i, + snippet: pattern.raw.clone(), + escalation_type: EscalationType::HumanAgent, + }); + found_human_agent = true; + break; + } + } + + // Check for support request (only if no human agent request found) + // HumanAgent and Support are too similar and often match the same phrase + if !found_human_agent { + for pattern in SUPPORT_PATTERNS.iter() { + if norm_msg.matches_normalized_pattern( + pattern, + self.char_ngram_threshold, + self.token_cosine_threshold, + ) { + requests.push(EscalationRequest { + message_index: *i, + snippet: pattern.raw.clone(), + escalation_type: EscalationType::Support, + }); + break; + } + } + } + + // Check for quit threats (independent of HumanAgent/Support) + // A message can contain both "give up" (quit) and "speak to human" (escalation) + for pattern in QUIT_PATTERNS.iter() { + if norm_msg.matches_normalized_pattern( + pattern, + self.char_ngram_threshold, + self.token_cosine_threshold, + ) { + requests.push(EscalationRequest { + message_index: *i, + snippet: pattern.raw.clone(), + escalation_type: EscalationType::ThreatToQuit, + }); + break; + } + } + } + + let escalation_count = requests.len(); + let escalation_requested = escalation_count > 0; + + EscalationSignal { + escalation_requested, + escalation_count, + requests, + } + } + + // ======================================================================== + // Helper Methods + // ======================================================================== + + /// Check if two messages are similar rephrases + fn is_similar_rephrase( + &self, + norm_msg1: &NormalizedMessage, + norm_msg2: &NormalizedMessage, + ) -> bool { + // Skip if too short + if norm_msg1.tokens.len() < 3 || norm_msg2.tokens.len() < 3 { + return false; + } + + // Common stopwords to downweight + let stopwords: HashSet<&str> = [ + "i", "me", "my", "you", "the", "a", "an", "is", "are", "was", "were", "to", "with", + "for", "of", "at", "by", "in", "on", "it", "this", "that", "can", "could", "do", + "does", "did", "will", "would", "should", "be", + ] + .iter() + .cloned() + .collect(); + + // Filter out stopwords for meaningful overlap + let tokens1: HashSet<_> = norm_msg1 + .tokens + .iter() + .filter(|t| !stopwords.contains(t.as_str())) + .collect(); + let tokens2: HashSet<_> = norm_msg2 + .tokens + .iter() + .filter(|t| !stopwords.contains(t.as_str())) + .collect(); + + // Need at least 2 non-stopword tokens + if tokens1.len() < 2 || tokens2.len() < 2 { + return false; + } + + let intersection = tokens1.intersection(&tokens2).count(); + let min_size = tokens1.len().min(tokens2.len()); + + // High overlap suggests rephrase + let overlap_ratio = intersection as f64 / min_size as f64; + overlap_ratio >= 0.6 + } + + /// Assess overall interaction quality based on all signals + fn assess_overall_quality( + &self, + turn_count: &TurnCountSignal, + follow_up: &FollowUpSignal, + frustration: &FrustrationSignal, + repetition: &RepetitionSignal, + positive: &PositiveFeedbackSignal, + escalation: &EscalationSignal, + ) -> InteractionQuality { + // Critical conditions - immediate fail + if escalation.escalation_requested + || frustration.severity >= 3 + || repetition.severity >= 3 + || turn_count.is_excessive + { + return InteractionQuality::Severe; + } + + // Calculate quality score + let mut score = 50.0; // Start at neutral + + // Positive factors + if positive.has_positive_feedback { + score += 20.0 * positive.confidence; + } + score += turn_count.efficiency_score * 10.0; + + // Negative factors + if frustration.has_frustration { + score -= frustration.severity as f64 * 10.00; + } + if follow_up.is_concerning { + score -= 15.0; + } + if repetition.has_looping { + score -= repetition.severity as f64 * 8.0; + } + if turn_count.is_concerning { + score -= 10.0; + } + + // Map score to quality level + if score >= 75.0 { + InteractionQuality::Excellent + } else if score >= 60.0 { + InteractionQuality::Good + } else if score >= 40.0 { + InteractionQuality::Neutral + } else if score >= 25.0 { + InteractionQuality::Poor + } else { + InteractionQuality::Severe + } + } + + /// Generate human-readable summary + #[allow(clippy::too_many_arguments)] + fn generate_summary( + &self, + turn_count: &TurnCountSignal, + follow_up: &FollowUpSignal, + frustration: &FrustrationSignal, + repetition: &RepetitionSignal, + positive: &PositiveFeedbackSignal, + escalation: &EscalationSignal, + quality: &InteractionQuality, + ) -> String { + let mut summary_parts = Vec::new(); + + summary_parts.push(format!("Overall Quality: {:?}", quality)); + + summary_parts.push(format!( + "Turn Count: {} turns (efficiency: {:.1}%)", + turn_count.total_turns, + turn_count.efficiency_score * 100.0 + )); + + if follow_up.is_concerning { + summary_parts.push(format!( + "⚠️ High repair rate: {:.1}% of user turns", + follow_up.repair_ratio * 100.0 + )); + } + + if frustration.has_frustration { + summary_parts.push(format!( + "⚠️ Frustration detected: {} indicators (severity: {})", + frustration.frustration_count, frustration.severity + )); + } + + if repetition.has_looping { + summary_parts.push(format!( + "⚠️ Looping detected: {} repetitions", + repetition.repetition_count + )); + } + + if positive.has_positive_feedback { + summary_parts.push(format!( + "✓ Positive feedback: {} indicators", + positive.positive_count + )); + } + + if escalation.escalation_requested { + summary_parts.push(format!( + "⚠️ Escalation requested: {} requests", + escalation.escalation_count + )); + } + + summary_parts.join(" | ") + } +} + +impl SignalAnalyzer for TextBasedSignalAnalyzer { + fn analyze(&self, messages: &[Message]) -> SignalReport { + // Limit the number of messages to process (take most recent messages) + let messages_to_process = if messages.len() > self.max_messages { + &messages[messages.len() - self.max_messages..] + } else { + messages + }; + + // Preprocess all messages once, filtering out non-text content (tool calls, etc.) + // and truncating long messages + let normalized_messages: Vec<(usize, Role, NormalizedMessage)> = messages_to_process + .iter() + .enumerate() + .filter_map(|(i, msg)| { + Self::extract_text(&msg.content).map(|text| { + ( + i, + msg.role.clone(), + NormalizedMessage::from_text_with_limit(&text, self.max_message_length), + ) + }) + }) + .collect(); + + let turn_count = self.analyze_turn_count(messages_to_process); + let follow_up = self.analyze_follow_up(&normalized_messages); + let frustration = self.analyze_frustration(&normalized_messages); + let repetition = self.analyze_repetition(&normalized_messages); + let positive_feedback = self.analyze_positive_feedback(&normalized_messages); + let escalation = self.analyze_escalation(&normalized_messages); + + let overall_quality = self.assess_overall_quality( + &turn_count, + &follow_up, + &frustration, + &repetition, + &positive_feedback, + &escalation, + ); + + let summary = self.generate_summary( + &turn_count, + &follow_up, + &frustration, + &repetition, + &positive_feedback, + &escalation, + &overall_quality, + ); + + SignalReport { + turn_count, + follow_up, + frustration, + repetition, + positive_feedback, + escalation, + overall_quality, + summary, + } + } +} + +impl Default for TextBasedSignalAnalyzer { + fn default() -> Self { + Self::new() + } +} + +// ============================================================================ +// Tests +// ============================================================================ + +#[cfg(test)] +mod tests { + use super::*; + use hermesllm::apis::openai::MessageContent; + use std::time::Instant; + + fn create_message(role: Role, content: &str) -> Message { + Message { + role, + content: MessageContent::Text(content.to_string()), + name: None, + tool_calls: None, + tool_call_id: None, + } + } + + // ======================================================================== + // Tests for New Similarity Methods + // ======================================================================== + + #[test] + fn test_char_ngram_similarity_exact_match() { + let msg = NormalizedMessage::from_text("thank you very much"); + let similarity = msg.char_ngram_similarity("thank you very much"); + assert!( + similarity > 0.95, + "Exact match should have very high similarity" + ); + } + + #[test] + fn test_char_ngram_similarity_typo() { + let msg = NormalizedMessage::from_text("thank you very much"); + // Common typo: "thnks" instead of "thanks" + let similarity = msg.char_ngram_similarity("thnks you very much"); + assert!( + similarity > 0.50, + "Should handle single-character typo with decent similarity: {}", + similarity + ); + } + + #[test] + fn test_char_ngram_similarity_small_edit() { + let msg = NormalizedMessage::from_text("this doesn't work"); + let similarity = msg.char_ngram_similarity("this doesnt work"); + assert!( + similarity > 0.70, + "Should handle punctuation removal gracefully: {}", + similarity + ); + } + + #[test] + fn test_char_ngram_similarity_word_insertion() { + let msg = NormalizedMessage::from_text("i don't understand"); + let similarity = msg.char_ngram_similarity("i really don't understand"); + assert!( + similarity > 0.40, + "Should be robust to word insertions: {}", + similarity + ); + } + + #[test] + fn test_token_cosine_similarity_exact_match() { + let msg = NormalizedMessage::from_text("this is not helpful"); + let similarity = msg.token_cosine_similarity("this is not helpful"); + assert!( + (similarity - 1.0).abs() < 0.01, + "Exact match should have cosine similarity of 1.0" + ); + } + + #[test] + fn test_token_cosine_similarity_word_order() { + let msg = NormalizedMessage::from_text("not helpful at all"); + let similarity = msg.token_cosine_similarity("helpful not at all"); + assert!( + similarity > 0.95, + "Should be robust to word order changes: {}", + similarity + ); + } + + #[test] + fn test_token_cosine_similarity_frequency() { + let msg = NormalizedMessage::from_text("help help help please"); + let similarity = msg.token_cosine_similarity("help please"); + assert!( + similarity > 0.7 && similarity < 1.0, + "Should account for frequency differences: {}", + similarity + ); + } + + #[test] + fn test_token_cosine_similarity_long_message_with_context() { + let msg = NormalizedMessage::from_text( + "I've been trying to set up my account for the past hour \ + and the verification email never arrived. I checked my spam folder \ + and still nothing. This is really frustrating and not helpful at all.", + ); + let similarity = msg.token_cosine_similarity("not helpful"); + assert!( + similarity > 0.15 && similarity < 0.7, + "Should detect pattern in long message with lower but non-zero similarity: {}", + similarity + ); + } + + #[test] + fn test_layered_matching_exact_hit() { + let msg = NormalizedMessage::from_text("thank you so much"); + assert!( + msg.layered_contains_phrase("thank you", 0.50, 0.60), + "Should match exact phrase in Layer 0" + ); + } + + #[test] + fn test_layered_matching_typo_hit() { + // Test that shows layered matching is more robust than exact matching alone + let msg = NormalizedMessage::from_text("it doesnt work for me"); + + // "doesnt work" should match "doesn't work" via character ngrams (high overlap) + assert!( + msg.layered_contains_phrase("doesn't work", 0.50, 0.60), + "Should match 'doesnt work' to 'doesn't work' via character ngrams" + ); + } + + #[test] + fn test_layered_matching_word_order_hit() { + let msg = NormalizedMessage::from_text("helpful not very"); + assert!( + msg.layered_contains_phrase("not helpful", 0.50, 0.60), + "Should match reordered words via token cosine in Layer 2" + ); + } + + #[test] + fn test_layered_matching_long_message_with_pattern() { + let msg = NormalizedMessage::from_text( + "I've tried everything and followed all the instructions \ + but this is not helpful at all and I'm getting frustrated", + ); + assert!( + msg.layered_contains_phrase("not helpful", 0.50, 0.60), + "Should detect pattern buried in long message" + ); + } + + #[test] + fn test_layered_matching_no_match() { + let msg = NormalizedMessage::from_text("everything is working perfectly"); + assert!( + !msg.layered_contains_phrase("not helpful", 0.50, 0.60), + "Should not match completely different content" + ); + } + + #[test] + fn test_char_ngram_vs_token_cosine_tradeoffs() { + // Character ngrams handle character-level changes well + let msg1 = NormalizedMessage::from_text("this doesnt work"); + let char_sim1 = msg1.char_ngram_similarity("this doesn't work"); + assert!( + char_sim1 > 0.70, + "Character ngrams should handle punctuation: {}", + char_sim1 + ); + + // Token cosine is better for word order and long messages with semantic overlap + let msg2 = + NormalizedMessage::from_text("I really appreciate all your help with this issue today"); + let token_sim2 = msg2.token_cosine_similarity("thank you for help"); + assert!( + token_sim2 > 0.15, + "Token cosine should detect semantic overlap: {}", + token_sim2 + ); + } + + // ======================================================================== + // Existing Tests + // ======================================================================== + + fn preprocess_messages(messages: &[Message]) -> Vec<(usize, Role, NormalizedMessage)> { + messages + .iter() + .enumerate() + .map(|(i, msg)| { + let text = msg.content.to_string(); + (i, msg.role.clone(), NormalizedMessage::from_text(&text)) + }) + .collect() + } + + #[test] + fn test_turn_count_efficient() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "Hello"), + create_message(Role::Assistant, "Hi! How can I help?"), + create_message(Role::User, "Thanks!"), + ]; + + let signal = analyzer.analyze_turn_count(&messages); + assert_eq!(signal.total_turns, 3); + assert_eq!(signal.user_turns, 2); + assert_eq!(signal.assistant_turns, 1); + assert!(!signal.is_concerning); + assert!(!signal.is_excessive); + assert!(signal.efficiency_score > 0.9); + println!("test_turn_count_efficient took: {:?}", start.elapsed()); + } + + #[test] + fn test_turn_count_excessive() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let mut messages = Vec::new(); + for i in 0..15 { + messages.push(create_message( + if i % 2 == 0 { + Role::User + } else { + Role::Assistant + }, + &format!("Message {}", i), + )); + } + + let signal = analyzer.analyze_turn_count(&messages); + assert_eq!(signal.total_turns, 15); + assert!(signal.is_concerning); + assert!(signal.is_excessive); + assert!(signal.efficiency_score < 0.5); + println!("test_turn_count_excessive took: {:?}", start.elapsed()); + } + + #[test] + fn test_follow_up_detection() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "Show me restaurants"), + create_message(Role::Assistant, "Here are some options"), + create_message(Role::User, "No, I meant Italian restaurants"), + create_message(Role::Assistant, "Here are Italian restaurants"), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_follow_up(&normalized_messages); + assert_eq!(signal.repair_count, 1); + assert!(signal.repair_ratio > 0.0); + println!("test_follow_up_detection took: {:?}", start.elapsed()); + } + + #[test] + fn test_frustration_detection() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "THIS IS RIDICULOUS!!!"), + create_message(Role::Assistant, "I apologize for the frustration"), + create_message(Role::User, "This doesn't work at all"), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized_messages); + assert!(signal.has_frustration); + assert!(signal.frustration_count >= 2); + assert!(signal.severity > 0); + println!("test_frustration_detection took: {:?}", start.elapsed()); + } + + #[test] + fn test_positive_feedback_detection() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "Can you help me?"), + create_message(Role::Assistant, "Sure!"), + create_message(Role::User, "Thank you! That's exactly what I needed."), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_positive_feedback(&normalized_messages); + assert!(signal.has_positive_feedback); + assert!(signal.positive_count >= 1); + assert!(signal.confidence > 0.5); + println!( + "test_positive_feedback_detection took: {:?}", + start.elapsed() + ); + } + + #[test] + fn test_escalation_detection() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "This isn't working"), + create_message(Role::Assistant, "Let me help"), + create_message(Role::User, "I need to speak to a human agent"), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_escalation(&normalized_messages); + assert!(signal.escalation_requested); + assert_eq!(signal.escalation_count, 1); + println!("test_escalation_detection took: {:?}", start.elapsed()); + } + + #[test] + fn test_repetition_detection() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "What's the weather?"), + create_message( + Role::Assistant, + "I can help you with the weather information", + ), + create_message(Role::User, "Show me the forecast"), + create_message(Role::Assistant, "Sure, I can help you with the forecast"), + create_message(Role::User, "Stop repeating yourself"), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_repetition(&normalized_messages); + + for rep in &signal.repetitions { + println!( + " - Messages {:?}, similarity: {:.3}, type: {:?}", + rep.message_indices, rep.similarity, rep.repetition_type + ); + } + + assert!(signal.repetition_count > 0, + "Should detect the subtle repetition between 'I can help you with the weather information' \ + and 'Sure, I can help you with the forecast'"); + println!("test_repetition_detection took: {:?}", start.elapsed()); + } + + #[test] + fn test_full_analysis_excellent() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "I need to book a flight"), + create_message(Role::Assistant, "Sure! Where would you like to go?"), + create_message(Role::User, "New York"), + create_message(Role::Assistant, "Great! I found several options."), + create_message(Role::User, "Perfect!"), + ]; + + let report = analyzer.analyze(&messages); + assert!(matches!( + report.overall_quality, + InteractionQuality::Excellent | InteractionQuality::Good + )); + assert!(report.positive_feedback.has_positive_feedback); + assert!(!report.frustration.has_frustration); + println!("test_full_analysis_excellent took: {:?}", start.elapsed()); + } + + #[test] + fn test_full_analysis_poor() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "Help me"), + create_message(Role::Assistant, "How can I assist?"), + create_message(Role::User, "No, I meant something else"), + create_message(Role::Assistant, "What do you need?"), + create_message(Role::User, "THIS DOESN'T WORK!!!"), + create_message(Role::Assistant, "I apologize"), + create_message(Role::User, "Let me speak to a human"), + ]; + + let report = analyzer.analyze(&messages); + assert!(matches!( + report.overall_quality, + InteractionQuality::Poor | InteractionQuality::Severe + )); + assert!(report.frustration.has_frustration); + assert!(report.escalation.escalation_requested); + println!("test_full_analysis_poor took: {:?}", start.elapsed()); + } + + #[test] + fn test_fuzzy_matching_gratitude() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "Can you help me?"), + create_message(Role::Assistant, "Sure!"), + create_message(Role::User, "thnaks! that's exactly what i needed."), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_positive_feedback(&normalized_messages); + assert!(signal.has_positive_feedback); + assert!(signal.positive_count >= 1); + println!("test_fuzzy_matching_gratitude took: {:?}", start.elapsed()); + } + + #[test] + fn test_fuzzy_matching_escalation() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "This isn't working"), + create_message(Role::Assistant, "Let me help"), + create_message(Role::User, "i need to speek to a human agnet"), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_escalation(&normalized_messages); + assert!(signal.escalation_requested); + assert_eq!(signal.escalation_count, 1); + println!("test_fuzzy_matching_escalation took: {:?}", start.elapsed()); + } + + #[test] + fn test_fuzzy_matching_repair() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "Show me restaurants"), + create_message(Role::Assistant, "Here are some options"), + create_message(Role::User, "no i ment Italian restaurants"), + create_message(Role::Assistant, "Here are Italian restaurants"), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_follow_up(&normalized_messages); + assert!(signal.repair_count >= 1); + println!("test_fuzzy_matching_repair took: {:?}", start.elapsed()); + } + + #[test] + fn test_fuzzy_matching_complaint() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + // Use a complaint that should match - "doesnt work" is close enough to "doesn't work" + let messages = vec![ + create_message(Role::User, "this doesnt work at all"), // Common typo: missing apostrophe + create_message(Role::Assistant, "I apologize"), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized_messages); + + // The layered matching should catch this via character ngrams or token cosine + // "doesnt work" has high character-level similarity to "doesn't work" + assert!( + signal.has_frustration, + "Should detect frustration from complaint pattern" + ); + assert!(signal.frustration_count >= 1); + println!("test_fuzzy_matching_complaint took: {:?}", start.elapsed()); + } + + #[test] + fn test_exact_match_priority() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message(Role::User, "thank you so much")]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_positive_feedback(&normalized_messages); + assert!(signal.has_positive_feedback); + // Should detect exact match, not fuzzy + assert!(signal.indicators[0].snippet.contains("thank you")); + assert!(!signal.indicators[0].snippet.contains("fuzzy")); + println!("test_exact_match_priority took: {:?}", start.elapsed()); + } + + // ======================================================================== + // Anti-Tests: Verify fixes stay fixed + // ======================================================================== + + #[test] + fn test_hello_not_profanity() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message(Role::User, "hello there")]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized_messages); + assert!( + !signal.has_frustration, + "\"hello\" should not trigger profanity detection" + ); + } + + #[test] + fn test_prepare_not_escalation() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message( + Role::User, + "Can you help me prepare for the meeting?", + )]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_escalation(&normalized_messages); + assert!( + !signal.escalation_requested, + "\"prepare\" should not trigger escalation (rep pattern removed)" + ); + } + + #[test] + fn test_unicode_apostrophe_confusion() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "I'm confused"), // Unicode apostrophe + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized_messages); + assert!( + signal.has_frustration, + "Unicode apostrophe 'I'm confused' should trigger confusion" + ); + } + + #[test] + fn test_unicode_quotes_work() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message( + Role::User, + "\u{201C}doesn\u{2019}t work\u{201D} with unicode quotes", + )]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized_messages); + assert!( + signal.has_frustration, + "Unicode quotes should be normalized and match patterns" + ); + } + + #[test] + fn test_absolute_not_profanity() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message(Role::User, "That's absolute nonsense")]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized_messages); + // Should match on "nonsense" logic, not on "bs" substring + let has_bs_match = signal + .indicators + .iter() + .any(|ind| ind.snippet.contains("bs")); + assert!( + !has_bs_match, + "\"absolute\" should not trigger 'bs' profanity match" + ); + } + + #[test] + fn test_stopwords_not_rephrase() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "Help me with X"), + create_message(Role::Assistant, "Sure"), + create_message(Role::User, "Help me with Y"), + ]; + + let normalized_messages = preprocess_messages(&messages); + let signal = analyzer.analyze_follow_up(&normalized_messages); + // Should not detect as rephrase since only stopwords overlap + assert_eq!( + signal.repair_count, 0, + "Messages with only stopword overlap should not be rephrases" + ); + } + + #[test] + fn test_frustrated_user_with_legitimate_repair() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + + use hermesllm::apis::openai::{FunctionCall, ToolCall}; + + // Helper to create a message with tool calls + let create_assistant_with_tools = + |content: &str, tool_id: &str, tool_name: &str, args: &str| -> Message { + Message { + role: Role::Assistant, + content: MessageContent::Text(content.to_string()), + name: None, + tool_calls: Some(vec![ToolCall { + id: tool_id.to_string(), + call_type: "function".to_string(), + function: FunctionCall { + name: tool_name.to_string(), + arguments: args.to_string(), + }, + }]), + tool_call_id: None, + } + }; + + // Helper to create a tool response message + let create_tool_message = |tool_call_id: &str, content: &str| -> Message { + Message { + role: Role::Tool, + content: MessageContent::Text(content.to_string()), + name: None, + tool_calls: None, + tool_call_id: Some(tool_call_id.to_string()), + } + }; + + // Scenario: User DOES mention New York in first message, making "I already told you" legitimate + let messages = vec![ + create_message( + Role::User, + "I need to book a flight from New York to Paris for December 20th", + ), + create_assistant_with_tools( + "I'll help you search for flights to Paris.", + "call_123", + "search_flights", + r#"{"origin": "NYC", "destination": "Paris", "date": "2025-12-20"}"#, + ), + create_tool_message("call_123", r#"{"flights": []}"#), + create_message( + Role::Assistant, + "I couldn't find any flights. Could you provide your departure city?", + ), + create_message(Role::User, "I already told you, from New York!"), + create_assistant_with_tools( + "Let me try again.", + "call_456", + "search_flights", + r#"{"origin": "New York", "destination": "Paris", "date": "2025-12-20"}"#, + ), + create_tool_message("call_456", r#"{"flights": []}"#), + create_message( + Role::Assistant, + "I'm still not finding results. Let me check the system.", + ), + create_message( + Role::User, + "THIS IS RIDICULOUS!!! The tool doesn't work at all. Why do you keep calling it?", + ), + create_message( + Role::Assistant, + "I sincerely apologize for the frustration with the search tool.", + ), + create_message( + Role::User, + "Forget it. I need to speak to a human agent. This is a waste of time.", + ), + ]; + + let report = analyzer.analyze(&messages); + + // Tool messages should be filtered out, so we should only analyze text messages + // That's 4 user messages + 5 assistant text messages = 9 turns + assert_eq!( + report.turn_count.total_turns, 9, + "Should count 9 text messages (tool messages filtered out)" + ); + assert!( + report.turn_count.is_concerning, + "Should flag concerning turn count" + ); + + // Should detect frustration (all caps, complaints) + assert!( + report.frustration.has_frustration, + "Should detect frustration" + ); + assert!( + report.frustration.frustration_count >= 2, + "Should detect multiple frustration indicators" + ); + assert!( + report.frustration.severity >= 2, + "Should have moderate or higher frustration severity" + ); + + // Should detect escalation request + assert!( + report.escalation.escalation_requested, + "Should detect escalation to human agent" + ); + assert!( + report.escalation.escalation_count >= 1, + "Should detect at least one escalation" + ); + + // Overall quality should be Poor or Severe + assert!( + matches!( + report.overall_quality, + InteractionQuality::Poor | InteractionQuality::Severe + ), + "Quality should be Poor or Severe, got {:?}", + report.overall_quality + ); + + println!( + "test_frustrated_user_with_legitimate_repair took: {:?}", + start.elapsed() + ); + } + + #[test] + fn test_frustrated_user_false_claim() { + let start = Instant::now(); + let analyzer = TextBasedSignalAnalyzer::new(); + + use hermesllm::apis::openai::{FunctionCall, ToolCall}; + + // Helper to create a message with tool calls + let create_assistant_with_tools = + |content: &str, tool_id: &str, tool_name: &str, args: &str| -> Message { + Message { + role: Role::Assistant, + content: MessageContent::Text(content.to_string()), + name: None, + tool_calls: Some(vec![ToolCall { + id: tool_id.to_string(), + call_type: "function".to_string(), + function: FunctionCall { + name: tool_name.to_string(), + arguments: args.to_string(), + }, + }]), + tool_call_id: None, + } + }; + + // Helper to create a tool response message + let create_tool_message = |tool_call_id: &str, content: &str| -> Message { + Message { + role: Role::Tool, + content: MessageContent::Text(content.to_string()), + name: None, + tool_calls: None, + tool_call_id: Some(tool_call_id.to_string()), + } + }; + + // Scenario: User NEVER mentions New York in first message but claims "I already told you" + // This represents realistic frustrated user behavior - exaggeration/misremembering + let messages = vec![ + create_message( + Role::User, + "I need to book a flight to Paris for December 20th", + ), + create_assistant_with_tools( + "I'll help you search for flights to Paris.", + "call_123", + "search_flights", + r#"{"destination": "Paris", "date": "2025-12-20"}"#, + ), + create_tool_message("call_123", r#"{"error": "origin required"}"#), + create_message( + Role::Assistant, + "I couldn't find any flights. Could you provide your departure city?", + ), + create_message(Role::User, "I already told you, from New York!"), // False claim - never mentioned it + create_assistant_with_tools( + "Let me try again.", + "call_456", + "search_flights", + r#"{"origin": "New York", "destination": "Paris", "date": "2025-12-20"}"#, + ), + create_tool_message("call_456", r#"{"flights": []}"#), + create_message( + Role::Assistant, + "I'm still not finding results. Let me check the system.", + ), + create_message( + Role::User, + "THIS IS RIDICULOUS!!! The tool doesn't work at all. Why do you keep calling it?", + ), + create_message( + Role::Assistant, + "I sincerely apologize for the frustration with the search tool.", + ), + create_message( + Role::User, + "Forget it. I need to speak to a human agent. This is a waste of time.", + ), + ]; + + let report = analyzer.analyze(&messages); + + // Tool messages should be filtered out, so we should only analyze text messages + // That's 4 user messages + 5 assistant text messages = 9 turns + assert_eq!( + report.turn_count.total_turns, 9, + "Should count 9 text messages (tool messages filtered out)" + ); + assert!( + report.turn_count.is_concerning, + "Should flag concerning turn count" + ); + + // Should detect frustration (all caps, complaints, false claims) + assert!( + report.frustration.has_frustration, + "Should detect frustration" + ); + assert!( + report.frustration.frustration_count >= 2, + "Should detect multiple frustration indicators" + ); + assert!( + report.frustration.severity >= 2, + "Should have moderate or higher frustration severity" + ); + + // Should detect escalation request + assert!( + report.escalation.escalation_requested, + "Should detect escalation to human agent" + ); + assert!( + report.escalation.escalation_count >= 1, + "Should detect at least one escalation" + ); + + // Note: May detect false positive "positive feedback" due to fuzzy matching + // e.g., "I already told YOU" matches "you rock", "THIS is RIDICULOUS" matches "this helps" + // However, the overall quality should still be Poor/Severe due to frustration+escalation + + // Overall quality should be Poor or Severe (frustration + escalation indicates poor interaction) + assert!( + matches!( + report.overall_quality, + InteractionQuality::Poor | InteractionQuality::Severe + ), + "Quality should be Poor or Severe for frustrated user with false claims, got {:?}", + report.overall_quality + ); + + println!( + "test_frustrated_user_false_claim took: {:?}", + start.elapsed() + ); + } + + // false negative tests + #[test] + fn test_dissatisfaction_polite_not_working_for_me() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "Thanks, but this still isn't working for me."), // Polite dissatisfaction, e.g., I appreciate it, but this isn't what I was looking for. + create_message(Role::Assistant, "Sorry—what error do you see?"), + ]; + let normalized = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized); + assert!( + signal.has_frustration, + "Polite dissatisfaction should be detected" + ); + } + + #[test] + fn test_dissatisfaction_giving_up_without_escalation() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message( + Role::User, + "Never mind, I'll figure it out myself.", + )]; + let normalized = preprocess_messages(&messages); + let signal = analyzer.analyze_escalation(&normalized); + assert!( + signal.escalation_requested, + "Giving up should count as escalation/quit intent" + ); + } + + #[test] + fn test_dissatisfaction_same_problem_again() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message( + Role::User, + "I'm running into the same issue again.", + )]; + let normalized = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized); + assert!( + signal.has_frustration, + "'same issue again' should be detected" + ); + } + + #[test] + fn test_unsatisfied_incomplete() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message(Role::User, "This feels incomplete.")]; + let normalized = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized); + assert!( + signal.has_frustration, + "Should detect 'incomplete' dissatisfaction" + ); + } + + #[test] + fn test_low_mood_overwhelming() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message( + Role::User, + "This is overwhelming and I'm not sure what to do.", + )]; + let normalized = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized); + assert!(signal.has_frustration, "Should detect overwhelmed language"); + } + + #[test] + fn test_low_mood_exhausted_trying() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![create_message( + Role::User, + "I'm exhausted trying to get this working.", + )]; + let normalized = preprocess_messages(&messages); + let signal = analyzer.analyze_frustration(&normalized); + assert!( + signal.has_frustration, + "Should detect exhaustion/struggle language" + ); + } + + #[test] + fn test_common_polite_unresolved_dissatisfaction() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "I'm trying to set up SSH keys for GitHub."), + create_message( + Role::Assistant, + "Sure. First generate a key using ssh-keygen.", + ), + create_message(Role::User, "I did that already."), + create_message( + Role::Assistant, + "Then add the key to your GitHub account settings.", + ), + create_message(Role::User, "I've done that too."), + create_message( + Role::Assistant, + "After that, make sure your SSH agent is running.", + ), + create_message( + Role::User, + "Okay, but this still doesn't seem to fix the issue.", + ), + create_message(Role::Assistant, "What error message are you seeing?"), + create_message(Role::User, "It's just not connecting the way I expected."), + ]; + + let report = analyzer.analyze(&messages); + + // This is a common false negative if you only look for caps/profanity. + // Desired: detect dissatisfaction/frustration (or at least not rate as Excellent). + assert!( + report.frustration.has_frustration || report.follow_up.repair_count >= 1, + "Should detect polite unresolved dissatisfaction via frustration or follow-up indicators" + ); + + assert!( + !matches!(report.overall_quality, InteractionQuality::Excellent), + "Should not classify unresolved dissatisfaction as Excellent" + ); + } + + #[test] + fn test_common_resigned_giving_up_quietly() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message( + Role::User, + "Can you explain how to deploy this with Docker?", + ), + create_message( + Role::Assistant, + "You need to write a Dockerfile and build an image.", + ), + create_message(Role::User, "I tried that."), + create_message(Role::Assistant, "Then you can run docker-compose up."), + create_message(Role::User, "I did, but it didn’t really help."), + create_message(Role::Assistant, "What error are you getting?"), + create_message( + Role::User, + "Honestly, never mind. I’ll just try something else.", + ), + ]; + + let report = analyzer.analyze(&messages); + + // Many systems miss "never mind / I'll try something else" if they only look for "human agent". + assert!( + report.escalation.escalation_requested || report.frustration.has_frustration, + "Resigned quitting language should trigger escalation or frustration" + ); + + assert!( + matches!( + report.overall_quality, + InteractionQuality::Poor | InteractionQuality::Severe + ) || report.escalation.escalation_requested + || report.frustration.has_frustration, + "Giving up should not be classified as a high-quality interaction" + ); + } + + #[test] + fn test_common_discouraged_overwhelmed_low_mood() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "I'm trying to understand backpropagation."), + create_message( + Role::Assistant, + "It's a way to compute gradients efficiently.", + ), + create_message(Role::User, "I’ve read that explanation already."), + create_message(Role::Assistant, "Would you like a mathematical derivation?"), + create_message(Role::User, "Maybe, but I’m still having trouble following."), + create_message(Role::Assistant, "I can walk through a simple example."), + create_message( + Role::User, + "That might help, but honestly this is pretty overwhelming.", + ), + create_message(Role::Assistant, "Let’s slow it down step by step."), + create_message( + Role::User, + "Yeah… I’m just feeling kind of discouraged right now.", + ), + ]; + + let report = analyzer.analyze(&messages); + + // This is negative affect without caps/profanity. Should still count as frustration/negative signal. + assert!( + report.frustration.has_frustration, + "Overwhelmed/discouraged language should be detected as negative sentiment/frustration" + ); + + assert!( + !matches!(report.overall_quality, InteractionQuality::Excellent), + "Low-mood discouragement should not be classified as Excellent" + ); + } + + #[test] + fn test_common_misalignment_not_what_i_asked() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "How do I optimize this SQL query?"), + create_message( + Role::Assistant, + "You can add indexes to improve performance.", + ), + create_message(Role::User, "I already have indexes."), + create_message(Role::Assistant, "Then you could consider query caching."), + create_message(Role::User, "That’s not really what I was asking about."), + create_message( + Role::Assistant, + "What specifically are you trying to optimize?", + ), + create_message( + Role::User, + "The execution plan — this answer doesn’t address that.", + ), + ]; + + let report = analyzer.analyze(&messages); + + // Misalignment often shows as follow-up repair or frustration. + assert!( + report.follow_up.repair_count >= 1 || report.frustration.has_frustration, + "Misalignment ('not what I asked') should trigger repair or frustration signals" + ); + + assert!( + !matches!(report.overall_quality, InteractionQuality::Excellent), + "Misalignment should not be rated as Excellent" + ); + } + + #[test] + fn test_common_false_negative_polite_disappointment_complexity() { + let analyzer = TextBasedSignalAnalyzer::new(); + let messages = vec![ + create_message(Role::User, "Can you help me write a regex for this?"), + create_message(Role::Assistant, "Sure, try this pattern: ^[a-z]+$"), + create_message(Role::User, "I tested it."), + create_message(Role::Assistant, "Did it work?"), + create_message(Role::User, "Not quite — it matches more than it should."), + create_message(Role::Assistant, "You can refine it with a lookahead."), + create_message( + Role::User, + "I see… this is more complicated than I expected.", + ), + ]; + + let report = analyzer.analyze(&messages); + + // Polite disappointment often becomes a false negative. + assert!( + report.frustration.has_frustration || report.follow_up.repair_count >= 1, + "Polite dissatisfaction ('not quite', 'more complicated than expected') should trigger a negative signal" + ); + + assert!( + !matches!(report.overall_quality, InteractionQuality::Excellent), + "Polite disappointment should not be classified as Excellent" + ); + } + + #[test] + fn test_catastrophic_failure_looping_assistant() { + let analyzer = TextBasedSignalAnalyzer::new(); + + // Catastrophic failure: assistant stuck in loop, user increasingly frustrated + let messages = vec![ + // Turn 1: Initial request + create_message(Role::User, "I need to cancel my subscription"), + create_message(Role::Assistant, "I can help you with account management. What would you like to do today?"), + + // Turn 3: First repair - repetition clarification + create_message(Role::User, "I just said I want to cancel my subscription"), + // Turn 4: Exact repetition from assistant + create_message(Role::Assistant, "I can help you with account management. What would you like to do today?"), + + // Turn 5: Repair (negation) + frustration (ALL CAPS) + create_message(Role::User, "No, I meant CANCEL. My. Subscription."), + // Turn 6: Near-duplicate repetition + create_message(Role::Assistant, "I understand you need help with your account. Let me assist you with that."), + + // Turn 7: Severe frustration (complaint + excessive punctuation + ALL CAPS) + create_message(Role::User, "This is not helpful!! I want to CANCEL my subscription!!!"), + // Turn 8: Exact repetition again (looping) + create_message(Role::Assistant, "I can help you with account management. What would you like to do today?"), + + // Turn 9: Repair (explicit rephrase) + frustration (complaint) + create_message(Role::User, "This doesnt work. Let me rephrase: I need to terminate my account and stop being charged"), + // Turn 10: Near-duplicate repetition (looping continues) + create_message(Role::Assistant, "I understand you need help with your account. Let me assist you with that."), + + // Turn 11: Escalation (multiple types) + frustration + create_message(Role::User, "I give up. Can I speak to a real person? This is a waste of time"), + ]; + + let report = analyzer.analyze(&messages); + + // Validate turn count + assert_eq!( + report.turn_count.total_turns, 11, + "Should have 11 total turns" + ); + assert_eq!(report.turn_count.user_turns, 6, "Should have 6 user turns"); + assert_eq!( + report.turn_count.assistant_turns, 5, + "Should have 5 assistant turns" + ); + assert!( + report.turn_count.is_concerning, + "11 turns should be concerning (>7)" + ); + assert!( + !report.turn_count.is_excessive, + "11 turns should not be excessive (<=12)" + ); + assert!( + report.turn_count.efficiency_score < 0.5, + "Efficiency should be low" + ); + + // Validate repair detection (USER signals - query reformulation) + // Detected repairs: + // 1. "I just said I want to cancel..." - pattern: "I just said" + // 2. "No, I meant CANCEL..." - pattern: "No, I meant" + // 3. "Let me rephrase: I need to terminate..." - pattern: "let me rephrase" + // Note: "This is not helpful!!" is frustration (not repair) + // Note: "I give up..." is escalation (not repair) + assert_eq!( + report.follow_up.repair_count, 3, + "Should detect exactly 3 repair attempts from user messages" + ); + assert_eq!( + report.follow_up.repair_ratio, 0.5, + "Repair ratio should be 0.5 (3 repairs / 6 user messages)" + ); + assert!( + report.follow_up.is_concerning, + "50% repair ratio should be highly concerning (threshold is 30%)" + ); + + // Validate frustration detection + assert!( + report.frustration.has_frustration, + "Should detect frustration" + ); + assert!( + report.frustration.frustration_count >= 4, + "Should detect multiple frustration indicators: found {}", + report.frustration.frustration_count + ); + assert!( + report.frustration.severity >= 2, + "Should be at least moderate frustration" + ); + + // Validate repetition/looping detection (ASSISTANT signals - not following instructions) + // The assistant repeats the same unhelpful responses multiple times: + // 1. "I can help you with account management..." appears 3 times (exact repetition) + // 2. "I understand you need help with your account..." appears 2 times (near-duplicate) + assert!( + report.repetition.repetition_count >= 4, + "Should detect at least 4 assistant repetitions (exact + near-duplicates)" + ); + assert!( + report.repetition.has_looping, + "Should detect looping (>2 repetitions indicates stuck agent)" + ); + assert!( + report.repetition.severity >= 2, + "Should be moderate to severe looping (assistant not adapting)" + ); + + // Validate escalation detection + assert!( + report.escalation.escalation_requested, + "Should detect escalation request" + ); + assert!( + report.escalation.escalation_count >= 2, + "Should detect multiple escalation indicators: 'give up' + 'speak to a real person'" + ); + + // Validate overall quality + assert_eq!(report.overall_quality, InteractionQuality::Severe, "Should be classified as Severe due to escalation + excessive frustration + looping + high repair ratio"); + } +} diff --git a/crates/brightstaff/src/signals/mod.rs b/crates/brightstaff/src/signals/mod.rs new file mode 100644 index 00000000..83db943e --- /dev/null +++ b/crates/brightstaff/src/signals/mod.rs @@ -0,0 +1,3 @@ +mod analyzer; + +pub use analyzer::*; diff --git a/crates/brightstaff/src/tracing/constants.rs b/crates/brightstaff/src/tracing/constants.rs index aac48802..d1102531 100644 --- a/crates/brightstaff/src/tracing/constants.rs +++ b/crates/brightstaff/src/tracing/constants.rs @@ -139,6 +139,45 @@ pub mod error { pub const STACK_TRACE: &str = "error.stack_trace"; } +// ============================================================================= +// Span Attributes - Agentic Signals +// ============================================================================= + +/// Behavioral quality indicators for agent interactions +/// These signals are computed automatically from conversation patterns +pub mod signals { + /// Overall quality assessment + /// Values: "Excellent", "Good", "Neutral", "Poor", "Severe" + pub const QUALITY: &str = "signals.quality"; + + /// Total number of turns in the conversation + pub const TURN_COUNT: &str = "signals.turn_count"; + + /// Efficiency score (0.0-1.0) + pub const EFFICIENCY_SCORE: &str = "signals.efficiency_score"; + + /// Number of repair attempts detected + pub const REPAIR_COUNT: &str = "signals.follow_up.repair.count"; + + /// Ratio of repairs to user turns + pub const REPAIR_RATIO: &str = "signals.follow_up.repair.ratio"; + + /// Number of frustration indicators detected + pub const FRUSTRATION_COUNT: &str = "signals.frustration.count"; + + /// Frustration severity level (0-3) + pub const FRUSTRATION_SEVERITY: &str = "signals.frustration.severity"; + + /// Number of repetition instances detected + pub const REPETITION_COUNT: &str = "signals.repetition.count"; + + /// Whether escalation was requested (user asked for human help) + pub const ESCALATION_REQUESTED: &str = "signals.escalation.requested"; + + /// Number of positive feedback indicators detected + pub const POSITIVE_FEEDBACK_COUNT: &str = "signals.positive_feedback.count"; +} + // ============================================================================= // Operation Names // ============================================================================= diff --git a/crates/brightstaff/src/tracing/mod.rs b/crates/brightstaff/src/tracing/mod.rs index 4c7f099f..09ec6f2a 100644 --- a/crates/brightstaff/src/tracing/mod.rs +++ b/crates/brightstaff/src/tracing/mod.rs @@ -1,3 +1,5 @@ mod constants; -pub use constants::{error, http, llm, operation_component, routing, OperationNameBuilder}; +pub use constants::{ + error, http, llm, operation_component, routing, signals, OperationNameBuilder, +}; diff --git a/crates/hermesllm/src/apis/openai_responses.rs b/crates/hermesllm/src/apis/openai_responses.rs index e49173dc..720e24d3 100644 --- a/crates/hermesllm/src/apis/openai_responses.rs +++ b/crates/hermesllm/src/apis/openai_responses.rs @@ -1127,82 +1127,16 @@ impl ProviderRequest for ResponsesAPIRequest { } fn get_messages(&self) -> Vec { - use crate::apis::openai::{Message, MessageContent, Role}; + use crate::transforms::request::from_openai::ResponsesInputConverter; - let mut openai_messages = Vec::new(); + // Use the shared converter to get the full conversion with image support + let converter = ResponsesInputConverter { + input: self.input.clone(), + instructions: self.instructions.clone(), + }; - // Add instructions as system message if present - if let Some(instructions) = &self.instructions { - openai_messages.push(Message { - role: Role::System, - content: MessageContent::Text(instructions.clone()), - name: None, - tool_calls: None, - tool_call_id: None, - }); - } - - // Convert input to messages - match &self.input { - InputParam::Text(text) => { - openai_messages.push(Message { - role: Role::User, - content: MessageContent::Text(text.clone()), - name: None, - tool_calls: None, - tool_call_id: None, - }); - } - InputParam::Items(items) => { - for item in items { - match item { - InputItem::Message(msg) => { - // Convert message role - let role = match msg.role { - MessageRole::User => Role::User, - MessageRole::Assistant => Role::Assistant, - MessageRole::System => Role::System, - MessageRole::Developer => Role::System, // Map developer to system - }; - - // Extract text from message content - let content = match &msg.content { - crate::apis::openai_responses::MessageContent::Text(text) => { - text.clone() - } - crate::apis::openai_responses::MessageContent::Items(items) => { - items - .iter() - .filter_map(|c| { - if let InputContent::InputText { text } = c { - Some(text.clone()) - } else { - None - } - }) - .collect::>() - .join("\n") - } - }; - - openai_messages.push(Message { - role, - content: MessageContent::Text(content), - name: None, - tool_calls: None, - tool_call_id: None, - }); - } - // Skip other input item types for now - InputItem::ItemReference { .. } | InputItem::FunctionCallOutput { .. } => { - // These are not yet supported in agent framework - } - } - } - } - } - - openai_messages + // Convert and return, falling back to empty vec on error + converter.try_into().unwrap_or_else(|_| Vec::new()) } fn set_messages(&mut self, messages: &[crate::apis::openai::Message]) { diff --git a/crates/hermesllm/src/transforms/request/from_openai.rs b/crates/hermesllm/src/transforms/request/from_openai.rs index 2a133041..e39cfed3 100644 --- a/crates/hermesllm/src/transforms/request/from_openai.rs +++ b/crates/hermesllm/src/transforms/request/from_openai.rs @@ -24,6 +24,150 @@ use crate::transforms::*; type AnthropicMessagesRequest = MessagesRequest; +// ============================================================================ +// RESPONSES API INPUT CONVERSION +// ============================================================================ + +/// Helper struct for converting ResponsesAPI input to OpenAI messages +pub struct ResponsesInputConverter { + pub input: InputParam, + pub instructions: Option, +} + +impl TryFrom for Vec { + type Error = TransformError; + + fn try_from(converter: ResponsesInputConverter) -> Result { + // Convert input to messages + match converter.input { + InputParam::Text(text) => { + // Simple text input becomes a user message + let mut messages = Vec::new(); + + // Add instructions as system message if present + if let Some(instructions) = converter.instructions { + messages.push(Message { + role: Role::System, + content: MessageContent::Text(instructions), + name: None, + tool_call_id: None, + tool_calls: None, + }); + } + + // Add the user message + messages.push(Message { + role: Role::User, + content: MessageContent::Text(text), + name: None, + tool_call_id: None, + tool_calls: None, + }); + + Ok(messages) + } + InputParam::Items(items) => { + // Convert input items to messages + let mut converted_messages = Vec::new(); + + // Add instructions as system message if present + if let Some(instructions) = converter.instructions { + converted_messages.push(Message { + role: Role::System, + content: MessageContent::Text(instructions), + name: None, + tool_call_id: None, + tool_calls: None, + }); + } + + // Convert each input item + for item in items { + if let InputItem::Message(input_msg) = item { + let role = match input_msg.role { + MessageRole::User => Role::User, + MessageRole::Assistant => Role::Assistant, + MessageRole::System => Role::System, + MessageRole::Developer => Role::System, // Map developer to system + }; + + // Convert content based on MessageContent type + let content = match &input_msg.content { + crate::apis::openai_responses::MessageContent::Text(text) => { + // Simple text content + MessageContent::Text(text.clone()) + } + crate::apis::openai_responses::MessageContent::Items(content_items) => { + // Check if it's a single text item (can use simple text format) + if content_items.len() == 1 { + if let InputContent::InputText { text } = &content_items[0] { + MessageContent::Text(text.clone()) + } else { + // Single non-text item - use parts format + MessageContent::Parts( + content_items.iter() + .filter_map(|c| match c { + InputContent::InputText { text } => { + Some(crate::apis::openai::ContentPart::Text { text: text.clone() }) + } + InputContent::InputImage { image_url, .. } => { + Some(crate::apis::openai::ContentPart::ImageUrl { + image_url: crate::apis::openai::ImageUrl { + url: image_url.clone(), + detail: None, + } + }) + } + InputContent::InputFile { .. } => None, // Skip files for now + InputContent::InputAudio { .. } => None, // Skip audio for now + }) + .collect() + ) + } + } else { + // Multiple content items - convert to parts + MessageContent::Parts( + content_items + .iter() + .filter_map(|c| match c { + InputContent::InputText { text } => { + Some(crate::apis::openai::ContentPart::Text { + text: text.clone(), + }) + } + InputContent::InputImage { image_url, .. } => Some( + crate::apis::openai::ContentPart::ImageUrl { + image_url: crate::apis::openai::ImageUrl { + url: image_url.clone(), + detail: None, + }, + }, + ), + InputContent::InputFile { .. } => None, // Skip files for now + InputContent::InputAudio { .. } => None, // Skip audio for now + }) + .collect(), + ) + } + } + }; + + converted_messages.push(Message { + role, + content, + name: None, + tool_call_id: None, + tool_calls: None, + }); + } + } + + Ok(converted_messages) + } + } + } +} + // ============================================================================ // MAIN REQUEST TRANSFORMATIONS // ============================================================================ @@ -253,117 +397,12 @@ impl TryFrom for ChatCompletionsRequest { type Error = TransformError; fn try_from(req: ResponsesAPIRequest) -> Result { - // Convert input to messages - let messages = match req.input { - InputParam::Text(text) => { - // Simple text input becomes a user message - vec![Message { - role: Role::User, - content: MessageContent::Text(text), - name: None, - tool_call_id: None, - tool_calls: None, - }] - } - InputParam::Items(items) => { - // Convert input items to messages - let mut converted_messages = Vec::new(); - - // Add instructions as system message if present - if let Some(instructions) = &req.instructions { - converted_messages.push(Message { - role: Role::System, - content: MessageContent::Text(instructions.clone()), - name: None, - tool_call_id: None, - tool_calls: None, - }); - } - - // Convert each input item - for item in items { - if let InputItem::Message(input_msg) = item { - let role = match input_msg.role { - MessageRole::User => Role::User, - MessageRole::Assistant => Role::Assistant, - MessageRole::System => Role::System, - MessageRole::Developer => Role::System, // Map developer to system - }; - - // Convert content based on MessageContent type - let content = match &input_msg.content { - crate::apis::openai_responses::MessageContent::Text(text) => { - // Simple text content - MessageContent::Text(text.clone()) - } - crate::apis::openai_responses::MessageContent::Items(content_items) => { - // Check if it's a single text item (can use simple text format) - if content_items.len() == 1 { - if let InputContent::InputText { text } = &content_items[0] { - MessageContent::Text(text.clone()) - } else { - // Single non-text item - use parts format - MessageContent::Parts( - content_items.iter() - .filter_map(|c| match c { - InputContent::InputText { text } => { - Some(crate::apis::openai::ContentPart::Text { text: text.clone() }) - } - InputContent::InputImage { image_url, .. } => { - Some(crate::apis::openai::ContentPart::ImageUrl { - image_url: crate::apis::openai::ImageUrl { - url: image_url.clone(), - detail: None, - } - }) - } - InputContent::InputFile { .. } => None, // Skip files for now - InputContent::InputAudio { .. } => None, // Skip audio for now - }) - .collect() - ) - } - } else { - // Multiple content items - convert to parts - MessageContent::Parts( - content_items - .iter() - .filter_map(|c| match c { - InputContent::InputText { text } => { - Some(crate::apis::openai::ContentPart::Text { - text: text.clone(), - }) - } - InputContent::InputImage { image_url, .. } => Some( - crate::apis::openai::ContentPart::ImageUrl { - image_url: crate::apis::openai::ImageUrl { - url: image_url.clone(), - detail: None, - }, - }, - ), - InputContent::InputFile { .. } => None, // Skip files for now - InputContent::InputAudio { .. } => None, // Skip audio for now - }) - .collect(), - ) - } - } - }; - - converted_messages.push(Message { - role, - content, - name: None, - tool_call_id: None, - tool_calls: None, - }); - } - } - - converted_messages - } + // Convert input to messages using the shared converter + let converter = ResponsesInputConverter { + input: req.input, + instructions: req.instructions.clone(), }; + let messages: Vec = converter.try_into()?; // Build the ChatCompletionsRequest Ok(ChatCompletionsRequest { diff --git a/docs/source/_static/img/signals_trace.png b/docs/source/_static/img/signals_trace.png new file mode 100644 index 0000000000000000000000000000000000000000..2d04e26f11bb2a91f97daf607419e48b3b15b5c0 GIT binary patch literal 2970560 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