| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 | 
							- import type {
 
-   FC,
 
-   ReactNode,
 
- } from 'react'
 
- import { useEffect, useMemo, useState } from 'react'
 
- import useSWR from 'swr'
 
- import { useTranslation } from 'react-i18next'
 
- import cn from 'classnames'
 
- import type {
 
-   DefaultModel,
 
-   FormValue,
 
-   ModelParameterRule,
 
- } from '../declarations'
 
- import { ModelStatusEnum } from '../declarations'
 
- import ModelSelector from '../model-selector'
 
- import {
 
-   useTextGenerationCurrentProviderAndModelAndModelList,
 
- } from '../hooks'
 
- import { isNullOrUndefined } from '../utils'
 
- import ParameterItem from './parameter-item'
 
- import type { ParameterValue } from './parameter-item'
 
- import Trigger from './trigger'
 
- import type { TriggerProps } from './trigger'
 
- import PresetsParameter from './presets-parameter'
 
- import {
 
-   PortalToFollowElem,
 
-   PortalToFollowElemContent,
 
-   PortalToFollowElemTrigger,
 
- } from '@/app/components/base/portal-to-follow-elem'
 
- import { fetchModelParameterRules } from '@/service/common'
 
- import Loading from '@/app/components/base/loading'
 
- import { useProviderContext } from '@/context/provider-context'
 
- import { TONE_LIST } from '@/config'
 
- import { ArrowNarrowLeft } from '@/app/components/base/icons/src/vender/line/arrows'
 
- export type ModelParameterModalProps = {
 
-   popupClassName?: string
 
-   portalToFollowElemContentClassName?: string
 
-   isAdvancedMode: boolean
 
-   mode: string
 
-   modelId: string
 
-   provider: string
 
-   setModel: (model: { modelId: string; provider: string; mode?: string; features?: string[] }) => void
 
-   completionParams: FormValue
 
-   onCompletionParamsChange: (newParams: FormValue) => void
 
-   hideDebugWithMultipleModel?: boolean
 
-   debugWithMultipleModel?: boolean
 
-   onDebugWithMultipleModelChange?: () => void
 
-   renderTrigger?: (v: TriggerProps) => ReactNode
 
-   readonly?: boolean
 
-   isInWorkflow?: boolean
 
- }
 
- const stopParameerRule: ModelParameterRule = {
 
-   default: [],
 
-   help: {
 
-     en_US: 'Up to four sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence.',
 
-     zh_Hans: '最多四个序列,API 将停止生成更多的 token。返回的文本将不包含停止序列。',
 
-   },
 
-   label: {
 
-     en_US: 'Stop sequences',
 
-     zh_Hans: '停止序列',
 
-   },
 
-   name: 'stop',
 
-   required: false,
 
-   type: 'tag',
 
-   tagPlaceholder: {
 
-     en_US: 'Enter sequence and press Tab',
 
-     zh_Hans: '输入序列并按 Tab 键',
 
-   },
 
- }
 
- const PROVIDER_WITH_PRESET_TONE = ['openai', 'azure_openai']
 
