MCPcopy
hub / github.com/coder/mux / AgentSession

Class AgentSession

src/node/services/agentSession.ts:340–6001  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

338}
339
340export class AgentSession {
341 private readonly workspaceId: string;
342 private readonly config: Config;
343 private readonly historyService: HistoryService;
344 private readonly aiService: AIService;
345 private readonly initStateManager: InitStateManager;
346 private readonly backgroundProcessManager: BackgroundProcessManager;
347 private readonly workspaceGoalService?: WorkspaceGoalService;
348 private readonly keepBackgroundProcesses: boolean;
349 private readonly onPostCompactionStateChange?: () => void;
350 private readonly emitter = new EventEmitter();
351 private readonly aiListeners: Array<{ event: string; handler: (...args: unknown[]) => void }> =
352 [];
353 private readonly initListeners: Array<{ event: string; handler: (...args: unknown[]) => void }> =
354 [];
355 private disposed = false;
356 private turnPhase: TurnPhase = TurnPhase.IDLE;
357 private activePreparedTurnAbortController: AbortController | null = null;
358 // When true, stream-end skips auto-flushing queued messages so an edit can truncate first.
359 private deferQueuedFlushUntilAfterEdit = false;
360 // A tool-end queued message should preempt the current turn after the next real tool result.
361 // We keep this set until the requested stream-abort arrives, so a re-queued replacement
362 // can still dispatch even if the original queued draft was edited while the abort was in flight.
363 private queuedToolEndAbortInFlight = false;
364
365 private idleWaiters: Array<() => void> = [];
366 private pendingExternalManualFollowUps = 0;
367 private readonly messageQueue = new MessageQueue();
368 private readonly compactionHandler: CompactionHandler;
369 private readonly compactionMonitor: CompactionMonitor;
370
371 private autoRetryStarting = false;
372 private readonly retryManager: RetryManager;
373 private lastAutoRetryResumeRequest?: AutoRetryResumeRequest;
374 /** Startup recovery should run once per session to avoid duplicate retry timers on reconnect. */
375 private startupRecoveryScheduled = false;
376 private startupRecoveryPromise: Promise<void> | null = null;
377 private startupAutoRetryCheckScheduled = false;
378 private startupAutoRetryCheckPromise: Promise<void> | null = null;
379 private startupAutoRetryHistoryReadFailureCount = 0;
380 private startupAutoRetryDeferredRetryDelayMs = 0;
381 private autoRetryEnabledPreference: boolean | null = null;
382 private legacyAutoRetryEnabledHint: boolean | null = null;
383 private startupAutoRetryAbandon: { reason: string; userMessageId?: string } | null = null;
384
385 /** Latest context-usage snapshot used for on-send compaction checks. */
386 private lastUsageState?: AutoCompactionUsageState;
387
388 /** Prevent duplicate mid-stream compaction interrupts while we are already transitioning. */
389 private midStreamCompactionPending = false;
390
391 /** Tracks file state for detecting external edits. */
392 private readonly fileChangeTracker = new FileChangeTracker();
393
394 /**
395 * Track turns since last post-compaction attachment injection.
396 * Start at max to trigger immediate injection on first turn after compaction.
397 */

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected