Skip to content

Fix OpenCode continuation prompt delivery - #11856

Closed
mrcha033 wants to merge 2 commits into
stablyai:mainfrom
mrcha033:fix/opencode-session-context-handoff
Closed

mrcha033 wants to merge 2 commits into
stablyai:mainfrom
mrcha033:fix/opencode-session-context-handoff

Conversation

@mrcha033

@mrcha033 mrcha033 commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • use OpenCode's supported --prompt launch path for normal Continue in New Session handoffs
  • retain post-ready paste for prompts that exceed the Windows command budget
  • track inline delivery until the OpenCode process is ready instead of reporting success synchronously
  • add regression coverage for inline, tracked, and fallback delivery

Why

The continuation flow always forced OpenCode through the readiness-gated paste path. The installed Orca build still uses that path, so context can fail to reach the new session. OpenCode supports --prompt, which avoids the startup paste race for normal-sized handoff prompts. Inline launches now wait for the launched process to become ready before reporting delivery success.

Validation

  • focused affected suite: 5 files, 102 tests passed
  • pnpm run typecheck:web
  • changed-file oxlint --deny-warnings
  • opencode --help confirms --prompt support
  • red-green regression: inline delivery promise absent before fix, present and readiness-tracked after fix

The full suite previously had 10 unrelated environment/pre-existing failures; details are documented in the task handoff.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The launch planner validates inline OpenCode startup drafts against platform limits. It embeds fitting prompts in startup commands. It uses the existing post-ready paste-and-submit path for oversized drafts and other agents. The launch flow waits up to 8 seconds for agent readiness before reporting prompt delivery. Vitest coverage verifies planning, fallback flags, readiness waiting, delivery results, and callback timing.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the change and validation, but it omits the required Screenshots, AI Review Report, Security Audit, and Notes sections. Add all missing template sections and complete the Testing checklist, including the required AI review, security audit, platform compatibility, and notes.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main change: fixing OpenCode continuation prompt delivery.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/renderer/src/lib/launch-agent-in-new-tab.test.ts (1)

178-178: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a deferred readiness mock.

mockWaitForAgentReady.mockResolvedValue returns an already fulfilled promise. The test only proves that onPromptDelivered is not called in the same synchronous stack. It does not prove that delivery waits for readiness or exercise the inline timeout branch. Hold the promise pending, assert that delivery remains pending, then resolve it and add a ready: false case.

Also applies to: 230-253


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5f07a0bd-7f8c-4956-9f3e-a3defe220b41

📥 Commits

Reviewing files that changed from the base of the PR and between 4f8ce8b and a87df5d.

📒 Files selected for processing (2)
  • src/renderer/src/lib/launch-agent-in-new-tab.test.ts
  • src/renderer/src/lib/launch-agent-in-new-tab.ts

@greptile-apps

greptile-apps Bot commented Aug 1, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes OpenCode's continuation prompt delivery by routing normal-sized handoff prompts through OpenCode's --prompt CLI flag instead of the readiness-gated paste path, and adds async readiness tracking for inline launches so onPromptDelivered is called only after the process is confirmed ready rather than synchronously.

  • launch-agent-startup-prompt-plan.ts now builds an inline startup plan for OpenCode submit-after-ready launches, falling back to post-ready paste only when the command would exceed platform limits (e.g. large prompts on Windows).
  • launch-agent-in-new-tab.ts adds a new branch that calls waitForAgentReady for the inline path (pasteDraftAfterLaunch === null) and surfaces a promptDeliveryResult promise, mirroring the existing paste-path promise.
  • Two new test files provide coverage for the inline plan selection, the oversized-Windows fallback, the success-path readiness wait, and mock wiring for waitForAgentReady.

Confidence Score: 3/5

The inline delivery tracking branch reuses a paste-path timeout mechanism that fires a misleading 'paste it once the agent is ready' toast and returns delivered: false when OpenCode takes longer than 8 s to emit readiness signals — even though the prompt was already committed to the launch command via --prompt and cannot be unsent.

The plan-selection logic and the Windows fallback are clean. The concern is in the new inline tracking branch: createPasteReadinessTimeoutNotice was designed for paste delivery, where timeout genuinely means the prompt was never received. For inline --prompt delivery, a timeout only means readiness detection failed, not that the prompt was lost. Reusing it here can instruct the user to paste a prompt that OpenCode will already process on startup, potentially causing duplication. The timeout path also has no test, so this regression would not be caught before reaching users.

Files Needing Attention: The new inline tracking block in launch-agent-in-new-tab.ts (lines 220–239) needs a dedicated timeout notice or a different handling strategy for the { ready: false } case to avoid the misleading toast and incorrect delivered value.

Important Files Changed

