vanilla-agent 1.23.0 → 1.24.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/dist/index.cjs +21 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -6
- package/dist/index.d.ts +33 -6
- package/dist/index.global.js +43 -43
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +20 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/types.ts +33 -6
- package/src/utils/code-generators.ts +237 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vanilla-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"description": "Themeable, plugable streaming agent widget for websites, in plain JS with support for voice input and reasoning / tool output.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
package/src/types.ts
CHANGED
|
@@ -105,6 +105,23 @@ export type AgentWidgetMessageFeedback = {
|
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Configuration for message action buttons (copy, upvote, downvote)
|
|
108
|
+
*
|
|
109
|
+
* **Client Token Mode**: When using `clientToken`, feedback is automatically
|
|
110
|
+
* sent to your Travrse backend. Just enable the buttons and you're done!
|
|
111
|
+
* The `onFeedback` and `onCopy` callbacks are optional for additional local handling.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* // With clientToken - feedback is automatic!
|
|
116
|
+
* config: {
|
|
117
|
+
* clientToken: 'ct_live_...',
|
|
118
|
+
* messageActions: {
|
|
119
|
+
* showUpvote: true,
|
|
120
|
+
* showDownvote: true,
|
|
121
|
+
* // No onFeedback needed - sent to backend automatically
|
|
122
|
+
* }
|
|
123
|
+
* }
|
|
124
|
+
* ```
|
|
108
125
|
*/
|
|
109
126
|
export type AgentWidgetMessageActionsConfig = {
|
|
110
127
|
/**
|
|
@@ -118,13 +135,15 @@ export type AgentWidgetMessageActionsConfig = {
|
|
|
118
135
|
*/
|
|
119
136
|
showCopy?: boolean;
|
|
120
137
|
/**
|
|
121
|
-
* Show upvote button
|
|
122
|
-
*
|
|
138
|
+
* Show upvote button.
|
|
139
|
+
* When using `clientToken`, feedback is sent to the backend automatically.
|
|
140
|
+
* @default false
|
|
123
141
|
*/
|
|
124
142
|
showUpvote?: boolean;
|
|
125
143
|
/**
|
|
126
|
-
* Show downvote button
|
|
127
|
-
*
|
|
144
|
+
* Show downvote button.
|
|
145
|
+
* When using `clientToken`, feedback is sent to the backend automatically.
|
|
146
|
+
* @default false
|
|
128
147
|
*/
|
|
129
148
|
showDownvote?: boolean;
|
|
130
149
|
/**
|
|
@@ -145,11 +164,19 @@ export type AgentWidgetMessageActionsConfig = {
|
|
|
145
164
|
*/
|
|
146
165
|
layout?: "pill-inside" | "row-inside";
|
|
147
166
|
/**
|
|
148
|
-
* Callback when user submits feedback (upvote/downvote)
|
|
167
|
+
* Callback when user submits feedback (upvote/downvote).
|
|
168
|
+
*
|
|
169
|
+
* **Note**: When using `clientToken`, feedback is AUTOMATICALLY sent to your
|
|
170
|
+
* backend via `/v1/client/feedback`. This callback is called IN ADDITION to
|
|
171
|
+
* the automatic submission, useful for updating local UI or analytics.
|
|
149
172
|
*/
|
|
150
173
|
onFeedback?: (feedback: AgentWidgetMessageFeedback) => void;
|
|
151
174
|
/**
|
|
152
|
-
* Callback when user copies a message
|
|
175
|
+
* Callback when user copies a message.
|
|
176
|
+
*
|
|
177
|
+
* **Note**: When using `clientToken`, copy events are AUTOMATICALLY tracked
|
|
178
|
+
* via `/v1/client/feedback`. This callback is called IN ADDITION to the
|
|
179
|
+
* automatic tracking.
|
|
153
180
|
*/
|
|
154
181
|
onCopy?: (message: AgentWidgetMessage) => void;
|
|
155
182
|
};
|
|
@@ -22,6 +22,154 @@ function getParserTypeFromConfig(config: AgentWidgetConfig): ParserType {
|
|
|
22
22
|
return config.parserType ?? detectParserTypeFromStreamParser(config.streamParser) ?? "plain";
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
// Helper to generate toolCall config
|
|
26
|
+
function generateToolCallConfig(config: any, indent: string): string[] {
|
|
27
|
+
const lines: string[] = [];
|
|
28
|
+
if (config.toolCall) {
|
|
29
|
+
lines.push(`${indent}toolCall: {`);
|
|
30
|
+
Object.entries(config.toolCall).forEach(([key, value]) => {
|
|
31
|
+
if (typeof value === "string") {
|
|
32
|
+
lines.push(`${indent} ${key}: "${value}",`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
lines.push(`${indent}},`);
|
|
36
|
+
}
|
|
37
|
+
return lines;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Helper to generate messageActions config (excluding callbacks)
|
|
41
|
+
function generateMessageActionsConfig(config: any, indent: string): string[] {
|
|
42
|
+
const lines: string[] = [];
|
|
43
|
+
if (config.messageActions) {
|
|
44
|
+
const hasSerializableProps = Object.entries(config.messageActions).some(
|
|
45
|
+
([key, value]) => key !== "onFeedback" && key !== "onCopy" && value !== undefined
|
|
46
|
+
);
|
|
47
|
+
if (hasSerializableProps) {
|
|
48
|
+
lines.push(`${indent}messageActions: {`);
|
|
49
|
+
Object.entries(config.messageActions).forEach(([key, value]) => {
|
|
50
|
+
// Skip function callbacks
|
|
51
|
+
if (key === "onFeedback" || key === "onCopy") return;
|
|
52
|
+
if (typeof value === "string") {
|
|
53
|
+
lines.push(`${indent} ${key}: "${value}",`);
|
|
54
|
+
} else if (typeof value === "boolean") {
|
|
55
|
+
lines.push(`${indent} ${key}: ${value},`);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
lines.push(`${indent}},`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return lines;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Helper to generate markdown config (excluding renderer functions)
|
|
65
|
+
function generateMarkdownConfig(config: any, indent: string): string[] {
|
|
66
|
+
const lines: string[] = [];
|
|
67
|
+
if (config.markdown) {
|
|
68
|
+
const hasOptions = config.markdown.options && Object.keys(config.markdown.options).length > 0;
|
|
69
|
+
const hasDisableDefaultStyles = config.markdown.disableDefaultStyles !== undefined;
|
|
70
|
+
|
|
71
|
+
if (hasOptions || hasDisableDefaultStyles) {
|
|
72
|
+
lines.push(`${indent}markdown: {`);
|
|
73
|
+
|
|
74
|
+
if (hasOptions) {
|
|
75
|
+
lines.push(`${indent} options: {`);
|
|
76
|
+
Object.entries(config.markdown.options).forEach(([key, value]) => {
|
|
77
|
+
if (typeof value === "string") {
|
|
78
|
+
lines.push(`${indent} ${key}: "${value}",`);
|
|
79
|
+
} else if (typeof value === "boolean") {
|
|
80
|
+
lines.push(`${indent} ${key}: ${value},`);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
lines.push(`${indent} },`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (hasDisableDefaultStyles) {
|
|
87
|
+
lines.push(`${indent} disableDefaultStyles: ${config.markdown.disableDefaultStyles},`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
lines.push(`${indent}},`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return lines;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Helper to generate layout config (excluding render functions and slots)
|
|
97
|
+
function generateLayoutConfig(config: any, indent: string): string[] {
|
|
98
|
+
const lines: string[] = [];
|
|
99
|
+
if (config.layout) {
|
|
100
|
+
const hasHeader = config.layout.header && Object.keys(config.layout.header).some(
|
|
101
|
+
(key: string) => key !== "render"
|
|
102
|
+
);
|
|
103
|
+
const hasMessages = config.layout.messages && Object.keys(config.layout.messages).some(
|
|
104
|
+
(key: string) => key !== "renderUserMessage" && key !== "renderAssistantMessage"
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (hasHeader || hasMessages) {
|
|
108
|
+
lines.push(`${indent}layout: {`);
|
|
109
|
+
|
|
110
|
+
// Header config (excluding render function)
|
|
111
|
+
if (hasHeader) {
|
|
112
|
+
lines.push(`${indent} header: {`);
|
|
113
|
+
Object.entries(config.layout.header).forEach(([key, value]) => {
|
|
114
|
+
if (key === "render") return; // Skip render function
|
|
115
|
+
if (typeof value === "string") {
|
|
116
|
+
lines.push(`${indent} ${key}: "${value}",`);
|
|
117
|
+
} else if (typeof value === "boolean") {
|
|
118
|
+
lines.push(`${indent} ${key}: ${value},`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
lines.push(`${indent} },`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Messages config (excluding render functions)
|
|
125
|
+
if (hasMessages) {
|
|
126
|
+
lines.push(`${indent} messages: {`);
|
|
127
|
+
Object.entries(config.layout.messages).forEach(([key, value]) => {
|
|
128
|
+
// Skip render functions
|
|
129
|
+
if (key === "renderUserMessage" || key === "renderAssistantMessage") return;
|
|
130
|
+
|
|
131
|
+
if (key === "avatar" && typeof value === "object" && value !== null) {
|
|
132
|
+
lines.push(`${indent} avatar: {`);
|
|
133
|
+
Object.entries(value as Record<string, unknown>).forEach(([avatarKey, avatarValue]) => {
|
|
134
|
+
if (typeof avatarValue === "string") {
|
|
135
|
+
lines.push(`${indent} ${avatarKey}: "${avatarValue}",`);
|
|
136
|
+
} else if (typeof avatarValue === "boolean") {
|
|
137
|
+
lines.push(`${indent} ${avatarKey}: ${avatarValue},`);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
lines.push(`${indent} },`);
|
|
141
|
+
} else if (key === "timestamp" && typeof value === "object" && value !== null) {
|
|
142
|
+
// Only emit serializable timestamp properties (skip format function)
|
|
143
|
+
const hasSerializableTimestamp = Object.entries(value as Record<string, unknown>).some(
|
|
144
|
+
([k]) => k !== "format"
|
|
145
|
+
);
|
|
146
|
+
if (hasSerializableTimestamp) {
|
|
147
|
+
lines.push(`${indent} timestamp: {`);
|
|
148
|
+
Object.entries(value as Record<string, unknown>).forEach(([tsKey, tsValue]) => {
|
|
149
|
+
if (tsKey === "format") return; // Skip format function
|
|
150
|
+
if (typeof tsValue === "string") {
|
|
151
|
+
lines.push(`${indent} ${tsKey}: "${tsValue}",`);
|
|
152
|
+
} else if (typeof tsValue === "boolean") {
|
|
153
|
+
lines.push(`${indent} ${tsKey}: ${tsValue},`);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
lines.push(`${indent} },`);
|
|
157
|
+
}
|
|
158
|
+
} else if (typeof value === "string") {
|
|
159
|
+
lines.push(`${indent} ${key}: "${value}",`);
|
|
160
|
+
} else if (typeof value === "boolean") {
|
|
161
|
+
lines.push(`${indent} ${key}: ${value},`);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
lines.push(`${indent} },`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
lines.push(`${indent}},`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return lines;
|
|
171
|
+
}
|
|
172
|
+
|
|
25
173
|
export function generateCodeSnippet(config: any, format: CodeFormat = "esm"): string {
|
|
26
174
|
// Remove non-serializable properties
|
|
27
175
|
const cleanConfig = { ...config };
|
|
@@ -159,6 +307,18 @@ function generateESMCode(config: any): string {
|
|
|
159
307
|
lines.push(" },");
|
|
160
308
|
}
|
|
161
309
|
|
|
310
|
+
// Add toolCall config
|
|
311
|
+
lines.push(...generateToolCallConfig(config, " "));
|
|
312
|
+
|
|
313
|
+
// Add messageActions config
|
|
314
|
+
lines.push(...generateMessageActionsConfig(config, " "));
|
|
315
|
+
|
|
316
|
+
// Add markdown config
|
|
317
|
+
lines.push(...generateMarkdownConfig(config, " "));
|
|
318
|
+
|
|
319
|
+
// Add layout config
|
|
320
|
+
lines.push(...generateLayoutConfig(config, " "));
|
|
321
|
+
|
|
162
322
|
if (config.debug) {
|
|
163
323
|
lines.push(` debug: ${config.debug},`);
|
|
164
324
|
}
|
|
@@ -295,6 +455,18 @@ function generateReactComponentCode(config: any): string {
|
|
|
295
455
|
lines.push(" },");
|
|
296
456
|
}
|
|
297
457
|
|
|
458
|
+
// Add toolCall config
|
|
459
|
+
lines.push(...generateToolCallConfig(config, " "));
|
|
460
|
+
|
|
461
|
+
// Add messageActions config
|
|
462
|
+
lines.push(...generateMessageActionsConfig(config, " "));
|
|
463
|
+
|
|
464
|
+
// Add markdown config
|
|
465
|
+
lines.push(...generateMarkdownConfig(config, " "));
|
|
466
|
+
|
|
467
|
+
// Add layout config
|
|
468
|
+
lines.push(...generateLayoutConfig(config, " "));
|
|
469
|
+
|
|
298
470
|
if (config.debug) {
|
|
299
471
|
lines.push(` debug: ${config.debug},`);
|
|
300
472
|
}
|
|
@@ -548,6 +720,18 @@ function generateReactAdvancedCode(config: any): string {
|
|
|
548
720
|
lines.push(" },");
|
|
549
721
|
}
|
|
550
722
|
|
|
723
|
+
// Add toolCall config
|
|
724
|
+
lines.push(...generateToolCallConfig(config, " "));
|
|
725
|
+
|
|
726
|
+
// Add messageActions config
|
|
727
|
+
lines.push(...generateMessageActionsConfig(config, " "));
|
|
728
|
+
|
|
729
|
+
// Add markdown config
|
|
730
|
+
lines.push(...generateMarkdownConfig(config, " "));
|
|
731
|
+
|
|
732
|
+
// Add layout config
|
|
733
|
+
lines.push(...generateLayoutConfig(config, " "));
|
|
734
|
+
|
|
551
735
|
if (config.debug) {
|
|
552
736
|
lines.push(` debug: ${config.debug},`);
|
|
553
737
|
}
|
|
@@ -788,6 +972,18 @@ function generateScriptInstallerCode(config: any): string {
|
|
|
788
972
|
lines.push(" },");
|
|
789
973
|
}
|
|
790
974
|
|
|
975
|
+
// Add toolCall config
|
|
976
|
+
lines.push(...generateToolCallConfig(config, " "));
|
|
977
|
+
|
|
978
|
+
// Add messageActions config
|
|
979
|
+
lines.push(...generateMessageActionsConfig(config, " "));
|
|
980
|
+
|
|
981
|
+
// Add markdown config
|
|
982
|
+
lines.push(...generateMarkdownConfig(config, " "));
|
|
983
|
+
|
|
984
|
+
// Add layout config
|
|
985
|
+
lines.push(...generateLayoutConfig(config, " "));
|
|
986
|
+
|
|
791
987
|
if (config.debug) {
|
|
792
988
|
lines.push(` debug: ${config.debug},`);
|
|
793
989
|
}
|
|
@@ -922,6 +1118,18 @@ function generateScriptManualCode(config: any): string {
|
|
|
922
1118
|
lines.push(" },");
|
|
923
1119
|
}
|
|
924
1120
|
|
|
1121
|
+
// Add toolCall config
|
|
1122
|
+
lines.push(...generateToolCallConfig(config, " "));
|
|
1123
|
+
|
|
1124
|
+
// Add messageActions config
|
|
1125
|
+
lines.push(...generateMessageActionsConfig(config, " "));
|
|
1126
|
+
|
|
1127
|
+
// Add markdown config
|
|
1128
|
+
lines.push(...generateMarkdownConfig(config, " "));
|
|
1129
|
+
|
|
1130
|
+
// Add layout config
|
|
1131
|
+
lines.push(...generateLayoutConfig(config, " "));
|
|
1132
|
+
|
|
925
1133
|
if (config.debug) {
|
|
926
1134
|
lines.push(` debug: ${config.debug},`);
|
|
927
1135
|
}
|
|
@@ -1029,6 +1237,35 @@ function generateScriptAdvancedCode(config: any): string {
|
|
|
1029
1237
|
lines.push(" ],");
|
|
1030
1238
|
}
|
|
1031
1239
|
|
|
1240
|
+
if (config.suggestionChipsConfig) {
|
|
1241
|
+
lines.push(" suggestionChipsConfig: {");
|
|
1242
|
+
if (config.suggestionChipsConfig.fontFamily) {
|
|
1243
|
+
lines.push(` fontFamily: "${config.suggestionChipsConfig.fontFamily}",`);
|
|
1244
|
+
}
|
|
1245
|
+
if (config.suggestionChipsConfig.fontWeight) {
|
|
1246
|
+
lines.push(` fontWeight: "${config.suggestionChipsConfig.fontWeight}",`);
|
|
1247
|
+
}
|
|
1248
|
+
if (config.suggestionChipsConfig.paddingX) {
|
|
1249
|
+
lines.push(` paddingX: "${config.suggestionChipsConfig.paddingX}",`);
|
|
1250
|
+
}
|
|
1251
|
+
if (config.suggestionChipsConfig.paddingY) {
|
|
1252
|
+
lines.push(` paddingY: "${config.suggestionChipsConfig.paddingY}",`);
|
|
1253
|
+
}
|
|
1254
|
+
lines.push(" },");
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
// Add toolCall config
|
|
1258
|
+
lines.push(...generateToolCallConfig(config, " "));
|
|
1259
|
+
|
|
1260
|
+
// Add messageActions config
|
|
1261
|
+
lines.push(...generateMessageActionsConfig(config, " "));
|
|
1262
|
+
|
|
1263
|
+
// Add markdown config
|
|
1264
|
+
lines.push(...generateMarkdownConfig(config, " "));
|
|
1265
|
+
|
|
1266
|
+
// Add layout config
|
|
1267
|
+
lines.push(...generateLayoutConfig(config, " "));
|
|
1268
|
+
|
|
1032
1269
|
lines.push(" };");
|
|
1033
1270
|
lines.push("</script>");
|
|
1034
1271
|
lines.push("");
|