@swiss-ai-hub/web 0.321.1 → 0.323.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/components/Event/Display/AddMemoryToChatHistoryEvent.vue +3 -3
  2. package/components/Event/Display/AttachedFileEvent.vue +42 -0
  3. package/components/Event/Display/AttachedFilesReadEvent.vue +22 -0
  4. package/components/Event/Display/BaseRetrieveMemoryEvent.vue +2 -2
  5. package/components/Event/Display/BaseStoreMemoryEvent.vue +2 -2
  6. package/components/Event/Display/CompleteConversationEvent.vue +35 -0
  7. package/components/Event/Display/ComposeContextEvent.vue +38 -0
  8. package/components/Event/Display/ContextComposedEvent.vue +60 -0
  9. package/components/Event/Display/ContextualizeConversationEvent.vue +26 -0
  10. package/components/Event/Display/ConversationContextualizedEvent.vue +34 -0
  11. package/components/Event/Display/HumanInTheLoopResponseEvent.vue +11 -1
  12. package/components/Event/Display/KnowledgeSearchedEvent.vue +33 -0
  13. package/components/Event/Display/MemoryRecalledEvent.vue +33 -0
  14. package/components/Event/Display/MemoryStorageRequestedEvent.vue +29 -0
  15. package/components/Event/Display/NotAMetaQuestionEvent.vue +20 -0
  16. package/components/Event/Display/Part/Facts.vue +39 -0
  17. package/components/Event/Display/Part/MessageList.vue +50 -0
  18. package/components/Event/Display/Part/ToolCalls.vue +58 -0
  19. package/components/Event/Display/Part/ToolLoopState.vue +36 -0
  20. package/components/Event/Display/ReadAttachedFilesEvent.vue +28 -0
  21. package/components/Event/Display/RecallMemoryEvent.vue +27 -0
  22. package/components/Event/Display/RunToolLoopEvent.vue +34 -0
  23. package/components/Event/Display/SandboxFileDisplayedEvent.vue +46 -0
  24. package/components/Event/Display/SearchKnowledgeEvent.vue +31 -0
  25. package/components/Event/Display/ToolCallApprovedEvent.vue +27 -0
  26. package/components/Event/Display/ToolCallsDecidedEvent.vue +24 -0
  27. package/components/Event/Display/ToolLoopCondensedEvent.vue +31 -0
  28. package/components/Event/Display/ToolLoopFinishedEvent.vue +49 -0
  29. package/components/Event/Display/ToolLoopIterationEvent.vue +18 -0
  30. package/components/Event/Display/ToolLoopStatusEvent.vue +27 -0
  31. package/components/Event/Display/ToolResultEvent.vue +38 -0
  32. package/components/Event/List/EventList.vue +1 -1
  33. package/components/FormKit/DynamicConfiguration.vue +6 -1
  34. package/components/FormKit/KnowledgeCollectionSelector.vue +281 -0
  35. package/components/FormKit/KnowledgeDatabaseSelector.vue +7 -0
  36. package/components/FormKit/LocaleInput.vue +2 -0
  37. package/components/FormKit/SecretFileInput.vue +181 -0
  38. package/components/FormKit/VectorStoreInput.vue +20 -1
  39. package/components/Knowledge/Database/CreateModal.vue +91 -2
  40. package/components/Knowledge/Database/SourceModal.vue +165 -0
  41. package/components/Knowledge/Document/UploadModal.vue +4 -0
  42. package/components/Knowledge/Namespace/Card.vue +4 -4
  43. package/components/Knowledge/Namespace/CreateModal.vue +1 -1
  44. package/components/Knowledge/Namespace/EditModal.vue +3 -4
  45. package/components/Role/AccessRulesEditor.vue +1 -1
  46. package/components/Service/Selection.vue +7 -1
  47. package/components/Support/IncidentButton.vue +37 -0
  48. package/components/Support/IncidentDialog.vue +119 -0
  49. package/components/User/Settings.vue +9 -8
  50. package/components/UserFiles/Browser.vue +361 -0
  51. package/components/UserFiles/MoveDialog.vue +77 -0
  52. package/components/UserFiles/NameDialog.vue +59 -0
  53. package/components/UserFiles/Preview.vue +110 -0
  54. package/composables/auth/useAuth.ts +19 -3
  55. package/composables/document/useDocumentIngestionPolling.ts +64 -0
  56. package/composables/document/useDocuments.ts +3 -0
  57. package/composables/document/useSourcePipelines.ts +23 -0
  58. package/composables/document/useUpdateDatabaseSource.ts +21 -0
  59. package/composables/event/useEventComponent.ts +46 -0
  60. package/composables/form/useFormKitTransform.ts +68 -17
  61. package/composables/openwebui/useOpenWebuiDisclaimer.ts +22 -0
  62. package/composables/suite/useApps.ts +12 -3
  63. package/composables/suite/useSuite.ts +2 -0
  64. package/composables/support/useIncidentAvailability.ts +17 -0
  65. package/composables/support/useIncidentContext.ts +56 -0
  66. package/composables/support/useIncidentForm.ts +45 -0
  67. package/composables/support/useIncidentReport.ts +16 -0
  68. package/composables/support/useOpenWebUIContext.ts +38 -0
  69. package/composables/tenant/useChatDisclaimer.ts +24 -0
  70. package/composables/user/useApplyLocale.ts +23 -0
  71. package/composables/user/useMyLocale.ts +20 -0
  72. package/composables/user/useRestorePreferredLocale.ts +38 -0
  73. package/composables/userFiles/useCreateUserFolder.ts +15 -0
  74. package/composables/userFiles/useDeleteUserFile.ts +15 -0
  75. package/composables/userFiles/useMoveUserFile.ts +15 -0
  76. package/composables/userFiles/useUploadUserFiles.ts +19 -0
  77. package/composables/userFiles/useUserFileContent.ts +24 -0
  78. package/composables/userFiles/useUserFiles.ts +25 -0
  79. package/formkit.config.ts +10 -2
  80. package/i18n/locales/de.yaml +171 -3
  81. package/i18n/locales/en.yaml +172 -3
  82. package/i18n/locales/fr.yaml +173 -3
  83. package/i18n/locales/it.yaml +173 -3
  84. package/layouts/default.vue +7 -1
  85. package/middleware/auth.global.ts +6 -3
  86. package/middleware/home-redirect.ts +15 -4
  87. package/package.json +4 -3
  88. package/pages/[tenant]/service/knowledge/[db]/[namespace].vue +6 -8
  89. package/pages/[tenant]/service/knowledge.vue +33 -7
  90. package/pages/[tenant]/service/openai/[thread_id]/[display_id]/files.vue +51 -0
  91. package/pages/[tenant]/service/openai.vue +61 -17
  92. package/pages/[tenant]/service/user-knowledge.vue +19 -0
  93. package/plugins/api-client.client.ts +5 -0
  94. package/plugins/oidc-client.ts +14 -7
  95. package/sdk/client/index.ts +171 -1
  96. package/sdk/client/schemas.gen.ts +18602 -8560
  97. package/sdk/client/sdk.gen.ts +482 -0
  98. package/sdk/client/types.gen.ts +13616 -7044
  99. package/types/EventFact.ts +4 -0
  100. package/utils/apiResponseGuard.ts +97 -0
