/** * group-join.ts — Enterprise Group Join Manager * * Manages fixed background agent completion notifications with: * - Event-driven state changes (for dashboard/UI observability) * - Delivery retry with exponential backoff * - Partial delivery strategies (all-or-nothing vs. progressive) * - Health monitoring and timeout escalation * - Metrics collection * * Unlike SwarmCoordinator (dynamic), groups are fixed at spawn time * and deliver consolidated notifications when all complete (or timeout). */ import type { AgentRecord } from "./types.js"; export type DeliveryCallback = (records: AgentRecord[], partial: boolean, meta?: GroupDeliveryMeta) => void; export interface GroupDeliveryMeta { groupId: string; totalAgents: number; completedAgents: number; timedOut: boolean; durationMs: number; retryAttempt?: number; } export type GroupEvent = { type: "agent:completed"; agentId: string; timestamp: number; } | { type: "agent:timeout"; agentId: string; timestamp: number; } | { type: "delivery:attempt"; records: AgentRecord[]; partial: boolean; attempt: number; timestamp: number; } | { type: "delivery:success"; records: AgentRecord[]; partial: boolean; timestamp: number; } | { type: "delivery:failed"; error: string; attempt: number; timestamp: number; } | { type: "group:created"; timestamp: number; } | { type: "group:disposed"; timestamp: number; }; export interface GroupConfig { groupId: string; agentIds: string[]; /** Timeout after first completion (ms). Default: 30s. */ timeout?: number; /** Shorter timeout for stragglers after partial delivery (ms). Default: 15s. */ stragglerTimeout?: number; /** Max retries for delivery callback failure. Default: 3. */ maxRetries?: number; /** Backoff multiplier for retries. Default: 2. */ retryBackoff?: number; /** If true, deliver progressively as agents complete. Default: false (all-or-nothing). */ progressiveDelivery?: boolean; /** Callback for group lifecycle events. */ onEvent?: (groupId: string, event: GroupEvent) => void; } export declare class GroupJoinManager { private groups; private agentToGroup; private deliverCb; private defaultGroupTimeout?; constructor(deliverCb: DeliveryCallback, groupTimeout?: number); /** Register a group with full configuration. */ registerGroup(config: GroupConfig): void; /** Legacy: register a group of agent IDs. */ registerGroup(groupId: string, agentIds: string[]): void; /** * Called when an agent completes. * Returns: * - 'pass' — agent is not grouped, caller should send individual nudge * - 'held' — result held, waiting for group completion * - 'delivered' — this completion triggered the group notification */ onAgentComplete(record: AgentRecord): "delivered" | "held" | "pass"; /** * Mark an agent as timed out / failed. */ onAgentTimeout(agentId: string): boolean; private onTimeout; private deliver; private cleanupGroup; private emit; /** Check if an agent is in a group. */ isGrouped(agentId: string): boolean; /** Get group info for dashboard. */ getGroupInfo(groupId: string): { total: number; completed: number; delivered: boolean; isStraggler: boolean; } | undefined; listGroups(): string[]; dispose(): void; }