diff options
| author | eytans <[email protected]> | 2026-02-13 13:25:47 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-13 05:25:47 -0600 |
| commit | e242fe19e48f6aa70e5c3f7d54f34d688181edb2 (patch) | |
| tree | e6a8789e50b6ea84e881f63825ef9f71ac770c33 | |
| parent | f991a6c0b6bba97be27f3c132c14c5fa78d05536 (diff) | |
| download | opencode-e242fe19e48f6aa70e5c3f7d54f34d688181edb2.tar.gz opencode-e242fe19e48f6aa70e5c3f7d54f34d688181edb2.zip | |
fix(web): use prompt_async endpoint to avoid timeout over VPN/tunnel (#12749)
| -rw-r--r-- | packages/app/e2e/prompt/prompt-async.spec.ts | 43 | ||||
| -rw-r--r-- | packages/app/src/components/prompt-input/submit.ts | 2 |
2 files changed, 44 insertions, 1 deletions
diff --git a/packages/app/e2e/prompt/prompt-async.spec.ts b/packages/app/e2e/prompt/prompt-async.spec.ts new file mode 100644 index 000000000..ce9b1a7a3 --- /dev/null +++ b/packages/app/e2e/prompt/prompt-async.spec.ts @@ -0,0 +1,43 @@ +import { test, expect } from "../fixtures" +import { promptSelector } from "../selectors" +import { sessionIDFromUrl } from "../actions" + +// Regression test for Issue #12453: the synchronous POST /message endpoint holds +// the connection open while the agent works, causing "Failed to fetch" over +// VPN/Tailscale. The fix switches to POST /prompt_async which returns immediately. +test("prompt succeeds when sync message endpoint is unreachable", async ({ page, sdk, gotoSession }) => { + test.setTimeout(120_000) + + // Simulate Tailscale/VPN killing the long-lived sync connection + await page.route("**/session/*/message", (route) => route.abort("connectionfailed")) + + await gotoSession() + + const token = `E2E_ASYNC_${Date.now()}` + await page.locator(promptSelector).click() + await page.keyboard.type(`Reply with exactly: ${token}`) + await page.keyboard.press("Enter") + + await expect(page).toHaveURL(/\/session\/[^/?#]+/, { timeout: 30_000 }) + const sessionID = sessionIDFromUrl(page.url())! + + try { + // Agent response arrives via SSE despite sync endpoint being dead + await expect + .poll( + async () => { + const messages = await sdk.session.messages({ sessionID, limit: 50 }).then((r) => r.data ?? []) + return messages + .filter((m) => m.info.role === "assistant") + .flatMap((m) => m.parts) + .filter((p) => p.type === "text") + .map((p) => p.text) + .join("\n") + }, + { timeout: 90_000 }, + ) + .toContain(token) + } finally { + await sdk.session.delete({ sessionID }).catch(() => undefined) + } +}) diff --git a/packages/app/src/components/prompt-input/submit.ts b/packages/app/src/components/prompt-input/submit.ts index 49d75a95e..9a1fba5d5 100644 --- a/packages/app/src/components/prompt-input/submit.ts +++ b/packages/app/src/components/prompt-input/submit.ts @@ -385,7 +385,7 @@ export function createPromptSubmit(input: PromptSubmitInput) { const send = async () => { const ok = await waitForWorktree() if (!ok) return - await client.session.prompt({ + await client.session.promptAsync({ sessionID: session.id, agent, model, |
