import { UploadStatus } from '../upload-types.js'; import { ShowToastFn, ChatUser, RecordOrUndef, UserAwsCredentials, MarkdownRendererConfig, WidgetRenderingContextType, ShareSessionState, UserPrefs, ChatAppMode, IUserWidgetDataStoreState, CustomDataUiRepresentation, ChatAppOverridableFeatures, TagDefinition, TagDefinitionWidget, ChatSession, UserDataOverrideSettings, ChatMessageForRendering, ChatApp, ChatAppActionMenu, ChatAppAction, WidgetInstance, WidgetSizing, InvokeAgentAsComponentOptions, IntentRouterHandler } from './chatbot-types.js'; import '@aws-sdk/client-bedrock-agent-runtime'; import '@aws-sdk/client-bedrock-agentcore'; /** * Note!!! The interfaces in this file are meant to expose public functionality to the web component authors. * They are not meant to be exhaustive or complete. */ type SidebarState = any; type Snippet = any; /** Declare global event map for pika context request */ declare global { interface HTMLElementEventMap { 'pika-wc-context-request': PikaWCContextRequestEvent; } } interface IIdentityState { readonly fullName: string; readonly initials: string; readonly user: ChatUser; readonly isSiteAdmin: boolean; readonly isInternalUser: boolean; readonly isContentAdmin: boolean; getUserAwsCredentials(): Promise; } interface IAppState { readonly showToast: ShowToastFn; readonly identity: IIdentityState; readonly isMobile: boolean; /** * Convert markdown to HTML. This is a helper function for convenience. * @param markdown - The markdown content to convert to HTML * @param config - Optional configuration for the markdown renderer * @returns The HTML content * @since 0.13.0 */ convertMarkdownToHtml(markdown: string, config?: MarkdownRendererConfig): string; } /** * Widget Metadata API - scoped to a specific widget instance. * Returned by getWidgetMetadataAPI() and bound to the widget's instanceId. * * This API allows widgets to register and update their display metadata (title and actions) * which the parent app uses to render context-appropriate chrome. * * @example * ```js * const ctx = await getPikaContext($host()); * const metadata = ctx.chatAppState.getWidgetMetadataAPI('weather', 'favorite-cities', ctx.instanceId, ctx.renderingContext); * * metadata.setMetadata({ * title: 'Favorite Cities', * actions: [ * { id: 'refresh', title: 'Refresh', iconSvg: '...', callback: () => refresh() } * ] * }); * ``` */ interface IWidgetMetadataAPI { /** * Register or update complete metadata (title and actions). * Replaces any previously registered metadata for this widget instance. * * @param metadata - The metadata to register * * @example * ```js * metadata.setMetadata({ * title: 'Weather Comparison', * actions: [ * { id: 'refresh', title: 'Refresh', iconSvg: '...', callback: () => refresh() }, * { id: 'settings', title: 'Settings', iconSvg: '...', callback: () => showSettings() } * ] * }); * ``` */ setMetadata(metadata: WidgetMetadata): void; /** * Update just the widget title without affecting actions. * * @param title - The new title * * @example * ```js * metadata.updateTitle(`Temperature Trend - ${newCity}`); * ``` */ updateTitle(title: string): void; /** * Update a specific action's properties (e.g., disable/enable). * Only updates the properties provided in `updates`. * * @param actionId - The ID of the action to update * @param updates - Partial properties to update (cannot change id or callback) * * @example * ```js * // Disable the refresh button during loading * metadata.updateAction('refresh', { disabled: true }); * * // Re-enable it after loading * metadata.updateAction('refresh', { disabled: false }); * ``` */ updateAction(actionId: string, updates: Partial>): void; /** * Add a new action button dynamically. * * @param action - The action to add * * @example * ```js * if (userHasPremium) { * metadata.addAction({ * id: 'export', * title: 'Export data', * iconSvg: '...', * callback: () => exportData() * }); * } * ``` */ addAction(action: WidgetAction): void; /** * Remove an action button. * * @param actionId - The ID of the action to remove * * @example * ```js * metadata.removeAction('export'); * ``` */ removeAction(actionId: string): void; /** * Set the loading status for the widget. * * @param loading - Whether the widget is loading * @param loadingMsg - The message to display while loading * * @example * ```js * metadata.setLoadingStatus(true, 'Loading...'); * ``` */ setLoadingStatus(loading: boolean, loadingMsg?: string): void; } /** * Event types for ChatAppState event system. * @since 0.17.0 */ interface ChatAppEvents { /** Fired when any widget instance is opened/rendered */ widgetOpen: { tagId: string; renderingContext: WidgetRenderingContextType; instanceId: string; }; /** Fired when any widget instance is closed/destroyed */ widgetClose: { tagId: string; renderingContext: WidgetRenderingContextType; instanceId: string; }; /** Fired when a widget signals it has finished loading and is ready @since 0.18.0 */ widgetReady: { tagId: string; renderingContext: WidgetRenderingContextType; instanceId: string; }; /** Fired when a canvas widget is opened */ canvasOpen: { tagId: string; instanceId?: string; }; /** Fired when a canvas widget is closed */ canvasClose: { tagId: string; instanceId?: string; }; /** Fired when chat pane is minimized to strip */ chatPaneMinimized: Record; /** Fired when chat pane is expanded from strip */ chatPaneExpanded: Record; /** Fired when companion mode is entered */ companionModeEnter: Record; /** Fired when companion mode is exited */ companionModeExit: Record; /** Fired before hero widget starts showing (widget can prepare) @since 0.18.0 */ heroWillShow: Record; /** Fired after hero widget is shown @since 0.18.0 */ heroDidShow: Record; /** Fired before hero widget starts hiding (widget can cleanup) @since 0.18.0 */ heroWillHide: Record; /** Fired after hero widget is hidden @since 0.18.0 */ heroDidHide: Record; /** Fired when hero widget is collapsed to header bar @since 0.18.0 */ heroCollapse: Record; /** Fired when hero widget is expanded from collapsed state @since 0.18.0 */ heroExpand: Record; /** Fired when spotlight area is shown @since 0.18.0 */ spotlightShow: Record; /** Fired when spotlight area is hidden @since 0.18.0 */ spotlightHide: Record; /** Fired when a question is suggested via suggestQuestion() - used to trigger input highlight animation @since 0.18.0 */ questionSuggested: { text: string; }; } /** Event handler type for ChatAppEvents */ type ChatAppEventHandler = (data: ChatAppEvents[K]) => void; interface IChatAppState { readonly entityFeatureEnabled: boolean; readonly shareCurrentSessionState: ShareSessionState; readonly showToast: ShowToastFn; readonly userPrefs: IUserPrefsState; readonly mode: ChatAppMode; /** * Get component-specific storage scoped to this component (scope.tag) and current user. * Max 400KB per component. */ getUserWidgetDataStoreState(scope: string, tag: string): IUserWidgetDataStoreState; readonly customDataUiRepresentation: CustomDataUiRepresentation | undefined; readonly features: ChatAppOverridableFeatures; readonly tagDefs: TagDefinition[]; readonly userIsContentAdmin: boolean; readonly userNeedsToProvideDataOverrides: boolean; readonly isViewingContentForAnotherUser: boolean; readonly currentSessionIsSharedBySomeoneElse: boolean; readonly currentShareId: string | undefined; readonly currentSessionIsReadOnly: boolean; readonly sortedChatSessions: ChatSession[]; readonly userDataOverrideSettings: UserDataOverrideSettings; readonly enableFileUpload: boolean; readonly chatSessions: ChatSession[]; readonly waitingForFirstStreamedResponse: boolean; readonly isStreamingResponseNow: boolean; readonly isInterimSession: boolean; readonly currentSession: ChatSession; readonly currentSessionMessages: ChatMessageForRendering[]; readonly inputFiles: IUploadInstance[]; readonly newSession: boolean; /** * The current chat input text. Can be set to pre-populate the chat input field. * Useful for AI helper icons that want to pre-fill a contextual question. * @example context.chatAppState.chatInput = 'Help me with this field'; */ chatInput: string; readonly chatApp: ChatApp; readonly retrievingMessages: boolean; readonly pageTitle: string | undefined; readonly customDataForChatApp: Record | undefined; readonly customTitleBarActions: (ChatAppActionMenu | ChatAppAction)[]; readonly widgetInstances: Map; /** * Current user information * @since 0.11.0 */ readonly user: ChatUser; setCurrentSessionById(sessionId: string): void; removeFile(s3Key: string): void; startNewChatSession(): void; refreshChatSessions(): Promise; downloadFile(s3Key: string): Promise; refreshMessagesForCurrentSession(): Promise; sendMessage(): Promise; getMessageByMessageId(messageId: string): ChatMessageForRendering | undefined; uploadFiles(files: File[]): Promise; initializeData(): Promise; /** * Render a tag in a specific context * @param metadata - Optional metadata for the widget (title, actions, icon). For canvas context, can include CanvasWidgetOptions (companionMode, etc.) * @since 0.11.0 - Added metadata parameter */ renderTag(tagId: string, context: 'spotlight' | 'inline' | 'dialog' | 'canvas' | 'static' | 'hero', data?: Record, metadata?: WidgetMetadata | CanvasWidgetOptions): Promise; closeCanvas(): void; closeDialog(): void; /** * Request to close the canvas widget. * Unlike closeCanvas(), this method respects the closeConfig settings: * - If confirmOnClose is true, shows confirmation dialog first * - Useful for fullControl widgets that provide their own close button * * @returns Promise that resolves to true if closed, false if user cancelled * @since 0.17.0 */ requestCanvasClose(): Promise; /** * Show the hero widget. Hero must have been previously rendered via renderTag() to be shown. * @since 0.17.0 */ showHero(): void; /** * Hide the hero widget. Does not destroy it - just hides it. * The widget remains in memory and can be shown again via showHero(). * @since 0.17.0 */ hideHero(): void; /** * Close and destroy the hero widget completely. * @since 0.17.0 */ closeHero(): void; /** * Whether the hero widget is currently visible. * @since 0.17.0 */ readonly heroVisible: boolean; /** * Whether the hero widget is currently collapsed to a header bar. * @since 0.18.0 */ readonly heroCollapsed: boolean; /** * Collapse the hero widget to a compact header bar. * @since 0.18.0 */ collapseHero(): void; /** * Expand the hero widget from collapsed state. * @since 0.18.0 */ expandHero(): void; /** * Toggle hero expanded/collapsed state. * @since 0.18.0 */ toggleHeroCollapsed(): void; /** * Signal that a widget has finished loading and is ready to receive commands. * Widgets should call this after initialization is complete. * This is a best practice for widgets that load data asynchronously. * @param instanceId - The widget instance ID * @since 0.18.0 */ signalWidgetReady(instanceId: string): void; /** * Suggest a question to the user by pre-filling the chat input. * Useful for AI assist buttons that want to help users ask contextual questions. * * @param text - The question text to pre-fill * @param options - Optional settings * @param options.focus - If true (default), focus the input field * @param options.highlight - If true (default), briefly highlight the input to draw attention * @param options.expandChatPane - If true (default), expand the chat pane if minimized (companion mode) * @example * chatAppState.suggestQuestion('What does this weather pattern mean?', { highlight: true }); * @since 0.18.0 */ suggestQuestion(text: string, options?: { focus?: boolean; highlight?: boolean; expandChatPane?: boolean; }): void; /** * Show/expand the spotlight area. * @since 0.18.0 */ showSpotlight(): void; /** * Hide/collapse the spotlight area. Does not destroy widgets - just hides the carousel. * Widgets remain in memory and can be shown again via showSpotlight(). * @since 0.18.0 */ hideSpotlight(): void; /** * Toggle spotlight visibility. * If visible, hides it. If hidden, shows it. * @since 0.18.0 */ toggleSpotlight(): void; /** * Whether the spotlight area is currently visible/expanded. * @since 0.18.0 */ readonly spotlightVisible: boolean; /** * Whether companion mode is currently active. * Companion mode is active when a canvas widget is open with companionMode: true. * @since 0.17.0 */ readonly isCompanionMode: boolean; /** * Whether the chat pane is currently minimized to a strip. * Only relevant when companion mode is active. * @since 0.17.0 */ readonly isChatPaneMinimized: boolean; /** * Minimize or expand the chat pane to/from a thin strip. * Only has effect when companion mode is active. * @param minimized - true to minimize, false to expand * @since 0.17.0 */ setChatPaneMinimized(minimized: boolean): void; /** * Subscribe to chat app events. * @param event - The event type to subscribe to * @param handler - The callback function to invoke when the event fires * @param instanceId - Optional widget instance ID. If provided, the handler will be * automatically cleaned up when the widget is destroyed, preventing memory leaks. * Widgets should always pass their instanceId when registering events. * @returns A function to unsubscribe * @since 0.17.0 */ addEventListener(event: K, handler: ChatAppEventHandler, instanceId?: string): () => void; /** * Unsubscribe from chat app events. * @param event - The event type to unsubscribe from * @param handler - The callback function to remove * @since 0.17.0 */ removeEventListener(event: K, handler: ChatAppEventHandler): void; setOrUpdateCustomTitleBarAction(action: ChatAppActionMenu | ChatAppAction): void; removeCustomTitleBarAction(actionId: string): void; getWidgetInstance(instanceId: string): WidgetInstance | undefined; /** * Get the full context for a widget instance * @since 0.11.0 */ getWidgetContext(instanceId: string): PikaWCContext | undefined; /** * Update context for a widget. Call this when your widget's context has changed. * * This method will re-check your widget's `getContextForLlm()` method and update * the context accordingly. Use this when: * - Your widget initially had no context, but now has context to share * - Your widget's context data has changed (e.g., user selected different items) * - You want to change whether context should be auto-added * * @param instanceId - Your widget's instance ID (from getPikaContext()) * * @example * ```typescript * // In a Svelte widget component: * let selectedCities = $state([]); * * onMount(async () => { * const context = await getPikaContext($host()); * * // Update context whenever selection changes * $effect(() => { * if (selectedCities.length > 0) { * // This triggers re-evaluation of getContextForLlm() * context.chatAppState.updateWidgetContext(context.instanceId); * } * }); * }); * * // Your getContextForLlm() method will be called again * getContextForLlm() { * if (selectedCities.length === 0) return undefined; * * return { * origin: 'auto', * title: 'Selected Cities', * description: `User selected ${selectedCities.length} cities`, * data: { cities: selectedCities }, * addAutomatically: true * }; * } * ``` */ updateWidgetContext(instanceId: string): void; /** * Manually register a web component as a spotlight widget. This allows components to * dynamically add themselves to the spotlight area at runtime. * * Note: Registration is ephemeral and does not persist across page refreshes. * Components must re-register themselves on each page load. * * @param definition - Simplified definition for the spotlight widget * * @example * ```typescript * chatAppState.manuallyRegisterSpotlightWidget({ * tag: 'my-widget', * scope: 'my-app', * tagTitle: 'My Widget', * displayOrder: 0 * }); * ``` */ manuallyRegisterSpotlightWidget(definition: SpotlightWidgetDefinition): void; /** * Save a persistent spotlight instance using the Virtual Tags Pattern. * Creates a new instance with its own UserWidgetDataStore (400KB limit per instance), * saves the data, registers it as a spotlight widget, and renders it immediately. * * Use this when users save content (like charts, queries, etc.) to spotlight. * * @param scope - Widget scope (e.g., 'weather') * @param baseTag - Base tag name (e.g., 'chart-saved') * @param displayName - User-facing name for this instance * @param customElementName - The custom element name (same for all instances) * @param data - The data to pass to this instance * @param dataKey - The key to store data under (default: 'data') * @param metadata - Optional widget metadata (title, actions, icon, etc.) * @returns The instance ID (UUID) * @since 0.11.0 - Added metadata parameter * * @example * ```typescript * const instanceId = await chatAppState.saveSpotlightInstance( * 'weather', * 'chart-saved', * 'Q4 Revenue Chart', * 'weather-chart-saved', * { chartType: 'bar', data: [...] }, * 'chartData', * { * title: 'Q4 Revenue Chart', * iconSvg: '...', * actions: [...] * } * ); * ``` */ saveSpotlightInstance(scope: string, baseTag: string, displayName: string, customElementName: string, data: Record, dataKey?: string, metadata?: WidgetMetadata): Promise; /** * Delete a saved spotlight instance. * Removes from spotlight, removes from registry, and unregisters from state. * * Note: Instance data is currently orphaned (not deleted) but could be recovered. * Future: Will add deleteAll() method to UserWidgetDataStore. * * @param scope - Widget scope * @param baseTag - Base tag name * @param instanceId - Instance UUID * * @example * ```typescript * await chatAppState.deleteSpotlightInstance('weather', 'chart-saved', instanceId); * ``` */ deleteSpotlightInstance(scope: string, baseTag: string, instanceId: string): Promise; /** * Invoke the agent directly from a web component using the 'chat-app-component' invocation mode. * This allows components to make out-of-band requests to the LLM without creating user sessions. * * The component must have a tag definition with `componentAgentInstructionsMd` that * includes instructions for the specified `instructionName`. * * @param scope - The scope of the tag definition (e.g., 'weather') * @param tag - The tag name (e.g., 'favorite-cities') * @param instructionName - The key in the tag definition's componentAgentInstructionsMd * @param userMessage - The message/query to send to the agent * @param options - Optional streaming callbacks and configuration * @returns Promise that resolves to the parsed JSON response from the agent * @throws Error if the request fails or response cannot be parsed * * @example * Simple usage: * ```typescript * const weatherData = await chatAppState.invokeAgentAsComponent<{ temperature: number, condition: string }>( * 'weather', * 'favorite-cities', * 'get-weather', * 'Get current weather for San Francisco' * ); * ``` * * With streaming callbacks: * ```typescript * const data = await chatAppState.invokeAgentAsComponent( * 'weather', * 'favorite-cities', * 'get-weather', * 'Get weather for NYC', * { * onThinking: (text) => console.log('Thinking:', text), * onToolCall: (call) => console.log('Calling tool:', call.name) * } * ); * ``` */ invokeAgentAsComponent(scope: string, tag: string, instructionName: string, userMessage: string, options?: InvokeAgentAsComponentOptions): Promise; /** * Get a scoped metadata API for registering widget title and actions. * Call this once during widget initialization to get an API bound to this widget instance. * * The metadata you register will be used by the parent app to render context-appropriate chrome: * - **Spotlight**: Small title bar overlay with icon + title + action menu * - **Canvas**: Full title bar with all action buttons + close * - **Dialog**: Title in header, actions as buttons in footer * - **Inline**: No chrome rendered (widget manages own UI) * * **IMPORTANT**: You MUST pass instanceId and renderingContext from the PikaWCContext. * These values are automatically set during component injection. * * @param scope - Widget scope (e.g., 'weather', 'pika') * @param tag - Widget tag (e.g., 'favorite-cities') * @param instanceId - Unique instance ID from context.instanceId (set during injection) * @param renderingContext - Rendering context from context.renderingContext (set during injection) * @returns Scoped API for this widget instance * * @example * Correct usage (always pass context values): * ```js * const ctx = await getPikaContext($host()); * const metadata = ctx.chatAppState.getWidgetMetadataAPI( * 'weather', * 'favorite-cities', * ctx.instanceId, // REQUIRED - set during injection * ctx.renderingContext // REQUIRED - set during injection * ); * * metadata.setMetadata({ * title: 'Favorite Cities', * actions: [ * { * id: 'refresh', * title: 'Refresh weather data', * lucideIconName: 'refresh-cw', // MUST be lowercase kebab-case * callback: async () => { * loading = true; * await fetchWeatherData(); * loading = false; * } * } * ] * }); * ``` */ getWidgetMetadataAPI(scope: string, tag: string, instanceId: string, renderingContext: WidgetRenderingContextType): IWidgetMetadataAPI; /** * Retrieve text content from an S3 file stored in the Pika S3 bucket. * This is a secure helper that allows web components to access files without * needing to manage AWS credentials or know the bucket name. * * @param s3Key - The S3 key (path) to the file in the Pika S3 bucket * @returns Promise that resolves to the file content as a string * @throws Error if the file doesn't exist or cannot be accessed * * @example * ```js * const context = await getPikaContext($host()); * try { * const content = await context.chatAppState.getS3TextFileContent('data/config.json'); * const config = JSON.parse(content); * console.log('Config loaded:', config); * } catch (error) { * console.error('Failed to load config:', error); * } * ``` */ getS3TextFileContent(s3Key: string): Promise; /** * Register a handler for Intent Router command dispatch. * Use this in orchestrator widgets that need to receive and handle * commands matched by the Intent Router. * * Only one handler can be registered per widget instance. * Handler is automatically cleaned up when widget unregisters. * * @param instanceId - Widget instance ID (for cleanup tracking) * @param tagId - Widget tagId in scope.tag format (e.g., 'weather.static-init') - used for reliable handler lookup * @param handler - Async function to handle dispatched commands * @returns A function to unregister the handler * @since 0.18.0 * * @example * ```typescript * onMount(async () => { * const ctx = await getPikaContext($host()); * * ctx.chatAppState.registerIntentRouterHandler( * ctx.instanceId, * ctx.tagId, // e.g., 'weather.static-init' * async (event) => { * if (event.commandId === 'view_jobs') { * const jobs = await fetchJobs(); * await ctx.chatAppState.renderTag('rcs.job-list', 'canvas', { jobs }); * return { handled: true, response: `Found ${jobs.length} jobs.` }; * } * return { handled: false }; * } * ); * }); * ``` */ registerIntentRouterHandler(instanceId: string, tagId: string, handler: IntentRouterHandler): () => void; } interface IUserPrefsState { readonly initialized: boolean; readonly prefs: UserPrefs | undefined; refreshPrefsFromServer(): Promise; getPref(key: string): Promise; modifyPref(key: string, value: unknown): Promise; } interface IUploadInstance { readonly s3Key: string; readonly file: File | undefined; readonly fileName: string; readonly size: number; readonly lastModified: number; readonly type: string; readonly xhr: XMLHttpRequest; readonly status: { status: UploadStatus['status']; progress?: number; error?: string; }; } /** * Callback invoked when the web component has been created and is ready. * Called after the element is created but before it's added to the DOM. */ interface OnReadyCallback { (params: WidgetCallbackContext): void; } /** * Action button that appears in the widget's chrome (title bar, toolbar, etc.) * * @example * ```js * const action: WidgetAction = { * id: 'refresh', * title: 'Refresh data', * iconSvg: '...', * callback: async () => { await fetchData(); } * }; * ``` * * @since 0.11.0 - Moved from chatbot-types to webcomp-types */ interface WidgetAction { /** Unique identifier for this action */ id: string; /** Tooltip/label for the action (also button text in dialog context) */ title: string; /** SVG markup string for the icon (e.g., from extractIconSvg() helper) */ iconSvg: string; /** Whether action is currently disabled */ disabled?: boolean; /** If true, renders as default/prominent button (used in dialog context) */ primary?: boolean; /** * Handler when clicked * @since 0.11.0 - Callback now receives WidgetCallbackContext parameter */ callback: (context: WidgetCallbackContext) => void | Promise; } /** * The context object that is passed to the onReady callback and in action callbacks functions. * * @since 0.11.0 */ interface WidgetCallbackContext { /** The web component element that was created */ element: HTMLElement; /** The unique instance ID assigned to this component */ instanceId: string; /** The full Pika context with instanceId */ context: PikaWCContext; } /** * Structure for data passed to web components. * * Special fields that affect element initialization: * - `attributes`: Set as HTML attributes (stringified) and also as properties if they exist * - `properties`: Set as JavaScript properties only (not attributes) * - `onReady`: Callback invoked when the component is created and ready * * All other fields are available through `context.dataForWidget` but not set on the element. */ interface DataForWidget { /** * HTML attributes to set on the element. * Values are stringified and set via `setAttributeNS()`. * If a corresponding property exists on the element, it's also set with the original value. */ attributes?: Record; /** * JavaScript properties to set on the element (not as HTML attributes). * Only properties that exist on the element will be set. * Use this for complex objects, arrays, functions, etc. */ properties?: Record; /** * Callback invoked when the web component is created and ready. * Called after element creation, property/attribute setting, and context setup, * but before the element is added to the DOM. * * Use this to get notified when the component is ready and to access the element directly. */ onReady?: OnReadyCallback; /** Any other data available through context (not set on the element) */ [key: string]: any; } /** * This is the context object that is passed to the web component when it is rendered. */ interface PikaWCContext { appState: IAppState; renderingContext: WidgetRenderingContextType; chatAppState: IChatAppState; chatAppId: string; /** * Unique instance ID for this component instance. * Set by injectChatAppWebComponent() and used by getWidgetMetadataAPI(). */ instanceId: string; /** * The tag ID in scope.tag format (e.g., 'weather.static-init'). * Set by injectChatAppWebComponent() from the tag definition. * Useful for registering Intent Router handlers without hardcoding. * @since 0.18.0 */ tagId: string; /** Data passed to the widget, available through `context.dataForWidget`. */ dataForWidget: DataForWidget; } type PikaWCContextWithoutInstanceId = Omit; type PikaWCContextRequestCallbackFn = (contextRequest: PikaWCContext) => void; interface PikaWCContextRequestDetail { callback: PikaWCContextRequestCallbackFn; } interface PikaWCContextRequestEvent extends CustomEvent { detail: PikaWCContextRequestDetail; } /** * Metadata that widgets register with the parent app * * @example * ```js * const metadata: WidgetMetadata = { * title: 'My Widget', * iconSvg: '...', * iconColor: '#001F3F', * actions: [ * { id: 'refresh', title: 'Refresh', iconSvg: '...', callback: () => refresh() } * ] * }; * ``` * * @since 0.11.0 - Moved from chatbot-types to webcomp-types */ interface WidgetMetadata { /** Widget title shown in chrome */ title?: string; /** * Optional Lucide icon name (will be fetched automatically and set as iconSvg). * * The name will be snake cased as in `arrow-big-down` and not `arrowBigDown` */ lucideIconName?: string; /** Optional icon SVG markup for the widget title */ iconSvg?: string; /** Optional color for the widget icon (hex, rgb, or CSS color name) */ iconColor?: string; /** Optional action buttons */ actions?: WidgetAction[]; /** Optional loading status */ loadingStatus?: { loading: boolean; loadingMsg?: string; }; } /** * Configuration for canvas close behavior. * @since 0.17.0 */ interface CanvasCloseConfig { /** * Show a confirmation dialog before closing. * User must confirm to close, or cancel to stay. */ confirmOnClose?: boolean; /** * Custom message for the confirmation dialog. * @default "Are you sure you want to close? Any unsaved changes will be lost." */ confirmMessage?: string; /** * Custom title for the confirmation dialog. * @default "Close Widget?" */ confirmTitle?: string; } /** * Extended metadata options for canvas widgets. * Includes all standard WidgetMetadata plus canvas-specific options. * @since 0.17.0 */ interface CanvasWidgetOptions extends WidgetMetadata { /** * Enter companion mode when opening this canvas. * Companion mode optimizes the chat pane as a secondary assistant: * - Auto-hides spotlight, hero, and chat history * - Applies compact UI styles (smaller fonts/buttons) * - Auto-exits when canvas closes * @since 0.17.0 */ companionMode?: boolean; /** * Minimize chat pane to a thin strip (~20px). * Only has effect when companionMode is true. * User can click the strip to expand. * @since 0.17.0 */ chatPaneMinimized?: boolean; /** * Widget takes full control of rendering (no framework chrome). * Widget is responsible for its own header, close button, etc. * @since 0.17.0 */ fullControl?: boolean; /** * Configuration for close behavior (confirmation dialog, etc.) * @since 0.17.0 */ closeConfig?: CanvasCloseConfig; } /** * Internal state tracked for each widget instance * * @since 0.11.0 - Moved from chatbot-types to webcomp-types */ interface WidgetMetadataState extends WidgetMetadata { /** Unique instance ID for this widget */ instanceId: string; /** Widget scope (e.g., 'weather', 'pika') */ scope: string; /** Widget tag (e.g., 'favorite-cities') */ tag: string; /** Rendering context (spotlight, canvas, dialog, inline) */ renderingContext: WidgetRenderingContextType; } /** * This is used when manually registering a custom element as a spotlight widget by a component in the client. * * @since 0.11.0 - Moved from chatbot-types to webcomp-types */ interface SpotlightWidgetDefinition { /** @see TagDefinition.tag */ tag: string; /** @see TagDefinition.scope */ scope: string; /** @see TagDefinitionWidgetWebComponent.customElementName */ customElementName?: string; /** @see TagDefinition.tagTitle */ tagTitle: string; /** @see TagDefinitionWidgetWebComponent.sizing */ sizing?: WidgetSizing; /** @see TagDefinition.componentAgentInstructionsMd */ componentAgentInstructionsMd?: Record; /** * If true and there isn't an instance of this widget already created as a spotlight widget, then a new instance will be created. */ autoCreateInstance?: boolean; /** The display order of the widget in the spotlight. If not provided, is put first. */ displayOrder?: number; /** Defaults to true. If true, then only one instance of this widget can be created. */ singleton?: boolean; /** If false, widget won't appear in unpinned menu. Default: true. Use false for base widgets that only create instances */ showInUnpinnedMenu?: boolean; /** * Optional metadata (title, actions, icon) to apply to the widget when rendered * @since 0.11.0 */ metadata?: WidgetMetadata; } export type { CanvasCloseConfig, CanvasWidgetOptions, ChatAppEventHandler, ChatAppEvents, DataForWidget, IAppState, IChatAppState, IIdentityState, IUploadInstance, IUserPrefsState, IWidgetMetadataAPI, OnReadyCallback, PikaWCContext, PikaWCContextRequestCallbackFn, PikaWCContextRequestDetail, PikaWCContextRequestEvent, PikaWCContextWithoutInstanceId, SidebarState, Snippet, SpotlightWidgetDefinition, WidgetAction, WidgetCallbackContext, WidgetMetadata, WidgetMetadataState };