@smooai/smooth-operator 1.11.4 → 1.13.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/widget/chat-widget.iife.js +135 -2
- package/dist/widget/chat-widget.iife.js.map +1 -1
- package/dist/widget/conversation.d.ts +69 -1
- package/dist/widget/conversation.d.ts.map +1 -1
- package/dist/widget/conversation.js +67 -2
- package/dist/widget/conversation.js.map +1 -1
- package/dist/widget/element.d.ts +8 -0
- package/dist/widget/element.d.ts.map +1 -1
- package/dist/widget/element.js +43 -0
- package/dist/widget/element.js.map +1 -1
- package/dist/widget/styles.d.ts.map +1 -1
- package/dist/widget/styles.js +29 -0
- package/dist/widget/styles.js.map +1 -1
- package/package.json +1 -1
- package/src/widget/conversation.ts +95 -3
- package/src/widget/element.ts +49 -1
- package/src/widget/styles.ts +29 -0
package/src/widget/element.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import type { ChatWidgetConfig, ChatWidgetMode, ChatWidgetTheme } from './config.js';
|
|
17
17
|
import { resolveConfig } from './config.js';
|
|
18
|
-
import { type ChatMessage, type Citation, type ConnectionStatus, ConversationController } from './conversation.js';
|
|
18
|
+
import { type ChatMessage, type ChatPrompt, type Citation, type ConnectionStatus, ConversationController } from './conversation.js';
|
|
19
19
|
import { SMOOTH_LOGO_SVG } from './logo.js';
|
|
20
20
|
import { buildStyles } from './styles.js';
|
|
21
21
|
|
|
@@ -271,6 +271,13 @@ export class SmoothAgentChatElement extends HTMLElement {
|
|
|
271
271
|
}
|
|
272
272
|
this.messagesEl.appendChild(el);
|
|
273
273
|
|
|
274
|
+
// Render chat-native button prompts (SEP ui/confirm + ui/select,
|
|
275
|
+
// projected from write_confirmation_required). The click resumes the
|
|
276
|
+
// paused turn via the controller.
|
|
277
|
+
if (msg.prompt) {
|
|
278
|
+
this.messagesEl.appendChild(this.renderPrompt(msg.prompt));
|
|
279
|
+
}
|
|
280
|
+
|
|
274
281
|
// Render a "Sources (N)" section under any assistant message whose
|
|
275
282
|
// terminal eventual_response carried citations. Back-compatible: most
|
|
276
283
|
// turns have none, so this is skipped.
|
|
@@ -281,6 +288,47 @@ export class SmoothAgentChatElement extends HTMLElement {
|
|
|
281
288
|
this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
|
|
282
289
|
}
|
|
283
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Render a chat-native button prompt (SEP `ui/confirm` / `ui/select`). Each
|
|
293
|
+
* option is a button; clicking one resumes the paused turn via
|
|
294
|
+
* {@link ConversationController.answerPrompt}. Once answered the buttons
|
|
295
|
+
* disable and the chosen label is shown, so the record stays in the
|
|
296
|
+
* transcript. Built with DOM APIs (no innerHTML) — prompt text is untrusted.
|
|
297
|
+
*/
|
|
298
|
+
private renderPrompt(prompt: ChatPrompt): HTMLElement {
|
|
299
|
+
const wrap = document.createElement('div');
|
|
300
|
+
wrap.className = 'prompt';
|
|
301
|
+
wrap.setAttribute('part', 'prompt');
|
|
302
|
+
|
|
303
|
+
const text = document.createElement('div');
|
|
304
|
+
text.className = 'prompt-text';
|
|
305
|
+
text.textContent = prompt.text;
|
|
306
|
+
wrap.appendChild(text);
|
|
307
|
+
|
|
308
|
+
if (prompt.answered) {
|
|
309
|
+
const chosen = document.createElement('div');
|
|
310
|
+
chosen.className = 'prompt-answered';
|
|
311
|
+
chosen.textContent = `You chose: ${prompt.answered}`;
|
|
312
|
+
wrap.appendChild(chosen);
|
|
313
|
+
return wrap;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const buttons = document.createElement('div');
|
|
317
|
+
buttons.className = 'prompt-buttons';
|
|
318
|
+
for (const opt of prompt.options) {
|
|
319
|
+
const btn = document.createElement('button');
|
|
320
|
+
btn.className = 'prompt-button';
|
|
321
|
+
btn.type = 'button';
|
|
322
|
+
btn.textContent = opt.label;
|
|
323
|
+
btn.addEventListener('click', () => {
|
|
324
|
+
this.controller?.answerPrompt(prompt.requestId, opt.value);
|
|
325
|
+
});
|
|
326
|
+
buttons.appendChild(btn);
|
|
327
|
+
}
|
|
328
|
+
wrap.appendChild(buttons);
|
|
329
|
+
return wrap;
|
|
330
|
+
}
|
|
331
|
+
|
|
284
332
|
/**
|
|
285
333
|
* Build the collapsible "Sources (N)" block for an assistant message's
|
|
286
334
|
* citations. Each source renders its `title` (linked to `citation.url` when
|
package/src/widget/styles.ts
CHANGED
|
@@ -168,6 +168,35 @@ export function buildStyles(theme: Required<ChatWidgetTheme>, mode: ChatWidgetMo
|
|
|
168
168
|
|
|
169
169
|
/* Sources panel — rendered under an assistant bubble whose terminal
|
|
170
170
|
eventual_response carried citations. */
|
|
171
|
+
.prompt {
|
|
172
|
+
align-self: flex-start;
|
|
173
|
+
max-width: 80%;
|
|
174
|
+
margin-top: -2px;
|
|
175
|
+
display: flex;
|
|
176
|
+
flex-direction: column;
|
|
177
|
+
gap: 8px;
|
|
178
|
+
}
|
|
179
|
+
.panel.fullpage .prompt { max-width: 100%; }
|
|
180
|
+
.prompt-text { font-size: 13.5px; color: var(--sac-text); opacity: 0.9; }
|
|
181
|
+
.prompt-buttons { display: flex; gap: 8px; flex-wrap: wrap; }
|
|
182
|
+
.prompt-button {
|
|
183
|
+
cursor: pointer;
|
|
184
|
+
border: 1px solid var(--sac-border);
|
|
185
|
+
background: var(--sac-bg);
|
|
186
|
+
color: var(--sac-text);
|
|
187
|
+
border-radius: 999px;
|
|
188
|
+
padding: 6px 16px;
|
|
189
|
+
font-size: 13px;
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
transition: background 0.15s, color 0.15s, border-color 0.15s;
|
|
192
|
+
}
|
|
193
|
+
.prompt-button:hover {
|
|
194
|
+
background: var(--sac-primary);
|
|
195
|
+
color: var(--sac-primary-text);
|
|
196
|
+
border-color: var(--sac-primary);
|
|
197
|
+
}
|
|
198
|
+
.prompt-answered { font-size: 12.5px; opacity: 0.7; font-style: italic; }
|
|
199
|
+
|
|
171
200
|
.sources {
|
|
172
201
|
align-self: flex-start;
|
|
173
202
|
max-width: 80%;
|