Skip to content

feat: send loop nudge message to agent when loop is detected #486

Description

@avoidwork

Summary

When the agent enters a repetitive loop, the system detects it via turn hash tracking but only displays a UI nudge ("You're looping.") to the user. The agent itself never receives feedback that it is stuck, so it continues looping.

Current Behavior

  1. src/agent/react.js tracks turn hashes in a sliding window (default size 20)
  2. When a duplicate hash is found, it emits a loop_detected event
  3. The TUI (src/tui/app.js:349-359) handles this by appending "You're looping." to the last assistant message display
  4. The agent continues its loop — it never receives a message telling it to try a different approach

Desired Behavior

When a loop is detected, inject a nudge message into the conversation that the agent can see. This message should:

  • Be sent to the agent (not just displayed to the user)
  • Inform the agent it is in a repetitive loop
  • Encourage the agent to try a different approach

Example nudge: "You are in a repetitive loop. Try a different approach."

Config Design

Two new fields under agent in config.yaml, with corresponding environment variable overrides:

  • loopMsg (string, optional) — The nudge message to inject when a loop is detected. If omitted, use a sensible default.
    • Env var: AGENT_LOOP_MSG
  • loopLimit (number, optional, default: 5) — Maximum number of loop nudge messages to inject before stopping. After this limit, the system should stop injecting nudges (but may still detect loops).
    • Env var: AGENT_LOOP_LIMIT

Example config:

agent:
  recursionLimit: 1000
  autoContinueLimit: 1000
  nodeTimeout: 600000
  turnHashWindow: 20
  turnBufferMax: 64
  loopMsg: "You are in a repetitive loop. Try a different approach."
  loopLimit: 5

Technical Notes

  • Loop detection lives in src/agent/react.js (turn hash tracking, checkTurnHash function around line 265)
  • The loop_detected event is emitted via callback({ type: "loop_detected" }) at line 269
  • The TUI currently only handles this for display purposes (line 349-359 in src/tui/app.js)
  • The nudge should be injected into the conversation messages before the next agent turn, not just displayed in the UI
  • Consider whether the nudge should be a user message or a system message
  • The turnHashWindow and turnBufferMax are configurable via config.agent.turnHashWindow and config.agent.turnBufferMax
  • Env var resolution follows the existing pattern in src/config/loader.js — container keys like agent are dropped, so agent.loopMsg resolves to AGENT_LOOP_MSG

Decisions

  • Nudge message is configurable: Yes, via agent.loopMsg / AGENT_LOOP_MSG
  • Max nudge count: Yes, via agent.loopLimit / AGENT_LOOP_LIMIT, default 5
  • Include repetition context in nudge: No

Metadata

Metadata

Assignees

No one assigned

    Labels

    approvedAn identifier for Madz to take action.feature

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions