@eshal-bot/chat-widget 0.1.107 → 0.1.109
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-MarkdownRenderer-CL9_3M7v.esm.js → chat-widget-MarkdownRenderer-CzlXDSHK.esm.js} +1 -1
- package/dist/{chat-widget-index-DhZDbyb2.esm.js → chat-widget-index-BeabB7Lu.esm.js} +4 -4
- package/dist/chat-widget.esm.js +1 -1
- package/dist/chat-widget.js +79 -46
- package/dist/chat-widget.min.js +4 -4
- package/dist/chat-widget.umd.js +8 -8
- package/package.json +1 -1
package/dist/chat-widget.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{S as default}from"./chat-widget-index-
|
|
1
|
+
export{S as default}from"./chat-widget-index-BeabB7Lu.esm.js";import"react";import"react-dom/client";import"react-dom";import"react/jsx-runtime";
|
package/dist/chat-widget.js
CHANGED
|
@@ -7887,6 +7887,10 @@
|
|
|
7887
7887
|
// StreamEventType.FOLLOW_UP_PROMPTS (the frontend's ChatService.ts
|
|
7888
7888
|
// already handled it).
|
|
7889
7889
|
FOLLOW_UP_PROMPTS: 'follow_up_prompts',
|
|
7890
|
+
// EV-3046: preliminary sources emitted as soon as retrieval resolves
|
|
7891
|
+
// (before generation). Carries a `sources` array; the complete event's
|
|
7892
|
+
// filtered list later replaces or clears it.
|
|
7893
|
+
SOURCES: 'sources',
|
|
7890
7894
|
ERROR: 'error',
|
|
7891
7895
|
HUMAN_DECISION_REQUIRED: 'human_decision_required'
|
|
7892
7896
|
};
|
|
@@ -7981,7 +7985,8 @@
|
|
|
7981
7985
|
}
|
|
7982
7986
|
};
|
|
7983
7987
|
|
|
7984
|
-
const _excluded$1 = ["prompts"]
|
|
7988
|
+
const _excluded$1 = ["prompts"],
|
|
7989
|
+
_excluded2 = ["sourcesPreliminary"];
|
|
7985
7990
|
|
|
7986
7991
|
// ============================================================================
|
|
7987
7992
|
// TYPES & INTERFACES
|
|
@@ -8393,6 +8398,22 @@
|
|
|
8393
8398
|
* @param {ReadableStream<Uint8Array>} stream - The response stream
|
|
8394
8399
|
* @param {function} setMessages - React state setter for messages
|
|
8395
8400
|
*/
|
|
8401
|
+
// EV-3046: one source-normalization path for BOTH the early {type:'sources'}
|
|
8402
|
+
// event and the complete event (API may send "Sources" or "sources").
|
|
8403
|
+
const normalizeSources = parsed => {
|
|
8404
|
+
var _ref3, _parsed$Sources;
|
|
8405
|
+
const rawSources = (_ref3 = (_parsed$Sources = parsed.Sources) !== null && _parsed$Sources !== void 0 ? _parsed$Sources : parsed.sources) !== null && _ref3 !== void 0 ? _ref3 : [];
|
|
8406
|
+
return Array.isArray(rawSources) ? rawSources.map(s => {
|
|
8407
|
+
var _ref4, _s$source_type, _s$sourceid, _ref5, _s$source_name, _s$citation_indices;
|
|
8408
|
+
return {
|
|
8409
|
+
source_type: (_ref4 = (_s$source_type = s.source_type) !== null && _s$source_type !== void 0 ? _s$source_type : s.sourceType) !== null && _ref4 !== void 0 ? _ref4 : 'website',
|
|
8410
|
+
source_id: (_s$sourceid = s.sourceid) !== null && _s$sourceid !== void 0 ? _s$sourceid : s.source_id,
|
|
8411
|
+
source_name: (_ref5 = (_s$source_name = s.source_name) !== null && _s$source_name !== void 0 ? _s$source_name : s.sourceName) !== null && _ref5 !== void 0 ? _ref5 : '',
|
|
8412
|
+
url: s.url,
|
|
8413
|
+
citation_indices: (_s$citation_indices = s.citation_indices) !== null && _s$citation_indices !== void 0 ? _s$citation_indices : s.citationIndices
|
|
8414
|
+
};
|
|
8415
|
+
}).filter(s => s.source_id || s.url || s.source_type === 'database') : [];
|
|
8416
|
+
};
|
|
8396
8417
|
const processStream = async (stream, setMessages) => {
|
|
8397
8418
|
const updateMessage = createMessageUpdater(setMessages);
|
|
8398
8419
|
const reader = stream.getReader();
|
|
@@ -8559,31 +8580,39 @@
|
|
|
8559
8580
|
continue;
|
|
8560
8581
|
}
|
|
8561
8582
|
|
|
8583
|
+
// EV-3046: early sources strip (the Perplexity ordering).
|
|
8584
|
+
// Retrieval resolves before generation; the backend emits
|
|
8585
|
+
// {type:'sources'} as soon as the source set is known so the
|
|
8586
|
+
// user sees grounding during the pre-token wait. PRELIMINARY:
|
|
8587
|
+
// the complete event's overlap-filtered list replaces - or
|
|
8588
|
+
// clears - it.
|
|
8589
|
+
if (parsed.type === 'sources') {
|
|
8590
|
+
const early = normalizeSources(parsed);
|
|
8591
|
+
if (early.length > 0) {
|
|
8592
|
+
setMessages(prev => {
|
|
8593
|
+
const updated = [...(prev || [])];
|
|
8594
|
+
const last = updated[updated.length - 1];
|
|
8595
|
+
if ((last === null || last === void 0 ? void 0 : last.role) === 'assistant') {
|
|
8596
|
+
updated[updated.length - 1] = _objectSpread2(_objectSpread2({}, last), {}, {
|
|
8597
|
+
sources: early,
|
|
8598
|
+
sourcesPreliminary: true
|
|
8599
|
+
});
|
|
8600
|
+
}
|
|
8601
|
+
return updated;
|
|
8602
|
+
});
|
|
8603
|
+
}
|
|
8604
|
+
continue;
|
|
8605
|
+
}
|
|
8606
|
+
|
|
8562
8607
|
// Handle complete events
|
|
8563
8608
|
if (parsed.type === 'complete') {
|
|
8564
|
-
var
|
|
8609
|
+
var _parsed$choices3;
|
|
8565
8610
|
streamCompleted = true;
|
|
8566
|
-
// Normalize Sources from stream
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
source_type: (_ref4 = (_s$source_type = s.source_type) !== null && _s$source_type !== void 0 ? _s$source_type : s.sourceType) !== null && _ref4 !== void 0 ? _ref4 : 'website',
|
|
8572
|
-
source_id: (_s$sourceid = s.sourceid) !== null && _s$sourceid !== void 0 ? _s$sourceid : s.source_id,
|
|
8573
|
-
source_name: (_ref5 = (_s$source_name = s.source_name) !== null && _s$source_name !== void 0 ? _s$source_name : s.sourceName) !== null && _ref5 !== void 0 ? _ref5 : '',
|
|
8574
|
-
url: s.url,
|
|
8575
|
-
// 2026-07-14 - preserve citation_indices so
|
|
8576
|
-
// `<CitationPill>` can resolve `[N]` markers even
|
|
8577
|
-
// when N exceeds sources.length (post inline-cite
|
|
8578
|
-
// filter, the emit list is shorter than the LLM's
|
|
8579
|
-
// manifest - sources[N-1] misses on high indices).
|
|
8580
|
-
citation_indices: (_s$citation_indices = s.citation_indices) !== null && _s$citation_indices !== void 0 ? _s$citation_indices : s.citationIndices
|
|
8581
|
-
};
|
|
8582
|
-
})
|
|
8583
|
-
// Database "Data used" entries (v3 PR 8) carry neither an
|
|
8584
|
-
// id nor a url by design - keep them; drop only OTHER
|
|
8585
|
-
// source shapes that lack both (nothing to open/download).
|
|
8586
|
-
.filter(s => s.source_id || s.url || s.source_type === 'database') : [];
|
|
8611
|
+
// Normalize Sources from stream. citation_indices are
|
|
8612
|
+
// preserved so <CitationPill> resolves [N] markers past the
|
|
8613
|
+
// inline-cite filter; database "Data used" entries keep their
|
|
8614
|
+
// id/url-less shape (see normalizeSources).
|
|
8615
|
+
const sources = normalizeSources(parsed);
|
|
8587
8616
|
|
|
8588
8617
|
// Finalize the message content.
|
|
8589
8618
|
// 2026-07-28 - prefer `finalContent` FIRST. It's the backend's
|
|
@@ -8615,22 +8644,26 @@
|
|
|
8615
8644
|
// Finalize message with content + prompts + conclusionDetected
|
|
8616
8645
|
updateFinalMessage(setMessages, finalContent, metadata);
|
|
8617
8646
|
|
|
8618
|
-
// Attach
|
|
8619
|
-
|
|
8620
|
-
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8647
|
+
// Attach the AUTHORITATIVE (overlap-filtered) sources. When an
|
|
8648
|
+
// EV-3046 preliminary strip was shown, an empty final list must
|
|
8649
|
+
// CLEAR it - the filter decided nothing was actually cited.
|
|
8650
|
+
setMessages(prev => {
|
|
8651
|
+
const updatedMessages = [...(prev || [])];
|
|
8652
|
+
const lastMessage = updatedMessages[updatedMessages.length - 1];
|
|
8653
|
+
if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'assistant' && (sources.length > 0 || lastMessage.sourcesPreliminary)) {
|
|
8654
|
+
const {
|
|
8655
|
+
sourcesPreliminary
|
|
8656
|
+
} = lastMessage,
|
|
8657
|
+
rest = _objectWithoutProperties(lastMessage, _excluded2);
|
|
8658
|
+
updatedMessages[updatedMessages.length - 1] = _objectSpread2(_objectSpread2({}, rest), {}, {
|
|
8659
|
+
sources,
|
|
8660
|
+
// Ensure final state is fully consistent
|
|
8661
|
+
content: finalContent,
|
|
8662
|
+
isProcessing: false
|
|
8663
|
+
});
|
|
8664
|
+
}
|
|
8665
|
+
return updatedMessages;
|
|
8666
|
+
});
|
|
8634
8667
|
continue;
|
|
8635
8668
|
}
|
|
8636
8669
|
|
|
@@ -8690,7 +8723,7 @@
|
|
|
8690
8723
|
}
|
|
8691
8724
|
} catch (err) {
|
|
8692
8725
|
// EV-3045: the user pressed Stop (fetch aborted). The partial answer
|
|
8693
|
-
// stays on screen, finalized
|
|
8726
|
+
// stays on screen, finalized - NOT an error, NOT a retry (retrying a
|
|
8694
8727
|
// deliberately-stopped answer re-asks the question the user killed).
|
|
8695
8728
|
if (err && err.name === 'AbortError') {
|
|
8696
8729
|
if (accumulatedText.current) {
|
|
@@ -8698,7 +8731,7 @@
|
|
|
8698
8731
|
stoppedByUser: true
|
|
8699
8732
|
});
|
|
8700
8733
|
} else {
|
|
8701
|
-
// nothing arrived yet
|
|
8734
|
+
// nothing arrived yet - just drop the skeleton bubble
|
|
8702
8735
|
setMessages(prev => (prev || []).filter(msg => !msg.isProcessing));
|
|
8703
8736
|
}
|
|
8704
8737
|
return;
|
|
@@ -10154,7 +10187,7 @@
|
|
|
10154
10187
|
});
|
|
10155
10188
|
}, [getNextMessageId]);
|
|
10156
10189
|
|
|
10157
|
-
// EV-3045: Stop control. Aborting the fetch is the cancellation signal
|
|
10190
|
+
// EV-3045: Stop control. Aborting the fetch is the cancellation signal -
|
|
10158
10191
|
// the server tears the generator down on disconnect (cancelling the ADK
|
|
10159
10192
|
// run, tool calls and delegation), and persists the partial answer to
|
|
10160
10193
|
// history with a "stopped" marker. Client-side, processStream finalizes
|
|
@@ -10406,7 +10439,7 @@
|
|
|
10406
10439
|
let lastErr;
|
|
10407
10440
|
for (let attempt = 0; attempt <= STREAM_RETRY_DELAYS_MS.length; attempt += 1) {
|
|
10408
10441
|
try {
|
|
10409
|
-
// EV-3045: one controller per attempt
|
|
10442
|
+
// EV-3045: one controller per attempt - the Stop button aborts
|
|
10410
10443
|
// exactly the attempt that is streaming.
|
|
10411
10444
|
streamAbortRef.current = new AbortController();
|
|
10412
10445
|
const stream = await sendStreamingRequest(chatRequest, apiBaseUrl, getAuthToken, streamAbortRef.current.signal);
|
|
@@ -10420,7 +10453,7 @@
|
|
|
10420
10453
|
// EV-3045: a user Stop that aborted BEFORE any bytes arrived
|
|
10421
10454
|
// rejects the fetch itself with AbortError (processStream's
|
|
10422
10455
|
// own AbortError handling covers mid-stream aborts). Treat as
|
|
10423
|
-
// a successful, deliberate end
|
|
10456
|
+
// a successful, deliberate end - never retry a stopped turn.
|
|
10424
10457
|
if (err && err.name === 'AbortError') {
|
|
10425
10458
|
setMessages(prev => (prev || []).filter(msg => !msg.isProcessing));
|
|
10426
10459
|
return {
|
|
@@ -12414,7 +12447,7 @@
|
|
|
12414
12447
|
scrollLeft: "Scroll left",
|
|
12415
12448
|
scrollRight: "Scroll right",
|
|
12416
12449
|
sendMessage: "Send message",
|
|
12417
|
-
// EV-3045: Stop control aria-label. EN-only for now
|
|
12450
|
+
// EV-3045: Stop control aria-label. EN-only for now - translate() falls
|
|
12418
12451
|
// back to EN for locales without the key.
|
|
12419
12452
|
stopGenerating: "Stop generating",
|
|
12420
12453
|
startVoiceInput: "Start voice input",
|
|
@@ -17926,7 +17959,7 @@
|
|
|
17926
17959
|
}), document.body)]
|
|
17927
17960
|
}), isLoading && !isVoiceSessionActive && typeof onStopGeneration === "function" ?
|
|
17928
17961
|
/*#__PURE__*/
|
|
17929
|
-
// EV-3045: Stop replaces Send while a reply streams
|
|
17962
|
+
// EV-3045: Stop replaces Send while a reply streams - the
|
|
17930
17963
|
// convention every benchmark assistant uses. Always enabled;
|
|
17931
17964
|
// the partial answer stays on screen and in history.
|
|
17932
17965
|
jsxRuntimeExports.jsx("button", {
|