pika-shared 1.4.1 → 1.4.3

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,14 +1,19 @@
1
1
  import { UploadStatus } from '../upload-types.mjs';
2
- import { ShowToastFn, ChatUser, RecordOrUndef, UserAwsCredentials, ShareSessionState, UserPrefs, ChatAppMode, CustomDataUiRepresentation, ChatAppOverridableFeatures, TagDefinition, TagDefinitionWidget, ChatSession, UserDataOverrideSettings, ChatMessageForRendering, ChatApp } from './chatbot-types.mjs';
2
+ import { ShowToastFn, ChatUser, RecordOrUndef, UserAwsCredentials, WidgetRenderingContextType, ShareSessionState, UserPrefs, ChatAppMode, IUserWidgetDataStoreState, CustomDataUiRepresentation, ChatAppOverridableFeatures, TagDefinition, TagDefinitionWidget, ChatSession, UserDataOverrideSettings, ChatMessageForRendering, ChatApp, ChatAppActionMenu, ChatAppAction, InvokeAgentAsComponentOptions, WidgetMetadata, WidgetAction } from './chatbot-types.mjs';
3
3
  import '@aws-sdk/client-bedrock-agent-runtime';
4
4
  import '@aws-sdk/client-bedrock-agentcore';
5
5
 
6
+ /**
7
+ * Note!!! The interfaces in this file are meant to expose public functionality to the web component authors.
8
+ * They are not meant to be exhaustive or complete.
9
+ */
10
+
6
11
  type SidebarState = any;
7
12
  type Snippet = any;
8
13
  /** Declare global event map for pika context request */
9
14
  declare global {
10
15
  interface HTMLElementEventMap {
11
- 'pika-context-request': PikaWCContextRequestEvent;
16
+ 'pika-wc-context-request': PikaWCContextRequestEvent;
12
17
  }
13
18
  }
