Skip to content

feat(run_agent): extend codex intermediate-ack detection to French + relax prior-tool bail - #22059

Open
Julientalbot wants to merge 1 commit into
NousResearch:mainfrom
Julientalbot:jt/intermediate-ack-fr-i18n
Open

feat(run_agent): extend codex intermediate-ack detection to French + relax prior-tool bail#22059
Julientalbot wants to merge 1 commit into
NousResearch:mainfrom
Julientalbot:jt/intermediate-ack-fr-i18n

Conversation

@Julientalbot

Copy link
Copy Markdown
Contributor

Problem

_looks_like_codex_intermediate_ack re-routes narrative acknowledgement turns ("I'll check the directory") into the post-tool nudge so the agent keeps working instead of ending the turn on a promise. Two coverage gaps were limiting it on real-world sessions:

1. English-only patterns. The future-ack regex and the action_markers / workspace_markers tuples only knew English. French Telegram/CLI users routinely produce IWE patterns that fall through detection:

  • "Je vais vérifier le dossier."
  • "Je corrige le binding du dashboard."
  • "Je relance le dashboard."
  • "Je m'occupe du fichier."

These are direct French equivalents of "I'll check...", "Let me fix..." — same intent, same need for nudge re-routing, but the detector returned False and the turn ended on a narration-only response, leaving the user in an IWE spiral.

2. Global bail on prior tool. The current implementation bails as soon as any message in messages has role == "tool":

if any(isinstance(msg, dict) and msg.get("role") == "tool" for msg in messages):
    return False

On long Telegram/CLI sessions (60–90 turns), the first tool call permanently disables detection for the rest of the conversation, even when the current user turn has produced zero tools. Captured from a real Alfred session: a fresh narration-only turn at message #150 was masked because a terminal call had executed at message #9.

Fix

A. Localize the bail to the current turn only. Walk back from the end of messages to the most recent user message; only that slice counts as the "current turn". A tool earlier in the session no longer invalidates detection.

B. Extend the future-ack regex with French intent verbs:

je vais | on va | je m'en occupe | je corrige | je relance | je fais
| je vérifie | d'accord | je m'y mets | je m'attèle | c'est noté
| noté | je regarde | je lance | je teste | je m'occupe
| je vais lancer | je vais vérifier | je m'en charge

C. Extend action_markers with French verb stems (substring match handles conjugations):

vérifi, corrig, relanc, examin, cherch, analys, exécut, lanc,
regard, parcour, lir, ouvr, explor, résum, diagnostiqu, répar

D. Extend workspace_markers with French nouns:

répertoire, dossier, arborescence, base de code, projet,
fichier, chemin, code

The multi-condition guard ((user_targets_workspace or assistant_targets_workspace) and assistant_mentions_action) is unchanged — false-positive risk on opinion-style French ("Je vais réfléchir à ça") remains contained.

Tests

New TestLooksLikeCodexIntermediateAck class in tests/run_agent/test_run_agent.py with 10 cases:

  • test_english_ack_with_workspace_action — regression
  • test_french_ack_je_vais_verifier_dossier — canonical FR IWE
  • test_french_je_corrige_le_binding — from a real Alfred Telegram session
  • test_french_je_relance_le_dashboard — same
  • test_french_action_diagnostiquer_arborescence
  • test_french_action_examiner_repertoire
  • test_french_no_action_no_workspace_returns_false — opinion ("Je vais réfléchir") stays out
  • test_french_no_future_ack_returns_false — no future-tense verb stays out
  • test_prior_tool_outside_current_turn_does_not_bail — relaxed bail regression
  • test_tool_in_current_turn_bails — relaxed bail still bails when correct

pytest tests/run_agent/test_run_agent.py -v -k LooksLikeCodexIntermediateAck10 passed.

Why now

Pairs naturally with the existing English narration coverage and PR #6757 (which generalizes intermediate-ack detection to all api_modes). Whether #6757 lands first or this PR does, the regex/markers extension here applies orthogonally. The relaxed bail also helps any agent stack where a single session legitimately interleaves productive tool turns with narration-only ones — common on Telegram/CLI gateways.

This is the second of a small series of PRs improving IWE detection on grok-4.x via xAI direct (paired with #22055 which transmits reasoning.effort to xAI Responses).

…relax prior-tool bail

The _looks_like_codex_intermediate_ack heuristic that re-routes narrative
acknowledgement turns into the post-tool nudge had two coverage gaps:

1. The future-ack regex, action_markers and workspace_markers were
   English-only. French Telegram users routinely produce IWE patterns
   ("Je vais vérifier le dossier", "Je corrige le binding", "Je relance
   le dashboard") that fell through detection.

2. The bail-on-prior-tool was global to the entire session, so any tool
   call earlier in the conversation permanently disabled detection.
   On long Telegram/CLI sessions (90 turns) this masked a fresh
   narration-only turn even when the *current* turn had no tool yet.

Changes:
- Replace the global bail with a current-turn-only check (since the
  most recent user message).
- Extend the future-ack regex with FR phrases (je vais, je corrige,
  je relance, je vérifie, je moccupe, cest noté, etc.).
- Extend action_markers with FR verb stems (vérifi, corrig, relanc,
  examin, cherch, analys, lanc, etc.) — substring match handles
  conjugations.
- Extend workspace_markers with FR nouns (répertoire, dossier,
  arborescence, projet, fichier, chemin, code, base de code).

Tests: 10 new cases in TestLooksLikeCodexIntermediateAck covering EN
regression, FR positives (verifier, corriger, relancer, diagnostiquer,
examiner), FR negatives (no action+workspace, no future ack), and the
relaxed prior-tool bail.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint labels May 9, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for identifying two still-present detector gaps. Current main still performs the full-history tool bail at agent/agent_runtime_helpers.py:2639 and its acknowledgement regex remains English-only at agent/agent_runtime_helpers.py:2648.

Problems

  • run_agent.py:3503 adds bare code as a substring workspace marker. A response such as “Je vais vérifier le code postal” also matches the proposed je vais future-ack and vérifi action markers, so it would receive an unnecessary continuation nudge.
  • The changed implementation location is stale: run_agent.py:1552-1563 now forwards to agent/agent_runtime_helpers.py:2619, and focused detector coverage lives in tests/agent/test_intent_ack_continuation.py.

Suggested changes

  • Port the current-turn-only tool check and French cases to the helper and its focused test module.
  • Remove or qualify bare code, and add a negative code postal regression test.

Automated hermes-sweeper review.

Comment thread run_agent.py
"projet",
"fichier",
"chemin",
"code",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bare code is too broad for substring matching: “Je vais vérifier le code postal” also matches the proposed future-ack and vérifi action markers, producing a false continuation. Please remove or qualify this marker and cover that negative case.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants