@swiss-ai-hub/web 0.290.11

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 (313) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +479 -0
  3. package/app.config.ts +1 -0
  4. package/app.vue +52 -0
  5. package/assets/css/main.css +4 -0
  6. package/assets/images/logo.png +0 -0
  7. package/components/Agent/Avatar.vue +40 -0
  8. package/components/Agent/Card.vue +139 -0
  9. package/components/Agent/Configuration.vue +20 -0
  10. package/components/Agent/CreateModal.vue +287 -0
  11. package/components/Agent/EmptyCard.vue +35 -0
  12. package/components/Agent/List.vue +85 -0
  13. package/components/Agent/TemplateCard.vue +58 -0
  14. package/components/AppLoader.vue +55 -0
  15. package/components/Chat/Message.vue +90 -0
  16. package/components/Chat/SourceNodes.vue +120 -0
  17. package/components/Chat/Thread.vue +134 -0
  18. package/components/Costs/Table.vue +56 -0
  19. package/components/Dashboard/Component/BarChart.vue +46 -0
  20. package/components/Dashboard/Component/LineChart.vue +138 -0
  21. package/components/Dashboard/Component/Number.vue +31 -0
  22. package/components/Dashboard/Grid.vue +214 -0
  23. package/components/Dashboard/Item.vue +75 -0
  24. package/components/Dashboard/Trend.vue +34 -0
  25. package/components/Display/List/DisplayList.vue +93 -0
  26. package/components/Evaluation/Dataset/Card.vue +70 -0
  27. package/components/Evaluation/Dataset/Create.vue +81 -0
  28. package/components/Evaluation/Dataset/Edit.vue +132 -0
  29. package/components/Event/Display/AddMemoryToChatHistoryEvent.vue +60 -0
  30. package/components/Event/Display/AgentInTheLoopRequestEvent.vue +56 -0
  31. package/components/Event/Display/AgentInTheLoopResponseEvent.vue +17 -0
  32. package/components/Event/Display/Base.vue +125 -0
  33. package/components/Event/Display/BaseRetrieveMemoryEvent.vue +101 -0
  34. package/components/Event/Display/BaseStoreMemoryEvent.vue +182 -0
  35. package/components/Event/Display/ChunkEvent.vue +40 -0
  36. package/components/Event/Display/EmbeddingEvent.vue +25 -0
  37. package/components/Event/Display/ExceptionEvent.vue +21 -0
  38. package/components/Event/Display/GuardAcceptEvent.vue +25 -0
  39. package/components/Event/Display/GuardEvent.vue +17 -0
  40. package/components/Event/Display/GuardRejectionEvent.vue +25 -0
  41. package/components/Event/Display/HumanInTheLoopRequestEvent.vue +53 -0
  42. package/components/Event/Display/HumanInTheLoopResponseEvent.vue +40 -0
  43. package/components/Event/Display/LLMCostEvent.vue +25 -0
  44. package/components/Event/Display/LLMEvent.vue +92 -0
  45. package/components/Event/Display/LimitChatHistoryEvent.vue +60 -0
  46. package/components/Event/Display/RAGFailureStopEvent.vue +28 -0
  47. package/components/Event/Display/RAGStartEvent.vue +77 -0
  48. package/components/Event/Display/RAGSuccessStopEvent.vue +16 -0
  49. package/components/Event/Display/RawDataContent.vue +69 -0
  50. package/components/Event/Display/RerankerEvent.vue +39 -0
  51. package/components/Event/Display/RetrieverEvent.vue +22 -0
  52. package/components/Event/Display/RouterEvent.vue +54 -0
  53. package/components/Event/Display/StandaloneQuestionCondenserEvent.vue +38 -0
  54. package/components/Event/Display/StopEvent.vue +16 -0
  55. package/components/Event/Display/ThoughtEvent.vue +20 -0
  56. package/components/Event/Display/ToolEvent.vue +38 -0
  57. package/components/Event/Display/UnknownEvent.vue +17 -0
  58. package/components/Event/Display/UserMessageEvent.vue +35 -0
  59. package/components/Event/List/EventList.vue +249 -0
  60. package/components/Event/Statistics.vue +49 -0
  61. package/components/Event/Timeseries.vue +224 -0
  62. package/components/FormKit/AgentSelector.vue +307 -0
  63. package/components/FormKit/ChipsInput.vue +62 -0
  64. package/components/FormKit/DynamicConfiguration.vue +155 -0
  65. package/components/FormKit/IconSelector.vue +72 -0
  66. package/components/FormKit/KnowledgeDatabaseSelector.vue +92 -0
  67. package/components/FormKit/LocaleInput.vue +150 -0
  68. package/components/FormKit/ModelSelect.vue +110 -0
  69. package/components/FormKit/Repeater.vue +93 -0
  70. package/components/FormKit/VectorStoreInput.vue +247 -0
  71. package/components/Knowledge/Document/List.vue +140 -0
  72. package/components/Knowledge/Document/Overview.vue +28 -0
  73. package/components/Knowledge/Document/UploadModal.vue +298 -0
  74. package/components/Knowledge/Document/WithNodes.vue +105 -0
  75. package/components/Knowledge/Namespace/Card.vue +108 -0
  76. package/components/Knowledge/Namespace/CreateModal.vue +203 -0
  77. package/components/Knowledge/Namespace/EditModal.vue +134 -0
  78. package/components/Knowledge/Namespace/EmptyCard.vue +35 -0
  79. package/components/Knowledge/Node/Content.vue +71 -0
  80. package/components/Markdown/Renderer.vue +87 -0
  81. package/components/Memory/DetailPage.vue +48 -0
  82. package/components/Memory/Edit.vue +241 -0
  83. package/components/Memory/Graph.vue +318 -0
  84. package/components/Memory/List.vue +155 -0
  85. package/components/Memory/MemoryManagementPage.vue +178 -0
  86. package/components/Memory/OpenWebUIContent.vue +96 -0
  87. package/components/Memory/PageLayout.vue +72 -0
  88. package/components/Models/ModelDetailsPanel.vue +250 -0
  89. package/components/Models/NamespaceCard.vue +79 -0
  90. package/components/Navigation/Left.vue +85 -0
  91. package/components/Navigation/Top.vue +31 -0
  92. package/components/Notification/Item.vue +88 -0
  93. package/components/Notification/NotificationsOverlay.vue +164 -0
  94. package/components/Process/Card.vue +119 -0
  95. package/components/Process/Configuration.vue +20 -0
  96. package/components/Process/CreateModal.vue +276 -0
  97. package/components/Process/EmptyCard.vue +35 -0
  98. package/components/Process/Form.vue +153 -0
  99. package/components/Process/Starts.vue +44 -0
  100. package/components/Process/Walkthrough/List.vue +162 -0
  101. package/components/Role/AccessRulesEditor.vue +132 -0
  102. package/components/Role/Card.vue +68 -0
  103. package/components/Role/Create.vue +55 -0
  104. package/components/Role/Edit.vue +82 -0
  105. package/components/Role/UsageLimitsEditor.vue +225 -0
  106. package/components/Service/Selection.vue +148 -0
  107. package/components/Structural/Column.vue +74 -0
  108. package/components/Structural/Screen.vue +10 -0
  109. package/components/Structural/Substructure.vue +5 -0
  110. package/components/Tenant/Switcher.vue +102 -0
  111. package/components/Thread/Details.vue +135 -0
  112. package/components/Thread/Hierarchy.vue +136 -0
  113. package/components/Thread/Info.vue +41 -0
  114. package/components/Thread/List.vue +136 -0
  115. package/components/User/Bar.vue +74 -0
  116. package/components/User/List.vue +86 -0
  117. package/components/User/RoleChips.vue +83 -0
  118. package/components/User/Settings.vue +79 -0
  119. package/components/Workflow/Modal.vue +39 -0
  120. package/components/Workflow/NodeCard.vue +41 -0
  121. package/components/Workflow/StartNode.vue +24 -0
  122. package/components/Workflow/StepNode.vue +27 -0
  123. package/components/Workflow/StopNode.vue +24 -0
  124. package/components/Workflow/Visualization.vue +265 -0
  125. package/components/mdc/MarkdownFigure.vue +9 -0
  126. package/components/mdc/MarkdownTable.vue +9 -0
  127. package/components/mdc/ResolveImageComponent.vue +58 -0
  128. package/composables/agent/useAgentClass.ts +27 -0
  129. package/composables/agent/useAgentClassInstances.ts +27 -0
  130. package/composables/agent/useAgentClasses.ts +27 -0
  131. package/composables/agent/useAgentIconFromThread.ts +8 -0
  132. package/composables/agent/useAgentInstance.ts +28 -0
  133. package/composables/agent/useAgentInstanceThreads.ts +76 -0
  134. package/composables/agent/useAgentInstances.ts +25 -0
  135. package/composables/agent/useAgentNavigation.ts +35 -0
  136. package/composables/agent/useCreateAgentInstance.ts +33 -0
  137. package/composables/agent/useDeleteAgentInstance.ts +31 -0
  138. package/composables/agent/useUpdateAgentInstance.ts +40 -0
  139. package/composables/auth/useAuth.ts +54 -0
  140. package/composables/auth/useAuthProviders.ts +14 -0
  141. package/composables/chat/useChatCompletions.ts +30 -0
  142. package/composables/dashboard/useAgentNameFromDashboardWidget.ts +27 -0
  143. package/composables/dashboard/useDashboardComponent.ts +27 -0
  144. package/composables/dashboard/useSaveDashboard.ts +21 -0
  145. package/composables/document/useCreateNamespace.ts +26 -0
  146. package/composables/document/useDatabases.ts +23 -0
  147. package/composables/document/useDocument.ts +29 -0
  148. package/composables/document/useDocumentUrl.ts +20 -0
  149. package/composables/document/useDocuments.ts +107 -0
  150. package/composables/document/useNodes.ts +29 -0
  151. package/composables/document/useSummaryNodes.ts +32 -0
  152. package/composables/document/useUpdateNamespace.ts +22 -0
  153. package/composables/evaluation/useCreateDataset.ts +19 -0
  154. package/composables/evaluation/useDataset.ts +26 -0
  155. package/composables/evaluation/useDatasets.ts +25 -0
  156. package/composables/evaluation/useUpdateDataset.ts +23 -0
  157. package/composables/event/useBasicEventStatistics.ts +83 -0
  158. package/composables/event/useEventColor.ts +25 -0
  159. package/composables/event/useEventComponent.ts +87 -0
  160. package/composables/event/useEventTimeseries.ts +39 -0
  161. package/composables/event/useEventTimeseriesStats.ts +26 -0
  162. package/composables/file/useFileUpload.ts +91 -0
  163. package/composables/file/useSupportedFileTypes.ts +22 -0
  164. package/composables/form/useCreateInstanceForm.ts +251 -0
  165. package/composables/form/useFormKitTransform.ts +753 -0
  166. package/composables/memory/useMemoryCRUD.ts +88 -0
  167. package/composables/memory/useMemoryFactory.ts +319 -0
  168. package/composables/memory/useMemorySearchFilter.ts +74 -0
  169. package/composables/models/useModelsList.ts +24 -0
  170. package/composables/models/useSingleModel.ts +30 -0
  171. package/composables/notification/useNotificationPoller.ts +58 -0
  172. package/composables/notification/useNotifications.ts +57 -0
  173. package/composables/notification/useUpdateMultipleNotifications.ts +17 -0
  174. package/composables/notification/useUpdateNotification.ts +17 -0
  175. package/composables/process/useCreateProcessInstance.ts +32 -0
  176. package/composables/process/useDeleteProcessInstance.ts +31 -0
  177. package/composables/process/useProcessClasses.ts +27 -0
  178. package/composables/process/useProcessInstance.ts +28 -0
  179. package/composables/process/useProcessInstances.ts +27 -0
  180. package/composables/process/useProcessWalkthroughs.ts +73 -0
  181. package/composables/process/useSendProcessStartForm.ts +43 -0
  182. package/composables/process/useUpdateProcessInstance.ts +40 -0
  183. package/composables/role/useCreateRole.ts +19 -0
  184. package/composables/role/useDeleteRole.ts +21 -0
  185. package/composables/role/useRole.ts +30 -0
  186. package/composables/role/useRoles.ts +25 -0
  187. package/composables/role/useUpdateRole.ts +22 -0
  188. package/composables/suite/useApps.ts +31 -0
  189. package/composables/suite/useSuite.ts +26 -0
  190. package/composables/tenant/useActiveTenant.ts +27 -0
  191. package/composables/tenant/useSysadminNavigation.ts +19 -0
  192. package/composables/tenant/useTenant.ts +38 -0
  193. package/composables/tenant/useTenantMemberships.ts +15 -0
  194. package/composables/tenant/useTenantPath.ts +20 -0
  195. package/composables/tenant/useTenantPolling.ts +30 -0
  196. package/composables/tenant/useTenantReady.ts +12 -0
  197. package/composables/theme/useDarkMode.ts +5 -0
  198. package/composables/thread/useThread.ts +27 -0
  199. package/composables/thread/useThreadEvents.ts +91 -0
  200. package/composables/thread/useThreadUtils.ts +49 -0
  201. package/composables/thread/useThreads.ts +64 -0
  202. package/composables/thread/useThreadsInfinite.ts +56 -0
  203. package/composables/translation/useTranslate.ts +20 -0
  204. package/composables/useRouteReady.ts +21 -0
  205. package/composables/useTimeAgo.ts +40 -0
  206. package/composables/user/useAssignRoleToUser.ts +22 -0
  207. package/composables/user/useMyUser.ts +25 -0
  208. package/composables/user/useRevokeRoleFromUser.ts +21 -0
  209. package/composables/user/useUser.ts +30 -0
  210. package/composables/user/useUsers.ts +63 -0
  211. package/composables/utils/useJsonTree.ts +138 -0
  212. package/formkit.config.ts +44 -0
  213. package/i18n/locales/de.yaml +815 -0
  214. package/i18n/locales/en.yaml +804 -0
  215. package/i18n/locales/fr.yaml +812 -0
  216. package/i18n/locales/it.yaml +808 -0
  217. package/layouts/anonymous.vue +8 -0
  218. package/layouts/default.vue +116 -0
  219. package/middleware/auth.global.ts +62 -0
  220. package/nuxt.config.ts +145 -0
  221. package/package.json +114 -0
  222. package/pages/[tenant]/index.vue +31 -0
  223. package/pages/[tenant]/notifications/index.vue +235 -0
  224. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/chat.vue +67 -0
  225. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/configuration.vue +122 -0
  226. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/memories/[memory_id].vue +3 -0
  227. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/memories.vue +20 -0
  228. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/overview.vue +72 -0
  229. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/threads.vue +52 -0
  230. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/workflow.vue +19 -0
  231. package/pages/[tenant]/service/agents/[agent_class]-[agent_id].vue +63 -0
  232. package/pages/[tenant]/service/agents/templates.vue +102 -0
  233. package/pages/[tenant]/service/agents.vue +185 -0
  234. package/pages/[tenant]/service/datasets/[dataset_id].vue +81 -0
  235. package/pages/[tenant]/service/datasets.vue +53 -0
  236. package/pages/[tenant]/service/health/index.vue +3 -0
  237. package/pages/[tenant]/service/knowledge/[db]/[namespace]/[document_id]/nodes.vue +20 -0
  238. package/pages/[tenant]/service/knowledge/[db]/[namespace]/[document_id]/overview.vue +40 -0
  239. package/pages/[tenant]/service/knowledge/[db]/[namespace]/[document_id]/summary.vue +88 -0
  240. package/pages/[tenant]/service/knowledge/[db]/[namespace]/[document_id].vue +48 -0
  241. package/pages/[tenant]/service/knowledge/[db]/[namespace].vue +144 -0
  242. package/pages/[tenant]/service/knowledge.vue +126 -0
  243. package/pages/[tenant]/service/models/[model_name].vue +84 -0
  244. package/pages/[tenant]/service/models.vue +61 -0
  245. package/pages/[tenant]/service/my-account.vue +117 -0
  246. package/pages/[tenant]/service/openai/[thread_id]/[display_id]/memories.vue +66 -0
  247. package/pages/[tenant]/service/openai/[thread_id]/[display_id]/sources.vue +100 -0
  248. package/pages/[tenant]/service/openai/[thread_id]/[display_id]/tracing.vue +49 -0
  249. package/pages/[tenant]/service/openai.vue +101 -0
  250. package/pages/[tenant]/service/organization-memories/graph.vue +97 -0
  251. package/pages/[tenant]/service/organization-memories/list/[memory_id].vue +3 -0
  252. package/pages/[tenant]/service/organization-memories/list.vue +150 -0
  253. package/pages/[tenant]/service/organization-memories.vue +3 -0
  254. package/pages/[tenant]/service/processes/[process_class]-[process_id]/[process_walkthrough_id].vue +7 -0
  255. package/pages/[tenant]/service/processes/[process_class]-[process_id]/configuration.vue +106 -0
  256. package/pages/[tenant]/service/processes/[process_class]-[process_id]/overview.vue +67 -0
  257. package/pages/[tenant]/service/processes/[process_class]-[process_id]/start.vue +26 -0
  258. package/pages/[tenant]/service/processes/[process_class]-[process_id]/walkthroughs/[process_walkthrough_id]/overview.vue +14 -0
  259. package/pages/[tenant]/service/processes/[process_class]-[process_id]/walkthroughs.vue +54 -0
  260. package/pages/[tenant]/service/processes/[process_class]-[process_id].vue +60 -0
  261. package/pages/[tenant]/service/processes.vue +129 -0
  262. package/pages/[tenant]/service/roles/[role_id].vue +54 -0
  263. package/pages/[tenant]/service/roles.vue +84 -0
  264. package/pages/[tenant]/service/threads/[thread_id]/chat.vue +51 -0
  265. package/pages/[tenant]/service/threads/[thread_id]/display/[display_id].vue +21 -0
  266. package/pages/[tenant]/service/threads/[thread_id]/display.vue +29 -0
  267. package/pages/[tenant]/service/threads/[thread_id]/hierarchy.vue +14 -0
  268. package/pages/[tenant]/service/threads/[thread_id]/memories/[memory_id].vue +3 -0
  269. package/pages/[tenant]/service/threads/[thread_id]/memories.vue +19 -0
  270. package/pages/[tenant]/service/threads/[thread_id]/overview.vue +100 -0
  271. package/pages/[tenant]/service/threads/[thread_id].vue +54 -0
  272. package/pages/[tenant]/service/threads.vue +52 -0
  273. package/pages/[tenant]/service/user-memories/graph.vue +97 -0
  274. package/pages/[tenant]/service/user-memories/list/[memory_id].vue +3 -0
  275. package/pages/[tenant]/service/user-memories/list.vue +150 -0
  276. package/pages/[tenant]/service/user-memories.vue +3 -0
  277. package/pages/[tenant]/service/users/[user_id].vue +117 -0
  278. package/pages/[tenant]/service/users.vue +88 -0
  279. package/pages/auth/callback.vue +52 -0
  280. package/pages/auth/login.vue +80 -0
  281. package/pages/auth/renew.vue +24 -0
  282. package/pages/index.vue +59 -0
  283. package/pages/select-tenant.vue +76 -0
  284. package/plugins/0.runtime-config.client.ts +55 -0
  285. package/plugins/apexcharts.client.ts +5 -0
  286. package/plugins/api-client.client.ts +38 -0
  287. package/plugins/dark-mode.client.ts +12 -0
  288. package/plugins/keycloak-client.ts +41 -0
  289. package/plugins/oidc-client.ts +78 -0
  290. package/sdk/client/client/client.gen.ts +237 -0
  291. package/sdk/client/client/index.ts +24 -0
  292. package/sdk/client/client/types.gen.ts +213 -0
  293. package/sdk/client/client/utils.gen.ts +407 -0
  294. package/sdk/client/client.gen.ts +25 -0
  295. package/sdk/client/core/auth.gen.ts +42 -0
  296. package/sdk/client/core/bodySerializer.gen.ts +96 -0
  297. package/sdk/client/core/params.gen.ts +181 -0
  298. package/sdk/client/core/pathSerializer.gen.ts +180 -0
  299. package/sdk/client/core/queryKeySerializer.gen.ts +136 -0
  300. package/sdk/client/core/serverSentEvents.gen.ts +265 -0
  301. package/sdk/client/core/types.gen.ts +118 -0
  302. package/sdk/client/core/utils.gen.ts +143 -0
  303. package/sdk/client/index.ts +1013 -0
  304. package/sdk/client/schemas.gen.ts +35395 -0
  305. package/sdk/client/sdk.gen.ts +3438 -0
  306. package/sdk/client/transformers.gen.ts +143 -0
  307. package/sdk/client/types.gen.ts +27567 -0
  308. package/tailwind.config.mjs +27 -0
  309. package/themes/aihub-theme.ts +125 -0
  310. package/types/DashboardWidget.ts +13 -0
  311. package/types/EventChartInput.ts +7 -0
  312. package/types/NavItem.ts +6 -0
  313. package/types/TimeseriesInput.ts +7 -0
