use super::{
apply_task_triage_filter, compression_tracker_tokens, mcp_error_category, shell_error_category,
tool_execution_error_category, triage_bypass_requested, verbatim_requested,
};
#[test]
fn test_tracker_in_pipeline() {
let mut tracker = lean_ctx::core::savings_tracker::SessionSavingsTracker::default();
let (raw, compressed) = compression_tracker_tokens("ctx_read", 75, 25).expect("tracked");
tracker.record_compression(raw, compressed, "ctx_read");
let after = tracker.session_summary();
assert_eq!(
(
after.total_raw,
after.total_compressed,
after.savings_tokens
),
(100, 25, 75)
);
}
#[test]
fn triage_filter_rewrites_raw_output_and_tracks_removed_lines() {
let profile = lean_ctx::core::triage::profile::TaskProfileLocal {
confidence_milli: 500,
context_need_milli: 400,
..Default::default()
};
let mut context = Some(
lean_ctx::core::execution_lifecycle::ExecutionLifecycle::default().begin(
lean_ctx::core::execution_lifecycle::ToolRequest {
tool_name: "ctx_search".into(),
query: Some("content".into()),
session_id: "triage-filter-test".into(),
agent_id: "test".into(),
surface: lean_ctx::core::execution_lifecycle::ToolSurface::Mcp,
idempotency_key: None,
},
lean_ctx::core::execution_lifecycle::RuntimeContext::default(),
lean_ctx::core::execution_lifecycle::ProductEntitlements::default(),
),
);
let raw = format!("// boilerplate\n{}", "content\n".repeat(100));
let filtered = apply_task_triage_filter(raw, Some(&profile), &mut context, 2);
assert!(!filtered.starts_with("// boilerplate"));
assert_eq!(context.as_ref().unwrap().filtered_lines, 1);
}
#[test]
fn triage_filter_fails_open_without_a_profile() {
let raw = "content\n".repeat(100);
let mut context = None;
assert_eq!(
apply_task_triage_filter(raw.clone(), None, &mut context, 2),
raw
);
}
#[test]
fn triage_filter_cap_zero_preserves_output_unchanged() {
let profile = lean_ctx::core::triage::profile::TaskProfileLocal {
confidence_milli: 500,
context_need_milli: 200,
..Default::default()
};
let raw = format!("fn render() {{\n{}\n}}", " token_value();\n".repeat(40));
let mut context = None;
assert_eq!(
apply_task_triage_filter(raw.clone(), Some(&profile), &mut context, 0),
raw
);
}
#[test]
fn ctx_read_always_bypasses_second_lossy_filter() {
let auto = serde_json::Map::from_iter([(
"mode".to_owned(),
serde_json::Value::String("auto".to_owned()),
)]);
assert!(triage_bypass_requested("ctx_read", Some(&auto)));
let shell = serde_json::Map::new();
assert!(!triage_bypass_requested("ctx_shell", Some(&shell)));
}
fn args(pairs: &[(&str, serde_json::Value)]) -> serde_json::Map<String, serde_json::Value> {
pairs
.iter()
.map(|(k, v)| ((*k).to_owned(), v.clone()))
.collect()
}
#[test]
fn raw_true_and_mode_raw_are_explicit_verbatim_requests() {
let raw_flag = args(&[("raw", serde_json::Value::Bool(true))]);
let raw_mode = args(&[("mode", serde_json::Value::String("raw".to_owned()))]);
assert!(verbatim_requested("ctx_read", Some(&raw_flag)));
assert!(verbatim_requested("ctx_read", Some(&raw_mode)));
assert!(verbatim_requested("ctx_shell", Some(&raw_flag)));
}
#[test]
fn ordinary_reads_stay_on_the_ordinary_budget() {
for mode in ["full", "auto", "lines:1-40", "anchored", "signatures"] {
let a = args(&[("mode", serde_json::Value::String(mode.to_owned()))]);
assert!(
!verbatim_requested("ctx_read", Some(&a)),
"mode={mode} must not claim the verbatim budget"
);
}
let off = args(&[("raw", serde_json::Value::Bool(false))]);
assert!(!verbatim_requested("ctx_read", Some(&off)));
assert!(!verbatim_requested("ctx_read", None));
}
#[test]
fn other_tools_never_claim_the_verbatim_budget() {
let raw_flag = args(&[("raw", serde_json::Value::Bool(true))]);
assert!(!verbatim_requested("ctx_search", Some(&raw_flag)));
assert!(!verbatim_requested("ctx_compose", Some(&raw_flag)));
}
#[test]
fn shell_error_categories_use_typed_outcomes_not_output_strings() {
use crate::server::tool_trait::{BackgroundJobState, BackgroundShellOutcome, ShellOutcome};
use lean_ctx::core::telemetry_v2::ErrorCategory;
assert_eq!(shell_error_category(None, "secret error"), None);
assert_eq!(
shell_error_category(Some(&ShellOutcome::Exit(0)), "error"),
None
);
assert_eq!(
shell_error_category(Some(&ShellOutcome::Blocked), "arbitrary details"),
Some(ErrorCategory::Authorization)
);
assert_eq!(
shell_error_category(Some(&ShellOutcome::Exit(124)), "[exit:124]"),
Some(ErrorCategory::Timeout)
);
assert_eq!(
shell_error_category(Some(&ShellOutcome::Exit(2)), "provider timeout"),
Some(ErrorCategory::Command)
);
assert_eq!(
shell_error_category(Some(&ShellOutcome::Exit(1)), "grep found no matches"),
None
);
let failed_background = ShellOutcome::Background(BackgroundShellOutcome {
state: BackgroundJobState::Failed,
exit_code: Some(124),
job_id: "opaque-job".into(),
archive_id: None,
archive_truncated: None,
captured_chars: None,
archived_chars: None,
summary: "typed summary".into(),
is_error: true,
display: None,
});
assert_eq!(
shell_error_category(Some(&failed_background), "arbitrary details"),
Some(ErrorCategory::Timeout)
);
}
#[test]
fn mcp_error_categories_use_protocol_codes() {
use lean_ctx::core::telemetry_v2::ErrorCategory;
assert_eq!(
mcp_error_category(rmcp::model::ErrorCode::INVALID_PARAMS),
ErrorCategory::Validation
);
assert_eq!(
mcp_error_category(rmcp::model::ErrorCode::INTERNAL_ERROR),
ErrorCategory::Internal
);
}
#[test]
fn tool_execution_errors_are_categorised_by_failure_class() {
use lean_ctx::core::telemetry_failure::{FAILURE_KINDS, FailureKind, classify};
use lean_ctx::core::telemetry_v2::ErrorCategory;
for kind in FAILURE_KINDS {
let expected = match kind {
FailureKind::Unavailable | FailureKind::Other => ErrorCategory::Internal,
FailureKind::Timeout => ErrorCategory::Timeout,
_ => ErrorCategory::Validation,
};
assert_eq!(tool_execution_error_category(kind), expected, "{kind:?}");
}
for (message, expected) in [
(
"ERROR: old_string not found in src/main.rs",
ErrorCategory::Validation,
),
(
"ERROR: old_string found 3 times in src/main.rs",
ErrorCategory::Validation,
),
(
"ERROR: path escapes project root: /etc/passwd",
ErrorCategory::Validation,
),
(
"ERROR: cannot read src/gone.rs: No such file or directory (os error 2)",
ErrorCategory::Validation,
),
(
"[POLICY BLOCKED] write denied by policy",
ErrorCategory::Validation,
),
("daemon not running", ErrorCategory::Internal),
("something unexpected happened", ErrorCategory::Internal),
] {
assert_eq!(
tool_execution_error_category(classify(message)),
expected,
"{message}"
);
}
}
#[test]
fn inline_earns_the_verbatim_budget_like_raw() {
let inline = args(&[("inline", serde_json::Value::Bool(true))]);
assert!(verbatim_requested("ctx_shell", Some(&inline)));
let raw = args(&[("raw", serde_json::Value::Bool(true))]);
assert_eq!(
verbatim_requested("ctx_shell", Some(&inline)),
verbatim_requested("ctx_shell", Some(&raw)),
"inline and raw request the same thing and must be budgeted alike"
);
}
#[test]
fn inline_false_stays_on_the_ordinary_budget() {
let off = args(&[("inline", serde_json::Value::Bool(false))]);
assert!(!verbatim_requested("ctx_shell", Some(&off)));
let none = args(&[]);
assert!(!verbatim_requested("ctx_shell", Some(&none)));
}