feat(agent): deliver child results to parent mailboxes - #1316
feat(agent): deliver child results to parent mailboxes#1316sentry-junior[bot] wants to merge 5 commits into
Conversation
Persist terminal agent-invocation parent notification state and append one idempotent parent-mailbox result so idle parents can resume from durable child work. Heartbeat repair retries pending parent delivery, and Slack synthetic result messages force a parent turn without depending on resource-event subscriptions. Fixes #878 Refs #883 Co-Authored-By: David Cramer <david@sentry.io>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Self-review against #878 / #883 after opening this.
The pending → append → notified outbox shape fits the shared conversation worker story: durable invocation state, stable parent mailbox identity, queue-as-wake, heartbeat repair. Keep that.
Two design holes before this should land:
-
Parent-result turns run as the synthetic system actor. Reply/resume treat
agent_invocation_resultlike a resource event (AGENT_INVOCATION_RESULT_SYSTEM_ACTOR). The invocation already stores the parent run'sactor+credentialContext, and #883 is explicit that child work must not broaden parent authority. Waking the parent under system credentials means tools/OAuth on that turn use the wrong principal, and bot-authored synthetic messages also pick updisabledFeatures: ["interactive-auth"]. Restore authority from the invocation (or another durable parent-turn reference) when handling the result, same spirit as dispatch routing restore. -
Slack synthetic delivery assumes
parentConversationIdisslack:channel:threadTs.createSlackAgentInvocationResultInboundMessageparses the parent id as a Slack conversation id. That matches ordinary Slack roots, but dispatch conversations areagent-dispatch:<id>(getDispatchConversationId), and production already wiresbindSpawnAgentonto the shared runner. Once experimental subagents are on, a dispatch parent that spawns will hard-fail parent delivery in the Slack builder and stayparentNotificationStatus: "pending"forever. Delivery needs to target the real parent conversation work identity, and only build Slack thread metadata when the parent is actually a Slack conversation — not by assuming the conversation id format.
Secondary: #878 asks for permanent notification failure to stay queryable. Today a permanent builder/destination mismatch just leaves pending and retries forever with no terminal failure visibility. Worth a durable failed/notified-failed state (or equivalent) once the two issues above are fixed.
I can fix these next on this branch unless you want a different authority model for parent-result turns.
Co-Authored-By: David Cramer <david@sentry.io>
Share one synthetic inbound builder with resource events, restore parent authority from the invocation, target non-Slack parents correctly, and terminalize permanent notification failures. Co-Authored-By: David Cramer <david@sentry.io>
Move parent-result delivery cases out of the oversized invocation work suite and cover permanent notification failure terminalization. Co-Authored-By: David Cramer <david@sentry.io>
Collapse duplicated dispatch parent-result handling into the shared worker path, drop unused synthetic builders/re-exports, and move behavior-focused parent delivery coverage into dedicated integration scenarios. Co-Authored-By: David Cramer <david@sentry.io> Co-Authored-By: David Cramer <david@sentry.io>
Summary
Durable parent-result delivery for terminal child agent invocations (#878 / #883).
parentNotificationStatus: pendingnotifiedfailed(queryable, no infinite retry)task-execution/synthetic-inbound.ts) without reusing resource-event subscriptionsactor+credentialContext), not a synthetic system principalagent-dispatch:*parents)Design notes
Resource events and agent-invocation results now share one durable mailbox wake shape (stable id, kind + reference, rendered text, optional Slack envelope). They still differ where they should:
parentConversationIdon invocationPolicy cleanup
createSlackAgentInvocationResultInboundMessage, permanent error wrapper, public render/build helpers)agent-invocation-parent-delivery.test.tsagent-dispatch-worksuite (pending wake + resume)Test plan
pnpm --filter @sentry/junior exec vitest run tests/integration/agent-invocation-work.test.ts(10/10)pnpm --filter @sentry/junior exec vitest run tests/integration/agent-invocation-parent-delivery.test.ts(3/3)pnpm --filter @sentry/junior exec vitest run tests/integration/agent-dispatch-work.test.ts(9/9)pnpm --filter @sentry/junior exec tsc -p tsconfig.json --noEmitFixes #878
Refs #883