/**
 * Queue Processor Service
 *
 * Processes messages from the queue one-at-a-time. Dequeues the next message,
 * delivers it to the orchestrator via AgentRegistrationService using a
 * fire-and-forget pattern. Responses are handled asynchronously by the
 * orchestrator through reply-* skills (reply-slack, reply-chat, reply-gchat).
 *
 * #239: Force-delivered user messages (Slack/web chat) are tracked in a
 * pending-ack list. When the agent returns to prompt, the PTY output is
 * checked for evidence the message was processed. If not found, the message
 * is re-delivered to prevent silent loss.
 *
 * @module services/messaging/queue-processor
 */
import { EventEmitter } from 'events';
import { MessageQueueService } from './message-queue.service.js';
import { ResponseRouterService } from './response-router.service.js';
import { AgentRegistrationService } from '../agent/agent-registration.service.js';
import { type RuntimeType } from '../../constants.js';
import type { ThreadStatusQueueService } from './thread-status-queue.service.js';
/**
 * Entry in the pending-ack list for force-delivered user messages.
 * Tracks all information needed to verify or redeliver the message.
 */
export interface PendingAckEntry {
    /** Unique message ID */
    messageId: string;
    /** Conversation ID used as a fingerprint to detect processing in PTY output */
    conversationId: string;
    /** The formatted delivery content (for redelivery) */
    deliveryContent: string;
    /** Target session the message was delivered to */
    targetSession: string;
    /** Runtime type of the target agent */
    runtimeType: RuntimeType;
    /** Timestamp when force-delivered */
    deliveredAt: number;
    /** Number of redelivery attempts so far */
    retryCount: number;
    /** The original queued message (for markCompleted / markFailed / routeResponse) */
    originalMessage: import('../../types/messaging.types.js').QueuedMessage;
}
export declare class QueueProcessorService extends EventEmitter {
    private logger;
    private queueService;
    private responseRouter;
    private agentRegistrationService;
    private running;
    private processing;
    private processNextTimeout;
    /** Set to true when an early-return path has already scheduled the next run. */
    private nextAlreadyScheduled;
    /**
     * Tracks message IDs that were successfully delivered to an agent.
     * Prevents duplicate delivery when the queue requeues a message that
     * the agent has already received and started processing.
     * Entries are purged after DEDUP_TTL_MS to prevent memory leaks.
     */
    private deliveredMessageIds;
    /** Timer for periodic cleanup of stale dedup entries */
    private dedupCleanupTimer;
    /** Timer for periodic cleanup of stale pending-ack entries */
    private pendingAckCleanupTimer;
    /**
     * #239: Tracks force-delivered user messages awaiting acknowledgment.
     * When a user message is force-delivered (agent not at prompt), it is
     * added here instead of being marked completed. On the next successful
     * waitForAgentReady (agent returns to prompt), the PTY output is checked
     * for evidence that each pending message was actually processed.
     */
    private pendingAckMessages;
    /** Thread status queue for tracking message lifecycle across restarts */
    private threadStatusQueue;
    /**
     * Optional Task Pool routing callback. When set, task-assignment messages
     * (content starting with "[TASK]") are routed through the Task Pool before
     * delivery, allowing the Reconciler to manage assignment lifecycle.
     */
    private taskPoolRouter;
    constructor(queueService: MessageQueueService, responseRouter: ResponseRouterService, agentRegistrationService: AgentRegistrationService);
    /**
     * Set the thread status queue service for tracking message delivery lifecycle.
     *
     * @param service - The ThreadStatusQueueService instance
     */
    setThreadStatusQueue(service: ThreadStatusQueueService): void;
    /**
     * Set the Task Pool routing callback.
     * When provided, messages with "[TASK]" prefix are offered to the Task Pool
     * before standard delivery. If the callback returns true, the message is
     * considered routed and delivery is skipped.
     *
     * @param router - Async callback that returns true if the message was routed to the pool
     */
    setTaskPoolRouter(router: (messageContent: string, targetSession: string) => Promise<boolean>): void;
    /**
     * Start the processor. Listens to queue 'enqueued' events and
     * triggers processing.
     */
    start(): void;
    /**
     * Stop the processor. Clears timers and removes listeners.
     */
    stop(): void;
    /**
     * Check if the processor is currently running.
     *
     * @returns True if running
     */
    isRunning(): boolean;
    /**
     * Check if a message is currently being processed.
     *
     * @returns True if processing
     */
    isProcessingMessage(): boolean;
    /**
     * Handler for queue 'enqueued' events. Triggers processing if idle.
     */
    private onMessageEnqueued;
    /**
     * Schedule the next message processing after a delay.
     *
     * @param delayMs - Delay in milliseconds before processing
     */
    private scheduleProcessNext;
    /**
     * Process the next message in the queue.
     * This is the core processing loop.
     */
    private processNext;
    /**
     * Schedule processing of the next message if there are pending messages.
     * Uses INTER_MESSAGE_DELAY to avoid overwhelming the orchestrator.
     *
     * #218: Skip the inter-message delay when a user message is pending.
     * This ensures user messages (from Slack, web chat, etc.) are never
     * blocked behind the 500ms cooldown after system event delivery.
     */
    private scheduleNextIfPending;
    /**
     * Start periodic cleanup of stale entries in the delivered message dedup set.
     * Runs every DEDUP_TTL_MS and removes entries older than DEDUP_TTL_MS.
     */
    private startDedupCleanup;
    /**
     * Stop the periodic dedup cleanup timer.
     */
    private stopDedupCleanup;
    /**
     * Remove entries from the dedup set that are older than DEDUP_TTL_MS.
     */
    private purgeStaleDedup;
    /**
     * Get the number of tracked delivered message IDs (for testing).
     *
     * @returns Number of entries in the dedup set
     */
    getDeliveredMessageCount(): number;
    /**
     * Get the number of messages awaiting acknowledgment (for testing).
     *
     * @returns Number of entries in the pending-ack list
     */
    getPendingAckCount(): number;
    /**
     * Start periodic cleanup of stale pending-ack entries.
     * Runs at PENDING_ACK_TTL_MS intervals and fails entries that have exceeded
     * the TTL — prevents memory leaks if an agent crashes and never returns to prompt.
     */
    private startPendingAckCleanup;
    /**
     * Stop the periodic pending-ack cleanup timer.
     */
    private stopPendingAckCleanup;
    /**
     * Remove pending-ack entries that have exceeded the TTL.
     * Marks them as failed and routes error to the source so the user is notified.
     */
    private purgeExpiredPendingAcks;
    /**
     * Check if a pending-ack message's fingerprint appears in PTY output.
     *
     * Matches the full [CHAT:conversationId:fingerprint] or [GCHAT:conversationId:fingerprint]
     * prefix. The fingerprint (last 8 chars of messageId) distinguishes between different
     * messages in the same conversation/thread, preventing false-positive ack confirmations
     * when a user sends multiple messages in quick succession.
     *
     * Falls back to conversationId-only matching for messages delivered before the
     * fingerprint format was introduced (backward compat).
     *
     * @param output - Captured PTY output string
     * @param conversationId - The conversation ID to search for
     * @param messageId - The unique message ID (last 8 chars used as fingerprint)
     * @returns true if the message fingerprint was found
     */
    private isPendingAckInOutput;
    /**
     * #239: Flush pending-ack messages by verifying them against PTY output.
     *
     * Called when the agent returns to prompt (waitForAgentReady succeeds).
     * For each pending-ack entry:
     * - Captures the agent's recent PTY output
     * - Checks if the conversationId or CHAT prefix appears in the output
     * - If found → message was processed, mark completed
     * - If not found → message was swallowed, redeliver
     * - If max retries exceeded → mark failed
     *
     * @param sessionName - The agent session to check
     * @param runtimeType - Runtime type for redelivery
     */
    private flushPendingAcks;
}
//# sourceMappingURL=queue-processor.service.d.ts.map