@iblai/iblai-js 2.27.0 → 2.27.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.
@@ -96838,6 +96838,9 @@ var analyticsAnalyticsFinancialStats$3 = {
96838
96838
  viewTraces: "Traces →",
96839
96839
  costByLLMFooter: "{shown} models · ranked by cost"
96840
96840
  };
96841
+ var agentSettingsLink$3 = {
96842
+ openSettings: "Open settings for {name}"
96843
+ };
96841
96844
  var analyticsAgentScopeLink$3 = {
96842
96845
  scopeToAgent: "View analytics for {name}"
96843
96846
  };
@@ -97059,6 +97062,8 @@ var analyticsAnalyticsTopicsStats$3 = {
97059
97062
  topicsRankedFooter: "{shown} of {total} topics · ranked by message volume"
97060
97063
  };
97061
97064
  var analyticsAnalyticsTranscriptsStats$3 = {
97065
+ conversationFallbackTitle: "Conversation",
97066
+ labelEmail: "Email:",
97062
97067
  anonymous: "Anonymous",
97063
97068
  justNow: "Just now",
97064
97069
  minutesAgo: "{count} min ago",
@@ -97503,6 +97508,7 @@ var careerEducationTab$3 = {
97503
97508
  nothingToShow: "Nothing to show here."
97504
97509
  };
97505
97510
  var chatHistoryChatHistoryTab$3 = {
97511
+ userSentiment: "User Sentiment",
97506
97512
  tabConversations: "Conversations",
97507
97513
  tabExports: "Exports",
97508
97514
  searchAgents: "Search Agents",
@@ -98547,6 +98553,10 @@ var disclaimersTabLabels$3 = {
98547
98553
  }
98548
98554
  };
98549
98555
  var documentSidebar$3 = {
98556
+ relevance: "Relevance {percent}%",
98557
+ relevanceHint: "How closely this passage matched the question",
98558
+ preview: "Preview",
98559
+ openInNewTab: "Open {title} in a new tab",
98550
98560
  retrievedDocuments: "Retrieved Documents"
98551
98561
  };
98552
98562
  var embedTabLabels$3 = {
@@ -98656,6 +98666,12 @@ var historyTabLabels$3 = {
98656
98666
  outOf: "out of 5"
98657
98667
  },
98658
98668
  conversation: {
98669
+ sentiment: {
98670
+ positive: "Positive",
98671
+ neutral: "Neutral",
98672
+ negative: "Negative",
98673
+ userSentiment: "User Sentiment"
98674
+ },
98659
98675
  title: "Conversation",
98660
98676
  anonymous: "Anonymous",
98661
98677
  noResponse: "No response available",
@@ -103336,6 +103352,7 @@ var en = {
103336
103352
  analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$3,
103337
103353
  analyticsAnalyticsCourses: analyticsAnalyticsCourses$3,
103338
103354
  analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$3,
103355
+ agentSettingsLink: agentSettingsLink$3,
103339
103356
  analyticsAgentScopeLink: analyticsAgentScopeLink$3,
103340
103357
  analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats$3,
103341
103358
  analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats$3,
@@ -104366,6 +104383,9 @@ var analyticsAnalyticsFinancialStats$2 = {
104366
104383
  viewTraces: "Traces →",
104367
104384
  costByLLMFooter: "{shown} modèles · classés par coût"
104368
104385
  };
104386
+ var agentSettingsLink$2 = {
104387
+ openSettings: "Ouvrir les paramètres de {name}"
104388
+ };
104369
104389
  var analyticsAgentScopeLink$2 = {
104370
104390
  scopeToAgent: "Voir les analyses de {name}"
104371
104391
  };
@@ -104587,6 +104607,8 @@ var analyticsAnalyticsTopicsStats$2 = {
104587
104607
  topicsRankedFooter: "{shown} sur {total} sujets · classés par volume de messages"
104588
104608
  };
104589
104609
  var analyticsAnalyticsTranscriptsStats$2 = {
104610
+ conversationFallbackTitle: "Conversation",
104611
+ labelEmail: "E-mail :",
104590
104612
  anonymous: "Anonyme",
104591
104613
  justNow: "À l'instant",
104592
104614
  minutesAgo: "Il y a {count} min",
@@ -105031,6 +105053,7 @@ var careerEducationTab$2 = {
105031
105053
  nothingToShow: "Rien à afficher ici."
105032
105054
  };
105033
105055
  var chatHistoryChatHistoryTab$2 = {
105056
+ userSentiment: "Sentiment de l'utilisateur",
105034
105057
  tabConversations: "Conversations",
105035
105058
  tabExports: "Exportations",
105036
105059
  searchAgents: "Rechercher des agents",
@@ -106241,6 +106264,10 @@ var disclaimersTabLabels$2 = {
106241
106264
  }
106242
106265
  };
106243
106266
  var documentSidebar$2 = {
106267
+ relevance: "Pertinence {percent}%",
106268
+ relevanceHint: "Dans quelle mesure ce passage correspond à la question",
106269
+ preview: "Aperçu",
106270
+ openInNewTab: "Ouvrir {title} dans un nouvel onglet",
106244
106271
  retrievedDocuments: "Documents récupérés"
106245
106272
  };
106246
106273
  var embedTabLabels$2 = {
@@ -106350,6 +106377,12 @@ var historyTabLabels$2 = {
106350
106377
  outOf: "sur 5"
106351
106378
  },
106352
106379
  conversation: {
106380
+ sentiment: {
106381
+ positive: "Positif",
106382
+ neutral: "Neutre",
106383
+ negative: "Négatif",
106384
+ userSentiment: "Sentiment de l'utilisateur"
106385
+ },
106353
106386
  title: "Conversation",
106354
106387
  anonymous: "Anonyme",
106355
106388
  noResponse: "Aucune réponse disponible",
@@ -110864,6 +110897,7 @@ var fr = {
110864
110897
  analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$2,
110865
110898
  analyticsAnalyticsCourses: analyticsAnalyticsCourses$2,
110866
110899
  analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$2,
110900
+ agentSettingsLink: agentSettingsLink$2,
110867
110901
  analyticsAgentScopeLink: analyticsAgentScopeLink$2,
110868
110902
  analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats$2,
110869
110903
  analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats$2,
@@ -111894,6 +111928,9 @@ var analyticsAnalyticsFinancialStats$1 = {
111894
111928
  viewTraces: "Trazas →",
111895
111929
  costByLLMFooter: "{shown} modelos · ordenados por costo"
111896
111930
  };
111931
+ var agentSettingsLink$1 = {
111932
+ openSettings: "Abrir la configuración de {name}"
111933
+ };
111897
111934
  var analyticsAgentScopeLink$1 = {
111898
111935
  scopeToAgent: "Ver analíticas de {name}"
111899
111936
  };
@@ -112115,6 +112152,8 @@ var analyticsAnalyticsTopicsStats$1 = {
112115
112152
  topicsRankedFooter: "{shown} de {total} temas · ordenados por volumen de mensajes"
112116
112153
  };
112117
112154
  var analyticsAnalyticsTranscriptsStats$1 = {
112155
+ conversationFallbackTitle: "Conversación",
112156
+ labelEmail: "Correo electrónico:",
112118
112157
  anonymous: "Anónimo",
112119
112158
  justNow: "Ahora mismo",
112120
112159
  minutesAgo: "Hace {count} min",
@@ -112559,6 +112598,7 @@ var careerEducationTab$1 = {
112559
112598
  nothingToShow: "No hay nada que mostrar aquí."
112560
112599
  };
112561
112600
  var chatHistoryChatHistoryTab$1 = {
112601
+ userSentiment: "Sentimiento del usuario",
112562
112602
  tabConversations: "Conversaciones",
112563
112603
  tabExports: "Exportaciones",
112564
112604
  searchAgents: "Buscar agentes",
@@ -113769,6 +113809,10 @@ var disclaimersTabLabels$1 = {
113769
113809
  }
113770
113810
  };
113771
113811
  var documentSidebar$1 = {
113812
+ relevance: "Relevancia {percent}%",
113813
+ relevanceHint: "Cuánto coincide este fragmento con la pregunta",
113814
+ preview: "Vista previa",
113815
+ openInNewTab: "Abrir {title} en una pestaña nueva",
113772
113816
  retrievedDocuments: "Documentos recuperados"
113773
113817
  };
113774
113818
  var embedTabLabels$1 = {
@@ -113878,6 +113922,12 @@ var historyTabLabels$1 = {
113878
113922
  outOf: "de 5"
113879
113923
  },
113880
113924
  conversation: {
113925
+ sentiment: {
113926
+ positive: "Positivo",
113927
+ neutral: "Neutral",
113928
+ negative: "Negativo",
113929
+ userSentiment: "Sentimiento del usuario"
113930
+ },
113881
113931
  title: "Conversación",
113882
113932
  anonymous: "Anónimo",
113883
113933
  noResponse: "No hay respuesta disponible",
@@ -118392,6 +118442,7 @@ var es = {
118392
118442
  analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$1,
118393
118443
  analyticsAnalyticsCourses: analyticsAnalyticsCourses$1,
118394
118444
  analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$1,
118445
+ agentSettingsLink: agentSettingsLink$1,
118395
118446
  analyticsAgentScopeLink: analyticsAgentScopeLink$1,
118396
118447
  analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats$1,
118397
118448
  analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats$1,
@@ -119422,6 +119473,9 @@ var analyticsAnalyticsFinancialStats = {
119422
119473
  viewTraces: "追踪 →",
119423
119474
  costByLLMFooter: "{shown} 个模型 · 按成本排序"
119424
119475
  };
119476
+ var agentSettingsLink = {
119477
+ openSettings: "打开 {name} 的设置"
119478
+ };
119425
119479
  var analyticsAgentScopeLink = {
119426
119480
  scopeToAgent: "查看 {name} 的分析"
119427
119481
  };
@@ -119643,6 +119697,8 @@ var analyticsAnalyticsTopicsStats = {
119643
119697
  topicsRankedFooter: "共 {total} 个主题,显示 {shown} 个 · 按消息量排序"
119644
119698
  };
119645
119699
  var analyticsAnalyticsTranscriptsStats = {
119700
+ conversationFallbackTitle: "对话",
119701
+ labelEmail: "邮箱:",
119646
119702
  anonymous: "匿名",
119647
119703
  justNow: "刚刚",
119648
119704
  minutesAgo: "{count} 分钟前",
@@ -120087,6 +120143,7 @@ var careerEducationTab = {
120087
120143
  nothingToShow: "暂无内容。"
120088
120144
  };
120089
120145
  var chatHistoryChatHistoryTab = {
120146
+ userSentiment: "用户情绪",
120090
120147
  tabConversations: "对话",
120091
120148
  tabExports: "导出",
120092
120149
  searchAgents: "搜索代理",
@@ -121297,6 +121354,10 @@ var disclaimersTabLabels = {
121297
121354
  }
121298
121355
  };
121299
121356
  var documentSidebar = {
121357
+ relevance: "相关度 {percent}%",
121358
+ relevanceHint: "该片段与问题的匹配程度",
121359
+ preview: "预览",
121360
+ openInNewTab: "在新标签页中打开 {title}",
121300
121361
  retrievedDocuments: "检索到的文档"
121301
121362
  };
121302
121363
  var embedTabLabels = {
@@ -121406,6 +121467,12 @@ var historyTabLabels = {
121406
121467
  outOf: "满分 5 分"
121407
121468
  },
121408
121469
  conversation: {
121470
+ sentiment: {
121471
+ positive: "积极",
121472
+ neutral: "中性",
121473
+ negative: "消极",
121474
+ userSentiment: "用户情绪"
121475
+ },
121409
121476
  title: "对话",
121410
121477
  anonymous: "匿名",
121411
121478
  noResponse: "暂无回复",
@@ -125920,6 +125987,7 @@ var zh = {
125920
125987
  analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail,
125921
125988
  analyticsAnalyticsCourses: analyticsAnalyticsCourses,
125922
125989
  analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats,
125990
+ agentSettingsLink: agentSettingsLink,
125923
125991
  analyticsAgentScopeLink: analyticsAgentScopeLink,
125924
125992
  analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats,
125925
125993
  analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats,
@@ -181054,7 +181122,7 @@ function MemoryTab({ org, username }) {
181054
181122
  username: editingMemory.mentorId ? currentUsername : username, memory: editingMemory, mentorId: editingMemory.mentorId }))] }));
181055
181123
  }
181056
181124
 
181057
- var _a$1;
181125
+ var _a$2;
181058
181126
  const dl = dataLayer;
181059
181127
  /**
181060
181128
  * Read a named export, tolerating absence. In real ESM a missing export reads
@@ -181087,7 +181155,7 @@ const pick = (name, fallback) => { var _a; return ((_a = read(name)) !== null &&
181087
181155
  /** Whether the resolved data-layer actually supports the chat-privacy feature. */
181088
181156
  const CHAT_PRIVACY_SUPPORTED = !!read('ChatPrivacyModeEnum') && !!read('CHAT_PRIVACY_MODES');
181089
181157
  const ChatPrivacyModeEnum = read('ChatPrivacyModeEnum');
181090
- const CHAT_PRIVACY_MODES = ((_a$1 = read('CHAT_PRIVACY_MODES')) !== null && _a$1 !== void 0 ? _a$1 : []);
181158
+ const CHAT_PRIVACY_MODES = ((_a$2 = read('CHAT_PRIVACY_MODES')) !== null && _a$2 !== void 0 ? _a$2 : []);
181091
181159
  read('chatPrivacyApiSlice');
181092
181160
  const useGetTenantChatPrivacyConfigQuery = pick('useGetTenantChatPrivacyConfigQuery', noopQuery);
181093
181161
  const useUpdateTenantChatPrivacyConfigMutation = pick('useUpdateTenantChatPrivacyConfigMutation', noopMutation);
@@ -181187,6 +181255,142 @@ function ChatPrivacyTab({ org, username }) {
181187
181255
 
181188
181256
  function c$3(e,u,c){var i=this,a=useRef(null),o=useRef(0),f=useRef(null),l=useRef([]),v=useRef(),m=useRef(),d=useRef(e),g=useRef(true);d.current=e;var p="undefined"!=typeof window,w=!u&&0!==u&&p;if("function"!=typeof e)throw new TypeError("Expected a function");u=+u||0;var s=!!(c=c||{}).leading,x=!("trailing"in c)||!!c.trailing,h="maxWait"in c,y="debounceOnServer"in c&&!!c.debounceOnServer,F=h?Math.max(+c.maxWait||0,u):null;useEffect(function(){return g.current=true,function(){g.current=false;}},[]);var A=useMemo(function(){var r=function(r){var n=l.current,t=v.current;return l.current=v.current=null,o.current=r,m.current=d.current.apply(t,n)},n=function(r,n){w&&cancelAnimationFrame(f.current),f.current=w?requestAnimationFrame(r):setTimeout(r,n);},t=function(r){if(!g.current)return false;var n=r-a.current;return !a.current||n>=u||n<0||h&&r-o.current>=F},e=function(n){return f.current=null,x&&l.current?r(n):(l.current=v.current=null,m.current)},c=function r(){var c=Date.now();if(t(c))return e(c);if(g.current){var i=u-(c-a.current),f=h?Math.min(i,F-(c-o.current)):i;n(r,f);}},A=function(){if(p||y){var e=Date.now(),d=t(e);if(l.current=[].slice.call(arguments),v.current=i,a.current=e,d){if(!f.current&&g.current)return o.current=a.current,n(c,u),s?r(a.current):m.current;if(h)return n(c,u),r(a.current)}return f.current||n(c,u),m.current}};return A.cancel=function(){f.current&&(w?cancelAnimationFrame(f.current):clearTimeout(f.current)),o.current=0,l.current=a.current=v.current=f.current=null;},A.isPending=function(){return !!f.current},A.flush=function(){return f.current?e(Date.now()):m.current},A},[s,h,u,F,x,w,p,y]);return A}function i$9(r,n){return r===n}function a$3(n,t,a){var o=i$9,f=useRef(n),l=useState({})[1],v=c$3(useCallback(function(r){f.current=r,l({});},[l]),t,a),m=useRef(n);return o(m.current,n)||(v(n),m.current=n),[f.current,v]}
181189
181257
 
181258
+ var _a$1;
181259
+ /**
181260
+ * One context object for every copy of this module. The SDK ships several
181261
+ * bundles (`index`, `next`, …) that each inline their own copy of this file,
181262
+ * so a host provider from one bundle would never reach a link rendered by
181263
+ * another (the profile modal comes from `next`; Transcripts from `index`).
181264
+ * Registering the context on `globalThis` under a well-known symbol makes
181265
+ * the copies share it — React is a single external instance, so the object
181266
+ * is interchangeable between them.
181267
+ */
181268
+ const CONTEXT_KEY = Symbol.for('@iblai/web-containers/agent-settings-launcher');
181269
+ const registry = globalThis;
181270
+ const AgentSettingsLauncherContext = (_a$1 = registry[CONTEXT_KEY]) !== null && _a$1 !== void 0 ? _a$1 : (registry[CONTEXT_KEY] = React__default.createContext(null));
181271
+ function useAgentSettingsLauncher() {
181272
+ return React__default.useContext(AgentSettingsLauncherContext);
181273
+ }
181274
+ /**
181275
+ * An agent's name, linked to its settings where the host lets this viewer
181276
+ * open them; plain text otherwise. Truncates inside an `inline-flex` box so
181277
+ * it keeps the baseline of the label beside it, and neither its clicks nor
181278
+ * its key presses reach a clickable row around it.
181279
+ */
181280
+ function AgentSettingsLink({ uniqueId, name, fallback = '-', className, testId, }) {
181281
+ var _a, _b;
181282
+ const t = useT();
181283
+ const launcher = useAgentSettingsLauncher();
181284
+ const display = name || uniqueId || fallback;
181285
+ const target = uniqueId ? { uniqueId, name: name || uniqueId } : null;
181286
+ const canOpen = !!launcher && !!target && ((_b = (_a = launcher.canOpenAgentSettings) === null || _a === void 0 ? void 0 : _a.call(launcher, target)) !== null && _b !== void 0 ? _b : true);
181287
+ if (!canOpen || !target) {
181288
+ return (jsx("span", { className: cn('inline-flex max-w-full', className), "data-testid": testId, children: jsx("span", { className: "min-w-0 truncate", children: display }) }));
181289
+ }
181290
+ return (jsx("button", { type: "button", onClick: (event) => {
181291
+ event.stopPropagation();
181292
+ launcher.openAgentSettings(target);
181293
+ },
181294
+ // Rows that open on Enter/Space would otherwise swallow the key press.
181295
+ onKeyDown: (event) => event.stopPropagation(), className: cn('inline-flex max-w-full cursor-pointer text-left hover:text-blue-600 hover:underline focus:text-blue-600 focus:outline-none', className), "aria-label": t('agentSettingsLink.openSettings', { name: display }), "data-testid": testId, children: jsx("span", { className: "min-w-0 truncate", children: display }) }));
181296
+ }
181297
+
181298
+ /**
181299
+ * A conversation's sentiment the way Analytics → Transcripts shows it: a
181300
+ * thumb and "<Sentiment> User Sentiment" — green when positive, blue when
181301
+ * negative, grey otherwise. Renders nothing when the record carries none.
181302
+ */
181303
+ function ConversationSentiment({ sentiment, labels, className, compact = false, }) {
181304
+ const key = (sentiment !== null && sentiment !== void 0 ? sentiment : '').trim().toLowerCase();
181305
+ if (!key)
181306
+ return null;
181307
+ const Icon = key === 'negative' ? ThumbsDown : ThumbsUp;
181308
+ const tone = key === 'negative' ? 'text-blue-600' : key === 'positive' ? 'text-green-600' : 'text-gray-600';
181309
+ const word = key === 'negative'
181310
+ ? labels.negative
181311
+ : key === 'positive'
181312
+ ? labels.positive
181313
+ : key === 'neutral'
181314
+ ? labels.neutral
181315
+ : key.charAt(0).toUpperCase() + key.slice(1);
181316
+ const text = `${word} ${labels.userSentiment}`;
181317
+ if (compact) {
181318
+ return (jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsxs("span", { className: cn('inline-flex cursor-default items-center', tone, className), "data-testid": "conversation-sentiment", "data-sentiment": key, "data-compact": "true", tabIndex: 0, children: [jsx(Icon, { className: "h-4 w-4", "aria-hidden": "true" }), jsx("span", { className: "sr-only", children: text })] }) }), jsx(TooltipContent, { className: "ibl-tooltip-content", children: text })] }) }));
181319
+ }
181320
+ return (jsxs("div", { className: cn('flex items-center gap-1 text-sm', tone, className), "data-testid": "conversation-sentiment", "data-sentiment": key, children: [jsx(Icon, { className: "h-4 w-4", "aria-hidden": "true" }), jsxs("span", { children: [word, " ", labels.userSentiment] })] }));
181321
+ }
181322
+
181323
+ /**
181324
+ * A conversation's topic names, whatever shape the endpoint uses: analytics
181325
+ * returns `["Biology"]`, the chat-history endpoints `[{ name: "Biology" }]`.
181326
+ * Blank entries are dropped and repeats collapsed; order is kept.
181327
+ */
181328
+ function conversationTopics(topics) {
181329
+ if (!Array.isArray(topics))
181330
+ return [];
181331
+ const names = [];
181332
+ for (const topic of topics) {
181333
+ const raw = typeof topic === 'string'
181334
+ ? topic
181335
+ : topic && typeof topic === 'object'
181336
+ ? topic.name
181337
+ : undefined;
181338
+ const name = typeof raw === 'string' ? raw.trim() : '';
181339
+ if (name && !names.includes(name))
181340
+ names.push(name);
181341
+ }
181342
+ return names;
181343
+ }
181344
+
181345
+ /** A conversation's topics as the chips Analytics → Transcripts draws. */
181346
+ function ConversationTopics({ topics, className, children, leading, }) {
181347
+ const names = conversationTopics(topics);
181348
+ if (names.length === 0 && !children && !leading)
181349
+ return null;
181350
+ return (jsxs("div", { className: cn('flex flex-wrap items-center gap-2', className), "data-testid": "conversation-topics", children: [leading, names.map((name) => (jsx("span", { className: "rounded-[5px] bg-gray-100 px-3 py-1 text-xs text-gray-600", children: name }, name))), children] }));
181351
+ }
181352
+
181353
+ const clean$2 = (value) => typeof value === 'string' && value.trim() ? value.trim() : undefined;
181354
+ /** The first human turn of a conversation, from an array or its JSON string form. */
181355
+ function firstHumanMessage(messages) {
181356
+ let turns = messages;
181357
+ if (typeof turns === 'string') {
181358
+ try {
181359
+ turns = JSON.parse(turns);
181360
+ }
181361
+ catch (_a) {
181362
+ return undefined;
181363
+ }
181364
+ }
181365
+ if (!Array.isArray(turns))
181366
+ return undefined;
181367
+ const first = turns[0];
181368
+ return clean$2(first === null || first === void 0 ? void 0 : first.human);
181369
+ }
181370
+ /**
181371
+ * One title for a conversation, on every surface: the backend's `title` when
181372
+ * it has one, else `first_user_message`, else the first human turn, else the
181373
+ * caller's fallback label. Endpoints differ in which of these they return;
181374
+ * this keeps Transcripts and both History tabs naming a conversation alike.
181375
+ */
181376
+ function conversationTitle(source, fallback) {
181377
+ var _a, _b, _c;
181378
+ return ((_c = (_b = (_a = clean$2(source === null || source === void 0 ? void 0 : source.title)) !== null && _a !== void 0 ? _a : clean$2(source === null || source === void 0 ? void 0 : source.first_user_message)) !== null && _b !== void 0 ? _b : firstHumanMessage(source === null || source === void 0 ? void 0 : source.messages)) !== null && _c !== void 0 ? _c : fallback);
181379
+ }
181380
+
181381
+ /**
181382
+ * A conversation's timestamp the way every history surface shows it:
181383
+ * "Sep 4, 2026, 3:56 PM · 21 days ago". Empty for a missing or invalid value.
181384
+ */
181385
+ const formatSessionDate = (value) => {
181386
+ if (!value)
181387
+ return '';
181388
+ const date = new Date(value);
181389
+ if (Number.isNaN(date.getTime()))
181390
+ return '';
181391
+ return `${format$1(date, 'MMM d, yyyy, h:mm a')} · ${formatDistanceToNow(date, { addSuffix: true })}`;
181392
+ };
181393
+
181190
181394
  const offsetFormatCache = {};
181191
181395
  const offsetCache = {};
181192
181396
 
@@ -220351,14 +220555,6 @@ function stripMarkdown$1(text) {
220351
220555
  * When a conversation happened: the calendar date and time, followed by the
220352
220556
  * relative "x ago" so both the exact day and recency read at a glance.
220353
220557
  */
220354
- const formatSessionDate = (value) => {
220355
- if (!value)
220356
- return '';
220357
- const date = new Date(value);
220358
- if (Number.isNaN(date.getTime()))
220359
- return '';
220360
- return `${format$1(date, 'MMM d, yyyy, h:mm a')} · ${formatDistanceToNow(date, { addSuffix: true })}`;
220361
- };
220362
220558
  /**
220363
220559
  * The list endpoint may serialize `messages` as a JSON string while the detail
220364
220560
  * endpoint returns a proper array; accept either shape.
@@ -220405,11 +220601,6 @@ function downloadTextFile(filename, content, mime) {
220405
220601
  document.body.removeChild(link);
220406
220602
  URL.revokeObjectURL(blobUrl);
220407
220603
  }
220408
- const SENTIMENT_CLASSES = {
220409
- positive: 'bg-green-100 text-green-800 border-transparent',
220410
- negative: 'bg-red-100 text-red-800 border-transparent',
220411
- neutral: 'bg-gray-100 text-gray-600 border-transparent',
220412
- };
220413
220604
  /**
220414
220605
  * Agent scope filter — the same inline searchable autocomplete the Billing
220415
220606
  * tab's Agent Limits section and the Memory tab use (`SearchSelect`): type to
@@ -220473,7 +220664,7 @@ function ConversationMessages({ messages, username, agent, fallbackEmail, }) {
220473
220664
  name: file.name,
220474
220665
  contentType: file.content_type,
220475
220666
  url: file.url,
220476
- })) })] })] }), jsxs("div", { className: "flex items-start gap-3 border-t border-gray-200 pt-4", children: [jsx(AgentMessageAvatar, { agent: agent, fallback: t('chatHistoryChatHistoryTab.aiAvatarLabel') }), jsxs("div", { className: "min-w-0 flex-1 overflow-x-hidden", children: [jsx("div", { className: "font-medium text-gray-700", children: agent.name }), jsx(Markdown, { className: "mt-1 text-sm text-gray-500", children: (_c = message.ai) !== null && _c !== void 0 ? _c : '' })] })] })] }, index));
220667
+ })) })] })] }), jsxs("div", { className: "flex items-start gap-3 border-t border-gray-200 pt-4", children: [jsx(AgentMessageAvatar, { agent: agent, fallback: t('chatHistoryChatHistoryTab.aiAvatarLabel') }), jsxs("div", { className: "min-w-0 flex-1 overflow-x-hidden", children: [jsx(AgentSettingsLink, { uniqueId: agent.uniqueId, name: agent.name, className: "font-medium text-gray-700" }), jsx(Markdown, { className: "mt-1 text-sm text-gray-500", children: (_c = message.ai) !== null && _c !== void 0 ? _c : '' })] })] })] }, index));
220477
220668
  }) }));
220478
220669
  }
220479
220670
  /**
@@ -220482,12 +220673,11 @@ function ConversationMessages({ messages, username, agent, fallbackEmail, }) {
220482
220673
  * download of just this conversation.
220483
220674
  */
220484
220675
  function ConversationPreview({ org, username, session, agent, }) {
220485
- var _a;
220486
220676
  const t = useT();
220487
220677
  const inlineMessages = normalizeMessages(session.messages);
220488
220678
  const { data: detail, isLoading } = useGetUserChatHistorySessionQuery({ org, userId: username, sessionId: session.id }, { skip: inlineMessages.length > 0 });
220489
220679
  const messages = inlineMessages.length > 0 ? inlineMessages : normalizeMessages(detail === null || detail === void 0 ? void 0 : detail.messages);
220490
- const title = stripMarkdown$1(session.title || ((_a = messages[0]) === null || _a === void 0 ? void 0 : _a.human) || t('chatHistoryChatHistoryTab.conversation'));
220680
+ const title = stripMarkdown$1(conversationTitle({ title: session.title, first_user_message: session.first_user_message, messages }, t('chatHistoryChatHistoryTab.conversation')));
220491
220681
  if (isLoading) {
220492
220682
  return (jsx("div", { className: "flex items-center justify-center py-10", children: jsx(Spinner, {}) }));
220493
220683
  }
@@ -220524,6 +220714,7 @@ function ChatHistoryTab({ org, username }) {
220524
220714
  var _a;
220525
220715
  const known = agentInfo[session.mentor];
220526
220716
  return {
220717
+ uniqueId: session.mentor || undefined,
220527
220718
  name: session.mentor_name ||
220528
220719
  (known === null || known === void 0 ? void 0 : known.name) ||
220529
220720
  ((_a = filters.agent) === null || _a === void 0 ? void 0 : _a.name) ||
@@ -220536,6 +220727,12 @@ function ChatHistoryTab({ org, username }) {
220536
220727
  const sentimentOptions = ((_a = filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.sentiment) === null || _a === void 0 ? void 0 : _a.length)
220537
220728
  ? filterOptions.sentiment
220538
220729
  : DEFAULT_SENTIMENTS;
220730
+ const sentimentLabels = React__default.useMemo(() => ({
220731
+ positive: t('chatHistoryChatHistoryTab.positive'),
220732
+ neutral: t('chatHistoryChatHistoryTab.neutral'),
220733
+ negative: t('chatHistoryChatHistoryTab.negative'),
220734
+ userSentiment: t('chatHistoryChatHistoryTab.userSentiment'),
220735
+ }), [t]);
220539
220736
  const sentimentLabel = React__default.useCallback((value) => {
220540
220737
  const key = value.toLowerCase();
220541
220738
  if (key === 'positive')
@@ -220559,22 +220756,18 @@ function ChatHistoryTab({ org, username }) {
220559
220756
  : t('chatHistoryChatHistoryTab.export')] }) })] }) }), isLoading && (jsx("div", { className: "flex w-full flex-1 items-center justify-center py-10", children: jsx(Spinner, {}) })), isError && !isLoading && (jsx("div", { className: "flex flex-1 flex-col items-center justify-center py-6", children: jsx("p", { className: "text-sm text-gray-600", children: isForbidden
220560
220757
  ? t('chatHistoryChatHistoryTab.forbidden')
220561
220758
  : t('chatHistoryChatHistoryTab.loadFailed') }) })), sessions.length === 0 && !isLoading && !isError && (jsx("div", { className: "flex flex-1 flex-col items-center justify-center py-6", children: jsx("p", { className: "text-sm text-gray-600", children: t('chatHistoryChatHistoryTab.noConversations') }) })), sessions.length > 0 && (jsxs("div", { className: "grid min-h-[320px] flex-1 grid-cols-1 gap-6 md:grid-cols-2", children: [jsxs("div", { className: "col-span-full flex min-h-0 flex-col gap-3 md:col-span-1", children: [jsx("div", { className: "scrollbar-hide min-h-0 flex-1 overflow-y-auto rounded-md border border-neutral-200", tabIndex: 0, role: "region", "aria-label": t('chatHistoryChatHistoryTab.conversationListLabel'), children: sessions.map((session) => {
220562
- var _a, _b, _c, _d, _e;
220759
+ var _a;
220563
220760
  const firstMessage = normalizeMessages(session.messages)[0];
220564
- const title = stripMarkdown$1(session.title ||
220565
- (firstMessage === null || firstMessage === void 0 ? void 0 : firstMessage.human) ||
220566
- session.first_user_message ||
220567
- t('chatHistoryChatHistoryTab.conversation'));
220761
+ const title = stripMarkdown$1(conversationTitle(session, t('chatHistoryChatHistoryTab.conversation')));
220568
220762
  const preview = stripMarkdown$1((_a = firstMessage === null || firstMessage === void 0 ? void 0 : firstMessage.ai) !== null && _a !== void 0 ? _a : '');
220569
- const sentiment = (_c = (_b = session.sentiment) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : '';
220570
220763
  return (jsxs("div", { role: "button", tabIndex: 0, "data-testid": "history-conversation-row", "data-session-id": session.id, className: cn('flex cursor-pointer items-center justify-between border-b border-neutral-200 p-4 last:border-b-0', (selectedSession === null || selectedSession === void 0 ? void 0 : selectedSession.id) === session.id ? 'bg-gray-100' : 'hover:bg-gray-50'), onClick: () => handleConversationClick(session), onKeyDown: (event) => {
220571
220764
  if (event.key === 'Enter' || event.key === ' ') {
220572
220765
  event.preventDefault();
220573
220766
  handleConversationClick(session);
220574
220767
  }
220575
- }, children: [jsxs("div", { className: "w-full", children: [jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [jsxs("span", { className: "flex items-center gap-2 text-sm text-gray-600", children: [formatSessionDate(session.inserted_at), sentiment && (jsx(Badge, { variant: "outline", className: cn('font-normal', (_d = SENTIMENT_CLASSES[sentiment]) !== null && _d !== void 0 ? _d : SENTIMENT_CLASSES.neutral), children: sentimentLabel((_e = session.sentiment) !== null && _e !== void 0 ? _e : '') }))] }), jsx("span", { className: "max-w-[100px] truncate text-sm text-gray-900 sm:max-w-[200px]", children: resolveAgent(session).name })] }), jsx("div", { className: "font-medium text-gray-900", children: textTruncate$2(title, 50) }), preview && (jsx("p", { className: "line-clamp-1 text-sm text-gray-600", children: textTruncate$2(preview, 60) }))] }), jsx("div", { className: "flex items-center gap-2 text-sm text-gray-600", children: jsx(ChevronRight, { className: "h-4 w-4" }) })] }, session.id));
220768
+ }, children: [jsxs("div", { className: "w-full", children: [jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [jsx("span", { className: "shrink-0 text-sm text-gray-600", children: formatSessionDate(session.inserted_at) }), jsx(AgentSettingsLink, { uniqueId: resolveAgent(session).uniqueId, name: resolveAgent(session).name, className: "min-w-0 text-right text-sm text-gray-900" })] }), jsx("div", { className: "font-medium text-gray-900", children: textTruncate$2(title, 50) }), jsx(ConversationTopics, { topics: session.topics, className: "mt-1", leading: jsx(ConversationSentiment, { sentiment: session.sentiment, labels: sentimentLabels, compact: true }) }), preview && (jsx("p", { className: "line-clamp-1 text-sm text-gray-600", children: textTruncate$2(preview, 60) }))] }), jsx("div", { className: "flex items-center gap-2 text-sm text-gray-600", children: jsx(ChevronRight, { className: "h-4 w-4" }) })] }, session.id));
220576
220769
  }) }), totalPages > 1 && (jsx("div", { className: "flex-shrink-0", children: jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isFetching || isLoading, disableNumberedButtons: isMobile }) }))] }), jsx("div", { className: "scrollbar-hide hidden min-h-0 flex-col overflow-y-auto rounded-lg border border-neutral-200 bg-white p-6 shadow-sm md:flex", tabIndex: 0, role: "region", "aria-label": t('chatHistoryChatHistoryTab.conversationPreviewLabel'), children: selectedSession ? (jsx(ConversationPreview, { org: org, username: username, session: selectedSession, agent: resolveAgent(selectedSession) })) : (jsx("div", { className: "flex h-full items-center justify-center text-gray-500", children: t('chatHistoryChatHistoryTab.selectPrompt') })) })] })), jsx(Dialog, { open: isPreviewModalOpen, onOpenChange: setIsPreviewModalOpen, children: jsxs(DialogContent, { className: "scrollbar-hide mx-auto max-h-[80vh] max-w-[90vw] overflow-x-hidden overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-lg font-semibold text-gray-900", children: selectedSession
220577
- ? stripMarkdown$1(selectedSession.title || t('chatHistoryChatHistoryTab.conversation'))
220770
+ ? stripMarkdown$1(conversationTitle(selectedSession, t('chatHistoryChatHistoryTab.conversation')))
220578
220771
  : t('chatHistoryChatHistoryTab.conversation') }) }), jsx("div", { className: "mx-auto max-w-full overflow-x-hidden", children: selectedSession && (jsx(ConversationPreview, { org: org, username: username, session: selectedSession, agent: resolveAgent(selectedSession) })) })] }) })] }), jsx(TabsContent, { value: "exports", className: "mt-0 min-h-0 flex-1 overflow-y-auto data-[state=inactive]:hidden", children: jsx(ReportHistory, { org: org, username: username, onDownload: downloadFromUrl }) })] }));
