import type { AIProviderRegistry, ChatAttachment, ChatDriverResult, ChatMessage } from '@genesislcap/foundation-ai';
import type { ActivityBus } from '../../channel/ai-activity-bus';
import type { AgentConfig } from '../../config/config';
import type { DiagnosticEntry } from '../../state/persistence/diagnostics';
import type { InteractionContext } from '../../types/interaction-context';
import type { AiDriver, AllAgentSummary } from '../ai-driver/ai-driver';
import { type TurnSnapshot } from '../chat-driver/chat-driver';
/**
 * Orchestrates multiple specialist agents. Sits between `FoundationAiAssistant`
 * and `ChatDriver`, classifying each user message and routing it to the right
 * specialist — each with its own focused system prompt, tools, and primer.
 *
 * @beta
 */
export declare class OrchestratingDriver extends EventTarget implements AiDriver {
    private readonly providerRegistry;
    private readonly agents;
    private readonly chatDriver;
    private readonly specialists;
    private readonly fallback?;
    private readonly maxHandoffs;
    private readonly classifierHistoryLength;
    private readonly classifierRetries;
    private readonly sessionKey;
    /**
     * Aborted on driver disposal. Threaded into `AgentLifecycleContext.signal`
     * so long-running `onActivate` work can bail if the session disconnects.
     */
    private readonly lifecycleAbortController;
    /**
     * Set by `cancel()` for the duration of a `sendMessage` run. Breaks the
     * handoff loop so we don't classify or start another agent turn after the
     * user stops. Reset at the start of each `sendMessage`.
     */
    private cancelled;
    /**
     * Sticky user pick from the picker (or the host's `setAgent` API). Only
     * changes on explicit user action. Survives flow completion: when a stateful
     * agent releases, the user-pin stays put and routing falls back to it on
     * the next turn.
     */
    private pinnedAgentName;
    /**
     * Transient flow lock — set when a stateful agent's `onActivate` fires,
     * cleared by `releaseActiveAgent`. While non-null, routing precedence goes
     * to this agent and the picker is locked. Independent of
     * `pinnedAgentName` so completing a flow doesn't wipe the user's sticky
     * choice.
     */
    private flowOwnerAgentName;
    /**
     * Per-agent restored state for a rehydrated session, keyed by agent name.
     * Primed by the host on restore; each entry is passed to that agent's
     * `onActivate` as `ctx.restored` on its next activation, then deleted so a
     * later re-activation starts fresh.
     */
    private restoredAgentStates;
    activeAgent?: AgentConfig;
    constructor(providerRegistry: AIProviderRegistry, agents: AgentConfig[], options?: {
        sessionKey?: string;
        maxHandoffs?: number;
        classifierHistoryLength?: number;
        classifierRetries?: number;
        maxToolIterations?: number;
        maxFoldOperations?: number;
        maxTurnSnapshots?: number;
        /** Activity bus passed through to the inner ChatDriver (browser host injects the singleton). */
        activityBus?: ActivityBus;
    });
    resolveInteraction(interactionId: string, result: unknown): void;
    getInteractionContext(interactionId: string): InteractionContext | undefined;
    isBusy(): boolean;
    /** Currently active provider name from the underlying ChatDriver. */
    getActiveProviderName(): string;
    /**
     * Pins routing to a specific agent by name. While pinned, the classifier is
     * skipped and the continuation tool is hidden from the agent's tool list, so
     * the agent cannot quietly hand back to the orchestrator. Pass `null` to
     * return to automatic routing.
     */
    setPinnedAgent(name: string | null): void;
    /**
     * Set the flow-owner lock — used to restore state from Redux on driver
     * reconstruction (agents-array changes, pop-in/pop-out). Not intended for
     * external callers to manipulate routing; that's what `setPinnedAgent` is
     * for.
     */
    setFlowOwner(name: string | null): void;
    loadHistory(messages: ChatMessage[]): void;
    getRawHistory(): readonly ChatMessage[];
    /** {@inheritDoc AiDriver.compact} */
    compact(): Promise<ChatMessage | null>;
    /** {@inheritDoc AiDriver.canCompact} */
    canCompact(): boolean;
    /** Delegates to the inner {@link ChatDriver} — turns are captured there. */
    getTurnSnapshots(): ReadonlyArray<TurnSnapshot>;
    /** Delegates to the inner {@link ChatDriver} — interactions resolve there, so it holds the buffer. */
    getExternalDiagnostics(): ReadonlyArray<DiagnosticEntry>;
    getSuggestions(history: ChatMessage[], prompt: string, count: number, allAgentInfo?: AllAgentSummary[]): Promise<string[]>;
    sendMessage(input: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult>;
    continueFromHistory(transientPrimer?: ChatMessage[]): Promise<ChatDriverResult>;
    /** {@inheritDoc AiDriver.primeRestoredAgentState} */
    primeRestoredAgentState(snapshots: Record<string, unknown>): void;
    /** {@inheritDoc AiDriver.getActiveAgent} */
    getActiveAgent(): AgentConfig | undefined;
    private applyAgent;
    /**
     * Release the current stateful agent: fire `onDeactivate`, clear the
     * flow-owner lock, dispatch events so the host (and Redux) reflect the
     * unlocked state. Called automatically when a tool handler invokes
     * `context.releaseAgent`.
     *
     * The user-pin (`pinnedAgentName`) is intentionally *not* cleared — a user
     * who explicitly picked this agent should stay on it after the flow ends,
     * so the next message starts a fresh flow on the same agent rather than
     * routing through the classifier.
     */
    private releaseActiveAgent;
    /**
     * Stop the current turn (user "stop" button). Cancels the inner chat driver's
     * in-flight request and breaks the handoff loop so no further agent turn or
     * classify runs. The driver stays usable for the next message.
     */
    cancel(): void;
    /**
     * Fire `onDeactivate` on the current active agent and abort any pending
     * lifecycle work. Called by the host on session teardown so machines can
     * release resources cleanly.
     */
    dispose(): Promise<void>;
    private classify;
    /**
     * Returns the agent that the current turn is locked to, if any. Flow-owner
     * (transient, set by stateful-agent activation) wins over user-pin (sticky,
     * set by picker click). `undefined` falls back to the classifier.
     *
     * Logs and returns `undefined` if a name no longer matches the agents array
     * — protects against stale state after an agents-array reassignment.
     */
    private resolvePinnedAgent;
    private appendInlineMessage;
}
//# sourceMappingURL=orchestrating-driver.d.ts.map