fix: create the model when a GGUF is uploaded to Ollama, in File Mode and URL Mode (#31862)

This commit is contained in:
G30 2026-10-04 22:43:06 -04:00 • committed by GitHub
parent 8c34af3033
commit 1b2ceedd61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 84 deletions

View file

@ -1632,12 +1632,29 @@ async def download_file_stream(
ssl=AIOHTTP_CLIENT_SESSION_SSL,
timeout=aiohttp.ClientTimeout(total=30),
) as blob_resp:
if blob_resp.ok:
await asyncio.to_thread(os.remove, file_path)
yield f'data: {JSONCodec.dumps({"done": done, "blob": f"sha256:{hashed}", "name": file_name})}\n\n'
else:
if not blob_resp.ok:
raise RuntimeError('Ollama: Could not create blob, Please try again.')
await asyncio.to_thread(os.remove, file_path)
model, _ext = os.path.splitext(file_name)
async with session.post(
f'{ollama_url}/api/create',
headers=ollama_headers,
cookies=ollama_cookies,
data=JSONCodec.dumps({'model': model, 'files': {file_name: f'sha256:{hashed}'}, 'stream': False}),
ssl=AIOHTTP_CLIENT_SESSION_SSL,
timeout=get_client_timeout(),
) as create_resp:
resp_text = await create_resp.text()
if not create_resp.ok:
raise RuntimeError(f'Failed to create model in Ollama. {resp_text}')
event = JSONCodec.dumps(
{'done': done, 'blob': f'sha256:{hashed}', 'name': file_name, 'model_created': model}
)
yield f'data: {event}\n\n'
@router.post('/models/download')
@router.post('/models/download/{url_idx}')
@ -1743,6 +1760,7 @@ async def upload_model(
create_payload = {
'model': model,
'files': {filename: f'sha256:{file_hash}'},
'stream': False,
}
log.info('Model Payload: %s', create_payload)
@ -1754,6 +1772,7 @@ async def upload_model(
ssl=AIOHTTP_CLIENT_SESSION_SSL,
timeout=get_client_timeout(),
) as create_resp:
resp_text = await create_resp.text()
if create_resp.ok:
log.info('API SUCCESS!')
event = JSONCodec.dumps(
@ -1761,7 +1780,6 @@ async def upload_model(
)
yield f'data: {event}\n\n'
else:
resp_text = await create_resp.text()
raise Exception(f'Failed to create model in Ollama. {resp_text}')
except Exception as exc:

View file

@ -54,13 +54,9 @@
let createModelDigest = '';
let createModelPullProgress = null;
let digest = '';
let pullProgress = null;
let modelUploadMode = 'file';
let modelInputFile: File[] | null = null;
let modelFileUrl = '';
let modelFileContent = `TEMPLATE """{{ .System }}\nUSER: {{ .Prompt }}\nASSISTANT: """\nPARAMETER num_ctx 4096\nPARAMETER stop "</s>"\nPARAMETER stop "USER:"\nPARAMETER stop "ASSISTANT:"`;
let modelFileDigest = '';
let uploadProgress = null;
@ -300,7 +296,6 @@
let uploaded = false;
let fileResponse = null;
let name = '';
if (modelUploadMode === 'file') {
const file = modelInputFile ? modelInputFile[0] : null;
@ -353,13 +348,13 @@
if (data.done) {
modelFileDigest = data.blob;
name = data.name;
uploaded = true;
}
}
}
} catch (err) {
console.error(err);
toast.error(`${err}`);
}
}
} else {
@ -368,65 +363,7 @@
}
if (uploaded) {
const res = await createModel(
localStorage.token,
`${name}:latest`,
`FROM @${modelFileDigest}\n${modelFileContent}`
);
if (res && res.ok) {
const reader = res.body
.pipeThrough(new TextDecoderStream())
.pipeThrough(splitStream('\n'))
.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
try {
let lines = value.split('\n');
for (const line of lines) {
if (line !== '') {
console.log(line);
let data = JSON.parse(line);
console.log(data);
if (data.error) {
throw data.error;
}
if (data.detail) {
throw data.detail;
}
if (data.status) {
if (
!data.digest &&
!data.status.includes('writing') &&
!data.status.includes('sha256')
) {
toast.success(data.status);
} else {
if (data.digest) {
digest = data.digest;
if (data.completed) {
pullProgress = Math.round((data.completed / data.total) * 1000) / 10;
} else {
pullProgress = 100;
}
}
}
}
}
}
} catch (err) {
console.error(err);
toast.error(`${err}`);
}
}
}
toast.success($i18n.t('Model created successfully!'));
}
modelFileUrl = '';
@ -1077,20 +1014,6 @@
{/if}
</div>
{#if (modelUploadMode === 'file' && modelInputFile && modelInputFile.length > 0) || (modelUploadMode === 'url' && modelFileUrl !== '')}
<div>
<div>
<div class=" my-2.5 text-sm font-normal">
{$i18n.t('Modelfile Content')}
</div>
<textarea
bind:value={modelFileContent}
class="{textareaClass} resize-none"
rows="6"
/>
</div>
</div>
{/if}
<div class=" mt-1 text-xs text-gray-400 dark:text-gray-500">
{$i18n.t('To access the GGUF models available for downloading,')}
<a