Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
ec6f53e2
Commit
ec6f53e2
authored
Feb 24, 2024
by
Timothy J. Baek
Browse files
feat: litellm proxy frontend integration
parent
a453be07
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
800 additions
and
337 deletions
+800
-337
backend/apps/images/main.py
backend/apps/images/main.py
+2
-0
package.json
package.json
+1
-1
src/lib/apis/litellm/index.ts
src/lib/apis/litellm/index.ts
+107
-1
src/lib/components/chat/Settings/About.svelte
src/lib/components/chat/Settings/About.svelte
+9
-7
src/lib/components/chat/Settings/Connections.svelte
src/lib/components/chat/Settings/Connections.svelte
+85
-63
src/lib/components/chat/Settings/Models.svelte
src/lib/components/chat/Settings/Models.svelte
+596
-265
No files found.
backend/apps/images/main.py
View file @
ec6f53e2
...
@@ -109,6 +109,7 @@ def get_models(user=Depends(get_current_user)):
...
@@ -109,6 +109,7 @@ def get_models(user=Depends(get_current_user)):
models
=
r
.
json
()
models
=
r
.
json
()
return
models
return
models
except
Exception
as
e
:
except
Exception
as
e
:
app
.
state
.
ENABLED
=
False
raise
HTTPException
(
status_code
=
400
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
e
))
raise
HTTPException
(
status_code
=
400
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
e
))
...
@@ -120,6 +121,7 @@ async def get_default_model(user=Depends(get_admin_user)):
...
@@ -120,6 +121,7 @@ async def get_default_model(user=Depends(get_admin_user)):
return
{
"model"
:
options
[
"sd_model_checkpoint"
]}
return
{
"model"
:
options
[
"sd_model_checkpoint"
]}
except
Exception
as
e
:
except
Exception
as
e
:
app
.
state
.
ENABLED
=
False
raise
HTTPException
(
status_code
=
400
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
e
))
raise
HTTPException
(
status_code
=
400
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
e
))
...
...
package.json
View file @
ec6f53e2
{
{
"name"
:
"open-webui"
,
"name"
:
"open-webui"
,
"version"
:
"0.1.10
2
"
,
"version"
:
"0.1.10
3
"
,
"private"
:
true
,
"private"
:
true
,
"scripts"
:
{
"scripts"
:
{
"dev"
:
"vite dev --host"
,
"dev"
:
"vite dev --host"
,
...
...
src/lib/apis/litellm/index.ts
View file @
ec6f53e2
...
@@ -17,7 +17,7 @@ export const getLiteLLMModels = async (token: string = '') => {
...
@@ -17,7 +17,7 @@ export const getLiteLLMModels = async (token: string = '') => {
})
})
.
catch
((
err
)
=>
{
.
catch
((
err
)
=>
{
console
.
log
(
err
);
console
.
log
(
err
);
error
=
`
OpenAI
:
${
err
?.
error
?.
message
??
'
Network Problem
'
}
`
;
error
=
`
LiteLLM
:
${
err
?.
error
?.
message
??
'
Network Problem
'
}
`
;
return
[];
return
[];
});
});
...
@@ -40,3 +40,109 @@ export const getLiteLLMModels = async (token: string = '') => {
...
@@ -40,3 +40,109 @@ export const getLiteLLMModels = async (token: string = '') => {
})
})
:
models
;
:
models
;
};
};
export
const
getLiteLLMModelInfo
=
async
(
token
:
string
=
''
)
=>
{
let
error
=
null
;
const
res
=
await
fetch
(
`
${
LITELLM_API_BASE_URL
}
/model/info`
,
{
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
=
`LiteLLM:
${
err
?.
error
?.
message
??
'
Network Problem
'
}
`
;
return
[];
});
if
(
error
)
{
throw
error
;
}
const
models
=
Array
.
isArray
(
res
)
?
res
:
res
?.
data
??
null
;
return
models
;
};
type
AddLiteLLMModelForm
=
{
name
:
string
;
model
:
string
;
api_base
:
string
;
api_key
:
string
;
rpm
:
string
;
};
export
const
addLiteLLMModel
=
async
(
token
:
string
=
''
,
payload
:
AddLiteLLMModelForm
)
=>
{
let
error
=
null
;
const
res
=
await
fetch
(
`
${
LITELLM_API_BASE_URL
}
/model/new`
,
{
method
:
'
POST
'
,
headers
:
{
Accept
:
'
application/json
'
,
'
Content-Type
'
:
'
application/json
'
,
...(
token
&&
{
authorization
:
`Bearer
${
token
}
`
})
},
body
:
JSON
.
stringify
({
model_name
:
payload
.
name
,
litellm_params
:
{
model
:
payload
.
model
,
...(
payload
.
api_base
===
''
?
{}
:
{
api_base
:
payload
.
api_base
}),
...(
payload
.
api_key
===
''
?
{}
:
{
api_key
:
payload
.
api_key
}),
...(
isNaN
(
parseInt
(
payload
.
rpm
))
?
{}
:
{
rpm
:
parseInt
(
payload
.
rpm
)
})
}
})
})
.
then
(
async
(
res
)
=>
{
if
(
!
res
.
ok
)
throw
await
res
.
json
();
return
res
.
json
();
})
.
catch
((
err
)
=>
{
console
.
log
(
err
);
error
=
`LiteLLM:
${
err
?.
error
?.
message
??
'
Network Problem
'
}
`
;
return
[];
});
if
(
error
)
{
throw
error
;
}
return
res
;
};
export
const
deleteLiteLLMModel
=
async
(
token
:
string
=
''
,
id
:
string
)
=>
{
let
error
=
null
;
const
res
=
await
fetch
(
`
${
LITELLM_API_BASE_URL
}
/model/delete`
,
{
method
:
'
POST
'
,
headers
:
{
Accept
:
'
application/json
'
,
'
Content-Type
'
:
'
application/json
'
,
...(
token
&&
{
authorization
:
`Bearer
${
token
}
`
})
},
body
:
JSON
.
stringify
({
id
:
id
})
})
.
then
(
async
(
res
)
=>
{
if
(
!
res
.
ok
)
throw
await
res
.
json
();
return
res
.
json
();
})
.
catch
((
err
)
=>
{
console
.
log
(
err
);
error
=
`LiteLLM:
${
err
?.
error
?.
message
??
'
Network Problem
'
}
`
;
return
[];
});
if
(
error
)
{
throw
error
;
}
return
res
;
};
src/lib/components/chat/Settings/About.svelte
View file @
ec6f53e2
...
@@ -38,16 +38,18 @@
...
@@ -38,16 +38,18 @@
</div>
</div>
</div>
</div>
<hr class=" dark:border-gray-700" />
{#if ollamaVersion}
<hr class=" dark:border-gray-700" />
<div>
<div>
<div class=" mb-2.5 text-sm font-medium">Ollama Version</div>
<div class=" mb-2.5 text-sm font-medium">Ollama Version</div>
<div class="flex w-full">
<div class="flex w-full">
<div class="flex-1 text-xs text-gray-700 dark:text-gray-200">
<div class="flex-1 text-xs text-gray-700 dark:text-gray-200">
{ollamaVersion ?? 'N/A'}
{ollamaVersion ?? 'N/A'}
</div>
</div>
</div>
</div>
</div>
</div>
{/if}
<hr class=" dark:border-gray-700" />
<hr class=" dark:border-gray-700" />
...
...
src/lib/components/chat/Settings/Connections.svelte
View file @
ec6f53e2
...
@@ -15,6 +15,9 @@
...
@@ -15,6 +15,9 @@
let OPENAI_API_KEY = '';
let OPENAI_API_KEY = '';
let OPENAI_API_BASE_URL = '';
let OPENAI_API_BASE_URL = '';
let showOpenAI = false;
let showLiteLLM = false;
const updateOpenAIHandler = async () => {
const updateOpenAIHandler = async () => {
OPENAI_API_BASE_URL = await updateOpenAIUrl(localStorage.token, OPENAI_API_BASE_URL);
OPENAI_API_BASE_URL = await updateOpenAIUrl(localStorage.token, OPENAI_API_BASE_URL);
OPENAI_API_KEY = await updateOpenAIKey(localStorage.token, OPENAI_API_KEY);
OPENAI_API_KEY = await updateOpenAIKey(localStorage.token, OPENAI_API_KEY);
...
@@ -45,7 +48,7 @@
...
@@ -45,7 +48,7 @@
</script>
</script>
<form
<form
class="flex flex-col h-full
space-y-3
text-sm"
class="flex flex-col h-full
justify-between
text-sm"
on:submit|preventDefault={() => {
on:submit|preventDefault={() => {
updateOpenAIHandler();
updateOpenAIHandler();
dispatch('save');
dispatch('save');
...
@@ -56,81 +59,100 @@
...
@@ -56,81 +59,100 @@
// });
// });
}}
}}
>
>
<div>
<div class=" pr-1.5 overflow-y-scroll max-h-[21rem] space-y-3">
<div class=" mb-2.5 text-sm font-medium">Ollama API URL</div>
<div class=" space-y-3">
<div class="flex w-full">
<div class="mt-2 space-y-2 pr-1.5">
<div class="flex-1 mr-2">
<div class="flex justify-between items-center text-sm">
<input
<div class=" font-medium">OpenAI API</div>
class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
<button
placeholder="Enter URL (e.g. http://localhost:11434/api)"
class=" text-xs font-medium text-gray-500"
bind:value={API_BASE_URL}
type="button"
/>
on:click={() => {
</div>
showOpenAI = !showOpenAI;
<button
}}>{showOpenAI ? 'Hide' : 'Show'}</button
class="px-3 bg-gray-200 hover:bg-gray-300 dark:bg-gray-600 dark:hover:bg-gray-700 rounded transition"
>
on:click={() => {
</div>
updateOllamaAPIUrlHandler();
}}
type="button"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M15.312 11.424a5.5 5.5 0 01-9.201 2.466l-.312-.311h2.433a.75.75 0 000-1.5H3.989a.75.75 0 00-.75.75v4.242a.75.75 0 001.5 0v-2.43l.31.31a7 7 0 0011.712-3.138.75.75 0 00-1.449-.39zm1.23-3.723a.75.75 0 00.219-.53V2.929a.75.75 0 00-1.5 0V5.36l-.31-.31A7 7 0 003.239 8.188a.75.75 0 101.448.389A5.5 5.5 0 0113.89 6.11l.311.31h-2.432a.75.75 0 000 1.5h4.243a.75.75 0 00.53-.219z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
{#if showOpenAI}
Trouble accessing Ollama?
<div>
<a
<div class=" mb-2.5 text-sm font-medium">API Key</div>
class=" text-gray-300 font-medium"
<div class="flex w-full">
href="https://github.com/open-webui/open-webui#troubleshooting"
<div class="flex-1">
target="_blank"
<input
>
class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
Click here for help.
placeholder="Enter OpenAI API Key"
</a>
bind:value={OPENAI_API_KEY}
autocomplete="off"
/>
</div>
</div>
</div>
<div>
<div class=" mb-2.5 text-sm font-medium">API Base URL</div>
<div class="flex w-full">
<div class="flex-1">
<input
class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
placeholder="Enter OpenAI API Base URL"
bind:value={OPENAI_API_BASE_URL}
autocomplete="off"
/>
</div>
</div>
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
WebUI will make requests to <span class=" text-gray-200"
>'{OPENAI_API_BASE_URL}/chat'</span
>
</div>
</div>
{/if}
</div>
</div>
</div>
</div>
<hr class=" dark:border-gray-700" />
<hr class=" dark:border-gray-700" />
<div class=" space-y-3">
<div>
<div>
<div class=" mb-2.5 text-sm font-medium">O
penAI
API
Key
</div>
<div class=" mb-2.5 text-sm font-medium">O
llama
API
URL
</div>
<div class="flex w-full">
<div class="flex w-full">
<div class="flex-1">
<div class="flex-1
mr-2
">
<input
<input
class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
placeholder="Enter OpenAI API Key"
placeholder="Enter URL (e.g. http://localhost:11434/api)"
bind:value={OPENAI_API_KEY}
bind:value={API_BASE_URL}
autocomplete="off"
/>
/>
</div>
</div>
<button
class="px-3 bg-gray-200 hover:bg-gray-300 dark:bg-gray-600 dark:hover:bg-gray-700 rounded transition"
on:click={() => {
updateOllamaAPIUrlHandler();
}}
type="button"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M15.312 11.424a5.5 5.5 0 01-9.201 2.466l-.312-.311h2.433a.75.75 0 000-1.5H3.989a.75.75 0 00-.75.75v4.242a.75.75 0 001.5 0v-2.43l.31.31a7 7 0 0011.712-3.138.75.75 0 00-1.449-.39zm1.23-3.723a.75.75 0 00.219-.53V2.929a.75.75 0 00-1.5 0V5.36l-.31-.31A7 7 0 003.239 8.188a.75.75 0 101.448.389A5.5 5.5 0 0113.89 6.11l.311.31h-2.432a.75.75 0 000 1.5h4.243a.75.75 0 00.53-.219z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</div>
</div>
<div>
<div class=" mb-2.5 text-sm font-medium">OpenAI API Base URL</div>
<div class="flex w-full">
<div class="flex-1">
<input
class="w-full rounded py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
placeholder="Enter OpenAI API Base URL"
bind:value={OPENAI_API_BASE_URL}
autocomplete="off"
/>
</div>
</div>
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
WebUI will make requests to <span class=" text-gray-200">'{OPENAI_API_BASE_URL}/chat'</span>
Trouble accessing Ollama?
<a
class=" text-gray-300 font-medium"
href="https://github.com/open-webui/open-webui#troubleshooting"
target="_blank"
>
Click here for help.
</a>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
src/lib/components/chat/Settings/Models.svelte
View file @
ec6f53e2
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment