fix: allow strategy self-triggers to dispatch in self-threads (by Wren)#417
Conversation
… trigger in self-threads resolveTriggeredAgents had an early return for self-threads (1 participant) that returned [] unless selfStudioTarget was set. This blocked strategy triggers (wren→wren session_resume) from ever dispatching, since the strategy group had no studioId and selfStudioTarget was false. Now session_resume and task_request messages trigger self even without a studio — these are inherently 'wake me up' signals (e.g., strategy kickoff) and should not be silently dropped. Co-Authored-By: Wren <noreply@anthropic.com>
conoremclaughlin
left a comment
There was a problem hiding this comment.
Changes requested — I found one remaining dispatch gap.
The resolver fix covers existing self-threads, but handleSendToInbox still has a separate new-thread branch that never calls resolveTriggeredAgents:
// New thread: trigger all recipients (exclude sender unless cross-studio self-message)
agentsToTrigger = allRecipients.filter((a) => selfStudioTarget || a !== senderAgentId);For a first session_resume strategy kickoff with senderAgentId === recipientAgentId and no recipientStudioId/slug, selfStudioTarget is false and the only recipient is filtered out. triggerOwnerAgent() can create exactly this first-use path via group.thread_key || strategy:${group.id}, so the kickoff message is inserted into a new self-thread but dispatchTrigger is still skipped until some later existing-thread retry/watchdog.
Please make the new-thread path apply the same actionable self-target rule (session_resume / task_request) or route new threads through the same resolver, and add a handleSendToInbox regression for a brand-new self-thread session_resume dispatching to the owner.
Validation run locally at head 6dd4364a:
git diff --check origin/main...HEADpassed- changed-file control-byte scan clean
yarn workspace @inklabs/api test src/mcp/tools/thread-handlers.test.ts src/mcp/tools/inbox-handlers.test.ts src/services/strategy.service.test.ts src/services/sessions/trigger-delivery.test.tspassed 152/152yarn workspace @inklabs/api type-checkstill fails only the known baselinechannels/gateway.tsJson typings andmcp/server.tsthiserror
…endToInbox The new-thread path had the same self-exclusion as the existing-thread path: it filtered out senderAgentId from trigger recipients unless selfStudioTarget was set. For the first strategy kickoff (no existing thread yet), this meant the trigger was never dispatched. Now session_resume and task_request allow self-trigger in both the new-thread and existing-thread paths. Co-Authored-By: Wren <noreply@anthropic.com>
conoremclaughlin
left a comment
There was a problem hiding this comment.
LGTM — the remaining new-thread dispatch gap is fixed.
Verified at head 006ef6e4:
handleSendToInboxnew-thread path now allows self-trigger for actionablesession_resume/task_requestmessages, covering first strategy kickoffs wheresenderAgentId === recipientAgentIdand no studio target is present.- Added regression for a brand-new self-thread
session_resumeprovingdispatchTriggeris called withtoAgentId: 'wren'. - Existing self-thread resolver coverage remains in place for existing-thread retries/watchdogs.
Validation run locally:
git diff --check origin/main...HEADpassed- changed-file control-byte scan clean
yarn workspace @inklabs/api test src/mcp/tools/thread-handlers.test.ts src/mcp/tools/inbox-handlers.test.ts src/services/strategy.service.test.ts src/services/sessions/trigger-delivery.test.ts src/mcp/tools/task-handlers.test.tspassed 244/244yarn workspace @inklabs/api type-checkstill fails only the known baselinechannels/gateway.tsJson typings andmcp/server.tsthiserror
GitHub checks at review time: GitGuardian and Integration Runtime green; Unit Tests / Integration DB still in progress.
Summary
resolveTriggeredAgentshad an early return for self-threads (1 participant) that returned[]unlessselfStudioTargetwas set. Strategy triggers (wren→wrensession_resume) hit this path because the group had nostudioId, so the trigger was silently swallowed —dispatchTriggerwas never called.session_resume,task_request). These are inherently "wake me up" signals and should not be dropped.shouldSkipSpawn), but the trigger wasn't even dispatched. Both fixes are needed for strategy self-triggers to work end-to-end.Files changed
packages/api/src/mcp/tools/thread-handlers.ts— self-thread trigger resolution now allows actionable typespackages/api/src/mcp/tools/thread-handlers.test.ts— 3 new test cases (session_resume, task_request, notification) for self-thread behaviorTest plan
resolveTriggeredAgentstest updated: plain self-messages still return[]session_resumein self-thread returns[senderAgentId]task_requestin self-thread returns[senderAgentId]notificationin self-thread still returns[]🤖 Generated with Claude Code