feat(sdk): surface a parked agent run to Head Start callers - #4791
Conversation
A Head Start turn splits across two processes: step 1 runs in the warm server, step 2 in the agent run. When the run is pinned to a deployment that has not landed yet it parks, so step 1 streams normally and step 2 arrives late, with nothing saying why. `pendingVersion` now reaches all three Head Start shapes: - the transport emits `run-pending-version` with a new `head-start` source, read from an `X-Trigger-Chat-Pending-Version` header the handler sets only when parked - `chat.startHeadStart` returns it, for the detached flow that has no open browser connection to emit into - the `chat.handover` session handle exposes it, for callers that build their own response Nothing about the wait changes: the handover signal is durable, the agent's idle timeout starts when the run boots rather than when it was triggered, and a fresh run reads `session.in` from the beginning, so a parked turn resumes at step 2 once the deployment lands.
🦋 Changeset detectedLatest commit: 266d394 The changes in this PR will be included in the next version bump. This PR includes changesets to release 27 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
| if (response.headers.get("X-Trigger-Chat-Pending-Version") === "1") { | ||
| this.emitEvent({ | ||
| type: "run-pending-version", | ||
| chatId, | ||
| timestamp: Date.now(), | ||
| source: "head-start", | ||
| }); | ||
| } |
There was a problem hiding this comment.
🔍 Parked notice clears on head-start step 1
On the head-start path, step 1 always streams from the warm server, so first-chunk fires immediately (chat.ts) right after run-pending-version is emitted (chat.ts). The docs' recommended first-chunk clear (version-skew-protection.mdx) then hides the parked notice before step 2, the actually-parked part, is reached. Unlike the direct path, where first-chunk arrives only after the deployment lands.
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
A Head Start turn runs across two processes: step 1 in your warm server, step 2 in the agent run. When that run is pinned to a deployment that has not landed yet, it parks, so step 1 streams normally and step 2 arrives late with nothing saying why.
pendingVersionnow reaches every Head Start shape.The transport learns it from the
headStartPOST and emits the existing event with a newhead-startsource:The detached flow has no open browser connection to emit into, so it returns the flag:
chat.handover's session handle exposes it too, for callers that build their own response.Design
The handler sets
X-Trigger-Chat-Pending-Version: 1only when the run is parked, next to theX-Trigger-Chat-*headers the transport already reads to hydrate. A chat that is not pinned, or is pinned to a live deployment, gets exactly the response it got before.Nothing about the wait itself changes, and it is gentler than it looks. The handover signal is written to
session.in, which is durable; a fresh run subscribes from the start of that stream rather than the live tail; and the agent'sidleTimeoutInSecondsis consumed inside the run at turn 0, so a parked run does not burn its idle budget while parked. A parked turn resumes at step 2 once the deployment lands.Stacked on #4789, which adds the session pin and the
run-pending-versionevent this extends.