Improve settings, allow model selection, fixes Suggestions: model choices, horizontal sliders with min/max value in settings #44

This commit is contained in:
Niek van der Maas 2023-03-17 18:03:07 +01:00
parent 7718f9d37f
commit dedb95c343
2 changed files with 104 additions and 13 deletions

View File

@ -2,7 +2,15 @@
//import { fetchEventSource } from "@microsoft/fetch-event-source"; //import { fetchEventSource } from "@microsoft/fetch-event-source";
import { apiKeyStorage, chatsStorage, addMessage, clearMessages } from "./Storage.svelte"; import { apiKeyStorage, chatsStorage, addMessage, clearMessages } from "./Storage.svelte";
import type { Request, Response, Message, Settings } from "./Types.svelte"; import {
type Request,
type Response,
type Message,
type Settings,
supportedModels,
type ResponseModels,
type SettingsSelect,
} from "./Types.svelte";
import Code from "./Code.svelte"; import Code from "./Code.svelte";
import { afterUpdate, onMount } from "svelte"; import { afterUpdate, onMount } from "svelte";
@ -19,40 +27,65 @@
let recording = false; let recording = false;
const settingsMap: Settings[] = [ const settingsMap: Settings[] = [
{
key: "model",
name: "Model",
default: "gpt-3.5-turbo",
options: supportedModels,
type: "select",
},
{ {
key: "temperature", key: "temperature",
name: "Sampling Temperature", name: "Sampling Temperature",
default: 1, default: 1,
min: 0,
max: 2,
step: 0.1,
type: "number", type: "number",
}, },
{ {
key: "top_p", key: "top_p",
name: "Nucleus Sampling", name: "Nucleus Sampling",
default: 1, default: 1,
min: 0,
max: 1,
step: 0.1,
type: "number", type: "number",
}, },
{ {
key: "n", key: "n",
name: "Number of Messages", name: "Number of Messages",
default: 1, default: 1,
min: 1,
max: 10,
step: 1,
type: "number", type: "number",
}, },
{ {
key: "max_tokens", key: "max_tokens",
name: "Max Tokens", name: "Max Tokens",
default: 0, default: 0,
min: 0,
max: 32768,
step: 1024,
type: "number", type: "number",
}, },
{ {
key: "presence_penalty", key: "presence_penalty",
name: "Presence Penalty", name: "Presence Penalty",
default: 0, default: 0,
min: -2,
max: 2,
step: 0.2,
type: "number", type: "number",
}, },
{ {
key: "frequency_penalty", key: "frequency_penalty",
name: "Frequency Penalty", name: "Frequency Penalty",
default: 0, default: 0,
min: -2,
max: 2,
step: 0.2,
type: "number", type: "number",
}, },
]; ];
@ -61,7 +94,7 @@
const token_price = 0.000002; // $0.002 per 1000 tokens const token_price = 0.000002; // $0.002 per 1000 tokens
// Focus the input on mount // Focus the input on mount
onMount(() => { onMount(async () => {
input.focus(); input.focus();
// Try to detect speech recognition support // Try to detect speech recognition support
@ -237,8 +270,23 @@
} }
}; };
const showSettings = () => { const showSettings = async () => {
settings.classList.add("is-active"); settings.classList.add("is-active");
// Load available models from OpenAI
const allModels = (await (
await fetch("https://api.openai.com/v1/models", {
method: "GET",
headers: {
Authorization: `Bearer ${$apiKeyStorage}`,
"Content-Type": "application/json",
},
})
).json()) as ResponseModels;
const filteredModels = supportedModels.filter((model) => allModels.data.find((m) => m.id === model));
// Update the models in the settings
(settingsMap[0] as SettingsSelect).options = filteredModels;
}; };
const closeSettings = () => { const closeSettings = () => {
@ -431,16 +479,29 @@
{#each settingsMap as setting} {#each settingsMap as setting}
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label is-normal"> <div class="field-label is-normal">
<label class="label" for="settings-temperature">{setting.name}</label> <label class="label" for="settings-{setting.key}">{setting.name}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
{#if setting.type === "number"}
<input <input
class="input" class="input"
type={setting.type} type={setting.type}
id="settings-{setting.key}" id="settings-{setting.key}"
min={setting.min}
max={setting.max}
step={setting.step}
placeholder={String(setting.default)} placeholder={String(setting.default)}
/> />
{:else if setting.type === "select"}
<div class="select">
<select id="settings-{setting.key}">
{#each setting.options as option}
<option value={option} selected={option == setting.default}>{option}</option>
{/each}
</select>
</div>
{/if}
</div> </div>
</div> </div>
</div> </div>

View File

@ -32,12 +32,35 @@
user?: string; user?: string;
}; };
// See: https://platform.openai.com/docs/models/model-endpoint-compatibility
export const supportedModels = [
"gpt-4",
"gpt-4-0314",
"gpt-4-32k",
"gpt-4-32k-0314",
"gpt-3.5-turbo",
"gpt-3.5-turbo-0301",
];
type Model = typeof supportedModels[number];
type SettingsNumber = {
type: "number";
default: number;
min: number;
max: number;
step: number;
};
export type SettingsSelect = {
type: "select";
default: Model;
options: Model[];
};
export type Settings = { export type Settings = {
key: string; key: string;
name: string; name: string;
default: number; } & (SettingsNumber | SettingsSelect);
type: "number";
};
type ResponseOK = { type ResponseOK = {
id: string; id: string;
@ -61,4 +84,11 @@
}; };
export type Response = ResponseOK & ResponseError; export type Response = ResponseOK & ResponseError;
export type ResponseModels = {
object: "list";
data: {
id: string;
}[];
};
</script> </script>