import type { FC } from 'react' import React, { useCallback } from 'react' import { useTranslation } from 'react-i18next' import MemoryConfig from '../_base/components/memory-config' import VarReferencePicker from '../_base/components/variable/var-reference-picker' import ConfigVision from '../_base/components/config-vision' import useConfig from './use-config' import type { LLMNodeType } from './types' import ConfigPrompt from './components/config-prompt' import VarList from '@/app/components/workflow/nodes/_base/components/variable/var-list' import AddButton2 from '@/app/components/base/button/add-button' import Field from '@/app/components/workflow/nodes/_base/components/field' import Split from '@/app/components/workflow/nodes/_base/components/split' import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal' import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars' import type { NodePanelProps } from '@/app/components/workflow/types' import Tooltip from '@/app/components/base/tooltip' import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor' import StructureOutput from './components/structure-output' import Switch from '@/app/components/base/switch' import { RiAlertFill, RiQuestionLine } from '@remixicon/react' import { fetchAndMergeValidCompletionParams } from '@/utils/completion-params' import Toast from '@/app/components/base/toast' const i18nPrefix = 'workflow.nodes.llm' const Panel: FC> = ({ id, data, }) => { const { t } = useTranslation() const { readOnly, inputs, isChatModel, isChatMode, isCompletionModel, shouldShowContextTip, isVisionModel, handleModelChanged, hasSetBlockStatus, handleCompletionParamsChange, handleContextVarChange, filterInputVar, filterVar, availableVars, availableNodesWithParent, isShowVars, handlePromptChange, handleAddEmptyVariable, handleAddVariable, handleVarListChange, handleVarNameChange, handleSyeQueryChange, handleMemoryChange, handleVisionResolutionEnabledChange, handleVisionResolutionChange, isModelSupportStructuredOutput, structuredOutputCollapsed, setStructuredOutputCollapsed, handleStructureOutputEnableChange, handleStructureOutputChange, filterJinjia2InputVar, } = useConfig(id, data) const model = inputs.model const handleModelChange = useCallback((model: { provider: string modelId: string mode?: string }) => { (async () => { try { const { params: filtered, removedDetails } = await fetchAndMergeValidCompletionParams( model.provider, model.modelId, inputs.model.completion_params, ) const keys = Object.keys(removedDetails) if (keys.length) Toast.notify({ type: 'warning', message: `${t('common.modelProvider.parametersInvalidRemoved')}: ${keys.map(k => `${k} (${removedDetails[k]})`).join(', ')}` }) handleCompletionParamsChange(filtered) } catch (e) { Toast.notify({ type: 'error', message: t('common.error') }) handleCompletionParamsChange({}) } finally { handleModelChanged(model) } })() }, [inputs.model.completion_params]) return (
{/* knowledge */} <> {shouldShowContextTip && (
{t(`${i18nPrefix}.notSetContextInPromptTip`)}
)}
{/* Prompt */} {model.name && ( )} {isShowVars && ( : undefined } > )} {/* Memory put place examples. */} {isChatMode && isChatModel && !!inputs.memory && (
{t('workflow.nodes.common.memories.title')}
{t('workflow.nodes.common.memories.builtIn')}
{/* Readonly User Query */}
user
{t('workflow.nodes.llm.roleDescription.user')}
} triggerClassName='w-4 h-4' />
} value={inputs.memory.query_prompt_template || '{{#sys.query#}}'} onChange={handleSyeQueryChange} readOnly={readOnly} isShowContext={false} isChatApp isChatModel hasSetBlockStatus={hasSetBlockStatus} nodesOutputVars={availableVars} availableNodes={availableNodesWithParent} isSupportFileVar /> {inputs.memory.query_prompt_template && !inputs.memory.query_prompt_template.includes('{{#sys.query#}}') && (
{t(`${i18nPrefix}.sysQueryInUser`)}
)}
)} {/* Memory */} {isChatMode && ( <> )} {/* Vision: GPT4-vision and so on */} {(!isModelSupportStructuredOutput && !!inputs.structured_output_enabled) && (
{t('app.structOutput.modelNotSupported')}
{t('app.structOutput.modelNotSupportedTip')}
}>
)}
{t('app.structOutput.structured')}
{t('app.structOutput.structuredTip')} }>
} > <> {inputs.structured_output_enabled && ( <> )}
) } export default React.memo(Panel)