Unverified Commit 437d7ff6 authored by Timothy Jaeryang Baek's avatar Timothy Jaeryang Baek Committed by GitHub
Browse files

Merge pull request #897 from open-webui/main

dev
parents 02f364bf 81eceb48
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
deleteModelfileByTagName, deleteModelfileByTagName,
getModelfiles getModelfiles
} from '$lib/apis/modelfiles'; } from '$lib/apis/modelfiles';
import { goto } from '$app/navigation';
let localModelfiles = []; let localModelfiles = [];
let importFiles; let importFiles;
...@@ -35,9 +36,9 @@ ...@@ -35,9 +36,9 @@
}; };
const shareModelfile = async (modelfile) => { const shareModelfile = async (modelfile) => {
toast.success('Redirecting you to OllamaHub'); toast.success('Redirecting you to OpenWebUI Community');
const url = 'https://ollamahub.com'; const url = 'https://openwebui.com';
const tab = await window.open(`${url}/modelfiles/create`, '_blank'); const tab = await window.open(`${url}/modelfiles/create`, '_blank');
window.addEventListener( window.addEventListener(
...@@ -68,12 +69,12 @@ ...@@ -68,12 +69,12 @@
}); });
</script> </script>
<div class="min-h-screen w-full flex justify-center dark:text-white"> <div class="min-h-screen max-h-[100dvh] w-full flex justify-center dark:text-white">
<div class=" py-2.5 flex flex-col justify-between w-full"> <div class="flex flex-col justify-between w-full overflow-y-auto">
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10"> <div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
<div class=" text-2xl font-semibold mb-6">My Modelfiles</div> <div class=" text-2xl font-semibold mb-3">My Modelfiles</div>
<a class=" flex space-x-4 cursor-pointer w-full mb-3" href="/modelfiles/create"> <a class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2" href="/modelfiles/create">
<div class=" self-center w-10"> <div class=" self-center w-10">
<div <div
class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200" class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
...@@ -99,105 +100,132 @@ ...@@ -99,105 +100,132 @@
</div> </div>
</a> </a>
{#each $modelfiles as modelfile} <hr class=" dark:border-gray-700" />
<hr class=" dark:border-gray-700 my-2.5" />
<div class=" flex space-x-4 cursor-pointer w-full mb-3"> <div class=" my-2 mb-5">
<a {#each $modelfiles as modelfile}
class=" flex flex-1 space-x-4 cursor-pointer w-full" <div
href={`/?models=${encodeURIComponent(modelfile.tagName)}`} class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
> >
<div class=" self-center w-10"> <a
<div class=" rounded-full bg-stone-700"> class=" flex flex-1 space-x-4 cursor-pointer w-full"
<img href={`/?models=${encodeURIComponent(modelfile.tagName)}`}
src={modelfile.imageUrl ?? '/user.png'} >
alt="modelfile profile" <div class=" self-center w-10">
class=" rounded-full w-full h-auto object-cover" <div class=" rounded-full bg-stone-700">
/> <img
src={modelfile.imageUrl ?? '/user.png'}
alt="modelfile profile"
class=" rounded-full w-full h-auto object-cover"
/>
</div>
</div> </div>
</div>
<div class=" flex-1 self-center"> <div class=" flex-1 self-center">
<div class=" font-bold capitalize">{modelfile.title}</div> <div class=" font-bold capitalize">{modelfile.title}</div>
<div class=" text-sm overflow-hidden text-ellipsis line-clamp-2"> <div class=" text-sm overflow-hidden text-ellipsis line-clamp-1">
{modelfile.desc} {modelfile.desc}
</div>
</div> </div>
</div>
</a>
<div class="flex flex-row space-x-1 self-center">
<a
class="self-center w-fit text-sm px-2 py-2 border dark:border-gray-600 rounded-xl"
type="button"
href={`/modelfiles/edit?tag=${encodeURIComponent(modelfile.tagName)}`}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
/>
</svg>
</a> </a>
<div class="flex flex-row space-x-1 self-center">
<a
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button"
href={`/modelfiles/edit?tag=${encodeURIComponent(modelfile.tagName)}`}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125"
/>
</svg>
</a>
<button <button
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 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button" type="button"
on:click={() => { on:click={() => {
shareModelfile(modelfile); // console.log(modelfile);
}} sessionStorage.modelfile = JSON.stringify(modelfile);
> goto('/modelfiles/create');
<!-- TODO: update to share icon --> }}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
> >
<path <svg
stroke-linecap="round" xmlns="http://www.w3.org/2000/svg"
stroke-linejoin="round" fill="none"
d="M7.217 10.907a2.25 2.25 0 100 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186l9.566-5.314m-9.566 7.5l9.566 5.314m0 0a2.25 2.25 0 103.935 2.186 2.25 2.25 0 00-3.935-2.186zm0-12.814a2.25 2.25 0 103.933-2.185 2.25 2.25 0 00-3.933 2.185z" viewBox="0 0 24 24"
/> stroke-width="1.5"
</svg> stroke="currentColor"
</button> class="w-4 h-4"
>
<button <path
class="self-center w-fit text-sm px-2 py-2 border dark:border-gray-600 rounded-xl" stroke-linecap="round"
type="button" stroke-linejoin="round"
on:click={() => { d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
deleteModelfile(modelfile.tagName); />
}} </svg>
> </button>
<svg
xmlns="http://www.w3.org/2000/svg" <button
fill="none" class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
viewBox="0 0 24 24" type="button"
stroke-width="1.5" on:click={() => {
stroke="currentColor" shareModelfile(modelfile);
class="w-4 h-4" }}
> >
<path <svg
stroke-linecap="round" xmlns="http://www.w3.org/2000/svg"
stroke-linejoin="round" fill="none"
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" viewBox="0 0 24 24"
/> stroke-width="1.5"
</svg> stroke="currentColor"
</button> class="w-4 h-4"
</div> >
</div> <path
{/each} stroke-linecap="round"
stroke-linejoin="round"
d="M7.217 10.907a2.25 2.25 0 1 0 0 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186 9.566-5.314m-9.566 7.5 9.566 5.314m0 0a2.25 2.25 0 1 0 3.935 2.186 2.25 2.25 0 0 0-3.935-2.186Zm0-12.814a2.25 2.25 0 1 0 3.933-2.185 2.25 2.25 0 0 0-3.933 2.185Z"
/>
</svg>
</button>
<hr class=" dark:border-gray-700 my-2.5" /> <button
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button"
on:click={() => {
deleteModelfile(modelfile.tagName);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
/>
</svg>
</button>
</div>
</div>
{/each}
</div>
<div class=" flex justify-between w-full mb-3"> <div class=" flex justify-end w-full mb-3">
<div class="flex space-x-1"> <div class="flex space-x-1">
<input <input
id="modelfiles-import-input" id="modelfiles-import-input"
...@@ -227,7 +255,7 @@ ...@@ -227,7 +255,7 @@
/> />
<button <button
class="self-center w-fit text-sm px-3 py-1 border dark:border-gray-600 rounded-xl flex" class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-200 transition"
on:click={async () => { on:click={async () => {
document.getElementById('modelfiles-import-input')?.click(); document.getElementById('modelfiles-import-input')?.click();
}} }}
...@@ -251,7 +279,7 @@ ...@@ -251,7 +279,7 @@
</button> </button>
<button <button
class="self-center w-fit text-sm px-3 py-1 border dark:border-gray-600 rounded-xl flex" class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-200 transition"
on:click={async () => { on:click={async () => {
saveModelfiles($modelfiles); saveModelfiles($modelfiles);
}} }}
...@@ -348,11 +376,11 @@ ...@@ -348,11 +376,11 @@
</div> </div>
<div class=" my-16"> <div class=" my-16">
<div class=" text-2xl font-semibold mb-6">Made by OllamaHub Community</div> <div class=" text-2xl font-semibold mb-3">Made by OpenWebUI Community</div>
<a <a
class=" flex space-x-4 cursor-pointer w-full mb-3" class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
href="https://ollamahub.com/" href="https://openwebui.com/"
target="_blank" target="_blank"
> >
<div class=" self-center w-10"> <div class=" self-center w-10">
...@@ -376,7 +404,7 @@ ...@@ -376,7 +404,7 @@
<div class=" self-center"> <div class=" self-center">
<div class=" font-bold">Discover a modelfile</div> <div class=" font-bold">Discover a modelfile</div>
<div class=" text-sm">Discover, download, and explore Ollama Modelfiles</div> <div class=" text-sm">Discover, download, and explore model presets</div>
</div> </div>
</a> </a>
</div> </div>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { settings, user, config, modelfiles, models } from '$lib/stores'; import { settings, user, config, modelfiles, models } from '$lib/stores';
import Advanced from '$lib/components/chat/Settings/Advanced.svelte'; import AdvancedParams from '$lib/components/chat/Settings/Advanced/AdvancedParams.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 { createModel } from '$lib/apis/ollama';
...@@ -209,12 +209,16 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); ...@@ -209,12 +209,16 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
success = false; success = false;
}; };
onMount(() => { onMount(async () => {
window.addEventListener('message', async (event) => { window.addEventListener('message', async (event) => {
if ( if (
!['https://ollamahub.com', 'https://www.ollamahub.com', 'http://localhost:5173'].includes( ![
event.origin 'https://ollamahub.com',
) 'https://www.ollamahub.com',
'https://openwebui.com',
'https://www.openwebui.com',
'http://localhost:5173'
].includes(event.origin)
) )
return; return;
const modelfile = JSON.parse(event.data); const modelfile = JSON.parse(event.data);
...@@ -249,11 +253,36 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); ...@@ -249,11 +253,36 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
if (window.opener ?? false) { if (window.opener ?? false) {
window.opener.postMessage('loaded', '*'); window.opener.postMessage('loaded', '*');
} }
if (sessionStorage.modelfile) {
const modelfile = JSON.parse(sessionStorage.modelfile);
console.log(modelfile);
imageUrl = modelfile.imageUrl;
title = modelfile.title;
await tick();
tagName = modelfile.tagName;
desc = modelfile.desc;
content = modelfile.content;
suggestions =
modelfile.suggestionPrompts.length != 0
? modelfile.suggestionPrompts
: [
{
content: ''
}
];
for (const category of modelfile.categories) {
categories[category.toLowerCase()] = true;
}
sessionStorage.removeItem('modelfile');
}
}); });
</script> </script>
<div class="min-h-screen w-full flex justify-center dark:text-white"> <div class="min-h-screen max-h-[100dvh] w-full flex justify-center dark:text-white">
<div class=" py-2.5 flex flex-col justify-between w-full"> <div class=" flex flex-col justify-between w-full overflow-y-auto">
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10"> <div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
<input <input
bind:this={filesInputElement} bind:this={filesInputElement}
...@@ -474,7 +503,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); ...@@ -474,7 +503,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
or or
<a <a
class=" text-gray-500 dark:text-gray-300 font-medium" class=" text-gray-500 dark:text-gray-300 font-medium"
href="https://ollamahub.com" href="https://openwebui.com"
target="_blank" target="_blank"
> >
Click here to check other modelfiles. Click here to check other modelfiles.
...@@ -497,7 +526,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); ...@@ -497,7 +526,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
<div class="mt-1 text-xs text-gray-400 dark:text-gray-500"> <div class="mt-1 text-xs text-gray-400 dark:text-gray-500">
To access the available model names for downloading, <a To access the available model names for downloading, <a
class=" text-gray-500 dark:text-gray-300 font-medium" class=" text-gray-500 dark:text-gray-300 font-medium"
href="https://ollama.ai/library" href="https://ollama.com/library"
target="_blank">click here.</a target="_blank">click here.</a
> >
</div> </div>
...@@ -552,7 +581,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); ...@@ -552,7 +581,7 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, '');
<div class=" text-xs font-semibold mb-2">Parameters</div> <div class=" text-xs font-semibold mb-2">Parameters</div>
<div> <div>
<Advanced bind:options /> <AdvancedParams bind:options />
</div> </div>
</div> </div>
{/if} {/if}
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
import { createModel } from '$lib/apis/ollama'; import { createModel } from '$lib/apis/ollama';
import { getModelfiles, updateModelfileByTagName } from '$lib/apis/modelfiles'; import { getModelfiles, updateModelfileByTagName } from '$lib/apis/modelfiles';
import Advanced from '$lib/components/chat/Settings/Advanced.svelte'; import AdvancedParams from '$lib/components/chat/Settings/Advanced/AdvancedParams.svelte';
let loading = false; let loading = false;
...@@ -180,8 +180,8 @@ ...@@ -180,8 +180,8 @@
}; };
</script> </script>
<div class="min-h-screen w-full flex justify-center dark:text-white"> <div class="min-h-screen max-h-[100dvh] w-full flex justify-center dark:text-white">
<div class=" py-2.5 flex flex-col justify-between w-full"> <div class="flex flex-col justify-between w-full overflow-y-auto">
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10"> <div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
<input <input
bind:this={filesInputElement} bind:this={filesInputElement}
......
...@@ -7,14 +7,15 @@ ...@@ -7,14 +7,15 @@
import { prompts } from '$lib/stores'; import { prompts } from '$lib/stores';
import { createNewPrompt, deletePromptByCommand, getPrompts } from '$lib/apis/prompts'; import { createNewPrompt, deletePromptByCommand, getPrompts } from '$lib/apis/prompts';
import { error } from '@sveltejs/kit'; import { error } from '@sveltejs/kit';
import { goto } from '$app/navigation';
let importFiles = ''; let importFiles = '';
let query = ''; let query = '';
const sharePrompt = async (prompt) => { const sharePrompt = async (prompt) => {
toast.success('Redirecting you to OllamaHub'); toast.success('Redirecting you to OpenWebUI Community');
const url = 'https://ollamahub.com'; const url = 'https://openwebui.com';
const tab = await window.open(`${url}/prompts/create`, '_blank'); const tab = await window.open(`${url}/prompts/create`, '_blank');
window.addEventListener( window.addEventListener(
...@@ -35,8 +36,8 @@ ...@@ -35,8 +36,8 @@
}; };
</script> </script>
<div class="min-h-screen w-full flex justify-center dark:text-white"> <div class="min-h-screen max-h-[100dvh] w-full flex justify-center dark:text-white">
<div class=" py-2.5 flex flex-col justify-between w-full"> <div class="flex flex-col justify-between w-full overflow-y-auto">
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10"> <div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
<div class="mb-6 flex justify-between items-center"> <div class="mb-6 flex justify-between items-center">
<div class=" text-2xl font-semibold self-center">My Prompts</div> <div class=" text-2xl font-semibold self-center">My Prompts</div>
...@@ -67,7 +68,7 @@ ...@@ -67,7 +68,7 @@
<div> <div>
<a <a
class=" px-2 py-2 rounded-xl border border-gray-200 dark:border-gray-600 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 transition font-medium text-sm flex items-center space-x-1" class=" px-2 py-2 rounded-xl border border-gray-200 dark:border-gray-600 dark:border-0 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 transition font-medium text-sm flex items-center space-x-1"
href="/prompts/create" href="/prompts/create"
> >
<svg <svg
...@@ -83,13 +84,13 @@ ...@@ -83,13 +84,13 @@
</a> </a>
</div> </div>
</div> </div>
<hr class=" dark:border-gray-700 my-2.5" />
{#if $prompts.length === 0} <div class="my-3 mb-5">
<div />
{:else}
{#each $prompts.filter((p) => query === '' || p.command.includes(query)) as prompt} {#each $prompts.filter((p) => query === '' || p.command.includes(query)) as prompt}
<hr class=" dark:border-gray-700 my-2.5" /> <div
<div class=" flex space-x-4 cursor-pointer w-full mb-3"> class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
>
<div class=" flex flex-1 space-x-4 cursor-pointer w-full"> <div class=" flex flex-1 space-x-4 cursor-pointer w-full">
<a href={`/prompts/edit?command=${encodeURIComponent(prompt.command)}`}> <a href={`/prompts/edit?command=${encodeURIComponent(prompt.command)}`}>
<div class=" flex-1 self-center pl-5"> <div class=" flex-1 self-center pl-5">
...@@ -102,7 +103,7 @@ ...@@ -102,7 +103,7 @@
</div> </div>
<div class="flex flex-row space-x-1 self-center"> <div class="flex flex-row space-x-1 self-center">
<a <a
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 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button" type="button"
href={`/prompts/edit?command=${encodeURIComponent(prompt.command)}`} href={`/prompts/edit?command=${encodeURIComponent(prompt.command)}`}
> >
...@@ -123,7 +124,32 @@ ...@@ -123,7 +124,32 @@
</a> </a>
<button <button
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 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button"
on:click={() => {
// console.log(modelfile);
sessionStorage.prompt = JSON.stringify(prompt);
goto('/prompts/create');
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
/>
</svg>
</button>
<button
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button" type="button"
on:click={() => { on:click={() => {
sharePrompt(prompt); sharePrompt(prompt);
...@@ -146,7 +172,7 @@ ...@@ -146,7 +172,7 @@
</button> </button>
<button <button
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 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button" type="button"
on:click={() => { on:click={() => {
deletePrompt(prompt.command); deletePrompt(prompt.command);
...@@ -170,11 +196,9 @@ ...@@ -170,11 +196,9 @@
</div> </div>
</div> </div>
{/each} {/each}
{/if} </div>
<hr class=" dark:border-gray-700 my-2.5" />
<div class=" flex justify-between w-full mb-3"> <div class=" flex justify-end w-full mb-3">
<div class="flex space-x-2"> <div class="flex space-x-2">
<input <input
id="prompts-import-input" id="prompts-import-input"
...@@ -210,7 +234,7 @@ ...@@ -210,7 +234,7 @@
/> />
<button <button
class="self-center w-fit text-sm px-3 py-1 border dark:border-gray-600 rounded-xl flex" class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-200 transition"
on:click={async () => { on:click={async () => {
document.getElementById('prompts-import-input')?.click(); document.getElementById('prompts-import-input')?.click();
}} }}
...@@ -234,7 +258,7 @@ ...@@ -234,7 +258,7 @@
</button> </button>
<button <button
class="self-center w-fit text-sm px-3 py-1 border dark:border-gray-600 rounded-xl flex" class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-200 transition"
on:click={async () => { on:click={async () => {
// document.getElementById('modelfiles-import-input')?.click(); // document.getElementById('modelfiles-import-input')?.click();
let blob = new Blob([JSON.stringify($prompts)], { let blob = new Blob([JSON.stringify($prompts)], {
...@@ -272,11 +296,11 @@ ...@@ -272,11 +296,11 @@
</div> </div>
<div class=" my-16"> <div class=" my-16">
<div class=" text-2xl font-semibold mb-6">Made by OllamaHub Community</div> <div class=" text-2xl font-semibold mb-3">Made by OpenWebUI Community</div>
<a <a
class=" flex space-x-4 cursor-pointer w-full mb-3" class=" flex space-x-4 cursor-pointer w-full mb-3 px-3 py-2"
href="https://ollamahub.com/?type=prompts" href="https://openwebui.com/?type=prompts"
target="_blank" target="_blank"
> >
<div class=" self-center w-10"> <div class=" self-center w-10">
...@@ -300,7 +324,7 @@ ...@@ -300,7 +324,7 @@
<div class=" self-center"> <div class=" self-center">
<div class=" font-bold">Discover a prompt</div> <div class=" font-bold">Discover a prompt</div>
<div class=" text-sm">Discover, download, and explore custom Prompts</div> <div class=" text-sm">Discover, download, and explore custom prompts</div>
</div> </div>
</a> </a>
</div> </div>
......
...@@ -50,12 +50,16 @@ ...@@ -50,12 +50,16 @@
return regex.test(inputString); return regex.test(inputString);
}; };
onMount(() => { onMount(async () => {
window.addEventListener('message', async (event) => { window.addEventListener('message', async (event) => {
if ( if (
!['https://ollamahub.com', 'https://www.ollamahub.com', 'http://localhost:5173'].includes( ![
event.origin 'https://ollamahub.com',
) 'https://www.ollamahub.com',
'https://openwebui.com',
'https://www.openwebui.com',
'http://localhost:5173'
].includes(event.origin)
) )
return; return;
const prompt = JSON.parse(event.data); const prompt = JSON.parse(event.data);
...@@ -70,11 +74,23 @@ ...@@ -70,11 +74,23 @@
if (window.opener ?? false) { if (window.opener ?? false) {
window.opener.postMessage('loaded', '*'); window.opener.postMessage('loaded', '*');
} }
if (sessionStorage.prompt) {
const prompt = JSON.parse(sessionStorage.prompt);
console.log(prompt);
title = prompt.title;
await tick();
content = prompt.content;
command = prompt.command.at(0) === '/' ? prompt.command.slice(1) : prompt.command;
sessionStorage.removeItem('prompt');
}
}); });
</script> </script>
<div class="min-h-screen w-full flex justify-center dark:text-white"> <div class="min-h-screen max-h-[100dvh] w-full flex justify-center dark:text-white">
<div class=" py-2.5 flex flex-col justify-between w-full"> <div class=" flex flex-col justify-between w-full overflow-y-auto">
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10"> <div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
<div class=" text-2xl font-semibold mb-6">My Prompts</div> <div class=" text-2xl font-semibold mb-6">My Prompts</div>
...@@ -167,12 +183,18 @@ ...@@ -167,12 +183,18 @@
</div> </div>
<div class="text-xs text-gray-400 dark:text-gray-500"> <div class="text-xs text-gray-400 dark:text-gray-500">
Format your variables using square brackets like this: <span Format your variables using square brackets like this: <span
class=" text-gray-600 dark:text-gray-300 font-medium">[variable]</span class=" text-gray-600 dark:text-gray-300 font-medium">[variable]</span
> >
. Make sure to enclose them with . Make sure to enclose them with
<span class=" text-gray-600 dark:text-gray-300 font-medium">'['</span> <span class=" text-gray-600 dark:text-gray-300 font-medium">'['</span>
and <span class=" text-gray-600 dark:text-gray-300 font-medium">']'</span> . and <span class=" text-gray-600 dark:text-gray-300 font-medium">']'</span>.
</div>
<div class="text-xs text-gray-400 dark:text-gray-500">
Utilize <span class=" text-gray-600 dark:text-gray-300 font-medium"
>{`{{CLIPBOARD}}`}</span
> variable to have them replaced with clipboard content.
</div> </div>
</div> </div>
</div> </div>
......
...@@ -71,8 +71,8 @@ ...@@ -71,8 +71,8 @@
}); });
</script> </script>
<div class="min-h-screen w-full flex justify-center dark:text-white"> <div class="min-h-screen max-h-[100dvh] w-full flex justify-center dark:text-white">
<div class=" py-2.5 flex flex-col justify-between w-full"> <div class="flex flex-col justify-between w-full overflow-y-auto">
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10"> <div class="max-w-2xl mx-auto w-full px-3 md:px-0 my-10">
<div class=" text-2xl font-semibold mb-6">My Prompts</div> <div class=" text-2xl font-semibold mb-6">My Prompts</div>
......
<script> <script>
import { onMount, tick } from 'svelte'; import { onMount, tick } from 'svelte';
import { config, user, theme } from '$lib/stores'; import { config, user, theme, WEBUI_NAME } from '$lib/stores';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import toast, { Toaster } from 'svelte-french-toast'; import toast, { Toaster } from 'svelte-french-toast';
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
import '../app.css'; import '../app.css';
import '../tailwind.css'; import '../tailwind.css';
import 'tippy.js/dist/tippy.css'; import 'tippy.js/dist/tippy.css';
import { WEBUI_BASE_URL } from '$lib/constants';
let loaded = false; let loaded = false;
...@@ -21,6 +22,8 @@ ...@@ -21,6 +22,8 @@
if (backendConfig) { if (backendConfig) {
// Save Backend Status to Store // Save Backend Status to Store
await config.set(backendConfig); await config.set(backendConfig);
await WEBUI_NAME.set(backendConfig.name);
console.log(backendConfig); console.log(backendConfig);
if ($config) { if ($config) {
...@@ -54,7 +57,8 @@ ...@@ -54,7 +57,8 @@
</script> </script>
<svelte:head> <svelte:head>
<title>Ollama</title> <title>{$WEBUI_NAME}</title>
<link rel="icon" href="{WEBUI_BASE_URL}/static/favicon.png" />
<link rel="stylesheet" type="text/css" href="/themes/rosepine.css" /> <link rel="stylesheet" type="text/css" href="/themes/rosepine.css" />
<link rel="stylesheet" type="text/css" href="/themes/rosepine-dawn.css" /> <link rel="stylesheet" type="text/css" href="/themes/rosepine-dawn.css" />
......
<script> <script>
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { userSignIn, userSignUp } from '$lib/apis/auths'; import { userSignIn, userSignUp } from '$lib/apis/auths';
import { WEBUI_API_BASE_URL } from '$lib/constants'; import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
import { config, user } from '$lib/stores'; import { WEBUI_NAME, config, user } from '$lib/stores';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import toast from 'svelte-french-toast'; import toast from 'svelte-french-toast';
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
<div class="fixed m-10 z-50"> <div class="fixed m-10 z-50">
<div class="flex space-x-2"> <div class="flex space-x-2">
<div class=" self-center"> <div class=" self-center">
<img src="/ollama.png" class=" w-8" /> <img src="{WEBUI_BASE_URL}/static/favicon.png" class=" w-8 rounded-full" alt="logo" />
</div> </div>
</div> </div>
</div> </div>
...@@ -90,9 +90,16 @@ ...@@ -90,9 +90,16 @@
}} }}
> >
<div class=" text-xl md:text-2xl font-bold"> <div class=" text-xl md:text-2xl font-bold">
{mode === 'signin' ? 'Sign in' : 'Sign up'} to Ollama Web UI {mode === 'signin' ? 'Sign in' : 'Sign up'} to {$WEBUI_NAME}
</div> </div>
{#if mode === 'signup'}
<div class=" mt-1 text-xs font-medium text-gray-500">
ⓘ {$WEBUI_NAME} does not make any external connections, and your data stays securely on
your locally hosted server.
</div>
{/if}
<div class="flex flex-col mt-4"> <div class="flex flex-col mt-4">
{#if mode === 'signup'} {#if mode === 'signup'}
<div> <div>
......
<script> <script>
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { config } from '$lib/stores'; import { WEBUI_NAME, config } from '$lib/stores';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
let loaded = false; let loaded = false;
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<div class="absolute rounded-xl w-full h-full backdrop-blur flex justify-center"> <div class="absolute rounded-xl w-full h-full backdrop-blur flex justify-center">
<div class="m-auto pb-44 flex flex-col justify-center"> <div class="m-auto pb-44 flex flex-col justify-center">
<div class="max-w-md"> <div class="max-w-md">
<div class="text-center text-2xl font-medium z-50">Ollama WebUI Backend Required</div> <div class="text-center text-2xl font-medium z-50">{$WEBUI_NAME} Backend Required</div>
<div class=" mt-4 text-center text-sm w-full"> <div class=" mt-4 text-center text-sm w-full">
Oops! You're using an unsupported method (frontend only). Please serve the WebUI from Oops! You're using an unsupported method (frontend only). Please serve the WebUI from
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
<br class=" " /> <br class=" " />
<a <a
class=" font-semibold underline" class=" font-semibold underline"
href="https://github.com/ollama-webui/ollama-webui#how-to-install-" href="https://github.com/open-webui/open-webui#how-to-install-"
target="_blank">See readme.md for instructions</a target="_blank">See readme.md for instructions</a
> >
or or
......
static/favicon.png

90.2 KB | W: | H:

static/favicon.png

6.02 KB | W: | H:

static/favicon.png
static/favicon.png
static/favicon.png
static/favicon.png
  • 2-up
  • Swipe
  • Onion skin
{ {
"name": "Ollama Web UI", "name": "Open WebUI",
"short_name": "Ollama", "short_name": "Open WebUI",
"start_url": "/", "start_url": "/",
"display": "standalone", "display": "standalone",
"background_color": "#343541", "background_color": "#343541",
...@@ -13,4 +13,4 @@ ...@@ -13,4 +13,4 @@
"sizes": "844x884" "sizes": "844x884"
} }
] ]
} }
\ No newline at end of file
...@@ -6,17 +6,19 @@ export default { ...@@ -6,17 +6,19 @@ export default {
extend: { extend: {
colors: { colors: {
gray: { gray: {
50: '#f7f7f8', 50: '#f9f9f9',
100: '#ececf1', 100: '#ececec',
200: '#d9d9e3', 200: '#e3e3e3',
300: '#c5c5d2', 300: '#cdcdcd',
400: '#acacbe', 400: '#b4b4b4',
500: '#8e8ea0', 500: '#9b9b9b',
600: '#565869', 600: '#676767',
700: '#40414f', 700: '#4e4e4e',
800: '#343541', 800: '#333',
900: '#202123', 850: '#262626',
950: '#050509'
900: '#171717',
950: '#0d0d0d'
} }
}, },
typography: { typography: {
......
...@@ -2,5 +2,8 @@ import { sveltekit } from '@sveltejs/kit/vite'; ...@@ -2,5 +2,8 @@ import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
export default defineConfig({ export default defineConfig({
plugins: [sveltekit()] plugins: [sveltekit()],
define: {
APP_VERSION: JSON.stringify(process.env.npm_package_version)
}
}); });
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment