feat: model tag support

This commit is contained in:
Timothy J. Baek 2024-05-31 12:08:25 -07:00
parent 0cf9b07ec2
commit eca20b1b2c
7 changed files with 155 additions and 54 deletions

View File

@ -39,7 +39,7 @@
{#if !dismissed}
{#if mounted}
<div
class=" top-0 left-0 right-0 p-2 mx-4 px-3 flex justify-center items-center relative rounded-xl border border-gray-100 dark:border-gray-850 text-gray-800 dark:text-gary-100 bg-white dark:bg-gray-900 backdrop-blur-xl z-40"
class=" top-0 left-0 right-0 p-2 mx-4 px-3 flex justify-center items-center relative rounded-xl border border-gray-50 dark:border-gray-850 text-gray-800 dark:text-gary-100 bg-white dark:bg-gray-900 backdrop-blur-xl z-40"
transition:fade={{ delay: 100, duration: 300 }}
>
<div class=" flex flex-col md:flex-row md:items-center flex-1 text-sm w-fit gap-1.5">

View File

@ -14,6 +14,7 @@
onOpenChange={(state) => {
dispatch('change', state);
}}
typeahead={false}
>
<DropdownMenu.Trigger>
<slot />

View File

@ -11,7 +11,7 @@
export let addTag: Function;
</script>
<div class="flex flex-row flex-wrap gap-0.5 line-clamp-1">
<div class="flex flex-row flex-wrap gap-1 line-clamp-1">
<TagList
{tags}
on:delete={(e) => {

View File

@ -22,26 +22,12 @@
};
</script>
<div class="flex space-x-1 pl-1.5">
<div class="flex {showTagInput ? 'flex-row-reverse' : ''}">
{#if showTagInput}
<div class="flex items-center">
<button type="button" on:click={addTagHandler}>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-3 h-3"
>
<path
fill-rule="evenodd"
d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z"
clip-rule="evenodd"
/>
</svg>
</button>
<input
bind:value={tagName}
class=" pl-2 cursor-pointer self-center text-xs h-fit bg-transparent outline-none line-clamp-1 w-[5.5rem]"
class=" px-2 cursor-pointer self-center text-xs h-fit bg-transparent outline-none line-clamp-1 w-[5.5rem]"
placeholder={$i18n.t('Add a tag')}
list="tagOptions"
on:keydown={(event) => {
@ -55,11 +41,27 @@
<option value={tag.name} />
{/each}
</datalist>
<button type="button" on:click={addTagHandler}>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
stroke-width="2"
class="w-3 h-3"
>
<path
fill-rule="evenodd"
d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
{/if}
<button
class=" cursor-pointer self-center p-0.5 space-x-1 flex h-fit items-center dark:hover:bg-gray-700 rounded-full transition border dark:border-gray-600 border-dashed"
class=" cursor-pointer self-center p-0.5 flex h-fit items-center dark:hover:bg-gray-700 rounded-full transition border dark:border-gray-600 border-dashed"
type="button"
on:click={() => {
showTagInput = !showTagInput;
@ -80,6 +82,6 @@
</button>
{#if label && !showTagInput}
<span class="text-xs pl-1.5 self-center">{label}</span>
<span class="text-xs pl-2 self-center">{label}</span>
{/if}
</div>

View File

@ -7,22 +7,23 @@
{#each tags as tag}
<div
class="px-2 py-0.5 space-x-1 flex h-fit items-center rounded-full transition border dark:border-gray-800 dark:text-white"
class="px-2 py-[0.5px] gap-0.5 flex justify-between h-fit items-center rounded-full transition border dark:border-gray-800 dark:text-white"
>
<div class=" text-[0.7rem] font-medium self-center line-clamp-1">
{tag.name}
</div>
<button
class=" m-auto self-center cursor-pointer"
class="h-full flex self-center cursor-pointer"
on:click={() => {
dispatch('delete', tag.name);
}}
type="button"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-3 h-3"
class="size-3 m-auto self-center translate-y-[0.3px] translate-x-[3px]"
>
<path
d="M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z"

View File

@ -10,6 +10,7 @@
import AdvancedParams from '$lib/components/chat/Settings/Advanced/AdvancedParams.svelte';
import Checkbox from '$lib/components/common/Checkbox.svelte';
import Tags from '$lib/components/common/Tags.svelte';
const i18n = getContext('i18n');
@ -262,7 +263,7 @@
<button
class=" {info.meta.profile_image_url
? ''
: 'p-6'} rounded-full dark:bg-gray-700 border border-dashed border-gray-200"
: 'p-4'} rounded-full dark:bg-gray-700 border border-dashed border-gray-200 flex items-center"
type="button"
on:click={() => {
filesInputElement.click();
@ -272,7 +273,7 @@
<img
src={info.meta.profile_image_url}
alt="modelfile profile"
class=" rounded-full w-20 h-20 object-cover"
class=" rounded-full size-16 object-cover"
/>
{:else}
<svg
@ -338,18 +339,40 @@
</div>
</div>
<div class="my-2">
<div class=" text-sm font-semibold mb-2">{$i18n.t('Description')}</div>
<div class="my-1">
<div class="flex w-full justify-between items-center mb-1">
<div class=" self-center text-sm font-semibold">{$i18n.t('Description')}</div>
<div>
<button
class="p-1 text-xs flex rounded transition"
type="button"
on:click={() => {
if (info.meta.description === null) {
info.meta.description = '';
} else {
info.meta.description = null;
}
}}
>
{#if info.meta.description === null}
<span class="ml-2 self-center">{$i18n.t('Default')}</span>
{:else}
<span class="ml-2 self-center">{$i18n.t('Custom')}</span>
{/if}
</button>
</div>
{#if info.meta.description !== null}
<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}
/>
</div>
{/if}
</div>
<hr class=" dark:border-gray-850 my-1" />
<div class="my-2">
<div class="flex w-full justify-between">
<div class=" self-center text-sm font-semibold">{$i18n.t('Model Params')}</div>
@ -401,7 +424,9 @@
</div>
</div>
<div class="my-2">
<hr class=" dark:border-gray-850 my-1" />
<div class="my-1">
<div class="flex w-full justify-between items-center">
<div class="flex w-full justify-between items-center">
<div class=" self-center text-sm font-semibold">{$i18n.t('Prompt suggestions')}</div>
@ -491,8 +516,8 @@
{/if}
</div>
<div class="my-2">
<div class="flex w-full justify-between">
<div class="my-1">
<div class="flex w-full justify-between mb-1">
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
</div>
<div class="flex flex-col">
@ -505,7 +530,7 @@
}}
/>
<div class=" py-1.5 text-sm w-full capitalize">
<div class=" py-0.5 text-sm w-full capitalize">
{$i18n.t(capability)}
</div>
</div>
@ -513,7 +538,30 @@
</div>
</div>
<div class="my-2 text-gray-500">
<div class="my-1">
<div class="flex w-full justify-between items-center">
<div class=" self-center text-sm font-semibold">{$i18n.t('Tags')}</div>
</div>
<div class="mt-2">
<Tags
tags={info?.meta?.tags ?? []}
deleteTag={(tagName) => {
info.meta.tags = info.meta.tags.filter((tag) => tag.name !== tagName);
}}
addTag={(tagName) => {
console.log(tagName);
if (!(info?.meta?.tags ?? null)) {
info.meta.tags = [{ name: tagName }];
} else {
info.meta.tags = [...info.meta.tags, { name: tagName }];
}
}}
/>
</div>
</div>
<div class="my-2 text-gray-300 dark:text-gray-700">
<div class="flex w-full justify-between mb-2">
<div class=" self-center text-sm font-semibold">{$i18n.t('JSON Preview')}</div>

View File

@ -13,6 +13,7 @@
import AdvancedParams from '$lib/components/chat/Settings/Advanced/AdvancedParams.svelte';
import { getModels } from '$lib/apis';
import Checkbox from '$lib/components/common/Checkbox.svelte';
import Tags from '$lib/components/common/Tags.svelte';
const i18n = getContext('i18n');
@ -44,7 +45,8 @@
meta: {
profile_image_url: '/favicon.png',
description: '',
suggestion_prompts: null
suggestion_prompts: null,
tags: []
},
params: {
system: ''
@ -223,26 +225,26 @@
<div class="flex justify-center my-4">
<div class="self-center">
<button
class=" {info?.meta?.profile_image_url
class=" {info.meta.profile_image_url
? ''
: 'p-6'} rounded-full dark:bg-gray-700 border border-dashed border-gray-200"
: 'p-4'} rounded-full dark:bg-gray-700 border border-dashed border-gray-200 flex items-center"
type="button"
on:click={() => {
filesInputElement.click();
}}
>
{#if info?.meta?.profile_image_url}
{#if info.meta.profile_image_url}
<img
src={info?.meta?.profile_image_url}
src={info.meta.profile_image_url}
alt="modelfile profile"
class=" rounded-full w-20 h-20 object-cover"
class=" rounded-full size-16 object-cover"
/>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-8"
class="size-8"
>
<path
fill-rule="evenodd"
@ -255,9 +257,9 @@
</div>
</div>
<div class="my-2 flex space-x-2">
<div class="mt-2 my-1 flex space-x-2">
<div class="flex-1">
<div class=" text-sm font-semibold mb-2">{$i18n.t('Name')}*</div>
<div class=" text-sm font-semibold mb-1">{$i18n.t('Name')}*</div>
<div>
<input
@ -270,7 +272,7 @@
</div>
<div class="flex-1">
<div class=" text-sm font-semibold mb-2">{$i18n.t('Model ID')}*</div>
<div class=" text-sm font-semibold mb-1">{$i18n.t('Model ID')}*</div>
<div>
<input
@ -285,8 +287,8 @@
</div>
{#if model.preset}
<div class="my-2">
<div class=" text-sm font-semibold mb-2">{$i18n.t('Base Model (From)')}</div>
<div class="my-1">
<div class=" text-sm font-semibold mb-1">{$i18n.t('Base Model (From)')}</div>
<div>
<select
@ -304,18 +306,40 @@
</div>
{/if}
<div class="my-2">
<div class=" text-sm font-semibold mb-2">{$i18n.t('Description')}</div>
<div class="my-1">
<div class="flex w-full justify-between items-center">
<div class=" self-center text-sm font-semibold">{$i18n.t('Description')}</div>
<div>
<button
class="p-1 text-xs flex rounded transition"
type="button"
on:click={() => {
if (info.meta.description === null) {
info.meta.description = '';
} else {
info.meta.description = null;
}
}}
>
{#if info.meta.description === null}
<span class="ml-2 self-center">{$i18n.t('Default')}</span>
{:else}
<span class="ml-2 self-center">{$i18n.t('Custom')}</span>
{/if}
</button>
</div>
{#if info.meta.description !== null}
<input
class="px-3 py-1.5 text-sm w-full bg-transparent border dark:border-gray-600 outline-none rounded-lg"
class="mt-1 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}
/>
</div>
{/if}
</div>
<hr class=" dark:border-gray-850 my-1" />
<div class="my-2">
<div class="flex w-full justify-between">
<div class=" self-center text-sm font-semibold">{$i18n.t('Model Params')}</div>
@ -369,7 +393,9 @@
</div>
</div>
<div class="my-2">
<hr class=" dark:border-gray-850 my-1" />
<div class="my-1">
<div class="flex w-full justify-between items-center">
<div class="flex w-full justify-between items-center">
<div class=" self-center text-sm font-semibold">{$i18n.t('Prompt suggestions')}</div>
@ -459,7 +485,7 @@
{/if}
</div>
<div class="my-2">
<div class="my-1">
<div class="flex w-full justify-between mb-1">
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
</div>
@ -481,7 +507,30 @@
</div>
</div>
<div class="my-2 text-gray-500">
<div class="my-1">
<div class="flex w-full justify-between items-center">
<div class=" self-center text-sm font-semibold">{$i18n.t('Tags')}</div>
</div>
<div class="mt-2">
<Tags
tags={info?.meta?.tags ?? []}
deleteTag={(tagName) => {
info.meta.tags = info.meta.tags.filter((tag) => tag.name !== tagName);
}}
addTag={(tagName) => {
console.log(tagName);
if (!(info?.meta?.tags ?? null)) {
info.meta.tags = [{ name: tagName }];
} else {
info.meta.tags = [...info.meta.tags, { name: tagName }];
}
}}
/>
</div>
</div>
<div class="my-2 text-gray-300 dark:text-gray-700">
<div class="flex w-full justify-between mb-2">
<div class=" self-center text-sm font-semibold">{$i18n.t('JSON Preview')}</div>