import { defineWebComponent } from './define'; import { Reasoning, ReasoningTrigger, ReasoningContent, type ReasoningController } from '../components/reasoning'; import { ChatConfig, useChatConfig } from '../primitives/chat-config'; import { wireDisclosure } from './disclosure'; interface Props extends Record { /** The reasoning text to display. */ text: string; /** Trigger label. */ label?: string; /** Drive/observe open state (Shoelace-style: settable + reflected to the `open` * attribute; the element still self-manages on trigger click + while * streaming). Set `el.open = true`; listen for `kai-open-change`. */ open?: boolean; /** Initial open state on mount (uncontrolled seed). */ defaultOpen?: boolean; /** While true, auto-expands (and re-collapses when it flips false). */ streaming?: boolean; /** Render `text` as markdown. */ markdown?: boolean; /** Gate the disclosure trigger — programmatic `show()/hide()/toggle()` still * work, but the trigger click no longer toggles. */ disabled?: boolean; } /** Events fired by ``. */ interface Events { /** The reasoning block expanded or collapsed (via the trigger, streaming * auto-open, or a method). */ 'kai-open-change': { open: boolean }; } /** * `` — a collapsible reasoning/thinking block that auto-expands * while `streaming`. Text via the `text` property; `markdown`/`streaming` flags. * Open state is the standard disclosure surface: settable+reflecting `open`, * `kai-open-change`, and `show()`/`hide()`/`toggle()` (gated by `disabled`); * seed with `defaultOpen`. */ defineWebComponent('kai-reasoning', { text: '', label: 'Reasoning', open: undefined, defaultOpen: undefined, streaming: false, markdown: true, disabled: undefined, }, (props, ctx) => { const { flag } = ctx; const outer = useChatConfig(); let api: ReasoningController | undefined; // The standard disclosure surface: settable+reflecting `open`, kai-open-change, // show/hide/toggle, disabled-gating. See ./disclosure. This is the SOLE emitter // of kai-open-change — we no longer dispatch it from Reasoning's onOpenChange. wireDisclosure(ctx, () => api, () => props.open); return ( (api = a)} > {props.label} {props.text} ); });