forked from open-webui/open-webui
feat: modelfile backend & ollama version 0.0.0 whitelisted
This commit is contained in:
parent
4221594778
commit
032d7c7440
9 changed files with 346 additions and 96 deletions
|
@ -42,6 +42,14 @@ class ModelfileForm(BaseModel):
|
||||||
modelfile: dict
|
modelfile: dict
|
||||||
|
|
||||||
|
|
||||||
|
class ModelfileTagNameForm(BaseModel):
|
||||||
|
tag_name: str
|
||||||
|
|
||||||
|
|
||||||
|
class ModelfileUpdateForm(ModelfileForm, ModelfileTagNameForm):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ModelfileResponse(BaseModel):
|
class ModelfileResponse(BaseModel):
|
||||||
tag_name: str
|
tag_name: str
|
||||||
user_id: str
|
user_id: str
|
||||||
|
@ -57,11 +65,11 @@ class ModelfilesTable:
|
||||||
def insert_new_modelfile(
|
def insert_new_modelfile(
|
||||||
self, user_id: str, form_data: ModelfileForm
|
self, user_id: str, form_data: ModelfileForm
|
||||||
) -> Optional[ModelfileModel]:
|
) -> Optional[ModelfileModel]:
|
||||||
if "title" in form_data.modelfile:
|
if "tagName" in form_data.modelfile:
|
||||||
modelfile = ModelfileModel(
|
modelfile = ModelfileModel(
|
||||||
**{
|
**{
|
||||||
"user_id": user_id,
|
"user_id": user_id,
|
||||||
"tag_name": form_data.modelfile["title"],
|
"tag_name": form_data.modelfile["tagName"],
|
||||||
"modelfile": json.dumps(form_data.modelfile),
|
"modelfile": json.dumps(form_data.modelfile),
|
||||||
"timestamp": int(time.time()),
|
"timestamp": int(time.time()),
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ from apps.web.models.users import Users
|
||||||
from apps.web.models.modelfiles import (
|
from apps.web.models.modelfiles import (
|
||||||
Modelfiles,
|
Modelfiles,
|
||||||
ModelfileForm,
|
ModelfileForm,
|
||||||
|
ModelfileTagNameForm,
|
||||||
|
ModelfileUpdateForm,
|
||||||
ModelfileResponse,
|
ModelfileResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -77,13 +79,15 @@ async def create_new_modelfile(form_data: ModelfileForm, cred=Depends(bearer_sch
|
||||||
############################
|
############################
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{tag_name}", response_model=Optional[ModelfileResponse])
|
@router.post("/", response_model=Optional[ModelfileResponse])
|
||||||
async def get_modelfile_by_tag_name(tag_name: str, cred=Depends(bearer_scheme)):
|
async def get_modelfile_by_tag_name(
|
||||||
|
form_data: ModelfileTagNameForm, cred=Depends(bearer_scheme)
|
||||||
|
):
|
||||||
token = cred.credentials
|
token = cred.credentials
|
||||||
user = Users.get_user_by_token(token)
|
user = Users.get_user_by_token(token)
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
modelfile = Modelfiles.get_modelfile_by_tag_name(tag_name)
|
modelfile = Modelfiles.get_modelfile_by_tag_name(form_data.tag_name)
|
||||||
|
|
||||||
if modelfile:
|
if modelfile:
|
||||||
return ModelfileResponse(
|
return ModelfileResponse(
|
||||||
|
@ -109,16 +113,16 @@ async def get_modelfile_by_tag_name(tag_name: str, cred=Depends(bearer_scheme)):
|
||||||
############################
|
############################
|
||||||
|
|
||||||
|
|
||||||
@router.post("/{tag_name}", response_model=Optional[ModelfileResponse])
|
@router.post("/update", response_model=Optional[ModelfileResponse])
|
||||||
async def update_modelfile_by_tag_name(
|
async def update_modelfile_by_tag_name(
|
||||||
tag_name: str, form_data: ModelfileForm, cred=Depends(bearer_scheme)
|
form_data: ModelfileUpdateForm, cred=Depends(bearer_scheme)
|
||||||
):
|
):
|
||||||
token = cred.credentials
|
token = cred.credentials
|
||||||
user = Users.get_user_by_token(token)
|
user = Users.get_user_by_token(token)
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
if user.role == "admin":
|
if user.role == "admin":
|
||||||
modelfile = Modelfiles.get_modelfile_by_tag_name(tag_name)
|
modelfile = Modelfiles.get_modelfile_by_tag_name(form_data.tag_name)
|
||||||
if modelfile:
|
if modelfile:
|
||||||
updated_modelfile = {
|
updated_modelfile = {
|
||||||
**json.loads(modelfile.modelfile),
|
**json.loads(modelfile.modelfile),
|
||||||
|
@ -126,7 +130,7 @@ async def update_modelfile_by_tag_name(
|
||||||
}
|
}
|
||||||
|
|
||||||
modelfile = Modelfiles.update_modelfile_by_tag_name(
|
modelfile = Modelfiles.update_modelfile_by_tag_name(
|
||||||
tag_name, updated_modelfile
|
form_data.tag_name, updated_modelfile
|
||||||
)
|
)
|
||||||
|
|
||||||
return ModelfileResponse(
|
return ModelfileResponse(
|
||||||
|
@ -157,14 +161,16 @@ async def update_modelfile_by_tag_name(
|
||||||
############################
|
############################
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/{tag_name}", response_model=bool)
|
@router.delete("/delete", response_model=bool)
|
||||||
async def delete_modelfile_by_tag_name(tag_name: str, cred=Depends(bearer_scheme)):
|
async def delete_modelfile_by_tag_name(
|
||||||
|
form_data: ModelfileTagNameForm, cred=Depends(bearer_scheme)
|
||||||
|
):
|
||||||
token = cred.credentials
|
token = cred.credentials
|
||||||
user = Users.get_user_by_token(token)
|
user = Users.get_user_by_token(token)
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
if user.role == "admin":
|
if user.role == "admin":
|
||||||
result = Modelfiles.delete_modelfile_by_tag_name(tag_name)
|
result = Modelfiles.delete_modelfile_by_tag_name(form_data.tag_name)
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
173
src/lib/apis/modelfiles/index.ts
Normal file
173
src/lib/apis/modelfiles/index.ts
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
import { WEBUI_API_BASE_URL } from '$lib/constants';
|
||||||
|
|
||||||
|
export const createNewModelfile = async (token: string, modelfile: object) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/modelfiles/create`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
modelfile: modelfile
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err;
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getModelfiles = async (token: string = '') => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/modelfiles/`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err;
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.map((modelfile) => modelfile.modelfile);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getModelfileByTagName = async (token: string, tagName: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/modelfiles/`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
tag_name: tagName
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.modelfile;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateModelfileByTagName = async (
|
||||||
|
token: string,
|
||||||
|
tagName: string,
|
||||||
|
modelfile: object
|
||||||
|
) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/modelfiles/update`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
tag_name: tagName,
|
||||||
|
modelfile: modelfile
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteModelfileByTagName = async (token: string, tagName: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/modelfiles/delete`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
tag_name: tagName
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
|
@ -134,3 +134,71 @@ export const generateChatCompletion = async (
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const createModel = async (
|
||||||
|
base_url: string = OLLAMA_API_BASE_URL,
|
||||||
|
token: string,
|
||||||
|
tagName: string,
|
||||||
|
content: string
|
||||||
|
) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${base_url}/create`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/event-stream',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: tagName,
|
||||||
|
modelfile: content
|
||||||
|
})
|
||||||
|
}).catch((err) => {
|
||||||
|
error = err;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteModel = async (
|
||||||
|
base_url: string = OLLAMA_API_BASE_URL,
|
||||||
|
token: string,
|
||||||
|
tagName: string
|
||||||
|
) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${base_url}/delete`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/event-stream',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: tagName
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
console.log(json);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
error = err.error;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
|
@ -102,11 +102,11 @@ export const copyToClipboard = (text) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const checkVersion = (required, current) => {
|
export const checkVersion = (required, current) => {
|
||||||
return (
|
return current === '0.0.0'
|
||||||
current.localeCompare(required, undefined, {
|
? true
|
||||||
|
: current.localeCompare(required, undefined, {
|
||||||
numeric: true,
|
numeric: true,
|
||||||
sensitivity: 'case',
|
sensitivity: 'case',
|
||||||
caseFirst: 'upper'
|
caseFirst: 'upper'
|
||||||
}) < 0
|
}) < 0;
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
const { saveAs } = fileSaver;
|
const { saveAs } = fileSaver;
|
||||||
|
|
||||||
import { getOllamaModels, getOllamaVersion } from '$lib/apis/ollama';
|
import { getOllamaModels, getOllamaVersion } from '$lib/apis/ollama';
|
||||||
|
import { getModelfiles } from '$lib/apis/modelfiles';
|
||||||
|
|
||||||
import { getOpenAIModels } from '$lib/apis/openai';
|
import { getOpenAIModels } from '$lib/apis/openai';
|
||||||
|
|
||||||
import { user, showSettings, settings, models, modelfiles } from '$lib/stores';
|
import { user, showSettings, settings, models, modelfiles } from '$lib/stores';
|
||||||
|
@ -95,11 +97,14 @@
|
||||||
|
|
||||||
console.log();
|
console.log();
|
||||||
await settings.set(JSON.parse(localStorage.getItem('settings') ?? '{}'));
|
await settings.set(JSON.parse(localStorage.getItem('settings') ?? '{}'));
|
||||||
await models.set(await getModels());
|
// await models.set(await getModels());
|
||||||
|
// JSON.parse(localStorage.getItem('modelfiles') ?? '[]')
|
||||||
|
await modelfiles.set(await getModelfiles(localStorage.token));
|
||||||
|
console.log($modelfiles);
|
||||||
|
|
||||||
await modelfiles.set(JSON.parse(localStorage.getItem('modelfiles') ?? '[]'));
|
|
||||||
modelfiles.subscribe(async () => {
|
modelfiles.subscribe(async () => {
|
||||||
// should fetch models
|
// should fetch models
|
||||||
|
await models.set(await getModels());
|
||||||
});
|
});
|
||||||
|
|
||||||
await setOllamaVersion();
|
await setOllamaVersion();
|
||||||
|
@ -176,7 +181,8 @@
|
||||||
<button
|
<button
|
||||||
class="relative z-20 flex px-5 py-2 rounded-full bg-white border border-gray-100 dark:border-none hover:bg-gray-100 transition font-medium text-sm"
|
class="relative z-20 flex px-5 py-2 rounded-full bg-white border border-gray-100 dark:border-none hover:bg-gray-100 transition font-medium text-sm"
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
await setOllamaVersion();
|
location.href = '/';
|
||||||
|
// await setOllamaVersion();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Check Again
|
Check Again
|
||||||
|
|
|
@ -4,43 +4,29 @@
|
||||||
import toast from 'svelte-french-toast';
|
import toast from 'svelte-french-toast';
|
||||||
|
|
||||||
import { OLLAMA_API_BASE_URL } from '$lib/constants';
|
import { OLLAMA_API_BASE_URL } from '$lib/constants';
|
||||||
|
import { deleteModel } from '$lib/apis/ollama';
|
||||||
|
import { deleteModelfileByTagName, getModelfiles } from '$lib/apis/modelfiles';
|
||||||
|
|
||||||
const deleteModelHandler = async (tagName) => {
|
const deleteModelHandler = async (tagName) => {
|
||||||
let success = null;
|
let success = null;
|
||||||
const res = await fetch(`${$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL}/delete`, {
|
|
||||||
method: 'DELETE',
|
success = await deleteModel(
|
||||||
headers: {
|
$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL,
|
||||||
'Content-Type': 'text/event-stream',
|
localStorage.token,
|
||||||
...($settings.authHeader && { Authorization: $settings.authHeader }),
|
tagName
|
||||||
...($user && { Authorization: `Bearer ${localStorage.token}` })
|
);
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
if (success) {
|
||||||
name: tagName
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(async (res) => {
|
|
||||||
if (!res.ok) throw await res.json();
|
|
||||||
return res.json();
|
|
||||||
})
|
|
||||||
.then((json) => {
|
|
||||||
console.log(json);
|
|
||||||
toast.success(`Deleted ${tagName}`);
|
toast.success(`Deleted ${tagName}`);
|
||||||
success = true;
|
}
|
||||||
return json;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
toast.error(err.error);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteModelfilebyTagName = async (tagName) => {
|
const deleteModelfile = async (tagName) => {
|
||||||
await deleteModelHandler(tagName);
|
await deleteModelHandler(tagName);
|
||||||
await modelfiles.set($modelfiles.filter((modelfile) => modelfile.tagName != tagName));
|
await deleteModelfileByTagName(localStorage.token, tagName);
|
||||||
localStorage.setItem('modelfiles', JSON.stringify($modelfiles));
|
await modelfiles.set(await getModelfiles(localStorage.token));
|
||||||
};
|
};
|
||||||
|
|
||||||
const shareModelfile = async (modelfile) => {
|
const shareModelfile = async (modelfile) => {
|
||||||
|
@ -167,7 +153,7 @@
|
||||||
class="self-center w-fit text-sm px-2 py-2 border dark:border-gray-600 rounded-xl"
|
class="self-center w-fit text-sm px-2 py-2 border dark:border-gray-600 rounded-xl"
|
||||||
type="button"
|
type="button"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
deleteModelfilebyTagName(modelfile.tagName);
|
deleteModelfile(modelfile.tagName);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
import Advanced from '$lib/components/chat/Settings/Advanced.svelte';
|
import Advanced from '$lib/components/chat/Settings/Advanced.svelte';
|
||||||
import { splitStream } from '$lib/utils';
|
import { splitStream } from '$lib/utils';
|
||||||
import { onMount, tick } from 'svelte';
|
import { onMount, tick } from 'svelte';
|
||||||
|
import { createModel } from '$lib/apis/ollama';
|
||||||
|
import { createNewModelfile, getModelfiles } from '$lib/apis/modelfiles';
|
||||||
|
|
||||||
let loading = false;
|
let loading = false;
|
||||||
|
|
||||||
|
@ -93,11 +95,14 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveModelfile = async (modelfile) => {
|
const saveModelfile = async (modelfile) => {
|
||||||
await modelfiles.set([
|
// await modelfiles.set([
|
||||||
...$modelfiles.filter((m) => m.tagName !== modelfile.tagName),
|
// ...$modelfiles.filter((m) => m.tagName !== modelfile.tagName),
|
||||||
modelfile
|
// modelfile
|
||||||
]);
|
// ]);
|
||||||
localStorage.setItem('modelfiles', JSON.stringify($modelfiles));
|
// localStorage.setItem('modelfiles', JSON.stringify($modelfiles));
|
||||||
|
|
||||||
|
await createNewModelfile(localStorage.token, modelfile);
|
||||||
|
await modelfiles.set(await getModelfiles(localStorage.token));
|
||||||
};
|
};
|
||||||
|
|
||||||
const submitHandler = async () => {
|
const submitHandler = async () => {
|
||||||
|
@ -128,17 +133,12 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
|
||||||
Object.keys(categories).filter((category) => categories[category]).length > 0 &&
|
Object.keys(categories).filter((category) => categories[category]).length > 0 &&
|
||||||
!$models.includes(tagName)
|
!$models.includes(tagName)
|
||||||
) {
|
) {
|
||||||
const res = await fetch(`${$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL}/create`, {
|
const res = await createModel(
|
||||||
method: 'POST',
|
$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL,
|
||||||
headers: {
|
localStorage.token,
|
||||||
'Content-Type': 'text/event-stream',
|
tagName,
|
||||||
...($user && { Authorization: `Bearer ${localStorage.token}` })
|
content
|
||||||
},
|
);
|
||||||
body: JSON.stringify({
|
|
||||||
name: tagName,
|
|
||||||
modelfile: content
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
const reader = res.body
|
const reader = res.body
|
||||||
|
|
|
@ -2,14 +2,20 @@
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { toast } from 'svelte-french-toast';
|
import { toast } from 'svelte-french-toast';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { OLLAMA_API_BASE_URL } from '$lib/constants';
|
|
||||||
import { settings, db, user, config, modelfiles } from '$lib/stores';
|
|
||||||
|
|
||||||
import Advanced from '$lib/components/chat/Settings/Advanced.svelte';
|
|
||||||
import { splitStream } from '$lib/utils';
|
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
|
|
||||||
|
import { settings, db, user, config, modelfiles } from '$lib/stores';
|
||||||
|
|
||||||
|
import { OLLAMA_API_BASE_URL } from '$lib/constants';
|
||||||
|
import { splitStream } from '$lib/utils';
|
||||||
|
|
||||||
|
import { createModel } from '$lib/apis/ollama';
|
||||||
|
import { getModelfiles, updateModelfileByTagName } from '$lib/apis/modelfiles';
|
||||||
|
|
||||||
|
import Advanced from '$lib/components/chat/Settings/Advanced.svelte';
|
||||||
|
|
||||||
let loading = false;
|
let loading = false;
|
||||||
|
|
||||||
let filesInputElement;
|
let filesInputElement;
|
||||||
|
@ -78,17 +84,20 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const saveModelfile = async (modelfile) => {
|
const updateModelfile = async (modelfile) => {
|
||||||
await modelfiles.set(
|
// await modelfiles.set(
|
||||||
$modelfiles.map((e) => {
|
// $modelfiles.map((e) => {
|
||||||
if (e.tagName === modelfile.tagName) {
|
// if (e.tagName === modelfile.tagName) {
|
||||||
return modelfile;
|
// return modelfile;
|
||||||
} else {
|
// } else {
|
||||||
return e;
|
// return e;
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
);
|
// );
|
||||||
localStorage.setItem('modelfiles', JSON.stringify($modelfiles));
|
// localStorage.setItem('modelfiles', JSON.stringify($modelfiles));
|
||||||
|
|
||||||
|
await updateModelfileByTagName(localStorage.token, modelfile.tagName, modelfile);
|
||||||
|
await modelfiles.set(await getModelfiles(localStorage.token));
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateHandler = async () => {
|
const updateHandler = async () => {
|
||||||
|
@ -106,18 +115,12 @@
|
||||||
content !== '' &&
|
content !== '' &&
|
||||||
Object.keys(categories).filter((category) => categories[category]).length > 0
|
Object.keys(categories).filter((category) => categories[category]).length > 0
|
||||||
) {
|
) {
|
||||||
const res = await fetch(`${$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL}/create`, {
|
const res = await createModel(
|
||||||
method: 'POST',
|
$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL,
|
||||||
headers: {
|
localStorage.token,
|
||||||
'Content-Type': 'text/event-stream',
|
tagName,
|
||||||
...($settings.authHeader && { Authorization: $settings.authHeader }),
|
content
|
||||||
...($user && { Authorization: `Bearer ${localStorage.token}` })
|
);
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
name: tagName,
|
|
||||||
modelfile: content
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
const reader = res.body
|
const reader = res.body
|
||||||
|
@ -178,7 +181,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
await saveModelfile({
|
await updateModelfile({
|
||||||
tagName: tagName,
|
tagName: tagName,
|
||||||
imageUrl: imageUrl,
|
imageUrl: imageUrl,
|
||||||
title: title,
|
title: title,
|
||||||
|
|
Loading…
Reference in a new issue