220579
220772
  }
220580
220773
 
@@ -222940,6 +223133,201 @@ function InvitedUsersDialog({ tenant, onClose }) {
222940
223133
  }, children: jsx(DialogPortal, { forceMount: true, children: jsxs(DialogContent, { "aria-label": t('profileInvitedUsers.dialogAriaLabel'), className: "max-w-sm rounded-2xl px-6 py-8 pointer-events-auto", "aria-describedby": "invited-users-dialog", children: [jsx(DialogHeader, { className: "relative flex-row justify-between", children: jsx(DialogTitle, { className: "text-blue-600 text-xl font-semibold", children: t('profileInvitedUsers.title') }) }), jsxs("div", { className: "mt-4 space-y-1", children: [jsx("p", { className: "text-gray-500 text-sm", children: t('profileInvitedUsers.pendingDescription') }), jsx("form", { children: jsx(Input, { value: query, onChange: (event) => setQuery(event.target.value), placeholder: t('profileInvitedUsers.searchPlaceholder'), className: "mt-2" }) })] }), jsxs("div", { children: [jsx("h2", { className: "text-md text-gray-600 font-semibold mb-4", children: t('profileInvitedUsers.emailHeading') }), invitedUsers === null || invitedUsers === void 0 ? void 0 : invitedUsers.results.map((user) => (jsx("div", { className: "border-b-gray-50 pb-2 mb-4 text-sm text-gray-600 dark:text-gray-400", children: user.email }, user.id))), (invitedUsers === null || invitedUsers === void 0 ? void 0 : invitedUsers.results.length) === 0 && (jsx("p", { className: "text-gray", children: t('profileInvitedUsers.noRecords') }))] })] }) }) }));