Filename Overview
src/renderer/src/lib/launch-agent-startup-prompt-plan.ts Adds OpenCode-specific inline launch path for submit-after-ready: tries --prompt first, falls back to paste-after-ready when the command exceeds platform limits. Logic is straightforward and well-bounded by the agent check and inlineAgentDraftFitsPlatform guard.
src/renderer/src/lib/launch-agent-in-new-tab.ts New inline delivery tracking branch for OpenCode reuses createPasteReadinessTimeoutNotice, which fires a misleading 'paste it once the agent is ready' toast and returns delivered: false on timeout — incorrect because the prompt is already embedded in the launch command via --prompt.
src/renderer/src/lib/launch-agent-in-new-tab.test.ts New test covers the inline delivery success path; the timeout/failure path for the inline branch is not exercised.
src/renderer/src/lib/launch-agent-startup-prompt-plan.test.ts New test file with clear coverage for the two key cases: fitting inline plan on Linux, and oversized prompt fallback to paste on Windows. Correct and sufficient for the plan logic.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[launchAgentInNewTab called with submit-after-ready] --> B[planLaunchAgentStartupPrompt]
    B --> C{agent === opencode?}
    C -- No --> D[pasteAfterReady pasteDraftAfterLaunch = prompt]
    C -- Yes --> E[buildAgentStartupPlan with --prompt flag]
    E --> F{inlineAgentDraftFitsPlatform?}
    F -- No / Windows oversized --> D
    F -- Yes --> G[pasteDraftAfterLaunch = null startupPlan has --prompt]
    G --> H[new inline tracking branch]
    H --> I[createPasteReadinessTimeoutNotice]
    H --> J[waitForAgentReady timeoutMs: 8000]
    J --> K{ready?}
    K -- true --> L[onPromptDelivered called delivered: true]
    K -- false / timeout --> M[timeoutNotice.onTimeout Your prompt was not sent paste it delivered: false misleading: prompt was in --prompt flag]
    D --> N[deliverLaunchPromptToAgentTab paste path]
    N --> O{delivered?}
    O -- true --> P[onPromptDelivered called]
    O -- false --> Q[timeoutNotice.onTimeout delivered: false]
Loading

Reviews (1): Last reviewed commit: "Track inline OpenCode delivery" | Re-trigger Greptile

Comment on lines +220 to +239
if (hasPrompt && promptDelivery === 'submit-after-ready' && pasteDraftAfterLaunch === null) {
const timeoutNotice = createPasteReadinessTimeoutNotice({
worktreeId,
tabId: tab.id,
agent,
submitted: true
})
promptDeliveryResult = waitForAgentReady(tab.id, startupPlan.expectedProcess, {
timeoutMs: INLINE_PROMPT_DELIVERY_TIMEOUT_MS
}).then(({ ready }) => {
if (ready) {
onPromptDelivered?.()
} else {
timeoutNotice.onTimeout()
}
return {
delivered: ready,
failureNotified: !ready && timeoutNotice.wasNotified()
}
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Misleading timeout toast on inline --prompt delivery

createPasteReadinessTimeoutNotice is reused here, but its onTimeout handler fires the message "Your prompt wasn't sent — paste it once the agent is ready." For the inline OpenCode path the prompt is already embedded in the launch command (opencode --prompt '...'), so OpenCode will process it regardless of whether waitForAgentReady detects readiness within 8 seconds. If the process simply takes longer than 8 s to emit a recognisable readiness signal (slow machine, cold start, large context), the user sees a false alarm instructing them to paste the prompt again — which would create a duplicate submission. The delivered: false value that propagates to callers is similarly incorrect: the prompt was already committed to the launch command, not paste-dependent.

A separate timeout notice that either skips the toast or uses a different message (e.g. "We couldn't confirm the agent started — check the terminal") is needed for this branch, or the delivered value should reflect that the command was issued even when readiness detection times out.

Comment on lines +230 to +252
it('tracks inline OpenCode continuation delivery until the agent is ready', async () => {
const onPromptDelivered = vi.fn()
const { launchAgentInNewTab } = await import('./launch-agent-in-new-tab')

const result = launchAgentInNewTab({
agent: 'opencode',
worktreeId: 'wt-1',
prompt: 'Continue from the previous session.',
promptDelivery: 'submit-after-ready',
onPromptDelivered
})

expect(result?.promptDeliveryResult).toBeDefined()
expect(onPromptDelivered).not.toHaveBeenCalled()
await expect(result?.promptDeliveryResult).resolves.toEqual({
delivered: true,
failureNotified: false
})
expect(mockWaitForAgentReady).toHaveBeenCalledWith('tab-1', 'opencode', {
timeoutMs: 8000
})
expect(onPromptDelivered).toHaveBeenCalledOnce()
})

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 Timeout path for inline delivery has no test coverage

The new test covers only the happy path (waitForAgentReady resolves { ready: true }). There is no test for waitForAgentReady resolving { ready: false, reason: 'timeout' } on the inline delivery branch. Given the P1 concern above (misleading toast + incorrect delivered value), this gap also means the incorrect behaviour would not be caught by the test suite until a user reports it.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@mrcha033

mrcha033 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #11859. The replacement keeps transcript-derived context on the sanitized post-ready transport and fixes synthetic OpenCode SQLite transcript paths.

@mrcha033 mrcha033 closed this Aug 1, 2026
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