use super::{
CrpMode, HookPoint, PluginManager, ReadMode, ReadOutput, ReadTuning, SessionCache,
count_tokens, dedup_hook, handle_with_options_inner, kernel, protocol,
};
pub fn handle(cache: &mut SessionCache, path: &str, mode: &str, crp_mode: CrpMode) -> String {
handle_with_options(cache, path, mode, false, crp_mode, None)
}
pub fn handle_fresh(cache: &mut SessionCache, path: &str, mode: &str, crp_mode: CrpMode) -> String {
handle_with_options(cache, path, mode, true, crp_mode, None)
}
pub fn handle_with_task(
cache: &mut SessionCache,
path: &str,
mode: &str,
crp_mode: CrpMode,
task: Option<&str>,
) -> String {
let mut result = handle_with_options(cache, path, mode, false, crp_mode, task);
kernel::enrich_with_kernel(&mut result, task);
result
}
pub fn handle_with_task_resolved(
cache: &mut SessionCache,
path: &str,
mode: &str,
crp_mode: CrpMode,
task: Option<&str>,
) -> ReadOutput {
handle_with_options_resolved(
cache,
path,
mode,
false,
crp_mode,
task,
ReadTuning::resolve(None, &[]),
)
}
pub fn handle_with_task_resolved_tuned(
cache: &mut SessionCache,
path: &str,
mode: &str,
crp_mode: CrpMode,
task: Option<&str>,
aggressiveness: Option<f64>,
protect: &[String],
) -> ReadOutput {
handle_with_options_resolved(
cache,
path,
mode,
false,
crp_mode,
task,
ReadTuning::resolve(aggressiveness, protect),
)
}
#[allow(clippy::too_many_arguments)]
pub fn handle_with_preread(
cache: &mut SessionCache,
path: &str,
mode: &str,
fresh: bool,
crp_mode: CrpMode,
task: Option<&str>,
aggressiveness: Option<f64>,
protect: &[String],
preread: String,
) -> ReadOutput {
handle_with_options_resolved_preread(
cache,
path,
mode,
fresh,
crp_mode,
task,
ReadTuning::resolve(aggressiveness, protect),
Some(preread),
)
}
pub fn handle_fresh_with_task(
cache: &mut SessionCache,
path: &str,
mode: &str,
crp_mode: CrpMode,
task: Option<&str>,
) -> String {
handle_with_options(cache, path, mode, true, crp_mode, task)
}
pub fn handle_fresh_with_task_resolved(
cache: &mut SessionCache,
path: &str,
mode: &str,
crp_mode: CrpMode,
task: Option<&str>,
) -> ReadOutput {
handle_with_options_resolved(
cache,
path,
mode,
true,
crp_mode,
task,
ReadTuning::resolve(None, &[]),
)
}
pub fn handle_fresh_with_task_resolved_tuned(
cache: &mut SessionCache,
path: &str,
mode: &str,
crp_mode: CrpMode,
task: Option<&str>,
aggressiveness: Option<f64>,
protect: &[String],
) -> ReadOutput {
handle_with_options_resolved(
cache,
path,
mode,
true,
crp_mode,
task,
ReadTuning::resolve(aggressiveness, protect),
)
}
fn handle_with_options(
cache: &mut SessionCache,
path: &str,
mode: &str,
fresh: bool,
crp_mode: CrpMode,
task: Option<&str>,
) -> String {
handle_with_options_resolved(
cache,
path,
mode,
fresh,
crp_mode,
task,
ReadTuning::resolve(None, &[]),
)
.content
}
pub(crate) fn force_fresh_env() -> bool {
static FORCE_FRESH: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
*FORCE_FRESH.get_or_init(|| {
std::env::var("LEAN_CTX_FORCE_FRESH").is_ok_and(|v| v == "1" || v == "true")
})
}
pub(crate) fn is_subagent_context() -> bool {
static IS_SUBAGENT: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
*IS_SUBAGENT.get_or_init(|| {
std::env::var("CURSOR_TASK_ID").is_ok_and(|v| !v.is_empty())
|| std::env::var("CLAUDE_CODE_ENTRYPOINT")
.ok()
.as_deref()
.map(str::trim)
== Some("local-agent")
})
}
#[allow(clippy::fn_params_excessive_bools)]
pub(crate) fn effective_fresh_flags(
fresh: bool,
force_fresh: bool,
subagent_context: bool,
delivery_for_subagents: bool,
) -> (bool, bool) {
let effective_fresh_for_cache = fresh || force_fresh || subagent_context;
let effective_fresh_for_delivery =
fresh || force_fresh || (subagent_context && !delivery_for_subagents);
(effective_fresh_for_cache, effective_fresh_for_delivery)
}
pub(crate) fn effective_fresh_for_delivery(fresh: bool) -> bool {
let config = crate::core::config::Config::load();
effective_fresh_flags(
fresh,
force_fresh_env(),
is_subagent_context(),
config.ocla.delivery.delivery_for_subagents,
)
.1
}
fn handle_with_options_resolved(
cache: &mut SessionCache,
path: &str,
mode: &str,
fresh: bool,
crp_mode: CrpMode,
task: Option<&str>,
tuning: ReadTuning<'_>,
) -> ReadOutput {
handle_with_options_resolved_preread(cache, path, mode, fresh, crp_mode, task, tuning, None)
}
fn handle_with_options_resolved_preread(
cache: &mut SessionCache,
path: &str,
mode: &str,
fresh: bool,
crp_mode: CrpMode,
task: Option<&str>,
tuning: ReadTuning<'_>,
preread: Option<String>,
) -> ReadOutput {
let config = crate::core::config::Config::load();
let (effective_fresh_for_cache, effective_fresh_for_delivery) = effective_fresh_flags(
fresh,
force_fresh_env(),
is_subagent_context(),
config.ocla.delivery.delivery_for_subagents,
);
let compress_protected = mode != "raw"
&& !mode.starts_with("lines:")
&& crate::core::config::Config::load()
.proxy
.is_path_compress_protected(path);
let delivery_metadata = config
.ocla
.delivery_enabled()
.then(|| file_blake3_prefix(path))
.flatten();
if !effective_fresh_for_delivery
&& !compress_protected
&& let Some((hash, mtime)) = delivery_metadata
&& let Some(stub) = try_cross_agent_stub(path, mode, hash, mtime)
{
cache.store(path, &stub.content);
cache.mark_full_delivered(path);
return stub;
}
if mode == "auto" {
let touched: Vec<String> = cache
.get_all_entries()
.iter()
.map(|(p, _)| (*p).clone())
.collect();
if crate::core::relevance_gate::should_gate(path, mode, task, &touched) {
let meta = std::fs::metadata(path);
let byte_count = meta.as_ref().map_or(0, std::fs::Metadata::len);
let line_count = preread
.as_ref()
.map_or(0, |c| bytecount::count(c.as_bytes(), b'\n'));
let stub = crate::core::relevance_gate::irrelevant_stub(path, line_count, byte_count);
let stub_tokens = count_tokens(&stub);
return ReadOutput {
content: stub,
resolved_mode: "auto".into(),
output_tokens: stub_tokens,
is_cache_hit: false,
};
}
}
if PluginManager::has_listener("pre_read") {
PluginManager::fire_hook_background(HookPoint::PreRead {
path: path.to_string(),
});
}
if let Ok(mut bt) = crate::core::bounce_tracker::global().lock() {
bt.next_seq();
}
let mut result = handle_with_options_inner(
cache,
path,
mode,
effective_fresh_for_cache,
crp_mode,
task,
tuning,
preread,
);
if let Some(entry) = cache.get_mut(path) {
entry.last_mode.clone_from(&result.resolved_mode);
if matches!(result.resolved_mode.as_str(), "full" | "full-compact")
&& entry.full_content_delivered
&& result.is_cache_hit
&& entry.bump_reread() >= crate::core::cache::full_degradation_threshold()
{
entry.full_content_delivered = false;
entry.reset_reread_count();
crate::core::auto_mode_resolver::count_source("full_delivery_degraded");
}
if !matches!(result.resolved_mode.as_str(), "full" | "full-compact") {
entry.full_content_delivered = false;
entry.reset_reread_count();
}
}
if !result.is_cache_hit
&& let Some((hash, mtime)) = delivery_metadata
{
let line_count = cache.get(path).map_or(0, |entry| entry.line_count as u32);
record_cross_agent_delivery(path, hash, mtime, line_count, result.output_tokens);
}
let dedup_allowed = result
.resolved_mode
.parse::<ReadMode>()
.is_ok_and(|m| m.is_lossy_summary());
if dedup_allowed && let Some(deduped) = cache.apply_dedup(path, &result.content) {
let new_tokens = count_tokens(&deduped);
if new_tokens < result.output_tokens {
result.content = deduped;
result.output_tokens = new_tokens;
}
}
if let Some(stub) = dedup_hook::maybe_dedup(path, &result.content, mode, fresh) {
let stub_tokens = count_tokens(&stub);
if stub_tokens < result.output_tokens {
result.content = stub;
result.output_tokens = stub_tokens;
result.is_cache_hit = true;
}
}
crate::core::context_kernel::adaptive_hook::update_from_bounce_tracker();
if let Ok(mut bt) = crate::core::bounce_tracker::global().lock() {
let original_tokens = cache.get(path).map_or(0, |e| e.original_tokens);
bt.record_read(
path,
&result.resolved_mode,
result.output_tokens,
original_tokens,
);
let compressed = result
.resolved_mode
.parse::<ReadMode>()
.map_or(true, |m| m.counts_as_compressed());
if compressed {
crate::core::adaptive_thresholds::record_quality_signal(
path,
crate::core::threshold_learning::QualitySignal::CleanCompressed,
);
} else if result.resolved_mode == "full"
&& result.output_tokens > 2000
&& bt.bounce_rate_for_extension(path).unwrap_or(0.0) < 0.05
{
crate::core::adaptive_thresholds::record_quality_signal(
path,
crate::core::threshold_learning::QualitySignal::WastedFull,
);
}
}
if PluginManager::has_listener("post_compress") {
let original_tokens = cache.get(path).map_or(0, |e| e.original_tokens);
PluginManager::fire_hook_background(HookPoint::PostCompress {
path: path.to_string(),
original_tokens,
compressed_tokens: result.output_tokens,
});
}
{
let self_agent = crate::core::scent_field::scent_agent_id();
let scent_path = crate::core::pathutil::normalize_tool_path(path);
std::thread::spawn(move || {
crate::core::scent_field::deposit(
self_agent,
crate::core::scent_field::ScentKind::Hot,
&scent_path,
0.3,
);
});
}
crate::core::context_gc::maybe_gc(cache);
result
}
pub fn try_stub_hit_readonly(cache: &SessionCache, path: &str) -> Option<ReadOutput> {
let current_conversation = crate::core::conversation::current_conversation_id_fresh();
try_stub_hit_readonly_scoped(cache, path, current_conversation.as_deref())
}
pub(crate) fn try_stub_hit_readonly_scoped(
cache: &SessionCache,
path: &str,
current_conversation: Option<&str>,
) -> Option<ReadOutput> {
let no_deg = crate::core::config::Config::load().no_degrade_effective();
let prof = crate::core::profiles::active_profile();
let force_full = no_deg
|| (prof.read.default_mode_effective() == "full"
&& prof.compression.crp_mode_effective() == "off");
let policy_allows_stub =
crate::server::compaction_sync::effective_cache_policy() != "safe" && !force_full;
if !policy_allows_stub {
return None;
}
if let Some(file_ref) = cache.get_file_ref_readonly(path) {
let (cached_mtime, cached_hash, line_count, delivered_conv) = {
let entry = cache.get(path)?;
(
entry.stored_mtime,
entry.hash.clone(),
entry.line_count,
entry.delivered_conversation.clone(),
)
};
if crate::core::cache::is_cache_entry_stale_verified(path, cached_mtime, &cached_hash)
|| !cache.is_full_delivered(path)
{
return None;
}
if !crate::core::conversation::conversation_allows_stub(
current_conversation,
delivered_conv.as_deref(),
) {
crate::core::cache_telemetry::record_conversation_mismatch();
return None;
}
let original_tokens = cache.record_cache_hit(path)?.original_tokens;
crate::core::telemetry::global_metrics().record_cache(true);
let stub = render_unchanged_stub(&file_ref, path, line_count);
crate::core::stats::record_reread(original_tokens.saturating_sub(stub.output_tokens));
return Some(stub);
}
let rec = crate::core::read_stub_index::lookup(path)?;
if crate::core::cache::is_cache_entry_stale_verified(path, rec.stored_mtime(), &rec.hash) {
return None;
}
if !crate::core::conversation::conversation_allows_cold_stub(
current_conversation,
rec.delivered_conversation.as_deref(),
) {
crate::core::cache_telemetry::record_conversation_mismatch();
return None;
}
Some(render_unchanged_stub(&rec.file_ref, path, rec.line_count))
}
fn render_unchanged_stub(file_ref: &str, path: &str, line_count: usize) -> ReadOutput {
let short = protocol::shorten_path(path);
let out = if crate::core::protocol::meta_visible() {
format!(
"{file_ref}={short} [unchanged {line_count}L]\nUnchanged on disk. Use fresh=true to force re-read.",
)
} else {
format!("{file_ref}={short} [unchanged {line_count}L · fresh=true to re-read]")
};
let out = crate::core::redaction::redact_text_if_enabled(&out);
let sent = count_tokens(&out);
ReadOutput {
content: out,
resolved_mode: "full".into(),
output_tokens: sent,
is_cache_hit: true,
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeltaExplicitDecision {
pub mode: String,
pub note: Option<String>,
}
pub fn resolve_explicit_delta_mode(
cache: &SessionCache,
path: &str,
mode: &str,
explicit_mode: bool,
fresh: bool,
enabled: bool,
) -> DeltaExplicitDecision {
let unchanged = DeltaExplicitDecision {
mode: mode.to_string(),
note: None,
};
if fresh
|| !enabled
|| !explicit_mode
|| !(mode == "full" || mode == "full-compact" || mode.starts_with("lines:"))
{
return unchanged;
}
let Some(entry) = cache.get(path) else {
return unchanged;
};
let stale =
crate::core::cache::is_cache_entry_stale_verified(path, entry.stored_mtime, &entry.hash);
if stale {
if entry.content().is_some() {
return DeltaExplicitDecision {
mode: "diff".to_string(),
note: Some(format!(
"[delta-explicit] requested mode={mode} served as a diff: the file \
changed since your last read and the diff is the new information. \
Pass fresh=true if you need the full content re-emitted."
)),
};
}
return unchanged;
}
if mode.starts_with("lines:") && cache.is_full_delivered(path) {
return DeltaExplicitDecision {
mode: "full".to_string(),
note: None,
};
}
unchanged
}
pub(crate) fn file_blake3_prefix(path: &str) -> Option<([u8; 12], u64)> {
let meta = std::fs::metadata(path).ok()?;
let mtime = meta
.modified()
.ok()?
.duration_since(std::time::UNIX_EPOCH)
.ok()?
.as_secs();
let bytes = std::fs::read(path).ok()?;
let hash = blake3::hash(&bytes);
let full = hash.as_bytes();
let mut prefix = [0u8; 12];
prefix.copy_from_slice(&full[..12]);
Some((prefix, mtime))
}
pub(crate) fn try_cross_agent_stub(
path: &str,
mode: &str,
hash: [u8; 12],
mtime: u64,
) -> Option<ReadOutput> {
if !crate::core::config::Config::load().ocla.delivery_enabled() {
return None;
}
if matches!(mode, "full" | "raw" | "diff") {
return None;
}
let current_agent = std::env::var("CURSOR_TASK_ID")
.or_else(|_| std::env::var("CLAUDECODE"))
.unwrap_or_else(|_| "local-agent".to_string());
let current_conversation = crate::core::conversation::current_conversation_id()
.unwrap_or_else(|| current_agent.clone());
let reg = crate::core::ocla::OclaRegistry::global();
let record = crate::daemon_client::try_delivery_check_blocking(
&hash,
mtime,
path,
Some(¤t_agent),
Some(¤t_conversation),
)
.or_else(|| {
reg.delivery_registry.check_delivery(
&hash,
mtime,
path,
Some(¤t_agent),
Some(¤t_conversation),
)
})?;
let short = protocol::shorten_path(path);
let stub = format!(
"{short} [cross-agent · {lines}L · read by {agent} · use fresh=true to force]",
lines = record.line_count,
agent = record.agent_id,
);
let tokens = count_tokens(&stub);
reg.delivery_registry
.record_stub_served(&record, tokens as u64);
Some(ReadOutput {
content: stub,
resolved_mode: "cross-agent-stub".into(),
output_tokens: tokens,
is_cache_hit: true,
})
}
pub(crate) fn record_cross_agent_delivery(
path: &str,
hash: [u8; 12],
mtime: u64,
line_count: u32,
tokens: usize,
) {
if !crate::core::config::Config::load().ocla.delivery_enabled() {
return;
}
let agent_id = std::env::var("CURSOR_TASK_ID")
.or_else(|_| std::env::var("CLAUDECODE"))
.unwrap_or_else(|_| "local-agent".to_string());
let conversation_id =
crate::core::conversation::current_conversation_id().unwrap_or_else(|| agent_id.clone());
let entry = crate::core::ocla::types::DeliveryEntry {
blake3: hash,
path: path.into(),
line_count,
token_count: tokens as u64,
agent_id,
conversation_id,
mtime,
};
crate::daemon_client::try_delivery_record_blocking(&entry);
let reg = crate::core::ocla::OclaRegistry::global();
reg.delivery_registry.record_delivery(entry);
}
#[cfg(test)]
mod tests {
use super::{
SessionCache, effective_fresh_flags, try_cross_agent_stub, try_stub_hit_readonly_scoped,
};
use std::sync::atomic::Ordering;
#[test]
fn cross_agent_stub_miss_returns_none() {
let stub = try_cross_agent_stub("/nonexistent/file.rs", "auto", [0; 12], 0);
assert!(stub.is_none());
}
#[test]
fn subagent_delivery_policy_keeps_cache_fresh_but_allows_delivery_by_default() {
let delivery_for_subagents =
crate::core::config::DeliveryConfig::default().delivery_for_subagents;
assert!(
delivery_for_subagents,
"delivery must default to enabled for subagents"
);
let (cache_fresh, delivery_fresh) =
effective_fresh_flags(false, false, true, delivery_for_subagents);
assert!(cache_fresh, "subagent cache must remain isolated");
assert!(
!delivery_fresh,
"default policy must allow a cross-agent delivery lookup"
);
}
#[test]
fn subagent_delivery_policy_can_force_fresh_delivery() {
let (cache_fresh, delivery_fresh) = effective_fresh_flags(false, false, true, false);
assert!(cache_fresh);
assert!(delivery_fresh, "disabled policy must bypass delivery stubs");
}
#[test]
fn cross_agent_fallback_is_deterministic() {
let _lock = crate::core::data_dir::test_env_lock();
crate::test_env::remove_var("CURSOR_TASK_ID");
crate::test_env::remove_var("CLAUDECODE");
let id1 = std::env::var("CURSOR_TASK_ID")
.or_else(|_| std::env::var("CLAUDECODE"))
.unwrap_or_else(|_| "local-agent".to_string());
let id2 = std::env::var("CURSOR_TASK_ID")
.or_else(|_| std::env::var("CLAUDECODE"))
.unwrap_or_else(|_| "local-agent".to_string());
assert_eq!(id1, id2, "fallback agent ID must be deterministic");
assert!(!id1.contains("proc:"), "must not contain PID");
}
#[test]
fn warm_stub_hit_records_central_telemetry() {
let dir = tempfile::tempdir().unwrap();
let file = dir.path().join("telemetry-hit.rs");
std::fs::write(&file, "fn telemetry_hit() {}\n").unwrap();
let path = file.to_string_lossy();
let mut cache = SessionCache::new();
cache.store(&path, "fn telemetry_hit() {}\n");
cache.mark_full_delivered(&path);
let metrics = crate::core::telemetry::global_metrics();
let before = metrics.cache_hits.load(Ordering::Relaxed);
let output = try_stub_hit_readonly_scoped(&cache, &path, None);
let after = metrics.cache_hits.load(Ordering::Relaxed);
assert!(output.is_some(), "warm re-read must use the stub cache");
assert!(
after > before,
"stub cache hit must increment central telemetry"
);
}
}