@iblai/iblai-js 2.27.0 → 2.28.0
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.
|
@@ -96359,7 +96359,11 @@ var advancedCustomDomain$3 = {
|
|
|
96359
96359
|
noProjects: "You have not deployed any apps yet. Deploy one first, then come back to give it a domain.",
|
|
96360
96360
|
customDomainLabel: "Domain",
|
|
96361
96361
|
domainHelpPlatform: "Without the scheme or a leading “www.” — for example, app.example.com.",
|
|
96362
|
-
domainHelpApp: "
|
|
96362
|
+
domainHelpApp: "A domain you own, without the scheme or a leading “www.” — for example, app.example.com. Leave it empty to use the subdomain above.",
|
|
96363
|
+
subdomainLabel: "Subdomain",
|
|
96364
|
+
subdomainHelp: "Lowercase letters, digits and hyphens, like a username. The app is served at <subdomain>.<the platform’s shared domain>, with no DNS records to set.",
|
|
96365
|
+
oneOfSubdomainOrDomain: "Fill in either the subdomain or a domain you own, not both.",
|
|
96366
|
+
subdomainInvalid: "A subdomain is 1–63 lowercase letters, digits and hyphens, and cannot start or end with a hyphen.",
|
|
96363
96367
|
cancel: "Cancel",
|
|
96364
96368
|
save: "Save",
|
|
96365
96369
|
expandAriaLabel: "Expand domains",
|
|
@@ -96381,6 +96385,9 @@ var advancedCustomDomain$3 = {
|
|
|
96381
96385
|
copyNameHostAriaLabel: "Copy name/host: {domain}",
|
|
96382
96386
|
copyValueAriaLabel: "Copy value/target",
|
|
96383
96387
|
noRecordsYet: "No records yet. Check the domain again to fetch them.",
|
|
96388
|
+
sharedDomainLine: "Runs on our shared domain — nothing to set up.",
|
|
96389
|
+
openSite: "Open {domain}",
|
|
96390
|
+
servesApp: "Serves {app}",
|
|
96384
96391
|
confirmRemoveTitle: "Remove this domain?",
|
|
96385
96392
|
confirmDeleteBody: "{domain} will stop signing users in to this organization.",
|
|
96386
96393
|
confirmDetachBody: "{domain} will stop serving the app, here and at the hosting provider.",
|
|
@@ -96838,6 +96845,9 @@ var analyticsAnalyticsFinancialStats$3 = {
|
|
|
96838
96845
|
viewTraces: "Traces →",
|
|
96839
96846
|
costByLLMFooter: "{shown} models · ranked by cost"
|
|
96840
96847
|
};
|
|
96848
|
+
var agentSettingsLink$3 = {
|
|
96849
|
+
openSettings: "Open settings for {name}"
|
|
96850
|
+
};
|
|
96841
96851
|
var analyticsAgentScopeLink$3 = {
|
|
96842
96852
|
scopeToAgent: "View analytics for {name}"
|
|
96843
96853
|
};
|
|
@@ -97059,6 +97069,8 @@ var analyticsAnalyticsTopicsStats$3 = {
|
|
|
97059
97069
|
topicsRankedFooter: "{shown} of {total} topics · ranked by message volume"
|
|
97060
97070
|
};
|
|
97061
97071
|
var analyticsAnalyticsTranscriptsStats$3 = {
|
|
97072
|
+
conversationFallbackTitle: "Conversation",
|
|
97073
|
+
labelEmail: "Email:",
|
|
97062
97074
|
anonymous: "Anonymous",
|
|
97063
97075
|
justNow: "Just now",
|
|
97064
97076
|
minutesAgo: "{count} min ago",
|
|
@@ -97503,6 +97515,7 @@ var careerEducationTab$3 = {
|
|
|
97503
97515
|
nothingToShow: "Nothing to show here."
|
|
97504
97516
|
};
|
|
97505
97517
|
var chatHistoryChatHistoryTab$3 = {
|
|
97518
|
+
userSentiment: "User Sentiment",
|
|
97506
97519
|
tabConversations: "Conversations",
|
|
97507
97520
|
tabExports: "Exports",
|
|
97508
97521
|
searchAgents: "Search Agents",
|
|
@@ -98547,6 +98560,10 @@ var disclaimersTabLabels$3 = {
|
|
|
98547
98560
|
}
|
|
98548
98561
|
};
|
|
98549
98562
|
var documentSidebar$3 = {
|
|
98563
|
+
relevance: "Relevance {percent}%",
|
|
98564
|
+
relevanceHint: "How closely this passage matched the question",
|
|
98565
|
+
preview: "Preview",
|
|
98566
|
+
openInNewTab: "Open {title} in a new tab",
|
|
98550
98567
|
retrievedDocuments: "Retrieved Documents"
|
|
98551
98568
|
};
|
|
98552
98569
|
var embedTabLabels$3 = {
|
|
@@ -98656,6 +98673,12 @@ var historyTabLabels$3 = {
|
|
|
98656
98673
|
outOf: "out of 5"
|
|
98657
98674
|
},
|
|
98658
98675
|
conversation: {
|
|
98676
|
+
sentiment: {
|
|
98677
|
+
positive: "Positive",
|
|
98678
|
+
neutral: "Neutral",
|
|
98679
|
+
negative: "Negative",
|
|
98680
|
+
userSentiment: "User Sentiment"
|
|
98681
|
+
},
|
|
98659
98682
|
title: "Conversation",
|
|
98660
98683
|
anonymous: "Anonymous",
|
|
98661
98684
|
noResponse: "No response available",
|
|
@@ -103336,6 +103359,7 @@ var en = {
|
|
|
103336
103359
|
analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$3,
|
|
103337
103360
|
analyticsAnalyticsCourses: analyticsAnalyticsCourses$3,
|
|
103338
103361
|
analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$3,
|
|
103362
|
+
agentSettingsLink: agentSettingsLink$3,
|
|
103339
103363
|
analyticsAgentScopeLink: analyticsAgentScopeLink$3,
|
|
103340
103364
|
analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats$3,
|
|
103341
103365
|
analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats$3,
|
|
@@ -103887,7 +103911,11 @@ var advancedCustomDomain$2 = {
|
|
|
103887
103911
|
noProjects: "Vous n’avez encore déployé aucune application. Déployez-en une, puis revenez lui donner un domaine.",
|
|
103888
103912
|
customDomainLabel: "Domaine",
|
|
103889
103913
|
domainHelpPlatform: "Sans le schéma ni un « www. » en tête — par exemple, app.example.com.",
|
|
103890
|
-
domainHelpApp: "
|
|
103914
|
+
domainHelpApp: "Un domaine qui vous appartient, sans le schéma ni un « www. » en tête — par exemple, app.example.com. Laissez ce champ vide pour utiliser le sous-domaine ci-dessus.",
|
|
103915
|
+
subdomainLabel: "Sous-domaine",
|
|
103916
|
+
subdomainHelp: "Lettres minuscules, chiffres et tirets, comme un nom d’utilisateur. L’application est servie à <sous-domaine>.<le domaine partagé de la plateforme>, sans aucun enregistrement DNS à créer.",
|
|
103917
|
+
oneOfSubdomainOrDomain: "Renseignez soit le sous-domaine, soit un domaine qui vous appartient, pas les deux.",
|
|
103918
|
+
subdomainInvalid: "Un sous-domaine compte de 1 à 63 lettres minuscules, chiffres et tirets, et ne peut ni commencer ni finir par un tiret.",
|
|
103891
103919
|
cancel: "Annuler",
|
|
103892
103920
|
save: "Enregistrer",
|
|
103893
103921
|
expandAriaLabel: "Déplier les domaines",
|
|
@@ -103909,6 +103937,9 @@ var advancedCustomDomain$2 = {
|
|
|
103909
103937
|
copyNameHostAriaLabel: "Copier le nom/hôte : {domain}",
|
|
103910
103938
|
copyValueAriaLabel: "Copier la valeur/cible",
|
|
103911
103939
|
noRecordsYet: "Aucun enregistrement pour l’instant. Vérifiez le domaine à nouveau pour les obtenir.",
|
|
103940
|
+
sharedDomainLine: "Fonctionne sur notre domaine partagé — rien à configurer.",
|
|
103941
|
+
openSite: "Ouvrir {domain}",
|
|
103942
|
+
servesApp: "Dessert {app}",
|
|
103912
103943
|
confirmRemoveTitle: "Supprimer ce domaine ?",
|
|
103913
103944
|
confirmDeleteBody: "{domain} ne permettra plus de se connecter à cette organisation.",
|
|
103914
103945
|
confirmDetachBody: "{domain} cessera de servir l’application, ici comme chez l’hébergeur.",
|
|
@@ -104366,6 +104397,9 @@ var analyticsAnalyticsFinancialStats$2 = {
|
|
|
104366
104397
|
viewTraces: "Traces →",
|
|
104367
104398
|
costByLLMFooter: "{shown} modèles · classés par coût"
|
|
104368
104399
|
};
|
|
104400
|
+
var agentSettingsLink$2 = {
|
|
104401
|
+
openSettings: "Ouvrir les paramètres de {name}"
|
|
104402
|
+
};
|
|
104369
104403
|
var analyticsAgentScopeLink$2 = {
|
|
104370
104404
|
scopeToAgent: "Voir les analyses de {name}"
|
|
104371
104405
|
};
|
|
@@ -104587,6 +104621,8 @@ var analyticsAnalyticsTopicsStats$2 = {
|
|
|
104587
104621
|
topicsRankedFooter: "{shown} sur {total} sujets · classés par volume de messages"
|
|
104588
104622
|
};
|
|
104589
104623
|
var analyticsAnalyticsTranscriptsStats$2 = {
|
|
104624
|
+
conversationFallbackTitle: "Conversation",
|
|
104625
|
+
labelEmail: "E-mail :",
|
|
104590
104626
|
anonymous: "Anonyme",
|
|
104591
104627
|
justNow: "À l'instant",
|
|
104592
104628
|
minutesAgo: "Il y a {count} min",
|
|
@@ -105031,6 +105067,7 @@ var careerEducationTab$2 = {
|
|
|
105031
105067
|
nothingToShow: "Rien à afficher ici."
|
|
105032
105068
|
};
|
|
105033
105069
|
var chatHistoryChatHistoryTab$2 = {
|
|
105070
|
+
userSentiment: "Sentiment de l'utilisateur",
|
|
105034
105071
|
tabConversations: "Conversations",
|
|
105035
105072
|
tabExports: "Exportations",
|
|
105036
105073
|
searchAgents: "Rechercher des agents",
|
|
@@ -106241,6 +106278,10 @@ var disclaimersTabLabels$2 = {
|
|
|
106241
106278
|
}
|
|
106242
106279
|
};
|
|
106243
106280
|
var documentSidebar$2 = {
|
|
106281
|
+
relevance: "Pertinence {percent}%",
|
|
106282
|
+
relevanceHint: "Dans quelle mesure ce passage correspond à la question",
|
|
106283
|
+
preview: "Aperçu",
|
|
106284
|
+
openInNewTab: "Ouvrir {title} dans un nouvel onglet",
|
|
106244
106285
|
retrievedDocuments: "Documents récupérés"
|
|
106245
106286
|
};
|
|
106246
106287
|
var embedTabLabels$2 = {
|
|
@@ -106350,6 +106391,12 @@ var historyTabLabels$2 = {
|
|
|
106350
106391
|
outOf: "sur 5"
|
|
106351
106392
|
},
|
|
106352
106393
|
conversation: {
|
|
106394
|
+
sentiment: {
|
|
106395
|
+
positive: "Positif",
|
|
106396
|
+
neutral: "Neutre",
|
|
106397
|
+
negative: "Négatif",
|
|
106398
|
+
userSentiment: "Sentiment de l'utilisateur"
|
|
106399
|
+
},
|
|
106353
106400
|
title: "Conversation",
|
|
106354
106401
|
anonymous: "Anonyme",
|
|
106355
106402
|
noResponse: "Aucune réponse disponible",
|
|
@@ -110864,6 +110911,7 @@ var fr = {
|
|
|
110864
110911
|
analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$2,
|
|
110865
110912
|
analyticsAnalyticsCourses: analyticsAnalyticsCourses$2,
|
|
110866
110913
|
analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$2,
|
|
110914
|
+
agentSettingsLink: agentSettingsLink$2,
|
|
110867
110915
|
analyticsAgentScopeLink: analyticsAgentScopeLink$2,
|
|
110868
110916
|
analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats$2,
|
|
110869
110917
|
analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats$2,
|
|
@@ -111415,7 +111463,11 @@ var advancedCustomDomain$1 = {
|
|
|
111415
111463
|
noProjects: "Todavía no has desplegado ninguna aplicación. Despliega una primero y vuelve para darle un dominio.",
|
|
111416
111464
|
customDomainLabel: "Dominio",
|
|
111417
111465
|
domainHelpPlatform: "Sin el esquema ni un “www.” inicial — por ejemplo, app.example.com.",
|
|
111418
|
-
domainHelpApp: "
|
|
111466
|
+
domainHelpApp: "Un dominio tuyo, sin el esquema ni un “www.” inicial — por ejemplo, app.example.com. Déjalo vacío para usar el subdominio de arriba.",
|
|
111467
|
+
subdomainLabel: "Subdominio",
|
|
111468
|
+
subdomainHelp: "Letras minúsculas, dígitos y guiones, como un nombre de usuario. La aplicación se sirve en <subdominio>.<el dominio compartido de la plataforma>, sin registros DNS que configurar.",
|
|
111469
|
+
oneOfSubdomainOrDomain: "Rellena el subdominio o un dominio tuyo, no ambos.",
|
|
111470
|
+
subdomainInvalid: "Un subdominio tiene entre 1 y 63 letras minúsculas, dígitos y guiones, y no puede empezar ni terminar con un guion.",
|
|
111419
111471
|
cancel: "Cancelar",
|
|
111420
111472
|
save: "Guardar",
|
|
111421
111473
|
expandAriaLabel: "Expandir dominios",
|
|
@@ -111437,6 +111489,9 @@ var advancedCustomDomain$1 = {
|
|
|
111437
111489
|
copyNameHostAriaLabel: "Copiar nombre/host: {domain}",
|
|
111438
111490
|
copyValueAriaLabel: "Copiar valor/destino",
|
|
111439
111491
|
noRecordsYet: "Aún no hay registros. Comprueba el dominio de nuevo para obtenerlos.",
|
|
111492
|
+
sharedDomainLine: "Funciona en nuestro dominio compartido — no hay nada que configurar.",
|
|
111493
|
+
openSite: "Abrir {domain}",
|
|
111494
|
+
servesApp: "Sirve {app}",
|
|
111440
111495
|
confirmRemoveTitle: "¿Eliminar este dominio?",
|
|
111441
111496
|
confirmDeleteBody: "{domain} dejará de permitir el inicio de sesión en esta organización.",
|
|
111442
111497
|
confirmDetachBody: "{domain} dejará de servir la aplicación, aquí y en el proveedor de alojamiento.",
|
|
@@ -111894,6 +111949,9 @@ var analyticsAnalyticsFinancialStats$1 = {
|
|
|
111894
111949
|
viewTraces: "Trazas →",
|
|
111895
111950
|
costByLLMFooter: "{shown} modelos · ordenados por costo"
|
|
111896
111951
|
};
|
|
111952
|
+
var agentSettingsLink$1 = {
|
|
111953
|
+
openSettings: "Abrir la configuración de {name}"
|
|
111954
|
+
};
|
|
111897
111955
|
var analyticsAgentScopeLink$1 = {
|
|
111898
111956
|
scopeToAgent: "Ver analíticas de {name}"
|
|
111899
111957
|
};
|
|
@@ -112115,6 +112173,8 @@ var analyticsAnalyticsTopicsStats$1 = {
|
|
|
112115
112173
|
topicsRankedFooter: "{shown} de {total} temas · ordenados por volumen de mensajes"
|
|
112116
112174
|
};
|
|
112117
112175
|
var analyticsAnalyticsTranscriptsStats$1 = {
|
|
112176
|
+
conversationFallbackTitle: "Conversación",
|
|
112177
|
+
labelEmail: "Correo electrónico:",
|
|
112118
112178
|
anonymous: "Anónimo",
|
|
112119
112179
|
justNow: "Ahora mismo",
|
|
112120
112180
|
minutesAgo: "Hace {count} min",
|
|
@@ -112559,6 +112619,7 @@ var careerEducationTab$1 = {
|
|
|
112559
112619
|
nothingToShow: "No hay nada que mostrar aquí."
|
|
112560
112620
|
};
|
|
112561
112621
|
var chatHistoryChatHistoryTab$1 = {
|
|
112622
|
+
userSentiment: "Sentimiento del usuario",
|
|
112562
112623
|
tabConversations: "Conversaciones",
|
|
112563
112624
|
tabExports: "Exportaciones",
|
|
112564
112625
|
searchAgents: "Buscar agentes",
|
|
@@ -113769,6 +113830,10 @@ var disclaimersTabLabels$1 = {
|
|
|
113769
113830
|
}
|
|
113770
113831
|
};
|
|
113771
113832
|
var documentSidebar$1 = {
|
|
113833
|
+
relevance: "Relevancia {percent}%",
|
|
113834
|
+
relevanceHint: "Cuánto coincide este fragmento con la pregunta",
|
|
113835
|
+
preview: "Vista previa",
|
|
113836
|
+
openInNewTab: "Abrir {title} en una pestaña nueva",
|
|
113772
113837
|
retrievedDocuments: "Documentos recuperados"
|
|
113773
113838
|
};
|
|
113774
113839
|
var embedTabLabels$1 = {
|
|
@@ -113878,6 +113943,12 @@ var historyTabLabels$1 = {
|
|
|
113878
113943
|
outOf: "de 5"
|
|
113879
113944
|
},
|
|
113880
113945
|
conversation: {
|
|
113946
|
+
sentiment: {
|
|
113947
|
+
positive: "Positivo",
|
|
113948
|
+
neutral: "Neutral",
|
|
113949
|
+
negative: "Negativo",
|
|
113950
|
+
userSentiment: "Sentimiento del usuario"
|
|
113951
|
+
},
|
|
113881
113952
|
title: "Conversación",
|
|
113882
113953
|
anonymous: "Anónimo",
|
|
113883
113954
|
noResponse: "No hay respuesta disponible",
|
|
@@ -118392,6 +118463,7 @@ var es = {
|
|
|
118392
118463
|
analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$1,
|
|
118393
118464
|
analyticsAnalyticsCourses: analyticsAnalyticsCourses$1,
|
|
118394
118465
|
analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$1,
|
|
118466
|
+
agentSettingsLink: agentSettingsLink$1,
|
|
118395
118467
|
analyticsAgentScopeLink: analyticsAgentScopeLink$1,
|
|
118396
118468
|
analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats$1,
|
|
118397
118469
|
analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats$1,
|
|
@@ -118943,7 +119015,11 @@ var advancedCustomDomain = {
|
|
|
118943
119015
|
noProjects: "你还没有部署任何应用。请先部署一个,然后回来为它设置域名。",
|
|
118944
119016
|
customDomainLabel: "域名",
|
|
118945
119017
|
domainHelpPlatform: "不要带协议前缀或开头的“www.”,例如 app.example.com。",
|
|
118946
|
-
domainHelpApp: "
|
|
119018
|
+
domainHelpApp: "你拥有的域名,不要带协议前缀或开头的“www.”,例如 app.example.com。留空则使用上方的子域名。",
|
|
119019
|
+
subdomainLabel: "子域名",
|
|
119020
|
+
subdomainHelp: "小写字母、数字和连字符,像用户名一样。应用将通过 <子域名>.<平台的共享域名> 提供服务,无需设置任何 DNS 记录。",
|
|
119021
|
+
oneOfSubdomainOrDomain: "请填写子域名或你拥有的域名,二者只填其一。",
|
|
119022
|
+
subdomainInvalid: "子域名为 1 到 63 个小写字母、数字和连字符,且不能以连字符开头或结尾。",
|
|
118947
119023
|
cancel: "取消",
|
|
118948
119024
|
save: "保存",
|
|
118949
119025
|
expandAriaLabel: "展开域名",
|
|
@@ -118965,6 +119041,9 @@ var advancedCustomDomain = {
|
|
|
118965
119041
|
copyNameHostAriaLabel: "复制名称/主机:{domain}",
|
|
118966
119042
|
copyValueAriaLabel: "复制值/目标",
|
|
118967
119043
|
noRecordsYet: "暂无记录。请重新检查该域名以获取记录。",
|
|
119044
|
+
sharedDomainLine: "运行在我们的共享域名上——无需任何设置。",
|
|
119045
|
+
openSite: "打开 {domain}",
|
|
119046
|
+
servesApp: "服务于 {app}",
|
|
118968
119047
|
confirmRemoveTitle: "要移除这个域名吗?",
|
|
118969
119048
|
confirmDeleteBody: "{domain} 将不再用于登录该组织。",
|
|
118970
119049
|
confirmDetachBody: "{domain} 将不再为该应用提供服务,本处和托管服务商处都会解除。",
|
|
@@ -119422,6 +119501,9 @@ var analyticsAnalyticsFinancialStats = {
|
|
|
119422
119501
|
viewTraces: "追踪 →",
|
|
119423
119502
|
costByLLMFooter: "{shown} 个模型 · 按成本排序"
|
|
119424
119503
|
};
|
|
119504
|
+
var agentSettingsLink = {
|
|
119505
|
+
openSettings: "打开 {name} 的设置"
|
|
119506
|
+
};
|
|
119425
119507
|
var analyticsAgentScopeLink = {
|
|
119426
119508
|
scopeToAgent: "查看 {name} 的分析"
|
|
119427
119509
|
};
|
|
@@ -119643,6 +119725,8 @@ var analyticsAnalyticsTopicsStats = {
|
|
|
119643
119725
|
topicsRankedFooter: "共 {total} 个主题,显示 {shown} 个 · 按消息量排序"
|
|
119644
119726
|
};
|
|
119645
119727
|
var analyticsAnalyticsTranscriptsStats = {
|
|
119728
|
+
conversationFallbackTitle: "对话",
|
|
119729
|
+
labelEmail: "邮箱:",
|
|
119646
119730
|
anonymous: "匿名",
|
|
119647
119731
|
justNow: "刚刚",
|
|
119648
119732
|
minutesAgo: "{count} 分钟前",
|
|
@@ -120087,6 +120171,7 @@ var careerEducationTab = {
|
|
|
120087
120171
|
nothingToShow: "暂无内容。"
|
|
120088
120172
|
};
|
|
120089
120173
|
var chatHistoryChatHistoryTab = {
|
|
120174
|
+
userSentiment: "用户情绪",
|
|
120090
120175
|
tabConversations: "对话",
|
|
120091
120176
|
tabExports: "导出",
|
|
120092
120177
|
searchAgents: "搜索代理",
|
|
@@ -121297,6 +121382,10 @@ var disclaimersTabLabels = {
|
|
|
121297
121382
|
}
|
|
121298
121383
|
};
|
|
121299
121384
|
var documentSidebar = {
|
|
121385
|
+
relevance: "相关度 {percent}%",
|
|
121386
|
+
relevanceHint: "该片段与问题的匹配程度",
|
|
121387
|
+
preview: "预览",
|
|
121388
|
+
openInNewTab: "在新标签页中打开 {title}",
|
|
121300
121389
|
retrievedDocuments: "检索到的文档"
|
|
121301
121390
|
};
|
|
121302
121391
|
var embedTabLabels = {
|
|
@@ -121406,6 +121495,12 @@ var historyTabLabels = {
|
|
|
121406
121495
|
outOf: "满分 5 分"
|
|
121407
121496
|
},
|
|
121408
121497
|
conversation: {
|
|
121498
|
+
sentiment: {
|
|
121499
|
+
positive: "积极",
|
|
121500
|
+
neutral: "中性",
|
|
121501
|
+
negative: "消极",
|
|
121502
|
+
userSentiment: "用户情绪"
|
|
121503
|
+
},
|
|
121409
121504
|
title: "对话",
|
|
121410
121505
|
anonymous: "匿名",
|
|
121411
121506
|
noResponse: "暂无回复",
|
|
@@ -125920,6 +126015,7 @@ var zh = {
|
|
|
125920
126015
|
analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail,
|
|
125921
126016
|
analyticsAnalyticsCourses: analyticsAnalyticsCourses,
|
|
125922
126017
|
analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats,
|
|
126018
|
+
agentSettingsLink: agentSettingsLink,
|
|
125923
126019
|
analyticsAgentScopeLink: analyticsAgentScopeLink,
|
|
125924
126020
|
analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats,
|
|
125925
126021
|
analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats,
|
|
@@ -181054,7 +181150,7 @@ function MemoryTab({ org, username }) {
|
|
|
181054
181150
|
username: editingMemory.mentorId ? currentUsername : username, memory: editingMemory, mentorId: editingMemory.mentorId }))] }));
|
|
181055
181151
|
}
|
|
181056
181152
|
|
|
181057
|
-
var _a$
|
|
181153
|
+
var _a$2;
|
|
181058
181154
|
const dl = dataLayer;
|
|
181059
181155
|
/**
|
|
181060
181156
|
* Read a named export, tolerating absence. In real ESM a missing export reads
|
|
@@ -181087,7 +181183,7 @@ const pick = (name, fallback) => { var _a; return ((_a = read(name)) !== null &&
|
|
|
181087
181183
|
/** Whether the resolved data-layer actually supports the chat-privacy feature. */
|
|
181088
181184
|
const CHAT_PRIVACY_SUPPORTED = !!read('ChatPrivacyModeEnum') && !!read('CHAT_PRIVACY_MODES');
|
|
181089
181185
|
const ChatPrivacyModeEnum = read('ChatPrivacyModeEnum');
|
|
181090
|
-
const CHAT_PRIVACY_MODES = ((_a$
|
|
181186
|
+
const CHAT_PRIVACY_MODES = ((_a$2 = read('CHAT_PRIVACY_MODES')) !== null && _a$2 !== void 0 ? _a$2 : []);
|
|
181091
181187
|
read('chatPrivacyApiSlice');
|
|
181092
181188
|
const useGetTenantChatPrivacyConfigQuery = pick('useGetTenantChatPrivacyConfigQuery', noopQuery);
|
|
181093
181189
|
const useUpdateTenantChatPrivacyConfigMutation = pick('useUpdateTenantChatPrivacyConfigMutation', noopMutation);
|
|
@@ -181187,6 +181283,142 @@ function ChatPrivacyTab({ org, username }) {
|
|
|
181187
181283
|
|
|
181188
181284
|
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
181285
|
|
|
181286
|
+
var _a$1;
|
|
181287
|
+
/**
|
|
181288
|
+
* One context object for every copy of this module. The SDK ships several
|
|
181289
|
+
* bundles (`index`, `next`, …) that each inline their own copy of this file,
|
|
181290
|
+
* so a host provider from one bundle would never reach a link rendered by
|
|
181291
|
+
* another (the profile modal comes from `next`; Transcripts from `index`).
|
|
181292
|
+
* Registering the context on `globalThis` under a well-known symbol makes
|
|
181293
|
+
* the copies share it — React is a single external instance, so the object
|
|
181294
|
+
* is interchangeable between them.
|
|
181295
|
+
*/
|
|
181296
|
+
const CONTEXT_KEY = Symbol.for('@iblai/web-containers/agent-settings-launcher');
|
|
181297
|
+
const registry = globalThis;
|
|
181298
|
+
const AgentSettingsLauncherContext = (_a$1 = registry[CONTEXT_KEY]) !== null && _a$1 !== void 0 ? _a$1 : (registry[CONTEXT_KEY] = React__default.createContext(null));
|
|
181299
|
+
function useAgentSettingsLauncher() {
|
|
181300
|
+
return React__default.useContext(AgentSettingsLauncherContext);
|
|
181301
|
+
}
|
|
181302
|
+
/**
|
|
181303
|
+
* An agent's name, linked to its settings where the host lets this viewer
|
|
181304
|
+
* open them; plain text otherwise. Truncates inside an `inline-flex` box so
|
|
181305
|
+
* it keeps the baseline of the label beside it, and neither its clicks nor
|
|
181306
|
+
* its key presses reach a clickable row around it.
|
|
181307
|
+
*/
|
|
181308
|
+
function AgentSettingsLink({ uniqueId, name, fallback = '-', className, testId, }) {
|
|
181309
|
+
var _a, _b;
|
|
181310
|
+
const t = useT();
|
|
181311
|
+
const launcher = useAgentSettingsLauncher();
|
|
181312
|
+
const display = name || uniqueId || fallback;
|
|
181313
|
+
const target = uniqueId ? { uniqueId, name: name || uniqueId } : null;
|
|
181314
|
+
const canOpen = !!launcher && !!target && ((_b = (_a = launcher.canOpenAgentSettings) === null || _a === void 0 ? void 0 : _a.call(launcher, target)) !== null && _b !== void 0 ? _b : true);
|
|
181315
|
+
if (!canOpen || !target) {
|
|
181316
|
+
return (jsx("span", { className: cn('inline-flex max-w-full', className), "data-testid": testId, children: jsx("span", { className: "min-w-0 truncate", children: display }) }));
|
|
181317
|
+
}
|
|
181318
|
+
return (jsx("button", { type: "button", onClick: (event) => {
|
|
181319
|
+
event.stopPropagation();
|
|
181320
|
+
launcher.openAgentSettings(target);
|
|
181321
|
+
},
|
|
181322
|
+
// Rows that open on Enter/Space would otherwise swallow the key press.
|
|
181323
|
+
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 }) }));
|
|
181324
|
+
}
|
|
181325
|
+
|
|
181326
|
+
/**
|
|
181327
|
+
* A conversation's sentiment the way Analytics → Transcripts shows it: a
|
|
181328
|
+
* thumb and "<Sentiment> User Sentiment" — green when positive, blue when
|
|
181329
|
+
* negative, grey otherwise. Renders nothing when the record carries none.
|
|
181330
|
+
*/
|
|
181331
|
+
function ConversationSentiment({ sentiment, labels, className, compact = false, }) {
|
|
181332
|
+
const key = (sentiment !== null && sentiment !== void 0 ? sentiment : '').trim().toLowerCase();
|
|
181333
|
+
if (!key)
|
|
181334
|
+
return null;
|
|
181335
|
+
const Icon = key === 'negative' ? ThumbsDown : ThumbsUp;
|
|
181336
|
+
const tone = key === 'negative' ? 'text-blue-600' : key === 'positive' ? 'text-green-600' : 'text-gray-600';
|
|
181337
|
+
const word = key === 'negative'
|
|
181338
|
+
? labels.negative
|
|
181339
|
+
: key === 'positive'
|
|
181340
|
+
? labels.positive
|
|
181341
|
+
: key === 'neutral'
|
|
181342
|
+
? labels.neutral
|
|
181343
|
+
: key.charAt(0).toUpperCase() + key.slice(1);
|
|
181344
|
+
const text = `${word} ${labels.userSentiment}`;
|
|
181345
|
+
if (compact) {
|
|
181346
|
+
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 })] }) }));
|
|
181347
|
+
}
|
|
181348
|
+
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] })] }));
|
|
181349
|
+
}
|
|
181350
|
+
|
|
181351
|
+
/**
|
|
181352
|
+
* A conversation's topic names, whatever shape the endpoint uses: analytics
|
|
181353
|
+
* returns `["Biology"]`, the chat-history endpoints `[{ name: "Biology" }]`.
|
|
181354
|
+
* Blank entries are dropped and repeats collapsed; order is kept.
|
|
181355
|
+
*/
|
|
181356
|
+
function conversationTopics(topics) {
|
|
181357
|
+
if (!Array.isArray(topics))
|
|
181358
|
+
return [];
|
|
181359
|
+
const names = [];
|
|
181360
|
+
for (const topic of topics) {
|
|
181361
|
+
const raw = typeof topic === 'string'
|
|
181362
|
+
? topic
|
|
181363
|
+
: topic && typeof topic === 'object'
|
|
181364
|
+
? topic.name
|
|
181365
|
+
: undefined;
|
|
181366
|
+
const name = typeof raw === 'string' ? raw.trim() : '';
|
|
181367
|
+
if (name && !names.includes(name))
|
|
181368
|
+
names.push(name);
|
|
181369
|
+
}
|
|
181370
|
+
return names;
|
|
181371
|
+
}
|
|
181372
|
+
|
|
181373
|
+
/** A conversation's topics as the chips Analytics → Transcripts draws. */
|
|
181374
|
+
function ConversationTopics({ topics, className, children, leading, }) {
|
|
181375
|
+
const names = conversationTopics(topics);
|
|
181376
|
+
if (names.length === 0 && !children && !leading)
|
|
181377
|
+
return null;
|
|
181378
|
+
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] }));
|
|
181379
|
+
}
|
|
181380
|
+
|
|
181381
|
+
const clean$2 = (value) => typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
181382
|
+
/** The first human turn of a conversation, from an array or its JSON string form. */
|
|
181383
|
+
function firstHumanMessage(messages) {
|
|
181384
|
+
let turns = messages;
|
|
181385
|
+
if (typeof turns === 'string') {
|
|
181386
|
+
try {
|
|
181387
|
+
turns = JSON.parse(turns);
|
|
181388
|
+
}
|
|
181389
|
+
catch (_a) {
|
|
181390
|
+
return undefined;
|
|
181391
|
+
}
|
|
181392
|
+
}
|
|
181393
|
+
if (!Array.isArray(turns))
|
|
181394
|
+
return undefined;
|
|
181395
|
+
const first = turns[0];
|
|
181396
|
+
return clean$2(first === null || first === void 0 ? void 0 : first.human);
|
|
181397
|
+
}
|
|
181398
|
+
/**
|
|
181399
|
+
* One title for a conversation, on every surface: the backend's `title` when
|
|
181400
|
+
* it has one, else `first_user_message`, else the first human turn, else the
|
|
181401
|
+
* caller's fallback label. Endpoints differ in which of these they return;
|
|
181402
|
+
* this keeps Transcripts and both History tabs naming a conversation alike.
|
|
181403
|
+
*/
|
|
181404
|
+
function conversationTitle(source, fallback) {
|
|
181405
|
+
var _a, _b, _c;
|
|
181406
|
+
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);
|
|
181407
|
+
}
|
|
181408
|
+
|
|
181409
|
+
/**
|
|
181410
|
+
* A conversation's timestamp the way every history surface shows it:
|
|
181411
|
+
* "Sep 4, 2026, 3:56 PM · 21 days ago". Empty for a missing or invalid value.
|
|
181412
|
+
*/
|
|
181413
|
+
const formatSessionDate = (value) => {
|
|
181414
|
+
if (!value)
|
|
181415
|
+
return '';
|
|
181416
|
+
const date = new Date(value);
|
|
181417
|
+
if (Number.isNaN(date.getTime()))
|
|
181418
|
+
return '';
|
|
181419
|
+
return `${format$1(date, 'MMM d, yyyy, h:mm a')} · ${formatDistanceToNow(date, { addSuffix: true })}`;
|
|
181420
|
+
};
|
|
181421
|
+
|
|
181190
181422
|
const offsetFormatCache = {};
|
|
181191
181423
|
const offsetCache = {};
|
|
181192
181424
|
|
|
@@ -220351,14 +220583,6 @@ function stripMarkdown$1(text) {
|
|
|
220351
220583
|
* When a conversation happened: the calendar date and time, followed by the
|
|
220352
220584
|
* relative "x ago" so both the exact day and recency read at a glance.
|
|
220353
220585
|
*/
|
|
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
220586
|
/**
|
|
220363
220587
|
* The list endpoint may serialize `messages` as a JSON string while the detail
|
|
220364
220588
|
* endpoint returns a proper array; accept either shape.
|
|
@@ -220405,11 +220629,6 @@ function downloadTextFile(filename, content, mime) {
|
|
|
220405
220629
|
document.body.removeChild(link);
|
|
220406
220630
|
URL.revokeObjectURL(blobUrl);
|
|
220407
220631
|
}
|
|
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
220632
|
/**
|
|
220414
220633
|
* Agent scope filter — the same inline searchable autocomplete the Billing
|
|
220415
220634
|
* tab's Agent Limits section and the Memory tab use (`SearchSelect`): type to
|
|
@@ -220473,7 +220692,7 @@ function ConversationMessages({ messages, username, agent, fallbackEmail, }) {
|
|
|
220473
220692
|
name: file.name,
|
|
220474
220693
|
contentType: file.content_type,
|
|
220475
220694
|
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(
|
|
220695
|
+
})) })] })] }), 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
220696
|
}) }));
|
|
220478
220697
|
}
|
|
220479
220698
|
/**
|
|
@@ -220482,12 +220701,11 @@ function ConversationMessages({ messages, username, agent, fallbackEmail, }) {
|
|
|
220482
220701
|
* download of just this conversation.
|
|
220483
220702
|
*/
|
|
220484
220703
|
function ConversationPreview({ org, username, session, agent, }) {
|
|
220485
|
-
var _a;
|
|
220486
220704
|
const t = useT();
|
|
220487
220705
|
const inlineMessages = normalizeMessages(session.messages);
|
|
220488
220706
|
const { data: detail, isLoading } = useGetUserChatHistorySessionQuery({ org, userId: username, sessionId: session.id }, { skip: inlineMessages.length > 0 });
|
|
220489
220707
|
const messages = inlineMessages.length > 0 ? inlineMessages : normalizeMessages(detail === null || detail === void 0 ? void 0 : detail.messages);
|
|
220490
|
-
const title = stripMarkdown$1(session.title
|
|
220708
|
+
const title = stripMarkdown$1(conversationTitle({ title: session.title, first_user_message: session.first_user_message, messages }, t('chatHistoryChatHistoryTab.conversation')));
|
|
220491
220709
|
if (isLoading) {
|
|
220492
220710
|
return (jsx("div", { className: "flex items-center justify-center py-10", children: jsx(Spinner, {}) }));
|
|
220493
220711
|
}
|
|
@@ -220524,6 +220742,7 @@ function ChatHistoryTab({ org, username }) {
|
|
|
220524
220742
|
var _a;
|
|
220525
220743
|
const known = agentInfo[session.mentor];
|
|
220526
220744
|
return {
|
|
220745
|
+
uniqueId: session.mentor || undefined,
|
|
220527
220746
|
name: session.mentor_name ||
|
|
220528
220747
|
(known === null || known === void 0 ? void 0 : known.name) ||
|
|
220529
220748
|
((_a = filters.agent) === null || _a === void 0 ? void 0 : _a.name) ||
|
|
@@ -220536,6 +220755,12 @@ function ChatHistoryTab({ org, username }) {
|
|
|
220536
220755
|
const sentimentOptions = ((_a = filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.sentiment) === null || _a === void 0 ? void 0 : _a.length)
|
|
220537
220756
|
? filterOptions.sentiment
|
|
220538
220757
|
: DEFAULT_SENTIMENTS;
|
|
220758
|
+
const sentimentLabels = React__default.useMemo(() => ({
|
|
220759
|
+
positive: t('chatHistoryChatHistoryTab.positive'),
|
|
220760
|
+
neutral: t('chatHistoryChatHistoryTab.neutral'),
|
|
220761
|
+
negative: t('chatHistoryChatHistoryTab.negative'),
|
|
220762
|
+
userSentiment: t('chatHistoryChatHistoryTab.userSentiment'),
|
|
220763
|
+
}), [t]);
|
|
220539
220764
|
const sentimentLabel = React__default.useCallback((value) => {
|
|
220540
220765
|
const key = value.toLowerCase();
|
|
220541
220766
|
if (key === 'positive')
|
|
@@ -220559,22 +220784,18 @@ function ChatHistoryTab({ org, username }) {
|
|
|
220559
220784
|
: 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
220785
|
? t('chatHistoryChatHistoryTab.forbidden')
|
|
220561
220786
|
: 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
|
|
220787
|
+
var _a;
|
|
220563
220788
|
const firstMessage = normalizeMessages(session.messages)[0];
|
|
220564
|
-
const title = stripMarkdown$1(session.
|
|
220565
|
-
(firstMessage === null || firstMessage === void 0 ? void 0 : firstMessage.human) ||
|
|
220566
|
-
session.first_user_message ||
|
|
220567
|
-
t('chatHistoryChatHistoryTab.conversation'));
|
|
220789
|
+
const title = stripMarkdown$1(conversationTitle(session, t('chatHistoryChatHistoryTab.conversation')));
|
|
220568
220790
|
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
220791
|
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
220792
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
220572
220793
|
event.preventDefault();
|
|
220573
220794
|
handleConversationClick(session);
|
|
220574
220795
|
}
|
|
220575
|
-
}, children: [jsxs("div", { className: "w-full", children: [jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [
|
|
220796
|
+
}, 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
220797
|
}) }), 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
|
|
220798
|
+
? stripMarkdown$1(conversationTitle(selectedSession, t('chatHistoryChatHistoryTab.conversation')))
|
|
220578
220799
|
: 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
220800
|
}
|
|
220580
220801
|
|
|
@@ -222940,6 +223161,201 @@ function InvitedUsersDialog({ tenant, onClose }) {
|
|
|
222940
223161
|
}, 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
223162
|
}
|
|
222942
223163
|
|
|
223164
|
+
/**
|
|
223165
|
+
* Whether, and how, a retrieved document can be shown inside the app.
|
|
223166
|
+
*
|
|
223167
|
+
* The Datasets tab accepts PDFs, Office files, CSV/TXT/Markdown, images,
|
|
223168
|
+
* audio, video, ZIPs, GitHub repos, YouTube videos, web pages and crawls, and
|
|
223169
|
+
* links to Google Drive, OneDrive and Dropbox. Only some of those a browser
|
|
223170
|
+
* can render on its own; the rest get no Preview button rather than a blank
|
|
223171
|
+
* frame. Decided from the source URL (extension and host) and, when the
|
|
223172
|
+
* backend sends one, the document's kind.
|
|
223173
|
+
*/
|
|
223174
|
+
const IMAGE = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp', 'avif']);
|
|
223175
|
+
const AUDIO = new Set(['mp3', 'wav', 'ogg', 'oga', 'm4a', 'aac', 'flac']);
|
|
223176
|
+
const VIDEO = new Set(['mp4', 'webm', 'ogv', 'mov', 'm4v']);
|
|
223177
|
+
/** Browsers cannot render these; a frame would only offer a download. */
|
|
223178
|
+
const NOT_VIEWABLE = new Set([
|
|
223179
|
+
'doc',
|
|
223180
|
+
'docx',
|
|
223181
|
+
'ppt',
|
|
223182
|
+
'pptx',
|
|
223183
|
+
'xls',
|
|
223184
|
+
'xlsx',
|
|
223185
|
+
'odt',
|
|
223186
|
+
'odp',
|
|
223187
|
+
'ods',
|
|
223188
|
+
'rtf',
|
|
223189
|
+
'zip',
|
|
223190
|
+
'rar',
|
|
223191
|
+
'7z',
|
|
223192
|
+
'tar',
|
|
223193
|
+
'gz',
|
|
223194
|
+
'tgz',
|
|
223195
|
+
]);
|
|
223196
|
+
/** Hosts that refuse to be framed, or need the viewer's own sign-in. */
|
|
223197
|
+
const UNFRAMEABLE_HOSTS = [
|
|
223198
|
+
'github.com',
|
|
223199
|
+
'dropbox.com',
|
|
223200
|
+
'onedrive.live.com',
|
|
223201
|
+
'1drv.ms',
|
|
223202
|
+
'sharepoint.com',
|
|
223203
|
+
];
|
|
223204
|
+
const hostMatches = (host, domain) => host === domain || host.endsWith(`.${domain}`);
|
|
223205
|
+
const extensionOf = (pathname) => {
|
|
223206
|
+
var _a;
|
|
223207
|
+
const last = (_a = pathname.split('/').pop()) !== null && _a !== void 0 ? _a : '';
|
|
223208
|
+
const dot = last.lastIndexOf('.');
|
|
223209
|
+
return dot > 0 ? last.slice(dot + 1).toLowerCase() : '';
|
|
223210
|
+
};
|
|
223211
|
+
const youtubeEmbed = (url) => {
|
|
223212
|
+
var _a;
|
|
223213
|
+
const host = url.hostname.toLowerCase().replace(/^(www|m)\./, '');
|
|
223214
|
+
let id = null;
|
|
223215
|
+
if (host === 'youtu.be')
|
|
223216
|
+
id = (_a = url.pathname.split('/')[1]) !== null && _a !== void 0 ? _a : null;
|
|
223217
|
+
else if (host === 'youtube.com' || host === 'youtube-nocookie.com') {
|
|
223218
|
+
const [, section, rest] = url.pathname.split('/');
|
|
223219
|
+
if (section === 'watch')
|
|
223220
|
+
id = url.searchParams.get('v');
|
|
223221
|
+
else if (section === 'embed' || section === 'shorts' || section === 'live' || section === 'v')
|
|
223222
|
+
id = rest !== null && rest !== void 0 ? rest : null;
|
|
223223
|
+
}
|
|
223224
|
+
return id && /^[\w-]{6,}$/.test(id) ? `https://www.youtube-nocookie.com/embed/${id}` : null;
|
|
223225
|
+
};
|
|
223226
|
+
const googleEmbed = (url) => {
|
|
223227
|
+
const host = url.hostname.toLowerCase();
|
|
223228
|
+
if (host === 'drive.google.com') {
|
|
223229
|
+
const file = url.pathname.match(/^\/file\/d\/([\w-]+)/);
|
|
223230
|
+
if (file)
|
|
223231
|
+
return `https://drive.google.com/file/d/${file[1]}/preview`;
|
|
223232
|
+
const open = url.pathname === '/open' && url.searchParams.get('id');
|
|
223233
|
+
if (open)
|
|
223234
|
+
return `https://drive.google.com/file/d/${open}/preview`;
|
|
223235
|
+
return null;
|
|
223236
|
+
}
|
|
223237
|
+
if (host === 'docs.google.com') {
|
|
223238
|
+
const doc = url.pathname.match(/^\/(document|spreadsheets|presentation)\/d\/([\w-]+)/);
|
|
223239
|
+
return doc ? `https://docs.google.com/${doc[1]}/d/${doc[2]}/preview` : null;
|
|
223240
|
+
}
|
|
223241
|
+
return null;
|
|
223242
|
+
};
|
|
223243
|
+
/** A kind the backend may name on the document, when it says one. */
|
|
223244
|
+
const kindFromHint = (hint) => {
|
|
223245
|
+
const h = (hint !== null && hint !== void 0 ? hint : '').toLowerCase();
|
|
223246
|
+
if (!h)
|
|
223247
|
+
return null;
|
|
223248
|
+
if (/image|photo|picture/.test(h))
|
|
223249
|
+
return 'image';
|
|
223250
|
+
if (/audio|podcast/.test(h))
|
|
223251
|
+
return 'audio';
|
|
223252
|
+
if (/video(?!.*youtube)/.test(h) && !/youtube/.test(h))
|
|
223253
|
+
return 'video';
|
|
223254
|
+
if (/docx|word|powerpoint|pptx|excel|xlsx|spreadsheet|zip|archive|course/.test(h))
|
|
223255
|
+
return 'none';
|
|
223256
|
+
return null;
|
|
223257
|
+
};
|
|
223258
|
+
/**
|
|
223259
|
+
* `null` when the document cannot be shown here: no URL, a host that refuses
|
|
223260
|
+
* framing, or a file type a browser cannot render (Office files, archives).
|
|
223261
|
+
*/
|
|
223262
|
+
function previewPlan(source, hint) {
|
|
223263
|
+
const raw = (source !== null && source !== void 0 ? source : '').trim();
|
|
223264
|
+
if (!/^https?:\/\//i.test(raw))
|
|
223265
|
+
return null;
|
|
223266
|
+
let url;
|
|
223267
|
+
try {
|
|
223268
|
+
url = new URL(raw);
|
|
223269
|
+
}
|
|
223270
|
+
catch (_a) {
|
|
223271
|
+
return null;
|
|
223272
|
+
}
|
|
223273
|
+
const host = url.hostname.toLowerCase();
|
|
223274
|
+
const yt = youtubeEmbed(url);
|
|
223275
|
+
if (yt)
|
|
223276
|
+
return { kind: 'frame', src: yt };
|
|
223277
|
+
// A YouTube page that is not a video (a channel, a playlist) cannot be framed.
|
|
223278
|
+
if (/(^|\.)(youtube\.com|youtu\.be|youtube-nocookie\.com)$/.test(host))
|
|
223279
|
+
return null;
|
|
223280
|
+
const google = googleEmbed(url);
|
|
223281
|
+
if (google)
|
|
223282
|
+
return { kind: 'frame', src: google };
|
|
223283
|
+
if (host === 'drive.google.com' || host === 'docs.google.com')
|
|
223284
|
+
return null;
|
|
223285
|
+
if (host === 'raw.githubusercontent.com')
|
|
223286
|
+
return { kind: 'frame', src: raw };
|
|
223287
|
+
if (UNFRAMEABLE_HOSTS.some((domain) => hostMatches(host, domain)))
|
|
223288
|
+
return null;
|
|
223289
|
+
const hinted = kindFromHint(hint);
|
|
223290
|
+
if (hinted === 'none')
|
|
223291
|
+
return null;
|
|
223292
|
+
if (hinted)
|
|
223293
|
+
return { kind: hinted, src: raw };
|
|
223294
|
+
const ext = extensionOf(url.pathname);
|
|
223295
|
+
if (IMAGE.has(ext))
|
|
223296
|
+
return { kind: 'image', src: raw };
|
|
223297
|
+
if (AUDIO.has(ext))
|
|
223298
|
+
return { kind: 'audio', src: raw };
|
|
223299
|
+
if (VIDEO.has(ext))
|
|
223300
|
+
return { kind: 'video', src: raw };
|
|
223301
|
+
if (NOT_VIEWABLE.has(ext))
|
|
223302
|
+
return null;
|
|
223303
|
+
// PDFs, text, CSV, Markdown, HTML, JSON and extension-less API URLs: the
|
|
223304
|
+
// browser renders these itself (its PDF viewer, or as text or a page).
|
|
223305
|
+
return { kind: 'frame', src: raw };
|
|
223306
|
+
}
|
|
223307
|
+
|
|
223308
|
+
/** The shape a retrieved document is listed by: the session query's `VectorResult`
|
|
223309
|
+
* and a transcript's `TranscriptRetrievedDocument` both satisfy it. */
|
|
223310
|
+
/** Only `http(s)` sources are links; a bare file name or dataset id is not. */
|
|
223311
|
+
const isHttpUrl = (value) => /^https?:\/\//i.test((value !== null && value !== void 0 ? value : '').trim());
|
|
223312
|
+
/** `0.7` → `70`; anything unusable → undefined. */
|
|
223313
|
+
const relevancePercent = (score) => typeof score === 'number' && Number.isFinite(score)
|
|
223314
|
+
? Math.round(Math.max(0, Math.min(1, score)) * 100)
|
|
223315
|
+
: undefined;
|
|
223316
|
+
/**
|
|
223317
|
+
* The document's URL with a text fragment for the matched passage's opening
|
|
223318
|
+
* words, so a browser that supports fragments (Chromium for HTML pages) opens
|
|
223319
|
+
* the page scrolled to, and highlighting, the passage. PDFs and other
|
|
223320
|
+
* viewers ignore it; a frame cannot honour it, so only new-tab links get it.
|
|
223321
|
+
*/
|
|
223322
|
+
const deepLink = (url, snippet) => {
|
|
223323
|
+
const words = (snippet !== null && snippet !== void 0 ? snippet : '').replace(/\s+/g, ' ').trim().split(' ').slice(0, 8).join(' ');
|
|
223324
|
+
const text = words.replace(/[\s.,;:!?"'”’)\]]+$/, '');
|
|
223325
|
+
if (text.length < 12)
|
|
223326
|
+
return url;
|
|
223327
|
+
return `${url.split('#')[0]}#:~:text=${encodeURIComponent(text)}`;
|
|
223328
|
+
};
|
|
223329
|
+
const hostOf = (value) => {
|
|
223330
|
+
try {
|
|
223331
|
+
return new URL(value).host;
|
|
223332
|
+
}
|
|
223333
|
+
catch (_a) {
|
|
223334
|
+
return '';
|
|
223335
|
+
}
|
|
223336
|
+
};
|
|
223337
|
+
/**
|
|
223338
|
+
* One retrieved document: its title (a new-tab link when the source is a
|
|
223339
|
+
* URL), its relevance, the matched passage, and — for URLs — a preview the
|
|
223340
|
+
* reader can open (the title link beside it still opens the source in a new
|
|
223341
|
+
* tab).
|
|
223342
|
+
*/
|
|
223343
|
+
function RetrievedDocumentRow({ doc }) {
|
|
223344
|
+
var _a, _b;
|
|
223345
|
+
const t = useT();
|
|
223346
|
+
const [previewOpen, setPreviewOpen] = React.useState(false);
|
|
223347
|
+
const source = ((_a = doc.source) !== null && _a !== void 0 ? _a : '').trim();
|
|
223348
|
+
const url = isHttpUrl(source) ? source : null;
|
|
223349
|
+
const title = doc.title || (url ? hostOf(url) : source);
|
|
223350
|
+
const relevance = relevancePercent(doc.score);
|
|
223351
|
+
const openHref = url ? deepLink(url, doc.snippet) : null;
|
|
223352
|
+
// Preview only what a browser can show; Office files, archives and
|
|
223353
|
+
// unframeable hosts get no button rather than a blank frame.
|
|
223354
|
+
const preview = previewPlan(source, doc.type);
|
|
223355
|
+
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",
|
|
223356
|
+
// Inline: the size must not depend on a host's Tailwind scan.
|
|
223357
|
+
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 })] })] }) }));
|
|
223358
|
+
}
|
|
222943
223359
|
function DocumentSidebar({ isModal = false, sessionId = '', documents, }) {
|
|
222944
223360
|
const t = useT();
|
|
222945
223361
|
const [isCollapsed, setIsCollapsed] = React.useState(false);
|
|
@@ -222972,10 +223388,7 @@ function DocumentSidebar({ isModal = false, sessionId = '', documents, }) {
|
|
|
222972
223388
|
backgroundColor: isCollapsed && !isModal ? 'white' : '#F3F6FB',
|
|
222973
223389
|
// In the dialog the parent bounds the height; the rail caps itself.
|
|
222974
223390
|
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 }));
|
|
223391
|
+
}, 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
223392
|
}
|
|
222980
223393
|
|
|
222981
223394
|
/**
|
|
@@ -230320,15 +230733,23 @@ const sanitizeDomain = (domain) => domain
|
|
|
230320
230733
|
.replace(/^https?:\/\//, '')
|
|
230321
230734
|
.replace(/\/.*$/, '')
|
|
230322
230735
|
.replace(/^www\./, '');
|
|
230323
|
-
|
|
230736
|
+
/** One label under the platform's shared domain — the backend's own rule. */
|
|
230737
|
+
const SUBDOMAIN_RE = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
230738
|
+
/** Typed like a username: only case and surrounding whitespace are forgiven. */
|
|
230739
|
+
const sanitizeSubdomain = (subdomain) => subdomain.trim().toLowerCase();
|
|
230740
|
+
const AddDomainDialog = ({ open, onOpenChange, canAddPlatformDomain, defaultMode = 'platform', projects, isLoadingProjects, isSubmitting, onSubmitPlatformDomain, onSubmitAppDomain, }) => {
|
|
230741
|
+
var _a;
|
|
230324
230742
|
const t = useT();
|
|
230325
|
-
const
|
|
230743
|
+
const initialMode = canAddPlatformDomain ? defaultMode : 'app';
|
|
230744
|
+
const [mode, setMode] = useState(initialMode);
|
|
230326
230745
|
const [domainValue, setDomainValue] = useState('');
|
|
230746
|
+
const [subdomainValue, setSubdomainValue] = useState('');
|
|
230327
230747
|
const [projectId, setProjectId] = useState('');
|
|
230328
230748
|
const reset = () => {
|
|
230329
230749
|
setDomainValue('');
|
|
230750
|
+
setSubdomainValue('');
|
|
230330
230751
|
setProjectId('');
|
|
230331
|
-
setMode(
|
|
230752
|
+
setMode(initialMode);
|
|
230332
230753
|
};
|
|
230333
230754
|
const close = () => {
|
|
230334
230755
|
reset();
|
|
@@ -230340,10 +230761,27 @@ const AddDomainDialog = ({ open, onOpenChange, canAddPlatformDomain, projects, i
|
|
|
230340
230761
|
await onSubmitPlatformDomain(sanitizeDomain(domainValue));
|
|
230341
230762
|
}
|
|
230342
230763
|
else {
|
|
230343
|
-
await onSubmitAppDomain(Number(projectId),
|
|
230764
|
+
await onSubmitAppDomain(Number(projectId), {
|
|
230765
|
+
domain: sanitizeDomain(domainValue),
|
|
230766
|
+
subdomain: sanitizeSubdomain(subdomainValue),
|
|
230767
|
+
});
|
|
230344
230768
|
}
|
|
230345
230769
|
};
|
|
230346
|
-
const
|
|
230770
|
+
const hasDomain = domainValue.trim().length > 0;
|
|
230771
|
+
const subdomain = sanitizeSubdomain(subdomainValue);
|
|
230772
|
+
const hasSubdomain = subdomain.length > 0;
|
|
230773
|
+
// An app is served at exactly one address, and a subdomain has to be one the
|
|
230774
|
+
// backend will take — say which rule is unmet, and only once something was
|
|
230775
|
+
// typed, so an untouched form stays quiet.
|
|
230776
|
+
const appAddressProblem = mode === 'app' && hasDomain && hasSubdomain
|
|
230777
|
+
? 'both'
|
|
230778
|
+
: mode === 'app' && hasSubdomain && !SUBDOMAIN_RE.test(subdomain)
|
|
230779
|
+
? 'invalid'
|
|
230780
|
+
: null;
|
|
230781
|
+
const canSubmit = mode === 'platform'
|
|
230782
|
+
? hasDomain
|
|
230783
|
+
: projectId.trim().length > 0 && (hasDomain || hasSubdomain) && appAddressProblem === null;
|
|
230784
|
+
const selectedProject = projects.find((project) => String(project.id) === projectId);
|
|
230347
230785
|
return (jsx(Dialog, { open: open, onOpenChange: (next) => {
|
|
230348
230786
|
if (!next) {
|
|
230349
230787
|
reset();
|
|
@@ -230352,9 +230790,11 @@ const AddDomainDialog = ({ open, onOpenChange, canAddPlatformDomain, projects, i
|
|
|
230352
230790
|
}, children: jsxs(DialogContent, { className: "sm:max-w-[480px]", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: t('advancedCustomDomain.dialogTitle') }), jsx(DialogDescription, { children: t('advancedCustomDomain.dialogDescription') })] }), jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "add-domain-kind", className: "text-sm", children: t('advancedCustomDomain.kindLabel') }), jsxs(Select$1, { value: mode, onValueChange: (next) => setMode(next), children: [jsx(SelectTrigger, { id: "add-domain-kind", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [canAddPlatformDomain && (jsx(SelectItem, { value: "platform", children: t('advancedCustomDomain.kindPlatform') })), jsx(SelectItem, { value: "app", children: t('advancedCustomDomain.kindApp') })] })] })] }), mode === 'app' && (jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "add-domain-project", className: "text-sm", children: t('advancedCustomDomain.projectLabel') }), isLoadingProjects ? (jsx("p", { className: "text-sm text-[#646464]", children: t('advancedCustomDomain.loading') })) : projects.length === 0 ? (
|
|
230353
230791
|
// The backend lists only the caller's own projects, so this is
|
|
230354
230792
|
// "you have not deployed anything", not "the platform has not".
|
|
230355
|
-
jsx("p", { className: "text-sm text-[#646464]", children: t('advancedCustomDomain.noProjects') })) : (jsxs(Select$1, { value: projectId, onValueChange: setProjectId, children: [jsx(SelectTrigger, { id: "add-domain-project", children: jsx(SelectValue, { placeholder: t('advancedCustomDomain.projectPlaceholder') }) }), jsx(SelectContent, { children: projects.map((project) => (jsx(SelectItem, { value: String(project.id), children: project.name }, project.id))) })] }))] })), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "add-domain-
|
|
230793
|
+
jsx("p", { className: "text-sm text-[#646464]", children: t('advancedCustomDomain.noProjects') })) : (jsxs(Select$1, { value: projectId, onValueChange: setProjectId, children: [jsx(SelectTrigger, { id: "add-domain-project", children: jsx(SelectValue, { placeholder: t('advancedCustomDomain.projectPlaceholder') }) }), jsx(SelectContent, { children: projects.map((project) => (jsx(SelectItem, { value: String(project.id), children: project.name }, project.id))) })] }))] })), mode === 'app' && (jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "add-domain-subdomain", className: "text-sm", children: t('advancedCustomDomain.subdomainLabel') }), jsx(Input, { id: "add-domain-subdomain", value: subdomainValue, onChange: (event) => setSubdomainValue(event.target.value),
|
|
230794
|
+
// The app's own name is the suggestion the deploy skill makes.
|
|
230795
|
+
placeholder: (_a = selectedProject === null || selectedProject === void 0 ? void 0 : selectedProject.name) !== null && _a !== void 0 ? _a : '', className: "w-full" }), jsx("p", { className: "text-xs text-[#646464]", children: t('advancedCustomDomain.subdomainHelp') })] })), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "add-domain-name", className: "text-sm", children: t('advancedCustomDomain.customDomainLabel') }), jsx(Input, { id: "add-domain-name", value: domainValue, onChange: (event) => setDomainValue(event.target.value), placeholder: "example.com", className: "w-full", required: mode === 'platform' }), jsx("p", { className: "text-xs text-[#646464]", children: mode === 'app'
|
|
230356
230796
|
? t('advancedCustomDomain.domainHelpApp')
|
|
230357
|
-
: t('advancedCustomDomain.domainHelpPlatform') })] }), jsxs("div", { className: "flex justify-end gap-2", children: [jsx(Button$1, { type: "button", variant: "outline", onClick: close, children: t('advancedCustomDomain.cancel') }), jsxs(Button$1, { type: "submit", disabled: isSubmitting || !canSubmit, children: [isSubmitting && jsx(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), t('advancedCustomDomain.save')] })] })] })] }) }));
|
|
230797
|
+
: t('advancedCustomDomain.domainHelpPlatform') }), appAddressProblem === 'both' && (jsx("p", { className: "text-xs text-[#646464]", role: "status", children: t('advancedCustomDomain.oneOfSubdomainOrDomain') })), appAddressProblem === 'invalid' && (jsx("p", { className: "text-xs text-[#646464]", role: "status", children: t('advancedCustomDomain.subdomainInvalid') }))] }), jsxs("div", { className: "flex justify-end gap-2", children: [jsx(Button$1, { type: "button", variant: "outline", onClick: close, children: t('advancedCustomDomain.cancel') }), jsxs(Button$1, { type: "submit", disabled: isSubmitting || !canSubmit, children: [isSubmitting && jsx(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), t('advancedCustomDomain.save')] })] })] })] }) }));
|
|
230358
230798
|
};
|
|
230359
230799
|
|
|
230360
230800
|
var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
|
|
@@ -230546,7 +230986,7 @@ const resolveCname = async (domain, target) => {
|
|
|
230546
230986
|
const body = await response.json();
|
|
230547
230987
|
return Boolean((_a = body === null || body === void 0 ? void 0 : body.Answer) === null || _a === void 0 ? void 0 : _a.some((answer) => { var _a; return ((_a = answer.data) !== null && _a !== void 0 ? _a : '').replace(/\.$/, '') === target; }));
|
|
230548
230988
|
};
|
|
230549
|
-
const DomainRow = ({ row, sslValue, onReverify, onRemove, isBusy, onStatusChange, }) => {
|
|
230989
|
+
const DomainRow = ({ row, sharedApp, sslValue, onReverify, onRemove, isBusy, onStatusChange, }) => {
|
|
230550
230990
|
var _a;
|
|
230551
230991
|
const t = useT();
|
|
230552
230992
|
const isHosted = row.spa === VERCEL_SPA;
|
|
@@ -230618,7 +231058,7 @@ const DomainRow = ({ row, sslValue, onReverify, onRemove, isBusy, onStatusChange
|
|
|
230618
231058
|
const statusBadge = (jsx("span", { className: status === 'verified'
|
|
230619
231059
|
? 'rounded bg-green-100 px-2 py-1 text-xs text-green-800'
|
|
230620
231060
|
: 'rounded bg-gray-100 px-2 py-1 text-xs text-gray-600', children: status === 'checking' ? (jsxs("span", { className: "flex items-center gap-1", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), t('advancedCustomDomain.verifying')] })) : (statusLabel()) }));
|
|
230621
|
-
return (jsxs("div", { className: "space-y-3 rounded-lg border border-gray-200 p-3 dark:border-gray-700", children: [jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm", children: row.custom_domain }), jsx("span", { className: "text-xs text-[#646464]", children: isHosted ? t('advancedCustomDomain.kindApp') : t('advancedCustomDomain.kindPlatform') }), statusBadge] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button$1, { variant: "outline", size: "sm", onClick: () => (isHosted ? void onReverify(row) : void checkSpaDomain()), disabled: isBusy || status === 'checking' || (!isHosted && !row.registered_with_dns_pro), "aria-label": t('advancedCustomDomain.reverifyAriaLabel', { domain: row.custom_domain }), children: isBusy || status === 'checking' ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" })) : (jsxs(Fragment$1, { children: [jsx(RefreshCw, { className: "mr-1 h-4 w-4", "aria-hidden": "true" }), t('advancedCustomDomain.reverify')] })) }), jsx(Button$1, { variant: "outline", size: "sm", className: "text-red-600 hover:text-red-700", onClick: () => setConfirmOpen(true), disabled: isBusy, "aria-label": t('advancedCustomDomain.removeAriaLabel', { domain: row.custom_domain }), children: isHosted ? t('advancedCustomDomain.detach') : t('advancedCustomDomain.delete') })] })] }), records.length > 0 ? (jsxs(Table$1, { className: "table-fixed", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { children: [jsx(TableHead, { className: "w-[90px]", children: t('advancedCustomDomain.tableType') }), jsx(TableHead, { className: "w-1/3", children: t('advancedCustomDomain.tableNameHost') }), jsx(TableHead, { children: t('advancedCustomDomain.tableValue') })] }) }), jsx(TableBody, { children: records.map((record, index) => (jsxs(TableRow$1, { children: [jsx(TableCell$1, { className: "text-sm", children: record.type }), jsx(TableCell$1, { children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm break-all", children: record.name }), jsx(Button$1, { type: "button", variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0", onClick: () => handleCopy(record.name, `name-${index}`), "aria-label": t('advancedCustomDomain.copyNameHostAriaLabel', {
|
|
231061
|
+
return (jsxs("div", { className: "space-y-3 rounded-lg border border-gray-200 p-3 dark:border-gray-700", children: [jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm", children: row.custom_domain }), jsx("span", { className: "text-xs text-[#646464]", children: isHosted ? t('advancedCustomDomain.kindApp') : t('advancedCustomDomain.kindPlatform') }), statusBadge] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button$1, { variant: "outline", size: "sm", onClick: () => (isHosted ? void onReverify(row) : void checkSpaDomain()), disabled: isBusy || status === 'checking' || (!isHosted && !row.registered_with_dns_pro), "aria-label": t('advancedCustomDomain.reverifyAriaLabel', { domain: row.custom_domain }), children: isBusy || status === 'checking' ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" })) : (jsxs(Fragment$1, { children: [jsx(RefreshCw, { className: "mr-1 h-4 w-4", "aria-hidden": "true" }), t('advancedCustomDomain.reverify')] })) }), jsx(Button$1, { variant: "outline", size: "sm", className: "text-red-600 hover:text-red-700", onClick: () => setConfirmOpen(true), disabled: isBusy, "aria-label": t('advancedCustomDomain.removeAriaLabel', { domain: row.custom_domain }), children: isHosted ? t('advancedCustomDomain.detach') : t('advancedCustomDomain.delete') })] })] }), sharedApp ? (jsxs("div", { className: "space-y-1 text-sm text-[#646464]", children: [jsxs("p", { children: [t('advancedCustomDomain.sharedDomainLine'), ' ', jsx("a", { href: `https://${row.custom_domain}`, target: "_blank", rel: "noreferrer", className: "underline", children: t('advancedCustomDomain.openSite', { domain: row.custom_domain }) })] }), jsx("p", { className: "text-xs", children: t('advancedCustomDomain.servesApp', { app: sharedApp.name }) })] })) : records.length > 0 ? (jsxs(Table$1, { className: "table-fixed", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { children: [jsx(TableHead, { className: "w-[90px]", children: t('advancedCustomDomain.tableType') }), jsx(TableHead, { className: "w-1/3", children: t('advancedCustomDomain.tableNameHost') }), jsx(TableHead, { children: t('advancedCustomDomain.tableValue') })] }) }), jsx(TableBody, { children: records.map((record, index) => (jsxs(TableRow$1, { children: [jsx(TableCell$1, { className: "text-sm", children: record.type }), jsx(TableCell$1, { children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm break-all", children: record.name }), jsx(Button$1, { type: "button", variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0", onClick: () => handleCopy(record.name, `name-${index}`), "aria-label": t('advancedCustomDomain.copyNameHostAriaLabel', {
|
|
230622
231062
|
domain: record.name,
|
|
230623
231063
|
}), children: copiedKey === `name-${index}` ? (jsx(Check, { className: "h-4 w-4 text-blue-600", "aria-hidden": "true" })) : (jsx(Copy, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) }), jsxs(TableCell$1, { children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm break-all", children: record.value }), jsx(Button$1, { type: "button", variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0", onClick: () => handleCopy(record.value, `value-${index}`), "aria-label": t('advancedCustomDomain.copyValueAriaLabel'), children: copiedKey === `value-${index}` ? (jsx(Check, { className: "h-4 w-4 text-blue-600", "aria-hidden": "true" })) : (jsx(Copy, { className: "h-4 w-4", "aria-hidden": "true" })) })] }), record.reason && jsx("p", { className: "mt-1 text-xs text-[#646464]", children: record.reason })] })] }, `${record.type}-${record.name}-${record.value}`))) })] })) : (jsx("p", { className: "text-sm text-[#646464]", children: t('advancedCustomDomain.noRecordsYet') })), jsx(AlertDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: jsxs(AlertDialogContent, { children: [jsxs(AlertDialogHeader, { children: [jsx(AlertDialogTitle, { children: t('advancedCustomDomain.confirmRemoveTitle') }), jsx(AlertDialogDescription, { children: isHosted
|
|
230624
231064
|
? t('advancedCustomDomain.confirmDetachBody', { domain: row.custom_domain })
|
|
@@ -230676,9 +231116,20 @@ const CustomDomainsContent = ({ platformKey, username, currentSPA, currentPlatfo
|
|
|
230676
231116
|
const { data, isLoading, isFetching, refetch } = useGetCustomDomainsQuery({
|
|
230677
231117
|
params: { platform_key: platformKey },
|
|
230678
231118
|
});
|
|
230679
|
-
// Only the caller's own deployed apps are listable
|
|
230680
|
-
//
|
|
230681
|
-
|
|
231119
|
+
// Only the caller's own deployed apps are listable. The Add dialog offers
|
|
231120
|
+
// them, and a row on the platform's shared domain names the app it serves
|
|
231121
|
+
// (`shared_domain` is that address), so the list is wanted from the start.
|
|
231122
|
+
const { data: projectData, isFetching: isLoadingProjects } = useGetHostingProjectsQuery({ org: platformKey, username }, { skip: !username });
|
|
231123
|
+
// The caller's app served at a shared-domain address, by that address. A
|
|
231124
|
+
// row without a match is an own domain (or another user's app): it keeps
|
|
231125
|
+
// its records.
|
|
231126
|
+
const sharedAppFor = (row) => {
|
|
231127
|
+
var _a;
|
|
231128
|
+
return row.spa === VERCEL_SPA
|
|
231129
|
+
? ((_a = projectData === null || projectData === void 0 ? void 0 : projectData.projects) !== null && _a !== void 0 ? _a : []).find((project) => !!project.shared_domain &&
|
|
231130
|
+
project.shared_domain.toLowerCase() === row.custom_domain.toLowerCase())
|
|
231131
|
+
: undefined;
|
|
231132
|
+
};
|
|
230682
231133
|
const [createCustomDomain, { isLoading: isCreating }] = useCreateCustomDomainMutation();
|
|
230683
231134
|
const [deleteCustomDomain] = useDeleteCustomDomainMutation();
|
|
230684
231135
|
const [createHostingProjectDomain, { isLoading: isAttaching }] = useCreateHostingProjectDomainMutation();
|
|
@@ -230707,10 +231158,15 @@ const CustomDomainsContent = ({ platformKey, username, currentSPA, currentPlatfo
|
|
|
230707
231158
|
: typeof window !== 'undefined'
|
|
230708
231159
|
? window.location.hostname.split('.').slice(-2).join('.')
|
|
230709
231160
|
: 'iblai.app'}`;
|
|
230710
|
-
//
|
|
230711
|
-
//
|
|
230712
|
-
|
|
230713
|
-
|
|
231161
|
+
// The Add dialog offers the sign-in kind whenever it knows which app to bind
|
|
231162
|
+
// the domain to. How many sign-in domains an app may have is the platform's
|
|
231163
|
+
// decision, not the panel's: a refusal comes back as the platform's own
|
|
231164
|
+
// message (`reportError` shows it), so no count is enforced here.
|
|
231165
|
+
const canAddPlatformDomain = Boolean(currentSPA);
|
|
231166
|
+
// The kind the dialog opens on: an app that already has a sign-in domain is
|
|
231167
|
+
// more often adding one for a deployed app; the sign-in kind stays one
|
|
231168
|
+
// click away either way.
|
|
231169
|
+
const hasPlatformDomain = useMemo(() => customDomains.some((domain) => { var _a; return domain.spa !== VERCEL_SPA && ((_a = domain.spa) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(currentSPA.toLowerCase())); }), [customDomains, currentSPA]);
|
|
230714
231170
|
/**
|
|
230715
231171
|
* The status decides what the user should do next, so it gets its own
|
|
230716
231172
|
* message. 409 shares 400's: both mean "not this domain, not here", and the
|
|
@@ -230735,10 +231191,10 @@ const CustomDomainsContent = ({ platformKey, username, currentSPA, currentPlatfo
|
|
|
230735
231191
|
};
|
|
230736
231192
|
const reportError = (error, fallback) => {
|
|
230737
231193
|
const status = error === null || error === void 0 ? void 0 : error.status;
|
|
230738
|
-
// The server's own words go underneath the headline
|
|
230739
|
-
//
|
|
230740
|
-
|
|
230741
|
-
toast.error(headlineForStatus(status, fallback), { description });
|
|
231194
|
+
// The server's own words go underneath the headline. A 409 body never
|
|
231195
|
+
// names the organization holding the domain — the backend keeps that out
|
|
231196
|
+
// on purpose — and for a taken subdomain it carries the way out.
|
|
231197
|
+
toast.error(headlineForStatus(status, fallback), { description: serverDetail(error) });
|
|
230742
231198
|
};
|
|
230743
231199
|
const handleAddPlatformDomain = async (domain) => {
|
|
230744
231200
|
if (!domain) {
|
|
@@ -230762,15 +231218,16 @@ const CustomDomainsContent = ({ platformKey, username, currentSPA, currentPlatfo
|
|
|
230762
231218
|
reportError(error, t('advancedCustomDomain.createError'));
|
|
230763
231219
|
}
|
|
230764
231220
|
};
|
|
230765
|
-
const handleAddAppDomain = async (project,
|
|
231221
|
+
const handleAddAppDomain = async (project, address) => {
|
|
230766
231222
|
try {
|
|
230767
|
-
//
|
|
230768
|
-
// reads
|
|
231223
|
+
// Only the address that was filled in is sent; the dialog guarantees
|
|
231224
|
+
// exactly one. The backend reads an absent key, never an empty string.
|
|
230769
231225
|
await createHostingProjectDomain({
|
|
230770
231226
|
org: platformKey,
|
|
230771
231227
|
username,
|
|
230772
231228
|
project,
|
|
230773
|
-
domain: domain || undefined,
|
|
231229
|
+
domain: address.domain || undefined,
|
|
231230
|
+
subdomain: address.subdomain || undefined,
|
|
230774
231231
|
}).unwrap();
|
|
230775
231232
|
await refetch();
|
|
230776
231233
|
toast.success(t('advancedCustomDomain.createSuccess'));
|
|
@@ -230835,7 +231292,7 @@ const CustomDomainsContent = ({ platformKey, username, currentSPA, currentPlatfo
|
|
|
230835
231292
|
setIsModalOpen(true);
|
|
230836
231293
|
}, children: [jsx(Plus, { className: "h-4 w-4", "aria-hidden": "true" }), t('advancedCustomDomain.add')] }), jsx("button", { onClick: () => setIsCollapsed((previous) => !previous), className: "rounded p-1 hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 focus:outline-none dark:hover:bg-gray-800", "aria-label": isCollapsed
|
|
230837
231294
|
? t('advancedCustomDomain.expandAriaLabel')
|
|
230838
|
-
: t('advancedCustomDomain.collapseAriaLabel'), type: "button", children: isCollapsed ? (jsx(ChevronDown, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) : (jsx(ChevronUp, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) })] })] }), !isCollapsed && (jsx("div", { className: "mt-4", children: isLoading ? (jsx("div", { className: "p-4 text-gray-500", children: t('advancedCustomDomain.loading') })) : customDomains.length > 0 ? (jsx("div", { className: "space-y-3", children: sortedDomains.map((row) => (jsx(DomainRow, { row: row, sslValue: sslValue, onReverify: handleReverify, onRemove: handleRemove, isBusy: busyDomainId === row.id, onStatusChange: handleStatusChange }, row.id))) })) : (jsx("div", { className: "p-4 text-center text-sm text-gray-500", children: t('advancedCustomDomain.noDomainConfigured') })) })), jsx(AddDomainDialog, { open: isModalOpen, onOpenChange: setIsModalOpen, canAddPlatformDomain: canAddPlatformDomain, projects: (_a = projectData === null || projectData === void 0 ? void 0 : projectData.projects) !== null && _a !== void 0 ? _a : [], isLoadingProjects: isLoadingProjects, isSubmitting: isCreating || isAttaching, onSubmitPlatformDomain: handleAddPlatformDomain, onSubmitAppDomain: handleAddAppDomain })] }));
|
|
231295
|
+
: t('advancedCustomDomain.collapseAriaLabel'), type: "button", children: isCollapsed ? (jsx(ChevronDown, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) : (jsx(ChevronUp, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) })] })] }), !isCollapsed && (jsx("div", { className: "mt-4", children: isLoading ? (jsx("div", { className: "p-4 text-gray-500", children: t('advancedCustomDomain.loading') })) : customDomains.length > 0 ? (jsx("div", { className: "space-y-3", children: sortedDomains.map((row) => (jsx(DomainRow, { row: row, sharedApp: sharedAppFor(row), sslValue: sslValue, onReverify: handleReverify, onRemove: handleRemove, isBusy: busyDomainId === row.id, onStatusChange: handleStatusChange }, row.id))) })) : (jsx("div", { className: "p-4 text-center text-sm text-gray-500", children: t('advancedCustomDomain.noDomainConfigured') })) })), jsx(AddDomainDialog, { open: isModalOpen, onOpenChange: setIsModalOpen, canAddPlatformDomain: canAddPlatformDomain, defaultMode: hasPlatformDomain ? 'app' : 'platform', projects: (_a = projectData === null || projectData === void 0 ? void 0 : projectData.projects) !== null && _a !== void 0 ? _a : [], isLoadingProjects: isLoadingProjects, isSubmitting: isCreating || isAttaching, onSubmitPlatformDomain: handleAddPlatformDomain, onSubmitAppDomain: handleAddAppDomain })] }));
|
|
230839
231296
|
};
|
|
230840
231297
|
|
|
230841
231298
|
const StudentMentorCreationContent = ({ platformKey, }) => {
|
|
@@ -275358,7 +275815,7 @@ function LocalModelRow({ name, size, logo, providerLabel, status, progress, disa
|
|
|
275358
275815
|
style: { width: `${status === 'starting' ? 6 : Math.max(pct, 6)}%` } })), jsx("span", { "aria-hidden": "true", className: "relative z-10 flex h-8 w-8 flex-shrink-0 items-center justify-center overflow-hidden rounded-lg", children: jsx(LLMProviderLogo, { logo: logo, label: providerLabel !== null && providerLabel !== void 0 ? providerLabel : name, alt: "", className: cn({ grayscale: isBusyDisabled }) }) }), jsxs("span", { className: "relative z-10 flex min-w-0 flex-1 flex-col gap-1.5", children: [jsx("span", { className: "truncate text-sm font-medium text-[#646464] lowercase", children: name }), jsxs("span", { className: "flex min-w-0 items-center gap-1.5 text-sm text-gray-500", children: [jsx("span", { className: "flex-shrink-0 rounded bg-gray-100 px-2 py-0.5 text-sm font-medium text-gray-500", children: labels.onDevice }), status === 'not-installed' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsx("span", { children: size }), jsx(Download, { className: "h-4 w-4", "aria-hidden": "true" })] })), status === 'starting' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsx("span", { children: labels.starting })] })), status === 'downloading' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsxs("span", { className: "tabular-nums group-hover:hidden group-focus-visible:hidden", children: [pct, "%"] }), jsxs("span", { className: "hidden items-center gap-1 text-blue-600 group-hover:flex group-focus-visible:flex", children: [jsx(X$2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), labels.cancel] })] })), status === 'selected' && (jsxs("span", { className: "flex items-center gap-1 text-blue-600", children: [jsx(Check, { className: "h-4 w-4", "aria-hidden": "true" }), labels.inUse] })), status === 'error' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsx("span", { className: "truncate text-red-500", children: errorMessage || labels.downloadFailedRetry }), jsx(RotateCcw, { className: "h-4 w-4 flex-shrink-0 text-red-500", "aria-hidden": "true" })] }))] })] })] }));
|
|
275359
275816
|
}
|
|
275360
275817
|
|
|
275361
|
-
function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting, mentorSettings, llms, labels: labelsProp, }) {
|
|
275818
|
+
function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting, mentorSettings, llms, labels: labelsProp, cloudOnly = false, }) {
|
|
275362
275819
|
var _a;
|
|
275363
275820
|
const t = useT();
|
|
275364
275821
|
const labels = React__default.useMemo(() => labelsProp !== null && labelsProp !== void 0 ? labelsProp : buildLLMTabLabels(t).providerModal, [labelsProp, t]);
|
|
@@ -275426,13 +275883,13 @@ function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting,
|
|
|
275426
275883
|
}, [searchQuery, llmProvider]);
|
|
275427
275884
|
// Local models belonging to THIS provider (merged into the same list).
|
|
275428
275885
|
const localModels = React__default.useMemo(() => {
|
|
275429
|
-
if (!isAvailable)
|
|
275886
|
+
if (cloudOnly || !isAvailable)
|
|
275430
275887
|
return [];
|
|
275431
275888
|
const key = getProviderName(llmProvider.name);
|
|
275432
275889
|
// Per-device catalog: Tauri iOS lists only models with phone-sized weights.
|
|
275433
275890
|
return localModelsForThisDevice().filter((m) => getProviderName(m.provider) === key &&
|
|
275434
275891
|
m.name.toLowerCase().includes(searchQuery.toLowerCase()));
|
|
275435
|
-
}, [isAvailable, llmProvider.name, searchQuery]);
|
|
275892
|
+
}, [cloudOnly, isAvailable, llmProvider.name, searchQuery]);
|
|
275436
275893
|
const switchLLMAllowed = canSwitchLLm(llmProvider);
|
|
275437
275894
|
const switchProviderAllowed = canSwitchProvider(llms, llmProvider.name);
|
|
275438
275895
|
// Only an actual pull counts as "busy". A status refresh ('checking') must NOT
|
|
@@ -275458,7 +275915,7 @@ function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting,
|
|
|
275458
275915
|
// is off.
|
|
275459
275916
|
const isCloudActive = (llm) => (mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.llm_name) === llm.llm_name &&
|
|
275460
275917
|
(mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.llm_provider) === llmProvider.name &&
|
|
275461
|
-
!localSel.enabled;
|
|
275918
|
+
(cloudOnly || !localSel.enabled);
|
|
275462
275919
|
// Order the WHOLE list — cloud + local — available (usable now) first,
|
|
275463
275920
|
// unavailable last, with the in-use model leading. "Available" for a cloud
|
|
275464
275921
|
// model means the provider is switchable (has credentials + models); for a
|
|
@@ -275527,7 +275984,7 @@ function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting,
|
|
|
275527
275984
|
};
|
|
275528
275985
|
const selectCloud = (llmName) => {
|
|
275529
275986
|
// Picking a cloud model turns local mode off so routing uses the cloud LLM.
|
|
275530
|
-
if (localSel.enabled) {
|
|
275987
|
+
if (!cloudOnly && localSel.enabled) {
|
|
275531
275988
|
setLocalLLMEnabled(false);
|
|
275532
275989
|
setLocalSel((prev) => ({ ...prev, enabled: false }));
|
|
275533
275990
|
window.dispatchEvent(new Event(LOCAL_LLM_CHANGED_EVENT));
|
|
@@ -281164,6 +281621,12 @@ const AGENT_HISTORY_TAB_LABELS = {
|
|
|
281164
281621
|
aiAgent: 'AI Agent',
|
|
281165
281622
|
noConversations: 'No conversations found',
|
|
281166
281623
|
documentsChip: (count) => `Documents · ${count}`,
|
|
281624
|
+
sentiment: {
|
|
281625
|
+
positive: 'Positive',
|
|
281626
|
+
neutral: 'Neutral',
|
|
281627
|
+
negative: 'Negative',
|
|
281628
|
+
userSentiment: 'User Sentiment',
|
|
281629
|
+
},
|
|
281167
281630
|
},
|
|
281168
281631
|
summary: {
|
|
281169
281632
|
notAvailable: 'Summary not available',
|
|
@@ -281203,6 +281666,12 @@ function buildHistoryTabLabels(t) {
|
|
|
281203
281666
|
aiAgent: t('historyTabLabels.conversation.aiAgent'),
|
|
281204
281667
|
noConversations: t('historyTabLabels.conversation.noConversations'),
|
|
281205
281668
|
documentsChip: (count) => t('historyTabLabels.conversation.documentsChip', { count }),
|
|
281669
|
+
sentiment: {
|
|
281670
|
+
positive: t('historyTabLabels.conversation.sentiment.positive'),
|
|
281671
|
+
neutral: t('historyTabLabels.conversation.sentiment.neutral'),
|
|
281672
|
+
negative: t('historyTabLabels.conversation.sentiment.negative'),
|
|
281673
|
+
userSentiment: t('historyTabLabels.conversation.sentiment.userSentiment'),
|
|
281674
|
+
},
|
|
281206
281675
|
},
|
|
281207
281676
|
summary: {
|
|
281208
281677
|
notAvailable: t('historyTabLabels.summary.notAvailable'),
|
|
@@ -281237,7 +281706,7 @@ function textTruncate$1(str, length, ending) {
|
|
|
281237
281706
|
return str;
|
|
281238
281707
|
}
|
|
281239
281708
|
function AgentHistoryTab({ renderMessageContent, PaginationComponent, onExport, isExporting = false, labels: labelsOverride, currentSPA, }) {
|
|
281240
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m
|
|
281709
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
281241
281710
|
const t = useT();
|
|
281242
281711
|
const { tenantKey, mentorId, username } = useAgentSettings();
|
|
281243
281712
|
const labels = React__default.useMemo(() => resolveHistoryTabLabels(labelsOverride, t), [labelsOverride, t]);
|
|
@@ -281325,12 +281794,10 @@ function AgentHistoryTab({ renderMessageContent, PaginationComponent, onExport,
|
|
|
281325
281794
|
const owner = resolveUserIdentity(conversation, {
|
|
281326
281795
|
anonymousLabel: labels.conversation.anonymous,
|
|
281327
281796
|
});
|
|
281328
|
-
|
|
281329
|
-
|
|
281330
|
-
|
|
281331
|
-
const title = (
|
|
281332
|
-
? textTruncate$1(firstMessage.human, 50)
|
|
281333
|
-
: labels.conversation.title;
|
|
281797
|
+
// The same date pattern as the profile History tab.
|
|
281798
|
+
const when = formatSessionDate(conversation.inserted_at);
|
|
281799
|
+
// title → first_user_message → first human turn → label, as everywhere.
|
|
281800
|
+
const title = textTruncate$1(conversationTitle(conversation, labels.conversation.title), 50);
|
|
281334
281801
|
const preview = (firstMessage === null || firstMessage === void 0 ? void 0 : firstMessage.ai)
|
|
281335
281802
|
? textTruncate$1(firstMessage.ai, 60)
|
|
281336
281803
|
: labels.conversation.noResponse;
|
|
@@ -281342,14 +281809,14 @@ function AgentHistoryTab({ renderMessageContent, PaginationComponent, onExport,
|
|
|
281342
281809
|
const rollup = summarizeTranscriptTurns(messages);
|
|
281343
281810
|
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
281811
|
? '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:
|
|
281812
|
+
: '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
281813
|
// The chat's documents dialog, as a chip: one
|
|
281347
281814
|
// click shows what the conversation retrieved.
|
|
281348
281815
|
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: (
|
|
281816
|
+
}) }), 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
281817
|
? 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, {}) })) : ((
|
|
281352
|
-
? (
|
|
281818
|
+
: 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
|
|
281819
|
+
? conversationTitle(previewConversationContent, labels.conversation.title)
|
|
281353
281820
|
: 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
281821
|
? conversationDocuments(previewConversationContent.messages)
|
|
281355
281822
|
: 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)))] })) })] }) })] }));
|