/** * Collaborative Debugging Session — parallel multi-agent debugging on the same problem. * * Architecture: * - BugHunter, RefactorPlanner, and Critic run in parallel on shared file snapshots. * - Findings flow through the FleetBus via structured events: bug.found → refactor.plan → critic.evaluation. * - The Director acts as ResultRouter, collecting outputs and routing them to dependents. * - A shared scratchpad stores intermediate results so agents can read each other's * conclusions without needing each other's full transcripts. * * Flow: * 1. Director.spawnCollab() creates a CollabSession with a SharedFileSnapshot. * 2. All three agents are spawned simultaneously and receive the same file snapshot. * 3. BugHunter emits bug.found events → Director routes to RefactorPlanner. * 4. RefactorPlanner subscribes to bug.found and emits refactor.plan events. * 5. Critic subscribes to both bug.found and refactor.plan and emits critic.evaluation. * 6. Director collects all results and produces a structured CollabDebugReport. * * Timeout and cancellation: * - CollabSession agents report budget threshold events to the Director via fleet events. * - The Director's collabAlert() handler receives warnings for timeout/iteration/tool_call * thresholds and can decide to cancel the session or let it continue. * - Director.cancelCollabSession() sends director.cancel_collab to all collab agents, * causing them to finish early with a 'cancelled' status in the report. * - The Director reads /btw notes via getLeaderBtwNotes() and can inject them into * collab agents via task context before making cancellation decisions. */ import { EventEmitter } from 'node:events'; import type { CollabDirectorHost } from './collab-director-host.js'; /** * Default maximum number of files a collab_debug session may target. * Each of the three agents (BugHunter, RefactorPlanner, Critic) receives * the full file snapshot as context — a large target causes token overflow * and timeout failures. Keep this low (20-30) for reliable sessions. * Used when neither `maxTargetFiles` nor `contextWindow` is provided. */ export declare const DEFAULT_MAX_TARGET_FILES = 30; /** * Alert levels the Director can emit when a collab session needs attention. * These flow through the FleetBus so the host can display them in the UI. */ export declare enum DirectorAlertLevel { /** The agent is still making progress but has hit a soft budget limit. */ WARNING = "warning", /** The agent has hit a hard limit and the session cannot continue. */ CRITICAL = "critical", /** The Director has decided to cancel the session (user request or policy). */ CANCELLED = "cancelled" } export interface DirectorAlert { sessionId: string; subagentId: string; role: string; level: DirectorAlertLevel; /** Human-readable message for UI/logs */ message: string; /** Budget kind that triggered this alert, if any */ budgetKind?: 'timeout' | 'idle_timeout' | 'iterations' | 'tool_calls' | 'tokens' | 'cost' | undefined; /** Elapsed ms at time of alert */ elapsedMs?: number | undefined; /** Limit that was hit */ limit?: number | undefined; /** /btw notes the director has collected (may be empty) */ btwNotes?: string[] | undefined; } /** * Immutable snapshot of target files at the start of a collab session. * All agents in the session read from this snapshot — they see the same baseline. */ export interface SharedFileSnapshot { id: string; createdAt: string; files: SharedFileEntry[]; } export interface SharedFileEntry { path: string; content: string; language?: string | undefined; snapshotMtimeMs?: number | undefined; snapshotSizeBytes?: number | undefined; } /** * Bug finding emitted by BugHunter and consumed by RefactorPlanner + Critic. */ export interface BugFinding { id: string; type: string; severity: 'critical' | 'high' | 'medium' | 'low'; location: { file: string; line: number; }; description: string; suggestedFix?: string | undefined; } /** * Refactoring plan emitted by RefactorPlanner, consuming BugFinding(s). */ export interface RefactorPlan { id: string; basedOnBugIds: string[]; phases: RefactorPhase[]; riskScore: 'low' | 'medium' | 'high'; estimatedChangeCount: number; rollbackStrategy: string; } /** One phase within a refactor plan. */ export interface RefactorPhase { number: number; title: string; tasks: string[]; risk: 'low' | 'medium' | 'high'; } /** * Critic evaluation of a bug finding or refactor plan. */ export interface CriticEvaluation { id: string; subjectType: 'bug_finding' | 'refactor_plan'; subjectId: string; score: number; verdict: 'approve' | 'needs_revision' | 'reject'; strengths: string[]; weaknesses: string[]; concerns: CriticConcern[]; } export interface CriticConcern { description: string; location?: { file: string | undefined; line: number; }; severity: 'blocking' | 'advisory'; } /** * Full structured report produced when a CollabSession resolves. */ export interface CollabDebugReport { sessionId: string; startedAt: string; completedAt: string; targetPaths: string[]; /** How the session ended. 'completed' = all agents finished normally. * 'cancelled' = Director called cancelCollabSession(). * 'timeout' = session-level timeout elapsed before all agents finished. * 'critical_alert' = Director escalated a warning to a cancel decision. */ disposition: 'completed' | 'cancelled' | 'timeout' | 'critical_alert'; bugs: BugFinding[]; refactorPlans: RefactorPlan[]; evaluations: CriticEvaluation[]; /** Alerts that were raised during the session (may be empty). */ alerts: DirectorAlert[]; /** Files modified after the initial static snapshot was captured. */ snapshotWarnings?: string[] | undefined; /** Overall verdict from the Critic across all evaluated subjects. */ overallVerdict: 'approve' | 'needs_revision' | 'reject'; /** Markdown-formatted summary for the director's context window. */ summary: string; } /** * Per-agent budget configuration for collab sessions. * Allows the caller (Director) to control the exact limits instead of * using hard-coded defaults that may not match the director's policy. */ export interface CollabBudgetConfig { maxIterations: number; maxToolCalls: number; timeoutMs: number; } /** * Budget overrides for specific roles in a collab session. * When a role is not present in the map, the default budget is used. */ export type CollabBudgetOverrides = Partial>; /** * Emitted by a collab agent when it hits a soft budget limit. * The Director's fleet handler receives this and calls collabAlert(). */ export interface CollabBudgetWarningPayload { sessionId: string; role: string; kind: 'timeout' | 'idle_timeout' | 'iterations' | 'tool_calls' | 'tokens' | 'cost'; used: number; limit: number; timeoutMs?: number | undefined; elapsedMs: number; } /** * Emitted by the Director to cancel all agents in a collab session. * CollabSession listens for this and causes its agent pool to finish early. */ export interface DirectorCancelCollabPayload { sessionId: string; reason: string; cancelledAt: string; } export interface CollabSessionOptions { /** Paths to scan — used to build the SharedFileSnapshot. */ targetPaths: string[]; /** Files already read and snapshot. When provided, snapshot is skipped. */ prebuiltSnapshot?: SharedFileSnapshot | undefined; /** Max time to wait for the session to resolve (ms). Default: 10 min. */ timeoutMs?: number | undefined; /** * Maximum number of files to include in the snapshot. * - If set explicitly: use this value (hard override). * - If `contextWindow` is set: calculate dynamically from estimated token budget. * - If neither: use `DEFAULT_MAX_TARGET_FILES` (30). */ maxTargetFiles?: number | undefined; /** * Context window size (in tokens) of the model running the subagents. * When provided and `maxTargetFiles` is not set, the limit is computed * dynamically: `floor((contextWindow * 0.4) / AVG_TOKENS_PER_FILE)`. * If not provided, `DEFAULT_MAX_TARGET_FILES` is used as the fallback. */ contextWindow?: number | undefined; /** * Budget overrides per role. When provided, these override the hard-coded * defaults so the Director can enforce fleet-wide budget policy. * Keys must match role names: 'bug-hunter', 'refactor-planner', 'critic'. */ budgetOverrides?: CollabBudgetOverrides | undefined; /** * Called by the Director when a collab agent hits a soft budget limit. * The Director uses this to decide whether to cancel the session or extend. * Return 'cancel' to stop the session immediately; 'extend' to continue * with the agent's proposed new limits; 'ignore' to let the default * auto-extend logic handle it. */ onBudgetWarning?: ((alert: DirectorAlert) => 'cancel' | 'extend' | 'ignore') | undefined; } export declare class CollabSession extends EventEmitter { readonly sessionId: string; readonly options: CollabSessionOptions; readonly snapshot: SharedFileSnapshot; private readonly director; private readonly fleetBus; private readonly subagentIds; private readonly bugs; private readonly plans; private readonly evaluations; private readonly disposers; private settled; private readonly timeoutMs; private cancelled; private _raceResolved; private readonly alerts; private snapshotWarnings; /** Tracks tool call counts per subagent for progress-based timeout decisions. */ private readonly progressBySubagent; /** Last tool call count when a timeout warning was handled. */ private readonly lastTimeoutProgress; /** Session-level timeout timer handle (cleared on cancel or natural completion). */ private _timeoutTimer?; constructor(director: CollabDirectorHost, fleetBus: import('./fleet-bus.js').FleetBus, options: CollabSessionOptions); get id(): string; getSessionAlerts(): DirectorAlert[]; isCancelled(): boolean; /** * Snapshot of role → subagentId map. The Director calls coordinator.stop() * for each agent when cancelling the session, using this map to enumerate * all three collab agents. */ getSubagentIds(): ReadonlyMap; /** * Returns the effective file limit for this session. * Priority: explicit `maxTargetFiles` > dynamic from `contextWindow` > `DEFAULT_MAX_TARGET_FILES`. */ effectiveFileLimit(): number; buildSnapshot(): Promise; /** * Cancel the session. Emits director.cancel_collab on the FleetBus so all * collab agents finish early. The session-level timeout timer is also cleared. * Safe to call multiple times (idempotent after first call). */ cancel(reason?: string): void; start(): Promise; private parseAndEmit; private extractJsonObjects; private budgetForRole; private spawnAgent; private buildBugHunterTask; private buildRefactorPlannerTask; private buildCriticTask; private wireFleetBus; private roleFromSubagentId; private assembleReport; private checkSnapshotFreshness; private buildMarkdownSummary; private cleanup; } //# sourceMappingURL=collab-debug.d.ts.map