Relay background-turn responses to Slack - #3704
Conversation
A background (task-notification) turn resolves no tracked prompt, so the prompt-resolution relay sites never fire for it: when the agent ends its turn to wait on a background process, the answer it produces on wake-up never reaches Slack, and the agent has no way to know it was dropped. Trigger the relay from the ACP transport tap when a clean _posthog/background_turn_complete passes through, and scope every relay to the prose no prior relay has delivered (background turns append to the same turn buffer as the tracked turn before them, so an unscoped read would re-post already-delivered prose, and a silent wake-up would re-post the previous answer).
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
|
Hey @VojtechBartos, we've migrated this repo into the PostHog/posthog monorepo, so this PR needs to be recreated there. Easiest path: check out the monorepo and run the Shout if you get stuck. |
Problem
When the cloud agent starts a background process and ends its turn to wait for it ("I'll wait for the completion notification"), the wake-up turn that eventually produces the answer never reaches Slack. A background (task-notification) turn resolves no tracked
prompt()call, andrelayAgentResponseonly fires at the three prompt-resolution sites, so the relay for that turn simply never happens. The agent's transcript contains the answer, the user's thread doesn't, and the agent has no way to know the reply was dropped.Origin: https://posthog.slack.com/archives/C09SK2PAGKF/p1784716116964029
Changes
agent-server.ts: the ACP transport tap now triggersrelayAgentResponsewhen a clean_posthog/background_turn_complete(stop reasonend_turn) passes through. Refusal/error background turns stay silent, matching the tracked path'send_turngating.session-log-writer.ts: relays now consume prose through a newtakeUnrelayedAgentResponseParts, which returns only the text blocks no prior relay has delivered. Background turns append to the same turn buffer as the tracked turn before them (only a new prompt resets it), so an unscoped read would re-post already-delivered prose, and a silent wake-up (e.g. the agent just reschedules) would re-post the previous answer verbatim.Companion backend PR (accepts late relays from completed runs): PostHog/posthog#72897
How did you test this?
Automated only, all in
packages/agent:agent-server.test.ts"background turn relay" — relays prose on a cleanbackground_turn_complete, skips non-end_turnstop reasons, skips silent wake-ups.session-log-writer.test.ts— take-cursor semantics (only prose since previous take; reset starts over).question-relay.test.ts, relay-echo tests) to the consuming API.agent-server.test.ts(150 passed),session-log-writer.test.ts+question-relay.test.ts(87 passed),claude-agent.task-notification.test.ts(2 passed),tsc --noEmit,biome check.Automatic notifications