| import { WEBUI_BASE_URL } from '$lib/constants'; |
| import { convertOpenApiToToolPayload } from '$lib/utils'; |
| import { getOpenAIModelsDirect } from './openai'; |
|
|
| export const getModels = async ( |
| token: string = '', |
| connections: object | null = null, |
| base: boolean = false, |
| refresh: boolean = false |
| ) => { |
| const searchParams = new URLSearchParams(); |
| if (refresh) { |
| searchParams.append('refresh', 'true'); |
| } |
|
|
| let error = null; |
| const res = await fetch( |
| `${WEBUI_BASE_URL}/api/models${base ? '/base' : ''}?${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) => { |
| error = err; |
| console.error(err); |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| let models = res?.data ?? []; |
|
|
| if (connections && !base) { |
| let localModels = []; |
|
|
| if (connections) { |
| const OPENAI_API_BASE_URLS = connections.OPENAI_API_BASE_URLS; |
| const OPENAI_API_KEYS = connections.OPENAI_API_KEYS; |
| const OPENAI_API_CONFIGS = connections.OPENAI_API_CONFIGS; |
|
|
| const requests = []; |
| for (const idx in OPENAI_API_BASE_URLS) { |
| const url = OPENAI_API_BASE_URLS[idx]; |
|
|
| if (idx.toString() in OPENAI_API_CONFIGS) { |
| const apiConfig = OPENAI_API_CONFIGS[idx.toString()] ?? {}; |
|
|
| const enable = apiConfig?.enable ?? true; |
| const modelIds = apiConfig?.model_ids ?? []; |
|
|
| if (enable) { |
| if (modelIds.length > 0) { |
| const modelList = { |
| object: 'list', |
| data: modelIds.map((modelId) => ({ |
| id: modelId, |
| name: modelId, |
| owned_by: 'openai', |
| openai: { id: modelId }, |
| urlIdx: idx |
| })) |
| }; |
|
|
| requests.push( |
| (async () => { |
| return modelList; |
| })() |
| ); |
| } else { |
| requests.push( |
| (async () => { |
| return await getOpenAIModelsDirect(url, OPENAI_API_KEYS[idx]) |
| .then((res) => { |
| return res; |
| }) |
| .catch((err) => { |
| return { |
| object: 'list', |
| data: [], |
| urlIdx: idx |
| }; |
| }); |
| })() |
| ); |
| } |
| } else { |
| requests.push( |
| (async () => { |
| return { |
| object: 'list', |
| data: [], |
| urlIdx: idx |
| }; |
| })() |
| ); |
| } |
| } |
| } |
|
|
| const responses = await Promise.all(requests); |
|
|
| for (const idx in responses) { |
| const response = responses[idx]; |
| const apiConfig = OPENAI_API_CONFIGS[idx.toString()] ?? {}; |
|
|
| let models = Array.isArray(response) ? response : (response?.data ?? []); |
| models = models.map((model) => ({ ...model, openai: { id: model.id }, urlIdx: idx })); |
|
|
| const prefixId = apiConfig.prefix_id; |
| if (prefixId) { |
| for (const model of models) { |
| model.id = `${prefixId}.${model.id}`; |
| } |
| } |
|
|
| const tags = apiConfig.tags; |
| if (tags) { |
| for (const model of models) { |
| model.tags = tags; |
| } |
| } |
|
|
| localModels = localModels.concat(models); |
| } |
| } |
|
|
| models = models.concat( |
| localModels.map((model) => ({ |
| ...model, |
| name: model?.name ?? model?.id, |
| direct: true |
| })) |
| ); |
|
|
| |
| const modelsMap = {}; |
| for (const model of models) { |
| modelsMap[model.id] = model; |
| } |
|
|
| models = Object.values(modelsMap); |
| } |
|
|
| 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.error(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.error(err); |
| if ('detail' in err) { |
| error = err.detail; |
| } else { |
| error = err; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| return res; |
| }; |
|
|
| export const stopTask = async (token: string, id: string) => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/tasks/stop/${id}`, { |
| method: 'POST', |
| 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.error(err); |
| if ('detail' in err) { |
| error = err.detail; |
| } else { |
| error = err; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| return res; |
| }; |
|
|
| export const getTaskIdsByChatId = async (token: string, chat_id: string) => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/tasks/chat/${chat_id}`, { |
| 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.error(err); |
| if ('detail' in err) { |
| error = err.detail; |
| } else { |
| error = err; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| return res; |
| }; |
|
|
| export const getToolServerData = async (token: string, url: string) => { |
| let error = null; |
|
|
| const res = await fetch(`${url}`, { |
| method: 'GET', |
| headers: { |
| Accept: 'application/json', |
| 'Content-Type': 'application/json', |
| ...(token && { authorization: `Bearer ${token}` }) |
| } |
| }) |
| .then(async (res) => { |
| |
| if (url.toLowerCase().endsWith('.yaml') || url.toLowerCase().endsWith('.yml')) { |
| if (!res.ok) throw await res.text(); |
| const [text, { parse }] = await Promise.all([res.text(), import('yaml')]); |
| return parse(text); |
| } else { |
| if (!res.ok) throw await res.json(); |
| return res.json(); |
| } |
| }) |
| .catch((err) => { |
| console.error(err); |
| if ('detail' in err) { |
| error = err.detail; |
| } else { |
| error = err; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| console.log(res); |
| return res; |
| }; |
|
|
| export const getToolServersData = async (servers: object[]) => { |
| return ( |
| await Promise.all( |
| servers |
| .filter((server) => server?.config?.enable) |
| .map(async (server) => { |
| let error = null; |
|
|
| let toolServerToken = null; |
|
|
| const auth_type = server?.auth_type ?? 'bearer'; |
| if (auth_type === 'bearer') { |
| toolServerToken = server?.key; |
| } else if (auth_type === 'none') { |
| |
| } else if (auth_type === 'session') { |
| toolServerToken = localStorage.token; |
| } |
|
|
| let res = null; |
| const specType = server?.spec_type ?? 'url'; |
|
|
| if (specType === 'url') { |
| res = await getToolServerData( |
| toolServerToken, |
| (server?.path ?? '').includes('://') |
| ? server?.path |
| : `${server?.url}${(server?.path ?? '').startsWith('/') ? '' : '/'}${server?.path}` |
| ).catch((err) => { |
| error = err; |
| return null; |
| }); |
| } else if ((specType === 'json' && server?.spec) ?? null) { |
| try { |
| res = JSON.parse(server?.spec); |
| } catch (e) { |
| error = 'Failed to parse JSON spec'; |
| } |
| } |
|
|
| if (res) { |
| if (!res.paths) { |
| return { |
| error: 'Invalid OpenAPI spec', |
| url: server?.url |
| }; |
| } |
|
|
| const { openapi, info, specs } = { |
| openapi: res, |
| info: res.info, |
| specs: convertOpenApiToToolPayload(res) |
| }; |
|
|
| return { |
| url: server?.url, |
| openapi: openapi, |
| info: info, |
| specs: specs |
| }; |
| } else if (error) { |
| return { |
| error, |
| url: server?.url |
| }; |
| } else { |
| return null; |
| } |
| }) |
| ) |
| ).filter((server) => server); |
| }; |
|
|
| export const executeToolServer = async ( |
| token: string, |
| url: string, |
| name: string, |
| params: Record<string, any>, |
| serverData: { openapi: any; info: any; specs: any } |
| ) => { |
| let error = null; |
|
|
| try { |
| |
| const matchingRoute = Object.entries(serverData.openapi.paths).find(([_, methods]) => |
| Object.entries(methods as any).some(([__, operation]: any) => operation.operationId === name) |
| ); |
|
|
| if (!matchingRoute) { |
| throw new Error(`No matching route found for operationId: ${name}`); |
| } |
|
|
| const [routePath, methods] = matchingRoute; |
|
|
| const methodEntry = Object.entries(methods as any).find( |
| ([_, operation]: any) => operation.operationId === name |
| ); |
|
|
| if (!methodEntry) { |
| throw new Error(`No matching method found for operationId: ${name}`); |
| } |
|
|
| const [httpMethod, operation]: [string, any] = methodEntry; |
|
|
| |
| const pathParams: Record<string, any> = {}; |
| const queryParams: Record<string, any> = {}; |
| let bodyParams: any = {}; |
|
|
| if (operation.parameters) { |
| operation.parameters.forEach((param: any) => { |
| const paramName = param?.name; |
| if (!paramName) return; |
| const paramIn = param?.in; |
| if (params.hasOwnProperty(paramName)) { |
| if (paramIn === 'path') { |
| pathParams[paramName] = params[paramName]; |
| } else if (paramIn === 'query') { |
| queryParams[paramName] = params[paramName]; |
| } |
| } |
| }); |
| } |
|
|
| let finalUrl = `${url}${routePath}`; |
|
|
| |
| Object.entries(pathParams).forEach(([key, value]) => { |
| finalUrl = finalUrl.replace(new RegExp(`{${key}}`, 'g'), encodeURIComponent(value)); |
| }); |
|
|
| |
| if (Object.keys(queryParams).length > 0) { |
| const queryString = new URLSearchParams( |
| Object.entries(queryParams).map(([k, v]) => [k, String(v)]) |
| ).toString(); |
| finalUrl += `?${queryString}`; |
| } |
|
|
| |
| if (operation.requestBody && operation.requestBody.content) { |
| const contentType = Object.keys(operation.requestBody.content)[0]; |
| if (params !== undefined) { |
| bodyParams = params; |
| } else { |
| |
| throw new Error(`Request body expected for operation '${name}' but none found.`); |
| } |
| } |
|
|
| |
| const headers: Record<string, string> = { |
| 'Content-Type': 'application/json', |
| ...(token && { authorization: `Bearer ${token}` }) |
| }; |
|
|
| const requestOptions: RequestInit = { |
| method: httpMethod.toUpperCase(), |
| headers |
| }; |
|
|
| if ( |
| ['post', 'put', 'patch', 'delete'].includes(httpMethod.toLowerCase()) && |
| operation.requestBody |
| ) { |
| requestOptions.body = JSON.stringify(bodyParams); |
| } |
|
|
| const res = await fetch(finalUrl, requestOptions); |
| if (!res.ok) { |
| const resText = await res.text(); |
| throw new Error(`HTTP error! Status: ${res.status}. Message: ${resText}`); |
| } |
|
|
| |
| const responseHeaders = {}; |
| res.headers.forEach((value, key) => { |
| responseHeaders[key] = value; |
| }); |
|
|
| const text = await res.text(); |
| let responseData; |
|
|
| try { |
| responseData = JSON.parse(text); |
| } catch { |
| responseData = text; |
| } |
| return [responseData, responseHeaders]; |
| } catch (err: any) { |
| error = err.message; |
| console.error('API Request Error:', error); |
| return [{ error }, null]; |
| } |
| }; |
|
|
| export const getTaskConfig = async (token: string = '') => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/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.error(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/v1/tasks/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.error(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: object[], |
| chat_id?: string |
| ) => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/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.error(err); |
| if ('detail' in err) { |
| error = err.detail; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| try { |
| |
| const response = res?.choices[0]?.message?.content ?? ''; |
|
|
| |
| const sanitizedResponse = response.replace(/['‘’`]/g, '"'); |
|
|
| |
| const jsonStartIndex = sanitizedResponse.indexOf('{'); |
| const jsonEndIndex = sanitizedResponse.lastIndexOf('}'); |
|
|
| |
| if (jsonStartIndex !== -1 && jsonEndIndex !== -1) { |
| const jsonResponse = sanitizedResponse.substring(jsonStartIndex, jsonEndIndex + 1); |
|
|
| |
| const parsed = JSON.parse(jsonResponse); |
|
|
| |
| if (parsed && parsed.title) { |
| return parsed.title; |
| } else { |
| return null; |
| } |
| } |
|
|
| |
| return null; |
| } catch (e) { |
| |
| console.error('Failed to parse response: ', e); |
| return null; |
| } |
| }; |
|
|
| export const generateFollowUps = async ( |
| token: string = '', |
| model: string, |
| messages: string, |
| chat_id?: string |
| ) => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/follow_ups/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.error(err); |
| if ('detail' in err) { |
| error = err.detail; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| try { |
| |
| const response = res?.choices[0]?.message?.content ?? ''; |
|
|
| |
| const sanitizedResponse = response.replace(/['‘’`]/g, '"'); |
|
|
| |
| const jsonStartIndex = sanitizedResponse.indexOf('{'); |
| const jsonEndIndex = sanitizedResponse.lastIndexOf('}'); |
|
|
| |
| if (jsonStartIndex !== -1 && jsonEndIndex !== -1) { |
| const jsonResponse = sanitizedResponse.substring(jsonStartIndex, jsonEndIndex + 1); |
|
|
| |
| const parsed = JSON.parse(jsonResponse); |
|
|
| |
| if (parsed && parsed.follow_ups) { |
| return Array.isArray(parsed.follow_ups) ? parsed.follow_ups : []; |
| } else { |
| return []; |
| } |
| } |
|
|
| |
| return []; |
| } catch (e) { |
| |
| console.error('Failed to parse response: ', e); |
| return []; |
| } |
| }; |
|
|
| export const generateTags = async ( |
| token: string = '', |
| model: string, |
| messages: string, |
| chat_id?: string |
| ) => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/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.error(err); |
| if ('detail' in err) { |
| error = err.detail; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| try { |
| |
| const response = res?.choices[0]?.message?.content ?? ''; |
|
|
| |
| const sanitizedResponse = response.replace(/['‘’`]/g, '"'); |
|
|
| |
| const jsonStartIndex = sanitizedResponse.indexOf('{'); |
| const jsonEndIndex = sanitizedResponse.lastIndexOf('}'); |
|
|
| |
| if (jsonStartIndex !== -1 && jsonEndIndex !== -1) { |
| const jsonResponse = sanitizedResponse.substring(jsonStartIndex, jsonEndIndex + 1); |
|
|
| |
| const parsed = JSON.parse(jsonResponse); |
|
|
| |
| if (parsed && parsed.tags) { |
| return Array.isArray(parsed.tags) ? parsed.tags : []; |
| } else { |
| return []; |
| } |
| } |
|
|
| |
| return []; |
| } catch (e) { |
| |
| 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/v1/tasks/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.error(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 generateQueries = async ( |
| token: string = '', |
| model: string, |
| messages: object[], |
| prompt: string, |
| type: string = 'web_search', |
| chat_id?: string |
| ) => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/queries/completions`, { |
| method: 'POST', |
| headers: { |
| Accept: 'application/json', |
| 'Content-Type': 'application/json', |
| Authorization: `Bearer ${token}` |
| }, |
| body: JSON.stringify({ |
| model: model, |
| messages: messages, |
| prompt: prompt, |
| type: type, |
| ...(chat_id && { chat_id: chat_id }) |
| }) |
| }) |
| .then(async (res) => { |
| if (!res.ok) throw await res.json(); |
| return res.json(); |
| }) |
| .catch((err) => { |
| console.error(err); |
| if ('detail' in err) { |
| error = err.detail; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| |
| const response = res?.choices[0]?.message?.content ?? ''; |
|
|
| try { |
| const jsonStartIndex = response.indexOf('{'); |
| const jsonEndIndex = response.lastIndexOf('}'); |
|
|
| if (jsonStartIndex !== -1 && jsonEndIndex !== -1) { |
| const jsonResponse = response.substring(jsonStartIndex, jsonEndIndex + 1); |
|
|
| |
| const parsed = JSON.parse(jsonResponse); |
|
|
| |
| if (parsed && parsed.queries) { |
| return Array.isArray(parsed.queries) ? parsed.queries : []; |
| } else { |
| return []; |
| } |
| } |
|
|
| |
| return [response]; |
| } catch (e) { |
| |
| console.error('Failed to parse response: ', e); |
| return [response]; |
| } |
| }; |
|
|
| export const generateAutoCompletion = async ( |
| token: string = '', |
| model: string, |
| prompt: string, |
| messages?: object[], |
| type: string = 'search query', |
| chat_id?: string |
| ) => { |
| const controller = new AbortController(); |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/auto/completions`, { |
| signal: controller.signal, |
| method: 'POST', |
| headers: { |
| Accept: 'application/json', |
| 'Content-Type': 'application/json', |
| Authorization: `Bearer ${token}` |
| }, |
| body: JSON.stringify({ |
| model: model, |
| prompt: prompt, |
| ...(messages && { messages: messages }), |
| type: type, |
| stream: false, |
| ...(chat_id && { chat_id: chat_id }) |
| }) |
| }) |
| .then(async (res) => { |
| if (!res.ok) throw await res.json(); |
| return res.json(); |
| }) |
| .catch((err) => { |
| console.error(err); |
| if ('detail' in err) { |
| error = err.detail; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| const response = res?.choices[0]?.message?.content ?? ''; |
|
|
| try { |
| const jsonStartIndex = response.indexOf('{'); |
| const jsonEndIndex = response.lastIndexOf('}'); |
|
|
| if (jsonStartIndex !== -1 && jsonEndIndex !== -1) { |
| const jsonResponse = response.substring(jsonStartIndex, jsonEndIndex + 1); |
|
|
| |
| const parsed = JSON.parse(jsonResponse); |
|
|
| |
| if (parsed && parsed.text) { |
| return parsed.text; |
| } else { |
| return ''; |
| } |
| } |
|
|
| |
| return response; |
| } catch (e) { |
| |
| console.error('Failed to parse response: ', e); |
| return response; |
| } |
| }; |
|
|
| 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/v1/tasks/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.error(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/v1/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.error(err); |
| error = err; |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| const pipelines = res?.data ?? []; |
| return pipelines; |
| }; |
|
|
| export const uploadPipeline = async (token: string, file: File, urlIdx: string) => { |
| let error = null; |
|
|
| |
| const formData = new FormData(); |
| formData.append('file', file); |
| formData.append('urlIdx', urlIdx); |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/v1/pipelines/upload`, { |
| method: 'POST', |
| headers: { |
| ...(token && { authorization: `Bearer ${token}` }) |
| |
| }, |
| body: formData |
| }) |
| .then(async (res) => { |
| if (!res.ok) throw await res.json(); |
| return res.json(); |
| }) |
| .catch((err) => { |
| console.error(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/v1/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.error(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/v1/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.error(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/v1/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.error(err); |
| error = err; |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| const 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/v1/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.error(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/v1/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.error(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/v1/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.error(err); |
|
|
| if ('detail' in err) { |
| error = err.detail; |
| } else { |
| error = err; |
| } |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| return res; |
| }; |
|
|
| export const getUsage = async (token: string = '') => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/usage`, { |
| method: 'GET', |
| headers: { |
| 'Content-Type': 'application/json', |
| ...(token && { Authorization: `Bearer ${token}` }) |
| } |
| }) |
| .then(async (res) => { |
| if (!res.ok) throw await res.json(); |
| return res.json(); |
| }) |
| .catch((err) => { |
| console.error(err); |
| 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.error(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.error(err); |
| error = err; |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| return res; |
| }; |
|
|
| export const getVersion = async (token: string) => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/version`, { |
| 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.error(err); |
| error = err; |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| return res; |
| }; |
|
|
| export const getVersionUpdates = async (token: string) => { |
| let error = null; |
|
|
| const res = await fetch(`${WEBUI_BASE_URL}/api/version/updates`, { |
| 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.error(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.error(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.error(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.error(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.error(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.error(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.error(err); |
| error = err.detail; |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| return res; |
| }; |
|
|
| export const getModelConfig = async (token: string): Promise<GlobalModelConfig> => { |
| 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.error(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 { |
| toolIds: never[]; |
| 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.error(err); |
| error = err; |
| return null; |
| }); |
|
|
| if (error) { |
| throw error; |
| } |
|
|
| return res; |
| }; |
|
|