@makemore/agent-frontend 1.6.1 → 1.7.1
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 +35 -0
- package/dist/chat-widget.js +74 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -174,6 +174,41 @@ See `django-tts-example.py` for the complete Django backend implementation.
|
|
|
174
174
|
| `showTTSButton` | boolean | `true` | Show TTS toggle button in header |
|
|
175
175
|
| `showVoiceSettings` | boolean | `true` | Show voice settings button in header (works with proxy and direct API) |
|
|
176
176
|
| `showExpandButton` | boolean | `true` | Show expand/minimize button in header |
|
|
177
|
+
| `onEvent` | function | `null` | Callback for SSE events: `(eventType, payload) => void` |
|
|
178
|
+
|
|
179
|
+
### Event Callback
|
|
180
|
+
|
|
181
|
+
The `onEvent` callback allows your application to react to all SSE events from the agent:
|
|
182
|
+
|
|
183
|
+
```javascript
|
|
184
|
+
ChatWidget.init({
|
|
185
|
+
backendUrl: 'http://localhost:8000',
|
|
186
|
+
agentKey: 'your-agent',
|
|
187
|
+
onEvent: (eventType, payload) => {
|
|
188
|
+
console.log('Event:', eventType, payload);
|
|
189
|
+
|
|
190
|
+
// Example: Navigate when a session is created
|
|
191
|
+
if (eventType === 'tool.result' && payload.result?.session_id) {
|
|
192
|
+
window.location.href = `/session/${payload.result.session_id}`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Example: Track tool usage
|
|
196
|
+
if (eventType === 'tool.call') {
|
|
197
|
+
analytics.track('Tool Called', { tool: payload.name });
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Event Types:**
|
|
204
|
+
- `assistant.message` - Streaming assistant responses (payload: `{ content: string }`)
|
|
205
|
+
- `tool.call` - Tool being called (payload: `{ name: string, arguments: object }`)
|
|
206
|
+
- `tool.result` - Tool result (payload: `{ result: any }`)
|
|
207
|
+
- `run.succeeded` - Run completed successfully
|
|
208
|
+
- `run.failed` - Run failed (payload: `{ error: string }`)
|
|
209
|
+
- `run.cancelled` - Run was cancelled
|
|
210
|
+
- `run.timed_out` - Run timed out
|
|
211
|
+
- Custom events emitted by your agent
|
|
177
212
|
|
|
178
213
|
### Text-to-Speech (ElevenLabs)
|
|
179
214
|
|
package/dist/chat-widget.js
CHANGED
|
@@ -70,6 +70,8 @@
|
|
|
70
70
|
showTTSButton: true,
|
|
71
71
|
showVoiceSettings: true,
|
|
72
72
|
showExpandButton: true,
|
|
73
|
+
// Event callback
|
|
74
|
+
onEvent: null, // Callback for SSE events: (eventType, payload) => void
|
|
73
75
|
};
|
|
74
76
|
|
|
75
77
|
// State
|
|
@@ -492,6 +494,12 @@
|
|
|
492
494
|
eventSource.addEventListener('assistant.message', (event) => {
|
|
493
495
|
try {
|
|
494
496
|
const data = JSON.parse(event.data);
|
|
497
|
+
|
|
498
|
+
// Call onEvent callback if provided
|
|
499
|
+
if (config.onEvent && typeof config.onEvent === 'function') {
|
|
500
|
+
config.onEvent('assistant.message', data.payload);
|
|
501
|
+
}
|
|
502
|
+
|
|
495
503
|
const content = data.payload.content;
|
|
496
504
|
if (content) {
|
|
497
505
|
assistantContent += content;
|
|
@@ -518,18 +526,25 @@
|
|
|
518
526
|
|
|
519
527
|
// Handler for tool calls (debug mode)
|
|
520
528
|
eventSource.addEventListener('tool.call', (event) => {
|
|
521
|
-
if (!state.debugMode) return;
|
|
522
529
|
try {
|
|
523
530
|
const data = JSON.parse(event.data);
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
531
|
+
|
|
532
|
+
// Call onEvent callback if provided
|
|
533
|
+
if (config.onEvent && typeof config.onEvent === 'function') {
|
|
534
|
+
config.onEvent('tool.call', data.payload);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (state.debugMode) {
|
|
538
|
+
state.messages.push({
|
|
539
|
+
id: 'tool-call-' + Date.now(),
|
|
540
|
+
role: 'system',
|
|
541
|
+
content: `🔧 Tool: ${data.payload.name}`,
|
|
542
|
+
timestamp: new Date(),
|
|
543
|
+
type: 'tool_call',
|
|
544
|
+
metadata: { name: data.payload.name, arguments: data.payload.arguments },
|
|
545
|
+
});
|
|
546
|
+
render();
|
|
547
|
+
}
|
|
533
548
|
} catch (err) {
|
|
534
549
|
console.error('[ChatWidget] Failed to parse tool.call:', err);
|
|
535
550
|
}
|
|
@@ -537,19 +552,26 @@
|
|
|
537
552
|
|
|
538
553
|
// Handler for tool results (debug mode)
|
|
539
554
|
eventSource.addEventListener('tool.result', (event) => {
|
|
540
|
-
if (!state.debugMode) return;
|
|
541
555
|
try {
|
|
542
556
|
const data = JSON.parse(event.data);
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
557
|
+
|
|
558
|
+
// Call onEvent callback if provided
|
|
559
|
+
if (config.onEvent && typeof config.onEvent === 'function') {
|
|
560
|
+
config.onEvent('tool.result', data.payload);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
if (state.debugMode) {
|
|
564
|
+
const result = data.payload.result || '';
|
|
565
|
+
state.messages.push({
|
|
566
|
+
id: 'tool-result-' + Date.now(),
|
|
567
|
+
role: 'system',
|
|
568
|
+
content: `✅ Result: ${result.substring(0, 100)}${result.length > 100 ? '...' : ''}`,
|
|
569
|
+
timestamp: new Date(),
|
|
570
|
+
type: 'tool_result',
|
|
571
|
+
metadata: { result },
|
|
572
|
+
});
|
|
573
|
+
render();
|
|
574
|
+
}
|
|
553
575
|
} catch (err) {
|
|
554
576
|
console.error('[ChatWidget] Failed to parse tool.result:', err);
|
|
555
577
|
}
|
|
@@ -559,6 +581,12 @@
|
|
|
559
581
|
const handleTerminal = (event) => {
|
|
560
582
|
try {
|
|
561
583
|
const data = JSON.parse(event.data);
|
|
584
|
+
|
|
585
|
+
// Call onEvent callback if provided
|
|
586
|
+
if (config.onEvent && typeof config.onEvent === 'function') {
|
|
587
|
+
config.onEvent(data.type, data.payload);
|
|
588
|
+
}
|
|
589
|
+
|
|
562
590
|
if (data.type === 'run.failed') {
|
|
563
591
|
state.error = data.payload.error || 'Agent run failed';
|
|
564
592
|
state.messages.push({
|
|
@@ -604,6 +632,22 @@
|
|
|
604
632
|
eventSource.addEventListener('run.cancelled', handleTerminal);
|
|
605
633
|
eventSource.addEventListener('run.timed_out', handleTerminal);
|
|
606
634
|
|
|
635
|
+
// Generic handler for any other custom events
|
|
636
|
+
eventSource.onmessage = (event) => {
|
|
637
|
+
try {
|
|
638
|
+
const data = JSON.parse(event.data);
|
|
639
|
+
|
|
640
|
+
// Call onEvent callback for any unhandled events
|
|
641
|
+
if (config.onEvent && typeof config.onEvent === 'function') {
|
|
642
|
+
// Extract event type from data or use 'message' as default
|
|
643
|
+
const eventType = data.type || 'message';
|
|
644
|
+
config.onEvent(eventType, data.payload || data);
|
|
645
|
+
}
|
|
646
|
+
} catch (err) {
|
|
647
|
+
console.debug('[ChatWidget] Received non-JSON SSE message:', event.data);
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
|
|
607
651
|
eventSource.onerror = () => {
|
|
608
652
|
if (eventSource.readyState !== EventSource.CLOSED) {
|
|
609
653
|
console.debug('[ChatWidget] SSE connection closed');
|
|
@@ -1015,6 +1059,13 @@
|
|
|
1015
1059
|
if (messagesEl) {
|
|
1016
1060
|
messagesEl.scrollTop = messagesEl.scrollHeight;
|
|
1017
1061
|
}
|
|
1062
|
+
|
|
1063
|
+
// Focus input field
|
|
1064
|
+
const inputEl = container.querySelector('.cw-input');
|
|
1065
|
+
if (inputEl && !state.isLoading) {
|
|
1066
|
+
// Use setTimeout to ensure focus happens after render completes
|
|
1067
|
+
setTimeout(() => inputEl.focus(), 0);
|
|
1068
|
+
}
|
|
1018
1069
|
}
|
|
1019
1070
|
|
|
1020
1071
|
function attachEventListeners() {
|
|
@@ -1064,6 +1115,8 @@
|
|
|
1064
1115
|
if (input && input.value.trim()) {
|
|
1065
1116
|
sendMessage(input.value);
|
|
1066
1117
|
input.value = '';
|
|
1118
|
+
// Keep focus on input after sending
|
|
1119
|
+
input.focus();
|
|
1067
1120
|
}
|
|
1068
1121
|
});
|
|
1069
1122
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@makemore/agent-frontend",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "A standalone, zero-dependency chat widget for AI agents. Embed conversational AI into any website with a single script tag.",
|
|
5
5
|
"main": "dist/chat-widget.js",
|
|
6
6
|
"files": [
|