/**
 * Health Steward Service
 *
 * This service monitors agent health and detects stuck agents.
 * The Health Steward detects problematic agents and takes corrective action.
 *
 * Key features:
 * - Detect agents with no output for configurable duration
 * - Detect agents with repeated errors
 * - Detect crashed agent processes
 * - Attempt to unstick agents
 * - Notify Director of issues
 * - Stop and reassign tasks from stuck agents
 *
 * TB-O24: Health Steward Implementation
 *
 * @module
 */
import type { ElementId, EntityId, Timestamp } from '@stoneforge/core';
import type { QuarryAPI } from '@stoneforge/quarry';
import type { AgentRole } from '../types/agent.js';
import type { AgentRegistry } from './agent-registry.js';
import type { SessionManager } from '../runtime/session-manager.js';
import type { TaskAssignmentService } from './task-assignment-service.js';
import type { DispatchService } from './dispatch-service.js';
/**
 * Health issue types that the steward can detect
 */
export type HealthIssueType = 'no_output' | 'repeated_errors' | 'process_crashed' | 'high_error_rate' | 'session_stale' | 'unresponsive';
/**
 * All valid health issue types
 */
export declare const HealthIssueTypes: readonly ["no_output", "repeated_errors", "process_crashed", "high_error_rate", "session_stale", "unresponsive"];
/**
 * Type guard for HealthIssueType
 */
export declare function isHealthIssueType(value: unknown): value is HealthIssueType;
/**
 * Severity levels for health issues
 */
export type HealthIssueSeverity = 'warning' | 'error' | 'critical';
/**
 * All valid severity levels
 */
export declare const HealthIssueSeverities: readonly ["warning", "error", "critical"];
/**
 * Type guard for HealthIssueSeverity
 */
export declare function isHealthIssueSeverity(value: unknown): value is HealthIssueSeverity;
/**
 * Action types the health steward can take
 */
export type HealthAction = 'monitor' | 'send_ping' | 'restart' | 'notify_director' | 'reassign_task' | 'escalate';
/**
 * All valid health actions
 */
export declare const HealthActions: readonly ["monitor", "send_ping", "restart", "notify_director", "reassign_task", "escalate"];
/**
 * Type guard for HealthAction
 */
export declare function isHealthAction(value: unknown): value is HealthAction;
/**
 * A detected health issue
 */
export interface HealthIssue {
    /** Unique issue ID */
    readonly id: string;
    /** Agent ID with the issue */
    readonly agentId: EntityId;
    /** Agent name */
    readonly agentName: string;
    /** Agent role */
    readonly agentRole: AgentRole;
    /** Type of issue detected */
    readonly issueType: HealthIssueType;
    /** Severity of the issue */
    readonly severity: HealthIssueSeverity;
    /** Human-readable description */
    readonly description: string;
    /** When the issue was first detected */
    readonly detectedAt: Timestamp;
    /** When the issue was last seen */
    readonly lastSeenAt: Timestamp;
    /** Number of times this issue has been seen */
    readonly occurrenceCount: number;
    /** Current session ID (if any) */
    readonly sessionId?: string;
    /** Current task ID (if any) */
    readonly taskId?: ElementId;
    /** Additional context data */
    readonly context?: Record<string, unknown>;
}
/**
 * Result of an action taken on an issue
 */
export interface HealthActionResult {
    /** Whether the action succeeded */
    readonly success: boolean;
    /** The action taken */
    readonly action: HealthAction;
    /** The issue that was addressed */
    readonly issueId: string;
    /** Description of what happened */
    readonly message: string;
    /** When the action was taken */
    readonly actionTakenAt: Timestamp;
    /** New task ID if task was reassigned */
    readonly newTaskId?: ElementId;
    /** New agent ID if task was reassigned */
    readonly newAgentId?: EntityId;
    /** Error if action failed */
    readonly error?: string;
}
/**
 * Session status values for health checks
 */
export type HealthSessionStatus = 'idle' | 'starting' | 'running' | 'suspended' | 'terminating' | 'terminated';
/**
 * Agent health status summary
 */
export interface AgentHealthStatus {
    /** Agent ID */
    readonly agentId: EntityId;
    /** Agent name */
    readonly agentName: string;
    /** Agent role */
    readonly agentRole: AgentRole;
    /** Whether the agent is healthy */
    readonly isHealthy: boolean;
    /** Current health issues (if any) */
    readonly issues: readonly HealthIssue[];
    /** Last activity timestamp */
    readonly lastActivityAt?: Timestamp;
    /** Last health check timestamp */
    readonly lastHealthCheckAt?: Timestamp;
    /** Current session status */
    readonly sessionStatus?: HealthSessionStatus;
    /** Current task (if any) */
    readonly currentTaskId?: ElementId;
    /** Recent error count (last N minutes) */
    readonly recentErrorCount: number;
    /** Recent output count (last N minutes) */
    readonly recentOutputCount: number;
}
/**
 * Configuration for the Health Steward service
 */
