Skip to content

fix(opencode): retry output-limit responses - #137

Merged
MagMueller merged 5 commits into
mainfrom
retry-output-limit
Aug 2, 2026
Merged

fix(opencode): retry output-limit responses#137
MagMueller merged 5 commits into
mainfrom
retry-output-limit

Conversation

@MagMueller

@MagMueller MagMueller commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • retry output-limit responses with at most three total LLM calls
  • resample the identical LLM request object without adding a continuation message
  • replace only attempts that will actually be retried, while rolling their billed usage into one final persisted step-finish record
  • preserve the third call's partial output when all attempts truncate, matching Cloud's intentional partial-result-plus-error behavior
  • leave existing retry behavior for rate limits, transport failures, and provider 5xx responses unchanged

Production evidence

Four V4 runs in the audited 12-hour window ended at provider output limits. None made another LLM request; two had no extractable answer and two retained only a truncated partial answer.

Historical behavior

  • output partials have been persisted since the 2025-11-17 agent-loop refactor
  • Cloud PR #5002 intentionally returns a final truncated partial next to its failure
  • generic retries were originally bounded at 10; the same 2025-11-17 refactor replaced that loop with an unbounded one

Validation

  • bun test test/session/retry.test.ts (34 passed)
  • targeted processor regression proves identical input, one final persisted boundary, and combined usage (1 passed)
  • real local bcode run: successful resample made 2 calls; exhausted resample stopped at exactly 3 calls and exited 1
  • the plain CLI stdout streams partial attempts before cleanup; Cloud's final result is extracted from the cleaned persisted transcript
  • package and root typecheck passed with Bun 1.3.14 (16/16 root tasks)
  • targeted oxlint: 0 errors

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread packages/opencode/src/session/retry.ts Outdated
Comment thread packages/opencode/src/session/processor.ts Outdated
Comment thread packages/opencode/test/session/processor-effect.test.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread packages/opencode/test/session/retry.test.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/opencode/src/session/processor.ts">

<violation number="1" location="packages/opencode/src/session/processor.ts:738">
P2: After both retries are exhausted, the final output-limited attempt still leaves its truncated text visible because `onRetry` is never called for the capped error. Keep terminal-attempt cleanup separate from retry scheduling so every length-truncated response is removed while its usage remains recorded.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

provider: input.model.providerID,
parse,
onRetry: (error) =>
SessionV1.OutputLengthError.isInstance(error) ? resetOutputLimit() : Effect.void,

@cubic-dev-ai cubic-dev-ai Bot Aug 2, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: After both retries are exhausted, the final output-limited attempt still leaves its truncated text visible because onRetry is never called for the capped error. Keep terminal-attempt cleanup separate from retry scheduling so every length-truncated response is removed while its usage remains recorded.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/src/session/processor.ts, line 738:

<comment>After both retries are exhausted, the final output-limited attempt still leaves its truncated text visible because `onRetry` is never called for the capped error. Keep terminal-attempt cleanup separate from retry scheduling so every length-truncated response is removed while its usage remains recorded.</comment>

<file context>
@@ -709,13 +730,12 @@ const layer = Layer.effect(
                 provider: input.model.providerID,
                 parse,
+                onRetry: (error) =>
+                  SessionV1.OutputLengthError.isInstance(error) ? resetOutputLimit() : Effect.void,
                 set: (info) => {
                   return status.set(ctx.sessionID, {
</file context>
Fix with cubic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional and I am not deleting the terminal partial. The original agent loop has persisted output-limited partial text since 2025-11-17, and Cloud PR #5002 explicitly requires the final partial to remain available next to the truncation error. Cleanup is therefore limited to attempts that will actually be retried; the third call remains the terminal evidence/result.

Comment thread packages/opencode/test/session/processor-effect.test.ts
@MagMueller
MagMueller merged commit c4ccff5 into main Aug 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant