Tiny steps toward UI for hosts/endpoints/models
This commit is contained in:
parent
a9a49f490a
commit
cd1803ed16
|
@ -13,7 +13,7 @@
|
||||||
checkStateChange,
|
checkStateChange,
|
||||||
addChat
|
addChat
|
||||||
} from './Storage.svelte'
|
} from './Storage.svelte'
|
||||||
import { supportedModels, type Chat, type ChatSetting, type ResponseModels, type SettingSelect, type SelectOption, type ChatSettings } from './Types.svelte'
|
import type { Chat, ChatSetting, ResponseModels, SettingSelect, SelectOption, ChatSettings } from './Types.svelte'
|
||||||
import { errorNotice, sizeTextElements } from './Util.svelte'
|
import { errorNotice, sizeTextElements } from './Util.svelte'
|
||||||
import Fa from 'svelte-fa/src/fa.svelte'
|
import Fa from 'svelte-fa/src/fa.svelte'
|
||||||
import {
|
import {
|
||||||
|
@ -37,6 +37,7 @@
|
||||||
import { openModal } from 'svelte-modals'
|
import { openModal } from 'svelte-modals'
|
||||||
import PromptConfirm from './PromptConfirm.svelte'
|
import PromptConfirm from './PromptConfirm.svelte'
|
||||||
import { getApiBase, getEndpointModels } from './ApiUtil.svelte'
|
import { getApiBase, getEndpointModels } from './ApiUtil.svelte'
|
||||||
|
import { supportedModelKeys } from './Models.svelte'
|
||||||
|
|
||||||
export let chatId:number
|
export let chatId:number
|
||||||
export const show = () => { showSettings() }
|
export const show = () => { showSettings() }
|
||||||
|
@ -194,7 +195,7 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
).json()) as ResponseModels
|
).json()) as ResponseModels
|
||||||
const filteredModels = supportedModels.filter((model) => allModels.data.find((m) => m.id === model))
|
const filteredModels = supportedModelKeys.filter((model) => allModels.data.find((m) => m.id === model))
|
||||||
|
|
||||||
const modelOptions:SelectOption[] = filteredModels.reduce((a, m) => {
|
const modelOptions:SelectOption[] = filteredModels.reduce((a, m) => {
|
||||||
const o:SelectOption = {
|
const o:SelectOption = {
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
<script context="module" lang="ts">
|
||||||
|
import type { ModelDetail, Model } from './Types.svelte'
|
||||||
|
|
||||||
|
// Reference: https://openai.com/pricing#language-models
|
||||||
|
// Eventually we'll add API hosts and endpoints to this
|
||||||
|
const modelDetails : Record<string, ModelDetail> = {
|
||||||
|
'gpt-4-32k': {
|
||||||
|
prompt: 0.00006, // $0.06 per 1000 tokens prompt
|
||||||
|
completion: 0.00012, // $0.12 per 1000 tokens completion
|
||||||
|
max: 32768 // 32k max token buffer
|
||||||
|
},
|
||||||
|
'gpt-4': {
|
||||||
|
prompt: 0.00003, // $0.03 per 1000 tokens prompt
|
||||||
|
completion: 0.00006, // $0.06 per 1000 tokens completion
|
||||||
|
max: 8192 // 8k max token buffer
|
||||||
|
},
|
||||||
|
'gpt-3.5': {
|
||||||
|
prompt: 0.000002, // $0.002 per 1000 tokens prompt
|
||||||
|
completion: 0.000002, // $0.002 per 1000 tokens completion
|
||||||
|
max: 4096 // 4k max token buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const unknownDetail = {
|
||||||
|
prompt: 0,
|
||||||
|
completion: 0,
|
||||||
|
max: 4096
|
||||||
|
}
|
||||||
|
|
||||||
|
// See: https://platform.openai.com/docs/models/model-endpoint-compatibility
|
||||||
|
// Eventually we'll add UI for managing this
|
||||||
|
export const supportedModels : Record<string, ModelDetail> = {
|
||||||
|
'gpt-4': modelDetails['gpt-4'],
|
||||||
|
'gpt-4-0314': modelDetails['gpt-4'],
|
||||||
|
'gpt-4-32k': modelDetails['gpt-4-32k'],
|
||||||
|
'gpt-4-32k-0314': modelDetails['gpt-4-32k'],
|
||||||
|
'gpt-3.5-turbo': modelDetails['gpt-3.5'],
|
||||||
|
'gpt-3.5-turbo-0301': modelDetails['gpt-3.5']
|
||||||
|
}
|
||||||
|
|
||||||
|
const lookupList = {
|
||||||
|
...modelDetails,
|
||||||
|
...supportedModels
|
||||||
|
}
|
||||||
|
|
||||||
|
export const supportedModelKeys = Object.keys(supportedModels)
|
||||||
|
|
||||||
|
const tpCache : Record<string, ModelDetail> = {}
|
||||||
|
|
||||||
|
export const getModelDetail = (model: Model) => {
|
||||||
|
// First try to get exact match, then from cache
|
||||||
|
let r = supportedModels[model] || tpCache[model]
|
||||||
|
if (r) return r
|
||||||
|
// If no exact match, find closest match
|
||||||
|
const k = Object.keys(lookupList)
|
||||||
|
.sort((a, b) => b.length - a.length) // Longest to shortest for best match
|
||||||
|
.find((k) => model.startsWith(k))
|
||||||
|
if (k) {
|
||||||
|
r = lookupList[k]
|
||||||
|
} else {
|
||||||
|
r = unknownDetail
|
||||||
|
}
|
||||||
|
// Cache it so we don't need to do that again
|
||||||
|
tpCache[model] = r
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
|
@ -1,32 +1,11 @@
|
||||||
<script context="module" lang="ts">
|
<script context="module" lang="ts">
|
||||||
|
import { getModelDetail } from './Models.svelte'
|
||||||
import type { Message, Model, Usage } from './Types.svelte'
|
import type { Message, Model, Usage } from './Types.svelte'
|
||||||
import { encode } from 'gpt-tokenizer'
|
import { encode } from 'gpt-tokenizer'
|
||||||
|
|
||||||
// Reference: https://openai.com/pricing#language-models
|
|
||||||
// TODO: Move to settings of some type
|
|
||||||
const modelDetails : Record<string, [number, number, number]> = {
|
|
||||||
'gpt-4-32k': [0.00006, 0.00012, 32768], // $0.06 per 1000 tokens prompt, $0.12 per 1000 tokens completion, max 32k
|
|
||||||
'gpt-4': [0.00003, 0.00006, 8192], // $0.03 per 1000 tokens prompt, $0.06 per 1000 tokens completion, max 8k
|
|
||||||
'gpt-3.5': [0.000002, 0.000002, 4096] // $0.002 per 1000 tokens (both prompt and completion), max 4k
|
|
||||||
}
|
|
||||||
|
|
||||||
const tpCache = {}
|
|
||||||
const getModelDetail = (model: Model) => {
|
|
||||||
let r = tpCache[model]
|
|
||||||
if (r) return r
|
|
||||||
const k = Object.keys(modelDetails).find((k) => model.startsWith(k))
|
|
||||||
if (k) {
|
|
||||||
r = modelDetails[k]
|
|
||||||
} else {
|
|
||||||
r = [0, 0, 4096]
|
|
||||||
}
|
|
||||||
tpCache[model] = r
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getPrice = (tokens: Usage, model: Model): number => {
|
export const getPrice = (tokens: Usage, model: Model): number => {
|
||||||
const t = getModelDetail(model)
|
const t = getModelDetail(model)
|
||||||
return ((tokens.prompt_tokens * t[0]) + (tokens.completion_tokens * t[1]))
|
return ((tokens.prompt_tokens * t.prompt) + (tokens.completion_tokens * t.completion))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const countPromptTokens = (prompts:Message[], model:Model):number => {
|
export const countPromptTokens = (prompts:Message[], model:Model):number => {
|
||||||
|
@ -44,7 +23,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getModelMaxTokens = (model:Model):number => {
|
export const getModelMaxTokens = (model:Model):number => {
|
||||||
return getModelDetail(model)[2]
|
return getModelDetail(model).max
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
|
@ -1,15 +1,13 @@
|
||||||
<script context="module" lang="ts">
|
<script context="module" lang="ts">
|
||||||
// import type internal from "stream";
|
import type { supportedModelKeys } from './Models.svelte'
|
||||||
|
|
||||||
export const supportedModels = [ // See: https://platform.openai.com/docs/models/model-endpoint-compatibility
|
export type Model = typeof supportedModelKeys[number];
|
||||||
'gpt-4',
|
|
||||||
'gpt-4-0314',
|
export type ModelDetail = {
|
||||||
'gpt-4-32k',
|
prompt: number;
|
||||||
'gpt-4-32k-0314',
|
completion: number;
|
||||||
'gpt-3.5-turbo',
|
max: number;
|
||||||
'gpt-3.5-turbo-0301'
|
};
|
||||||
]
|
|
||||||
export type Model = typeof supportedModels[number];
|
|
||||||
|
|
||||||
export type Usage = {
|
export type Usage = {
|
||||||
completion_tokens: number;
|
completion_tokens: number;
|
||||||
|
|
Loading…
Reference in New Issue