From c45236912ea9715960aa95ab8b8165e30b364062 Mon Sep 17 00:00:00 2001 From: Henry Estela Date: Fri, 20 Mar 2026 13:40:58 -0700 Subject: [PATCH] feat(ai-chat): add connection status badge to chat --- admin/app/controllers/ollama_controller.ts | 15 +++++++++++++++ admin/inertia/components/chat/index.tsx | 18 ++++++++++++++++-- admin/inertia/lib/api.ts | 9 +++++++++ admin/start/routes.ts | 1 + 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/admin/app/controllers/ollama_controller.ts b/admin/app/controllers/ollama_controller.ts index 3324eab..e58d249 100644 --- a/admin/app/controllers/ollama_controller.ts +++ b/admin/app/controllers/ollama_controller.ts @@ -189,6 +189,21 @@ export default class OllamaController { } } + async remoteStatus() { + const remoteUrl = await KVStore.getValue('ai.remoteOllamaUrl') + if (!remoteUrl) { + return { configured: false, connected: false } + } + try { + const testResponse = await fetch(`${remoteUrl.replace(/\/$/, '')}/v1/models`, { + signal: AbortSignal.timeout(3000), + }) + return { configured: true, connected: testResponse.ok } + } catch { + return { configured: true, connected: false } + } + } + async configureRemote({ request, response }: HttpContext) { const remoteUrl: string | null = request.input('remoteUrl', null) diff --git a/admin/inertia/components/chat/index.tsx b/admin/inertia/components/chat/index.tsx index db4ff6a..577579a 100644 --- a/admin/inertia/components/chat/index.tsx +++ b/admin/inertia/components/chat/index.tsx @@ -55,6 +55,13 @@ export default function Chat({ const { data: lastModelSetting } = useSystemSetting({ key: 'chat.lastModel', enabled }) const { data: remoteOllamaUrlSetting } = useSystemSetting({ key: 'ai.remoteOllamaUrl', enabled }) + const { data: remoteStatus } = useQuery({ + queryKey: ['remoteOllamaStatus'], + queryFn: () => api.getRemoteOllamaStatus(), + enabled: enabled && !!remoteOllamaUrlSetting?.value, + refetchInterval: 15000, + }) + const { data: installedModels = [], isLoading: isLoadingModels } = useQuery({ queryKey: ['installedModels'], queryFn: () => api.getInstalledModels(), @@ -365,8 +372,15 @@ export default function Chat({
{remoteOllamaUrlSetting?.value && ( - - Remote Connected + + {remoteStatus?.connected === false ? 'Remote Disconnected' : 'Remote Connected'} )}
diff --git a/admin/inertia/lib/api.ts b/admin/inertia/lib/api.ts index aa28c3c..8f7e82f 100644 --- a/admin/inertia/lib/api.ts +++ b/admin/inertia/lib/api.ts @@ -48,6 +48,15 @@ class API { })() } + async getRemoteOllamaStatus(): Promise<{ configured: boolean; connected: boolean }> { + return catchInternal(async () => { + const response = await this.client.get<{ configured: boolean; connected: boolean }>( + '/ollama/remote-status' + ) + return response.data + })() + } + async configureRemoteOllama(remoteUrl: string | null): Promise<{ success: boolean; message: string }> { return catchInternal(async () => { const response = await this.client.post<{ success: boolean; message: string }>( diff --git a/admin/start/routes.ts b/admin/start/routes.ts index dcc3174..dc2ea9c 100644 --- a/admin/start/routes.ts +++ b/admin/start/routes.ts @@ -108,6 +108,7 @@ router router.delete('/models', [OllamaController, 'deleteModel']) router.get('/installed-models', [OllamaController, 'installedModels']) router.post('/configure-remote', [OllamaController, 'configureRemote']) + router.get('/remote-status', [OllamaController, 'remoteStatus']) }) .prefix('/api/ollama')