feat: opencode fallback provider + deleted-file annotation#31
Merged
Conversation
Two related fixes that surfaced during the data-pathways v2.3.7 release (see flowcore-io/data-pathways#89), where the validator repeatedly tried to read files that had been deleted in the PR and eventually tripped the OpenCode agent's loop detector. 1. `scripts/validate.sh` — `generate_diff_summary` now emits a `Status` field per file (ADDED / MODIFIED / DELETED / RENAMED / COPIED / TYPE-CHANGED) derived from `git diff --name-status`. DELETED entries get an explicit "do NOT attempt to read" note with a pointer to `git show HEAD^:path` for inspecting prior contents. Modified-range extraction is skipped for deleted files. Rename detection handles the `old => new` numstat notation so status lookup matches. 2. `scripts/validate.sh` — `run_opencode` and `run_gemini` now retry on a broader set of transient upstream signals: 504, 530, "provider returned error", "unmapped", ECONNRESET, EAI_AGAIN, "socket hang up", "deadline exceeded", plus the existing 429/503/timeout/rate-limit set. Previously these caused a single-shot failure. Grep is now case-insensitive. 3. `system-prompt.md` — adds a "DELETED files — STOP condition" section that explicitly tells the LLM to trust the Status annotation, never retry bare reads on deleted paths, and use `git show origin/<BASE>:path` if it actually needs the former contents. Updates the example workflow to include a DELETED row so the pattern is concrete. Tested locally against the data-pathways v2.3.6→v2.3.7 diff: both deleted handler files are now annotated `Status: DELETED` with the read-warning note, and modification-only diffs still render cleanly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Primary opencode-provider often hits sustained 429s (e.g., OpenRouter rate-limited). Internal exponential-backoff retries can't recover when the upstream is broadly throttled, so the action fails. This adds an optional second opencode-provider that takes over only after the primary exhausts its retries on retryable errors (429/503/504/timeout/etc.). Non-retryable errors still fail immediately without invoking the fallback. - New inputs: fallback-opencode-provider, fallback-opencode-model, fallback-opencode-api-key-secret. The key secret is optional when the fallback re-uses the same opencode-provider as the primary. - setup-mcp.sh enables both providers in opencode.json when a different fallback is configured, so a single CLI run can route via -m. - run_opencode now distinguishes retryable-exhausted (rc=2) from non-retryable (rc=1); main() invokes fallback only on rc=2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
New inputs
fallback-opencode-provider(openrouter|anthropic|openai) — empty disables.fallback-opencode-model— model id used by the fallback provider.fallback-opencode-api-key-secret— optional when fallback uses the same provider as primary (key reused); required when providers differ.How it works
setup-mcp.shenables both providers inopencode.jsonwhen a different fallback is configured, so oneopencodeinstall can route via-m.run_opencodenow returns2on retryable-exhausted (vs1non-retryable).main()re-invokesrun_opencodewith the fallback model only on rc=2.Test plan
setup-mcp.shJSON shape verified for no-fallback / different-fallback / same-as-primarybash -nclean on all modified scripts;action.ymlparses as YAML