|
@@ -0,0 +1,477 @@
|
|
|
|
|
+<script lang="ts">
|
|
|
|
|
+ import { Card } from '$lib/components/common/card';
|
|
|
|
|
+ import { Button } from '$lib/components/controls/button';
|
|
|
|
|
+ import * as Field from '$lib/components/controls/field';
|
|
|
|
|
+ import { Input } from '$lib/components/controls/input';
|
|
|
|
|
+ import * as Select from '$lib/components/controls/select';
|
|
|
|
|
+ import { Spinner } from '$lib/components/controls/spinner';
|
|
|
|
|
+ import { Textarea } from '$lib/components/controls/textarea';
|
|
|
|
|
+ import * as ToggleGroup from '$lib/components/controls/toggle-group';
|
|
|
|
|
+ import { ArrayInput } from '$lib/components/forms/array-input';
|
|
|
|
|
+ import { AuthForm } from '$lib/components/forms/auth';
|
|
|
|
|
+ import { DeploymentForm } from '$lib/components/forms/deployment';
|
|
|
|
|
+ import { IconPicker } from '$lib/components/forms/icon-picker';
|
|
|
|
|
+ import { Optional } from '$lib/components/forms/optional';
|
|
|
|
|
+ import {
|
|
|
|
|
+ MODEL_CATEGORIES,
|
|
|
|
|
+ MODEL_MODALITIES,
|
|
|
|
|
+ MODEL_PROVIDERS,
|
|
|
|
|
+ MODEL_RUNTIMES,
|
|
|
|
|
+ } from '$lib/types/entities';
|
|
|
|
|
+
|
|
|
|
|
+ import { DEFAULT_MODEL_FORM_VALUE, type ModelFormValue } from './types';
|
|
|
|
|
+
|
|
|
|
|
+ let {
|
|
|
|
|
+ workspaceId,
|
|
|
|
|
+ disabled = false,
|
|
|
|
|
+ submitting = false,
|
|
|
|
|
+ value,
|
|
|
|
|
+ cancelHref,
|
|
|
|
|
+ onsubmit = () => {},
|
|
|
|
|
+ }: {
|
|
|
|
|
+ workspaceId: string;
|
|
|
|
|
+ disabled?: boolean;
|
|
|
|
|
+ submitting?: boolean;
|
|
|
|
|
+ value?: ModelFormValue;
|
|
|
|
|
+ cancelHref: string;
|
|
|
|
|
+ onsubmit: (value: ModelFormValue) => void;
|
|
|
|
|
+ } = $props();
|
|
|
|
|
+ const isEdit = $derived(value !== undefined);
|
|
|
|
|
+ let form = $state<ModelFormValue>({ ...DEFAULT_MODEL_FORM_VALUE });
|
|
|
|
|
+ let errors = $state<{
|
|
|
|
|
+ name?: string;
|
|
|
|
|
+ }>({});
|
|
|
|
|
+ const providerLabel = $derived(
|
|
|
|
|
+ MODEL_PROVIDERS.find((p) => p.value === form.provider)?.label ?? form.provider,
|
|
|
|
|
+ );
|
|
|
|
|
+ const runtimes = $derived(MODEL_RUNTIMES.filter((r) => r.supports.has(form.modelCategory)));
|
|
|
|
|
+
|
|
|
|
|
+ const initForm = (value?: ModelFormValue) => {
|
|
|
|
|
+ if (!value) {
|
|
|
|
|
+ form = { ...DEFAULT_MODEL_FORM_VALUE };
|
|
|
|
|
+ } else {
|
|
|
|
|
+ form = {
|
|
|
|
|
+ ...$state.snapshot(value),
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const inferRuntime = (modelCategory: string, runtime?: string) => {
|
|
|
|
|
+ if (runtime === 'llama.cpp') {
|
|
|
|
|
+ if (modelCategory === 'embedding') {
|
|
|
|
|
+ form.runtimeVersion = 'llama.cpp-embedding';
|
|
|
|
|
+ form.runtimeContextWindow = 512;
|
|
|
|
|
+ } else if (modelCategory === 'reranker') {
|
|
|
|
|
+ form.runtimeVersion = 'llama.cpp-reranker';
|
|
|
|
|
+ form.runtimeContextWindow = 512;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ form.runtimeVersion = undefined;
|
|
|
|
|
+ form.runtimeContextWindow = 16384;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ $effect(() => initForm(value));
|
|
|
|
|
+ $effect(() => {
|
|
|
|
|
+ inferRuntime(form.modelCategory, form.runtime);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const handleSubmit = () => {
|
|
|
|
|
+ onsubmit(form);
|
|
|
|
|
+ };
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+{#snippet panel()}
|
|
|
|
|
+ <div class="flex items-center gap-2">
|
|
|
|
|
+ <Button href={cancelHref} size="sm" variant="outline">Cancel</Button>
|
|
|
|
|
+ <Button disabled={disabled || submitting} size="sm" onclick={handleSubmit}>
|
|
|
|
|
+ {#if submitting}
|
|
|
|
|
+ <Spinner />
|
|
|
|
|
+ {/if}
|
|
|
|
|
+ {isEdit ? 'Save Changes' : 'Create'}
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+{/snippet}
|
|
|
|
|
+
|
|
|
|
|
+<div class="mx-auto max-w-2xl p-6">
|
|
|
|
|
+ <!-- Page header -->
|
|
|
|
|
+ <div class="mb-4 flex items-center justify-between gap-4">
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <h1 class="text-xl font-semibold text-white/90">
|
|
|
|
|
+ {isEdit ? 'Edit Model' : 'New Model'}
|
|
|
|
|
+ </h1>
|
|
|
|
|
+ {#if isEdit}
|
|
|
|
|
+ <div class="text-xs text-white/30 capitalize">{form.mode}</div>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ {@render panel()}
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Basic Information panel (shared) -->
|
|
|
|
|
+ <Card class="mb-4" title="Basic Information">
|
|
|
|
|
+ <div class="mb-4 flex gap-8">
|
|
|
|
|
+ <!-- Icon -->
|
|
|
|
|
+ <div class="shrink-0">
|
|
|
|
|
+ <IconPicker {disabled} bind:value={form.icon} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <!-- Name, Description, Mode, Model Category -->
|
|
|
|
|
+ <div class="min-w-0 flex-1 space-y-4">
|
|
|
|
|
+ <Field.Set>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="name">Name</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="name"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ maxlength={64}
|
|
|
|
|
+ placeholder="e.g. DeepSeek R1 Production"
|
|
|
|
|
+ bind:value={form.name}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Field.Error>{errors.name}</Field.Error>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="description">Description</Field.Label>
|
|
|
|
|
+ <Textarea
|
|
|
|
|
+ id="description"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="What will this model be used for?"
|
|
|
|
|
+ rows={3}
|
|
|
|
|
+ bind:value={form.description}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Field.Description>
|
|
|
|
|
+ Provide a brief description that can also help AI assistant to understand the model's
|
|
|
|
|
+ intended usage.
|
|
|
|
|
+ </Field.Description>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="mode">Mode</Field.Label>
|
|
|
|
|
+ <ToggleGroup.Root
|
|
|
|
|
+ id="mode"
|
|
|
|
|
+ disabled={isEdit || disabled}
|
|
|
|
|
+ type="single"
|
|
|
|
|
+ variant="outline"
|
|
|
|
|
+ bind:value={form.mode}
|
|
|
|
|
+ >
|
|
|
|
|
+ <ToggleGroup.Item value="external">External</ToggleGroup.Item>
|
|
|
|
|
+ <ToggleGroup.Item value="managed">Managed</ToggleGroup.Item>
|
|
|
|
|
+ </ToggleGroup.Root>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="modelCategory">Model Category</Field.Label>
|
|
|
|
|
+ <ToggleGroup.Root
|
|
|
|
|
+ id="modelCategory"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ type="single"
|
|
|
|
|
+ variant="outline"
|
|
|
|
|
+ bind:value={form.modelCategory}
|
|
|
|
|
+ >
|
|
|
|
|
+ {#each MODEL_CATEGORIES as type (type.value)}
|
|
|
|
|
+ <ToggleGroup.Item value={type.value}>{type.label}</ToggleGroup.Item>
|
|
|
|
|
+ {/each}
|
|
|
|
|
+ </ToggleGroup.Root>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ </Field.Set>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <Optional class="mb-4" title="Tags">
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <ArrayInput {disabled} bind:value={form.tags} />
|
|
|
|
|
+ <Field.Description>
|
|
|
|
|
+ Tags can be used for filtering and searching in the list view.
|
|
|
|
|
+ </Field.Description>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ </Optional>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Provider (collapsible) -->
|
|
|
|
|
+ <Optional class="mb-4" title="Provider">
|
|
|
|
|
+ <Field.Set>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="baseModelId">Base Model ID</Field.Label>
|
|
|
|
|
+ <Input id="baseModelId" {disabled} bind:value={form.baseModelId} />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <div class="grid grid-cols-3 gap-4">
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="family">Family</Field.Label>
|
|
|
|
|
+ <Input id="family" {disabled} bind:value={form.family} />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="releaseDate">Release Date</Field.Label>
|
|
|
|
|
+ <Input id="releaseDate" {disabled} bind:value={form.releaseDate} />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="parameterCount">Parameter Count</Field.Label>
|
|
|
|
|
+ <Input id="parameterCount" {disabled} bind:value={form.parameterCount} />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Field.Set>
|
|
|
|
|
+ </Optional>
|
|
|
|
|
+
|
|
|
|
|
+ <Optional title="Capabilities">
|
|
|
|
|
+ <Field.Set>
|
|
|
|
|
+ {#if form.modelCategory === 'language'}
|
|
|
|
|
+ <div class="grid grid-cols-2 gap-4">
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="contextWindow">Context Window</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="contextWindow"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ min={0}
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.contextWindow}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="maxOutputTokens">Max Output Tokens</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="maxOutputTokens"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ min={0}
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.maxOutputTokens}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="inputs">Inputs</Field.Label>
|
|
|
|
|
+ <ToggleGroup.Root
|
|
|
|
|
+ id="inputs"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ type="multiple"
|
|
|
|
|
+ variant="outline"
|
|
|
|
|
+ bind:value={form.inputs}
|
|
|
|
|
+ >
|
|
|
|
|
+ {#each MODEL_MODALITIES as option (option.value)}
|
|
|
|
|
+ <ToggleGroup.Item value={option.value}>
|
|
|
|
|
+ {option.label}
|
|
|
|
|
+ </ToggleGroup.Item>
|
|
|
|
|
+ {/each}
|
|
|
|
|
+ </ToggleGroup.Root>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="outputs">Outputs</Field.Label>
|
|
|
|
|
+ <ToggleGroup.Root
|
|
|
|
|
+ id="outputs"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ type="multiple"
|
|
|
|
|
+ variant="outline"
|
|
|
|
|
+ bind:value={form.outputs}
|
|
|
|
|
+ >
|
|
|
|
|
+ {#each MODEL_MODALITIES as option (option.value)}
|
|
|
|
|
+ <ToggleGroup.Item value={option.value}>
|
|
|
|
|
+ {option.label}
|
|
|
|
|
+ </ToggleGroup.Item>
|
|
|
|
|
+ {/each}
|
|
|
|
|
+ </ToggleGroup.Root>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ {:else if form.modelCategory === 'embedding'}
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="embeddingDimensions">Embedding Dimensions</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="embeddingDimensions"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ min={1}
|
|
|
|
|
+ placeholder="1024"
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.embeddingDimensions}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="maxInputTokens">Max Input Tokens</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="maxInputTokens"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ min={0}
|
|
|
|
|
+ placeholder="128000"
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.maxInputTokens}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Field.Description>Maximum input length. Set to 0 for unlimited.</Field.Description>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="languages">Languages</Field.Label>
|
|
|
|
|
+ <ArrayInput {disabled} bind:value={form.languages} />
|
|
|
|
|
+ <Field.Description>e.g. English, Chinese, Spanish</Field.Description>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="tags">Tags</Field.Label>
|
|
|
|
|
+ <ArrayInput {disabled} bind:value={form.tags} />
|
|
|
|
|
+ <Field.Description>e.g. Reasoning, Tool Use, Code Generation</Field.Description>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ </Field.Set>
|
|
|
|
|
+ </Optional>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Managed panels -->
|
|
|
|
|
+ {#if form.mode === 'managed'}
|
|
|
|
|
+ <Card class="mb-4" title="Deployment">
|
|
|
|
|
+ <Field.Set>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="huggingFaceEndpoint">Hugging Face Endpoint</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="huggingFaceEndpoint"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="https://huggingface.co"
|
|
|
|
|
+ bind:value={form.huggingFaceEndpoint}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <div class="grid grid-cols-2 gap-4">
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="huggingFaceRepo">Hugging Face Repository</Field.Label>
|
|
|
|
|
+ <Input id="huggingFaceRepo" {disabled} bind:value={form.huggingFaceRepo} />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="huggingFaceRevision">Revision</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="huggingFaceRevision"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="main"
|
|
|
|
|
+ bind:value={form.huggingFaceRevision}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="huggingFaceRepoFileName">File</Field.Label>
|
|
|
|
|
+ <Input id="huggingFaceRepoFileName" {disabled} bind:value={form.huggingFaceFileName} />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Optional title="Runtime Settings">
|
|
|
|
|
+ <DeploymentForm {disabled} {runtimes} bind:form />
|
|
|
|
|
+ </Optional>
|
|
|
|
|
+ </Field.Set>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+
|
|
|
|
|
+ {#if form.mode === 'external'}
|
|
|
|
|
+ <Card class="mb-4" title={`Endpoint${form.mode === 'external' ? '' : ' (Optional)'}`}>
|
|
|
|
|
+ <Field.Set>
|
|
|
|
|
+ <div class="grid grid-cols-2 gap-4">
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="provider">Provider</Field.Label>
|
|
|
|
|
+ <Select.Root {disabled} type="single" bind:value={form.provider}>
|
|
|
|
|
+ <Select.Trigger id="provider" class="w-full">{providerLabel}</Select.Trigger>
|
|
|
|
|
+ <Select.Content>
|
|
|
|
|
+ {#each MODEL_PROVIDERS as p (p.value)}
|
|
|
|
|
+ <Select.Item label={p.label} value={p.value} />
|
|
|
|
|
+ {/each}
|
|
|
|
|
+ </Select.Content>
|
|
|
|
|
+ </Select.Root>
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="providerModel">Model ID</Field.Label>
|
|
|
|
|
+ <Input id="providerModel" {disabled} bind:value={form.providerModel} />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="apiBase">API Base</Field.Label>
|
|
|
|
|
+ <Input id="apiBase" {disabled} placeholder="Provider default" bind:value={form.apiBase} />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="apiVersion">API Version</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="apiVersion"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="Provider default"
|
|
|
|
|
+ bind:value={form.apiVersion}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <AuthForm {disabled} {workspaceId} bind:form />
|
|
|
|
|
+ </Field.Set>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+
|
|
|
|
|
+ {#if form.mode === 'managed' || form.modelCategory === 'language'}
|
|
|
|
|
+ <Card class="mb-4" title="Inference Settings">
|
|
|
|
|
+ <Field.Set>
|
|
|
|
|
+ {#if form.mode === 'external'}
|
|
|
|
|
+ {#if form.modelCategory === 'language'}
|
|
|
|
|
+ <Optional title="Default Sampling">
|
|
|
|
|
+ <div class="grid grid-cols-3 gap-4">
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="defaultTemperature">Temperature</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="defaultTemperature"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="0.8"
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.defaultTemperature}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="defaultMaxTokens">Max Tokens</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="defaultMaxTokens"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="Infinite"
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.defaultMaxTokens}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="defaultTopP">Top-P</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="defaultTopP"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="0.95"
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.defaultTopP}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Optional>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+ {:else if form.mode === 'managed'}
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="runtimeContextWindow">Context Window Size</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="runtimeContextWindow"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.runtimeContextWindow}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ {#if form.modelCategory === 'language'}
|
|
|
|
|
+ <Optional title="Runtime Settings">
|
|
|
|
|
+ <div class="grid grid-cols-3 gap-4">
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="runtimeTemperature">Temperature</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="runtimeTemperature"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="0.8"
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.runtimeTemperature}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="runtimeTopK">Top-K</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="runtimeTopK"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="40"
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.runtimeTopK}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ <Field.Field>
|
|
|
|
|
+ <Field.Label for="runtimeTopP">Top-P</Field.Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="runtimeTopP"
|
|
|
|
|
+ {disabled}
|
|
|
|
|
+ placeholder="0.95"
|
|
|
|
|
+ type="number"
|
|
|
|
|
+ bind:value={form.runtimeTopP}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Field.Field>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Optional>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+ {/if}
|
|
|
|
|
+ </Field.Set>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Footer actions -->
|
|
|
|
|
+ <div class="flex justify-end">
|
|
|
|
|
+ {@render panel()}
|
|
|
|
|
+ </div>
|
|
|
|
|
+</div>
|