@helpai/elements 0.58.2 → 0.59.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/elements-web-component.esm.js +19 -19
- package/elements-web-component.esm.js.map +3 -3
- package/elements.cjs.js +19 -19
- package/elements.cjs.js.map +3 -3
- package/elements.esm.js +19 -19
- package/elements.esm.js.map +3 -3
- package/elements.js +19 -19
- package/elements.js.map +3 -3
- package/index.d.ts +1 -1
- package/index.mjs +56 -6
- package/package.json +1 -1
- package/schema.d.ts +26 -26
- package/web-component.mjs +56 -6
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-
|
|
1
|
+
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-Daefe1g1.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
package/index.mjs
CHANGED
|
@@ -29,7 +29,7 @@ var BRAND = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
// src/core/version.ts
|
|
32
|
-
var ELEMENTS_VERSION = true ? "0.
|
|
32
|
+
var ELEMENTS_VERSION = true ? "0.59.1" : "0.0.0-dev";
|
|
33
33
|
var ELEMENTS_VERSION_PARAM = "_ev";
|
|
34
34
|
|
|
35
35
|
// src/i18n/strings.ts
|
|
@@ -2149,6 +2149,22 @@ var DEFAULT_PATHS = {
|
|
|
2149
2149
|
submitForm: "/pai/submit-form"
|
|
2150
2150
|
};
|
|
2151
2151
|
var CONTEXT_PARAM = "context";
|
|
2152
|
+
function parseSuggestions(data) {
|
|
2153
|
+
const raw = data?.suggestions;
|
|
2154
|
+
if (!Array.isArray(raw)) return [];
|
|
2155
|
+
const out = [];
|
|
2156
|
+
for (const item of raw) {
|
|
2157
|
+
if (!item || typeof item !== "object") continue;
|
|
2158
|
+
const { id, label, text } = item;
|
|
2159
|
+
if (typeof label !== "string" || !label) continue;
|
|
2160
|
+
out.push({
|
|
2161
|
+
id: typeof id === "string" && id ? id : `s${out.length}`,
|
|
2162
|
+
label,
|
|
2163
|
+
text: typeof text === "string" && text ? text : label
|
|
2164
|
+
});
|
|
2165
|
+
}
|
|
2166
|
+
return out;
|
|
2167
|
+
}
|
|
2152
2168
|
function buildSendMessageRequest(params) {
|
|
2153
2169
|
const wire = params.messages.map((m) => ({
|
|
2154
2170
|
// Use the backend's id when known (adopted from the stream's `start` chunk)
|
|
@@ -2240,6 +2256,15 @@ function retryAfterMs(headers) {
|
|
|
2240
2256
|
const ms = Number.isFinite(secs) ? secs * 1e3 : Date.parse(raw) - Date.now();
|
|
2241
2257
|
return Number.isFinite(ms) && ms >= 0 ? Math.min(ms, 3e4) : null;
|
|
2242
2258
|
}
|
|
2259
|
+
function followupsFromMessages(messages) {
|
|
2260
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
2261
|
+
const m = messages[i];
|
|
2262
|
+
if (!m || m.role !== "assistant") continue;
|
|
2263
|
+
const part = m.parts.find((p36) => p36.type === "data-suggestions");
|
|
2264
|
+
return part?.type === "data-suggestions" ? parseSuggestions(part.data) : void 0;
|
|
2265
|
+
}
|
|
2266
|
+
return void 0;
|
|
2267
|
+
}
|
|
2243
2268
|
function sleep(ms, signal7) {
|
|
2244
2269
|
return new Promise((resolve) => {
|
|
2245
2270
|
if (signal7?.aborted) return resolve();
|
|
@@ -2486,7 +2511,10 @@ var AgentTransport = class {
|
|
|
2486
2511
|
canContinue: res.canContinue ?? true,
|
|
2487
2512
|
messages,
|
|
2488
2513
|
agent: res.agent,
|
|
2489
|
-
|
|
2514
|
+
// The latest turn's model follow-ups are persisted ON the assistant message (a `data-suggestions`
|
|
2515
|
+
// part), not in a top-level field — read them off there, falling back to any server-provided
|
|
2516
|
+
// top-level `suggestions` (e.g. resume chips) when the last turn carried none.
|
|
2517
|
+
suggestions: followupsFromMessages(messages) ?? res.suggestions
|
|
2490
2518
|
};
|
|
2491
2519
|
}
|
|
2492
2520
|
/**
|
|
@@ -2726,6 +2754,7 @@ var AgentTransport = class {
|
|
|
2726
2754
|
* (a drop), so the caller can attempt a resume.
|
|
2727
2755
|
*/
|
|
2728
2756
|
async *drain(source, seenIds, ctrl) {
|
|
2757
|
+
let terminal = false;
|
|
2729
2758
|
try {
|
|
2730
2759
|
for await (const evt of source) {
|
|
2731
2760
|
if (ctrl.signal.aborted) return true;
|
|
@@ -2734,14 +2763,14 @@ var AgentTransport = class {
|
|
|
2734
2763
|
seenIds.add(evt.eventId);
|
|
2735
2764
|
}
|
|
2736
2765
|
yield evt;
|
|
2737
|
-
if (evt.chunk.type === "finish" || evt.chunk.type === "error")
|
|
2766
|
+
if (evt.chunk.type === "finish" || evt.chunk.type === "error") terminal = true;
|
|
2738
2767
|
}
|
|
2739
2768
|
} catch (err) {
|
|
2740
2769
|
if (ctrl.signal.aborted) return true;
|
|
2741
2770
|
if (err instanceof StreamError && err.status !== void 0) throw err;
|
|
2742
2771
|
log6.debug("stream segment dropped", { err });
|
|
2743
2772
|
}
|
|
2744
|
-
return
|
|
2773
|
+
return terminal;
|
|
2745
2774
|
}
|
|
2746
2775
|
/** Abort + fire-and-forget POST to `/pai/cancel-stream`. Idempotent. */
|
|
2747
2776
|
cancelStream(ctrl, conversationId) {
|
|
@@ -2969,6 +2998,9 @@ function fromWireMessage(w) {
|
|
|
2969
2998
|
mediaType: part.mediaType
|
|
2970
2999
|
};
|
|
2971
3000
|
}
|
|
3001
|
+
if (part.type === "data-suggestions") {
|
|
3002
|
+
return null;
|
|
3003
|
+
}
|
|
2972
3004
|
if (part.type.startsWith("tool-")) {
|
|
2973
3005
|
return {
|
|
2974
3006
|
kind: "tool",
|
|
@@ -3208,6 +3240,8 @@ var StreamReducer = class {
|
|
|
3208
3240
|
return;
|
|
3209
3241
|
case "data-conversation-rebind":
|
|
3210
3242
|
return;
|
|
3243
|
+
case "data-suggestions":
|
|
3244
|
+
return;
|
|
3211
3245
|
default: {
|
|
3212
3246
|
const _exhaustive = chunk;
|
|
3213
3247
|
void _exhaustive;
|
|
@@ -8407,6 +8441,18 @@ function App({ options, hostElement, bus }) {
|
|
|
8407
8441
|
useEffect16(() => {
|
|
8408
8442
|
if (effectiveLocale !== activeLocale) setActiveLocale(effectiveLocale);
|
|
8409
8443
|
}, [effectiveLocale, activeLocale]);
|
|
8444
|
+
const pendingSuggestionsRef = useRef9(null);
|
|
8445
|
+
const captureSuggestions = useCallback6((chunk) => {
|
|
8446
|
+
if (chunk.type !== "data-suggestions") return false;
|
|
8447
|
+
pendingSuggestionsRef.current = parseSuggestions(chunk.data);
|
|
8448
|
+
return true;
|
|
8449
|
+
}, []);
|
|
8450
|
+
const flushSuggestions = useCallback6(() => {
|
|
8451
|
+
if (pendingSuggestionsRef.current) {
|
|
8452
|
+
setSuggestions(pendingSuggestionsRef.current);
|
|
8453
|
+
pendingSuggestionsRef.current = null;
|
|
8454
|
+
}
|
|
8455
|
+
}, []);
|
|
8410
8456
|
const adoptConversationRebind = useCallback6(
|
|
8411
8457
|
(chunk) => {
|
|
8412
8458
|
if (chunk.type !== "data-conversation-rebind") return false;
|
|
@@ -8426,9 +8472,10 @@ function App({ options, hostElement, bus }) {
|
|
|
8426
8472
|
const runResume = useCallback6(
|
|
8427
8473
|
async (handle) => {
|
|
8428
8474
|
let bubble = null;
|
|
8475
|
+
pendingSuggestionsRef.current = null;
|
|
8429
8476
|
try {
|
|
8430
8477
|
for await (const evt of handle.iter) {
|
|
8431
|
-
if (adoptConversationRebind(evt.chunk)) continue;
|
|
8478
|
+
if (adoptConversationRebind(evt.chunk) || captureSuggestions(evt.chunk)) continue;
|
|
8432
8479
|
if (!bubble) {
|
|
8433
8480
|
bubble = makeAssistantMessage();
|
|
8434
8481
|
resumeBubbleRef.current = bubble;
|
|
@@ -8454,6 +8501,7 @@ function App({ options, hostElement, bus }) {
|
|
|
8454
8501
|
bubble.status = "complete";
|
|
8455
8502
|
feedback.play("messageReceived");
|
|
8456
8503
|
emitMessage(bus, options, "assistant", assistantText(bubble));
|
|
8504
|
+
flushSuggestions();
|
|
8457
8505
|
}
|
|
8458
8506
|
}
|
|
8459
8507
|
} catch (err) {
|
|
@@ -8592,12 +8640,13 @@ function App({ options, hostElement, bus }) {
|
|
|
8592
8640
|
userPrefs: persistence.loadUserPrefs()
|
|
8593
8641
|
});
|
|
8594
8642
|
setStreaming(true);
|
|
8643
|
+
pendingSuggestionsRef.current = null;
|
|
8595
8644
|
const handle = transport.sendMessage(body);
|
|
8596
8645
|
setActiveCancel(() => handle.cancel);
|
|
8597
8646
|
setActiveDetach(() => handle.detach);
|
|
8598
8647
|
try {
|
|
8599
8648
|
for await (const evt of handle.iter) {
|
|
8600
|
-
if (adoptConversationRebind(evt.chunk)) continue;
|
|
8649
|
+
if (adoptConversationRebind(evt.chunk) || captureSuggestions(evt.chunk)) continue;
|
|
8601
8650
|
reducer.apply(evt.chunk);
|
|
8602
8651
|
if (evt.chunk.type === "finish" && evt.chunk.canContinue === false) {
|
|
8603
8652
|
setCanSend(false);
|
|
@@ -8616,6 +8665,7 @@ function App({ options, hostElement, bus }) {
|
|
|
8616
8665
|
assistantMsg.status = "complete";
|
|
8617
8666
|
feedback.play("messageReceived");
|
|
8618
8667
|
emitMessage(bus, options, "assistant", assistantText(assistantMsg));
|
|
8668
|
+
flushSuggestions();
|
|
8619
8669
|
}
|
|
8620
8670
|
} catch (error) {
|
|
8621
8671
|
if (isAbortError(error)) {
|
package/package.json
CHANGED
package/schema.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-
|
|
1
|
+
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-Daefe1g1.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -56,9 +56,9 @@ declare const presentationSchema: z.ZodObject<{
|
|
|
56
56
|
inset: z.ZodOptional<z.ZodString>;
|
|
57
57
|
initialSize: z.ZodDefault<z.ZodEnum<{
|
|
58
58
|
fullscreen: "fullscreen";
|
|
59
|
-
normal: "normal";
|
|
60
59
|
expanded: "expanded";
|
|
61
60
|
auto: "auto";
|
|
61
|
+
normal: "normal";
|
|
62
62
|
}>>;
|
|
63
63
|
autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
|
|
64
64
|
}, z.core.$loose>>;
|
|
@@ -242,9 +242,9 @@ type LauncherOptions = z.infer<typeof launcherOptionsSchema>;
|
|
|
242
242
|
|
|
243
243
|
declare const initialSizeSchema: z.ZodEnum<{
|
|
244
244
|
fullscreen: "fullscreen";
|
|
245
|
-
normal: "normal";
|
|
246
245
|
expanded: "expanded";
|
|
247
246
|
auto: "auto";
|
|
247
|
+
normal: "normal";
|
|
248
248
|
}>;
|
|
249
249
|
declare const resizeOptionsSchema: z.ZodObject<{
|
|
250
250
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -271,9 +271,9 @@ declare const sizeOptionsSchema: z.ZodObject<{
|
|
|
271
271
|
inset: z.ZodOptional<z.ZodString>;
|
|
272
272
|
initialSize: z.ZodDefault<z.ZodEnum<{
|
|
273
273
|
fullscreen: "fullscreen";
|
|
274
|
-
normal: "normal";
|
|
275
274
|
expanded: "expanded";
|
|
276
275
|
auto: "auto";
|
|
276
|
+
normal: "normal";
|
|
277
277
|
}>>;
|
|
278
278
|
autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
|
|
279
279
|
}, z.core.$loose>;
|
|
@@ -325,40 +325,40 @@ type FeatureFlags = z.infer<typeof featureFlagsSchema>;
|
|
|
325
325
|
*/
|
|
326
326
|
|
|
327
327
|
declare const actionNameSchema: z.ZodEnum<{
|
|
328
|
+
close: "close";
|
|
328
329
|
expand: "expand";
|
|
329
330
|
fullscreen: "fullscreen";
|
|
330
|
-
|
|
331
|
-
language: "language";
|
|
331
|
+
clear: "clear";
|
|
332
332
|
theme: "theme";
|
|
333
|
+
language: "language";
|
|
333
334
|
textSize: "textSize";
|
|
334
335
|
history: "history";
|
|
335
|
-
clear: "clear";
|
|
336
336
|
sound: "sound";
|
|
337
337
|
}>;
|
|
338
338
|
type ActionName = z.infer<typeof actionNameSchema>;
|
|
339
339
|
declare const headerActionsSchema: z.ZodArray<z.ZodEnum<{
|
|
340
|
+
close: "close";
|
|
340
341
|
expand: "expand";
|
|
341
342
|
fullscreen: "fullscreen";
|
|
342
|
-
|
|
343
|
-
language: "language";
|
|
343
|
+
clear: "clear";
|
|
344
344
|
theme: "theme";
|
|
345
|
+
language: "language";
|
|
345
346
|
textSize: "textSize";
|
|
346
347
|
history: "history";
|
|
347
|
-
clear: "clear";
|
|
348
348
|
sound: "sound";
|
|
349
349
|
}>>;
|
|
350
350
|
type HeaderActions = z.infer<typeof headerActionsSchema>;
|
|
351
351
|
/** Section wrapper — `actions` list wrapped under `header` in the dashboard form. */
|
|
352
352
|
declare const headerSchema: z.ZodObject<{
|
|
353
353
|
actions: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
354
|
+
close: "close";
|
|
354
355
|
expand: "expand";
|
|
355
356
|
fullscreen: "fullscreen";
|
|
356
|
-
|
|
357
|
-
language: "language";
|
|
357
|
+
clear: "clear";
|
|
358
358
|
theme: "theme";
|
|
359
|
+
language: "language";
|
|
359
360
|
textSize: "textSize";
|
|
360
361
|
history: "history";
|
|
361
|
-
clear: "clear";
|
|
362
362
|
sound: "sound";
|
|
363
363
|
}>>>;
|
|
364
364
|
}, z.core.$loose>;
|
|
@@ -374,33 +374,33 @@ type HeaderOptions = z.infer<typeof headerSchema>;
|
|
|
374
374
|
*/
|
|
375
375
|
|
|
376
376
|
declare const feedbackEventSchema: z.ZodEnum<{
|
|
377
|
+
voiceStart: "voiceStart";
|
|
378
|
+
voiceStop: "voiceStop";
|
|
377
379
|
error: "error";
|
|
378
380
|
messageReceived: "messageReceived";
|
|
379
381
|
messageSent: "messageSent";
|
|
380
|
-
voiceStart: "voiceStart";
|
|
381
|
-
voiceStop: "voiceStop";
|
|
382
382
|
}>;
|
|
383
383
|
type FeedbackEvent = z.infer<typeof feedbackEventSchema>;
|
|
384
384
|
declare const soundOptionsSchema: z.ZodObject<{
|
|
385
385
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
386
386
|
volume: z.ZodDefault<z.ZodNumber>;
|
|
387
387
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
388
|
+
voiceStart: "voiceStart";
|
|
389
|
+
voiceStop: "voiceStop";
|
|
388
390
|
error: "error";
|
|
389
391
|
messageReceived: "messageReceived";
|
|
390
392
|
messageSent: "messageSent";
|
|
391
|
-
voiceStart: "voiceStart";
|
|
392
|
-
voiceStop: "voiceStop";
|
|
393
393
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
|
|
394
394
|
}, z.core.$loose>;
|
|
395
395
|
type SoundOptions = z.infer<typeof soundOptionsSchema>;
|
|
396
396
|
declare const hapticsOptionsSchema: z.ZodObject<{
|
|
397
397
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
398
398
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
399
|
+
voiceStart: "voiceStart";
|
|
400
|
+
voiceStop: "voiceStop";
|
|
399
401
|
error: "error";
|
|
400
402
|
messageReceived: "messageReceived";
|
|
401
403
|
messageSent: "messageSent";
|
|
402
|
-
voiceStart: "voiceStart";
|
|
403
|
-
voiceStop: "voiceStop";
|
|
404
404
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
|
|
405
405
|
}, z.core.$loose>;
|
|
406
406
|
type HapticsOptions = z.infer<typeof hapticsOptionsSchema>;
|
|
@@ -409,21 +409,21 @@ declare const feedbackSchema: z.ZodObject<{
|
|
|
409
409
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
410
410
|
volume: z.ZodDefault<z.ZodNumber>;
|
|
411
411
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
412
|
+
voiceStart: "voiceStart";
|
|
413
|
+
voiceStop: "voiceStop";
|
|
412
414
|
error: "error";
|
|
413
415
|
messageReceived: "messageReceived";
|
|
414
416
|
messageSent: "messageSent";
|
|
415
|
-
voiceStart: "voiceStart";
|
|
416
|
-
voiceStop: "voiceStop";
|
|
417
417
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
|
|
418
418
|
}, z.core.$loose>>;
|
|
419
419
|
haptics: z.ZodOptional<z.ZodObject<{
|
|
420
420
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
421
421
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
422
|
+
voiceStart: "voiceStart";
|
|
423
|
+
voiceStop: "voiceStop";
|
|
422
424
|
error: "error";
|
|
423
425
|
messageReceived: "messageReceived";
|
|
424
426
|
messageSent: "messageSent";
|
|
425
|
-
voiceStart: "voiceStart";
|
|
426
|
-
voiceStop: "voiceStop";
|
|
427
427
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
|
|
428
428
|
}, z.core.$loose>>;
|
|
429
429
|
}, z.core.$loose>;
|
|
@@ -858,18 +858,18 @@ type I18nOptions = z.infer<typeof i18nSchema>;
|
|
|
858
858
|
*/
|
|
859
859
|
|
|
860
860
|
declare const moduleLayoutSchema: z.ZodEnum<{
|
|
861
|
+
home: "home";
|
|
861
862
|
chat: "chat";
|
|
862
863
|
help: "help";
|
|
863
|
-
home: "home";
|
|
864
864
|
news: "news";
|
|
865
865
|
}>;
|
|
866
866
|
type ModuleLayout = z.infer<typeof moduleLayoutSchema>;
|
|
867
867
|
declare const moduleSchema: z.ZodObject<{
|
|
868
868
|
label: z.ZodString;
|
|
869
869
|
layout: z.ZodEnum<{
|
|
870
|
+
home: "home";
|
|
870
871
|
chat: "chat";
|
|
871
872
|
help: "help";
|
|
872
|
-
home: "home";
|
|
873
873
|
news: "news";
|
|
874
874
|
}>;
|
|
875
875
|
contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -895,9 +895,9 @@ type ModuleOptions = z.infer<typeof moduleSchema>;
|
|
|
895
895
|
declare const modulesSchema: z.ZodArray<z.ZodObject<{
|
|
896
896
|
label: z.ZodString;
|
|
897
897
|
layout: z.ZodEnum<{
|
|
898
|
+
home: "home";
|
|
898
899
|
chat: "chat";
|
|
899
900
|
help: "help";
|
|
900
|
-
home: "home";
|
|
901
901
|
news: "news";
|
|
902
902
|
}>;
|
|
903
903
|
contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
package/web-component.mjs
CHANGED
|
@@ -1934,7 +1934,7 @@ function createAuth(opts) {
|
|
|
1934
1934
|
}
|
|
1935
1935
|
|
|
1936
1936
|
// src/core/version.ts
|
|
1937
|
-
var ELEMENTS_VERSION = true ? "0.
|
|
1937
|
+
var ELEMENTS_VERSION = true ? "0.59.1" : "0.0.0-dev";
|
|
1938
1938
|
var ELEMENTS_VERSION_PARAM = "_ev";
|
|
1939
1939
|
|
|
1940
1940
|
// src/stream/types.ts
|
|
@@ -2108,6 +2108,22 @@ var DEFAULT_PATHS = {
|
|
|
2108
2108
|
submitForm: "/pai/submit-form"
|
|
2109
2109
|
};
|
|
2110
2110
|
var CONTEXT_PARAM = "context";
|
|
2111
|
+
function parseSuggestions(data) {
|
|
2112
|
+
const raw = data?.suggestions;
|
|
2113
|
+
if (!Array.isArray(raw)) return [];
|
|
2114
|
+
const out = [];
|
|
2115
|
+
for (const item of raw) {
|
|
2116
|
+
if (!item || typeof item !== "object") continue;
|
|
2117
|
+
const { id, label, text } = item;
|
|
2118
|
+
if (typeof label !== "string" || !label) continue;
|
|
2119
|
+
out.push({
|
|
2120
|
+
id: typeof id === "string" && id ? id : `s${out.length}`,
|
|
2121
|
+
label,
|
|
2122
|
+
text: typeof text === "string" && text ? text : label
|
|
2123
|
+
});
|
|
2124
|
+
}
|
|
2125
|
+
return out;
|
|
2126
|
+
}
|
|
2111
2127
|
function buildSendMessageRequest(params) {
|
|
2112
2128
|
const wire = params.messages.map((m) => ({
|
|
2113
2129
|
// Use the backend's id when known (adopted from the stream's `start` chunk)
|
|
@@ -2199,6 +2215,15 @@ function retryAfterMs(headers) {
|
|
|
2199
2215
|
const ms = Number.isFinite(secs) ? secs * 1e3 : Date.parse(raw) - Date.now();
|
|
2200
2216
|
return Number.isFinite(ms) && ms >= 0 ? Math.min(ms, 3e4) : null;
|
|
2201
2217
|
}
|
|
2218
|
+
function followupsFromMessages(messages) {
|
|
2219
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
2220
|
+
const m = messages[i];
|
|
2221
|
+
if (!m || m.role !== "assistant") continue;
|
|
2222
|
+
const part = m.parts.find((p36) => p36.type === "data-suggestions");
|
|
2223
|
+
return part?.type === "data-suggestions" ? parseSuggestions(part.data) : void 0;
|
|
2224
|
+
}
|
|
2225
|
+
return void 0;
|
|
2226
|
+
}
|
|
2202
2227
|
function sleep(ms, signal7) {
|
|
2203
2228
|
return new Promise((resolve) => {
|
|
2204
2229
|
if (signal7?.aborted) return resolve();
|
|
@@ -2445,7 +2470,10 @@ var AgentTransport = class {
|
|
|
2445
2470
|
canContinue: res.canContinue ?? true,
|
|
2446
2471
|
messages,
|
|
2447
2472
|
agent: res.agent,
|
|
2448
|
-
|
|
2473
|
+
// The latest turn's model follow-ups are persisted ON the assistant message (a `data-suggestions`
|
|
2474
|
+
// part), not in a top-level field — read them off there, falling back to any server-provided
|
|
2475
|
+
// top-level `suggestions` (e.g. resume chips) when the last turn carried none.
|
|
2476
|
+
suggestions: followupsFromMessages(messages) ?? res.suggestions
|
|
2449
2477
|
};
|
|
2450
2478
|
}
|
|
2451
2479
|
/**
|
|
@@ -2685,6 +2713,7 @@ var AgentTransport = class {
|
|
|
2685
2713
|
* (a drop), so the caller can attempt a resume.
|
|
2686
2714
|
*/
|
|
2687
2715
|
async *drain(source, seenIds, ctrl) {
|
|
2716
|
+
let terminal = false;
|
|
2688
2717
|
try {
|
|
2689
2718
|
for await (const evt of source) {
|
|
2690
2719
|
if (ctrl.signal.aborted) return true;
|
|
@@ -2693,14 +2722,14 @@ var AgentTransport = class {
|
|
|
2693
2722
|
seenIds.add(evt.eventId);
|
|
2694
2723
|
}
|
|
2695
2724
|
yield evt;
|
|
2696
|
-
if (evt.chunk.type === "finish" || evt.chunk.type === "error")
|
|
2725
|
+
if (evt.chunk.type === "finish" || evt.chunk.type === "error") terminal = true;
|
|
2697
2726
|
}
|
|
2698
2727
|
} catch (err) {
|
|
2699
2728
|
if (ctrl.signal.aborted) return true;
|
|
2700
2729
|
if (err instanceof StreamError && err.status !== void 0) throw err;
|
|
2701
2730
|
log5.debug("stream segment dropped", { err });
|
|
2702
2731
|
}
|
|
2703
|
-
return
|
|
2732
|
+
return terminal;
|
|
2704
2733
|
}
|
|
2705
2734
|
/** Abort + fire-and-forget POST to `/pai/cancel-stream`. Idempotent. */
|
|
2706
2735
|
cancelStream(ctrl, conversationId) {
|
|
@@ -2928,6 +2957,9 @@ function fromWireMessage(w) {
|
|
|
2928
2957
|
mediaType: part.mediaType
|
|
2929
2958
|
};
|
|
2930
2959
|
}
|
|
2960
|
+
if (part.type === "data-suggestions") {
|
|
2961
|
+
return null;
|
|
2962
|
+
}
|
|
2931
2963
|
if (part.type.startsWith("tool-")) {
|
|
2932
2964
|
return {
|
|
2933
2965
|
kind: "tool",
|
|
@@ -3167,6 +3199,8 @@ var StreamReducer = class {
|
|
|
3167
3199
|
return;
|
|
3168
3200
|
case "data-conversation-rebind":
|
|
3169
3201
|
return;
|
|
3202
|
+
case "data-suggestions":
|
|
3203
|
+
return;
|
|
3170
3204
|
default: {
|
|
3171
3205
|
const _exhaustive = chunk;
|
|
3172
3206
|
void _exhaustive;
|
|
@@ -8366,6 +8400,18 @@ function App({ options, hostElement, bus }) {
|
|
|
8366
8400
|
useEffect16(() => {
|
|
8367
8401
|
if (effectiveLocale !== activeLocale) setActiveLocale(effectiveLocale);
|
|
8368
8402
|
}, [effectiveLocale, activeLocale]);
|
|
8403
|
+
const pendingSuggestionsRef = useRef9(null);
|
|
8404
|
+
const captureSuggestions = useCallback6((chunk) => {
|
|
8405
|
+
if (chunk.type !== "data-suggestions") return false;
|
|
8406
|
+
pendingSuggestionsRef.current = parseSuggestions(chunk.data);
|
|
8407
|
+
return true;
|
|
8408
|
+
}, []);
|
|
8409
|
+
const flushSuggestions = useCallback6(() => {
|
|
8410
|
+
if (pendingSuggestionsRef.current) {
|
|
8411
|
+
setSuggestions(pendingSuggestionsRef.current);
|
|
8412
|
+
pendingSuggestionsRef.current = null;
|
|
8413
|
+
}
|
|
8414
|
+
}, []);
|
|
8369
8415
|
const adoptConversationRebind = useCallback6(
|
|
8370
8416
|
(chunk) => {
|
|
8371
8417
|
if (chunk.type !== "data-conversation-rebind") return false;
|
|
@@ -8385,9 +8431,10 @@ function App({ options, hostElement, bus }) {
|
|
|
8385
8431
|
const runResume = useCallback6(
|
|
8386
8432
|
async (handle) => {
|
|
8387
8433
|
let bubble = null;
|
|
8434
|
+
pendingSuggestionsRef.current = null;
|
|
8388
8435
|
try {
|
|
8389
8436
|
for await (const evt of handle.iter) {
|
|
8390
|
-
if (adoptConversationRebind(evt.chunk)) continue;
|
|
8437
|
+
if (adoptConversationRebind(evt.chunk) || captureSuggestions(evt.chunk)) continue;
|
|
8391
8438
|
if (!bubble) {
|
|
8392
8439
|
bubble = makeAssistantMessage();
|
|
8393
8440
|
resumeBubbleRef.current = bubble;
|
|
@@ -8413,6 +8460,7 @@ function App({ options, hostElement, bus }) {
|
|
|
8413
8460
|
bubble.status = "complete";
|
|
8414
8461
|
feedback.play("messageReceived");
|
|
8415
8462
|
emitMessage(bus, options, "assistant", assistantText(bubble));
|
|
8463
|
+
flushSuggestions();
|
|
8416
8464
|
}
|
|
8417
8465
|
}
|
|
8418
8466
|
} catch (err) {
|
|
@@ -8551,12 +8599,13 @@ function App({ options, hostElement, bus }) {
|
|
|
8551
8599
|
userPrefs: persistence.loadUserPrefs()
|
|
8552
8600
|
});
|
|
8553
8601
|
setStreaming(true);
|
|
8602
|
+
pendingSuggestionsRef.current = null;
|
|
8554
8603
|
const handle = transport.sendMessage(body);
|
|
8555
8604
|
setActiveCancel(() => handle.cancel);
|
|
8556
8605
|
setActiveDetach(() => handle.detach);
|
|
8557
8606
|
try {
|
|
8558
8607
|
for await (const evt of handle.iter) {
|
|
8559
|
-
if (adoptConversationRebind(evt.chunk)) continue;
|
|
8608
|
+
if (adoptConversationRebind(evt.chunk) || captureSuggestions(evt.chunk)) continue;
|
|
8560
8609
|
reducer.apply(evt.chunk);
|
|
8561
8610
|
if (evt.chunk.type === "finish" && evt.chunk.canContinue === false) {
|
|
8562
8611
|
setCanSend(false);
|
|
@@ -8575,6 +8624,7 @@ function App({ options, hostElement, bus }) {
|
|
|
8575
8624
|
assistantMsg.status = "complete";
|
|
8576
8625
|
feedback.play("messageReceived");
|
|
8577
8626
|
emitMessage(bus, options, "assistant", assistantText(assistantMsg));
|
|
8627
|
+
flushSuggestions();
|
|
8578
8628
|
}
|
|
8579
8629
|
} catch (error) {
|
|
8580
8630
|
if (isAbortError(error)) {
|