Skip to content

fix(agent, cron): handle final reports at iteration limits - #50967

Closed
helix4u wants to merge 2 commits into
NousResearch:mainfrom
helix4u:fix/turn-finalizer-last-call-completion
Closed

fix(agent, cron): handle final reports at iteration limits#50967
helix4u wants to merge 2 commits into
NousResearch:mainfrom
helix4u:fix/turn-finalizer-last-call-completion

Conversation

@helix4u

@helix4u helix4u commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes two completion-state boundary cases where Hermes can produce usable final text at the iteration limit, but downstream code still treats the turn as incomplete.

First, agent.turn_finalizer.finalize_turn() now treats a normal final text_response(...) as completed even when it lands on exactly the last allowed API call. The previous predicate required api_call_count < max_iterations, so a successful text_response(finish_reason=stop) at api_call_count == max_iterations returned completed=False.

Second, cron now handles the related but distinct max-iteration fallback-summary path. A cron run can hit max_iterations_reached(...), receive a non-empty fallback report from the no-tools summary call, and still have completed=False in the generic agent result. Cron should deliver that report instead of raising RuntimeError(<full report>).

The generic max-iteration semantics stay intact for interactive and worker paths. The cron-specific exception only applies when failed is not true, the exit reason is max_iterations_reached(...), and the fallback response is non-empty.

Related Issue

Discord support thread: https://discord.com/channels/1053877538025386074/1518634271122784427

Supersedes #50980; the cron fallback-summary fix has been consolidated here so the support thread has a single review target.

Separate related PR:

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • agent/turn_finalizer.py: treat text_response(...) exits with a final response as completed even when they happen on the last allowed API call.
  • cron/scheduler.py: let cron deliver a non-empty max_iterations_reached(...) fallback response instead of raising it as an error when completed=False.
  • tests/agent/test_turn_finalizer_cleanup_guard.py: add regression coverage for a final text response at the max-iteration boundary, while keeping true max-iteration summary turns incomplete.
  • tests/cron/test_scheduler.py: add regression coverage for cron delivering a non-empty max-iteration fallback report.

How to Test

  1. Run the focused finalizer and scheduler suites:
    scripts/run_tests.sh -j 4 tests/agent/test_turn_finalizer_cleanup_guard.py tests/cron/test_scheduler.py
  2. Confirm normal final text at the max API-call boundary returns completed=True.
  3. Confirm generic max-iteration summary turns still return completed=False.
  4. Confirm cron delivers a non-empty max_iterations_reached(...) fallback response instead of failing the run.
  5. Confirm real agent failure paths with failed=True, empty incomplete output, or explicit errors still fail.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: WSL/Linux

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

N/A

Screenshots / Logs

Focused test run:

scripts/run_tests.sh -j 4 tests/agent/test_turn_finalizer_cleanup_guard.py tests/cron/test_scheduler.py

Result: 169 tests passed.

@helix4u
helix4u marked this pull request as ready for review June 22, 2026 18:07
@helix4u helix4u changed the title fix(agent): complete final text on last turn fix(agent, cron): handle final reports at iteration limits Jun 22, 2026
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management P2 Medium — degraded but workaround exists labels Jun 22, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #50989 (#50989). Both of your commits were cherry-picked onto current main with your authorship preserved in git log (3972701, ae7e857).

This fixes exactly the symptom NilVaw reported: a complete cron report landing on the last allowed API call was marked incomplete and raised as a RuntimeError whose text was the report itself. Your turn_finalizer change (text_response → completed=True) and the cron-side delivery of max-iteration summaries both landed. Thanks!

@teknium1 teknium1 closed this Jun 22, 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 comp/cron Cron scheduler and job management P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants