import type { IconRenderer } from '../icons/icon-renderer'; import type { PhotonAIConfig } from '../types/photon-ai.types'; import type { PhotonCommandResult } from './photon-ai.types'; /** * The "Photon AI" panel — a docked sidebar sliding in from the right edge of * the grid's own body viewport, where users type natural-language commands * and questions for {@link PhotonAIService} to interpret, with a scrollable * conversation history (not just a one-line status) so multi-turn use * (a command, then a follow-up question, then another command) reads like a * chat rather than a disappearing toast. * * Mounted as a sibling of the pinned-column panels (same pattern as * `DetailRowRenderer`/the sticky layer — see `GridRenderer.buildLayout`), so * it floats independently of virtualization and never affects row layout. * It deliberately stays *inside* the grid's own body box (never * `document.body`) — `bodyWrapEl`'s `overflow: hidden` is what keeps the * whole widget contained to the grid the way an embeddable component should * be, rather than taking over the host page. Unlike a modal, it never * blocks interaction with the grid behind it — there is no backdrop. * * Pure UI: it knows nothing about intents, columns, or the `GridApi` — it * only calls the submit handler wired in via {@link setSubmitHandler} and * renders whatever `PhotonCommandResult` comes back. */ export declare class PhotonAIPanel { private iconRenderer; private launcherEl; private panelEl; private logEl; private inputEl; private sendBtnEl; private submitHandler; /** Optional async handler (a configured generative provider). When set, {@link trySubmit} streams the reply instead of rendering it instantly. */ private asyncSubmitHandler; private isOpen; private messages; /** In-flight generative request, so a second submit / close / destroy can cancel the first. */ private activeController; /** Handle for the running typewriter animation frame, so it can be cancelled on teardown. */ private typewriterHandle; /** True while a request is being processed or its reply streamed — blocks concurrent submits. */ private isBusy; constructor(iconRenderer: IconRenderer); /** Mounts the launcher + docked side panel into the grid body. Idempotent-safe: call once per grid instance. */ mount(bodyWrapEl: HTMLElement, config: PhotonAIConfig): void; /** Wires the callback that turns typed text into a result — set once `GridApi`/`PhotonAIService` exist (after `GridCore` construction). */ setSubmitHandler(fn: (text: string) => PhotonCommandResult): void; /** * Wires an async handler used when a generative provider (e.g. Gemini) is * configured. When present it takes precedence over the synchronous handler: * the panel shows a loading indicator while the request is in flight, then * streams the reply in with a typewriter effect. The passed `AbortSignal` is * aborted if the user submits again, closes, or the grid is destroyed. */ setAsyncSubmitHandler(fn: (text: string, signal: AbortSignal) => Promise): void; /** Programmatic equivalent of typing `text` and pressing send — also appends to the conversation log, so a scripted call and a manual one look identical. */ invoke(text: string): PhotonCommandResult; /** * Async, streaming counterpart to {@link invoke}, used when an async handler * is configured. Appends the user's message, shows a loading bubble while the * provider works, then reveals the reply with a typewriter animation that * keeps the log scrolled to the latest text. Always resolves — errors are * rendered as an error bubble, never thrown. */ invokeAsync(text: string): Promise; open(): void; close(): void; destroy(): void; private buildLauncher; private buildPanel; private buildHeader; private buildInputArea; private autoGrow; private trySubmit; private appendGreeting; private appendMessage; /** Creates an empty message bubble for `role`, without inserting it — callers append and fill it. */ private createBubble; /** * Renders `text` into `bubble`. * * User messages stay plain text (they are echoes of what was typed, and a * user typing backticks means backticks). Assistant messages go through the * Markdown renderer so code blocks, lists, and headings display properly — * with a copy button on every fenced block. */ private renderLines; /** Appends an assistant bubble in its "thinking" state (animated dots) and returns it for later streaming. */ private appendLoadingBubble; /** Turns the loading bubble into the final reply — instantly under reduced-motion, else via a typewriter reveal. */ private renderStreamingResult; /** Reveals `text` character-by-character, auto-scrolling as it grows, and resolves when fully rendered. */ private typewrite; /** Toggles the input/send disabled state while a request is being processed. */ private setBusy; /** Aborts any in-flight request and stops a running typewriter — used on new submit, close, and destroy. */ private cancelActiveRequest; private scrollToBottom; private prefersReducedMotion; } //# sourceMappingURL=photon-ai-panel.d.ts.map