export interface HealthStewardConfig {
    /** How long without output before considering stuck (ms). Default: 5 minutes */
    readonly noOutputThresholdMs?: number;
    /** How many errors in the window before alerting. Default: 5 */
    readonly errorCountThreshold?: number;
    /** Time window for counting errors (ms). Default: 10 minutes */
    readonly errorWindowMs?: number;
    /** How long a session can be stale before alerting (ms). Default: 15 minutes */
    readonly staleSessionThresholdMs?: number;
    /** Interval between health checks (ms). Default: 1 minute */
    readonly healthCheckIntervalMs?: number;
    /** Number of ping attempts before escalating. Default: 3 */
    readonly maxPingAttempts?: number;
    /** Whether to auto-restart stuck agents. Default: true */
    readonly autoRestart?: boolean;
    /** Whether to auto-reassign from crashed agents. Default: true */
    readonly autoReassign?: boolean;
    /** Whether to notify Director on issues. Default: true */
    readonly notifyDirector?: boolean;
    /** Entity ID of the health steward (for creating messages) */
    readonly stewardEntityId?: EntityId;
    /** Maximum issues to track per agent. Default: 10 */
    readonly maxIssuesPerAgent?: number;
}
/**
 * Result of a health check run
 */
export interface HealthCheckResult {
    /** When the check was run */
    readonly timestamp: Timestamp;
    /** Total agents checked */
    readonly agentsChecked: number;
    /** Agents with issues */
    readonly agentsWithIssues: number;
    /** New issues detected */
    readonly newIssues: readonly HealthIssue[];
    /** Resolved issues (no longer present) */
    readonly resolvedIssues: readonly string[];
    /** Actions taken */
    readonly actionsTaken: readonly HealthActionResult[];
    /** Duration of the check in ms */
    readonly durationMs: number;
}
/**
 * Statistics about health steward operations
 */
export interface HealthStewardStats {
    /** Total health checks run */
    readonly totalChecks: number;
    /** Total issues detected */
    readonly totalIssuesDetected: number;
    /** Total issues resolved */
    readonly totalIssuesResolved: number;
    /** Total actions taken */
    readonly totalActionsTaken: number;
    /** Successful actions */
    readonly successfulActions: number;
    /** Failed actions */
    readonly failedActions: number;
    /** Currently active issues */
    readonly activeIssues: number;
    /** Agents currently being monitored */
    readonly monitoredAgents: number;
}
/**
 * Internal tracking for agent activity
 */
export interface AgentActivityTracker {
    /** Agent ID */
    readonly agentId: EntityId;
    /** Last output timestamp */
    lastOutputAt?: Timestamp;
    /** Last error timestamp */
    lastErrorAt?: Timestamp;
    /** Error timestamps in the window */
    errorTimestamps: Timestamp[];
    /** Output timestamps in the window */
    outputTimestamps: Timestamp[];
    /** Last ping attempt */
    lastPingAt?: Timestamp;
    /** Ping attempt count */
    pingAttempts: number;
    /** Last health check */
    lastHealthCheckAt?: Timestamp;
}
/**
 * Health Steward Service interface for monitoring agent health.
 *
 * The service provides methods for:
 * - Running health checks on agents
 * - Detecting stuck or problematic agents
 * - Taking corrective actions
 * - Tracking health issues
 */
