diff --git a/tools/ui/src/lib/services/chat.service.ts b/tools/ui/src/lib/services/chat.service.ts index 7e652f99c5..31cefe3c9a 100644 --- a/tools/ui/src/lib/services/chat.service.ts +++ b/tools/ui/src/lib/services/chat.service.ts @@ -43,7 +43,7 @@ import type { ApiStreamSession } from '$lib/types/api'; import { isAbortError } from '$lib/utils/abort'; -import { apiUrl } from '$lib/utils/api-base'; +import { apiChatUrl, apiUrl } from '$lib/utils/api-base'; import { ApiError } from '$lib/utils/api-fetch'; import { getAuthHeaders, getJsonHeaders } from '$lib/utils/api-headers'; import { formatAttachmentText } from '$lib/utils/formatters'; @@ -874,7 +874,7 @@ export class ChatService { } try { - await fetch(apiUrl(API_CHAT.COMPLETIONS), { + await fetch(apiChatUrl(), { body: JSON.stringify(requestBody), headers: getJsonHeaders(), method: 'POST', @@ -1235,7 +1235,7 @@ export class ChatService { ChatService.saveStreamState(conversationId, 0, options.model ?? null); } - const response = await fetch(apiUrl(API_CHAT.COMPLETIONS), { + const response = await fetch(apiChatUrl(), { body: JSON.stringify(requestBody), headers, method: 'POST', diff --git a/tools/ui/src/lib/services/models.service.ts b/tools/ui/src/lib/services/models.service.ts index 710f5b8966..70b3d23208 100644 --- a/tools/ui/src/lib/services/models.service.ts +++ b/tools/ui/src/lib/services/models.service.ts @@ -12,6 +12,7 @@ import type { ParsedModelId } from '$lib/types/models'; import { apiDelete, apiFetch, + apiModelsUrl, apiPost, apiUrl, extractSseDataPayload, @@ -140,7 +141,7 @@ export class ModelsService { * @returns List of available models with basic metadata */ static async list(): Promise { - return apiFetch(API_MODELS.LIST); + return apiFetch(apiModelsUrl()); } /** diff --git a/tools/ui/src/lib/utils/api-base.ts b/tools/ui/src/lib/utils/api-base.ts index 07e8517200..d88d536531 100644 --- a/tools/ui/src/lib/utils/api-base.ts +++ b/tools/ui/src/lib/utils/api-base.ts @@ -7,8 +7,9 @@ * store, which keeps URL resolution free of store dependencies. */ +import { backendChatUrl, backendModelsUrl } from './backend'; import { base } from '$app/paths'; -import { API_ABSOLUTE_URL_PROTOCOLS } from '$lib/constants'; +import { API_ABSOLUTE_URL_PROTOCOLS, API_CHAT, API_MODELS } from '$lib/constants'; import type { Backend } from '$lib/types'; /** Backend list and active selection as exposed to URL resolution. */ @@ -44,6 +45,36 @@ export function getBackendBaseUrl(backendId?: string): string { return getBackend(backendId)?.baseUrl.trim() ?? ''; } +/** + * Request target for a backend's chat completions endpoint. Returns a relative + * path for the local backend and an absolute URL for external ones, so callers + * can pass the result straight to `fetch` (or `apiFetch`, which resolves + * relative paths against the base). + */ +export function apiChatUrl(backendId?: string): string { + const backend = getBackend(backendId); + + if (backend?.baseUrl.trim()) { + return backendChatUrl(backend); + } + + return apiUrl(API_CHAT.COMPLETIONS, backendId); +} + +/** + * Request target for a backend's models listing. Returns a plain path for the + * local backend (so `apiFetch` applies the base) and an absolute URL otherwise. + */ +export function apiModelsUrl(backendId?: string): string { + const backend = getBackend(backendId); + + if (backend?.baseUrl.trim()) { + return backendModelsUrl(backend); + } + + return API_MODELS.LIST; +} + /** * Absolute URL for an API path on a backend. * diff --git a/tools/ui/src/lib/utils/index.ts b/tools/ui/src/lib/utils/index.ts index 2278531bb3..f40d882029 100644 --- a/tools/ui/src/lib/utils/index.ts +++ b/tools/ui/src/lib/utils/index.ts @@ -8,7 +8,14 @@ */ // API utilities -export { apiUrl, getBackend, getBackendBaseUrl, type BackendsSnapshot } from './api-base'; +export { + apiChatUrl, + apiModelsUrl, + apiUrl, + getBackend, + getBackendBaseUrl, + type BackendsSnapshot +} from './api-base'; export { getAuthHeaders, getAuthHeadersForBackend,