@smartspace/chat-ui 1.14.4-pr.436.a1b2dae → 1.14.4-pr.440.6667153

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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import MuiButton from '@mui/material/Button';
2
2
  import IconButton from '@mui/material/IconButton';
3
- import { Loader2, Cpu, ChevronDown, Check, Globe, Zap, SlidersHorizontal, X, Paperclip, Mic, Square, Send, Minimize2, AlertTriangle, FileImage, FileVideo, FileAudio, FileArchive, FileCode, FileSpreadsheet, Presentation, FileText, ChevronUp, Download, ShieldAlert, Copy } from 'lucide-react';
3
+ import { Loader2, Cpu, ChevronDown, Check, Globe, Zap, SlidersHorizontal, X, Paperclip, Mic, Square, Send, Minimize2, AlertTriangle, FileImage, FileVideo, FileAudio, FileArchive, FileCode, FileSpreadsheet, Presentation, FileText, ChevronUp, ExternalLink, Download, ShieldAlert, Copy } from 'lucide-react';
4
4
  import * as React8 from 'react';
5
5
  import { createContext, forwardRef, useImperativeHandle, useRef, useState, useEffect, useMemo, useCallback, useContext, useSyncExternalStore } from 'react';
6
6
  import { createPortal } from 'react-dom';
@@ -365,6 +365,19 @@ var MessageValueType = /* @__PURE__ */ ((MessageValueType2) => {
365
365
  MessageValueType2["INPUT"] = "Input";
366
366
  return MessageValueType2;
367
367
  })(MessageValueType || {});
368
+ var MessageResponseSourceType = /* @__PURE__ */ ((MessageResponseSourceType2) => {
369
+ MessageResponseSourceType2["BlobInternal"] = "BlobInternal";
370
+ MessageResponseSourceType2["WebExternal"] = "WebExternal";
371
+ MessageResponseSourceType2["File"] = "File";
372
+ MessageResponseSourceType2["URL"] = "URL";
373
+ return MessageResponseSourceType2;
374
+ })(MessageResponseSourceType || {});
375
+ var MessageAttribution = /* @__PURE__ */ ((MessageAttribution2) => {
376
+ MessageAttribution2["Supported"] = "supported";
377
+ MessageAttribution2["Partial"] = "partial";
378
+ MessageAttribution2["Unsupported"] = "unsupported";
379
+ return MessageAttribution2;
380
+ })(MessageAttribution || {});
368
381
 
369
382
  // src/domains/threads/queryKeys.ts
370
383
  var THREAD_LIST_PAGE_SIZE = 30;
@@ -18944,6 +18957,79 @@ var getMessageErrorText = (error) => {
18944
18957
  }
18945
18958
  return STATUS_CODE_TEXT[error.code] ?? GENERIC_ERROR_TEXT;
18946
18959
  };
18960
+ var FileInfoSchema = z.object({
18961
+ id: z.string(),
18962
+ name: z.string()
18963
+ });
18964
+ z.object({
18965
+ workspaceId: z.string().optional(),
18966
+ threadId: z.string().optional()
18967
+ });
18968
+
18969
+ // src/domains/messages/schemas.ts
18970
+ var MessageResponseSourceSchema = z.object({
18971
+ index: z.number(),
18972
+ datasetItemId: z.string().optional(),
18973
+ containerItemId: z.string().nullish(),
18974
+ flowRunId: z.string().optional(),
18975
+ file: FileInfoSchema.nullish(),
18976
+ url: z.string().nullish(),
18977
+ sourceType: z.nativeEnum(MessageResponseSourceType),
18978
+ // WS3c citation grounding (additive; absent on older responses).
18979
+ uri: z.string().nullish(),
18980
+ citedText: z.string().nullish(),
18981
+ attribution: z.nativeEnum(MessageAttribution).nullish(),
18982
+ // Where the cited item lives at its source (SharePoint web link, HubSpot record page).
18983
+ // Distinct from `url` (the source *is* that URL): this rides File sources so the card
18984
+ // can offer "open at source" beside the download of our copy. Absent when unknown.
18985
+ webUrl: z.string().nullish()
18986
+ });
18987
+ var MessageResponseSchema = z.object({
18988
+ content: z.string(),
18989
+ messageId: z.string(),
18990
+ sources: z.array(MessageResponseSourceSchema).nullish(),
18991
+ isReplying: z.boolean().nullish().default(false),
18992
+ requestedJsonSchema: z.string().nullish()
18993
+ });
18994
+ var MessageErrorMessageSchema = z.object({
18995
+ code: z.number(),
18996
+ // Stable machine-readable category (e.g. "llm.rate_limit"). Accept both
18997
+ // spellings: app-api serialises camelCase, the ai-api origin field is
18998
+ // snake_case — the mapper coalesces them.
18999
+ errorCode: z.string().nullish(),
19000
+ error_code: z.string().nullish(),
19001
+ message: z.string().nullish(),
19002
+ data: z.string().nullish(),
19003
+ blockId: z.string().nullish()
19004
+ });
19005
+ var MessageSchema = z.object({
19006
+ id: z.string().nullish(),
19007
+ createdAt: DateFromApi,
19008
+ createdBy: z.string().nullish(),
19009
+ hasComments: z.boolean().default(false),
19010
+ createdByUserId: z.string().nullish(),
19011
+ messageThreadId: z.string().nullish(),
19012
+ errors: z.array(MessageErrorMessageSchema).nullish(),
19013
+ values: z.array(
19014
+ z.object({
19015
+ id: z.string(),
19016
+ name: z.string(),
19017
+ type: z.nativeEnum(MessageValueType),
19018
+ value: z.any(),
19019
+ // Can be string (for Output), array (for Input), or object (for Variables)
19020
+ channels: z.record(z.string(), z.number()),
19021
+ createdAt: DateFromApi,
19022
+ createdBy: z.string(),
19023
+ createdByUserId: z.string().nullish()
19024
+ })
19025
+ ).nullish(),
19026
+ optimistic: z.boolean().optional().default(false)
19027
+ });
19028
+ z.object({
19029
+ text: z.string().nullish(),
19030
+ image: FileInfoSchema.nullish()
19031
+ });
19032
+ z.array(MessageSchema);
18947
19033
 
