@iblai/iblai-js 2.37.0 → 2.38.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.
|
@@ -93067,12 +93067,12 @@ var shimExports = shim.exports;
|
|
|
93067
93067
|
// src/use-is-hydrated.tsx
|
|
93068
93068
|
function useIsHydrated() {
|
|
93069
93069
|
return shimExports.useSyncExternalStore(
|
|
93070
|
-
subscribe$
|
|
93070
|
+
subscribe$3,
|
|
93071
93071
|
() => true,
|
|
93072
93072
|
() => false
|
|
93073
93073
|
);
|
|
93074
93074
|
}
|
|
93075
|
-
function subscribe$
|
|
93075
|
+
function subscribe$3() {
|
|
93076
93076
|
return () => {
|
|
93077
93077
|
};
|
|
93078
93078
|
}
|
|
@@ -103422,20 +103422,48 @@ var chat$3 = {
|
|
|
103422
103422
|
copied: "Copied",
|
|
103423
103423
|
share: "Share"
|
|
103424
103424
|
},
|
|
103425
|
+
chatCodeActivity: {
|
|
103426
|
+
steps: "{count, plural, one {# step} other {# steps}}",
|
|
103427
|
+
aFile: "a file",
|
|
103428
|
+
statusRunning: "Running",
|
|
103429
|
+
statusDone: "Done",
|
|
103430
|
+
statusFailed: "Didn’t go through",
|
|
103431
|
+
statusStopped: "Stopped",
|
|
103432
|
+
read: "{form, select, running {Reading {file}} done {Read {file}} failed {Couldn’t read {file}} other {Code wants to read {file}}}",
|
|
103433
|
+
create: "{form, select, running {Creating {file}} done {Created {file}} failed {Couldn’t create {file}} other {Code wants to create {file}}}",
|
|
103434
|
+
edit: "{form, select, running {Changing {file}} done {Changed {file}} failed {Couldn’t change {file}} other {Code wants to change {file}}}",
|
|
103435
|
+
editMany: "{form, select, running {Changing {count} files} done {Changed {count} files} failed {Couldn’t change {count} files} other {Code wants to change {count} files}}",
|
|
103436
|
+
remove: "{form, select, running {Removing {file}} done {Removed {file}} failed {Couldn’t remove {file}} other {Code wants to remove {file}}}",
|
|
103437
|
+
removeMany: "{form, select, running {Removing {count} files} done {Removed {count} files} failed {Couldn’t remove {count} files} other {Code wants to remove {count} files}}",
|
|
103438
|
+
move: "{form, select, running {Moving {file}} done {Moved {file}} failed {Couldn’t move {file}} other {Code wants to move {file}}}",
|
|
103439
|
+
search: "{form, select, running {Looking through the app’s files} done {Looked through the app’s files} failed {Couldn’t look through the app’s files} other {Code wants to look through the app’s files}}",
|
|
103440
|
+
run: "{form, select, running {Running a command} done {Ran a command} failed {A command didn’t go through} other {Code wants to run a command}}",
|
|
103441
|
+
runDescribed: "{form, select, running {Running a command: {description}} done {Ran a command: {description}} failed {A command didn’t go through: {description}} other {Code wants to run a command: {description}}}",
|
|
103442
|
+
install: "{form, select, running {Installing what the app needs} done {Installed what the app needs} failed {Couldn’t install what the app needs} other {Code wants to install what the app needs}}",
|
|
103443
|
+
preview: "{form, select, running {Starting the preview} done {Started the preview} failed {Couldn’t start the preview} other {Code wants to start the preview}}",
|
|
103444
|
+
open: "{form, select, running {Opening {host}} done {Opened {host}} failed {Couldn’t open {host}} other {Code wants to open {host}}}",
|
|
103445
|
+
openPreview: "{form, select, running {Checking the preview} done {Checked the preview} failed {Couldn’t reach the preview} other {Code wants to check the preview}}",
|
|
103446
|
+
web: "{form, select, running {Searching the web for “{query}”} done {Searched the web for “{query}”} failed {Couldn’t search the web for “{query}”} other {Code wants to search the web for “{query}”}}",
|
|
103447
|
+
helper: "{form, select, running {Working on a side task: {description}} done {Finished a side task: {description}} failed {A side task didn’t go through: {description}} other {Code wants to start a side task: {description}}}",
|
|
103448
|
+
helperPlain: "{form, select, running {Working on a side task} done {Finished a side task} failed {A side task didn’t go through} other {Code wants to start a side task}}",
|
|
103449
|
+
skill: "{form, select, running {Looking up how to do this} done {Looked up how to do this} failed {Couldn’t look up how to do this} other {Code wants to look up how to do this}}",
|
|
103450
|
+
plan: "{form, select, running {Updating its task list} done {Updated its task list} failed {Couldn’t update its task list} other {Code wants to update its task list}}",
|
|
103451
|
+
approve: "{form, select, running {Asking to go ahead with its plan} done {Got the go-ahead for its plan} failed {Didn’t get the go-ahead} other {Code wants to go ahead with its plan}}",
|
|
103452
|
+
ask: "{form, select, running {Asking you a question} done {Asked you a question} failed {Couldn’t ask its question} other {Code wants to ask you a question}}",
|
|
103453
|
+
connector: "{form, select, running {Using {name}} done {Used {name}} failed {Couldn’t use {name}} other {Code wants to use {name}}}",
|
|
103454
|
+
think: "{form, select, running {Working something out} done {Worked something out} failed {Couldn’t work it out} other {Code wants to think this through}}",
|
|
103455
|
+
other: "{form, select, running {Working on a step} done {Finished a step} failed {A step didn’t go through} other {Code wants to do something it didn’t describe}}"
|
|
103456
|
+
},
|
|
103457
|
+
chatCodeErrors: {
|
|
103458
|
+
stopped: "Code stopped unexpectedly. Send your message again.",
|
|
103459
|
+
noAnswer: "Code took too long to answer. Try again.",
|
|
103460
|
+
noModel: "Pick a model in the top-left, then send again.",
|
|
103461
|
+
couldNotStart: "Code couldn’t start. Try again, and restart the app if it keeps happening.",
|
|
103462
|
+
signedOut: "Sign in to use Code."
|
|
103463
|
+
},
|
|
103425
103464
|
chatCodePermissionCard: {
|
|
103426
103465
|
title: "Code needs your permission",
|
|
103427
103466
|
unnamedAction: "An action it didn’t name",
|
|
103428
|
-
kind: {
|
|
103429
|
-
read: "read",
|
|
103430
|
-
write: "write",
|
|
103431
|
-
exec: "exec",
|
|
103432
|
-
"delete": "delete",
|
|
103433
|
-
move: "move",
|
|
103434
|
-
search: "search",
|
|
103435
|
-
fetch: "fetch",
|
|
103436
|
-
think: "think",
|
|
103437
|
-
other: "action"
|
|
103438
|
-
},
|
|
103439
103467
|
allow: "Allow",
|
|
103440
103468
|
deny: "Deny"
|
|
103441
103469
|
},
|
|
@@ -111726,20 +111754,48 @@ var chat$2 = {
|
|
|
111726
111754
|
copied: "Copié",
|
|
111727
111755
|
share: "Partager"
|
|
111728
111756
|
},
|
|
111757
|
+
chatCodeActivity: {
|
|
111758
|
+
steps: "{count, plural, one {# étape} other {# étapes}}",
|
|
111759
|
+
aFile: "un fichier",
|
|
111760
|
+
statusRunning: "En cours",
|
|
111761
|
+
statusDone: "Terminé",
|
|
111762
|
+
statusFailed: "N’a pas abouti",
|
|
111763
|
+
statusStopped: "Interrompu",
|
|
111764
|
+
read: "{form, select, running {Lecture de {file}} done {A lu {file}} failed {N’a pas pu lire {file}} other {Code veut lire {file}}}",
|
|
111765
|
+
create: "{form, select, running {Création de {file}} done {A créé {file}} failed {N’a pas pu créer {file}} other {Code veut créer {file}}}",
|
|
111766
|
+
edit: "{form, select, running {Modification de {file}} done {A modifié {file}} failed {N’a pas pu modifier {file}} other {Code veut modifier {file}}}",
|
|
111767
|
+
editMany: "{form, select, running {Modification de {count} fichiers} done {A modifié {count} fichiers} failed {N’a pas pu modifier {count} fichiers} other {Code veut modifier {count} fichiers}}",
|
|
111768
|
+
remove: "{form, select, running {Suppression de {file}} done {A supprimé {file}} failed {N’a pas pu supprimer {file}} other {Code veut supprimer {file}}}",
|
|
111769
|
+
removeMany: "{form, select, running {Suppression de {count} fichiers} done {A supprimé {count} fichiers} failed {N’a pas pu supprimer {count} fichiers} other {Code veut supprimer {count} fichiers}}",
|
|
111770
|
+
move: "{form, select, running {Déplacement de {file}} done {A déplacé {file}} failed {N’a pas pu déplacer {file}} other {Code veut déplacer {file}}}",
|
|
111771
|
+
search: "{form, select, running {Parcourt les fichiers de l’app} done {A parcouru les fichiers de l’app} failed {N’a pas pu parcourir les fichiers de l’app} other {Code veut parcourir les fichiers de l’app}}",
|
|
111772
|
+
run: "{form, select, running {Exécution d’une commande} done {A exécuté une commande} failed {Une commande n’a pas abouti} other {Code veut exécuter une commande}}",
|
|
111773
|
+
runDescribed: "{form, select, running {Exécution d’une commande : {description}} done {A exécuté une commande : {description}} failed {Une commande n’a pas abouti : {description}} other {Code veut exécuter une commande : {description}}}",
|
|
111774
|
+
install: "{form, select, running {Installation de ce dont l’app a besoin} done {A installé ce dont l’app a besoin} failed {N’a pas pu installer ce dont l’app a besoin} other {Code veut installer ce dont l’app a besoin}}",
|
|
111775
|
+
preview: "{form, select, running {Lancement de l’aperçu} done {A lancé l’aperçu} failed {N’a pas pu lancer l’aperçu} other {Code veut lancer l’aperçu}}",
|
|
111776
|
+
open: "{form, select, running {Ouverture de {host}} done {A ouvert {host}} failed {N’a pas pu ouvrir {host}} other {Code veut ouvrir {host}}}",
|
|
111777
|
+
openPreview: "{form, select, running {Vérification de l’aperçu} done {A vérifié l’aperçu} failed {N’a pas pu joindre l’aperçu} other {Code veut vérifier l’aperçu}}",
|
|
111778
|
+
web: "{form, select, running {Recherche sur le web de « {query} »} done {A cherché sur le web « {query} »} failed {N’a pas pu chercher sur le web « {query} »} other {Code veut chercher sur le web « {query} »}}",
|
|
111779
|
+
helper: "{form, select, running {Travaille sur une tâche annexe : {description}} done {A terminé une tâche annexe : {description}} failed {Une tâche annexe n’a pas abouti : {description}} other {Code veut lancer une tâche annexe : {description}}}",
|
|
111780
|
+
helperPlain: "{form, select, running {Travaille sur une tâche annexe} done {A terminé une tâche annexe} failed {Une tâche annexe n’a pas abouti} other {Code veut lancer une tâche annexe}}",
|
|
111781
|
+
skill: "{form, select, running {Consulte la marche à suivre} done {A consulté la marche à suivre} failed {N’a pas pu consulter la marche à suivre} other {Code veut consulter la marche à suivre}}",
|
|
111782
|
+
plan: "{form, select, running {Mise à jour de sa liste de tâches} done {A mis à jour sa liste de tâches} failed {N’a pas pu mettre à jour sa liste de tâches} other {Code veut mettre à jour sa liste de tâches}}",
|
|
111783
|
+
approve: "{form, select, running {Demande le feu vert pour son plan} done {A reçu le feu vert pour son plan} failed {N’a pas reçu le feu vert} other {Code veut poursuivre son plan}}",
|
|
111784
|
+
ask: "{form, select, running {Vous pose une question} done {Vous a posé une question} failed {N’a pas pu poser sa question} other {Code veut vous poser une question}}",
|
|
111785
|
+
connector: "{form, select, running {Utilisation de {name}} done {A utilisé {name}} failed {N’a pas pu utiliser {name}} other {Code veut utiliser {name}}}",
|
|
111786
|
+
think: "{form, select, running {Réfléchit à quelque chose} done {A réfléchi à quelque chose} failed {N’a pas pu trancher} other {Code veut y réfléchir}}",
|
|
111787
|
+
other: "{form, select, running {Travaille sur une étape} done {A terminé une étape} failed {Une étape n’a pas abouti} other {Code veut faire quelque chose qu’il n’a pas décrit}}"
|
|
111788
|
+
},
|
|
111789
|
+
chatCodeErrors: {
|
|
111790
|
+
stopped: "Code s’est arrêté de façon inattendue. Renvoyez votre message.",
|
|
111791
|
+
noAnswer: "Code a mis trop de temps à répondre. Réessayez.",
|
|
111792
|
+
noModel: "Choisissez un modèle en haut à gauche, puis renvoyez votre message.",
|
|
111793
|
+
couldNotStart: "Code n’a pas pu démarrer. Réessayez, et redémarrez l’app si cela continue.",
|
|
111794
|
+
signedOut: "Connectez-vous pour utiliser Code."
|
|
111795
|
+
},
|
|
111729
111796
|
chatCodePermissionCard: {
|
|
111730
111797
|
title: "Code a besoin de votre autorisation",
|
|
111731
111798
|
unnamedAction: "Une action non nommée",
|
|
111732
|
-
kind: {
|
|
111733
|
-
read: "lire",
|
|
111734
|
-
write: "écrire",
|
|
111735
|
-
exec: "exécuter",
|
|
111736
|
-
"delete": "supprimer",
|
|
111737
|
-
move: "déplacer",
|
|
111738
|
-
search: "chercher",
|
|
111739
|
-
fetch: "récupérer",
|
|
111740
|
-
think: "réfléchir",
|
|
111741
|
-
other: "action"
|
|
111742
|
-
},
|
|
111743
111799
|
allow: "Autoriser",
|
|
111744
111800
|
deny: "Refuser"
|
|
111745
111801
|
},
|
|
@@ -120030,20 +120086,48 @@ var chat$1 = {
|
|
|
120030
120086
|
copied: "Copiado",
|
|
120031
120087
|
share: "Compartir"
|
|
120032
120088
|
},
|
|
120089
|
+
chatCodeActivity: {
|
|
120090
|
+
steps: "{count, plural, one {# paso} other {# pasos}}",
|
|
120091
|
+
aFile: "un archivo",
|
|
120092
|
+
statusRunning: "En curso",
|
|
120093
|
+
statusDone: "Hecho",
|
|
120094
|
+
statusFailed: "No se completó",
|
|
120095
|
+
statusStopped: "Detenido",
|
|
120096
|
+
read: "{form, select, running {Leyendo {file}} done {Leyó {file}} failed {No pudo leer {file}} other {Código quiere leer {file}}}",
|
|
120097
|
+
create: "{form, select, running {Creando {file}} done {Creó {file}} failed {No pudo crear {file}} other {Código quiere crear {file}}}",
|
|
120098
|
+
edit: "{form, select, running {Cambiando {file}} done {Cambió {file}} failed {No pudo cambiar {file}} other {Código quiere cambiar {file}}}",
|
|
120099
|
+
editMany: "{form, select, running {Cambiando {count} archivos} done {Cambió {count} archivos} failed {No pudo cambiar {count} archivos} other {Código quiere cambiar {count} archivos}}",
|
|
120100
|
+
remove: "{form, select, running {Eliminando {file}} done {Eliminó {file}} failed {No pudo eliminar {file}} other {Código quiere eliminar {file}}}",
|
|
120101
|
+
removeMany: "{form, select, running {Eliminando {count} archivos} done {Eliminó {count} archivos} failed {No pudo eliminar {count} archivos} other {Código quiere eliminar {count} archivos}}",
|
|
120102
|
+
move: "{form, select, running {Moviendo {file}} done {Movió {file}} failed {No pudo mover {file}} other {Código quiere mover {file}}}",
|
|
120103
|
+
search: "{form, select, running {Revisando los archivos de la app} done {Revisó los archivos de la app} failed {No pudo revisar los archivos de la app} other {Código quiere revisar los archivos de la app}}",
|
|
120104
|
+
run: "{form, select, running {Ejecutando un comando} done {Ejecutó un comando} failed {Un comando no se completó} other {Código quiere ejecutar un comando}}",
|
|
120105
|
+
runDescribed: "{form, select, running {Ejecutando un comando: {description}} done {Ejecutó un comando: {description}} failed {Un comando no se completó: {description}} other {Código quiere ejecutar un comando: {description}}}",
|
|
120106
|
+
install: "{form, select, running {Instalando lo que la app necesita} done {Instaló lo que la app necesita} failed {No pudo instalar lo que la app necesita} other {Código quiere instalar lo que la app necesita}}",
|
|
120107
|
+
preview: "{form, select, running {Iniciando la vista previa} done {Inició la vista previa} failed {No pudo iniciar la vista previa} other {Código quiere iniciar la vista previa}}",
|
|
120108
|
+
open: "{form, select, running {Abriendo {host}} done {Abrió {host}} failed {No pudo abrir {host}} other {Código quiere abrir {host}}}",
|
|
120109
|
+
openPreview: "{form, select, running {Comprobando la vista previa} done {Comprobó la vista previa} failed {No pudo acceder a la vista previa} other {Código quiere comprobar la vista previa}}",
|
|
120110
|
+
web: "{form, select, running {Buscando en la web “{query}”} done {Buscó en la web “{query}”} failed {No pudo buscar en la web “{query}”} other {Código quiere buscar en la web “{query}”}}",
|
|
120111
|
+
helper: "{form, select, running {Trabajando en una tarea aparte: {description}} done {Terminó una tarea aparte: {description}} failed {Una tarea aparte no se completó: {description}} other {Código quiere iniciar una tarea aparte: {description}}}",
|
|
120112
|
+
helperPlain: "{form, select, running {Trabajando en una tarea aparte} done {Terminó una tarea aparte} failed {Una tarea aparte no se completó} other {Código quiere iniciar una tarea aparte}}",
|
|
120113
|
+
skill: "{form, select, running {Consultando cómo hacerlo} done {Consultó cómo hacerlo} failed {No pudo consultar cómo hacerlo} other {Código quiere consultar cómo hacerlo}}",
|
|
120114
|
+
plan: "{form, select, running {Actualizando su lista de tareas} done {Actualizó su lista de tareas} failed {No pudo actualizar su lista de tareas} other {Código quiere actualizar su lista de tareas}}",
|
|
120115
|
+
approve: "{form, select, running {Pidiendo permiso para seguir con su plan} done {Recibió permiso para seguir con su plan} failed {No recibió permiso para seguir} other {Código quiere seguir con su plan}}",
|
|
120116
|
+
ask: "{form, select, running {Haciéndote una pregunta} done {Te hizo una pregunta} failed {No pudo hacer su pregunta} other {Código quiere hacerte una pregunta}}",
|
|
120117
|
+
connector: "{form, select, running {Usando {name}} done {Usó {name}} failed {No pudo usar {name}} other {Código quiere usar {name}}}",
|
|
120118
|
+
think: "{form, select, running {Resolviendo algo} done {Resolvió algo} failed {No pudo resolverlo} other {Código quiere pensarlo}}",
|
|
120119
|
+
other: "{form, select, running {Trabajando en un paso} done {Terminó un paso} failed {Un paso no se completó} other {Código quiere hacer algo que no describió}}"
|
|
120120
|
+
},
|
|
120121
|
+
chatCodeErrors: {
|
|
120122
|
+
stopped: "Código se detuvo de forma inesperada. Envía tu mensaje de nuevo.",
|
|
120123
|
+
noAnswer: "Código tardó demasiado en responder. Inténtalo de nuevo.",
|
|
120124
|
+
noModel: "Elige un modelo arriba a la izquierda y vuelve a enviar.",
|
|
120125
|
+
couldNotStart: "Código no pudo iniciarse. Inténtalo de nuevo y reinicia la app si sigue pasando.",
|
|
120126
|
+
signedOut: "Inicia sesión para usar Código."
|
|
120127
|
+
},
|
|
120033
120128
|
chatCodePermissionCard: {
|
|
120034
120129
|
title: "Código necesita tu permiso",
|
|
120035
120130
|
unnamedAction: "Una acción sin nombre",
|
|
120036
|
-
kind: {
|
|
120037
|
-
read: "leer",
|
|
120038
|
-
write: "escribir",
|
|
120039
|
-
exec: "ejecutar",
|
|
120040
|
-
"delete": "eliminar",
|
|
120041
|
-
move: "mover",
|
|
120042
|
-
search: "buscar",
|
|
120043
|
-
fetch: "obtener",
|
|
120044
|
-
think: "pensar",
|
|
120045
|
-
other: "acción"
|
|
120046
|
-
},
|
|
120047
120131
|
allow: "Permitir",
|
|
120048
120132
|
deny: "Denegar"
|
|
120049
120133
|
},
|
|
@@ -128334,20 +128418,48 @@ var chat = {
|
|
|
128334
128418
|
copied: "已复制",
|
|
128335
128419
|
share: "分享"
|
|
128336
128420
|
},
|
|
128421
|
+
chatCodeActivity: {
|
|
128422
|
+
steps: "{count, plural, other {# 个步骤}}",
|
|
128423
|
+
aFile: "一个文件",
|
|
128424
|
+
statusRunning: "进行中",
|
|
128425
|
+
statusDone: "已完成",
|
|
128426
|
+
statusFailed: "未成功",
|
|
128427
|
+
statusStopped: "已中断",
|
|
128428
|
+
read: "{form, select, running {正在读取 {file}} done {已读取 {file}} failed {无法读取 {file}} other {代码模式想读取 {file}}}",
|
|
128429
|
+
create: "{form, select, running {正在创建 {file}} done {已创建 {file}} failed {无法创建 {file}} other {代码模式想创建 {file}}}",
|
|
128430
|
+
edit: "{form, select, running {正在修改 {file}} done {已修改 {file}} failed {无法修改 {file}} other {代码模式想修改 {file}}}",
|
|
128431
|
+
editMany: "{form, select, running {正在修改 {count} 个文件} done {已修改 {count} 个文件} failed {无法修改 {count} 个文件} other {代码模式想修改 {count} 个文件}}",
|
|
128432
|
+
remove: "{form, select, running {正在删除 {file}} done {已删除 {file}} failed {无法删除 {file}} other {代码模式想删除 {file}}}",
|
|
128433
|
+
removeMany: "{form, select, running {正在删除 {count} 个文件} done {已删除 {count} 个文件} failed {无法删除 {count} 个文件} other {代码模式想删除 {count} 个文件}}",
|
|
128434
|
+
move: "{form, select, running {正在移动 {file}} done {已移动 {file}} failed {无法移动 {file}} other {代码模式想移动 {file}}}",
|
|
128435
|
+
search: "{form, select, running {正在查看应用的文件} done {已查看应用的文件} failed {无法查看应用的文件} other {代码模式想查看应用的文件}}",
|
|
128436
|
+
run: "{form, select, running {正在运行一条命令} done {已运行一条命令} failed {一条命令未成功} other {代码模式想运行一条命令}}",
|
|
128437
|
+
runDescribed: "{form, select, running {正在运行一条命令:{description}} done {已运行一条命令:{description}} failed {一条命令未成功:{description}} other {代码模式想运行一条命令:{description}}}",
|
|
128438
|
+
install: "{form, select, running {正在安装应用所需的内容} done {已安装应用所需的内容} failed {无法安装应用所需的内容} other {代码模式想安装应用所需的内容}}",
|
|
128439
|
+
preview: "{form, select, running {正在启动预览} done {已启动预览} failed {无法启动预览} other {代码模式想启动预览}}",
|
|
128440
|
+
open: "{form, select, running {正在打开 {host}} done {已打开 {host}} failed {无法打开 {host}} other {代码模式想打开 {host}}}",
|
|
128441
|
+
openPreview: "{form, select, running {正在检查预览} done {已检查预览} failed {无法访问预览} other {代码模式想检查预览}}",
|
|
128442
|
+
web: "{form, select, running {正在网上搜索“{query}”} done {已在网上搜索“{query}”} failed {无法在网上搜索“{query}”} other {代码模式想在网上搜索“{query}”}}",
|
|
128443
|
+
helper: "{form, select, running {正在处理一项附带任务:{description}} done {已完成一项附带任务:{description}} failed {一项附带任务未成功:{description}} other {代码模式想开始一项附带任务:{description}}}",
|
|
128444
|
+
helperPlain: "{form, select, running {正在处理一项附带任务} done {已完成一项附带任务} failed {一项附带任务未成功} other {代码模式想开始一项附带任务}}",
|
|
128445
|
+
skill: "{form, select, running {正在查阅操作方法} done {已查阅操作方法} failed {无法查阅操作方法} other {代码模式想查阅操作方法}}",
|
|
128446
|
+
plan: "{form, select, running {正在更新任务清单} done {已更新任务清单} failed {无法更新任务清单} other {代码模式想更新任务清单}}",
|
|
128447
|
+
approve: "{form, select, running {正在请求按计划继续} done {已获准按计划继续} failed {未获准继续} other {代码模式想按计划继续}}",
|
|
128448
|
+
ask: "{form, select, running {正在向你提问} done {已向你提问} failed {无法提出问题} other {代码模式想向你提问}}",
|
|
128449
|
+
connector: "{form, select, running {正在使用 {name}} done {已使用 {name}} failed {无法使用 {name}} other {代码模式想使用 {name}}}",
|
|
128450
|
+
think: "{form, select, running {正在思考} done {已想清楚} failed {没能想清楚} other {代码模式想先思考一下}}",
|
|
128451
|
+
other: "{form, select, running {正在处理一个步骤} done {已完成一个步骤} failed {一个步骤未成功} other {代码模式想做一件没有说明的事}}"
|
|
128452
|
+
},
|
|
128453
|
+
chatCodeErrors: {
|
|
128454
|
+
stopped: "代码模式意外停止了。请再发送一次你的消息。",
|
|
128455
|
+
noAnswer: "代码模式响应太慢。请再试一次。",
|
|
128456
|
+
noModel: "请先在左上角选择一个模型,然后再发送。",
|
|
128457
|
+
couldNotStart: "代码模式无法启动。请再试一次;如果持续出现,请重启应用。",
|
|
128458
|
+
signedOut: "请先登录再使用代码模式。"
|
|
128459
|
+
},
|
|
128337
128460
|
chatCodePermissionCard: {
|
|
128338
128461
|
title: "代码模式需要你的许可",
|
|
128339
128462
|
unnamedAction: "一项未命名的操作",
|
|
128340
|
-
kind: {
|
|
128341
|
-
read: "读取",
|
|
128342
|
-
write: "写入",
|
|
128343
|
-
exec: "执行",
|
|
128344
|
-
"delete": "删除",
|
|
128345
|
-
move: "移动",
|
|
128346
|
-
search: "搜索",
|
|
128347
|
-
fetch: "获取",
|
|
128348
|
-
think: "思考",
|
|
128349
|
-
other: "操作"
|
|
128350
|
-
},
|
|
128351
128463
|
allow: "允许",
|
|
128352
128464
|
deny: "拒绝"
|
|
128353
128465
|
},
|
|
@@ -184967,7 +185079,7 @@ class Style {
|
|
|
184967
185079
|
* Get a text or display version of this style.
|
|
184968
185080
|
*/
|
|
184969
185081
|
text() {
|
|
184970
|
-
return styles[text$1[this.id]];
|
|
185082
|
+
return styles[text$1$1[this.id]];
|
|
184971
185083
|
}
|
|
184972
185084
|
/**
|
|
184973
185085
|
* Return true if this style is tightly spaced (scriptstyle/scriptscriptstyle)
|
|
@@ -184993,7 +185105,7 @@ var sub$1 = [Sc$1, Sc$1, Sc$1, Sc$1, SSc, SSc, SSc, SSc];
|
|
|
184993
185105
|
var fracNum = [T$1, Tc, S, Sc$1, SS, SSc, SS, SSc];
|
|
184994
185106
|
var fracDen = [Tc, Tc, Sc$1, Sc$1, SSc, SSc, SSc, SSc];
|
|
184995
185107
|
var cramp = [Dc, Dc, Tc, Tc, Sc$1, Sc$1, SSc, SSc];
|
|
184996
|
-
var text$1 = [D$1, Dc, T$1, Tc, T$1, Tc, T$1, Tc];
|
|
185108
|
+
var text$1$1 = [D$1, Dc, T$1, Tc, T$1, Tc, T$1, Tc];
|
|
184997
185109
|
// We only export some of the styles.
|
|
184998
185110
|
var Style$1 = {
|
|
184999
185111
|
DISPLAY: styles[D$1],
|
|
@@ -243093,7 +243205,7 @@ function chatTextPreview(text) {
|
|
|
243093
243205
|
.trim();
|
|
243094
243206
|
}
|
|
243095
243207
|
|
|
243096
|
-
const clean$
|
|
243208
|
+
const clean$3 = (value) => typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
243097
243209
|
/** The first human turn of a conversation, from an array or its JSON string form. */
|
|
243098
243210
|
function firstHumanMessage(messages) {
|
|
243099
243211
|
let turns = messages;
|
|
@@ -243108,7 +243220,7 @@ function firstHumanMessage(messages) {
|
|
|
243108
243220
|
if (!Array.isArray(turns))
|
|
243109
243221
|
return undefined;
|
|
243110
243222
|
const first = turns[0];
|
|
243111
|
-
return clean$
|
|
243223
|
+
return clean$3(first === null || first === void 0 ? void 0 : first.human);
|
|
243112
243224
|
}
|
|
243113
243225
|
const preview = (value) => (typeof value === 'string' && chatTextPreview(value)) || undefined;
|
|
243114
243226
|
/**
|
|
@@ -247706,7 +247818,7 @@ function one(state, node, key) {
|
|
|
247706
247818
|
}
|
|
247707
247819
|
|
|
247708
247820
|
if (node.type === 'text') {
|
|
247709
|
-
return text(state, node)
|
|
247821
|
+
return text$1(state, node)
|
|
247710
247822
|
}
|
|
247711
247823
|
}
|
|
247712
247824
|
|
|
@@ -247870,7 +247982,7 @@ function root(state, node, key) {
|
|
|
247870
247982
|
* @returns {Child | undefined}
|
|
247871
247983
|
* Child, optional.
|
|
247872
247984
|
*/
|
|
247873
|
-
function text(_, node) {
|
|
247985
|
+
function text$1(_, node) {
|
|
247874
247986
|
return node.value
|
|
247875
247987
|
}
|
|
247876
247988
|
|
|
@@ -283258,7 +283370,7 @@ const OVERVIEW_LLM_RANGE = '30d';
|
|
|
283258
283370
|
const OVERVIEW_ENROLLMENT_PAGE_SIZE = 50;
|
|
283259
283371
|
/** Models fetched for the breakdown; the tab folds the tail into "Other". */
|
|
283260
283372
|
const OVERVIEW_MODEL_LIMIT = 10;
|
|
283261
|
-
const statusOf = (error) => error && typeof error === 'object' ? error.status : undefined;
|
|
283373
|
+
const statusOf$1 = (error) => error && typeof error === 'object' ? error.status : undefined;
|
|
283262
283374
|
/**
|
|
283263
283375
|
* Everything the Overview tab shows, read through the same endpoints the
|
|
283264
283376
|
* individual tabs use so the two never disagree. Each section is requested
|
|
@@ -283335,7 +283447,7 @@ function useOverviewData(org, username, sections) {
|
|
|
283335
283447
|
enabled: sections.chatHistory,
|
|
283336
283448
|
isLoading: sections.chatHistory && historyQ.isLoading,
|
|
283337
283449
|
isError: historyQ.isError,
|
|
283338
|
-
isForbidden: statusOf(historyQ.error) === 403,
|
|
283450
|
+
isForbidden: statusOf$1(historyQ.error) === 403,
|
|
283339
283451
|
count: (_b = (_a = historyQ.data) === null || _a === void 0 ? void 0 : _a.count) !== null && _b !== void 0 ? _b : 0,
|
|
283340
283452
|
recent: (_d = (_c = historyQ.data) === null || _c === void 0 ? void 0 : _c.results) !== null && _d !== void 0 ? _d : [],
|
|
283341
283453
|
});
|
|
@@ -285780,7 +285892,7 @@ const deepLink = (url, snippet) => {
|
|
|
285780
285892
|
return url;
|
|
285781
285893
|
return `${url.split('#')[0]}#:~:text=${encodeURIComponent(text)}`;
|
|
285782
285894
|
};
|
|
285783
|
-
const hostOf = (value) => {
|
|
285895
|
+
const hostOf$1 = (value) => {
|
|
285784
285896
|
try {
|
|
285785
285897
|
return new URL(value).host;
|
|
285786
285898
|
}
|
|
@@ -285800,7 +285912,7 @@ function RetrievedDocumentRow({ doc }) {
|
|
|
285800
285912
|
const [previewOpen, setPreviewOpen] = React.useState(false);
|
|
285801
285913
|
const source = ((_a = doc.source) !== null && _a !== void 0 ? _a : '').trim();
|
|
285802
285914
|
const url = isHttpUrl(source) ? source : null;
|
|
285803
|
-
const title = doc.title || (url ? hostOf(url) : source);
|
|
285915
|
+
const title = doc.title || (url ? hostOf$1(url) : source);
|
|
285804
285916
|
const relevance = relevancePercent(doc.score);
|
|
285805
285917
|
const openHref = url ? deepLink(url, doc.snippet) : null;
|
|
285806
285918
|
// Preview only what a browser can show; Office files, archives and
|
|
@@ -286163,7 +286275,7 @@ function useLlmProviderCatalogue({ org, userId, mentorId }) {
|
|
|
286163
286275
|
};
|
|
286164
286276
|
}, [rowsByName, rowsByLooseName, rowForModel]);
|
|
286165
286277
|
}
|
|
286166
|
-
const clean$
|
|
286278
|
+
const clean$2 = (value) => (value === null || value === void 0 ? void 0 : value.trim()) || undefined;
|
|
286167
286279
|
/**
|
|
286168
286280
|
* The label to show for a model.
|
|
286169
286281
|
*
|
|
@@ -286180,7 +286292,7 @@ const clean$1 = (value) => (value === null || value === void 0 ? void 0 : value.
|
|
|
286180
286292
|
*/
|
|
286181
286293
|
function useLlmDisplayName({ llmName, llmConfig, org, userId, mentorId, }) {
|
|
286182
286294
|
var _a;
|
|
286183
|
-
const fromConfig = clean$
|
|
286295
|
+
const fromConfig = clean$2(llmConfig === null || llmConfig === void 0 ? void 0 : llmConfig.display_name);
|
|
286184
286296
|
const skip = Boolean(fromConfig) || !llmName || !org || !userId || !mentorId;
|
|
286185
286297
|
const { data: providers } = useGetLlmsQuery({
|
|
286186
286298
|
org: org !== null && org !== void 0 ? org : '',
|
|
@@ -286195,7 +286307,7 @@ function useLlmDisplayName({ llmName, llmConfig, org, userId, mentorId, }) {
|
|
|
286195
286307
|
const wanted = modelKey(llmName);
|
|
286196
286308
|
for (const provider of providers) {
|
|
286197
286309
|
const match = (_a = provider === null || provider === void 0 ? void 0 : provider.chat_models) === null || _a === void 0 ? void 0 : _a.find((model) => modelKey(model === null || model === void 0 ? void 0 : model.llm_name) === wanted || modelKey(model === null || model === void 0 ? void 0 : model.display_name) === wanted);
|
|
286198
|
-
const label = clean$
|
|
286310
|
+
const label = clean$2(match === null || match === void 0 ? void 0 : match.display_name);
|
|
286199
286311
|
if (label)
|
|
286200
286312
|
return label;
|
|
286201
286313
|
}
|
|
@@ -289549,7 +289661,7 @@ function parseMetadataValue(raw) {
|
|
|
289549
289661
|
return undefined;
|
|
289550
289662
|
}
|
|
289551
289663
|
}
|
|
289552
|
-
function isRecord(value) {
|
|
289664
|
+
function isRecord$1(value) {
|
|
289553
289665
|
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
289554
289666
|
}
|
|
289555
289667
|
/** A blank form for a platform that has never configured onboarding. */
|
|
@@ -289567,7 +289679,7 @@ function emptyUserOnboardingForm(title = '') {
|
|
|
289567
289679
|
function coerceOnboardingAgent(raw) {
|
|
289568
289680
|
var _a, _b;
|
|
289569
289681
|
const value = parseMetadataValue(raw);
|
|
289570
|
-
if (!isRecord(value))
|
|
289682
|
+
if (!isRecord$1(value))
|
|
289571
289683
|
return null;
|
|
289572
289684
|
const id = (_b = (_a = value.mentor_unique_id) !== null && _a !== void 0 ? _a : value.unique_id) !== null && _b !== void 0 ? _b : value.mentor;
|
|
289573
289685
|
if (typeof id !== 'string' || !id.trim())
|
|
@@ -289612,10 +289724,10 @@ function coerceOnboardingAgents(rawAgents, rawAgent) {
|
|
|
289612
289724
|
function coerceUserOnboardingForm(raw) {
|
|
289613
289725
|
var _a;
|
|
289614
289726
|
const value = parseMetadataValue(raw);
|
|
289615
|
-
if (!isRecord(value))
|
|
289727
|
+
if (!isRecord$1(value))
|
|
289616
289728
|
return emptyUserOnboardingForm();
|
|
289617
289729
|
const sections = Array.isArray(value.sections)
|
|
289618
|
-
? value.sections.filter((section) => isRecord(section) && Array.isArray(section.fields))
|
|
289730
|
+
? value.sections.filter((section) => isRecord$1(section) && Array.isArray(section.fields))
|
|
289619
289731
|
: [];
|
|
289620
289732
|
const agents = coerceOnboardingAgents(value.agents, value.agent);
|
|
289621
289733
|
return {
|
|
@@ -300316,7 +300428,7 @@ const isEmailLike = (value) => {
|
|
|
300316
300428
|
return dot > 0 && !domain.endsWith('.');
|
|
300317
300429
|
};
|
|
300318
300430
|
/** Trimmed string, or undefined for blanks, non-strings and placeholders. */
|
|
300319
|
-
const clean = (value) => {
|
|
300431
|
+
const clean$1 = (value) => {
|
|
300320
300432
|
if (typeof value !== 'string')
|
|
300321
300433
|
return undefined;
|
|
300322
300434
|
const trimmed = value.trim();
|
|
@@ -300324,7 +300436,7 @@ const clean = (value) => {
|
|
|
300324
300436
|
};
|
|
300325
300437
|
const firstOf = (...candidates) => {
|
|
300326
300438
|
for (const candidate of candidates) {
|
|
300327
|
-
const value = clean(candidate);
|
|
300439
|
+
const value = clean$1(candidate);
|
|
300328
300440
|
if (value)
|
|
300329
300441
|
return value;
|
|
300330
300442
|
}
|
|
@@ -300360,12 +300472,12 @@ function resolveUserIdentity(source, options = {}) {
|
|
|
300360
300472
|
// A bare `user` value is a username — unless it is a numeric id, which
|
|
300361
300473
|
// names nobody: transcript rows carry `user: 1` beside `username: null`,
|
|
300362
300474
|
// and showing "1" for that person is worse than "Anonymous".
|
|
300363
|
-
const bareString = typeof record.user === 'string' ? clean(record.user) : undefined;
|
|
300475
|
+
const bareString = typeof record.user === 'string' ? clean$1(record.user) : undefined;
|
|
300364
300476
|
const bareUser = bareString && !/^\d+$/.test(bareString) ? bareString : undefined;
|
|
300365
300477
|
let email = firstOf(record.lti_email, record.email, record.user_email, inner === null || inner === void 0 ? void 0 : inner.lti_email, inner === null || inner === void 0 ? void 0 : inner.email, inner === null || inner === void 0 ? void 0 : inner.user_email);
|
|
300366
300478
|
const platformUsername = firstOf(record.username, record.student, record.user_username, inner === null || inner === void 0 ? void 0 : inner.username, inner === null || inner === void 0 ? void 0 : inner.student, inner === null || inner === void 0 ? void 0 : inner.user_username, bareUser && !isEmailLike(bareUser) ? bareUser : undefined);
|
|
300367
300479
|
let username = firstOf(record.lti_username, inner === null || inner === void 0 ? void 0 : inner.lti_username, platformUsername);
|
|
300368
|
-
const composed = [clean(record.first_name), clean(record.last_name)].filter(Boolean).join(' ');
|
|
300480
|
+
const composed = [clean$1(record.first_name), clean$1(record.last_name)].filter(Boolean).join(' ');
|
|
300369
300481
|
const name = firstOf(record.user_full_name, record.full_name, record.name, composed, inner === null || inner === void 0 ? void 0 : inner.user_full_name, inner === null || inner === void 0 ? void 0 : inner.full_name, inner === null || inner === void 0 ? void 0 : inner.name);
|
|
300370
300482
|
// A bare string that looks like an email is an email, and so is a
|
|
300371
300483
|
// "username" field that actually carries one.
|
|
@@ -303660,14 +303772,14 @@ function writeCoworkApprovals(mode) {
|
|
|
303660
303772
|
}
|
|
303661
303773
|
}
|
|
303662
303774
|
/** True inside the Tauri desktop/mobile shell. */
|
|
303663
|
-
const isTauriApp$
|
|
303775
|
+
const isTauriApp$4 = () => {
|
|
303664
303776
|
if (typeof window === 'undefined')
|
|
303665
303777
|
return false;
|
|
303666
303778
|
return '__TAURI_INTERNALS__' in window || '__TAURI__' in window;
|
|
303667
303779
|
};
|
|
303668
303780
|
/** True on Tauri iOS/Android; false outside Tauri or without the OS plugin. */
|
|
303669
303781
|
const isTauriMobile = async () => {
|
|
303670
|
-
if (!isTauriApp$
|
|
303782
|
+
if (!isTauriApp$4())
|
|
303671
303783
|
return false;
|
|
303672
303784
|
try {
|
|
303673
303785
|
const { platform } = await import('@tauri-apps/plugin-os');
|
|
@@ -303701,7 +303813,7 @@ function useChatMentorSettings(props = {}) {
|
|
|
303701
303813
|
const COMMUNITY_MENTOR_VISIBILITY = MentorVisibilityEnum.VIEWABLE_BY_ANYONE;
|
|
303702
303814
|
const isLoggedIn = Boolean(username);
|
|
303703
303815
|
// Check if we're in Tauri offline mode
|
|
303704
|
-
const isOffline = isTauriApp$
|
|
303816
|
+
const isOffline = isTauriApp$4() && isTauriOfflineMode$1();
|
|
303705
303817
|
// Get cached data for offline mode
|
|
303706
303818
|
const [cachedSettings, setCachedSettings] = useState(null);
|
|
303707
303819
|
const [cachedPublicSettings, setCachedPublicSettings] = useState(null);
|
|
@@ -303744,12 +303856,12 @@ function useChatMentorSettings(props = {}) {
|
|
|
303744
303856
|
});
|
|
303745
303857
|
// Cache responses when online for offline use
|
|
303746
303858
|
useEffect(() => {
|
|
303747
|
-
if (isTauriApp$
|
|
303859
|
+
if (isTauriApp$4() && !isOffline && mentorSettings && mentorId && tenantKey && username) {
|
|
303748
303860
|
setCachedApiResponse(CacheKeys.mentorSettings(tenantKey, mentorId, username), mentorSettings, { org: tenantKey, mentor: mentorId, userId: username });
|
|
303749
303861
|
}
|
|
303750
303862
|
}, [mentorSettings, mentorId, tenantKey, username, isOffline]);
|
|
303751
303863
|
useEffect(() => {
|
|
303752
|
-
if (isTauriApp$
|
|
303864
|
+
if (isTauriApp$4() && !isOffline && mentorPublicSettings && mentorId && tenantKey) {
|
|
303753
303865
|
setCachedApiResponse(CacheKeys.mentorPublicSettings(tenantKey, mentorId), mentorPublicSettings, { org: tenantKey, mentor: mentorId });
|
|
303754
303866
|
}
|
|
303755
303867
|
}, [mentorPublicSettings, mentorId, tenantKey, isOffline]);
|
|
@@ -305020,7 +305132,7 @@ const initialModelDownloadState = {
|
|
|
305020
305132
|
* In Tauri 2.0, the global is __TAURI_INTERNALS__ (with withGlobalTauri: true)
|
|
305021
305133
|
* We also check for __TAURI__ for backwards compatibility
|
|
305022
305134
|
*/
|
|
305023
|
-
const isTauriApp$
|
|
305135
|
+
const isTauriApp$3 = () => {
|
|
305024
305136
|
if (typeof window === 'undefined')
|
|
305025
305137
|
return false;
|
|
305026
305138
|
return '__TAURI_INTERNALS__' in window || '__TAURI__' in window;
|
|
@@ -305129,7 +305241,7 @@ function useTauri() {
|
|
|
305129
305241
|
const [apis, setApis] = useState(null);
|
|
305130
305242
|
useEffect(() => {
|
|
305131
305243
|
// Check if we're in a Tauri environment
|
|
305132
|
-
const inTauri = isTauriApp$
|
|
305244
|
+
const inTauri = isTauriApp$3();
|
|
305133
305245
|
if (inTauri) {
|
|
305134
305246
|
getTauriAPIs().then((result) => {
|
|
305135
305247
|
setApis(result);
|
|
@@ -305574,7 +305686,7 @@ function useCuaDriver() {
|
|
|
305574
305686
|
};
|
|
305575
305687
|
}, [isAvailable, checkStatus]);
|
|
305576
305688
|
// Only expose the feature as available inside the desktop (Tauri) app.
|
|
305577
|
-
const finalIsAvailable = isAvailable && isTauriApp$
|
|
305689
|
+
const finalIsAvailable = isAvailable && isTauriApp$3();
|
|
305578
305690
|
// Deliberately `=== true`, not `?? true`: until the first status check lands
|
|
305579
305691
|
// we do not know whether this desktop session is one the driver can drive, and
|
|
305580
305692
|
// offering Cowork optimistically would show the toggle to (say) a KDE user for
|
|
@@ -311400,7 +311512,7 @@ function useModelDownload() {
|
|
|
311400
311512
|
(ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.installed) &&
|
|
311401
311513
|
!(ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.model_installed) &&
|
|
311402
311514
|
state.status === 'idle';
|
|
311403
|
-
const finalIsAvailable = isAvailable && isTauriApp$
|
|
311515
|
+
const finalIsAvailable = isAvailable && isTauriApp$3();
|
|
311404
311516
|
return {
|
|
311405
311517
|
// State
|
|
311406
311518
|
isAvailable: finalIsAvailable,
|
|
@@ -317455,7 +317567,7 @@ function AgentLLMTab({ showConfigurationHeader = true, mentorId: mentorIdOverrid
|
|
|
317455
317567
|
// are absent, and a provider card that opens onto an empty picker is worse
|
|
317456
317568
|
// than no card.
|
|
317457
317569
|
const localOnlyProviders = React__default.useMemo(() => {
|
|
317458
|
-
if (!isTauriApp$
|
|
317570
|
+
if (!isTauriApp$3())
|
|
317459
317571
|
return [];
|
|
317460
317572
|
const cloudKeys = new Set((llmProviders !== null && llmProviders !== void 0 ? llmProviders : []).map((p) => getProviderName(p.name)));
|
|
317461
317573
|
const seen = new Set();
|
|
@@ -317477,7 +317589,7 @@ function AgentLLMTab({ showConfigurationHeader = true, mentorId: mentorIdOverrid
|
|
|
317477
317589
|
// match the desktop catalog (openai, google, mistral…). Both inputs are fixed
|
|
317478
317590
|
// for the life of the webview, so this never goes stale.
|
|
317479
317591
|
const localProviderKeys = React__default.useMemo(() => {
|
|
317480
|
-
if (!isTauriApp$
|
|
317592
|
+
if (!isTauriApp$3())
|
|
317481
317593
|
return new Set();
|
|
317482
317594
|
return new Set(localModelsForThisDevice().map((m) => getProviderName(m.provider)));
|
|
317483
317595
|
}, []);
|
|
@@ -329717,6 +329829,9 @@ function WorkingIndicator({ phase, restatedByVisibleRow = false, content, classN
|
|
|
329717
329829
|
// over as the progress indicator.
|
|
329718
329830
|
const isStreamOnScreen = isWriting && (content !== null && content !== void 0 ? content : '').trim().length > 0;
|
|
329719
329831
|
const [showReassurance, setShowReassurance] = useState(false);
|
|
329832
|
+
const rawLabel = phaseLabel(phase, t);
|
|
329833
|
+
// A new label is a sign of life (a Code turn moves step to step without
|
|
329834
|
+
// ever writing), so it restarts the clock.
|
|
329720
329835
|
useEffect(() => {
|
|
329721
329836
|
if (!isActive || isWriting) {
|
|
329722
329837
|
setShowReassurance(false);
|
|
@@ -329724,13 +329839,13 @@ function WorkingIndicator({ phase, restatedByVisibleRow = false, content, classN
|
|
|
329724
329839
|
}
|
|
329725
329840
|
const timer = setTimeout(() => setShowReassurance(true), LONG_TURN_REASSURANCE_DELAY_MS);
|
|
329726
329841
|
return () => clearTimeout(timer);
|
|
329727
|
-
}, [isActive, isWriting]);
|
|
329842
|
+
}, [isActive, isWriting, rawLabel]);
|
|
329728
329843
|
// The phase sticks at `writing` after the last token — it only moves when
|
|
329729
329844
|
// some other signal arrives — so a mid-turn grind looks identical to a
|
|
329730
329845
|
// healthy stream from the phase alone. The content clock is what separates
|
|
329731
329846
|
// them, and it is why this component must not be unmounted while hidden.
|
|
329732
329847
|
const isStreamStalled = useStalledStream(content, isActive, isWriting) && isStreamOnScreen;
|
|
329733
|
-
const label = useThrottledPhaseLabel(
|
|
329848
|
+
const label = useThrottledPhaseLabel(rawLabel, isActive);
|
|
329734
329849
|
// Nothing to add: the turn is over, a visible row already says this, or the
|
|
329735
329850
|
// answer text is moving on its own.
|
|
329736
329851
|
if (!isActive || restatedByVisibleRow || (isStreamOnScreen && !isStreamStalled)) {
|
|
@@ -329864,7 +329979,7 @@ function bubbleTodos(toolCalls, showReasoning) {
|
|
|
329864
329979
|
* call to decide whether the standalone working placeholder is still needed, so
|
|
329865
329980
|
* the two must stay in lockstep: exactly one agent frame per turn, never two.
|
|
329866
329981
|
*/
|
|
329867
|
-
function hasVisibleBubbleContent({ content, message, reasoningContent, toolCalls, showReasoning, hasPermissionPrompts, }) {
|
|
329982
|
+
function hasVisibleBubbleContent({ content, message, reasoningContent, toolCalls, showReasoning, hasPermissionPrompts, hasCodeActivity, }) {
|
|
329868
329983
|
var _a, _b;
|
|
329869
329984
|
const hasReasoningToShow = !!(showReasoning && reasoningContent);
|
|
329870
329985
|
const hasToolCallsToShow = hasGenericToolCalls(toolCalls, showReasoning);
|
|
@@ -329878,6 +329993,8 @@ function hasVisibleBubbleContent({ content, message, reasoningContent, toolCalls
|
|
|
329878
329993
|
// silently stalled — and the standalone placeholder would keep its own
|
|
329879
329994
|
// frame up alongside the prompt.
|
|
329880
329995
|
!!hasPermissionPrompts ||
|
|
329996
|
+
// Likewise a plan that arrives before the first step (Codex plans first).
|
|
329997
|
+
!!hasCodeActivity ||
|
|
329881
329998
|
!!((_b = message === null || message === void 0 ? void 0 : message.actions) === null || _b === void 0 ? void 0 : _b.length) ||
|
|
329882
329999
|
hasArtifactVersions(message));
|
|
329883
330000
|
}
|
|
@@ -329900,6 +330017,416 @@ function AIWorkingMessage({ phase, profileImage, mentorName, timestamp, }) {
|
|
|
329900
330017
|
return (jsx("div", { "data-testid": "chat-working-message", children: jsx(AIMessageFrame, { profileImage: profileImage, mentorName: mentorName, timestamp: timestamp, children: jsx("div", { className: "mb-1.5 rounded-2xl bg-gray-100 p-3 wrap-anywhere", children: jsx(WorkingIndicator, { phase: phase }) }) }) }));
|
|
329901
330018
|
}
|
|
329902
330019
|
|
|
330020
|
+
const MAX_INPUT_STRING = 2000;
|
|
330021
|
+
const MAX_ERROR = 500;
|
|
330022
|
+
const PREVIEW_HOSTS = new Set(['localhost', '127.0.0.1', '[::1]']);
|
|
330023
|
+
// C0/C1 controls, zero-widths and the bidi controls that could fake a file's extension.
|
|
330024
|
+
const UNSAFE_CHARS = /[\u0000-\u001f\u007f-\u009f\u061c\u200b-\u200f\u202a-\u202e\u2060\u2066-\u2069\ufeff]/g;
|
|
330025
|
+
// The same set minus tab and newline, for literals shown whole: a command keeps its own
|
|
330026
|
+
// lines and gains none (U+2028/9 break lines without being newlines).
|
|
330027
|
+
const UNSAFE_DETAIL_CHARS = /[\u0000-\u0008\u000b-\u001f\u007f-\u009f\u061c\u200b-\u200f\u2028-\u202e\u2060\u2066-\u2069\ufeff]/g;
|
|
330028
|
+
function isRecord(value) {
|
|
330029
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
330030
|
+
}
|
|
330031
|
+
function text(value) {
|
|
330032
|
+
return typeof value === 'string' && value.trim() ? value : undefined;
|
|
330033
|
+
}
|
|
330034
|
+
/** Display-safe: controls stripped, whitespace collapsed, cut by code points. */
|
|
330035
|
+
function clean(value, max) {
|
|
330036
|
+
const chars = Array.from(value.replace(UNSAFE_CHARS, '').replace(/\s+/g, ' ').trim());
|
|
330037
|
+
return chars.length > max ? `${chars.slice(0, max).join('')}…` : chars.join('');
|
|
330038
|
+
}
|
|
330039
|
+
/** A command, path or failure text the user will judge: nothing that hides or reorders it. */
|
|
330040
|
+
function safeDetail(value) {
|
|
330041
|
+
return (value === null || value === void 0 ? void 0 : value.replace(UNSAFE_DETAIL_CHARS, '')) || undefined;
|
|
330042
|
+
}
|
|
330043
|
+
/** `about/page.tsx`: Next apps are full of `page.tsx`, so one segment is ambiguous. */
|
|
330044
|
+
function shortPath(path) {
|
|
330045
|
+
const parts = path.split(/[\\/]+/).filter(Boolean);
|
|
330046
|
+
return clean(parts.slice(-2).join('/'), 48);
|
|
330047
|
+
}
|
|
330048
|
+
function hostOf(url) {
|
|
330049
|
+
try {
|
|
330050
|
+
return new URL(url).hostname.replace(/^www\./, '') || undefined;
|
|
330051
|
+
}
|
|
330052
|
+
catch (_a) {
|
|
330053
|
+
return undefined;
|
|
330054
|
+
}
|
|
330055
|
+
}
|
|
330056
|
+
// ponytail: two command shapes recognised (install, preview); add a third when a row reads too vaguely.
|
|
330057
|
+
function commandAction(command) {
|
|
330058
|
+
let bare = command.trim();
|
|
330059
|
+
for (let i = 0; i < 4; i += 1) {
|
|
330060
|
+
const next = bare
|
|
330061
|
+
.replace(/^cd\s+\S+\s*&&\s*/, '')
|
|
330062
|
+
.replace(/^[A-Za-z_][A-Za-z0-9_]*=\S*\s+/, '');
|
|
330063
|
+
if (next === bare)
|
|
330064
|
+
break;
|
|
330065
|
+
bare = next;
|
|
330066
|
+
}
|
|
330067
|
+
if (/^(?:npm|pnpm|yarn|bun)\s+(?:i|install|add|ci)\b/.test(bare)) {
|
|
330068
|
+
return 'install';
|
|
330069
|
+
}
|
|
330070
|
+
if (/^(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?(?:dev|start|preview)\b/.test(bare) ||
|
|
330071
|
+
/^(?:npx\s+)?(?:next\s+dev|vite)\b/.test(bare)) {
|
|
330072
|
+
return 'preview';
|
|
330073
|
+
}
|
|
330074
|
+
return 'run';
|
|
330075
|
+
}
|
|
330076
|
+
/** Finished steps stay finished; pending, in_progress and the unknown all run. */
|
|
330077
|
+
function statusOf(raw, prev) {
|
|
330078
|
+
if (prev !== 'running')
|
|
330079
|
+
return prev;
|
|
330080
|
+
if (raw === 'completed')
|
|
330081
|
+
return 'done';
|
|
330082
|
+
if (raw === 'failed')
|
|
330083
|
+
return 'failed';
|
|
330084
|
+
return 'running';
|
|
330085
|
+
}
|
|
330086
|
+
// ponytail: top-level strings only; clip nested payloads if a turn's facts ever weigh.
|
|
330087
|
+
function clipStrings(input) {
|
|
330088
|
+
return Object.fromEntries(Object.entries(input).map(([key, value]) => [
|
|
330089
|
+
key,
|
|
330090
|
+
typeof value === 'string' && value.length > MAX_INPUT_STRING
|
|
330091
|
+
? `${value.slice(0, MAX_INPUT_STRING)}…`
|
|
330092
|
+
: value,
|
|
330093
|
+
]));
|
|
330094
|
+
}
|
|
330095
|
+
function diffsOf(content) {
|
|
330096
|
+
if (!Array.isArray(content))
|
|
330097
|
+
return [];
|
|
330098
|
+
const diffs = [];
|
|
330099
|
+
for (const item of content) {
|
|
330100
|
+
if (isRecord(item) && item.type === 'diff' && text(item.path)) {
|
|
330101
|
+
diffs.push({ path: item.path, isNew: item.oldText == null });
|
|
330102
|
+
}
|
|
330103
|
+
}
|
|
330104
|
+
return diffs;
|
|
330105
|
+
}
|
|
330106
|
+
function errorOf(content) {
|
|
330107
|
+
if (typeof content === 'string')
|
|
330108
|
+
return text(content);
|
|
330109
|
+
if (!Array.isArray(content))
|
|
330110
|
+
return undefined;
|
|
330111
|
+
const lines = content.flatMap((item) => isRecord(item) &&
|
|
330112
|
+
item.type === 'content' &&
|
|
330113
|
+
isRecord(item.content) &&
|
|
330114
|
+
typeof item.content.text === 'string'
|
|
330115
|
+
? [item.content.text]
|
|
330116
|
+
: []);
|
|
330117
|
+
return text(lines.join('\n'));
|
|
330118
|
+
}
|
|
330119
|
+
function pathsOf(update, input, diffs) {
|
|
330120
|
+
const paths = new Set();
|
|
330121
|
+
if (Array.isArray(update.locations)) {
|
|
330122
|
+
for (const location of update.locations) {
|
|
330123
|
+
const path = isRecord(location) ? text(location.path) : undefined;
|
|
330124
|
+
if (path)
|
|
330125
|
+
paths.add(path);
|
|
330126
|
+
}
|
|
330127
|
+
}
|
|
330128
|
+
for (const diff of diffs)
|
|
330129
|
+
paths.add(diff.path);
|
|
330130
|
+
for (const key of ['file_path', 'filePath', 'path']) {
|
|
330131
|
+
const path = text(input[key]);
|
|
330132
|
+
if (path)
|
|
330133
|
+
paths.add(path);
|
|
330134
|
+
}
|
|
330135
|
+
return [...paths];
|
|
330136
|
+
}
|
|
330137
|
+
/**
|
|
330138
|
+
* ACP ToolCallUpdate semantics, hardened: only present, non-blank fields
|
|
330139
|
+
* overwrite (Claude's result update has no title or kind), the tool name is
|
|
330140
|
+
* set once (opencode's pending title IS the tool name), `content` and
|
|
330141
|
+
* `locations` replace but never blank a subject already known, and nothing
|
|
330142
|
+
* from `_meta` or a tool's output is kept.
|
|
330143
|
+
*/
|
|
330144
|
+
function mergeToolCall(prev, update) {
|
|
330145
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
330146
|
+
const base = prev !== null && prev !== void 0 ? prev : {
|
|
330147
|
+
status: 'running',
|
|
330148
|
+
input: {},
|
|
330149
|
+
paths: [],
|
|
330150
|
+
diffs: [],
|
|
330151
|
+
};
|
|
330152
|
+
const meta = isRecord(update._meta) ? update._meta : {};
|
|
330153
|
+
const claude = isRecord(meta.claudeCode) ? meta.claudeCode : {};
|
|
330154
|
+
const input = isRecord(update.rawInput) && Object.keys(update.rawInput).length > 0
|
|
330155
|
+
? clipStrings(update.rawInput)
|
|
330156
|
+
: base.input;
|
|
330157
|
+
const freshDiffs = diffsOf(update.content);
|
|
330158
|
+
const diffs = freshDiffs.length > 0 ? freshDiffs : base.diffs;
|
|
330159
|
+
const found = pathsOf(update, input, diffs);
|
|
330160
|
+
const status = statusOf(update.status, base.status);
|
|
330161
|
+
return {
|
|
330162
|
+
name: (_c = (_b = (_a = base.name) !== null && _a !== void 0 ? _a : text(claude.toolName)) !== null && _b !== void 0 ? _b : text(update.name)) !== null && _c !== void 0 ? _c : text(update.title),
|
|
330163
|
+
title: (_d = text(update.title)) !== null && _d !== void 0 ? _d : base.title,
|
|
330164
|
+
kind: (_e = text(update.kind)) !== null && _e !== void 0 ? _e : base.kind,
|
|
330165
|
+
status,
|
|
330166
|
+
input,
|
|
330167
|
+
paths: found.length > 0 ? found : base.paths,
|
|
330168
|
+
diffs,
|
|
330169
|
+
error: status === 'failed'
|
|
330170
|
+
? ((_g = (_f = errorOf(update.content)) === null || _f === void 0 ? void 0 : _f.slice(0, MAX_ERROR)) !== null && _g !== void 0 ? _g : base.error)
|
|
330171
|
+
: undefined,
|
|
330172
|
+
};
|
|
330173
|
+
}
|
|
330174
|
+
/** The plain-words reading of a tool call. Never null: the vaguest is `other`. */
|
|
330175
|
+
function describeStep(facts, id) {
|
|
330176
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
330177
|
+
const name = ((_a = facts.name) !== null && _a !== void 0 ? _a : '').toLowerCase();
|
|
330178
|
+
const kind = ((_b = facts.kind) !== null && _b !== void 0 ? _b : '').toLowerCase();
|
|
330179
|
+
const title = (_c = facts.title) !== null && _c !== void 0 ? _c : '';
|
|
330180
|
+
const { input, paths, diffs } = facts;
|
|
330181
|
+
const is = (...names) => names.includes(name) || names.includes(kind);
|
|
330182
|
+
const file = paths[0] ? { file: shortPath(paths[0]) } : {};
|
|
330183
|
+
const allPaths = paths.join('\n') || undefined;
|
|
330184
|
+
const step = (action, values = {}, details) => ({
|
|
330185
|
+
id,
|
|
330186
|
+
action,
|
|
330187
|
+
status: facts.status,
|
|
330188
|
+
values,
|
|
330189
|
+
details: safeDetail([details, facts.error].filter(Boolean).join('\n')),
|
|
330190
|
+
});
|
|
330191
|
+
if (Array.isArray(input.todos) || is('todowrite', 'todoread')) {
|
|
330192
|
+
return step('plan');
|
|
330193
|
+
}
|
|
330194
|
+
const mcp = (_d = name.match(/^mcp__(.+?)__(.+)$/)) !== null && _d !== void 0 ? _d : title.match(/^mcp\.([^.]+)\.(.+)$/);
|
|
330195
|
+
if (mcp) {
|
|
330196
|
+
return step('connector', { name: clean(mcp[2].replace(/_/g, ' '), 48) }, title);
|
|
330197
|
+
}
|
|
330198
|
+
if (is('skill') || text(input.skill)) {
|
|
330199
|
+
return step('skill', {}, (_f = (_e = text(input.skill)) !== null && _e !== void 0 ? _e : text(input.name)) !== null && _f !== void 0 ? _f : title);
|
|
330200
|
+
}
|
|
330201
|
+
const description = text(input.description);
|
|
330202
|
+
if (is('task', 'agent') || text(input.subagent_type) || text(input.agentThreadId)) {
|
|
330203
|
+
const prompt = text(input.prompt);
|
|
330204
|
+
const excerpt = prompt ? clean(prompt, 300) : undefined;
|
|
330205
|
+
return description
|
|
330206
|
+
? step('helper', { description: clean(description, 120) }, excerpt)
|
|
330207
|
+
: step('helperPlain', {}, excerpt);
|
|
330208
|
+
}
|
|
330209
|
+
if (is('exitplanmode') || kind === 'switch_mode') {
|
|
330210
|
+
return step('approve', {}, text(input.plan));
|
|
330211
|
+
}
|
|
330212
|
+
if (is('askuserquestion'))
|
|
330213
|
+
return step('ask', {}, title);
|
|
330214
|
+
const command = (_h = (_g = text(input.command)) !== null && _g !== void 0 ? _g : text(input.cmd)) !== null && _h !== void 0 ? _h : text(input.script);
|
|
330215
|
+
if (command || is('bash', 'shell', 'powershell')) {
|
|
330216
|
+
if (description) {
|
|
330217
|
+
return step('runDescribed', { description: clean(description, 120) }, command);
|
|
330218
|
+
}
|
|
330219
|
+
return step(command ? commandAction(command) : 'run', {}, command);
|
|
330220
|
+
}
|
|
330221
|
+
const query = (_j = text(input.query)) !== null && _j !== void 0 ? _j : (_k = title.match(/^Web search: (.+)$/)) === null || _k === void 0 ? void 0 : _k[1];
|
|
330222
|
+
const url = (_m = (_l = text(input.url)) !== null && _l !== void 0 ? _l : (isRecord(input.action) ? text(input.action.url) : undefined)) !== null && _m !== void 0 ? _m : (_o = title.match(/^Open page: (.+)$/)) === null || _o === void 0 ? void 0 : _o[1];
|
|
330223
|
+
if (is('websearch') || (query && !url && is('search', 'fetch'))) {
|
|
330224
|
+
return step('web', { query: clean(query !== null && query !== void 0 ? query : title, 60) });
|
|
330225
|
+
}
|
|
330226
|
+
if (url || is('fetch', 'webfetch')) {
|
|
330227
|
+
const host = url ? hostOf(url) : undefined;
|
|
330228
|
+
if (!host)
|
|
330229
|
+
return step('other', {}, url !== null && url !== void 0 ? url : title);
|
|
330230
|
+
return PREVIEW_HOSTS.has(host)
|
|
330231
|
+
? step('openPreview', {}, url)
|
|
330232
|
+
: step('open', { host: clean(host, 48) }, url);
|
|
330233
|
+
}
|
|
330234
|
+
// ACP's command kind, once a command or an address would have been read above.
|
|
330235
|
+
if (kind === 'execute')
|
|
330236
|
+
return step('run', {}, title);
|
|
330237
|
+
if (is('delete')) {
|
|
330238
|
+
return paths.length > 1
|
|
330239
|
+
? step('removeMany', { count: paths.length }, allPaths)
|
|
330240
|
+
: step('remove', file, allPaths);
|
|
330241
|
+
}
|
|
330242
|
+
if (kind === 'move')
|
|
330243
|
+
return step('move', file, allPaths);
|
|
330244
|
+
if (is('edit', 'write', 'patch', 'apply_patch', 'multiedit', 'notebookedit')) {
|
|
330245
|
+
const creates = diffs.length > 0 ? diffs.every((d) => d.isNew) : is('write');
|
|
330246
|
+
if (creates)
|
|
330247
|
+
return step('create', file, allPaths);
|
|
330248
|
+
if (paths.length > 1)
|
|
330249
|
+
return step('editMany', { count: paths.length }, allPaths);
|
|
330250
|
+
return step('edit', file, allPaths);
|
|
330251
|
+
}
|
|
330252
|
+
const listing = /^list\b/.test(name) || /^list files/i.test(title);
|
|
330253
|
+
if (is('read') && !listing)
|
|
330254
|
+
return step('read', file, allPaths);
|
|
330255
|
+
if (listing || is('glob', 'grep', 'codesearch', 'list', 'search')) {
|
|
330256
|
+
return step('search', {}, text(input.pattern));
|
|
330257
|
+
}
|
|
330258
|
+
if (kind === 'think')
|
|
330259
|
+
return step('think', {}, title);
|
|
330260
|
+
return step('other', {}, title);
|
|
330261
|
+
}
|
|
330262
|
+
function stepSentence(t, step, form) {
|
|
330263
|
+
return t(`chat.chatCodeActivity.${step.action}`, {
|
|
330264
|
+
form,
|
|
330265
|
+
file: t('chat.chatCodeActivity.aFile'),
|
|
330266
|
+
count: 0,
|
|
330267
|
+
description: '',
|
|
330268
|
+
host: '',
|
|
330269
|
+
query: '',
|
|
330270
|
+
name: '',
|
|
330271
|
+
...step.values,
|
|
330272
|
+
});
|
|
330273
|
+
}
|
|
330274
|
+
/**
|
|
330275
|
+
* The working line's phase for a Code turn: reply text first (so the stalled-
|
|
330276
|
+
* reply reassurance still works when a step never reports completion), then
|
|
330277
|
+
* the latest step while it runs (an older stuck step never shows stale), else
|
|
330278
|
+
* thinking. `workflow` rather than `tool`: the line narrates, no row animates.
|
|
330279
|
+
*/
|
|
330280
|
+
function codeTurnPhase(steps, content, t) {
|
|
330281
|
+
if ((content !== null && content !== void 0 ? content : '').trim())
|
|
330282
|
+
return { kind: 'writing' };
|
|
330283
|
+
const last = steps[steps.length - 1];
|
|
330284
|
+
if ((last === null || last === void 0 ? void 0 : last.status) === 'running') {
|
|
330285
|
+
return { kind: 'workflow', detail: stepSentence(t, last, 'running') };
|
|
330286
|
+
}
|
|
330287
|
+
return { kind: 'thinking' };
|
|
330288
|
+
}
|
|
330289
|
+
// ---------------------------------------------------------------------------
|
|
330290
|
+
// Shared store
|
|
330291
|
+
// ---------------------------------------------------------------------------
|
|
330292
|
+
const EMPTY_TURN = { steps: [] };
|
|
330293
|
+
// ponytail: kept for the app session like the SDK's tool calls; 200 turns is a few MB at worst.
|
|
330294
|
+
const MAX_TURNS = 200;
|
|
330295
|
+
const turns = new Map();
|
|
330296
|
+
const facts = new Map();
|
|
330297
|
+
const subscribers$1 = new Set();
|
|
330298
|
+
let listening$1 = false;
|
|
330299
|
+
function publish$1() {
|
|
330300
|
+
subscribers$1.forEach((notify) => notify());
|
|
330301
|
+
}
|
|
330302
|
+
function turnFor(generationId) {
|
|
330303
|
+
const existing = turns.get(generationId);
|
|
330304
|
+
if (existing)
|
|
330305
|
+
return existing;
|
|
330306
|
+
if (turns.size >= MAX_TURNS) {
|
|
330307
|
+
const oldest = turns.keys().next().value;
|
|
330308
|
+
if (oldest !== undefined) {
|
|
330309
|
+
turns.delete(oldest);
|
|
330310
|
+
facts.delete(oldest);
|
|
330311
|
+
}
|
|
330312
|
+
}
|
|
330313
|
+
turns.set(generationId, EMPTY_TURN);
|
|
330314
|
+
return EMPTY_TURN;
|
|
330315
|
+
}
|
|
330316
|
+
/** ACP plan entries and opencode's `todowrite` rows through the SDK's normaliser. */
|
|
330317
|
+
function todosOf(entries) {
|
|
330318
|
+
if (!Array.isArray(entries))
|
|
330319
|
+
return undefined;
|
|
330320
|
+
return extractLatestTodos([
|
|
330321
|
+
{
|
|
330322
|
+
id: '',
|
|
330323
|
+
name: WRITE_TODOS_TOOL,
|
|
330324
|
+
input: { todos: entries },
|
|
330325
|
+
log: '',
|
|
330326
|
+
result: '',
|
|
330327
|
+
},
|
|
330328
|
+
]);
|
|
330329
|
+
}
|
|
330330
|
+
function applyToolCall(generationId, update) {
|
|
330331
|
+
var _a;
|
|
330332
|
+
const id = update ? text(update.toolCallId) : undefined;
|
|
330333
|
+
if (!generationId || !id || !update)
|
|
330334
|
+
return;
|
|
330335
|
+
const turn = turnFor(generationId);
|
|
330336
|
+
const byId = (_a = facts.get(generationId)) !== null && _a !== void 0 ? _a : new Map();
|
|
330337
|
+
facts.set(generationId, byId);
|
|
330338
|
+
const merged = mergeToolCall(byId.get(id), update);
|
|
330339
|
+
byId.set(id, merged);
|
|
330340
|
+
const step = describeStep(merged, id);
|
|
330341
|
+
let next;
|
|
330342
|
+
if (step.action === 'plan') {
|
|
330343
|
+
// A todo tool recognised only once its input arrived may already sit in the list as a row.
|
|
330344
|
+
const steps = turn.steps.filter((s) => s.id !== id);
|
|
330345
|
+
const plan = Array.isArray(merged.input.todos) ? todosOf(merged.input.todos) : turn.plan;
|
|
330346
|
+
if (plan !== turn.plan || steps.length !== turn.steps.length) {
|
|
330347
|
+
next = { ...turn, steps, plan };
|
|
330348
|
+
}
|
|
330349
|
+
}
|
|
330350
|
+
else {
|
|
330351
|
+
const index = turn.steps.findIndex((s) => s.id === id);
|
|
330352
|
+
if (index < 0) {
|
|
330353
|
+
next = { ...turn, steps: [...turn.steps, step] };
|
|
330354
|
+
}
|
|
330355
|
+
else if (JSON.stringify(turn.steps[index]) !== JSON.stringify(step)) {
|
|
330356
|
+
const steps = turn.steps.slice();
|
|
330357
|
+
steps[index] = step;
|
|
330358
|
+
next = { ...turn, steps };
|
|
330359
|
+
}
|
|
330360
|
+
}
|
|
330361
|
+
if (!next)
|
|
330362
|
+
return;
|
|
330363
|
+
turns.set(generationId, next);
|
|
330364
|
+
publish$1();
|
|
330365
|
+
}
|
|
330366
|
+
function applyPlan(generationId, update) {
|
|
330367
|
+
const entries = update === null || update === void 0 ? void 0 : update.entries;
|
|
330368
|
+
if (!generationId || !Array.isArray(entries))
|
|
330369
|
+
return;
|
|
330370
|
+
// An empty list clears the plan, as the SDK's `bubbleTodos` does.
|
|
330371
|
+
turns.set(generationId, { ...turnFor(generationId), plan: todosOf(entries) });
|
|
330372
|
+
publish$1();
|
|
330373
|
+
}
|
|
330374
|
+
/** A crash-respawn into the same generation starts over, as the SDK does. */
|
|
330375
|
+
function clearTurn(generationId) {
|
|
330376
|
+
if (!generationId || !turns.delete(generationId))
|
|
330377
|
+
return;
|
|
330378
|
+
facts.delete(generationId);
|
|
330379
|
+
publish$1();
|
|
330380
|
+
}
|
|
330381
|
+
function isTauriApp$2() {
|
|
330382
|
+
return typeof window !== 'undefined' && '__TAURI__' in window;
|
|
330383
|
+
}
|
|
330384
|
+
async function startListening$1() {
|
|
330385
|
+
if (listening$1 || !isTauriApp$2())
|
|
330386
|
+
return;
|
|
330387
|
+
listening$1 = true;
|
|
330388
|
+
const { listen } = await import('@tauri-apps/api/event');
|
|
330389
|
+
await listen('opencode:tool_call', (evt) => applyToolCall(evt.payload.generation_id, evt.payload.update));
|
|
330390
|
+
await listen('opencode:plan', (evt) => applyPlan(evt.payload.generation_id, evt.payload.update));
|
|
330391
|
+
await listen('ollama:restart', (evt) => clearTurn(evt.payload.generation_id));
|
|
330392
|
+
}
|
|
330393
|
+
// A new chat's first step lands before any bubble mounts, and the listeners
|
|
330394
|
+
// deliberately outlive every subscriber, as the permission store's do.
|
|
330395
|
+
void startListening$1();
|
|
330396
|
+
function subscribe$2(notify) {
|
|
330397
|
+
subscribers$1.add(notify);
|
|
330398
|
+
void startListening$1();
|
|
330399
|
+
return () => {
|
|
330400
|
+
subscribers$1.delete(notify);
|
|
330401
|
+
};
|
|
330402
|
+
}
|
|
330403
|
+
function useCodeTurn(generationId) {
|
|
330404
|
+
return useSyncExternalStore(subscribe$2, () => (generationId && turns.get(generationId)) || EMPTY_TURN, () => EMPTY_TURN);
|
|
330405
|
+
}
|
|
330406
|
+
/** Distinct shapes, never colour alone (WCAG 1.4.1), with an sr-only label. */
|
|
330407
|
+
const ROW_META = {
|
|
330408
|
+
running: { Icon: CircleDot$1, labelKey: 'statusRunning' },
|
|
330409
|
+
done: { Icon: CircleCheck, labelKey: 'statusDone' },
|
|
330410
|
+
failed: { Icon: CircleX, labelKey: 'statusFailed' },
|
|
330411
|
+
stopped: { Icon: Circle, labelKey: 'statusStopped' },
|
|
330412
|
+
};
|
|
330413
|
+
const StepRow = React__default.memo(function StepRow({ step, stale, }) {
|
|
330414
|
+
const t = useChatT();
|
|
330415
|
+
const status = stale ? 'stopped' : step.status;
|
|
330416
|
+
const { Icon, labelKey } = ROW_META[status];
|
|
330417
|
+
const body = (jsxs(Fragment$1, { children: [jsx(Icon, { "aria-hidden": "true", className: "mt-0.5 h-3 w-3 shrink-0 text-gray-400" }), jsx("span", { className: "sr-only", children: t(`chat.chatCodeActivity.${labelKey}`) }), jsx("span", { className: "min-w-0 flex-1 text-gray-700 dark:text-gray-300", children: stepSentence(t, step, step.status) })] }));
|
|
330418
|
+
return (jsx("li", { "data-testid": "code-activity-step", "data-status": status, children: step.details ? (jsxs("details", { children: [jsx("summary", { className: "flex cursor-pointer list-none items-start gap-1.5 [&::-webkit-details-marker]:hidden", children: body }), jsx("code", { "data-testid": "code-activity-details", className: "mt-1 ml-[18px] block rounded bg-gray-200 px-1.5 py-1 font-mono break-all whitespace-pre-wrap text-gray-700", children: step.details })] })) : (jsx("div", { className: "flex items-start gap-1.5", children: body })) }));
|
|
330419
|
+
});
|
|
330420
|
+
function CodeActivity({ generationId, isCurrentlyStreaming = false, }) {
|
|
330421
|
+
const t = useChatT();
|
|
330422
|
+
const { steps } = useCodeTurn(generationId);
|
|
330423
|
+
// Folded by default and never animated: the working line narrates the live step.
|
|
330424
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
330425
|
+
if (steps.length === 0)
|
|
330426
|
+
return null;
|
|
330427
|
+
return (jsxs(Collapsible, { open: isOpen, onOpenChange: setIsOpen, className: "mb-2", "data-testid": "code-activity", children: [jsxs(CollapsibleTrigger, { className: "flex cursor-pointer items-center gap-1 pt-1 text-xs text-gray-500 transition-colors hover:text-gray-600 dark:text-gray-400 dark:hover:text-gray-300", "data-testid": "code-activity-trigger", children: [jsx(ChevronRight, { className: cn('h-3 w-3 shrink-0 transition-transform duration-200', isOpen && 'rotate-90') }), jsx("span", { className: "font-medium", children: t('chat.chatCodeActivity.steps', { count: steps.length }) })] }), jsx(CollapsibleContent, { className: "pb-2 pl-4", children: jsx("ol", { className: "space-y-1.5 border-l-2 border-gray-200 pt-2 pl-3 text-xs leading-relaxed dark:border-gray-700", "data-testid": "code-activity-steps", children: steps.map((step) => (jsx(StepRow, { step: step, stale: !isCurrentlyStreaming && step.status === 'running' }, step.id))) }) })] }));
|
|
330428
|
+
}
|
|
330429
|
+
|
|
329903
330430
|
function isTauriApp$1() {
|
|
329904
330431
|
return typeof window !== 'undefined' && '__TAURI__' in window;
|
|
329905
330432
|
}
|
|
@@ -329989,17 +330516,27 @@ function resetCodePermissionsForTests() {
|
|
|
329989
330516
|
listening = false;
|
|
329990
330517
|
subscribers.forEach((notify) => notify());
|
|
329991
330518
|
}
|
|
329992
|
-
/**
|
|
329993
|
-
|
|
329994
|
-
|
|
329995
|
-
|
|
329996
|
-
|
|
329997
|
-
|
|
329998
|
-
|
|
329999
|
-
|
|
330000
|
-
|
|
330001
|
-
|
|
330002
|
-
};
|
|
330519
|
+
/**
|
|
330520
|
+
* A request without a tool call (a paired phone, an older binary, a Browse run)
|
|
330521
|
+
* described from its kind: a phone's `command` holds command patterns for bash,
|
|
330522
|
+
* file patterns for edit, URL patterns for webfetch.
|
|
330523
|
+
*/
|
|
330524
|
+
function legacyToolCall(request) {
|
|
330525
|
+
var _a, _b;
|
|
330526
|
+
const kind = (_a = request.kind) !== null && _a !== void 0 ? _a : '';
|
|
330527
|
+
const value = (_b = request.command) !== null && _b !== void 0 ? _b : undefined;
|
|
330528
|
+
if (/^(execute|bash|shell)$/.test(kind)) {
|
|
330529
|
+
return { title: request.title, kind, rawInput: { command: value } };
|
|
330530
|
+
}
|
|
330531
|
+
if (/^(fetch|webfetch)$/.test(kind)) {
|
|
330532
|
+
return { title: request.title, kind, rawInput: { url: value } };
|
|
330533
|
+
}
|
|
330534
|
+
return {
|
|
330535
|
+
title: request.title,
|
|
330536
|
+
kind,
|
|
330537
|
+
locations: value === null || value === void 0 ? void 0 : value.split(/\s+/).map((path) => ({ path })),
|
|
330538
|
+
};
|
|
330539
|
+
}
|
|
330003
330540
|
function CodePermissionCards({ generationId, }) {
|
|
330004
330541
|
const all = useCodePermissionRequests();
|
|
330005
330542
|
const requests = all.filter((r) => r.generation_id === generationId);
|
|
@@ -330023,20 +330560,28 @@ function CodePermissionCards({ generationId, }) {
|
|
|
330023
330560
|
console.error('[code-permission] respond failed', e);
|
|
330024
330561
|
}
|
|
330025
330562
|
};
|
|
330026
|
-
if (requests.length === 0)
|
|
330027
|
-
return null;
|
|
330028
330563
|
return (
|
|
330029
|
-
//
|
|
330030
|
-
//
|
|
330031
|
-
|
|
330032
|
-
|
|
330033
|
-
|
|
330034
|
-
|
|
330035
|
-
|
|
330036
|
-
|
|
330037
|
-
|
|
330038
|
-
|
|
330039
|
-
|
|
330564
|
+
// Mounted empty for the whole turn, so the first card is a mutation screen
|
|
330565
|
+
// readers announce rather than content they never see arrive.
|
|
330566
|
+
jsx("div", { "aria-live": "polite", "data-testid": "code-permission-cards", children: requests.length > 0 && (
|
|
330567
|
+
// Same visual language as ToolCallIndicator directly above it — gray left rail,
|
|
330568
|
+
// xs gray text, 18px sub-indent (12px icon + 6px gap). A white bordered card here
|
|
330569
|
+
// shouted next to that quiet list; this reads as a continuation of the agent's
|
|
330570
|
+
// activity, which is what it is. Only the buttons carry colour.
|
|
330571
|
+
jsx("div", { className: "mb-2 space-y-3 border-l-2 border-gray-200 pt-1 pl-3 text-xs leading-relaxed", children: requests.map((request) => {
|
|
330572
|
+
var _a, _b, _c, _d;
|
|
330573
|
+
const step = describeStep(mergeToolCall(undefined, (_a = request.tool_call) !== null && _a !== void 0 ? _a : legacyToolCall(request)), request.request_id);
|
|
330574
|
+
// A Browse run (own responder) keeps its own title; anything else described gets a sentence.
|
|
330575
|
+
const named = !request.respond && step.action !== 'other';
|
|
330576
|
+
const shown = (_c = safeDetail((_b = request.command) !== null && _b !== void 0 ? _b : undefined)) !== null && _c !== void 0 ? _c : (named ? step.details : undefined);
|
|
330577
|
+
return (jsxs("div", { children: [jsxs("div", { className: "flex flex-wrap items-center gap-1.5 text-gray-600 dark:text-gray-300", children: [jsx(ShieldCheck, { className: "h-3 w-3 shrink-0 text-gray-400" }), jsx("span", { className: "font-medium", children: t('chat.chatCodePermissionCard.title') })] }), jsx("div", { className: "mt-0.5 ml-[18px] text-gray-400 dark:text-gray-500", children: named
|
|
330578
|
+
? stepSentence(t, step, 'want')
|
|
330579
|
+
: safeDetail((_d = request.title) !== null && _d !== void 0 ? _d : undefined) ||
|
|
330580
|
+
t('chat.chatCodePermissionCard.unnamedAction') }), shown && (
|
|
330581
|
+
// bg-gray-200 is what the bubble already uses for inline code and pre
|
|
330582
|
+
// blocks, so the command sits on the same surface as the reply's own.
|
|
330583
|
+
jsx("code", { className: "mt-1 ml-[18px] block rounded bg-gray-200 px-1.5 py-1 font-mono break-all whitespace-pre-wrap text-gray-700", children: shown })), jsxs("div", { className: "mt-2 ml-[18px] flex items-center gap-2", children: [jsx(Button$1, { size: "sm", type: "button", className: "ibl-button-primary h-7 text-xs", onClick: () => answer(request, request.allow_option_id), children: t('chat.chatCodePermissionCard.allow') }), jsx(Button$1, { variant: "outline", size: "sm", type: "button", className: "h-7 text-xs", onClick: () => answer(request, request.reject_option_id), children: t('chat.chatCodePermissionCard.deny') })] })] }, request.request_id));
|
|
330584
|
+
}) })) }));
|
|
330040
330585
|
}
|
|
330041
330586
|
|
|
330042
330587
|
/**
|
|
@@ -331150,7 +331695,8 @@ function AgentTodoList({ todos, isCurrentlyStreaming = false }) {
|
|
|
331150
331695
|
}
|
|
331151
331696
|
const summary = t('chat.chatAiMessageBubble.agentTodoProgress', { done, total });
|
|
331152
331697
|
return (jsxs(Collapsible, { open: isOpen, onOpenChange: setIsOpen, className: "mb-2", "data-testid": "agent-todo-list", children: [jsxs(CollapsibleTrigger, { className: "flex cursor-pointer items-center gap-1 pt-1 text-xs text-gray-500 transition-colors hover:text-gray-600 dark:text-gray-400 dark:hover:text-gray-300", "data-testid": "agent-todo-list-trigger", children: [jsx(ChevronRight, { className: cn('h-3 w-3 shrink-0 transition-transform duration-200', isOpen && 'rotate-90') }), jsx("span", { className: "font-medium", children: t('chat.chatAiMessageBubble.agentTodoListTitle') }), jsxs("span", { className: "text-gray-400 dark:text-gray-500", "data-testid": "agent-todo-list-progress", children: ["\u2014 ", summary] })] }), jsx(CollapsibleContent, { className: "pb-2 pl-4", children: jsx("ol", { className: "space-y-1.5 border-l-2 border-gray-200 pt-2 pl-3 text-xs leading-relaxed dark:border-gray-700", "data-testid": "agent-todo-list-items", children: items.map((todo, index) => {
|
|
331153
|
-
|
|
331698
|
+
// An unfinished step after the turn ended must not keep shimmering.
|
|
331699
|
+
const meta = getStatusMeta(todo.status === 'in_progress' && !isCurrentlyStreaming ? 'pending' : todo.status);
|
|
331154
331700
|
const { Icon } = meta;
|
|
331155
331701
|
const statusLabel = t(`chat.chatAiMessageBubble.${meta.labelKey}`);
|
|
331156
331702
|
return (jsxs("li", { className: "flex items-start gap-1.5", "data-testid": "agent-todo-item", "data-status": todo.status, children: [jsx(Icon, { "aria-hidden": "true", className: cn('mt-0.5 h-3 w-3 shrink-0', meta.iconClass) }), jsx("span", { className: "sr-only", children: statusLabel }), jsx("span", { className: cn('min-w-0 flex-1', meta.contentClass), children: todo.content })] }, `${index}-${todo.content}`));
|
|
@@ -331170,7 +331716,7 @@ const mapActionToCallback = (key, joinTenant) => ({
|
|
|
331170
331716
|
})[key];
|
|
331171
331717
|
/** The forwarded ref lands on the Copy button (the chat focuses it when a reply settles). */
|
|
331172
331718
|
const AIMessageBubble = forwardRef(function AIMessageBubble({ content, profileImage, mentorName, timestamp, sessionId, mentorId, onRetry, messages, message, tenantKey, onOpenCanvas, streamingArtifactId, reasoningContent, toolCalls, isCurrentlyStreaming, showReasoning, workingPhase, }, ref) {
|
|
331173
|
-
var _a, _b;
|
|
331719
|
+
var _a, _b, _c;
|
|
331174
331720
|
const t = useChatT();
|
|
331175
331721
|
const host = useChatHost();
|
|
331176
331722
|
// OS `redirectToAuthSpaJoinTenant()`: the host's callback, else web-utils'
|
|
@@ -331215,7 +331761,14 @@ const AIMessageBubble = forwardRef(function AIMessageBubble({ content, profileIm
|
|
|
331215
331761
|
// that spends minutes running commands would otherwise look frozen.
|
|
331216
331762
|
const isCodeTurn = typeof (message === null || message === void 0 ? void 0 : message.id) === 'string' && message.id.startsWith('opencode-');
|
|
331217
331763
|
const showAgentActivity = showReasoning || isCodeTurn;
|
|
331218
|
-
//
|
|
331764
|
+
// A Code turn's steps and plan come from the OS store, in plain words; the
|
|
331765
|
+
// generic tool list only ever showed raw agent titles.
|
|
331766
|
+
const codeTurn = useCodeTurn(isCodeTurn ? message.id : undefined);
|
|
331767
|
+
// Code and Browse turns raise permission cards; their live region must exist first.
|
|
331768
|
+
const hostsPermissionCards = !!isCurrentlyStreaming &&
|
|
331769
|
+
typeof (message === null || message === void 0 ? void 0 : message.id) === 'string' &&
|
|
331770
|
+
/^(?:opencode|browse)-/.test(message.id);
|
|
331771
|
+
// The reasoning section and tool-call indicator are gated by `showAgentActivity`.
|
|
331219
331772
|
// While that's off, an assistant message that is still streaming has no text
|
|
331220
331773
|
// yet — without the verbose surfaces there would be nothing to show, so the
|
|
331221
331774
|
// bubble would render as an empty gray box. Skip rendering entirely until the
|
|
@@ -331231,24 +331784,31 @@ const AIMessageBubble = forwardRef(function AIMessageBubble({ content, profileIm
|
|
|
331231
331784
|
toolCalls,
|
|
331232
331785
|
showReasoning: showAgentActivity,
|
|
331233
331786
|
hasPermissionPrompts,
|
|
331787
|
+
hasCodeActivity: codeTurn.steps.length > 0 || !!((_b = codeTurn.plan) === null || _b === void 0 ? void 0 : _b.length),
|
|
331234
331788
|
});
|
|
331235
331789
|
if (!hasVisibleContent) {
|
|
331236
331790
|
return null;
|
|
331237
331791
|
}
|
|
331238
331792
|
const showReasoningSection = Boolean(showAgentActivity && reasoningContent);
|
|
331239
|
-
const showToolCalls =
|
|
331240
|
-
|
|
331793
|
+
const showToolCalls = isCodeTurn
|
|
331794
|
+
? codeTurn.steps.length > 0
|
|
331795
|
+
: hasGenericToolCalls(toolCalls, showAgentActivity);
|
|
331796
|
+
const todos = isCodeTurn ? codeTurn.plan : bubbleTodos(toolCalls, showAgentActivity);
|
|
331241
331797
|
const hasTodosToShow = !!(todos === null || todos === void 0 ? void 0 : todos.length);
|
|
331798
|
+
// The SDK emits no phase for Code turns; the store knows which step runs.
|
|
331799
|
+
const phase = isCodeTurn && workingPhase ? codeTurnPhase(codeTurn.steps, content, t) : workingPhase;
|
|
331242
331800
|
// A disclosure row is "active" when the phase it depicts is the live one AND
|
|
331243
331801
|
// the row is actually on screen. These two booleans do double duty, and the
|
|
331244
331802
|
// symmetry is the point: the active row gets its bouncing dots (it is now the
|
|
331245
331803
|
// thing conveying progress), and the same fact stands the working line down,
|
|
331246
331804
|
// because repeating "Thinking…" under a row that says "Thought" puts the same
|
|
331247
331805
|
// statement on screen twice. Exactly one of them animates.
|
|
331248
|
-
const isReasoningRowActive = (
|
|
331249
|
-
const isToolRowActive = (
|
|
331250
|
-
|
|
331251
|
-
|
|
331806
|
+
const isReasoningRowActive = (phase === null || phase === void 0 ? void 0 : phase.kind) === 'thinking' && showReasoningSection;
|
|
331807
|
+
const isToolRowActive = (phase === null || phase === void 0 ? void 0 : phase.kind) === 'tool' && showToolCalls;
|
|
331808
|
+
// A waiting permission card is the thing needing attention, not the line.
|
|
331809
|
+
const isRestatedByVisibleRow = isReasoningRowActive || isToolRowActive || hasPermissionPrompts;
|
|
331810
|
+
return (jsx(TooltipProvider, { children: jsx(AIMessageFrame, { profileImage: profileImage, mentorName: mentorName, timestamp: timestamp, children: jsxs(Fragment$1, { children: [jsxs("div", { className: cn('mb-1.5 rounded-2xl bg-gray-100 p-3 wrap-anywhere', CHAT_CSS_CLASS_NAMES.CHAT.AI_MESSAGE_RESPONSE, hasArtifactVersions(message) && 'bg-white p-0'), children: [showReasoningSection && (jsx(ReasoningSection, { reasoningContent: reasoningContent, isActive: isReasoningRowActive })), showToolCalls &&
|
|
331811
|
+
(isCodeTurn ? (jsx(CodeActivity, { generationId: message.id, isCurrentlyStreaming: isCurrentlyStreaming })) : (jsx(ToolCallIndicator, { toolCalls: toolCalls, isActive: isToolRowActive }))), hasTodosToShow && (jsx(AgentTodoList, { todos: todos, isCurrentlyStreaming: isCurrentlyStreaming })), (hasPermissionPrompts || hostsPermissionCards) && (jsx(CodePermissionCards, { generationId: message.id })), jsx("div", { "data-testid": "ai-message-body", className: "overflow-x-auto text-sm/6 text-gray-800 [&_.katex-display]:overflow-x-auto [&_.katex-display]:overflow-y-hidden [&_code]:rounded [&_code]:bg-gray-200 [&_code]:px-1 [&_code]:py-0.5 [&_code]:font-mono [&_em]:italic [&_li]:mb-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_pre]:overflow-x-auto [&_pre]:rounded [&_pre]:bg-gray-200 [&_pre]:p-2 [&_strong]:font-bold [&_ul]:list-disc [&_ul]:pl-4", children: jsx(MessagePreview, { content: content, artifactVersions: message === null || message === void 0 ? void 0 : message.artifactVersions, onOpenCanvas: onOpenCanvas, streamingArtifactId: streamingArtifactId }) }), (message === null || message === void 0 ? void 0 : message.actions) && (jsx("div", { className: "flex flex-wrap", children: message.actions.map((action, index) => (jsx(Button$1, { onClick: mapActionToCallback(action.actionType, joinTenant), className: "ibl-button-primary cursor-pointer", children: action.text }, index))) })), phase && (jsx(WorkingIndicator, { phase: phase, restatedByVisibleRow: isRestatedByVisibleRow, content: content, className: "mt-2" }))] }), jsxs("div", { className: cn('flex items-center space-x-4', isCurrentlyStreaming && 'hidden'), children: [jsx(AIMessageCopy, { ref: ref, content: content }), isLoggedIn() && !showingSharedChat && (jsx(AIMessageRating, { content: content, messages: messages, sessionId: sessionId, mentorId: mentorId, tenantKey: tenantKey })), (((_c = host.config) === null || _c === void 0 ? void 0 : _c.showMessageActionsWhenLoggedOut) || isLoggedIn()) &&
|
|
331252
331812
|
!showingSharedChat &&
|
|
331253
331813
|
!chatPrivacyActive && (jsxs(Fragment$1, { children: [jsx(AIMessageShare, { sessionId: sessionId, tenantKey: tenantKey }), jsx(AIMessageDownload, { message: message, messages: messages, mentorName: mentorName })] })), isLoggedIn() && !showingSharedChat && isMentorInappropriateContentEnabled && (jsx(AIMessageReportInappropriateContent, { mentorName: mentorName, messages: messages, supportEmail: supportEmail })), jsx(AIMessageSpeak, { message: message, mentorId: mentorId, tenantKey: tenantKey }), isLoggedIn() && !showingSharedChat && (jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsxs("button", { onClick: () => {
|
|
331254
331814
|
const lastUserMessage = getLastUserMessage(messages);
|
|
@@ -331897,6 +332457,29 @@ function ChatActionBlockingOverlay({ isOpen, actionType, onStopScreenShare, }) {
|
|
|
331897
332457
|
: t('modalsChatActionBlockingOverlay.screenSharingActiveTitle') }), jsx("p", { id: "blocking-overlay-description", className: "mb-6 text-gray-600", children: t('modalsChatActionBlockingOverlay.sessionActiveDescription', { actionLabel }) }), jsx("div", { className: "mb-4 flex flex-col gap-3", children: !isVoiceCall && onStopScreenShare && (jsxs("button", { onClick: onStopScreenShare, className: "flex w-full items-center justify-center gap-2 rounded-lg bg-red-600 px-4 py-3 font-medium text-white transition-colors hover:bg-red-700", children: [jsx(CircleStop, { className: "h-5 w-5" }), jsx("span", { children: t('modalsChatActionBlockingOverlay.stopScreenSharing') })] })) }), jsx("p", { className: "mt-4 text-xs text-gray-500", children: t('modalsChatActionBlockingOverlay.backgroundHandleDescription', { actionLabel }) })] }) }));
|
|
331898
332458
|
}
|
|
331899
332459
|
|
|
332460
|
+
/**
|
|
332461
|
+
* Plain-words keys (`chatCodeErrors.*`) for the Code errors the Rust side and
|
|
332462
|
+
* the SDK surface as raw strings. Only the developer-shaped ones are mapped; a
|
|
332463
|
+
* string that is already a sentence (install, sign-in, a refused model) shows
|
|
332464
|
+
* as it is. First match wins.
|
|
332465
|
+
*/
|
|
332466
|
+
const PLAIN_CODE_ERRORS = [
|
|
332467
|
+
[
|
|
332468
|
+
/^opencode error on |opencode closed before responding|failed writing to opencode|no user message to send/,
|
|
332469
|
+
'stopped',
|
|
332470
|
+
],
|
|
332471
|
+
// Anchored to the desktop's and the phone's exact wording: every host's chat shares this toast.
|
|
332472
|
+
[/^(?:Codex|Claude Code|opencode) did not answer within \d+s\.$|^turn timed out$/, 'noAnswer'],
|
|
332473
|
+
[/no model selected for Code/, 'noModel'],
|
|
332474
|
+
[/^failed to launch|returned no sessionId|ibl\.ai guidance anchor missing/, 'couldNotStart'],
|
|
332475
|
+
[/Not signed in .*missing tenant or token/, 'signedOut'],
|
|
332476
|
+
];
|
|
332477
|
+
function plainCodeError(raw) {
|
|
332478
|
+
const text = raw.replace(/^opencode failed: /, '');
|
|
332479
|
+
const hit = PLAIN_CODE_ERRORS.find(([pattern]) => pattern.test(text));
|
|
332480
|
+
return hit ? hit[1] : null;
|
|
332481
|
+
}
|
|
332482
|
+
|
|
331900
332483
|
const ToastErrorMessage = ({ message, supportEmail, supportPhone, useSupportPhone = false, tenantKey: tenantKeyProp, }) => {
|
|
331901
332484
|
const t = useChatT();
|
|
331902
332485
|
const host = useChatHost();
|
|
@@ -331904,8 +332487,15 @@ const ToastErrorMessage = ({ message, supportEmail, supportPhone, useSupportPhon
|
|
|
331904
332487
|
useEffect(() => {
|
|
331905
332488
|
console.error(JSON.stringify({ tenant: tenantKey, error: message }));
|
|
331906
332489
|
}, [message]);
|
|
331907
|
-
|
|
331908
|
-
|
|
332490
|
+
// A developer-shaped Code error reads as a plain sentence; the raw text stays in the log above.
|
|
332491
|
+
const codeKey = plainCodeError(message);
|
|
332492
|
+
const plainMessage = String(markdownToPlainText(message));
|
|
332493
|
+
const sentence = codeKey
|
|
332494
|
+
? t(`chat.chatCodeErrors.${codeKey}`)
|
|
332495
|
+
: plainMessage.match(/[.!?]$/)
|
|
332496
|
+
? plainMessage
|
|
332497
|
+
: `${plainMessage}.`;
|
|
332498
|
+
return (jsx("div", { children: jsxs("span", { children: [t('chat.toastErrorMessage.sorryAboutThat'), " ", sentence, ' ', t('chat.toastErrorMessage.pleaseTryAgainOr'), ' ', jsx("a", { className: "toast-wrapped-contact-tag text-blue-600 hover:text-blue-800", href: `mailto:${supportEmail}`, children: t('chat.toastErrorMessage.contactUs') }), ".", useSupportPhone && supportPhone ? (jsxs(Fragment$1, { children: [' ', t('chat.toastErrorMessage.textUsAt'), ' ', jsx("a", { className: "toast-wrapped-contact-tag text-blue-600 hover:text-blue-800", href: `tel:${supportPhone}`, children: supportPhone }), "."] })) : null] }) }));
|
|
331909
332499
|
};
|
|
331910
332500
|
|
|
331911
332501
|
/**
|
|
@@ -332169,7 +332759,7 @@ function useHostIsOnline(override) {
|
|
|
332169
332759
|
return override !== null && override !== void 0 ? override : providerOnline;
|
|
332170
332760
|
}
|
|
332171
332761
|
function ChatInner({ mode = 'default', isPreviewMode = false, hasBorder = true, isInCanvasView = false, }) {
|
|
332172
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
332762
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
332173
332763
|
const t = useChatT();
|
|
332174
332764
|
const { tenantKey, mentorId, username, axdToken, userTenants, visitingTenant, isEmbedMode: isEmbeddedMode, isPublicRoute, redirectToAuthSpa, config: hostConfig, features, } = useChatHost();
|
|
332175
332765
|
// `Chat` always provides a config; the fallback only satisfies the types.
|
|
@@ -333337,6 +333927,7 @@ function ChatInner({ mode = 'default', isPreviewMode = false, hasBorder = true,
|
|
|
333337
333927
|
const hasPermissionPrompts = isStreaming &&
|
|
333338
333928
|
!!streamingMessage &&
|
|
333339
333929
|
permissionRequests.some((r) => r.generation_id === streamingMessage.id);
|
|
333930
|
+
const streamCodeTurn = useCodeTurn(streamIsCodeTurn ? streamingMessage === null || streamingMessage === void 0 ? void 0 : streamingMessage.id : undefined);
|
|
333340
333931
|
const isStreamingBubbleVisible = isStreaming &&
|
|
333341
333932
|
!!streamingMessage &&
|
|
333342
333933
|
streamingMessage.visible === true &&
|
|
@@ -333347,10 +333938,11 @@ function ChatInner({ mode = 'default', isPreviewMode = false, hasBorder = true,
|
|
|
333347
333938
|
toolCalls: streamingToolCalls,
|
|
333348
333939
|
showReasoning: mentorSettings.showReasoning || streamIsCodeTurn,
|
|
333349
333940
|
hasPermissionPrompts,
|
|
333941
|
+
hasCodeActivity: streamCodeTurn.steps.length > 0 || !!((_f = streamCodeTurn.plan) === null || _f === void 0 ? void 0 : _f.length),
|
|
333350
333942
|
});
|
|
333351
333943
|
// The new-chat screen: no messages yet, or only the agent's greeting.
|
|
333352
333944
|
const isWelcomeVisible = (messages.length === 0 ||
|
|
333353
|
-
(!isNewSession.current && messages.length === 1 && ((
|
|
333945
|
+
(!isNewSession.current && messages.length === 1 && ((_g = messages[0]) === null || _g === void 0 ? void 0 : _g.role) === 'assistant')) &&
|
|
333354
333946
|
!isAdvancedMode &&
|
|
333355
333947
|
!(!isNewSession.current && isLoadingChats && messages.length === 0);
|
|
333356
333948
|
const workingIndicator = isTurnInFlight && !isStreamingBubbleVisible ? (jsx(AIWorkingMessage, { phase: workingPhase, mentorName: mentorName, profileImage: profileImage, timestamp: turnStartedAtRef.current })) : null;
|
|
@@ -333362,7 +333954,7 @@ function ChatInner({ mode = 'default', isPreviewMode = false, hasBorder = true,
|
|
|
333362
333954
|
// Fill available space when the messages section won't render
|
|
333363
333955
|
// (no messages, or only a single assistant greeting/proactive prompt)
|
|
333364
333956
|
'min-h-0 flex-1': !isCanvasOpen &&
|
|
333365
|
-
(messages.length === 0 || (messages.length === 1 && ((
|
|
333957
|
+
(messages.length === 0 || (messages.length === 1 && ((_h = messages[0]) === null || _h === void 0 ? void 0 : _h.role) === 'assistant')),
|
|
333366
333958
|
// Reserve the same scrollbar gutter as the chat input container so
|
|
333367
333959
|
// the welcome message stays horizontally aligned with the input.
|
|
333368
333960
|
// Advanced mode scrolls inside its own panel, so it only needs the
|
|
@@ -333371,7 +333963,7 @@ function ChatInner({ mode = 'default', isPreviewMode = false, hasBorder = true,
|
|
|
333371
333963
|
'overflow-y-auto': !isAdvancedMode && !isCanvasOpen,
|
|
333372
333964
|
'overflow-y-hidden': isAdvancedMode && !isCanvasOpen,
|
|
333373
333965
|
'min-h-0': isCompactMode, // Allow flex shrinking in compact mode
|
|
333374
|
-
}), style: isCanvasOpen ? { display: 'none' } : undefined, children: [isAdvancedMode && (jsxs("div", { className: "mx-auto flex h-full w-full flex-col overflow-hidden rounded-lg bg-white", style: { maxWidth: `${chatAreaMaxWidth}px` }, children: [jsx(AdvancedChatHeader, { mentorName: mentorName, profileImage: profileImage, tabs: advancedTabs, activeTab: activeTab, setActiveTab: changeTab, isTyping: isStreaming }), messages.length === 0 && (jsx(AdvancedStaticChatBuilder, { mentorName: mentorName, profileImage: profileImage, sendMessage: sendMessage, activeTab: activeTab, tenantKey: tenantKey, username: username !== null && username !== void 0 ? username : '', sessionId: (
|
|
333966
|
+
}), style: isCanvasOpen ? { display: 'none' } : undefined, children: [isAdvancedMode && (jsxs("div", { className: "mx-auto flex h-full w-full flex-col overflow-hidden rounded-lg bg-white", style: { maxWidth: `${chatAreaMaxWidth}px` }, children: [jsx(AdvancedChatHeader, { mentorName: mentorName, profileImage: profileImage, tabs: advancedTabs, activeTab: activeTab, setActiveTab: changeTab, isTyping: isStreaming }), messages.length === 0 && (jsx(AdvancedStaticChatBuilder, { mentorName: mentorName, profileImage: profileImage, sendMessage: sendMessage, activeTab: activeTab, tenantKey: tenantKey, username: username !== null && username !== void 0 ? username : '', sessionId: (_j = cachedSessionId === null || cachedSessionId === void 0 ? void 0 : cachedSessionId[sessionKey]) !== null && _j !== void 0 ? _j : sessionId, mentorId: mentorId, mentorUniqueId: uniqueMentorId, welcomeWsUrl: `${config.baseWsUrl()}/ws/langflow/`, isPublicRoute: isAccessingPublicRoute }))] })), !isAdvancedMode && !isNewSession.current && isLoadingChats && messages.length === 0 && (jsx("div", { className: "flex h-full w-full items-center justify-center", children: jsx(Spinner, { className: "h-14 w-14" }) })), isWelcomeVisible && (jsx(WelcomeChatNew, { mentorName: mentorName, sessionId: (_k = cachedSessionId === null || cachedSessionId === void 0 ? void 0 : cachedSessionId[sessionKey]) !== null && _k !== void 0 ? _k : sessionId, isNewSession: isNewSession.current || (messages.length === 0 && !isLoadingChats), aiWelcomeMessage: messages.length === 1 && ((_l = messages[0]) === null || _l === void 0 ? void 0 : _l.role) === 'assistant' ? (_m = messages[0]) === null || _m === void 0 ? void 0 : _m.content : '', enabledGuidedPrompts: enabledGuidedPrompts, onSubmit: handleSubmit, onScreenSharingClick: handleScreenSharingClick, isScreenSharingModalOpen: isScreenSharingModalOpen, onPhoneCallClick: handlePhoneCallClick, stopGenerating: stopAnyGeneration, tenantKey: tenantKey, username: username !== null && username !== void 0 ? username : '', enableWebBrowsing: enableWebBrowsing, setMessage: setMessage, isStreaming: isStreaming, enableSafetyDisclaimer: enableSafetyDisclaimer, isPreviewMode: isPreviewMode, updateSessionTools: updateSessionTools, setSessionTools: setSessionTools, activeTools: activeTools, screenSharing: screenSharing, deepResearch: deepResearch, studyMode: studyMode, imageGeneration: imageGeneration, codeInterpreter: codeInterpreter, mentorUniqueId: mentorId, profileImage: profileImage, promptsIsEnabled: promptsIsEnabled, googleSlidesIsEnabled: googleSlidesIsEnabled, googleDocumentIsEnabled: googleDocumentIsEnabled, artifactsEnabled: artifactsEnabled, chatAreaMaxWidth: chatAreaMaxWidth, isConnecting: !isConnected, compactMode: isCompactMode }))] }), isCanvasOpen && !isInCanvasView ? (
|
|
333375
333967
|
/* Split layout when canvas is open */
|
|
333376
333968
|
jsxs("div", { className: "relative flex flex-1 overflow-hidden", ref: resizeRef, style: { minHeight: 0, maxHeight: '100%', height: '100%' }, children: [jsxs("div", { className: "hidden flex-shrink-0 flex-col overflow-hidden border-r border-gray-200 md:flex", style: { width: `${chatWidth}%`, minHeight: 0, maxHeight: '100%' }, children: [jsx("div", { ref: chatContainerRef, onScroll: handleScroll, className: "flex-1 overflow-y-auto [scrollbar-gutter:stable]", children: jsxs("div", { className: "px-3 py-4", children: [isLoadingOlderMessages && (jsx("div", { className: "flex justify-center py-2", "data-testid": "loading-older-messages", children: jsx(Spinner, { className: "h-5 w-5" }) })), jsxs(ErrorBoundary, { children: [messages.length > 0 ? (jsx(ChatMessages, { ref: lastAIMessageCopyButtonRef, messages: messages, highlightedMessageId: highlightedMessageId, profileImage: profileImage, mentorName: mentorName, sessionId: sessionId, mentorId: mentorId, tenantKey: tenantKey, handleHighlightMessage: handleHighlightMessage, handleSubmit: handleSubmit, onReply: (message) => {
|
|
333377
333969
|
setReplyingToMessage(message);
|
|
@@ -333383,10 +333975,10 @@ function ChatInner({ mode = 'default', isPreviewMode = false, hasBorder = true,
|
|
|
333383
333975
|
height: '100%',
|
|
333384
333976
|
}, children: [jsx(CanvasView, { canvasTitle: canvasState.title, canvasContent: canvasState.content, canvasType: canvasState.type, artifactId: canvasState.artifactId, org: canvasState.org, userId: canvasState.userId, fileExtension: canvasState.fileExtension, metadata: canvasState.metadata, sessionId: sessionId, tenantKey: tenantKey, activeTools: activeTools, artifactsEnabled: artifactsEnabled, refreshTrigger: canvasRefreshTrigger, sendMessage: (text, options) => {
|
|
333385
333977
|
sendMessage(activeTab, text, options);
|
|
333386
|
-
}, onClose: handleCloseCanvas }, `${(
|
|
333978
|
+
}, onClose: handleCloseCanvas }, `${(_o = canvasState.artifactId) !== null && _o !== void 0 ? _o : 'canvas'}-${canvasRefreshTrigger}`), jsx("div", { className: "flex-shrink-0 border-t border-gray-200 bg-white p-3 md:hidden", children: jsx(ChatInputForm, { variant: "redesign", stopStreamingButtonRef: stopStreamingButtonRef, sessionId: sessionId, onSubmit: handleSubmit, stopGenerating: stopAnyGeneration, onScreenSharingClick: handleScreenSharingClick, isScreenSharingModalOpen: isScreenSharingModalOpen, onPhoneCallClick: handlePhoneCallClick, tenantKey: tenantKey, username: username !== null && username !== void 0 ? username : '', setMessage: setMessage, enableSafetyDisclaimer: enableSafetyDisclaimer, isPreviewMode: isPreviewMode, enableWebBrowsing: enableWebBrowsing, isStreaming: isStreaming, updateSessionTools: updateSessionTools, setSessionTools: setSessionTools, activeTools: activeTools, screenSharing: screenSharing, deepResearch: deepResearch, studyMode: studyMode, imageGeneration: imageGeneration, codeInterpreter: codeInterpreter, promptsIsEnabled: promptsIsEnabled, googleSlidesIsEnabled: googleSlidesIsEnabled, googleDocumentIsEnabled: googleDocumentIsEnabled, artifactsEnabled: artifactsEnabled, compactMode: isCompactMode, isConnecting: !isConnected }) })] })] })) : (
|
|
333387
333979
|
/* Normal chat layout when canvas is closed */
|
|
333388
333980
|
messages.length > 0 &&
|
|
333389
|
-
(messages[0].role === 'assistant' ? messages.slice(1) : messages).length > 0 && (jsx("div", { ref: chatContainerRef, onScroll: handleScroll, className: "min-h-0 flex-1 overflow-y-auto", children: jsxs("div", { className: "mx-auto w-full py-6", style: { maxWidth: `${chatAreaMaxWidth}px` }, children: [isLoadingOlderMessages && (jsx("div", { className: "flex justify-center py-2", "data-testid": "loading-older-messages", children: jsx(Spinner, { className: "h-5 w-5" }) })), jsxs(ErrorBoundary, { children: [jsx(ChatMessages, { ref: lastAIMessageCopyButtonRef, messages: messages[0].role === 'assistant' ? messages.slice(1) : messages, highlightedMessageId: highlightedMessageId, profileImage: profileImage, mentorName: mentorName, sessionId: (
|
|
333981
|
+
(messages[0].role === 'assistant' ? messages.slice(1) : messages).length > 0 && (jsx("div", { ref: chatContainerRef, onScroll: handleScroll, className: "min-h-0 flex-1 overflow-y-auto", children: jsxs("div", { className: "mx-auto w-full py-6", style: { maxWidth: `${chatAreaMaxWidth}px` }, children: [isLoadingOlderMessages && (jsx("div", { className: "flex justify-center py-2", "data-testid": "loading-older-messages", children: jsx(Spinner, { className: "h-5 w-5" }) })), jsxs(ErrorBoundary, { children: [jsx(ChatMessages, { ref: lastAIMessageCopyButtonRef, messages: messages[0].role === 'assistant' ? messages.slice(1) : messages, highlightedMessageId: highlightedMessageId, profileImage: profileImage, mentorName: mentorName, sessionId: (_p = cachedSessionId === null || cachedSessionId === void 0 ? void 0 : cachedSessionId[sessionKey]) !== null && _p !== void 0 ? _p : sessionId, mentorId: mentorId, tenantKey: tenantKey, handleHighlightMessage: handleHighlightMessage, handleSubmit: handleSubmit, onReply: (message) => {
|
|
333390
333982
|
setReplyingToMessage(message);
|
|
333391
333983
|
focusPromptTextarea();
|
|
333392
333984
|
}, onOpenCanvas: handleOpenCanvas, streamingArtifactId: streamingArtifactId, isStreaming: isStreaming, streamingReasoningContent: streamingReasoningContent, streamingToolCalls: streamingToolCalls, showReasoning: mentorSettings.showReasoning, currentStreamingMessageId: currentStreamingMsg === null || currentStreamingMsg === void 0 ? void 0 : currentStreamingMsg.id, workingPhase: isTurnInFlight ? workingPhase : undefined }), jsx("div", { "aria-live": "polite", role: "status", className: "sr-only", children: mentorAccessibilityMessage }), workingIndicator, !showingSharedChat && guidedPrompts] })] }) }))), isScrolledUp && !isPreviewMode && messages.length > 0 && !isCanvasOpen && (jsx("div", { className: "pointer-events-none sticky bottom-4 z-10 flex h-0 w-full justify-center bg-transparent", children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsxs(Button$1, { onClick: (event) => {
|
|
@@ -333397,11 +333989,11 @@ function ChatInner({ mode = 'default', isPreviewMode = false, hasBorder = true,
|
|
|
333397
333989
|
(isAdvancedMode ||
|
|
333398
333990
|
isEmbeddedMode ||
|
|
333399
333991
|
(messages.length > 0 &&
|
|
333400
|
-
(messages[0].role === 'assistant' ? messages.slice(1) : messages).length > 0)) && (jsx("div", { className: "flex-shrink-0 overflow-y-auto pb-3.5 [scrollbar-gutter:stable]", children: jsx(ChatInputForm, { variant: "redesign", stopStreamingButtonRef: stopStreamingButtonRef, sessionId: (
|
|
333992
|
+
(messages[0].role === 'assistant' ? messages.slice(1) : messages).length > 0)) && (jsx("div", { className: "flex-shrink-0 overflow-y-auto pb-3.5 [scrollbar-gutter:stable]", children: jsx(ChatInputForm, { variant: "redesign", stopStreamingButtonRef: stopStreamingButtonRef, sessionId: (_q = cachedSessionId === null || cachedSessionId === void 0 ? void 0 : cachedSessionId[sessionKey]) !== null && _q !== void 0 ? _q : sessionId, onSubmit: handleSubmit, stopGenerating: stopAnyGeneration, onScreenSharingClick: handleScreenSharingClick, isScreenSharingModalOpen: isScreenSharingModalOpen, onPhoneCallClick: handlePhoneCallClick, tenantKey: tenantKey, username: username !== null && username !== void 0 ? username : '', setMessage: setMessage, enableSafetyDisclaimer: enableSafetyDisclaimer, isPreviewMode: isPreviewMode, enableWebBrowsing: enableWebBrowsing, isStreaming: isStreaming, updateSessionTools: updateSessionTools, setSessionTools: setSessionTools, activeTools: activeTools, screenSharing: screenSharing, deepResearch: deepResearch, studyMode: studyMode, imageGeneration: imageGeneration, codeInterpreter: codeInterpreter, promptsIsEnabled: promptsIsEnabled, googleSlidesIsEnabled: googleSlidesIsEnabled, googleDocumentIsEnabled: googleDocumentIsEnabled, artifactsEnabled: artifactsEnabled, compactMode: isCompactMode,
|
|
333401
333993
|
// The embed composer widens with its frame up to ~680px (#2586 Embed v2 / LTI).
|
|
333402
333994
|
chatAreaMaxWidth: isEmbeddedMode
|
|
333403
333995
|
? Math.min(chatAreaMaxWidth, EMBED_COMPOSER_MAX_WIDTH)
|
|
333404
|
-
: chatAreaMaxWidth, promptsAbove: isEmbeddedMode && isWelcomeVisible ? (jsx(EmbedStarterPrompts, { onPromptSelect: handleSubmit, enabledGuidedPrompts: enabledGuidedPrompts, sessionId: (
|
|
333996
|
+
: chatAreaMaxWidth, promptsAbove: isEmbeddedMode && isWelcomeVisible ? (jsx(EmbedStarterPrompts, { onPromptSelect: handleSubmit, enabledGuidedPrompts: enabledGuidedPrompts, sessionId: (_r = cachedSessionId === null || cachedSessionId === void 0 ? void 0 : cachedSessionId[sessionKey]) !== null && _r !== void 0 ? _r : sessionId })) : undefined }) })), isPhoneCallModalOpen && (jsx(LiveKitChat$1, { tenantKey: tenantKey, mentorUniqueId: uniqueMentorId, sessionId: (_s = cachedSessionId === null || cachedSessionId === void 0 ? void 0 : cachedSessionId[sessionKey]) !== null && _s !== void 0 ? _s : sessionId, username: username !== null && username !== void 0 ? username : '',
|
|
333405
333997
|
// Labels the agent's transcript lines with the mentor's real name
|
|
333406
333998
|
// and face, so call captions match the chat thread behind them.
|
|
333407
333999
|
mentorName: mentorName, mentorImage: profileImage, isOpen: isPhoneCallModalOpen, onClose: () => {
|
|
@@ -333415,7 +334007,7 @@ function ChatInner({ mode = 'default', isPreviewMode = false, hasBorder = true,
|
|
|
333415
334007
|
// this mirrors the screen-sharing handler below.
|
|
333416
334008
|
refetchChats();
|
|
333417
334009
|
}
|
|
333418
|
-
} })), isScreenSharingModalOpen && (jsx(LiveKitScreenSharing$1, { tenantKey: tenantKey, mentorUniqueId: uniqueMentorId, sessionId: (
|
|
334010
|
+
} })), isScreenSharingModalOpen && (jsx(LiveKitScreenSharing$1, { tenantKey: tenantKey, mentorUniqueId: uniqueMentorId, sessionId: (_t = cachedSessionId === null || cachedSessionId === void 0 ? void 0 : cachedSessionId[sessionKey]) !== null && _t !== void 0 ? _t : sessionId, username: username !== null && username !== void 0 ? username : '', isOpen: isScreenSharingModalOpen, mentorName: mentorName, onClose: () => {
|
|
333419
334011
|
if (window.opener) {
|
|
333420
334012
|
window.close();
|
|
333421
334013
|
}
|