@@ -0,0 +1,150 @@
1
+ <template>
2
+ <div>
3
+ <!-- Language Selector and Translate Button -->
4
+ <div class="mb-2 flex items-center gap-2">
5
+ <SelectButton
6
+ v-model="activeLocale"
7
+ :options="localeOptions"
8
+ option-label="label"
9
+ option-value="value"
10
+ size="small"
11
+ >
12
+ <template #option="{ option }">
13
+ <span>{{ option.label }}</span>
14
+ <!-- Filled indicator dot -->
15
+ <span
16
+ v-if="hasValue(option.value)"
17
+ class="absolute bottom-0.5 left-1/2 size-1 -translate-x-1/2 rounded-full bg-green-500"
18
+ />
19
+ </template>
20
+ </SelectButton>
21
+
22
+ <!-- Translate Button -->
23
+ <Button
24
+ v-if="canTranslate"
25
+ v-tooltip.top="t('form.locale_input.translate_tooltip')"
26
+ :loading="isTranslating"
27
+ :disabled="isTranslating"
28
+ icon="pi pi-language"
29
+ size="small"
30
+ severity="secondary"
31
+ text
32
+ @click="handleTranslate"
33
+ />
34
+ </div>
35
+
36
+ <!-- Text Input (single line) -->
37
+ <div class="relative">
38
+ <InputText
39
+ v-if="inputType === 'text'"
40
+ v-model="currentValue"
41
+ :placeholder="localizedPlaceholder"
42
+ class="w-full"
43
+ />
44
+
45
+ <!-- Textarea (multi-line) -->
46
+ <Textarea
47
+ v-else
48
+ v-model="currentValue"
49
+ :placeholder="localizedPlaceholder"
50
+ :rows="rows"
51
+ class="w-full"
52
+ />
53
+
54
+ <!-- Loading overlay -->
55
+ <div
56
+ v-if="isTranslating"
57
+ class="absolute inset-0 flex items-center justify-center rounded bg-surface-100/80 dark:bg-surface-800/80"
58
+ >
59
+ <i class="pi pi-spin pi-spinner text-xl" />
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </template>
64
+
65
+ <script setup lang="ts">
66
+ import type { LocaleStringDto } from '@core/sdk/client'
67
+
68
+ interface LocaleInputProps {
69
+ context: {
70
+ node: {
71
+ input: (value: LocaleStringDto) => void
72
+ }
73
+ value?: LocaleStringDto
74
+ attrs: Record<string, unknown>
75
+ // Custom props are passed through context, not as direct Vue props
76
+ inputType?: 'text' | 'textarea'
77
+ rows?: number
78
+ placeholder?: LocaleStringDto
79
+ }
80
+ }
81
+
82
+ const props = defineProps<LocaleInputProps>()
83
+ const { t } = useI18n()
84
+ const { translate, isTranslating } = useTranslate()
85
+ const { tenantId } = useTenant()
86
+
87
+ // Get custom props from context (FormKit passes them there, not as direct props)
88
+ const inputType = computed(() => props.context.inputType ?? 'text')
89
+ const rows = computed(() => props.context.rows ?? 3)
90
+ const placeholder = computed(() => props.context.placeholder)
91
+
92
+ const locales = ['de', 'en', 'fr', 'it'] as const
93
+ type Locale = (typeof locales)[number]
94
+
95
+ const localeOptions = locales.map(lang => ({
96
+ label: lang.toUpperCase(),
97
+ value: lang,
98
+ }))
99
+
100
+ const activeLocale = ref<Locale>('en')
101
+
102
+ // Get the current locale string value
103
+ const localeValue = computed<LocaleStringDto>(() => {
104
+ return props.context.value ?? { de: null, en: null, fr: null, it: null }
105
+ })
106
+
107
+ // Current input value for the active locale
108
+ const currentValue = computed({
109
+ get: () => localeValue.value[activeLocale.value] ?? '',
110
+ set: (newVal: string) => {
111
+ const updated: LocaleStringDto = {
112
+ ...localeValue.value,
113
+ [activeLocale.value]: newVal || null,
114
+ }
115
+ props.context.node.input(updated)
116
+ },
117
+ })
118
+
119
+ // Get localized placeholder for current locale
120
+ const localizedPlaceholder = computed(() => {
121
+ if (!placeholder.value) return undefined
122
+ return placeholder.value[activeLocale.value] ?? placeholder.value.en ?? ''
123
+ })
124
+
125
+ function hasValue(lang: Locale): boolean {
126
+ const val = localeValue.value[lang]
127
+ return val !== null && val !== undefined && val !== ''
128
+ }
129
+
130
+ // Check if translation is possible (current locale has text and at least one other locale is empty)
131
+ const canTranslate = computed(() => {
132
+ const currentText = localeValue.value[activeLocale.value]
133
+ if (!currentText) return false
134
+
135
+ // Check if any other locale is missing a value
136
+ return locales.some(lang => lang !== activeLocale.value && !hasValue(lang))
137
+ })
138
+
139
+ // Handle translation
140
+ async function handleTranslate() {
141
+ const response = await translate({
142
+ request: {
143
+ text: localeValue.value,
144
+ source_locale: activeLocale.value,
145
+ },
146
+ tenantId: tenantId.value!,
147
+ })
148
+ props.context.node.input(response.translated)
149
+ }
150
+ </script>
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <Select
3
+ v-model="selectedModel"
4
+ :options="models"
5
+ option-label="model_name"
6
+ option-value="model_name"
7
+ :placeholder="placeholder ?? t('common.selectModel')"
8
+ :filter="filter"
9
+ :show-clear="showClear"
10
+ :loading="isLoading"
11
+ class="w-full"
12
+ >
13
+ <template #option="{ option }">
14
+ <div class="flex items-center gap-2">
15
+ <Icon
16
+ :name="option.icon"
17
+ size="1.2em"
18
+ />
19
+ <span>{{ option.model_name }}</span>
20
+ </div>
21
+ </template>
22
+ <template #value="{ value }">
23
+ <div
24
+ v-if="value"
25
+ class="flex items-center gap-2"
26
+ >
27
+ <Icon
28
+ :name="getModelIcon(value)"
29
+ size="1.2em"
30
+ />
31
+ <span>{{ value }}</span>
32
+ </div>
33
+ </template>
34
+ </Select>
35
+ </template>
36
+
37
+ <script setup lang="ts">
38
+ import { getLitellmModelsByMode } from '@core/sdk/client'
39
+
40
+ import type { ModelDto } from '@core/sdk/client'
41
+
42
+ interface ModelSelectProps {
43
+ context: {
44
+ node: {
45
+ input: (value: string | null) => void
46
+ }
47
+ value?: string | null
48
+ attrs: Record<string, unknown>
49
+ // Custom props are passed through context, not as direct Vue props
50
+ mode?: 'chat' | 'embedding' | 'rerank' | 'image_generation' | 'audio_transcription' | 'audio_speech'
51
+ placeholder?: string
52
+ filter?: boolean
53
+ showClear?: boolean
54
+ }
55
+ }
56
+
57
+ const props = defineProps<ModelSelectProps>()
58
+
59
+ // Get custom props from context (FormKit passes them there, not as direct props)
60
+ const mode = computed(() => props.context.mode ?? 'chat')
61
+ const placeholder = computed(() => props.context.placeholder)
62
+ const filter = computed(() => props.context.filter ?? true)
63
+ const showClear = computed(() => props.context.showClear ?? false)
64
+
65
+ const { t } = useI18n()
66
+ const { tenantId } = useTenant()
67
+
68
+ const models = ref<ModelDto[]>([])
69
+ const isLoading = ref(false)
70
+
71
+ const selectedModel = computed({
72
+ get: () => props.context.value ?? null,
73
+ set: (value: string | null) => {
74
+ props.context.node.input(value)
75
+ },
76
+ })
77
+
78
+ function getModelIcon(modelName: string): string {
79
+ const model = models.value.find(m => m.model_name === modelName)
80
+ return model?.icon ?? 'meteor-icons:cpu'
81
+ }
82
+
83
+ async function fetchModels() {
84
+ isLoading.value = true
85
+ try {
86
+ const response = await getLitellmModelsByMode({
87
+ composable: '$fetch',
88
+ path: { tenant_id: tenantId.value!, mode: mode.value },
89
+ })
90
+ models.value = response
91
+ }
92
+ catch (error) {
93
+ console.error(`Failed to fetch models for mode "${mode.value}":`, error)
94
+ models.value = []
95
+ }
96
+ finally {
97
+ isLoading.value = false
98
+ }
99
+ }
100
+
101
+ // Fetch models on mount
102
+ onMounted(() => {
103
+ fetchModels()
104
+ })
105
+
106
+ // Refetch if mode changes
107
+ watch(mode, () => {
108
+ fetchModels()
109
+ })
110
+ </script>
@@ -0,0 +1,93 @@
1
+ <template>
2
+ <fieldset class="mb-4 rounded-lg border border-surface-300 p-4 dark:border-surface-600">
3
+ <legend class="px-2 text-sm font-semibold text-surface-700 dark:text-surface-300">
4
+ {{ label }}
5
+ </legend>
6
+
7
+ <div class="flex flex-col gap-3">
8
+ <div
9
+ v-for="(item, index) in items"
10
+ :key="index"
11
+ class="relative rounded-lg border border-surface-200 p-4 dark:border-surface-700"
12
+ >
13
+ <div class="mb-3 flex items-center justify-between">
14
+ <span class="text-sm font-medium text-surface-600 dark:text-surface-400">
15
+ #{{ index + 1 }}
16
+ </span>
17
+ <Button
18
+ type="button"
19
+ icon="pi pi-trash"
20
+ severity="danger"
21
+ text
22
+ size="small"
23
+ :disabled="isRemoveDisabled"
24
+ @click.prevent.stop="removeItem(index)"
25
+ />
26
+ </div>
27
+
28
+ <FormKit
29
+ v-if="modelValue"
30
+ :id="`__validate__${name}__${index}`"
31
+ v-model="modelValue[index]"
32
+ :name="`__validate__${name}__${index}`"
33
+ type="group"
34
+ >
35
+ <FormKitSchema
36
+ :schema="childrenSchema"
37
+ :data="modelValue[index]"
38
+ />
39
+ </FormKit>
40
+ </div>
41
+ </div>
42
+
43
+ <Button
44
+ type="button"
45
+ :label="addLabel || 'Add Item'"
46
+ icon="pi pi-plus"
47
+ size="small"
48
+ class="mt-3"
49
+ :disabled="isAddDisabled"
50
+ @click.prevent.stop="addItem"
51
+ />
52
+ </fieldset>
53
+ </template>
54
+
55
+ <script setup lang="ts">
56
+ import type { FormKitSchemaNode } from '@formkit/core'
57
+
58
+ const props = defineProps<{
59
+ name: string
60
+ label?: string
61
+ addLabel?: string
62
+ childrenSchema: FormKitSchemaNode[]
63
+ min?: number
64
+ max?: number
65
+ }>()
66
+
67
+ const modelValue = defineModel<Record<string, unknown>[]>({ default: () => [] })
68
+
69
+ const items = computed(() => modelValue.value || [])
70
+
71
+ const isAddDisabled = computed(() => {
72
+ if (typeof props.max !== 'number') return false
73
+ return items.value.length >= props.max
74
+ })
75
+
76
+ const isRemoveDisabled = computed(() => {
77
+ const minVal = typeof props.min === 'number' ? props.min : 0
78
+ return items.value.length <= minVal
79
+ })
80
+
81
+ function addItem() {
82
+ if (isAddDisabled.value) return
83
+ if (!modelValue.value) {
84
+ modelValue.value = []
85
+ }
86
+ modelValue.value.push({})
87
+ }
88
+
89
+ function removeItem(index: number) {
90
+ if (!modelValue.value || isRemoveDisabled.value) return
91
+ modelValue.value = modelValue.value.filter((_, i) => i !== index)
92
+ }
93
+ </script>
@@ -0,0 +1,247 @@
1
+ <template>
2
+ <div class="flex flex-col gap-4">
3
+ <!-- Database Selection -->
4
+ <div>
5
+ <label
6
+ for="vector-store-database-select"
7
+ class="mb-1 block text-sm font-medium"
8
+ >
9
+ {{ t('lib.vectorStore.database.label') }}
10
+ </label>
11
+ <Select
12
+ v-model="selectedDatabase"
13
+ input-id="vector-store-database-select"
14
+ :options="databaseOptions"
15
+ option-label="displayName"
16
+ option-value="name"
17
+ :placeholder="databasePlaceholder ?? t('common.selectDatabase')"
18
+ :filter="filter"
19
+ :loading="isLoading"
20
+ class="w-full"
21
+ >
22
+ <template #option="{ option }">
23
+ <div class="flex items-center gap-2">
24
+ <Icon
25
+ name="mage:database"
26
+ size="1.2em"
27
+ />
28
+ <span>{{ option.displayName }}</span>
29
+ </div>
30
+ </template>
31
+ <template #value="{ value }">
32
+ <div
33
+ v-if="value"
34
+ class="flex items-center gap-2"
35
+ >
36
+ <Icon
37
+ name="mage:database"
38
+ size="1.2em"
39
+ />
40
+ <span>{{ getDatabaseDisplayName(value) }}</span>
41
+ </div>
42
+ </template>
43
+ </Select>
44
+ </div>
45
+
46
+ <!-- Namespace Selection (shown when database selected) -->
47
+ <div v-if="selectedDatabase">
48
+ <label
49
+ for="vector-store-namespaces-select"
50
+ class="mb-1 block text-sm font-medium"
51
+ >
52
+ {{ t('lib.vectorStore.namespaces.label') }}
53
+ </label>
54
+ <MultiSelect
55
+ v-model="selectedNamespaces"
56
+ input-id="vector-store-namespaces-select"
57
+ :options="namespaceOptions"
58
+ option-label="displayName"
59
+ option-value="name"
60
+ :placeholder="namespacePlaceholder ?? t('lib.vectorStore.namespaces.placeholder')"
61
+ :filter="filter"
62
+ display="chip"
63
+ class="w-full"
64
+ >
65
+ <template #option="{ option }">
66
+ <div class="flex items-center gap-2">
67
+ <Icon
68
+ name="mage:folder"
69
+ size="1.2em"
70
+ />
71
+ <span>{{ option.displayName }}</span>
72
+ </div>
73
+ </template>
74
+ </MultiSelect>
75
+ <small class="mt-1 text-surface-500">
76
+ {{ t('lib.vectorStore.namespaces.help') }}
77
+ </small>
78
+ </div>
79
+
80
+ <!-- Allowed metadata filter fields (shown when database selected) -->
81
+ <div v-if="selectedDatabase">
82
+ <label
83
+ for="vector-store-filter-fields-input"
84
+ class="mb-1 block text-sm font-medium"
85
+ >
86
+ {{ t('lib.vectorStore.allowedFilterFields.label') }}
87
+ </label>
88
+ <ChipsInput :context="chipsInputContext" />
89
+ <small class="mt-1 text-surface-500">
90
+ {{ t('lib.vectorStore.allowedFilterFields.help') }}
91
+ </small>
92
+ </div>
93
+ </div>
94
+ </template>
95
+
96
+ <script setup lang="ts">
97
+ import ChipsInput from '@core/components/FormKit/ChipsInput.vue'
98
+ import { getDatabases } from '@core/sdk/client'
99
+ import { useChangeCase } from '@vueuse/integrations/useChangeCase'
100
+
101
+ import type { DatabaseDto } from '@core/sdk/client'
102
+
103
+ interface VectorStoreInputValue {
104
+ collection_name: string
105
+ index_namespaces: string[]
106
+ allowed_metadata_filter_fields: string[]
107
+ }
108
+
109
+ interface DatabaseOption {
110
+ name: string
111
+ displayName: string
112
+ }
113
+
114
+ interface NamespaceOption {
115
+ name: string
116
+ displayName: string
117
+ }
118
+
119
+ interface VectorStoreInputProps {
120
+ context: {
121
+ node: {
122
+ input: (value: VectorStoreInputValue | null) => void
123
+ }
124
+ value?: VectorStoreInputValue | null
125
+ attrs: Record<string, unknown>
126
+ databasePlaceholder?: string
127
+ namespacePlaceholder?: string
128
+ allowedFilterFieldsPlaceholder?: string
129
+ filter?: boolean
130
+ }
131
+ }
132
+
133
+ const props = defineProps<VectorStoreInputProps>()
134
+ const { t } = useI18n()
135
+ const { tenantId } = useTenant()
136
+
137
+ // Get custom props from context (FormKit passes them there, not as direct props)
138
+ const databasePlaceholder = computed(() => props.context.databasePlaceholder)
139
+ const namespacePlaceholder = computed(() => props.context.namespacePlaceholder)
140
+ const allowedFilterFieldsPlaceholder = computed(() => props.context.allowedFilterFieldsPlaceholder)
141
+ const filter = computed(() => props.context.filter ?? true)
142
+
143
+ // State
144
+ const databases = ref<DatabaseDto[]>([])
145
+ const isLoading = ref(false)
146
+
147
+ // Get current value from context
148
+ const currentValue = computed(() => props.context.value ?? null)
149
+
150
+ // Selected database (computed property that syncs with the form value)
151
+ const selectedDatabase = computed({
152
+ get: () => currentValue.value?.collection_name ?? null,
153
+ set: (value: string | null) => {
154
+ if (value) {
155
+ // When database changes, reset namespaces and allowed filter fields
156
+ emitValue(value, [], [])
157
+ }
158
+ else {
159
+ props.context.node.input(null)
160
+ }
161
+ },
162
+ })
163
+
164
+ // Selected namespaces (computed property that syncs with the form value)
165
+ const selectedNamespaces = computed({
166
+ get: () => currentValue.value?.index_namespaces ?? [],
167
+ set: (value: string[]) => {
168
+ if (selectedDatabase.value) {
169
+ emitValue(selectedDatabase.value, value, allowedFilterFields.value)
170
+ }
171
+ },
172
+ })
173
+
174
+ // Allowed metadata filter fields (delegated to ChipsInput child component)
175
+ const allowedFilterFields = computed(() => currentValue.value?.allowed_metadata_filter_fields ?? [])
176
+
177
+ const chipsInputContext = computed(() => ({
178
+ node: {
179
+ input: (value: string[]) => {
180
+ if (selectedDatabase.value) {
181
+ emitValue(selectedDatabase.value, selectedNamespaces.value, value)
182
+ }
183
+ },
184
+ },
185
+ value: allowedFilterFields.value,
186
+ placeholder: allowedFilterFieldsPlaceholder.value ?? t('lib.vectorStore.allowedFilterFields.placeholder'),
187
+ inputId: 'vector-store-filter-fields-input',
188
+ }))
189
+
190
+ // Emit complete value object
191
+ function emitValue(collectionName: string, namespaces: string[], allowedFilterFieldKeys: string[]) {
192
+ props.context.node.input({
193
+ collection_name: collectionName,
194
+ index_namespaces: namespaces,
195
+ allowed_metadata_filter_fields: allowedFilterFieldKeys,
196
+ })
197
+ }
198
+
199
+ // Database options for select
200
+ const databaseOptions = computed<DatabaseOption[]>(() =>
201
+ databases.value.map(db => ({
202
+ name: db.name,
203
+ displayName: db.display_name || useChangeCase(db.name, 'capitalCase'),
204
+ })),
205
+ )
206
+
207
+ // Namespace options based on selected database
208
+ const namespaceOptions = computed<NamespaceOption[]>(() => {
209
+ if (!selectedDatabase.value)
210
+ return []
211
+ const db = databases.value.find(d => d.name === selectedDatabase.value)
212
+ if (!db)
213
+ return []
214
+ return db.namespaces.map(ns => ({
215
+ name: ns.name,
216
+ displayName: ns.display_name || useChangeCase(ns.name, 'capitalCase'),
217
+ }))
218
+ })
219
+
220
+ function getDatabaseDisplayName(name: string): string {
221
+ const option = databaseOptions.value.find(opt => opt.name === name)
222
+ return option?.displayName ?? name
223
+ }
224
+
225
+ async function fetchDatabases() {
226
+ isLoading.value = true
227
+ try {
228
+ const response = await getDatabases({
229
+ composable: '$fetch',
230
+ path: { tenant_id: tenantId.value! },
231
+ })
232
+ databases.value = response
233
+ }
234
+ catch (error) {
235
+ console.error('Failed to fetch databases:', error)
236
+ databases.value = []
237
+ }
238
+ finally {
239
+ isLoading.value = false
240
+ }
241
+ }
242
+
243
+ // Fetch databases on mount
244
+ onMounted(() => {
245
+ fetchDatabases()
246
+ })
247
+ </script>