vanilla-agent 1.10.0 → 1.12.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 +57 -8
- package/dist/index.cjs +52 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +308 -1
- package/dist/index.d.ts +308 -1
- package/dist/index.global.js +97 -52
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +52 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/composer-builder.ts +366 -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/defaults.ts +49 -1
- package/src/index.ts +45 -1
- package/src/runtime/init.ts +27 -1
- package/src/types.ts +231 -0
- package/src/ui.ts +452 -34
- package/src/utils/code-generators.ts +1242 -0
package/src/defaults.ts
CHANGED
|
@@ -66,8 +66,9 @@ export const DEFAULT_WIDGET_CONFIG: Partial<AgentWidgetConfig> = {
|
|
|
66
66
|
backgroundColor: "transparent",
|
|
67
67
|
borderColor: "transparent",
|
|
68
68
|
enabled: true,
|
|
69
|
+
placement: "inline",
|
|
69
70
|
iconName: "refresh-cw",
|
|
70
|
-
size: "
|
|
71
|
+
size: "32px",
|
|
71
72
|
showTooltip: true,
|
|
72
73
|
tooltipText: "Clear chat",
|
|
73
74
|
paddingX: "0px",
|
|
@@ -134,6 +135,29 @@ export const DEFAULT_WIDGET_CONFIG: Partial<AgentWidgetConfig> = {
|
|
|
134
135
|
paddingX: "12px",
|
|
135
136
|
paddingY: "6px",
|
|
136
137
|
},
|
|
138
|
+
layout: {
|
|
139
|
+
header: {
|
|
140
|
+
layout: "default",
|
|
141
|
+
showIcon: true,
|
|
142
|
+
showTitle: true,
|
|
143
|
+
showSubtitle: true,
|
|
144
|
+
showCloseButton: true,
|
|
145
|
+
showClearChat: true,
|
|
146
|
+
},
|
|
147
|
+
messages: {
|
|
148
|
+
layout: "bubble",
|
|
149
|
+
avatar: {
|
|
150
|
+
show: false,
|
|
151
|
+
position: "left",
|
|
152
|
+
},
|
|
153
|
+
timestamp: {
|
|
154
|
+
show: false,
|
|
155
|
+
position: "below",
|
|
156
|
+
},
|
|
157
|
+
groupConsecutive: false,
|
|
158
|
+
},
|
|
159
|
+
slots: {},
|
|
160
|
+
},
|
|
137
161
|
debug: false,
|
|
138
162
|
};
|
|
139
163
|
|
|
@@ -186,5 +210,29 @@ export function mergeWithDefaults(
|
|
|
186
210
|
...DEFAULT_WIDGET_CONFIG.suggestionChipsConfig,
|
|
187
211
|
...config.suggestionChipsConfig,
|
|
188
212
|
},
|
|
213
|
+
layout: {
|
|
214
|
+
...DEFAULT_WIDGET_CONFIG.layout,
|
|
215
|
+
...config.layout,
|
|
216
|
+
header: {
|
|
217
|
+
...DEFAULT_WIDGET_CONFIG.layout?.header,
|
|
218
|
+
...config.layout?.header,
|
|
219
|
+
},
|
|
220
|
+
messages: {
|
|
221
|
+
...DEFAULT_WIDGET_CONFIG.layout?.messages,
|
|
222
|
+
...config.layout?.messages,
|
|
223
|
+
avatar: {
|
|
224
|
+
...DEFAULT_WIDGET_CONFIG.layout?.messages?.avatar,
|
|
225
|
+
...config.layout?.messages?.avatar,
|
|
226
|
+
},
|
|
227
|
+
timestamp: {
|
|
228
|
+
...DEFAULT_WIDGET_CONFIG.layout?.messages?.timestamp,
|
|
229
|
+
...config.layout?.messages?.timestamp,
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
slots: {
|
|
233
|
+
...DEFAULT_WIDGET_CONFIG.layout?.slots,
|
|
234
|
+
...config.layout?.slots,
|
|
235
|
+
},
|
|
236
|
+
},
|
|
189
237
|
};
|
|
190
238
|
}
|
package/src/index.ts
CHANGED
|
@@ -17,7 +17,18 @@ export type {
|
|
|
17
17
|
AgentWidgetCustomFetch,
|
|
18
18
|
AgentWidgetSSEEventParser,
|
|
19
19
|
AgentWidgetSSEEventResult,
|
|
20
|
-
AgentWidgetHeadersFunction
|
|
20
|
+
AgentWidgetHeadersFunction,
|
|
21
|
+
// Layout types
|
|
22
|
+
AgentWidgetLayoutConfig,
|
|
23
|
+
AgentWidgetHeaderLayoutConfig,
|
|
24
|
+
AgentWidgetMessageLayoutConfig,
|
|
25
|
+
AgentWidgetAvatarConfig,
|
|
26
|
+
AgentWidgetTimestampConfig,
|
|
27
|
+
WidgetLayoutSlot,
|
|
28
|
+
SlotRenderer,
|
|
29
|
+
SlotRenderContext,
|
|
30
|
+
HeaderRenderContext,
|
|
31
|
+
MessageRenderContext
|
|
21
32
|
} from "./types";
|
|
22
33
|
|
|
23
34
|
export { initAgentWidgetFn as initAgentWidget };
|
|
@@ -48,6 +59,8 @@ export {
|
|
|
48
59
|
createRegexJsonParser,
|
|
49
60
|
createXmlParser
|
|
50
61
|
} from "./utils/formatting";
|
|
62
|
+
export { generateCodeSnippet } from "./utils/code-generators";
|
|
63
|
+
export type { CodeFormat } from "./utils/code-generators";
|
|
51
64
|
export type { AgentWidgetInitHandle };
|
|
52
65
|
|
|
53
66
|
// Plugin system exports
|
|
@@ -72,4 +85,35 @@ export {
|
|
|
72
85
|
// Default configuration exports
|
|
73
86
|
export { DEFAULT_WIDGET_CONFIG, mergeWithDefaults } from "./defaults";
|
|
74
87
|
|
|
88
|
+
// Layout system exports
|
|
89
|
+
export {
|
|
90
|
+
buildHeader,
|
|
91
|
+
buildComposer,
|
|
92
|
+
attachHeaderToContainer
|
|
93
|
+
} from "./components/panel";
|
|
94
|
+
export type {
|
|
95
|
+
HeaderElements,
|
|
96
|
+
HeaderBuildContext,
|
|
97
|
+
ComposerElements,
|
|
98
|
+
ComposerBuildContext
|
|
99
|
+
} from "./components/panel";
|
|
100
|
+
export {
|
|
101
|
+
headerLayouts,
|
|
102
|
+
getHeaderLayout,
|
|
103
|
+
buildHeaderWithLayout,
|
|
104
|
+
buildDefaultHeader,
|
|
105
|
+
buildMinimalHeader,
|
|
106
|
+
buildExpandedHeader
|
|
107
|
+
} from "./components/header-layouts";
|
|
108
|
+
export type {
|
|
109
|
+
HeaderLayoutContext,
|
|
110
|
+
HeaderLayoutRenderer
|
|
111
|
+
} from "./components/header-layouts";
|
|
112
|
+
export {
|
|
113
|
+
createStandardBubble,
|
|
114
|
+
createBubbleWithLayout,
|
|
115
|
+
createTypingIndicator
|
|
116
|
+
} from "./components/message-bubble";
|
|
117
|
+
export type { MessageTransform } from "./components/message-bubble";
|
|
118
|
+
|
|
75
119
|
export default initAgentWidgetFn;
|
package/src/runtime/init.ts
CHANGED
|
@@ -92,9 +92,19 @@ export const initAgentWidget = (
|
|
|
92
92
|
const target = ensureTarget(options.target);
|
|
93
93
|
const host = document.createElement("div");
|
|
94
94
|
host.className = "vanilla-agent-host";
|
|
95
|
+
|
|
96
|
+
// When launcher is disabled (inline embed mode), ensure the host fills its container
|
|
97
|
+
// This allows the widget to respect the parent container's height
|
|
98
|
+
const launcherEnabled = options.config?.launcher?.enabled ?? true;
|
|
99
|
+
if (!launcherEnabled) {
|
|
100
|
+
host.style.height = "100%";
|
|
101
|
+
host.style.display = "flex";
|
|
102
|
+
host.style.flexDirection = "column";
|
|
103
|
+
}
|
|
104
|
+
|
|
95
105
|
target.appendChild(host);
|
|
96
106
|
|
|
97
|
-
const useShadow = options.useShadowDom
|
|
107
|
+
const useShadow = options.useShadowDom === true;
|
|
98
108
|
let mount: HTMLElement;
|
|
99
109
|
let root: ShadowRoot | HTMLElement;
|
|
100
110
|
|
|
@@ -103,12 +113,28 @@ export const initAgentWidget = (
|
|
|
103
113
|
root = shadowRoot;
|
|
104
114
|
mount = document.createElement("div");
|
|
105
115
|
mount.id = "vanilla-agent-root";
|
|
116
|
+
// When launcher is disabled, ensure mount fills the host
|
|
117
|
+
if (!launcherEnabled) {
|
|
118
|
+
mount.style.height = "100%";
|
|
119
|
+
mount.style.display = "flex";
|
|
120
|
+
mount.style.flexDirection = "column";
|
|
121
|
+
mount.style.flex = "1";
|
|
122
|
+
mount.style.minHeight = "0";
|
|
123
|
+
}
|
|
106
124
|
shadowRoot.appendChild(mount);
|
|
107
125
|
mountStyles(shadowRoot);
|
|
108
126
|
} else {
|
|
109
127
|
root = host;
|
|
110
128
|
mount = document.createElement("div");
|
|
111
129
|
mount.id = "vanilla-agent-root";
|
|
130
|
+
// When launcher is disabled, ensure mount fills the host
|
|
131
|
+
if (!launcherEnabled) {
|
|
132
|
+
mount.style.height = "100%";
|
|
133
|
+
mount.style.display = "flex";
|
|
134
|
+
mount.style.flexDirection = "column";
|
|
135
|
+
mount.style.flex = "1";
|
|
136
|
+
mount.style.minHeight = "0";
|
|
137
|
+
}
|
|
112
138
|
host.appendChild(mount);
|
|
113
139
|
mountStyles(host);
|
|
114
140
|
}
|
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;
|
|
@@ -386,6 +434,174 @@ export type AgentWidgetCustomFetch = (
|
|
|
386
434
|
*/
|
|
387
435
|
export type AgentWidgetHeadersFunction = () => Record<string, string> | Promise<Record<string, string>>;
|
|
388
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
|
+
|
|
389
605
|
export type AgentWidgetConfig = {
|
|
390
606
|
apiUrl?: string;
|
|
391
607
|
flowId?: string;
|
|
@@ -580,6 +796,21 @@ export type AgentWidgetConfig = {
|
|
|
580
796
|
* ```
|
|
581
797
|
*/
|
|
582
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;
|
|
583
814
|
};
|
|
584
815
|
|
|
585
816
|
export type AgentWidgetMessageRole = "user" | "assistant" | "system";
|