import type { AggregateUsage, AIProviderRegistryStatusEntry, ChatAttachment, ChatConfig, ChatInputDuringExecutionMode, ChatMessage } from '@genesislcap/foundation-ai';
import { AIProviderRegistry } from '@genesislcap/foundation-ai';
import type { Modal } from '@genesislcap/rapid-design-system';
import { GenesisElement } from '@genesislcap/web-core';
import type { SettingsModalTab } from '../components/settings-modal';
import type { AgentConfig } from '../config/config';
import { AssistantAppSettingsProvider, type AssistantAppSettingsHeading, type AssistantAppSettingsToggle } from '../provider/assistant-app-settings';
import type { DebugLog } from '../state/persistence/diagnostics';
import type { SessionPersistenceConfig } from '../state/persistence/session-persistence-provider';
import type { InteractionContext } from '../types/interaction-context';
import { type CostSessionRecord } from '../utils/cost-session-history';
import { type ResolvedCostHistoryConfig } from '../utils/resolve-cost-history-config';
import type { AgentPickerMode, AiAssistantAnimation, AiAssistantState, PopoutMode, SubmitMessageResult, SuggestionsState } from './main.types';
/** Design-system tabs element bound to the settings modal tab bar. */
type SettingsModalTabsElement = HTMLElement & {
    activeid?: string;
};
/** Three-star AI "sparkle" mark — the conventional AI signifier; default assistant avatar. */
export declare const sparkleIconSvg = "<svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5 5 C9.5 11.4 11.1 13 17.5 13 C11.1 13 9.5 14.6 9.5 21 C9.5 14.6 7.9 13 1.5 13 C7.9 13 9.5 11.4 9.5 5 Z\" fill=\"currentColor\"/><path d=\"M17 2.5 C17 5.7 17.8 6.5 21 6.5 C17.8 6.5 17 7.3 17 10.5 C17 7.3 16.2 6.5 13 6.5 C16.2 6.5 17 5.7 17 2.5 Z\" fill=\"currentColor\"/><path d=\"M17.5 15 C17.5 17 18 17.5 20 17.5 C18 17.5 17.5 18 17.5 20 C17.5 18 17 17.5 15 17.5 C17 17.5 17.5 17 17.5 15 Z\" fill=\"currentColor\"/></svg>";
/** Person silhouette — default user avatar. */
export declare const userIconSvg = "<svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\" fill=\"currentColor\"/></svg>";
/** Genesis G-mark — opt-in assistant avatar (the default before the sparkle mark). */
export declare const genesisIconSvg = "<svg viewBox=\"-4 0 30 26\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M18.7702 23.0437C18.7702 22.4675 18.8526 21.8089 19.0995 21.3149C19.3465 20.7386 19.6758 20.2447 20.0874 19.833C20.4991 19.4214 20.993 19.0921 21.5693 18.8451C22.1456 18.5982 22.7219 18.5158 23.2981 18.5158H25.9326V11.6828H19.1819V14.3172C19.1819 15.5521 18.6879 16.7047 17.8647 17.5279C17.0414 18.3512 15.8888 18.8451 14.7363 18.9275H6.7507V6.99025H16.4651V0.157227H3.54C2.63442 0.157227 1.72884 0.568855 1.07023 1.22746C0.411628 1.88606 0 2.79165 0 3.77955V22.2205C0 23.1261 0.411628 24.0316 1.07023 24.7726C1.72884 25.4312 2.63442 25.8428 3.54 25.8428H18.7702V23.0437Z\" fill=\"currentColor\"/></svg>";
/**
 * Foundation AI Assistant component.
 *
 * @remarks
 * Register one or more AI providers via `registerAIProviders` from
 * `@genesislcap/foundation-ai`; this element resolves the `AIProviderRegistry`
 * through the DI container. Pass agent configuration via the `agents` property —
 * each agent can override which registered provider it uses via `provider:`.
 * The component creates a `ChatDriver` (single agent) or `OrchestratingDriver`
 * (multiple agents) to manage the conversation loop.
 *
 * Popout/collapse coordination uses `agenticActivityBus` topics `chat-popout` and `chat-popin` — not DOM `CustomEvent`s on this element.
 *
 * **Cost build history:** opt-in via `chatConfig.costHistory.enabled`. When enabled, each
 * session's usage is kept as exactly ONE row per session key in `localStorage` (scoped by
 * `costHistory.scope`, the element `id`, or `'default'`), upserted as spend accrues. So a
 * row is a project's lifetime usage rather than a visit to it, and the Usage tab's total is
 * the sum of the rows alone — the live session is never added on top, because the active
 * project's own row already reflects it. Hosts may call
 * {@link FoundationAiAssistant.finalizeCostSession} to flush early; it is idempotent.
 *
 * @fires chat-header-mousedown - Fired when the user presses the chat header in `popout-mode="expand"` (for drag-to-popout hosts). Bubbles and composed. detail: `ChatHeaderMouseDownDetail`
 * @fires session-cleared - Fired after the session is wiped (the lifecycle menu's Clear). The payload is captured before teardown so the host can clean up any external state the active agent was working on. Bubbles and composed. detail: `SessionClearedDetail`
 *
 * @beta
 */
