Skip to content

feat: add safe agent retry and recovery #8695

Description

@thinhlpg

Background and Goal

Jan Agent recovers context-window overflow and avoids executing truncated tool-call arguments, but transient provider failures, ordinary output truncation, and dropped MCP connections still end a run without a bounded recovery path. Add safe, observable recovery for those cases without replaying output or side-effecting tools.

Approach

  • Add one typed transient-retry policy at the model invocation boundary. Retry only pre-output transport failures, timeouts, 429, and retryable 5xx responses.
  • Keep existing context-overflow compaction separate. Treat cancellation, request validation or other 4xx responses, malformed tool arguments, and unsupported requests as terminal.
  • Apply existing credential rotation before the ordinary retry path. Honor an upstream Retry-After value when present; otherwise use bounded exponential backoff with jitter.
  • Gate replay on emitted state. A request that has produced visible text, an image, a tool call, or a completed tool result must not be resent automatically.
  • Normalize finish_reason: "length" for ordinary text into an incomplete-output result carrying the partial text and continuation metadata. Continue only with an append-safe follow-up, never by replaying the original request.
  • Replace polling-only MCP recovery with bounded reconnect-on-transport-close. A tool call may retry once only when it is idempotent or explicitly marked retry-safe; mutating calls must surface their error instead.

Acceptance Criteria

  • A transient provider failure before visible output retries at most three times with cancellation-aware exponential backoff, jitter, and Retry-After support.
  • Context overflow continues through the existing compaction path and is never handled by the transient retry policy.
  • A 400 validation error, malformed tool-call arguments, user cancellation, or a failure after visible output/tool emission does not automatically replay the request.
  • Credential rotation remains the first response for configured-key authentication or rate-limit handling; a single-key provider follows the bounded transient-retry policy only when the error is retryable.
  • A normal text response ending at the output limit retains the emitted text and uses an append-safe continuation without duplicating it. Truncated tool-call arguments remain non-executable.
  • A dropped MCP transport reconnects with a capped attempt/window policy. At most one retry is made for idempotent or explicitly retry-safe calls; mutating calls are never replayed automatically.
  • Focused tests cover retry classification, retry limits and cancellation, replay-safety gates, Retry-After, text-length continuation, and MCP reconnect/retry boundaries.

Non-goals

  • New provider credentials, model fallback chains, or retrying arbitrary 4xx failures.
  • Automatic replay of write, edit, exec, or other side-effecting tool calls.
  • Changes to the context-compaction algorithm beyond preserving its existing recovery boundary.

Migrated from janhq/jan-internal#326.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Status
No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions