refactor(i18n): use JSON with flattened key and namespace (#30114)

Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Stephen Zhou
2025-12-29 14:52:32 +08:00
committed by GitHub
parent 09be869f58
commit 6d0e36479b
2552 changed files with 111159 additions and 142972 deletions

View File

@ -11,7 +11,7 @@ import { PromptRole } from '@/models/debug'
import { useWorkflowStore } from '../../../store'
import { EditionType } from '../../../types'
const i18nPrefix = 'workflow.nodes.llm'
const i18nPrefix = 'nodes.llm'
type Props = {
instanceId: string
@ -121,7 +121,7 @@ const ConfigPromptItem: FC<Props> = ({
<Tooltip
popupContent={
<div className="max-w-[180px]">{t(`${i18nPrefix}.roleDescription.${payload.role}` as any) as string}</div>
<div className="max-w-[180px]">{payload.role && t(`${i18nPrefix}.roleDescription.${payload.role}`, { ns: 'workflow' })}</div>
}
triggerClassName="w-4 h-4"
/>

View File

@ -16,7 +16,7 @@ import { EditionType, PromptRole } from '../../../types'
import useAvailableVarList from '../../_base/hooks/use-available-var-list'
import ConfigPromptItem from './config-prompt-item'
const i18nPrefix = 'workflow.nodes.llm'
const i18nPrefix = 'nodes.llm'
type Props = {
readOnly: boolean
@ -215,7 +215,7 @@ const ConfigPrompt: FC<Props> = ({
</div>
<AddButton
className="mt-2"
text={t(`${i18nPrefix}.addMessage`)}
text={t(`${i18nPrefix}.addMessage`, { ns: 'workflow' })}
onClick={handleAddPrompt}
/>
</div>
@ -224,7 +224,7 @@ const ConfigPrompt: FC<Props> = ({
<div>
<Editor
instanceId={`${nodeId}-chat-workflow-llm-prompt-editor`}
title={<span className="capitalize">{t(`${i18nPrefix}.prompt`)}</span>}
title={<span className="capitalize">{t(`${i18nPrefix}.prompt`, { ns: 'workflow' })}</span>}
value={((payload as PromptItem).edition_type === EditionType.basic || !(payload as PromptItem).edition_type) ? (payload as PromptItem).text : ((payload as PromptItem).jinja2_text || '')}
onChange={handleCompletionPromptChange}
readOnly={readOnly}

View File

@ -122,7 +122,7 @@ const CodeEditor: FC<CodeEditorProps> = ({
</div>
<div className="flex items-center gap-x-0.5">
{showFormatButton && (
<Tooltip popupContent={t('common.operation.format')}>
<Tooltip popupContent={t('operation.format', { ns: 'common' })}>
<button
type="button"
className="flex h-6 w-6 items-center justify-center"
@ -132,7 +132,7 @@ const CodeEditor: FC<CodeEditorProps> = ({
</button>
</Tooltip>
)}
<Tooltip popupContent={t('common.operation.copy')}>
<Tooltip popupContent={t('operation.copy', { ns: 'common' })}>
<button
type="button"
className="flex h-6 w-6 items-center justify-center"

View File

@ -94,7 +94,7 @@ const JsonImporter: FC<JsonImporterProps> = ({
open && 'bg-components-button-ghost-bg-hover',
)}
>
<span className="px-0.5">{t('workflow.nodes.llm.jsonSchema.import')}</span>
<span className="px-0.5">{t('nodes.llm.jsonSchema.import', { ns: 'workflow' })}</span>
</button>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className="z-[100]">
@ -105,7 +105,7 @@ const JsonImporter: FC<JsonImporterProps> = ({
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
</div>
<div className="system-xl-semibold flex pl-1 pr-8 text-text-primary">
{t('workflow.nodes.llm.jsonSchema.import')}
{t('nodes.llm.jsonSchema.import', { ns: 'workflow' })}
</div>
</div>
{/* Content */}
@ -122,10 +122,10 @@ const JsonImporter: FC<JsonImporterProps> = ({
{/* Footer */}
<div className="flex items-center justify-end gap-x-2 p-4 pt-2">
<Button variant="secondary" onClick={onClose}>
{t('common.operation.cancel')}
{t('operation.cancel', { ns: 'common' })}
</Button>
<Button variant="primary" onClick={handleSubmit}>
{t('common.operation.submit')}
{t('operation.submit', { ns: 'common' })}
</Button>
</div>
</div>

View File

@ -193,7 +193,7 @@ const JsonSchemaConfig: FC<JsonSchemaConfigProps> = ({
if (advancedEditing || isAddingNewField) {
Toast.notify({
type: 'warning',
message: t('workflow.nodes.llm.jsonSchema.warningTips.saveSchema'),
message: t('nodes.llm.jsonSchema.warningTips.saveSchema', { ns: 'workflow' }),
})
return
}
@ -207,7 +207,7 @@ const JsonSchemaConfig: FC<JsonSchemaConfigProps> = ({
{/* Header */}
<div className="relative flex p-6 pb-3 pr-14">
<div className="title-2xl-semi-bold grow truncate text-text-primary">
{t('workflow.nodes.llm.jsonSchema.title')}
{t('nodes.llm.jsonSchema.title', { ns: 'workflow' })}
</div>
<div className="absolute right-5 top-5 flex h-8 w-8 items-center justify-center p-1.5" onClick={onClose}>
<RiCloseLine className="h-[18px] w-[18px] text-text-tertiary" />
@ -259,22 +259,22 @@ const JsonSchemaConfig: FC<JsonSchemaConfigProps> = ({
target="_blank"
rel="noopener noreferrer"
>
<span className="system-xs-regular">{t('workflow.nodes.llm.jsonSchema.doc')}</span>
<span className="system-xs-regular">{t('nodes.llm.jsonSchema.doc', { ns: 'workflow' })}</span>
<RiExternalLinkLine className="h-3 w-3" />
</a>
<div className="flex items-center gap-x-3">
<div className="flex items-center gap-x-2">
<Button variant="secondary" onClick={handleResetDefaults}>
{t('workflow.nodes.llm.jsonSchema.resetDefaults')}
{t('nodes.llm.jsonSchema.resetDefaults', { ns: 'workflow' })}
</Button>
<Divider type="vertical" className="ml-1 mr-0 h-4" />
</div>
<div className="flex items-center gap-x-2">
<Button variant="secondary" onClick={handleCancel}>
{t('common.operation.cancel')}
{t('operation.cancel', { ns: 'common' })}
</Button>
<Button variant="primary" onClick={handleSave}>
{t('common.operation.save')}
{t('operation.save', { ns: 'common' })}
</Button>
</div>
</div>

View File

@ -64,7 +64,7 @@ const GeneratedResult: FC<GeneratedResultProps> = ({
isGenerating ? (
<div className="flex h-[600px] flex-col items-center justify-center gap-y-3">
<Loading type="area" />
<div className="system-xs-regular text-text-tertiary">{t('workflow.nodes.llm.jsonSchema.generating')}</div>
<div className="system-xs-regular text-text-tertiary">{t('nodes.llm.jsonSchema.generating', { ns: 'workflow' })}</div>
</div>
) : (
<>
@ -74,10 +74,10 @@ const GeneratedResult: FC<GeneratedResultProps> = ({
{/* Title */}
<div className="flex flex-col gap-y-[0.5px] px-3 pb-1 pt-3.5">
<div className="system-xl-semibold flex pl-1 pr-8 text-text-primary">
{t('workflow.nodes.llm.jsonSchema.generatedResult')}
{t('nodes.llm.jsonSchema.generatedResult', { ns: 'workflow' })}
</div>
<div className="system-xs-regular flex px-1 text-text-tertiary">
{t('workflow.nodes.llm.jsonSchema.resultTip')}
{t('nodes.llm.jsonSchema.resultTip', { ns: 'workflow' })}
</div>
</div>
{/* Content */}
@ -96,7 +96,7 @@ const GeneratedResult: FC<GeneratedResultProps> = ({
<div className="flex items-center justify-between p-4 pt-2">
<Button variant="secondary" className="flex items-center gap-x-0.5" onClick={onBack}>
<RiArrowLeftLine className="h-4 w-4" />
<span>{t('workflow.nodes.llm.jsonSchema.back')}</span>
<span>{t('nodes.llm.jsonSchema.back', { ns: 'workflow' })}</span>
</Button>
<div className="flex items-center gap-x-2">
<Button
@ -105,10 +105,10 @@ const GeneratedResult: FC<GeneratedResultProps> = ({
onClick={onRegenerate}
>
<RiSparklingLine className="h-4 w-4" />
<span>{t('workflow.nodes.llm.jsonSchema.regenerate')}</span>
<span>{t('nodes.llm.jsonSchema.regenerate', { ns: 'workflow' })}</span>
</Button>
<Button variant="primary" onClick={handleApply}>
{t('workflow.nodes.llm.jsonSchema.apply')}
{t('nodes.llm.jsonSchema.apply', { ns: 'workflow' })}
</Button>
</div>
</div>

View File

@ -50,16 +50,16 @@ const PromptEditor: FC<PromptEditorProps> = ({
{/* Title */}
<div className="flex flex-col gap-y-[0.5px] px-3 pb-1 pt-3.5">
<div className="system-xl-semibold flex pl-1 pr-8 text-text-primary">
{t('workflow.nodes.llm.jsonSchema.generateJsonSchema')}
{t('nodes.llm.jsonSchema.generateJsonSchema', { ns: 'workflow' })}
</div>
<div className="system-xs-regular flex px-1 text-text-tertiary">
{t('workflow.nodes.llm.jsonSchema.generationTip')}
{t('nodes.llm.jsonSchema.generationTip', { ns: 'workflow' })}
</div>
</div>
{/* Content */}
<div className="flex flex-col gap-y-1 px-4 py-2">
<div className="system-sm-semibold-uppercase flex h-6 items-center text-text-secondary">
{t('common.modelProvider.model')}
{t('modelProvider.model', { ns: 'common' })}
</div>
<ModelParameterModal
popupClassName="!w-[448px]"
@ -75,14 +75,14 @@ const PromptEditor: FC<PromptEditorProps> = ({
</div>
<div className="flex flex-col gap-y-1 px-4 py-2">
<div className="system-sm-semibold-uppercase flex h-6 items-center text-text-secondary">
<span>{t('workflow.nodes.llm.jsonSchema.instruction')}</span>
<Tooltip popupContent={t('workflow.nodes.llm.jsonSchema.promptTooltip')} />
<span>{t('nodes.llm.jsonSchema.instruction', { ns: 'workflow' })}</span>
<Tooltip popupContent={t('nodes.llm.jsonSchema.promptTooltip', { ns: 'workflow' })} />
</div>
<div className="flex items-center">
<Textarea
className="h-[364px] resize-none px-2 py-1"
value={instruction}
placeholder={t('workflow.nodes.llm.jsonSchema.promptPlaceholder')}
placeholder={t('nodes.llm.jsonSchema.promptPlaceholder', { ns: 'workflow' })}
onChange={handleInstructionChange}
/>
</div>
@ -90,7 +90,7 @@ const PromptEditor: FC<PromptEditorProps> = ({
{/* Footer */}
<div className="flex justify-end gap-x-2 p-4 pt-2">
<Button variant="secondary" onClick={onClose}>
{t('common.operation.cancel')}
{t('operation.cancel', { ns: 'common' })}
</Button>
<Button
variant="primary"
@ -98,7 +98,7 @@ const PromptEditor: FC<PromptEditorProps> = ({
onClick={onGenerate}
>
<RiSparklingFill className="h-4 w-4" />
<span>{t('workflow.nodes.llm.jsonSchema.generate')}</span>
<span>{t('nodes.llm.jsonSchema.generate', { ns: 'workflow' })}</span>
</Button>
</div>
</div>

View File

@ -28,7 +28,7 @@ const AddField = () => {
onClick={handleAddField}
>
<RiAddCircleFill className="h-3.5 w-3.5" />
<span className="px-[3px]">{t('workflow.nodes.llm.jsonSchema.addField')}</span>
<span className="px-[3px]">{t('nodes.llm.jsonSchema.addField', { ns: 'workflow' })}</span>
</Button>
</div>
)

View File

@ -29,7 +29,7 @@ const Card: FC<CardProps> = ({
{
required && (
<div className="system-2xs-medium-uppercase px-1 py-0.5 text-text-warning">
{t('workflow.nodes.llm.jsonSchema.required')}
{t('nodes.llm.jsonSchema.required', { ns: 'workflow' })}
</div>
)
}

View File

@ -21,7 +21,7 @@ const Actions: FC<ActionsProps> = ({
return (
<div className="flex items-center gap-x-0.5">
<Tooltip popupContent={t('workflow.nodes.llm.jsonSchema.addChildField')}>
<Tooltip popupContent={t('nodes.llm.jsonSchema.addChildField', { ns: 'workflow' })}>
<button
type="button"
className="flex h-6 w-6 items-center justify-center rounded-md text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary disabled:cursor-not-allowed disabled:text-text-disabled"
@ -31,7 +31,7 @@ const Actions: FC<ActionsProps> = ({
<RiAddCircleLine className="h-4 w-4" />
</button>
</Tooltip>
<Tooltip popupContent={t('common.operation.edit')}>
<Tooltip popupContent={t('operation.edit', { ns: 'common' })}>
<button
type="button"
className="flex h-6 w-6 items-center justify-center rounded-md text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary"
@ -40,7 +40,7 @@ const Actions: FC<ActionsProps> = ({
<RiEditLine className="h-4 w-4" />
</button>
</Tooltip>
<Tooltip popupContent={t('common.operation.remove')}>
<Tooltip popupContent={t('operation.remove', { ns: 'common' })}>
<button
type="button"
className="flex h-6 w-6 items-center justify-center rounded-md text-text-tertiary hover:bg-state-destructive-hover hover:text-text-destructive"

View File

@ -38,7 +38,7 @@ const AdvancedActions: FC<AdvancedActionsProps> = ({
return (
<div className="flex items-center gap-x-1">
<Button size="small" variant="secondary" onClick={onCancel}>
{t('common.operation.cancel')}
{t('operation.cancel', { ns: 'common' })}
</Button>
<Button
className="flex items-center gap-x-1"
@ -47,7 +47,7 @@ const AdvancedActions: FC<AdvancedActionsProps> = ({
variant="primary"
onClick={onConfirm}
>
<span>{t('common.operation.confirm')}</span>
<span>{t('operation.confirm', { ns: 'common' })}</span>
<div className="flex items-center gap-x-0.5">
<Key keyName={getKeyboardKeyNameBySystem('ctrl')} />
<Key keyName="⏎" />

View File

@ -40,7 +40,7 @@ const AdvancedOptions: FC<AdvancedOptionsProps> = ({
<div className="flex flex-col gap-y-1 px-2 py-1.5">
<div className="flex w-full items-center gap-x-2">
<span className="system-2xs-medium-uppercase text-text-tertiary">
{t('workflow.nodes.llm.jsonSchema.stringValidations')}
{t('nodes.llm.jsonSchema.stringValidations', { ns: 'workflow' })}
</span>
<div className="grow">
<Divider type="horizontal" className="my-0 h-px bg-line-divider-bg" />

View File

@ -222,7 +222,7 @@ const EditCard: FC<EditCardProps> = ({
<div className="flex grow items-center gap-x-1">
<AutoWidthInput
value={currentFields.name}
placeholder={t('workflow.nodes.llm.jsonSchema.fieldNamePlaceholder')}
placeholder={t('nodes.llm.jsonSchema.fieldNamePlaceholder', { ns: 'workflow' })}
minWidth={80}
maxWidth={300}
onChange={handlePropertyNameChange}
@ -237,7 +237,7 @@ const EditCard: FC<EditCardProps> = ({
{
currentFields.required && (
<div className="system-2xs-medium-uppercase px-1 py-0.5 text-text-warning">
{t('workflow.nodes.llm.jsonSchema.required')}
{t('nodes.llm.jsonSchema.required', { ns: 'workflow' })}
</div>
)
}
@ -270,7 +270,7 @@ const EditCard: FC<EditCardProps> = ({
<input
value={currentFields.description}
className="system-xs-regular placeholder:system-xs-regular h-4 w-full p-0 text-text-tertiary caret-[#295EFF] outline-none placeholder:text-text-placeholder"
placeholder={t('workflow.nodes.llm.jsonSchema.descriptionPlaceholder')}
placeholder={t('nodes.llm.jsonSchema.descriptionPlaceholder', { ns: 'workflow' })}
onChange={handleDescriptionChange}
onBlur={handleDescriptionBlur}
onKeyUp={e => e.key === 'Enter' && e.currentTarget.blur()}

View File

@ -16,7 +16,7 @@ const RequiredSwitch: FC<RequiredSwitchProps> = ({
return (
<div className="flex items-center gap-x-1 rounded-[5px] border border-divider-subtle bg-background-default-lighter px-1.5 py-1">
<span className="system-2xs-medium-uppercase text-text-secondary">{t('workflow.nodes.llm.jsonSchema.required')}</span>
<span className="system-2xs-medium-uppercase text-text-secondary">{t('nodes.llm.jsonSchema.required', { ns: 'workflow' })}</span>
<Switch size="xs" defaultValue={defaultValue} onChange={toggleRequired} />
</div>
)

View File

@ -19,8 +19,8 @@ const ReasoningFormatConfig: FC<ReasoningFormatConfigProps> = ({
return (
<Field
title={t('workflow.nodes.llm.reasoningFormat.title')}
tooltip={t('workflow.nodes.llm.reasoningFormat.tooltip')}
title={t('nodes.llm.reasoningFormat.title', { ns: 'workflow' })}
tooltip={t('nodes.llm.reasoningFormat.tooltip', { ns: 'workflow' })}
operations={(
// ON = separated, OFF = tagged
<Switch

View File

@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next'
import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card'
import { Resolution } from '@/types/app'
const i18nPrefix = 'workflow.nodes.llm'
const i18nPrefix = 'nodes.llm'
type Props = {
value: Resolution
@ -26,15 +26,15 @@ const ResolutionPicker: FC<Props> = ({
}, [onChange])
return (
<div className="flex items-center justify-between">
<div className="mr-2 text-xs font-medium uppercase text-text-secondary">{t(`${i18nPrefix}.resolution.name`)}</div>
<div className="mr-2 text-xs font-medium uppercase text-text-secondary">{t(`${i18nPrefix}.resolution.name`, { ns: 'workflow' })}</div>
<div className="flex items-center space-x-1">
<OptionCard
title={t(`${i18nPrefix}.resolution.high`)}
title={t(`${i18nPrefix}.resolution.high`, { ns: 'workflow' })}
onSelect={handleOnChange(Resolution.high)}
selected={value === Resolution.high}
/>
<OptionCard
title={t(`${i18nPrefix}.resolution.low`)}
title={t(`${i18nPrefix}.resolution.low`, { ns: 'workflow' })}
onSelect={handleOnChange(Resolution.low)}
selected={value === Resolution.low}
/>

View File

@ -48,7 +48,7 @@ const StructureOutput: FC<Props> = ({
onClick={showConfigModal}
>
<RiEditLine className="mr-1 size-3.5" />
<div className="system-xs-medium text-components-button-secondary-text">{t('app.structOutput.configure')}</div>
<div className="system-xs-medium text-components-button-secondary-text">{t('structOutput.configure', { ns: 'app' })}</div>
</Button>
</div>
{(value?.schema && value.schema.properties && Object.keys(value.schema.properties).length > 0)
@ -58,7 +58,7 @@ const StructureOutput: FC<Props> = ({
/>
)
: (
<div className="system-xs-regular mt-1.5 flex h-10 cursor-pointer items-center justify-center rounded-[10px] bg-background-section text-text-tertiary" onClick={showConfigModal}>{t('app.structOutput.notConfiguredTip')}</div>
<div className="system-xs-regular mt-1.5 flex h-10 cursor-pointer items-center justify-center rounded-[10px] bg-background-section text-text-tertiary" onClick={showConfigModal}>{t('structOutput.notConfiguredTip', { ns: 'app' })}</div>
)}
{showConfig && (

View File

@ -25,7 +25,7 @@ const RETRIEVAL_OUTPUT_STRUCT = `{
}
}`
const i18nPrefix = 'workflow.errorMsg'
const i18nPrefix = 'errorMsg'
const metaData = genNodeMetaData({
sort: 1,
@ -61,7 +61,7 @@ const nodeDefault: NodeDefault<LLMNodeType> = {
checkValid(payload: LLMNodeType, t: any) {
let errorMessages = ''
if (!errorMessages && !payload.model.provider)
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.fields.model`) })
errorMessages = t(`${i18nPrefix}.fieldRequired`, { ns: 'workflow', field: t(`${i18nPrefix}.fields.model`, { ns: 'workflow' }) })
if (!errorMessages && !payload.memory) {
const isChatModel = payload.model.mode === AppModeEnum.CHAT
@ -74,14 +74,14 @@ const nodeDefault: NodeDefault<LLMNodeType> = {
})
: ((payload.prompt_template as PromptItem).edition_type === EditionType.jinja2 ? (payload.prompt_template as PromptItem).jinja2_text === '' : (payload.prompt_template as PromptItem).text === '')
if (isPromptEmpty)
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t('workflow.nodes.llm.prompt') })
errorMessages = t(`${i18nPrefix}.fieldRequired`, { ns: 'workflow', field: t('nodes.llm.prompt', { ns: 'workflow' }) })
}
if (!errorMessages && !!payload.memory) {
const isChatModel = payload.model.mode === AppModeEnum.CHAT
// payload.memory.query_prompt_template not pass is default: {{#sys.query#}}
if (isChatModel && !!payload.memory.query_prompt_template && !payload.memory.query_prompt_template.includes('{{#sys.query#}}'))
errorMessages = t('workflow.nodes.llm.sysQueryInUser')
errorMessages = t('nodes.llm.sysQueryInUser', { ns: 'workflow' })
}
if (!errorMessages) {
@ -94,14 +94,14 @@ const nodeDefault: NodeDefault<LLMNodeType> = {
if (isShowVars && payload.prompt_config?.jinja2_variables) {
payload.prompt_config?.jinja2_variables.forEach((i) => {
if (!errorMessages && !i.variable)
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.fields.variable`) })
errorMessages = t(`${i18nPrefix}.fieldRequired`, { ns: 'workflow', field: t(`${i18nPrefix}.fields.variable`, { ns: 'workflow' }) })
if (!errorMessages && !i.value_selector.length)
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.fields.variableValue`) })
errorMessages = t(`${i18nPrefix}.fieldRequired`, { ns: 'workflow', field: t(`${i18nPrefix}.fields.variableValue`, { ns: 'workflow' }) })
})
}
}
if (!errorMessages && payload.vision?.enabled && !payload.vision.configs?.variable_selector?.length)
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.fields.visionVariable`) })
errorMessages = t(`${i18nPrefix}.fieldRequired`, { ns: 'workflow', field: t(`${i18nPrefix}.fields.visionVariable`, { ns: 'workflow' }) })
return {
isValid: !errorMessages,
errorMessage: errorMessages,

View File

@ -24,7 +24,7 @@ import ReasoningFormatConfig from './components/reasoning-format-config'
import StructureOutput from './components/structure-output'
import useConfig from './use-config'
const i18nPrefix = 'workflow.nodes.llm'
const i18nPrefix = 'nodes.llm'
const Panel: FC<NodePanelProps<LLMNodeType>> = ({
id,
@ -83,11 +83,11 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
)
const keys = Object.keys(removedDetails)
if (keys.length)
Toast.notify({ type: 'warning', message: `${t('common.modelProvider.parametersInvalidRemoved')}: ${keys.map(k => `${k} (${removedDetails[k]})`).join(', ')}` })
Toast.notify({ type: 'warning', message: `${t('modelProvider.parametersInvalidRemoved', { ns: 'common' })}: ${keys.map(k => `${k} (${removedDetails[k]})`).join(', ')}` })
handleCompletionParamsChange(filtered)
}
catch {
Toast.notify({ type: 'error', message: t('common.error') })
Toast.notify({ type: 'error', message: t('error', { ns: 'common' }) })
handleCompletionParamsChange({})
}
finally {
@ -99,7 +99,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
<div className="mt-2">
<div className="space-y-4 px-4 pb-4">
<Field
title={t(`${i18nPrefix}.model`)}
title={t(`${i18nPrefix}.model`, { ns: 'workflow' })}
required
>
<ModelParameterModal
@ -119,8 +119,8 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
{/* knowledge */}
<Field
title={t(`${i18nPrefix}.context`)}
tooltip={t(`${i18nPrefix}.contextTooltip`)!}
title={t(`${i18nPrefix}.context`, { ns: 'workflow' })}
tooltip={t(`${i18nPrefix}.contextTooltip`, { ns: 'workflow' })!}
>
<>
<VarReferencePicker
@ -132,7 +132,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
filterVar={filterVar}
/>
{shouldShowContextTip && (
<div className="text-xs font-normal leading-[18px] text-[#DC6803]">{t(`${i18nPrefix}.notSetContextInPromptTip`)}</div>
<div className="text-xs font-normal leading-[18px] text-[#DC6803]">{t(`${i18nPrefix}.notSetContextInPromptTip`, { ns: 'workflow' })}</div>
)}
</>
</Field>
@ -157,7 +157,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
{isShowVars && (
<Field
title={t('workflow.nodes.templateTransform.inputVars')}
title={t('nodes.templateTransform.inputVars', { ns: 'workflow' })}
operations={
!readOnly ? <AddButton2 onClick={handleAddEmptyVariable} /> : undefined
}
@ -179,13 +179,13 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
<div className="mt-4">
<div className="flex h-8 items-center justify-between rounded-lg bg-components-input-bg-normal pl-3 pr-2">
<div className="flex items-center space-x-1">
<div className="text-xs font-semibold uppercase text-text-secondary">{t('workflow.nodes.common.memories.title')}</div>
<div className="text-xs font-semibold uppercase text-text-secondary">{t('nodes.common.memories.title', { ns: 'workflow' })}</div>
<Tooltip
popupContent={t('workflow.nodes.common.memories.tip')}
popupContent={t('nodes.common.memories.tip', { ns: 'workflow' })}
triggerClassName="w-4 h-4"
/>
</div>
<div className="flex h-[18px] items-center rounded-[5px] border border-divider-deep bg-components-badge-bg-dimm px-1 text-xs font-semibold uppercase text-text-tertiary">{t('workflow.nodes.common.memories.builtIn')}</div>
<div className="flex h-[18px] items-center rounded-[5px] border border-divider-deep bg-components-badge-bg-dimm px-1 text-xs font-semibold uppercase text-text-tertiary">{t('nodes.common.memories.builtIn', { ns: 'workflow' })}</div>
</div>
{/* Readonly User Query */}
<div className="mt-4">
@ -195,7 +195,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
<div className="text-xs font-semibold uppercase text-text-secondary">user</div>
<Tooltip
popupContent={
<div className="max-w-[180px]">{t('workflow.nodes.llm.roleDescription.user')}</div>
<div className="max-w-[180px]">{t('nodes.llm.roleDescription.user', { ns: 'workflow' })}</div>
}
triggerClassName="w-4 h-4"
/>
@ -214,7 +214,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
/>
{inputs.memory.query_prompt_template && !inputs.memory.query_prompt_template.includes('{{#sys.query#}}') && (
<div className="text-xs font-normal leading-[18px] text-[#DC6803]">{t(`${i18nPrefix}.sysQueryInUser`)}</div>
<div className="text-xs font-normal leading-[18px] text-[#DC6803]">{t(`${i18nPrefix}.sysQueryInUser`, { ns: 'workflow' })}</div>
)}
</div>
</div>
@ -263,8 +263,8 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
noDecoration
popupContent={(
<div className="w-[232px] rounded-xl border-[0.5px] border-components-panel-border bg-components-tooltip-bg px-4 py-3.5 shadow-lg backdrop-blur-[5px]">
<div className="title-xs-semi-bold text-text-primary">{t('app.structOutput.modelNotSupported')}</div>
<div className="body-xs-regular mt-1 text-text-secondary">{t('app.structOutput.modelNotSupportedTip')}</div>
<div className="title-xs-semi-bold text-text-primary">{t('structOutput.modelNotSupported', { ns: 'app' })}</div>
<div className="body-xs-regular mt-1 text-text-secondary">{t('structOutput.modelNotSupportedTip', { ns: 'app' })}</div>
</div>
)}
>
@ -273,9 +273,9 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
</div>
</Tooltip>
)}
<div className="system-xs-medium-uppercase mr-0.5 text-text-tertiary">{t('app.structOutput.structured')}</div>
<div className="system-xs-medium-uppercase mr-0.5 text-text-tertiary">{t('structOutput.structured', { ns: 'app' })}</div>
<Tooltip popupContent={
<div className="max-w-[150px]">{t('app.structOutput.structuredTip')}</div>
<div className="max-w-[150px]">{t('structOutput.structuredTip', { ns: 'app' })}</div>
}
>
<div>
@ -296,17 +296,17 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
<VarItem
name="text"
type="string"
description={t(`${i18nPrefix}.outputVars.output`)}
description={t(`${i18nPrefix}.outputVars.output`, { ns: 'workflow' })}
/>
<VarItem
name="reasoning_content"
type="string"
description={t(`${i18nPrefix}.outputVars.reasoning_content`)}
description={t(`${i18nPrefix}.outputVars.reasoning_content`, { ns: 'workflow' })}
/>
<VarItem
name="usage"
type="object"
description={t(`${i18nPrefix}.outputVars.usage`)}
description={t(`${i18nPrefix}.outputVars.usage`, { ns: 'workflow' })}
/>
{inputs.structured_output_enabled && (
<>

View File

@ -14,7 +14,7 @@ import useAvailableVarList from '../_base/hooks/use-available-var-list'
import useNodeCrud from '../_base/hooks/use-node-crud'
import { findVariableWhenOnLLMVision } from '../utils'
const i18nPrefix = 'workflow.nodes.llm'
const i18nPrefix = 'nodes.llm'
type Params = {
id: string
payload: LLMNodeType
@ -125,7 +125,7 @@ const useSingleRunFormParams = ({
if (varInputs.length > 0) {
forms.push(
{
label: t(`${i18nPrefix}.singleRun.variable`)!,
label: t(`${i18nPrefix}.singleRun.variable`, { ns: 'workflow' })!,
inputs: varInputs,
values: inputVarValues,
onChange: setInputVarValues,
@ -136,7 +136,7 @@ const useSingleRunFormParams = ({
if (inputs.context?.variable_selector && inputs.context?.variable_selector.length > 0) {
forms.push(
{
label: t(`${i18nPrefix}.context`)!,
label: t(`${i18nPrefix}.context`, { ns: 'workflow' })!,
inputs: [{
label: '',
variable: '#context#',
@ -153,7 +153,7 @@ const useSingleRunFormParams = ({
forms.push(
{
label: t(`${i18nPrefix}.vision`)!,
label: t(`${i18nPrefix}.vision`, { ns: 'workflow' })!,
inputs: [{
label: currentVariable?.variable as any,
variable: '#files#',