feat: model update
This commit is contained in:
1 parent
0a48114bd2
commit
708d755eda
8 files changed
+396
-407
No files matched your search
@@ -5,181 +5,83 @@
|
||||
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
import { settings, user, config, modelfiles } from '$lib/stores';
|
||||
import { settings, user, config, models } from '$lib/stores';
|
||||
import { splitStream } from '$lib/utils';
|
||||
|
||||
import { createModel } from '$lib/apis/ollama';
|
||||
import { getModelInfos, updateModelById } from '$lib/apis/models';
|
||||
|
||||
import AdvancedParams from '$lib/components/chat/Settings/Advanced/AdvancedParams.svelte';
|
||||
import { getModels } from '$lib/apis';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let loading = false;
|
||||
let success = false;
|
||||
|
||||
let filesInputElement;
|
||||
let inputFiles;
|
||||
let imageUrl = null;
|
||||
|
||||
let digest = '';
|
||||
let pullProgress = null;
|
||||
let success = false;
|
||||
|
||||
let modelfile = null;
|
||||
// ///////////
|
||||
// Modelfile
|
||||
// model
|
||||
// ///////////
|
||||
|
||||
let title = '';
|
||||
let tagName = '';
|
||||
let desc = '';
|
||||
|
||||
// Raw Mode
|
||||
let content = '';
|
||||
|
||||
let suggestions = [
|
||||
{
|
||||
content: ''
|
||||
}
|
||||
];
|
||||
|
||||
let categories = {
|
||||
character: false,
|
||||
assistant: false,
|
||||
writing: false,
|
||||
productivity: false,
|
||||
programming: false,
|
||||
'data analysis': false,
|
||||
lifestyle: false,
|
||||
education: false,
|
||||
business: false
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
tagName = $page.url.searchParams.get('tag');
|
||||
|
||||
if (tagName) {
|
||||
modelfile = $modelfiles.filter((modelfile) => modelfile.tagName === tagName)[0];
|
||||
|
||||
console.log(modelfile);
|
||||
|
||||
imageUrl = modelfile.imageUrl;
|
||||
title = modelfile.title;
|
||||
desc = modelfile.desc;
|
||||
content = modelfile.content;
|
||||
suggestions =
|
||||
modelfile.suggestionPrompts.length != 0
|
||||
? modelfile.suggestionPrompts
|
||||
: [
|
||||
{
|
||||
content: ''
|
||||
}
|
||||
];
|
||||
|
||||
for (const category of modelfile.categories) {
|
||||
categories[category.toLowerCase()] = true;
|
||||
}
|
||||
} else {
|
||||
goto('/workspace/modelfiles');
|
||||
}
|
||||
});
|
||||
|
||||
const updateModelfile = async (modelfile) => {
|
||||
await updateModelById(localStorage.token, modelfile.tagName, modelfile);
|
||||
await modelfiles.set(await getModelInfos(localStorage.token));
|
||||
let model = null;
|
||||
let info = {
|
||||
id: '',
|
||||
base_model_id: null,
|
||||
name: '',
|
||||
meta: {
|
||||
profile_image_url: '/favicon.png',
|
||||
description: '',
|
||||
content: '',
|
||||
suggestion_prompts: []
|
||||
},
|
||||
params: {}
|
||||
};
|
||||
|
||||
const updateHandler = async () => {
|
||||
loading = true;
|
||||
const res = await updateModelById(localStorage.token, info.id, info);
|
||||
|
||||
if (Object.keys(categories).filter((category) => categories[category]).length == 0) {
|
||||
toast.error(
|
||||
'Uh-oh! It looks like you missed selecting a category. Please choose one to complete your modelfile.'
|
||||
);
|
||||
if (res) {
|
||||
await goto('/workspace/models');
|
||||
await models.set(await getModels(localStorage.token));
|
||||
}
|
||||
|
||||
if (
|
||||
title !== '' &&
|
||||
desc !== '' &&
|
||||
content !== '' &&
|
||||
Object.keys(categories).filter((category) => categories[category]).length > 0
|
||||
) {
|
||||
const res = await createModel(localStorage.token, tagName, content);
|
||||
|
||||
if (res) {
|
||||
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);
|
||||
|
||||
if (data.status === 'success') {
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
if (data.digest) {
|
||||
digest = data.digest;
|
||||
|
||||
if (data.completed) {
|
||||
pullProgress = Math.round((data.completed / data.total) * 1000) / 10;
|
||||
} else {
|
||||
pullProgress = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
toast.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
await updateModelfile({
|
||||
tagName: tagName,
|
||||
imageUrl: imageUrl,
|
||||
title: title,
|
||||
desc: desc,
|
||||
content: content,
|
||||
suggestionPrompts: suggestions.filter((prompt) => prompt.content !== ''),
|
||||
categories: Object.keys(categories).filter((category) => categories[category])
|
||||
});
|
||||
await goto('/workspace/modelfiles');
|
||||
}
|
||||
}
|
||||
loading = false;
|
||||
success = false;
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
const id = $page.url.searchParams.get('id');
|
||||
|
||||
if (id) {
|
||||
model = $models.find((m) => m.id === id);
|
||||
if (model) {
|
||||
info = {
|
||||
...info,
|
||||
...JSON.parse(
|
||||
JSON.stringify(
|
||||
model?.info
|
||||
? model?.info
|
||||
: {
|
||||
id: model.id,
|
||||
name: model.name
|
||||
}
|
||||
)
|
||||
)
|
||||
};
|
||||
console.log(model);
|
||||
} else {
|
||||
goto('/workspace/models');
|
||||
}
|
||||
} else {
|
||||
goto('/workspace/models');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="w-full max-h-full">
|
||||
@@ -229,7 +131,7 @@
|
||||
const compressedSrc = canvas.toDataURL('image/jpeg');
|
||||
|
||||
// Display the compressed image
|
||||
imageUrl = compressedSrc;
|
||||
info.meta.profile_image_url = compressedSrc;
|
||||
|
||||
inputFiles = null;
|
||||
};
|
||||
@@ -270,238 +172,230 @@
|
||||
</div>
|
||||
<div class=" self-center font-medium text-sm">{$i18n.t('Back')}</div>
|
||||
</button>
|
||||
<form
|
||||
class="flex flex-col max-w-2xl mx-auto mt-4 mb-10"
|
||||
on:submit|preventDefault={() => {
|
||||
updateHandler();
|
||||
}}
|
||||
>
|
||||
<div class="flex justify-center my-4">
|
||||
<div class="self-center">
|
||||
<button
|
||||
class=" {imageUrl
|
||||
? ''
|
||||
: 'p-6'} rounded-full dark:bg-gray-700 border border-dashed border-gray-200"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
filesInputElement.click();
|
||||
}}
|
||||
>
|
||||
{#if imageUrl}
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt="modelfile profile"
|
||||
class=" rounded-full w-20 h-20 object-cover"
|
||||
|
||||
{#if model}
|
||||
<form
|
||||
class="flex flex-col max-w-2xl mx-auto mt-4 mb-10"
|
||||
on:submit|preventDefault={() => {
|
||||
updateHandler();
|
||||
}}
|
||||
>
|
||||
<div class="flex justify-center my-4">
|
||||
<div class="self-center">
|
||||
<button
|
||||
class=" {info?.meta?.profile_image_url
|
||||
? ''
|
||||
: 'p-6'} rounded-full dark:bg-gray-700 border border-dashed border-gray-200"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
filesInputElement.click();
|
||||
}}
|
||||
>
|
||||
{#if info?.meta?.profile_image_url}
|
||||
<img
|
||||
src={info?.meta?.profile_image_url}
|
||||
alt="modelfile profile"
|
||||
class=" rounded-full w-20 h-20 object-cover"
|
||||
/>
|
||||
{:else}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-8"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-2 flex space-x-2">
|
||||
<div class="flex-1">
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Name')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent border dark:border-gray-600 outline-none rounded-lg"
|
||||
placeholder={$i18n.t('Name your model')}
|
||||
bind:value={info.name}
|
||||
required
|
||||
/>
|
||||
{:else}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Model ID')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent disabled:text-gray-500 border dark:border-gray-600 outline-none rounded-lg"
|
||||
placeholder={$i18n.t('Add a model id')}
|
||||
value={info.id}
|
||||
disabled
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('description')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent border dark:border-gray-600 outline-none rounded-lg"
|
||||
placeholder={$i18n.t('Add a short description about what this model does')}
|
||||
bind:value={info.meta.description}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Model')}</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class=" text-sm font-semibold mb-2"></div> -->
|
||||
|
||||
<div class="mt-2">
|
||||
<div class=" text-xs font-semibold mb-2">{$i18n.t('Params')}*</div>
|
||||
|
||||
<div>
|
||||
<!-- <textarea
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent border dark:border-gray-600 outline-none rounded-lg"
|
||||
placeholder={`FROM llama2\nPARAMETER temperature 1\nSYSTEM """\nYou are Mario from Super Mario Bros, acting as an assistant.\n"""`}
|
||||
rows="6"
|
||||
bind:value={content}
|
||||
required
|
||||
/> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between mb-2">
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Prompt suggestions')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
if (
|
||||
info.meta.suggestion_prompts.length === 0 ||
|
||||
info.meta.suggestion_prompts.at(-1).content !== ''
|
||||
) {
|
||||
info.meta.suggestion_prompts = [...info.meta.suggestion_prompts, { content: '' }];
|
||||
}
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
class="w-8"
|
||||
class="w-4 h-4"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
|
||||
clip-rule="evenodd"
|
||||
d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-1">
|
||||
{#each info.meta.suggestion_prompts as prompt, promptIdx}
|
||||
<div class=" flex border dark:border-gray-600 rounded-lg">
|
||||
<input
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent outline-none border-r dark:border-gray-600"
|
||||
placeholder={$i18n.t('Write a prompt suggestion (e.g. Who are you?)')}
|
||||
bind:value={prompt.content}
|
||||
/>
|
||||
|
||||
<button
|
||||
class="px-2"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
info.meta.suggestion_prompts.splice(promptIdx, 1);
|
||||
info.meta.suggestion_prompts = info.meta.suggestion_prompts;
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
class="w-4 h-4"
|
||||
>
|
||||
<path
|
||||
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if pullProgress !== null}
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Pull Progress')}</div>
|
||||
<div class="w-full rounded-full dark:bg-gray-800">
|
||||
<div
|
||||
class="dark:bg-gray-600 text-xs font-medium text-blue-100 text-center p-0.5 leading-none rounded-full"
|
||||
style="width: {Math.max(15, pullProgress ?? 0)}%"
|
||||
>
|
||||
{pullProgress ?? 0}%
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
|
||||
{digest}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="my-2 flex justify-end">
|
||||
<button
|
||||
class=" text-sm px-3 py-2 transition rounded-xl {loading
|
||||
? ' cursor-not-allowed bg-gray-100 dark:bg-gray-800'
|
||||
: ' bg-gray-50 hover:bg-gray-100 dark:bg-gray-700 dark:hover:bg-gray-800'} flex"
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
>
|
||||
<div class=" self-center font-medium">{$i18n.t('Save & Update')}</div>
|
||||
|
||||
{#if loading}
|
||||
<div class="ml-1.5 self-center">
|
||||
<svg
|
||||
class=" w-4 h-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><style>
|
||||
.spinner_ajPY {
|
||||
transform-origin: center;
|
||||
animation: spinner_AtaB 0.75s infinite linear;
|
||||
}
|
||||
@keyframes spinner_AtaB {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style><path
|
||||
d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
|
||||
opacity=".25"
|
||||
/><path
|
||||
d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
|
||||
class="spinner_ajPY"
|
||||
/></svg
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-2 flex space-x-2">
|
||||
<div class="flex-1">
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Name')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent border dark:border-gray-600 outline-none rounded-lg"
|
||||
placeholder={$i18n.t('Name your modelfile')}
|
||||
bind:value={title}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Model Tag Name')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent disabled:text-gray-500 border dark:border-gray-600 outline-none rounded-lg"
|
||||
placeholder={$i18n.t('Add a model tag name')}
|
||||
value={tagName}
|
||||
disabled
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Description')}*</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent border dark:border-gray-600 outline-none rounded-lg"
|
||||
placeholder={$i18n.t('Add a short description about what this modelfile does')}
|
||||
bind:value={desc}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Modelfile')}</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class=" text-sm font-semibold mb-2"></div> -->
|
||||
|
||||
<div class="mt-2">
|
||||
<div class=" text-xs font-semibold mb-2">{$i18n.t('Content')}*</div>
|
||||
|
||||
<div>
|
||||
<textarea
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent border dark:border-gray-600 outline-none rounded-lg"
|
||||
placeholder={`FROM llama2\nPARAMETER temperature 1\nSYSTEM """\nYou are Mario from Super Mario Bros, acting as an assistant.\n"""`}
|
||||
rows="6"
|
||||
bind:value={content}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between mb-2">
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Prompt suggestions')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
if (suggestions.length === 0 || suggestions.at(-1).content !== '') {
|
||||
suggestions = [...suggestions, { content: '' }];
|
||||
}
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
class="w-4 h-4"
|
||||
>
|
||||
<path
|
||||
d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-1">
|
||||
{#each suggestions as prompt, promptIdx}
|
||||
<div class=" flex border dark:border-gray-600 rounded-lg">
|
||||
<input
|
||||
class="px-3 py-1.5 text-sm w-full bg-transparent outline-none border-r dark:border-gray-600"
|
||||
placeholder={$i18n.t('Write a prompt suggestion (e.g. Who are you?)')}
|
||||
bind:value={prompt.content}
|
||||
/>
|
||||
|
||||
<button
|
||||
class="px-2"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
suggestions.splice(promptIdx, 1);
|
||||
suggestions = suggestions;
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
class="w-4 h-4"
|
||||
>
|
||||
<path
|
||||
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Categories')}</div>
|
||||
|
||||
<div class="grid grid-cols-4">
|
||||
{#each Object.keys(categories) as category}
|
||||
<div class="flex space-x-2 text-sm">
|
||||
<input type="checkbox" bind:checked={categories[category]} />
|
||||
|
||||
<div class=" capitalize">{category}</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if pullProgress !== null}
|
||||
<div class="my-2">
|
||||
<div class=" text-sm font-semibold mb-2">{$i18n.t('Pull Progress')}</div>
|
||||
<div class="w-full rounded-full dark:bg-gray-800">
|
||||
<div
|
||||
class="dark:bg-gray-600 text-xs font-medium text-blue-100 text-center p-0.5 leading-none rounded-full"
|
||||
style="width: {Math.max(15, pullProgress ?? 0)}%"
|
||||
>
|
||||
{pullProgress ?? 0}%
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
|
||||
{digest}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="my-2 flex justify-end">
|
||||
<button
|
||||
class=" text-sm px-3 py-2 transition rounded-xl {loading
|
||||
? ' cursor-not-allowed bg-gray-100 dark:bg-gray-800'
|
||||
: ' bg-gray-50 hover:bg-gray-100 dark:bg-gray-700 dark:hover:bg-gray-800'} flex"
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
>
|
||||
<div class=" self-center font-medium">{$i18n.t('Save & Update')}</div>
|
||||
|
||||
{#if loading}
|
||||
<div class="ml-1.5 self-center">
|
||||
<svg
|
||||
class=" w-4 h-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><style>
|
||||
.spinner_ajPY {
|
||||
transform-origin: center;
|
||||
animation: spinner_AtaB 0.75s infinite linear;
|
||||
}
|
||||
@keyframes spinner_AtaB {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style><path
|
||||
d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
|
||||
opacity=".25"
|
||||
/><path
|
||||
d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
|
||||
class="spinner_ajPY"
|
||||
/></svg
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"description": "Developer lead assistant with no code explanation",
|
||||
"profile_image_url": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCABkAGQDASIAAhEBAxEB/8QAHQAAAQQDAQEAAAAAAAAAAAAAAAUGBwgCBAkBA//EADkQAAEDAwMCBQEGBAUFAAAAAAECAwQFBhEAEiEHMQgTIkFRYRQjMnGBkRUzQlIXJHKh0RaCkrHB/8QAGwEAAQUBAQAAAAAAAAAAAAAABgABAwQFAgf/xAA0EQABAgUCBAQEBAcAAAAAAAABAhEAAwQFIRIxQVFxgQYTImGRsfDxMkKhwQcUFSRSYtH/2gAMAwEAAhEDEQA/AOcQA9zrIJyeDrHHGdbENnzl7QMn2HydbccEtmFCn0tchtLinmGvMVsb8xe3er4+g7DccJ+vfSvCo77bi25TSmVtEpWlxJSUqHsQeQfodOG3bZqLsih0yW81AclLSuKuW0kt+U6cFe1Q5OQcDueNvJGn7bVuUiNcM1lVbXVGfMC26lFSpPnHOc+o7hnOc5ByMHToUkr0Hdn4/PbtGJX1aZUrzSfTt9cYZFHt9+a4lmOyST8+2nnD6S3JMfRFYpshxxz8KG2FqKvy451eTw2eDGnVqInqB1JRIiQHSJMSC4va4tkDKVuqP4Qe+Pg6tWzaApVrGBY1EplMKSoluMUJ80J7J3gElXyT++kqtkS1CW+XZ3YCBoS7hVjz5YZDEgM6ldB+5+EcfKt0KvCmRzJnUSpREdtz8Nbaf3I7ajyv2vIpii26EnvlSRxrtNNpt5UaiyKxU5FOVBjJUouhw7lp2nB38cFWAM98/vFN9dBenF9uqkVCkUiJUlJw1LjFpIW+RnYtKSEqyM+rHcjnJGbSDLmg6SDFNNVXUagqckkbswB+Z5YjkLNgqb5CTj2OMZ0mVKmyYLnlyWS2vaFhOedpGR/tq8vU3pbbvS+JVoV3WymQphRkQE7TtUtQKQQocgEhI+MgDvjVY6/07rcyS/VKhCYgtPBCmQ2coKVJyNuCckDv3OfbUM2WqWpjBRaLmK9BIBDcf2iOptHYaYklhb/mw2m33vMSAlSFKQkFOD/c4n9NI4GdONyAXG3qbT3VSJCf5risgqbTztQD/TkZP+lPAwdN5xCmXFNrGCDqKCNJcRho0aNKHjJOCDz7cDUo9FLZrdTrqpVEpqJzsJhUl5h5KSy4yAVEOJc9KhgE8/GRzqO6YYwQ4l1kvLcSUpSBgp4Pqz9Dz29u+rjeFjw31G5LLk9S3qk4mG04YyEMqwHCMBQUDwUjcARj99D/AImvCbFbl1jsRtgn9B7fDeNeyWuVd6xNLUfgO+W3x84QlWtP6j30xK/hbjCqktLLBQdiWlpQAAOwSjCTntgasf0L6JUCtX+uoV12RPjW1/mZrklwrEh/OEIJUTlO4Ek9iEnPfTOvV6g0KS1bdLq7LNYiNqkIbaUUEZHG44x9SBzjPtqc/DDWmKP0qui6lPQ33JD/AKVKUMY8kkJyfqc//dWvDVzm3mgTVrlspTM4Z0k4PQtHm/jqxos13FHKmvIRu2cpGQejjEWrplEduijQZlZVIitrQV/Y2XChCknsV45OR7fXTauZHTXpKpm47jveTSGUPF1lh+WpSXAkEqSGwCpSQkq47dtJsfxBwYEOnRahbkl+RIp5luOQnm1MpbSg5UCSMYKQCCeM++Ma5eeIrxEV6/LvlVhxEp4uuSG48QhTyUtJWoBCMcbex5JBP0I1VrF1tGsy1+kKfHBn+t8wU2W30F2HmpZRQzlsu31tiOltu+L7w1XDcTFkUy5EpdqEpuKyXac43GekLUNidxTgEkjlQGpsi0Gjwpbk2JTYzLruNy0NJSSeecgd+e+uElsdJ/EjdtErN3ROn77dLpiBIccSpCFbQ4hX3baDlSglC/btz7Z12G8JnUif1O6CW7dVSkLkyg25GceUoqW8WiUhRzySQNZyZoyELfmxjYraBEgJmaWbmMwzvF10ohXJ03rRpsNs1GNEeqELekrCy2NzrXzhSRkDP4kp1yNotHuaqThDp6JbEZ9fBAOwEJOSn9M9tdtbsmiXVVNKdfeaMYlQWMpQHAfQBjjgjIPPtrlxWLc6fUq37ouaBeNShXfTKo5Fp9BQz9y5FCglR3gcZBcUDkJBQAeVDJ1bkhcuUmpyMP0jzhFVKpaqeiSNOS3Xb66RDlZtagUSrtrbnyP4hFUlzzXAkp3DHO33Go9vB+LImyHH0BuoeafMQ2kBAOeSPgH204a9MfVLVKktOLyrncgg/ue2mbXl/aJiprqlb5Hrxjt+vx/xq1cpUlCgZQA6coKKATglpp3HGEzRo0azIvwo0iFMnlbcFlTi2x5hwCeB9ANXD8PfiQqHT6hvdPY9KcqNHkPeamMhX3zDpQN2Rjtxn8xqp1k1mqUSoKdpjnlqfSWFHcPwkcjHvxqx9PsqHavTo3dKUqVJjoRLfW02ltKWk7XHkn33lreE59wOw1UuVno7zRqpq1GpG5HHHI4LwkXKfa5yZ1ORqdg+R3hW6l31Kk3G/dESlNwU1SKmHIQ+nKwoA7HM+xwRhQ+n5iefCLf0aq2lcdoVNtiVFp7jNXQwpoLEhls4cST7gENgkn8KvjUWUO0rav20qqic5Lrk9qA69AVHc9SVMY3DgY8vy1NOAr4wrjSt0RoMDp46q5FVZyl1+DUZUV1ie+y3AnQG1FtzygpQW4FoKk5BzuHAJB1H4dqrZNQaSgQUkADO7J9Iy5JZmgc8Sy7lUJFVXkEpLsNgV+rYAYJx2bhEzdRaI3QJEdulNNi36l5lQpUxj0ulhw48pageNispKTz3+dV3qvT65qJfkS7LD6ZU64JDrzsmUZtWSHHN52koQVYbOC5kkkEjkDIBs3GoNQuRul1W1Cudbcqol1K3gsR2N5QFNuHGQMp7AZIIIByNQd0369IrPWK++nlctSiuMwnnkUdctoNtQkIkJjuNvPHKlbvu1j2UoYOMjC8YVEpFJLkvqWMluI2z77Rf/h1S1Jq50/TplkAZwX/1HEb54YESDJ8SvV0R4dn9MvDpEptEjMtJqzlaqjZcPmp3FTaWVblIKQSlZB3gpIAyNTr4OZQ6eeGWZKepqmmaK/UZyo4WCoDcp3ywc44BCc8DjVdLv6pu2fYteuO7WrUuCqRIDsSm/YWigpU02fKaWkoAW2jJO48ZxtznX28Ht9Vy4ujkrpq9VnG3avMdY2vqShc5v7OjzEtPr4UQUuZ9ikKGcjBDrPKRPmGW2l+OWxz37Yg88Ry5lLR+ekamIJHEu4wMdSHdtotdNvplVhS76q0hhQbivSnW9oQlB2DY2k+/Khj3yrVC7bpVp1e+KS9crcppUqqMInPSWQ2wmIcFxSlk8EZ+exzpx9W/EhelEkf4QQLAnUSU+r7O3/GYzrS9vBD/AJZTgp2jeCQpJwkg++o46q9VZRgU3pLYS5M+rONIgPupkArc5SFMb92BnykhROMJQrn7xWS2nrRQyxTqLgAkqJGBwzj7Z4GPMbj4ZNbUCtSdIJACW34qfMW88VXTzofP6FVKu0GgW4ZbTbblNm09hkFxe8J2hafx5Tu9z8+2uUt6KrlRVEpri5U2HQ4YYjpQjKY7ZUVEZA7ZPc6sj1BHUe0en9JoNWr0wuyEqQ+l8q8tACQfLZ/pUnKuVA8beeeNQMbqrlIYqtHgRm3xW2G2pG5lO9KUqyAkqHHIH6ampqrzJIMs6gcjLj4wWSaQJYzT6Rx+8RkQQSCCCO4OjX0klYfWFoAVuOR9dGrgdsxFG7QyszEtskh08tEDOFf84z+uNXEsu4XplKRCmYUxLgIjSI76DtSvZsGQASAPxfkCPcaqTaMeQ3UGapHfhJMZalbZK8JVtTnB/PsNSlbXV+sSruauebTZU1C1Bx1LbatpAONvGRwAeeM6h8yf5umWzNvxfpxjuZIkTad1uVPtzHXnE29JbL64Wk9Wadbdhu1SmPNhFMfFUhtpcABbxtdfQvaWlkjcB6mm8jA19ha9+xuq9BpvValOMU6DHNUqsVE9hzzkNpAbTllxQAW55aFdjsK8YJzpO6pTZKrybj0ev1WHRqnFadp70WS422lCgHUghKuSU4BOe24540jW5X5lChVm9qRVqk1MqJaprK5MkydvkukOoSXd3Csg/BwdC9Db6mnrEzULSNTHAIPqA9Line truncated
|
||||
"ollama": {
|
||||
"modelfile": "FROM llama3\nPARAMETER temperature 1\nSYSTEM \"\"\"\nI want you to act as a senior full-stack tech leader and top-tier brilliant software developer, you embody technical excellence and a deep understanding of a wide range of technologies. Your expertise covers not just coding, but also algorithm design, system architecture, and technology strategy. for every question there is no need to explain, only give the solution.\n\nCoding Mastery: Possess exceptional skills in programming languages including Python, JavaScript, SQL, NoSQL, mySQL, C++, C, Rust, Groovy, Go, and Java. Your proficiency goes beyond mere syntax; you explore and master the nuances and complexities of each language, crafting code that is both highly efficient and robust. Your capability to optimize performance and manage complex codebases sets the benchmark in software development.\n\nPython | JavaScript | C++ | C | RUST | Groovy | Go | Java | SQL | MySQL | NoSQL\nEfficient, Optimal, Good Performance, Excellent Complexity, Robust Code\n\nCutting-Edge Technologies: Adept at leveraging the latest technologies, frameworks, and tools to drive innovation and efficiency. Experienced with Docker, Kubernetes, React, Angular, AWS, Supabase, Firebase, Azure, and Google Cloud. Your understanding of these platforms enables you to architect and deploy scalable, resilient applications that meet modern business demands.\n\nDocker | Kubernetes | React | Angular | AWS | Supabase | Firebase | Azure | Google Cloud\nSeamlessly Integrating Modern Tech Stacks\n\nComplex Algorithms & Data Structures\nOptimized Solutions for Enhanced Performance & Scalability\n\nSolution Architect: Your comprehensive grasp of the software development lifecycle empowers you to design solutions that are not only technically sound but also align perfectly with business goals. From concept to deployment, you ensure adherence to industry best practices and agile methodologies, making the development process both agile and effective.\n\nInteractive Solutions: When crafting user-facing features, employ modern ES6 JavaScript, TypeScript, and native browser APIs to manage interactivity seamlessly, enabling a dynamic and engaging user experience. Your focus lies in delivering functional, ready-to-deploy code, ensuring that explanations are succinct and directly aligned with the required solutions.\n\nnever explain the code just write code \n\"\"\""
|
||||
},
|
||||
"suggestion_prompts": [
|
||||
{
|
||||
"content": "Create a pac-man game in C"
|
||||
},
|
||||
{
|
||||
"content": "Create react page example"
|
||||
},
|
||||
{
|
||||
"content": "write character collisions in godot engine"
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
"assistant",
|
||||
"programming",
|
||||
"data analysis"
|
||||
],
|
||||
"user": {
|
||||
"username": "vianch",
|
||||
"name": "",
|
||||
"community": true
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user