@makemore/agent-frontend 2.8.3 → 2.9.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/chat-widget.cjs.js +348 -239
- package/dist/chat-widget.css +340 -16
- package/dist/chat-widget.esm.js +359 -250
- package/dist/chat-widget.js +306 -197
- package/dist/react.cjs.js +353 -244
- package/dist/react.esm.js +364 -255
- package/package.json +2 -2
- package/src/components/ChatWidget.js +38 -6
- package/src/components/DevToolbar.js +135 -0
- package/src/hooks/useSystems.js +163 -0
- package/src/index.js +17 -0
- package/src/utils/config.js +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@makemore/agent-frontend",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"description": "A lightweight chat widget for AI agents. Use as an embeddable script tag or import directly into React/Preact projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/chat-widget.cjs.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"build:dev": "node build.js --dev",
|
|
31
31
|
"build:embed": "esbuild src/index.js --bundle --minify --format=iife --global-name=ChatWidgetModule --outfile=dist/chat-widget.js",
|
|
32
32
|
"watch": "node watch.js",
|
|
33
|
-
"copy": "cp -f dist/chat-widget.js ../django_agent_studio/static/agent-frontend/
|
|
33
|
+
"copy": "mkdir -p ../django_agent_studio/static/agent-frontend && cp -f dist/chat-widget.js dist/chat-widget.css dist/chat-widget-markdown.js ../django_agent_studio/static/agent-frontend/ 2>/dev/null || true && echo 'Copied to django_agent_studio'",
|
|
34
34
|
"prepublishOnly": "npm run build",
|
|
35
35
|
"serve": "python -m http.server 8080"
|
|
36
36
|
},
|
|
@@ -10,9 +10,11 @@ import { InputForm } from './InputForm.js';
|
|
|
10
10
|
import { Sidebar } from './Sidebar.js';
|
|
11
11
|
import { ModelSelector } from './ModelSelector.js';
|
|
12
12
|
import { TaskList } from './TaskList.js';
|
|
13
|
+
import { DevToolbar } from './DevToolbar.js';
|
|
13
14
|
import { useChat } from '../hooks/useChat.js';
|
|
14
15
|
import { useModels } from '../hooks/useModels.js';
|
|
15
16
|
import { useTasks } from '../hooks/useTasks.js';
|
|
17
|
+
import { useSystems } from '../hooks/useSystems.js';
|
|
16
18
|
import { createApiClient } from '../utils/api.js';
|
|
17
19
|
import { createStorage, getContrastingTextColor } from '../utils/helpers.js';
|
|
18
20
|
|
|
@@ -55,8 +57,21 @@ export function ChatWidget({ config, onStateChange, markdownParser, apiRef }) {
|
|
|
55
57
|
return createApiClient(config, getState, setState);
|
|
56
58
|
}, [config, authToken, storage]);
|
|
57
59
|
|
|
58
|
-
//
|
|
59
|
-
const
|
|
60
|
+
// Systems/agents discovery hook (for dev tools)
|
|
61
|
+
const systemsHook = useSystems(config, api, storage);
|
|
62
|
+
|
|
63
|
+
// Create a config override with the effective agent key from dev tools
|
|
64
|
+
const effectiveConfig = useMemo(() => {
|
|
65
|
+
if (!config.showDevTools) return config;
|
|
66
|
+
const effectiveKey = systemsHook.getEffectiveAgentKey();
|
|
67
|
+
if (effectiveKey && effectiveKey !== config.agentKey) {
|
|
68
|
+
return { ...config, agentKey: effectiveKey };
|
|
69
|
+
}
|
|
70
|
+
return config;
|
|
71
|
+
}, [config, systemsHook.getEffectiveAgentKey]);
|
|
72
|
+
|
|
73
|
+
// Chat hook — uses effective config so agentKey is dynamic
|
|
74
|
+
const chat = useChat(effectiveConfig, api, storage);
|
|
60
75
|
|
|
61
76
|
// Models hook
|
|
62
77
|
const models = useModels(config, api, storage);
|
|
@@ -113,12 +128,13 @@ export function ChatWidget({ config, onStateChange, markdownParser, apiRef }) {
|
|
|
113
128
|
// Load conversations for sidebar
|
|
114
129
|
const loadConversations = useCallback(async () => {
|
|
115
130
|
if (!config.showConversationSidebar) return;
|
|
116
|
-
|
|
131
|
+
|
|
117
132
|
setConversationsLoading(true);
|
|
118
133
|
try {
|
|
119
|
-
const
|
|
134
|
+
const agentKey = effectiveConfig.agentKey;
|
|
135
|
+
const url = `${config.backendUrl}${config.apiPaths.conversations}?agent_key=${encodeURIComponent(agentKey)}`;
|
|
120
136
|
const response = await fetch(url, api.getFetchOptions({ method: 'GET' }));
|
|
121
|
-
|
|
137
|
+
|
|
122
138
|
if (response.ok) {
|
|
123
139
|
const data = await response.json();
|
|
124
140
|
setConversations(data.results || data);
|
|
@@ -129,7 +145,7 @@ export function ChatWidget({ config, onStateChange, markdownParser, apiRef }) {
|
|
|
129
145
|
} finally {
|
|
130
146
|
setConversationsLoading(false);
|
|
131
147
|
}
|
|
132
|
-
}, [config, api]);
|
|
148
|
+
}, [config, effectiveConfig, api]);
|
|
133
149
|
|
|
134
150
|
// Handlers
|
|
135
151
|
const handleToggleSidebar = useCallback(() => {
|
|
@@ -243,6 +259,22 @@ export function ChatWidget({ config, onStateChange, markdownParser, apiRef }) {
|
|
|
243
259
|
onToggleSidebar=${handleToggleSidebar}
|
|
244
260
|
/>
|
|
245
261
|
|
|
262
|
+
${config.showDevTools && html`
|
|
263
|
+
<${DevToolbar}
|
|
264
|
+
systems=${systemsHook.systems}
|
|
265
|
+
agents=${systemsHook.agents}
|
|
266
|
+
selectedSystem=${systemsHook.selectedSystem}
|
|
267
|
+
selectedAgent=${systemsHook.selectedAgent}
|
|
268
|
+
selectedSystemVersion=${systemsHook.selectedSystemVersion}
|
|
269
|
+
selectedAgentVersion=${systemsHook.selectedAgentVersion}
|
|
270
|
+
onSelectSystem=${systemsHook.selectSystem}
|
|
271
|
+
onSelectAgent=${systemsHook.selectAgent}
|
|
272
|
+
onSelectSystemVersion=${systemsHook.selectSystemVersion}
|
|
273
|
+
onSelectAgentVersion=${systemsHook.selectAgentVersion}
|
|
274
|
+
disabled=${chat.isLoading}
|
|
275
|
+
/>
|
|
276
|
+
`}
|
|
277
|
+
|
|
246
278
|
${config.showTasksTab !== false && html`
|
|
247
279
|
<div class="cw-tabs">
|
|
248
280
|
<button
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DevToolbar component - system/agent/version picker for developers and testers.
|
|
3
|
+
*
|
|
4
|
+
* Always shows when rendered — displays info badges for single items,
|
|
5
|
+
* dropdowns when there are multiple options to choose from.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { html } from 'htm/preact';
|
|
9
|
+
import { escapeHtml } from '../utils/helpers.js';
|
|
10
|
+
|
|
11
|
+
export function DevToolbar({
|
|
12
|
+
systems,
|
|
13
|
+
agents,
|
|
14
|
+
selectedSystem,
|
|
15
|
+
selectedAgent,
|
|
16
|
+
selectedSystemVersion,
|
|
17
|
+
selectedAgentVersion,
|
|
18
|
+
onSelectSystem,
|
|
19
|
+
onSelectAgent,
|
|
20
|
+
onSelectSystemVersion,
|
|
21
|
+
onSelectAgentVersion,
|
|
22
|
+
disabled,
|
|
23
|
+
}) {
|
|
24
|
+
// Find current system and agent objects
|
|
25
|
+
const currentSystem = systems.find(s => s.slug === selectedSystem);
|
|
26
|
+
const currentAgent = agents.find(a => a.slug === selectedAgent);
|
|
27
|
+
|
|
28
|
+
// Get versions for current selections
|
|
29
|
+
const systemVersions = currentSystem?.versions || [];
|
|
30
|
+
const agentVersions = currentAgent?.versions || [];
|
|
31
|
+
|
|
32
|
+
// Nothing loaded yet
|
|
33
|
+
if (systems.length === 0 && agents.length === 0) return null;
|
|
34
|
+
|
|
35
|
+
const hasMultipleSystems = systems.length > 1;
|
|
36
|
+
const hasMultipleAgents = agents.length > 1;
|
|
37
|
+
const hasMultipleSystemVersions = systemVersions.length > 1;
|
|
38
|
+
const hasMultipleAgentVersions = agentVersions.length > 1;
|
|
39
|
+
|
|
40
|
+
return html`
|
|
41
|
+
<div class="cw-dev-toolbar">
|
|
42
|
+
<div class="cw-dev-toolbar-label">
|
|
43
|
+
<span class="cw-dev-toolbar-icon">🛠️</span>
|
|
44
|
+
<span>Dev</span>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div class="cw-dev-toolbar-selectors">
|
|
48
|
+
<!-- System -->
|
|
49
|
+
<div class="cw-dev-select-group">
|
|
50
|
+
<label class="cw-dev-label">System</label>
|
|
51
|
+
${hasMultipleSystems ? html`
|
|
52
|
+
<select
|
|
53
|
+
class="cw-dev-select"
|
|
54
|
+
value=${selectedSystem || ''}
|
|
55
|
+
onChange=${(e) => onSelectSystem(e.target.value)}
|
|
56
|
+
disabled=${disabled}
|
|
57
|
+
>
|
|
58
|
+
${systems.map(sys => html`
|
|
59
|
+
<option key=${sys.slug} value=${sys.slug}>
|
|
60
|
+
${sys.name}
|
|
61
|
+
</option>
|
|
62
|
+
`)}
|
|
63
|
+
</select>
|
|
64
|
+
` : html`
|
|
65
|
+
<span class="cw-dev-badge">${currentSystem?.name || '—'}</span>
|
|
66
|
+
`}
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<!-- System Version -->
|
|
70
|
+
<div class="cw-dev-select-group">
|
|
71
|
+
<label class="cw-dev-label">Sys Ver</label>
|
|
72
|
+
${hasMultipleSystemVersions ? html`
|
|
73
|
+
<select
|
|
74
|
+
class="cw-dev-select"
|
|
75
|
+
value=${selectedSystemVersion || ''}
|
|
76
|
+
onChange=${(e) => onSelectSystemVersion(e.target.value || null)}
|
|
77
|
+
disabled=${disabled}
|
|
78
|
+
>
|
|
79
|
+
${systemVersions.map(v => html`
|
|
80
|
+
<option key=${v.version} value=${v.version}>
|
|
81
|
+
${v.version}${v.is_active ? ' ✓' : ''}${v.is_draft ? ' (draft)' : ''}
|
|
82
|
+
</option>
|
|
83
|
+
`)}
|
|
84
|
+
</select>
|
|
85
|
+
` : html`
|
|
86
|
+
<span class="cw-dev-badge">${systemVersions.length === 1 ? systemVersions[0].version : 'none'}</span>
|
|
87
|
+
`}
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<!-- Agent -->
|
|
91
|
+
<div class="cw-dev-select-group">
|
|
92
|
+
<label class="cw-dev-label">Agent</label>
|
|
93
|
+
${hasMultipleAgents ? html`
|
|
94
|
+
<select
|
|
95
|
+
class="cw-dev-select"
|
|
96
|
+
value=${selectedAgent || ''}
|
|
97
|
+
onChange=${(e) => onSelectAgent(e.target.value)}
|
|
98
|
+
disabled=${disabled}
|
|
99
|
+
>
|
|
100
|
+
${agents.map(agent => html`
|
|
101
|
+
<option key=${agent.slug} value=${agent.slug}>
|
|
102
|
+
${agent.name}${currentSystem?.entry_agent?.slug === agent.slug ? ' ★' : ''}
|
|
103
|
+
</option>
|
|
104
|
+
`)}
|
|
105
|
+
</select>
|
|
106
|
+
` : html`
|
|
107
|
+
<span class="cw-dev-badge">${currentAgent?.name || agents[0]?.name || '—'}${currentSystem?.entry_agent?.slug === (currentAgent?.slug || agents[0]?.slug) ? ' ★' : ''}</span>
|
|
108
|
+
`}
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<!-- Agent Version -->
|
|
112
|
+
<div class="cw-dev-select-group">
|
|
113
|
+
<label class="cw-dev-label">Agent Ver</label>
|
|
114
|
+
${hasMultipleAgentVersions ? html`
|
|
115
|
+
<select
|
|
116
|
+
class="cw-dev-select"
|
|
117
|
+
value=${selectedAgentVersion || ''}
|
|
118
|
+
onChange=${(e) => onSelectAgentVersion(e.target.value || null)}
|
|
119
|
+
disabled=${disabled}
|
|
120
|
+
>
|
|
121
|
+
${agentVersions.map(v => html`
|
|
122
|
+
<option key=${v.version} value=${v.version}>
|
|
123
|
+
${v.version}${v.is_active ? ' ✓' : ''}${v.is_draft ? ' (draft)' : ''}
|
|
124
|
+
</option>
|
|
125
|
+
`)}
|
|
126
|
+
</select>
|
|
127
|
+
` : html`
|
|
128
|
+
<span class="cw-dev-badge">${agentVersions.length === 1 ? agentVersions[0].version : (currentAgent?.active_version || '—')}</span>
|
|
129
|
+
`}
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
`;
|
|
134
|
+
}
|
|
135
|
+
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Systems hook - manages system/agent/version discovery and selection
|
|
3
|
+
* for developer/tester UI (DevToolbar).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useState, useEffect, useCallback } from 'preact/hooks';
|
|
7
|
+
|
|
8
|
+
const SYSTEM_KEY = 'cw_selected_system';
|
|
9
|
+
const AGENT_KEY = 'cw_selected_agent';
|
|
10
|
+
const SYSTEM_VERSION_KEY = 'cw_selected_system_version';
|
|
11
|
+
const AGENT_VERSION_KEY = 'cw_selected_agent_version';
|
|
12
|
+
|
|
13
|
+
export function useSystems(config, api, storage) {
|
|
14
|
+
const [systems, setSystems] = useState([]);
|
|
15
|
+
const [agents, setAgents] = useState([]);
|
|
16
|
+
const [selectedSystem, setSelectedSystem] = useState(null);
|
|
17
|
+
const [selectedAgent, setSelectedAgent] = useState(null);
|
|
18
|
+
const [selectedSystemVersion, setSelectedSystemVersion] = useState(null);
|
|
19
|
+
const [selectedAgentVersion, setSelectedAgentVersion] = useState(null);
|
|
20
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
21
|
+
|
|
22
|
+
// Compute the effective agent key to use for runs
|
|
23
|
+
const getEffectiveAgentKey = useCallback(() => {
|
|
24
|
+
if (selectedAgent) return selectedAgent;
|
|
25
|
+
if (selectedSystem) {
|
|
26
|
+
const sys = systems.find(s => s.slug === selectedSystem);
|
|
27
|
+
if (sys?.entry_agent) return sys.entry_agent.slug;
|
|
28
|
+
}
|
|
29
|
+
return config.agentKey;
|
|
30
|
+
}, [selectedAgent, selectedSystem, systems, config.agentKey]);
|
|
31
|
+
|
|
32
|
+
// Load systems on mount
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (!config.showDevTools) return;
|
|
35
|
+
|
|
36
|
+
const loadSystems = async () => {
|
|
37
|
+
setIsLoading(true);
|
|
38
|
+
try {
|
|
39
|
+
const response = await fetch(
|
|
40
|
+
`${config.backendUrl}${config.apiPaths.systems}`,
|
|
41
|
+
api.getFetchOptions({ method: 'GET' })
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
if (response.ok) {
|
|
45
|
+
const data = await response.json();
|
|
46
|
+
const systemsList = data.results || data;
|
|
47
|
+
setSystems(systemsList);
|
|
48
|
+
|
|
49
|
+
// Restore saved selection or auto-select if only 1 system
|
|
50
|
+
const saved = storage?.get(SYSTEM_KEY);
|
|
51
|
+
if (saved && systemsList.some(s => s.slug === saved)) {
|
|
52
|
+
setSelectedSystem(saved);
|
|
53
|
+
} else if (systemsList.length === 1) {
|
|
54
|
+
setSelectedSystem(systemsList[0].slug);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.warn('[ChatWidget] Failed to load systems:', err);
|
|
59
|
+
} finally {
|
|
60
|
+
setIsLoading(false);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
loadSystems();
|
|
65
|
+
}, [config.backendUrl, config.apiPaths.systems, config.showDevTools, api, storage]);
|
|
66
|
+
|
|
67
|
+
// Load agents when system changes
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!config.showDevTools) return;
|
|
70
|
+
|
|
71
|
+
const loadAgents = async () => {
|
|
72
|
+
try {
|
|
73
|
+
const systemParam = selectedSystem ? `?system=${encodeURIComponent(selectedSystem)}` : '';
|
|
74
|
+
const response = await fetch(
|
|
75
|
+
`${config.backendUrl}${config.apiPaths.agents}${systemParam}`,
|
|
76
|
+
api.getFetchOptions({ method: 'GET' })
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (response.ok) {
|
|
80
|
+
const data = await response.json();
|
|
81
|
+
const agentsList = data.results || data;
|
|
82
|
+
setAgents(agentsList);
|
|
83
|
+
|
|
84
|
+
// Restore saved agent or default to entry agent
|
|
85
|
+
const saved = storage?.get(AGENT_KEY);
|
|
86
|
+
if (saved && agentsList.some(a => a.slug === saved)) {
|
|
87
|
+
setSelectedAgent(saved);
|
|
88
|
+
} else if (selectedSystem) {
|
|
89
|
+
const sys = systems.find(s => s.slug === selectedSystem);
|
|
90
|
+
if (sys?.entry_agent) {
|
|
91
|
+
setSelectedAgent(sys.entry_agent.slug);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Restore saved agent version
|
|
96
|
+
const savedVersion = storage?.get(AGENT_VERSION_KEY);
|
|
97
|
+
if (savedVersion) {
|
|
98
|
+
setSelectedAgentVersion(savedVersion);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch (err) {
|
|
102
|
+
console.warn('[ChatWidget] Failed to load agents:', err);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
loadAgents();
|
|
107
|
+
}, [config.backendUrl, config.apiPaths.agents, config.showDevTools, selectedSystem, api, storage, systems]);
|
|
108
|
+
|
|
109
|
+
// Select a system
|
|
110
|
+
const selectSystem = useCallback((slug) => {
|
|
111
|
+
setSelectedSystem(slug);
|
|
112
|
+
storage?.set(SYSTEM_KEY, slug);
|
|
113
|
+
// Reset agent selection — will be re-set by the agents useEffect
|
|
114
|
+
setSelectedAgent(null);
|
|
115
|
+
setSelectedAgentVersion(null);
|
|
116
|
+
storage?.set(AGENT_KEY, null);
|
|
117
|
+
storage?.set(AGENT_VERSION_KEY, null);
|
|
118
|
+
// Set system version
|
|
119
|
+
const sys = systems.find(s => s.slug === slug);
|
|
120
|
+
const activeVer = sys?.active_version || null;
|
|
121
|
+
setSelectedSystemVersion(activeVer);
|
|
122
|
+
storage?.set(SYSTEM_VERSION_KEY, activeVer);
|
|
123
|
+
}, [storage, systems]);
|
|
124
|
+
|
|
125
|
+
// Select an agent
|
|
126
|
+
const selectAgent = useCallback((slug) => {
|
|
127
|
+
setSelectedAgent(slug);
|
|
128
|
+
storage?.set(AGENT_KEY, slug);
|
|
129
|
+
// Reset agent version to active
|
|
130
|
+
const agent = agents.find(a => a.slug === slug);
|
|
131
|
+
const activeVer = agent?.active_version || null;
|
|
132
|
+
setSelectedAgentVersion(activeVer);
|
|
133
|
+
storage?.set(AGENT_VERSION_KEY, activeVer);
|
|
134
|
+
}, [storage, agents]);
|
|
135
|
+
|
|
136
|
+
// Select system version
|
|
137
|
+
const selectSystemVersion = useCallback((version) => {
|
|
138
|
+
setSelectedSystemVersion(version);
|
|
139
|
+
storage?.set(SYSTEM_VERSION_KEY, version);
|
|
140
|
+
}, [storage]);
|
|
141
|
+
|
|
142
|
+
// Select agent version
|
|
143
|
+
const selectAgentVersion = useCallback((version) => {
|
|
144
|
+
setSelectedAgentVersion(version);
|
|
145
|
+
storage?.set(AGENT_VERSION_KEY, version);
|
|
146
|
+
}, [storage]);
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
systems,
|
|
150
|
+
agents,
|
|
151
|
+
selectedSystem,
|
|
152
|
+
selectedAgent,
|
|
153
|
+
selectedSystemVersion,
|
|
154
|
+
selectedAgentVersion,
|
|
155
|
+
isLoading,
|
|
156
|
+
selectSystem,
|
|
157
|
+
selectAgent,
|
|
158
|
+
selectSystemVersion,
|
|
159
|
+
selectAgentVersion,
|
|
160
|
+
getEffectiveAgentKey,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
package/src/index.js
CHANGED
|
@@ -52,6 +52,9 @@ class ChatWidgetInstance {
|
|
|
52
52
|
document.body.appendChild(this.container);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
// Apply theme class
|
|
56
|
+
this._applyTheme();
|
|
57
|
+
|
|
55
58
|
// Render the Preact component
|
|
56
59
|
this._render();
|
|
57
60
|
|
|
@@ -59,6 +62,16 @@ class ChatWidgetInstance {
|
|
|
59
62
|
return this;
|
|
60
63
|
}
|
|
61
64
|
|
|
65
|
+
_applyTheme() {
|
|
66
|
+
if (!this.container) return;
|
|
67
|
+
this.container.classList.remove('cw-dark', 'cw-auto');
|
|
68
|
+
if (this.config.theme === 'dark') {
|
|
69
|
+
this.container.classList.add('cw-dark');
|
|
70
|
+
} else if (this.config.theme === 'auto') {
|
|
71
|
+
this.container.classList.add('cw-auto');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
62
75
|
_render(configOverrides = {}) {
|
|
63
76
|
if (!this.container) return;
|
|
64
77
|
render(
|
|
@@ -172,6 +185,10 @@ class ChatWidgetInstance {
|
|
|
172
185
|
...this.config,
|
|
173
186
|
...configUpdates,
|
|
174
187
|
};
|
|
188
|
+
// Re-apply theme if it changed
|
|
189
|
+
if ('theme' in configUpdates) {
|
|
190
|
+
this._applyTheme();
|
|
191
|
+
}
|
|
175
192
|
// Re-render with updated config
|
|
176
193
|
this._render();
|
|
177
194
|
console.log(`[ChatWidget] Instance ${this.instanceId} config updated`);
|
package/src/utils/config.js
CHANGED
|
@@ -41,6 +41,8 @@ export const DEFAULT_CONFIG = {
|
|
|
41
41
|
ttsVoices: '/api/tts/voices/',
|
|
42
42
|
ttsSetVoice: '/api/tts/set-voice/',
|
|
43
43
|
models: '/api/agent-runtime/models/',
|
|
44
|
+
systems: '/api/agent-runtime/systems/',
|
|
45
|
+
agents: '/api/agent-runtime/agents/',
|
|
44
46
|
},
|
|
45
47
|
|
|
46
48
|
// API case style: 'camel', 'snake', or 'auto' (accepts both, sends camelCase)
|
|
@@ -49,6 +51,9 @@ export const DEFAULT_CONFIG = {
|
|
|
49
51
|
// - 'auto': Accept both in responses, send snake_case in requests (default)
|
|
50
52
|
apiCaseStyle: 'auto',
|
|
51
53
|
|
|
54
|
+
// Theme: 'light' (default), 'dark', or 'auto' (follows prefers-color-scheme)
|
|
55
|
+
theme: 'light',
|
|
56
|
+
|
|
52
57
|
// UI options
|
|
53
58
|
showConversationSidebar: true,
|
|
54
59
|
showClearButton: true,
|
|
@@ -57,6 +62,7 @@ export const DEFAULT_CONFIG = {
|
|
|
57
62
|
showVoiceSettings: true,
|
|
58
63
|
showExpandButton: true,
|
|
59
64
|
showModelSelector: false,
|
|
65
|
+
showDevTools: false, // Show system/agent/version picker for developers/testers
|
|
60
66
|
enableVoice: true, // Enable voice input (speech-to-text)
|
|
61
67
|
|
|
62
68
|
// Model selection
|