@@ -271,11 +271,27 @@ event:
271
271
  assistant: Assistant
272
272
  system: Système
273
273
  user: Utilisateur
274
+ contextComposed:
275
+ summary: 'Contexte assemblé pour le modèle : {count} message | Contexte assemblé
276
+ pour le modèle : {count} messages'
277
+ description: L'historique de chat reçu par le modèle, avec tous les blocs de contexte
278
+ récupérés
279
+ assistant: Assistant
280
+ system: Système
281
+ user: Utilisateur
274
282
  metaQuestionDetected:
275
283
  category:
276
284
  identity: Identité
277
285
  capabilities: Capacités
278
286
  behavior: Comportement
287
+ sandboxFileDisplayed:
288
+ file: Fichier
289
+ type: Type
290
+ size: Taille
291
+ path: Dans le bac à sable
292
+ humanInTheLoopResponse:
293
+ confirmed: Confirmé
294
+ declined: Refusé
279
295
  standaloneQuestionCondenser:
280
296
  summary: Question affinée et condensée
281
297
  condensedQuestion: Question Condensée
@@ -294,6 +310,63 @@ event:
294
310
  delegations: Délégations
295
311
  delegatedTaskAgentInTheLoop: Tâche déléguée (Agent dans la boucle)
296
312
  allEvents: Tous les événements
