import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; export const getModels = async (token: string = '') => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/models`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } let models = res?.data ?? []; models = models .filter((models) => models) // Sort the models .sort((a, b) => { // Check if models have position property const aHasPosition = a.info?.meta?.position !== undefined; const bHasPosition = b.info?.meta?.position !== undefined; // If both a and b have the position property if (aHasPosition && bHasPosition) { return a.info.meta.position - b.info.meta.position; } // If only a has the position property, it should come first if (aHasPosition) return -1; // If only b has the position property, it should come first if (bHasPosition) return 1; // Compare case-insensitively by name for models without position property const lowerA = a.name.toLowerCase(); const lowerB = b.name.toLowerCase(); if (lowerA < lowerB) return -1; if (lowerA > lowerB) return 1; // If same case-insensitively, sort by original strings, // lowercase will come before uppercase due to ASCII values if (a.name < b.name) return -1; if (a.name > b.name) return 1; return 0; // They are equal }); console.log(models); return models; }; type ChatCompletedForm = { model: string; messages: string[]; chat_id: string; session_id: string; }; export const chatCompleted = async (token: string, body: ChatCompletedForm) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/chat/completed`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) }, body: JSON.stringify(body) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } else { error = err; } return null; }); if (error) { throw error; } return res; }; type ChatActionForm = { model: string; messages: string[]; chat_id: string; }; export const chatAction = async (token: string, action_id: string, body: ChatActionForm) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/chat/actions/${action_id}`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) }, body: JSON.stringify(body) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } else { error = err; } return null; }); if (error) { throw error; } return res; }; export const getTaskConfig = async (token: string = '') => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/task/config`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; }; export const updateTaskConfig = async (token: string, config: object) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/task/config/update`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) }, body: JSON.stringify(config) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } else { error = err; } return null; }); if (error) { throw error; } return res; }; export const generateTitle = async ( token: string = '', model: string, messages: string[], chat_id?: string ) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/task/title/completions`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ model: model, messages: messages, ...(chat_id && { chat_id: chat_id }) }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } return null; }); if (error) { throw error; } return res?.choices[0]?.message?.content.replace(/["']/g, '') ?? 'New Chat'; }; export const generateTags = async ( token: string = '', model: string, messages: string, chat_id?: string ) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/task/tags/completions`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ model: model, messages: messages, ...(chat_id && { chat_id: chat_id }) }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } return null; }); if (error) { throw error; } try { // Step 1: Safely extract the response string const response = res?.choices[0]?.message?.content ?? ''; // Step 2: Attempt to fix common JSON format issues like single quotes const sanitizedResponse = response.replace(/['‘’`]/g, '"'); // Convert single quotes to double quotes for valid JSON // Step 3: Find the relevant JSON block within the response const jsonStartIndex = sanitizedResponse.indexOf('{'); const jsonEndIndex = sanitizedResponse.lastIndexOf('}'); // Step 4: Check if we found a valid JSON block (with both `{` and `}`) if (jsonStartIndex !== -1 && jsonEndIndex !== -1) { const jsonResponse = sanitizedResponse.substring(jsonStartIndex, jsonEndIndex + 1); // Step 5: Parse the JSON block const parsed = JSON.parse(jsonResponse); // Step 6: If there's a "tags" key, return the tags array; otherwise, return an empty array if (parsed && parsed.tags) { return Array.isArray(parsed.tags) ? parsed.tags : []; } else { return []; } } // If no valid JSON block found, return an empty array return []; } catch (e) { // Catch and safely return empty array on any parsing errors console.error('Failed to parse response: ', e); return []; } }; export const generateEmoji = async ( token: string = '', model: string, prompt: string, chat_id?: string ) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/task/emoji/completions`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ model: model, prompt: prompt, ...(chat_id && { chat_id: chat_id }) }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } return null; }); if (error) { throw error; } const response = res?.choices[0]?.message?.content.replace(/["']/g, '') ?? null; if (response) { if (/\p{Extended_Pictographic}/u.test(response)) { return response.match(/\p{Extended_Pictographic}/gu)[0]; } } return null; }; export const generateSearchQuery = async ( token: string = '', model: string, messages: object[], prompt: string ) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/task/query/completions`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ model: model, messages: messages, prompt: prompt }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } return null; }); if (error) { throw error; } return res?.choices[0]?.message?.content.replace(/["']/g, '') ?? prompt; }; export const generateMoACompletion = async ( token: string = '', model: string, prompt: string, responses: string[] ) => { const controller = new AbortController(); let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/task/moa/completions`, { signal: controller.signal, method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ model: model, prompt: prompt, responses: responses, stream: true }) }).catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return [res, controller]; }; export const getPipelinesList = async (token: string = '') => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines/list`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } let pipelines = res?.data ?? []; return pipelines; }; export const uploadPipeline = async (token: string, file: File, urlIdx: string) => { let error = null; // Create a new FormData object to handle the file upload const formData = new FormData(); formData.append('file', file); formData.append('urlIdx', urlIdx); const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines/upload`, { method: 'POST', headers: { ...(token && { authorization: `Bearer ${token}` }) // 'Content-Type': 'multipart/form-data' is not needed as Fetch API will set it automatically }, body: formData }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } else { error = err; } return null; }); if (error) { throw error; } return res; }; export const downloadPipeline = async (token: string, url: string, urlIdx: string) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines/add`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) }, body: JSON.stringify({ url: url, urlIdx: urlIdx }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } else { error = err; } return null; }); if (error) { throw error; } return res; }; export const deletePipeline = async (token: string, id: string, urlIdx: string) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines/delete`, { method: 'DELETE', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) }, body: JSON.stringify({ id: id, urlIdx: urlIdx }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } else { error = err; } return null; }); if (error) { throw error; } return res; }; export const getPipelines = async (token: string, urlIdx?: string) => { let error = null; const searchParams = new URLSearchParams(); if (urlIdx !== undefined) { searchParams.append('urlIdx', urlIdx); } const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines?${searchParams.toString()}`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } let pipelines = res?.data ?? []; return pipelines; }; export const getPipelineValves = async (token: string, pipeline_id: string, urlIdx: string) => { let error = null; const searchParams = new URLSearchParams(); if (urlIdx !== undefined) { searchParams.append('urlIdx', urlIdx); } const res = await fetch( `${WEBUI_BASE_URL}/api/pipelines/${pipeline_id}/valves?${searchParams.toString()}`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) } } ) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; }; export const getPipelineValvesSpec = async (token: string, pipeline_id: string, urlIdx: string) => { let error = null; const searchParams = new URLSearchParams(); if (urlIdx !== undefined) { searchParams.append('urlIdx', urlIdx); } const res = await fetch( `${WEBUI_BASE_URL}/api/pipelines/${pipeline_id}/valves/spec?${searchParams.toString()}`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) } } ) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; }; export const updatePipelineValves = async ( token: string = '', pipeline_id: string, valves: object, urlIdx: string ) => { let error = null; const searchParams = new URLSearchParams(); if (urlIdx !== undefined) { searchParams.append('urlIdx', urlIdx); } const res = await fetch( `${WEBUI_BASE_URL}/api/pipelines/${pipeline_id}/valves/update?${searchParams.toString()}`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) }, body: JSON.stringify(valves) } ) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); if ('detail' in err) { error = err.detail; } else { error = err; } return null; }); if (error) { throw error; } return res; }; export const getBackendConfig = async () => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/config`, { method: 'GET', credentials: 'include', headers: { 'Content-Type': 'application/json' } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; }; export const getChangelog = async () => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/changelog`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; }; export const getVersionUpdates = async () => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/version/updates`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; }; export const getModelFilterConfig = async (token: string) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/config/model/filter`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; }; export const updateModelFilterConfig = async ( token: string, enabled: boolean, models: string[] ) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/config/model/filter`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ enabled: enabled, models: models }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; }; export const getWebhookUrl = async (token: string) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/webhook`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res.url; }; export const updateWebhookUrl = async (token: string, url: string) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/webhook`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ url: url }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res.url; }; export const getCommunitySharingEnabledStatus = async (token: string) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/community_sharing`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; }; export const toggleCommunitySharingEnabledStatus = async (token: string) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/community_sharing/toggle`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err.detail; return null; }); if (error) { throw error; } return res; }; export const getModelConfig = async (token: string): Promise => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/config/models`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` } }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res.models; }; export interface ModelConfig { id: string; name: string; meta: ModelMeta; base_model_id?: string; params: ModelParams; } export interface ModelMeta { description?: string; capabilities?: object; profile_image_url?: string; } export interface ModelParams {} export type GlobalModelConfig = ModelConfig[]; export const updateModelConfig = async (token: string, config: GlobalModelConfig) => { let error = null; const res = await fetch(`${WEBUI_BASE_URL}/api/config/models`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ models: config }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err; return null; }); if (error) { throw error; } return res; };