import { DefaultChatTransport } from '../../lib/ai-lite'; import { Chat } from '../../lib/chat'; import type { AbstractChat, ChatInit as ChatInitAi, UIMessage } from '../../lib/chat'; import type { SendEventForHits } from '../../lib/utils'; import type { Connector, Renderer, Unmounter, UnknownWidgetParams, IndexUiState, IndexWidget, InitOptions, RenderOptions, WidgetRenderState, IndexRenderState } from '../../types'; import type { UserClientSideTool, ClientSideTools, ChatRecordsStore } from 'instantsearch-ui-components'; export type ChatRenderState = { indexUiState: IndexUiState; input: string; open: boolean; /** * Sends an event to the Insights middleware. */ sendEvent: SendEventForHits; setIndexUiState: IndexWidget['setIndexUiState']; setInput: (input: string) => void; setOpen: (open: boolean) => void; /** * Opens the chat (if needed) and focuses the prompt input. */ focusInput: () => void; /** * Updates the `messages` state locally. This is useful when you want to * edit the messages on the client, and then trigger the `reload` method * manually to regenerate the AI response. */ setMessages: (messages: TUiMessage[] | ((m: TUiMessage[]) => TUiMessage[])) => void; /** * Clear all messages. This is a synchronous, immediate commit; any fade-out * animation before clearing is handled by the view layer. */ clearMessages: () => void; /** * Tools configuration with addToolResult bound, ready to be used by the UI. */ tools: ClientSideTools; /** * The records the chat's tools have fetched, keyed by `objectID`: every tool * call that returned `hits` contributes them, last write winning. Attached to * every tool too, which is how a `layoutComponent` reads it. */ records: ChatRecordsStore; /** * Suggestions received from the AI model. */ suggestions?: string[]; /** * Sends feedback (thumbs up/down) for an assistant message. * Only available when using `agentId` and `feedback` is true. * Returns `undefined` otherwise. */ sendChatMessageFeedback?: (messageId: string, vote: 0 | 1) => void; /** * Map of message IDs to their feedback state. * 'sending' means the request is in flight, 0/1 means the vote was recorded. */ feedbackState: Record; } & Pick, 'addToolResult' | 'clearError' | 'error' | 'id' | 'messages' | 'regenerate' | 'resumeStream' | 'sendMessage' | 'status' | 'stop'>; export type ChatPersistence = boolean | { messages?: boolean; open?: boolean; }; export type ChatInitWithoutTransport = Omit, 'persistence' | 'transport'> & { chat?: never; /** * Whether to persist messages and open state in sessionStorage. * An object configures each policy independently. * * @default true */ persistence?: ChatPersistence; }; export type ChatAgentRequestOptions = { /** * Query parameters to send with built-in Agent Studio completion requests. */ queryParameters?: Record; /** * Headers to send with built-in Agent Studio completion requests. */ headers?: Record | Headers; }; export type ChatTransport = { agentId: string; transport?: never; /** * Request options to send with built-in Agent Studio completion requests. */ requestOptions?: ChatAgentRequestOptions; /** * Whether to enable feedback (thumbs up/down) on assistant messages. */ feedback?: boolean; } | { agentId: string; transport?: ConstructorParameters[0]; feedback?: boolean; requestOptions?: never; } | { agentId?: undefined; transport?: ConstructorParameters[0]; feedback?: never; requestOptions?: never; }; export type ChatCustomInstance = { chat: Chat; agentId?: undefined; transport?: ConstructorParameters[0]; feedback?: never; requestOptions?: never; /** * Whether to persist open state in sessionStorage. Message persistence is * configured when constructing the Chat instance. * * @default { open: true } */ persistence?: { open?: boolean; messages?: never; }; sendAutomaticallyWhen?: never; }; export type ApplyFiltersParams = { query?: string; facetFilters?: string[][]; /** * Numeric refinements, in the Algolia `numericFilters` format * (e.g. `['price <= 1500']`). Only the search tool's resolved search params * can express these; the raw `facet_` keys cannot. * * Kept in sync with `ApplyFiltersParams` in `instantsearch-ui-components`, * which declares the same contract for the component layer. */ numericFilters?: string[]; }; export type ChatInit = ChatInitWithoutTransport & ChatTransport; export type ChatConnectorParams = (ChatCustomInstance | ChatInit) & { /** * Disable validation that requires either a dedicated trigger or AI mode. */ disableTriggerValidation?: boolean; /** * Whether to resume an ongoing chat generation stream. * This option has no effect during server rendering. */ resume?: boolean; /** * Whether this widget should make InstantSearch require a main search request. * If this is the only widget, and you mark `requiresSearch: false`, no search request will happen. * * @default true */ requiresSearch?: boolean; /** * Configuration for client-side tools. */ tools?: Record>; /** * Identifier of this type of chat widget. This is used for the key in renderState. * @default 'chat' */ type?: string; /** * Ambient session facts to attach to the latest user turn (e.g. current page * URL, locale, product id). Sent over the wire as * `messages[last].metadata.turnContext` per the Agent Studio contract — never * rendered as a chat bubble and never persisted on assistant turns. * * The server validates the payload (flat `Record`, key/value * length and shape) and rejects malformed contexts. Pass a function when the * values change per-turn — it is invoked once per send. If the source is * async, resolve it upstream and close over the value. */ context?: Record | (() => Record); /** * A message to send automatically when the chat is initialized. * This message is sent only in the browser. * * This message is only sent when the chat has no existing messages yet. If * messages were restored or otherwise already exist when the widget starts, * this message is not sent. * * When `resume` is enabled, this message is not sent. */ initialUserMessage?: string; /** * Messages to pre-populate the chat with when it is initialized. * These messages are applied only in the browser. * * These messages are set without triggering an AI response. They are only * applied when the chat has no existing messages yet. If messages were * restored or otherwise already exist when the widget starts, these messages * are not applied. * * When `resume` is enabled, these messages are not applied. * * `initialUserMessage` is sent after `initialMessages` are applied, so an * assistant welcome followed by a user prompt works. */ initialMessages?: TUiMessage[]; }; export type ChatWidgetDescription = { $$type: 'ais.chat'; renderState: ChatRenderState; indexRenderState: { chat: WidgetRenderState, ChatConnectorParams>; }; }; export type ChatConnector = Connector, ChatConnectorParams>; declare const _default: (renderFn: Renderer, unmountFn?: Unmounter) => >(widgetParams: TWidgetParams & ChatConnectorParams) => { $$type: "ais.chat"; dependsOn: "search" | "none"; init(initOptions: InitOptions): void; render(renderOptions: RenderOptions): void; getRenderState(renderState: IndexRenderState, renderOptions: InitOptions | RenderOptions): IndexRenderState & ChatWidgetDescription["indexRenderState"]; getWidgetRenderState(renderOptions: InitOptions | RenderOptions): WidgetRenderState, TWidgetParams & ChatConnectorParams>; dispose(): void; shouldRender(): true; readonly chatInstance: Chat; }; export default _default;