18948
19034
  // src/domains/messages/statuses.ts
18949
19035
  var asRecord = (value) => {
@@ -19550,6 +19636,7 @@ function ChatMessageSources({
19550
19636
  /* @__PURE__ */ jsx(SectionLabel, { children: "Files" }),
19551
19637
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: fileSources.map((source) => {
19552
19638
  const Icon = getFileIcon3(source.file.name);
19639
+ const sourceHref = source.webUrl ? getSafeUrl(source.webUrl) : null;
19553
19640
  if (!openIndexes.has(source.index)) {
19554
19641
  return /* @__PURE__ */ jsxs(
19555
19642
  "button",
@@ -19598,19 +19685,36 @@ function ChatMessageSources({
19598
19685
  )
19599
19686
  ] }),
19600
19687
  /* @__PURE__ */ jsx(CitedQuote, { text: source.citedText }),
19601
- /* @__PURE__ */ jsxs(
19602
- "button",
19603
- {
19604
- type: "button",
19605
- onClick: () => downloadFileMutation.mutate(source.file),
19606
- disabled: downloadFileMutation.isPending,
19607
- className: "inline-flex w-fit items-center gap-1 rounded-md border border-border/60 px-2 py-1 text-xs font-medium text-foreground transition-colors hover:bg-muted/40 disabled:cursor-not-allowed disabled:opacity-50",
19608
- children: [
19609
- /* @__PURE__ */ jsx(Download, { className: "h-3 w-3" }),
19610
- "Download"
19611
- ]
19612
- }
19613
- )
19688
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
19689
+ sourceHref && /* @__PURE__ */ jsxs(
19690
+ "a",
19691
+ {
19692
+ href: sourceHref,
19693
+ target: "_blank",
19694
+ rel: "noreferrer",
19695
+ title: source.webUrl ?? void 0,
19696
+ className: "inline-flex w-fit items-center gap-1 rounded-md border border-border/60 px-2 py-1 text-xs font-medium text-foreground no-underline transition-colors hover:bg-muted/40",
19697
+ children: [
19698
+ /* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3" }),
19699
+ "Open in ",
19700
+ getHost(sourceHref)
19701
+ ]
19702
+ }
19703
+ ),
19704
+ /* @__PURE__ */ jsxs(
19705
+ "button",
19706
+ {
19707
+ type: "button",
19708
+ onClick: () => downloadFileMutation.mutate(source.file),
19709
+ disabled: downloadFileMutation.isPending,
19710
+ className: "inline-flex w-fit items-center gap-1 rounded-md border border-border/60 px-2 py-1 text-xs font-medium text-foreground transition-colors hover:bg-muted/40 disabled:cursor-not-allowed disabled:opacity-50",
19711
+ children: [
19712
+ /* @__PURE__ */ jsx(Download, { className: "h-3 w-3" }),
19713
+ "Download"
19714
+ ]
19715
+ }
19716
+ )
19717
+ ] })
19614
19718
  ]
19615
19719
  },
19616
19720
  `${source.file.id}-${source.index}`
@@ -19814,6 +19918,10 @@ function coerceSources(x) {
19814
19918
  if (!Array.isArray(x)) return [];
19815
19919
  return x.filter(isMessageResponseSource);
19816
19920
  }
19921
+ var ENVELOPE_KEYS = Object.keys(MessageResponseSchema.shape);
19922
+ function isResponseEnvelope(keys2) {
19923
+ return keys2.length > 0 && keys2.every((key) => ENVELOPE_KEYS.includes(key));
19924
+ }
19817
19925
  var MessageItem = ({
19818
19926
  message,
19819
19927
  isLive = false
@@ -19921,9 +20029,16 @@ var MessageItem = ({
19921
20029
  });
19922
20030
  } else if (name === "response" && typeof v.value === "object" && v.value !== null && !Array.isArray(v.value)) {
19923
20031
  const resp = v.value;
19924
- const isContentPart = "text" in resp || "image" in resp;
19925
- pushContent(groupContent, isContentPart ? resp : resp.content);
19926
- groupSources = coerceSources(resp.sources);
20032
+ const keys2 = Object.keys(resp);
20033
+ const isEnvelope = isResponseEnvelope(keys2);
20034
+ if ("sources" in resp && (isEnvelope || "text" in resp || "image" in resp)) {
20035
+ groupSources = coerceSources(resp.sources);
20036
+ }
20037
+ if (isEnvelope) {
20038
+ pushContent(groupContent, resp.content);
20039
+ } else if (keys2.length > 0) {
20040
+ pushContent(groupContent, resp);
20041
+ }
19927
20042
  } else {
19928
20043
  pushContent(groupContent, v.value);
19929
20044
  }