Model Runtime (#1858)
Co-authored-by: StyleZhang <jasonapring2015@outlook.com> Co-authored-by: Garfield Dai <dai.hai@foxmail.com> Co-authored-by: chenhe <guchenhe@gmail.com> Co-authored-by: jyong <jyong@dify.ai> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Yeuoly <admin@srmxy.cn>
This commit is contained in:
parent
e91dd28a76
commit
d069c668f8
807 changed files with 171310 additions and 23806 deletions
265
web/app/components/app/annotation/mock-data.ts
Normal file
265
web/app/components/app/annotation/mock-data.ts
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
import type { AnnotationItem, HitHistoryItem } from './type'
|
||||
|
||||
const list: AnnotationItem[] = [
|
||||
// create some mock data
|
||||
{
|
||||
id: '1',
|
||||
question: 'What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?',
|
||||
answer: 'What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?',
|
||||
created_at: '2020-01-01T00:00:00Z',
|
||||
hit_count: 1,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
question: 'What is the capital of Canada?',
|
||||
answer: 'Ottawa',
|
||||
created_at: '2020-01-02T00:00:00Z',
|
||||
hit_count: 2,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
question: 'What is the capital of Mexico?',
|
||||
answer: 'Mexico City',
|
||||
created_at: '2020-01-03T00:00:00Z',
|
||||
hit_count: 3,
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
question: 'What is the capital of Brazil?',
|
||||
answer: 'Brasilia',
|
||||
created_at: '2020-01-04T00:00:00Z',
|
||||
hit_count: 4,
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
question: 'What is the capital of Argentina?',
|
||||
answer: 'Buenos Aires',
|
||||
created_at: '2020-01-05T00:00:00Z',
|
||||
hit_count: 5,
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
question: 'What is the capital of Chile?',
|
||||
answer: 'Santiago',
|
||||
created_at: '2020-01-06T00:00:00Z',
|
||||
hit_count: 6,
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
question: 'What is the capital of Peru?',
|
||||
answer: 'Lima',
|
||||
created_at: '2020-01-07T00:00:00Z',
|
||||
hit_count: 7,
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
question: 'What is the capital of Ecuador?',
|
||||
answer: 'Quito',
|
||||
created_at: '2020-01-08T00:00:00Z',
|
||||
hit_count: 8,
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
question: 'What is the capital of Colombia?',
|
||||
answer: 'Bogota',
|
||||
created_at: '2020-01-09T00:00:00Z',
|
||||
hit_count: 9,
|
||||
},
|
||||
]
|
||||
|
||||
export const hitHistoryList: HitHistoryItem[] = [
|
||||
// create some mock data. source can only be: API/Webapp/Explore/Debug
|
||||
{
|
||||
id: '1',
|
||||
question: 'What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?What is the capital of the United States?',
|
||||
source: 'API',
|
||||
score: 0.9,
|
||||
created_at: '2020-01-01T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
question: 'What is the capital of Canada?',
|
||||
source: 'Webapp',
|
||||
score: 0.8,
|
||||
created_at: '2020-01-02T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
question: 'What is the capital of Mexico?',
|
||||
source: 'Explore',
|
||||
score: 0.7,
|
||||
created_at: '2020-01-03T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
question: 'What is the capital of Brazil?',
|
||||
source: 'Debug',
|
||||
score: 0.6,
|
||||
created_at: '2020-01-04T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
question: 'What is the capital of Argentina?',
|
||||
source: 'API',
|
||||
score: 0.5,
|
||||
created_at: '2020-01-05T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
question: 'What is the capital of Chile?',
|
||||
source: 'Webapp',
|
||||
score: 0.4,
|
||||
created_at: '2020-01-06T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
question: 'What is the capital of Peru?',
|
||||
source: 'Explore',
|
||||
score: 0.3,
|
||||
created_at: '2020-01-07T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
question: 'What is the capital of Ecuador?',
|
||||
source: 'Debug',
|
||||
score: 0.2,
|
||||
created_at: '2020-01-08T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
question: 'What is the capital of Colombia?',
|
||||
source: 'API',
|
||||
score: 0.1,
|
||||
created_at: '2020-01-09T00:00:00Z',
|
||||
},
|
||||
// make more mock data
|
||||
{
|
||||
id: '10',
|
||||
question: 'What is the capital of the United States?',
|
||||
source: 'API',
|
||||
score: 0.9,
|
||||
created_at: '2020-01-01T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '11',
|
||||
question: 'What is the capital of Canada?',
|
||||
source: 'Webapp',
|
||||
score: 0.8,
|
||||
created_at: '2020-01-02T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '12',
|
||||
question: 'What is the capital of Mexico?',
|
||||
source: 'Explore',
|
||||
score: 0.7,
|
||||
created_at: '2020-01-03T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '13',
|
||||
question: 'What is the capital of Brazil?',
|
||||
source: 'Debug',
|
||||
score: 0.6,
|
||||
created_at: '2020-01-04T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '14',
|
||||
question: 'What is the capital of Argentina?',
|
||||
source: 'API',
|
||||
score: 0.5,
|
||||
created_at: '2020-01-05T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '15',
|
||||
question: 'What is the capital of Chile?',
|
||||
source: 'Webapp',
|
||||
score: 0.4,
|
||||
created_at: '2020-01-06T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '16',
|
||||
question: 'What is the capital of Peru?',
|
||||
source: 'Explore',
|
||||
score: 0.3,
|
||||
created_at: '2020-01-07T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '17',
|
||||
question: 'What is the capital of Ecuador?',
|
||||
source: 'Debug',
|
||||
score: 0.2,
|
||||
created_at: '2020-01-08T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '18',
|
||||
question: 'What is the capital of Colombia?',
|
||||
source: 'API',
|
||||
score: 0.1,
|
||||
created_at: '2020-01-09T00:00:00Z',
|
||||
},
|
||||
// make more mock data
|
||||
{
|
||||
id: '19',
|
||||
question: 'What is the capital of the United States?',
|
||||
source: 'API',
|
||||
score: 0.9,
|
||||
created_at: '2020-01-01T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '20',
|
||||
question: 'What is the capital of Canada?',
|
||||
source: 'Webapp',
|
||||
score: 0.8,
|
||||
created_at: '2020-01-02T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '21',
|
||||
question: 'What is the capital of Mexico?',
|
||||
source: 'Explore',
|
||||
score: 0.7,
|
||||
created_at: '2020-01-03T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '22',
|
||||
question: 'What is the capital of Brazil?',
|
||||
source: 'Debug',
|
||||
score: 0.6,
|
||||
created_at: '2020-01-04T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '23',
|
||||
question: 'What is the capital of Argentina?',
|
||||
source: 'API',
|
||||
score: 0.5,
|
||||
created_at: '2020-01-05T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '24',
|
||||
question: 'What is the capital of Chile?',
|
||||
source: 'Webapp',
|
||||
score: 0.4,
|
||||
created_at: '2020-01-06T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '25',
|
||||
question: 'What is the capital of Peru?',
|
||||
source: 'Explore',
|
||||
score: 0.3,
|
||||
created_at: '2020-01-07T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '26',
|
||||
question: 'What is the capital of Ecuador?',
|
||||
source: 'Debug',
|
||||
score: 0.2,
|
||||
created_at: '2020-01-08T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '27',
|
||||
question: 'What is the capital of Colombia?',
|
||||
source: 'API',
|
||||
score: 0.1,
|
||||
created_at: '2020-01-09T00:00:00Z',
|
||||
},
|
||||
]
|
||||
|
||||
export default list
|
||||
|
|
@ -72,7 +72,16 @@ export type IChatItem = {
|
|||
|
||||
export type MessageEnd = {
|
||||
id: string
|
||||
retriever_resources?: CitationItem[]
|
||||
metadata: {
|
||||
retriever_resources?: CitationItem[]
|
||||
annotation_reply: {
|
||||
id: string
|
||||
account: {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type MessageReplace = {
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@ import { useBoolean, useClickAway, useGetState } from 'ahooks'
|
|||
import { InformationCircleIcon } from '@heroicons/react/24/outline'
|
||||
import produce from 'immer'
|
||||
import ParamItem from './param-item'
|
||||
import ModelIcon from './model-icon'
|
||||
import ModelName from './model-name'
|
||||
import ModelModeTypeLabel from './model-mode-type-label'
|
||||
import { SlidersH } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
|
||||
import Radio from '@/app/components/base/radio'
|
||||
import Panel from '@/app/components/base/panel'
|
||||
|
|
@ -24,17 +21,19 @@ import { Target04 } from '@/app/components/base/icons/src/vender/solid/general'
|
|||
import { Sliders02 } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices'
|
||||
import { fetchModelParams } from '@/service/debug'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-page/model-selector'
|
||||
import { ModelType, ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
import type { ModelModeType } from '@/types/app'
|
||||
import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon'
|
||||
import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
||||
import { useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
export type IConfigModelProps = {
|
||||
isAdvancedMode: boolean
|
||||
mode: string
|
||||
modelId: string
|
||||
provider: ProviderEnum
|
||||
setModel: (model: { id: string; provider: ProviderEnum; mode: ModelModeType; features: string[] }) => void
|
||||
provider: string
|
||||
setModel: (model: { id: string; provider: string; mode: ModelModeType; features: string[] }) => void
|
||||
completionParams: CompletionParams
|
||||
onCompletionParamsChange: (newParams: CompletionParams) => void
|
||||
disabled: boolean
|
||||
|
|
@ -50,11 +49,16 @@ const ConfigModel: FC<IConfigModelProps> = ({
|
|||
disabled,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { textGenerationModelList } = useProviderContext()
|
||||
const [isShowConfig, { setFalse: hideConfig, toggle: toogleShowConfig }] = useBoolean(false)
|
||||
const [maxTokenSettingTipVisible, setMaxTokenSettingTipVisible] = useState(false)
|
||||
const configContentRef = React.useRef(null)
|
||||
const currModel = textGenerationModelList.find(item => item.model_name === modelId)
|
||||
const {
|
||||
currentProvider,
|
||||
currentModel: currModel,
|
||||
textGenerationModelList,
|
||||
} = useTextGenerationCurrentProviderAndModelAndModelList(
|
||||
{ provider, model: modelId },
|
||||
)
|
||||
|
||||
const media = useBreakpoints()
|
||||
const isMobile = media === MediaType.mobile
|
||||
|
|
@ -81,7 +85,7 @@ const ConfigModel: FC<IConfigModelProps> = ({
|
|||
setAllParams(newAllParams)
|
||||
}
|
||||
})()
|
||||
}, [provider, modelId])
|
||||
}, [provider, modelId, allParams, setAllParams])
|
||||
|
||||
useClickAway(() => {
|
||||
hideConfig()
|
||||
|
|
@ -89,7 +93,7 @@ const ConfigModel: FC<IConfigModelProps> = ({
|
|||
|
||||
const selectedModel = { name: modelId } // options.find(option => option.id === modelId)
|
||||
|
||||
const ensureModelParamLoaded = (provider: ProviderEnum, modelId: string) => {
|
||||
const ensureModelParamLoaded = (provider: string, modelId: string) => {
|
||||
return new Promise<void>((resolve) => {
|
||||
if (getAllParams()[provider]?.[modelId]) {
|
||||
resolve()
|
||||
|
|
@ -126,13 +130,13 @@ const ConfigModel: FC<IConfigModelProps> = ({
|
|||
return adjustedValue
|
||||
}
|
||||
|
||||
const handleSelectModel = ({ id, provider: nextProvider, mode, features }: { id: string; provider: ProviderEnum; mode: ModelModeType; features: string[] }) => {
|
||||
const handleSelectModel = ({ id, provider: nextProvider, mode, features }: { id: string; provider: string; mode: ModelModeType; features: string[] }) => {
|
||||
return async () => {
|
||||
const prevParamsRule = getAllParams()[provider]?.[modelId]
|
||||
|
||||
setModel({
|
||||
id,
|
||||
provider: nextProvider || ProviderEnum.openai,
|
||||
provider: nextProvider || 'openai',
|
||||
mode,
|
||||
features,
|
||||
})
|
||||
|
|
@ -269,26 +273,34 @@ const ConfigModel: FC<IConfigModelProps> = ({
|
|||
|
||||
const max = currParams.max_tokens.max
|
||||
const isSupportMaxToken = currParams.max_tokens.enabled
|
||||
if (isSupportMaxToken && currModel?.model_provider.provider_name !== ProviderEnum.anthropic && completionParams.max_tokens > max * 2 / 3)
|
||||
if (isSupportMaxToken && currentProvider?.provider !== 'anthropic' && completionParams.max_tokens > max * 2 / 3)
|
||||
setMaxTokenSettingTipVisible(true)
|
||||
else
|
||||
setMaxTokenSettingTipVisible(false)
|
||||
}, [currParams, completionParams.max_tokens, setMaxTokenSettingTipVisible])
|
||||
}, [currParams, completionParams.max_tokens, setMaxTokenSettingTipVisible, currentProvider])
|
||||
return (
|
||||
<div className='relative' ref={configContentRef}>
|
||||
<div
|
||||
className={cn('flex items-center border h-8 px-2 space-x-2 rounded-lg', disabled ? diabledStyle : ableStyle)}
|
||||
onClick={() => !disabled && toogleShowConfig()}
|
||||
>
|
||||
<ModelIcon
|
||||
className='!w-5 !h-5'
|
||||
modelId={modelId}
|
||||
providerName={provider}
|
||||
/>
|
||||
<div className='text-[13px] text-gray-900 font-medium'>
|
||||
<ModelName modelId={selectedModel.name} modelDisplayName={currModel?.model_display_name} />
|
||||
</div>
|
||||
{isAdvancedMode && <ModelModeTypeLabel type={currModel?.model_mode as ModelModeType} isHighlight />}
|
||||
{
|
||||
currentProvider && (
|
||||
<ModelIcon
|
||||
className='!w-5 !h-5'
|
||||
provider={currentProvider}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
currModel && (
|
||||
<ModelName
|
||||
className='text-gray-900'
|
||||
modelItem={currModel}
|
||||
showMode={isAdvancedMode}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{disabled ? <InformationCircleIcon className='w-4 h-4 text-[#F79009]' /> : <SlidersH className='w-4 h-4 text-indigo-600' />}
|
||||
</div>
|
||||
{isShowConfig && (
|
||||
|
|
@ -312,21 +324,16 @@ const ConfigModel: FC<IConfigModelProps> = ({
|
|||
<div className="flex items-center justify-between my-5 h-9">
|
||||
<div>{t('appDebug.modelConfig.model')}</div>
|
||||
<ModelSelector
|
||||
isShowModelModeType={isAdvancedMode}
|
||||
isShowAddModel
|
||||
popClassName='right-0'
|
||||
triggerIconSmall
|
||||
value={{
|
||||
modelName: modelId,
|
||||
providerName: provider,
|
||||
}}
|
||||
modelType={ModelType.textGeneration}
|
||||
onChange={(model) => {
|
||||
defaultModel={{ model: modelId, provider }}
|
||||
modelList={textGenerationModelList}
|
||||
onSelect={({ provider, model }) => {
|
||||
const targetProvider = textGenerationModelList.find(modelItem => modelItem.provider === provider)
|
||||
const targetModelItem = targetProvider?.models.find(modelItem => modelItem.model === model)
|
||||
handleSelectModel({
|
||||
id: model.model_name,
|
||||
provider: model.model_provider.provider_name as ProviderEnum,
|
||||
mode: model.model_mode,
|
||||
features: model.features,
|
||||
id: model,
|
||||
provider,
|
||||
mode: targetModelItem?.model_properties.mode as ModelModeType,
|
||||
features: targetModelItem?.features || [],
|
||||
})()
|
||||
}}
|
||||
/>
|
||||
|
|
@ -336,7 +343,7 @@ const ConfigModel: FC<IConfigModelProps> = ({
|
|||
)}
|
||||
|
||||
{/* Tone type */}
|
||||
{[ProviderEnum.openai, ProviderEnum.azure_openai].includes(provider) && (
|
||||
{['openai', 'azure_openai'].includes(provider) && (
|
||||
<div className="mt-5 mb-4">
|
||||
<div className="mb-3 text-sm text-gray-900">{t('appDebug.modelConfig.setTone')}</div>
|
||||
<Radio.Group className={cn('!rounded-lg', toneTabBgClassName)} value={toneId} onChange={handleToneChange}>
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import cn from 'classnames'
|
||||
import {
|
||||
OpenaiGreen,
|
||||
OpenaiViolet,
|
||||
} from '@/app/components/base/icons/src/public/llm'
|
||||
import { ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
|
||||
import ProviderConfig from '@/app/components/header/account-setting/model-page/configs'
|
||||
|
||||
export type IModelIconProps = {
|
||||
modelId: string
|
||||
providerName: ProviderEnum
|
||||
className?: string
|
||||
}
|
||||
|
||||
const ModelIcon: FC<IModelIconProps> = ({ modelId, providerName, className }) => {
|
||||
let Icon = <OpenaiGreen className='w-full h-full' />
|
||||
if (providerName === ProviderEnum.openai)
|
||||
Icon = modelId.includes('gpt-4') ? <OpenaiViolet className='w-full h-full' /> : <OpenaiGreen className='w-full h-full' />
|
||||
else
|
||||
Icon = ProviderConfig[providerName]?.selector.icon
|
||||
|
||||
return (
|
||||
<div className={cn(className, 'w-4 h-4')}>
|
||||
{Icon}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(ModelIcon)
|
||||
|
|
@ -21,10 +21,10 @@ import ConfigPrompt from '@/app/components/app/configuration/config-prompt'
|
|||
import ConfigVar from '@/app/components/app/configuration/config-var'
|
||||
import type { CitationConfig, ModelConfig, ModerationConfig, MoreLikeThisConfig, PromptVariable, SpeechToTextConfig, SuggestedQuestionsAfterAnswerConfig } from '@/models/debug'
|
||||
import { AppType, ModelModeType } from '@/types/app'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import ConfigParamModal from '@/app/components/app/configuration/toolbox/annotation/config-param-modal'
|
||||
import AnnotationFullModal from '@/app/components/billing/annotation-full/modal'
|
||||
import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
const Config: FC = () => {
|
||||
const {
|
||||
|
|
@ -55,7 +55,7 @@ const Config: FC = () => {
|
|||
setModerationConfig,
|
||||
} = useContext(ConfigContext)
|
||||
const isChatApp = mode === AppType.chat
|
||||
const { speech2textDefaultModel } = useProviderContext()
|
||||
const { data: speech2textDefaultModel } = useDefaultModel(4)
|
||||
const { setShowModerationSettingModal } = useModalContext()
|
||||
|
||||
const promptTemplate = modelConfig.configs.prompt_template
|
||||
|
|
|
|||
|
|
@ -12,15 +12,14 @@ import Modal from '@/app/components/base/modal'
|
|||
import Button from '@/app/components/base/button'
|
||||
import RadioCard from '@/app/components/base/radio-card/simple'
|
||||
import { RETRIEVE_TYPE } from '@/types/app'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-page/model-selector'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { ModelType } from '@/app/components/header/account-setting/model-page/declarations'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { DATASET_DEFAULT } from '@/config'
|
||||
import {
|
||||
MultiPathRetrieval,
|
||||
NTo1Retrieval,
|
||||
} from '@/app/components/base/icons/src/public/common'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
||||
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
const ParamsConfig: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
|
@ -38,11 +37,11 @@ const ParamsConfig: FC = () => {
|
|||
retrieval_model: value,
|
||||
})
|
||||
}
|
||||
|
||||
const {
|
||||
rerankDefaultModel,
|
||||
isRerankDefaultModelVaild,
|
||||
} = useProviderContext()
|
||||
modelList: rerankModelList,
|
||||
defaultModel: rerankDefaultModel,
|
||||
currentModel: isRerankDefaultModelVaild,
|
||||
} = useModelListAndDefaultModelAndCurrentProviderAndModel(3)
|
||||
|
||||
const rerankModel = (() => {
|
||||
if (tempDataSetConfigs.reranking_model) {
|
||||
|
|
@ -53,8 +52,8 @@ const ParamsConfig: FC = () => {
|
|||
}
|
||||
else if (rerankDefaultModel) {
|
||||
return {
|
||||
provider_name: rerankDefaultModel.model_provider.provider_name,
|
||||
model_name: rerankDefaultModel.model_name,
|
||||
provider_name: rerankDefaultModel.provider.provider,
|
||||
model_name: rerankDefaultModel.model,
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
|
@ -104,8 +103,8 @@ const ParamsConfig: FC = () => {
|
|||
const config = { ...tempDataSetConfigs }
|
||||
if (config.retrieval_model === RETRIEVE_TYPE.multiWay && !config.reranking_model) {
|
||||
config.reranking_model = {
|
||||
reranking_provider_name: rerankDefaultModel?.model_provider.provider_name,
|
||||
reranking_model_name: rerankDefaultModel?.model_name,
|
||||
reranking_provider_name: rerankDefaultModel?.provider,
|
||||
reranking_model_name: rerankDefaultModel?.model,
|
||||
} as any
|
||||
}
|
||||
setDatasetConfigs(config)
|
||||
|
|
@ -163,18 +162,17 @@ const ParamsConfig: FC = () => {
|
|||
<div className='leading-[32px] text-[13px] font-medium text-gray-900'>{t('common.modelProvider.rerankModel.key')}</div>
|
||||
<div>
|
||||
<ModelSelector
|
||||
popClassName='!max-w-[100%] !w-full'
|
||||
value={rerankModel && { providerName: rerankModel.provider_name, modelName: rerankModel.model_name } as any}
|
||||
modelType={ModelType.reranking}
|
||||
onChange={(v) => {
|
||||
defaultModel={rerankModel && { provider: rerankModel?.provider_name, model: rerankModel?.model_name }}
|
||||
onSelect={(v) => {
|
||||
setTempDataSetConfigs({
|
||||
...tempDataSetConfigs,
|
||||
reranking_model: {
|
||||
reranking_provider_name: v.model_provider.provider_name,
|
||||
reranking_model_name: v.model_name,
|
||||
reranking_provider_name: v.provider,
|
||||
reranking_model_name: v.model,
|
||||
},
|
||||
})
|
||||
}}
|
||||
modelList={rerankModelList}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@ import cn from 'classnames'
|
|||
import { BookOpenIcon } from '@heroicons/react/24/outline'
|
||||
import IndexMethodRadio from '@/app/components/datasets/settings/index-method-radio'
|
||||
import Button from '@/app/components/base/button'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-page/model-selector'
|
||||
import type { ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
|
||||
import { ModelType } from '@/app/components/header/account-setting/model-page/declarations'
|
||||
import type { DataSet } from '@/models/datasets'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { updateDatasetSetting } from '@/service/datasets'
|
||||
|
|
@ -17,10 +14,14 @@ import { XClose } from '@/app/components/base/icons/src/vender/line/general'
|
|||
import type { RetrievalConfig } from '@/types/app'
|
||||
import RetrievalMethodConfig from '@/app/components/datasets/common/retrieval-method-config'
|
||||
import EconomicalRetrievalMethodConfig from '@/app/components/datasets/common/economical-retrieval-method-config'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { ensureRerankModelSelected, isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model'
|
||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
|
||||
import PermissionsRadio from '@/app/components/datasets/settings/permissions-radio'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
||||
import {
|
||||
useModelList,
|
||||
useModelListAndDefaultModelAndCurrentProviderAndModel,
|
||||
} from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
type SettingsModalProps = {
|
||||
currentDataset: DataSet
|
||||
|
|
@ -41,6 +42,12 @@ const SettingsModal: FC<SettingsModalProps> = ({
|
|||
onCancel,
|
||||
onSave,
|
||||
}) => {
|
||||
const { data: embeddingsModelList } = useModelList(2)
|
||||
const {
|
||||
modelList: rerankModelList,
|
||||
defaultModel: rerankDefaultModel,
|
||||
currentModel: isRerankDefaultModelVaild,
|
||||
} = useModelListAndDefaultModelAndCurrentProviderAndModel(3)
|
||||
const { t } = useTranslation()
|
||||
const { notify } = useToastContext()
|
||||
const ref = useRef(null)
|
||||
|
|
@ -51,12 +58,6 @@ const SettingsModal: FC<SettingsModalProps> = ({
|
|||
const [indexMethod, setIndexMethod] = useState(currentDataset.indexing_technique)
|
||||
const [retrievalConfig, setRetrievalConfig] = useState(localeCurrentDataset?.retrieval_model_dict as RetrievalConfig)
|
||||
|
||||
const {
|
||||
rerankDefaultModel,
|
||||
isRerankDefaultModelVaild,
|
||||
rerankModelList,
|
||||
} = useProviderContext()
|
||||
|
||||
const handleValueChange = (type: string, value: string) => {
|
||||
setLocaleCurrentDataset({ ...localeCurrentDataset, [type]: value })
|
||||
}
|
||||
|
|
@ -73,7 +74,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
|
|||
if (
|
||||
!isReRankModelSelected({
|
||||
rerankDefaultModel,
|
||||
isRerankDefaultModelVaild,
|
||||
isRerankDefaultModelVaild: !!isRerankDefaultModelVaild,
|
||||
rerankModelList,
|
||||
retrievalConfig,
|
||||
indexMethod,
|
||||
|
|
@ -204,12 +205,11 @@ const SettingsModal: FC<SettingsModalProps> = ({
|
|||
<div className='w-full h-9 rounded-lg bg-gray-100 opacity-60'>
|
||||
<ModelSelector
|
||||
readonly
|
||||
value={{
|
||||
providerName: localeCurrentDataset.embedding_model_provider as ProviderEnum,
|
||||
modelName: localeCurrentDataset.embedding_model,
|
||||
defaultModel={{
|
||||
provider: localeCurrentDataset.embedding_model_provider,
|
||||
model: localeCurrentDataset.embedding_model,
|
||||
}}
|
||||
modelType={ModelType.embeddings}
|
||||
onChange={() => {}}
|
||||
modelList={embeddingsModelList}
|
||||
/>
|
||||
</div>
|
||||
<div className='mt-2 w-full text-xs leading-6 text-gray-500'>
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ import type { ModelConfig as BackendModelConfig, VisionFile } from '@/types/app'
|
|||
import { promptVariablesToUserInputsForm } from '@/utils/model-config'
|
||||
import TextGeneration from '@/app/components/app/text-generate/item'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import type { Inputs } from '@/models/debug'
|
||||
import { fetchFileUploadConfig } from '@/service/common'
|
||||
import type { Annotation as AnnotationType } from '@/models/log'
|
||||
import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
type IDebug = {
|
||||
hasSetAPIKEY: boolean
|
||||
onSetting: () => void
|
||||
|
|
@ -69,7 +70,7 @@ const Debug: FC<IDebug> = ({
|
|||
visionConfig,
|
||||
annotationConfig,
|
||||
} = useContext(ConfigContext)
|
||||
const { speech2textDefaultModel } = useProviderContext()
|
||||
const { data: speech2textDefaultModel } = useDefaultModel(4)
|
||||
const [chatList, setChatList, getChatList] = useGetState<IChatItem[]>([])
|
||||
const chatListDomRef = useRef<HTMLDivElement>(null)
|
||||
const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig)
|
||||
|
|
@ -346,7 +347,27 @@ const Debug: FC<IDebug> = ({
|
|||
}
|
||||
},
|
||||
onMessageEnd: (messageEnd) => {
|
||||
responseItem.citation = messageEnd.retriever_resources
|
||||
// TODO
|
||||
if (messageEnd.metadata?.annotation_reply) {
|
||||
responseItem.id = messageEnd.id
|
||||
responseItem.annotation = ({
|
||||
id: messageEnd.metadata.annotation_reply.id,
|
||||
authorName: messageEnd.metadata.annotation_reply.account.name,
|
||||
} as AnnotationType)
|
||||
const newListWithAnswer = produce(
|
||||
getChatList().filter(item => item.id !== responseItem.id && item.id !== placeholderAnswerId),
|
||||
(draft) => {
|
||||
if (!draft.find(item => item.id === questionId))
|
||||
draft.push({ ...questionItem })
|
||||
|
||||
draft.push({
|
||||
...responseItem,
|
||||
})
|
||||
})
|
||||
setChatList(newListWithAnswer)
|
||||
return
|
||||
}
|
||||
responseItem.citation = messageEnd.metadata?.retriever_resources || []
|
||||
|
||||
const newListWithAnswer = produce(
|
||||
getChatList().filter(item => item.id !== responseItem.id && item.id !== placeholderAnswerId),
|
||||
|
|
@ -362,6 +383,7 @@ const Debug: FC<IDebug> = ({
|
|||
responseItem.content = messageReplace.answer
|
||||
},
|
||||
onAnnotationReply: (annotationReply) => {
|
||||
// TODO: temp debug
|
||||
responseItem.id = annotationReply.id
|
||||
responseItem.content = annotationReply.answer
|
||||
responseItem.annotation = ({
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import { useState } from 'react'
|
||||
import { clone } from 'lodash-es'
|
||||
import produce from 'immer'
|
||||
import type { ChatPromptConfig, CompletionParams, CompletionPromptConfig, ConversationHistoriesRole, PromptItem } from '@/models/debug'
|
||||
import type { ChatPromptConfig, CompletionPromptConfig, ConversationHistoriesRole, PromptItem } from '@/models/debug'
|
||||
import { PromptMode } from '@/models/debug'
|
||||
import { AppType, ModelModeType } from '@/types/app'
|
||||
import { DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/config'
|
||||
import { PRE_PROMPT_PLACEHOLDER_TEXT, checkHasContextBlock, checkHasHistoryBlock, checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants'
|
||||
import { fetchPromptTemplate } from '@/service/debug'
|
||||
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
|
||||
type Param = {
|
||||
appMode: string
|
||||
|
|
@ -16,8 +17,8 @@ type Param = {
|
|||
prePrompt: string
|
||||
onUserChangedPrompt: () => void
|
||||
hasSetDataSet: boolean
|
||||
completionParams: CompletionParams
|
||||
setCompletionParams: (params: CompletionParams) => void
|
||||
completionParams: FormValue
|
||||
setCompletionParams: (params: FormValue) => void
|
||||
setStop: (stop: string[]) => void
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import useAdvancedPromptConfig from './hooks/use-advanced-prompt-config'
|
|||
import EditHistoryModal from './config-prompt/conversation-histroy/edit-modal'
|
||||
import type {
|
||||
AnnotationReplyConfig,
|
||||
CompletionParams,
|
||||
DatasetConfigs,
|
||||
Inputs,
|
||||
ModelConfig,
|
||||
|
|
@ -29,11 +28,11 @@ import type { ExternalDataTool } from '@/models/common'
|
|||
import type { DataSet } from '@/models/datasets'
|
||||
import type { ModelConfig as BackendModelConfig, VisionSettings } from '@/types/app'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import ConfigModel from '@/app/components/app/configuration/config-model'
|
||||
// import ConfigModel from '@/app/components/app/configuration/config-model'
|
||||
import Config from '@/app/components/app/configuration/config'
|
||||
import Debug from '@/app/components/app/configuration/debug'
|
||||
import Confirm from '@/app/components/base/confirm'
|
||||
import { ModelFeature, ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
|
||||
import { ModelFeatureEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { fetchAppDetail, updateAppModelConfig } from '@/service/apps'
|
||||
import { promptVariablesToUserInputsForm, userInputsFormToPromptVariables } from '@/utils/model-config'
|
||||
|
|
@ -48,10 +47,13 @@ import I18n from '@/context/i18n'
|
|||
import { useModalContext } from '@/context/modal-context'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
import Drawer from '@/app/components/base/drawer'
|
||||
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
|
||||
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
type PublichConfig = {
|
||||
modelConfig: ModelConfig
|
||||
completionParams: CompletionParams
|
||||
completionParams: FormValue
|
||||
}
|
||||
|
||||
const Configuration: FC = () => {
|
||||
|
|
@ -112,16 +114,9 @@ const Configuration: FC = () => {
|
|||
const [externalDataToolsConfig, setExternalDataToolsConfig] = useState<ExternalDataTool[]>([])
|
||||
const [inputs, setInputs] = useState<Inputs>({})
|
||||
const [query, setQuery] = useState('')
|
||||
const [completionParams, doSetCompletionParams] = useState<CompletionParams>({
|
||||
max_tokens: 16,
|
||||
temperature: 1, // 0-2
|
||||
top_p: 1,
|
||||
presence_penalty: 1, // -2-2
|
||||
frequency_penalty: 1, // -2-2
|
||||
stop: [],
|
||||
})
|
||||
const [completionParams, doSetCompletionParams] = useState<FormValue>({})
|
||||
const [tempStop, setTempStop, getTempStop] = useGetState<string[]>([])
|
||||
const setCompletionParams = (value: CompletionParams) => {
|
||||
const setCompletionParams = (value: FormValue) => {
|
||||
const params = { ...value }
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
|
|
@ -133,7 +128,7 @@ const Configuration: FC = () => {
|
|||
}
|
||||
|
||||
const [modelConfig, doSetModelConfig] = useState<ModelConfig>({
|
||||
provider: ProviderEnum.openai,
|
||||
provider: 'openai',
|
||||
model_id: 'gpt-3.5-turbo',
|
||||
mode: ModelModeType.unset,
|
||||
configs: {
|
||||
|
|
@ -223,28 +218,21 @@ const Configuration: FC = () => {
|
|||
})
|
||||
}
|
||||
|
||||
const { textGenerationModelList } = useProviderContext()
|
||||
const currModel = textGenerationModelList.find(item => item.model_name === modelConfig.model_id)
|
||||
const hasSetCustomAPIKEY = !!textGenerationModelList?.find(({ model_provider: provider }) => {
|
||||
if (provider.provider_type === 'system' && provider.quota_type === 'paid')
|
||||
return true
|
||||
|
||||
if (provider.provider_type === 'custom')
|
||||
return true
|
||||
|
||||
return false
|
||||
})
|
||||
const isTrailFinished = !hasSetCustomAPIKEY && textGenerationModelList
|
||||
.filter(({ model_provider: provider }) => provider.quota_type === 'trial')
|
||||
.every(({ model_provider: provider }) => {
|
||||
const { quota_used, quota_limit } = provider
|
||||
return quota_used === quota_limit
|
||||
})
|
||||
const { hasSettedApiKey } = useProviderContext()
|
||||
const {
|
||||
currentModel: currModel,
|
||||
textGenerationModelList,
|
||||
} = useTextGenerationCurrentProviderAndModelAndModelList(
|
||||
{
|
||||
provider: modelConfig.provider,
|
||||
model: modelConfig.model_id,
|
||||
},
|
||||
)
|
||||
|
||||
// Fill old app data missing model mode.
|
||||
useEffect(() => {
|
||||
if (hasFetchedDetail && !modelModeType) {
|
||||
const mode = textGenerationModelList.find(({ model_name }) => model_name === modelConfig.model_id)?.model_mode
|
||||
const mode = currModel?.model_properties.mode as (ModelModeType | undefined)
|
||||
if (mode) {
|
||||
const newModelConfig = produce(modelConfig, (draft: ModelConfig) => {
|
||||
draft.mode = mode
|
||||
|
|
@ -252,9 +240,7 @@ const Configuration: FC = () => {
|
|||
setModelConfig(newModelConfig)
|
||||
}
|
||||
}
|
||||
}, [textGenerationModelList, hasFetchedDetail])
|
||||
|
||||
const hasSetAPIKEY = hasSetCustomAPIKEY || !isTrailFinished
|
||||
}, [textGenerationModelList, hasFetchedDetail, modelModeType, currModel, modelConfig])
|
||||
|
||||
const [promptMode, doSetPromptMode] = useState(PromptMode.simple)
|
||||
const isAdvancedMode = promptMode === PromptMode.advanced
|
||||
|
|
@ -295,11 +281,11 @@ const Configuration: FC = () => {
|
|||
})
|
||||
|
||||
const setModel = async ({
|
||||
id: modelId,
|
||||
modelId,
|
||||
provider,
|
||||
mode: modeMode,
|
||||
features,
|
||||
}: { id: string; provider: ProviderEnum; mode: ModelModeType; features: string[] }) => {
|
||||
}: { modelId: string; provider: string; mode: string; features: string[] }) => {
|
||||
if (isAdvancedMode) {
|
||||
const appMode = mode
|
||||
|
||||
|
|
@ -321,11 +307,11 @@ const Configuration: FC = () => {
|
|||
const newModelConfig = produce(modelConfig, (draft: ModelConfig) => {
|
||||
draft.provider = provider
|
||||
draft.model_id = modelId
|
||||
draft.mode = modeMode
|
||||
draft.mode = modeMode as ModelModeType
|
||||
})
|
||||
|
||||
setModelConfig(newModelConfig)
|
||||
const supportVision = features && features.includes(ModelFeature.vision)
|
||||
const supportVision = features && features.includes(ModelFeatureEnum.vision)
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
setVisionConfig({
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
|
|
@ -334,7 +320,7 @@ const Configuration: FC = () => {
|
|||
}, true)
|
||||
}
|
||||
|
||||
const isShowVisionConfig = !!currModel?.features.includes(ModelFeature.vision)
|
||||
const isShowVisionConfig = !!currModel?.features?.includes(ModelFeatureEnum.vision)
|
||||
const [visionConfig, doSetVisionConfig] = useState({
|
||||
enabled: false,
|
||||
number_limits: 2,
|
||||
|
|
@ -566,8 +552,8 @@ const Configuration: FC = () => {
|
|||
return (
|
||||
<ConfigContext.Provider value={{
|
||||
appId,
|
||||
hasSetAPIKEY,
|
||||
isTrailFinished,
|
||||
hasSetAPIKEY: hasSettedApiKey,
|
||||
isTrailFinished: false,
|
||||
mode,
|
||||
modelModeType,
|
||||
promptMode,
|
||||
|
|
@ -660,17 +646,17 @@ const Configuration: FC = () => {
|
|||
|
||||
<div className='flex items-center flex-wrap gap-y-2 gap-x-2'>
|
||||
{/* Model and Parameters */}
|
||||
<ConfigModel
|
||||
<ModelParameterModal
|
||||
isAdvancedMode={isAdvancedMode}
|
||||
mode={mode}
|
||||
provider={modelConfig.provider as ProviderEnum}
|
||||
provider={modelConfig.provider}
|
||||
completionParams={completionParams}
|
||||
modelId={modelConfig.model_id}
|
||||
setModel={setModel}
|
||||
onCompletionParamsChange={(newParams: CompletionParams) => {
|
||||
setModel={setModel as any}
|
||||
onCompletionParamsChange={(newParams: FormValue) => {
|
||||
setCompletionParams(newParams)
|
||||
}}
|
||||
disabled={!hasSetAPIKEY}
|
||||
disabled={!hasSettedApiKey}
|
||||
/>
|
||||
<div className='w-[1px] h-[14px] bg-gray-200'></div>
|
||||
<Button onClick={() => setShowConfirm(true)} className='shrink-0 mr-2 w-[70px] !h-8 !text-[13px] font-medium'>{t('appDebug.operation.resetConfig')}</Button>
|
||||
|
|
@ -689,7 +675,7 @@ const Configuration: FC = () => {
|
|||
</div>
|
||||
{!isMobile && <div className="relative w-1/2 grow h-full overflow-y-auto py-4 px-6 bg-gray-50 flex flex-col rounded-tl-2xl border-t border-l" style={{ borderColor: 'rgba(0, 0, 0, 0.02)' }}>
|
||||
<Debug
|
||||
hasSetAPIKEY={hasSetAPIKEY}
|
||||
hasSetAPIKEY={hasSettedApiKey}
|
||||
onSetting={() => setShowAccountSettingModal({ payload: 'provider' })}
|
||||
inputs={inputs}
|
||||
/>
|
||||
|
|
@ -744,7 +730,7 @@ const Configuration: FC = () => {
|
|||
{isMobile && (
|
||||
<Drawer showClose isOpen={isShowDebugPanel} onClose={hideDebugPanel} mask footer={null} panelClassname='!bg-gray-50'>
|
||||
<Debug
|
||||
hasSetAPIKEY={hasSetAPIKEY}
|
||||
hasSetAPIKEY={hasSettedApiKey}
|
||||
onSetting={() => setShowAccountSettingModal({ payload: 'provider' })}
|
||||
inputs={inputs}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@ import ScoreSlider from '../score-slider'
|
|||
import { Item } from './config-param'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { ModelType } from '@/app/components/header/account-setting/model-page/declarations'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-page/model-selector/portal-select'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import type { AnnotationReplyConfig } from '@/models/debug'
|
||||
import { ANNOTATION_DEFAULT } from '@/config'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
||||
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
type Props = {
|
||||
appId: string
|
||||
|
|
@ -34,9 +33,10 @@ const ConfigParamModal: FC<Props> = ({
|
|||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const {
|
||||
embeddingsDefaultModel,
|
||||
isEmbeddingsDefaultModelValid,
|
||||
} = useProviderContext()
|
||||
modelList: embeddingsModelList,
|
||||
defaultModel: embeddingsDefaultModel,
|
||||
currentModel: isEmbeddingsDefaultModelValid,
|
||||
} = useModelListAndDefaultModelAndCurrentProviderAndModel(2)
|
||||
const [annotationConfig, setAnnotationConfig] = useState(oldAnnotationConfig)
|
||||
|
||||
const [isLoading, setLoading] = useState(false)
|
||||
|
|
@ -47,8 +47,8 @@ const ConfigParamModal: FC<Props> = ({
|
|||
}
|
||||
: (embeddingsDefaultModel
|
||||
? {
|
||||
providerName: embeddingsDefaultModel.model_provider.provider_name,
|
||||
modelName: embeddingsDefaultModel.model_name,
|
||||
providerName: embeddingsDefaultModel.provider.provider,
|
||||
modelName: embeddingsDefaultModel.model,
|
||||
}
|
||||
: undefined))
|
||||
const onHide = () => {
|
||||
|
|
@ -57,7 +57,7 @@ const ConfigParamModal: FC<Props> = ({
|
|||
}
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!embeddingModel || !embeddingModel.modelName || (embeddingModel.modelName === embeddingsDefaultModel?.model_name && !isEmbeddingsDefaultModelValid)) {
|
||||
if (!embeddingModel || !embeddingModel.modelName || (embeddingModel.modelName === embeddingsDefaultModel?.model && !isEmbeddingsDefaultModelValid)) {
|
||||
Toast.notify({
|
||||
message: t('common.modelProvider.embeddingModel.required'),
|
||||
type: 'error',
|
||||
|
|
@ -106,13 +106,15 @@ const ConfigParamModal: FC<Props> = ({
|
|||
>
|
||||
<div className='pt-1'>
|
||||
<ModelSelector
|
||||
widthSameToTrigger
|
||||
value={embeddingModel as any}
|
||||
modelType={ModelType.embeddings}
|
||||
onChange={(val) => {
|
||||
defaultModel={embeddingModel && {
|
||||
provider: embeddingModel.providerName,
|
||||
model: embeddingModel.modelName,
|
||||
}}
|
||||
modelList={embeddingsModelList}
|
||||
onSelect={(val) => {
|
||||
setEmbeddingModel({
|
||||
providerName: val.model_provider.provider_name,
|
||||
modelName: val.model_name,
|
||||
providerName: val.provider,
|
||||
modelName: val.model,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import type { CodeBasedExtensionItem } from '@/models/common'
|
|||
import I18n from '@/context/i18n'
|
||||
import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import { CustomConfigurationStatusEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
|
||||
const systemTypes = ['openai_moderation', 'keywords', 'api']
|
||||
|
||||
|
|
@ -57,10 +58,11 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
|
|||
'/code-based-extension?module=moderation',
|
||||
fetchCodeBasedExtensionList,
|
||||
)
|
||||
const systemOpenaiProvider = modelProviders?.openai.providers.find(item => item.provider_type === 'system')
|
||||
const systemOpenaiProviderCanUse = systemOpenaiProvider && (((systemOpenaiProvider as any).quota_limit - (systemOpenaiProvider as any).quota_used) > 0)
|
||||
const customOpenaiProviders = modelProviders?.openai.providers.filter(item => item.provider_type !== 'system')
|
||||
const customOpenaiProvidersCanUse = customOpenaiProviders?.some(item => item.is_valid)
|
||||
const openaiProvider = modelProviders?.data.find(item => item.provider === 'openai')
|
||||
const systemOpenaiProviderEnabled = openaiProvider?.system_configuration.enabled
|
||||
const systemOpenaiProviderQuota = systemOpenaiProviderEnabled ? openaiProvider?.system_configuration.quota_configurations.find(item => item.quota_type === openaiProvider.system_configuration.current_quota_type) : undefined
|
||||
const systemOpenaiProviderCanUse = systemOpenaiProviderQuota?.is_valid
|
||||
const customOpenaiProvidersCanUse = openaiProvider?.custom_configuration.status === CustomConfigurationStatusEnum.active
|
||||
const openaiProviderConfiged = customOpenaiProvidersCanUse || systemOpenaiProviderCanUse
|
||||
const providers: Provider[] = [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ import Tooltip from '@/app/components/base/tooltip'
|
|||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import { fetchChatConversationDetail, fetchChatMessages, fetchCompletionConversationDetail, updateLogMessageAnnotations, updateLogMessageFeedbacks } from '@/service/log'
|
||||
import { TONE_LIST } from '@/config'
|
||||
import ModelIcon from '@/app/components/app/configuration/config-model/model-icon'
|
||||
import ModelName from '@/app/components/app/configuration/config-model/model-name'
|
||||
import ModelModeTypeLabel from '@/app/components/app/configuration/config-model/model-mode-type-label'
|
||||
import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon'
|
||||
import { useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
import TextGeneration from '@/app/components/app/text-generate/item'
|
||||
|
||||
|
|
@ -188,6 +188,12 @@ function DetailPanel<T extends ChatConversationFullDetailResponse | CompletionCo
|
|||
|
||||
const modelName = (detail.model_config as any).model.name
|
||||
const provideName = (detail.model_config as any).model.provider as any
|
||||
const {
|
||||
currentModel,
|
||||
currentProvider,
|
||||
} = useTextGenerationCurrentProviderAndModelAndModelList(
|
||||
{ provider: provideName, model: modelName },
|
||||
)
|
||||
const varList = (detail.model_config as any).user_input_form.map((item: any) => {
|
||||
const itemContent = item[Object.keys(item)[0]]
|
||||
return {
|
||||
|
|
@ -224,13 +230,13 @@ function DetailPanel<T extends ChatConversationFullDetailResponse | CompletionCo
|
|||
>
|
||||
<ModelIcon
|
||||
className='!w-5 !h-5'
|
||||
modelId={modelName}
|
||||
providerName={provideName}
|
||||
provider={currentProvider}
|
||||
modelName={currentModel?.model}
|
||||
/>
|
||||
<ModelName
|
||||
modelItem={currentModel!}
|
||||
showMode
|
||||
/>
|
||||
<div className='text-[13px] text-gray-900 font-medium'>
|
||||
<ModelName modelId={modelName} modelDisplayName={modelName} />
|
||||
</div>
|
||||
<ModelModeTypeLabel type={detail?.model_config.model.mode as any} isHighlight />
|
||||
</div>
|
||||
<Popover
|
||||
position='br'
|
||||
|
|
|
|||
|
|
@ -3,78 +3,35 @@ import type { FC } from 'react'
|
|||
import React, { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import cn from 'classnames'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import Progress from './progress'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { LinkExternal02, XClose } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { formatNumber } from '@/utils/format'
|
||||
import I18n from '@/context/i18n'
|
||||
import ProviderConfig from '@/app/components/header/account-setting/model-page/configs'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
|
||||
const APIKeyInfoPanel: FC = () => {
|
||||
const isCloud = !IS_CE_EDITION
|
||||
const { locale } = useContext(I18n)
|
||||
|
||||
const { textGenerationModelList } = useProviderContext()
|
||||
const { hasSettedApiKey } = useProviderContext()
|
||||
const { setShowAccountSettingModal } = useModalContext()
|
||||
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [isShow, setIsShow] = useState(true)
|
||||
|
||||
const hasSetAPIKEY = !!textGenerationModelList?.find(({ model_provider: provider }) => {
|
||||
if (provider.provider_type === 'system' && provider.quota_type === 'paid')
|
||||
return true
|
||||
|
||||
if (provider.provider_type === 'custom')
|
||||
return true
|
||||
|
||||
return false
|
||||
})
|
||||
if (hasSetAPIKEY)
|
||||
if (hasSettedApiKey)
|
||||
return null
|
||||
|
||||
// first show in trail and not used exhausted, else find the exhausted
|
||||
const [used, total, unit, providerName] = (() => {
|
||||
if (!textGenerationModelList || !isCloud)
|
||||
return [0, 0, '', '']
|
||||
|
||||
let used = 0
|
||||
let total = 0
|
||||
let unit = 'times'
|
||||
let trailProviderName = ''
|
||||
let hasFoundNotExhausted = false
|
||||
textGenerationModelList?.filter(({ model_provider: provider }) => {
|
||||
return provider.quota_type === 'trial'
|
||||
}).forEach(({ model_provider: provider }) => {
|
||||
if (hasFoundNotExhausted)
|
||||
return
|
||||
const { provider_name, quota_used, quota_limit, quota_unit } = provider
|
||||
if (quota_limit !== quota_used)
|
||||
hasFoundNotExhausted = true
|
||||
used = quota_used
|
||||
total = quota_limit
|
||||
unit = quota_unit
|
||||
trailProviderName = provider_name
|
||||
})
|
||||
|
||||
return [used, total, unit, trailProviderName]
|
||||
})()
|
||||
const usedPercent = Math.round(used / total * 100)
|
||||
const exhausted = isCloud && usedPercent === 100
|
||||
if (!(isShow))
|
||||
return null
|
||||
|
||||
return (
|
||||
<div className={cn(exhausted ? 'bg-[#FEF3F2] border-[#FEE4E2]' : 'bg-[#EFF4FF] border-[#D1E0FF]', 'mb-6 relative rounded-2xl shadow-md border p-8 ')}>
|
||||
<div className={cn('bg-[#EFF4FF] border-[#D1E0FF]', 'mb-6 relative rounded-2xl shadow-md border p-8 ')}>
|
||||
<div className={cn('text-[24px] text-gray-800 font-semibold', isCloud ? 'flex items-center h-8 space-x-1' : 'leading-8 mb-6')}>
|
||||
{isCloud && <em-emoji id={exhausted ? '🤔' : '😀'} />}
|
||||
{isCloud && <em-emoji id={'😀'} />}
|
||||
{isCloud
|
||||
? (
|
||||
<div>{t(`appOverview.apiKeyInfo.cloud.${exhausted ? 'exhausted' : 'trial'}.title`, { providerName: (ProviderConfig as any)[providerName as string]?.selector?.name[locale] || providerName })}</div>
|
||||
<div>{t('appOverview.apiKeyInfo.cloud.trial.title', { providerName: 'OpenAI' })}</div>
|
||||
)
|
||||
: (
|
||||
<div>
|
||||
|
|
@ -84,18 +41,7 @@ const APIKeyInfoPanel: FC = () => {
|
|||
)}
|
||||
</div>
|
||||
{isCloud && (
|
||||
<div className='mt-1 text-sm text-gray-600 font-normal'>{t(`appOverview.apiKeyInfo.cloud.${exhausted ? 'exhausted' : 'trial'}.description`)}</div>
|
||||
)}
|
||||
{/* Call times info */}
|
||||
{isCloud && (
|
||||
<div className='my-5'>
|
||||
<div className='flex items-center h-5 space-x-2 text-sm text-gray-700 font-medium'>
|
||||
<div>{t(`appOverview.apiKeyInfo.${unit === 'times' ? 'callTimes' : 'usedToken'}`)}</div>
|
||||
<div>·</div>
|
||||
<div className={cn('font-semibold', exhausted && 'text-[#D92D20]')}>{formatNumber(used)}/{formatNumber(total)}</div>
|
||||
</div>
|
||||
<Progress className='mt-2' value={usedPercent} />
|
||||
</div>
|
||||
<div className='mt-1 text-sm text-gray-600 font-normal'>{t(`appOverview.apiKeyInfo.cloud.${'trial'}.description`)}</div>
|
||||
)}
|
||||
<Button
|
||||
type='primary'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue