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.
@@ -0,0 +1,87 @@
1
+ import { AgentWidgetConfig, AgentWidgetMessage } from "../types";
2
+
3
+ /**
4
+ * Context provided to component renderers
5
+ */
6
+ export interface ComponentContext {
7
+ message: AgentWidgetMessage;
8
+ config: AgentWidgetConfig;
9
+ /**
10
+ * Update component props during streaming
11
+ */
12
+ updateProps: (newProps: Record<string, unknown>) => void;
13
+ }
14
+
15
+ /**
16
+ * Component renderer function signature
17
+ */
18
+ export type ComponentRenderer = (
19
+ props: Record<string, unknown>,
20
+ context: ComponentContext
21
+ ) => HTMLElement;
22
+
23
+ /**
24
+ * Component registry for managing custom components
25
+ */
26
+ class ComponentRegistry {
27
+ private components: Map<string, ComponentRenderer> = new Map();
28
+
29
+ /**
30
+ * Register a custom component
31
+ */
32
+ register(name: string, renderer: ComponentRenderer): void {
33
+ if (this.components.has(name)) {
34
+ console.warn(`[ComponentRegistry] Component "${name}" is already registered. Overwriting.`);
35
+ }
36
+ this.components.set(name, renderer);
37
+ }
38
+
39
+ /**
40
+ * Unregister a component
41
+ */
42
+ unregister(name: string): void {
43
+ this.components.delete(name);
44
+ }
45
+
46
+ /**
47
+ * Get a component renderer by name
48
+ */
49
+ get(name: string): ComponentRenderer | undefined {
50
+ return this.components.get(name);
51
+ }
52
+
53
+ /**
54
+ * Check if a component is registered
55
+ */
56
+ has(name: string): boolean {
57
+ return this.components.has(name);
58
+ }
59
+
60
+ /**
61
+ * Get all registered component names
62
+ */
63
+ getAllNames(): string[] {
64
+ return Array.from(this.components.keys());
65
+ }
66
+
67
+ /**
68
+ * Clear all registered components
69
+ */
70
+ clear(): void {
71
+ this.components.clear();
72
+ }
73
+
74
+ /**
75
+ * Register multiple components at once
76
+ */
77
+ registerAll(components: Record<string, ComponentRenderer>): void {
78
+ Object.entries(components).forEach(([name, renderer]) => {
79
+ this.register(name, renderer);
80
+ });
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Global component registry instance
86
+ */
87
+ export const componentRegistry = new ComponentRegistry();
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: "29px",
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
@@ -12,7 +12,23 @@ export type {
12
12
  AgentWidgetLauncherConfig,
13
13
  AgentWidgetEvent,
14
14
  AgentWidgetStreamParser,
15
- AgentWidgetStreamParserResult
15
+ AgentWidgetStreamParserResult,
16
+ AgentWidgetRequestPayload,
17
+ AgentWidgetCustomFetch,
18
+ AgentWidgetSSEEventParser,
19
+ AgentWidgetSSEEventResult,
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
16
32
  } from "./types";
17
33
 
18
34
  export { initAgentWidgetFn as initAgentWidget };
@@ -36,7 +52,7 @@ export {
36
52
  escapeHtml,
37
53
  directivePostprocessor
38
54
  } from "./postprocessors";
39
- export {
55
+ export {
40
56
  createPlainTextParser,
41
57
  createJsonStreamParser,
42
58
  createFlexibleJsonStreamParser,
@@ -49,7 +65,53 @@ export type { AgentWidgetInitHandle };
49
65
  export type { AgentWidgetPlugin } from "./plugins/types";
50
66
  export { pluginRegistry } from "./plugins/registry";
51
67
 
68
+ // Component system exports
69
+ export { componentRegistry } from "./components/registry";
70
+ export type { ComponentRenderer, ComponentContext } from "./components/registry";
71
+ export {
72
+ createComponentStreamParser,
73
+ isComponentDirectiveType
74
+ } from "./utils/component-parser";
75
+ export type { ComponentDirective } from "./utils/component-parser";
76
+ export {
77
+ renderComponentDirective,
78
+ createComponentMiddleware,
79
+ hasComponentDirective,
80
+ extractComponentDirectiveFromMessage
81
+ } from "./utils/component-middleware";
82
+
52
83
  // Default configuration exports
53
84
  export { DEFAULT_WIDGET_CONFIG, mergeWithDefaults } from "./defaults";
54
85
 
86
+ // Layout system exports
87
+ export {
88
+ buildHeader,
89
+ buildComposer,
90
+ attachHeaderToContainer
91
+ } from "./components/panel";
92
+ export type {
93
+ HeaderElements,
94
+ HeaderBuildContext,
95
+ ComposerElements,
96
+ ComposerBuildContext
97
+ } from "./components/panel";
98
+ export {
99
+ headerLayouts,
100
+ getHeaderLayout,
101
+ buildHeaderWithLayout,
102
+ buildDefaultHeader,
103
+ buildMinimalHeader,
104
+ buildExpandedHeader
105
+ } from "./components/header-layouts";
106
+ export type {
107
+ HeaderLayoutContext,
108
+ HeaderLayoutRenderer
109
+ } from "./components/header-layouts";
110
+ export {
111
+ createStandardBubble,
112
+ createBubbleWithLayout,
113
+ createTypingIndicator
114
+ } from "./components/message-bubble";
115
+ export type { MessageTransform } from "./components/message-bubble";
116
+
55
117
  export default initAgentWidgetFn;
@@ -74,3 +74,4 @@ export const pluginRegistry = new PluginRegistry();
74
74
 
75
75
 
76
76
 
77
+
@@ -92,3 +92,4 @@ export interface AgentWidgetPlugin {
92
92
 
93
93
 
94
94
 
95
+
@@ -92,6 +92,16 @@ 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
107
  const useShadow = options.useShadowDom !== false;
@@ -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
  }