313
+ parts:
314
+ noMessages: Aucun message
315
+ yes: Oui
316
+ no: Non
317
+ capability:
318
+ userQuery: Message de l'utilisateur
319
+ historyMessages: Messages dans l'historique
320
+ condensed: Condensée à partir de l'historique
321
+ query: Requête
322
+ block: Bloc {number}
323
+ blocks: Blocs de contexte
324
+ namespaces: Portées de la mémoire d'organisation
325
+ toolCall: Appel d'outil
326
+ userMemories: Souvenirs de l'utilisateur
327
+ organizationMemories: Souvenirs de l'organisation
328
+ references: Collections référencées
329
+ citeSources: Citer les sources
330
+ sections: Sections trouvées
331
+ notSearched: Non recherchées (pas d'accès)
332
+ files: Fichiers
333
+ reserveTokens: Jetons réservés
334
+ fileStatus:
335
+ read: Lu
336
+ truncated: Raccourci
337
+ failed: Échec
338
+ citationId: Identifiant de citation
339
+ pages: Pages
340
+ error: Erreur
341
+ stop: Se termine par
342
+ targetAgent: Rédacteur de mémoire
343
+ toolLoop:
344
+ loop: Ensemble d'outils
345
+ mode: Mode
346
+ modes:
347
+ answer: Répondre
348
+ gather: Rassembler le contexte
349
+ iteration: Décisions
350
+ toolCallsMade: Appels d'outils jusqu'ici
351
+ messages: Messages dans la boucle
352
+ offeredTools: Outils proposés
353
+ condensedResults: Résultats condensés
354
+ needsCondensing: Doit être condensé
355
+ decidedCalls: Un appel d'outil décidé | {count} appels d'outils décidés
356
+ narrowedTools: Limité à
357
+ maxIterations: Limite de décisions
358
+ tool: Outil
359
+ kind: Type
360
+ kinds:
361
+ function: Fonction
362
+ capability: Capacité
363
+ failed: Échec
364
+ resultContext: Contexte renvoyé
365
+ stoppedEarly: Arrêtée à ses limites
366
+ gathered: Contexte rassemblé
367
+ gatheredMessages: Messages rassemblés
368
+ tokens: Jetons
369
+ condensedTurns: Tours condensés
297
370
  costs:
298
371
  table:
299
372
  count: Nombre
@@ -518,9 +591,9 @@ knowledge:
518
591
  add_database:
519
592
  title: Ajouter une base de connaissances
520
593
  description: Créer une nouvelle base de connaissances en libre-service
521
- auto_sync:
522
- title: Synchronisé automatiquement
523
- description: Les collections sont gérées automatiquement
594
+ source:
595
+ description: Synchronisé depuis {name}
596
+ edit: Modifier la source
524
597
  manual_management:
525
598
  description: Les collections peuvent être créées et gérées manuellement
526
599
  pipeline: 'Pipeline : {name}'
@@ -558,6 +631,18 @@ knowledge:
558
631
  un pipeline est en cours d'exécution.
559
632
  steps:
560
633
  basic_info: Informations de base
634
+ source: Source
635
+ edit_source:
636
+ title: Source de {name}
637
+ success: Source mise à jour
638
+ error: Échec de la mise à jour de la source
639
+ switch_to_manual: Passer au téléversement manuel
640
+ replace_documents:
641
+ header: Confier le contenu à la source ?
642
+ message: "{name} contient déjà {count} document(s) téléversé(s) manuellement.\
643
+ \ Dès qu'une source alimente cette base, chaque fichier absent de la source\
644
+ \ est supprimé lors de la prochaine synchronisation."
645
+ accept: Remplacer les documents existants
561
646
  edit:
562
647
  title: Modifier la collection
563
648
  database:
@@ -571,6 +656,15 @@ knowledge:
571
656
  validation_error: Le nom de la base de données doit commencer par une lettre
572
657
  minuscule et ne contenir que des lettres minuscules et des chiffres, entre
573
658
  3 et 63 caractères
659
+ source:
660
+ label: Source
661
+ placeholder: Choisissez d'où proviennent les documents
662
+ help: Un pipeline source maintient cette base synchronisée avec un système externe
663
+ ; chaque dossier de premier niveau devient un espace de noms.
664
+ manual_upload:
665
+ label: Téléversement manuel
666
+ description: Les documents sont téléversés à la main dans des espaces de noms
667
+ que vous créez.
574
668
  ingestor:
575
669
  label: Pipeline d'ingestion
576
670
  placeholder: Sélectionner un pipeline d'ingestion
@@ -841,6 +935,16 @@ process:
841
935
  done: Terminé
842
936
  steps: Progression
843
937
  form:
938
+ secret_file_input:
939
+ drop_hint: Déposez le fichier ici ou cliquez pour le choisir
940
+ limits: "{accept}, jusqu'à {size}"
941
+ selected: Fichier sélectionné
942
+ stored: Fichier de clé enregistré (chiffré)
943
+ client_email: 'Compte de service : {email}'
944
+ replace: Remplacer
945
+ remove: Supprimer
946
+ too_large: Le fichier dépasse {size}.
947
+ invalid_json: Le fichier n'est pas un JSON valide.
844
948
  locale_input:
845
949
  translate_tooltip: Traduire dans toutes les langues
846
950
  warnings:
@@ -870,6 +974,15 @@ lib:
870
974
  placeholder: Sélectionner un fuseau horaire
871
975
  help: Les positions cron sont interprétées dans ce fuseau horaire, afin qu'une
872
976
  planification quotidienne conserve la même heure lors des changements d'heure.
977
+ knowledgeCollections:
978
+ placeholder: Sélectionner des collections
979
+ help: Seules les collections sélectionnées sont recherchées.
980
+ noAgent: Choisissez d'abord un agent de connaissances — ce sont ses collections
981
+ qui peuvent être sélectionnées ici.
982
+ noSource: Aucun agent de connaissances n'est associé à ce champ, aucune collection
983
+ ne peut donc être proposée.
984
+ empty: L'agent sélectionné n'est configuré pour interroger aucune collection.
985
+ unavailable: Enregistrée, mais non interrogée par l'agent sélectionné
873
986
  vectorStore:
874
987
  label: Stockage vectoriel
875
988
  help: Sélectionner la base de connaissances et les espaces de noms à rechercher
@@ -879,6 +992,8 @@ lib:
879
992
  label: Espaces de noms
880
993
  placeholder: Sélectionner au moins un espace de noms
881
994
  help: Seuls les espaces de noms sélectionnés sont recherchés
995
+ required: Sélectionner au moins un espace de noms ou activer « Rechercher dans
996
+ tous les espaces de noms ». Sinon, la configuration ne peut pas être enregistrée.
882
997
  allNamespaces:
883
998
  label: Rechercher dans tous les espaces de noms
884
999
  help: Chaque espace de noms de cette base est recherché, y compris ceux ajoutés
@@ -949,6 +1064,7 @@ memory:
949
1064
  title: Suppression échouée
950
1065
  message: Échec de la suppression de tous les souvenirs. Veuillez réessayer.
951
1066
  openwebui:
1067
+ default_disclaimer: L’IA peut faire des erreurs. Veuillez vérifier les réponses.
952
1068
  memories:
953
1069
  title: Souvenirs de l'Agent
954
1070
  select_agent: Sélectionner l'Agent
@@ -970,3 +1086,57 @@ tenant:
970
1086
  mismatch_switch_action: Changer de locataire
971
1087
  administration_title: Administration des tenants
972
1088
  administration_description: Gérer les tenants sur l'ensemble de la plateforme
1089
+ support:
1090
+ report_bug: Signaler un problème
1091
+ dialog_title: Signaler un problème
1092
+ choose_files: Choisir des fichiers
1093
+ submit: Envoyer le signalement
1094
+ submitting: Envoi…
1095
+ sent: Signalement envoyé
1096
+ sent_detail: 'Référence {reference}, signalement #{number}. Le support vous répondra
1097
+ par e-mail.'
1098
+ send_failed: Signalement non envoyé
1099
+ send_failed_detail: Vos réponses sont toujours là — réessayez.
1100
+ unavailable: Le signalement n'est pas configuré sur cette installation. Contactez
1101
+ votre administrateur.
1102
+ userFiles:
1103
+ title: "Mes fichiers"
1104
+ description: "Les fichiers avec lesquels vous et vos agents travaillez : pièces jointes des chats, fichiers créés pour vous par les agents et vos propres envois."
1105
+ conversation: "Chat"
1106
+ actions:
1107
+ move: "Déplacer"
1108
+ upload: "Envoyer"
1109
+ newFolder: "Nouveau dossier"
1110
+ refresh: "Actualiser"
1111
+ download: "Télécharger"
1112
+ rename: "Renommer"
1113
+ delete: "Supprimer"
1114
+ close: "Fermer"
1115
+ cancel: "Annuler"
1116
+ save: "Enregistrer"
1117
+ openFolder: "Ouvrir le dossier {name}"
1118
+ preview: "Aperçu de {name}"
1119
+ columns:
1120
+ name: "Nom"
1121
+ size: "Taille"
1122
+ modified: "Modifié"
1123
+ empty:
1124
+ folder: "Ce dossier est vide. Déposez des fichiers ici pour les envoyer."
1125
+ noSpace: "Votre espace de fichiers est créé avec votre compte de chat. Ouvrez le chat une fois, puis revenez."
1126
+ error:
1127
+ load: "Impossible de charger ce dossier. Réessayez avec Actualiser."
1128
+ move:
1129
+ header: "Déplacer {name} vers"
1130
+ noTargets: "Aucun dossier vers lequel le déplacer."
1131
+ preview:
1132
+ unavailable: "Pas d'aperçu pour ce type de fichier. Téléchargez-le pour l'ouvrir."
1133
+ name:
1134
+ invalid: "Un nom ne doit pas être vide ni contenir de barre oblique."
1135
+ delete:
1136
+ header: "Supprimer"
1137
+ file: "Supprimer {name} ?"
1138
+ folder: "Supprimer le dossier {name} et tout son contenu ?"
1139
+ toast:
1140
+ uploaded: "{count} fichier(s) envoyé(s)"
1141
+ uploadFailed: "Échec de l'envoi"
1142
+ changeFailed: "La modification a échoué"
@@ -272,11 +272,27 @@ event:
272
272
  assistant: Assistente
273
273
  system: Sistema
274
274
  user: Utente
275
+ contextComposed:
276
+ summary: 'Contesto assemblato per il modello: {count} messaggio | Contesto assemblato
277
+ per il modello: {count} messaggi'
278
+ description: La cronologia della chat ricevuta dal modello, con tutti i blocchi
279
+ di contesto recuperati
280
+ assistant: Assistente
281
+ system: Sistema
282
+ user: Utente
275
283
  metaQuestionDetected:
276
284
  category:
277
285
  identity: Identità
278
286
  capabilities: Capacità
279
287
  behavior: Comportamento
288
+ sandboxFileDisplayed:
289
+ file: File
290
+ type: Tipo
291
+ size: Dimensione
292
+ path: Nella sandbox
293
+ humanInTheLoopResponse:
294
+ confirmed: Confermato
295
+ declined: Rifiutato
280
296
  standaloneQuestionCondenser:
281
297
  summary: Domanda rifinita e condensata
282
298
  condensedQuestion: Domanda Condensata
@@ -295,6 +311,64 @@ event:
295
311
  delegations: Deleghe
296
312
  delegatedTaskAgentInTheLoop: Compito delegato (Agente nel loop)
297
313
  allEvents: Tutti gli eventi
314
+ parts:
315
+ noMessages: Nessun messaggio
316
+ yes: Sì
317
+ no: 'No'
318
+ capability:
319
+ userQuery: Messaggio dell'utente
320
+ historyMessages: Messaggi nella cronologia
321
+ condensed: Condensata dalla cronologia
322
+ query: Richiesta
323
+ block: Blocco {number}
324
+ blocks: Blocchi di contesto
325
+ namespaces: Ambiti della memoria dell'organizzazione
326
+ toolCall: Chiamata di strumento
327
+ userMemories: Ricordi dell'utente
328
+ organizationMemories: Ricordi dell'organizzazione
329
+ references: Raccolte referenziate
330
+ citeSources: Citare le fonti
331
+ sections: Sezioni trovate
332
+ notSearched: Non cercate (nessun accesso)
333
+ files: File
334
+ reserveTokens: Token riservati
335
+ fileStatus:
336
+ read: Letto
337
+ truncated: Abbreviato
338
+ failed: Non riuscito
339
+ citationId: ID di citazione
340
+ pages: Pagine
341
+ error: Errore
342
+ stop: Termina con
343
+ targetAgent: Scrittore di memoria
344
+ toolLoop:
345
+ loop: Insieme di strumenti
346
+ mode: Modalità
347
+ modes:
348
+ answer: Rispondere
349
+ gather: Raccogliere il contesto
350
+ iteration: Decisioni
351
+ toolCallsMade: Chiamate di strumenti finora
352
+ messages: Messaggi nel ciclo
353
+ offeredTools: Strumenti offerti
354
+ condensedResults: Risultati condensati
355
+ needsCondensing: Da condensare
356
+ decidedCalls: Una chiamata di strumento decisa | {count} chiamate di strumenti
357
+ decise
358
+ narrowedTools: Limitato a
359
+ maxIterations: Limite di decisioni
360
+ tool: Strumento
361
+ kind: Tipo
362
+ kinds:
363
+ function: Funzione
364
+ capability: Capacità
365
+ failed: Non riuscito
366
+ resultContext: Contesto restituito
367
+ stoppedEarly: Fermato ai suoi limiti
368
+ gathered: Contesto raccolto
369
+ gatheredMessages: Messaggi raccolti
370
+ tokens: Token
371
+ condensedTurns: Turni condensati
298
372
  costs:
299
373
  table:
300
374
  count: Conteggio
@@ -517,9 +591,9 @@ knowledge:
517
591
  add_database:
518
592
  title: Aggiungi database di conoscenza
519
593
  description: Crea un nuovo database di conoscenza self-service
520
- auto_sync:
521
- title: Sincronizzato automaticamente
522
- description: Le collezioni sono gestite automaticamente
594
+ source:
595
+ description: Sincronizzato da {name}
596
+ edit: Modifica sorgente
523
597
  manual_management:
524
598
  description: Le collezioni possono essere create e gestite manualmente
525
599
  pipeline: 'Pipeline: {name}'
@@ -559,6 +633,18 @@ knowledge:
559
633
  una pipeline sia in esecuzione.
560
634
  steps:
561
635
  basic_info: Informazioni di base
636
+ source: Sorgente
637
+ edit_source:
638
+ title: Sorgente di {name}
639
+ success: Sorgente aggiornata
640
+ error: Impossibile aggiornare la sorgente
641
+ switch_to_manual: Passa al caricamento manuale
642
+ replace_documents:
643
+ header: Affidare il contenuto alla sorgente?
644
+ message: '{name} contiene già {count} documento/i caricato/i manualmente.
645
+ Quando una sorgente alimenta questo database, alla prossima sincronizzazione
646
+ viene rimosso ogni file che la sorgente non possiede.'
647
+ accept: Sostituisci i documenti esistenti
562
648
  edit:
563
649
  title: Modifica collezione
564
650
  database:
@@ -571,6 +657,14 @@ knowledge:
571
657
  da 3 a 63 caratteri. Il nome non può essere modificato in seguito.
572
658
  validation_error: Il nome del database deve iniziare con una lettera minuscola
573
659
  e può contenere solo lettere minuscole e cifre, tra 3 e 63 caratteri
660
+ source:
661
+ label: Sorgente
662
+ placeholder: Scegli da dove provengono i documenti
663
+ help: Una pipeline sorgente mantiene questa base sincronizzata con un sistema
664
+ esterno; ogni cartella di primo livello diventa un namespace.
665
+ manual_upload:
666
+ label: Caricamento manuale
667
+ description: I documenti vengono caricati a mano in namespace creati da te.
574
668
  ingestor:
575
669
  label: Pipeline di ingestione
576
670
  placeholder: Seleziona una pipeline di ingestione
@@ -839,6 +933,16 @@ process:
839
933
  done: Completato
840
934
  steps: Progresso
841
935
  form:
936
+ secret_file_input:
937
+ drop_hint: Trascina qui il file o fai clic per sceglierlo
938
+ limits: '{accept}, fino a {size}'
939
+ selected: File selezionato
940
+ stored: File chiave salvato (cifrato)
941
+ client_email: 'Account di servizio: {email}'
942
+ replace: Sostituisci
943
+ remove: Rimuovi
944
+ too_large: Il file supera {size}.
945
+ invalid_json: Il file non è un JSON valido.
842
946
  locale_input:
843
947
  translate_tooltip: Traduci in tutte le lingue
844
948
  warnings:
@@ -868,6 +972,15 @@ lib:
868
972
  placeholder: Seleziona un fuso orario
869
973
  help: Le posizioni cron sono interpretate in questo fuso orario, così una pianificazione
870
974
  giornaliera mantiene la stessa ora durante i cambi di orario.
975
+ knowledgeCollections:
976
+ placeholder: Seleziona raccolte
977
+ help: Vengono cercate solo le raccolte selezionate.
978
+ noAgent: Scegli prima un agente di conoscenza — qui si possono selezionare le
979
+ sue raccolte.
980
+ noSource: A questo campo non è associato alcun agente di conoscenza, quindi non
981
+ è possibile offrire raccolte.
982
+ empty: L'agente selezionato non è configurato per alcuna raccolta.
983
+ unavailable: Salvata, ma non consultata dall'agente selezionato
871
984
  vectorStore:
872
985
  label: Archivio vettoriale
873
986
  help: Seleziona il database di conoscenza e gli spazi dei nomi da cercare
@@ -877,6 +990,8 @@ lib:
877
990
  label: Spazi dei nomi
878
991
  placeholder: Seleziona almeno uno spazio dei nomi
879
992
  help: Vengono cercati solo gli spazi dei nomi selezionati
993
+ required: Seleziona almeno uno spazio dei nomi o attiva «Cerca in tutti gli
994
+ spazi dei nomi». Altrimenti la configurazione non può essere salvata.
880
995
  allNamespaces:
881
996
  label: Cerca in tutti gli spazi dei nomi
882
997
  help: Viene cercato ogni spazio dei nomi di questo database, inclusi quelli
@@ -947,6 +1062,7 @@ memory:
947
1062
  title: Eliminazione fallita
948
1063
  message: Impossibile eliminare tutti i ricordi. Riprova.
949
1064
  openwebui:
1065
+ default_disclaimer: L’IA può commettere errori. Verifica le risposte.
950
1066
  memories:
951
1067
  title: Ricordi dell'Agente
952
1068
  select_agent: Seleziona Agente
@@ -967,3 +1083,57 @@ tenant:
967
1083
  mismatch_switch_action: Cambia tenant
968
1084
  administration_title: Amministrazione tenant
969
1085
  administration_description: Gestisci i tenant nell'intera piattaforma
1086
+ support:
1087
+ report_bug: Segnala un problema
1088
+ dialog_title: Segnala un problema
1089
+ choose_files: Scegli i file
1090
+ submit: Invia segnalazione
1091
+ submitting: Invio…
1092
+ sent: Segnalazione inviata
1093
+ sent_detail: 'Riferimento {reference}, segnalazione #{number}. Il supporto ti risponderà
1094
+ via e-mail.'
1095
+ send_failed: Segnalazione non inviata
1096
+ send_failed_detail: 'Le tue risposte sono ancora qui: riprova a inviare.'
1097
+ unavailable: La segnalazione non è configurata su questa installazione. Contatta
1098
+ l'amministratore.
1099
+ userFiles:
1100
+ title: "I miei file"
1101
+ description: "I file con cui lavorate tu e i tuoi agenti: allegati delle chat, file creati per te dagli agenti e i tuoi caricamenti."
1102
+ conversation: "Chat"
1103
+ actions:
1104
+ move: "Sposta"
1105
+ upload: "Carica"
1106
+ newFolder: "Nuova cartella"
1107
+ refresh: "Aggiorna"
1108
+ download: "Scarica"
1109
+ rename: "Rinomina"
1110
+ delete: "Elimina"
1111
+ close: "Chiudi"
1112
+ cancel: "Annulla"
1113
+ save: "Salva"
1114
+ openFolder: "Apri la cartella {name}"
1115
+ preview: "Anteprima di {name}"
1116
+ columns:
1117
+ name: "Nome"
1118
+ size: "Dimensione"
1119
+ modified: "Modificato"
1120
+ empty:
1121
+ folder: "Questa cartella è vuota. Trascina qui i file per caricarli."
1122
+ noSpace: "Il tuo spazio file viene creato con il tuo account chat. Apri la chat una volta, poi torna qui."
1123
+ error:
1124
+ load: "Impossibile caricare questa cartella. Riprova con Aggiorna."
1125
+ move:
1126
+ header: "Sposta {name} in"
1127
+ noTargets: "Nessuna cartella in cui spostarlo."
1128
+ preview:
1129
+ unavailable: "Nessuna anteprima per questo tipo di file. Scaricalo per aprirlo."
1130
+ name:
1131
+ invalid: "Un nome non può essere vuoto né contenere una barra."
1132
+ delete:
1133
+ header: "Elimina"
1134
+ file: "Eliminare {name}?"
1135
+ folder: "Eliminare la cartella {name} con tutto il contenuto?"
1136
+ toast:
1137
+ uploaded: "{count} file caricati"
1138
+ uploadFailed: "Caricamento non riuscito"
1139
+ changeFailed: "La modifica non è riuscita"
@@ -25,9 +25,11 @@
25
25
  </Button>
26
26
  </NuxtLink>
27
27
  </div>
28
- <div>
28
+ <div class="flex flex-col items-center">
29
+ <SupportIncidentButton />
29
30
  <UserSettings />
30
31
  </div>
32
+ <SupportIncidentDialog />
31
33
  </div>
32
34
  <div class="w-full pl-[50px]">
33
35
  <div class="fixed z-50 flex h-[50px] w-full items-center justify-between bg-surface-50 pr-[50px] dark:bg-surface-950">
@@ -77,6 +79,10 @@ import type { MenuItem } from 'primevue/menuitem'
77
79
  const route = useRoute()
78
80
  const tenantPath = useTenantPath()
79
81
 
82
+ // Here rather than app.vue: this layout is where the language switcher lives,
83
+ // and extenders supplying their own app.vue would otherwise lose the restore.
84
+ useRestorePreferredLocale()
85
+
80
86
  const online = ref<boolean>(false)
81
87
 
82
88
  const { apps } = useApps()
@@ -36,6 +36,9 @@ const rememberRedirect = (fullPath: string, isAuthPath: boolean) => {
36
36
  }
37
37
  }