14
19
  interface IIdentityState {
@@ -25,12 +30,126 @@ interface IAppState {
25
30
  readonly identity: IIdentityState;
26
31
  readonly isMobile: boolean;
27
32
  }
33
+ /**
34
+ * Widget Metadata API - scoped to a specific widget instance.
35
+ * Returned by getWidgetMetadataAPI() and bound to the widget's instanceId.
36
+ *
37
+ * This API allows widgets to register and update their display metadata (title and actions)
38
+ * which the parent app uses to render context-appropriate chrome.
39
+ *
40
+ * @example
41
+ * ```js
42
+ * const ctx = await getPikaContext($host());
43
+ * const metadata = ctx.chatAppState.getWidgetMetadataAPI('weather', 'favorite-cities', ctx.instanceId, ctx.renderingContext);
44
+ *
45
+ * metadata.setMetadata({
46
+ * title: 'Favorite Cities',
47
+ * actions: [
48
+ * { id: 'refresh', title: 'Refresh', iconSvg: '<svg>...</svg>', callback: () => refresh() }
49
+ * ]
50
+ * });
51
+ * ```
52
+ */
53
+ interface IWidgetMetadataAPI {
54
+ /**
55
+ * Register or update complete metadata (title and actions).
56
+ * Replaces any previously registered metadata for this widget instance.
57
+ *
58
+ * @param metadata - The metadata to register
59
+ *
60
+ * @example
61
+ * ```js
62
+ * metadata.setMetadata({
63
+ * title: 'Weather Comparison',
64
+ * actions: [
65
+ * { id: 'refresh', title: 'Refresh', iconSvg: '<svg>...</svg>', callback: () => refresh() },
66
+ * { id: 'settings', title: 'Settings', iconSvg: '<svg>...</svg>', callback: () => showSettings() }
67
+ * ]
68
+ * });
69
+ * ```
70
+ */
71
+ setMetadata(metadata: WidgetMetadata): void;
72
+ /**
73
+ * Update just the widget title without affecting actions.
74
+ *
75
+ * @param title - The new title
76
+ *
77
+ * @example
78
+ * ```js
79
+ * metadata.updateTitle(`Temperature Trend - ${newCity}`);
80
+ * ```
81
+ */
82
+ updateTitle(title: string): void;
83
+ /**
84
+ * Update a specific action's properties (e.g., disable/enable).
85
+ * Only updates the properties provided in `updates`.
86
+ *
87
+ * @param actionId - The ID of the action to update
88
+ * @param updates - Partial properties to update (cannot change id or callback)
89
+ *
90
+ * @example
91
+ * ```js
92
+ * // Disable the refresh button during loading
93
+ * metadata.updateAction('refresh', { disabled: true });
94
+ *
95
+ * // Re-enable it after loading
96
+ * metadata.updateAction('refresh', { disabled: false });
97
+ * ```
98
+ */
99
+ updateAction(actionId: string, updates: Partial<Omit<WidgetAction, 'id' | 'callback'>>): void;
100
+ /**
101
+ * Add a new action button dynamically.
102
+ *
103
+ * @param action - The action to add
104
+ *
105
+ * @example
106
+ * ```js
107
+ * if (userHasPremium) {
108
+ * metadata.addAction({
109
+ * id: 'export',
110
+ * title: 'Export data',
111
+ * iconSvg: '<svg>...</svg>',
112
+ * callback: () => exportData()
113
+ * });
114
+ * }
115
+ * ```
116
+ */
117
+ addAction(action: WidgetAction): void;
118
+ /**
119
+ * Remove an action button.
120
+ *
121
+ * @param actionId - The ID of the action to remove
122
+ *
123
+ * @example
124
+ * ```js
125
+ * metadata.removeAction('export');
126
+ * ```
127
+ */
128
+ removeAction(actionId: string): void;
129
+ /**
130
+ * Set the loading status for the widget.
131
+ *
132
+ * @param loading - Whether the widget is loading
133
+ * @param loadingMsg - The message to display while loading
134
+ *
135
+ * @example
136
+ * ```js
137
+ * metadata.setLoadingStatus(true, 'Loading...');
138
+ * ```
139
+ */
140
+ setLoadingStatus(loading: boolean, loadingMsg?: string): void;
141
+ }
28
142
  interface IChatAppState {
29
143
  readonly entityFeatureEnabled: boolean;
30
144
  readonly shareCurrentSessionState: ShareSessionState;
31
145
  readonly showToast: ShowToastFn;
32
146
  readonly userPrefs: IUserPrefsState;
33
147
  readonly mode: ChatAppMode;
148
+ /**
149
+ * Get component-specific storage scoped to this component (scope.tag) and current user.
150
+ * Max 400KB per component.
151
+ */
152
+ getUserWidgetDataStoreState(scope: string, tag: string): IUserWidgetDataStoreState;
34
153
  readonly customDataUiRepresentation: CustomDataUiRepresentation | undefined;
35
154
  readonly features: ChatAppOverridableFeatures;
36
155
  readonly tagDefs: TagDefinition<TagDefinitionWidget>[];
@@ -55,6 +174,8 @@ interface IChatAppState {
55
174
  readonly chatApp: ChatApp;
56
175
  readonly retrievingMessages: boolean;
57
176
  readonly pageTitle: string | undefined;
177
+ readonly customDataForChatApp: Record<string, unknown> | undefined;
178
+ readonly customTitleBarActions: (ChatAppActionMenu | ChatAppAction)[];
58
179
  setCurrentSessionById(sessionId: string): void;
59
180
  removeFile(s3Key: string): void;
60
181
  startNewChatSession(): void;
@@ -65,6 +186,100 @@ interface IChatAppState {
65
186
  getMessageByMessageId(messageId: string): ChatMessageForRendering | undefined;
66
187
  uploadFiles(files: File[]): Promise<void>;
67
188
  initializeData(): Promise<void>;
189
+ renderTag(tagId: string, context: 'spotlight' | 'inline' | 'dialog' | 'canvas', data?: Record<string, any>): Promise<void>;
190
+ closeCanvas(): void;
191
+ closeDialog(): void;
192
+ setOrUpdateCustomTitleBarAction(action: ChatAppActionMenu | ChatAppAction): void;
193
+ removeCustomTitleBarAction(actionId: string): void;
194
+ /**
195
+ * Invoke the agent directly from a web component using the 'chat-app-component' invocation mode.
196
+ * This allows components to make out-of-band requests to the LLM without creating user sessions.
197
+ *
198
+ * The component must have a tag definition with `componentAgentInstructionsMd` that
199
+ * includes instructions for the specified `instructionName`.
200
+ *
201
+ * @param scope - The scope of the tag definition (e.g., 'weather')
202
+ * @param tag - The tag name (e.g., 'favorite-cities')
203
+ * @param instructionName - The key in the tag definition's componentAgentInstructionsMd
204
+ * @param userMessage - The message/query to send to the agent
205
+ * @param options - Optional streaming callbacks and configuration
206
+ * @returns Promise that resolves to the parsed JSON response from the agent
207
+ * @throws Error if the request fails or response cannot be parsed
208
+ *
209
+ * @example
210
+ * Simple usage:
211
+ * ```typescript
212
+ * const weatherData = await chatAppState.invokeAgentAsComponent<{ temperature: number, condition: string }>(
213
+ * 'weather',
214
+ * 'favorite-cities',
215
+ * 'get-weather',
216
+ * 'Get current weather for San Francisco'
217
+ * );
218
+ * ```
219
+ *
220
+ * With streaming callbacks:
221
+ * ```typescript
222
+ * const data = await chatAppState.invokeAgentAsComponent<WeatherData>(
223
+ * 'weather',
224
+ * 'favorite-cities',
225
+ * 'get-weather',
226
+ * 'Get weather for NYC',
227
+ * {
228
+ * onThinking: (text) => console.log('Thinking:', text),
229
+ * onToolCall: (call) => console.log('Calling tool:', call.name)
230
+ * }
231
+ * );
232
+ * ```
233
+ */
234
+ invokeAgentAsComponent<T = any>(scope: string, tag: string, instructionName: string, userMessage: string, options?: InvokeAgentAsComponentOptions): Promise<T>;
235
+ /**
236
+ * Get a scoped metadata API for registering widget title and actions.
237
+ * Call this once during widget initialization to get an API bound to this widget instance.
238
+ *
239
+ * The metadata you register will be used by the parent app to render context-appropriate chrome:
240
+ * - **Spotlight**: Small title bar overlay with icon + title + action menu
241
+ * - **Canvas**: Full title bar with all action buttons + close
242
+ * - **Dialog**: Title in header, actions as buttons in footer
243
+ * - **Inline**: No chrome rendered (widget manages own UI)
244
+ *
245
+ * **IMPORTANT**: You MUST pass instanceId and renderingContext from the PikaWCContext.
246
+ * These values are automatically set during component injection.
247
+ *
248
+ * @param scope - Widget scope (e.g., 'weather', 'pika')
249
+ * @param tag - Widget tag (e.g., 'favorite-cities')
250
+ * @param instanceId - Unique instance ID from context.instanceId (set during injection)
251
+ * @param renderingContext - Rendering context from context.renderingContext (set during injection)
252
+ * @returns Scoped API for this widget instance
253
+ *
254
+ * @example
255
+ * Correct usage (always pass context values):
256
+ * ```js
257
+ * const ctx = await getPikaContext($host());
258
+ * const metadata = ctx.chatAppState.getWidgetMetadataAPI(
259
+ * 'weather',
260
+ * 'favorite-cities',
261
+ * ctx.instanceId, // REQUIRED - set during injection
262
+ * ctx.renderingContext // REQUIRED - set during injection
263
+ * );
264
+ *
265
+ * metadata.setMetadata({
266
+ * title: 'Favorite Cities',
267
+ * actions: [
268
+ * {
269
+ * id: 'refresh',
270
+ * title: 'Refresh weather data',
271
+ * lucideIconName: 'refresh-cw', // MUST be lowercase kebab-case
272
+ * callback: async () => {
273
+ * loading = true;
274
+ * await fetchWeatherData();
275
+ * loading = false;
276
+ * }
277
+ * }
278
+ * ]
279
+ * });
280
+ * ```
281
+ */
282
+ getWidgetMetadataAPI(scope: string, tag: string, instanceId: string, renderingContext: WidgetRenderingContextType): IWidgetMetadataAPI;
68
283
  }
69
284
  interface IUserPrefsState {
70
285
  readonly initialized: boolean;
@@ -92,10 +307,18 @@ interface IUploadInstance {
92
307
  */
93
308
  interface PikaWCContext {
94
309
  appState: IAppState;
95
- context: 'spotlight' | 'inline' | 'dialog' | 'canvas';
310
+ renderingContext: WidgetRenderingContextType;
96
311
  chatAppState: IChatAppState;
97
312
  chatAppId: string;
313
+ /**
314
+ * Unique instance ID for this component instance.
315
+ * Set by injectChatAppWebComponent() and used by getWidgetMetadataAPI().
316
+ */
317
+ instanceId: string;
318
+ /** Arbitrary data to be passed to the widget. */
319
+ dataForWidget: Record<string, any>;
98
320
  }
321
+ type PikaWCContextWithoutInstanceId = Omit<PikaWCContext, 'instanceId'>;
99
322
  type PikaWCContextRequestCallbackFn = (contextRequest: PikaWCContext) => void;
100
323
  interface PikaWCContextRequestDetail {
101
324
  callback: PikaWCContextRequestCallbackFn;
@@ -104,4 +327,4 @@ interface PikaWCContextRequestEvent extends CustomEvent<PikaWCContextRequestDeta
104
327
  detail: PikaWCContextRequestDetail;
105
328
  }
106
329
 
107
- export type { IAppState, IChatAppState, IIdentityState, IUploadInstance, IUserPrefsState, PikaWCContext, PikaWCContextRequestCallbackFn, PikaWCContextRequestDetail, PikaWCContextRequestEvent, SidebarState, Snippet };
330
+ export type { IAppState, IChatAppState, IIdentityState, IUploadInstance, IUserPrefsState, IWidgetMetadataAPI, PikaWCContext, PikaWCContextRequestCallbackFn, PikaWCContextRequestDetail, PikaWCContextRequestEvent, PikaWCContextWithoutInstanceId, SidebarState, Snippet };
@@ -1,14 +1,19 @@
1
1
  import { UploadStatus } from '../upload-types.js';
2
- import { ShowToastFn, ChatUser, RecordOrUndef, UserAwsCredentials, ShareSessionState, UserPrefs, ChatAppMode, CustomDataUiRepresentation, ChatAppOverridableFeatures, TagDefinition, TagDefinitionWidget, ChatSession, UserDataOverrideSettings, ChatMessageForRendering, ChatApp } from './chatbot-types.js';
2
+ import { ShowToastFn, ChatUser, RecordOrUndef, UserAwsCredentials, WidgetRenderingContextType, ShareSessionState, UserPrefs, ChatAppMode, IUserWidgetDataStoreState, CustomDataUiRepresentation, ChatAppOverridableFeatures, TagDefinition, TagDefinitionWidget, ChatSession, UserDataOverrideSettings, ChatMessageForRendering, ChatApp, ChatAppActionMenu, ChatAppAction, InvokeAgentAsComponentOptions, WidgetMetadata, WidgetAction } from './chatbot-types.js';
3
3
  import '@aws-sdk/client-bedrock-agent-runtime';
4
4
  import '@aws-sdk/client-bedrock-agentcore';
5
5
 
6
+ /**
7
+ * Note!!! The interfaces in this file are meant to expose public functionality to the web component authors.
8
+ * They are not meant to be exhaustive or complete.
9
+ */
10
+
6
11
  type SidebarState = any;
7
12
  type Snippet = any;
8
13
  /** Declare global event map for pika context request */
9
14
  declare global {
10
15
  interface HTMLElementEventMap {
11
- 'pika-context-request': PikaWCContextRequestEvent;
16
+ 'pika-wc-context-request': PikaWCContextRequestEvent;
12
17
  }
13
18
  }
14
19
  interface IIdentityState {
@@ -25,12 +30,126 @@ interface IAppState {
25
30
  readonly identity: IIdentityState;
26
31
  readonly isMobile: boolean;
27
32
  }
33
+ /**
34
+ * Widget Metadata API - scoped to a specific widget instance.
35
+ * Returned by getWidgetMetadataAPI() and bound to the widget's instanceId.
36
+ *
37
+ * This API allows widgets to register and update their display metadata (title and actions)
38
+ * which the parent app uses to render context-appropriate chrome.
39
+ *
40
+ * @example
41
+ * ```js
42
+ * const ctx = await getPikaContext($host());
43
+ * const metadata = ctx.chatAppState.getWidgetMetadataAPI('weather', 'favorite-cities', ctx.instanceId, ctx.renderingContext);
44
+ *
45
+ * metadata.setMetadata({
46
+ * title: 'Favorite Cities',
47
+ * actions: [
48
+ * { id: 'refresh', title: 'Refresh', iconSvg: '<svg>...</svg>', callback: () => refresh() }
49
+ * ]
50
+ * });
51
+ * ```
52
+ */
53
+ interface IWidgetMetadataAPI {
54
+ /**
55
+ * Register or update complete metadata (title and actions).
56
+ * Replaces any previously registered metadata for this widget instance.
57
+ *
58
+ * @param metadata - The metadata to register
59
+ *
60
+ * @example
61
+ * ```js
62
+ * metadata.setMetadata({
63
+ * title: 'Weather Comparison',
64
+ * actions: [
65
+ * { id: 'refresh', title: 'Refresh', iconSvg: '<svg>...</svg>', callback: () => refresh() },
66
+ * { id: 'settings', title: 'Settings', iconSvg: '<svg>...</svg>', callback: () => showSettings() }
67
+ * ]
68
+ * });
69
+ * ```
70
+ */
71
+ setMetadata(metadata: WidgetMetadata): void;
72
+ /**
73
+ * Update just the widget title without affecting actions.
74
+ *
75
+ * @param title - The new title
76
+ *
77
+ * @example
78
+ * ```js
79
+ * metadata.updateTitle(`Temperature Trend - ${newCity}`);
80
+ * ```
81
+ */
82
+ updateTitle(title: string): void;
83
+ /**
84
+ * Update a specific action's properties (e.g., disable/enable).
85
+ * Only updates the properties provided in `updates`.
86
+ *
87
+ * @param actionId - The ID of the action to update
88
+ * @param updates - Partial properties to update (cannot change id or callback)
89
+ *
90
+ * @example
91
+ * ```js
92
+ * // Disable the refresh button during loading
93
+ * metadata.updateAction('refresh', { disabled: true });
94
+ *
95
+ * // Re-enable it after loading
96
+ * metadata.updateAction('refresh', { disabled: false });
97
+ * ```
98
+ */
99
+ updateAction(actionId: string, updates: Partial<Omit<WidgetAction, 'id' | 'callback'>>): void;
100
+ /**
101
+ * Add a new action button dynamically.
102
+ *
103
+ * @param action - The action to add
104
+ *
105
+ * @example
106
+ * ```js
107
+ * if (userHasPremium) {
108
+ * metadata.addAction({
109
+ * id: 'export',
110
+ * title: 'Export data',
111
+ * iconSvg: '<svg>...</svg>',
112
+ * callback: () => exportData()
113
+ * });
114
+ * }
115
+ * ```
116
+ */
117
+ addAction(action: WidgetAction): void;
118
+ /**
119
+ * Remove an action button.
120
+ *
121
+ * @param actionId - The ID of the action to remove
122
+ *
123
+ * @example
124
+ * ```js
125
+ * metadata.removeAction('export');
126
+ * ```
127
+ */
128
+ removeAction(actionId: string): void;
129
+ /**
130
+ * Set the loading status for the widget.
131
+ *
132
+ * @param loading - Whether the widget is loading
133
+ * @param loadingMsg - The message to display while loading
134
+ *
135
+ * @example
136
+ * ```js
137
+ * metadata.setLoadingStatus(true, 'Loading...');
138
+ * ```
139
+ */
140
+ setLoadingStatus(loading: boolean, loadingMsg?: string): void;
141
+ }
28
142
  interface IChatAppState {
29
143
  readonly entityFeatureEnabled: boolean;
30
144
  readonly shareCurrentSessionState: ShareSessionState;
31
145
  readonly showToast: ShowToastFn;
32
146
  readonly userPrefs: IUserPrefsState;
33
147
  readonly mode: ChatAppMode;
148
+ /**
149
+ * Get component-specific storage scoped to this component (scope.tag) and current user.
150
+ * Max 400KB per component.
151
+ */
152
+ getUserWidgetDataStoreState(scope: string, tag: string): IUserWidgetDataStoreState;
34
153
  readonly customDataUiRepresentation: CustomDataUiRepresentation | undefined;
35
154
  readonly features: ChatAppOverridableFeatures;
36
155
  readonly tagDefs: TagDefinition<TagDefinitionWidget>[];
@@ -55,6 +174,8 @@ interface IChatAppState {
55
174
  readonly chatApp: ChatApp;
56
175
  readonly retrievingMessages: boolean;
57
176
  readonly pageTitle: string | undefined;
177
+ readonly customDataForChatApp: Record<string, unknown> | undefined;
178
+ readonly customTitleBarActions: (ChatAppActionMenu | ChatAppAction)[];
58
179
  setCurrentSessionById(sessionId: string): void;
59
180
  removeFile(s3Key: string): void;
60
181
  startNewChatSession(): void;
@@ -65,6 +186,100 @@ interface IChatAppState {
65
186
  getMessageByMessageId(messageId: string): ChatMessageForRendering | undefined;
66
187
  uploadFiles(files: File[]): Promise<void>;
67
188
  initializeData(): Promise<void>;
189
+ renderTag(tagId: string, context: 'spotlight' | 'inline' | 'dialog' | 'canvas', data?: Record<string, any>): Promise<void>;
190
+ closeCanvas(): void;
191
+ closeDialog(): void;
192
+ setOrUpdateCustomTitleBarAction(action: ChatAppActionMenu | ChatAppAction): void;
193
+ removeCustomTitleBarAction(actionId: string): void;
194
+ /**
195
+ * Invoke the agent directly from a web component using the 'chat-app-component' invocation mode.
196
+ * This allows components to make out-of-band requests to the LLM without creating user sessions.
197
+ *
198
+ * The component must have a tag definition with `componentAgentInstructionsMd` that
199
+ * includes instructions for the specified `instructionName`.
200
+ *
201
+ * @param scope - The scope of the tag definition (e.g., 'weather')
202
+ * @param tag - The tag name (e.g., 'favorite-cities')
203
+ * @param instructionName - The key in the tag definition's componentAgentInstructionsMd
204
+ * @param userMessage - The message/query to send to the agent
205
+ * @param options - Optional streaming callbacks and configuration
206
+ * @returns Promise that resolves to the parsed JSON response from the agent
207
+ * @throws Error if the request fails or response cannot be parsed
208
+ *
209
+ * @example
210
+ * Simple usage:
211
+ * ```typescript
212
+ * const weatherData = await chatAppState.invokeAgentAsComponent<{ temperature: number, condition: string }>(
213
+ * 'weather',
214
+ * 'favorite-cities',
215
+ * 'get-weather',
216
+ * 'Get current weather for San Francisco'
217
+ * );
218
+ * ```
219
+ *
220
+ * With streaming callbacks:
221
+ * ```typescript
222
+ * const data = await chatAppState.invokeAgentAsComponent<WeatherData>(
223
+ * 'weather',
224
+ * 'favorite-cities',
225
+ * 'get-weather',
226
+ * 'Get weather for NYC',
227
+ * {
228
+ * onThinking: (text) => console.log('Thinking:', text),
229
+ * onToolCall: (call) => console.log('Calling tool:', call.name)
230
+ * }
231
+ * );
232
+ * ```
233
+ */
234
+ invokeAgentAsComponent<T = any>(scope: string, tag: string, instructionName: string, userMessage: string, options?: InvokeAgentAsComponentOptions): Promise<T>;
235
+ /**
236
+ * Get a scoped metadata API for registering widget title and actions.
237
+ * Call this once during widget initialization to get an API bound to this widget instance.
238
+ *
239
+ * The metadata you register will be used by the parent app to render context-appropriate chrome:
240
+ * - **Spotlight**: Small title bar overlay with icon + title + action menu
241
+ * - **Canvas**: Full title bar with all action buttons + close
242
+ * - **Dialog**: Title in header, actions as buttons in footer
243
+ * - **Inline**: No chrome rendered (widget manages own UI)
244
+ *
245
+ * **IMPORTANT**: You MUST pass instanceId and renderingContext from the PikaWCContext.
246
+ * These values are automatically set during component injection.
247
+ *
248
+ * @param scope - Widget scope (e.g., 'weather', 'pika')
249
+ * @param tag - Widget tag (e.g., 'favorite-cities')
250
+ * @param instanceId - Unique instance ID from context.instanceId (set during injection)
251
+ * @param renderingContext - Rendering context from context.renderingContext (set during injection)
252
+ * @returns Scoped API for this widget instance
253
+ *
254
+ * @example
255
+ * Correct usage (always pass context values):
256
+ * ```js
257
+ * const ctx = await getPikaContext($host());
258
+ * const metadata = ctx.chatAppState.getWidgetMetadataAPI(
259
+ * 'weather',
260
+ * 'favorite-cities',
261
+ * ctx.instanceId, // REQUIRED - set during injection
262
+ * ctx.renderingContext // REQUIRED - set during injection
263
+ * );
264
+ *
265
+ * metadata.setMetadata({
266
+ * title: 'Favorite Cities',
267
+ * actions: [
268
+ * {
269
+ * id: 'refresh',
270
+ * title: 'Refresh weather data',
271
+ * lucideIconName: 'refresh-cw', // MUST be lowercase kebab-case
272
+ * callback: async () => {
273
+ * loading = true;
274
+ * await fetchWeatherData();
275
+ * loading = false;
276
+ * }
277
+ * }
278
+ * ]
279
+ * });
280
+ * ```
281
+ */
282
+ getWidgetMetadataAPI(scope: string, tag: string, instanceId: string, renderingContext: WidgetRenderingContextType): IWidgetMetadataAPI;
68
283
  }
69
284
  interface IUserPrefsState {
70
285
  readonly initialized: boolean;
@@ -92,10 +307,18 @@ interface IUploadInstance {
92
307
  */
93
308
  interface PikaWCContext {
94
309
  appState: IAppState;
95
- context: 'spotlight' | 'inline' | 'dialog' | 'canvas';
310
+ renderingContext: WidgetRenderingContextType;
96
311
  chatAppState: IChatAppState;
97
312
  chatAppId: string;
313
+ /**
314
+ * Unique instance ID for this component instance.
315
+ * Set by injectChatAppWebComponent() and used by getWidgetMetadataAPI().
316
+ */
317
+ instanceId: string;
318
+ /** Arbitrary data to be passed to the widget. */
319
+ dataForWidget: Record<string, any>;
98
320
  }
321
+ type PikaWCContextWithoutInstanceId = Omit<PikaWCContext, 'instanceId'>;
99
322
  type PikaWCContextRequestCallbackFn = (contextRequest: PikaWCContext) => void;
100
323
  interface PikaWCContextRequestDetail {
101
324
  callback: PikaWCContextRequestCallbackFn;
@@ -104,4 +327,4 @@ interface PikaWCContextRequestEvent extends CustomEvent<PikaWCContextRequestDeta
104
327
  detail: PikaWCContextRequestDetail;
105
328
  }
106
329
 
107
- export type { IAppState, IChatAppState, IIdentityState, IUploadInstance, IUserPrefsState, PikaWCContext, PikaWCContextRequestCallbackFn, PikaWCContextRequestDetail, PikaWCContextRequestEvent, SidebarState, Snippet };
330
+ export type { IAppState, IChatAppState, IIdentityState, IUploadInstance, IUserPrefsState, IWidgetMetadataAPI, PikaWCContext, PikaWCContextRequestCallbackFn, PikaWCContextRequestDetail, PikaWCContextRequestEvent, PikaWCContextWithoutInstanceId, SidebarState, Snippet };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This is useful when you need to dynamically retrieve the SVG for an icon.
3
+ * It will cache the icon SVG so that it doesn't need to be fetched multiple times.
4
+ * It will also return the same SVG for the same icon name and collection.
5
+ *
6
+ * @param iconName - The name of the icon to retrieve.
7
+ * @param collection - The collection of the icon to retrieve. Today we only support lucide.
8
+ * @returns The SVG for the icon.
9
+ */
10
+ declare function getIconSvg(iconName: string, collection?: string): Promise<string>;
11
+
12
+ export { getIconSvg };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This is useful when you need to dynamically retrieve the SVG for an icon.
3
+ * It will cache the icon SVG so that it doesn't need to be fetched multiple times.
4
+ * It will also return the same SVG for the same icon name and collection.
5
+ *
6
+ * @param iconName - The name of the icon to retrieve.
7
+ * @param collection - The collection of the icon to retrieve. Today we only support lucide.
8
+ * @returns The SVG for the icon.
9
+ */
10
+ declare function getIconSvg(iconName: string, collection?: string): Promise<string>;
11
+
12
+ export { getIconSvg };
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ // src/util/icon-utils.ts
4
+ var iconCache = {};
5
+ async function getIconSvg(iconName, collection = "lucide") {
6
+ if (collection !== "lucide") {
7
+ throw new Error(`Unsupported collection: ${collection}`);
8
+ }
9
+ if (iconName !== iconName.toLowerCase()) {
10
+ throw new Error(`Icon name must be all lower case and hyphen based: ${iconName}`);
11
+ }
12
+ const iconKey = `${collection}:${iconName}`;
13
+ if (iconCache[iconKey]) {
14
+ return iconCache[iconKey];
15
+ }
16
+ const lucideIconUrl = `https://cdn.jsdelivr.net/npm/lucide-static@0/icons/${iconName}.svg`;
17
+ const response = await fetch(lucideIconUrl);
18
+ let iconSvg = await response.text();
19
+ iconSvg = iconSvg.replace(/width="\d+" height="\d+"/, 'width="24" height="24"');
20
+ iconCache[iconKey] = iconSvg;
21
+ return iconSvg;
22
+ }
23
+
24
+ exports.getIconSvg = getIconSvg;
25
+ //# sourceMappingURL=icon-utils.js.map
26
+ //# sourceMappingURL=icon-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/icon-utils.ts"],"names":[],"mappings":";;;AAAA,IAAM,YAAoC,EAAC;AAW3C,eAAsB,UAAA,CAAW,QAAA,EAAkB,UAAA,GAAa,QAAA,EAA2B;AAEvF,EAAA,IAAI,eAAe,QAAA,EAAU;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,UAAU,CAAA,CAAE,CAAA;AAAA,EAC3D;AAIA,EAAA,IAAI,QAAA,KAAa,QAAA,CAAS,WAAA,EAAY,EAAG;AACrC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mDAAA,EAAsD,QAAQ,CAAA,CAAE,CAAA;AAAA,EACpF;AAEA,EAAA,MAAM,OAAA,GAAU,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA;AACzC,EAAA,IAAI,SAAA,CAAU,OAAO,CAAA,EAAG;AACpB,IAAA,OAAO,UAAU,OAAO,CAAA;AAAA,EAC5B;AAEA,EAAA,MAAM,aAAA,GAAgB,sDAAsD,QAAQ,CAAA,IAAA,CAAA;AAGpF,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,aAAa,CAAA;AAC1C,EAAA,IAAI,OAAA,GAAU,MAAM,QAAA,CAAS,IAAA,EAAK;AAGlC,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,0BAAA,EAA4B,wBAAwB,CAAA;AAE9E,EAAA,SAAA,CAAU,OAAO,CAAA,GAAI,OAAA;AACrB,EAAA,OAAO,OAAA;AACX","file":"icon-utils.js","sourcesContent":["const iconCache: Record<string, string> = {};\n\n/**\n * This is useful when you need to dynamically retrieve the SVG for an icon.\n * It will cache the icon SVG so that it doesn't need to be fetched multiple times.\n * It will also return the same SVG for the same icon name and collection.\n *\n * @param iconName - The name of the icon to retrieve.\n * @param collection - The collection of the icon to retrieve. Today we only support lucide.\n * @returns The SVG for the icon.\n */\nexport async function getIconSvg(iconName: string, collection = 'lucide'): Promise<string> {\n // Today we only support lucide\n if (collection !== 'lucide') {\n throw new Error(`Unsupported collection: ${collection}`);\n }\n\n // Lucide icon names must be lower case and they are all hyphen based, not camel case\n // If the icon name isn't all lower case then throw an error so the developer knows to use the correct icon name\n if (iconName !== iconName.toLowerCase()) {\n throw new Error(`Icon name must be all lower case and hyphen based: ${iconName}`);\n }\n\n const iconKey = `${collection}:${iconName}`;\n if (iconCache[iconKey]) {\n return iconCache[iconKey];\n }\n\n const lucideIconUrl = `https://cdn.jsdelivr.net/npm/lucide-static@0/icons/${iconName}.svg`;\n\n // Use fetch to get the icon SVG\n const response = await fetch(lucideIconUrl);\n let iconSvg = await response.text();\n\n // Replace the width and height attributes with width=\"24\" and height=\"24\"\n iconSvg = iconSvg.replace(/width=\"\\d+\" height=\"\\d+\"/, 'width=\"24\" height=\"24\"');\n\n iconCache[iconKey] = iconSvg;\n return iconSvg;\n}\n"]}
@@ -0,0 +1,24 @@
1
+ // src/util/icon-utils.ts
2
+ var iconCache = {};
3
+ async function getIconSvg(iconName, collection = "lucide") {
4
+ if (collection !== "lucide") {
5
+ throw new Error(`Unsupported collection: ${collection}`);
6
+ }
7
+ if (iconName !== iconName.toLowerCase()) {
8
+ throw new Error(`Icon name must be all lower case and hyphen based: ${iconName}`);
9
+ }
10
+ const iconKey = `${collection}:${iconName}`;
11
+ if (iconCache[iconKey]) {
12
+ return iconCache[iconKey];
13
+ }
14
+ const lucideIconUrl = `https://cdn.jsdelivr.net/npm/lucide-static@0/icons/${iconName}.svg`;
15
+ const response = await fetch(lucideIconUrl);
16
+ let iconSvg = await response.text();
17
+ iconSvg = iconSvg.replace(/width="\d+" height="\d+"/, 'width="24" height="24"');
18
+ iconCache[iconKey] = iconSvg;
19
+ return iconSvg;
20
+ }
21
+
22
+ export { getIconSvg };
23
+ //# sourceMappingURL=icon-utils.mjs.map
24
+ //# sourceMappingURL=icon-utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/icon-utils.ts"],"names":[],"mappings":";AAAA,IAAM,YAAoC,EAAC;AAW3C,eAAsB,UAAA,CAAW,QAAA,EAAkB,UAAA,GAAa,QAAA,EAA2B;AAEvF,EAAA,IAAI,eAAe,QAAA,EAAU;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,UAAU,CAAA,CAAE,CAAA;AAAA,EAC3D;AAIA,EAAA,IAAI,QAAA,KAAa,QAAA,CAAS,WAAA,EAAY,EAAG;AACrC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mDAAA,EAAsD,QAAQ,CAAA,CAAE,CAAA;AAAA,EACpF;AAEA,EAAA,MAAM,OAAA,GAAU,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA;AACzC,EAAA,IAAI,SAAA,CAAU,OAAO,CAAA,EAAG;AACpB,IAAA,OAAO,UAAU,OAAO,CAAA;AAAA,EAC5B;AAEA,EAAA,MAAM,aAAA,GAAgB,sDAAsD,QAAQ,CAAA,IAAA,CAAA;AAGpF,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,aAAa,CAAA;AAC1C,EAAA,IAAI,OAAA,GAAU,MAAM,QAAA,CAAS,IAAA,EAAK;AAGlC,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,0BAAA,EAA4B,wBAAwB,CAAA;AAE9E,EAAA,SAAA,CAAU,OAAO,CAAA,GAAI,OAAA;AACrB,EAAA,OAAO,OAAA;AACX","file":"icon-utils.mjs","sourcesContent":["const iconCache: Record<string, string> = {};\n\n/**\n * This is useful when you need to dynamically retrieve the SVG for an icon.\n * It will cache the icon SVG so that it doesn't need to be fetched multiple times.\n * It will also return the same SVG for the same icon name and collection.\n *\n * @param iconName - The name of the icon to retrieve.\n * @param collection - The collection of the icon to retrieve. Today we only support lucide.\n * @returns The SVG for the icon.\n */\nexport async function getIconSvg(iconName: string, collection = 'lucide'): Promise<string> {\n // Today we only support lucide\n if (collection !== 'lucide') {\n throw new Error(`Unsupported collection: ${collection}`);\n }\n\n // Lucide icon names must be lower case and they are all hyphen based, not camel case\n // If the icon name isn't all lower case then throw an error so the developer knows to use the correct icon name\n if (iconName !== iconName.toLowerCase()) {\n throw new Error(`Icon name must be all lower case and hyphen based: ${iconName}`);\n }\n\n const iconKey = `${collection}:${iconName}`;\n if (iconCache[iconKey]) {\n return iconCache[iconKey];\n }\n\n const lucideIconUrl = `https://cdn.jsdelivr.net/npm/lucide-static@0/icons/${iconName}.svg`;\n\n // Use fetch to get the icon SVG\n const response = await fetch(lucideIconUrl);\n let iconSvg = await response.text();\n\n // Replace the width and height attributes with width=\"24\" and height=\"24\"\n iconSvg = iconSvg.replace(/width=\"\\d+\" height=\"\\d+\"/, 'width=\"24\" height=\"24\"');\n\n iconCache[iconKey] = iconSvg;\n return iconSvg;\n}\n"]}