Skip to content

Decompose Smithers OpenRouter recovery into an explicit state machine #999

Closed

Description

@aviggiano

Context

The metric ratchet added by #997 identifies withOpenRouterRecovery in packages/runtime/src/templates/smithers/agents/openrouter.tsx as the largest cognitive-complexity hotspot in the repository:

  • cognitive complexity: 148 (template target: 20)
  • cyclomatic complexity: 82 (template target: 20)

This is generated runner code at a sensitive provider/retry boundary, so refactoring must preserve quota detection, retry deadlines, session continuation, error classification, and usage accounting.

Proposed work

  • Model recovery phases and terminal outcomes explicitly rather than through nested conditional control flow.
  • Extract pure transition/classification functions with table-driven tests.
  • Keep provider command execution and filesystem effects at a narrow adapter boundary.
  • Preserve generated-template compatibility under both Node and Bun.

Acceptance criteria

  • The recovery transition core has exhaustive state/outcome handling.
  • withOpenRouterRecovery falls below cyclomatic and cognitive complexity 40 as an intermediate ceiling.
  • Existing OpenRouter recovery, timeout, quota, resume, and usage tests remain green.
  • The metric baseline is lowered in the same PR.

Follow-up to #997.

Activity

  1. aviggiano commented on Oct 2, 2026

    @aviggiano
    CollaboratorAuthor

    Closing as completed by #1007 (ff27466). withOpenRouterRecovery is now a short entry point that builds an OpenRouterRecoveryContext and hands off to runOpenRouterRecovery. The recovery is split into small per-phase handlers: failure precedence, rate-limit classification, retry preparation and deadline checks, success, and terminal-answer continuation. They all use the existing pure decideOpenRouter429Recovery decision (rate-limit-exhausted / total-timeout / backoff), and each new function sits well below the 40 target. The .quality metric baseline this issue mentions never landed (#1005 chose not to add one), and the changed-line strict lint (lint:strict:ci, complexity 25 for templates) keeps the function from growing back.

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

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions