From 28614bb7d45d5e76bf5d057a0eb8f469bc855cc7 Mon Sep 17 00:00:00 2001 From: lin onetwo Date: Tue, 10 Jun 2025 02:27:44 +0800 Subject: [PATCH] fix: translated label --- .github/instructions/agent.instructions.md | 4 +- localization/locales/en/agent.json | 3 +- localization/locales/fr/agent.json | 3 +- localization/locales/ja/agent.json | 3 +- localization/locales/ru/agent.json | 3 +- localization/locales/zh_CN/agent.json | 161 +++++++++-- .../components/ErrorDisplay.tsx | 33 +++ .../components/PromptConfigForm/index.tsx | 116 +++----- .../templates/FieldTemplate.tsx | 11 +- .../templates/ObjectFieldTemplate.tsx | 58 ++-- .../PromptConfigForm/usePromptConfigForm.ts | 109 ------- .../widgets/AutoResizeTextareaWidget.tsx | 2 - .../widgets/CheckboxWidget.tsx | 8 +- .../PromptConfigForm/widgets/SelectWidget.tsx | 7 - .../PromptConfigForm/widgets/TagsWidget.tsx | 2 - .../PromptPreviewDialog/EditView.tsx | 26 +- .../promptConcat/promptConcatSchema/index.ts | 36 ++- .../promptConcatSchema/modelParameters.ts | 40 ++- .../promptDynamicModification.ts | 265 ++++++++++++++---- .../promptConcatSchema/prompts.ts | 70 ++++- .../promptConcatSchema/response.ts | 1 + .../responseDynamicModification.ts | 110 ++++++-- 22 files changed, 685 insertions(+), 386 deletions(-) create mode 100644 src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/components/ErrorDisplay.tsx delete mode 100644 src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/usePromptConfigForm.ts diff --git a/.github/instructions/agent.instructions.md b/.github/instructions/agent.instructions.md index b3dc9f76..d6000909 100644 --- a/.github/instructions/agent.instructions.md +++ b/.github/instructions/agent.instructions.md @@ -1,4 +1,4 @@ --- -applyTo: '**/*.ts|tsx|js|jsx' +applyTo: '**/*.ts|tsx|js|jsx|tid' --- -用英文注释,不用关心eslint的格式要求,全部编辑完成后再用pnpm exec eslint --fix。我使用powershell,但尽量用无须审批的vscode内置功能工具,少用需要人类审批的shell,例如尽量不要通过创建新文件再用powershell覆盖原文件的方式来更新文件。没用的 props 不要保留,不要搞向前兼容,修改时也要检查调用处。还有去掉代码中没用的注释,有话就直接在聊天中和我说就行。 \ No newline at end of file +用英文注释,不用关心eslint的格式要求,全部编辑完成后再用pnpm exec eslint --fix,先不用处理格式,以免影响你的主要工作。我使用powershell,但尽量用无须审批的vscode内置功能工具,少用需要人类审批的shell,例如尽量不要通过创建新文件再用powershell覆盖原文件的方式来更新文件。没用的 props 不要保留,不要搞向前兼容,修改时也要检查调用处。还有去掉代码中没用的注释,有话就直接在聊天中和我说就行。 \ No newline at end of file diff --git a/localization/locales/en/agent.json b/localization/locales/en/agent.json index d2499a41..f13716ca 100644 --- a/localization/locales/en/agent.json +++ b/localization/locales/en/agent.json @@ -202,7 +202,8 @@ "SchemaNotProvided": "Schema Not Provided", "SchemaNotProvidedDescription": "No JSON schema was provided or could be fetched. Form cannot be rendered.", "ToggleFullScreen": "Toggle Fullscreen", - "Tree": "Tree View" + "Tree": "Tree View", + "ValidationErrors": "Validation Errors" }, "PromptConfig": { "AddItem": "", diff --git a/localization/locales/fr/agent.json b/localization/locales/fr/agent.json index d0449421..404a788a 100644 --- a/localization/locales/fr/agent.json +++ b/localization/locales/fr/agent.json @@ -201,7 +201,8 @@ "SchemaNotProvided": "", "SchemaNotProvidedDescription": "", "ToggleFullScreen": "", - "Tree": "" + "Tree": "", + "ValidationErrors": "" }, "PromptConfig": { "AddItem": "", diff --git a/localization/locales/ja/agent.json b/localization/locales/ja/agent.json index 15a557ad..a3805454 100644 --- a/localization/locales/ja/agent.json +++ b/localization/locales/ja/agent.json @@ -202,7 +202,8 @@ "SchemaNotProvided": "", "SchemaNotProvidedDescription": "", "ToggleFullScreen": "", - "Tree": "" + "Tree": "", + "ValidationErrors": "" }, "PromptConfig": { "AddItem": "", diff --git a/localization/locales/ru/agent.json b/localization/locales/ru/agent.json index 8719af46..dfa29af1 100644 --- a/localization/locales/ru/agent.json +++ b/localization/locales/ru/agent.json @@ -202,7 +202,8 @@ "SchemaNotProvided": "", "SchemaNotProvidedDescription": "", "ToggleFullScreen": "", - "Tree": "" + "Tree": "", + "ValidationErrors": "" }, "PromptConfig": { "AddItem": "", diff --git a/localization/locales/zh_CN/agent.json b/localization/locales/zh_CN/agent.json index 952157b2..e17ef88b 100644 --- a/localization/locales/zh_CN/agent.json +++ b/localization/locales/zh_CN/agent.json @@ -202,7 +202,8 @@ "SchemaNotProvided": "格式未提供", "SchemaNotProvidedDescription": "没有提供 JSON Schema 或无法正确获取到。编辑表单无法展示。", "ToggleFullScreen": "切换全屏", - "Tree": "树形视图" + "Tree": "树形视图", + "ValidationErrors": "发现错误" }, "PromptConfig": { "AddItem": "添加项目", @@ -223,13 +224,17 @@ }, "Schema": { "AIConfig": { - "Description": "AI 会话设置配置" + "Description": "AI 会话设置配置", + "Title": "AI 配置" }, "AgentConfig": { "Description": "智能体配置", + "Title": "智能体配置", "Id": "智能体唯一标识符", + "IdTitle": "智能体 ID", "PromptConfig": { "Description": "提示词配置", + "Title": "提示词配置", "PromptDynamicModification": "提示词动态修改配置列表", "Prompts": "提示词配置列表", "Response": "响应配置列表", @@ -238,154 +243,260 @@ }, "AutoReply": { "Description": "自动回复参数配置", + "Title": "自动回复参数", "MaxAutoReply": "最大自动回复次数", + "MaxAutoReplyTitle": "最大回复次数", "TargetId": "目标元素ID", + "TargetIdTitle": "目标ID", "Text": "回复文本", - "Trigger": "触发条件" + "TextTitle": "回复文本", + "Trigger": "触发条件", + "TriggerTitle": "触发条件" }, "AutoReroll": { "Description": "自动重新生成参数配置", + "Title": "自动重新生成参数", "MaxRetry": "最大重试次数", + "MaxRetryTitle": "最大重试次数", "Search": "搜索关键词", - "TargetId": "目标元素ID" + "SearchTitle": "搜索关键词", + "TargetId": "目标元素ID", + "TargetIdTitle": "目标ID" }, "BaseAPIConfig": { "API": "API 提供商和模型配置", + "APITitle": "API 配置", "Description": "基础 API 配置", - "ModelParameters": "模型参数配置" + "ModelParameters": "模型参数配置", + "ModelParametersTitle": "模型参数", + "Title": "基础 API 配置" }, "DefaultAgents": { - "Description": "默认智能体配置列表" + "Description": "默认智能体配置列表", + "Title": "默认智能体" }, "DynamicPosition": { - "Description": "动态位置参数配置" + "Description": "动态位置参数配置", + "Title": "动态位置参数" }, "FullReplacement": { "Description": "完全替换参数配置", + "Title": "完全替换参数", "SourceType": "源类型", - "TargetId": "目标元素ID" + "SourceTypeTitle": "源类型", + "TargetId": "目标元素ID", + "TargetIdTitle": "目标ID" }, "Function": { "Description": "函数参数配置", + "Title": "函数参数", "FunctionId": "函数ID", + "FunctionIdTitle": "函数ID", "TimeoutMessage": "超时消息", + "TimeoutMessageTitle": "超时消息", "TimeoutSecond": "超时时间(秒)", - "Trigger": "触发条件" + "TimeoutSecondTitle": "超时时间", + "Trigger": "触发条件", + "TriggerTitle": "触发条件" + }, + "HandlerConfig": { + "Description": "处理器配置", + "Title": "处理器配置" }, "JavascriptTool": { "Description": "JavaScript 工具参数配置", - "URI": "JavaScript 工具 URI" + "Title": "JavaScript 工具参数", + "URI": "JavaScript 工具 URI", + "URITitle": "工具 URI" }, "MCP": { "Description": "模型上下文协议参数配置", + "Title": "模型上下文协议参数", "Id": "MCP 服务器 ID", + "IdTitle": "服务器 ID", "ResponseProcessing": { "Description": "响应处理配置", - "Id": "响应处理器 ID" + "Title": "响应处理", + "Id": "响应处理器 ID", + "IdTitle": "处理器 ID" }, "TimeoutMessage": "超时消息", + "TimeoutMessageTitle": "超时消息", "TimeoutSecond": "超时时间(秒)", - "Trigger": "触发条件" + "TimeoutSecondTitle": "超时时间", + "Trigger": "触发条件", + "TriggerTitle": "触发条件" }, "ModelParameters": { "Description": "模型参数配置", + "Title": "模型参数", "MaxTokens": "生成的最大令牌数量", + "MaxTokensTitle": "最大令牌数", "SystemPrompt": "模型系统提示词", + "SystemPromptTitle": "系统提示词", "Temperature": "响应生成温度(越高=越创造性)", - "TopP": "Top P 采样参数" + "TemperatureTitle": "温度", + "TopP": "Top P 采样参数", + "TopPTitle": "Top P" }, "Position": { "Bottom": "自底部偏移几条消息", + "BottomTitle": "底部偏移", "Description": "位置参数配置", + "Title": "位置参数", "TargetId": "目标元素ID", + "TargetIdTitle": "目标ID", "Top": "自顶部偏移几条消息", - "Type": "位置类型" + "TopTitle": "顶部偏移", + "Type": "位置类型", + "TypeTitle": "位置类型" }, "Prompt": { "Caption": "简短描述", + "CaptionTitle": "描述", "Children": "子提示词列表,将从上到下,从外到里地拼接为最终的提示词文本。", "Description": "完整的提示词配置,包含类型和内容", + "Title": "提示词", "Enabled": "是否启用此提示词,启用的才会拼入到最终的提示词中", + "EnabledTitle": "启用", "Id": "提示词配置的唯一标识符,方便在 PromptDynamicModification 里通过 targetId 引用。", + "IdTitle": "ID", "Role": "OpenAI 兼容接口的提示词角色", + "RoleTitle": "角色", "Tags": "标签列表", - "Text": "提示词内容,可以包含维基文本支持的语法,例如<<变量名>>。" + "Text": "提示词内容,可以包含维基文本支持的语法,例如<<变量名>>。", + "TextTitle": "文本", + "TagsTitle": "标签", + "ChildrenTitle": "子提示词" }, "PromptDynamicModification": { "Caption": "简短描述", + "CaptionTitle": "描述", "Content": "内容", + "ContentTitle": "内容", "Description": "详细描述", + "Title": "提示词动态修改", "DynamicModificationType": "动态修改类型", + "DynamicModificationTypeTitle": "修改类型", "DynamicPositionParam": "动态位置参数", + "DynamicPositionParamTitle": "动态位置参数", "ForbidOverrides": "是否禁止覆盖", + "ForbidOverridesTitle": "禁止覆盖", "FullReplacementParam": "完全替换参数", + "FullReplacementParamTitle": "完全替换参数", "FunctionParam": "函数参数", + "FunctionParamTitle": "函数参数", "Id": "唯一标识符", + "IdTitle": "ID", "JavascriptToolParam": "JavaScript 工具参数", + "JavascriptToolParamTitle": "JavaScript 工具参数", "MCPParam": "模型上下文协议参数", + "MCPParamTitle": "MCP 参数", "RAGParam": "检索增强生成参数", + "RAGParamTitle": "RAG 参数", "SchemaDescription": "提示词动态修改配置" }, "PromptPart": { "Caption": "提示词的简短描述", + "CaptionTitle": "描述", "Children": "子提示词列表,将从上到下,从外到里地拼接为最终的提示词文本。", "Description": "表示提示词的一部分,可以是文本或嵌套结构", + "Title": "提示词片段", "Id": "唯一标识符,方便在 PromptDynamicModification 里通过 targetId 引用。", + "IdTitle": "ID", "Tags": "标签列表,用于分类和引用", - "Text": "提示词文本内容,可以包含维基文本支持的语法,例如<<变量名>>。" + "Text": "提示词文本内容,可以包含维基文本支持的语法,例如<<变量名>>。", + "TextTitle": "文本", + "TagsTitle": "标签", + "ChildrenTitle": "子提示词" }, "ProviderModel": { "Description": "提供商和模型配置", + "Title": "提供商模型", "Model": "AI 模型名称", - "Provider": "AI 提供商名称" + "ModelTitle": "模型", + "Provider": "AI 提供商名称", + "ProviderTitle": "提供商" }, "RAG": { "Description": "检索增强生成参数配置", + "Title": "检索增强生成参数", "Removal": { "CoolDownChatRound": "上次展示后冷却轮数", + "CoolDownChatRoundTitle": "冷却轮数", "Description": "移除条件", - "ExpireAfterChatRound": "多少轮对话后过期" + "Title": "移除条件", + "ExpireAfterChatRound": "多少轮对话后过期", + "ExpireAfterChatRoundTitle": "过期轮数" }, "SourceType": "源类型", + "SourceTypeTitle": "源类型", "Trigger": "触发条件", - "WikiParam": "Wiki 参数" + "TriggerTitle": "触发条件", + "WikiParam": "Wiki 参数", + "WikiParamTitle": "Wiki 参数" }, "Response": { - "Description": "外部API的响应,通常作为响应动态修改的目标,结构与提示词的一样,可以填写预置内容,也可以作为占位符或容器,由 ResponseDynamicModification 填入外部API的响应的具体内容。" + "Description": "外部API的响应,通常作为响应动态修改的目标,结构与提示词的一样,可以填写预置内容,也可以作为占位符或容器,由 ResponseDynamicModification 填入外部API的响应的具体内容。", + "Title": "响应" }, "ResponseDynamicModification": { "AutoReplyParam": "自动回复参数", + "AutoReplyParamTitle": "自动回复参数", "AutoRerollParam": "自动重新生成参数", + "AutoRerollParamTitle": "自动重新生成参数", "Caption": "简短描述", + "CaptionTitle": "描述", "Description": "响应动态修改配置", + "Title": "响应动态修改", "DynamicModificationType": "动态修改类型", + "DynamicModificationTypeTitle": "修改类型", "ForbidOverrides": "是否禁止覆盖", + "ForbidOverridesTitle": "禁止覆盖", "FullReplacementParam": "完全替换参数", + "FullReplacementParamTitle": "完全替换参数", "Id": "唯一标识符", + "IdTitle": "ID", "ResponseProcessingType": "响应处理类型", - "ToolCallingParam": "工具调用参数" + "ResponseProcessingTypeTitle": "处理类型", + "ToolCallingParam": "工具调用参数", + "ToolCallingParamTitle": "工具调用参数" }, "ToolCalling": { "Description": "工具调用参数配置", + "Title": "工具调用参数", "Match": "匹配模式", - "TargetId": "目标元素ID" + "MatchTitle": "匹配模式", + "TargetId": "目标元素ID", + "TargetIdTitle": "目标ID" }, "Trigger": { "Description": "触发条件配置", + "Title": "触发条件", "Filter": "筛选条件", + "FilterTitle": "筛选条件", "Model": { "Description": "基于模型判断的触发条件", + "Title": "模型判断", "Preset": "预设模型", + "PresetTitle": "预设模型", "System": "系统提示词", - "User": "用户提示词" + "SystemTitle": "系统提示词", + "User": "用户提示词", + "UserTitle": "用户提示词" }, "RandomChance": "随机触发概率", - "Search": "搜索关键词" + "RandomChanceTitle": "随机概率", + "Search": "搜索关键词", + "SearchTitle": "搜索关键词" }, "Wiki": { "Description": "Wiki 参数配置", + "Title": "Wiki 参数", "Filter": "筛选器表达式,可以使用 TiddlyWiki 支持的筛选器,从知识库中提取数据", - "WorkspaceName": "工作区名称" + "FilterTitle": "筛选器", + "WorkspaceName": "工作区名称", + "WorkspaceNameTitle": "工作区名称" } }, "Search": { diff --git a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/components/ErrorDisplay.tsx b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/components/ErrorDisplay.tsx new file mode 100644 index 00000000..8a2c1d15 --- /dev/null +++ b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/components/ErrorDisplay.tsx @@ -0,0 +1,33 @@ +import { Alert, AlertTitle, Collapse, Typography } from '@mui/material'; +import { RJSFValidationError } from '@rjsf/utils'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +interface ErrorDisplayProps { + errors: RJSFValidationError[]; +} + +/** + * Display validation errors in a collapsible alert + */ +export const ErrorDisplay: React.FC = ({ errors }) => { + const { t } = useTranslation('agent'); + + if (errors.length === 0) { + return null; + } + + return ( + + + {t('Prompt.ValidationErrors')} + {errors.map((error, index) => ( + + {error.property ? `${error.property}: ` : ''} + {error.message} + + ))} + + + ); +}; diff --git a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/index.tsx b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/index.tsx index 5466d1ed..1434675f 100644 --- a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/index.tsx +++ b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/index.tsx @@ -1,35 +1,28 @@ -import { AgentWithoutMessages } from '@/pages/Agent/store/agentChatStore/types'; import { Box, CircularProgress, Paper, Typography } from '@mui/material'; +import { IChangeEvent } from '@rjsf/core'; import Form from '@rjsf/mui'; -import { ErrorSchema, ObjectFieldTemplateProps } from '@rjsf/utils'; +import { ObjectFieldTemplateProps, RJSFSchema, RJSFValidationError } from '@rjsf/utils'; import validator from '@rjsf/validator-ajv8'; -import { AgentInstance } from '@services/agentInstance/interface'; import { HandlerConfig } from '@services/agentInstance/promptConcat/promptConcatSchema'; -import React, { useMemo } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { ErrorDisplay } from './components/ErrorDisplay'; import { ArrayItemProvider } from './context/ArrayItemContext'; import { useDefaultUiSchema } from './defaultUiSchema'; import { ArrayFieldTemplate, FieldTemplate, ObjectFieldTemplate, RootObjectFieldTemplate } from './templates'; -import { usePromptConfigForm } from './usePromptConfigForm'; import { widgets } from './widgets'; interface PromptConfigFormProps { /** JSON Schema for form validation and generation */ - schema?: Record; + schema?: RJSFSchema; /** UI schema for layout customization */ uiSchema?: Record; /** Initial form data */ formData?: HandlerConfig; - /** Submit handler for form data */ - onSubmit?: (formData: HandlerConfig) => void; /** Change handler for form data */ onChange?: (formData: HandlerConfig) => void; - /** Error handler for validation errors */ - onError?: (errors: ErrorSchema) => void; - /** Agent update handler */ - onUpdate?: (data: Partial) => Promise; - /** Agent instance (without messages) */ - agent?: AgentWithoutMessages; + /** Error handler for form validation errors */ + onError?: (errors: RJSFValidationError[]) => void; /** Whether the form is disabled */ disabled?: boolean; /** Whether to show loading indicator */ @@ -42,53 +35,17 @@ interface PromptConfigFormProps { */ export const PromptConfigForm: React.FC = ({ schema, - uiSchema: uiSchemaOverride = {}, - formData: initialFormData, - onSubmit: externalSubmit, - onChange: externalChange, - onError: externalError, - onUpdate, - agent, + uiSchema: uiSchemaOverride, + formData, + onChange, + onError, disabled = false, loading = false, }) => { const { t } = useTranslation('agent'); - - // Add debug render tracking in development - if (process.env.NODE_ENV === 'development') { - React.useEffect(() => { - console.log('🔄 PromptConfigForm render with props:', { - hasSchema: schema && Object.keys(schema).length > 0, - hasFormData: !!initialFormData, - hasAgent: !!agent, - disabled, - loading, - }); - }); - } - + const [validationErrors, setValidationErrors] = useState([]); const uiSchema = useDefaultUiSchema(uiSchemaOverride, schema); - const { - localFormData, - formKey, - handleChange, - handleError, - handleSubmit, - } = usePromptConfigForm({ - initialFormData, - schema, - onSubmit: externalSubmit, - onChange: externalChange, - onError: externalError, - onUpdate, - agent, - }); - - if (!schema || Object.keys(schema).length === 0) { - console.error('PromptConfigForm: No schema provided or fetched. Form cannot be rendered.'); - } - const templates = useMemo(() => { const rootObjectFieldTemplate = (props: ObjectFieldTemplateProps) => { const isRootLevel = props.idSchema.$id === 'root'; @@ -104,6 +61,18 @@ export const PromptConfigForm: React.FC = ({ }; }, []); + const handleError = useCallback((errors: RJSFValidationError[]) => { + setValidationErrors(errors); + onError?.(errors); + }, [onError]); + + const handleChange = useCallback((changeEvent: IChangeEvent) => { + const formData = changeEvent.formData; + if (formData) { + onChange?.(formData); + } + }, [onChange]); + if (loading) { return ( @@ -139,24 +108,25 @@ export const PromptConfigForm: React.FC = ({ return ( -
-
- + +
+
+ + + ); }; diff --git a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/templates/FieldTemplate.tsx b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/templates/FieldTemplate.tsx index e25e7622..6ac85599 100644 --- a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/templates/FieldTemplate.tsx +++ b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/templates/FieldTemplate.tsx @@ -1,6 +1,7 @@ import { Box } from '@mui/material'; import { FieldTemplateProps } from '@rjsf/utils'; import React from 'react'; +import { useTranslation } from 'react-i18next'; import { HelpTooltip, StyledErrorText, StyledFieldLabel, StyledFieldWrapper, StyledRequiredIndicator } from '../components'; export const FieldTemplate: React.FC = (props) => { @@ -15,6 +16,7 @@ export const FieldTemplate: React.FC = (props) => { displayLabel, label, } = props; + const { t } = useTranslation('agent'); if (hidden) { return
{children}
; @@ -22,14 +24,17 @@ export const FieldTemplate: React.FC = (props) => { const description = schema.description; + // Translate the label if it exists + const translatedLabel = label ? t(label, label) : undefined; + return ( - {displayLabel && label && ( + {displayLabel && translatedLabel && ( - {label} + {translatedLabel} {required && *} - {typeof description === 'string' && description && } + {typeof description === 'string' && description && } )} diff --git a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/templates/ObjectFieldTemplate.tsx b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/templates/ObjectFieldTemplate.tsx index f9318e1e..3c37d0a6 100644 --- a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/templates/ObjectFieldTemplate.tsx +++ b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/templates/ObjectFieldTemplate.tsx @@ -1,45 +1,19 @@ -import { Box, Grid, Typography } from '@mui/material'; +import { Box, Grid } from '@mui/material'; import { ObjectFieldTemplateProps } from '@rjsf/utils'; -import React, { useState } from 'react'; +import React from 'react'; import { useTranslation } from 'react-i18next'; -import { CollapseIcon, ExpandIcon, HelpTooltip, StyledCard, StyledCardContent, StyledCollapse, StyledExpandButton } from '../components'; +import { HelpTooltip, StyledCard, StyledCardContent, StyledFieldLabel } from '../components'; import { useArrayItemContext } from '../context/ArrayItemContext'; export const ObjectFieldTemplate: React.FC = (props) => { - const { properties, title, schema, uiSchema } = props; - const [expanded, setExpanded] = useState(true); + const { properties, schema, uiSchema } = props; const { t } = useTranslation('agent'); const { isInArrayItem } = useArrayItemContext(); - - // Only allow collapsing if not in array item (since array item has its own collapse control) - const isCollapsible = uiSchema?.['ui:collapsible'] !== false && !isInArrayItem; - const description = schema.description; - // Check if this should use compact layout const compactFieldsValue = uiSchema?.['ui:compactFields'] as unknown; const compactFields = Array.isArray(compactFieldsValue) ? (compactFieldsValue as string[]) : []; const useCompactLayout = compactFields.length > 0; - const handleToggleExpanded = () => { - setExpanded(!expanded); - }; - - const titleWithHelp = ( - - - - {t(title)} - - {typeof description === 'string' && description && } - - {isCollapsible && ( - - {expanded ? : } - - )} - - ); - const renderProperties = () => { if (!useCompactLayout) { // Default vertical layout @@ -87,12 +61,24 @@ export const ObjectFieldTemplate: React.FC = (props) = return ( - {titleWithHelp} - - - {renderProperties()} - - + + {schema.title && ( + + + {t(schema.title)} + {schema.description && } + + + )} + {renderProperties()} + ); }; diff --git a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/usePromptConfigForm.ts b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/usePromptConfigForm.ts deleted file mode 100644 index b0727655..00000000 --- a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/usePromptConfigForm.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { AgentWithoutMessages } from '@/pages/Agent/store/agentChatStore/types'; -import type { IChangeEvent } from '@rjsf/core'; -import { ErrorSchema, RJSFValidationError } from '@rjsf/utils'; -import { AgentInstance } from '@services/agentInstance/interface'; -import { HandlerConfig } from '@services/agentInstance/promptConcat/promptConcatSchema'; -import { isEqual } from 'lodash'; -import { useCallback, useEffect, useRef, useState } from 'react'; - -interface UsePromptConfigFormProps { - initialFormData?: HandlerConfig; - schema?: Record; - onSubmit?: (formData: HandlerConfig) => void; - onChange?: (formData: HandlerConfig) => void; - onError?: (errors: ErrorSchema) => void; - onUpdate?: (data: Partial) => Promise; - agent?: AgentWithoutMessages; -} - -export const usePromptConfigForm = ({ - initialFormData, - schema, - onSubmit: externalSubmit, - onChange: externalChange, - onError: externalError, - onUpdate, - agent, -}: UsePromptConfigFormProps) => { - const [validationErrors, setValidationErrors] = useState([]); - const [localFormData, setLocalFormData] = useState(initialFormData); - const [formKey, setFormKey] = useState(0); - - // Use refs to track previous values and prevent unnecessary re-renders - const previousFormDataReference = useRef(undefined); - const previousSchemaReference = useRef | undefined>(undefined); - - // Set form data from initial form data if provided - with deep comparison using lodash - useEffect(() => { - if (initialFormData && !isEqual(initialFormData, previousFormDataReference.current)) { - setLocalFormData(initialFormData); - previousFormDataReference.current = initialFormData; - } - }, [initialFormData]); - - // Force re-render only when schema significantly changes - useEffect(() => { - if (schema && !isEqual(schema, previousSchemaReference.current)) { - setFormKey(previous => previous + 1); - previousSchemaReference.current = schema; - } - }, [schema]); - - const handleChange = useCallback((event: IChangeEvent, Record>) => { - if (event.formData) { - const updatedFormData: HandlerConfig = event.formData; - setLocalFormData(updatedFormData); - - if (externalChange) { - externalChange(updatedFormData); - } - } - }, [externalChange]); - - const handleError = useCallback((errors: RJSFValidationError[]) => { - const errorSchemas = errors.map(error => { - const property = error.property || 'unknown'; - return { [property]: { __errors: [error.message] } } as ErrorSchema; - }); - setValidationErrors(errorSchemas); - - if (externalError) { - const combinedErrors = errors.reduce((accumulator, error) => { - const property = error.property || 'unknown'; - accumulator[property] = { - __errors: [error.message || 'Unknown error'], - } as ErrorSchema; - return accumulator; - }, {}); - externalError(combinedErrors); - } - }, [externalError]); - - const handleSubmit = useCallback(async (event: IChangeEvent, Record>) => { - try { - if (event.formData) { - const typedFormData: HandlerConfig = event.formData; - if (externalSubmit) { - externalSubmit(typedFormData); - } else if (agent?.id && onUpdate) { - await onUpdate({ - id: agent.id, - handlerConfig: typedFormData, - }); - } - } - } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error); - console.error('Failed to submit form data:', errorMessage); - } - }, [externalSubmit, agent?.id, onUpdate]); - - return { - validationErrors, - localFormData, - formKey, - handleChange, - handleError, - handleSubmit, - }; -}; diff --git a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/AutoResizeTextareaWidget.tsx b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/AutoResizeTextareaWidget.tsx index 6756fc8c..6fd40e60 100644 --- a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/AutoResizeTextareaWidget.tsx +++ b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/AutoResizeTextareaWidget.tsx @@ -15,7 +15,6 @@ export const AutoResizeTextareaWidget: React.FC = ({ disabled, readonly, required, - label, placeholder, uiSchema, }) => { @@ -53,7 +52,6 @@ export const AutoResizeTextareaWidget: React.FC = ({ }, }} required={required} - label={label} placeholder={placeholder} multiline minRows={minRows} diff --git a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/CheckboxWidget.tsx b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/CheckboxWidget.tsx index 6a15a8c0..25573d2e 100644 --- a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/CheckboxWidget.tsx +++ b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/CheckboxWidget.tsx @@ -2,6 +2,7 @@ import { Checkbox, FormControlLabel } from '@mui/material'; import { WidgetProps } from '@rjsf/utils'; import React from 'react'; +import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; const StyledFormControlLabel = styled(FormControlLabel)` @@ -33,12 +34,15 @@ export const CheckboxWidget: React.FC = (props) => { onFocus, onChange, } = props; + const { t } = useTranslation('agent'); + + // Translate the label if it exists + const translatedLabel = label ? t(label, label) : undefined; const handleChange = (event: React.ChangeEvent) => { onChange(event.target.checked); }; - // 修改类型以匹配 Checkbox 组件的期望类型 const handleBlur = () => { onBlur(id, value); }; @@ -61,7 +65,7 @@ export const CheckboxWidget: React.FC = (props) => { onFocus={handleFocus} /> } - label={label} + label={translatedLabel} /> ); }; diff --git a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/SelectWidget.tsx b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/SelectWidget.tsx index 018c9a5a..08f46aa8 100644 --- a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/SelectWidget.tsx +++ b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/SelectWidget.tsx @@ -17,7 +17,6 @@ export const SelectWidget: React.FC = (props) => { readonly, disabled, autofocus, - label, onBlur, onFocus, onChange, @@ -41,11 +40,6 @@ export const SelectWidget: React.FC = (props) => { return ( - {label && ( - - {label} - - )} = (props) => { onChange={handleChange} onBlur={handleBlur} onFocus={handleFocus} - label={label} > {!required && ( diff --git a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/TagsWidget.tsx b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/TagsWidget.tsx index 55027103..6bc7d599 100644 --- a/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/TagsWidget.tsx +++ b/src/pages/Agent/components/TabContent/TabTypes/ChatTabContent/components/PromptConfigForm/widgets/TagsWidget.tsx @@ -16,7 +16,6 @@ export const TagsWidget: React.FC = ({ disabled, readonly, required, - label, placeholder, _schema, _uiSchema, @@ -81,7 +80,6 @@ export const TagsWidget: React.FC = ({ renderInput={(parameters) => ( = ({ })), ); - const saveTimeoutReference = useRef(null); - - const handleFormChange = useCallback((updatedConfig: HandlerConfig) => { - console.log('Form data changed', { - configKeys: Object.keys(updatedConfig), - }); - - if (saveTimeoutReference.current) { - clearTimeout(saveTimeoutReference.current); - } - - saveTimeoutReference.current = setTimeout(async () => { + const handleFormChange = useDebouncedCallback( + async (updatedConfig: HandlerConfig) => { try { await handleConfigChange(updatedConfig); if (agent?.agentDefId) { @@ -69,9 +60,10 @@ export const EditView: React.FC = ({ } catch (error) { console.error('EditView: Error auto-saving config:', error); } - }, 1000); - }, [handleConfigChange, agent?.agentDefId, getPreviewPromptResult, inputText]); - + }, + [handleConfigChange, agent?.agentDefId, getPreviewPromptResult, inputText], + 1000, + ); const handleEditorModeChange = useCallback((_event: React.SyntheticEvent, newValue: 'form' | 'code') => { setEditorMode(newValue); }, []); @@ -80,7 +72,7 @@ export const EditView: React.FC = ({ if (!value) return; try { const parsedConfig = JSON.parse(value) as HandlerConfig; - handleFormChange(parsedConfig); + void handleFormChange(parsedConfig); } catch (error) { console.error('Invalid JSON in code editor:', error); } diff --git a/src/services/agentInstance/promptConcat/promptConcatSchema/index.ts b/src/services/agentInstance/promptConcat/promptConcatSchema/index.ts index 796f125e..1d19edbd 100644 --- a/src/services/agentInstance/promptConcat/promptConcatSchema/index.ts +++ b/src/services/agentInstance/promptConcat/promptConcatSchema/index.ts @@ -15,15 +15,27 @@ const t = identity; * Contains common fields shared between AIConfigSchema and AgentConfigSchema */ export const BaseAPIConfigSchema = z.object({ - api: ProviderModelSchema.meta({ description: t('Schema.BaseAPIConfig.API') }), - modelParameters: ModelParametersSchema.meta({ description: t('Schema.BaseAPIConfig.ModelParameters') }), -}).meta({ description: t('Schema.BaseAPIConfig.Description') }); + api: ProviderModelSchema.meta({ + title: t('Schema.BaseAPIConfig.APITitle'), + description: t('Schema.BaseAPIConfig.API'), + }), + modelParameters: ModelParametersSchema.meta({ + title: t('Schema.BaseAPIConfig.ModelParametersTitle'), + description: t('Schema.BaseAPIConfig.ModelParameters'), + }), +}).meta({ + title: t('Schema.BaseAPIConfig.Title'), + description: t('Schema.BaseAPIConfig.Description'), +}); /** * AI configuration schema for session settings */ export const AIConfigSchema = BaseAPIConfigSchema - .meta({ description: t('Schema.AIConfig.Description') }); + .meta({ + title: t('Schema.AIConfig.Title'), + description: t('Schema.AIConfig.Description'), + }); /** * Handler configuration schema @@ -47,6 +59,7 @@ export const HandlerConfigSchema = z.object({ title: t('PromptConfig.Tabs.ResponseDynamicModification'), }), }).meta({ + title: t('Schema.AgentConfig.PromptConfig.Title'), description: t('Schema.AgentConfig.PromptConfig.Description'), uiSchema: HANDLER_CONFIG_UI_SCHEMA, }); @@ -71,15 +84,24 @@ export const HandlerConfigSchema = z.object({ * ``` */ export const AgentConfigSchema = BaseAPIConfigSchema.extend({ - id: z.string().meta({ description: t('Schema.AgentConfig.Id') }), + id: z.string().meta({ + title: t('Schema.AgentConfig.IdTitle'), + description: t('Schema.AgentConfig.Id'), + }), promptConfig: HandlerConfigSchema, -}).meta({ description: t('Schema.AgentConfig.Description') }); +}).meta({ + title: t('Schema.AgentConfig.Title'), + description: t('Schema.AgentConfig.Description'), +}); /** * Default agents list schema * Contains an array of agent configurations */ -export const DefaultAgentsSchema = z.array(AgentConfigSchema).meta({ description: t('Schema.DefaultAgents.Description') }); +export const DefaultAgentsSchema = z.array(AgentConfigSchema).meta({ + title: t('Schema.DefaultAgents.Title'), + description: t('Schema.DefaultAgents.Description'), +}); export type DefaultAgents = z.infer; export type AgentPromptDescription = z.infer; diff --git a/src/services/agentInstance/promptConcat/promptConcatSchema/modelParameters.ts b/src/services/agentInstance/promptConcat/promptConcatSchema/modelParameters.ts index eed312ac..9a4df8a8 100644 --- a/src/services/agentInstance/promptConcat/promptConcatSchema/modelParameters.ts +++ b/src/services/agentInstance/promptConcat/promptConcatSchema/modelParameters.ts @@ -8,23 +8,47 @@ const t = identity; * Provider and model selection schema */ export const ProviderModelSchema = z.object({ - provider: z.string().meta({ description: t('Schema.ProviderModel.Provider') }), - model: z.string().meta({ description: t('Schema.ProviderModel.Model') }), + provider: z.string().meta({ + title: t('Schema.ProviderModel.ProviderTitle'), + description: t('Schema.ProviderModel.Provider'), + }), + model: z.string().meta({ + title: t('Schema.ProviderModel.ModelTitle'), + description: t('Schema.ProviderModel.Model'), + }), }) .catchall(z.unknown()) - .meta({ description: t('Schema.ProviderModel.Description') }); + .meta({ + title: t('Schema.ProviderModel.Title'), + description: t('Schema.ProviderModel.Description'), + }); /** * Model parameters schema */ export const ModelParametersSchema = z.object({ - temperature: z.number().optional().meta({ description: t('Schema.ModelParameters.Temperature') }), - maxTokens: z.number().optional().meta({ description: t('Schema.ModelParameters.MaxTokens') }), - topP: z.number().optional().meta({ description: t('Schema.ModelParameters.TopP') }), - systemPrompt: z.string().optional().meta({ description: t('Schema.ModelParameters.SystemPrompt') }), + temperature: z.number().optional().meta({ + title: t('Schema.ModelParameters.TemperatureTitle'), + description: t('Schema.ModelParameters.Temperature'), + }), + maxTokens: z.number().optional().meta({ + title: t('Schema.ModelParameters.MaxTokensTitle'), + description: t('Schema.ModelParameters.MaxTokens'), + }), + topP: z.number().optional().meta({ + title: t('Schema.ModelParameters.TopPTitle'), + description: t('Schema.ModelParameters.TopP'), + }), + systemPrompt: z.string().optional().meta({ + title: t('Schema.ModelParameters.SystemPromptTitle'), + description: t('Schema.ModelParameters.SystemPrompt'), + }), }) .catchall(z.unknown()) - .meta({ description: t('Schema.ModelParameters.Description') }); + .meta({ + title: t('Schema.ModelParameters.Title'), + description: t('Schema.ModelParameters.Description'), + }); export type ModelParameters = z.infer; export type ProviderModel = z.infer; diff --git a/src/services/agentInstance/promptConcat/promptConcatSchema/promptDynamicModification.ts b/src/services/agentInstance/promptConcat/promptConcatSchema/promptDynamicModification.ts index a6f692a6..300292a9 100644 --- a/src/services/agentInstance/promptConcat/promptConcatSchema/promptDynamicModification.ts +++ b/src/services/agentInstance/promptConcat/promptConcatSchema/promptDynamicModification.ts @@ -16,9 +16,18 @@ const t = identity; * ``` */ const WikiParameterSchema = z.object({ - workspaceName: z.string().describe(t('Schema.Wiki.WorkspaceName')), - filter: z.string().describe(t('Schema.Wiki.Filter')), -}).describe(t('Schema.Wiki.Description')); + workspaceName: z.string().meta({ + title: t('Schema.Wiki.WorkspaceNameTitle'), + description: t('Schema.Wiki.WorkspaceName'), + }), + filter: z.string().meta({ + title: t('Schema.Wiki.FilterTitle'), + description: t('Schema.Wiki.Filter'), + }), +}).meta({ + title: t('Schema.Wiki.Title'), + description: t('Schema.Wiki.Description'), +}); /** * Trigger conditions that determine when a dynamic modification procedure should be applied to prompt. @@ -36,15 +45,39 @@ const WikiParameterSchema = z.object({ * ``` */ const TriggerSchema = z.object({ - search: z.string().optional().meta({ description: t('Schema.Trigger.Search') }), - randomChance: z.number().min(0).max(1).optional().meta({ description: t('Schema.Trigger.RandomChance') }), - filter: z.string().optional().meta({ description: t('Schema.Trigger.Filter') }), + search: z.string().optional().meta({ + title: t('Schema.Trigger.SearchTitle'), + description: t('Schema.Trigger.Search'), + }), + randomChance: z.number().min(0).max(1).optional().meta({ + title: t('Schema.Trigger.RandomChanceTitle'), + description: t('Schema.Trigger.RandomChance'), + }), + filter: z.string().optional().meta({ + title: t('Schema.Trigger.FilterTitle'), + description: t('Schema.Trigger.Filter'), + }), model: z.object({ - preset: z.string().optional().meta({ description: t('Schema.Trigger.Model.Preset') }), - system: z.string().optional().meta({ description: t('Schema.Trigger.Model.System') }), - user: z.string().optional().meta({ description: t('Schema.Trigger.Model.User') }), - }).optional().meta({ description: t('Schema.Trigger.Model.Description') }), -}).meta({ description: t('Schema.Trigger.Description') }); + preset: z.string().optional().meta({ + title: t('Schema.Trigger.Model.PresetTitle'), + description: t('Schema.Trigger.Model.Preset'), + }), + system: z.string().optional().meta({ + title: t('Schema.Trigger.Model.SystemTitle'), + description: t('Schema.Trigger.Model.System'), + }), + user: z.string().optional().meta({ + title: t('Schema.Trigger.Model.UserTitle'), + description: t('Schema.Trigger.Model.User'), + }), + }).optional().meta({ + title: t('Schema.Trigger.Model.Title'), + description: t('Schema.Trigger.Model.Description'), + }), +}).meta({ + title: t('Schema.Trigger.Title'), + description: t('Schema.Trigger.Description'), +}); /** * Base position parameters used by multiple modification types @@ -59,11 +92,26 @@ const TriggerSchema = z.object({ * ``` */ const PositionParameterSchema = z.object({ - position: z.enum(['relative', 'absolute', 'before', 'after']).meta({ description: t('Schema.Position.Type') }), - targetId: z.string().meta({ description: t('Schema.Position.TargetId') }), - bottom: z.number().optional().meta({ description: t('Schema.Position.Bottom') }), - top: z.number().optional().meta({ description: t('Schema.Position.Top') }), -}).meta({ description: t('Schema.Position.Description')}); + position: z.enum(['relative', 'absolute', 'before', 'after']).meta({ + title: t('Schema.Position.TypeTitle'), + description: t('Schema.Position.Type'), + }), + targetId: z.string().meta({ + title: t('Schema.Position.TargetIdTitle'), + description: t('Schema.Position.TargetId'), + }), + bottom: z.number().optional().meta({ + title: t('Schema.Position.BottomTitle'), + description: t('Schema.Position.Bottom'), + }), + top: z.number().optional().meta({ + title: t('Schema.Position.TopTitle'), + description: t('Schema.Position.Top'), + }), +}).meta({ + title: t('Schema.Position.Title'), + description: t('Schema.Position.Description'), +}); /** * Parameters for dynamicModificationType: "fullReplacement" @@ -77,9 +125,18 @@ const PositionParameterSchema = z.object({ * ``` */ const FullReplacementParameterSchema = z.object({ - targetId: z.string().meta({ description: t('Schema.FullReplacement.TargetId') }), - sourceType: z.enum(['historyOfSession', 'llmResponse']).meta({ description: t('Schema.FullReplacement.SourceType') }), -}).meta({ description: t('Schema.FullReplacement.Description')}); + targetId: z.string().meta({ + title: t('Schema.FullReplacement.TargetIdTitle'), + description: t('Schema.FullReplacement.TargetId'), + }), + sourceType: z.enum(['historyOfSession', 'llmResponse']).meta({ + title: t('Schema.FullReplacement.SourceTypeTitle'), + description: t('Schema.FullReplacement.SourceType'), + }), +}).meta({ + title: t('Schema.FullReplacement.Title'), + description: t('Schema.FullReplacement.Description'), +}); /** * Parameters for dynamicModificationType: "dynamicPosition" @@ -93,7 +150,10 @@ const FullReplacementParameterSchema = z.object({ * } * ``` */ -const DynamicPositionParameterSchema = PositionParameterSchema.extend({}).describe(t('Schema.DynamicPosition.Description')); +const DynamicPositionParameterSchema = PositionParameterSchema.extend({}).meta({ + title: t('Schema.DynamicPosition.Title'), + description: t('Schema.DynamicPosition.Description'), +}); /** * Parameters for dynamicModificationType: "retrievalAugmentedGeneration" @@ -116,14 +176,35 @@ const DynamicPositionParameterSchema = PositionParameterSchema.extend({}).descri * ``` */ const RetrievalAugmentedGenerationParameterSchema = PositionParameterSchema.extend({ - sourceType: z.enum(['wiki']).meta({ description: t('Schema.RAG.SourceType') }), - wikiParam: WikiParameterSchema.optional().meta({ description: t('Schema.RAG.WikiParam') }), - trigger: TriggerSchema.optional().meta({ description: t('Schema.RAG.Trigger') }), + sourceType: z.enum(['wiki']).meta({ + title: t('Schema.RAG.SourceTypeTitle'), + description: t('Schema.RAG.SourceType'), + }), + wikiParam: WikiParameterSchema.optional().meta({ + title: t('Schema.RAG.WikiParamTitle'), + description: t('Schema.RAG.WikiParam'), + }), + trigger: TriggerSchema.optional().meta({ + title: t('Schema.RAG.TriggerTitle'), + description: t('Schema.RAG.Trigger'), + }), removal: z.object({ - expireAfterChatRound: z.number().optional().meta({ description: t('Schema.RAG.Removal.ExpireAfterChatRound') }), - coolDownChatRoundAfterLastShown: z.number().optional().meta({ description: t('Schema.RAG.Removal.CoolDownChatRound') }), - }).optional().meta({ description: t('Schema.RAG.Removal.Description') }), -}).meta({ description: t('Schema.RAG.Description')}); + expireAfterChatRound: z.number().optional().meta({ + title: t('Schema.RAG.Removal.ExpireAfterChatRoundTitle'), + description: t('Schema.RAG.Removal.ExpireAfterChatRound'), + }), + coolDownChatRoundAfterLastShown: z.number().optional().meta({ + title: t('Schema.RAG.Removal.CoolDownChatRoundTitle'), + description: t('Schema.RAG.Removal.CoolDownChatRound'), + }), + }).optional().meta({ + title: t('Schema.RAG.Removal.Title'), + description: t('Schema.RAG.Removal.Description'), + }), +}).meta({ + title: t('Schema.RAG.Title'), + description: t('Schema.RAG.Description'), +}); /** * Parameters for dynamicModificationType: "function" @@ -147,11 +228,26 @@ const RetrievalAugmentedGenerationParameterSchema = PositionParameterSchema.exte * ``` */ const FunctionParameterSchema = PositionParameterSchema.extend({ - functionId: z.string().meta({ description: t('Schema.Function.FunctionId') }), - timeoutSecond: z.number().optional().meta({ description: t('Schema.Function.TimeoutSecond') }), - timeoutMessage: z.string().optional().meta({ description: t('Schema.Function.TimeoutMessage') }), - trigger: TriggerSchema.optional().meta({ description: t('Schema.Function.Trigger') }), -}).meta({ description: t('Schema.Function.Description')}); + functionId: z.string().meta({ + title: t('Schema.Function.FunctionIdTitle'), + description: t('Schema.Function.FunctionId'), + }), + timeoutSecond: z.number().optional().meta({ + title: t('Schema.Function.TimeoutSecondTitle'), + description: t('Schema.Function.TimeoutSecond'), + }), + timeoutMessage: z.string().optional().meta({ + title: t('Schema.Function.TimeoutMessageTitle'), + description: t('Schema.Function.TimeoutMessage'), + }), + trigger: TriggerSchema.optional().meta({ + title: t('Schema.Function.TriggerTitle'), + description: t('Schema.Function.Trigger'), + }), +}).meta({ + title: t('Schema.Function.Title'), + description: t('Schema.Function.Description'), +}); /** * Parameters for dynamicModificationType: "javascriptTool" @@ -166,8 +262,14 @@ const FunctionParameterSchema = PositionParameterSchema.extend({ * ``` */ const JavascriptToolParameterSchema = PositionParameterSchema.extend({ - uri: z.string().meta({ description: t('Schema.JavascriptTool.URI') }), -}).meta({ description: t('Schema.JavascriptTool.Description')}); + uri: z.string().meta({ + title: t('Schema.JavascriptTool.URITitle'), + description: t('Schema.JavascriptTool.URI'), + }), +}).meta({ + title: t('Schema.JavascriptTool.Title'), + description: t('Schema.JavascriptTool.Description'), +}); /** * Parameters for dynamicModificationType: "modelContextProtocol" @@ -189,14 +291,35 @@ const JavascriptToolParameterSchema = PositionParameterSchema.extend({ * ``` */ const ModelContextProtocolParameterSchema = PositionParameterSchema.extend({ - id: z.string().meta({ description: t('Schema.MCP.Id') }), - timeoutSecond: z.number().optional().meta({ description: t('Schema.MCP.TimeoutSecond') }), - timeoutMessage: z.string().optional().meta({ description: t('Schema.MCP.TimeoutMessage') }), + id: z.string().meta({ + title: t('Schema.MCP.IdTitle'), + description: t('Schema.MCP.Id'), + }), + timeoutSecond: z.number().optional().meta({ + title: t('Schema.MCP.TimeoutSecondTitle'), + description: t('Schema.MCP.TimeoutSecond'), + }), + timeoutMessage: z.string().optional().meta({ + title: t('Schema.MCP.TimeoutMessageTitle'), + description: t('Schema.MCP.TimeoutMessage'), + }), responseProcessing: z.object({ - id: z.array(z.string()).meta({ description: t('Schema.MCP.ResponseProcessing.Id') }), - }).optional().meta({ description: t('Schema.MCP.ResponseProcessing.Description') }), - trigger: TriggerSchema.optional().meta({ description: t('Schema.MCP.Trigger') }), -}).meta({ description: t('Schema.MCP.Description')}); + id: z.array(z.string()).meta({ + title: t('Schema.MCP.ResponseProcessing.IdTitle'), + description: t('Schema.MCP.ResponseProcessing.Id'), + }), + }).optional().meta({ + title: t('Schema.MCP.ResponseProcessing.Title'), + description: t('Schema.MCP.ResponseProcessing.Description'), + }), + trigger: TriggerSchema.optional().meta({ + title: t('Schema.MCP.TriggerTitle'), + description: t('Schema.MCP.Trigger'), + }), +}).meta({ + title: t('Schema.MCP.Title'), + description: t('Schema.MCP.Description'), +}); /** * Main schema for prompt dynamic modifications @@ -223,10 +346,22 @@ const ModelContextProtocolParameterSchema = PositionParameterSchema.extend({ * ``` */ export const PromptDynamicModificationSchema = z.object({ - id: z.string().meta({ description: t('Schema.PromptDynamicModification.Id') }), - caption: z.string().meta({ description: t('Schema.PromptDynamicModification.Caption') }), - content: z.string().optional().meta({ description: t('Schema.PromptDynamicModification.Content') }), - forbidOverrides: z.boolean().optional().default(false).meta({ description: t('Schema.PromptDynamicModification.ForbidOverrides') }), + id: z.string().meta({ + title: t('Schema.PromptDynamicModification.IdTitle'), + description: t('Schema.PromptDynamicModification.Id'), + }), + caption: z.string().meta({ + title: t('Schema.PromptDynamicModification.CaptionTitle'), + description: t('Schema.PromptDynamicModification.Caption'), + }), + content: z.string().optional().meta({ + title: t('Schema.PromptDynamicModification.ContentTitle'), + description: t('Schema.PromptDynamicModification.Content'), + }), + forbidOverrides: z.boolean().optional().default(false).meta({ + title: t('Schema.PromptDynamicModification.ForbidOverridesTitle'), + description: t('Schema.PromptDynamicModification.ForbidOverrides'), + }), // 动态修改过程的类型 dynamicModificationType: z.enum([ @@ -236,16 +371,40 @@ export const PromptDynamicModificationSchema = z.object({ 'function', 'javascriptTool', 'modelContextProtocol', - ]).meta({ description: t('Schema.PromptDynamicModification.DynamicModificationType') }), + ]).meta({ + title: t('Schema.PromptDynamicModification.DynamicModificationTypeTitle'), + description: t('Schema.PromptDynamicModification.DynamicModificationType'), + }), // 根据 dynamicModificationType 不同,而使用不同的参数配置 - fullReplacementParam: FullReplacementParameterSchema.optional().meta({ description: t('Schema.PromptDynamicModification.FullReplacementParam') }), - dynamicPositionParam: DynamicPositionParameterSchema.optional().meta({ description: t('Schema.PromptDynamicModification.DynamicPositionParam') }), - retrievalAugmentedGenerationParam: RetrievalAugmentedGenerationParameterSchema.optional().meta({ description: t('Schema.PromptDynamicModification.RAGParam') }), - functionParam: FunctionParameterSchema.optional().meta({ description: t('Schema.PromptDynamicModification.FunctionParam') }), - javascriptToolParam: JavascriptToolParameterSchema.optional().meta({ description: t('Schema.PromptDynamicModification.JavascriptToolParam') }), - modelContextProtocolParam: ModelContextProtocolParameterSchema.optional().meta({ description: t('Schema.PromptDynamicModification.MCPParam') }), -}).meta({ description: t('Schema.PromptDynamicModification.SchemaDescription') }); + fullReplacementParam: FullReplacementParameterSchema.optional().meta({ + title: t('Schema.PromptDynamicModification.FullReplacementParamTitle'), + description: t('Schema.PromptDynamicModification.FullReplacementParam'), + }), + dynamicPositionParam: DynamicPositionParameterSchema.optional().meta({ + title: t('Schema.PromptDynamicModification.DynamicPositionParamTitle'), + description: t('Schema.PromptDynamicModification.DynamicPositionParam'), + }), + retrievalAugmentedGenerationParam: RetrievalAugmentedGenerationParameterSchema.optional().meta({ + title: t('Schema.PromptDynamicModification.RAGParamTitle'), + description: t('Schema.PromptDynamicModification.RAGParam'), + }), + functionParam: FunctionParameterSchema.optional().meta({ + title: t('Schema.PromptDynamicModification.FunctionParamTitle'), + description: t('Schema.PromptDynamicModification.FunctionParam'), + }), + javascriptToolParam: JavascriptToolParameterSchema.optional().meta({ + title: t('Schema.PromptDynamicModification.JavascriptToolParamTitle'), + description: t('Schema.PromptDynamicModification.JavascriptToolParam'), + }), + modelContextProtocolParam: ModelContextProtocolParameterSchema.optional().meta({ + title: t('Schema.PromptDynamicModification.MCPParamTitle'), + description: t('Schema.PromptDynamicModification.MCPParam'), + }), +}).meta({ + title: t('Schema.PromptDynamicModification.Title'), + description: t('Schema.PromptDynamicModification.SchemaDescription'), +}); export { DynamicPositionParameterSchema, diff --git a/src/services/agentInstance/promptConcat/promptConcatSchema/prompts.ts b/src/services/agentInstance/promptConcat/promptConcatSchema/prompts.ts index cebbeb82..69da0d8b 100644 --- a/src/services/agentInstance/promptConcat/promptConcatSchema/prompts.ts +++ b/src/services/agentInstance/promptConcat/promptConcatSchema/prompts.ts @@ -39,14 +39,32 @@ export interface IPromptPart { * ``` */ export const PromptPartSchema: z.ZodType = z.object({ - id: z.string().meta({ description: t('Schema.PromptPart.Id') }), - text: z.string().optional().meta({ description: t('Schema.PromptPart.Text') }), - tags: z.array(z.string()).optional().meta({ description: t('Schema.PromptPart.Tags') }), - caption: z.string().optional().meta({ description: t('Schema.PromptPart.Caption') }), + id: z.string().meta({ + title: t('Schema.PromptPart.IdTitle'), + description: t('Schema.PromptPart.Id'), + }), + text: z.string().optional().meta({ + title: t('Schema.PromptPart.TextTitle'), + description: t('Schema.PromptPart.Text'), + }), + tags: z.array(z.string()).optional().meta({ + title: t('Schema.PromptPart.TagsTitle'), + description: t('Schema.PromptPart.Tags'), + }), + caption: z.string().optional().meta({ + title: t('Schema.PromptPart.CaptionTitle'), + description: t('Schema.PromptPart.Caption'), + }), get children() { - return z.array(PromptPartSchema).optional().meta({ description: t('Schema.PromptPart.Children') }); + return z.array(PromptPartSchema).optional().meta({ + title: t('Schema.PromptPart.ChildrenTitle'), + description: t('Schema.PromptPart.Children'), + }); }, -}).meta({ description: t('Schema.PromptPart.Description') }); +}).meta({ + title: t('Schema.PromptPart.Title'), + description: t('Schema.PromptPart.Description'), +}); /** * Complete prompt configuration schema @@ -70,14 +88,38 @@ export const PromptPartSchema: z.ZodType = z.object({ * ``` */ export const PromptSchema = z.object({ - id: z.string().meta({ description: t('Schema.Prompt.Id') }), - caption: z.string().meta({ description: t('Schema.Prompt.Caption') }), - enabled: z.boolean().optional().meta({ description: t('Schema.Prompt.Enabled') }), - role: z.enum(['system', 'user', 'assistant']).optional().meta({ description: t('Schema.Prompt.Role') }), - tags: z.array(z.string()).optional().meta({ description: t('Schema.Prompt.Tags') }), - text: z.string().optional().meta({ description: t('Schema.Prompt.Text') }), - children: z.array(PromptPartSchema).optional().meta({ description: t('Schema.Prompt.Children') }), -}).meta({ description: t('Schema.Prompt.Description') }); + id: z.string().meta({ + title: t('Schema.Prompt.IdTitle'), + description: t('Schema.Prompt.Id'), + }), + caption: z.string().meta({ + title: t('Schema.Prompt.CaptionTitle'), + description: t('Schema.Prompt.Caption'), + }), + enabled: z.boolean().optional().meta({ + title: t('Schema.Prompt.EnabledTitle'), + description: t('Schema.Prompt.Enabled'), + }), + role: z.enum(['system', 'user', 'assistant']).optional().meta({ + title: t('Schema.Prompt.RoleTitle'), + description: t('Schema.Prompt.Role'), + }), + tags: z.array(z.string()).optional().meta({ + title: t('Schema.Prompt.TagsTitle'), + description: t('Schema.Prompt.Tags'), + }), + text: z.string().optional().meta({ + title: t('Schema.Prompt.TextTitle'), + description: t('Schema.Prompt.Text'), + }), + children: z.array(PromptPartSchema).optional().meta({ + title: t('Schema.Prompt.ChildrenTitle'), + description: t('Schema.Prompt.Children'), + }), +}).meta({ + title: t('Schema.Prompt.Title'), + description: t('Schema.Prompt.Description'), +}); export type Prompt = z.infer; export type PromptPart = z.infer; diff --git a/src/services/agentInstance/promptConcat/promptConcatSchema/response.ts b/src/services/agentInstance/promptConcat/promptConcatSchema/response.ts index 4e019ade..44527c8d 100644 --- a/src/services/agentInstance/promptConcat/promptConcatSchema/response.ts +++ b/src/services/agentInstance/promptConcat/promptConcatSchema/response.ts @@ -18,6 +18,7 @@ const t = identity; * ``` */ export const ResponseSchema = PromptSchema.extend({}).meta({ + title: t('Schema.Response.Title'), description: t('Schema.Response.Description'), }); diff --git a/src/services/agentInstance/promptConcat/promptConcatSchema/responseDynamicModification.ts b/src/services/agentInstance/promptConcat/promptConcatSchema/responseDynamicModification.ts index 9c768323..7fb86a7b 100644 --- a/src/services/agentInstance/promptConcat/promptConcatSchema/responseDynamicModification.ts +++ b/src/services/agentInstance/promptConcat/promptConcatSchema/responseDynamicModification.ts @@ -17,9 +17,18 @@ const t = identity; * ``` */ const ToolCallingParameterSchema = z.object({ - targetId: z.string().meta({ description: t('Schema.ToolCalling.TargetId') }), - match: z.string().meta({ description: t('Schema.ToolCalling.Match') }), -}).meta({ description: t('Schema.ToolCalling.Description') }); + targetId: z.string().meta({ + title: t('Schema.ToolCalling.TargetIdTitle'), + description: t('Schema.ToolCalling.TargetId'), + }), + match: z.string().meta({ + title: t('Schema.ToolCalling.MatchTitle'), + description: t('Schema.ToolCalling.Match'), + }), +}).meta({ + title: t('Schema.ToolCalling.Title'), + description: t('Schema.ToolCalling.Description'), +}); /** * Parameters for responseProcessingType: "autoReroll" @@ -34,10 +43,22 @@ const ToolCallingParameterSchema = z.object({ * ``` */ const AutoRerollParameterSchema = z.object({ - targetId: z.string().meta({ description: t('Schema.AutoReroll.TargetId') }), - search: z.string().meta({ description: t('Schema.AutoReroll.Search') }), - maxRetry: z.number().meta({ description: t('Schema.AutoReroll.MaxRetry') }), -}).meta({ description: t('Schema.AutoReroll.Description') }); + targetId: z.string().meta({ + title: t('Schema.AutoReroll.TargetIdTitle'), + description: t('Schema.AutoReroll.TargetId'), + }), + search: z.string().meta({ + title: t('Schema.AutoReroll.SearchTitle'), + description: t('Schema.AutoReroll.Search'), + }), + maxRetry: z.number().meta({ + title: t('Schema.AutoReroll.MaxRetryTitle'), + description: t('Schema.AutoReroll.MaxRetry'), + }), +}).meta({ + title: t('Schema.AutoReroll.Title'), + description: t('Schema.AutoReroll.Description'), +}); /** * Parameters for responseType: "autoReply" @@ -59,11 +80,26 @@ const AutoRerollParameterSchema = z.object({ * ``` */ const AutoReplyParameterSchema = z.object({ - targetId: z.string().meta({ description: t('Schema.AutoReply.TargetId') }), - text: z.string().meta({ description: t('Schema.AutoReply.Text') }), - trigger: TriggerSchema.meta({ description: t('Schema.AutoReply.Trigger') }), - maxAutoReply: z.number().meta({ description: t('Schema.AutoReply.MaxAutoReply') }), -}).meta({ description: t('Schema.AutoReply.Description') }); + targetId: z.string().meta({ + title: t('Schema.AutoReply.TargetIdTitle'), + description: t('Schema.AutoReply.TargetId'), + }), + text: z.string().meta({ + title: t('Schema.AutoReply.TextTitle'), + description: t('Schema.AutoReply.Text'), + }), + trigger: TriggerSchema.meta({ + title: t('Schema.AutoReply.TriggerTitle'), + description: t('Schema.AutoReply.Trigger'), + }), + maxAutoReply: z.number().meta({ + title: t('Schema.AutoReply.MaxAutoReplyTitle'), + description: t('Schema.AutoReply.MaxAutoReply'), + }), +}).meta({ + title: t('Schema.AutoReply.Title'), + description: t('Schema.AutoReply.Description'), +}); /** * Main schema for response dynamic modifications @@ -86,20 +122,50 @@ const AutoReplyParameterSchema = z.object({ * ``` */ export const ResponseDynamicModificationSchema = z.object({ - id: z.string().meta({ description: t('Schema.ResponseDynamicModification.Id') }), - caption: z.string().optional().meta({ description: t('Schema.ResponseDynamicModification.Caption') }), + id: z.string().meta({ + title: t('Schema.ResponseDynamicModification.IdTitle'), + description: t('Schema.ResponseDynamicModification.Id'), + }), + caption: z.string().optional().meta({ + title: t('Schema.ResponseDynamicModification.CaptionTitle'), + description: t('Schema.ResponseDynamicModification.Caption'), + }), // 对响应内容做修改的过程 - dynamicModificationType: z.enum(['fullReplacement']).optional().meta({ description: t('Schema.ResponseDynamicModification.DynamicModificationType') }), - fullReplacementParam: FullReplacementParameterSchema.optional().meta({ description: t('Schema.ResponseDynamicModification.FullReplacementParam') }), - forbidOverrides: z.boolean().optional().default(false).meta({ description: t('Schema.ResponseDynamicModification.ForbidOverrides') }), + dynamicModificationType: z.enum(['fullReplacement']).optional().meta({ + title: t('Schema.ResponseDynamicModification.DynamicModificationTypeTitle'), + description: t('Schema.ResponseDynamicModification.DynamicModificationType'), + }), + fullReplacementParam: FullReplacementParameterSchema.optional().meta({ + title: t('Schema.ResponseDynamicModification.FullReplacementParamTitle'), + description: t('Schema.ResponseDynamicModification.FullReplacementParam'), + }), + forbidOverrides: z.boolean().optional().default(false).meta({ + title: t('Schema.ResponseDynamicModification.ForbidOverridesTitle'), + description: t('Schema.ResponseDynamicModification.ForbidOverrides'), + }), // 基于响应结果,调用程序做额外处理的过程 - responseProcessingType: z.enum(['toolCalling', 'autoReroll', 'autoReply']).optional().meta({ description: t('Schema.ResponseDynamicModification.ResponseProcessingType') }), - toolCallingParam: ToolCallingParameterSchema.optional().meta({ description: t('Schema.ResponseDynamicModification.ToolCallingParam') }), - autoRerollParam: AutoRerollParameterSchema.optional().meta({ description: t('Schema.ResponseDynamicModification.AutoRerollParam') }), - autoReplyParam: AutoReplyParameterSchema.optional().meta({ description: t('Schema.ResponseDynamicModification.AutoReplyParam') }), -}).meta({ description: t('Schema.ResponseDynamicModification.Description') }); + responseProcessingType: z.enum(['toolCalling', 'autoReroll', 'autoReply']).optional().meta({ + title: t('Schema.ResponseDynamicModification.ResponseProcessingTypeTitle'), + description: t('Schema.ResponseDynamicModification.ResponseProcessingType'), + }), + toolCallingParam: ToolCallingParameterSchema.optional().meta({ + title: t('Schema.ResponseDynamicModification.ToolCallingParamTitle'), + description: t('Schema.ResponseDynamicModification.ToolCallingParam'), + }), + autoRerollParam: AutoRerollParameterSchema.optional().meta({ + title: t('Schema.ResponseDynamicModification.AutoRerollParamTitle'), + description: t('Schema.ResponseDynamicModification.AutoRerollParam'), + }), + autoReplyParam: AutoReplyParameterSchema.optional().meta({ + title: t('Schema.ResponseDynamicModification.AutoReplyParamTitle'), + description: t('Schema.ResponseDynamicModification.AutoReplyParam'), + }), +}).meta({ + title: t('Schema.ResponseDynamicModification.Title'), + description: t('Schema.ResponseDynamicModification.Description'), +}); export { AutoReplyParameterSchema, AutoRerollParameterSchema, ToolCallingParameterSchema };