Skip to content

feat(github): resume the prior session when github run retries#32584

Open
NathanDrake2406 wants to merge 2 commits into
anomalyco:devfrom
NathanDrake2406:feat/github-run-resume-session
Open

feat(github): resume the prior session when github run retries#32584
NathanDrake2406 wants to merge 2 commits into
anomalyco:devfrom
NathanDrake2406:feat/github-run-resume-session

Conversation

@NathanDrake2406

@NathanDrake2406 NathanDrake2406 commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #32583

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

opencode github run calls Session.create() on every invocation, so a retry starts a new session. The agent redoes all the setup: re-clone, re-read the PR/issue, re-prompt the model. The prior attempt's session is still in the local DB, but nothing looks for it.

This stamps GITHUB_RUN_ID into the session metadata at creation. That id stays the same across re-runs (only GITHUB_RUN_ATTEMPT changes), so it works as a resume key. On start, github run looks up the session for the current run id and resumes it if found, otherwise creates as before.

On resume it sends a short "continue" message instead of re-sending the full prompt, which is where the tokens are saved. The user prompt is persisted before the model call, so a transient mid-call failure (the case a retry targets) leaves it in history and the nudge has context. If the prior attempt died during setup before any message was written, it falls back to the full prompt so the model still gets the task.

Scope: same-runner retries, where the session DB survives (for example a wrapper that re-runs the command after a transient failure). A GitHub UI "Re-run" starts on a fresh runner with an empty DB and still creates a new session. Persisting the data dir across runners is a separate change, called out in a code comment.

How did you verify your code works?

  • Extracted the resume selection as findResumableSession and tested it against the real Session service and SQLite: match by run id, isolation across runs, no-match returns undefined, and a fork (which copies metadata) resolves back to the original. Plus a pure tiebreak test.
  • bun test test/cli/github-resume.test.ts passes (6). Existing github-action.test.ts and github-remote.test.ts pass (33).
  • bun run typecheck is clean. oxlint is clean on the changed files.
  • The full github run flow (OIDC, octokit, git) has no automated coverage here; it needs a live GitHub Actions environment to exercise end to end.

Screenshots / recordings

Not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions Bot added contributor needs:compliance This means the issue will auto-close after 2 hours. and removed needs:compliance This means the issue will auto-close after 2 hours. labels Jun 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

opencode github run always calls Session.create(), so a retry that
re-spawns the command on the same runner starts a fresh session: the
agent re-clones the repo, re-reads the PR/issue, and re-prompts the
model from zero even though the prior attempt's session is still in the
local DB. Every retry pays full setup cost again.

github run never wired in the session resume that opencode run already
has via --continue/--session. The fix keys the session on GITHUB_RUN_ID
(stable across re-runs; only GITHUB_RUN_ATTEMPT increments) by stamping
it into session metadata at creation, then on start reuses the session
for that run id when one exists instead of creating.

When continuing it sends a short nudge rather than re-injecting the full
prompt, which is where the tokens are saved. The user prompt is
persisted before the model call, so a transient mid-call failure leaves
it in history and the nudge has context. If the prior attempt died
during setup before any message was stored, it falls back to the full
prompt so the resumed session still receives the task.

Scope: same-runner retries only, where the session DB survives. A GitHub
UI re-run lands on a fresh runner with an empty DB and still starts
fresh; persisting the data dir across runners is out of scope.

The two decisions are pulled into pure functions (findResumableSession,
shouldSendContinuation) keyed by a shared GITHUB_RUN_METADATA_KEY. The
handler's resolution sequence is exercised against the real Session
service and SQLite, plus pure branch tests for each decision.

Fixes anomalyco#32583
@NathanDrake2406 NathanDrake2406 force-pushed the feat/github-run-resume-session branch from e31b32f to ab4266e Compare June 16, 2026 16:57
Query session metadata by GITHUB_RUN_ID instead of depending on bounded session listing, so same-runner retries find the workflow-run session directly.

Keep continuation prompt/file selection in a tested helper and cover lookup past the list limit, duplicate/fork metadata, and resume prompt behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: continue the prior session when github run retries

1 participant