222941
223134
  }
222942
223135
 
223136
+ /**
223137
+ * Whether, and how, a retrieved document can be shown inside the app.
223138
+ *
223139
+ * The Datasets tab accepts PDFs, Office files, CSV/TXT/Markdown, images,
223140
+ * audio, video, ZIPs, GitHub repos, YouTube videos, web pages and crawls, and
223141
+ * links to Google Drive, OneDrive and Dropbox. Only some of those a browser
223142
+ * can render on its own; the rest get no Preview button rather than a blank
223143
+ * frame. Decided from the source URL (extension and host) and, when the
223144
+ * backend sends one, the document's kind.
223145
+ */
223146
+ const IMAGE = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp', 'avif']);
223147
+ const AUDIO = new Set(['mp3', 'wav', 'ogg', 'oga', 'm4a', 'aac', 'flac']);
223148
+ const VIDEO = new Set(['mp4', 'webm', 'ogv', 'mov', 'm4v']);
223149
+ /** Browsers cannot render these; a frame would only offer a download. */
223150
+ const NOT_VIEWABLE = new Set([
223151
+ 'doc',
223152
+ 'docx',
223153
+ 'ppt',
223154
+ 'pptx',
223155
+ 'xls',
223156
+ 'xlsx',
223157
+ 'odt',
223158
+ 'odp',
223159
+ 'ods',
223160
+ 'rtf',
223161
+ 'zip',
223162
+ 'rar',
223163
+ '7z',
223164
+ 'tar',
223165
+ 'gz',
223166
+ 'tgz',
223167
+ ]);
223168
+ /** Hosts that refuse to be framed, or need the viewer's own sign-in. */
223169
+ const UNFRAMEABLE_HOSTS = [
223170
+ 'github.com',
223171
+ 'dropbox.com',
223172
+ 'onedrive.live.com',
223173
+ '1drv.ms',
223174
+ 'sharepoint.com',
223175
+ ];
223176
+ const hostMatches = (host, domain) => host === domain || host.endsWith(`.${domain}`);
223177
+ const extensionOf = (pathname) => {
223178
+ var _a;
223179
+ const last = (_a = pathname.split('/').pop()) !== null && _a !== void 0 ? _a : '';
223180
+ const dot = last.lastIndexOf('.');
223181
+ return dot > 0 ? last.slice(dot + 1).toLowerCase() : '';
223182
+ };
223183
+ const youtubeEmbed = (url) => {
223184
+ var _a;
223185
+ const host = url.hostname.toLowerCase().replace(/^(www|m)\./, '');
223186
+ let id = null;
223187
+ if (host === 'youtu.be')
223188
+ id = (_a = url.pathname.split('/')[1]) !== null && _a !== void 0 ? _a : null;
223189
+ else if (host === 'youtube.com' || host === 'youtube-nocookie.com') {
223190
+ const [, section, rest] = url.pathname.split('/');
223191
+ if (section === 'watch')
223192
+ id = url.searchParams.get('v');
223193
+ else if (section === 'embed' || section === 'shorts' || section === 'live' || section === 'v')
223194
+ id = rest !== null && rest !== void 0 ? rest : null;
223195
+ }
223196
+ return id && /^[\w-]{6,}$/.test(id) ? `https://www.youtube-nocookie.com/embed/${id}` : null;
223197
+ };
223198
+ const googleEmbed = (url) => {
223199
+ const host = url.hostname.toLowerCase();
223200
+ if (host === 'drive.google.com') {
223201
+ const file = url.pathname.match(/^\/file\/d\/([\w-]+)/);
223202
+ if (file)
223203
+ return `https://drive.google.com/file/d/${file[1]}/preview`;
223204
+ const open = url.pathname === '/open' && url.searchParams.get('id');
223205
+ if (open)
223206
+ return `https://drive.google.com/file/d/${open}/preview`;
223207
+ return null;
223208
+ }
223209
+ if (host === 'docs.google.com') {
223210
+ const doc = url.pathname.match(/^\/(document|spreadsheets|presentation)\/d\/([\w-]+)/);
223211
+ return doc ? `https://docs.google.com/${doc[1]}/d/${doc[2]}/preview` : null;
223212
+ }
223213
+ return null;
223214
+ };
223215
+ /** A kind the backend may name on the document, when it says one. */
223216
+ const kindFromHint = (hint) => {
223217
+ const h = (hint !== null && hint !== void 0 ? hint : '').toLowerCase();
223218
+ if (!h)
223219
+ return null;
223220
+ if (/image|photo|picture/.test(h))
223221
+ return 'image';
223222
+ if (/audio|podcast/.test(h))
223223
+ return 'audio';
223224
+ if (/video(?!.*youtube)/.test(h) && !/youtube/.test(h))
223225
+ return 'video';
223226
+ if (/docx|word|powerpoint|pptx|excel|xlsx|spreadsheet|zip|archive|course/.test(h))
223227
+ return 'none';
223228
+ return null;
223229
+ };
223230
+ /**
223231
+ * `null` when the document cannot be shown here: no URL, a host that refuses
223232
+ * framing, or a file type a browser cannot render (Office files, archives).
223233
+ */
223234
+ function previewPlan(source, hint) {
223235
+ const raw = (source !== null && source !== void 0 ? source : '').trim();
223236
+ if (!/^https?:\/\//i.test(raw))
223237
+ return null;
223238
+ let url;
223239
+ try {
223240
+ url = new URL(raw);
223241
+ }
223242
+ catch (_a) {
223243
+ return null;
223244
+ }
223245
+ const host = url.hostname.toLowerCase();
223246
+ const yt = youtubeEmbed(url);
223247
+ if (yt)
223248
+ return { kind: 'frame', src: yt };
223249
+ // A YouTube page that is not a video (a channel, a playlist) cannot be framed.
223250
+ if (/(^|\.)(youtube\.com|youtu\.be|youtube-nocookie\.com)$/.test(host))
223251
+ return null;
223252
+ const google = googleEmbed(url);
223253
+ if (google)
223254
+ return { kind: 'frame', src: google };
223255
+ if (host === 'drive.google.com' || host === 'docs.google.com')
223256
+ return null;
223257
+ if (host === 'raw.githubusercontent.com')
223258
+ return { kind: 'frame', src: raw };
223259
+ if (UNFRAMEABLE_HOSTS.some((domain) => hostMatches(host, domain)))
223260
+ return null;
223261
+ const hinted = kindFromHint(hint);
223262
+ if (hinted === 'none')
223263
+ return null;
223264
+ if (hinted)
223265
+ return { kind: hinted, src: raw };
223266
+ const ext = extensionOf(url.pathname);
223267
+ if (IMAGE.has(ext))
223268
+ return { kind: 'image', src: raw };
223269
+ if (AUDIO.has(ext))
223270
+ return { kind: 'audio', src: raw };
223271
+ if (VIDEO.has(ext))
223272
+ return { kind: 'video', src: raw };
223273
+ if (NOT_VIEWABLE.has(ext))
223274
+ return null;
223275
+ // PDFs, text, CSV, Markdown, HTML, JSON and extension-less API URLs: the
223276
+ // browser renders these itself (its PDF viewer, or as text or a page).
223277
+ return { kind: 'frame', src: raw };
223278
+ }
223279
+
223280
+ /** The shape a retrieved document is listed by: the session query's `VectorResult`
223281
+ * and a transcript's `TranscriptRetrievedDocument` both satisfy it. */
223282
+ /** Only `http(s)` sources are links; a bare file name or dataset id is not. */
223283
+ const isHttpUrl = (value) => /^https?:\/\//i.test((value !== null && value !== void 0 ? value : '').trim());
223284
+ /** `0.7` → `70`; anything unusable → undefined. */
223285
+ const relevancePercent = (score) => typeof score === 'number' && Number.isFinite(score)
223286
+ ? Math.round(Math.max(0, Math.min(1, score)) * 100)
223287
+ : undefined;
223288
+ /**
223289
+ * The document's URL with a text fragment for the matched passage's opening
223290
+ * words, so a browser that supports fragments (Chromium for HTML pages) opens
223291
+ * the page scrolled to, and highlighting, the passage. PDFs and other
223292
+ * viewers ignore it; a frame cannot honour it, so only new-tab links get it.
223293
+ */
223294
+ const deepLink = (url, snippet) => {
223295
+ const words = (snippet !== null && snippet !== void 0 ? snippet : '').replace(/\s+/g, ' ').trim().split(' ').slice(0, 8).join(' ');
223296
+ const text = words.replace(/[\s.,;:!?"'”’)\]]+$/, '');
223297
+ if (text.length < 12)
223298
+ return url;
223299
+ return `${url.split('#')[0]}#:~:text=${encodeURIComponent(text)}`;
223300
+ };
223301
+ const hostOf = (value) => {
223302
+ try {
223303
+ return new URL(value).host;
223304
+ }
223305
+ catch (_a) {
223306
+ return '';
223307
+ }
223308
+ };
223309
+ /**
223310
+ * One retrieved document: its title (a new-tab link when the source is a
223311
+ * URL), its relevance, the matched passage, and — for URLs — a preview the
223312
+ * reader can open (the title link beside it still opens the source in a new
223313
+ * tab).
223314
+ */
223315
+ function RetrievedDocumentRow({ doc }) {
223316
+ var _a, _b;
223317
+ const t = useT();
223318
+ const [previewOpen, setPreviewOpen] = React.useState(false);
223319
+ const source = ((_a = doc.source) !== null && _a !== void 0 ? _a : '').trim();
223320
+ const url = isHttpUrl(source) ? source : null;
223321
+ const title = doc.title || (url ? hostOf(url) : source);
223322
+ const relevance = relevancePercent(doc.score);
223323
+ const openHref = url ? deepLink(url, doc.snippet) : null;
223324
+ // Preview only what a browser can show; Office files, archives and
223325
+ // unframeable hosts get no button rather than a blank frame.
223326
+ const preview = previewPlan(source, doc.type);
223327
+ return (jsx("div", { className: "rounded-lg p-2 hover:bg-gray-50", "data-testid": "retrieved-document", children: jsxs("div", { className: "flex items-start gap-2", children: [jsx(Radio$1, { className: "mt-1 h-4 w-4 text-gray-400" }), jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [jsxs("div", { className: "flex items-start justify-between gap-2", children: [jsx("div", { className: "min-w-0", children: url ? (jsxs("a", { href: openHref !== null && openHref !== void 0 ? openHref : url, target: "_blank", rel: "noopener noreferrer", className: "inline-flex min-w-0 items-center gap-1 text-sm font-semibold text-[#646464] hover:text-blue-600", "aria-label": t('documentSidebar.openInNewTab', { title }), "data-testid": "retrieved-document-link", children: [jsx("span", { className: "min-w-0 break-words", children: title }), jsx(SquareArrowOutUpRight, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": "true" })] })) : (jsx("span", { className: "text-sm font-semibold break-words text-[#646464]", children: title })) }), relevance !== undefined && (jsx("span", { className: "shrink-0 rounded-[5px] bg-blue-50 px-2 py-0.5 text-xs text-blue-700", title: t('documentSidebar.relevanceHint'), "data-testid": "retrieved-document-relevance", children: t('documentSidebar.relevance', { percent: relevance }) }))] }), preview && (jsxs("div", { className: "pt-1", children: [jsxs(Button$1, { type: "button", variant: "outline", size: "sm", onClick: () => setPreviewOpen(true), className: "h-7 gap-1.5 px-2.5 text-xs", "data-testid": "retrieved-document-preview-toggle", children: [jsx(Eye, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), t('documentSidebar.preview')] }), jsx(Dialog, { open: previewOpen, onOpenChange: setPreviewOpen, children: jsxs(DialogContent, { className: "flex flex-col gap-0 overflow-hidden rounded-lg p-0",
223328
+ // Inline: the size must not depend on a host's Tailwind scan.
223329
+ style: { width: '94vw', maxWidth: '94vw', height: '92vh' }, "data-testid": "retrieved-document-preview", children: [jsxs(DialogHeader, { className: "border-b border-gray-200 bg-white px-5 py-3 pr-12 text-left", children: [jsxs(DialogTitle, { className: "flex min-w-0 items-center gap-2 text-base font-semibold text-gray-800", children: [jsx("span", { className: "min-w-0 truncate", children: title }), jsx("a", { href: (_b = openHref !== null && openHref !== void 0 ? openHref : url) !== null && _b !== void 0 ? _b : undefined, target: "_blank", rel: "noopener noreferrer", className: "inline-flex shrink-0 items-center text-blue-600 hover:text-blue-700", "aria-label": t('documentSidebar.openInNewTab', { title }), children: jsx(SquareArrowOutUpRight, { className: "h-4 w-4", "aria-hidden": "true" }) })] }), jsx(DialogDescription, { className: "flex flex-wrap items-center gap-2 text-xs text-gray-500", children: relevance !== undefined && (jsx("span", { className: "rounded-[5px] bg-blue-50 px-2 py-0.5 text-blue-700", children: t('documentSidebar.relevance', { percent: relevance }) })) })] }), jsx("div", { className: "flex min-h-0 flex-1 items-center justify-center bg-gray-100", children: preview.kind === 'image' ? (jsx("img", { src: preview.src, alt: title, className: "h-full w-full object-contain" })) : preview.kind === 'audio' ? (jsx("audio", { src: preview.src, controls: true, className: "w-full max-w-2xl px-6" })) : preview.kind === 'video' ? (jsx("video", { src: preview.src, controls: true, className: "h-full w-full bg-black" })) : (jsx("iframe", { src: preview.src, title: title, referrerPolicy: "no-referrer", allow: "fullscreen; autoplay; encrypted-media; picture-in-picture", className: "h-full w-full border-0 bg-white" })) })] }) })] })), jsx("p", { className: "line-clamp-6 pt-[10px] text-[14px] text-gray-600", children: doc.snippet })] })] }) }));
223330
+ }
222943
223331
  function DocumentSidebar({ isModal = false, sessionId = '', documents, }) {
222944
223332
  const t = useT();
222945
223333
  const [isCollapsed, setIsCollapsed] = React.useState(false);
@@ -222972,10 +223360,7 @@ function DocumentSidebar({ isModal = false, sessionId = '', documents, }) {
222972
223360
  backgroundColor: isCollapsed && !isModal ? 'white' : '#F3F6FB',
222973
223361
  // In the dialog the parent bounds the height; the rail caps itself.
222974
223362
  maxHeight: isModal ? undefined : 'calc(100vh - 80px)',
222975
- }, children: jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [!isModal && (jsxs("div", { className: cn('flex cursor-pointer items-center gap-2 border-b border-gray-200 p-4 transition-colors duration-200', isCollapsed && 'h-[80px] justify-center rounded-tl-[5px] rounded-bl-[5px] p-2', 'hover:bg-blue-100'), onClick: toggleCollapse, style: { backgroundColor: '#F3F6FB' }, children: [jsx(FileText, { className: "h-5 w-5 shrink-0 text-blue-600" }), !isCollapsed && (jsxs(Fragment$1, { children: [jsx("h2", { className: "text-base font-medium text-[#646464]", children: t('documentSidebar.retrievedDocuments') }), jsx(ChevronRight, { className: cn('ml-auto h-4 w-4 text-gray-400 transition-transform', isCollapsed ? 'rotate-180' : '') })] }))] })), (!isCollapsed || isModal) && (jsx(Fragment$1, { children: jsx("div", { className: "min-h-0 flex-1 overflow-auto", style: { backgroundColor: '#F3F6FB' }, children: jsx("div", { className: "mt-0 space-y-1 p-2", children: vectorDocuments.map((doc, index) => {
222976
- var _a, _b;
222977
- return (jsxs(React.Fragment, { children: [jsx("div", { className: "rounded-lg p-2 hover:bg-gray-50", children: jsxs("div", { className: "flex items-start gap-2", children: [jsx(Radio$1, { className: "mt-1 h-4 w-4 text-gray-400" }), jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx(Link$2, { href: (_a = doc.source) !== null && _a !== void 0 ? _a : '', target: "_blank", className: "min-w-0", children: jsx("span", { className: "text-sm font-semibold break-words text-[#646464] hover:text-blue-600", children: doc.title }) }), jsx("div", { className: "flex items-center gap-2 self-center", children: jsx("span", { className: "text-xs text-gray-500", children: (_b = doc === null || doc === void 0 ? void 0 : doc.score) === null || _b === void 0 ? void 0 : _b.toFixed(2) }) })] }), jsx("p", { className: "line-clamp-6 pt-[10px] text-[14px] text-gray-600", children: doc.snippet })] })] }) }), index < vectorDocuments.length - 1 && (jsx("div", { className: "my-2 border-t border-gray-200" }))] }, index));
222978
- }) }) }) }))] }) })) : null }));
223363
+ }, children: jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [!isModal && (jsxs("div", { className: cn('flex cursor-pointer items-center gap-2 border-b border-gray-200 p-4 transition-colors duration-200', isCollapsed && 'h-[80px] justify-center rounded-tl-[5px] rounded-bl-[5px] p-2', 'hover:bg-blue-100'), onClick: toggleCollapse, style: { backgroundColor: '#F3F6FB' }, children: [jsx(FileText, { className: "h-5 w-5 shrink-0 text-blue-600" }), !isCollapsed && (jsxs(Fragment$1, { children: [jsx("h2", { className: "text-base font-medium text-[#646464]", children: t('documentSidebar.retrievedDocuments') }), jsx(ChevronRight, { className: cn('ml-auto h-4 w-4 text-gray-400 transition-transform', isCollapsed ? 'rotate-180' : '') })] }))] })), (!isCollapsed || isModal) && (jsx(Fragment$1, { children: jsx("div", { className: "min-h-0 flex-1 overflow-auto", style: { backgroundColor: '#F3F6FB' }, children: jsx("div", { className: "mt-0 space-y-1 p-2", children: vectorDocuments.map((doc, index) => (jsxs(React.Fragment, { children: [jsx(RetrievedDocumentRow, { doc: doc }), index < vectorDocuments.length - 1 && (jsx("div", { className: "my-2 border-t border-gray-200" }))] }, index))) }) }) }))] }) })) : null }));
222979
223364
  }
