MCPcopy Create free account
hub / github.com/Noumena-Network/code / getTeammateMailboxAttachments

Function getTeammateMailboxAttachments

src/utils/attachments.ts:3539–3776  ·  view source on GitHub ↗

* Get teammate mailbox attachments for agent swarm communication * Teammates are independent NCode sessions running in parallel (swarms), * not parent-child subagent relationships. * * This function checks two sources for messages: * 1. File-based mailbox (for messages that arrived between poll

(
  toolUseContext: ToolUseContext,
)

Source from the content-addressed store, hash-verified

3537 * allowing teammates to receive messages without waiting for the turn to end.
3538 */
3539async function getTeammateMailboxAttachments(
3540 toolUseContext: ToolUseContext,
3541): Promise<Attachment[]> {
3542 if (!isAgentSwarmsEnabled()) {
3543 return []
3544 }
3545 if ((process.env.NCODE_BUILD_MODE !== 'noumena' && process.env.USER_TYPE !== 'ant')) {
3546 return []
3547 }
3548
3549 // Get AppState early to check for team lead status
3550 const appState = toolUseContext.getAppState()
3551
3552 // Use agent name from helper (checks AsyncLocalStorage, then dynamicTeamContext)
3553 const envAgentName = getAgentName()
3554
3555 // Get team name (checks AsyncLocalStorage, dynamicTeamContext, then AppState)
3556 const teamName = getTeamName(appState.teamContext)
3557
3558 // Check if we're the team lead (uses shared logic from swarm utils)
3559 const teamLeadStatus = isTeamLead(appState.teamContext)
3560
3561 // Check if viewing a teammate's transcript (for in-process teammates)
3562 const viewedTeammate = getViewedTeammateTask(appState)
3563
3564 // Resolve agent name based on who we're VIEWING:
3565 // - If viewing a teammate, use THEIR name (to read from their mailbox)
3566 // - Otherwise use env var if set, or leader's name if we're the team lead
3567 let agentName = viewedTeammate?.identity.agentName ?? envAgentName
3568 if (!agentName && teamLeadStatus && appState.teamContext) {
3569 const leadAgentId = appState.teamContext.leadAgentId
3570 // Look up the lead's name from agents map (not the UUID)
3571 agentName = appState.teamContext.teammates[leadAgentId]?.name || 'team-lead'
3572 }
3573
3574 logForDebugging(
3575 `[SwarmMailbox] getTeammateMailboxAttachments called: envAgentName=${envAgentName}, isTeamLead=${teamLeadStatus}, resolved agentName=${agentName}, teamName=${teamName}`,
3576 )
3577
3578 // Only check inbox if running as an agent in a swarm or team lead
3579 if (!agentName) {
3580 logForDebugging(
3581 `[SwarmMailbox] Not checking inbox - not in a swarm or team lead`,
3582 )
3583 return []
3584 }
3585
3586 logForDebugging(
3587 `[SwarmMailbox] Checking inbox for agent="${agentName}" team="${teamName || 'default'}"`,
3588 )
3589
3590 // Check mailbox for unread messages (routes to in-process or file-based)
3591 // Filter out structured protocol messages (permission requests/responses, shutdown
3592 // messages, etc.) — these must be left unread for useInboxPoller to route to their
3593 // proper handlers (workerPermissions queue, sandbox queue, etc.). Without filtering,
3594 // attachment generation races with InboxPoller: whichever reads first marks all
3595 // messages as read, and if attachments wins, protocol messages get bundled as raw
3596 // LLM context text instead of being routed to their UI handlers.

Callers 1

getAttachmentsFunction · 0.85

Calls 15

isAgentSwarmsEnabledFunction · 0.85
getAgentNameFunction · 0.85
getTeamNameFunction · 0.85
isTeamLeadFunction · 0.85
getViewedTeammateTaskFunction · 0.85
readUnreadMessagesFunction · 0.85
isInProcessTeammateFunction · 0.85
isShutdownApprovedFunction · 0.85
unassignTeammateTasksFunction · 0.85

Tested by

no test coverage detected