@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,88 @@
1
+ import { useToast } from 'primevue/usetoast'
2
+ import { useRouter } from 'vue-router'
3
+
4
+ import type { ComputedRef } from 'vue'
5
+
6
+ export interface UseMemoryCRUDOptions {
7
+ selectedMemory: ComputedRef<{ id: string } | undefined>
8
+ updateMemory: (params: { memoryId: string, data: string }) => Promise<void>
9
+ deleteMemory: (params: { memoryId: string }) => Promise<void>
10
+ closeRoute: string
11
+ }
12
+
13
+ /**
14
+ * Shared composable for memory CRUD operations with toast notifications.
15
+ * Eliminates duplication across user/org detail pages.
16
+ *
17
+ * Provides:
18
+ * - Update handler with success/error toasts (matches MemoryEdit @update signature)
19
+ * - Delete handler with success/error toasts + navigation (matches MemoryEdit @delete signature)
20
+ * - Close handler for navigation back to list (matches MemoryEdit @close signature)
21
+ *
22
+ * @param options - Selected memory ref, CRUD mutation functions, and close route
23
+ * @returns CRUD handlers with toast notifications
24
+ */
25
+ export function useMemoryCRUD(options: UseMemoryCRUDOptions) {
26
+ const { t } = useI18n()
27
+ const toast = useToast()
28
+ const router = useRouter()
29
+ const tenantPath = useTenantPath()
30
+
31
+ const handleUpdate = async (data: string) => {
32
+ if (!options.selectedMemory.value) return
33
+
34
+ try {
35
+ await options.updateMemory({ memoryId: options.selectedMemory.value.id, data })
36
+ toast.add({
37
+ severity: 'success',
38
+ summary: t('memory.update.success.title'),
39
+ detail: t('memory.update.success.message'),
40
+ life: 3000,
41
+ })
42
+ }
43
+ catch (error) {
44
+ console.error('Failed to update memory:', error)
45
+ toast.add({
46
+ severity: 'error',
47
+ summary: t('memory.update.error.title'),
48
+ detail: t('memory.update.error.message'),
49
+ life: 5000,
50
+ })
51
+ }
52
+ }
53
+
54
+ const handleDelete = async () => {
55
+ if (!options.selectedMemory.value) return
56
+
57
+ try {
58
+ await options.deleteMemory({ memoryId: options.selectedMemory.value.id })
59
+ toast.add({
60
+ severity: 'success',
61
+ summary: t('memory.delete.success.title'),
62
+ detail: t('memory.delete.success.message'),
63
+ life: 3000,
64
+ })
65
+ // Navigate back to list after successful deletion
66
+ router.push(tenantPath(options.closeRoute))
67
+ }
68
+ catch (error) {
69
+ console.error('Failed to delete memory:', error)
70
+ toast.add({
71
+ severity: 'error',
72
+ summary: t('memory.delete.error.title'),
73
+ detail: t('memory.delete.error.message'),
74
+ life: 5000,
75
+ })
76
+ }
77
+ }
78
+
79
+ const handleClose = () => {
80
+ router.push(tenantPath(options.closeRoute))
81
+ }
82
+
83
+ return {
84
+ handleUpdate,
85
+ handleDelete,
86
+ handleClose,
87
+ }
88
+ }
@@ -0,0 +1,319 @@
1
+ import {
2
+ getUserMemories,
3
+ searchUserMemories,
4
+ updateUserMemory,
5
+ deleteUserMemory,
6
+ deleteAllUserMemories,
7
+ getOrganizationMemories,
8
+ searchOrganizationMemories,
9
+ updateOrganizationMemory,
10
+ deleteOrganizationMemory,
11
+ deleteAllOrganizationMemories,
12
+ } from '@core/sdk/client'
13
+ import { minutesToMilliseconds } from 'date-fns'
14
+ import { computed, ref } from 'vue'
15
+
16
+ import type { MemoriesResponse, MemorySearchResponse } from '@core/sdk/client'
17
+
18
+ type MemoryType = 'user' | 'organization'
19
+
20
+ interface MemoryContext {
21
+ type: MemoryType
22
+ agent_class?: string
23
+ agent_id?: string
24
+ thread_id?: string
25
+ }
26
+
27
+ /**
28
+ * Factory function to create memory composables for both user and organization memory types.
29
+ * This eliminates code duplication by generating type-specific hooks from a single implementation.
30
+ *
31
+ * @param context - Memory context specifying type (user/organization)
32
+ * @returns Object containing all memory-related composables
33
+ *
34
+ * @example
35
+ * // User memory
36
+ * const { useMemories, useMemorySearch } = createMemoryComposables({ type: 'user' })
37
+ *
38
+ * @example
39
+ * // Organization memory (tenant from env-var)
40
+ * const { useMemories, useMemorySearch } = createMemoryComposables({ type: 'organization' })
41
+ */
42
+ export function createMemoryComposables(context: MemoryContext) {
43
+ const { type, agent_class, agent_id, thread_id } = context
44
+
45
+ /**
46
+ * Generate cache keys with proper scoping for user vs organization memory.
47
+ * Includes the tenant prefix for hierarchical cache invalidation.
48
+ */
49
+ const getCacheKey = (operation: string, params: Record<string, unknown> = {}) => {
50
+ const baseParams = { ...params, agent_class, agent_id, thread_id }
51
+ const memoryType = type === 'user' ? 'user' : 'organization'
52
+ return ['tenant', params.tenant, 'memories', memoryType, operation, baseParams]
53
+ }
54
+
55
+ /**
56
+ * Composable for fetching and paginating memories
57
+ */
58
+ const useMemories = () => {
59
+ const { tenantId } = useTenant()
60
+ const currentPage = ref(1)
61
+ const pageSize = ref(20)
62
+
63
+ const {
64
+ data: memoriesData,
65
+ isPending: memoriesAreLoading,
66
+ } = useQuery<MemoriesResponse>({
67
+ key: () => getCacheKey('list', { tenant: tenantId.value, page: currentPage.value }),
68
+ staleTime: minutesToMilliseconds(5),
69
+ enabled: useTenantReady(),
70
+ query: async () => {
71
+ // Use search endpoint when filters are provided (agent_class/agent_id/thread_id)
72
+ const hasFilters = agent_class || agent_id || thread_id
73
+
74
+ if (type === 'user') {
75
+ if (hasFilters) {
76
+ // Search endpoint supports filtering
77
+ return await searchUserMemories({
78
+ composable: '$fetch',
79
+ path: { tenant_id: tenantId.value! },
80
+ query: {
81
+ query: '', // Empty query returns all memories
82
+ limit: 1000,
83
+ agent_class: agent_class || null,
84
+ agent_id: agent_id || null,
85
+ thread_id: thread_id || null,
86
+ },
87
+ })
88
+ }
89
+ return await getUserMemories({
90
+ composable: '$fetch',
91
+ path: { tenant_id: tenantId.value! },
92
+ query: { limit: 1000 },
93
+ })
94
+ }
95
+
96
+ if (hasFilters) {
97
+ return await searchOrganizationMemories({
98
+ composable: '$fetch',
99
+ path: { tenant_id: tenantId.value! },
100
+ query: {
101
+ query: '', // Empty query returns all memories
102
+ limit: 1000,
103
+ agent_class: agent_class || null,
104
+ agent_id: agent_id || null,
105
+ thread_id: thread_id || null,
106
+ },
107
+ })
108
+ }
109
+ return await getOrganizationMemories({
110
+ composable: '$fetch',
111
+ path: { tenant_id: tenantId.value! },
112
+ query: {
113
+ limit: 1000,
114
+ },
115
+ })
116
+ },
117
+ })
118
+
119
+ const paginatedMemories = computed(() => {
120
+ if (!memoriesData.value) return []
121
+ const start = (currentPage.value - 1) * pageSize.value
122
+ const end = start + pageSize.value
123
+ return memoriesData.value.memories.slice(start, end)
124
+ })
125
+
126
+ const totalPages = computed(() => {
127
+ if (!memoriesData.value) return 0
128
+ return Math.ceil(memoriesData.value.memories.length / pageSize.value)
129
+ })
130
+
131
+ const allRelations = computed(() => {
132
+ return memoriesData.value?.relations || []
133
+ })
134
+
135
+ const nextPage = () => {
136
+ if (currentPage.value < totalPages.value) {
137
+ currentPage.value++
138
+ }
139
+ }
140
+
141
+ const prevPage = () => {
142
+ if (currentPage.value > 1) {
143
+ currentPage.value--
144
+ }
145
+ }
146
+
147
+ return {
148
+ memoriesData,
149
+ memoriesAreLoading,
150
+ paginatedMemories,
151
+ allRelations,
152
+ currentPage,
153
+ pageSize,
154
+ totalPages,
155
+ nextPage,
156
+ prevPage,
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Composable for semantic memory search
162
+ */
163
+ const useMemorySearch = () => {
164
+ const { tenantId } = useTenant()
165
+ const query = ref<string>('')
166
+ const limit = ref(100)
167
+
168
+ const {
169
+ data: searchData,
170
+ isPending: searchIsLoading,
171
+ } = useQuery<MemorySearchResponse>({
172
+ key: () => getCacheKey('search', { tenant: tenantId.value, query: query.value, limit: limit.value }),
173
+ staleTime: minutesToMilliseconds(1),
174
+ enabled: () => !!query.value && !!tenantId.value,
175
+ query: async () => {
176
+ if (type === 'user') {
177
+ return await searchUserMemories({
178
+ composable: '$fetch',
179
+ path: { tenant_id: tenantId.value! },
180
+ query: {
181
+ query: query.value,
182
+ limit: limit.value,
183
+ agent_class: agent_class || null,
184
+ agent_id: agent_id || null,
185
+ thread_id: thread_id || null,
186
+ },
187
+ })
188
+ }
189
+
190
+ return await searchOrganizationMemories({
191
+ composable: '$fetch',
192
+ path: { tenant_id: tenantId.value! },
193
+ query: {
194
+ query: query.value,
195
+ limit: limit.value,
196
+ agent_class: agent_class || null,
197
+ agent_id: agent_id || null,
198
+ thread_id: thread_id || null,
199
+ },
200
+ })
201
+ },
202
+ })
203
+
204
+ const isSearchActive = computed(() => !!query.value)
205
+
206
+ const setSearchQuery = (q: string) => {
207
+ query.value = q
208
+ }
209
+
210
+ const clearSearch = () => {
211
+ query.value = ''
212
+ }
213
+
214
+ return {
215
+ searchData,
216
+ searchIsLoading,
217
+ query,
218
+ isSearchActive,
219
+ setSearchQuery,
220
+ clearSearch,
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Composable for updating memory content
226
+ */
227
+ const useUpdateMemory = () => {
228
+ const queryCache = useQueryCache()
229
+ const { tenantId } = useTenant()
230
+
231
+ const { mutate: updateMemoryMutation } = useMutation({
232
+ mutation: async ({ memoryId, data }: { memoryId: string, data: string }) => {
233
+ const tenant = tenantId.value!
234
+ if (type === 'user') {
235
+ await updateUserMemory({
236
+ composable: '$fetch',
237
+ path: { tenant_id: tenant, memory_id: memoryId },
238
+ body: { data },
239
+ })
240
+ }
241
+ else {
242
+ await updateOrganizationMemory({
243
+ composable: '$fetch',
244
+ path: { tenant_id: tenant, memory_id: memoryId },
245
+ body: { data },
246
+ })
247
+ }
248
+
249
+ // Invalidate cache to trigger refetch
250
+ queryCache.invalidateQueries({ key: getCacheKey('list', { tenant }) })
251
+ },
252
+ })
253
+
254
+ return { updateMemory: updateMemoryMutation }
255
+ }
256
+
257
+ /**
258
+ * Composable for deleting memories
259
+ */
260
+ const useDeleteMemory = () => {
261
+ const queryCache = useQueryCache()
262
+ const { tenantId } = useTenant()
263
+
264
+ const { mutate: deleteMemoryMutation } = useMutation({
265
+ mutation: async ({ memoryId }: { memoryId: string }) => {
266
+ const tenant = tenantId.value!
267
+ if (type === 'user') {
268
+ await deleteUserMemory({
269
+ composable: '$fetch',
270
+ path: { tenant_id: tenant, memory_id: memoryId },
271
+ })
272
+ }
273
+ else {
274
+ await deleteOrganizationMemory({
275
+ composable: '$fetch',
276
+ path: { tenant_id: tenant, memory_id: memoryId },
277
+ })
278
+ }
279
+
280
+ // Invalidate cache to trigger refetch
281
+ queryCache.invalidateQueries({ key: getCacheKey('list', { tenant }) })
282
+ },
283
+ })
284
+
285
+ const { mutate: deleteAllMemoriesMutation } = useMutation({
286
+ mutation: async () => {
287
+ const tenant = tenantId.value!
288
+ if (type === 'user') {
289
+ await deleteAllUserMemories({
290
+ composable: '$fetch',
291
+ path: { tenant_id: tenant },
292
+ })
293
+ }
294
+ else {
295
+ await deleteAllOrganizationMemories({
296
+ composable: '$fetch',
297
+ path: { tenant_id: tenant },
298
+ })
299
+ }
300
+
301
+ // Invalidate both list and search cache
302
+ queryCache.invalidateQueries({ key: getCacheKey('list', { tenant }) })
303
+ queryCache.invalidateQueries({ key: getCacheKey('search', { tenant }) })
304
+ },
305
+ })
306
+
307
+ return {
308
+ deleteMemory: deleteMemoryMutation,
309
+ deleteAllMemories: deleteAllMemoriesMutation,
310
+ }
311
+ }
312
+
313
+ return {
314
+ useMemories,
315
+ useMemorySearch,
316
+ useUpdateMemory,
317
+ useDeleteMemory,
318
+ }
319
+ }
@@ -0,0 +1,74 @@
1
+ import { computed, onMounted } from 'vue'
2
+
3
+ import type { Ref } from 'vue'
4
+
5
+ export interface UseMemorySearchFilterOptions {
6
+ searchData: Ref<{ memories: unknown[] } | undefined>
7
+ paginatedMemories: Ref<unknown[]>
8
+ isSearchActive: Ref<boolean>
9
+ setSearchQuery: (query: string) => void
10
+ clearSearch: () => void
11
+ searchIsLoading: Ref<boolean>
12
+ currentPage?: Ref<number>
13
+ totalPages?: Ref<number>
14
+ }
15
+
16
+ /**
17
+ * Shared composable for memory search and filtering logic.
18
+ * Eliminates duplication across user/org list and graph pages.
19
+ *
20
+ * Provides:
21
+ * - Search input synced with URL query param
22
+ * - Displayed memories (search results or paginated)
23
+ * - Search/clear handlers
24
+ * - Loading states
25
+ *
26
+ * @param options - Memory search composable outputs from factory
27
+ * @returns Search filter state and handlers
28
+ */
29
+ export function useMemorySearchFilter(options: UseMemorySearchFilterOptions) {
30
+ const searchInput = useRouteQuery('q', '')
31
+ const isSearchButtonLoading = computed(() =>
32
+ options.isSearchActive.value && options.searchIsLoading.value,
33
+ )
34
+
35
+ // Sync URL query param with search on mount
36
+ onMounted(() => {
37
+ if (searchInput.value) {
38
+ options.setSearchQuery(searchInput.value as string)
39
+ }
40
+ })
41
+
42
+ const displayedMemories = computed(() => {
43
+ return options.isSearchActive.value && options.searchData.value
44
+ ? options.searchData.value.memories
45
+ : options.paginatedMemories.value
46
+ })
47
+
48
+ const displayedCurrentPage = computed(() => {
49
+ return options.isSearchActive.value ? 1 : (options.currentPage?.value ?? 1)
50
+ })
51
+
52
+ const displayedTotalPages = computed(() => {
53
+ return options.isSearchActive.value ? 1 : (options.totalPages?.value ?? 1)
54
+ })
55
+
56
+ const handleSearch = () => {
57
+ options.setSearchQuery(searchInput.value)
58
+ }
59
+
60
+ const handleClearSearch = () => {
61
+ searchInput.value = null
62
+ options.clearSearch()
63
+ }
64
+
65
+ return {
66
+ searchInput,
67
+ isSearchButtonLoading,
68
+ displayedMemories,
69
+ displayedCurrentPage,
70
+ displayedTotalPages,
71
+ handleSearch,
72
+ handleClearSearch,
73
+ }
74
+ }
@@ -0,0 +1,24 @@
1
+ import { getLitellmModels, type ModelTypeGroupDto } from '@core/sdk/client'
2
+ import { minutesToMilliseconds } from 'date-fns'
3
+
4
+ export const useModelsList = defineQuery(() => {
5
+ const { tenantId } = useTenant()
6
+
7
+ const { data: modelTypes, isPending: modelsAreLoading, error } = useQuery<ModelTypeGroupDto[]>({
8
+ key: () => ['tenant', tenantId.value, 'models'],
9
+ staleTime: minutesToMilliseconds(5),
10
+ enabled: useTenantReady(),
11
+ query: async () => {
12
+ return await getLitellmModels({
13
+ composable: '$fetch',
14
+ path: { tenant_id: tenantId.value! },
15
+ })
16
+ },
17
+ })
18
+
19
+ return {
20
+ modelTypes,
21
+ modelsAreLoading,
22
+ error,
23
+ }
24
+ })
@@ -0,0 +1,30 @@
1
+ import { getLitellmModel, type ModelDto } from '@core/sdk/client'
2
+ import { minutesToMilliseconds } from 'date-fns'
3
+
4
+ export const useSingleModel = () => {
5
+ const route = useRoute()
6
+ const { tenantId } = useTenant()
7
+
8
+ const modelName = computed<string>(() => decodeURIComponent(route.params?.model_name as string))
9
+
10
+ const { data: model, isPending: modelIsLoading, error } = useQuery<ModelDto>({
11
+ key: () => ['tenant', tenantId.value, 'model', modelName.value],
12
+ staleTime: minutesToMilliseconds(5),
13
+ enabled: useTenantReady('model_name'),
14
+ query: async () => {
15
+ return await getLitellmModel({
16
+ composable: '$fetch',
17
+ path: {
18
+ tenant_id: tenantId.value!,
19
+ model_name: modelName.value,
20
+ },
21
+ })
22
+ },
23
+ })
24
+
25
+ return {
26
+ model,
27
+ modelIsLoading,
28
+ error,
29
+ }
30
+ }
@@ -0,0 +1,58 @@
1
+ import { getNotifications, type NotificationDto } from '@core/sdk/client'
2
+ import { useIntervalFn } from '@vueuse/core'
3
+ import { useToast } from 'primevue/usetoast'
4
+
5
+ export const useNotificationPoller = (options?: {
6
+ pollingInterval?: number
7
+ enabled?: boolean
8
+ }) => {
9
+ const { tenantId } = useTenant()
10
+ const toast = useToast()
11
+ const queryCache = useQueryCache()
12
+
13
+ const knownUnreadIds = ref(new Set<string>())
14
+
15
+ const { data: unreadResponse, refetch } = useQuery({
16
+ key: () => ['tenant', tenantId.value, 'notifications_poller_data'],
17
+ query: () =>
18
+ getNotifications({
19
+ composable: '$fetch',
20
+ path: { tenant_id: tenantId.value! },
21
+ query: { read: false, page_size: 100 },
22
+ }),
23
+ enabled: useTenantReady(),
24
+ })
25
+
26
+ watch(unreadResponse, (newData) => {
27
+ const newNotifications = newData?.notifications
28
+ if (!newNotifications) return
29
+
30
+ let hasNew = false
31
+ newNotifications.forEach((notification: NotificationDto) => {
32
+ if (!knownUnreadIds.value.has(notification.id)) {
33
+ hasNew = true
34
+ toast.add({
35
+ severity: notification.type,
36
+ summary: notification.title,
37
+ detail: notification.message,
38
+ life: 5000,
39
+ })
40
+ }
41
+ })
42
+
43
+ knownUnreadIds.value = new Set(newNotifications.map(n => n.id))
44
+
45
+ if (hasNew) {
46
+ queryCache.invalidateQueries({ key: ['tenant', tenantId.value, 'notifications'] })
47
+ }
48
+ })
49
+
50
+ const pollingInterval = options?.pollingInterval ?? 30_000
51
+ const enabled = options?.enabled ?? true
52
+
53
+ useIntervalFn(() => {
54
+ if (tenantId.value) {
55
+ refetch()
56
+ }
57
+ }, pollingInterval, { immediate: enabled })
58
+ }
@@ -0,0 +1,57 @@
1
+ import { getNotifications, type PaginatedNotificationsResponse } from '@core/sdk/client'
2
+
3
+ export const useNotifications = (options: {
4
+ currentPage: Ref<number>
5
+ pageSize: Ref<number>
6
+ filters?: {
7
+ read?: Ref<boolean | undefined>
8
+ done?: Ref<boolean | undefined>
9
+ types?: Ref<string[] | undefined>
10
+ severities?: Ref<string[] | undefined>
11
+ }
12
+ }) => {
13
+ const { tenantId } = useTenant()
14
+ const { currentPage, pageSize, filters } = options
15
+
16
+ const key = () => [
17
+ 'tenant',
18
+ tenantId.value,
19
+ 'notifications',
20
+ {
21
+ page: currentPage.value,
22
+ pageSize: pageSize.value,
23
+ read: filters?.read?.value,
24
+ done: filters?.done?.value,
25
+ types: filters?.types?.value,
26
+ severities: filters?.severities?.value,
27
+ },
28
+ ]
29
+
30
+ const query = useQuery<PaginatedNotificationsResponse>({
31
+ key,
32
+ enabled: useTenantReady(),
33
+ query: () =>
34
+ getNotifications({
35
+ composable: '$fetch',
36
+ path: { tenant_id: tenantId.value! },
37
+ query: {
38
+ page: currentPage.value,
39
+ page_size: pageSize.value,
40
+ read: filters?.read?.value,
41
+ done: filters?.done?.value,
42
+ types: filters?.types?.value,
43
+ severities: filters?.severities?.value,
44
+ },
45
+ }),
46
+ })
47
+
48
+ const notifications = computed(() => query.data.value?.notifications ?? [])
49
+ const totalRecords = computed(() => query.data.value?.total ?? 0)
50
+
51
+ return {
52
+ notifications,
53
+ isLoading: query.isPending,
54
+ refetch: query.refetch,
55
+ totalRecords,
56
+ }
57
+ }
@@ -0,0 +1,17 @@
1
+ import { type UpdateNotificationRequest, updateNotificationsBulk } from '@core/sdk/client'
2
+
3
+ export const useUpdateMultipleNotifications = defineMutation(() => {
4
+ const queryCache = useQueryCache()
5
+ const { tenantId } = useTenant()
6
+ return useMutation({
7
+ mutation: ({ ids, payload, tenantId }: { ids: string[], payload: Ref<UpdateNotificationRequest>, tenantId: string }) =>
8
+ updateNotificationsBulk({
9
+ composable: '$fetch',
10
+ path: { tenant_id: tenantId },
11
+ body: { notification_ids: ids, updates: payload },
12
+ }),
13
+ onSuccess: () => {
14
+ queryCache.invalidateQueries({ key: ['tenant', tenantId.value, 'notifications'] })
15
+ },
16
+ })
17
+ })
@@ -0,0 +1,17 @@
1
+ import { updateNotification, type UpdateNotificationRequest } from '@core/sdk/client'
2
+
3
+ export const useUpdateNotification = defineMutation(() => {
4
+ const queryCache = useQueryCache()
5
+ const { tenantId } = useTenant()
6
+ return useMutation({
7
+ mutation: ({ id, payload, tenantId }: { id: string, payload: Ref<UpdateNotificationRequest>, tenantId: string }) =>
8
+ updateNotification({
9
+ composable: '$fetch',
10
+ path: { tenant_id: tenantId, notification_id: id },
11
+ body: payload,
12
+ }),
13
+ onSuccess: () => {
14
+ queryCache.invalidateQueries({ key: ['tenant', tenantId.value, 'notifications'] })
15
+ },
16
+ })
17
+ })