Skip to content

[bug] Surface guard-triggered Agent stops as actionable terminal states #2122

Description

@zerob13

Summary

Safety guards such as the tool-call limit and repeated no-progress detection can stop an Agent correctly, but the resulting user/CLI state can look like an ordinary completion or an unexplained stop.

The guards should remain. Their terminal outcomes need explicit, actionable product semantics.

Priority: P2

Current behavior

  • src/main/agent/deepchat/loop/deepChatLoopEngine.ts enforces MAX_TOOL_CALLS = 128.
  • src/main/agent/deepchat/runtime/noProgressToolLoopGuard.ts adds a correction after two identical tool batches and terminates after four.
  • In src/main/agent/deepchat/runtime/process.ts, the max-tool path stamps runOutcome = 'completed' with runStopReason = 'max_tool_calls' and maps the plan terminal reason to max_steps.

The structured stop reason exists, but an ordinary “completed” outcome can dominate the renderer/CLI presentation. A user may conclude that the Agent chose to finish, even though a safety budget ended the run before the requested task was complete.

Related contracts and documentation

  • docs/architecture/durable-execution-journal/spec.md requires authoritative terminal facts before terminal transcript/status/UI projection.
  • docs/architecture/local-control-plane/spec.md requires terminal benchmark records to expose finish reason, retries, cancellation outcome, and stable machine semantics.
  • docs/architecture/deepchat-agent-harness-boundaries/spec.md requires terminal persistence and public return values to remain explicit across lifecycle owners.

Impact

  • Users experience a protective stop as random Agent behavior.
  • Automation may treat a partial task as successful completion.
  • The user has no direct “continue with a fresh budget” action.
  • Support cannot distinguish model choice from runtime guard activation without inspecting metadata.

Proposed direction

  • Define a user-visible terminal category such as limit_reached/needs_continuation while preserving the exact stop reason.
  • Show concise reason-specific copy:
    • tool-call limit reached;
    • repeated identical tool batches/no progress;
    • provider-round limit reached.
  • Offer safe actions such as Continue, Change approach, or Review details where applicable.
  • Ensure CLI terminal results are non-success or explicitly partial according to a documented contract; do not overload ordinary completed.
  • Keep no-progress and tool-call protections fail-safe.

Acceptance criteria

  • Guard-triggered stops cannot render as an indistinguishable ordinary completion.
  • Renderer and CLI expose the exact structured stop reason.
  • Continuing creates a new physical run and does not mutate the historical terminal fact.
  • No-progress copy explains that repeated tool results caused the stop without exposing sensitive tool output.
  • Existing safety thresholds and loop protections remain intact.
  • Tests cover max tools, no progress, max provider rounds, user stop, and normal completion.

User benefit

Users understand why the Agent stopped and can take a safe next action instead of assuming the model silently abandoned the task.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions