@smartspace/chat-ui 1.13.1-dev.c6d0f32 → 1.13.1-dev.e6bbec9

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
@@ -4,7 +4,7 @@ import { Loader2, Check, X, Paperclip, ArrowBigUp, Minimize2, AlertTriangle, Fil
4
4
  import * as React8 from 'react';
5
5
  import { createContext, forwardRef, useImperativeHandle, useRef, useState, useEffect, useMemo, useCallback, createElement, useContext } from 'react';
6
6
  import { createPortal } from 'react-dom';
7
- import { useQuery, queryOptions, useQueryClient, useMutation } from '@tanstack/react-query';
7
+ import { useQuery, queryOptions, useQueryClient, useMutation, skipToken } from '@tanstack/react-query';
8
8
  import { toast } from 'sonner';
9
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
10
  import { Editor, rootCtx, defaultValueCtx, editorViewOptionsCtx, editorViewCtx, serializerCtx, SchemaReady, nodeViewCtx, markViewCtx, schemaCtx, prosePluginsCtx, nodesCtx } from '@milkdown/core';
@@ -127,6 +127,7 @@ var filesKeys = {
127
127
  var useFileMutations = (scope) => {
128
128
  const { workspaceId, threadId } = scope;
129
129
  const service = useChatService();
130
+ const queryClient = useQueryClient();
130
131
  const [uploadedFiles, setUploadedFiles] = useState([]);
131
132
  const [fileProgress, setFileProgress] = useState({});
132
133
  const clearUploadState = useCallback(() => {
@@ -185,11 +186,19 @@ var useFileMutations = (scope) => {
185
186
  status: uploadedFiles.some((f) => f.name === file.name) ? "done" : "uploading"
186
187
  }));
187
188
  const getFileBlobUrl = useCallback(
188
- async (id) => {
189
- const blob = await service.downloadFile(id, { workspaceId, threadId });
190
- return URL.createObjectURL(blob);
191
- },
192
- [service, workspaceId, threadId]
189
+ (id) => queryClient.fetchQuery({
190
+ queryKey: filesKeys.downloadBlob(id),
191
+ queryFn: async () => {
192
+ const blob = await service.downloadFile(id, {
193
+ workspaceId,
194
+ threadId
195
+ });
196
+ return URL.createObjectURL(blob);
197
+ },
198
+ staleTime: Infinity,
199
+ gcTime: Infinity
200
+ }),
201
+ [queryClient, service, workspaceId, threadId]
193
202
  );
194
203
  return {
195
204
  uploadFilesMutation,
@@ -871,7 +880,7 @@ var ssImageView = $view(ssImageNode, (ctx) => (node2) => {
871
880
  removeBtn.type = "button";
872
881
  removeBtn.className = "ss-attach__remove";
873
882
  removeBtn.setAttribute("aria-label", "Remove image");
874
- removeBtn.textContent = "\xD7";
883
+ removeBtn.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>';
875
884
  removeBtn.addEventListener("mousedown", (e) => {
876
885
  e.preventDefault();
877
886
  e.stopPropagation();
@@ -890,16 +899,19 @@ var ssImageView = $view(ssImageNode, (ctx) => (node2) => {
890
899
  }
891
900
  });
892
901
  img.style.background = "rgba(0,0,0,0.04)";
902
+ img.style.visibility = "hidden";
893
903
  let hasSetRealSrc = false;
894
904
  img.addEventListener("load", () => {
895
905
  if (!hasSetRealSrc) return;
896
906
  spinner.remove();
897
907
  img.style.background = "";
908
+ img.style.visibility = "";
898
909
  });
899
910
  img.addEventListener("error", () => {
900
911
  if (!hasSetRealSrc) return;
901
912
  spinner.remove();
902
913
  img.style.background = "rgba(255,0,0,0.06)";
914
+ img.style.visibility = "";
903
915
  });
904
916
  try {
905
917
  const anyWin = window;
@@ -3221,7 +3233,20 @@ var threadsKeys = {
3221
3233
  };
3222
3234
 
3223
3235
  // src/domains/threads/cache.ts
3236
+ function isStaleSummary(incoming, existing) {
3237
+ if (!existing) return false;
3238
+ if (typeof existing.summaryEmittedAt !== "number") return false;
3239
+ if (typeof incoming.summaryEmittedAt !== "number") return false;
3240
+ if (incoming.summaryEmittedAt >= existing.summaryEmittedAt) return false;
3241
+ return existing.isFlowRunning === false && incoming.isFlowRunning === true;
3242
+ }
3224
3243
  function applyThreadToCache(qc, thread) {
3244
+ const existingDetail = qc.getQueryData(
3245
+ threadsKeys.detail(thread.workSpaceId, thread.id)
3246
+ );
3247
+ if (isStaleSummary(thread, existingDetail)) {
3248
+ return false;
3249
+ }
3225
3250
  qc.setQueryData(
3226
3251
  threadsKeys.detail(thread.workSpaceId, thread.id),
3227
3252
  (old) => ({ ...old ?? thread, ...thread })
@@ -3242,6 +3267,7 @@ function applyThreadToCache(qc, thread) {
3242
3267
  if (!page?.data) return page;
3243
3268
  const idx2 = page.data.findIndex((t) => t.id === thread.id);
3244
3269
  if (idx2 === -1) return page;
3270
+ if (isStaleSummary(thread, page.data[idx2])) return page;
3245
3271
  changed = true;
3246
3272
  foundInList = true;
3247
3273
  const nextData2 = page.data.slice();
@@ -3254,6 +3280,7 @@ function applyThreadToCache(qc, thread) {
3254
3280
  if (!list2.data) return old;
3255
3281
  const idx = list2.data.findIndex((t) => t.id === thread.id);
3256
3282
  if (idx === -1) return old;
3283
+ if (isStaleSummary(thread, list2.data[idx])) return old;
3257
3284
  foundInList = true;
3258
3285
  const nextData = list2.data.slice();
3259
3286
  nextData[idx] = { ...nextData[idx], ...thread };
@@ -3310,7 +3337,7 @@ function utcDate(value) {
3310
3337
  }
3311
3338
  return new Date(value);
3312
3339
  }
3313
- z.preprocess((val) => {
3340
+ var DateFromApi = z.preprocess((val) => {
3314
3341
  if (typeof val === "string" && !hasTimezone(val)) {
3315
3342
  return val + "Z";
3316
3343
  }
@@ -3323,36 +3350,40 @@ var {
3323
3350
  messageThreadsGetMessageThreadWorkspacesWorkspaceIdMessagethreadsIdResponse: threadResponseSchema
3324
3351
  } = ChatZod;
3325
3352
  function mapThreadDtoToModel(dto) {
3353
+ const lastUpdatedAt = utcDate(dto.lastUpdatedAt);
3326
3354
  return {
3327
3355
  id: dto.id,
3328
3356
  createdAt: utcDate(dto.createdAt),
3329
3357
  createdBy: dto.createdBy ?? "",
3330
3358
  createdByUserId: dto.createdByUserId,
3331
3359
  isFlowRunning: dto.isFlowRunning,
3332
- lastUpdatedAt: utcDate(dto.lastUpdatedAt),
3360
+ lastUpdatedAt,
3333
3361
  lastUpdatedByUserId: dto.lastUpdatedByUserId,
3334
3362
  name: dto.name ?? "",
3335
3363
  totalMessages: dto.totalMessages,
3336
3364
  pinned: dto.favorited,
3337
- workSpaceId: dto.workSpaceId
3365
+ workSpaceId: dto.workSpaceId,
3366
+ summaryEmittedAt: lastUpdatedAt.getTime()
3338
3367
  };
3339
3368
  }
3340
3369
  function mapThreadsResponseDtoToModel(dto) {
3341
3370
  return { data: dto.data.map(mapThreadDtoToModel), total: dto.total };
3342
3371
  }
3343
3372
  function mapSignalRThreadSummaryToModel(summary) {
3373
+ const lastUpdatedAt = utcDate(summary.lastUpdatedAt);
3344
3374
  return {
3345
3375
  id: summary.id,
3346
3376
  createdAt: utcDate(summary.createdAt),
3347
3377
  createdBy: summary.createdBy ?? "",
3348
3378
  createdByUserId: summary.createdByUserId,
3349
3379
  isFlowRunning: summary.isFlowRunning,
3350
- lastUpdatedAt: utcDate(summary.lastUpdatedAt),
3380
+ lastUpdatedAt,
3351
3381
  lastUpdatedByUserId: summary.lastUpdatedByUserId,
3352
3382
  name: summary.name ?? "",
3353
3383
  totalMessages: summary.totalMessages,
3354
3384
  pinned: summary.favorited,
3355
- workSpaceId: summary.workSpaceId
3385
+ workSpaceId: summary.workSpaceId,
3386
+ summaryEmittedAt: lastUpdatedAt.getTime()
3356
3387
  };
3357
3388
  }
3358
3389
  var threadDetailOptions = ({
@@ -3406,11 +3437,12 @@ var useThread = ({
3406
3437
  });
3407
3438
  };
3408
3439
  var useThreadIsRunning = (workspaceId, threadId) => {
3409
- const { data: thread } = useThread({
3410
- workspaceId: workspaceId ?? "",
3411
- threadId: threadId ?? "",
3412
- enabled: !!workspaceId && !!threadId
3440
+ const queryClient = useQueryClient();
3441
+ const { data: detailThread } = useQuery({
3442
+ queryKey: threadsKeys.detail(workspaceId ?? "", threadId ?? ""),
3443
+ queryFn: skipToken
3413
3444
  });
3445
+ const listThread = workspaceId && threadId ? getThreadPlaceholderFromListCache(queryClient, workspaceId, threadId) : void 0;
3414
3446
  const { data: optimistic } = useQuery({
3415
3447
  queryKey: threadsKeys.optimisticRunning(threadId ?? ""),
3416
3448
  queryFn: () => false,
@@ -3418,7 +3450,7 @@ var useThreadIsRunning = (workspaceId, threadId) => {
3418
3450
  staleTime: Infinity,
3419
3451
  enabled: !!threadId
3420
3452
  });
3421
- return !!optimistic || !!thread?.isFlowRunning;
3453
+ return !!optimistic || !!(detailThread ?? listThread)?.isFlowRunning;
3422
3454
  };
3423
3455
 
3424
3456
  // src/domains/messages/enums.ts
@@ -3444,6 +3476,15 @@ var messagesMutationsKeys = {
3444
3476
  };
3445
3477
 
3446
3478
  // src/domains/messages/mutations.ts
3479
+ function reconcileWithMessage(old, incoming, onDuplicate = "keep-existing") {
3480
+ const stable = old.filter((m) => !m.optimistic);
3481
+ const idx = stable.findIndex((m) => m.id === incoming.id);
3482
+ if (idx === -1) return [...stable, incoming];
3483
+ if (onDuplicate === "keep-existing") return stable;
3484
+ const copy = stable.slice();
3485
+ copy[idx] = incoming;
3486
+ return copy;
3487
+ }
3447
3488
  function useSendMessage() {
3448
3489
  const qc = useQueryClient();
3449
3490
  const { userId, displayName: userName } = useChatIdentity();
@@ -3459,10 +3500,10 @@ function useSendMessage() {
3459
3500
  if (!threadId) throw new Error("Thread ID is required");
3460
3501
  if (!workspaceId) throw new Error("Workspace ID is required");
3461
3502
  const optimistic = {
3462
- id: `temp-${Date.now()}`,
3503
+ id: `temp-${crypto.randomUUID()}`,
3463
3504
  values: [
3464
3505
  {
3465
- id: `temp-${Date.now()}-prompt`,
3506
+ id: `temp-${crypto.randomUUID()}-prompt`,
3466
3507
  type: "Input" /* INPUT */,
3467
3508
  name: "prompt",
3468
3509
  value: contentList,
@@ -3473,7 +3514,7 @@ function useSendMessage() {
3473
3514
  },
3474
3515
  ...files?.length ? [
3475
3516
  {
3476
- id: `temp-${Date.now()}-files`,
3517
+ id: `temp-${crypto.randomUUID()}-files`,
3477
3518
  type: "Input" /* INPUT */,
3478
3519
  name: "files",
3479
3520
  value: files,
@@ -3485,7 +3526,7 @@ function useSendMessage() {
3485
3526
  ] : [],
3486
3527
  ...variables && Object.keys(variables).length ? [
3487
3528
  {
3488
- id: `temp-${Date.now()}-vars`,
3529
+ id: `temp-${crypto.randomUUID()}-vars`,
3489
3530
  type: "Input" /* INPUT */,
3490
3531
  name: "variables",
3491
3532
  value: variables,
@@ -3527,13 +3568,10 @@ function useSendMessage() {
3527
3568
  toast.error("There was an error posting your message");
3528
3569
  throw err;
3529
3570
  }
3530
- qc.setQueryData(messagesKeys.list(threadId), (old = []) => {
3531
- const withoutOptimistic = old.filter((m) => !m.optimistic);
3532
- const alreadyPresent = withoutOptimistic.some(
3533
- (m) => m.id === realMessage.id
3534
- );
3535
- return alreadyPresent ? withoutOptimistic : [...withoutOptimistic, realMessage];
3536
- });
3571
+ qc.setQueryData(
3572
+ messagesKeys.list(threadId),
3573
+ (old = []) => reconcileWithMessage(old, realMessage)
3574
+ );
3537
3575
  qc.setQueryData(
3538
3576
  threadsKeys.detail(workspaceId, threadId),
3539
3577
  (old) => old ? { ...old, isFlowRunning: true } : old
@@ -3589,14 +3627,10 @@ function useAddInputToMessage() {
3589
3627
  });
3590
3628
  },
3591
3629
  onSuccess: (message, { threadId }) => {
3592
- qc.setQueryData(messagesKeys.list(threadId), (old = []) => {
3593
- const stable = old.filter((x) => !x.optimistic);
3594
- const idx = stable.findIndex((x) => x.id === message.id);
3595
- if (idx === -1) return [...stable, message];
3596
- const copy = stable.slice();
3597
- copy[idx] = message;
3598
- return copy;
3599
- });
3630
+ qc.setQueryData(
3631
+ messagesKeys.list(threadId),
3632
+ (old = []) => reconcileWithMessage(old, message, "replace")
3633
+ );
3600
3634
  },
3601
3635
  onError: (_e, { threadId }) => {
3602
3636
  qc.setQueryData(
@@ -3633,7 +3667,10 @@ var workspaceDetailOptions = ({
3633
3667
  });
3634
3668
  function useWorkspace(workspaceId) {
3635
3669
  const service = useChatService();
3636
- return useQuery(workspaceDetailOptions({ service, workspaceId }));
3670
+ return useQuery({
3671
+ ...workspaceDetailOptions({ service, workspaceId }),
3672
+ enabled: !!workspaceId
3673
+ });
3637
3674
  }
3638
3675
  var taggableUsersOptions = ({
3639
3676
  service,
@@ -3821,11 +3858,13 @@ function MessageComposer({
3821
3858
  workspaceId,
3822
3859
  threadId: isDraftThread ? void 0 : threadId
3823
3860
  });
3824
- if (typeof window !== "undefined") {
3825
- window.__ssDownloadFile = async (id) => {
3826
- return await getFileBlobUrl(id);
3861
+ useEffect(() => {
3862
+ if (typeof window === "undefined") return;
3863
+ window.__ssDownloadFile = (id) => getFileBlobUrl(id);
3864
+ return () => {
3865
+ if (window.__ssDownloadFile) delete window.__ssDownloadFile;
3827
3866
  };
3828
- }
3867
+ }, [getFileBlobUrl]);
3829
3868
  const onUploadFiles = async (files) => {
3830
3869
  const res = await uploadFilesMutation.mutateAsync(files);
3831
3870
  return res.map(({ id, name }) => ({ id, name }));
@@ -4233,43 +4272,14 @@ function MessageComposer({
4233
4272
  )
4234
4273
  ] });
4235
4274
  }
4236
- function getPromptSignature(m) {
4237
- const prompt = m.values?.find(
4238
- (v) => v.type === "Input" /* INPUT */ && v.name === "prompt"
4239
- );
4240
- if (!prompt) return null;
4241
- try {
4242
- return JSON.stringify(prompt.value ?? null);
4243
- } catch {
4244
- return null;
4245
- }
4246
- }
4247
- function mergeFetchedWithOptimistics(current, fetched) {
4248
- if (!current?.length) return fetched;
4249
- const optimistics = current.filter((m) => m.optimistic);
4250
- if (!optimistics.length) return fetched;
4251
- const fetchedPromptSigs = new Set(
4252
- fetched.map((m) => getPromptSignature(m)).filter((s2) => typeof s2 === "string" && s2.length > 0)
4253
- );
4254
- const dedupedOptimistics = optimistics.filter((o) => {
4255
- const sig = getPromptSignature(o);
4256
- if (!sig) return true;
4257
- return !fetchedPromptSigs.has(sig);
4258
- });
4259
- return [...fetched, ...dedupedOptimistics];
4260
- }
4261
4275
  var messagesListOptions = (service, threadId, opts) => queryOptions({
4262
4276
  queryKey: threadId ? messagesKeys.list(threadId) : messagesKeys.lists(),
4263
4277
  // NOTE: queryKey intentionally does NOT include opts. This keeps cache updates from
4264
4278
  // message mutations (which write to messagesKeys.list(threadId)) working.
4265
4279
  // If opts changes (e.g. user clicks "Load full history"), we manually refetch.
4266
- queryFn: async (ctx) => {
4280
+ queryFn: async () => {
4267
4281
  if (!threadId) return [];
4268
- const fetched = (await service.fetchMessages(threadId, opts)).reverse();
4269
- const current = ctx.client.getQueryData(
4270
- messagesKeys.list(threadId)
4271
- );
4272
- return mergeFetchedWithOptimistics(current, fetched);
4282
+ return (await service.fetchMessages(threadId, opts)).reverse();
4273
4283
  },
4274
4284
  retry: false,
4275
4285
  refetchOnWindowFocus: false,
@@ -4277,15 +4287,13 @@ var messagesListOptions = (service, threadId, opts) => queryOptions({
4277
4287
  // Avoid re-fetching the entire thread on every small navigation.
4278
4288
  staleTime: 3e4
4279
4289
  });
4280
- function useMessages(threadId, opts) {
4290
+ function useMessages(threadId) {
4281
4291
  const service = useChatService();
4282
4292
  const isDraft = isDraftThreadId(threadId);
4283
- const skipFetch = opts?.skipWhenNewThread || !threadId || isDraft;
4284
- const listOpts = opts?.take != null || opts?.skip != null ? { take: opts.take, skip: opts.skip } : void 0;
4285
4293
  return useQuery({
4286
- ...messagesListOptions(service, threadId, listOpts),
4287
- enabled: !opts?.skipWhenNewThread && !!threadId && !isDraft,
4288
- initialData: skipFetch ? [] : void 0
4294
+ ...messagesListOptions(service, threadId),
4295
+ enabled: !!threadId && !isDraft,
4296
+ initialData: !threadId || isDraft ? [] : void 0
4289
4297
  });
4290
4298
  }
4291
4299
 
@@ -18792,7 +18800,8 @@ function SsImage(props) {
18792
18800
  alt: alt ?? "",
18793
18801
  title,
18794
18802
  width: finalWidth,
18795
- height: finalHeight
18803
+ height: finalHeight,
18804
+ style: !resolvedSrc && !errored ? { visibility: "hidden" } : void 0
18796
18805
  }
18797
18806
  )
18798
18807
  ]
@@ -19118,14 +19127,20 @@ dayjs.extend(relativeTime);
19118
19127
  dayjs.extend(advancedFormat);
19119
19128
  function parseDateTime(date, customFormat) {
19120
19129
  const d = dayjs.utc(date).local();
19121
- return d.format(customFormat);
19130
+ if (customFormat === "X") return Math.floor(d.valueOf() / 1e3).toString();
19131
+ if (customFormat === "x") return d.valueOf().toString();
19132
+ return d.format(customFormat ?? "YYYY-MM-DD HH:mm:ss");
19133
+ }
19134
+ function parseDateTimeHuman(date) {
19135
+ return dayjs.utc(date).local().fromNow();
19122
19136
  }
19123
19137
 
19124
19138
  // src/shared/utils/userPhoto.ts
19125
19139
  function getChatApiBaseUrl() {
19126
19140
  try {
19127
19141
  const w = window;
19128
- const cfg = w?.ssconfig?.Chat_Api_Uri ?? import.meta.env.VITE_CHAT_API_URI;
19142
+ const env2 = import.meta.env;
19143
+ const cfg = w?.ssconfig?.Chat_Api_Uri ?? env2?.VITE_CHAT_API_URI;
19129
19144
  return typeof cfg === "string" && cfg.trim() ? cfg.trim() : "";
19130
19145
  } catch {
19131
19146
  return "";
@@ -19619,7 +19634,19 @@ var MessageItem = ({
19619
19634
  const t = d.getTime();
19620
19635
  return Number.isFinite(t) ? t : 0;
19621
19636
  };
19622
- const values = (message.values ?? []).slice().sort((a, b) => safeTime(a.createdAt) - safeTime(b.createdAt));
19637
+ const sortedValues = (message.values ?? []).slice().sort((a, b) => safeTime(a.createdAt) - safeTime(b.createdAt));
19638
+ const slotByKey = /* @__PURE__ */ new Map();
19639
+ const values = [];
19640
+ for (const v of sortedValues) {
19641
+ const key = `${v.name}|${v.type}`;
19642
+ const existing = slotByKey.get(key);
19643
+ if (existing !== void 0) {
19644
+ values[existing] = v;
19645
+ } else {
19646
+ slotByKey.set(key, values.length);
19647
+ values.push(v);
19648
+ }
19649
+ }
19623
19650
  const bubbles = [];
19624
19651
  let groupContent = [];
19625
19652
  let groupSources = [];
@@ -19804,6 +19831,10 @@ function MessageList({
19804
19831
  const messagesEndRef = useRef(null);
19805
19832
  const prevMessageCountRef = useRef(0);
19806
19833
  const hasInitialScrollRef = useRef(false);
19834
+ const everHadMessagesRef = useRef({
19835
+ threadId: "",
19836
+ had: false
19837
+ });
19807
19838
  const isMobile = useIsMobile();
19808
19839
  const { data: activeWorkspace } = useWorkspace(workspaceId);
19809
19840
  const [isAtBottom, setIsAtBottom] = useState(true);
@@ -19875,8 +19906,15 @@ function MessageList({
19875
19906
  ro.observe(content);
19876
19907
  return () => ro.disconnect();
19877
19908
  }, [isAtBottom, scrollToBottom]);
19909
+ const safeMessages = messages ?? [];
19910
+ if (everHadMessagesRef.current.threadId !== threadId) {
19911
+ everHadMessagesRef.current = { threadId, had: safeMessages.length > 0 };
19912
+ } else if (safeMessages.length > 0) {
19913
+ everHadMessagesRef.current.had = true;
19914
+ }
19915
+ const hadMessagesBefore = everHadMessagesRef.current.had;
19878
19916
  const isLoading = isChoosingThread || (threadPending || threadFetching) && !thread || (messagesPending || messagesFetching) && messages === void 0;
19879
- if (isLoading) {
19917
+ if (isLoading && !hadMessagesBefore) {
19880
19918
  return /* @__PURE__ */ jsx(
19881
19919
  "div",
19882
19920
  {
@@ -19892,7 +19930,7 @@ function MessageList({
19892
19930
  }
19893
19931
  );
19894
19932
  }
19895
- if (threadError || messagesError) {
19933
+ if ((threadError || messagesError) && !hadMessagesBefore) {
19896
19934
  return /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-md space-y-3", children: [
19897
19935
  threadError && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-destructive", children: [
19898
19936
  /* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4" }),
@@ -19904,8 +19942,7 @@ function MessageList({
19904
19942
  ] })
19905
19943
  ] }) });
19906
19944
  }
19907
- const safeMessages = messages ?? [];
19908
- if (safeMessages.length === 0) {
19945
+ if (safeMessages.length === 0 && !hadMessagesBefore) {
19909
19946
  return /* @__PURE__ */ jsxs("div", { className: "flex overflow-auto flex-shrink-10 flex-col p-8 text-center", children: [
19910
19947
  /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium mb-2", children: activeWorkspace?.name ?? "No messages yet" }),
19911
19948
  activeWorkspace?.firstPrompt && /* @__PURE__ */ jsx("div", { className: "max-w-3xl mx-auto p-4", children: /* @__PURE__ */ jsx(MessageMarkdown, { value: activeWorkspace.firstPrompt }) })
@@ -20146,26 +20183,28 @@ function mapWorkspaceDtoToModel(dto) {
20146
20183
  id: dto.id ?? "",
20147
20184
  name: dto.name ?? "",
20148
20185
  tags: dto.tags ?? [],
20149
- showSources: dto.showSources ?? void 0,
20150
- dataSpaces: Array.isArray(dto.dataSpaces) ? dto.dataSpaces : void 0,
20186
+ showSources: truthy(dto.showSources),
20187
+ dataSpaces: Array.isArray(dto.dataSpaces) ? dto.dataSpaces : [],
20151
20188
  createdByUserId: dto.createdByUserId ?? void 0,
20152
20189
  createdAt: dto.createdAt != null ? utcDate(dto.createdAt) : void 0,
20153
20190
  modifiedByUserId: dto.modifiedByUserId ?? void 0,
20154
20191
  modifiedAt: dto.modifiedAt != null ? utcDate(dto.modifiedAt) : void 0,
20155
20192
  favorited: truthy(dto.favorited),
20156
- summary: dto.summary ?? void 0,
20157
- firstPrompt: dto.firstPrompt ?? void 0,
20193
+ summary: dto.summary ?? "",
20194
+ firstPrompt: dto.firstPrompt ?? "",
20158
20195
  outputSchema: dto.outputSchema ?? void 0,
20159
- isPromptAndResponseLoggingEnabled: dto.isPromptAndResponseLoggingEnabled ?? void 0,
20160
20196
  inputs: dto.inputs ?? void 0,
20197
+ isPromptAndResponseLoggingEnabled: truthy(
20198
+ dto.isPromptAndResponseLoggingEnabled
20199
+ ),
20161
20200
  variables,
20162
20201
  sandBoxThreadId: dto.sandBoxThreadId ?? void 0,
20163
- supportsFiles: dto.supportsFiles ?? void 0,
20202
+ supportsFiles: truthy(dto.supportsFiles),
20164
20203
  avatarName: computeAvatar(dto.name ?? "")
20165
20204
  };
20166
20205
  }
20167
20206
  var mapWorkspacesDtoToModels = (arr) => arr.map(mapWorkspaceDtoToModel);
20168
20207
 
20169
- export { ChatProvider, ChatVariablesForm, DRAFT_THREAD_PREFIX, MarkdownEditor, MessageComposer, MessageList, MessageListSkeleton, MessageMarkdown, MessageValueType, NEW_THREAD_ID, THREAD_LIST_PAGE_SIZE, applyDeltaToMessage, applyThreadToCache, createDraftThreadId, createThreadId, downloadFileBlobOptions, filesKeys, flowRunsKeys, getModelIcon, getThreadPlaceholderFromListCache, invalidateWorkspaceThreadLists, isDraftThreadId, mapFileInfoDtoToModel, mapMentionUserDtoToModel, mapMessageDtoToModel, mapMessageErrorDtoToModel, mapMessageValueDtoToModel, mapMessagesDtoToModels, mapSignalRThreadSummaryToModel, mapThreadDtoToModel, mapThreadsResponseDtoToModel, mapWorkspaceDtoToModel, mapWorkspacesDtoToModels, markDraftThreadId, messagesKeys, messagesListOptions, messagesMutationsKeys, modelsKeys, setThreadOptimisticRunning, setThreadRunningInLists, taggableUsersOptions, threadDetailOptions, threadsKeys, unmarkDraftThreadId, useAddInputToMessage, useChatContext, useChatIdentity, useChatService, useDownloadFileBlobQuery, useFileMutations, useFlowRunVariables, useMessages, useModels, useSendMessage, useTaggableWorkspaceUsers, useThread, useThreadIsRunning, useUpdateFlowRunVariable, useWorkspace, workspaceDetailOptions, workspaceKeys };
20208
+ export { ChatProvider, ChatVariablesForm, DRAFT_THREAD_PREFIX, DateFromApi, MarkdownEditor, MessageComposer, MessageList, MessageListSkeleton, MessageMarkdown, MessageValueType, NEW_THREAD_ID, THREAD_LIST_PAGE_SIZE, applyDeltaToMessage, applyThreadToCache, createDraftThreadId, createThreadId, downloadFileBlobOptions, filesKeys, flowRunsKeys, getModelIcon, getThreadPlaceholderFromListCache, getUserPhotoUrl, invalidateWorkspaceThreadLists, isDraftThreadId, mapFileInfoDtoToModel, mapMentionUserDtoToModel, mapMessageDtoToModel, mapMessageErrorDtoToModel, mapMessageValueDtoToModel, mapMessagesDtoToModels, mapSignalRThreadSummaryToModel, mapThreadDtoToModel, mapThreadsResponseDtoToModel, mapWorkspaceDtoToModel, mapWorkspacesDtoToModels, markDraftThreadId, messagesKeys, messagesListOptions, messagesMutationsKeys, modelsKeys, parseDateTime, parseDateTimeHuman, setThreadOptimisticRunning, setThreadRunningInLists, taggableUsersOptions, threadDetailOptions, threadsKeys, unmarkDraftThreadId, useAddInputToMessage, useChatContext, useChatIdentity, useChatService, useDownloadFileBlobQuery, useFileMutations, useFlowRunVariables, useMessages, useModels, useSendMessage, useTaggableWorkspaceUsers, useThread, useThreadIsRunning, useUpdateFlowRunVariable, useWorkspace, utcDate, workspaceDetailOptions, workspaceKeys };
20170
20209
  //# sourceMappingURL=index.js.map
20171
20210
  //# sourceMappingURL=index.js.map