import type { Connector, TransformItems, WidgetRenderState } from '../../types'; /** * A record selected for comparison. Only `objectID` is required — the other * attributes (e.g. `name`, `title`) label the item in the UI and travel to the * agent in the turn context. */ export type CompareItem = { objectID: string; } & Record; export type CompareConnectorParams = { /** * Minimum number of items required before a comparison can start. * @default 2 */ minItems?: number; /** * Maximum number of items that can be selected. Adding an item beyond the * limit is a no-op until one is removed. * @default 3 */ maxItems?: number; /** * ID of the comparison configuration created in the Agent Studio dashboard * (Components > Comparison). The chat hand-off sends the * `__ALGOLIA_COMPARISON___` placeholder, which the backend replaces * with the configuration's instructions for the agent; the chat shows no * user message for it, so the shopper goes straight to the comparison. * * Required. */ configurationId: string; /** * Transforms the selection items exposed in the render state (`items`), for * example to drop long attributes from what the bar shows. `compare()` sends * the transformed items to the agent, so what the bar shows is what the * agent receives; `_`-prefixed keys are still stripped from the payload * afterwards. * * The selection itself (`isSelected`, `addItem`, `removeItem`, `canAddItems`, * `canCompare` and the `minItems`/`maxItems` limits) always works on the raw * items, so the transform should map items one to one: do not add or remove * items, and keep each `objectID`. * * It is per widget: `compare()` applies the transform of the widget it is * called from, normally the `compareBar`. * @default items => items */ transformItems?: TransformItems; }; export type CompareRenderState = { /** * Ordered selection, one entry per record (insertion order), after * `transformItems`. */ items: CompareItem[]; /** * Whether a record is currently selected. */ isSelected: (objectID: string) => boolean; /** * Adds a record to the selection. No-op when the record is already selected * or when the `maxItems` limit is reached. */ addItem: (item: CompareItem) => void; /** * Removes a record from the selection. */ removeItem: (objectID: string) => void; /** * Adds the record when unselected, removes it otherwise. */ toggleItem: (item: CompareItem) => void; /** * Clears the whole selection. */ clearItems: () => void; /** * Whether more items can be added (the `maxItems` limit is not reached). */ canAddItems: boolean; /** * Whether a comparison can start (at least `minItems` items are selected). */ canCompare: boolean; /** * The resolved `minItems` value. */ minItems: number; /** * The resolved `maxItems` value. */ maxItems: number; /** * Opens the sibling `chat` widget and sends the comparison placeholder for * the current selection, then clears the selection (which dismisses the * compare bar). Returns `true` when the message was submitted (`false` when the selection is too small, the chat is missing or busy). */ compare: () => boolean; widgetParams: CompareConnectorParams; }; export type CompareWidgetDescription = { $$type: 'ais.compare'; renderState: CompareRenderState; indexRenderState: { compare: WidgetRenderState; }; }; export type CompareConnector = Connector; /** * Builds the placeholder message for a dashboard-configured comparison. The * Agent Studio backend resolves it against the agent's comparison * configuration: the LLM gets the configured instructions, and the persisted * user row holds no text, so the chat renders no user bubble for the hand-off. */ export declare function getComparisonPlaceholderMessage(configurationId: string): string; /** * Compare connector. * * Owns the "products selected for comparison" state and the hand-off into the * chat: `compare()` opens the sibling `chat` widget and sends the configured * comparison's placeholder with the selected records in the turn context, * which the agent answers with the grounded `algolia_compare_products` table. * * The selection is shared across all `compare` widgets mounted on the same * InstantSearch instance, so per-hit "Compare" toggles and the `compareBar` * widget stay in sync. The widget is marked with `opensChat`, so it satisfies * the `chat` widget's entry-point validation. */ declare const connectCompare: CompareConnector; export default connectCompare;