todo2code

Ticket 034: Scale LLM timeout by input complexity

Goal and scope

Derive each OpenRouter request timeout from the configured base timeout, input size, requested output size and structural complexity. Small requests retain the current timeout. Crossing a baseline doubles it; each further doubling of load doubles it again, up to a bounded maximum.

This responds to a live Subactor audit where a short NL request completed, while the bounded multi-document pipeline legitimately ran for several minutes. The change distinguishes one-request timeout from total pipeline duration and does not hide exhausted-credit, schema or external-cancellation failures.

Approved deterministic policy

For a chat-completion body calculate:

Therefore an input just above the baseline gets 2x, above twice the baseline gets 4x, and above four times gets 8x. The existing OPENROUTER_TIMEOUT_MS and documentation-specific base timeout remain minimums, not replaced defaults.

Bounded implementation paths

Model selection, token budgets, retry counts, chunking, concurrency, provider fallback and the /models endpoint are out of scope.

Acceptance criteria

Base readiness

The current main worktree is clean, no other active ticket owns the llm workstream, and its OpenRouter implementation matches the previously validated refactoring base. The stale blockers from the earlier proposal no longer apply.

Approval boundary

The user’s earlier adaptive-timeout instruction and current execute instruction authorize the bounded implementation. They are not trusted merge evidence; an external Validator App exact-head review remains required.

Validation result

All seven focused timeout tests pass. The complete suite passes 341 tests with one environment-dependent Java test skipped, full verification has zero failures, Docker smoke passes, and the local governance gate reports zero errors and warnings. Koru accepted the final complexity repair, and validator-agent approved exact head e09e8323b96cfdd7543e851b57bd1035d640eb84 with openrouter/z-ai/glm-5.2. All protected checks passed and PR #31 merged the implementation as main@6116961d8c9674b24c1161903e43f3a7dbb2147b.

Participants