forked from open-webui/open-webui
feat: openai compatible api support
This commit is contained in:
parent
5e4dc98f44
commit
17c66fde0f
9 changed files with 260 additions and 85 deletions
|
@ -1,4 +1,176 @@
|
|||
export const getOpenAIModels = async (
|
||||
import { OPENAI_API_BASE_URL } from '$lib/constants';
|
||||
|
||||
export const getOpenAIUrl = async (token: string = '') => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${OPENAI_API_BASE_URL}/url`, {
|
||||
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);
|
||||
if ('detail' in err) {
|
||||
error = err.detail;
|
||||
} else {
|
||||
error = 'Server connection failed';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res.OPENAI_API_BASE_URL;
|
||||
};
|
||||
|
||||
export const updateOpenAIUrl = async (token: string = '', url: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${OPENAI_API_BASE_URL}/url/update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
...(token && { 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);
|
||||
if ('detail' in err) {
|
||||
error = err.detail;
|
||||
} else {
|
||||
error = 'Server connection failed';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res.OPENAI_API_BASE_URL;
|
||||
};
|
||||
|
||||
export const getOpenAIKey = async (token: string = '') => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${OPENAI_API_BASE_URL}/key`, {
|
||||
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);
|
||||
if ('detail' in err) {
|
||||
error = err.detail;
|
||||
} else {
|
||||
error = 'Server connection failed';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res.OPENAI_API_KEY;
|
||||
};
|
||||
|
||||
export const updateOpenAIKey = async (token: string = '', key: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${OPENAI_API_BASE_URL}/key/update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
...(token && { authorization: `Bearer ${token}` })
|
||||
},
|
||||
body: JSON.stringify({
|
||||
key: key
|
||||
})
|
||||
})
|
||||
.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 = 'Server connection failed';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res.OPENAI_API_KEY;
|
||||
};
|
||||
|
||||
export const getOpenAIModels = async (token: string = '') => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${OPENAI_API_BASE_URL}/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 = `OpenAI: ${err?.error?.message ?? 'Network Problem'}`;
|
||||
return [];
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const models = Array.isArray(res) ? res : res?.data ?? null;
|
||||
|
||||
return models
|
||||
? models
|
||||
.map((model) => ({ name: model.id, external: true }))
|
||||
.sort((a, b) => {
|
||||
return a.name.localeCompare(b.name);
|
||||
})
|
||||
: models;
|
||||
};
|
||||
|
||||
export const getOpenAIModelsDirect = async (
|
||||
base_url: string = 'https://api.openai.com/v1',
|
||||
api_key: string = ''
|
||||
) => {
|
||||
|
|
|
@ -24,6 +24,13 @@
|
|||
import { updateUserPassword } from '$lib/apis/auths';
|
||||
import { goto } from '$app/navigation';
|
||||
import Page from '../../../routes/(app)/+page.svelte';
|
||||
import {
|
||||
getOpenAIKey,
|
||||
getOpenAIModels,
|
||||
getOpenAIUrl,
|
||||
updateOpenAIKey,
|
||||
updateOpenAIUrl
|
||||
} from '$lib/apis/openai';
|
||||
|
||||
export let show = false;
|
||||
|
||||
|
@ -153,6 +160,13 @@
|
|||
}
|
||||
};
|
||||
|
||||
const updateOpenAIHandler = async () => {
|
||||
OPENAI_API_BASE_URL = await updateOpenAIUrl(localStorage.token, OPENAI_API_BASE_URL);
|
||||
OPENAI_API_KEY = await updateOpenAIKey(localStorage.token, OPENAI_API_KEY);
|
||||
|
||||
await models.set(await getModels());
|
||||
};
|
||||
|
||||
const toggleTheme = async () => {
|
||||
if (theme === 'dark') {
|
||||
theme = 'light';
|
||||
|
@ -484,7 +498,7 @@
|
|||
};
|
||||
|
||||
const getModels = async (type = 'all') => {
|
||||
let models = [];
|
||||
const models = [];
|
||||
models.push(
|
||||
...(await getOllamaModels(localStorage.token).catch((error) => {
|
||||
toast.error(error);
|
||||
|
@ -493,43 +507,13 @@
|
|||
);
|
||||
|
||||
// If OpenAI API Key exists
|
||||
if (type === 'all' && $settings.OPENAI_API_KEY) {
|
||||
const OPENAI_API_BASE_URL = $settings.OPENAI_API_BASE_URL ?? 'https://api.openai.com/v1';
|
||||
if (type === 'all' && OPENAI_API_KEY) {
|
||||
const openAIModels = await getOpenAIModels(localStorage.token).catch((error) => {
|
||||
console.log(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
// Validate OPENAI_API_KEY
|
||||
const openaiModelRes = await fetch(`${OPENAI_API_BASE_URL}/models`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${$settings.OPENAI_API_KEY}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
toast.error(`OpenAI: ${error?.error?.message ?? 'Network Problem'}`);
|
||||
return null;
|
||||
});
|
||||
|
||||
const openAIModels = Array.isArray(openaiModelRes)
|
||||
? openaiModelRes
|
||||
: openaiModelRes?.data ?? null;
|
||||
|
||||
models.push(
|
||||
...(openAIModels
|
||||
? [
|
||||
{ name: 'hr' },
|
||||
...openAIModels
|
||||
.map((model) => ({ name: model.id, external: true }))
|
||||
.filter((model) =>
|
||||
OPENAI_API_BASE_URL.includes('openai') ? model.name.includes('gpt') : true
|
||||
)
|
||||
]
|
||||
: [])
|
||||
);
|
||||
models.push(...(openAIModels ? [{ name: 'hr' }, ...openAIModels] : []));
|
||||
}
|
||||
|
||||
return models;
|
||||
|
@ -564,6 +548,8 @@
|
|||
console.log('settings', $user.role === 'admin');
|
||||
if ($user.role === 'admin') {
|
||||
API_BASE_URL = await getOllamaAPIUrl(localStorage.token);
|
||||
OPENAI_API_BASE_URL = await getOpenAIUrl(localStorage.token);
|
||||
OPENAI_API_KEY = await getOpenAIKey(localStorage.token);
|
||||
}
|
||||
|
||||
let settings = JSON.parse(localStorage.getItem('settings') ?? '{}');
|
||||
|
@ -584,9 +570,6 @@
|
|||
options = { ...options, ...settings.options };
|
||||
options.stop = (settings?.options?.stop ?? []).join(',');
|
||||
|
||||
OPENAI_API_KEY = settings.OPENAI_API_KEY ?? '';
|
||||
OPENAI_API_BASE_URL = settings.OPENAI_API_BASE_URL ?? 'https://api.openai.com/v1';
|
||||
|
||||
titleAutoGenerate = settings.titleAutoGenerate ?? true;
|
||||
speechAutoSend = settings.speechAutoSend ?? false;
|
||||
responseAutoCopy = settings.responseAutoCopy ?? false;
|
||||
|
@ -1415,10 +1398,12 @@
|
|||
<form
|
||||
class="flex flex-col h-full justify-between space-y-3 text-sm"
|
||||
on:submit|preventDefault={() => {
|
||||
saveSettings({
|
||||
OPENAI_API_KEY: OPENAI_API_KEY !== '' ? OPENAI_API_KEY : undefined,
|
||||
OPENAI_API_BASE_URL: OPENAI_API_BASE_URL !== '' ? OPENAI_API_BASE_URL : undefined
|
||||
});
|
||||
updateOpenAIHandler();
|
||||
|
||||
// saveSettings({
|
||||
// OPENAI_API_KEY: OPENAI_API_KEY !== '' ? OPENAI_API_KEY : undefined,
|
||||
// OPENAI_API_BASE_URL: OPENAI_API_BASE_URL !== '' ? OPENAI_API_BASE_URL : undefined
|
||||
// });
|
||||
show = false;
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { dev } from '$app/environment';
|
||||
|
||||
export const OLLAMA_API_BASE_URL = dev
|
||||
? `http://${location.hostname}:8080/ollama/api`
|
||||
: '/ollama/api';
|
||||
|
||||
export const WEBUI_BASE_URL = dev ? `http://${location.hostname}:8080` : ``;
|
||||
|
||||
export const WEBUI_API_BASE_URL = `${WEBUI_BASE_URL}/api/v1`;
|
||||
export const OLLAMA_API_BASE_URL = `${WEBUI_BASE_URL}/ollama/api`;
|
||||
export const OPENAI_API_BASE_URL = `${WEBUI_BASE_URL}/openai/api`;
|
||||
|
||||
export const WEB_UI_VERSION = 'v1.0.0-alpha-static';
|
||||
|
||||
|
|
|
@ -37,19 +37,17 @@
|
|||
return [];
|
||||
}))
|
||||
);
|
||||
// If OpenAI API Key exists
|
||||
if ($settings.OPENAI_API_KEY) {
|
||||
const openAIModels = await getOpenAIModels(
|
||||
$settings.OPENAI_API_BASE_URL ?? 'https://api.openai.com/v1',
|
||||
$settings.OPENAI_API_KEY
|
||||
).catch((error) => {
|
||||
console.log(error);
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
models.push(...(openAIModels ? [{ name: 'hr' }, ...openAIModels] : []));
|
||||
}
|
||||
// $settings.OPENAI_API_BASE_URL ?? 'https://api.openai.com/v1',
|
||||
// $settings.OPENAI_API_KEY
|
||||
|
||||
const openAIModels = await getOpenAIModels(localStorage.token).catch((error) => {
|
||||
console.log(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
models.push(...(openAIModels ? [{ name: 'hr' }, ...openAIModels] : []));
|
||||
|
||||
return models;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue