UNPKG

@kitn.ai/ui

Version:

Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.

67 lines (66 loc) 3.12 kB
import { ToolPart } from './tool'; import { AttachmentData } from './attachments'; /** One assistant response in a comparison. Rendered identically to an assistant * message (reasoning + tools + attachments + markdown content) via `MessageBody`. */ export interface CompareCandidate { /** Stable id, unique within the pair; echoed back in the selection. */ id: string; /** The response text/markdown. */ content: string; /** Optional collapsible reasoning block. */ reasoning?: { text: string; label?: string; }; /** Tool-call parts rendered above the content. */ tools?: ToolPart[]; /** Inline attachment previews rendered above the content. */ attachments?: AttachmentData[]; /** Optional short column label (e.g. "A" / "B" / "Concise"). */ label?: string; /** Optional model name shown as a sub-label. */ model?: string; /** When true this candidate is still streaming — its pick control is disabled * and a per-column shimmer shows until it (and its sibling) settle. */ streaming?: boolean; } /** The two-candidate tuple. Enforced at the type level; validated at runtime by * `normalizeCandidates`. */ export type ComparePair = [CompareCandidate, CompareCandidate]; /** How the card collapses once the user picks. `'winner'` (default) shows just the * chosen candidate's body; `'none'` keeps both columns but marks the choice. */ export type CompareCollapse = 'winner' | 'none'; /** The compare definition (set as the `data` JS property on `<kai-compare>`). */ export interface ResponseCompareData { /** Optional prompt/question shown above the two columns. */ prompt?: string; /** Exactly two candidates: [A, B]. */ candidates: ComparePair; /** Collapse behaviour after a pick. Default `'winner'`. */ collapse?: CompareCollapse; } /** Emitted (and re-hydratable) when the user picks. The consumer pairs * `(prompt, chosenId, rejectedIds)` for preference capture / RLHF. */ export interface CompareSelection { /** The id of the chosen candidate. */ chosenId: string; /** The id(s) of the rejected candidate(s) — for a pair, the other one. */ rejectedIds: string[]; /** Epoch ms when the pick was made. */ at?: number; } /** * Validate + normalize the candidate list. A compare requires EXACTLY two * candidates with unique, non-empty string ids. Returns the usable pair, or an * error message when the definition is unusable (rendered as an inline error / * emitted as a `kai-error`). Modeled on `normalizeOptions`. */ export declare function normalizeCandidates(candidates: unknown): { candidates: ComparePair | null; error?: string; }; /** Build the selection payload for choosing `chosenId` out of the pair (the other * candidate is the rejected one). Stamps `at` with the current time. */ export declare function buildSelection(pair: ComparePair, chosenId: string): CompareSelection; /** Whether any candidate in the pair is still streaming (pick stays disabled). */ export declare function isAnyStreaming(pair: ComparePair | null): boolean;