Skip to content

merge_interventions lets an empty-string stop_reason shadow a later real one #5

Description

@zhanghanduo

agent_core/loop_types.py merges stop reasons with a None check:

if stop_reason is None and iv.stop_reason is not None:
    stop_reason = iv.stop_reason

Intervention.stop_reason is str | None, so an observer returning Intervention(stop_reason="") — e.g. a reason built from a config value that defaulted empty — claims the slot.

Consequence: a later observer's real stop_reason="budget_exhausted" is discarded, and a loop testing truthiness (if merged.stop_reason:) then sees no stop at all — the run continues past both stop requests. A budget or deadline observer silently stops working.

Fix direction: treat the empty string as absent — normalise "" to None at merge, or gate on truthiness. The docstring rule ("first non-None wins") should be restated as "first non-empty wins". Worth a test in tests/test_loop_types.py pinning the shadowing case.

Provenance: pre-existing in ApodexHarness/miroharness/core/loop_types.py, ported verbatim by #1 — not introduced by the refactor. ApodexHarness carries the same code and needs the same change until it consumes AgentCore.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions