26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
235 lines
7.8 KiB
Rust
235 lines
7.8 KiB
Rust
use lean_ctx::core::config::{CompressionLevel, Config, TerseAgent};
|
|
use lean_ctx::instructions;
|
|
use lean_ctx::tools::CrpMode;
|
|
use std::sync::Mutex;
|
|
|
|
static ENV_LOCK: Mutex<()> = Mutex::new(());
|
|
|
|
fn lock() -> std::sync::MutexGuard<'static, ()> {
|
|
ENV_LOCK
|
|
.lock()
|
|
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
|
}
|
|
|
|
fn set_compression(compression: &str) {
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::set_var("LEAN_CTX_COMPRESSION", compression) };
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::remove_var("LEAN_CTX_TERSE_AGENT") };
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::remove_var("LEAN_CTX_OUTPUT_DENSITY") };
|
|
}
|
|
|
|
fn set_legacy_terse(terse: &str) {
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::remove_var("LEAN_CTX_COMPRESSION") };
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::set_var("LEAN_CTX_TERSE_AGENT", terse) };
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::remove_var("LEAN_CTX_OUTPUT_DENSITY") };
|
|
isolate_config_with_compression_off();
|
|
}
|
|
|
|
fn isolate_config_with_compression_off() {
|
|
let tmp = std::env::temp_dir().join("lean_ctx_test_config_legacy");
|
|
let _ = std::fs::create_dir_all(&tmp);
|
|
let _ = std::fs::write(tmp.join("config.toml"), "compression_level = \"off\"\n");
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::set_var("LEAN_CTX_DATA_DIR", &tmp) };
|
|
}
|
|
|
|
fn cleanup_env() {
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::remove_var("LEAN_CTX_COMPRESSION") };
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::remove_var("LEAN_CTX_TERSE_AGENT") };
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::remove_var("LEAN_CTX_OUTPUT_DENSITY") };
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::remove_var("LEAN_CTX_DATA_DIR") };
|
|
}
|
|
|
|
// ── TerseAgent unit tests ──
|
|
|
|
#[test]
|
|
fn terse_agent_default_is_off() {
|
|
let ta = TerseAgent::default();
|
|
assert!(matches!(ta, TerseAgent::Off));
|
|
}
|
|
|
|
#[test]
|
|
fn terse_agent_from_env() {
|
|
let _g = lock();
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::set_var("LEAN_CTX_TERSE_AGENT", "full") };
|
|
assert!(matches!(TerseAgent::from_env(), TerseAgent::Full));
|
|
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::set_var("LEAN_CTX_TERSE_AGENT", "lite") };
|
|
assert!(matches!(TerseAgent::from_env(), TerseAgent::Lite));
|
|
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::set_var("LEAN_CTX_TERSE_AGENT", "ultra") };
|
|
assert!(matches!(TerseAgent::from_env(), TerseAgent::Ultra));
|
|
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::set_var("LEAN_CTX_TERSE_AGENT", "off") };
|
|
assert!(matches!(TerseAgent::from_env(), TerseAgent::Off));
|
|
|
|
cleanup_env();
|
|
}
|
|
|
|
// ── Legacy LEAN_CTX_TERSE_AGENT routes through CompressionLevel ──
|
|
|
|
#[test]
|
|
fn legacy_terse_lite_routes_to_compression_lite() {
|
|
let _g = lock();
|
|
set_legacy_terse("lite");
|
|
let text = instructions::build_instructions_for_test(CrpMode::Off);
|
|
assert!(
|
|
text.contains("OUTPUT STYLE: concise"),
|
|
"legacy terse lite should route to compression lite prompt"
|
|
);
|
|
cleanup_env();
|
|
}
|
|
|
|
#[test]
|
|
fn legacy_terse_full_routes_to_compression_standard() {
|
|
let _g = lock();
|
|
set_legacy_terse("full");
|
|
let text = instructions::build_instructions_for_test(CrpMode::Off);
|
|
assert!(
|
|
text.contains("OUTPUT STYLE: dense"),
|
|
"legacy terse full should route to compression standard prompt"
|
|
);
|
|
cleanup_env();
|
|
}
|
|
|
|
#[test]
|
|
fn legacy_terse_ultra_routes_to_compression_max() {
|
|
let _g = lock();
|
|
set_legacy_terse("ultra");
|
|
let text = instructions::build_instructions_for_test(CrpMode::Off);
|
|
assert!(
|
|
text.contains("OUTPUT STYLE: expert-terse"),
|
|
"legacy terse ultra should route to compression max prompt"
|
|
);
|
|
cleanup_env();
|
|
}
|
|
|
|
#[test]
|
|
fn legacy_terse_off_no_output_style() {
|
|
let _g = lock();
|
|
set_legacy_terse("off");
|
|
let text = instructions::build_instructions_for_test(CrpMode::Off);
|
|
assert!(
|
|
!text.contains("OUTPUT STYLE"),
|
|
"terse off should not inject OUTPUT STYLE block"
|
|
);
|
|
cleanup_env();
|
|
}
|
|
|
|
// ── Unified CompressionLevel env var ──
|
|
|
|
#[test]
|
|
fn compression_env_overrides_legacy_terse_agent() {
|
|
let _g = lock();
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::set_var("LEAN_CTX_COMPRESSION", "max") };
|
|
// TODO: Audit that the environment access only happens in single-threaded code.
|
|
unsafe { std::env::set_var("LEAN_CTX_TERSE_AGENT", "lite") };
|
|
let text = instructions::build_instructions_for_test(CrpMode::Off);
|
|
assert!(
|
|
text.contains("expert-terse"),
|
|
"compression env should override legacy terse_agent"
|
|
);
|
|
cleanup_env();
|
|
}
|
|
|
|
#[test]
|
|
fn compression_level_lite_injects_concise() {
|
|
let _g = lock();
|
|
set_compression("lite");
|
|
let text = instructions::build_instructions_for_test(CrpMode::Off);
|
|
assert!(
|
|
text.contains("OUTPUT STYLE: concise"),
|
|
"compression lite should inject concise prompt"
|
|
);
|
|
cleanup_env();
|
|
}
|
|
|
|
#[test]
|
|
fn compression_level_standard_injects_dense() {
|
|
let _g = lock();
|
|
set_compression("standard");
|
|
let text = instructions::build_instructions_for_test(CrpMode::Off);
|
|
assert!(
|
|
text.contains("OUTPUT STYLE: dense"),
|
|
"compression standard should inject dense prompt"
|
|
);
|
|
assert!(
|
|
text.contains("fn, cfg, impl"),
|
|
"compression standard should mention abbreviations"
|
|
);
|
|
cleanup_env();
|
|
}
|
|
|
|
#[test]
|
|
fn compression_level_max_injects_expert_terse() {
|
|
let _g = lock();
|
|
set_compression("max");
|
|
let text = instructions::build_instructions_for_test(CrpMode::Off);
|
|
assert!(
|
|
text.contains("OUTPUT STYLE: expert-terse"),
|
|
"compression max should inject expert-terse prompt"
|
|
);
|
|
cleanup_env();
|
|
}
|
|
|
|
#[test]
|
|
fn compression_level_off_no_output_style() {
|
|
let _g = lock();
|
|
set_compression("off");
|
|
let text = instructions::build_instructions_for_test(CrpMode::Off);
|
|
assert!(
|
|
!text.contains("OUTPUT STYLE"),
|
|
"compression off should not inject any OUTPUT STYLE block"
|
|
);
|
|
cleanup_env();
|
|
}
|
|
|
|
// ── Config deserialization ──
|
|
|
|
#[test]
|
|
fn terse_agent_config_deserializes() {
|
|
let toml = r#"
|
|
terse_agent = "full"
|
|
"#;
|
|
let config: Config = toml::from_str(toml).expect("should parse terse_agent from toml");
|
|
assert!(matches!(config.terse_agent, TerseAgent::Full));
|
|
}
|
|
|
|
#[test]
|
|
fn terse_agent_config_default_off() {
|
|
let toml = "";
|
|
let config: Config = toml::from_str(toml).expect("empty toml should use defaults");
|
|
assert!(matches!(config.terse_agent, TerseAgent::Off));
|
|
}
|
|
|
|
#[test]
|
|
fn compression_level_config_deserializes() {
|
|
let toml = r#"compression_level = "standard""#;
|
|
let config: Config = toml::from_str(toml).expect("should parse compression_level");
|
|
assert!(matches!(
|
|
config.compression_level,
|
|
CompressionLevel::Standard
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn compression_level_config_default_lite() {
|
|
let toml = "";
|
|
let config: Config = toml::from_str(toml).expect("empty toml should use defaults");
|
|
assert!(matches!(config.compression_level, CompressionLevel::Lite));
|
|
}
|