mirror of
https://github.com/wassname/chatGPTBox.git
synced 2026-06-27 17:47:56 +08:00
WIP, custom API Modes
This commit is contained in:
@@ -3,7 +3,13 @@ import PropTypes from 'prop-types'
|
||||
import Browser from 'webextension-polyfill'
|
||||
import InputBox from '../InputBox'
|
||||
import ConversationItem from '../ConversationItem'
|
||||
import { createElementAtPosition, isFirefox, isMobile, isSafari } from '../../utils'
|
||||
import {
|
||||
createElementAtPosition,
|
||||
isFirefox,
|
||||
isMobile,
|
||||
isSafari,
|
||||
modelNameToDesc,
|
||||
} from '../../utils'
|
||||
import {
|
||||
ArchiveIcon,
|
||||
DesktopDownloadIcon,
|
||||
@@ -16,7 +22,7 @@ import FileSaver from 'file-saver'
|
||||
import { render } from 'preact'
|
||||
import FloatingToolbar from '../FloatingToolbar'
|
||||
import { useClampWindowSize } from '../../hooks/use-clamp-window-size'
|
||||
import { bingWebModelKeys, getUserConfig, ModelMode, Models } from '../../config/index.mjs'
|
||||
import { bingWebModelKeys, getUserConfig, Models } from '../../config/index.mjs'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import DeleteButton from '../DeleteButton'
|
||||
import { useConfig } from '../../hooks/use-config.mjs'
|
||||
@@ -370,14 +376,7 @@ function ConversationCard(props) {
|
||||
}}
|
||||
>
|
||||
{config.activeApiModes.map((modelName) => {
|
||||
let desc
|
||||
if (modelName.includes('-')) {
|
||||
const splits = modelName.split('-')
|
||||
if (splits[0] in Models)
|
||||
desc = `${t(Models[splits[0]].desc)} (${t(ModelMode[splits[1]])})`
|
||||
} else {
|
||||
if (modelName in Models) desc = t(Models[modelName].desc)
|
||||
}
|
||||
const desc = modelNameToDesc(modelName, t)
|
||||
if (desc)
|
||||
return (
|
||||
<option
|
||||
|
||||
@@ -82,6 +82,73 @@ export const poeWebModelKeys = [
|
||||
]
|
||||
export const moonshotApiModelKeys = ['moonshot_v1_8k', 'moonshot_v1_32k', 'moonshot_v1_128k']
|
||||
|
||||
export const AlwaysCustomGroups = [
|
||||
'ollamaApiModelKeys',
|
||||
'customApiModelKeys',
|
||||
'azureOpenAiApiModelKeys',
|
||||
]
|
||||
export const CustomUrlGroups = ['customApiModelKeys']
|
||||
export const CustomApiKeyGroups = ['customApiModelKeys']
|
||||
export const ModelGroups = {
|
||||
chatgptWebModelKeys: {
|
||||
value: chatgptWebModelKeys,
|
||||
desc: 'ChatGPT (Web)',
|
||||
},
|
||||
claudeWebModelKeys: {
|
||||
value: claudeWebModelKeys,
|
||||
desc: 'Claude.ai (Web)',
|
||||
},
|
||||
moonshotWebModelKeys: {
|
||||
value: moonshotWebModelKeys,
|
||||
desc: 'Kimi.Moonshot (Web)',
|
||||
},
|
||||
bingWebModelKeys: {
|
||||
value: bingWebModelKeys,
|
||||
desc: 'Bing (Web)',
|
||||
},
|
||||
bardWebModelKeys: {
|
||||
value: bardWebModelKeys,
|
||||
desc: 'Gemini (Web)',
|
||||
},
|
||||
|
||||
chatgptApiModelKeys: {
|
||||
value: chatgptApiModelKeys,
|
||||
desc: 'ChatGPT (API)',
|
||||
},
|
||||
claudeApiModelKeys: {
|
||||
value: claudeApiModelKeys,
|
||||
desc: 'Claude.ai (API)',
|
||||
},
|
||||
moonshotApiModelKeys: {
|
||||
value: moonshotApiModelKeys,
|
||||
desc: 'Kimi.Moonshot (API)',
|
||||
},
|
||||
chatglmApiModelKeys: {
|
||||
value: chatglmApiModelKeys,
|
||||
desc: 'ChatGLM (API)',
|
||||
},
|
||||
ollamaApiModelKeys: {
|
||||
value: ollamaApiModelKeys,
|
||||
desc: 'Ollama (API)',
|
||||
},
|
||||
azureOpenAiApiModelKeys: {
|
||||
value: azureOpenAiApiModelKeys,
|
||||
desc: 'ChatGPT (Azure API)',
|
||||
},
|
||||
gptApiModelKeys: {
|
||||
value: gptApiModelKeys,
|
||||
desc: 'GPT Completion (API)',
|
||||
},
|
||||
githubThirdPartyApiModelKeys: {
|
||||
value: githubThirdPartyApiModelKeys,
|
||||
desc: 'Github Third Party Waylaidwanderer (API)',
|
||||
},
|
||||
customApiModelKeys: {
|
||||
value: customApiModelKeys,
|
||||
desc: 'Custom Model',
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} Model
|
||||
* @property {string} value
|
||||
@@ -290,6 +357,17 @@ export const defaultConfig = {
|
||||
'ollamaModel',
|
||||
'azureOpenAi',
|
||||
],
|
||||
customApiModes: [
|
||||
{
|
||||
groupName: '',
|
||||
itemName: '',
|
||||
isCustom: false,
|
||||
customName: '',
|
||||
customUrl: '',
|
||||
apiKey: '',
|
||||
active: false,
|
||||
},
|
||||
],
|
||||
activeSelectionTools: ['translate', 'summary', 'polish', 'code', 'ask'],
|
||||
customSelectionTools: [
|
||||
{
|
||||
|
||||
+174
-21
@@ -1,43 +1,196 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import PropTypes from 'prop-types'
|
||||
import { ModelMode, Models } from '../../config/index.mjs'
|
||||
import { apiModeToModelName, modelNameToDesc } from '../../utils/index.mjs'
|
||||
import { PencilIcon, TrashIcon } from '@primer/octicons-react'
|
||||
import { useState } from 'react'
|
||||
import {
|
||||
AlwaysCustomGroups,
|
||||
CustomApiKeyGroups,
|
||||
CustomUrlGroups,
|
||||
ModelGroups,
|
||||
} from '../../config/index.mjs'
|
||||
|
||||
ApiModes.propTypes = {
|
||||
config: PropTypes.object.isRequired,
|
||||
updateConfig: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
const defaultApiMode = {
|
||||
groupName: 'chatgptWebModelKeys',
|
||||
itemName: 'chatgptFree35',
|
||||
isCustom: false,
|
||||
customName: '',
|
||||
customUrl: '',
|
||||
apiKey: '',
|
||||
active: true,
|
||||
}
|
||||
|
||||
export function ApiModes({ config, updateConfig }) {
|
||||
const { t } = useTranslation()
|
||||
const [editing, setEditing] = useState(false)
|
||||
const [editingApiMode, setEditingApiMode] = useState(defaultApiMode)
|
||||
const [editingIndex, setEditingIndex] = useState(-1)
|
||||
|
||||
const editingComponent = (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', '--spacing': '4px' }}>
|
||||
<div style={{ display: 'flex', gap: '12px' }}>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
setEditing(false)
|
||||
}}
|
||||
>
|
||||
{t('Cancel')}
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
if (editingIndex === -1) {
|
||||
updateConfig({
|
||||
customApiModes: [...config.customApiModes, editingApiMode],
|
||||
})
|
||||
} else {
|
||||
const customApiModes = [...config.customApiModes]
|
||||
customApiModes[editingIndex] = editingApiMode
|
||||
updateConfig({ customApiModes })
|
||||
}
|
||||
setEditing(false)
|
||||
}}
|
||||
>
|
||||
{t('Save')}
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: '4px', alignItems: 'center', whiteSpace: 'noWrap' }}>
|
||||
{t('Type')}
|
||||
<select
|
||||
value={editingApiMode.groupName}
|
||||
onChange={(e) => {
|
||||
const groupName = e.target.value
|
||||
const itemName = ModelGroups[groupName].value[0]
|
||||
setEditingApiMode({ ...editingApiMode, groupName, itemName })
|
||||
}}
|
||||
>
|
||||
{Object.entries(ModelGroups).map(([groupName, { desc }]) => (
|
||||
<option key={groupName} value={groupName}>
|
||||
{t(desc)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: '4px', alignItems: 'center', whiteSpace: 'noWrap' }}>
|
||||
{t('Mode')}
|
||||
<select
|
||||
value={editingApiMode.itemName}
|
||||
onChange={(e) => {
|
||||
const itemName = e.target.value
|
||||
const isCustom = itemName === 'custom'
|
||||
setEditingApiMode({ ...editingApiMode, itemName, isCustom })
|
||||
}}
|
||||
>
|
||||
{ModelGroups[editingApiMode.groupName].value.map((itemName) => (
|
||||
<option key={itemName} value={itemName}>
|
||||
{modelNameToDesc(itemName, t)}
|
||||
</option>
|
||||
))}
|
||||
{!AlwaysCustomGroups.includes(editingApiMode.groupName) && (
|
||||
<option value="custom">{t('Custom')}</option>
|
||||
)}
|
||||
</select>
|
||||
{(editingApiMode.isCustom || AlwaysCustomGroups.includes(editingApiMode.groupName)) && (
|
||||
<input
|
||||
type="text"
|
||||
value={editingApiMode.customName}
|
||||
placeholder={t('Model Name')}
|
||||
onChange={(e) => setEditingApiMode({ ...editingApiMode, customName: e.target.value })}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{CustomUrlGroups.includes(editingApiMode.groupName) &&
|
||||
(editingApiMode.isCustom || AlwaysCustomGroups.includes(editingApiMode.groupName)) && (
|
||||
<input
|
||||
type="text"
|
||||
value={editingApiMode.customUrl}
|
||||
placeholder={t('API Url')}
|
||||
onChange={(e) => setEditingApiMode({ ...editingApiMode, customUrl: e.target.value })}
|
||||
/>
|
||||
)}
|
||||
{CustomApiKeyGroups.includes(editingApiMode.groupName) &&
|
||||
(editingApiMode.isCustom || AlwaysCustomGroups.includes(editingApiMode.groupName)) && (
|
||||
<input
|
||||
type="password"
|
||||
value={editingApiMode.apiKey}
|
||||
placeholder={t('API Key')}
|
||||
onChange={(e) => setEditingApiMode({ ...editingApiMode, apiKey: e.target.value })}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
{config.apiModes.map((modelName) => {
|
||||
let desc
|
||||
if (modelName.includes('-')) {
|
||||
const splits = modelName.split('-')
|
||||
if (splits[0] in Models)
|
||||
desc = `${t(Models[splits[0]].desc)} (${t(ModelMode[splits[1]])})`
|
||||
} else {
|
||||
if (modelName in Models) desc = t(Models[modelName].desc)
|
||||
}
|
||||
if (desc)
|
||||
return (
|
||||
<label key={modelName}>
|
||||
{config.customApiModes.map(
|
||||
(apiMode, index) =>
|
||||
apiMode.groupName &&
|
||||
apiMode.itemName &&
|
||||
(editing && editingIndex === index ? (
|
||||
editingComponent
|
||||
) : (
|
||||
<label key={index} style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={config.activeApiModes.includes(modelName)}
|
||||
checked={apiMode.active}
|
||||
onChange={(e) => {
|
||||
const checked = e.target.checked
|
||||
const activeApiModes = config.activeApiModes.filter((i) => i !== modelName)
|
||||
if (checked) activeApiModes.push(modelName)
|
||||
updateConfig({ activeApiModes })
|
||||
const customApiModes = [...config.customApiModes]
|
||||
customApiModes[index] = { ...apiMode, active: e.target.checked }
|
||||
updateConfig({ customApiModes })
|
||||
}}
|
||||
/>
|
||||
{desc}
|
||||
{modelNameToDesc(apiModeToModelName(apiMode), t)}
|
||||
<div style={{ flexGrow: 1 }} />
|
||||
<div style={{ display: 'flex', gap: '12px' }}>
|
||||
<div
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
setEditing(true)
|
||||
setEditingApiMode(apiMode)
|
||||
setEditingIndex(index)
|
||||
}}
|
||||
>
|
||||
<PencilIcon />
|
||||
</div>
|
||||
<div
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
const customApiModes = [...config.customApiModes]
|
||||
customApiModes.splice(index, 1)
|
||||
updateConfig({ customApiModes })
|
||||
}}
|
||||
>
|
||||
<TrashIcon />
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
)
|
||||
})}
|
||||
)),
|
||||
)}
|
||||
<div style={{ height: '30px' }} />
|
||||
{editing ? (
|
||||
editingIndex === -1 ? (
|
||||
editingComponent
|
||||
) : undefined
|
||||
) : (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
setEditing(true)
|
||||
setEditingApiMode(defaultApiMode)
|
||||
setEditingIndex(-1)
|
||||
}}
|
||||
>
|
||||
{t('New')}
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useState } from 'react'
|
||||
import FileSaver from 'file-saver'
|
||||
import { openUrl } from '../../utils/index.mjs'
|
||||
import { openUrl, modelNameToDesc } from '../../utils/index.mjs'
|
||||
import {
|
||||
isUsingOpenAiApiKey,
|
||||
isUsingAzureOpenAi,
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
isUsingGithubThirdPartyApi,
|
||||
isUsingMultiModeModel,
|
||||
ModelMode,
|
||||
Models,
|
||||
ThemeMode,
|
||||
TriggerMode,
|
||||
isUsingMoonshotApi,
|
||||
@@ -161,14 +160,7 @@ export function GeneralPart({ config, updateConfig }) {
|
||||
}}
|
||||
>
|
||||
{config.activeApiModes.map((modelName) => {
|
||||
let desc
|
||||
if (modelName.includes('-')) {
|
||||
const splits = modelName.split('-')
|
||||
if (splits[0] in Models)
|
||||
desc = `${t(Models[splits[0]].desc)} (${t(ModelMode[splits[1]])})`
|
||||
} else {
|
||||
if (modelName in Models) desc = t(Models[modelName].desc)
|
||||
}
|
||||
const desc = modelNameToDesc(modelName, t)
|
||||
if (desc)
|
||||
return (
|
||||
<option
|
||||
|
||||
@@ -62,7 +62,7 @@ export function SelectionTools({ config, updateConfig }) {
|
||||
</button>
|
||||
</div>
|
||||
{errorMessage && <div style={{ color: 'red' }}>{errorMessage}</div>}
|
||||
<div style={{ display: 'flex', gap: '4px', alignItems: 'center' }}>
|
||||
<div style={{ display: 'flex', gap: '4px', alignItems: 'center', whiteSpace: 'noWrap' }}>
|
||||
{t('Name')}
|
||||
<input
|
||||
type="text"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import BingAIClient from '../clients/bing/index.mjs'
|
||||
import { getUserConfig } from '../../config/index.mjs'
|
||||
import { pushRecord, setAbortController } from './shared.mjs'
|
||||
import { isCustomModelName, modelNameToCustomPart } from '../../utils/model-name-convert.mjs'
|
||||
|
||||
/**
|
||||
* @param {Runtime.Port} port
|
||||
@@ -19,7 +20,7 @@ export async function generateAnswersWithBingWebApi(
|
||||
const { controller, messageListener, disconnectListener } = setAbortController(port)
|
||||
const config = await getUserConfig()
|
||||
let modelMode
|
||||
if (session.modelName.includes('-')) modelMode = session.modelName.split('-')[1]
|
||||
if (isCustomModelName(session.modelName)) modelMode = modelNameToCustomPart(session.modelName)
|
||||
else modelMode = config.modelMode
|
||||
|
||||
console.debug('mode', modelMode)
|
||||
|
||||
@@ -9,6 +9,7 @@ import { v4 as uuidv4 } from 'uuid'
|
||||
import { t } from 'i18next'
|
||||
import { sha3_512 } from 'js-sha3'
|
||||
import randomInt from 'random-int'
|
||||
import { modelNameToValue } from '../../utils/model-name-convert.mjs'
|
||||
|
||||
async function request(token, method, path, data) {
|
||||
const apiUrl = (await getUserConfig()).customChatGptWebApiUrl
|
||||
@@ -233,7 +234,7 @@ export async function generateAnswersWithChatgptWebApi(port, question, session,
|
||||
isNeedWebsocket(accessToken).catch(() => undefined),
|
||||
])
|
||||
console.debug('models', models)
|
||||
const selectedModel = Models[session.modelName].value
|
||||
const selectedModel = modelNameToValue(session.modelName)
|
||||
const usedModel =
|
||||
models && models.includes(selectedModel) ? selectedModel : Models[chatgptWebModelKeys[0]].value
|
||||
console.debug('usedModel', usedModel)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getUserConfig, Models } from '../../config/index.mjs'
|
||||
import { getUserConfig } from '../../config/index.mjs'
|
||||
import { pushRecord, setAbortController } from './shared.mjs'
|
||||
import { fetchSSE } from '../../utils/fetch-sse.mjs'
|
||||
import { isEmpty } from 'lodash-es'
|
||||
import { getConversationPairs } from '../../utils/get-conversation-pairs.mjs'
|
||||
import { modelNameToValue } from '../../utils/model-name-convert.mjs'
|
||||
|
||||
/**
|
||||
* @param {Runtime.Port} port
|
||||
@@ -31,7 +32,7 @@ export async function generateAnswersWithClaudeApi(port, question, session) {
|
||||
'x-api-key': config.claudeApiKey,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: Models[modelName].value,
|
||||
model: modelNameToValue(modelName),
|
||||
messages: prompt,
|
||||
stream: true,
|
||||
max_tokens: config.maxResponseTokenLength,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { pushRecord, setAbortController } from './shared.mjs'
|
||||
import Claude from '../clients/claude'
|
||||
import { Models } from '../../config/index.mjs'
|
||||
import { modelNameToValue } from '../../utils/model-name-convert.mjs'
|
||||
|
||||
/**
|
||||
* @param {Runtime.Port} port
|
||||
@@ -35,7 +35,7 @@ export async function generateAnswersWithClaudeWebApi(
|
||||
const params = {
|
||||
progress: progressFunc,
|
||||
done: doneFunc,
|
||||
model: Models[modelName].value,
|
||||
model: modelNameToValue(modelName),
|
||||
signal: controller.signal,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { pushRecord, setAbortController } from './shared.mjs'
|
||||
import { Models, setUserConfig } from '../../config/index.mjs'
|
||||
import { setUserConfig } from '../../config/index.mjs'
|
||||
import { fetchSSE } from '../../utils/fetch-sse'
|
||||
import { isEmpty } from 'lodash-es'
|
||||
import { modelNameToValue } from '../../utils/model-name-convert.mjs'
|
||||
|
||||
export class MoonshotWeb {
|
||||
/**
|
||||
@@ -596,7 +597,7 @@ export async function generateAnswersWithMoonshotWebApi(
|
||||
const params = {
|
||||
progress: progressFunc,
|
||||
done: doneFunc,
|
||||
model: Models[modelName].value,
|
||||
model: modelNameToValue(modelName),
|
||||
signal: controller.signal,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// api version
|
||||
|
||||
import { Models, getUserConfig } from '../../config/index.mjs'
|
||||
import { getUserConfig } from '../../config/index.mjs'
|
||||
import { fetchSSE } from '../../utils/fetch-sse.mjs'
|
||||
import { getConversationPairs } from '../../utils/get-conversation-pairs.mjs'
|
||||
import { isEmpty } from 'lodash-es'
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
pushRecord,
|
||||
setAbortController,
|
||||
} from './shared.mjs'
|
||||
import { modelNameToValue } from '../../utils/model-name-convert.mjs'
|
||||
|
||||
/**
|
||||
* @param {Browser.Runtime.Port} port
|
||||
@@ -54,7 +55,7 @@ export async function generateAnswersWithGptCompletionApi(
|
||||
},
|
||||
body: JSON.stringify({
|
||||
prompt: prompt,
|
||||
model: Models[modelName].value,
|
||||
model: modelNameToValue(modelName),
|
||||
stream: true,
|
||||
max_tokens: config.maxResponseTokenLength,
|
||||
temperature: config.temperature,
|
||||
@@ -154,7 +155,7 @@ export async function generateAnswersWithChatgptApiCompat(
|
||||
},
|
||||
body: JSON.stringify({
|
||||
messages: prompt,
|
||||
model: Models[modelName].value,
|
||||
model: modelNameToValue(modelName),
|
||||
stream: true,
|
||||
max_tokens: config.maxResponseTokenLength,
|
||||
temperature: config.temperature,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Models } from '../config/index.mjs'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { modelNameToDesc } from '../utils/model-name-convert.mjs'
|
||||
|
||||
/**
|
||||
* @typedef {object} Session
|
||||
@@ -54,7 +54,7 @@ export function initSession({
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
|
||||
aiName: modelName ? Models[modelName].desc : null,
|
||||
aiName: modelName ? modelNameToDesc(modelName) : null,
|
||||
modelName,
|
||||
|
||||
autoClean,
|
||||
|
||||
@@ -3,11 +3,11 @@ import {
|
||||
claudeWebModelKeys,
|
||||
clearOldAccessToken,
|
||||
getUserConfig,
|
||||
Models,
|
||||
setAccessToken,
|
||||
} from '../config/index.mjs'
|
||||
import Browser from 'webextension-polyfill'
|
||||
import { t } from 'i18next'
|
||||
import { modelNameToDesc } from '../utils/model-name-convert.mjs'
|
||||
|
||||
export async function getChatGptAccessToken() {
|
||||
await clearOldAccessToken()
|
||||
@@ -103,7 +103,7 @@ export function registerPortListener(executor) {
|
||||
if (!session) return
|
||||
const config = await getUserConfig()
|
||||
if (!session.modelName) session.modelName = config.modelName
|
||||
if (!session.aiName) session.aiName = Models[session.modelName].desc
|
||||
if (!session.aiName) session.aiName = modelNameToDesc(session.modelName)
|
||||
port.postMessage({ session })
|
||||
try {
|
||||
await executor(session, port, config)
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
// SOFTWARE.
|
||||
|
||||
import { encode } from '@nem035/gpt-3-encoder'
|
||||
import { getUserConfig, Models } from '../config/index.mjs'
|
||||
import { getUserConfig } from '../config/index.mjs'
|
||||
import { modelNameToDesc } from './model-name-convert.mjs'
|
||||
|
||||
const clamp = (v, min, max) => {
|
||||
return Math.min(Math.max(v, min), max)
|
||||
@@ -35,7 +36,7 @@ export async function cropText(
|
||||
tiktoken = true,
|
||||
) {
|
||||
const userConfig = await getUserConfig()
|
||||
const k = Models[userConfig.modelName].desc.match(/[- (]*([0-9]+)k/)?.[1]
|
||||
const k = modelNameToDesc(userConfig.modelName).match(/[- (]*([0-9]+)k/)?.[1]
|
||||
if (k) {
|
||||
maxLength = Number(k) * 1000
|
||||
maxLength -= 100 + clamp(userConfig.maxResponseTokenLength, 1, maxLength - 1000)
|
||||
|
||||
@@ -19,3 +19,4 @@ export * from './set-element-position-in-viewport'
|
||||
export * from './eventsource-parser.mjs'
|
||||
export * from './update-ref-height'
|
||||
export * from './wait-for-element-to-exist-and-select.mjs'
|
||||
export * from './model-name-convert.mjs'
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import { AlwaysCustomGroups, ModelGroups, ModelMode, Models } from '../config/index.mjs'
|
||||
|
||||
export function modelNameToDesc(modelName, t) {
|
||||
if (!t) t = (x) => x
|
||||
if (modelName in Models) return t(Models[modelName].desc)
|
||||
|
||||
let desc = modelName
|
||||
if (isCustomModelName(modelName)) {
|
||||
const presetPart = modelNameToPresetPart(modelName)
|
||||
const customPart = modelNameToCustomPart(modelName)
|
||||
if (presetPart in Models) {
|
||||
if (customPart in ModelMode)
|
||||
desc = `${t(Models[presetPart].desc)} (${t(ModelMode[customPart])})`
|
||||
else desc = `${t(Models[presetPart].desc)} (${customPart})`
|
||||
} else if (presetPart in ModelGroups) {
|
||||
desc = `${t(ModelGroups[presetPart].desc)} (${customPart})`
|
||||
}
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
export function modelNameToPresetPart(modelName) {
|
||||
if (isCustomModelName(modelName)) {
|
||||
return modelName.split('-')[0]
|
||||
} else {
|
||||
return modelName
|
||||
}
|
||||
}
|
||||
|
||||
export function modelNameToCustomPart(modelName) {
|
||||
if (isCustomModelName(modelName)) {
|
||||
return modelName.substring(modelName.indexOf('-') + 1)
|
||||
} else {
|
||||
return modelName
|
||||
}
|
||||
}
|
||||
|
||||
export function modelNameToValue(modelName) {
|
||||
if (modelName in Models) return Models[modelName].value
|
||||
|
||||
return modelNameToCustomPart(modelName)
|
||||
}
|
||||
|
||||
export function isCustomModelName(modelName) {
|
||||
return modelName.includes('-')
|
||||
}
|
||||
|
||||
export function modelNameToApiMode(modelName) {
|
||||
const presetPart = modelNameToPresetPart(modelName)
|
||||
const found =
|
||||
Object.entries(ModelGroups).find(([k]) => presetPart === k) ||
|
||||
Object.entries(ModelGroups).find(([, g]) => presetPart in g.value)
|
||||
if (found) {
|
||||
const [groupName] = found
|
||||
const isCustom = isCustomModelName(modelName)
|
||||
let customName = ''
|
||||
if (isCustom) customName = modelNameToCustomPart()
|
||||
return {
|
||||
groupName,
|
||||
itemName: presetPart,
|
||||
isCustom,
|
||||
customName,
|
||||
customUrl: '',
|
||||
apiKey: '',
|
||||
active: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function apiModeToModelName(apiMode) {
|
||||
if (AlwaysCustomGroups.includes(apiMode.groupName))
|
||||
return apiMode.groupName + '-' + apiMode.customName
|
||||
|
||||
if (apiMode.isCustom) {
|
||||
if (apiMode.itemName === 'custom') return apiMode.groupName + '-' + apiMode.customName
|
||||
return apiMode.itemName + '-' + apiMode.customName
|
||||
}
|
||||
|
||||
return apiMode.itemName
|
||||
}
|
||||
Reference in New Issue
Block a user