export declare class FoundationAiAssistant extends GenesisElement {
    providerRegistry: AIProviderRegistry;
    appSettingsProvider: AssistantAppSettingsProvider;
    designSystemPrefix: string;
    headerTitle: string;
    /**
     * Explicit session/persistence key (GENC-1351 §5.12). When set, this is the
     * session identity — the key for the driver/store/persister/diagnostics
     * registries and the `sessionKey` passed to the persistence provider — taking
     * precedence over the DOM `id`. A host that scopes persistence per-entity
     * (e.g. one chat session per project) binds this to a stable per-entity id;
     * changing it on a **connected** element re-keys the session in place — tears
     * down the current conversation and restores the new key's — via
     * `switchSession`. Falls back to `id` when unset,
     * so existing consumers are unaffected.
     */
    sessionKey?: string;
    imageSrc?: string;
    userImageSrc?: string;
    /**
     * Inline SVG markup overriding the default assistant "sparkle" avatar. The
     * markup is sanitized (SVG profile) before rendering and uses the avatar's
     * theme colour via `currentColor`. For a raster/photo avatar set `imageSrc`
     * instead, which takes precedence. Set to `genesisIconSvg` to restore the
     * Genesis G-mark.
     */
    assistantIcon?: string;
    /** Sanitized `assistantIcon`, or the default sparkle mark; bound into the template. @internal */
    assistantIconSafe: string;
    protected assistantIconChanged(): void;
    /**
     * Inline SVG markup overriding the default user "person" avatar. The markup is
     * sanitized (SVG profile) before rendering and uses the avatar's theme colour
     * via `currentColor`. For a raster/photo avatar set `userImageSrc` instead,
     * which takes precedence.
     */
    userIcon?: string;
    /** Sanitized `userIcon`, or the default person mark; bound into the template. @internal */
    userIconSafe: string;
    protected userIconChanged(): void;
    placeholder: string;
    /**
     * Controls the pop-out button shown next to the settings cog.
     * "expand" — in bubble, expands to layout panel (fires chat-popout).
     * "collapse" — in layout panel, collapses back to bubble (fires chat-popin).
     * Absent — no button (default standalone behaviour, no breaking change).
     */
    popoutMode?: PopoutMode;
    /**
     * Agent configuration. Each user message is routed to the appropriate specialist
     * based on intent. With a single entry, orchestration is skipped.
     */
    agents?: AgentConfig[];
    chatConfig: ChatConfig;
    /**
     * Optional session persistence (GENC-1351). Off by default — set `enabled`
     * and a `provider` (e.g. a `WebStorageSessionProvider`) to have the assistant
     * autosave on idle and auto-restore the conversation on page reload. Exposed
     * as a top-level property (like `agents`/`providerRegistry`) rather than via
     * `chatConfig`, since the provider type lives in this package while
     * `ChatConfig` lives in `foundation-ai`.
     */
    persistence: SessionPersistenceConfig;
    /**
     * Resolved agent picker mode from `chatConfig.picker.mode`. Defaults to
     * `'disabled'`.
     */
    get agentPicker(): AgentPickerMode;
    /**
     * Whether the built-in composer (input row + attachment chips) is hidden by
     * the host's `chatConfig.ui.hideComposer` setting. Used by the template to
     * gate those blocks. Marked `@volatile` because the `'while-splash'` branch
     * reads `showingSplash` only conditionally, so FAST cannot rely on cached
     * dependency tracking.
     */
    get composerHiddenByConfig(): boolean;
    debugStateFactory?: () => unknown;
    /** When set, enables Redux DevTools for this instance's session store. */
    debugRedux: boolean;
    /**
     * Pointer to this session's redux store. `@observable` (GENC-1351 §5.12) so that
     * **swapping** it — the in-place session switch/re-key (`switchSession`) —
     * forces every store-backed getter binding to re-evaluate against the NEW store.
     * Without this, FAST's per-store slice tracking would leave the view subscribed
     * to the old store after a swap and it wouldn't re-render. (A same-store reset via
     * redux actions re-renders without this; a store *swap* needs it.)
     */
    private _sessionRef?;
    get messages(): ChatMessage[];
    set messages(value: ChatMessage[]);
    get state(): AiAssistantState;
    set state(value: AiAssistantState);
    /** Whether a state value counts as "busy" — a turn is active. */
    private isBusyState;
    /**
     * True while a turn is active — `loading` or `cancelling` (a stop was
     * requested but the turn is still winding down). The single "is a turn
     * running" predicate; UI gates use this so `cancelling` behaves like
     * `loading` everywhere. `@volatile` so the template re-evaluates it when the
     * store-backed `state` changes.
     */
    get busy(): boolean;
    /**
     * True when a new send must be refused: a turn is running (`busy`), a page-reload
     * restore is loading history that would clobber it (`restoring`), or a manual
     * compaction is rewriting history (`compacting`). Mirrors the composer's
     * `?disabled` gate so a **programmatic** `send`/`submitMessage` (e.g. a host's
     * custom input while the built-in composer is hidden) can't slip past it and have
     * its message wiped when the restored/compacted history lands (GENC-1351 §6).
     */
    private get sendBlocked();
    /**
     * Re-runs `agentsChanged` if the live `agents` array no longer matches the
     * fingerprint of the currently installed driver. Used to apply swaps that
     * landed during a turn (and were skipped by the `isBusy()` guard) once the
     * driver returns to idle.
     */
    private applyDeferredAgentsSwap;
    /**
     * Apply a `session-key` re-key that arrived mid-turn and was deferred by
     * `switchSession`'s busy guard (GENC-1351 §5.12). Run at each point the driver
     * returns to idle, BEFORE `applyDeferredAgentsSwap` — a switch rebuilds the
     * driver against the current agents, so a pending agents-swap then no-ops.
     */
    private applyDeferredSessionSwitch;
    /**
     * Focus the main chat input if the user is still engaged with the assistant.
     * Deferred to the next frame so any conditional re-render (e.g. unhiding the
     * input row when an agent's `chatInputDuringExecution: 'hidden'` execution
     * ends) has committed before we call `.focus()`.
     *
     * `rapid-text-area` does not delegate focus to its inner native `<textarea>`,
     * so we drill into its shadow root and focus the textarea directly.
     */
    private maybeAutoFocusChatInput;
    get activeAgent(): Omit<AgentConfig, 'toolHandlers'> | undefined;
    set activeAgent(value: AgentConfig | undefined);
    get suggestionsState(): SuggestionsState;
    set suggestionsState(value: SuggestionsState);
    /** Current user-facing toggle state for tool call visibility. */
    get showToolCalls(): boolean;
    set showToolCalls(value: boolean);
    /** Current user-facing toggle state for thinking step visibility. */
    get showThinkingSteps(): boolean;
    set showThinkingSteps(value: boolean);
    /** Current user-facing toggle state for narration (interstitial prose) visibility. */
    get showNarration(): boolean;
    set showNarration(value: boolean);
    /** Current user-facing toggle state for agent switch indicator visibility. */
    get showAgentSwitchIndicator(): boolean;
    set showAgentSwitchIndicator(value: boolean);
    /** Currently enabled animations. */
    get enabledAnimations(): AiAssistantAnimation[];
    set enabledAnimations(value: AiAssistantAnimation[]);
    /**
     * Whether the agent picker slide-out panel is open. Lives on the session
     * store so the bubble-dialog and popout-panel instances stay in sync.
     */
    get agentPickerOpen(): boolean;
    set agentPickerOpen(value: boolean);
    /**
     * Whether the lifecycle (session) menu slide-out panel is open. Like the
     * agent picker, lives on the session store so bubble/popout stay in sync.
     */
    get sessionMenuOpen(): boolean;
    set sessionMenuOpen(value: boolean);
    /**
     * Whether a manual compaction is in flight (GENC-1351 §5.7). On the session
     * store (not element-local) so the "Compacting…" view + input-disable stay in
     * sync across pop-in/out, like the panel flags.
     */
    get compacting(): boolean;
    set compacting(value: boolean);
    /**
     * Whether a page-reload restore is in flight (GENC-1351 §6). On the session
     * store (like `compacting`) so the "Restoring…" view + input-disable stay in
     * sync across pop-in/out. Gating input while true prevents a mid-load send from
     * being clobbered when the restored history loads.
     */
    get restoring(): boolean;
    set restoring(value: boolean);
    /**
     * Name of the agent the user has pinned via the agent picker. `null` means
     * automatic routing (Auto). Persisted on the session store, so it survives
     * pop-in/pop-out but resets on page refresh.
     *
     * Only changes on explicit user action (picker click or host's `setAgent`).
     * The orchestrator's auto-pin on stateful activation writes
     * `flowOwnerAgentName` instead, so finishing a guided flow doesn't wipe
     * the user's sticky pick.
     */
    get pinnedAgentName(): string | null;
    set pinnedAgentName(value: string | null);
    /**
     * Name of the agent that currently owns a guided flow. Set by the
     * orchestrator when a stateful agent's `onActivate` fires, cleared when the
     * agent calls `releaseAgent` from a terminal-state tool handler. While
     * non-null, routing precedence goes to this agent and the picker is locked.
     *
     * Independent of `pinnedAgentName`: a flow can complete and release
     * without disturbing the user's sticky picker choice.
     */
    get flowOwnerAgentName(): string | null;
    set flowOwnerAgentName(value: string | null);
    get liveSubAgentTrace(): ChatMessage[];
    set liveSubAgentTrace(value: ChatMessage[]);
    get liveSubAgentName(): string | null;
    set liveSubAgentName(value: string | null);
    /**
     * In-flight per-call chat-input overrides pushed by `requestSubAgent` or
     * `requestInteraction` calls. Empty means no override is active.
     */
    get inputOverrides(): import("../state/ai-assistant-slice").InputOverride[];
    /**
     * Resolves the effective chat-input behaviour while the assistant is
     * executing. Per-call overrides take precedence over the agent-level
     * config; among overrides the most restrictive wins (`'hidden'` >
     * `'disabled'`). Falls back to the active agent's config, then `'disabled'`.
     */
    get effectiveChatInputDuringExecution(): ChatInputDuringExecutionMode;
    /** Most recent prompt token count from the AI provider, if available. */
    get contextTokens(): number | undefined;
    set contextTokens(value: number | undefined);
    /** Context window size for the active model, if known. */
    get contextLimit(): number | undefined;
    set contextLimit(value: number | undefined);
    /**
     * Cost plus the four token buckets for this session — derived from the transcript
     * on every change, so it includes sub-agent turns and spend banked by a compaction.
     */
    get sessionUsage(): AggregateUsage;
    set sessionUsage(value: AggregateUsage);
    /**
     * Aggregated USD cost across every chat turn in this session.
     *
     * Read-only (unlike previously): it is a projection of `sessionUsage`, and a
     * host assigning it would have set a figure the next transcript change overwrites.
     */
    get sessionCostUsd(): number;
    /**
     * Lifetime usage across every project in the history scope — cost and all four token
     * buckets. What the Usage tab's lifetime section renders.
     *
     * Rows ONLY — deliberately not rows + live session. Each row holds a project's lifetime
     * usage and the active project's row is kept current on every transcript change, so
     * adding the live total would count this project's spend twice. That double-count is what
     * made the figure grow on every refresh: a page-hide banked a row while the restored
     * session still carried the same spend.
     */
    get cumulativeUsage(): AggregateUsage;
    /** Lifetime USD across every project in the history scope. */
    get cumulativeCostUsd(): number;
    /**
     * Whether the live session figures amount to this project's whole history, which is true
     * exactly when the transcript is restored on load. Drives the Usage tab's live labels
     * ("Project cost" vs "Session cost") so they state the scope rather than imply one.
     *
     * Note this is NOT what makes the *rows* lifetime — those bank their pre-transcript spend
     * (see `CostSessionRecord.banked`) and are lifetime either way.
     */
    get liveUsageIsProjectLifetime(): boolean;
    /** Resolved cost tab and build-history settings from `chatConfig.costHistory`. */
    get resolvedCostHistory(): ResolvedCostHistoryConfig;
    /**
     * Total tokens across every chat turn in this session — all four buckets added up.
     * Read-only; the per-bucket split is on `sessionUsage`.
     */
    get sessionTokensConsumed(): number;
    /** Label shown on the Usage tab for the in-flight session (app title or first user phrase). */
    get liveCostSessionTitle(): string | undefined;
    /**
     * Write this session's usage into persisted build history (`localStorage`) as a single
     * row keyed by the session key, replacing any existing row for that key.
     *
     * **Idempotent** — safe to call per turn, on tab close, and on a title change alike.
     * The name is historical: it does NOT end the session or reset the running totals.
     * Resetting them is what used to double-count spend, since the row was banked while the
     * persisted transcript still carried the same usage, so a reload restored it and the
     * Usage tab counted both.
     *
     * No-op unless `chatConfig.costHistory.enabled` is `true`, when the live session has no
     * usage yet, or when the session has no key to upsert against. Gating on the *live*
     * figures (not the banked total) means a reload that restores nothing rewrites nothing.
     */
    finalizeCostSession(options?: {
        title?: string;
    }): void;
    /**
     * Spend for `projectKey` that predates the current transcript, resolved once per project
     * and memoised (`_bankedFor`) so it cannot drift mid-session as the row it came from is
     * rewritten by our own upserts.
     *
     * The two cases turn on whether the transcript is authoritative for this project:
     *
     * - **Transcript restored** (`persistenceActive`): it already accounts for everything after
     *   the previous row's own banked figure, so carry that figure forward unchanged. Re-banking
     *   `usage` here would add the restored history to itself on every reload.
     * - **Transcript starts empty**: nothing on screen accounts for the previous total, so the
     *   whole of it becomes banked. Without this the next turn would rewrite the row downwards
     *   to just that turn, losing the project's earlier spend.
     */
    private bankedUsageFor;
    /**
     * Discard the banked figure — for when the spend it stands for has been deliberately
     * thrown away (the user clearing history, or deleting this project's row).
     *
     * NOT for reloads. A reload re-reads rows that already include our own upserts, so
     * re-deriving from them would fold the live session into its own baseline; only a genuine
     * project change should re-derive, which `bankedUsageFor`'s per-project memo handles.
     */
    private resetBankedUsage;
    showConfirmationDialog(confirmationMessage: string, modalParent: HTMLElement, onConfirm: () => void, onCancel?: () => void): void;
    /** Remove one entry from persisted build history. */
    removeCostSessionFromHistory(id: string): void;
    /** Clear all persisted build history for this assistant scope. */
    clearCostSessionHistory(): void;
    private getCostHistoryScope;
    private reloadCostSessionHistory;
    /**
     * The persistence provider, but only when it implements BOTH cost-history methods.
     *
     * Both or neither: a provider that can save but not load would silently accumulate a
     * ledger nobody ever reads back, so a partial implementation is treated as absent and
     * falls back to `localStorage`.
     */
    private costHistoryProvider;
    /**
     * Adopt `records` as the live list and write them through to whichever backend owns
     * cost history — the provider when the host implements it, else `localStorage`.
     *
     * Provider writes are fire-and-forget and best-effort: the ledger is accounting, not
     * conversation content, so a failed write is logged and never surfaced into the chat.
     */
    private persistCostHistory;
    /** Finalize the previous session when the host-provided title changes. */
    private syncActiveCostSessionTitle;
    /** Active model id resolved from the AIProvider, if exposed. */
    get activeModel(): string | undefined;
    set activeModel(value: string | undefined);
    /** Name of the AI provider used on the most recent turn. */
    get activeProviderName(): string | undefined;
    set activeProviderName(value: string | undefined);
    /** Per-provider status snapshot used by the settings panel. */
    get providerStatuses(): AIProviderRegistryStatusEntry[];
    set providerStatuses(value: AIProviderRegistryStatusEntry[]);
    private _suggestionsGeneration;
    get inputValue(): string;
    set inputValue(value: string);
    attachments: ChatAttachment[];
    attachmentErrors: string[];
    /** Whether the loading spinner is currently visible. Controlled by the loading delay timer. */
    showLoadingIndicator: boolean;
    /** Bump to re-render app settings toggles when the host provider notifies a change. */
    appSettingsRevision: number;
    /** Whether the settings modal is open. */
    settingsOpen: boolean;
    /**
     * True while `downloadDebugLog` is building the log (GENC-1351 §5.8). Drives the
     * download button's disabled + spinner state — the lifetime-stitch path is async
     * (a provider `loadDiagnostics` round-trip), so without feedback a click looks
     * like nothing happened. Per-instance and transient (not shared/persisted): each
     * element has its own settings modal.
     */
    downloadingDebugLog: boolean;
    /** Active tab inside the settings modal. */
    settingsModalTab: SettingsModalTab;
    /** Bound to the design-system modal via the template ref. */
    settingsModal?: Modal;
    /** Bound to the settings modal tab bar — used to resync selection after reopen. */
    settingsTabsEl?: SettingsModalTabsElement;
    /** Light-DOM nodes assigned to settings modal slots (via `slotted()` bindings). */
    settingsModelSlotted: HTMLElement[];
    settingsAppSlotted: HTMLElement[];
    settingsCostCurrentSlotted: HTMLElement[];
    settingsCostHistorySlotted: HTMLElement[];
    /** Persisted finalized cost sessions shown on the Usage tab build history list. */
    costSessionHistory: CostSessionRecord[];
    /** Whether the splash overlay is currently showing (no messages and showSplash is enabled). Reflected as a boolean attribute on the host. */
    showingSplash: boolean;
    private driver?;
    private driverCleanup?;
    private loadingTimer;
    private unsubBus?;
    /** Unsubscribe handle for the provider-registry change listener (observable registries only). */
    private unsubProviderRegistry?;
    /** Unsubscribe handle for {@link (AssistantAppSettingsProvider:interface).subscribe}. */
    private unsubAppSettingsProvider?;
    /** Title tracked for the in-flight cost session (used when `header-title` changes). */
    private _activeCostSessionTitle;
    /** Memoised pre-transcript spend for `_bankedFor` — see `bankedUsageFor`. */
    private _bankedUsage;
    /** Project key `_bankedUsage` was resolved for; `undefined` means "not yet resolved". */
    private _bankedFor;
    /**
     * Whether the row list reflects storage yet. Gates cost writes so a project's banked
     * spend is never derived from a ledger that simply hasn't arrived.
     */
    private _costHistoryLoaded;
    private _handlePageHide;
    private haloStartPublished;
    /** Fingerprint of the agents array used to build the current driver. Used by agentsChanged to skip spurious rebuilds. */
    private _driverAgentsKey?;
    /** Bound to the messages container via the template ref — assigned by FAST before connectedCallback logic runs. */
    messagesEl?: HTMLElement;
    /** Bound to the rapid-text-area chat input via the template ref. */
    chatInputEl?: HTMLElement;
    /**
     * Explicit composer height (px) once the user has dragged the resize handle;
     * `null` keeps the default auto-grow behaviour. Written into the
     * `--composer-height` custom property via the `composerHeightStyle` getter.
     */
    composerHeightPx: number | null;
    /** Pointer Y and composer height captured at the start of a resize drag. */
    private _resizeStartY;
    private _resizeStartHeight;
    /** The composer's natural (un-resized) height, measured on first drag — used
     * as the lower bound so the box can't be dragged smaller than it started. */
    private _composerNaturalHeight;
    /** Upper bound for the current drag — capped to the headroom above so growing
     * the composer never pushes the input row's buttons off the bottom. */
    private _resizeMaxHeight;
    /**
     * True when the user's last interaction (pointer or keyboard focus) was inside
     * the assistant. Defaults to true so the assistant claims focus on first mount.
     * Auto-focus features (chat input on idle, widget inputs on mount) gate on this
     * to avoid stealing focus from elsewhere on the page.
     */
    isEngaged: boolean;
    private _handleGlobalInteraction;
    /** True when the user has intentionally scrolled away from the bottom — suppresses auto-scroll. */
    private _userScrolledAway;
    private _scrollListener?;
    private static readonly SCROLL_BOTTOM_THRESHOLD_PX;
    /** Context-usage percentage that fires the one-shot `context.threshold-crossed` event. */
    private static readonly CONTEXT_USAGE_WARN_PERCENT;
    /** Last `contextTokens` logged to the timeline — dedupes the `context.updated` event. */
    private _lastLoggedContextTokens?;
    /** Whether the one-shot ≥80% `context.threshold-crossed` event has fired this session. */
    private _contextThresholdCrossed;
    /**
     * Interaction widgets that grow mid-lifecycle (e.g. expanding a "More info"
     * panel, appending an SSE status row, revealing generated code) bubble a
     * `request-scroll-to-bottom` event up from `ai-chat-interaction-wrapper`,
     * which observes them with a ResizeObserver. We re-snap to the bottom on
     * receipt, honouring `_userScrolledAway` so a user reading old messages is
     * not yanked back when content elsewhere grows.
     */
    private readonly _handleRequestScrollToBottom;
    /**
     * Unsubscribes a one-shot state subscription created when this element connects
     * mid-execution. The subscription watches for `state` becoming 'idle' so that
     * this element can stop its loading timer and sync the halo even when the
     * originating `send()` ran on a different element instance.
     */
    private _executionCompletionUnsub?;
    /**
     * True while UI preferences are being applied programmatically (config defaults
     * on connect, or a loaded-preferences restore) — suppresses the save hook so we
     * don't persist config defaults or re-persist what we just loaded. Cleared once
     * the apply completes; a genuine *user* toggle (menu switch) runs with it false
     * and saves (GENC-1351).
     */
    private _applyingPreferences;
    /**
     * Fresh-store flag (`= isNewStore`) captured in `connectedCallback`. Only a
     * freshly created store takes the config/stored-prefs baseline; an existing
     * store — a reload with a live in-realm store, or the popped-out second instance
     * — already holds the correct state, so `applyPreferenceBaseline` no-ops for it.
     */
    private _freshStore;
    /**
     * True once `connectedCallback` has fully wired the initial session (GENC-1351
     * §5.12). Guards `sessionKeyChanged` so the initial, pre-connect `session-key`
     * set doesn't trigger a re-key — only a genuine change to a connected element
     * switches the session. Reset on disconnect.
     */
    private _sessionActive;
    /**
     * The key of the session currently WIRED to this element (its driver/store/
     * `_sessionRef`). Authoritative for `getStateKey()` once a session is active,
     * because the `session-key` attr can run ahead of an actual switch: a mid-turn
     * rebind is deferred to idle (§5.12), and reading the attr in that window would
     * retarget autosave/diagnostics at a not-yet-activated key and silently drop the
     * rest of the live turn. Set by `activateSession`. Undefined before first connect.
     */
    private _activeStateKey?;
    /**
     * Target key of a `session-key` rebind that arrived mid-turn and was deferred
     * (§5.12). Applied by `applyDeferredSessionSwitch` once the driver goes idle. The
     * latest rebind wins if several land while busy. Undefined = no switch pending.
     */
    private _deferredSwitchToKey?;
    showHalo: 'no' | 'orchestrating' | 'agent';
    private syncShowHalo;
    /** True when there is a pending (unresolved) interaction. */
    get hasActivePendingInteraction(): boolean;
    showHaloChanged(): void;
    private getActiveToolNames;
    /**
     * Messages rendered in the scrolling list, filtered by the current toggle
     * state. Tool-related messages (those with toolCalls or toolResult) are hidden
     * when `showToolCalls` is false.
     *
     * Excludes the trailing interaction (see `activeInteractionRow`), which is
     * rendered in a separate pinned slot so toggling the message filters never
     * re-creates a live interaction widget.
     *
     * Marked `@volatile` because the filter branches conditionally access
     * `showToolCalls`, `showThinkingSteps`, and `showAgentSwitchIndicator`
     * depending on message content. Without it, FAST would only track the
     * observables accessed on the last evaluation and miss toggle changes that
     * happen to hit an untracked branch.
     */
    get visibleMessages(): ChatMessage[];
    /**
     * The trailing interaction, rendered in a pinned slot below the scrolling
     * list rather than inside it. Reads only `messages` (never the toggle state),
     * so a cog-menu toggle leaves this binding — and the live widget's DOM —
     * untouched. See `trailingInteractionRow` for the rationale.
     */
    get activeInteractionRow(): ChatMessage[];
    agentsChanged(): void;
    /** Returns a stable fingerprint for an agents array based on agent names and tool handler keys. */
    private getAgentsKey;
    /**
     * Pure factory — creates a ChatDriver or OrchestratingDriver based on the
     * current agent configuration. Does not wire event listeners or register in
     * the driver registry.
     */
    /**
     * Warn at config time if any stateful agent (one with lifecycle hooks) is
     * configured in a way that makes it unreachable: `excludeFromClassifier`
     * removes the classifier path, so the only entry left is manual pinning —
     * which requires both `manualSelection.enabled` on the agent and the picker
     * itself being enabled at the assistant level.
     */
    private warnUnreachableStatefulAgents;
    private createDriver;
    /**
     * Attaches event listeners to the current driver. Stores a cleanup function
     * so `unwireDriver` can remove them precisely. Safe to call multiple
     * times — unwires any existing listeners first.
     */
    private wireDriver;
    /**
     * Removes event listeners attached by `wireDriver`. Does not destroy
     * the driver or remove it from the registry.
     */
    private unwireDriver;
    /**
     * Tear down the session's currently-wired driver (GENC-1351): unwire this view, drop
     * the driver from the registry, and dispose it — which fires the active agent's
     * `onDeactivate` → `machine.stop()`. Shared by `agentsChanged`, `clearSession`, and
     * `switchSession` so the teardown stays identical. `unwireDriver` does not clear
     * `this.driver`, so the instance is still readable here for disposal.
     */
    private teardownDriver;
    /**
     * Build (or adopt from the registry) a fresh driver for `key` against the current
     * agents and wire it to this view (GENC-1351). Records the agents fingerprint so a
     * later `agentsChanged` skips a spurious rebuild. Shared by `agentsChanged` and
     * `clearSession`.
     */
    private rebuildDriver;
    /**
     * Wire up the session identified by `key` on this element: preference baseline,
     * driver (build/reuse) + wiring, restore (fresh store only), and the per-session
     * view state (splash, loading-resume, suggestions, context/provider status, cost
     * history). Extracted from `connectedCallback` (GENC-1351 §5.12) so an in-place
     * session switch (`switchSession`) can re-run exactly this against a new
     * key without re-adding element-lifetime listeners. Session-scoped only — the
     * element-lifetime wiring (DOM/document/window listeners, provider-registry
     * subscription, app-settings, pagehide) stays in `connectedCallback`.
     */
    private activateSession;
    connectedCallback(): void;
    /**
     * Switch this element to a different session **in place**, without a page reload
     * (GENC-1351 §5.12) — the load-a-different-project flow. Tears down the current
     * session's driver + per-key registries and restores the target key's session
     * (its transcript and any mid-flow stateful agent). Fired automatically by
     * `sessionKeyChanged` when a host rebinds
     * `session-key` on a connected element; may also be called directly.
     *
     * Clobber-safe: the outgoing session's pending autosave is cancelled BEFORE the
     * store swaps, so its transcript can never be written to the incoming session's
     * file. Idle-only — a switch while a turn is running is refused.
     *
     * @param oldKey - the state key being switched away from.
     * @param newKey - the state key to activate.
     * @public
     */
    switchSession(oldKey: string, newKey: string): void;
    /**
     * FAST reflection hook for the `session-key` attr: a change on a **connected**
     * element re-keys the session in place (GENC-1351 §5.12). Guarded by
     * `_sessionActive` so the initial, pre-connect set does not switch — the first
     * key is wired by `connectedCallback`.
     */
    sessionKeyChanged(_oldValue: string | undefined, _newValue: string | undefined): void;
    disconnectedCallback(): void;
    private resolveContextLimit;
    private loadProviderStatuses;
    chatConfigChanged(): void;
    /**
     * `persistence` (like `chatConfig`) can bind after `connectedCallback` — a host may
     * resolve the `provider` asynchronously (an auth token, a feature flag). The connect
     * path gates the whole persistence init on a provider being present *at connect*, and
     * nothing else re-triggers it — so a late provider would silently never restore the
     * session or load stored preferences (GENC-1351 #13). Mirror `chatConfigChanged`: when
     * a provider first appears on a connected element whose store is still fresh, run the
     * fresh-store init now. Guards keep it a one-shot:
     *  - pre-connect sets are handled by `connectedCallback` (`_sessionActive` is false);
     *  - a provider that was already present (incl. the internal `enabled`-only
     *    reassignments) is a no-op (`oldValue?.provider`);
     *  - a non-fresh (restored) store already holds its session (`_freshStore`).
     */
    persistenceChanged(oldValue: SessionPersistenceConfig | undefined, newValue: SessionPersistenceConfig | undefined): void;
    showingSplashChanged(): void;
    private syncShowingSplash;
    /**
     * Runs side effects that were previously in `messagesChanged()`.
     * Called from the `messages` setter after dispatching to the store.
     */
    private handleMessagesUpdate;
    showLoadingIndicatorChanged(): void;
    private scrollToBottom;
    private static readonly DEFAULT_LOADING_DELAY_S;
    private static readonly DEFAULT_SUGGESTION_COUNT;
    private static readonly MS_PER_SECOND;
    private startLoadingTimer;
    private clearLoadingTimer;
    private stopLoadingTimer;
    /** Called when the user clicks the popout button. */
    handlePopout(): void;
    /** Returns a cache key for this instance, or undefined if the component has no identity. */
    private getStateKey;
    /**
     * The session key implied by the element's current attributes (GENC-1351 §5.12).
     * An explicit `session-key` IS the complete session identity — the host fully
     * qualifies it (e.g. a per-project id), so `headerTitle` is NOT appended
     * (appending it was multi-window disambiguation, obsolete under the single-window
     * orchestration/pinning model for keyed hosts). Without a `session-key`, fall back
     * to `id` + `headerTitle` (the original scheme, kept so existing consumers — e.g. a
     * title-only key with no `id` — aren't re-keyed). This is the *desired* key;
     * `getStateKey` returns the *wired* key, which can lag during a deferred switch.
     */
    private computeStateKeyFromAttrs;
    /**
     * Record a meta/lifecycle event onto this session's debug-log timeline
     * (exported via {@link FoundationAiAssistant.getDebugLog}). Every event
     * auto-carries `placement` so a session emitted from both the bubble and the
     * layout panel stays disambiguated. Keyed by `stateKey` so the timeline is
     * shared across pop-in/pop-out and survives driver rebuilds.
     */
    private logMeta;
    private readonly _agentPickerToggle;
    toggleAgentPicker(): void;
    /** Two-step confirm for the destructive Clear action; reset whenever the menu toggles. */
    confirmingClear: boolean;
    confirmingCompact: boolean;
    private readonly _sessionMenuToggle;
    /**
     * Whether the lifecycle-menu button shows. It occupies the stop-button slot,
     * so it only appears when idle (mutually exclusive with Stop). Gated on
     * persistence — the menu's actions (Compact, Clear, the "remember chat" toggle)
     * only make sense with a provider configured, so it's hidden entirely without
     * one. A host can additionally force it off via `chatConfig.ui.showSessionMenu:
     * false` even when a provider is present (e.g. a guided onboarding flow where
     * clearing/compacting mid-journey would be disruptive).
     */
    get sessionMenuEnabled(): boolean;
    /** The persistence toggle row renders only when a provider is configured. */
    get persistenceToggleable(): boolean;
    /** Whether persistence is currently active (on + a provider) for this session. */
    get persistenceActive(): boolean;
    /**
     * Whether the menu's "Compact" action would do anything (GENC-1351 §5.7).
     * Delegates to `driver.canCompact()` so the gate uses the exact same history
     * `compact()` acts on — one source of truth. Also reads `messages`, purely to
     * stay reactive as the conversation grows: the driver's history isn't a tracked
     * observable, so the button keys its re-evaluation off the Redux mirror.
     */
    get compactable(): boolean;
    toggleSessionMenu(): void;
    /**
     * Set persistence on/off for this session (the menu switch). Reassigns the
     * `persistence` object so the `@observable` fires. Turning it **off** drops the
     * stored snapshot; **on** captures the current chat immediately. Either way the
     * *choice* is remembered in the preferences blob (`persistPreferences`) — stored
     * independently of the snapshot, so it survives the clear and re-applies on the
     * next load (GENC-1351).
     */
    setPersistenceEnabled(enabled: boolean): void;
    /** Toggle persistence (convenience / programmatic). */
    togglePersistence(): void;
    /** Snapshot the user-changeable settings into a persistable preferences blob. */
    private gatherPreferences;
    /**
     * Persist the current UI preferences whenever the user changes a setting
     * (GENC-1351). Fires **regardless of "remember chat"** — display choices are the
     * user's, not tied to whether the chat is remembered — needing only a provider
     * that implements `savePreferences`. No-op while preferences are being applied
     * programmatically (`_applyingPreferences`), so config defaults and loaded prefs
     * aren't re-saved.
     */
    private persistPreferences;
    /**
     * Apply the effective UI-preference baseline onto the live toggles for a fresh
     * store (GENC-1351 #2). Precedence, lowest → highest:
     *
     *   slice defaults  <  `chatConfig.ui` defaults  <  stored user preferences
     *
     * Recomputed from scratch (not layered) on every call, because its two inputs
     * arrive at unpredictable times: `chatConfig` is a parent-supplied `@observable`
     * that may bind *after* `connectedCallback`, and stored prefs load asynchronously.
     * So it re-runs from `connectedCallback`, `chatConfigChanged`, and once
     * `loadPreferences` resolves — whichever order they happen in, the final state is
     * the same. No-op once the store isn't fresh (an existing/popped-out store owns
     * its state) or the user has toggled something (their choice then wins, and
     * `chatConfig` doesn't change post-startup in practice). Save hook suppressed so
     * applying the baseline never persists as if it were a user choice.
     *
     * This is the fix for "nuking server prefs drops to all-disabled instead of the
     * `chatConfig` defaults": stored prefs are simply absent, so the baseline falls
     * through to the config layer — which the old apply-once-on-connect path missed
     * whenever `chatConfig` hadn't bound yet.
     */
    private applyPreferenceBaseline;
    /**
     * Compact the conversation (GENC-1351 §5.7) — the menu's "Compact" action.
     * Delegates to the driver, which summarizes older turns into a single
     * `compacted-summary` message (destructive, atomic). On success records a
     * high-importance `context.compacted` meta-event capturing the summary; the
     * normal `history-updated` → autosave path then persists the smaller
     * transcript. No-op when there is nothing to compact or the provider cannot
     * summarize (the driver returns `null`).
     */
    compactSession(): Promise<void>;
    /**
     * Clear the session — the "New chat" action (GENC-1351 §5.6). Tears down the
     * active driver (firing the stateful agent's `onDeactivate` → `machine.stop()`),
     * resets the store, rebuilds a fresh driver with no history, and wipes durable
     * storage. Mirrors `agentsChanged`'s teardown, minus the history reseed.
     *
     * Emits `session-cleared` (`SessionClearedDetail`, declared on the class `@fires`)
     * with `sessionKey`, `agentName`, and `agentSnapshot` captured *before* teardown, so
     * the host can clean up any external state the active agent was working on (generated
     * files, server-side scratch, etc.). Bubbles and composed.
     */
    clearSession(): Promise<void>;
    /**
     * Programmatically pin an agent by name. Returns `true` if the pin was
     * applied, `false` if the agent isn't in the configured agents array or
     * the call was suppressed by `force: false`.
     *
     * With `force: false`, the call is a no-op when a `picker.defaultAgent` is
     * configured and the user has already moved away from it (either by picking
     * another agent or by switching to Auto). This lets hosts seed an opinion
     * without overriding an explicit user choice.
     *
     * @public
     */
    setAgent(agentName: string, options?: {
        force?: boolean;
    }): boolean;
    /** Whether the picker toggle button should appear. Mirrors the picker's own visibility rule. */
    get agentPickerEnabled(): boolean;
    /** Whether the settings modal AI Model section has slotted app content or context usage. */
    get settingsModelSectionVisible(): boolean;
    /** Built-in context window indicator (generic platform concern). */
    get settingsContextUsageVisible(): boolean;
    /** Whether the settings modal UI Builder section should render. */
    get settingsAppSectionVisible(): boolean;
    /** App toggles currently visible per each entry's `visible()` predicate. */
    get visibleAppSettingsToggles(): AssistantAppSettingsToggle[];
    /**
     * Host-supplied heading for the toggle group, or `undefined` for none — the assistant has no
     * default. Suppressed when no toggle is currently visible, so a `visible()` predicate hiding
     * the last one takes its heading with it rather than leaving a label over nothing.
     */
    get appSettingsTogglesHeading(): AssistantAppSettingsHeading | undefined;
    getAppSettingValue(id: string): boolean;
    setAppSettingValue(id: string, value: boolean): void;
    private wireAppSettingsProvider;
    private unwireAppSettingsProvider;
    get settingsCostCurrentSectionVisible(): boolean;
    get settingsCostHistorySectionVisible(): boolean;
    /** Whether the built-in Usage tab summary block has anything to show. */
    get settingsCostSummaryVisible(): boolean;
    /**
     * Whether the lifetime-usage section has anything to say.
     *
     * Requires build history: with it off there are no rows, so `cumulativeUsage` falls back to
     * the live session and the section would restate the block directly below it under a
     * "lifetime" heading it hasn't earned.
     */
    get settingsCostLifetimeVisible(): boolean;
    /** Whether the Usage tab should appear in the settings modal. */
    get settingsCostTabVisible(): boolean;
    /** Whether session token usage should render on the Usage tab. */
    get settingsSessionTokensVisible(): boolean;
    /** Whether the chat header (and settings cog) should render. */
    get settingsCogVisible(): boolean;
    openSettingsModal(): void;
    closeSettingsModal(): void;
    onSettingsModalClosed(): void;
    setSettingsModalTab(tab: SettingsModalTab): void;
    /** Sync the active settings modal tab when the design-system tab bar changes. */
    onSettingsModalTabsChange(event: Event): void;
    /** Ensure the settings tab is selected when the modal opens. */
    private resetSettingsModalTabsOnOpen;
    /** Return to the settings tab when the modal closes on Cost. */
    private resetSettingsModalTabsOnClose;
    /**
     * Snap the tab underline to the settings tab without animating from Cost.
     * Used after hide/show when aria state is correct but the indicator drifted.
     */
    private snapSettingsModalTabIndicator;
    /** Hint text for the currently pinned agent, if any. Used in the toggle button tooltip. */
    get pinnedAgentHint(): string | undefined;
    /**
     * The pin is locked when a stateful flow is mid-stream — i.e. some agent's
     * `onActivate` has fired and it owns live state, and it hasn't yet called
     * `releaseAgent`. Derives directly from `flowOwnerAgentName`, the
     * single source of truth the orchestrator writes on activation and clears
     * on release. Until the user sends their first message, a freshly pinned
     * stateful agent is not yet active and the picker should remain free; the
     * user might change their mind and unpin without anything to clean up.
     */
    get pinLocked(): boolean;
    /** Tooltip shown on the picker toggle button. */
    get agentToggleTitle(): string;
    /**
     * Tint applied to the pin icon when an agent is pinned. Picked from the
     * brand palette by agent position (modulo the palette length), so each agent
     * gets a consistent colour across renders. `undefined` when nothing is
     * pinned, the agent isn't in the current array, or the host has opted out
     * via `chatConfig.picker.disablePinColours`.
     */
    get pinnedAgentColour(): string | undefined;
    /**
     * Placeholder shown in the chat input. Substitutes the pinned agent's name
     * when one is selected so the user has a clearer signal of where their
     * message will go; otherwise falls back to the host-provided placeholder.
     */
    get effectivePlaceholder(): string;
    toggleShowToolCalls(): void;
    toggleShowThinkingSteps(): void;
    toggleShowNarration(): void;
    toggleShowAgentSwitchIndicator(): void;
    setEnabledAnimations(animations: AiAssistantAnimation[]): void;
    /** The live current-page debug log (`{ readme, timeline, meta }`). @public */
    getDebugLog(): DebugLog;
    /**
     * Build the current page's diagnostic entries (GENC-1351 §5.8) — the debug-log
     * timeline entries (`message`/`turn`/`event`) plus one `meta-snapshot` carrying
     * the export-time `meta` block. `getDebugLog()` reassembles these into the live
     * log; the persister's forward-capture path (`SessionPersister.flushDiagnostics`,
     * fed these via the `getDiagnosticEntries` dep) diffs them against what's already
     * been appended to the persisted stream.
     */
    private buildDiagnosticEntries;
    downloadDebugLog(): Promise<void>;
    /**
     * The log to download (GENC-1351 §5.8). When the provider persists diagnostics,
     * stitch the **whole lifetime** stream (every page load) rather than just the
     * current page's in-memory view: flush the current delta first so it's included,
     * then reassemble everything `loadDiagnostics` returns. Independent of "remember
     * chat" — diagnostics are a forensic stream keyed on provider capability, not on
     * whether the *chat* is remembered (like preferences). Falls back to the live
     * current-page log when diagnostics isn't available or the fetch fails.
     */
    private buildDownloadLog;
    /**
     * The shared per-session `SessionPersister` that owns restore-core
     * save/restore/freeze (GENC-1351 §5.10). Created once per `stateKey` and shared by
     * every element view (bubble + panel) via the registry, so there is a single save
     * timer + carry-forward cache — no per-view double-writes. The deps are getters so
     * the persister always reads the current driver/store/config and never holds a
     * stale reference. `undefined` before the session key is available.
     */
    private persister;
    /**
     * The `SessionPersister` dependency getters bound to THIS element + `key`.
     * The host-owned getters (`getPersistence`/`getAgentNames`/`getDiagnosticEntries`)
     * read the live element; `getDriver`/`getStore` resolve by key from the registries.
     * Rebound onto the shared persister on every activation (see `activateSession`) so
     * a remounted element becomes the live source, not the torn-down creator (GENC-1351 §5.10 / #7).
     */
    private buildPersisterDeps;
    /**
     * First-load persistence init for a freshly created store (GENC-1351). Restores
     * the user's remembered persistence-toggle choice — kept independently of the
     * session snapshot so it survives a clear; the host-configured `enabled` is only
     * the default for a first-ever load — then auto-restores the session when
     * persistence is (now) on.
     */
    private initPersistenceForNewStore;
    triggerFileInput(): void;
    handleFileSelect(e: Event): void;
    removeAttachment(attachment: ChatAttachment): void;
    removeAttachmentError(message: string): void;
    private isAcceptedFile;
    private readFileAsText;
    private processFiles;
    private loadSelectedFiles;
    handleSendClick(): void;
    /**
     * User clicked Stop. Cancels the current turn via the driver and flips the
     * button to "Stopping…" until the turn winds down (a tool mid-execution
     * finishes first). Guarded so a second click is a no-op.
     */
    handleStopClick(): void;
    handleSuggestionClick(suggestion: string): void;
    /**
     * Programmatically submit a message. Equivalent to the user typing into the
     * built-in composer and pressing send, but callable from external code — most
     * commonly a custom input rendered inside `slot="splash"` when paired with
     * `chatConfig.ui.hideComposer`.
     *
     * The input fully describes the turn: `text` and `files` REPLACE any current
     * composer state (they are not appended to it). Files are validated against
     * `chatConfig.ui.acceptedFiles` using the same pipeline as the composer's
     * attach button.
     *
     * Atomic on validation: if any file fails validation, no attachments are
     * committed and no send is dispatched. Failure messages are returned in
     * `errors` AND appended to the `attachmentErrors` observable so the built-in
     * chip UI still surfaces them when visible.
     *
     * Resolves once the underlying send has been kicked off — it does NOT await
     * the assistant's response.
     *
     * @beta
     */
    submitMessage(input: {
        text?: string;
        files?: File[];
    }): Promise<SubmitMessageResult>;
    private fetchSuggestions;
    /**
     * User text of the message currently being sent, stashed for the lifetime of `send()`.
     * `flow-owner-changed` fires while the driver routes this turn — before the message is
     * appended to raw history — so the flow-activation-prompt capture reads this rather than
     * a stale raw-history lookup. Cleared once the send settles. (GENC-1351 §5.9)
     */
    private _pendingSendPrompt?;
    private send;
    onChatHeaderMouseDown(e: MouseEvent): void;
    handleInteractionCompleted(e: Event): void;
    /**
     * The live {@link InteractionContext} for a pending interaction (GENC-1390).
     * `AiChatInteractionWrapper` pierces this across the shadow boundary to build the
     * widget's pending `interaction` descriptor. Narrow public surface over the
     * private `driver`; returns `undefined` for a resolved/evicted interaction.
     * @internal
     */
    getInteractionContext(interactionId: string): InteractionContext | undefined;
    /** Whether the message input shows a drag handle to resize its height.
     * On by default; hosts opt out via `chatConfig.ui.resizableInput: false`. */
    get isComposerResizable(): boolean;
    /** Inline style for the chat input: writes the chosen height into the
     * `--composer-height` custom property (read by `.chat-input` + its control in
     * `main.styles.ts`). Empty until the user drags (or when resizing is disabled),
     * so the default applies. */
    get composerHeightStyle(): string;
    /** Begin a composer resize drag. Captures the pointer so move/up keep firing
     * on the handle even when the cursor leaves its 7px band. */
    onComposerResizeStart(e: PointerEvent): void;
    /** Resize while dragging. Dragging up (clientY decreases) grows the composer;
     * the result is clamped between the natural height (lower) and the available
     * headroom/max (upper). No-op unless a drag is active (the handle holds pointer
     * capture), so plain hover-moves are ignored. */
    onComposerResizeMove(e: PointerEvent): void;
    /** End a resize drag and release the pointer capture. */
    onComposerResizeEnd(e: PointerEvent): void;
}
export {};
//# sourceMappingURL=main.d.ts.map