You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
chat.headStart relay ends the first turn after one empty session.out long-poll window (SDK 4.7.7) #5056
chat.headStart relay ends the first turn after one empty session.out long-poll window
SDK:@trigger.dev/sdk 4.7.7 (also present in 0.0.0-rc-4-8-0-20261021151928 and 4.8.0-webhooks.20261020092920)
What happens
On a head-start first turn, stitchHandoverStream (dist/esm/v3/chat-server.js) reads the agent's session.out once with apiClient.subscribeToSessionStream. When a tool runs for more than ~60 s without writing a record, the long-poll window closes empty, the for await loop ends, the relay writes trigger:session-state and closes the response — without trigger:turn-complete. The browser transport's sendMessagesViaHandover then clears isStreaming, so the UI treats the turn as finished while the agent run keeps going and later completes normally.
Measured in a browser: the /api/chat body ended 59,994 ms and 60,003 ms after the last chunk, both times with trigger:session-state and no turn-complete.
Why it looks like a bug
docs/ai-chat/client-protocol.mdx § Stream timeout: "If nothing arrives by the deadline, the server sends data: [DONE] and closes. Reconnect with Last-Event-ID to continue." The browser transport does this (resumeAfterEof); the head-start relay does not.
Repro
chat.headStart route + chat.agent with a tool that sleeps 90 s without writing to the stream.
Send the first message of a new chat through the transport's headStart option.
The response ends ~60 s into the tool; the run finishes the turn later.
Fix we are running (patch on 4.7.7)
Loop the session.out read until turn-complete or abort, resuming from the last seen record, with waitBeforeEofResubscribe between empty windows:
Related: docs/ai-chat/fast-starts.mdx says the handler keeps the response open for the whole first turn, so the serverless maxDuration must cover it. It may be worth noting that a first turn longer than the platform maximum still ends the relay, and that the transport does not fall back to session.out when the head-start response ends or errors before turn-complete.
Activity