@eshal-bot/chat-widget 0.1.107 → 0.1.108

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.
@@ -1 +1 @@
1
- export{S as default}from"./chat-widget-index-DhZDbyb2.esm.js";import"react";import"react-dom/client";import"react-dom";import"react/jsx-runtime";
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";
@@ -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 _ref3, _parsed$Sources, _parsed$choices3;
8609
+ var _parsed$choices3;
8565
8610
  streamCompleted = true;
8566
- // Normalize Sources from stream (API may send "Sources" or "sources")
8567
- const rawSources = (_ref3 = (_parsed$Sources = parsed.Sources) !== null && _parsed$Sources !== void 0 ? _parsed$Sources : parsed.sources) !== null && _ref3 !== void 0 ? _ref3 : [];
8568
- const sources = Array.isArray(rawSources) ? rawSources.map(s => {
8569
- var _ref4, _s$source_type, _s$sourceid, _ref5, _s$source_name, _s$citation_indices;
8570
- return {
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 sources to the last assistant message if present
8619
- if (sources.length > 0) {
8620
- setMessages(prev => {
8621
- const updatedMessages = [...(prev || [])];
8622
- const lastMessage = updatedMessages[updatedMessages.length - 1];
8623
- if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'assistant') {
8624
- updatedMessages[updatedMessages.length - 1] = _objectSpread2(_objectSpread2({}, lastMessage), {}, {
8625
- sources,
8626
- // Ensure final state is fully consistent
8627
- content: finalContent,
8628
- isProcessing: false
8629
- });
8630
- }
8631
- return updatedMessages;
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