Skip to content

Commit e242fe1

Browse files
authored
fix(web): use prompt_async endpoint to avoid timeout over VPN/tunnel (anomalyco#12749)
1 parent f991a6c commit e242fe1

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { test, expect } from "../fixtures"
2+
import { promptSelector } from "../selectors"
3+
import { sessionIDFromUrl } from "../actions"
4+
5+
// Regression test for Issue #12453: the synchronous POST /message endpoint holds
6+
// the connection open while the agent works, causing "Failed to fetch" over
7+
// VPN/Tailscale. The fix switches to POST /prompt_async which returns immediately.
8+
test("prompt succeeds when sync message endpoint is unreachable", async ({ page, sdk, gotoSession }) => {
9+
test.setTimeout(120_000)
10+
11+
// Simulate Tailscale/VPN killing the long-lived sync connection
12+
await page.route("**/session/*/message", (route) => route.abort("connectionfailed"))
13+
14+
await gotoSession()
15+
16+
const token = `E2E_ASYNC_${Date.now()}`
17+
await page.locator(promptSelector).click()
18+
await page.keyboard.type(`Reply with exactly: ${token}`)
19+
await page.keyboard.press("Enter")
20+
21+
await expect(page).toHaveURL(/\/session\/[^/?#]+/, { timeout: 30_000 })
22+
const sessionID = sessionIDFromUrl(page.url())!
23+
24+
try {
25+
// Agent response arrives via SSE despite sync endpoint being dead
26+
await expect
27+
.poll(
28+
async () => {
29+
const messages = await sdk.session.messages({ sessionID, limit: 50 }).then((r) => r.data ?? [])
30+
return messages
31+
.filter((m) => m.info.role === "assistant")
32+
.flatMap((m) => m.parts)
33+
.filter((p) => p.type === "text")
34+
.map((p) => p.text)
35+
.join("\n")
36+
},
37+
{ timeout: 90_000 },
38+
)
39+
.toContain(token)
40+
} finally {
41+
await sdk.session.delete({ sessionID }).catch(() => undefined)
42+
}
43+
})

packages/app/src/components/prompt-input/submit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ export function createPromptSubmit(input: PromptSubmitInput) {
385385
const send = async () => {
386386
const ok = await waitForWorktree()
387387
if (!ok) return
388-
await client.session.prompt({
388+
await client.session.promptAsync({
389389
sessionID: session.id,
390390
agent,
391391
model,

0 commit comments

Comments
 (0)