38
38
 
39
+ // Redirects are returned as plain locations, not via navigateTo(): after an
40
+ // await, another navigation may already have finished, and navigateTo() then
41
+ // navigates on its own instead of redirecting this one (see home-redirect.ts).
39
42
  export default defineNuxtRouteMiddleware(async (to) => {
40
43
  const { $auth, $i18n } = useNuxtApp()
41
44
  const locale = $i18n.locale.value
@@ -52,7 +55,7 @@ export default defineNuxtRouteMiddleware(async (to) => {
52
55
 
53
56
  if (!user) {
54
57
  rememberRedirect(to.fullPath, isAuthPath)
55
- return navigateTo(`/${locale}/auth/login`)
58
+ return `/${locale}/auth/login`
56
59
  }
57
60
 
58
61
  if (user.expired) {
@@ -62,7 +65,7 @@ export default defineNuxtRouteMiddleware(async (to) => {
62
65
  catch {
63
66
  await $auth.removeUser()
64
67
  rememberRedirect(to.fullPath, isAuthPath)
65
- return navigateTo(`/${locale}/auth/login`)
68
+ return `/${locale}/auth/login`
66
69
  }
67
70
  }
68
71
 
@@ -76,6 +79,6 @@ export default defineNuxtRouteMiddleware(async (to) => {
76
79
  }
77
80
  catch (error) {
78
81
  console.error('Error in auth middleware:', error)
79
- return navigateTo(`/${locale}/auth/login`)
82
+ return `/${locale}/auth/login`
80
83
  }
81
84
  })
@@ -6,10 +6,19 @@ const REDIRECT_KEY = 'aihub_redirect_after_login'
6
6
 
7
7
  // Redirect runs in the guard pipeline, not the page: a page-component redirect
8
8
  // here can be dropped by an in-flight navigation.
9
+ //
10
+ // The target is returned as a plain location, not via navigateTo(). If another
11
+ // navigation finishes while the tenant lookup is awaited, navigateTo() no
12
+ // longer sees a running middleware and calls router.replace() itself; when the
13
+ // router is already on that page it yields NAVIGATION_DUPLICATED, and returning
14
+ // that failure from here makes Nuxt show a fatal 500 during app start. A
15
+ // returned location is handed to vue-router as this navigation's redirect, so a
16
+ // duplicate ends as an ordinary navigation failure instead.
9
17
  export default defineNuxtRouteMiddleware(async () => {
10
18
  useHomeResolving().value = true
11
19
 
12
20
  const localePath = useLocalePath()
21
+ const router = useRouter()
13
22
 
14
23
  const [tenantsResponse, activeTenant] = await Promise.all([
15
24
  getMyTenants({ composable: '$fetch' }).catch(() => null),
@@ -24,13 +33,15 @@ export default defineNuxtRouteMiddleware(async () => {
24
33
  sessionStorage.removeItem(REDIRECT_KEY)
25
34
 
26
35
  if (storedRedirect && storedRedirect !== '/') {
27
- return navigateTo(storedRedirect, { replace: true })
36
+ // The stored value is a fullPath; resolve it so its query and hash survive.
37
+ const { path, query, hash } = router.resolve(storedRedirect)
38
+ return { path, query, hash, replace: true }
28
39
  }
29
40
  if (tenants.length === 1) {
30
- return navigateTo(localePath(`/${tenants[0].id}/service/openai`), { replace: true })
41
+ return { path: localePath(`/${tenants[0].id}/service/openai`), replace: true }
31
42
  }
32
43
  if (activeTenant && tenants.some(tenant => tenant.id === activeTenant.id)) {
33
- return navigateTo(localePath(`/${activeTenant.id}/service/openai`), { replace: true })
44
+ return { path: localePath(`/${activeTenant.id}/service/openai`), replace: true }
34
45
  }
35
- return navigateTo(localePath('/select-tenant'), { replace: true })
46
+ return { path: localePath('/select-tenant'), replace: true }
36
47
  })
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "license": "AGPL-3.0-or-later",
4
4
  "author": "bbv Software Services AG (https://www.bbv.ch)",
5
5
  "type": "module",
6
- "version": "0.321.1",
6
+ "version": "0.323.1",
7
7
  "description": "Swiss AI Hub - Admin & Management UI (Nuxt 3 layer)",
8
8
  "main": "./nuxt.config.ts",
9
9
  "repository": {
@@ -30,7 +30,8 @@
30
30
  "plugins/",
31
31
  "sdk/",
32
32
  "themes/",
33
- "types/"
33
+ "types/",
34
+ "utils/"
34
35
  ],
35
36
  "scripts": {
36
37
  "dev": "nuxi prepare && nuxi dev .app --port 3333 --dotenv ../../../.env",
@@ -102,7 +103,7 @@
102
103
  "eslint-plugin-import": "^2.32.0",
103
104
  "eslint-plugin-sonarjs": "^4.0.3",
104
105
  "eslint-plugin-tailwindcss": "^3.18.3",
105
- "nuxt": "3.21.0",
106
+ "nuxt": "3.21.10",
106
107
  "tailwindcss": "^3.4.19",
107
108
  "typescript": "^5.9.3",
108
109
  "typescript-eslint": "^8.59.3"
@@ -6,20 +6,20 @@
6
6
  >
7
7
  <div class="mb-4 flex items-center gap-4">
8
8
  <IconField class="flex-1">
9
- <InputIcon :class="isFetching ? 'pi pi-spinner pi-spin' : 'pi pi-search'" />
9
+ <InputIcon :class="isSearching ? 'pi pi-spinner pi-spin' : 'pi pi-search'" />
10
10
  <InputText
11
11
  v-model="searchInput"
12
12
  :placeholder="t('knowledge.documents.search.placeholder')"
13
13
  class="w-full"
14
14
  />
15
15
  <InputIcon
16
- v-if="searchInput && !isFetching"
16
+ v-if="searchInput && !isSearching"
17
17
  class="pi pi-times cursor-pointer"
18
18
  @click="searchInput = ''"
19
19
  />
20
20
  </IconField>
21
21
  <Button
22
- v-if="!currentDatabase?.auto_sync"
22
+ v-if="!currentDatabase?.source"
23
23
  icon="pi pi-upload"
24
24
  :label="t('knowledge.documents.upload.title')"
25
25
  @click="openUploadModal"
@@ -53,7 +53,6 @@
53
53
  :namespace="route.params.namespace as string"
54
54
  :database-display-name="databaseDisplayName"
55
55
  :namespace-display-name="namespaceDisplayName"
56
- @success="handleUpload"
57
56
  />
58
57
  </template>
59
58
 
@@ -74,6 +73,7 @@ const {
74
73
  documents,
75
74
  isLoading,
76
75
  isFetching,
76
+ isSearching,
77
77
  pagination,
78
78
  currentPage,
79
79
  pageSize,
@@ -86,6 +86,8 @@ const {
86
86
  refetch,
87
87
  } = useDocuments()
88
88
 
89
+ useDocumentIngestionPolling(documents, refetch, isFetching)
90
+
89
91
  const uploadModalVisible = ref(false)
90
92
  const searchInput = ref(searchQuery.value ?? '')
91
93
 
@@ -139,10 +141,6 @@ const openUploadModal = () => {
139
141
  uploadModalVisible.value = true
140
142
  }
141
143
 
142
- const handleUpload = () => {
143
- refetch()
144
- }
145
-
146
144
  const handleDeleted = (documentIds: string[]) => {
147
145
  refetch()
148
146
  if (documentIds.includes(route.params.document_id as string)) {