@noodleseed/assistant 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react.ts","../src/appearance.ts","../src/transport.ts","../src/element.ts"],"sourcesContent":["import {\n createElement,\n forwardRef,\n type ReactElement,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\nimport type { AssistantThemeMode } from './appearance.js';\nimport { type NoodleAssistantElement, registerNoodleAssistant } from './element.js';\nimport type { AssistantErrorDetail } from './transport.js';\n\nexport interface NoodleAssistantProps {\n readonly sessionEndpoint: string;\n readonly theme?: AssistantThemeMode;\n readonly open?: boolean;\n readonly className?: string;\n readonly onReady?: () => void;\n readonly onError?: (error: AssistantErrorDetail) => void;\n readonly onSessionExpired?: () => void;\n}\n\nexport const NoodleAssistant = forwardRef<NoodleAssistantElement, NoodleAssistantProps>(\n function NoodleAssistant(props, forwardedRef): ReactElement {\n const ref = useRef<NoodleAssistantElement>(null);\n useImperativeHandle(forwardedRef, () => ref.current as NoodleAssistantElement, []);\n useEffect(() => {\n registerNoodleAssistant();\n const element = ref.current;\n if (!element) return;\n element.sessionEndpoint = props.sessionEndpoint;\n const ready = () => props.onReady?.();\n const error = (event: Event) =>\n props.onError?.((event as CustomEvent<AssistantErrorDetail>).detail);\n const expired = () => props.onSessionExpired?.();\n element.addEventListener('assistant-ready', ready);\n element.addEventListener('assistant-error', error);\n element.addEventListener('assistant-session-expired', expired);\n return () => {\n element.removeEventListener('assistant-ready', ready);\n element.removeEventListener('assistant-error', error);\n element.removeEventListener('assistant-session-expired', expired);\n };\n }, [props.onError, props.onReady, props.onSessionExpired, props.sessionEndpoint]);\n return createElement('noodle-assistant', {\n ref,\n class: props.className,\n 'session-endpoint': props.sessionEndpoint,\n ...(props.theme ? { theme: props.theme } : {}),\n ...(props.open ? { open: '' } : {}),\n });\n },\n);\n","export type AssistantThemeMode = 'auto' | 'light' | 'dark';\nexport type AssistantLayoutMode = 'floating' | 'inline' | 'drawer';\nexport type AssistantPosition = 'bottom-left' | 'bottom-right';\n\nexport interface AssistantThemeTokens {\n readonly page: string;\n readonly panel: string;\n readonly elevated: string;\n readonly input: string;\n readonly hover: string;\n readonly selected: string;\n readonly text: string;\n readonly mutedText: string;\n readonly accent: string;\n readonly accentText: string;\n readonly link: string;\n readonly divider: string;\n readonly focus: string;\n readonly success: string;\n readonly warning: string;\n readonly danger: string;\n readonly overlay: string;\n readonly code: string;\n readonly widgetFrame: string;\n readonly fontFamily: string;\n readonly monoFontFamily: string;\n readonly baseFontSize: number;\n readonly messageFontSize: number;\n readonly lineHeight: number;\n readonly panelRadius: number;\n readonly cardRadius: number;\n readonly inputRadius: number;\n readonly buttonRadius: number;\n readonly launcherRadius: number;\n readonly spacing: number;\n readonly shadow: string;\n readonly backdropBlur: number;\n readonly motionScale: number;\n}\n\nexport interface AssistantConfiguration {\n readonly branding?: {\n readonly name?: string;\n readonly accent?: string;\n readonly surface?: string;\n readonly surfaceDark?: string;\n readonly logo?: AssistantBrandAsset;\n readonly mark?: AssistantBrandAsset;\n readonly avatar?: AssistantBrandAsset;\n readonly theme?: {\n readonly light?: BrandThemeOverrides;\n readonly dark?: BrandThemeOverrides;\n };\n readonly radius?: 'none' | 'sm' | 'md' | 'lg';\n readonly density?: 'compact' | 'comfortable';\n readonly typography?: 'system' | 'serif' | 'mono';\n readonly colorScheme?: AssistantThemeMode;\n };\n readonly assistant?: AssistantUiConfiguration;\n}\n\ninterface AssistantBrandAsset {\n readonly uri: string;\n readonly darkUri?: string;\n readonly alt: string;\n}\n\ninterface BrandThemeOverrides {\n readonly surface?: string;\n readonly surfaceRaised?: string;\n readonly surfaceMuted?: string;\n readonly text?: string;\n readonly textMuted?: string;\n readonly accent?: string;\n readonly accentText?: string;\n readonly link?: string;\n readonly border?: string;\n readonly borderStrong?: string;\n readonly focus?: string;\n readonly success?: string;\n readonly warning?: string;\n readonly danger?: string;\n readonly code?: string;\n}\n\ninterface AssistantUiConfiguration {\n readonly layout?: {\n readonly mode?: AssistantLayoutMode;\n readonly position?: AssistantPosition;\n readonly panelWidth?: number;\n readonly panelMinHeight?: number;\n readonly panelMaxHeight?: number;\n readonly zIndex?: number;\n readonly density?: 'compact' | 'comfortable';\n readonly mobileFullscreen?: boolean;\n };\n readonly behavior?: {\n readonly startOpen?: boolean;\n readonly closeOnEscape?: boolean;\n readonly closeOnOutsideClick?: boolean;\n readonly showLauncher?: boolean;\n readonly showHeader?: boolean;\n readonly showAvatars?: boolean;\n readonly showTimestamps?: boolean;\n };\n readonly labels?: Partial<AssistantLabels>;\n readonly suggestedPrompts?: readonly string[];\n readonly privacyUrl?: string;\n readonly termsUrl?: string;\n readonly locale?: string;\n readonly direction?: 'ltr' | 'rtl' | 'auto';\n}\n\nexport interface AssistantLabels {\n readonly welcomeHeading: string;\n readonly welcomeMessage: string;\n readonly composerPlaceholder: string;\n readonly send: string;\n readonly stop: string;\n readonly close: string;\n readonly open: string;\n readonly confirm: string;\n readonly cancel: string;\n readonly retry: string;\n readonly unavailable: string;\n readonly sessionExpired: string;\n}\n\nexport interface ResolvedAssistantAppearance {\n readonly brand: {\n readonly name: string;\n readonly logo: { readonly light?: string; readonly dark?: string };\n readonly avatar: { readonly light?: string; readonly dark?: string };\n readonly mark: { readonly light?: string; readonly dark?: string };\n };\n readonly theme: {\n readonly defaultMode: AssistantThemeMode;\n readonly light: AssistantThemeTokens;\n readonly dark: AssistantThemeTokens;\n };\n readonly layout: {\n readonly mode: AssistantLayoutMode;\n readonly position: AssistantPosition;\n readonly panelWidth: number;\n readonly panelMinHeight: number;\n readonly panelMaxHeight: number;\n readonly zIndex: number;\n readonly density: 'compact' | 'comfortable';\n readonly mobileFullscreen: boolean;\n };\n readonly behavior: {\n readonly startOpen: boolean;\n readonly closeOnEscape: boolean;\n readonly closeOnOutsideClick: boolean;\n readonly showLauncher: boolean;\n readonly showHeader: boolean;\n readonly showAvatars: boolean;\n readonly showTimestamps: boolean;\n };\n readonly labels: AssistantLabels;\n readonly suggestedPrompts: readonly string[];\n readonly privacyUrl?: string;\n readonly termsUrl?: string;\n readonly locale: string;\n readonly direction: 'ltr' | 'rtl' | 'auto';\n}\n\nconst common = {\n fontFamily: 'inherit',\n monoFontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n baseFontSize: 15,\n messageFontSize: 15,\n lineHeight: 1.5,\n panelRadius: 20,\n cardRadius: 14,\n inputRadius: 14,\n buttonRadius: 12,\n launcherRadius: 999,\n spacing: 12,\n backdropBlur: 18,\n motionScale: 1,\n} as const;\n\nexport const DEFAULT_APPEARANCE: ResolvedAssistantAppearance = {\n brand: { name: 'Assistant', logo: {}, avatar: {}, mark: {} },\n theme: {\n defaultMode: 'auto',\n light: {\n ...common,\n page: '#F7F7F8',\n panel: '#FFFFFF',\n elevated: '#FFFFFF',\n input: '#F1F1F3',\n hover: '#ECECEF',\n selected: '#E4E2FF',\n text: '#18181B',\n mutedText: '#71717A',\n accent: '#5B4CF0',\n accentText: '#FFFFFF',\n link: '#4A3BD5',\n divider: '#E4E4E7',\n focus: '#5B4CF0',\n success: '#16835D',\n warning: '#A45B00',\n danger: '#C92A45',\n overlay: '#18181B66',\n code: '#F1F1F3',\n widgetFrame: '#E4E4E7',\n shadow: '0 24px 80px rgba(24, 24, 27, 0.18)',\n },\n dark: {\n ...common,\n page: '#111113',\n panel: '#19191D',\n elevated: '#222228',\n input: '#26262C',\n hover: '#303038',\n selected: '#37315F',\n text: '#FAFAFA',\n mutedText: '#A1A1AA',\n accent: '#A99FFF',\n accentText: '#17131F',\n link: '#B9B1FF',\n divider: '#34343B',\n focus: '#B9B1FF',\n success: '#58C69A',\n warning: '#F2B45F',\n danger: '#FF8094',\n overlay: '#00000099',\n code: '#26262C',\n widgetFrame: '#34343B',\n shadow: '0 24px 90px rgba(0, 0, 0, 0.55)',\n },\n },\n layout: {\n mode: 'floating',\n position: 'bottom-right',\n panelWidth: 400,\n panelMinHeight: 420,\n panelMaxHeight: 720,\n zIndex: 2147483000,\n density: 'comfortable',\n mobileFullscreen: true,\n },\n behavior: {\n startOpen: false,\n closeOnEscape: true,\n closeOnOutsideClick: false,\n showLauncher: true,\n showHeader: true,\n showAvatars: true,\n showTimestamps: false,\n },\n labels: {\n welcomeHeading: 'How can I help?',\n welcomeMessage: '',\n composerPlaceholder: 'Ask a question…',\n send: 'Send',\n stop: 'Stop',\n close: 'Close assistant',\n open: 'Open assistant',\n confirm: 'Confirm',\n cancel: 'Cancel',\n retry: 'Try again',\n unavailable: 'The assistant is temporarily unavailable.',\n sessionExpired: 'Your assistant session expired. Reopen it to continue.',\n },\n suggestedPrompts: [],\n locale: 'en',\n direction: 'auto',\n};\n\nexport function resolveAppearance(input: AssistantConfiguration = {}): ResolvedAssistantAppearance {\n const branding = input.branding;\n const assistant = input.assistant;\n return {\n brand: {\n ...DEFAULT_APPEARANCE.brand,\n ...(branding?.name ? { name: branding.name } : {}),\n logo: themedAsset(branding?.logo),\n avatar: themedAsset(branding?.avatar),\n mark: themedAsset(branding?.mark),\n },\n theme: {\n defaultMode: branding?.colorScheme ?? DEFAULT_APPEARANCE.theme.defaultMode,\n light: resolveTheme('light', branding),\n dark: resolveTheme('dark', branding),\n },\n layout: {\n ...DEFAULT_APPEARANCE.layout,\n ...(branding?.density ? { density: branding.density } : {}),\n ...assistant?.layout,\n },\n behavior: { ...DEFAULT_APPEARANCE.behavior, ...assistant?.behavior },\n labels: { ...DEFAULT_APPEARANCE.labels, ...assistant?.labels },\n suggestedPrompts: assistant?.suggestedPrompts ?? DEFAULT_APPEARANCE.suggestedPrompts,\n ...(assistant?.privacyUrl ? { privacyUrl: assistant.privacyUrl } : {}),\n ...(assistant?.termsUrl ? { termsUrl: assistant.termsUrl } : {}),\n locale: assistant?.locale ?? DEFAULT_APPEARANCE.locale,\n direction: assistant?.direction ?? DEFAULT_APPEARANCE.direction,\n };\n}\n\nfunction themedAsset(asset: AssistantBrandAsset | undefined): {\n readonly light?: string;\n readonly dark?: string;\n} {\n return asset ? { light: asset.uri, dark: asset.darkUri ?? asset.uri } : {};\n}\n\nfunction resolveTheme(\n mode: 'light' | 'dark',\n branding: AssistantConfiguration['branding'],\n): AssistantThemeTokens {\n const defaults = DEFAULT_APPEARANCE.theme[mode];\n const surface = mode === 'light' ? branding?.surface : branding?.surfaceDark;\n const portable = branding?.theme?.[mode];\n const radius = branding?.radius ? radiusValue(branding.radius) : undefined;\n return {\n ...defaults,\n ...(branding?.accent ? { accent: branding.accent } : {}),\n ...(surface ? { page: surface, panel: surface } : {}),\n ...mapPortableTheme(portable),\n ...(radius === undefined\n ? {}\n : {\n panelRadius: radius,\n cardRadius: radius,\n inputRadius: Math.max(0, radius - 2),\n buttonRadius: Math.max(0, radius - 2),\n }),\n ...(branding?.typography === 'serif'\n ? { fontFamily: 'ui-serif, Georgia, serif' }\n : branding?.typography === 'mono'\n ? { fontFamily: defaults.monoFontFamily }\n : {}),\n };\n}\n\nfunction mapPortableTheme(input: BrandThemeOverrides | undefined): Partial<AssistantThemeTokens> {\n if (!input) return {};\n return {\n ...(input.surface ? { page: input.surface, panel: input.surface } : {}),\n ...(input.surfaceRaised ? { elevated: input.surfaceRaised } : {}),\n ...(input.surfaceMuted\n ? { input: input.surfaceMuted, hover: input.surfaceMuted, selected: input.surfaceMuted }\n : {}),\n ...(input.text ? { text: input.text } : {}),\n ...(input.textMuted ? { mutedText: input.textMuted } : {}),\n ...(input.accent ? { accent: input.accent } : {}),\n ...(input.accentText ? { accentText: input.accentText } : {}),\n ...(input.link ? { link: input.link } : {}),\n ...(input.border ? { divider: input.border, widgetFrame: input.border } : {}),\n ...(input.focus ? { focus: input.focus } : {}),\n ...(input.success ? { success: input.success } : {}),\n ...(input.warning ? { warning: input.warning } : {}),\n ...(input.danger ? { danger: input.danger } : {}),\n ...(input.code ? { code: input.code } : {}),\n };\n}\n\nfunction radiusValue(radius: 'none' | 'sm' | 'md' | 'lg'): number {\n if (radius === 'none') return 0;\n if (radius === 'sm') return 8;\n if (radius === 'lg') return 18;\n return 14;\n}\n","export interface AssistantEvent {\n readonly event: string;\n readonly data: Readonly<Record<string, unknown>>;\n}\n\nexport interface AssistantErrorDetail {\n readonly code: string;\n readonly status?: number;\n readonly retryable: boolean;\n}\n\n/**\n * A 2xx response whose body carried no assistant events at all — typically an auth redirect or\n * proxy page returning HTML with a 200. Silently rendering nothing strands the end user, so the\n * transport fails loudly instead (ADR 0151 hardening).\n */\nexport class AssistantTransportError extends Error {\n readonly code = 'invalid_response' as const;\n\n constructor(contentType: string) {\n super(`assistant response was not an event stream (content-type: ${contentType || 'unknown'})`);\n this.name = 'AssistantTransportError';\n }\n}\n\n/** Consume JSON-bearing server-sent events without buffering the whole assistant turn. */\nexport async function consumeAssistantEvents(\n response: Response,\n onEvent: (event: AssistantEvent) => void,\n): Promise<void> {\n let delivered = 0;\n let sawText = false;\n const deliver = (event: AssistantEvent): void => {\n delivered += 1;\n onEvent(event);\n };\n if (!response.body) {\n const text = await response.text();\n sawText = text.trim().length > 0;\n emitFrames(text, deliver, true);\n } else {\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let pending = '';\n while (true) {\n const { done, value } = await reader.read();\n const chunk = decoder.decode(value, { stream: !done });\n if (!sawText && chunk.trim().length > 0) sawText = true;\n pending += chunk;\n pending = emitFrames(pending, deliver, done);\n if (done) break;\n }\n }\n if (delivered === 0 && sawText) {\n throw new AssistantTransportError(response.headers.get('content-type') ?? '');\n }\n}\n\nfunction emitFrames(\n input: string,\n onEvent: (event: AssistantEvent) => void,\n flush: boolean,\n): string {\n const normalized = input.replaceAll('\\r\\n', '\\n').replaceAll('\\r', '\\n');\n const frames = normalized.split('\\n\\n');\n const pending = flush ? '' : (frames.pop() ?? '');\n for (const frame of frames) {\n const event = parseFrame(frame);\n if (event) onEvent(event);\n }\n if (flush && frames.length === 0 && normalized.trim()) {\n const event = parseFrame(normalized);\n if (event) onEvent(event);\n }\n return pending;\n}\n\nfunction parseFrame(frame: string): AssistantEvent | undefined {\n let event = 'message';\n const data: string[] = [];\n for (const line of frame.split('\\n')) {\n if (line.startsWith(':')) continue;\n const separator = line.indexOf(':');\n const field = separator < 0 ? line : line.slice(0, separator);\n const value = separator < 0 ? '' : line.slice(separator + 1).replace(/^ /, '');\n if (field === 'event') event = value;\n if (field === 'data') data.push(value);\n }\n if (data.length === 0) return undefined;\n try {\n return { event, data: JSON.parse(data.join('\\n')) as Readonly<Record<string, unknown>> };\n } catch {\n return undefined;\n }\n}\n","import {\n type AssistantConfiguration,\n type AssistantThemeMode,\n type AssistantThemeTokens,\n resolveAppearance,\n} from './appearance.js';\nimport {\n type AssistantErrorDetail,\n AssistantTransportError,\n consumeAssistantEvents,\n} from './transport.js';\n\nexport const ASSISTANT_TAG_NAME = 'noodle-assistant';\nconst HTMLElementBase: typeof HTMLElement =\n globalThis.HTMLElement ?? (class {} as unknown as typeof HTMLElement);\n\ninterface SessionResponse {\n readonly token: string;\n readonly expiresAt: string;\n readonly endpoints: {\n readonly turns: string;\n readonly toolConfirmations: string;\n };\n readonly configuration?: AssistantConfiguration;\n}\n\nexport class NoodleAssistantElement extends HTMLElementBase {\n static readonly observedAttributes = ['open', 'theme'];\n #appearance = resolveAppearance();\n #session: SessionResponse | undefined;\n #messages: HTMLElement | undefined;\n #media: MediaQueryList | undefined;\n #context: Readonly<Record<string, string | number | boolean | null>> | undefined;\n sessionEndpoint = '';\n\n connectedCallback(): void {\n if (!this.shadowRoot) this.attachShadow({ mode: 'open' });\n if (!this.sessionEndpoint) this.sessionEndpoint = this.getAttribute('session-endpoint') ?? '';\n this.#media = globalThis.matchMedia?.('(prefers-color-scheme: dark)');\n this.#media?.addEventListener('change', this.#handleSystemTheme);\n document.addEventListener('keydown', this.#handleDocumentKeydown);\n document.addEventListener('pointerdown', this.#handleDocumentPointerDown);\n if (this.#appearance.behavior.startOpen) this.setAttribute('open', '');\n this.#render();\n this.dispatchEvent(new CustomEvent('assistant-ready'));\n }\n\n disconnectedCallback(): void {\n this.#media?.removeEventListener('change', this.#handleSystemTheme);\n document.removeEventListener('keydown', this.#handleDocumentKeydown);\n document.removeEventListener('pointerdown', this.#handleDocumentPointerDown);\n }\n\n attributeChangedCallback(name: string): void {\n if (name === 'theme') this.#applyTheme();\n }\n\n open(): void {\n this.setAttribute('open', '');\n this.dispatchEvent(new CustomEvent('assistant-open'));\n }\n\n close(): void {\n this.removeAttribute('open');\n this.dispatchEvent(new CustomEvent('assistant-close'));\n }\n\n toggle(): void {\n this.hasAttribute('open') ? this.close() : this.open();\n }\n\n focusComposer(): void {\n this.shadowRoot?.querySelector<HTMLTextAreaElement>('textarea')?.focus();\n }\n\n resetSession(): void {\n this.#session = undefined;\n this.#messages?.replaceChildren();\n this.dispatchEvent(new CustomEvent('assistant-session-reset'));\n }\n\n updateContext(context: Readonly<Record<string, string | number | boolean | null>>): void {\n this.#context = { ...context };\n this.dispatchEvent(new CustomEvent('assistant-context-changed', { detail: { context } }));\n }\n\n async sendMessage(text: string): Promise<void> {\n const message = text.trim();\n if (!message) return;\n if (!this.#session) this.#session = await this.#createSession();\n this.#appendMessage('user', message);\n this.dispatchEvent(new CustomEvent('assistant-message-started'));\n await this.#sendTurn(message, true);\n }\n\n async #sendTurn(message: string, mayRetry: boolean): Promise<void> {\n if (!this.#session) this.#session = await this.#createSession();\n const response = await fetch(this.#session.endpoints.turns, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.#session.token}`,\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n },\n body: JSON.stringify({ message }),\n });\n if (response.status === 401 && mayRetry) {\n this.#session = undefined;\n this.dispatchEvent(new CustomEvent('assistant-session-expired'));\n await this.#sendTurn(message, false);\n return;\n }\n if (!response.ok) {\n this.#dispatchError({ code: 'turn_failed', status: response.status, retryable: false });\n throw new Error(`Assistant turn failed (${response.status})`);\n }\n let assistantBody: HTMLElement | undefined;\n try {\n await consumeAssistantEvents(response, (event) => {\n if (event.event === 'content') {\n const body = assistantBody ?? this.#appendMessage('assistant', '');\n assistantBody = body;\n if (body) body.textContent += String(event.data.delta ?? '');\n }\n if (event.event === 'tool_proposed') {\n this.#appendToolProposal(\n String(event.data.id ?? ''),\n String(event.data.tool ?? 'Action'),\n );\n }\n if (event.event === 'error') {\n this.#dispatchError({\n code: String(event.data.code ?? 'stream_failed'),\n retryable: event.data.retryable === true,\n });\n }\n });\n } catch (error) {\n if (error instanceof AssistantTransportError) {\n this.#dispatchError({ code: error.code, retryable: false });\n }\n throw error;\n }\n this.dispatchEvent(new CustomEvent('assistant-message-completed'));\n }\n\n /**\n * Every listener the element attaches to its own DOM must go through this guard: internal UI\n * failures surface as `assistant-error` events (already dispatched by the failing path) and must\n * never escape as unhandled rejections into the embedding page. Programmatic callers use\n * `sendMessage`/`confirmTool` directly and keep the rejection.\n */\n #sendGuarded(text: string): void {\n void this.sendMessage(text).catch(() => {});\n }\n\n async confirmTool(id: string): Promise<void> {\n if (!this.#session) {\n this.#dispatchError({ code: 'confirmation_expired', retryable: false });\n throw new Error('assistant session is not active');\n }\n const response = await fetch(this.#session.endpoints.toolConfirmations, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.#session.token}`,\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n },\n body: JSON.stringify({ id }),\n });\n if (!response.ok) {\n const expired = response.status === 401 || response.status === 409;\n if (response.status === 401) {\n this.#session = undefined;\n this.dispatchEvent(new CustomEvent('assistant-session-expired'));\n }\n this.#dispatchError({\n code: expired ? 'confirmation_expired' : 'confirmation_failed',\n status: response.status,\n retryable: false,\n });\n throw new Error(`Assistant confirmation failed (${response.status})`);\n }\n let completed: Readonly<Record<string, unknown>> | undefined;\n let narrationBody: HTMLElement | undefined;\n await consumeAssistantEvents(response, (event) => {\n if (event.event === 'tool_completed') completed = event.data;\n if (event.event === 'content') {\n const body = narrationBody ?? this.#appendMessage('assistant', '');\n narrationBody = body;\n if (body) body.textContent += String(event.data.delta ?? '');\n }\n });\n // The narrated reply supersedes the raw result; older services send only tool_completed,\n // so the JSON rendering remains as the fallback.\n if (completed && !narrationBody) {\n this.#appendMessage('assistant', JSON.stringify(completed.result ?? {}));\n }\n this.dispatchEvent(new CustomEvent('assistant-tool-completed', { detail: { id } }));\n }\n\n #handleSystemTheme = (): void => this.#applyTheme();\n\n #handleDocumentKeydown = (event: KeyboardEvent): void => {\n if (\n event.key === 'Escape' &&\n this.hasAttribute('open') &&\n this.#appearance.behavior.closeOnEscape\n ) {\n this.close();\n }\n };\n\n #handleDocumentPointerDown = (event: PointerEvent): void => {\n if (\n this.hasAttribute('open') &&\n this.#appearance.behavior.closeOnOutsideClick &&\n !event.composedPath().includes(this)\n ) {\n this.close();\n }\n };\n\n async #createSession(): Promise<SessionResponse> {\n if (!this.sessionEndpoint) throw new Error('sessionEndpoint is required');\n let response: Response;\n try {\n response = await fetch(this.sessionEndpoint, {\n method: 'POST',\n headers: { Accept: 'application/json', 'Content-Type': 'application/json' },\n body: JSON.stringify(this.#context ? { context: this.#context } : {}),\n credentials: 'same-origin',\n });\n } catch (error) {\n this.#dispatchError({ code: 'session_failed', retryable: true });\n throw error;\n }\n if (!response.ok) {\n this.#dispatchError({ code: 'session_failed', status: response.status, retryable: true });\n throw new Error(`Assistant session failed (${response.status})`);\n }\n let session: SessionResponse;\n try {\n session = (await response.json()) as SessionResponse;\n } catch (error) {\n this.#dispatchError({ code: 'session_failed', retryable: true });\n throw error;\n }\n if (session.configuration) {\n this.#appearance = resolveAppearance(session.configuration);\n this.#render();\n }\n this.dispatchEvent(\n new CustomEvent('assistant-session-started', { detail: { expiresAt: session.expiresAt } }),\n );\n return session;\n }\n\n #appendMessage(role: 'user' | 'assistant', text: string): HTMLElement | undefined {\n if (!this.#messages) return undefined;\n const message = document.createElement('div');\n message.className = `message ${role}`;\n if (\n role === 'assistant' &&\n this.#appearance.behavior.showAvatars &&\n this.#appearance.brand.avatar[this.#resolvedMode()]\n ) {\n const avatar = document.createElement('img');\n avatar.className = 'avatar';\n avatar.src = this.#appearance.brand.avatar[this.#resolvedMode()] ?? '';\n avatar.alt = '';\n message.append(avatar);\n }\n const body = document.createElement('span');\n body.textContent = text;\n message.append(body);\n if (this.#appearance.behavior.showTimestamps) {\n const timestamp = document.createElement('time');\n timestamp.dateTime = new Date().toISOString();\n timestamp.textContent = new Intl.DateTimeFormat(this.#appearance.locale, {\n hour: 'numeric',\n minute: '2-digit',\n }).format(new Date());\n message.append(timestamp);\n }\n this.#messages.append(message);\n return body;\n }\n\n #dispatchError(detail: AssistantErrorDetail): void {\n this.dispatchEvent(new CustomEvent('assistant-error', { detail }));\n }\n\n #appendToolProposal(id: string, tool: string): void {\n if (!this.#messages || !id) return;\n const card = document.createElement('section');\n card.className = 'tool-proposal';\n const label = document.createElement('strong');\n label.textContent = tool;\n const confirm = document.createElement('button');\n confirm.type = 'button';\n confirm.textContent = this.#appearance.labels.confirm;\n confirm.addEventListener('click', () => {\n confirm.disabled = true;\n void this.confirmTool(id).catch(() => {\n confirm.disabled = false;\n this.dispatchEvent(\n new CustomEvent('assistant-error', { detail: { code: 'confirmation_failed' } }),\n );\n });\n });\n const cancel = document.createElement('button');\n cancel.type = 'button';\n cancel.textContent = this.#appearance.labels.cancel;\n cancel.addEventListener('click', () => card.remove());\n card.append(label, confirm, cancel);\n this.#messages.append(card);\n this.dispatchEvent(new CustomEvent('assistant-tool-proposed', { detail: { id, tool } }));\n }\n\n #resolvedMode(): Exclude<AssistantThemeMode, 'auto'> {\n const configured =\n (this.getAttribute('theme') as AssistantThemeMode | null) ??\n this.#appearance.theme.defaultMode;\n return configured === 'auto' ? (this.#media?.matches ? 'dark' : 'light') : configured;\n }\n\n #applyTheme(): void {\n const mode = this.#resolvedMode();\n this.setAttribute('data-theme', mode);\n const tokens = this.#appearance.theme[mode];\n for (const [name, value] of Object.entries(tokens)) {\n this.style.setProperty(\n `--ns-assistant-default-${camelToKebab(name)}`,\n tokenValue(name, value),\n );\n }\n this.style.setProperty(\n '--ns-assistant-default-panel-width',\n `${this.#appearance.layout.panelWidth}px`,\n );\n this.style.setProperty(\n '--ns-assistant-default-min-height',\n `${this.#appearance.layout.panelMinHeight}px`,\n );\n this.style.setProperty(\n '--ns-assistant-default-max-height',\n `${this.#appearance.layout.panelMaxHeight}px`,\n );\n this.style.setProperty(\n '--ns-assistant-default-z-index',\n String(this.#appearance.layout.zIndex),\n );\n const logo = this.shadowRoot?.querySelector<HTMLImageElement>('.brand-logo');\n const logoUrl = this.#appearance.brand.logo[mode];\n if (logo) {\n logo.hidden = !logoUrl;\n if (logoUrl) logo.src = logoUrl;\n }\n }\n\n #render(): void {\n if (!this.shadowRoot) return;\n const appearance = this.#appearance;\n this.setAttribute('role', 'complementary');\n this.setAttribute('aria-label', appearance.brand.name);\n this.setAttribute('lang', appearance.locale);\n this.setAttribute('dir', appearance.direction);\n this.dataset.mode = appearance.layout.mode;\n this.dataset.position = appearance.layout.position;\n this.dataset.density = appearance.layout.density;\n this.toggleAttribute('mobile-fullscreen', appearance.layout.mobileFullscreen);\n this.shadowRoot.innerHTML = `${styles}\n <button class=\"launcher\" type=\"button\" aria-label=\"${escapeAttribute(appearance.labels.open)}\"><slot name=\"launcher-icon\">✦</slot></button>\n <section class=\"panel\" aria-label=\"${escapeAttribute(appearance.brand.name)}\">\n <header><slot name=\"header-leading\"></slot><img class=\"brand-logo\" alt=\"\"><strong></strong><slot name=\"header-actions\"></slot><button class=\"close\" type=\"button\" aria-label=\"${escapeAttribute(appearance.labels.close)}\">×</button></header>\n <div class=\"welcome\"><slot name=\"empty-state\"><h2></h2><p></p></slot></div>\n <div class=\"suggested-prompts\"></div>\n <div class=\"messages\" aria-live=\"polite\"></div>\n <form><slot name=\"composer-leading\"></slot><textarea rows=\"1\"></textarea><button class=\"send\" type=\"submit\"></button><slot name=\"composer-trailing\"></slot></form>\n <nav class=\"legal\" aria-label=\"Legal\"></nav>\n <slot name=\"conversation-footer\"></slot>\n </section>`;\n queryRequired<HTMLElement>(this.shadowRoot, 'strong').textContent = appearance.brand.name;\n const launcherIcon = appearance.brand.mark[this.#resolvedMode()];\n if (launcherIcon) {\n const launcherSlot = queryRequired<HTMLSlotElement>(\n this.shadowRoot,\n 'slot[name=\"launcher-icon\"]',\n );\n const icon = document.createElement('img');\n icon.src = launcherIcon;\n icon.alt = '';\n launcherSlot.replaceChildren(icon);\n }\n const logo = queryRequired<HTMLImageElement>(this.shadowRoot, '.brand-logo');\n const logoUrl = appearance.brand.logo[this.#resolvedMode()];\n if (logoUrl) {\n logo.src = logoUrl;\n logo.alt = appearance.brand.name;\n } else {\n logo.hidden = true;\n }\n queryRequired<HTMLElement>(this.shadowRoot, 'h2').textContent =\n appearance.labels.welcomeHeading;\n queryRequired<HTMLElement>(this.shadowRoot, 'p').textContent = appearance.labels.welcomeMessage;\n const textarea = queryRequired<HTMLTextAreaElement>(this.shadowRoot, 'textarea');\n textarea.placeholder = appearance.labels.composerPlaceholder;\n textarea.setAttribute('aria-label', appearance.labels.composerPlaceholder);\n queryRequired<HTMLElement>(this.shadowRoot, '.send').textContent = appearance.labels.send;\n const prompts = queryRequired<HTMLElement>(this.shadowRoot, '.suggested-prompts');\n for (const prompt of appearance.suggestedPrompts) {\n const button = document.createElement('button');\n button.type = 'button';\n button.textContent = prompt;\n button.addEventListener('click', () => this.#sendGuarded(prompt));\n prompts.append(button);\n }\n if (!appearance.behavior.showLauncher)\n queryRequired<HTMLElement>(this.shadowRoot, '.launcher').hidden = true;\n if (!appearance.behavior.showHeader)\n queryRequired<HTMLElement>(this.shadowRoot, 'header').hidden = true;\n const legal = queryRequired<HTMLElement>(this.shadowRoot, '.legal');\n for (const [label, href] of [\n ['Privacy', appearance.privacyUrl],\n ['Terms', appearance.termsUrl],\n ] as const) {\n if (!href) continue;\n const link = document.createElement('a');\n link.href = href;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n link.textContent = label;\n legal.append(link);\n }\n this.#messages = this.shadowRoot.querySelector('.messages') ?? undefined;\n this.shadowRoot.querySelector('.launcher')?.addEventListener('click', () => this.open());\n this.shadowRoot.querySelector('.close')?.addEventListener('click', () => this.close());\n this.shadowRoot.querySelector('form')?.addEventListener('submit', (event) => {\n event.preventDefault();\n const value = textarea.value;\n textarea.value = '';\n this.#sendGuarded(value);\n });\n this.#applyTheme();\n }\n}\n\nexport function registerNoodleAssistant(): void {\n if (globalThis.customElements && !customElements.get(ASSISTANT_TAG_NAME)) {\n customElements.define(ASSISTANT_TAG_NAME, NoodleAssistantElement);\n }\n}\n\nfunction camelToKebab(value: string): string {\n return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n\nfunction tokenValue(name: string, value: AssistantThemeTokens[keyof AssistantThemeTokens]): string {\n if (typeof value !== 'number') return value;\n if (name === 'lineHeight' || name === 'motionScale') return String(value);\n return `${value}px`;\n}\n\nfunction escapeAttribute(value: string): string {\n return value.replaceAll('&', '&amp;').replaceAll('\"', '&quot;').replaceAll('<', '&lt;');\n}\n\nfunction queryRequired<T extends Element>(root: ShadowRoot, selector: string): T {\n const element = root.querySelector<T>(selector);\n if (!element) throw new Error(`assistant renderer is missing ${selector}`);\n return element;\n}\n\nconst styles = `<style>\n :host { color-scheme: light dark; font-family: var(--ns-assistant-font-family, var(--ns-assistant-default-font-family)); font-size: var(--ns-assistant-base-font-size, var(--ns-assistant-default-base-font-size)); line-height: var(--ns-assistant-line-height, var(--ns-assistant-default-line-height)); z-index: var(--ns-assistant-z-index, var(--ns-assistant-default-z-index)); }\n :host([data-mode=\"floating\"]) { position: fixed; bottom: 24px; right: 24px; }\n :host([data-mode=\"floating\"][data-position=\"bottom-left\"]) { right: auto; left: 24px; }\n .launcher { width: 54px; height: 54px; border: 0; border-radius: var(--ns-assistant-launcher-radius, var(--ns-assistant-default-launcher-radius)); color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); cursor: pointer; }\n .launcher img { width: 24px; height: 24px; object-fit: contain; }\n .panel { display: none; width: min(var(--ns-assistant-panel-width, var(--ns-assistant-default-panel-width)), calc(100vw - 32px)); min-height: var(--ns-assistant-min-height, var(--ns-assistant-default-min-height)); max-height: min(var(--ns-assistant-max-height, var(--ns-assistant-default-max-height)), calc(100vh - 32px)); overflow: hidden; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-panel, var(--ns-assistant-default-panel)); border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-default-panel-radius)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); }\n :host([open]) .panel { display: grid; grid-template-rows: auto auto 1fr auto; }\n :host([open]) .launcher { display: none; }\n header { display: flex; gap: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); align-items: center; padding: calc(var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)) * 1.2); border-bottom: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); }\n header strong { flex: 1; }\n .brand-logo { display: block; max-width: 120px; max-height: 28px; object-fit: contain; }\n button { font: inherit; }\n .close, .send { border: 0; border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); cursor: pointer; }\n .close { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent; font-size: 24px; }\n .welcome { padding: calc(var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)) * 1.5); }\n .welcome h2 { margin: 0; font-size: 1.25em; }\n .welcome p { margin: 6px 0 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }\n .suggested-prompts { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); }\n .suggested-prompts:empty { display: none; }\n .suggested-prompts button { padding: 7px 10px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: transparent; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; cursor: pointer; }\n .messages { min-height: 120px; padding: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); overflow: auto; }\n .message { width: fit-content; max-width: 84%; margin: 8px 0; padding: 10px 12px; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); white-space: pre-wrap; }\n .message .avatar { float: left; width: 24px; height: 24px; margin-right: 8px; border-radius: 50%; object-fit: cover; }\n .message time { display: block; margin-top: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .75em; }\n .message.user { margin-left: auto; color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }\n .tool-proposal { display: grid; grid-template-columns: 1fr auto auto; gap: 8px; align-items: center; margin: 10px 0; padding: 12px; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); }\n .tool-proposal button { padding: 8px 10px; border: 0; border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); cursor: pointer; }\n .tool-proposal button:first-of-type { color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }\n form { display: flex; gap: 8px; align-items: end; padding: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); border-top: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); }\n textarea { flex: 1; resize: none; padding: 10px 12px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); border: 0; border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius)); font: inherit; }\n textarea:focus-visible, button:focus-visible { outline: 3px solid var(--ns-assistant-focus, var(--ns-assistant-default-focus)); outline-offset: 2px; }\n .send { padding: 10px 14px; color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }\n .legal { display: flex; gap: 12px; justify-content: center; padding: 0 12px 10px; font-size: .8em; }\n .legal:empty { display: none; }\n .legal a { color: var(--ns-assistant-link, var(--ns-assistant-default-link)); }\n :host([data-density=\"compact\"]) .welcome { padding: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); }\n @media (max-width: 640px) { :host([mobile-fullscreen][open]) { inset: 0; } :host([mobile-fullscreen][open]) .panel { width: 100vw; min-height: 100vh; max-height: 100vh; border-radius: 0; } }\n @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; } }\n @media (max-width: 560px) { :host([data-mode=\"floating\"]) { inset: auto 12px 12px; } :host([open]) .panel { width: calc(100vw - 24px); max-height: calc(100vh - 24px); } }\n</style>`;\n"],"mappings":"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","names":["NoodleAssistant"]}
1
+ {"version":3,"sources":["../src/react.ts","../src/appearance.ts","../src/browser-context.ts","../src/events.ts","../src/model-context.ts","../src/transport.ts","../src/client.ts","../src/input-request-card.ts","../src/interaction-card.ts","../src/element-event-controller.ts","../src/element-styles.ts","../src/element.ts"],"sourcesContent":["import {\n createElement,\n forwardRef,\n type ReactElement,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\nimport type { AssistantThemeMode } from './appearance.js';\nimport { type NoodleAssistantElement, registerNoodleAssistant } from './element.js';\nimport type { AssistantErrorDetail } from './transport.js';\n\nexport interface NoodleAssistantProps {\n readonly sessionEndpoint: string;\n readonly theme?: AssistantThemeMode;\n readonly open?: boolean;\n readonly className?: string;\n readonly onReady?: () => void;\n readonly onError?: (error: AssistantErrorDetail) => void;\n readonly onSessionExpired?: () => void;\n}\n\nexport const NoodleAssistant = forwardRef<NoodleAssistantElement, NoodleAssistantProps>(\n function NoodleAssistant(props, forwardedRef): ReactElement {\n const ref = useRef<NoodleAssistantElement>(null);\n useImperativeHandle(forwardedRef, () => ref.current as NoodleAssistantElement, []);\n useEffect(() => {\n registerNoodleAssistant();\n const element = ref.current;\n if (!element) return;\n element.sessionEndpoint = props.sessionEndpoint;\n const ready = () => props.onReady?.();\n const error = (event: Event) =>\n props.onError?.((event as CustomEvent<AssistantErrorDetail>).detail);\n const expired = () => props.onSessionExpired?.();\n element.addEventListener('assistant-ready', ready);\n element.addEventListener('assistant-error', error);\n element.addEventListener('assistant-session-expired', expired);\n return () => {\n element.removeEventListener('assistant-ready', ready);\n element.removeEventListener('assistant-error', error);\n element.removeEventListener('assistant-session-expired', expired);\n };\n }, [props.onError, props.onReady, props.onSessionExpired, props.sessionEndpoint]);\n return createElement('noodle-assistant', {\n ref,\n class: props.className,\n 'session-endpoint': props.sessionEndpoint,\n ...(props.theme ? { theme: props.theme } : {}),\n ...(props.open ? { open: '' } : {}),\n });\n },\n);\n","export type AssistantThemeMode = 'auto' | 'light' | 'dark';\nexport type AssistantLayoutMode = 'floating' | 'inline' | 'drawer';\nexport type AssistantPosition = 'bottom-left' | 'bottom-right';\n\nexport interface AssistantThemeTokens {\n readonly page: string;\n readonly panel: string;\n readonly elevated: string;\n readonly input: string;\n readonly hover: string;\n readonly selected: string;\n readonly text: string;\n readonly mutedText: string;\n readonly accent: string;\n readonly accentText: string;\n readonly link: string;\n readonly divider: string;\n readonly focus: string;\n readonly success: string;\n readonly warning: string;\n readonly danger: string;\n readonly overlay: string;\n readonly code: string;\n readonly widgetFrame: string;\n readonly fontFamily: string;\n readonly monoFontFamily: string;\n readonly baseFontSize: number;\n readonly messageFontSize: number;\n readonly lineHeight: number;\n readonly panelRadius: number;\n readonly cardRadius: number;\n readonly inputRadius: number;\n readonly buttonRadius: number;\n readonly launcherRadius: number;\n readonly spacing: number;\n readonly shadow: string;\n readonly backdropBlur: number;\n readonly motionScale: number;\n}\n\nexport interface AssistantConfiguration {\n readonly branding?: {\n readonly name?: string;\n readonly accent?: string;\n readonly surface?: string;\n readonly surfaceDark?: string;\n readonly logo?: AssistantBrandAsset;\n readonly mark?: AssistantBrandAsset;\n readonly avatar?: AssistantBrandAsset;\n readonly theme?: {\n readonly light?: BrandThemeOverrides;\n readonly dark?: BrandThemeOverrides;\n };\n readonly radius?: 'none' | 'sm' | 'md' | 'lg';\n readonly density?: 'compact' | 'comfortable';\n readonly typography?: 'system' | 'serif' | 'mono';\n readonly colorScheme?: AssistantThemeMode;\n };\n readonly assistant?: AssistantUiConfiguration;\n}\n\ninterface AssistantBrandAsset {\n readonly uri: string;\n readonly darkUri?: string;\n readonly alt: string;\n}\n\ninterface BrandThemeOverrides {\n readonly surface?: string;\n readonly surfaceRaised?: string;\n readonly surfaceMuted?: string;\n readonly text?: string;\n readonly textMuted?: string;\n readonly accent?: string;\n readonly accentText?: string;\n readonly link?: string;\n readonly border?: string;\n readonly borderStrong?: string;\n readonly focus?: string;\n readonly success?: string;\n readonly warning?: string;\n readonly danger?: string;\n readonly code?: string;\n}\n\ninterface AssistantUiConfiguration {\n readonly layout?: {\n readonly mode?: AssistantLayoutMode;\n readonly position?: AssistantPosition;\n readonly panelWidth?: number;\n readonly panelMinHeight?: number;\n readonly panelMaxHeight?: number;\n readonly zIndex?: number;\n readonly density?: 'compact' | 'comfortable';\n readonly mobileFullscreen?: boolean;\n };\n readonly behavior?: {\n readonly startOpen?: boolean;\n readonly closeOnEscape?: boolean;\n readonly closeOnOutsideClick?: boolean;\n readonly showLauncher?: boolean;\n readonly showHeader?: boolean;\n readonly showAvatars?: boolean;\n readonly showTimestamps?: boolean;\n };\n readonly labels?: Partial<AssistantLabels>;\n readonly suggestedPrompts?: readonly string[];\n readonly privacyUrl?: string;\n readonly termsUrl?: string;\n readonly locale?: string;\n readonly direction?: 'ltr' | 'rtl' | 'auto';\n}\n\nexport interface AssistantLabels {\n readonly welcomeHeading: string;\n readonly welcomeMessage: string;\n readonly composerPlaceholder: string;\n readonly send: string;\n readonly stop: string;\n readonly close: string;\n readonly open: string;\n readonly confirm: string;\n readonly cancel: string;\n readonly retry: string;\n readonly unavailable: string;\n readonly sessionExpired: string;\n}\n\nexport interface ResolvedAssistantAppearance {\n readonly brand: {\n readonly name: string;\n readonly logo: { readonly light?: string; readonly dark?: string };\n readonly avatar: { readonly light?: string; readonly dark?: string };\n readonly mark: { readonly light?: string; readonly dark?: string };\n };\n readonly theme: {\n readonly defaultMode: AssistantThemeMode;\n readonly light: AssistantThemeTokens;\n readonly dark: AssistantThemeTokens;\n };\n readonly layout: {\n readonly mode: AssistantLayoutMode;\n readonly position: AssistantPosition;\n readonly panelWidth: number;\n readonly panelMinHeight: number;\n readonly panelMaxHeight: number;\n readonly zIndex: number;\n readonly density: 'compact' | 'comfortable';\n readonly mobileFullscreen: boolean;\n };\n readonly behavior: {\n readonly startOpen: boolean;\n readonly closeOnEscape: boolean;\n readonly closeOnOutsideClick: boolean;\n readonly showLauncher: boolean;\n readonly showHeader: boolean;\n readonly showAvatars: boolean;\n readonly showTimestamps: boolean;\n };\n readonly labels: AssistantLabels;\n readonly suggestedPrompts: readonly string[];\n readonly privacyUrl?: string;\n readonly termsUrl?: string;\n readonly locale: string;\n readonly direction: 'ltr' | 'rtl' | 'auto';\n}\n\nconst common = {\n fontFamily: 'inherit',\n monoFontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n baseFontSize: 15,\n messageFontSize: 15,\n lineHeight: 1.5,\n panelRadius: 20,\n cardRadius: 14,\n inputRadius: 14,\n buttonRadius: 12,\n launcherRadius: 999,\n spacing: 12,\n backdropBlur: 18,\n motionScale: 1,\n} as const;\n\nexport const DEFAULT_APPEARANCE: ResolvedAssistantAppearance = {\n brand: { name: 'Assistant', logo: {}, avatar: {}, mark: {} },\n theme: {\n defaultMode: 'auto',\n light: {\n ...common,\n page: '#F7F7F8',\n panel: '#FFFFFF',\n elevated: '#FFFFFF',\n input: '#F1F1F3',\n hover: '#ECECEF',\n selected: '#E4E2FF',\n text: '#18181B',\n mutedText: '#71717A',\n accent: '#5B4CF0',\n accentText: '#FFFFFF',\n link: '#4A3BD5',\n divider: '#E4E4E7',\n focus: '#5B4CF0',\n success: '#16835D',\n warning: '#A45B00',\n danger: '#C92A45',\n overlay: '#18181B66',\n code: '#F1F1F3',\n widgetFrame: '#E4E4E7',\n shadow: '0 24px 80px rgba(24, 24, 27, 0.18)',\n },\n dark: {\n ...common,\n page: '#111113',\n panel: '#19191D',\n elevated: '#222228',\n input: '#26262C',\n hover: '#303038',\n selected: '#37315F',\n text: '#FAFAFA',\n mutedText: '#A1A1AA',\n accent: '#A99FFF',\n accentText: '#17131F',\n link: '#B9B1FF',\n divider: '#34343B',\n focus: '#B9B1FF',\n success: '#58C69A',\n warning: '#F2B45F',\n danger: '#FF8094',\n overlay: '#00000099',\n code: '#26262C',\n widgetFrame: '#34343B',\n shadow: '0 24px 90px rgba(0, 0, 0, 0.55)',\n },\n },\n layout: {\n mode: 'floating',\n position: 'bottom-right',\n panelWidth: 400,\n panelMinHeight: 420,\n panelMaxHeight: 720,\n zIndex: 2147483000,\n density: 'comfortable',\n mobileFullscreen: true,\n },\n behavior: {\n startOpen: false,\n closeOnEscape: true,\n closeOnOutsideClick: false,\n showLauncher: true,\n showHeader: true,\n showAvatars: true,\n showTimestamps: false,\n },\n labels: {\n welcomeHeading: 'How can I help?',\n welcomeMessage: '',\n composerPlaceholder: 'Ask a question…',\n send: 'Send',\n stop: 'Stop',\n close: 'Close assistant',\n open: 'Open assistant',\n confirm: 'Confirm',\n cancel: 'Cancel',\n retry: 'Try again',\n unavailable: 'The assistant is temporarily unavailable.',\n sessionExpired: 'Your assistant session expired. Reopen it to continue.',\n },\n suggestedPrompts: [],\n locale: 'en',\n direction: 'auto',\n};\n\nexport function resolveAppearance(input: AssistantConfiguration = {}): ResolvedAssistantAppearance {\n const branding = input.branding;\n const assistant = input.assistant;\n return {\n brand: {\n ...DEFAULT_APPEARANCE.brand,\n ...(branding?.name ? { name: branding.name } : {}),\n logo: themedAsset(branding?.logo),\n avatar: themedAsset(branding?.avatar),\n mark: themedAsset(branding?.mark),\n },\n theme: {\n defaultMode: branding?.colorScheme ?? DEFAULT_APPEARANCE.theme.defaultMode,\n light: resolveTheme('light', branding),\n dark: resolveTheme('dark', branding),\n },\n layout: {\n ...DEFAULT_APPEARANCE.layout,\n ...(branding?.density ? { density: branding.density } : {}),\n ...assistant?.layout,\n },\n behavior: { ...DEFAULT_APPEARANCE.behavior, ...assistant?.behavior },\n labels: { ...DEFAULT_APPEARANCE.labels, ...assistant?.labels },\n suggestedPrompts: assistant?.suggestedPrompts ?? DEFAULT_APPEARANCE.suggestedPrompts,\n ...(assistant?.privacyUrl ? { privacyUrl: assistant.privacyUrl } : {}),\n ...(assistant?.termsUrl ? { termsUrl: assistant.termsUrl } : {}),\n locale: assistant?.locale ?? DEFAULT_APPEARANCE.locale,\n direction: assistant?.direction ?? DEFAULT_APPEARANCE.direction,\n };\n}\n\nfunction themedAsset(asset: AssistantBrandAsset | undefined): {\n readonly light?: string;\n readonly dark?: string;\n} {\n return asset ? { light: asset.uri, dark: asset.darkUri ?? asset.uri } : {};\n}\n\nfunction resolveTheme(\n mode: 'light' | 'dark',\n branding: AssistantConfiguration['branding'],\n): AssistantThemeTokens {\n const defaults = DEFAULT_APPEARANCE.theme[mode];\n const surface = mode === 'light' ? branding?.surface : branding?.surfaceDark;\n const portable = branding?.theme?.[mode];\n const radius = branding?.radius ? radiusValue(branding.radius) : undefined;\n return {\n ...defaults,\n ...(branding?.accent ? { accent: branding.accent } : {}),\n ...(surface ? { page: surface, panel: surface } : {}),\n ...mapPortableTheme(portable),\n ...(radius === undefined\n ? {}\n : {\n panelRadius: radius,\n cardRadius: radius,\n inputRadius: Math.max(0, radius - 2),\n buttonRadius: Math.max(0, radius - 2),\n }),\n ...(branding?.typography === 'serif'\n ? { fontFamily: 'ui-serif, Georgia, serif' }\n : branding?.typography === 'mono'\n ? { fontFamily: defaults.monoFontFamily }\n : {}),\n };\n}\n\nfunction mapPortableTheme(input: BrandThemeOverrides | undefined): Partial<AssistantThemeTokens> {\n if (!input) return {};\n return {\n ...(input.surface ? { page: input.surface, panel: input.surface } : {}),\n ...(input.surfaceRaised ? { elevated: input.surfaceRaised } : {}),\n ...(input.surfaceMuted\n ? { input: input.surfaceMuted, hover: input.surfaceMuted, selected: input.surfaceMuted }\n : {}),\n ...(input.text ? { text: input.text } : {}),\n ...(input.textMuted ? { mutedText: input.textMuted } : {}),\n ...(input.accent ? { accent: input.accent } : {}),\n ...(input.accentText ? { accentText: input.accentText } : {}),\n ...(input.link ? { link: input.link } : {}),\n ...(input.border ? { divider: input.border, widgetFrame: input.border } : {}),\n ...(input.focus ? { focus: input.focus } : {}),\n ...(input.success ? { success: input.success } : {}),\n ...(input.warning ? { warning: input.warning } : {}),\n ...(input.danger ? { danger: input.danger } : {}),\n ...(input.code ? { code: input.code } : {}),\n };\n}\n\nfunction radiusValue(radius: 'none' | 'sm' | 'md' | 'lg'): number {\n if (radius === 'none') return 0;\n if (radius === 'sm') return 8;\n if (radius === 'lg') return 18;\n return 14;\n}\n","import type { AssistantClientContext } from './client.js';\n\n/** Resolve untrusted presentation hints without making them part of verified user or page context. */\nexport function browserClientContext(): AssistantClientContext {\n let timeZone: string | undefined;\n try {\n timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // Older or restricted browsers may not expose an IANA timezone; the service falls back safely.\n }\n const locale = globalThis.navigator?.language;\n return {\n ...(locale ? { locale } : {}),\n ...(timeZone ? { timeZone } : {}),\n };\n}\n","import type { AssistantConfiguration } from './appearance.js';\nimport type { AssistantJsonValue, AssistantModelContextUpdate } from './model-context.js';\nimport type { AssistantEvent } from './transport.js';\n\ninterface NamedEvent<Name extends string, Data> {\n readonly event: Name;\n readonly data: Data;\n}\n\ninterface TurnDetail {\n readonly turnId?: string;\n}\n\nexport interface AssistantContentDetail extends TurnDetail {\n readonly delta: string;\n}\n\nexport interface AssistantToolProposedDetail extends TurnDetail {\n readonly id: string;\n readonly tool: string;\n readonly arguments?: AssistantJsonValue;\n readonly expiresAt?: string;\n /** Optional only for compatibility with assistant services published before named-event pinning. */\n readonly requiresConfirmation?: true;\n}\n\nexport interface AssistantInputRequestedDetail extends TurnDetail {\n readonly id: string;\n readonly message: string;\n readonly requestedSchema: Readonly<Record<string, unknown>>;\n readonly expiresAt: string;\n}\n\nexport interface AssistantInteractionResolvedDetail extends TurnDetail {\n readonly id: string;\n /** Optional only for compatibility with the original accept-only confirmation endpoint. */\n readonly action?: 'accept' | 'decline' | 'cancel';\n}\n\nexport interface AssistantToolCompletedDetail extends TurnDetail {\n readonly id: string;\n readonly tool: string;\n readonly result: AssistantJsonValue;\n readonly replayed?: true;\n}\n\nexport interface AssistantViewAvailableDetail extends TurnDetail {\n /** Model tool-call id for an immediate result, or interaction id for a confirmed result. */\n readonly id: string;\n readonly tool: string;\n readonly resourceUri: string;\n readonly title?: string;\n /** Bounded, schema-redacted public tool output; widget-only metadata is never included. */\n readonly result: AssistantJsonValue;\n readonly replayed?: true;\n}\n\nexport interface AssistantErrorEventDetail extends TurnDetail {\n readonly code: string;\n readonly status?: number;\n readonly retryable?: boolean;\n}\n\nexport type AssistantContentEvent = NamedEvent<'content', AssistantContentDetail>;\nexport type AssistantToolProposedEvent = NamedEvent<'tool_proposed', AssistantToolProposedDetail>;\nexport type AssistantInputRequestedEvent = NamedEvent<\n 'input_requested',\n AssistantInputRequestedDetail\n>;\nexport type AssistantInteractionResolvedEvent = NamedEvent<\n 'interaction_resolved',\n AssistantInteractionResolvedDetail\n>;\nexport type AssistantToolCompletedEvent = NamedEvent<\n 'tool_completed',\n AssistantToolCompletedDetail\n>;\nexport type AssistantViewAvailableEvent = NamedEvent<\n 'view_available',\n AssistantViewAvailableDetail\n>;\nexport type AssistantErrorEvent = NamedEvent<'error', AssistantErrorEventDetail>;\nexport type AssistantDoneEvent = NamedEvent<'done', TurnDetail>;\n\ninterface AssistantLegacyInteractionProposedDetail {\n readonly id: string;\n readonly tool?: string;\n readonly title?: string;\n readonly arguments?: AssistantJsonValue;\n}\n\ntype AssistantContextValue = string | number | boolean | null;\n\nexport type AssistantClientLifecycleEvent =\n | NamedEvent<\n 'session_started',\n { readonly expiresAt: string; readonly configuration?: AssistantConfiguration }\n >\n | NamedEvent<'session_expired', Readonly<Record<string, never>>>\n | NamedEvent<'session_reset', Readonly<Record<string, never>>>\n | NamedEvent<\n 'context_changed',\n { readonly context: Readonly<Record<string, AssistantContextValue>> }\n >\n | NamedEvent<'model_context_changed', { readonly modelContext: AssistantModelContextUpdate }>\n | NamedEvent<'message_started', { readonly message: string }>\n | NamedEvent<'message_completed', Readonly<Record<string, never>>>\n | NamedEvent<\n 'interaction_started',\n { readonly id: string; readonly action: 'accept' | 'decline' | 'cancel' }\n >\n | NamedEvent<\n 'interaction_completed',\n { readonly id: string; readonly action: 'accept' | 'decline' | 'cancel' }\n >;\n\nexport interface AssistantUnrecognizedEvent {\n readonly event: 'unrecognized';\n readonly data: {\n readonly name: string;\n readonly payload: Readonly<Record<string, unknown>>;\n };\n}\n\n/** Closed event union for the DOM-free client; unknown future SSE names remain observable safely. */\nexport type AssistantClientEvent =\n | AssistantContentEvent\n | AssistantToolProposedEvent\n | AssistantInputRequestedEvent\n | AssistantInteractionResolvedEvent\n | AssistantToolCompletedEvent\n | AssistantViewAvailableEvent\n | AssistantErrorEvent\n | AssistantDoneEvent\n | NamedEvent<'interaction_proposed', AssistantLegacyInteractionProposedDetail>\n | AssistantClientLifecycleEvent\n | AssistantUnrecognizedEvent;\n\n/** Normalize and minimally validate generic transport frames before asserting public event types. */\nexport function toAssistantClientEvent(event: AssistantEvent): AssistantClientEvent {\n const value = event.data;\n switch (event.event) {\n case 'content':\n if (typeof value.delta === 'string' && hasOptionalTurnId(value)) {\n return event as unknown as AssistantContentEvent;\n }\n break;\n case 'tool_proposed':\n if (\n hasString(value, 'id') &&\n hasString(value, 'tool') &&\n hasOptionalJson(value.arguments) &&\n hasOptionalString(value.expiresAt) &&\n (value.requiresConfirmation === undefined || value.requiresConfirmation === true) &&\n hasOptionalTurnId(value)\n ) {\n return event as unknown as AssistantToolProposedEvent;\n }\n break;\n case 'input_requested':\n if (\n hasString(value, 'id') &&\n hasString(value, 'message') &&\n isRecord(value.requestedSchema) &&\n hasString(value, 'expiresAt') &&\n hasOptionalTurnId(value)\n ) {\n return event as unknown as AssistantInputRequestedEvent;\n }\n break;\n case 'interaction_resolved':\n if (\n hasString(value, 'id') &&\n (value.action === undefined || isInteractionAction(value.action)) &&\n hasOptionalTurnId(value)\n ) {\n return event as unknown as AssistantInteractionResolvedEvent;\n }\n break;\n case 'tool_completed':\n if (\n hasString(value, 'id') &&\n hasString(value, 'tool') &&\n isJsonValue(value.result, 0) &&\n (value.replayed === undefined || value.replayed === true) &&\n hasOptionalTurnId(value)\n ) {\n return event as unknown as AssistantToolCompletedEvent;\n }\n break;\n case 'view_available':\n if (isViewAvailableDetail(value)) return event as unknown as AssistantViewAvailableEvent;\n break;\n case 'error':\n if (\n hasString(value, 'code') &&\n (value.status === undefined || typeof value.status === 'number') &&\n (value.retryable === undefined || typeof value.retryable === 'boolean') &&\n hasOptionalTurnId(value)\n ) {\n return event as unknown as AssistantErrorEvent;\n }\n break;\n case 'done':\n if (hasOptionalTurnId(value)) return event as AssistantDoneEvent;\n break;\n case 'interaction_proposed':\n if (\n hasString(value, 'id') &&\n (hasString(value, 'tool') || hasString(value, 'title')) &&\n hasOptionalJson(value.arguments)\n ) {\n return event as unknown as NamedEvent<\n 'interaction_proposed',\n AssistantLegacyInteractionProposedDetail\n >;\n }\n break;\n }\n return { event: 'unrecognized', data: { name: event.event, payload: value } };\n}\n\nfunction isViewAvailableDetail(value: Readonly<Record<string, unknown>>): boolean {\n return (\n hasString(value, 'id') &&\n hasString(value, 'tool') &&\n typeof value.resourceUri === 'string' &&\n value.resourceUri.startsWith('ui://') &&\n hasOptionalString(value.title) &&\n (value.replayed === undefined || value.replayed === true) &&\n isJsonValue(value.result, 0) &&\n hasOptionalTurnId(value)\n );\n}\n\nfunction hasOptionalTurnId(value: Readonly<Record<string, unknown>>): boolean {\n return hasOptionalString(value.turnId);\n}\n\nfunction hasString(value: Readonly<Record<string, unknown>>, key: string): boolean {\n const entry = value[key];\n return typeof entry === 'string' && entry.length > 0;\n}\n\nfunction hasOptionalString(value: unknown): value is string | undefined {\n return value === undefined || typeof value === 'string';\n}\n\nfunction hasOptionalJson(value: unknown): boolean {\n return value === undefined || isJsonValue(value, 0);\n}\n\nfunction isInteractionAction(value: unknown): value is 'accept' | 'decline' | 'cancel' {\n return value === 'accept' || value === 'decline' || value === 'cancel';\n}\n\nfunction isJsonValue(value: unknown, depth: number): value is AssistantJsonValue {\n if (depth > 16) return false;\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return true;\n if (typeof value === 'number') return Number.isFinite(value);\n if (Array.isArray(value)) {\n return value.length <= 256 && value.every((entry) => isJsonValue(entry, depth + 1));\n }\n if (!isRecord(value)) return false;\n const entries = Object.entries(value);\n return entries.length <= 256 && entries.every(([, entry]) => isJsonValue(entry, depth + 1));\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","export type AssistantJsonValue =\n | string\n | number\n | boolean\n | null\n | readonly AssistantJsonValue[]\n | { readonly [key: string]: AssistantJsonValue };\n\n/** MCP-Apps-shaped summary deliberately selected by the renderer for the next assistant turn. */\nexport interface AssistantModelContextUpdate {\n readonly content?: readonly { readonly type: 'text'; readonly text: string }[];\n readonly structuredContent?: Readonly<Record<string, AssistantJsonValue>>;\n}\n\nconst MAX_BYTES = 16 * 1024;\nconst MAX_DEPTH = 8;\nconst MAX_ENTRIES = 128;\nconst SENSITIVE_KEY = /(?:secret|token|api[-_]?key|password|credential|authorization|cookie)/i;\nconst CREDENTIAL_SHAPED_TEXT =\n /(?:-----BEGIN [A-Z ]*PRIVATE KEY-----|\\bsk-[A-Za-z0-9_-]{20,}\\b|\\b(?:bearer|basic)\\s+[A-Za-z0-9._~+/=-]{20,}\\b|\\b[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}\\b)/i;\n\n/** Validate and detach renderer-owned mutable data before retaining it in the client. */\nexport function copyAssistantModelContext(\n update: AssistantModelContextUpdate,\n): AssistantModelContextUpdate {\n const copied = copyJsonValue(update, '$', 0, new Set<object>());\n assertModelContextShape(copied);\n const encoded = JSON.stringify(copied);\n if (new TextEncoder().encode(encoded).byteLength > MAX_BYTES) {\n throw new Error('Model context must not exceed 16 KiB');\n }\n return copied;\n}\n\nfunction assertModelContextShape(value: unknown): asserts value is AssistantModelContextUpdate {\n if (!isPlainRecord(value)) throw new Error('Model context must be a JSON object');\n for (const key of Object.keys(value)) {\n if (key !== 'content' && key !== 'structuredContent') {\n throw new Error(`Model context contains unknown field ${key}`);\n }\n }\n if (value.content !== undefined) {\n if (!Array.isArray(value.content)) throw new Error('Model context content must be an array');\n for (const part of value.content) {\n if (\n !isPlainRecord(part) ||\n Object.keys(part).some((key) => key !== 'type' && key !== 'text') ||\n part.type !== 'text' ||\n typeof part.text !== 'string'\n ) {\n throw new Error('Model context content supports text parts only');\n }\n }\n }\n if (value.structuredContent !== undefined && !isPlainRecord(value.structuredContent)) {\n throw new Error('Model context structuredContent must be an object');\n }\n}\n\nfunction copyJsonValue(\n value: unknown,\n path: string,\n depth: number,\n ancestors: Set<object>,\n): AssistantJsonValue {\n if (depth > MAX_DEPTH) throw new Error(`Model context exceeds maximum depth at ${path}`);\n if (typeof value === 'string') {\n if (CREDENTIAL_SHAPED_TEXT.test(value)) {\n throw new Error(`Model context contains credential-shaped text at ${path}`);\n }\n return value;\n }\n if (\n value === null ||\n typeof value === 'boolean' ||\n (typeof value === 'number' && Number.isFinite(value))\n ) {\n return value;\n }\n if (typeof value !== 'object') throw new Error(`Model context contains non-JSON data at ${path}`);\n if (hasToJsonProperty(value)) {\n throw new Error(`Model context must not define or inherit toJSON at ${path}`);\n }\n const prototype = Object.getPrototypeOf(value);\n if (Array.isArray(value)) {\n if (prototype !== Array.prototype) {\n throw new Error(`Model context contains a non-JSON object at ${path}`);\n }\n } else if (prototype !== Object.prototype && prototype !== null) {\n throw new Error(`Model context contains a non-JSON object at ${path}`);\n }\n if (ancestors.has(value)) throw new Error(`Model context contains a cycle at ${path}`);\n\n if (Array.isArray(value)) {\n if (value.length > MAX_ENTRIES) {\n throw new Error(`Model context has more than 128 entries at ${path}`);\n }\n const copy: AssistantJsonValue[] = [];\n ancestors.add(value);\n for (let index = 0; index < value.length; index += 1) {\n const entry = Object.hasOwn(value, index) ? value[index] : null;\n copy.push(copyJsonValue(entry, `${path}.${index}`, depth + 1, ancestors));\n }\n ancestors.delete(value);\n return copy;\n }\n\n const entries = Object.entries(value);\n if (entries.length > MAX_ENTRIES) {\n throw new Error(`Model context has more than 128 entries at ${path}`);\n }\n const copy: Record<string, AssistantJsonValue> = Object.create(null);\n ancestors.add(value);\n for (const [key, entry] of entries) {\n if (SENSITIVE_KEY.test(key)) {\n throw new Error(`Model context contains sensitive key ${path}.${key}`);\n }\n copy[key] = copyJsonValue(entry, `${path}.${key}`, depth + 1, ancestors);\n }\n ancestors.delete(value);\n return copy;\n}\n\nfunction isPlainRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction hasToJsonProperty(value: object): boolean {\n let current: object | null = value;\n const visited = new Set<object>();\n while (current !== null && !visited.has(current)) {\n visited.add(current);\n if (Object.getOwnPropertyDescriptor(current, 'toJSON') !== undefined) return true;\n current = Object.getPrototypeOf(current);\n }\n return false;\n}\n","export interface AssistantEvent {\n readonly event: string;\n readonly data: Readonly<Record<string, unknown>>;\n}\n\nexport interface AssistantErrorDetail {\n readonly code: string;\n readonly status?: number;\n readonly retryable: boolean;\n}\n\n/** A 2xx response that is not one complete, well-formed assistant event stream. */\nexport class AssistantTransportError extends Error {\n readonly code = 'invalid_response' as const;\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = 'AssistantTransportError';\n }\n}\n\n/**\n * Consume JSON-bearing server-sent events without buffering the whole assistant turn.\n *\n * `done` is the stream commit marker. It is delivered only after EOF proves that it was the one terminal\n * event, so truncated, duplicate-terminal, and post-terminal responses can never resolve a client turn.\n */\nexport async function consumeAssistantEvents(\n response: Response,\n onEvent: (event: AssistantEvent) => void,\n): Promise<void> {\n const stream = new AssistantEventStream(onEvent);\n if (!response.body) {\n let text: string;\n try {\n text = await response.text();\n } catch (error) {\n if (isAbortError(error)) throw error;\n throw invalidStream('assistant event stream could not be read', error);\n }\n stream.push(text);\n stream.finish(response.headers.get('content-type') ?? '');\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8', { fatal: true });\n while (true) {\n let result: ReadableStreamReadResult<Uint8Array>;\n try {\n result = await reader.read();\n } catch (error) {\n if (isAbortError(error)) throw error;\n throw invalidStream('assistant event stream ended unexpectedly', error);\n }\n\n let chunk: string;\n try {\n chunk = decoder.decode(result.value, { stream: !result.done });\n } catch (error) {\n throw invalidStream('assistant event stream contained invalid UTF-8', error);\n }\n stream.push(chunk);\n if (result.done) break;\n }\n stream.finish(response.headers.get('content-type') ?? '');\n}\n\nclass AssistantEventStream {\n readonly #onEvent: (event: AssistantEvent) => void;\n #pending = '';\n #terminal: AssistantEvent | undefined;\n\n constructor(onEvent: (event: AssistantEvent) => void) {\n this.#onEvent = onEvent;\n }\n\n push(chunk: string): void {\n this.#pending += chunk;\n const protectedCarriageReturn = this.#pending.endsWith('\\r');\n const normalizable = protectedCarriageReturn ? this.#pending.slice(0, -1) : this.#pending;\n const frames = normalizeLineEndings(normalizable).split('\\n\\n');\n this.#pending = `${frames.pop() ?? ''}${protectedCarriageReturn ? '\\r' : ''}`;\n for (const frame of frames) this.#acceptFrame(frame);\n }\n\n finish(contentType: string): void {\n if (this.#pending.trim().length > 0) {\n throw invalidStream('assistant event stream ended with an unterminated frame');\n }\n if (!this.#terminal) {\n throw invalidStream(\n `assistant response did not contain a terminal done event (content-type: ${contentType || 'unknown'})`,\n );\n }\n this.#onEvent(this.#terminal);\n }\n\n #acceptFrame(frame: string): void {\n const event = parseFrame(frame);\n if (!event) return;\n if (this.#terminal) {\n throw invalidStream('assistant event stream contained an event after done');\n }\n if (event.event === 'done') {\n this.#terminal = event;\n return;\n }\n this.#onEvent(event);\n }\n}\n\nfunction parseFrame(frame: string): AssistantEvent | undefined {\n let event: string | undefined;\n const data: string[] = [];\n let hasFields = false;\n for (const line of frame.split('\\n')) {\n if (!line || line.startsWith(':')) continue;\n hasFields = true;\n const separator = line.indexOf(':');\n const field = separator < 0 ? line : line.slice(0, separator);\n const value = separator < 0 ? '' : line.slice(separator + 1).replace(/^ /, '');\n if (field === 'event') event = value;\n if (field === 'data') data.push(value);\n }\n if (!hasFields) return undefined;\n if (!event || data.length === 0) {\n throw invalidStream('assistant event stream contained a malformed frame');\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data.join('\\n'));\n } catch (error) {\n throw invalidStream('assistant event stream contained malformed JSON', error);\n }\n if (event === 'done' && !isValidDonePayload(parsed)) {\n throw invalidStream('assistant event stream contained an invalid done event');\n }\n return { event, data: isRecord(parsed) ? parsed : { value: parsed } };\n}\n\nfunction normalizeLineEndings(input: string): string {\n return input.replaceAll('\\r\\n', '\\n').replaceAll('\\r', '\\n');\n}\n\nfunction isValidDonePayload(value: unknown): value is Readonly<Record<string, unknown>> {\n return (\n isRecord(value) &&\n (value.turnId === undefined || (typeof value.turnId === 'string' && value.turnId.length > 0))\n );\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction invalidStream(message: string, cause?: unknown): AssistantTransportError {\n return new AssistantTransportError(message, cause === undefined ? undefined : { cause });\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === 'AbortError';\n}\n","import type { AssistantConfiguration } from './appearance.js';\nimport { type AssistantClientEvent, toAssistantClientEvent } from './events.js';\nimport {\n type AssistantJsonValue,\n type AssistantModelContextUpdate,\n copyAssistantModelContext,\n} from './model-context.js';\nimport {\n type AssistantErrorDetail,\n AssistantTransportError,\n consumeAssistantEvents,\n} from './transport.js';\n\nexport type AssistantContextValue = string | number | boolean | null;\nexport type AssistantContext = Readonly<Record<string, AssistantContextValue>>;\n\nexport interface AssistantClientContext {\n readonly locale?: string;\n readonly timeZone?: string;\n}\n\nexport type { AssistantJsonValue, AssistantModelContextUpdate } from './model-context.js';\n\nexport type AssistantInteractionResponse =\n | { readonly action: 'accept'; readonly content?: AssistantJsonValue }\n | { readonly action: 'decline' | 'cancel' };\n\nexport interface AssistantSessionResponse {\n readonly token: string;\n readonly expiresAt: string;\n readonly endpoints: {\n readonly turns: string;\n readonly toolConfirmations: string;\n readonly interactions?: string;\n };\n readonly configuration?: AssistantConfiguration;\n}\n\nexport type {\n AssistantClientEvent,\n AssistantClientLifecycleEvent,\n AssistantContentDetail,\n AssistantContentEvent,\n AssistantDoneEvent,\n AssistantErrorEvent,\n AssistantErrorEventDetail,\n AssistantInputRequestedDetail,\n AssistantInputRequestedEvent,\n AssistantInteractionResolvedDetail,\n AssistantInteractionResolvedEvent,\n AssistantToolCompletedDetail,\n AssistantToolCompletedEvent,\n AssistantToolProposedDetail,\n AssistantToolProposedEvent,\n AssistantUnrecognizedEvent,\n AssistantViewAvailableDetail,\n AssistantViewAvailableEvent,\n} from './events.js';\n\nexport interface CreateAssistantClientOptions {\n readonly sessionEndpoint: string;\n readonly fetch?: typeof fetch;\n /** Untrusted page context sent only when exchanging a session. */\n readonly context?: AssistantContext;\n /** Untrusted presentation hints evaluated for every turn request. */\n readonly clientContext?: AssistantClientContext | (() => AssistantClientContext | undefined);\n /** Latest renderer-selected summary included as untrusted data on every message turn. */\n readonly modelContext?: AssistantModelContextUpdate;\n}\n\nexport interface AssistantClient {\n subscribe(listener: (event: AssistantClientEvent) => void): () => void;\n sendMessage(message: string): Promise<void>;\n respond(id: string, response: AssistantInteractionResponse): Promise<void>;\n updateContext(context: AssistantContext): void;\n updateModelContext(update: AssistantModelContextUpdate): void;\n resetSession(): void;\n abort(): void;\n}\n\nexport class AssistantClientError extends Error {\n readonly detail: AssistantErrorDetail;\n\n constructor(detail: AssistantErrorDetail, message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = 'AssistantClientError';\n this.detail = detail;\n }\n}\n\nclass DefaultAssistantClient implements AssistantClient {\n readonly #sessionEndpoint: string;\n readonly #fetch: typeof fetch;\n readonly #listeners = new Set<(event: AssistantClientEvent) => void>();\n readonly #clientContext:\n | AssistantClientContext\n | (() => AssistantClientContext | undefined)\n | undefined;\n #session: AssistantSessionResponse | undefined;\n #context: AssistantContext | undefined;\n #modelContext: AssistantModelContextUpdate | undefined;\n #active: AbortController | undefined;\n\n constructor(options: CreateAssistantClientOptions) {\n if (!options.sessionEndpoint) throw new Error('sessionEndpoint is required');\n this.#sessionEndpoint = options.sessionEndpoint;\n // Some browsers require `window.fetch` to be invoked with its global receiver. Keep the default\n // behind a closure instead of storing the unbound host method; injected test/server fetches remain exact.\n this.#fetch = options.fetch ?? ((input, init) => globalThis.fetch(input, init));\n this.#context = options.context ? { ...options.context } : undefined;\n this.#modelContext = options.modelContext\n ? copyAssistantModelContext(options.modelContext)\n : undefined;\n this.#clientContext = options.clientContext;\n }\n\n subscribe(listener: (event: AssistantClientEvent) => void): () => void {\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n async sendMessage(text: string): Promise<void> {\n const message = text.trim();\n if (!message) return;\n await this.#singleFlight(async (signal) => {\n await this.#sendTurn(message, true, signal, this.#modelContext);\n });\n }\n\n async respond(id: string, resolution: AssistantInteractionResponse): Promise<void> {\n if (!id) {\n throw clientError('invalid_request', 'interaction id is required', false);\n }\n await this.#singleFlight(async (signal) => {\n const session = this.#session;\n if (!session) {\n throw clientError('confirmation_expired', 'assistant session is not active', false);\n }\n const modernEndpoint = session.endpoints.interactions;\n if (!modernEndpoint && resolution.action !== 'accept') {\n throw clientError(\n 'unsupported_service',\n 'the assistant service does not support declining or cancelling interactions',\n false,\n );\n }\n const endpoint = modernEndpoint ?? session.endpoints.toolConfirmations;\n const body = modernEndpoint\n ? {\n id,\n action: resolution.action,\n ...(resolution.action === 'accept' && resolution.content !== undefined\n ? { content: resolution.content }\n : {}),\n }\n : { id };\n this.#emit({ event: 'interaction_started', data: { id, action: resolution.action } });\n const response = await this.#request(\n endpoint,\n {\n method: 'POST',\n headers: authorizedHeaders(session.token, 'text/event-stream'),\n body: JSON.stringify(body),\n signal,\n },\n 'confirmation_failed',\n );\n if (response.status === 401) {\n this.#session = undefined;\n this.#emit({ event: 'session_expired', data: {} });\n }\n if (!response.ok) {\n const serverCode = await readStableErrorCode(response);\n const expired = response.status === 401 || response.status === 409;\n throw clientError(\n serverCode ?? (expired ? 'confirmation_expired' : 'confirmation_failed'),\n `Assistant interaction failed (${response.status})`,\n false,\n response.status,\n );\n }\n await this.#consume(response);\n this.#emit({ event: 'interaction_completed', data: { id, action: resolution.action } });\n });\n }\n\n updateContext(context: AssistantContext): void {\n this.#context = { ...context };\n this.#emit({ event: 'context_changed', data: { context: this.#context } });\n }\n\n updateModelContext(update: AssistantModelContextUpdate): void {\n this.#modelContext = copyAssistantModelContext(update);\n this.#emit({ event: 'model_context_changed', data: { modelContext: this.#modelContext } });\n }\n\n resetSession(): void {\n this.#session = undefined;\n this.#emit({ event: 'session_reset', data: {} });\n }\n\n abort(): void {\n this.#active?.abort();\n }\n\n async #sendTurn(\n message: string,\n mayRetry: boolean,\n signal: AbortSignal,\n modelContext: AssistantModelContextUpdate | undefined,\n ): Promise<void> {\n const session = this.#session ?? (await this.#createSession(signal));\n if (mayRetry) this.#emit({ event: 'message_started', data: { message } });\n const clientContext = this.#resolveClientContext();\n const response = await this.#request(\n session.endpoints.turns,\n {\n method: 'POST',\n headers: authorizedHeaders(session.token, 'text/event-stream'),\n body: JSON.stringify({\n message,\n ...(clientContext ? { clientContext } : {}),\n ...(modelContext ? { modelContext } : {}),\n }),\n signal,\n },\n 'turn_failed',\n );\n if (response.status === 401 && mayRetry) {\n this.#session = undefined;\n this.#emit({ event: 'session_expired', data: {} });\n await this.#sendTurn(message, false, signal, modelContext);\n return;\n }\n if (!response.ok) {\n throw clientError(\n 'turn_failed',\n `Assistant turn failed (${response.status})`,\n false,\n response.status,\n );\n }\n await this.#consume(response);\n this.#emit({ event: 'message_completed', data: {} });\n }\n\n #resolveClientContext(): AssistantClientContext | undefined {\n let value: AssistantClientContext | undefined;\n try {\n value =\n typeof this.#clientContext === 'function' ? this.#clientContext() : this.#clientContext;\n } catch (error) {\n throw clientError(\n 'turn_failed',\n 'Assistant client context provider failed',\n false,\n undefined,\n {\n cause: error,\n },\n );\n }\n if (!value) return undefined;\n const context = {\n ...(typeof value.locale === 'string' && value.locale ? { locale: value.locale } : {}),\n ...(typeof value.timeZone === 'string' && value.timeZone ? { timeZone: value.timeZone } : {}),\n };\n return Object.keys(context).length > 0 ? context : undefined;\n }\n\n async #createSession(signal: AbortSignal): Promise<AssistantSessionResponse> {\n const response = await this.#request(\n this.#sessionEndpoint,\n {\n method: 'POST',\n headers: { Accept: 'application/json', 'Content-Type': 'application/json' },\n body: JSON.stringify(this.#context ? { context: this.#context } : {}),\n credentials: 'same-origin',\n signal,\n },\n 'session_failed',\n );\n if (!response.ok) {\n throw clientError(\n 'session_failed',\n `Assistant session failed (${response.status})`,\n true,\n response.status,\n );\n }\n let value: unknown;\n try {\n value = await response.json();\n } catch (error) {\n throw clientError(\n 'session_failed',\n 'Assistant session returned invalid JSON',\n true,\n undefined,\n {\n cause: error,\n },\n );\n }\n const session = parseSession(value);\n this.#session = session;\n this.#emit({\n event: 'session_started',\n data: {\n expiresAt: session.expiresAt,\n ...(session.configuration ? { configuration: session.configuration } : {}),\n },\n });\n return session;\n }\n\n async #consume(response: Response): Promise<void> {\n let streamError: AssistantErrorDetail | undefined;\n try {\n await consumeAssistantEvents(response, (event) => {\n const clientEvent = toAssistantClientEvent(event);\n this.#emit(clientEvent);\n if (clientEvent.event !== 'error' || typeof clientEvent.data.code !== 'string') return;\n streamError = {\n code: clientEvent.data.code,\n ...(typeof clientEvent.data.status === 'number'\n ? { status: clientEvent.data.status }\n : {}),\n retryable: clientEvent.data.retryable === true,\n };\n });\n } catch (error) {\n if (error instanceof AssistantTransportError) {\n throw clientError(error.code, error.message, false, undefined, { cause: error });\n }\n throw error;\n }\n if (streamError) {\n throw clientError(\n streamError.code,\n `Assistant stream failed (${streamError.code})`,\n streamError.retryable,\n streamError.status,\n );\n }\n }\n\n async #request(input: string, init: RequestInit, failureCode: string): Promise<Response> {\n try {\n return await this.#fetch(input, init);\n } catch (error) {\n if (init.signal?.aborted) throw error;\n throw clientError(failureCode, 'Assistant request failed', true, undefined, { cause: error });\n }\n }\n\n async #singleFlight(operation: (signal: AbortSignal) => Promise<void>): Promise<void> {\n if (this.#active) {\n throw clientError('request_in_progress', 'an assistant request is already in progress', true);\n }\n const controller = new AbortController();\n this.#active = controller;\n try {\n await operation(controller.signal);\n } catch (error) {\n if (controller.signal.aborted) {\n throw clientError('request_aborted', 'assistant request was aborted', true, undefined, {\n cause: error,\n });\n }\n throw error;\n } finally {\n this.#active = undefined;\n }\n }\n\n #emit(event: AssistantClientEvent): void {\n for (const listener of this.#listeners) {\n try {\n listener(event);\n } catch {\n // Renderers are independent observers; one subscriber cannot change a completed request.\n }\n }\n }\n}\n\nexport function createAssistantClient(options: CreateAssistantClientOptions): AssistantClient {\n return new DefaultAssistantClient(options);\n}\n\nfunction authorizedHeaders(token: string, accept: string): Readonly<Record<string, string>> {\n return {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n Accept: accept,\n };\n}\n\nfunction parseSession(value: unknown): AssistantSessionResponse {\n if (!isRecord(value) || !isRecord(value.endpoints)) {\n throw clientError('session_failed', 'Assistant session response is invalid', true);\n }\n const interactions = value.endpoints.interactions;\n if (\n typeof value.token !== 'string' ||\n typeof value.expiresAt !== 'string' ||\n typeof value.endpoints.turns !== 'string' ||\n typeof value.endpoints.toolConfirmations !== 'string' ||\n (interactions !== undefined && typeof interactions !== 'string')\n ) {\n throw clientError('session_failed', 'Assistant session response is invalid', true);\n }\n return {\n token: value.token,\n expiresAt: value.expiresAt,\n endpoints: {\n turns: value.endpoints.turns,\n toolConfirmations: value.endpoints.toolConfirmations,\n ...(typeof interactions === 'string' ? { interactions } : {}),\n },\n ...(isRecord(value.configuration)\n ? { configuration: value.configuration as AssistantConfiguration }\n : {}),\n };\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nasync function readStableErrorCode(response: Response): Promise<string | undefined> {\n let value: unknown;\n try {\n value = await response.json();\n } catch {\n return undefined;\n }\n if (!isRecord(value) || typeof value.code !== 'string') return undefined;\n return /^[A-Za-z0-9_.-]{1,64}$/.test(value.code) ? value.code : undefined;\n}\n\nfunction clientError(\n code: string,\n message: string,\n retryable: boolean,\n status?: number,\n options?: ErrorOptions,\n): AssistantClientError {\n return new AssistantClientError(\n { code, ...(status === undefined ? {} : { status }), retryable },\n message,\n options,\n );\n}\n","import type { AssistantJsonValue } from './client.js';\n\ninterface InputRequestCardOptions {\n readonly message: string;\n readonly requestedSchema: Readonly<Record<string, unknown>>;\n readonly labels: {\n readonly submit: string;\n readonly decline: string;\n readonly cancel: string;\n };\n readonly respond: (\n response:\n | { readonly action: 'accept'; readonly content: AssistantJsonValue }\n | { readonly action: 'decline' | 'cancel' },\n ) => Promise<void>;\n}\n\n/** Render the portable MCP form-elicitation subset without interpreting author HTML. */\nexport function createInputRequestCard(options: InputRequestCardOptions): HTMLElement {\n const card = document.createElement('section');\n card.className = 'tool-proposal input-request';\n card.dataset.kind = 'input';\n const form = document.createElement('form');\n const heading = document.createElement('strong');\n heading.textContent = options.message;\n form.append(heading);\n\n const properties = record(options.requestedSchema.properties);\n const required = new Set(\n Array.isArray(options.requestedSchema.required)\n ? options.requestedSchema.required.filter(\n (value): value is string => typeof value === 'string',\n )\n : [],\n );\n const controls = new Map<string, HTMLInputElement | HTMLSelectElement>();\n const touched = new WeakSet<HTMLInputElement | HTMLSelectElement>();\n for (const [name, rawProperty] of Object.entries(properties)) {\n const property = record(rawProperty);\n const label = document.createElement('label');\n const caption = document.createElement('span');\n caption.textContent =\n typeof property.title === 'string' && property.title ? property.title : humanize(name);\n const control = createControl(name, property, required.has(name));\n const markTouched = (): void => {\n touched.add(control);\n updateControlValidity(control, property, required.has(name), touched.has(control));\n };\n control.addEventListener('input', markTouched);\n control.addEventListener('change', markTouched);\n label.append(caption, control);\n form.append(label);\n controls.set(name, control);\n }\n\n const actions = document.createElement('div');\n actions.className = 'proposal-actions';\n const submit = button(options.labels.submit, 'submit');\n const decline = button(options.labels.decline, 'button');\n const cancel = button(options.labels.cancel, 'button');\n const buttons = [submit, decline, cancel];\n const resolve = async (\n response:\n | { readonly action: 'accept'; readonly content: AssistantJsonValue }\n | { readonly action: 'decline' | 'cancel' },\n ): Promise<void> => {\n buttons.forEach((item) => {\n item.disabled = true;\n });\n try {\n await options.respond(response);\n } catch (error) {\n buttons.forEach((item) => {\n item.disabled = false;\n });\n throw error;\n }\n };\n form.addEventListener('submit', (event) => {\n event.preventDefault();\n for (const [name, control] of controls) {\n updateControlValidity(\n control,\n record(properties[name]),\n required.has(name),\n touched.has(control),\n );\n }\n if (!form.reportValidity()) return;\n void resolve({\n action: 'accept',\n content: readContent(controls, properties, required, touched),\n }).catch(() => {});\n });\n decline.addEventListener('click', () => {\n void resolve({ action: 'decline' }).catch(() => {});\n });\n cancel.addEventListener('click', () => {\n void resolve({ action: 'cancel' }).catch(() => {});\n });\n actions.append(submit, decline, cancel);\n form.append(actions);\n card.append(form);\n return card;\n}\n\nfunction createControl(\n name: string,\n property: Readonly<Record<string, unknown>>,\n required: boolean,\n): HTMLInputElement | HTMLSelectElement {\n const choices = stringChoices(property);\n if (choices || property.type === 'array') {\n const select = document.createElement('select');\n select.name = name;\n select.multiple = property.type === 'array';\n const availableChoices = choices ?? arrayChoices(property);\n if (\n !select.multiple &&\n (!required || !availableChoices.some((choice) => choice.value === property.default))\n ) {\n select.append(placeholderOption(availableChoices));\n }\n for (const choice of availableChoices) {\n select.append(option(choice.title, choice.value));\n }\n applySelectDefault(select, property.default);\n updateControlValidity(select, property, required, false);\n return select;\n }\n const input = document.createElement('input');\n input.name = name;\n input.type = inputType(property);\n // JSON Schema `required` means property presence. An empty string and `false` remain present values,\n // while an empty number/date control has no representable JSON value.\n input.required = required && inputNeedsNonEmptyValue(property);\n if (property.type === 'integer') input.step = '1';\n if (typeof property.minimum === 'number') input.min = String(property.minimum);\n if (typeof property.maximum === 'number') input.max = String(property.maximum);\n if (typeof property.minLength === 'number') input.minLength = property.minLength;\n if (typeof property.maxLength === 'number') input.maxLength = property.maxLength;\n if (property.format === 'date-time') input.step = '0.001';\n applyInputDefault(input, property);\n return input;\n}\n\nfunction readContent(\n controls: ReadonlyMap<string, HTMLInputElement | HTMLSelectElement>,\n properties: Readonly<Record<string, unknown>>,\n required: ReadonlySet<string>,\n touched: Readonly<WeakSet<HTMLInputElement | HTMLSelectElement>>,\n): AssistantJsonValue {\n const content: Record<string, AssistantJsonValue> = {};\n for (const [name, control] of controls) {\n const property = record(properties[name]);\n if (control instanceof HTMLSelectElement && control.multiple) {\n const values = [...control.selectedOptions].map((option) => option.value);\n if (shouldIncludeArray(property, required.has(name), touched.has(control), values.length)) {\n content[name] = values;\n }\n } else if (control instanceof HTMLInputElement && control.type === 'checkbox') {\n if (required.has(name) || hasDefault(property) || touched.has(control)) {\n content[name] = control.checked;\n }\n } else if (control instanceof HTMLSelectElement) {\n if (!isPlaceholderSelected(control)) content[name] = control.value;\n } else if (\n control.value !== '' ||\n (property.type === 'string' &&\n (required.has(name) || hasDefault(property) || touched.has(control)))\n ) {\n if (property.format === 'date-time') {\n const value = dateTimeLocalToRfc3339(control.value);\n if (value !== undefined) content[name] = value;\n } else {\n content[name] =\n property.type === 'number' || property.type === 'integer'\n ? Number(control.value)\n : control.value;\n }\n }\n }\n return content;\n}\n\nfunction updateControlValidity(\n control: HTMLInputElement | HTMLSelectElement,\n property: Readonly<Record<string, unknown>>,\n required: boolean,\n touched: boolean,\n): void {\n control.setCustomValidity('');\n if (!(control instanceof HTMLSelectElement)) return;\n if (!control.multiple) {\n control.required = required;\n if (required && isPlaceholderSelected(control)) {\n control.setCustomValidity('Please select an option.');\n }\n return;\n }\n\n const count = control.selectedOptions.length;\n const included = shouldIncludeArray(property, required, touched, count);\n const minimum = integerBound(property.minItems);\n const maximum = integerBound(property.maxItems);\n // HTML's multi-select `required` means one selection, so it only matches a present array whose\n // schema minimum is at least one. Higher cardinality remains a custom JSON Schema constraint.\n control.required = included && minimum !== undefined && minimum > 0;\n if (included && minimum !== undefined && count < minimum) {\n control.setCustomValidity(`Select at least ${minimum} option${minimum === 1 ? '' : 's'}.`);\n } else if (included && maximum !== undefined && count > maximum) {\n control.setCustomValidity(`Select at most ${maximum} option${maximum === 1 ? '' : 's'}.`);\n }\n}\n\nfunction shouldIncludeArray(\n property: Readonly<Record<string, unknown>>,\n required: boolean,\n touched: boolean,\n selectedCount: number,\n): boolean {\n return required || hasDefault(property) || touched || selectedCount > 0;\n}\n\nfunction hasDefault(property: Readonly<Record<string, unknown>>): boolean {\n return Object.hasOwn(property, 'default');\n}\n\nfunction integerBound(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isInteger(value) && value >= 0 ? value : undefined;\n}\n\nfunction inputNeedsNonEmptyValue(property: Readonly<Record<string, unknown>>): boolean {\n if (property.type === 'number' || property.type === 'integer') return true;\n if (property.type !== 'string') return false;\n return (\n property.format === 'date' ||\n property.format === 'date-time' ||\n property.format === 'email' ||\n property.format === 'uri' ||\n (typeof property.minLength === 'number' && property.minLength > 0)\n );\n}\n\nfunction isPlaceholderSelected(select: HTMLSelectElement): boolean {\n return select.selectedOptions[0]?.dataset.placeholder === 'true';\n}\n\nfunction stringChoices(\n property: Readonly<Record<string, unknown>>,\n): readonly { readonly value: string; readonly title: string }[] | undefined {\n if (Array.isArray(property.enum) && property.enum.every((value) => typeof value === 'string')) {\n return property.enum.map((value) => ({ value, title: value }));\n }\n return titledChoices(property.oneOf) ?? titledChoices(property.anyOf);\n}\n\nfunction arrayChoices(\n property: Readonly<Record<string, unknown>>,\n): readonly { readonly value: string; readonly title: string }[] {\n return stringChoices(record(property.items)) ?? [];\n}\n\nfunction inputType(property: Readonly<Record<string, unknown>>): string {\n if (property.type === 'boolean') return 'checkbox';\n if (property.type === 'number' || property.type === 'integer') return 'number';\n if (property.format === 'date') return 'date';\n if (property.format === 'date-time') return 'datetime-local';\n if (property.format === 'email') return 'email';\n if (property.format === 'uri') return 'url';\n return 'text';\n}\n\nfunction titledChoices(\n value: unknown,\n): readonly { readonly value: string; readonly title: string }[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const choices = value.map((item) => record(item));\n if (!choices.every((item) => typeof item.const === 'string')) return undefined;\n return choices.map((item) => ({\n value: String(item.const),\n title: typeof item.title === 'string' ? item.title : String(item.const),\n }));\n}\n\nfunction applySelectDefault(select: HTMLSelectElement, value: unknown): void {\n if (select.multiple) {\n const selected = new Set(\n Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [],\n );\n for (const item of select.options) item.selected = selected.has(item.value);\n return;\n }\n if (typeof value === 'string') select.value = value;\n}\n\nfunction applyInputDefault(\n input: HTMLInputElement,\n property: Readonly<Record<string, unknown>>,\n): void {\n const value = property.default;\n if (property.type === 'boolean') {\n if (typeof value === 'boolean') input.checked = value;\n return;\n }\n if (property.type === 'number' || property.type === 'integer') {\n if (typeof value === 'number' && Number.isFinite(value)) input.value = String(value);\n return;\n }\n if (typeof value !== 'string') return;\n if (property.format === 'date-time') {\n input.value = rfc3339ToDateTimeLocal(value) ?? '';\n return;\n }\n input.value = value;\n}\n\nfunction rfc3339ToDateTimeLocal(value: string): string | undefined {\n const instant = new Date(value);\n if (Number.isNaN(instant.valueOf())) return undefined;\n return [\n String(instant.getFullYear()).padStart(4, '0'),\n '-',\n twoDigits(instant.getMonth() + 1),\n '-',\n twoDigits(instant.getDate()),\n 'T',\n twoDigits(instant.getHours()),\n ':',\n twoDigits(instant.getMinutes()),\n ':',\n twoDigits(instant.getSeconds()),\n '.',\n String(instant.getMilliseconds()).padStart(3, '0'),\n ].join('');\n}\n\nfunction dateTimeLocalToRfc3339(value: string): string | undefined {\n const instant = new Date(value);\n return Number.isNaN(instant.valueOf()) ? undefined : instant.toISOString();\n}\n\nfunction twoDigits(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nfunction button(label: string, type: HTMLButtonElement['type']): HTMLButtonElement {\n const element = document.createElement('button');\n element.type = type;\n element.textContent = label;\n return element;\n}\n\nfunction option(label: string, value: string): HTMLOptionElement {\n const element = document.createElement('option');\n element.textContent = label;\n element.value = value;\n return element;\n}\n\nfunction placeholderOption(\n choices: readonly { readonly value: string; readonly title: string }[],\n): HTMLOptionElement {\n let value = '';\n while (choices.some((choice) => choice.value === value)) value += '\\u0000';\n const element = option('', value);\n element.dataset.placeholder = 'true';\n return element;\n}\n\nfunction humanize(value: string): string {\n const words = value.replaceAll(/([a-z0-9])([A-Z])/g, '$1 $2').replaceAll(/[_-]+/g, ' ');\n return words ? `${words[0]?.toUpperCase() ?? ''}${words.slice(1)}` : value;\n}\n\nfunction record(value: unknown): Readonly<Record<string, unknown>> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Readonly<Record<string, unknown>>)\n : {};\n}\n","export type InteractionAction = 'accept' | 'decline' | 'cancel';\n\ninterface InteractionCardOptions {\n readonly tool: string;\n readonly arguments?: Readonly<Record<string, unknown>>;\n readonly labels: {\n readonly accept: string;\n readonly decline: string;\n readonly cancel: string;\n };\n readonly respond: (action: InteractionAction) => Promise<void>;\n}\n\nexport function createInteractionCard(options: InteractionCardOptions): HTMLElement {\n const card = document.createElement('section');\n card.className = 'tool-proposal';\n const label = document.createElement('strong');\n label.textContent = options.tool;\n card.append(label);\n if (options.arguments && Object.keys(options.arguments).length > 0) {\n card.append(createArgumentList(options.arguments));\n }\n const actions = document.createElement('div');\n actions.className = 'proposal-actions';\n const buttons: HTMLButtonElement[] = [];\n for (const [labelText, action] of [\n [options.labels.accept, 'accept'],\n [options.labels.decline, 'decline'],\n [options.labels.cancel, 'cancel'],\n ] as const) {\n const button = document.createElement('button');\n button.type = 'button';\n button.textContent = labelText;\n buttons.push(button);\n button.addEventListener('click', () => {\n for (const candidate of buttons) candidate.disabled = true;\n void options.respond(action).catch(() => {\n for (const candidate of buttons) candidate.disabled = false;\n });\n });\n actions.append(button);\n }\n card.append(actions);\n return card;\n}\n\nfunction createArgumentList(arguments_: Readonly<Record<string, unknown>>): HTMLDListElement {\n const details = document.createElement('dl');\n details.className = 'proposal-arguments';\n for (const [name, value] of Object.entries(arguments_)) {\n const term = document.createElement('dt');\n term.textContent = humanizeArgumentName(name);\n const description = document.createElement('dd');\n description.textContent = formatArgumentValue(value);\n details.append(term, description);\n }\n return details;\n}\n\nfunction humanizeArgumentName(value: string): string {\n const words = value.replaceAll(/([a-z0-9])([A-Z])/g, '$1 $2').replaceAll(/[_-]+/g, ' ');\n return words ? `${words[0]?.toUpperCase() ?? ''}${words.slice(1)}` : value;\n}\n\nfunction formatArgumentValue(value: unknown): string {\n if (value === null) return 'None';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value) ?? '';\n}\n","import type { AssistantConfiguration } from './appearance.js';\nimport type {\n AssistantClientEvent,\n AssistantInteractionResponse,\n AssistantToolCompletedDetail,\n AssistantViewAvailableDetail,\n} from './client.js';\nimport { createInputRequestCard } from './input-request-card.js';\nimport { createInteractionCard } from './interaction-card.js';\nimport type { AssistantErrorDetail } from './transport.js';\n\ninterface AssistantElementEventHost {\n readonly element: HTMLElement;\n readonly messages: () => HTMLElement | undefined;\n readonly appendMessage: (role: 'user' | 'assistant', text: string) => HTMLElement | undefined;\n readonly applyConfiguration: (configuration: AssistantConfiguration) => void;\n readonly labels: () => { readonly confirm: string; readonly cancel: string };\n readonly respond: (id: string, response: AssistantInteractionResponse) => Promise<void>;\n readonly dispatchError: (detail: AssistantErrorDetail) => void;\n}\n\n/** Owns streamed client-event state and its translation into the standard element renderer. */\nexport class AssistantElementEventController {\n readonly #host: AssistantElementEventHost;\n #assistantBody: HTMLElement | undefined;\n #completedTool: AssistantToolCompletedDetail | undefined;\n readonly #proposalCards = new Map<string, HTMLElement>();\n\n constructor(host: AssistantElementEventHost) {\n this.#host = host;\n }\n\n handle(event: AssistantClientEvent): void {\n if (event.event === 'view_available') {\n // Availability is not presentation proof: the standard element neither fetches nor executes\n // arbitrary `ui://` content. Embedders may map this typed identity to a trusted renderer.\n this.#host.element.dispatchEvent(\n new CustomEvent<AssistantViewAvailableDetail>('assistant-view-available', {\n detail: event.data,\n }),\n );\n return;\n }\n if (event.event === 'unrecognized') return;\n const { event: name, data } = event;\n if (name === 'session_started') {\n if (isRecord(data.configuration)) {\n this.#host.applyConfiguration(data.configuration as AssistantConfiguration);\n }\n this.#host.element.dispatchEvent(\n new CustomEvent('assistant-session-started', {\n detail: { expiresAt: String(data.expiresAt ?? '') },\n }),\n );\n return;\n }\n if (name === 'session_expired') {\n this.#host.element.dispatchEvent(new CustomEvent('assistant-session-expired'));\n return;\n }\n if (name === 'session_reset') {\n this.resetConversation();\n return;\n }\n if (name === 'context_changed') {\n this.#host.element.dispatchEvent(\n new CustomEvent('assistant-context-changed', { detail: { context: data.context } }),\n );\n return;\n }\n if (name === 'model_context_changed') {\n this.#host.element.dispatchEvent(\n new CustomEvent('assistant-model-context-changed', {\n detail: { modelContext: data.modelContext },\n }),\n );\n return;\n }\n if (name === 'message_started') {\n this.#assistantBody = undefined;\n this.#host.appendMessage('user', String(data.message ?? ''));\n this.#host.element.dispatchEvent(new CustomEvent('assistant-message-started'));\n return;\n }\n if (name === 'message_completed') {\n this.#assistantBody = undefined;\n this.#host.element.dispatchEvent(new CustomEvent('assistant-message-completed'));\n return;\n }\n if (name === 'interaction_started') {\n this.#assistantBody = undefined;\n this.#completedTool = undefined;\n return;\n }\n if (name === 'interaction_completed') {\n this.#finishInteraction(String(data.id ?? ''), String(data.action ?? 'accept'));\n return;\n }\n if (name === 'content') {\n const body = this.#assistantBody ?? this.#host.appendMessage('assistant', '');\n this.#assistantBody = body;\n if (body) body.textContent += String(data.delta ?? '');\n return;\n }\n if (name === 'tool_proposed' || name === 'interaction_proposed') {\n this.#appendToolProposal(\n String(data.id ?? ''),\n String(data.tool ?? ('title' in data ? data.title : undefined) ?? 'Action'),\n isRecord(data.arguments) ? data.arguments : undefined,\n );\n return;\n }\n if (name === 'input_requested' && isRecord(data.requestedSchema)) {\n this.#appendInputRequest(\n String(data.id ?? ''),\n String(data.message ?? 'More information is required'),\n data.requestedSchema,\n );\n return;\n }\n if (name === 'tool_completed') {\n this.#completedTool = data;\n return;\n }\n if (name === 'error') {\n this.#host.dispatchError({\n code: String(data.code ?? 'stream_failed'),\n ...(typeof data.status === 'number' ? { status: data.status } : {}),\n retryable: data.retryable === true,\n });\n }\n }\n\n resetConversation(): void {\n this.#host.messages()?.replaceChildren();\n this.#proposalCards.clear();\n this.#assistantBody = undefined;\n this.#completedTool = undefined;\n this.#host.element.dispatchEvent(new CustomEvent('assistant-session-reset'));\n }\n\n #finishInteraction(id: string, action: string): void {\n if (this.#completedTool && !this.#assistantBody) {\n this.#host.appendMessage('assistant', JSON.stringify(this.#completedTool.result ?? {}) ?? '');\n }\n this.#proposalCards.get(id)?.remove();\n this.#proposalCards.delete(id);\n if (action === 'accept') {\n this.#host.element.dispatchEvent(\n new CustomEvent('assistant-tool-completed', { detail: { id } }),\n );\n }\n this.#host.element.dispatchEvent(\n new CustomEvent('assistant-interaction-resolved', { detail: { id, action } }),\n );\n this.#assistantBody = undefined;\n this.#completedTool = undefined;\n }\n\n #appendToolProposal(\n id: string,\n tool: string,\n arguments_: Readonly<Record<string, unknown>> | undefined,\n ): void {\n const messages = this.#host.messages();\n if (!messages || !id) return;\n this.#proposalCards.get(id)?.remove();\n const labels = this.#host.labels();\n const card = createInteractionCard({\n tool,\n ...(arguments_ ? { arguments: arguments_ } : {}),\n labels: {\n accept: labels.confirm,\n decline: 'Decline',\n cancel: labels.cancel,\n },\n respond: (action) => this.#host.respond(id, { action }),\n });\n messages.append(card);\n this.#proposalCards.set(id, card);\n this.#host.element.dispatchEvent(\n new CustomEvent('assistant-tool-proposed', { detail: { id, tool, arguments: arguments_ } }),\n );\n }\n\n #appendInputRequest(\n id: string,\n message: string,\n requestedSchema: Readonly<Record<string, unknown>>,\n ): void {\n const messages = this.#host.messages();\n if (!messages || !id) return;\n this.#proposalCards.get(id)?.remove();\n const labels = this.#host.labels();\n const card = createInputRequestCard({\n message,\n requestedSchema,\n labels: {\n submit: labels.confirm,\n decline: 'Decline',\n cancel: labels.cancel,\n },\n respond: (response) => this.#host.respond(id, response),\n });\n messages.append(card);\n this.#proposalCards.set(id, card);\n this.#host.element.dispatchEvent(\n new CustomEvent('assistant-input-requested', {\n detail: { id, message, requestedSchema },\n }),\n );\n }\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","export const ASSISTANT_ELEMENT_STYLES = `<style>\n :host { color-scheme: light dark; font-family: var(--ns-assistant-font-family, var(--ns-assistant-default-font-family)); font-size: var(--ns-assistant-base-font-size, var(--ns-assistant-default-base-font-size)); line-height: var(--ns-assistant-line-height, var(--ns-assistant-default-line-height)); z-index: var(--ns-assistant-z-index, var(--ns-assistant-default-z-index)); }\n :host([data-mode=\"floating\"]) { position: fixed; bottom: 24px; right: 24px; }\n :host([data-mode=\"floating\"][data-position=\"bottom-left\"]) { right: auto; left: 24px; }\n .launcher { width: 54px; height: 54px; border: 0; border-radius: var(--ns-assistant-launcher-radius, var(--ns-assistant-default-launcher-radius)); color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); cursor: pointer; }\n .launcher img { width: 24px; height: 24px; object-fit: contain; }\n .panel { display: none; width: min(var(--ns-assistant-panel-width, var(--ns-assistant-default-panel-width)), calc(100vw - 32px)); min-height: var(--ns-assistant-min-height, var(--ns-assistant-default-min-height)); max-height: min(var(--ns-assistant-max-height, var(--ns-assistant-default-max-height)), calc(100vh - 32px)); overflow: hidden; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-panel, var(--ns-assistant-default-panel)); border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-default-panel-radius)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); }\n :host([open]) .panel { display: grid; grid-template-rows: auto auto 1fr auto; }\n :host([open]) .launcher { display: none; }\n header { display: flex; gap: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); align-items: center; padding: calc(var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)) * 1.2); border-bottom: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); }\n header strong { flex: 1; }\n .brand-logo { display: block; max-width: 120px; max-height: 28px; object-fit: contain; }\n button { font: inherit; }\n .close, .send { border: 0; border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); cursor: pointer; }\n .close { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent; font-size: 24px; }\n .welcome { padding: calc(var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)) * 1.5); }\n .welcome h2 { margin: 0; font-size: 1.25em; }\n .welcome p { margin: 6px 0 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }\n .suggested-prompts { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); }\n .suggested-prompts:empty { display: none; }\n .suggested-prompts button { padding: 7px 10px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: transparent; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; cursor: pointer; }\n .messages { min-height: 120px; padding: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); overflow: auto; }\n .message { width: fit-content; max-width: 84%; margin: 8px 0; padding: 10px 12px; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); white-space: pre-wrap; }\n .message .avatar { float: left; width: 24px; height: 24px; margin-right: 8px; border-radius: 50%; object-fit: cover; }\n .message time { display: block; margin-top: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .75em; }\n .message.user { margin-left: auto; color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }\n .tool-proposal { display: grid; gap: 10px; margin: 10px 0; padding: 12px; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); }\n .proposal-arguments { display: grid; grid-template-columns: minmax(90px, auto) 1fr; gap: 4px 10px; margin: 0; font-size: .9em; }\n .proposal-arguments dt { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }\n .proposal-arguments dd { margin: 0; overflow-wrap: anywhere; }\n .proposal-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: end; }\n .tool-proposal button { padding: 8px 10px; border: 0; border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); cursor: pointer; }\n .tool-proposal button:first-of-type { color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }\n .input-request form { display: grid; gap: 10px; padding: 0; border: 0; }\n .input-request label { display: grid; gap: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .9em; }\n .input-request input, .input-request select { width: 100%; box-sizing: border-box; padding: 8px 10px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius)); font: inherit; }\n .input-request input[type=\"checkbox\"] { width: auto; justify-self: start; }\n form { display: flex; gap: 8px; align-items: end; padding: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); border-top: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); }\n textarea { flex: 1; resize: none; padding: 10px 12px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); border: 0; border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius)); font: inherit; }\n textarea:focus-visible, button:focus-visible { outline: 3px solid var(--ns-assistant-focus, var(--ns-assistant-default-focus)); outline-offset: 2px; }\n .send { padding: 10px 14px; color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }\n .legal { display: flex; gap: 12px; justify-content: center; padding: 0 12px 10px; font-size: .8em; }\n .legal:empty { display: none; }\n .legal a { color: var(--ns-assistant-link, var(--ns-assistant-default-link)); }\n :host([data-density=\"compact\"]) .welcome { padding: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); }\n @media (max-width: 640px) { :host([mobile-fullscreen][open]) { inset: 0; } :host([mobile-fullscreen][open]) .panel { width: 100vw; min-height: 100vh; max-height: 100vh; border-radius: 0; } }\n @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; } }\n @media (max-width: 560px) { :host([data-mode=\"floating\"]) { inset: auto 12px 12px; } :host([open]) .panel { width: calc(100vw - 24px); max-height: calc(100vh - 24px); } }\n</style>`;\n","import {\n type AssistantThemeMode,\n type AssistantThemeTokens,\n resolveAppearance,\n} from './appearance.js';\nimport { browserClientContext } from './browser-context.js';\nimport {\n type AssistantClient,\n AssistantClientError,\n type AssistantContext,\n type AssistantInteractionResponse,\n type AssistantModelContextUpdate,\n createAssistantClient,\n} from './client.js';\nimport { AssistantElementEventController } from './element-event-controller.js';\nimport { ASSISTANT_ELEMENT_STYLES } from './element-styles.js';\nimport type { AssistantViewAvailableDetail } from './events.js';\nimport { copyAssistantModelContext } from './model-context.js';\nimport type { AssistantErrorDetail } from './transport.js';\n\nexport const ASSISTANT_TAG_NAME = 'noodle-assistant';\n\ndeclare global {\n interface HTMLElementEventMap {\n 'assistant-view-available': CustomEvent<AssistantViewAvailableDetail>;\n }\n}\n\nconst HTMLElementBase: typeof HTMLElement =\n globalThis.HTMLElement ?? (class {} as unknown as typeof HTMLElement);\n\nexport class NoodleAssistantElement extends HTMLElementBase {\n static readonly observedAttributes = ['open', 'theme'];\n #appearance = resolveAppearance();\n #client: AssistantClient | undefined;\n #clientEndpoint = '';\n #unsubscribeClient: (() => void) | undefined;\n #messages: HTMLElement | undefined;\n #media: MediaQueryList | undefined;\n #context: AssistantContext | undefined;\n #modelContext: AssistantModelContextUpdate | undefined;\n sessionEndpoint = '';\n readonly #events = new AssistantElementEventController({\n element: this,\n messages: () => this.#messages,\n appendMessage: (role, text) => this.#appendMessage(role, text),\n applyConfiguration: (configuration) => {\n this.#appearance = resolveAppearance(configuration);\n this.#render();\n },\n labels: () => ({\n confirm: this.#appearance.labels.confirm,\n cancel: this.#appearance.labels.cancel,\n }),\n respond: (id, response) => this.respond(id, response),\n dispatchError: (detail) => this.#dispatchError(detail),\n });\n\n connectedCallback(): void {\n if (!this.shadowRoot) this.attachShadow({ mode: 'open' });\n if (!this.sessionEndpoint) this.sessionEndpoint = this.getAttribute('session-endpoint') ?? '';\n this.#media = globalThis.matchMedia?.('(prefers-color-scheme: dark)');\n this.#media?.addEventListener('change', this.#handleSystemTheme);\n document.addEventListener('keydown', this.#handleDocumentKeydown);\n document.addEventListener('pointerdown', this.#handleDocumentPointerDown);\n if (this.#appearance.behavior.startOpen) this.setAttribute('open', '');\n this.#render();\n this.dispatchEvent(new CustomEvent('assistant-ready'));\n }\n\n disconnectedCallback(): void {\n this.#client?.abort();\n this.#unsubscribeClient?.();\n this.#client = undefined;\n this.#clientEndpoint = '';\n this.#unsubscribeClient = undefined;\n this.#media?.removeEventListener('change', this.#handleSystemTheme);\n document.removeEventListener('keydown', this.#handleDocumentKeydown);\n document.removeEventListener('pointerdown', this.#handleDocumentPointerDown);\n }\n\n attributeChangedCallback(name: string): void {\n if (name === 'theme') this.#applyTheme();\n }\n\n open(): void {\n this.setAttribute('open', '');\n this.dispatchEvent(new CustomEvent('assistant-open'));\n }\n\n close(): void {\n this.removeAttribute('open');\n this.dispatchEvent(new CustomEvent('assistant-close'));\n }\n\n toggle(): void {\n this.hasAttribute('open') ? this.close() : this.open();\n }\n\n focusComposer(): void {\n this.shadowRoot?.querySelector<HTMLTextAreaElement>('textarea')?.focus();\n }\n\n resetSession(): void {\n if (this.#client) {\n this.#client.resetSession();\n } else {\n this.#events.resetConversation();\n }\n }\n\n updateContext(context: AssistantContext): void {\n this.#context = { ...context };\n if (this.#client) {\n this.#client.updateContext(this.#context);\n } else {\n this.dispatchEvent(\n new CustomEvent('assistant-context-changed', { detail: { context: this.#context } }),\n );\n }\n }\n\n /** Replace the compact renderer summary attached to subsequent message turns. */\n updateModelContext(update: AssistantModelContextUpdate): void {\n this.#modelContext = copyAssistantModelContext(update);\n if (this.#client) {\n this.#client.updateModelContext(this.#modelContext);\n } else {\n this.dispatchEvent(\n new CustomEvent('assistant-model-context-changed', {\n detail: { modelContext: this.#modelContext },\n }),\n );\n }\n }\n\n async sendMessage(text: string): Promise<void> {\n const message = text.trim();\n if (!message) return;\n try {\n await this.#ensureClient().sendMessage(message);\n } catch (error) {\n this.#dispatchClientError(error, 'turn_failed');\n throw error;\n }\n }\n\n /**\n * Every listener the element attaches to its own DOM must go through this guard: internal UI\n * failures surface as `assistant-error` events (already dispatched by the failing path) and must\n * never escape as unhandled rejections into the embedding page. Programmatic callers use\n * `sendMessage`/`confirmTool` directly and keep the rejection.\n */\n #sendGuarded(text: string): void {\n void this.sendMessage(text).catch(() => {});\n }\n\n async confirmTool(id: string): Promise<void> {\n await this.respond(id, { action: 'accept' });\n }\n\n async respond(id: string, response: AssistantInteractionResponse): Promise<void> {\n try {\n await this.#ensureClient().respond(id, response);\n } catch (error) {\n this.#dispatchClientError(error, 'confirmation_failed');\n throw error;\n }\n }\n\n #handleSystemTheme = (): void => this.#applyTheme();\n\n #handleDocumentKeydown = (event: KeyboardEvent): void => {\n if (\n event.key === 'Escape' &&\n this.hasAttribute('open') &&\n this.#appearance.behavior.closeOnEscape\n ) {\n this.close();\n }\n };\n\n #handleDocumentPointerDown = (event: PointerEvent): void => {\n if (\n this.hasAttribute('open') &&\n this.#appearance.behavior.closeOnOutsideClick &&\n !event.composedPath().includes(this)\n ) {\n this.close();\n }\n };\n\n #ensureClient(): AssistantClient {\n if (this.#client && this.#clientEndpoint === this.sessionEndpoint) return this.#client;\n this.#client?.abort();\n this.#unsubscribeClient?.();\n const client = createAssistantClient({\n sessionEndpoint: this.sessionEndpoint,\n ...(this.#context ? { context: this.#context } : {}),\n clientContext: browserClientContext,\n ...(this.#modelContext ? { modelContext: this.#modelContext } : {}),\n });\n this.#client = client;\n this.#clientEndpoint = this.sessionEndpoint;\n this.#unsubscribeClient = client.subscribe((event) => this.#events.handle(event));\n return client;\n }\n\n #appendMessage(role: 'user' | 'assistant', text: string): HTMLElement | undefined {\n if (!this.#messages) return undefined;\n const message = document.createElement('div');\n message.className = `message ${role}`;\n if (\n role === 'assistant' &&\n this.#appearance.behavior.showAvatars &&\n this.#appearance.brand.avatar[this.#resolvedMode()]\n ) {\n const avatar = document.createElement('img');\n avatar.className = 'avatar';\n avatar.src = this.#appearance.brand.avatar[this.#resolvedMode()] ?? '';\n avatar.alt = '';\n message.append(avatar);\n }\n const body = document.createElement('span');\n body.textContent = text;\n message.append(body);\n if (this.#appearance.behavior.showTimestamps) {\n const timestamp = document.createElement('time');\n timestamp.dateTime = new Date().toISOString();\n timestamp.textContent = new Intl.DateTimeFormat(this.#appearance.locale, {\n hour: 'numeric',\n minute: '2-digit',\n }).format(new Date());\n message.append(timestamp);\n }\n this.#messages.append(message);\n return body;\n }\n\n #dispatchError(detail: AssistantErrorDetail): void {\n this.dispatchEvent(new CustomEvent('assistant-error', { detail }));\n }\n\n #dispatchClientError(error: unknown, fallbackCode: string): void {\n this.#dispatchError(\n error instanceof AssistantClientError\n ? error.detail\n : { code: fallbackCode, retryable: false },\n );\n }\n\n #resolvedMode(): Exclude<AssistantThemeMode, 'auto'> {\n const configured =\n (this.getAttribute('theme') as AssistantThemeMode | null) ??\n this.#appearance.theme.defaultMode;\n return configured === 'auto' ? (this.#media?.matches ? 'dark' : 'light') : configured;\n }\n\n #applyTheme(): void {\n const mode = this.#resolvedMode();\n this.setAttribute('data-theme', mode);\n const tokens = this.#appearance.theme[mode];\n for (const [name, value] of Object.entries(tokens)) {\n this.style.setProperty(\n `--ns-assistant-default-${camelToKebab(name)}`,\n tokenValue(name, value),\n );\n }\n this.style.setProperty(\n '--ns-assistant-default-panel-width',\n `${this.#appearance.layout.panelWidth}px`,\n );\n this.style.setProperty(\n '--ns-assistant-default-min-height',\n `${this.#appearance.layout.panelMinHeight}px`,\n );\n this.style.setProperty(\n '--ns-assistant-default-max-height',\n `${this.#appearance.layout.panelMaxHeight}px`,\n );\n this.style.setProperty(\n '--ns-assistant-default-z-index',\n String(this.#appearance.layout.zIndex),\n );\n const logo = this.shadowRoot?.querySelector<HTMLImageElement>('.brand-logo');\n const logoUrl = this.#appearance.brand.logo[mode];\n if (logo) {\n logo.hidden = !logoUrl;\n if (logoUrl) logo.src = logoUrl;\n }\n }\n\n #render(): void {\n if (!this.shadowRoot) return;\n const conversation = this.#messages ? [...this.#messages.childNodes] : [];\n const appearance = this.#appearance;\n this.setAttribute('role', 'complementary');\n this.setAttribute('aria-label', appearance.brand.name);\n this.setAttribute('lang', appearance.locale);\n this.setAttribute('dir', appearance.direction);\n this.dataset.mode = appearance.layout.mode;\n this.dataset.position = appearance.layout.position;\n this.dataset.density = appearance.layout.density;\n this.toggleAttribute('mobile-fullscreen', appearance.layout.mobileFullscreen);\n this.shadowRoot.innerHTML = `${ASSISTANT_ELEMENT_STYLES}\n <button class=\"launcher\" type=\"button\" aria-label=\"${escapeAttribute(appearance.labels.open)}\"><slot name=\"launcher-icon\">✦</slot></button>\n <section class=\"panel\" aria-label=\"${escapeAttribute(appearance.brand.name)}\">\n <header><slot name=\"header-leading\"></slot><img class=\"brand-logo\" alt=\"\"><strong></strong><slot name=\"header-actions\"></slot><button class=\"close\" type=\"button\" aria-label=\"${escapeAttribute(appearance.labels.close)}\">×</button></header>\n <div class=\"welcome\"><slot name=\"empty-state\"><h2></h2><p></p></slot></div>\n <div class=\"suggested-prompts\"></div>\n <div class=\"messages\" aria-live=\"polite\"></div>\n <form><slot name=\"composer-leading\"></slot><textarea rows=\"1\"></textarea><button class=\"send\" type=\"submit\"></button><slot name=\"composer-trailing\"></slot></form>\n <nav class=\"legal\" aria-label=\"Legal\"></nav>\n <slot name=\"conversation-footer\"></slot>\n </section>`;\n queryRequired<HTMLElement>(this.shadowRoot, 'strong').textContent = appearance.brand.name;\n const launcherIcon = appearance.brand.mark[this.#resolvedMode()];\n if (launcherIcon) {\n const launcherSlot = queryRequired<HTMLSlotElement>(\n this.shadowRoot,\n 'slot[name=\"launcher-icon\"]',\n );\n const icon = document.createElement('img');\n icon.src = launcherIcon;\n icon.alt = '';\n launcherSlot.replaceChildren(icon);\n }\n const logo = queryRequired<HTMLImageElement>(this.shadowRoot, '.brand-logo');\n const logoUrl = appearance.brand.logo[this.#resolvedMode()];\n if (logoUrl) {\n logo.src = logoUrl;\n logo.alt = appearance.brand.name;\n } else {\n logo.hidden = true;\n }\n queryRequired<HTMLElement>(this.shadowRoot, 'h2').textContent =\n appearance.labels.welcomeHeading;\n queryRequired<HTMLElement>(this.shadowRoot, 'p').textContent = appearance.labels.welcomeMessage;\n const textarea = queryRequired<HTMLTextAreaElement>(this.shadowRoot, 'textarea');\n textarea.placeholder = appearance.labels.composerPlaceholder;\n textarea.setAttribute('aria-label', appearance.labels.composerPlaceholder);\n queryRequired<HTMLElement>(this.shadowRoot, '.send').textContent = appearance.labels.send;\n const prompts = queryRequired<HTMLElement>(this.shadowRoot, '.suggested-prompts');\n for (const prompt of appearance.suggestedPrompts) {\n const button = document.createElement('button');\n button.type = 'button';\n button.textContent = prompt;\n button.addEventListener('click', () => this.#sendGuarded(prompt));\n prompts.append(button);\n }\n if (!appearance.behavior.showLauncher)\n queryRequired<HTMLElement>(this.shadowRoot, '.launcher').hidden = true;\n if (!appearance.behavior.showHeader)\n queryRequired<HTMLElement>(this.shadowRoot, 'header').hidden = true;\n const legal = queryRequired<HTMLElement>(this.shadowRoot, '.legal');\n for (const [label, href] of [\n ['Privacy', appearance.privacyUrl],\n ['Terms', appearance.termsUrl],\n ] as const) {\n if (!href) continue;\n const link = document.createElement('a');\n link.href = href;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n link.textContent = label;\n legal.append(link);\n }\n this.#messages = this.shadowRoot.querySelector('.messages') ?? undefined;\n this.#messages?.append(...conversation);\n this.shadowRoot.querySelector('.launcher')?.addEventListener('click', () => this.open());\n this.shadowRoot.querySelector('.close')?.addEventListener('click', () => this.close());\n this.shadowRoot.querySelector('form')?.addEventListener('submit', (event) => {\n event.preventDefault();\n const value = textarea.value;\n textarea.value = '';\n this.#sendGuarded(value);\n });\n this.#applyTheme();\n }\n}\n\nexport function registerNoodleAssistant(): void {\n if (globalThis.customElements && !customElements.get(ASSISTANT_TAG_NAME)) {\n customElements.define(ASSISTANT_TAG_NAME, NoodleAssistantElement);\n }\n}\n\nfunction camelToKebab(value: string): string {\n return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n\nfunction tokenValue(name: string, value: AssistantThemeTokens[keyof AssistantThemeTokens]): string {\n if (typeof value !== 'number') return value;\n if (name === 'lineHeight' || name === 'motionScale') return String(value);\n return `${value}px`;\n}\n\nfunction escapeAttribute(value: string): string {\n return value.replaceAll('&', '&amp;').replaceAll('\"', '&quot;').replaceAll('<', '&lt;');\n}\n\nfunction queryRequired<T extends Element>(root: ShadowRoot, selector: string): T {\n const element = root.querySelector<T>(selector);\n if (!element) throw new Error(`assistant renderer is missing ${selector}`);\n return element;\n}\n"],"mappings":"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","names":["copy","isRecord","isRecord","option","button","isRecord","button","NoodleAssistant"]}
package/dist/react.d.cts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { A as AssistantThemeMode } from './appearance-KDbtkt2G.cjs';
3
- import { AssistantErrorDetail, NoodleAssistantElement } from './index.cjs';
3
+ import { NoodleAssistantElement } from './index.cjs';
4
+ import { A as AssistantErrorDetail } from './client-CwvdK4O6.cjs';
4
5
 
5
6
  interface NoodleAssistantProps {
6
7
  readonly sessionEndpoint: string;
package/dist/react.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { A as AssistantThemeMode } from './appearance-KDbtkt2G.js';
3
- import { AssistantErrorDetail, NoodleAssistantElement } from './index.js';
3
+ import { NoodleAssistantElement } from './index.js';
4
+ import { A as AssistantErrorDetail } from './client-DkAfqcSb.js';
4
5
 
5
6
  interface NoodleAssistantProps {
6
7
  readonly sessionEndpoint: string;
package/dist/react.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  registerNoodleAssistant
3
- } from "./chunk-IM7SAHNE.js";
3
+ } from "./chunk-J2YDKISA.js";
4
+ import "./chunk-WUDHE5BD.js";
4
5
 
5
6
  // src/react.ts
6
7
  import {
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react.ts"],"sourcesContent":["import {\n createElement,\n forwardRef,\n type ReactElement,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\nimport type { AssistantThemeMode } from './appearance.js';\nimport { type NoodleAssistantElement, registerNoodleAssistant } from './element.js';\nimport type { AssistantErrorDetail } from './transport.js';\n\nexport interface NoodleAssistantProps {\n readonly sessionEndpoint: string;\n readonly theme?: AssistantThemeMode;\n readonly open?: boolean;\n readonly className?: string;\n readonly onReady?: () => void;\n readonly onError?: (error: AssistantErrorDetail) => void;\n readonly onSessionExpired?: () => void;\n}\n\nexport const NoodleAssistant = forwardRef<NoodleAssistantElement, NoodleAssistantProps>(\n function NoodleAssistant(props, forwardedRef): ReactElement {\n const ref = useRef<NoodleAssistantElement>(null);\n useImperativeHandle(forwardedRef, () => ref.current as NoodleAssistantElement, []);\n useEffect(() => {\n registerNoodleAssistant();\n const element = ref.current;\n if (!element) return;\n element.sessionEndpoint = props.sessionEndpoint;\n const ready = () => props.onReady?.();\n const error = (event: Event) =>\n props.onError?.((event as CustomEvent<AssistantErrorDetail>).detail);\n const expired = () => props.onSessionExpired?.();\n element.addEventListener('assistant-ready', ready);\n element.addEventListener('assistant-error', error);\n element.addEventListener('assistant-session-expired', expired);\n return () => {\n element.removeEventListener('assistant-ready', ready);\n element.removeEventListener('assistant-error', error);\n element.removeEventListener('assistant-session-expired', expired);\n };\n }, [props.onError, props.onReady, props.onSessionExpired, props.sessionEndpoint]);\n return createElement('noodle-assistant', {\n ref,\n class: props.className,\n 'session-endpoint': props.sessionEndpoint,\n ...(props.theme ? { theme: props.theme } : {}),\n ...(props.open ? { open: '' } : {}),\n });\n },\n);\n"],"mappings":";;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAeA,IAAM,kBAAkB;AAAA,EAC7B,SAASA,iBAAgB,OAAO,cAA4B;AAC1D,UAAM,MAAM,OAA+B,IAAI;AAC/C,wBAAoB,cAAc,MAAM,IAAI,SAAmC,CAAC,CAAC;AACjF,cAAU,MAAM;AACd,8BAAwB;AACxB,YAAM,UAAU,IAAI;AACpB,UAAI,CAAC,QAAS;AACd,cAAQ,kBAAkB,MAAM;AAChC,YAAM,QAAQ,MAAM,MAAM,UAAU;AACpC,YAAM,QAAQ,CAAC,UACb,MAAM,UAAW,MAA4C,MAAM;AACrE,YAAM,UAAU,MAAM,MAAM,mBAAmB;AAC/C,cAAQ,iBAAiB,mBAAmB,KAAK;AACjD,cAAQ,iBAAiB,mBAAmB,KAAK;AACjD,cAAQ,iBAAiB,6BAA6B,OAAO;AAC7D,aAAO,MAAM;AACX,gBAAQ,oBAAoB,mBAAmB,KAAK;AACpD,gBAAQ,oBAAoB,mBAAmB,KAAK;AACpD,gBAAQ,oBAAoB,6BAA6B,OAAO;AAAA,MAClE;AAAA,IACF,GAAG,CAAC,MAAM,SAAS,MAAM,SAAS,MAAM,kBAAkB,MAAM,eAAe,CAAC;AAChF,WAAO,cAAc,oBAAoB;AAAA,MACvC;AAAA,MACA,OAAO,MAAM;AAAA,MACb,oBAAoB,MAAM;AAAA,MAC1B,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,MAC5C,GAAI,MAAM,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;AAAA,IACnC,CAAC;AAAA,EACH;AACF;","names":["NoodleAssistant"]}
1
+ {"version":3,"sources":["../src/react.ts"],"sourcesContent":["import {\n createElement,\n forwardRef,\n type ReactElement,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\nimport type { AssistantThemeMode } from './appearance.js';\nimport { type NoodleAssistantElement, registerNoodleAssistant } from './element.js';\nimport type { AssistantErrorDetail } from './transport.js';\n\nexport interface NoodleAssistantProps {\n readonly sessionEndpoint: string;\n readonly theme?: AssistantThemeMode;\n readonly open?: boolean;\n readonly className?: string;\n readonly onReady?: () => void;\n readonly onError?: (error: AssistantErrorDetail) => void;\n readonly onSessionExpired?: () => void;\n}\n\nexport const NoodleAssistant = forwardRef<NoodleAssistantElement, NoodleAssistantProps>(\n function NoodleAssistant(props, forwardedRef): ReactElement {\n const ref = useRef<NoodleAssistantElement>(null);\n useImperativeHandle(forwardedRef, () => ref.current as NoodleAssistantElement, []);\n useEffect(() => {\n registerNoodleAssistant();\n const element = ref.current;\n if (!element) return;\n element.sessionEndpoint = props.sessionEndpoint;\n const ready = () => props.onReady?.();\n const error = (event: Event) =>\n props.onError?.((event as CustomEvent<AssistantErrorDetail>).detail);\n const expired = () => props.onSessionExpired?.();\n element.addEventListener('assistant-ready', ready);\n element.addEventListener('assistant-error', error);\n element.addEventListener('assistant-session-expired', expired);\n return () => {\n element.removeEventListener('assistant-ready', ready);\n element.removeEventListener('assistant-error', error);\n element.removeEventListener('assistant-session-expired', expired);\n };\n }, [props.onError, props.onReady, props.onSessionExpired, props.sessionEndpoint]);\n return createElement('noodle-assistant', {\n ref,\n class: props.className,\n 'session-endpoint': props.sessionEndpoint,\n ...(props.theme ? { theme: props.theme } : {}),\n ...(props.open ? { open: '' } : {}),\n });\n },\n);\n"],"mappings":";;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAeA,IAAM,kBAAkB;AAAA,EAC7B,SAASA,iBAAgB,OAAO,cAA4B;AAC1D,UAAM,MAAM,OAA+B,IAAI;AAC/C,wBAAoB,cAAc,MAAM,IAAI,SAAmC,CAAC,CAAC;AACjF,cAAU,MAAM;AACd,8BAAwB;AACxB,YAAM,UAAU,IAAI;AACpB,UAAI,CAAC,QAAS;AACd,cAAQ,kBAAkB,MAAM;AAChC,YAAM,QAAQ,MAAM,MAAM,UAAU;AACpC,YAAM,QAAQ,CAAC,UACb,MAAM,UAAW,MAA4C,MAAM;AACrE,YAAM,UAAU,MAAM,MAAM,mBAAmB;AAC/C,cAAQ,iBAAiB,mBAAmB,KAAK;AACjD,cAAQ,iBAAiB,mBAAmB,KAAK;AACjD,cAAQ,iBAAiB,6BAA6B,OAAO;AAC7D,aAAO,MAAM;AACX,gBAAQ,oBAAoB,mBAAmB,KAAK;AACpD,gBAAQ,oBAAoB,mBAAmB,KAAK;AACpD,gBAAQ,oBAAoB,6BAA6B,OAAO;AAAA,MAClE;AAAA,IACF,GAAG,CAAC,MAAM,SAAS,MAAM,SAAS,MAAM,kBAAkB,MAAM,eAAe,CAAC;AAChF,WAAO,cAAc,oBAAoB;AAAA,MACvC;AAAA,MACA,OAAO,MAAM;AAAA,MACb,oBAAoB,MAAM;AAAA,MAC1B,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,MAC5C,GAAI,MAAM,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;AAAA,IACnC,CAAC;AAAA,EACH;AACF;","names":["NoodleAssistant"]}
package/dist/server.cjs CHANGED
@@ -40,7 +40,8 @@ async function createAssistantSession(input, dependencies = {}) {
40
40
  origin: input.origin,
41
41
  user: input.user,
42
42
  ...input.claims ? { claims: input.claims } : {},
43
- ...input.context ? { context: input.context } : {}
43
+ ...input.context ? { context: input.context } : {},
44
+ ...input.preferences ? { preferences: input.preferences } : {}
44
45
  })
45
46
  });
46
47
  if (!response.ok) throw new Error(`Assistant session exchange failed (${response.status})`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import type { AssistantConfiguration } from './appearance.js';\n\nexport interface CreateAssistantSessionInput {\n readonly serviceUrl: string;\n readonly clientId: string;\n readonly clientSecret: string;\n /** Browser origin to bind into the short-lived assistant session. */\n readonly origin: string;\n readonly user: {\n readonly id: string;\n readonly email?: string;\n readonly name?: string;\n readonly tenant?: string;\n readonly roles?: readonly string[];\n };\n readonly context?: Readonly<Record<string, string | number | boolean | null>>;\n /**\n * Verified session claims from your authenticated backend. Only claims the server declares in\n * `embeddedAssistant({ sessionClaims })` reach tools (`\\${user.claims.<key>}`) and, when marked\n * `exposeToModel`, the assistant's identity context. Flat scalars only.\n */\n readonly claims?: Readonly<Record<string, string | number | boolean | null>>;\n}\n\nexport interface AssistantSession {\n readonly token: string;\n readonly expiresAt: string;\n readonly endpoints: {\n readonly turns: string;\n readonly toolConfirmations: string;\n };\n readonly configuration?: AssistantConfiguration;\n}\n\nexport async function createAssistantSession(\n input: CreateAssistantSessionInput,\n dependencies: { readonly fetch?: typeof fetch } = {},\n): Promise<AssistantSession> {\n const request = dependencies.fetch ?? fetch;\n const serviceUrl = input.serviceUrl.replace(/\\/$/, '');\n const credentials = Buffer.from(`${input.clientId}:${input.clientSecret}`, 'utf8').toString(\n 'base64',\n );\n const response = await request(`${serviceUrl}/v1/assistant/sessions`, {\n method: 'POST',\n headers: {\n Authorization: `Basic ${credentials}`,\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n origin: input.origin,\n user: input.user,\n ...(input.claims ? { claims: input.claims } : {}),\n ...(input.context ? { context: input.context } : {}),\n }),\n });\n if (!response.ok) throw new Error(`Assistant session exchange failed (${response.status})`);\n return (await response.json()) as AssistantSession;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCA,eAAsB,uBACpB,OACA,eAAkD,CAAC,GACxB;AAC3B,QAAM,UAAU,aAAa,SAAS;AACtC,QAAM,aAAa,MAAM,WAAW,QAAQ,OAAO,EAAE;AACrD,QAAM,cAAc,OAAO,KAAK,GAAG,MAAM,QAAQ,IAAI,MAAM,YAAY,IAAI,MAAM,EAAE;AAAA,IACjF;AAAA,EACF;AACA,QAAM,WAAW,MAAM,QAAQ,GAAG,UAAU,0BAA0B;AAAA,IACpE,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,eAAe,SAAS,WAAW;AAAA,MACnC,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,MAC/C,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,IACpD,CAAC;AAAA,EACH,CAAC;AACD,MAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,sCAAsC,SAAS,MAAM,GAAG;AAC1F,SAAQ,MAAM,SAAS,KAAK;AAC9B;","names":[]}
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import type { AssistantConfiguration } from './appearance.js';\n\nexport interface CreateAssistantSessionInput {\n readonly serviceUrl: string;\n readonly clientId: string;\n readonly clientSecret: string;\n /** Browser origin to bind into the short-lived assistant session. */\n readonly origin: string;\n readonly user: {\n readonly id: string;\n readonly email?: string;\n readonly name?: string;\n readonly tenant?: string;\n readonly roles?: readonly string[];\n };\n readonly context?: Readonly<Record<string, string | number | boolean | null>>;\n /** Backend-verified user preferences; these outrank untrusted browser presentation hints. */\n readonly preferences?: {\n readonly locale?: string;\n readonly timeZone?: string;\n };\n /**\n * Verified session claims from your authenticated backend. Only claims the server declares in\n * `embeddedAssistant({ sessionClaims })` reach tools (`\\${user.claims.<key>}`) and, when marked\n * `exposeToModel`, the assistant's identity context. Flat scalars only.\n */\n readonly claims?: Readonly<Record<string, string | number | boolean | null>>;\n}\n\nexport interface AssistantSession {\n readonly token: string;\n readonly expiresAt: string;\n readonly endpoints: {\n readonly turns: string;\n readonly toolConfirmations: string;\n readonly interactions?: string;\n };\n readonly configuration?: AssistantConfiguration;\n}\n\nexport async function createAssistantSession(\n input: CreateAssistantSessionInput,\n dependencies: { readonly fetch?: typeof fetch } = {},\n): Promise<AssistantSession> {\n const request = dependencies.fetch ?? fetch;\n const serviceUrl = input.serviceUrl.replace(/\\/$/, '');\n const credentials = Buffer.from(`${input.clientId}:${input.clientSecret}`, 'utf8').toString(\n 'base64',\n );\n const response = await request(`${serviceUrl}/v1/assistant/sessions`, {\n method: 'POST',\n headers: {\n Authorization: `Basic ${credentials}`,\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n origin: input.origin,\n user: input.user,\n ...(input.claims ? { claims: input.claims } : {}),\n ...(input.context ? { context: input.context } : {}),\n ...(input.preferences ? { preferences: input.preferences } : {}),\n }),\n });\n if (!response.ok) throw new Error(`Assistant session exchange failed (${response.status})`);\n return (await response.json()) as AssistantSession;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwCA,eAAsB,uBACpB,OACA,eAAkD,CAAC,GACxB;AAC3B,QAAM,UAAU,aAAa,SAAS;AACtC,QAAM,aAAa,MAAM,WAAW,QAAQ,OAAO,EAAE;AACrD,QAAM,cAAc,OAAO,KAAK,GAAG,MAAM,QAAQ,IAAI,MAAM,YAAY,IAAI,MAAM,EAAE;AAAA,IACjF;AAAA,EACF;AACA,QAAM,WAAW,MAAM,QAAQ,GAAG,UAAU,0BAA0B;AAAA,IACpE,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,eAAe,SAAS,WAAW;AAAA,MACnC,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,MAC/C,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,MAClD,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAChE,CAAC;AAAA,EACH,CAAC;AACD,MAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,sCAAsC,SAAS,MAAM,GAAG;AAC1F,SAAQ,MAAM,SAAS,KAAK;AAC9B;","names":[]}
package/dist/server.d.cts CHANGED
@@ -14,6 +14,11 @@ interface CreateAssistantSessionInput {
14
14
  readonly roles?: readonly string[];
15
15
  };
16
16
  readonly context?: Readonly<Record<string, string | number | boolean | null>>;
17
+ /** Backend-verified user preferences; these outrank untrusted browser presentation hints. */
18
+ readonly preferences?: {
19
+ readonly locale?: string;
20
+ readonly timeZone?: string;
21
+ };
17
22
  /**
18
23
  * Verified session claims from your authenticated backend. Only claims the server declares in
19
24
  * `embeddedAssistant({ sessionClaims })` reach tools (`\${user.claims.<key>}`) and, when marked
@@ -27,6 +32,7 @@ interface AssistantSession {
27
32
  readonly endpoints: {
28
33
  readonly turns: string;
29
34
  readonly toolConfirmations: string;
35
+ readonly interactions?: string;
30
36
  };
31
37
  readonly configuration?: AssistantConfiguration;
32
38
  }