diff options
Diffstat (limited to 'src/detect')
| -rw-r--r-- | src/detect/manifest.rs | 27 | ||||
| -rw-r--r-- | src/detect/manifest/tests.rs | 20 | ||||
| -rw-r--r-- | src/detect/manifests/codex.toml | 16 | ||||
| -rw-r--r-- | src/detect/mod.rs | 4 |
4 files changed, 21 insertions, 46 deletions
diff --git a/src/detect/manifest.rs b/src/detect/manifest.rs index acd6b8f9..e224adfe 100644 --- a/src/detect/manifest.rs +++ b/src/detect/manifest.rs @@ -416,23 +416,6 @@ pub fn explain_for_label(agent_label: &str, screen_content: &str) -> DetectionEx explain(agent, screen_content) } -pub fn should_skip_state_update(agent: Agent, screen_content: &str) -> bool { - let Some(loaded) = load_manifest(agent) else { - return false; - }; - evaluate_loaded_manifest( - agent, - DetectionInput { - screen: screen_content, - osc_title: "", - osc_progress: "", - }, - loaded, - false, - ) - .skip_state_update -} - impl DetectionExplain { fn into_detection(self) -> AgentDetection { AgentDetection { @@ -557,14 +540,14 @@ fn fallback_explain( ) }) .unwrap_or((None, Vec::new(), None, None, None, false)); - let known_agent = agent.is_some(); + let assume_idle = agent.is_some_and(|agent| agent != Agent::Codex); let remote_update_status = include_update_status .then(|| agent.and_then(remote_update_status)) .flatten(); DetectionExplain { agent: agent.map(|agent| agent_label(agent).to_string()), - state: if known_agent { + state: if assume_idle { AgentState::Idle } else { AgentState::Unknown @@ -577,7 +560,11 @@ fn fallback_explain( visible_working: false, skip_state_update: false, skipped_update_reason: None, - fallback_reason: known_agent.then(|| DEFAULT_KNOWN_AGENT_IDLE_FALLBACK.to_string()), + fallback_reason: match agent { + Some(Agent::Codex) => Some("codex_state_ambiguous".to_string()), + Some(_) => Some(DEFAULT_KNOWN_AGENT_IDLE_FALLBACK.to_string()), + None => None, + }, evaluated_rules, warning, manifest_version, diff --git a/src/detect/manifest/tests.rs b/src/detect/manifest/tests.rs index 07e9aa38..1e6b1a85 100644 --- a/src/detect/manifest/tests.rs +++ b/src/detect/manifest/tests.rs @@ -89,15 +89,21 @@ fn write_local_codex(content: &str) { } #[test] -fn known_agent_no_match_defaults_to_idle_fallback() { +fn codex_no_match_is_unknown_without_changing_other_agents() { with_manifest_dirs("no-match", || { write_local_codex(&local_manifest("working", "active-marker")); let explain = explain(Agent::Codex, "unmatched-marker"); - assert_eq!(explain.state, AgentState::Idle); + assert_eq!(explain.state, AgentState::Unknown); assert!(!explain.visible_idle); assert_eq!( explain.fallback_reason.as_deref(), + Some("codex_state_ambiguous") + ); + let other = fallback_explain(Some(Agent::Pi), None, false); + assert_eq!(other.state, AgentState::Idle); + assert_eq!( + other.fallback_reason.as_deref(), Some(DEFAULT_KNOWN_AGENT_IDLE_FALLBACK) ); }); @@ -184,10 +190,10 @@ fn fallback_explain_preserves_active_manifest_version() { let explain = explain(Agent::Codex, "ordinary prompt text"); - assert_eq!(explain.state, AgentState::Idle); + assert_eq!(explain.state, AgentState::Unknown); assert_eq!( explain.fallback_reason.as_deref(), - Some(DEFAULT_KNOWN_AGENT_IDLE_FALLBACK) + Some("codex_state_ambiguous") ); assert_eq!(explain.manifest_version.as_deref(), Some("9999.01.01.1")); assert!(matches!( @@ -267,10 +273,10 @@ fn detection_uses_cached_manifest_until_explicit_reload() { write_remote_codex_without_reload(&remote_manifest("9999.01.01.2", "working", "new-ready")); let unchanged = explain(Agent::Codex, "new-ready"); - assert_eq!(unchanged.state, AgentState::Idle); + assert_eq!(unchanged.state, AgentState::Unknown); assert_eq!( unchanged.fallback_reason.as_deref(), - Some(DEFAULT_KNOWN_AGENT_IDLE_FALLBACK) + Some("codex_state_ambiguous") ); assert_eq!( unchanged.cached_remote_version.as_deref(), @@ -479,8 +485,6 @@ contains = ["overlay-marker"] assert!(!result.visible_working); assert!(!result.visible_blocker); assert!(detect(Agent::Codex, screen).skip_state_update); - assert!(should_skip_state_update(Agent::Codex, screen)); - assert!(!should_skip_state_update(Agent::Codex, "activity-marker")); }); } diff --git a/src/detect/manifests/codex.toml b/src/detect/manifests/codex.toml index ecef12b7..dd275758 100644 --- a/src/detect/manifests/codex.toml +++ b/src/detect/manifests/codex.toml @@ -1,7 +1,7 @@ id = "codex" -version = "2026.09.22.1" +version = "2026.09.23.1" min_engine_version = 3 -updated_at = "2026-09-22T00:00:00Z" +updated_at = "2026-09-23T22:12:00Z" [[rules]] id = "osc_title_blocked" @@ -92,15 +92,3 @@ any = [{ contains = [" to interrupt)"] }, { contains = ["s)"] }] regex = ['(?m)^(?:[•◦][ \t]+)?[^\s›•◦■✗✓─][^\r\n]* \((?:[0-9]+[hm] )*[0-9]+s(?: • [^\r\n]+? to interrupt)?\)(?: · [^\r\n]*)?(?:\r?\n(?:[^•◦›■✗✓─\r\n][^\r\n]*|•[ \t]+(?:Queued\s+follow-up\s+inputs|Messages\s+to\s+be\s+submitted\s+after\s+next\s+tool\s+call(?:\s+\(press\s+[^\r\n]+?\s+to\s+interrupt\s+and\s+send\s+immediately\))?|Messages\s+to\s+be\s+submitted\s+at\s+end\s+of\s+turn)|›[⠁⠂⠄⠈⠐⠠⡀⢀][^\r\n]*)?)*\s*\z'] # A failed reconnect keeps its final elapsed timer but is no longer working. not = [{ line_regex = ['^(?:[•◦][ \t]+)?Reconnect failed — check the endpoint, then relaunch \([0-9hms ]+\)$'] }] - -[[rules]] -id = "osc_title_idle" -state = "idle" -priority = 100 -region = "osc_title" -visible_idle = true -regex = ['\S'] -not = [ - { regex = ['(?:^| )[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏](?: |$)'] }, - { contains = ["Action Required"] }, -] diff --git a/src/detect/mod.rs b/src/detect/mod.rs index 3dae571b..408ee669 100644 --- a/src/detect/mod.rs +++ b/src/detect/mod.rs @@ -320,10 +320,6 @@ pub fn detect_agent_with_osc( ) } -pub fn should_skip_state_update(agent: Option<Agent>, screen_content: &str) -> bool { - agent.is_some_and(|agent| manifest::should_skip_state_update(agent, screen_content)) -} - pub(crate) fn full_lifecycle_hook_authority(source: &str, agent_label: &str) -> bool { matches!( (source, agent_label), |
