vanilla-agent 1.9.0 → 1.11.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.
- package/README.md +303 -8
- package/dist/index.cjs +46 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +581 -1
- package/dist/index.d.ts +581 -1
- package/dist/index.global.js +69 -30
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +46 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +141 -12
- package/src/components/composer-builder.ts +366 -0
- package/src/components/forms.ts +1 -0
- package/src/components/header-builder.ts +454 -0
- package/src/components/header-layouts.ts +303 -0
- package/src/components/message-bubble.ts +251 -34
- package/src/components/panel.ts +46 -684
- package/src/components/registry.ts +87 -0
- package/src/defaults.ts +49 -1
- package/src/index.ts +64 -2
- package/src/plugins/registry.ts +1 -0
- package/src/plugins/types.ts +1 -0
- package/src/runtime/init.ts +26 -0
- package/src/types.ts +381 -0
- package/src/ui.ts +521 -40
- package/src/utils/component-middleware.ts +137 -0
- package/src/utils/component-parser.ts +119 -0
- package/src/utils/constants.ts +1 -0
- package/src/utils/dom.ts +1 -0
- package/src/utils/formatting.ts +33 -8
- package/src/utils/positioning.ts +1 -0
- package/src/utils/theme.ts +1 -0
package/src/types.ts
CHANGED
|
@@ -156,6 +156,24 @@ export type AgentWidgetTheme = {
|
|
|
156
156
|
radiusLg?: string;
|
|
157
157
|
launcherRadius?: string;
|
|
158
158
|
buttonRadius?: string;
|
|
159
|
+
/**
|
|
160
|
+
* Border style for the chat panel container.
|
|
161
|
+
* @example "1px solid #e5e7eb" | "none"
|
|
162
|
+
* @default "1px solid var(--tvw-cw-border)"
|
|
163
|
+
*/
|
|
164
|
+
panelBorder?: string;
|
|
165
|
+
/**
|
|
166
|
+
* Box shadow for the chat panel container.
|
|
167
|
+
* @example "0 25px 50px -12px rgba(0,0,0,0.25)" | "none"
|
|
168
|
+
* @default "0 25px 50px -12px rgba(0,0,0,0.25)"
|
|
169
|
+
*/
|
|
170
|
+
panelShadow?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Border radius for the chat panel container.
|
|
173
|
+
* @example "16px" | "0"
|
|
174
|
+
* @default "16px"
|
|
175
|
+
*/
|
|
176
|
+
panelBorderRadius?: string;
|
|
159
177
|
};
|
|
160
178
|
|
|
161
179
|
export type AgentWidgetLauncherConfig = {
|
|
@@ -170,6 +188,35 @@ export type AgentWidgetLauncherConfig = {
|
|
|
170
188
|
position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
|
|
171
189
|
autoExpand?: boolean;
|
|
172
190
|
width?: string;
|
|
191
|
+
/**
|
|
192
|
+
* When true, the widget panel will fill the full height of its container.
|
|
193
|
+
* Useful for sidebar layouts where the chat should take up the entire viewport height.
|
|
194
|
+
* The widget will use flex layout to ensure header stays at top, messages scroll in middle,
|
|
195
|
+
* and composer stays fixed at bottom.
|
|
196
|
+
*
|
|
197
|
+
* @default false
|
|
198
|
+
*/
|
|
199
|
+
fullHeight?: boolean;
|
|
200
|
+
/**
|
|
201
|
+
* When true, the widget panel will be positioned as a sidebar flush with the viewport edges.
|
|
202
|
+
* The panel will have:
|
|
203
|
+
* - No border-radius (square corners)
|
|
204
|
+
* - No margins (flush with top, left/right, and bottom edges)
|
|
205
|
+
* - Full viewport height
|
|
206
|
+
* - Subtle shadow on the edge facing the content
|
|
207
|
+
* - No border between footer and messages
|
|
208
|
+
*
|
|
209
|
+
* Use with `position` to control which side ('bottom-left' for left sidebar, 'bottom-right' for right sidebar).
|
|
210
|
+
* Automatically enables fullHeight when true.
|
|
211
|
+
*
|
|
212
|
+
* @default false
|
|
213
|
+
*/
|
|
214
|
+
sidebarMode?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Width of the sidebar panel when sidebarMode is true.
|
|
217
|
+
* @default "420px"
|
|
218
|
+
*/
|
|
219
|
+
sidebarWidth?: string;
|
|
173
220
|
callToActionIconText?: string;
|
|
174
221
|
callToActionIconName?: string;
|
|
175
222
|
callToActionIconColor?: string;
|
|
@@ -214,6 +261,7 @@ export type AgentWidgetSendButtonConfig = {
|
|
|
214
261
|
|
|
215
262
|
export type AgentWidgetClearChatConfig = {
|
|
216
263
|
enabled?: boolean;
|
|
264
|
+
placement?: "inline" | "top-right";
|
|
217
265
|
iconName?: string;
|
|
218
266
|
iconColor?: string;
|
|
219
267
|
backgroundColor?: string;
|
|
@@ -339,10 +387,240 @@ export interface AgentWidgetStreamParser {
|
|
|
339
387
|
}
|
|
340
388
|
|
|
341
389
|
|
|
390
|
+
/**
|
|
391
|
+
* Component renderer function signature for custom components
|
|
392
|
+
*/
|
|
393
|
+
export type AgentWidgetComponentRenderer = (
|
|
394
|
+
props: Record<string, unknown>,
|
|
395
|
+
context: {
|
|
396
|
+
message: AgentWidgetMessage;
|
|
397
|
+
config: AgentWidgetConfig;
|
|
398
|
+
updateProps: (newProps: Record<string, unknown>) => void;
|
|
399
|
+
}
|
|
400
|
+
) => HTMLElement;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Result from custom SSE event parser
|
|
404
|
+
*/
|
|
405
|
+
export type AgentWidgetSSEEventResult = {
|
|
406
|
+
/** Text content to display */
|
|
407
|
+
text?: string;
|
|
408
|
+
/** Whether the stream is complete */
|
|
409
|
+
done?: boolean;
|
|
410
|
+
/** Error message if an error occurred */
|
|
411
|
+
error?: string;
|
|
412
|
+
} | null;
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Custom SSE event parser function
|
|
416
|
+
* Allows transforming non-standard SSE event formats to vanilla-agent's expected format
|
|
417
|
+
*/
|
|
418
|
+
export type AgentWidgetSSEEventParser = (
|
|
419
|
+
eventData: unknown
|
|
420
|
+
) => AgentWidgetSSEEventResult | Promise<AgentWidgetSSEEventResult>;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Custom fetch function for full control over API requests
|
|
424
|
+
* Use this for custom authentication, request transformation, etc.
|
|
425
|
+
*/
|
|
426
|
+
export type AgentWidgetCustomFetch = (
|
|
427
|
+
url: string,
|
|
428
|
+
init: RequestInit,
|
|
429
|
+
payload: AgentWidgetRequestPayload
|
|
430
|
+
) => Promise<Response>;
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Dynamic headers function - called before each request
|
|
434
|
+
*/
|
|
435
|
+
export type AgentWidgetHeadersFunction = () => Record<string, string> | Promise<Record<string, string>>;
|
|
436
|
+
|
|
437
|
+
// ============================================================================
|
|
438
|
+
// Layout Configuration Types
|
|
439
|
+
// ============================================================================
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Context provided to header render functions
|
|
443
|
+
*/
|
|
444
|
+
export type HeaderRenderContext = {
|
|
445
|
+
config: AgentWidgetConfig;
|
|
446
|
+
onClose?: () => void;
|
|
447
|
+
onClearChat?: () => void;
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Context provided to message render functions
|
|
452
|
+
*/
|
|
453
|
+
export type MessageRenderContext = {
|
|
454
|
+
message: AgentWidgetMessage;
|
|
455
|
+
config: AgentWidgetConfig;
|
|
456
|
+
streaming: boolean;
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Context provided to slot render functions
|
|
461
|
+
*/
|
|
462
|
+
export type SlotRenderContext = {
|
|
463
|
+
config: AgentWidgetConfig;
|
|
464
|
+
defaultContent: () => HTMLElement | null;
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Header layout configuration
|
|
469
|
+
* Allows customization of the header section appearance and behavior
|
|
470
|
+
*/
|
|
471
|
+
export type AgentWidgetHeaderLayoutConfig = {
|
|
472
|
+
/**
|
|
473
|
+
* Layout preset: "default" | "minimal" | "expanded"
|
|
474
|
+
* - default: Standard layout with icon, title, subtitle, and buttons
|
|
475
|
+
* - minimal: Simplified layout with just title and close button
|
|
476
|
+
* - expanded: Full branding area with additional content space
|
|
477
|
+
*/
|
|
478
|
+
layout?: "default" | "minimal" | "expanded";
|
|
479
|
+
/** Show/hide the header icon */
|
|
480
|
+
showIcon?: boolean;
|
|
481
|
+
/** Show/hide the title */
|
|
482
|
+
showTitle?: boolean;
|
|
483
|
+
/** Show/hide the subtitle */
|
|
484
|
+
showSubtitle?: boolean;
|
|
485
|
+
/** Show/hide the close button */
|
|
486
|
+
showCloseButton?: boolean;
|
|
487
|
+
/** Show/hide the clear chat button */
|
|
488
|
+
showClearChat?: boolean;
|
|
489
|
+
/**
|
|
490
|
+
* Custom renderer for complete header override
|
|
491
|
+
* When provided, replaces the entire header with custom content
|
|
492
|
+
*/
|
|
493
|
+
render?: (context: HeaderRenderContext) => HTMLElement;
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Avatar configuration for message bubbles
|
|
498
|
+
*/
|
|
499
|
+
export type AgentWidgetAvatarConfig = {
|
|
500
|
+
/** Whether to show avatars */
|
|
501
|
+
show?: boolean;
|
|
502
|
+
/** Position of avatar relative to message bubble */
|
|
503
|
+
position?: "left" | "right";
|
|
504
|
+
/** URL or emoji for user avatar */
|
|
505
|
+
userAvatar?: string;
|
|
506
|
+
/** URL or emoji for assistant avatar */
|
|
507
|
+
assistantAvatar?: string;
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Timestamp configuration for message bubbles
|
|
512
|
+
*/
|
|
513
|
+
export type AgentWidgetTimestampConfig = {
|
|
514
|
+
/** Whether to show timestamps */
|
|
515
|
+
show?: boolean;
|
|
516
|
+
/** Position of timestamp relative to message */
|
|
517
|
+
position?: "inline" | "below";
|
|
518
|
+
/** Custom formatter for timestamp display */
|
|
519
|
+
format?: (date: Date) => string;
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Message layout configuration
|
|
524
|
+
* Allows customization of how chat messages are displayed
|
|
525
|
+
*/
|
|
526
|
+
export type AgentWidgetMessageLayoutConfig = {
|
|
527
|
+
/**
|
|
528
|
+
* Layout preset: "bubble" | "flat" | "minimal"
|
|
529
|
+
* - bubble: Standard chat bubble appearance (default)
|
|
530
|
+
* - flat: Flat messages without bubble styling
|
|
531
|
+
* - minimal: Minimal styling with reduced padding/borders
|
|
532
|
+
*/
|
|
533
|
+
layout?: "bubble" | "flat" | "minimal";
|
|
534
|
+
/** Avatar configuration */
|
|
535
|
+
avatar?: AgentWidgetAvatarConfig;
|
|
536
|
+
/** Timestamp configuration */
|
|
537
|
+
timestamp?: AgentWidgetTimestampConfig;
|
|
538
|
+
/** Group consecutive messages from the same role */
|
|
539
|
+
groupConsecutive?: boolean;
|
|
540
|
+
/**
|
|
541
|
+
* Custom renderer for user messages
|
|
542
|
+
* When provided, replaces the default user message rendering
|
|
543
|
+
*/
|
|
544
|
+
renderUserMessage?: (context: MessageRenderContext) => HTMLElement;
|
|
545
|
+
/**
|
|
546
|
+
* Custom renderer for assistant messages
|
|
547
|
+
* When provided, replaces the default assistant message rendering
|
|
548
|
+
*/
|
|
549
|
+
renderAssistantMessage?: (context: MessageRenderContext) => HTMLElement;
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Available layout slots for content injection
|
|
554
|
+
*/
|
|
555
|
+
export type WidgetLayoutSlot =
|
|
556
|
+
| "header-left"
|
|
557
|
+
| "header-center"
|
|
558
|
+
| "header-right"
|
|
559
|
+
| "body-top"
|
|
560
|
+
| "messages"
|
|
561
|
+
| "body-bottom"
|
|
562
|
+
| "footer-top"
|
|
563
|
+
| "composer"
|
|
564
|
+
| "footer-bottom";
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Slot renderer function signature
|
|
568
|
+
* Returns HTMLElement to render in the slot, or null to use default content
|
|
569
|
+
*/
|
|
570
|
+
export type SlotRenderer = (context: SlotRenderContext) => HTMLElement | null;
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Main layout configuration
|
|
574
|
+
* Provides comprehensive control over widget layout and appearance
|
|
575
|
+
*
|
|
576
|
+
* @example
|
|
577
|
+
* ```typescript
|
|
578
|
+
* config: {
|
|
579
|
+
* layout: {
|
|
580
|
+
* header: { layout: "minimal" },
|
|
581
|
+
* messages: {
|
|
582
|
+
* avatar: { show: true, assistantAvatar: "/bot.png" },
|
|
583
|
+
* timestamp: { show: true, position: "below" }
|
|
584
|
+
* },
|
|
585
|
+
* slots: {
|
|
586
|
+
* "footer-top": () => {
|
|
587
|
+
* const el = document.createElement("div");
|
|
588
|
+
* el.textContent = "Powered by AI";
|
|
589
|
+
* return el;
|
|
590
|
+
* }
|
|
591
|
+
* }
|
|
592
|
+
* }
|
|
593
|
+
* }
|
|
594
|
+
* ```
|
|
595
|
+
*/
|
|
596
|
+
export type AgentWidgetLayoutConfig = {
|
|
597
|
+
/** Header layout configuration */
|
|
598
|
+
header?: AgentWidgetHeaderLayoutConfig;
|
|
599
|
+
/** Message layout configuration */
|
|
600
|
+
messages?: AgentWidgetMessageLayoutConfig;
|
|
601
|
+
/** Slot renderers for custom content injection */
|
|
602
|
+
slots?: Partial<Record<WidgetLayoutSlot, SlotRenderer>>;
|
|
603
|
+
};
|
|
604
|
+
|
|
342
605
|
export type AgentWidgetConfig = {
|
|
343
606
|
apiUrl?: string;
|
|
344
607
|
flowId?: string;
|
|
608
|
+
/**
|
|
609
|
+
* Static headers to include with each request.
|
|
610
|
+
* For dynamic headers (e.g., auth tokens), use `getHeaders` instead.
|
|
611
|
+
*/
|
|
345
612
|
headers?: Record<string, string>;
|
|
613
|
+
/**
|
|
614
|
+
* Dynamic headers function - called before each request.
|
|
615
|
+
* Useful for adding auth tokens that may change.
|
|
616
|
+
* @example
|
|
617
|
+
* ```typescript
|
|
618
|
+
* getHeaders: async () => ({
|
|
619
|
+
* 'Authorization': `Bearer ${await getAuthToken()}`
|
|
620
|
+
* })
|
|
621
|
+
* ```
|
|
622
|
+
*/
|
|
623
|
+
getHeaders?: AgentWidgetHeadersFunction;
|
|
346
624
|
copy?: {
|
|
347
625
|
welcomeTitle?: string;
|
|
348
626
|
welcomeSubtitle?: string;
|
|
@@ -374,6 +652,32 @@ export type AgentWidgetConfig = {
|
|
|
374
652
|
actionParsers?: AgentWidgetActionParser[];
|
|
375
653
|
actionHandlers?: AgentWidgetActionHandler[];
|
|
376
654
|
storageAdapter?: AgentWidgetStorageAdapter;
|
|
655
|
+
/**
|
|
656
|
+
* Registry of custom components that can be rendered from JSON directives.
|
|
657
|
+
* Components are registered by name and can be invoked via JSON responses
|
|
658
|
+
* with the format: `{"component": "ComponentName", "props": {...}}`
|
|
659
|
+
*
|
|
660
|
+
* @example
|
|
661
|
+
* ```typescript
|
|
662
|
+
* config: {
|
|
663
|
+
* components: {
|
|
664
|
+
* ProductCard: (props, context) => {
|
|
665
|
+
* const card = document.createElement("div");
|
|
666
|
+
* card.innerHTML = `<h3>${props.title}</h3><p>$${props.price}</p>`;
|
|
667
|
+
* return card;
|
|
668
|
+
* }
|
|
669
|
+
* }
|
|
670
|
+
* }
|
|
671
|
+
* ```
|
|
672
|
+
*/
|
|
673
|
+
components?: Record<string, AgentWidgetComponentRenderer>;
|
|
674
|
+
/**
|
|
675
|
+
* Enable component streaming. When true, component props will be updated
|
|
676
|
+
* incrementally as they stream in from the JSON response.
|
|
677
|
+
*
|
|
678
|
+
* @default true
|
|
679
|
+
*/
|
|
680
|
+
enableComponentStreaming?: boolean;
|
|
377
681
|
/**
|
|
378
682
|
* Custom stream parser for extracting text from streaming structured responses.
|
|
379
683
|
* Handles incremental parsing of JSON, XML, or other formats.
|
|
@@ -430,6 +734,83 @@ export type AgentWidgetConfig = {
|
|
|
430
734
|
* ```
|
|
431
735
|
*/
|
|
432
736
|
parserType?: "plain" | "json" | "regex-json" | "xml";
|
|
737
|
+
/**
|
|
738
|
+
* Custom fetch function for full control over API requests.
|
|
739
|
+
* Use this for custom authentication, request/response transformation, etc.
|
|
740
|
+
*
|
|
741
|
+
* When provided, this function is called instead of the default fetch.
|
|
742
|
+
* You receive the URL, RequestInit, and the payload that would be sent.
|
|
743
|
+
*
|
|
744
|
+
* @example
|
|
745
|
+
* ```typescript
|
|
746
|
+
* config: {
|
|
747
|
+
* customFetch: async (url, init, payload) => {
|
|
748
|
+
* // Transform request for your API format
|
|
749
|
+
* const myPayload = {
|
|
750
|
+
* flow: { id: 'my-flow-id' },
|
|
751
|
+
* messages: payload.messages,
|
|
752
|
+
* options: { stream_response: true }
|
|
753
|
+
* };
|
|
754
|
+
*
|
|
755
|
+
* // Add auth header
|
|
756
|
+
* const token = await getAuthToken();
|
|
757
|
+
*
|
|
758
|
+
* return fetch('/my-api/dispatch', {
|
|
759
|
+
* method: 'POST',
|
|
760
|
+
* headers: {
|
|
761
|
+
* 'Content-Type': 'application/json',
|
|
762
|
+
* 'Authorization': `Bearer ${token}`
|
|
763
|
+
* },
|
|
764
|
+
* body: JSON.stringify(myPayload),
|
|
765
|
+
* signal: init.signal
|
|
766
|
+
* });
|
|
767
|
+
* }
|
|
768
|
+
* }
|
|
769
|
+
* ```
|
|
770
|
+
*/
|
|
771
|
+
customFetch?: AgentWidgetCustomFetch;
|
|
772
|
+
/**
|
|
773
|
+
* Custom SSE event parser for non-standard streaming response formats.
|
|
774
|
+
*
|
|
775
|
+
* Use this when your API returns SSE events in a different format than expected.
|
|
776
|
+
* Return `{ text }` for text chunks, `{ done: true }` for completion,
|
|
777
|
+
* `{ error }` for errors, or `null` to ignore the event.
|
|
778
|
+
*
|
|
779
|
+
* @example
|
|
780
|
+
* ```typescript
|
|
781
|
+
* // For Travrse API format
|
|
782
|
+
* config: {
|
|
783
|
+
* parseSSEEvent: (data) => {
|
|
784
|
+
* if (data.type === 'step_chunk' && data.chunk) {
|
|
785
|
+
* return { text: data.chunk };
|
|
786
|
+
* }
|
|
787
|
+
* if (data.type === 'flow_complete') {
|
|
788
|
+
* return { done: true };
|
|
789
|
+
* }
|
|
790
|
+
* if (data.type === 'step_error') {
|
|
791
|
+
* return { error: data.error };
|
|
792
|
+
* }
|
|
793
|
+
* return null; // Ignore other events
|
|
794
|
+
* }
|
|
795
|
+
* }
|
|
796
|
+
* ```
|
|
797
|
+
*/
|
|
798
|
+
parseSSEEvent?: AgentWidgetSSEEventParser;
|
|
799
|
+
/**
|
|
800
|
+
* Layout configuration for customizing widget appearance and structure.
|
|
801
|
+
* Provides control over header, messages, and content slots.
|
|
802
|
+
*
|
|
803
|
+
* @example
|
|
804
|
+
* ```typescript
|
|
805
|
+
* config: {
|
|
806
|
+
* layout: {
|
|
807
|
+
* header: { layout: "minimal" },
|
|
808
|
+
* messages: { avatar: { show: true } }
|
|
809
|
+
* }
|
|
810
|
+
* }
|
|
811
|
+
* ```
|
|
812
|
+
*/
|
|
813
|
+
layout?: AgentWidgetLayoutConfig;
|
|
433
814
|
};
|
|
434
815
|
|
|
435
816
|
export type AgentWidgetMessageRole = "user" | "assistant" | "system";
|