222980
223365
 
222981
223366
  /**
@@ -281164,6 +281549,12 @@ const AGENT_HISTORY_TAB_LABELS = {
281164
281549
  aiAgent: 'AI Agent',
281165
281550
  noConversations: 'No conversations found',
281166
281551
  documentsChip: (count) => `Documents · ${count}`,
281552
+ sentiment: {
281553
+ positive: 'Positive',
281554
+ neutral: 'Neutral',
281555
+ negative: 'Negative',
281556
+ userSentiment: 'User Sentiment',
281557
+ },
281167
281558
  },
281168
281559
  summary: {
281169
281560
  notAvailable: 'Summary not available',
@@ -281203,6 +281594,12 @@ function buildHistoryTabLabels(t) {
281203
281594
  aiAgent: t('historyTabLabels.conversation.aiAgent'),
281204
281595
  noConversations: t('historyTabLabels.conversation.noConversations'),
281205
281596
  documentsChip: (count) => t('historyTabLabels.conversation.documentsChip', { count }),
281597
+ sentiment: {
281598
+ positive: t('historyTabLabels.conversation.sentiment.positive'),
281599
+ neutral: t('historyTabLabels.conversation.sentiment.neutral'),
281600
+ negative: t('historyTabLabels.conversation.sentiment.negative'),
281601
+ userSentiment: t('historyTabLabels.conversation.sentiment.userSentiment'),
281602
+ },
281206
281603
  },
281207
281604
  summary: {
281208
281605
  notAvailable: t('historyTabLabels.summary.notAvailable'),
@@ -281237,7 +281634,7 @@ function textTruncate$1(str, length, ending) {
281237
281634
  return str;
281238
281635
  }
281239
281636
  function AgentHistoryTab({ renderMessageContent, PaginationComponent, onExport, isExporting = false, labels: labelsOverride, currentSPA, }) {
281240
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
281637
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
281241
281638
  const t = useT();
281242
281639
  const { tenantKey, mentorId, username } = useAgentSettings();
281243
281640
  const labels = React__default.useMemo(() => resolveHistoryTabLabels(labelsOverride, t), [labelsOverride, t]);
@@ -281325,12 +281722,10 @@ function AgentHistoryTab({ renderMessageContent, PaginationComponent, onExport,
281325
281722
  const owner = resolveUserIdentity(conversation, {
281326
281723
  anonymousLabel: labels.conversation.anonymous,
281327
281724
  });
281328
- const timeAgo = formatDistanceToNow(new Date(conversation.inserted_at), {
281329
- addSuffix: true,
281330
- });
281331
- const title = (firstMessage === null || firstMessage === void 0 ? void 0 : firstMessage.human)
281332
- ? textTruncate$1(firstMessage.human, 50)
281333
- : labels.conversation.title;
281725
+ // The same date pattern as the profile History tab.
281726
+ const when = formatSessionDate(conversation.inserted_at);
281727
+ // title → first_user_message → first human turn → label, as everywhere.
281728
+ const title = textTruncate$1(conversationTitle(conversation, labels.conversation.title), 50);
281334
281729
  const preview = (firstMessage === null || firstMessage === void 0 ? void 0 : firstMessage.ai)
281335
281730
  ? textTruncate$1(firstMessage.ai, 60)
281336
281731
  : labels.conversation.noResponse;
@@ -281342,14 +281737,14 @@ function AgentHistoryTab({ renderMessageContent, PaginationComponent, onExport,
281342
281737
  const rollup = summarizeTranscriptTurns(messages);
281343
281738
  return (jsxs("div", { className: cn('flex cursor-pointer items-center justify-between border-b p-4 last:border-b-0', (selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.id) === conversation.id
281344
281739
  ? 'bg-gray-100'
281345
- : 'hover:bg-gray-50'), onClick: () => handleConversationClick(conversation), children: [jsxs("div", { className: "w-full", children: [jsxs("div", { className: "mb-2 flex items-center justify-between", children: [jsx("span", { className: "text-sm text-gray-600", children: timeAgo }), jsx(UserProfileLink, { tenantKey: tenantKey, username: owner.profileUsername, display: owner.label, currentSPA: currentSPA, className: "max-w-[100px] text-sm text-gray-900 sm:max-w-[200px]" })] }), jsx("div", { className: "font-medium text-gray-900", children: title }), jsx("p", { className: "line-clamp-1 text-sm text-gray-600", children: preview }), (rollup.documentsCount > 0 || rollup.toolCallsCount > 0) && (jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [rollup.documentsCount > 0 && (
281740
+ : 'hover:bg-gray-50'), onClick: () => handleConversationClick(conversation), children: [jsxs("div", { className: "w-full", children: [jsxs("div", { className: "mb-2 flex items-center justify-between", children: [jsx("span", { className: "text-sm text-gray-600", children: when }), jsx(UserProfileLink, { tenantKey: tenantKey, username: owner.profileUsername, display: owner.label, currentSPA: currentSPA, className: "max-w-[100px] text-sm text-gray-900 sm:max-w-[200px]" })] }), jsx("div", { className: "font-medium text-gray-900", children: title }), jsx(ConversationTopics, { topics: conversation.topics, className: "mt-1", leading: jsx(ConversationSentiment, { sentiment: conversation.sentiment, labels: labels.conversation.sentiment, compact: true }) }), jsx("p", { className: "line-clamp-1 text-sm text-gray-600", children: preview }), (rollup.documentsCount > 0 || rollup.toolCallsCount > 0) && (jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [rollup.documentsCount > 0 && (
281346
281741
  // The chat's documents dialog, as a chip: one
281347
281742
  // click shows what the conversation retrieved.
281348
281743
  jsx(RetrievedDocumentsButton, { documents: documents, label: labels.conversation.documentsChip(rollup.documentsCount), className: "h-6 gap-1 rounded-md border-transparent bg-blue-50 px-2 text-xs font-normal text-blue-700 hover:bg-blue-100 [&_svg]:h-3 [&_svg]:w-3" })), jsx(TranscriptRollupBadges, { documentsCount: 0, toolCallsCount: rollup.toolCallsCount })] }))] }), jsx("div", { className: "flex items-center gap-2 text-sm text-gray-600", children: jsx(ChevronRight, { className: "h-4 w-4" }) })] }, conversation.id));
281349
- }) }), totalPages > 1 && PaginationComponent && (jsx("div", { className: "my-2", children: jsx(PaginationComponent, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, disabled: isChatHistoryFetching || isChatHistoryLoading, disableNumberedButtons: isMobile }) }))] }), jsx("div", { className: "scrollbar-hide hidden max-h-[500px] flex-col overflow-y-auto rounded-lg border bg-white p-6 shadow-sm md:flex", tabIndex: 0, role: "region", "aria-label": t('tabsHistoryTab.conversationPreviewLabel'), children: selectedConversation && previewConversationContent ? (jsxs(Fragment$1, { children: [jsxs("div", { className: "mb-4", children: [jsx("h3", { className: "mb-1 text-base font-semibold text-gray-700", children: ((_m = selectedConversation.messages[0]) === null || _m === void 0 ? void 0 : _m.human) || labels.conversation.title }), jsx("span", { className: "text-sm text-gray-500", children: format$1(new Date(selectedConversation.inserted_at), "MMM dd, yyyy 'at' h:mm a") }), jsx(RetrievedDocumentsButton, { sessionId: selectedConversation.id, documents: conversationDocuments(selectedConversation.messages).length > 0
281744
+ }) }), totalPages > 1 && PaginationComponent && (jsx("div", { className: "my-2", children: jsx(PaginationComponent, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, disabled: isChatHistoryFetching || isChatHistoryLoading, disableNumberedButtons: isMobile }) }))] }), jsx("div", { className: "scrollbar-hide hidden max-h-[500px] flex-col overflow-y-auto rounded-lg border bg-white p-6 shadow-sm md:flex", tabIndex: 0, role: "region", "aria-label": t('tabsHistoryTab.conversationPreviewLabel'), children: selectedConversation && previewConversationContent ? (jsxs(Fragment$1, { children: [jsxs("div", { className: "mb-4", children: [jsx("h3", { className: "mb-1 text-base font-semibold text-gray-700", children: conversationTitle(selectedConversation, labels.conversation.title) }), jsx("span", { className: "text-sm text-gray-500", children: format$1(new Date(selectedConversation.inserted_at), "MMM dd, yyyy 'at' h:mm a") }), jsx(RetrievedDocumentsButton, { sessionId: selectedConversation.id, documents: conversationDocuments(selectedConversation.messages).length > 0
281350
281745
  ? conversationDocuments(selectedConversation.messages)
281351
- : undefined, className: "mt-2" })] }), jsxs("div", { className: "space-y-6", children: [selectedConversation.messages.map((message, index) => (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-start gap-3", children: [jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-blue-100", children: jsx("span", { className: "text-sm font-medium text-blue-600", children: selectedOwner.initial }) }), jsxs("div", { className: "flex-1", children: [jsx("div", { className: "font-medium text-gray-700", children: jsx(UserProfileLink, { tenantKey: tenantKey, username: selectedOwner.profileUsername, display: selectedOwner.label, currentSPA: currentSPA }) }), jsx("p", { className: "mt-1 text-sm whitespace-pre-line text-gray-500", children: message.human }), jsx(TranscriptFileCards, { files: attachmentCards(message.human_files) })] })] }), jsxs("div", { className: "flex items-start gap-3 border-t border-gray-200 pt-4", children: [jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-gray-100", children: jsx("span", { className: "text-sm font-medium text-gray-600", children: t('tabsHistoryTab.aiAvatarLabel') }) }), jsxs("div", { className: "flex-1", children: [jsx("div", { className: "font-medium text-gray-700", children: labels.conversation.aiAgent }), jsx("div", { className: "mt-1 text-sm text-gray-500", children: renderAiContent(message.ai) }), jsx(TranscriptFileCards, { files: attachmentCards(message.ai_files) }), jsx(TranscriptTurnDetails, { turn: message, tenantKey: tenantKey, mentorId: mentorId })] })] })] }, index))), (selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.memory_tracked) && (jsxs("div", { className: "border-t border-gray-200 pt-4", children: [jsxs(Button$1, { variant: "outline", onClick: () => setShowConversationMemory(!showConversationMemory), className: "flex w-full items-center justify-center gap-2 border-gray-200 text-gray-700 hover:bg-gray-50", children: [jsx(Brain, { className: "h-4 w-4" }), showConversationMemory ? labels.memory.hide : labels.memory.show] }), showConversationMemory && (jsx("div", { className: "mt-4 space-y-6", children: isConversationMemoryLoading ? (jsx("div", { className: "flex items-center justify-center py-4", children: jsx(Spinner, {}) })) : ((_o = conversationMemory === null || conversationMemory === void 0 ? void 0 : conversationMemory.entries) === null || _o === void 0 ? void 0 : _o.length) ? (jsx(Fragment$1, { children: conversationMemory.entries.map((entry, index) => (jsxs("div", { children: [jsx("h4", { className: "mb-3 font-semibold text-gray-900", children: entry.key }), jsx("ul", { className: "space-y-2", children: jsx("li", { className: "flex items-start gap-2 text-sm text-gray-600", children: entry.value }) })] }, index))) })) : (jsx("div", { className: "text-sm text-gray-500", children: labels.memory.notAvailable })) }))] }))] })] })) : (jsx("div", { className: "flex h-full items-center justify-center text-gray-500", children: labels.conversation.selectPrompt })) })] }))] }) }), jsx(Dialog, { open: isConversationPreviewModalOpen, onOpenChange: setIsConversationPreviewModalOpen, children: jsxs(DialogContent, { className: "scrollbar-hide mx-auto max-h-[80vh] max-w-[90vw] overflow-x-hidden overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-lg font-semibold text-gray-900", children: previewConversationContent
281352
- ? ((_p = previewConversationContent.messages[0]) === null || _p === void 0 ? void 0 : _p.human) || labels.conversation.title
281746
+ : undefined, className: "mt-2" })] }), jsxs("div", { className: "space-y-6", children: [selectedConversation.messages.map((message, index) => (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-start gap-3", children: [jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-blue-100", children: jsx("span", { className: "text-sm font-medium text-blue-600", children: selectedOwner.initial }) }), jsxs("div", { className: "flex-1", children: [jsx("div", { className: "font-medium text-gray-700", children: jsx(UserProfileLink, { tenantKey: tenantKey, username: selectedOwner.profileUsername, display: selectedOwner.label, currentSPA: currentSPA }) }), jsx("p", { className: "mt-1 text-sm whitespace-pre-line text-gray-500", children: message.human }), jsx(TranscriptFileCards, { files: attachmentCards(message.human_files) })] })] }), jsxs("div", { className: "flex items-start gap-3 border-t border-gray-200 pt-4", children: [jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-gray-100", children: jsx("span", { className: "text-sm font-medium text-gray-600", children: t('tabsHistoryTab.aiAvatarLabel') }) }), jsxs("div", { className: "flex-1", children: [jsx("div", { className: "font-medium text-gray-700", children: labels.conversation.aiAgent }), jsx("div", { className: "mt-1 text-sm text-gray-500", children: renderAiContent(message.ai) }), jsx(TranscriptFileCards, { files: attachmentCards(message.ai_files) }), jsx(TranscriptTurnDetails, { turn: message, tenantKey: tenantKey, mentorId: mentorId })] })] })] }, index))), (selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.memory_tracked) && (jsxs("div", { className: "border-t border-gray-200 pt-4", children: [jsxs(Button$1, { variant: "outline", onClick: () => setShowConversationMemory(!showConversationMemory), className: "flex w-full items-center justify-center gap-2 border-gray-200 text-gray-700 hover:bg-gray-50", children: [jsx(Brain, { className: "h-4 w-4" }), showConversationMemory ? labels.memory.hide : labels.memory.show] }), showConversationMemory && (jsx("div", { className: "mt-4 space-y-6", children: isConversationMemoryLoading ? (jsx("div", { className: "flex items-center justify-center py-4", children: jsx(Spinner, {}) })) : ((_m = conversationMemory === null || conversationMemory === void 0 ? void 0 : conversationMemory.entries) === null || _m === void 0 ? void 0 : _m.length) ? (jsx(Fragment$1, { children: conversationMemory.entries.map((entry, index) => (jsxs("div", { children: [jsx("h4", { className: "mb-3 font-semibold text-gray-900", children: entry.key }), jsx("ul", { className: "space-y-2", children: jsx("li", { className: "flex items-start gap-2 text-sm text-gray-600", children: entry.value }) })] }, index))) })) : (jsx("div", { className: "text-sm text-gray-500", children: labels.memory.notAvailable })) }))] }))] })] })) : (jsx("div", { className: "flex h-full items-center justify-center text-gray-500", children: labels.conversation.selectPrompt })) })] }))] }) }), jsx(Dialog, { open: isConversationPreviewModalOpen, onOpenChange: setIsConversationPreviewModalOpen, children: jsxs(DialogContent, { className: "scrollbar-hide mx-auto max-h-[80vh] max-w-[90vw] overflow-x-hidden overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-lg font-semibold text-gray-900", children: previewConversationContent
281747
+ ? conversationTitle(previewConversationContent, labels.conversation.title)
281353
281748
  : labels.conversation.title }) }), jsx("div", { className: "mx-auto max-w-full overflow-x-hidden", children: previewConversationContent && (jsxs("div", { className: "scrollbar-hide space-y-4 overflow-y-auto", children: [jsx("div", { className: "text-sm text-gray-500", children: format$1(new Date(previewConversationContent.inserted_at), "MMM dd, yyyy 'at' h:mm a") }), jsx(RetrievedDocumentsButton, { sessionId: previewConversationContent.id, documents: conversationDocuments(previewConversationContent.messages).length > 0
281354
281749
  ? conversationDocuments(previewConversationContent.messages)
281355
281750
  : undefined }), previewConversationContent.messages.map((message, index) => (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-start gap-3", children: [jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-blue-100", children: jsx("span", { className: "text-sm font-medium text-blue-600", children: previewOwner.initial }) }), jsxs("div", { className: "overflow-x-hidden", children: [jsx("div", { className: "truncate font-medium text-gray-900", children: jsx(UserProfileLink, { tenantKey: tenantKey, username: previewOwner.profileUsername, display: previewOwner.label, currentSPA: currentSPA }) }), jsx("p", { className: "mt-1 text-sm whitespace-pre-line text-gray-900", children: message.human }), jsx(TranscriptFileCards, { files: attachmentCards(message.human_files) })] })] }), jsxs("div", { className: "flex items-start gap-3 border-t border-gray-200 pt-4", children: [jsx("div", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-gray-100", children: jsx("span", { className: "text-sm font-medium text-gray-600", children: t('tabsHistoryTab.aiAvatarLabel') }) }), jsxs("div", { className: "overflow-x-hidden", children: [jsx("div", { className: "font-medium text-gray-900", children: labels.conversation.aiAgent }), jsx("div", { className: "mt-1 text-sm text-gray-900", children: renderAiContent(message.ai) }), jsx(TranscriptFileCards, { files: attachmentCards(message.ai_files) }), jsx(TranscriptTurnDetails, { turn: message, tenantKey: tenantKey, mentorId: mentorId })] })] })] }, index)))] })) })] }) })] }));