- const ModelParameterModal: FC<ModelParameterModalProps> = ({
 
-   popupClassName,
 
-   portalToFollowElemContentClassName,
 
-   isAdvancedMode,
 
-   modelId,
 
-   provider,
 
-   setModel,
 
-   completionParams,
 
-   onCompletionParamsChange,
 
-   hideDebugWithMultipleModel,
 
-   debugWithMultipleModel,
 
-   onDebugWithMultipleModelChange,
 
-   renderTrigger,
 
-   readonly,
 
-   isInWorkflow,
 
- }) => {
 
-   const { t } = useTranslation()
 
-   const { hasSettedApiKey } = useProviderContext()
 
-   const [open, setOpen] = useState(false)
 
-   const { data: parameterRulesData, isLoading } = useSWR((provider && modelId) ? `/workspaces/current/model-providers/${provider}/models/parameter-rules?model=${modelId}` : null, fetchModelParameterRules)
 
-   const {
 
-     currentProvider,
 
-     currentModel,
 
-     activeTextGenerationModelList,
 
-   } = useTextGenerationCurrentProviderAndModelAndModelList(
 
-     { provider, model: modelId },
 
-   )
 
-   const hasDeprecated = !currentProvider || !currentModel
 
-   const modelDisabled = currentModel?.status !== ModelStatusEnum.active
 
-   const disabled = !hasSettedApiKey || hasDeprecated || modelDisabled
 
-   const parameterRules: ModelParameterRule[] = useMemo(() => {
 
-     return parameterRulesData?.data || []
 
-   }, [parameterRulesData])
 
-   const handleParamChange = (key: string, value: ParameterValue) => {
 
-     onCompletionParamsChange({
 
-       ...completionParams,
 
-       [key]: value,
 
-     })
 
-   }
 
-   const handleChangeModel = ({ provider, model }: DefaultModel) => {
 
-     const targetProvider = activeTextGenerationModelList.find(modelItem => modelItem.provider === provider)
 
-     const targetModelItem = targetProvider?.models.find(modelItem => modelItem.model === model)
 
-     setModel({
 
-       modelId: model,
 
-       provider,
 
-       mode: targetModelItem?.model_properties.mode as string,
 
-       features: targetModelItem?.features || [],
 
-     })
 
-   }
 
-   const handleSwitch = (key: string, value: boolean, assignValue: ParameterValue) => {
 
-     if (!value) {
 
-       const newCompletionParams = { ...completionParams }
 
-       delete newCompletionParams[key]
 
-       onCompletionParamsChange(newCompletionParams)
 
-     }
 
-     if (value) {
 
-       onCompletionParamsChange({
 
-         ...completionParams,
 
-         [key]: assignValue,
 
-       })
 
-     }
 
-   }
 
-   const handleInitialParams = () => {
 
-     const newCompletionParams = { ...completionParams }
 
-     if (parameterRules.length) {
 
-       parameterRules.forEach((parameterRule) => {
 
-         if (!newCompletionParams[parameterRule.name]) {
 
-           if (!isNullOrUndefined(parameterRule.default))
 
-             newCompletionParams[parameterRule.name] = parameterRule.default
 
-           else
 
-             delete newCompletionParams[parameterRule.name]
 
-         }
 
-       })
 
-       onCompletionParamsChange(newCompletionParams)
 
-     }
 
-   }
 
-   useEffect(() => {
 
-     handleInitialParams()
 
-   }, [parameterRules])
 
-   const handleSelectPresetParameter = (toneId: number) => {
 
-     const tone = TONE_LIST.find(tone => tone.id === toneId)
 
-     if (tone) {
 
-       onCompletionParamsChange({
 
-         ...completionParams,
 
-         ...tone.config,
 
-       })
 
-     }
 
-   }
 
-   return (
 
-     <PortalToFollowElem
 
-       open={open}
 
-       onOpenChange={setOpen}
 
-       placement='bottom-end'
 
-       offset={4}
 
-     >
 
-       <div className='relative'>
 
-         <PortalToFollowElemTrigger
 
-           onClick={() => {
 
-             if (readonly)
 
-               return
 
-             setOpen(v => !v)
 
-           }}
 
-           className='block'
 
-         >
 
-           {
 
-             renderTrigger
 
-               ? renderTrigger({
 
-                 open,
 
-                 disabled,
 
-                 modelDisabled,
 
-                 hasDeprecated,
 
-                 currentProvider,
 
-                 currentModel,
 
-                 providerName: provider,
 
-                 modelId,
 
-               })
 
-               : (
 
-                 <Trigger
 
-                   disabled={disabled}
 
-                   isInWorkflow={isInWorkflow}
 
-                   modelDisabled={modelDisabled}
 
-                   hasDeprecated={hasDeprecated}
 
-                   currentProvider={currentProvider}
 
-                   currentModel={currentModel}
 
-                   providerName={provider}
 
-                   modelId={modelId}
 
-                 />
 
-               )
 
-           }
 
-         </PortalToFollowElemTrigger>
 
-         <PortalToFollowElemContent className={cn(portalToFollowElemContentClassName, 'z-[60]')}>
 
-           <div className={cn(popupClassName, 'w-[496px] rounded-xl border border-gray-100 bg-white shadow-xl')}>
 
-             <div className={cn(
 
-               'max-h-[480px]  overflow-y-auto',
 
-               !isInWorkflow && 'px-10 pt-6 pb-8',
 
-               isInWorkflow && 'p-4')}>
 
-               <div className='flex items-center justify-between h-8'>
 
-                 <div className={cn('font-semibold text-gray-900', isInWorkflow && 'text-[13px]')}>
 
-                   {t('common.modelProvider.model').toLocaleUpperCase()}
 
-                 </div>
 
-                 <ModelSelector
 
-                   defaultModel={(provider || modelId) ? { provider, model: modelId } : undefined}
 
-                   modelList={activeTextGenerationModelList}
 
-                   onSelect={handleChangeModel}
 
-                 />
 
-               </div>
 
-               {
 
-                 !!parameterRules.length && (
 
-                   <div className='my-5 h-[1px] bg-gray-100' />
 
-                 )
 
-               }
 
-               {
 
-                 isLoading && (
 
-                   <div className='mt-5'><Loading /></div>
 
-                 )
 
-               }
 
-               {
 
-                 !isLoading && !!parameterRules.length && (
 
-                   <div className='flex items-center justify-between mb-4'>
 
-                     <div className={cn('font-semibold text-gray-900', isInWorkflow && 'text-[13px]')}>{t('common.modelProvider.parameters')}</div>
 
-                     {
 
-                       PROVIDER_WITH_PRESET_TONE.includes(provider) && (
 
-                         <PresetsParameter onSelect={handleSelectPresetParameter} />
 
-                       )
 
-                     }
 
-                   </div>
 
-                 )
 
-               }
 
-               {
 
-                 !isLoading && !!parameterRules.length && (
 
-                   [
 
-                     ...parameterRules,
 
-                     ...(isAdvancedMode ? [stopParameerRule] : []),
 
-                   ].map(parameter => (
 
-                     <ParameterItem
 
-                       key={`${modelId}-${parameter.name}`}
 
-                       className='mb-4'
 
-                       parameterRule={parameter}
 
-                       value={completionParams[parameter.name]}
 
-                       onChange={v => handleParamChange(parameter.name, v)}
 
-                       onSwitch={(checked, assignValue) => handleSwitch(parameter.name, checked, assignValue)}
 
-                       isInWorkflow={isInWorkflow}
 
-                     />
 
-                   ))
 
-                 )
 
-               }
 
-             </div>
 
-             {!hideDebugWithMultipleModel && (
 
-               <div
 
-                 className='flex items-center justify-between px-6 h-[50px] bg-gray-50 border-t border-t-gray-100 text-xs font-medium text-primary-600 cursor-pointer rounded-b-xl'
 
-                 onClick={() => onDebugWithMultipleModelChange?.()}
 
-               >
 
-                 {
 
-                   debugWithMultipleModel
 
-                     ? t('appDebug.debugAsSingleModel')
 
-                     : t('appDebug.debugAsMultipleModel')
 
-                 }
 
-                 <ArrowNarrowLeft className='w-3 h-3 rotate-180' />
 
-               </div>
 
-             )}
 
-           </div>
 
-         </PortalToFollowElemContent>
 
-       </div>
 
-     </PortalToFollowElem>
 
-   )
 
- }
 
- export default ModelParameterModal
 
 
  |