export interface HealthStewardService {
    /**
     * Runs a health check on all running agents.
     *
     * @returns Health check result with issues and actions
     */
    runHealthCheck(): Promise<HealthCheckResult>;
    /**
     * Runs a health check on a specific agent.
     *
     * @param agentId - The agent to check
     * @returns Agent health status
     */
    checkAgent(agentId: EntityId): Promise<AgentHealthStatus>;
    /**
     * Gets all agents with their current health status.
     *
     * @returns Array of agent health statuses
     */
    getAllAgentHealth(): Promise<readonly AgentHealthStatus[]>;
    /**
     * Gets all active health issues.
     *
     * @returns Array of active issues
     */
    getActiveIssues(): readonly HealthIssue[];
    /**
     * Gets issues for a specific agent.
     *
     * @param agentId - The agent to get issues for
     * @returns Array of issues for the agent
     */
    getIssuesForAgent(agentId: EntityId): readonly HealthIssue[];
    /**
     * Resolves an issue (marks it as handled).
     *
     * @param issueId - The issue ID to resolve
     * @returns Whether the issue was resolved
     */
    resolveIssue(issueId: string): boolean;
    /**
     * Clears all resolved issues from history.
     */
    clearResolvedIssues(): void;
    /**
     * Takes action on a detected issue.
     *
     * @param issueId - The issue to act on
     * @param action - The action to take (optional, will auto-determine if not provided)
     * @returns Result of the action
     */
    takeAction(issueId: string, action?: HealthAction): Promise<HealthActionResult>;
    /**
     * Sends a ping to an agent to check responsiveness.
     *
     * @param agentId - The agent to ping
     * @returns Whether the agent responded
     */
    pingAgent(agentId: EntityId): Promise<boolean>;
    /**
     * Attempts to unstick an agent by restarting its session.
     *
     * @param agentId - The agent to unstick
     * @returns Whether the restart succeeded
     */
    restartAgent(agentId: EntityId): Promise<boolean>;
    /**
     * Notifies the Director about an agent issue.
     *
     * @param issue - The issue to report
     * @returns Whether notification was sent
     */
    notifyDirector(issue: HealthIssue): Promise<boolean>;
    /**
     * Reassigns a task from a stuck agent to another available agent.
     *
     * @param agentId - The stuck agent
     * @param taskId - The task to reassign
     * @returns Result with new assignment info
     */
    reassignTask(agentId: EntityId, taskId: ElementId): Promise<{
        success: boolean;
        newAgentId?: EntityId;
        error?: string;
    }>;
    /**
     * Records agent output (call this when agent produces output).
     *
     * @param agentId - The agent that produced output
     */
    recordOutput(agentId: EntityId): void;
    /**
     * Records an agent error (call this when agent encounters an error).
     *
     * @param agentId - The agent that had an error
     * @param error - The error message
     */
    recordError(agentId: EntityId, error?: string): void;
    /**
     * Records a process crash (call this when agent process exits unexpectedly).
     *
     * @param agentId - The agent that crashed
     * @param exitCode - The exit code
     */
    recordCrash(agentId: EntityId, exitCode?: number): void;
    /**
     * Starts the health monitoring service.
     * Begins periodic health checks based on config.
     */
    start(): void;
    /**
     * Stops the health monitoring service.
     */
    stop(): void;
    /**
     * Whether the service is currently running.
     */
    isRunning(): boolean;
    /**
     * Gets statistics about health steward operations.
     */
    getStats(): HealthStewardStats;
    /**
     * Subscribe to health steward events.
     */
    on(event: 'issue:detected', listener: (issue: HealthIssue) => void): void;
    on(event: 'issue:resolved', listener: (issueId: string) => void): void;
    on(event: 'action:taken', listener: (result: HealthActionResult) => void): void;
    on(event: 'check:completed', listener: (result: HealthCheckResult) => void): void;
    /**
     * Unsubscribe from events.
     */
    off(event: string, listener: (...args: unknown[]) => void): void;
}
/**
 * Implementation of the Health Steward Service.
 */
export declare class HealthStewardServiceImpl implements HealthStewardService {
    private readonly _api;
    private readonly config;
    private readonly agentRegistry;
    private readonly sessionManager;
    private readonly taskAssignment;
    private readonly dispatchService;
    private readonly emitter;
    private running;
    private checkInterval?;
    private issueCounter;
    private readonly activityTrackers;
    private readonly activeIssues;
    private readonly resolvedIssueIds;
    private totalChecks;
    private totalIssuesDetected;
    private totalIssuesResolved;
    private totalActionsTaken;
    private successfulActions;
    private failedActions;
    constructor(api: QuarryAPI, agentRegistry: AgentRegistry, sessionManager: SessionManager, taskAssignment: TaskAssignmentService, dispatchService: DispatchService, config?: HealthStewardConfig);
    runHealthCheck(): Promise<HealthCheckResult>;
    checkAgent(agentId: EntityId): Promise<AgentHealthStatus>;
    getAllAgentHealth(): Promise<readonly AgentHealthStatus[]>;
    getActiveIssues(): readonly HealthIssue[];
    getIssuesForAgent(agentId: EntityId): readonly HealthIssue[];
    resolveIssue(issueId: string): boolean;
    clearResolvedIssues(): void;
    takeAction(issueId: string, action?: HealthAction): Promise<HealthActionResult>;
    pingAgent(agentId: EntityId): Promise<boolean>;
    restartAgent(agentId: EntityId): Promise<boolean>;
    notifyDirector(issue: HealthIssue): Promise<boolean>;
    reassignTask(agentId: EntityId, taskId: ElementId): Promise<{
        success: boolean;
        newAgentId?: EntityId;
        error?: string;
    }>;
    recordOutput(agentId: EntityId): void;
    recordError(agentId: EntityId, _error?: string): void;
    recordCrash(agentId: EntityId, exitCode?: number): void;
    start(): void;
    stop(): void;
    isRunning(): boolean;
    getStats(): HealthStewardStats;
    on(event: 'issue:detected', listener: (issue: HealthIssue) => void): void;
    on(event: 'issue:resolved', listener: (issueId: string) => void): void;
    on(event: 'action:taken', listener: (result: HealthActionResult) => void): void;
    on(event: 'check:completed', listener: (result: HealthCheckResult) => void): void;
    off(event: string, listener: (...args: unknown[]) => void): void;
    private getRunningAgents;
    private getOrCreateTracker;
    private createIssue;
    private createUnhealthyStatus;
    private determineSeverity;
    private getIssueDescription;
    private determineAction;
    private getRecommendedActionDescription;
    private findExistingIssue;
    private issueStillApplies;
    private countRecentEvents;
    private pruneTimestamps;
    private getTimestampMs;
}
/**
 * Creates a HealthStewardService instance
 */
export declare function createHealthStewardService(api: QuarryAPI, agentRegistry: AgentRegistry, sessionManager: SessionManager, taskAssignment: TaskAssignmentService, dispatchService: DispatchService, config?: HealthStewardConfig): HealthStewardService;
//# sourceMappingURL=health-steward-service.d.ts.map