From 61fd71cae3f212f3c6e5971fe8a3666c1e01494f Mon Sep 17 00:00:00 2001 From: qihai Date: Mon, 14 Jul 2025 19:05:28 +0800 Subject: [PATCH 01/30] fix(prompt): update prompt state --- .../prompt-pages/src/develop/index.tsx | 8 ++-- .../prompt-pages/src/hooks/use-playground.ts | 6 +-- .../prompt-pages/src/hooks/use-prompt.ts | 40 +++++++++---------- .../src/store/use-mockdata-store.ts | 4 +- 4 files changed, 27 insertions(+), 31 deletions(-) diff --git a/frontend/packages/cozeloop/prompt-pages/src/develop/index.tsx b/frontend/packages/cozeloop/prompt-pages/src/develop/index.tsx index 2be0fe488..8c251fe3a 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/develop/index.tsx +++ b/frontend/packages/cozeloop/prompt-pages/src/develop/index.tsx @@ -20,7 +20,7 @@ export function PromptDevelop() { const queryVersion = searchParams.get('version') || undefined; const [getPromptLoading, setGetPromptLoading] = useState(true); - const { getPromptByVersion } = usePrompt({ promptID, regiesterSub: true }); + const { getPromptByVersion } = usePrompt({ promptID, registerSub: true }); const { clearStore: clearPromptStore, promptInfo } = usePromptStore( useShallow(state => ({ clearStore: state.clearStore, @@ -32,9 +32,9 @@ export function PromptDevelop() { useShallow(state => ({ clearStore: state.clearStore })), ); - const { clearMockdataStore } = usePromptMockDataStore( + const { clearMockDataStore } = usePromptMockDataStore( useShallow(state => ({ - clearMockdataStore: state.clearMockdataStore, + clearMockDataStore: state.clearMockDataStore, })), ); @@ -51,7 +51,7 @@ export function PromptDevelop() { return () => { clearPromptStore(); clearBasicStore(); - clearMockdataStore(); + clearMockDataStore(); }; }, [promptID, queryVersion]); diff --git a/frontend/packages/cozeloop/prompt-pages/src/hooks/use-playground.ts b/frontend/packages/cozeloop/prompt-pages/src/hooks/use-playground.ts index a276c9a4d..6d3a9bbab 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/hooks/use-playground.ts +++ b/frontend/packages/cozeloop/prompt-pages/src/hooks/use-playground.ts @@ -57,7 +57,7 @@ export const usePlayground = () => { setHistoricMessage, setMockVariables, setUserDebugConfig, - clearMockdataStore, + clearMockDataStore, setCompareConfig, } = usePromptMockDataStore( useShallow(state => ({ @@ -66,7 +66,7 @@ export const usePlayground = () => { setUserDebugConfig: state.setUserDebugConfig, compareConfig: state.compareConfig, setCompareConfig: state.setCompareConfig, - clearMockdataStore: state.clearMockdataStore, + clearMockDataStore: state.clearMockDataStore, })), ); @@ -109,7 +109,7 @@ export const usePlayground = () => { setTimeout(() => { clearPromptStore(); clearBasicStore(); - clearMockdataStore(); + clearMockDataStore(); }, 0); }; }, [spaceID]); diff --git a/frontend/packages/cozeloop/prompt-pages/src/hooks/use-prompt.ts b/frontend/packages/cozeloop/prompt-pages/src/hooks/use-prompt.ts index 47c1780eb..af69a4ba9 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/hooks/use-prompt.ts +++ b/frontend/packages/cozeloop/prompt-pages/src/hooks/use-prompt.ts @@ -26,13 +26,10 @@ import { useBasicStore } from '@/store/use-basic-store'; interface UsePromptProps { promptID?: string; - regiesterSub?: boolean; + registerSub?: boolean; } -export const usePrompt = ({ - promptID, - regiesterSub = false, -}: UsePromptProps) => { +export const usePrompt = ({ promptID, registerSub = false }: UsePromptProps) => { const { spaceID } = useSpace(); const { setReadonly, setSaveLock } = useBasicStore( @@ -106,6 +103,20 @@ export const usePrompt = ({ if (onlyGetData) { return res; } + setPromptInfo(res.prompt); + const currentPromptDetail = + res.prompt?.prompt_draft || res.prompt?.prompt_commit; + + const messageList = + currentPromptDetail?.detail?.prompt_template?.messages || []; + setMessageList( + messageList.map(item => ({ ...item, key: nanoid() })), + ); + + setModelConfig(currentPromptDetail?.detail?.model_config); + setToolCallConfig(currentPromptDetail?.detail?.tool_call_config); + setTools(currentPromptDetail?.detail?.tools); + setReadonly(Boolean(version)); if (res.prompt) { const mockRes = await getMockData(); @@ -130,21 +141,6 @@ export const usePrompt = ({ setCompareConfig(mockRes.debug_context?.compare_config); } - setPromptInfo(res.prompt); - const currentPromptDetail = - res.prompt?.prompt_draft || res.prompt?.prompt_commit; - - const messageList = - currentPromptDetail?.detail?.prompt_template?.messages || []; - setMessageList( - messageList.map(item => ({ ...item, key: nanoid() })), - ); - - setModelConfig(currentPromptDetail?.detail?.model_config); - setToolCallConfig(currentPromptDetail?.detail?.tool_call_config); - setTools(currentPromptDetail?.detail?.tools); - setReadonly(Boolean(version)); - setTimeout(() => { setSaveLock(false); }, 500); @@ -231,7 +227,7 @@ export const usePrompt = ({ useEffect(() => { let dataSub: () => void; let mockSub: () => void; - if (regiesterSub && promptID) { + if (registerSub && promptID) { dataSub = usePromptStore.subscribe( state => ({ toolCallConfig: state.toolCallConfig, @@ -290,7 +286,7 @@ export const usePrompt = ({ dataSub?.(); mockSub?.(); }; - }, [regiesterSub, promptID]); + }, [registerSub, promptID]); useEffect(() => { setAutoSaving(savePromptLoading || mockLoading); diff --git a/frontend/packages/cozeloop/prompt-pages/src/store/use-mockdata-store.ts b/frontend/packages/cozeloop/prompt-pages/src/store/use-mockdata-store.ts index 1f1705827..c6c912537 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/store/use-mockdata-store.ts +++ b/frontend/packages/cozeloop/prompt-pages/src/store/use-mockdata-store.ts @@ -116,7 +116,7 @@ interface PromptMockDataAction { index: number, model: SetStateAction, ) => void; - clearMockdataStore: () => void; + clearMockDataStore: () => void; } const normalUpdateFunc = ( @@ -435,7 +435,7 @@ export const usePromptMockDataStore = create< group.currentModel = newValue; }), ), - clearMockdataStore: () => + clearMockDataStore: () => set( produce((state: PromptMockDataState) => { state.historicMessage = []; From 3496d541aeb3bbb00b193dfeeff06918f9c0b6b6 Mon Sep 17 00:00:00 2001 From: qihai Date: Tue, 15 Jul 2025 20:04:54 +0800 Subject: [PATCH 02/30] feat: auth, base, common and components lng --- .../loop-lng/src/locales/auth/en-US.json | 21 ++++++++++ .../loop-lng/src/locales/auth/zh-CN.json | 21 ++++++++++ .../loop-lng/src/locales/base/en-US.json | 21 ++++++++++ .../loop-lng/src/locales/base/zh-CN.json | 21 ++++++++++ .../loop-lng/src/locales/common/en-US.json | 42 +++++++++++++++++++ .../loop-lng/src/locales/common/zh-CN.json | 42 +++++++++++++++++++ .../src/locales/components/en-US.json | 28 +++++++++++++ .../src/locales/components/zh-CN.json | 28 +++++++++++++ 8 files changed, 224 insertions(+) create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/zh-CN.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/base/en-US.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/base/zh-CN.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/components/en-US.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/components/zh-CN.json diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json new file mode 100644 index 000000000..4d218916e --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json @@ -0,0 +1,21 @@ +{ + "api_authorization": "API Authorization", + "account": "Account", + "welcome_to_cozeloop": "Welcome to Cozeloop - Community Edition.", + "please_input_email": "Please enter your email address.", + "please_input_password": "Please enter the password.", + "register": "Register", + "login": "Login", + "please_agree_first": "Please agree {agreement}.", + "user_agreement": "User Agreement", + "token_show_only_once": "This token will be displayed only once. Keep this key in a secure and accessible place. Do not share it with others, nor expose it in browser or other client code.", + "name": "Name", + "expiration_time": "Expiration time", + "token": "Token", + "delete_token": "Delete the token", + "remove_will_affect_all_in_use": "Removal will affect all ongoing uses.", + "confirm": "Confirm.", + "x_days": "{num, plural, =0 {0 day} =1 {1 day} other {# days}}", + "permanent": "Permanent", + "register_or_login_failed": "Registration/Login failed. Please check your email or password." +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/zh-CN.json new file mode 100644 index 000000000..3c7b18a1d --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/zh-CN.json @@ -0,0 +1,21 @@ +{ + "api_authorization": "API 授权", + "account": "账户", + "welcome_to_cozeloop": "欢迎使用扣子罗盘-社区版", + "please_input_email": "请输入邮箱", + "please_input_password": "请输入密码", + "register": "注册", + "login": "登录", + "please_agree_first": "请先同意{agreement}", + "user_agreement": "用户协议", + "token_show_only_once": "此令牌仅显示一次。请将此密钥保存在安全且可获取的地方。不要与他人共享,也不要在浏览器或其他客户端代码中暴露它。", + "name": "名称", + "expiration_time": "过期时间", + "token": "令牌", + "delete_token": "删除令牌", + "remove_will_affect_all_in_use": "移除后会影响所有正在使用", + "confirm": "确定", + "x_days": "{num}天", + "permanent": "永久", + "register_or_login_failed": "注册/登录失败,请检查邮箱或密码" +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/base/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/base/en-US.json new file mode 100644 index 000000000..111ad1662 --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/base/en-US.json @@ -0,0 +1,21 @@ +{ + "space_not_exists": "Space does not exist", + "back": "Back", + "network_error": "Network error", + "click_retry": "Click to retry", + "document": "Document", + "lark_group": "Lark Group", + "prompt_engineering": "Prompt Engineering", + "prompt_development": "Prompt Development", + "evaluation": "Evaluation", + "evaluation_set": "Evaluation set", + "evaluator": "Evaluator", + "experiment": "Experiment", + "observation": "Observation", + "confirm_logout": "Are you sure you want to log out?", + "logout": "Log out", + "cancel": "Cancel.", + "account_settings": "Account settings", + "no_space": "No available space at present.", + "not_join_space": "You have not joined any spaces." +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/base/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/base/zh-CN.json new file mode 100644 index 000000000..7f8bf664b --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/base/zh-CN.json @@ -0,0 +1,21 @@ +{ + "space_not_exists": "空间不存在", + "back": "返回", + "network_error": "网络错误", + "click_retry": "点击重试", + "document": "文档", + "lark_group": "飞书群", + "prompt_engineering": "Prompt 工程", + "prompt_development": "Prompt 开发", + "evaluation": "评测", + "evaluation_set": "评测集", + "evaluator": "评估器", + "experiment": "实验", + "observation": "观测", + "confirm_logout": "确认要退出登录吗?", + "logout": "退出登录", + "cancel": "取消", + "account_settings": "账户设置", + "no_space": "暂无空间", + "not_join_space": "你未加入任何空间" +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json new file mode 100644 index 000000000..f4a4088a5 --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json @@ -0,0 +1,42 @@ +{ + "account": "account", + "back": "Back", + "cancel": "Cancel", + "clear": "Clear", + "collapse": "Collapse", + "confirm": "Confirm", + "debug": "Debug", + "delete": "Delete", + "demo_space": "Demo space", + "description": "Description", + "detail": "Detail", + "email": "email", + "expand": "Expand", + "experiment": "Experiment", + "field_exists": "{field} exists", + "field_is_required": "{field} is required", + "login": "Login", + "name": "Name", + "network_error": "Network error", + "operation": "Operation", + "password": "password", + "permanent": "Permanent", + "please_agree": "Please agree {field}", + "please_input": "Please enter {field}", + "please_select": "Please select {field}", + "preview": "Preview", + "refresh": "Refresh", + "register": "Register", + "remove": "Remove", + "retry": "Retry", + "retrying": "Retrying", + "run": "Run", + "save": "Save", + "submit": "Submit", + "today": "today", + "tomorrow": "tomorrow", + "undefined": "Undefined", + "user_agreement": "user agreement", + "yesterday": "yesterday", + "version": "Version" +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json new file mode 100644 index 000000000..450631abc --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json @@ -0,0 +1,42 @@ +{ + "account": "账户", + "back": "返回", + "cancel": "取消", + "clear": "清空", + "collapse": "收起", + "confirm": "确定", + "debug": "调试", + "delete": "删除", + "demo_space": "样板空间", + "description": "描述", + "detail": "详情", + "email": "邮箱", + "expand": "展开", + "experiment": "实验", + "field_exists": "{field}已存在", + "field_is_required": "{field}必填", + "login": "登录", + "name": "名称", + "network_error": "网络错误", + "operation": "操作", + "password": "密码", + "permanent": "永久", + "please_agree": "请同意{field}", + "please_input": "请输入{field}", + "please_select": "请选择{field}", + "preview": "预览", + "refresh": "刷新", + "register": "注册", + "remove": "移除", + "retry": "重试", + "retrying": "重试中", + "run": "运行", + "save": "保存", + "submit": "提交", + "today": "今天", + "tomorrow": "明天", + "undefined": "未定义", + "user_agreement": "用户协议", + "yesterday": "昨天", + "version": "版本" +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/components/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/components/en-US.json new file mode 100644 index 000000000..c983b7c5f --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/components/en-US.json @@ -0,0 +1,28 @@ +{ + "search_creator": "Search for the creator", + "current_user": "Current user", + "demo_space": "Demo Space", + "refresh": "Refresh", + "reset_to_default": "Reset to default", + "drag_to_sort": "Drag to sort", + "column_management": "Column management", + "copy_id": "Copy ID", + "copy_success": "Copy succeeded", + "copy_failed": "Copying failed", + "view_detail": "View details", + "page_not_found": "Page not found", + "page_load_failed": "Page loading failed", + "no_permission": "No permission", + "click_ascending": "Ascending order", + "click_descending": "Descending order", + "restore_default_sort": "Restore the default sorting", + "copy_content": "Copy the content", + "save_time": "Retention time", + "current_draft": "Current draft", + "submit": "Submit", + "version": "Version", + "submit_time": "Submission time", + "submitter": "Submitter", + "version_description": "Version description", + "version_record": "Version records" +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/components/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/components/zh-CN.json new file mode 100644 index 000000000..ad7bb0cc1 --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/components/zh-CN.json @@ -0,0 +1,28 @@ +{ + "search_creator": "搜索创建人", + "current_user": "当前用户", + "demo_space": "Demo 空间", + "refresh": "刷新", + "reset_to_default": "重置为默认", + "drag_to_sort": "拖动排序", + "column_management": "列管理", + "copy_id": "复制 ID", + "copy_success": "复制成功", + "copy_failed": "复制失败", + "view_detail": "查看详情", + "page_not_found": "页面丢失了", + "page_load_failed": "页面加载失败", + "no_permission": "暂无权限", + "click_ascending": "点击升序", + "click_descending": "点击降序", + "restore_default_sort": "点击恢复默认排序", + "copy_content": "复制内容", + "save_time": "保存时间", + "current_draft": "当前草稿", + "submit": "提交", + "version": "版本", + "submit_time": "提交时间", + "submitter": "提交人", + "version_description": "版本说明", + "version_record": "版本记录" +} From 0a2c8a95af7b0b05f5e648317c907d55d2e5dc05 Mon Sep 17 00:00:00 2001 From: qihai Date: Wed, 16 Jul 2025 10:49:45 +0800 Subject: [PATCH 03/30] feat: prompt, observation lng --- .../loop-lng/src/locales/auth/en-US.json | 2 +- .../loop-lng/src/locales/common/en-US.json | 1 + .../loop-lng/src/locales/common/zh-CN.json | 1 + .../resources/loop-lng/src/locales/en-US.json | 2 +- .../src/locales/observation/en-US.json | 29 ++++++ .../src/locales/observation/zh-CN.json | 29 ++++++ .../loop-lng/src/locales/prompt/en-US.json | 96 +++++++++++++++++++ .../loop-lng/src/locales/prompt/zh-CN.json | 96 +++++++++++++++++++ 8 files changed, 254 insertions(+), 2 deletions(-) create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/observation/en-US.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/observation/zh-CN.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/en-US.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/zh-CN.json diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json index 4d218916e..31017b6f1 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json @@ -15,7 +15,7 @@ "delete_token": "Delete the token", "remove_will_affect_all_in_use": "Removal will affect all ongoing uses.", "confirm": "Confirm.", - "x_days": "{num, plural, =0 {0 day} =1 {1 day} other {# days}}", + "x_days": "{num, plural, zero {0 day} one {1 day} other {# days}}", "permanent": "Permanent", "register_or_login_failed": "Registration/Login failed. Please check your email or password." } diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json index f4a4088a5..7cb129e7f 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json @@ -15,6 +15,7 @@ "experiment": "Experiment", "field_exists": "{field} exists", "field_is_required": "{field} is required", + "field_not_empty": "{field} cannot be empty", "login": "Login", "name": "Name", "network_error": "Network error", diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json index 450631abc..14b521d0c 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json @@ -15,6 +15,7 @@ "experiment": "实验", "field_exists": "{field}已存在", "field_is_required": "{field}必填", + "field_not_empty": "{field}不能为空", "login": "登录", "name": "名称", "network_error": "网络错误", diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/en-US.json index 5fc4a09d0..4d97f33ca 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/en-US.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/en-US.json @@ -38,7 +38,7 @@ "Description": "Description", "edit_pat_1": "Edit Personal Access Token", "Edit": "Edit", - "error": "Sorry, some error occured, please try again later.", + "error": "Sorry, some error occurred, please try again later.", "expand": "Expand", "expire_time_1": "Expiration time", "expired_time_days_1": "{num, plural, one {# day ({date})} other {# days ({date})}}", diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/observation/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/observation/en-US.json new file mode 100644 index 000000000..a0860f8ee --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/observation/en-US.json @@ -0,0 +1,29 @@ +{ + "current_trace_expired_to_view": "The current Trace has expired and cannot be viewed", + "no_permission_to_view_trace": "The current role permissions do not allow viewing the details of this Trace temporarily", + "no_permission_to_view": "No permission to view.", + "copy": "Copy", + "reported_data_not_found": "No reported data was found", + "report_in_sdk": "Please try to write the Input and Output information when reporting SDK data", + "all_span_tip": "Query all SpanIDs and display them at the granularity of reported buried points.", + "root_span_tip": "Query by TraceID and display at the granularity of call entry.", + "llm_span_tip": "Only query and model call-related buried points", + "confirm_delete_view": "Are you sure to delete this view?", + "deletion_irreversible": "The operation will be irreversible after deletion", + "max_display_view_num": "Display a maximum of {num} views", + "default_view_not_editable": "The default view cannot be edited.", + "default_view_cannot_be_deleted": "The default view cannot be deleted", + "new_view_cannot_be_displayed": "The new view cannot be displayed. Please modify the view display management", + "viewing_method": "Viewing method", + "belong_to": "Belong to", + "data_source": "Data source", + "viewing_method_data_source_linkage": "The viewing method and data source are linked with the Trace list on the outer side and the SDK reporting dropdown box. When saving as a view, these two filtering conditions need to be set.", + "data_expiration_time": "Data expiration time", + "sdk_reporting": "SDK reporting", + "customize": "Customize", + "all_time": "All the time", + "not_allowed_to_be_empty": "Empty is not allowed", + "name_length_limit": "The name length cannot exceed {num} characters", + "view_name_exists": "The view name already exists", + "tos_url_not_exist": "The TOS URL does not exist. Please contact Cozeloop" +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/observation/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/observation/zh-CN.json new file mode 100644 index 000000000..2c644a86b --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/observation/zh-CN.json @@ -0,0 +1,29 @@ +{ + "current_trace_expired_to_view": "当前 Trace 已过期无法查看", + "no_permission_to_view_trace": "当前的角色权限暂时无法查看该 Trace 详情", + "no_permission_to_view": "无权限查看", + "copy": "复制", + "reported_data_not_found": "未找到上报的数据", + "report_in_sdk": "请尝试在SDK数据上报时,写入Input和Output信息", + "all_span_tip": "查询所有 SpanID,以上报埋点为粒度进行展示", + "root_span_tip": "根据 TraceID 查询,以调用入口为粒度进行展示", + "llm_span_tip": "仅查询和模型调用相关的埋点", + "confirm_delete_view": "确认删除该视图?", + "deletion_irreversible": "删除后操作将不可逆", + "max_display_view_num": "最多展示{num}个视图", + "default_view_not_editable": "默认视图不可编辑", + "default_view_cannot_be_deleted": "默认视图不可删除", + "new_view_cannot_be_displayed": "新视图无法展示, 请修改视图展示管理", + "viewing_method": "查看方式", + "belong_to": "属于", + "data_source": "数据来源", + "viewing_method_data_source_linkage": "查看方式、数据来源,和外侧的 Trace 列表和 SDK 上报下拉框联动。保存为视图时,需要设置这 2 项过滤条件", + "data_expiration_time": "数据到期时间", + "sdk_reporting": "SDK 上报", + "customize": "自定义", + "all_time": "全部时间", + "not_allowed_to_be_empty": "不允许为空", + "name_length_limit": "名称长度不能超过{num}个字符", + "view_name_exists": "视图名称已存在", + "tos_url_not_exist": "TOS URL 不存在,请联系 Cozeloop" +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/en-US.json new file mode 100644 index 000000000..ccf29f4b8 --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/en-US.json @@ -0,0 +1,96 @@ +{ + "please_input_with_vars": "Please enter the content. Variables can be written in the following format: '{{USER_NAME}}", + "temperature": "Temperature", + "max_tokens": "Max tokens", + "top_p": "Top P", + "top_k": "Top K", + "presence_penalty": "Presence penalty", + "frequency_penalty": "Frequency penalty", + "edit_prompt": "Edit Prompt", + "create_copy": "Copy Prompt", + "create_prompt": "Create Prompt", + "prompt_key": "Prompt key", + "prompt_key_format": "Only English letters, digits, \"_\", and \".\" are supported, and it must start with an English letter.", + "prompt_name": "Prompt name", + "prompt_name_format": "Only English letters, digits, Chinese characters, \"-\", \"_\", and \".\" are supported, and it must start with English letters, digits, or Chinese characters.", + "prompt_description": "Prompt description", + "prompt_var_format": "English letters and underscores are supported for input, and the first character must be a letter.", + "placeholder_var_name": "Placeholder variable name", + "placeholder_format": "Only English letters, digits, and underscores are allowed, and the first character must be an English letter.", + "placeholder_name_exists": "The text variable name already exists. Please modify the Placeholder variable name.", + "placeholder_var_error": "The Placeholder variable does not exist or is named incorrectly.", + "historical_data_has_empty_content": "The historical data contains empty content.", + "add_prompt_tpl_or_input_question": "Please add a Prompt template or enter the question content.", + "set_to_reference_group": "Set as the reference group.", + "delete_control_group": "Delete the control group.", + "loading": "Loading", + "load_more": "Load more", + "no_debug_record": "No debugging records now.", + "debug_history": "Debugging history", + "delete_prompt_template": "Delete the Prompt template.", + "confirm_delete_current_prompt_template": "Are you sure you want to delete the current Prompt template?", + "mock_value": "Mock value", + "deeply_thought": "Thought deeply", + "deep_thinking": "Deep in thought", + "num_words": "Number of characters: {num}", + "edit": "Edit", + "delete_message": "Delete the message", + "confirm_delete_message": "Are you sure to delete this message?", + "rerun": "Rerun", + "delete_success": "Deletion successful", + "delete_prompt": "Delete the Prompt", + "copy_prompt_key": "Copy Prompt Key", + "prompt_key_again_confirm": "Please enter the Prompt Key to confirm again.", + "control_group_index": "Control group {index}", + "orchestration": "Orchestration", + "collapse_model_and_var_area": "Collapse the model configuration and variable area", + "expand_model_and_var_area": "Expand the model configuration and variable area", + "expand_preview_and_debug": "Expand preview and debugging", + "collapse_preview_and_debug": "Collapse the preview and debugging", + "no_draft_change": "Currently no draft changes", + "submitted": "Submitted", + "placeholder_var_create_error": "The variable name of Placeholder does not exist or is named incorrectly, and cannot be created", + "model_id": "Model ID", + "model_name": "Model name", + "submission_no_version_diff": "There is no version difference in this submission.", + "open_enable_function": "Turn on the enabling function.", + "close_enable_function": "Turn off the enabling function.", + "continue": "Continue", + "close": "Close", + "input_version_number": "Please enter the version number. The format of the version number is a.b.c, and each segment ranges from 0 to 9999.", + "image_upload_error": "Image upload failed. Please try again later.", + "max_upload_picture_num": "Upload a maximum of {num} pictures.", + "image_size_not_exceed_num_mb": "The size of the picture cannot exceed {num}MB.", + "clear_history_messages": "Clear historical messages.", + "input_question_tip": "Please enter a question to test the large model's response. Press Enter to send, and Shift+Enter to start a new line.", + "delete_function": "Delete function", + "confirm_delete_function": "Are you sure you want to delete this function?", + "method_exists": "The current method already exists. Please rename it.", + "new_function": "New function", + "method_name_rule": "The method name must consist of a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.", + "input_mock_value_here": "Enter simulation values here to simulate the return values of the function.", + "trace_id": "Trace ID", + "copy_trace_id": "Copy the Trace ID", + "copy_variable_name": "Copy the variable name", + "delete_variable": "Delete variable", + "confirm_delete_var_in_tpl": "This variable in the Prompt template will be deleted. Are you sure you want to delete it?", + "param_value": "Parameter value", + "mock_message_group": "Mock message group - {key}", + "mock_message": "Mock message", + "system_role": "System", + "assistant_role": "Assistant", + "user_role": "User", + "rollback_success": "Rollback succeeded.", + "restore_to_this_version": "Restore to this version.", + "restore_version_tip": "Restoring will overwrite the latest edited prompt. Confirm to restore to this version?", + "restore": "Restore", + "model_run_error": "An error occurred during the model operation.", + "model_runtime_error": "Model operation error", + "prompt_id_inconsistent": "The prompt IDs are inconsistent", + "recent_submission_time": "Recent submission time", + "search_prompt_key_or_prompt_name": "Search for Prompt Key or Prompt name", + "no_prompt": "No Prompt", + "prompt_version_number_needed": "The Prompt version number needs to be provided.", + "incorrect_version_number": "The version number format is incorrect.", + "version_number_lt_error": "The version number cannot be less than the current version." +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/zh-CN.json new file mode 100644 index 000000000..cbb92a677 --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/zh-CN.json @@ -0,0 +1,96 @@ +{ + "please_input_with_vars": "请输入内容,支持按此格式书写变量:'{{USER_NAME}}", + "temperature": "生成随机性", + "max_tokens": "最大回复长度", + "top_p": "Top P", + "top_k": "Top K", + "presence_penalty": "存在惩罚", + "frequency_penalty": "频率惩罚", + "edit_prompt": "编辑 Prompt", + "create_copy": "创建副本", + "create_prompt": "创建 Prompt", + "prompt_key": "Prompt key", + "prompt_key_format": "仅支持英文字母、数字、“_”、“.”,且仅支持英文字母开头", + "prompt_name": "Prompt 名称", + "prompt_name_format": "仅支持英文字母、数字、中文,“-”,“_”,“.”,且仅支持英文字母、数字、中文开头", + "prompt_description": "Prompt 描述", + "prompt_var_format": "支持输入英文字母和下划线,且首字母必须是字母", + "placeholder_var_name": "Placeholder 变量名", + "placeholder_format": "只允许输入英文、数字及下划线且首字母需为英文", + "placeholder_name_exists": "文本变量名称已存在,请修改 Placeholder 变量名", + "placeholder_var_error": "Placeholder 变量不存在或命名错误", + "historical_data_has_empty_content": "历史数据有空内容", + "add_prompt_tpl_or_input_question": "请添加 Prompt 模板或输入提问内容", + "set_to_reference_group": "设置为基准组", + "delete_control_group": "删除对照组", + "loading": "加载中", + "load_more": "加载更多", + "no_debug_record": "暂无调试记录", + "debug_history": "调试历史", + "delete_prompt_template": "删除 Prompt 模板", + "confirm_delete_current_prompt_template": "确定删除当前 Prompt 模板?", + "mock_value": "模拟值", + "deeply_thought": "已深度思考", + "deep_thinking": "深度思考中", + "num_words": "字数: {num}", + "edit": "编辑", + "delete_message": "删除消息", + "confirm_delete_message": "确认删除该消息吗?", + "rerun": "重新运行", + "delete_success": "删除成功", + "delete_prompt": "删除Prompt", + "copy_prompt_key": "复制 Prompt Key", + "prompt_key_again_confirm": "请输入 Prompt Key 再次确认", + "control_group_index": "对照组{index}", + "orchestration": "编排", + "collapse_model_and_var_area": "收起模型配置与变量区", + "expand_model_and_var_area": "展开模型配置与变量区", + "expand_preview_and_debug": "展开预览与调试", + "collapse_preview_and_debug": "收起预览与调试", + "no_draft_change": "当前无草稿变更", + "submitted": "已提交", + "placeholder_var_create_error": "Placeholder 变量名不存在或命名错误,无法创建", + "model_id": "模型 ID", + "model_name": "模型名称", + "submission_no_version_diff": "本次提交无版本差异", + "open_enable_function": "打开 启用函数", + "close_enable_function": "关闭 启用函数", + "continue": "继续", + "close": "关闭", + "input_version_number": "请输入版本号,版本号格式为a.b.c, 且每段为0-9999", + "image_upload_error": "图片上传失败,请稍后重试", + "max_upload_picture_num": "最多上传{num}张图片", + "image_size_not_exceed_num_mb": "图片大小不能超过{num}MB", + "clear_history_messages": "清空历史消息", + "input_question_tip": "请输入问题测试大模型回复,回车发送,Shift+回车换行", + "delete_function": "删除函数", + "confirm_delete_function": "确认删除该函数吗?", + "method_exists": "当前方法已经存在,请重新命名", + "new_function": "新函数", + "method_name_rule": "方法名称必须是 a-z、A-Z、0-9,或包含下划线和破折号,长度最长为 64。", + "input_mock_value_here": "在此处输入模拟值以模拟函数的返回值。", + "trace_id": "Trace ID", + "copy_trace_id": "复制 Trace ID", + "copy_variable_name": "复制变量名", + "delete_variable": "删除变量", + "confirm_delete_var_in_tpl": "将删除 Prompt 模板中的该变量。确认删除吗?", + "param_value": "参数值", + "mock_message_group": "模拟消息组-{key}", + "mock_message": "模拟消息", + "system_role": "System", + "assistant_role": "Assistant", + "user_role": "User", + "rollback_success": "回滚成功", + "restore_to_this_version": "还原为此版本", + "restore_version_tip": "还原后将覆盖最新编辑的提示词。确认还原为此版本?", + "restore": "还原", + "model_run_error": "模型运行出错", + "model_runtime_error": "模型运行错误", + "prompt_id_inconsistent": "promptID 不一致", + "recent_submission_time": "最近提交时间", + "search_prompt_key_or_prompt_name": "搜索 Prompt Key 或 Prompt 名称", + "no_prompt": "暂无 Prompt", + "prompt_version_number_needed": "需要提供 Prompt 版本号", + "incorrect_version_number": "版本号格式不正确", + "version_number_lt_error": "版本号不能小于当前版本" +} From 2257f5699906b6367812a933ed5cb48e84071262 Mon Sep 17 00:00:00 2001 From: qihai Date: Wed, 16 Jul 2025 14:49:44 +0800 Subject: [PATCH 04/30] feat: evaluate lng --- .../loop-lng/src/locales/common/en-US.json | 4 + .../loop-lng/src/locales/common/zh-CN.json | 4 + .../loop-lng/src/locales/evaluate/en-US.json | 258 ++++++++++++++++++ .../loop-lng/src/locales/evaluate/zh-CN.json | 258 ++++++++++++++++++ .../loop-lng/src/locales/prompt/en-US.json | 1 + .../loop-lng/src/locales/prompt/zh-CN.json | 1 + 6 files changed, 526 insertions(+) create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/en-US.json create mode 100644 frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/zh-CN.json diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json index 7cb129e7f..c96da6ab9 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/en-US.json @@ -13,6 +13,7 @@ "email": "email", "expand": "Expand", "experiment": "Experiment", + "field": "field", "field_exists": "{field} exists", "field_is_required": "{field} is required", "field_not_empty": "{field} cannot be empty", @@ -22,7 +23,9 @@ "operation": "Operation", "password": "password", "permanent": "Permanent", + "please_add": "Please add {field}", "please_agree": "Please agree {field}", + "please_configure": "Please configure {field}", "please_input": "Please enter {field}", "please_select": "Please select {field}", "preview": "Preview", @@ -38,6 +41,7 @@ "tomorrow": "tomorrow", "undefined": "Undefined", "user_agreement": "user agreement", + "unknown_error": "Unknown error", "yesterday": "yesterday", "version": "Version" } diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json index 14b521d0c..ca0024888 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/common/zh-CN.json @@ -13,6 +13,7 @@ "email": "邮箱", "expand": "展开", "experiment": "实验", + "field": "字段", "field_exists": "{field}已存在", "field_is_required": "{field}必填", "field_not_empty": "{field}不能为空", @@ -22,7 +23,9 @@ "operation": "操作", "password": "密码", "permanent": "永久", + "please_add": "请添加{field}", "please_agree": "请同意{field}", + "please_configure": "请配置{field}", "please_input": "请输入{field}", "please_select": "请选择{field}", "preview": "预览", @@ -38,6 +41,7 @@ "tomorrow": "明天", "undefined": "未定义", "user_agreement": "用户协议", + "unknown_error": "未知问题", "yesterday": "昨天", "version": "版本" } diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/en-US.json new file mode 100644 index 000000000..0c0bf1f10 --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/en-US.json @@ -0,0 +1,258 @@ +{ + "compact_view": "Compact view", + "loose_view": "Loose view", + "draft_version": "Draft version", + "modify_not_submitted": "Modifications are not submitted", + "go_submit": "Go to submit", + "select_experiment": "Select experiment", + "initiate_experiment_comparison": "Initiate an experimental comparison", + "only_experiments_with_same_evaluation_set_and_completed_can_be_compared": "Only experiments with the same evaluation set and have been completed can be compared.", + "selected": "Selected", + "creator": "Creator", + "evaluation_object_type": "Evaluation object type", + "evaluation_object": "Evaluation object", + "coze_bot": "Coze Bot", + "coze_agent": "Coze Agent", + "evaluation_set_version": "Evaluation set version", + "status": "Status", + "this_is_a_cozebot": "This is a CozeBot", + "pedia_dataset": "Encyclopedic dataset ${index}", + "view_actual_output_trace": "Check the actual output trace", + "experiment_name": "Experiment name", + "the_field_required": "The field is required", + "experiment_description": "Experiment description", + "edit_experiment": "Edit the experiment", + "retrying": "Retrying", + "retry": "Retry", + "choose_model": "Please select a model", + "check_parameters": "Check the parameters", + "no_data": "No data", + "associated_experiment": "Related experiments", + "evaluator_type": "Evaluator type", + "model_selection": "", + "debug": "Debug", + "preview_and_debug": "", + "construct_test_data_to_preview_evaluator_runtime_result": "Previewed the running results of the evaluator by constructing test data.", + "config_info": "Config info", + "construct_test_data": "Construct test data", + "testrun_require_fee": "The testrun will incur resource point consumption", + "clear": "Clear", + "run": "Run", + "generated_by_ai_tip": "The content is generated by AI. Its authenticity and accuracy cannot be guaranteed and it is for reference only.", + "evaluator_lacks_input": "The evaluator lacks input", + "information_unsaved": "The information is not saved", + "leave_page_tip": "Leaving the current page will result in the information not being saved.", + "confirm": "Confirm", + "new_evaluator": "Create evaluator", + "description": "Description", + "create": "Create", + "confirm_clear_prompt": "Confirm to clear the Prompt?", + "system_prompt_not_empty": "The System Prompt cannot be empty.", + "delete_user_prompt": "Delete User Prompt", + "confirm_delete_user_prompt": "Confirm to delete the User Prompt?", + "add_user_prompt": "Add User Prompt", + "submit_new_version": "Submit a new version", + "create_evaluator": "Create evaluator", + "version_number_format": "The version number is in the format of a.b.c, and each segment ranges from 0 to 9999", + "version_number": "Version number", + "version_number_gt_current": "The version number must be greater than the current version number: {version}", + "version_description": "Version description", + "select_template": "Select a template", + "preset_evaluator": "Preset evaluator", + "preview": "Preview", + "edit_evaluator": "Edit evaluator", + "draft_auto_saving": "", + "draft_auto_save_failed": "", + "draft_auto_saved_date": "The draft has been automatically saved on {date}.", + "submission_time": "Submission time:", + "submitter": "Submitter:", + "description_is": "Description: {desc}", + "version_submit_success": "Version submitted", + "search_name": "", + "copy_evaluator_config": "Copy the evaluator config", + "copy_record_name_config_and_create_new_evaluator": "Copy the config of ${name} and create a new evaluator.", + "evaluator_name": "Evaluator name", + "latest_version": "The latest version", + "updated_person": "Updater", + "update_time": "Update time", + "create_time": "Creation time", + "operation": "Operation", + "detail": "Detail", + "delete": "", + "confirm_delete_evaluator": "Confirm to delete the evaluator: {name} ?", + "this_operation_is_irreversible_please_operate_carefully": "Caution: this operation is irreversible", + "failed_to_find_related_results": "No relevant results found", + "try_other_keywords_or_modify_filter_options": "Please try other keywords or modify the filter options", + "no_evaluator": "No evaluator", + "click_to_create": "Click the button in the upper right corner to create.", + "benchmark_group": "Baseline group", + "remove_experimental_group": "Remove the experimental group", + "experimental_group_index": "Experimental group {index}", + "remove": "Remove", + "collapse": "Collapse", + "expand": "Expand", + "evaluation_object_actual_output": "Actual output of the evaluation object", + "compare_x_experiments": "{count, plural, zero {No experiement to compare} one {Compare 1 experiment} other {Compare {num} experiments.}}", + "benchmark": "Benchmark", + "benchmark_experiment_switch_success": "The benchmark experiment has been switched.", + "data_detail": "Data detail", + "measure_stat": "Indicator statistics", + "data_total_count": "Total data count", + "loading_field_mapping": "Loading field mappings", + "type": "Type", + "select_type": "Please select type", + "actual_output": "Actual output", + "interface_problem": "Request problem", + "evaluation_object_version": "Version of the evaluated object", + "config_evaluation_object_mapping": "Please config the evaluation object mapping", + "add_at_least_one_evaluator": "Add at least one evaluator", + "max_add_x_evaluators": "Add a maximum of 5 evaluators", + "name_and_version": "Name and version", + "field_mapping": "Field mapping", + "next_step_evaluation_set": "Next step: Evaluation set", + "next_step_evaluation_object": "Next step: Evaluation object", + "next_step_evaluator": "Next step: Evaluator", + "confirm_experiment_config": "Confirm the experiment config", + "initiate_experiment": "Initiate an experiment", + "new_experiment": "New experiment", + "selected_fields_inconsistent": "The data types of the selected fields are inconsistent. Please select again.", + "evaluation_set_field_mapping_tip": "The mapping from the evaluation set fields and the actual outputs of the evaluation objects to the evaluator fields is used for the evaluator to accurately obtain inputs for evaluation.", + "add_evaluator": "Add evaluator", + "submit_form_problems": "Encounter problem when submitting the form", + "update_rating_success": "Score updated", + "view_evaluator_trace": "View the Trace of evaluator", + "manual_calibration": "Manual calibration", + "score_details": "Score detail", + "score": "Score", + "x_items ": "{item, plural, zero {No item} one {1 item} other{# items}}", + "refresh_after_experiment": "Refresh to retry once the experiment is completed", + "aggregation_score": "Aggregation score", + "score_details_data_item_distribution": "Score details - Data item distribution", + "indicator": "Indicator", + "experiment_initializing": "Initializing the experiment", + "wait_and_refresh_page": "Wait a few seconds and then {refresh} the page to view.", + "score_reason": "Reasons for scoring", + "end_time": "End time", + "confirm_evaluation_set_version": "Confirm the version of the evaluation set used for the experiment", + "draft_unsubmitted_tip": "There are unsubmitted changes in the current draft. The latest historical version has been selected by default", + "retain_one_data_item": "Retain at least one data item", + "single_max_add_data_items": "A maximum of {num} data items can be added at one time.", + "data_item_index": "Data item {index}", + "collapse_all_data_items": "Collapse all data items", + "expand_all_data_items": "Expand all data items", + "execution_result": "Execution result", + "known": "I known", + "confirm_delete_x_columns": "Confirm to delete {num} columns. This operation is irreversible.", + "delete_column": "Delete the column", + "max_support_columns": "Supports a maximum of {num} columns", + "column_name": "Column name", + "column_description": "Column description", + "add_column": "Add column", + "basic_info": "Basic info", + "evaluation_set_name": "Evaluation set name", + "evaluation_set_description": "Evaluation set description", + "configuration_column": "Config columns", + "can_still_modify_column": "Column configuration can still be modified after the evaluation set is created.", + "data_type": "Data type", + "view_format": "View the format", + "no_modification_to_submit": "No modification to submit", + "version_format_and_range": "The version format is a.b.c, and each segment ranges from 0 to 999.", + "click_to_add_data": "", + "edit_evaluation_set": "Edit evaluation set", + "import_data": "Import data", + "upload_data": "Upload data", + "click_or_drag_file_to_upload": "Click to upload or drag files here", + "recommend_template_upload_tip": "It is recommended to upload 1 file using the template. CSV format is supported", + "download_template": "Download template", + "upload_file": "Please upload the file", + "no_mapping_no_import": "The column will not be imported if no mapping relationship is configured for a column in the dataset to be imported", + "column_mapping": "Column mapping", + "source_column_mapping": "The mapping relationship between the column names of the data to be imported and the column names of the current evaluation set.", + "configure_at_least_one_import_column": "Please configure at least one import column", + "import_method": "Import method", + "import": "Import", + "no_evaluation_dataset": "No evaluation set", + "click_to_create_evaluation_set": "Click the \"New Evaluation Set\" button in the upper right - hand corner to create one.", + "evaluation_set_column": "Evaluation set columns", + "configure_column_mapping": "Please configure column mapping", + "select_import_method": "Please select the import method", + "confirm_select_full_coverage": "Confirm to select full coverage", + "continue_will_override_existing_data": "Continuing to import data will overwrite the existing data", + "execution_in_progress": "In execution", + "number": "Number", + "string": "String", + "input_num_gte": "Please enter a number greater than or equal to {num}", + "input_num_lte": "Please enter a number less than or equal to {num}", + "integer": "Integer", + "support_precision": "Only supports precision up to {precision} decimal places", + "input_float_with_precision": "Please enter a float number with at most 4 decimal places.", + "edit_data_item": "Edit data items:", + "view_data_item": "View data items:", + "data_item": "Data item", + "delete_evaluation_set": "Delete the evaluation set", + "debug_failure": "Debug failed", + "debugging_succeeded": "Debug succeed", + "reason_is": "Reason: {reason}", + "prompt_detail": "Prompt detail", + "loading_prompt_detail": "Loading Prompt details", + "select_evaluator_and_version_number_to_view": "Please select an evaluator and a version number before viewing", + "model": "Model", + "output": "Output", + "extract_via_function_call": "Extract data from the LLM via Function Call and standardize the output format of the evaluator as \"Score - Reason\".", + "score_is": "Score:", + "rating": "Scoring", + "input_score_between_0_and_1": "Please enter a score between 0 and 1", + "input_number_between_0_and_1": "Please enter a number in the range of 0 to 1", + "keep_precision_num": "Keep at most {num} decimal places", + "reason": "Reason", + "view_evaluator_details": "View the details of the evaluator", + "batch_delete_experiment": "Batch delete experiments", + "confirm_batch_delete_x_experiment": "Are you sure to delete {num} experimental data entries in batch? This modification is irreversible.", + "aggregate_statistics_score_on_metrics": "In the experiment list, aggregate and calculate the scores of each experiment on the indicators.", + "line_chart": "Line chart", + "bar_chart": "Bar chart", + "no_experiment": "No experiment", + "click_to_create_experiment": "Click the \"New Experiment\" button in the upper right corner to create.", + "schema_mismatch": "Schema mismatch", + "empty_data": "Empty data", + "single_data_size_exceeded": "Single data size exceeds the limit", + "dataset_capacity_exceeded": "The dataset capacity exceeds the limit", + "file_format_error": "File format error", + "system_error": "System error", + "contains_illegal_content": "Contains illegal content", + "operator": "Operator", + "equal_to": "Equal to", + "not_equal_to": "Is not equal to", + "contain": "Include", + "not_contain": "Does not contain", + "greater_than": "Greater than", + "greater_than_or_equal_to": "Greater than or equal to", + "less_than": "Less than", + "less_than_or_equal_to": "Less than or equal to", + "later_than": "Later than", + "earlier_than": "Earlier than", + "new_evaluation_set": "Create evaluation set", + "prompt_variable_to_ensure_effect": "The evaluator prompt must have at least one variable to ensure the effectiveness of automatic evaluation", + "new_prompt": "Create Prompt", + "in_progress": "In progress", + "abort": "Abort", + "to_be_executed": "Pending execution", + "fold": "Fold", + "re_evaluate_failed_only": "Re-evaluate the parts that failed to execute only", + "copy_and_create_experiment": "Duplicate the experiment configuration and create a new experiment.", + "associated_evaluation_set": "Related evaluation set", + "delete_experiment": "Delete experiment", + "retry_experiment": "Retry experiment", + "only_re_evaluate_failed_part": "Re-evaluate the parts with failed execution only.", + "copy_experiment_config": "Duplicate the experimental config", + "evaluation_set_field_to_evaluation_object_field_mapping": "Mapping from evaluation set fields to evaluation object fields, used for accurate input acquisition by evaluation objects.", + "get_evaluation_object_error": "An error occurred while obtaining the evaluation object", + "experiments_compared_tip": "Only experiments with the same evaluation set and completed execution can be compared. The currently selected experiments involve different associated evaluation sets. Please reselect.", + "experiment_comparison_max_number": "The maximum number of experimental comparisons cannot exceed {num}. Please make a new selection.", + "only_completed_experiments_can_be_compared": "Only completed experiments can be compared. Please make a new selection.", + "experiment_comparison_initiation_failure": "Failed to initiate the experimental comparison", + "experimental_group": "Experimental group", + "only_support_english_letters_numbers_and_chinese_at_the_beginning": "Only support starting with English letters, numbers, or Chinese characters.", + "only_support_english_letters_numbers_and_chinese_and_": "Only English letters, numbers, Chinese characters, \"-\", \"_\", and \".\" are supported.", + "only_support_english_numbers_and_underscores_and_start_with_a_letter": "Only English letters, digits, and underscores are supported, and it must start with a letter." +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/zh-CN.json new file mode 100644 index 000000000..31b9bb740 --- /dev/null +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/zh-CN.json @@ -0,0 +1,258 @@ +{ + "compact_view": "紧凑视图", + "loose_view": "宽松视图", + "draft_version": "草稿版本", + "modify_not_submitted": "修改未提交", + "go_submit": "去提交", + "select_experiment": "选择实验", + "initiate_experiment_comparison": "发起实验对比", + "only_experiments_with_same_evaluation_set_and_completed_can_be_compared": "仅评测集相同且已执行完成的实验可进行对比。", + "selected": "已选", + "creator": "创建人", + "evaluation_object_type": "评测对象类型", + "evaluation_object": "评测对象", + "coze_bot": "Coze Bot", + "coze_agent": "Coze 智能体", + "evaluation_set_version": "评测集版本", + "status": "状态", + "this_is_a_cozebot": "这是一个 CozeBot", + "pedia_dataset": "百科知识数据集 {index}", + "view_actual_output_trace": "查看实际输出的trace", + "experiment_name": "实验名称", + "the_field_required": "该字段必填", + "experiment_description": "实验描述", + "edit_experiment": "编辑实验", + "retrying": "重试中", + "retry": "重试", + "choose_model": "请选择模型", + "check_parameters": "查看参数", + "no_data": "暂无数据", + "associated_experiment": "关联实验", + "evaluator_type": "评估器类型", + "model_selection": "模型选择", + "debug": "调试", + "preview_and_debug": "预览与调试", + "construct_test_data_to_preview_evaluator_runtime_result": "可通过构造测试数据,预览评估器的运行结果。", + "config_info": "配置信息", + "construct_test_data": "构造测试数据", + "testrun_require_fee": "试运行将产生资源点消耗", + "clear": "清空", + "run": "运行", + "generated_by_ai_tip": "内容由AI生成,无法确保真实准确,仅供参考。", + "evaluator_lacks_input": "评估器缺少输入", + "information_unsaved": "信息未保存", + "leave_page_tip": "离开当前页面,信息将不被保存。", + "confirm": "确认", + "new_evaluator": "新建评估器", + "basic_info": "基础信息", + "description": "描述", + "create": "创建", + "confirm_clear_prompt": "确认清空 Prompt?", + "system_prompt_not_empty": "System Prompt 不可为空", + "delete_user_prompt": "删除 User Prompt", + "confirm_delete_user_prompt": "确认删除 User Prompt ?", + "add_user_prompt": "添加 User Prompt", + "submit_new_version": "提交新版本", + "create_evaluator": "创建评估器", + "version_number_format": "版本号格式为a.b.c,且每段为0-9999", + "version_number": "版本号", + "version_number_gt_current": "版本号必须大于当前版本号:{version}", + "version_description": "版本说明", + "select_template": "选择模板", + "preset_evaluator": "预置评估器", + "preview": "预览", + "edit_evaluator": "编辑评估器", + "draft_auto_saving": "草稿自动保存中", + "draft_auto_save_failed": "草稿自动保存失败", + "draft_auto_saved_date": "草稿已自动保存于{date}", + "submission_time": "提交时间:", + "submitter": "提交人:", + "description_is": "描述:{desc}", + "version_submit_success": "版本提交成功", + "search_name": "搜索名称", + "copy_evaluator_config": "复制评估器配置", + "copy_record_name_config_and_create_new_evaluator": "复制{name}配置,并新建评估器", + "evaluator_name": "评估器名称", + "latest_version": "最新版本", + "updated_person": "更新人", + "update_time": "更新时间", + "create_time": "创建时间", + "operation": "操作", + "detail": "详情", + "delete": "删除", + "confirm_delete_evaluator": "确定删除评估器:{name}?", + "this_operation_is_irreversible_please_operate_carefully": "此操作不可逆,请慎重操作", + "failed_to_find_related_results": "未能找到相关结果", + "try_other_keywords_or_modify_filter_options": "请尝试其他关键词或修改筛选项", + "no_evaluator": "暂无评估器", + "click_to_create": "点击右上角创建按钮进行创建", + "benchmark_group": "基准组", + "remove_experimental_group": "移除实验组", + "experimental_group_index": "实验组 {index}", + "remove": "移除", + "collapse": "收起", + "expand": "展开", + "evaluation_object_actual_output": "评测对象的实际输出", + "compare_x_experiments": "对比{num}个实验", + "benchmark": "基准", + "benchmark_experiment_switch_success": "基准实验切换成功", + "data_detail": "数据明细", + "measure_stat": "指标统计", + "data_total_count": "数据总量", + "loading_field_mapping": "正在加载字段映射", + "type": "类型", + "select_type": "请选择类型", + "actual_output": "实际输出", + "interface_problem": "接口遇到问题", + "evaluation_object_version": "评测对象版本", + "config_evaluation_object_mapping": "请配置评测对象映射", + "add_at_least_one_evaluator": "至少添加一个评估器", + "max_add_x_evaluators": "最多添加5个评估器", + "name_and_version": "名称和版本", + "field_mapping": "字段映射", + "next_step_evaluation_set": "下一步:评测集", + "next_step_evaluation_object": "下一步:评测对象", + "next_step_evaluator": "下一步:评估器", + "confirm_experiment_config": "确认实验配置", + "initiate_experiment": "发起实验", + "new_experiment": "新建实验", + "selected_fields_inconsistent": "所选字段数据类型不一致,请重新选择", + "evaluation_set_field_mapping_tip": "评测集字段、评测对象实际输出到评估器字段的映射,用于评估器准确获取输入进行评估。", + "add_evaluator": "添加评估器", + "submit_form_problems": "提交表单遇到问题", + "update_rating_success": "更新评分成功", + "view_evaluator_trace": "查看评估器 Trace", + "manual_calibration": "人工校准", + "score_details": "得分明细", + "score": "得分", + "x_items ": "{num, plural, zero {无} other {#条}}", + "refresh_after_experiment": "实验完成后,再刷新重试", + "aggregation_score": "聚合得分", + "score_details_data_item_distribution": "得分明细 - 数据项分布", + "indicator": "指标", + "experiment_initializing": "实验初始化中", + "wait_and_refresh_page": "稍等几秒后{refresh}页面查看", + "score_reason": "得分理由", + "end_time": "结束时间", + "confirm_evaluation_set_version": "确认用于实验的评测集版本", + "draft_unsubmitted_tip": "当前草稿有修改未提交,已默认选择最新历史版本", + "retain_one_data_item": "至少保留一个数据项", + "single_max_add_data_items": "单次最多添加{num}条数据项", + "data_item_index": "数据项 {index}", + "collapse_all_data_items": "折叠全部数据项", + "expand_all_data_items": "展开全部数据项", + "execution_result": "执行结果", + "known": "已知晓", + "confirm_delete_x_columns": "确认删除{num}列,此操作不可逆", + "delete_column": "删除列", + "max_support_columns": "最多支持{num}列", + "column_name": "列名称", + "column_description": "列描述", + "add_column": "添加列", + "evaluation_set_name": "评测集名称", + "evaluation_set_description": "评测集描述", + "configuration_column": "配置列", + "can_still_modify_column": "评测集创建完成后,仍可修改列配置", + "data_type": "数据类型", + "view_format": "查看格式", + "no_modification_to_submit": "暂无修改可提交", + "version_format_and_range": "版本格式为a.b.c,且每段为0-999", + "click_to_add_data": "点击右上角添加数据进行添加", + "edit_evaluation_set": "编辑评测集", + "import_data": "导入数据", + "upload_data": "上传数据", + "click_or_drag_file_to_upload": "点击上传或者拖拽文件至此处", + "recommend_template_upload_tip": "推荐使用模板上传1个文件,支持CSV格式", + "download_template": "下载模板", + "upload_file": "请上传文件", + "no_mapping_no_import": "如果待导入数据集的列没有配置映射关系,则该列不会被导入。", + "column_mapping": "列映射", + "source_column_mapping": "待导入数据的列名和当前评测集列名的映射关系。", + "configure_at_least_one_import_column": "请配置最少一个导入列", + "import_method": "导入方式", + "import": "导入", + "no_evaluation_dataset": "暂无评测集", + "click_to_create_evaluation_set": "点击右上角新建评测集按钮进行创建", + "evaluation_set_column": "评测集列", + "configure_column_mapping": "请配置列映射", + "select_import_method": "请选择导入方式", + "confirm_select_full_coverage": "确认选择全量覆盖", + "continue_will_override_existing_data": "继续导入数据将覆盖现有数据", + "execution_in_progress": "执行中", + "number": "数字", + "string": "字符串", + "input_num_gte": "请输入大于等于{num}的数字", + "input_num_lte": "请输入小于等于{num}的数字", + "integer": "整数", + "support_precision": "仅支持精确到小数点后{precision}位", + "input_float_with_precision": "请输入浮点数,至多小数点后4位", + "edit_data_item": "编辑数据项:", + "view_data_item": "查看数据项:", + "data_item": "数据项", + "delete_evaluation_set": "删除评测集", + "debug_failure": "调试失败", + "debugging_succeeded": "调试成功", + "reason_is": "原因:{reason}", + "prompt_detail": "Prompt 详情", + "loading_prompt_detail": "正在加载 Prompt 详情", + "select_evaluator_and_version_number_to_view": "请选择评估器和版本号后再查看", + "model": "模型", + "output": "输出", + "extract_via_function_call": "通过 Function Call 从 LLM 中提取数据,固定评估器输出格式为“得分-原因”。", + "score_is": "得分:", + "rating": "评分", + "input_score_between_0_and_1": "请输入0-1的分值", + "input_number_between_0_and_1": "请输入0~1区间内的数字", + "keep_precision_num": "最多保留小数点后{num}位", + "reason": "原因", + "view_evaluator_details": "查看评估器详情", + "batch_delete_experiment": "批量删除实验", + "confirm_batch_delete_x_experiment": "确认批量删除 {num} 条实验数据吗?此修改将不可逆。", + "aggregate_statistics_score_on_metrics": "在实验列表中,聚合统计各实验在指标上的得分。", + "line_chart": "折线图", + "bar_chart": "柱状图", + "no_experiment": "暂无实验", + "click_to_create_experiment": "点击右上角新建实验按钮进行创建", + "schema_mismatch": "schema 不匹配", + "empty_data": "空数据", + "single_data_size_exceeded": "单条数据大小超限", + "dataset_capacity_exceeded": "数据集容量超限", + "file_format_error": "文件格式错误", + "system_error": "系统错误", + "contains_illegal_content": "包含非法内容", + "operator": "操作符", + "equal_to": "等于", + "not_equal_to": "不等于", + "contain": "包含", + "not_contain": "不包含", + "greater_than": "大于", + "greater_than_or_equal_to": "大于等于", + "less_than": "小于", + "less_than_or_equal_to": "小于等于", + "later_than": "晚于", + "earlier_than": "早于", + "new_evaluation_set": "新建评测集", + "prompt_variable_to_ensure_effect": "为保证自动评测效果,评估器 Prompt 需至少有1个变量", + "new_prompt": "新建 Prompt", + "in_progress": "进行中", + "abort": "中止", + "to_be_executed": "待执行", + "fold": "折叠", + "re_evaluate_failed_only": "仅针对执行失败的部分重新评测", + "copy_and_create_experiment": "复制实验配置并新建实验", + "associated_evaluation_set": "关联评测集", + "delete_experiment": "删除实验", + "retry_experiment": "重试实验", + "only_re_evaluate_failed_part": "仅针对执行失败的部分重新评测。", + "copy_experiment_config": "复制实验配置", + "evaluation_set_field_to_evaluation_object_field_mapping": "评测集字段到评测对象字段的映射,用于评测对象准确获取输入。", + "get_evaluation_object_error": "获取评测对象遇到错误", + "experiments_compared_tip": "仅评测集相同且已执行完成的实验可进行对比。目前选择的实验有关联评测集不同的情况,请重新选择。", + "experiment_comparison_max_number": "实验对比最大数量不能超过 {num} 个,请重新选择。", + "only_completed_experiments_can_be_compared": "仅已执行完成的实验可进行对比,请重新选择。", + "experiment_comparison_initiation_failure": "实验对比发起失败", + "experimental_group": "实验组", + "only_support_english_letters_numbers_and_chinese_at_the_beginning": "仅支持英文字母、数字、中文开头", + "only_support_english_letters_numbers_and_chinese_and_": "仅支持英文字母、数字、中文,“-”,“_”,“.”", + "only_support_english_numbers_and_underscores_and_start_with_a_letter": "仅支持英文、数字、下划线,且需要以字母开头" +} diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/en-US.json index ccf29f4b8..baf711dbc 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/en-US.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/en-US.json @@ -1,4 +1,5 @@ { + "prompt": "Prompt", "please_input_with_vars": "Please enter the content. Variables can be written in the following format: '{{USER_NAME}}", "temperature": "Temperature", "max_tokens": "Max tokens", diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/zh-CN.json index cbb92a677..633b877f9 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/zh-CN.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/prompt/zh-CN.json @@ -1,4 +1,5 @@ { + "prompt": "Prompt", "please_input_with_vars": "请输入内容,支持按此格式书写变量:'{{USER_NAME}}", "temperature": "生成随机性", "max_tokens": "最大回复长度", From 3c6cb7a692c8334ca5919eb2256a900046e7de54 Mon Sep 17 00:00:00 2001 From: qihai Date: Wed, 16 Jul 2025 15:29:08 +0800 Subject: [PATCH 05/30] feat: using i18next key to detect lng --- .../experiment-select-modal/logic-filter.tsx | 79 +-- .../cozeloop/i18n/scripts/gen-i18n-types.ts | 6 +- frontend/packages/cozeloop/i18n/src/i18n.ts | 7 +- .../cozeloop/i18n/src/locale-types.ts | 607 +++++++++++++++++- .../cozeloop/intl/__tests__/intl.test.ts | 4 +- .../packages/cozeloop/intl/src/intl-client.ts | 5 + .../components/prompt-submit/diff-content.tsx | 2 +- .../cozeloop/resources/loop-lng/src/index.ts | 57 +- 8 files changed, 678 insertions(+), 89 deletions(-) diff --git a/frontend/packages/cozeloop/evaluate/src/components/experiment/experiment-select-modal/logic-filter.tsx b/frontend/packages/cozeloop/evaluate/src/components/experiment/experiment-select-modal/logic-filter.tsx index 8f046e6c4..91b23ad91 100644 --- a/frontend/packages/cozeloop/evaluate/src/components/experiment/experiment-select-modal/logic-filter.tsx +++ b/frontend/packages/cozeloop/evaluate/src/components/experiment/experiment-select-modal/logic-filter.tsx @@ -1,15 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 -import { - LogicEditor, - type LogicField, - type LogicFilter, -} from '@cozeloop/evaluate-components'; -import { - type ExptStatus, - FieldType, - type Evaluator, -} from '@cozeloop/api-schema/evaluation'; +import { type ExptStatus, FieldType } from '@cozeloop/api-schema/evaluation'; export interface Filter { name?: string; @@ -27,71 +18,3 @@ export const filterFields: { key: keyof Filter; type: FieldType }[] = [ type: FieldType.EvalSetID, }, ]; - -export default function ExperimentLogicFilter({ - logicFilter, - evaluators = [], - onChange, - onClose, -}: { - logicFilter: LogicFilter | undefined; - evaluators: Evaluator[] | undefined; - onChange: (newData?: LogicFilter) => void; - onClose?: () => void; -}) { - const logicFields: LogicField[] = [ - { - title: '创建人', - name: 'created_by', - type: 'options', - setterProps: { - optionList: [ - { label: '张三', value: 1 }, - { label: '李四', value: 2 }, - { label: '王五', value: 3 }, - ], - }, - }, - { - title: '评测对象类型', - name: 'eval_target_type', - type: 'options', - setterProps: { - optionList: [ - { label: 'Prompt', value: 1 }, - { label: 'Coze 智能体', value: 2 }, - ], - }, - }, - { - title: '评测对象', - name: 'eval_target', - type: 'options', - setterProps: { - optionList: [ - { label: '百科达人', value: 1 }, - { label: '笑话大王', value: 2 }, - ], - }, - }, - ...evaluators.map(evaluator => { - const field: LogicField = { - title: evaluator.name ?? '', - name: `${evaluator.evaluator_id ?? ''}`, - type: 'number' as const, - setterProps: { - step: 0.1, - }, - }; - return field; - }), - ]; - return ( - - ); -} diff --git a/frontend/packages/cozeloop/i18n/scripts/gen-i18n-types.ts b/frontend/packages/cozeloop/i18n/scripts/gen-i18n-types.ts index 46aaa4b0a..df2590aee 100644 --- a/frontend/packages/cozeloop/i18n/scripts/gen-i18n-types.ts +++ b/frontend/packages/cozeloop/i18n/scripts/gen-i18n-types.ts @@ -3,7 +3,7 @@ import { join } from 'node:path'; import { writeFile } from 'node:fs/promises'; -import { localeEnUS as localeJson } from '@cozeloop/loop-lng'; +import { localeEnUS, localeZhCN } from '@cozeloop/loop-lng'; import { icu2Type } from './utils'; @@ -17,6 +17,7 @@ function generateOptionsMap(localeData: Record) { continue; } const indent = ' '; + withInterpolation.push(`${indent}/** ${localeZhCN[key]} */`); withInterpolation.push( `${indent}${key}: {`, typeInfos @@ -41,10 +42,11 @@ ${noInterpolationKeys.map(it => ` | '${it}'`).join('\n')};`, async function main() { const startAt = Date.now(); const { withInterpolation, noInterpolationKeys } = - generateOptionsMap(localeJson); + generateOptionsMap(localeEnUS); const localeTypes = `// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 /** Generated by rushx gen-i18n-types */ +/* eslint-disable max-lines -- skip */ import { type ReactNode } from 'react'; /** I18n with interpolation */ diff --git a/frontend/packages/cozeloop/i18n/src/i18n.ts b/frontend/packages/cozeloop/i18n/src/i18n.ts index c6dff777e..03dbe0046 100644 --- a/frontend/packages/cozeloop/i18n/src/i18n.ts +++ b/frontend/packages/cozeloop/i18n/src/i18n.ts @@ -19,9 +19,10 @@ async function initIntl(options: IntlClientOptions = {}) { ...options, detection: { order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag'], - lookupQuerystring: 'locale', - lookupCookie: 'locale', - lookupLocalStorage: 'locale', + lookupQuerystring: 'i18next', + /** keep `i18next` with backend */ + lookupCookie: 'i18next', + lookupLocalStorage: 'i18next', caches: ['cookie'], }, resources: { diff --git a/frontend/packages/cozeloop/i18n/src/locale-types.ts b/frontend/packages/cozeloop/i18n/src/locale-types.ts index fa92ee0b6..087f4b097 100644 --- a/frontend/packages/cozeloop/i18n/src/locale-types.ts +++ b/frontend/packages/cozeloop/i18n/src/locale-types.ts @@ -1,44 +1,245 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 /** Generated by rushx gen-i18n-types */ +/* eslint-disable max-lines -- skip */ import { type ReactNode } from 'react'; /** I18n with interpolation */ export interface I18nWithInterpolation { + /** {num, plural, other {{num}天({date})}} */ expired_time_days_1: { /** number */ num: ReactNode; /** string */ date: ReactNode; }; + /** 获取元数据信息失败:{msg} */ fornax_analytics_fetch_meta_error: { /** string */ msg: ReactNode; }; + /** 输入Tokens: {count} */ fornax_analytics_input_tokens_count: { /** string */ count: ReactNode; }; + /** 输出Tokens: {count} */ fornax_analytics_output_tokens_count: { /** string */ count: ReactNode; }; + /** 推理Tokens: {count} */ fornax_analytics_reasoning_tokens_count: { /** string */ count: ReactNode; }; + /** 过去 {count} 天 */ fornax_analytics_time_last_days: { /** string */ count: ReactNode; }; + /** 过去 {count} 小时 */ fornax_analytics_time_last_hours: { /** string */ count: ReactNode; }; + /** 过去{count}分钟 */ fornax_analytics_time_last_minutes: { /** string */ count: ReactNode; }; + /** {field}已存在 */ + field_exists: { + /** string */ + field: ReactNode; + }; + /** {field}必填 */ + field_is_required: { + /** string */ + field: ReactNode; + }; + /** {field}不能为空 */ + field_not_empty: { + /** string */ + field: ReactNode; + }; + /** 请添加{field} */ + please_add: { + /** string */ + field: ReactNode; + }; + /** 请同意{field} */ + please_agree: { + /** string */ + field: ReactNode; + }; + /** 请配置{field} */ + please_configure: { + /** string */ + field: ReactNode; + }; + /** 请输入{field} */ + please_input: { + /** string */ + field: ReactNode; + }; + /** 请选择{field} */ + please_select: { + /** string */ + field: ReactNode; + }; + /** 请先同意{agreement} */ + please_agree_first: { + /** string */ + agreement: ReactNode; + }; + /** {num}天 */ + x_days: { + /** number */ + num: ReactNode; + }; + /** 字数: {num} */ + num_words: { + /** string */ + num: ReactNode; + }; + /** 对照组{index} */ + control_group_index: { + /** string */ + index: ReactNode; + }; + /** 最多上传{num}张图片 */ + max_upload_picture_num: { + /** string */ + num: ReactNode; + }; + /** 图片大小不能超过{num}MB */ + image_size_not_exceed_num_mb: { + /** string */ + num: ReactNode; + }; + /** 模拟消息组-{key} */ + mock_message_group: { + /** string */ + key: ReactNode; + }; + /** 百科知识数据集 {index} */ + pedia_dataset: { + /** string */ + index: ReactNode; + }; + /** 版本号必须大于当前版本号:{version} */ + version_number_gt_current: { + /** string */ + version: ReactNode; + }; + /** 草稿已自动保存于{date} */ + draft_auto_saved_date: { + /** string */ + date: ReactNode; + }; + /** 描述:{desc} */ + description_is: { + /** string */ + desc: ReactNode; + }; + /** 复制{name}配置,并新建评估器 */ + copy_record_name_config_and_create_new_evaluator: { + /** string */ + name: ReactNode; + }; + /** 确定删除评估器:{name}? */ + confirm_delete_evaluator: { + /** string */ + name: ReactNode; + }; + /** 实验组 {index} */ + experimental_group_index: { + /** string */ + index: ReactNode; + }; + /** 对比{num}个实验 */ + compare_x_experiments: { + /** number */ + count: ReactNode; + /** string */ + num: ReactNode; + }; + /** {num, plural, zero {无} other {#条}} */ + x_items : { + /** number */ + item: ReactNode; + }; + /** 稍等几秒后{refresh}页面查看 */ + wait_and_refresh_page: { + /** string */ + refresh: ReactNode; + }; + /** 单次最多添加{num}条数据项 */ + single_max_add_data_items: { + /** string */ + num: ReactNode; + }; + /** 数据项 {index} */ + data_item_index: { + /** string */ + index: ReactNode; + }; + /** 确认删除{num}列,此操作不可逆 */ + confirm_delete_x_columns: { + /** string */ + num: ReactNode; + }; + /** 最多支持{num}列 */ + max_support_columns: { + /** string */ + num: ReactNode; + }; + /** 请输入大于等于{num}的数字 */ + input_num_gte: { + /** string */ + num: ReactNode; + }; + /** 请输入小于等于{num}的数字 */ + input_num_lte: { + /** string */ + num: ReactNode; + }; + /** 仅支持精确到小数点后{precision}位 */ + support_precision: { + /** string */ + precision: ReactNode; + }; + /** 原因:{reason} */ + reason_is: { + /** string */ + reason: ReactNode; + }; + /** 最多保留小数点后{num}位 */ + keep_precision_num: { + /** string */ + num: ReactNode; + }; + /** 确认批量删除 {num} 条实验数据吗?此修改将不可逆。 */ + confirm_batch_delete_x_experiment: { + /** string */ + num: ReactNode; + }; + /** 实验对比最大数量不能超过 {num} 个,请重新选择。 */ + experiment_comparison_max_number: { + /** string */ + num: ReactNode; + }; + /** 最多展示{num}个视图 */ + max_display_view_num: { + /** string */ + num: ReactNode; + }; + /** 名称长度不能超过{num}个字符 */ + name_length_limit: { + /** string */ + num: ReactNode; + }; } /** I18n keys without interpolation */ @@ -181,4 +382,408 @@ export type I18nKeysNoInterpolation = | 'user_info_email' | 'user_info_username' | 'version' - | 'Workflow'; + | 'Workflow' + | 'account' + | 'back' + | 'clear' + | 'collapse' + | 'debug' + | 'demo_space' + | 'description' + | 'detail' + | 'email' + | 'experiment' + | 'field' + | 'login' + | 'name' + | 'network_error' + | 'operation' + | 'password' + | 'permanent' + | 'preview' + | 'refresh' + | 'register' + | 'remove' + | 'retrying' + | 'run' + | 'save' + | 'submit' + | 'today' + | 'tomorrow' + | 'user_agreement' + | 'unknown_error' + | 'yesterday' + | 'search_creator' + | 'current_user' + | 'reset_to_default' + | 'drag_to_sort' + | 'column_management' + | 'copy_id' + | 'copy_success' + | 'copy_failed' + | 'view_detail' + | 'page_not_found' + | 'page_load_failed' + | 'no_permission' + | 'click_ascending' + | 'click_descending' + | 'restore_default_sort' + | 'copy_content' + | 'save_time' + | 'current_draft' + | 'submit_time' + | 'submitter' + | 'version_description' + | 'version_record' + | 'space_not_exists' + | 'click_retry' + | 'document' + | 'lark_group' + | 'prompt_engineering' + | 'prompt_development' + | 'evaluation' + | 'evaluation_set' + | 'evaluator' + | 'observation' + | 'confirm_logout' + | 'account_settings' + | 'no_space' + | 'not_join_space' + | 'api_authorization' + | 'welcome_to_cozeloop' + | 'please_input_email' + | 'please_input_password' + | 'token_show_only_once' + | 'expiration_time' + | 'token' + | 'delete_token' + | 'remove_will_affect_all_in_use' + | 'register_or_login_failed' + | 'prompt' + | 'please_input_with_vars' + | 'temperature' + | 'max_tokens' + | 'top_p' + | 'top_k' + | 'presence_penalty' + | 'frequency_penalty' + | 'edit_prompt' + | 'create_copy' + | 'create_prompt' + | 'prompt_key' + | 'prompt_key_format' + | 'prompt_name' + | 'prompt_name_format' + | 'prompt_description' + | 'prompt_var_format' + | 'placeholder_var_name' + | 'placeholder_format' + | 'placeholder_name_exists' + | 'placeholder_var_error' + | 'historical_data_has_empty_content' + | 'add_prompt_tpl_or_input_question' + | 'set_to_reference_group' + | 'delete_control_group' + | 'load_more' + | 'no_debug_record' + | 'debug_history' + | 'delete_prompt_template' + | 'confirm_delete_current_prompt_template' + | 'mock_value' + | 'deeply_thought' + | 'deep_thinking' + | 'edit' + | 'delete_message' + | 'confirm_delete_message' + | 'rerun' + | 'delete_success' + | 'delete_prompt' + | 'copy_prompt_key' + | 'prompt_key_again_confirm' + | 'orchestration' + | 'collapse_model_and_var_area' + | 'expand_model_and_var_area' + | 'expand_preview_and_debug' + | 'collapse_preview_and_debug' + | 'no_draft_change' + | 'submitted' + | 'placeholder_var_create_error' + | 'model_id' + | 'submission_no_version_diff' + | 'open_enable_function' + | 'close_enable_function' + | 'continue' + | 'close' + | 'input_version_number' + | 'image_upload_error' + | 'clear_history_messages' + | 'input_question_tip' + | 'delete_function' + | 'confirm_delete_function' + | 'method_exists' + | 'new_function' + | 'method_name_rule' + | 'input_mock_value_here' + | 'trace_id' + | 'copy_trace_id' + | 'copy_variable_name' + | 'delete_variable' + | 'confirm_delete_var_in_tpl' + | 'param_value' + | 'mock_message' + | 'system_role' + | 'assistant_role' + | 'user_role' + | 'rollback_success' + | 'restore_to_this_version' + | 'restore_version_tip' + | 'restore' + | 'model_run_error' + | 'model_runtime_error' + | 'prompt_id_inconsistent' + | 'recent_submission_time' + | 'search_prompt_key_or_prompt_name' + | 'no_prompt' + | 'prompt_version_number_needed' + | 'incorrect_version_number' + | 'version_number_lt_error' + | 'compact_view' + | 'loose_view' + | 'draft_version' + | 'modify_not_submitted' + | 'go_submit' + | 'select_experiment' + | 'initiate_experiment_comparison' + | 'only_experiments_with_same_evaluation_set_and_completed_can_be_compared' + | 'selected' + | 'creator' + | 'evaluation_object_type' + | 'evaluation_object' + | 'coze_bot' + | 'coze_agent' + | 'evaluation_set_version' + | 'status' + | 'this_is_a_cozebot' + | 'view_actual_output_trace' + | 'experiment_name' + | 'the_field_required' + | 'experiment_description' + | 'edit_experiment' + | 'choose_model' + | 'check_parameters' + | 'no_data' + | 'associated_experiment' + | 'evaluator_type' + | 'model_selection' + | 'preview_and_debug' + | 'construct_test_data_to_preview_evaluator_runtime_result' + | 'config_info' + | 'construct_test_data' + | 'testrun_require_fee' + | 'generated_by_ai_tip' + | 'evaluator_lacks_input' + | 'information_unsaved' + | 'leave_page_tip' + | 'new_evaluator' + | 'create' + | 'confirm_clear_prompt' + | 'system_prompt_not_empty' + | 'delete_user_prompt' + | 'confirm_delete_user_prompt' + | 'add_user_prompt' + | 'submit_new_version' + | 'create_evaluator' + | 'version_number_format' + | 'version_number' + | 'select_template' + | 'preset_evaluator' + | 'edit_evaluator' + | 'draft_auto_saving' + | 'draft_auto_save_failed' + | 'submission_time' + | 'version_submit_success' + | 'search_name' + | 'copy_evaluator_config' + | 'evaluator_name' + | 'updated_person' + | 'update_time' + | 'create_time' + | 'this_operation_is_irreversible_please_operate_carefully' + | 'failed_to_find_related_results' + | 'try_other_keywords_or_modify_filter_options' + | 'no_evaluator' + | 'click_to_create' + | 'benchmark_group' + | 'remove_experimental_group' + | 'evaluation_object_actual_output' + | 'benchmark' + | 'benchmark_experiment_switch_success' + | 'data_detail' + | 'measure_stat' + | 'data_total_count' + | 'loading_field_mapping' + | 'select_type' + | 'actual_output' + | 'interface_problem' + | 'evaluation_object_version' + | 'config_evaluation_object_mapping' + | 'add_at_least_one_evaluator' + | 'max_add_x_evaluators' + | 'name_and_version' + | 'field_mapping' + | 'next_step_evaluation_set' + | 'next_step_evaluation_object' + | 'next_step_evaluator' + | 'confirm_experiment_config' + | 'initiate_experiment' + | 'new_experiment' + | 'selected_fields_inconsistent' + | 'evaluation_set_field_mapping_tip' + | 'add_evaluator' + | 'submit_form_problems' + | 'update_rating_success' + | 'view_evaluator_trace' + | 'manual_calibration' + | 'score_details' + | 'score' + | 'refresh_after_experiment' + | 'aggregation_score' + | 'score_details_data_item_distribution' + | 'indicator' + | 'experiment_initializing' + | 'score_reason' + | 'end_time' + | 'confirm_evaluation_set_version' + | 'draft_unsubmitted_tip' + | 'retain_one_data_item' + | 'collapse_all_data_items' + | 'expand_all_data_items' + | 'execution_result' + | 'known' + | 'delete_column' + | 'column_name' + | 'column_description' + | 'add_column' + | 'basic_info' + | 'evaluation_set_name' + | 'evaluation_set_description' + | 'configuration_column' + | 'can_still_modify_column' + | 'data_type' + | 'view_format' + | 'no_modification_to_submit' + | 'version_format_and_range' + | 'click_to_add_data' + | 'edit_evaluation_set' + | 'import_data' + | 'upload_data' + | 'click_or_drag_file_to_upload' + | 'recommend_template_upload_tip' + | 'download_template' + | 'upload_file' + | 'no_mapping_no_import' + | 'column_mapping' + | 'source_column_mapping' + | 'configure_at_least_one_import_column' + | 'import_method' + | 'no_evaluation_dataset' + | 'click_to_create_evaluation_set' + | 'evaluation_set_column' + | 'configure_column_mapping' + | 'select_import_method' + | 'confirm_select_full_coverage' + | 'continue_will_override_existing_data' + | 'execution_in_progress' + | 'number' + | 'string' + | 'integer' + | 'input_float_with_precision' + | 'edit_data_item' + | 'view_data_item' + | 'data_item' + | 'delete_evaluation_set' + | 'debug_failure' + | 'debugging_succeeded' + | 'prompt_detail' + | 'loading_prompt_detail' + | 'select_evaluator_and_version_number_to_view' + | 'model' + | 'output' + | 'extract_via_function_call' + | 'score_is' + | 'rating' + | 'input_score_between_0_and_1' + | 'input_number_between_0_and_1' + | 'reason' + | 'view_evaluator_details' + | 'batch_delete_experiment' + | 'aggregate_statistics_score_on_metrics' + | 'line_chart' + | 'bar_chart' + | 'no_experiment' + | 'click_to_create_experiment' + | 'schema_mismatch' + | 'empty_data' + | 'single_data_size_exceeded' + | 'dataset_capacity_exceeded' + | 'file_format_error' + | 'system_error' + | 'contains_illegal_content' + | 'operator' + | 'equal_to' + | 'not_equal_to' + | 'contain' + | 'not_contain' + | 'greater_than' + | 'greater_than_or_equal_to' + | 'less_than' + | 'less_than_or_equal_to' + | 'later_than' + | 'earlier_than' + | 'new_evaluation_set' + | 'prompt_variable_to_ensure_effect' + | 'new_prompt' + | 'in_progress' + | 'abort' + | 'to_be_executed' + | 'fold' + | 're_evaluate_failed_only' + | 'copy_and_create_experiment' + | 'associated_evaluation_set' + | 'delete_experiment' + | 'retry_experiment' + | 'only_re_evaluate_failed_part' + | 'copy_experiment_config' + | 'evaluation_set_field_to_evaluation_object_field_mapping' + | 'get_evaluation_object_error' + | 'experiments_compared_tip' + | 'only_completed_experiments_can_be_compared' + | 'experiment_comparison_initiation_failure' + | 'experimental_group' + | 'only_support_english_letters_numbers_and_chinese_at_the_beginning' + | 'only_support_english_letters_numbers_and_chinese_and_' + | 'only_support_english_numbers_and_underscores_and_start_with_a_letter' + | 'current_trace_expired_to_view' + | 'no_permission_to_view_trace' + | 'no_permission_to_view' + | 'reported_data_not_found' + | 'report_in_sdk' + | 'all_span_tip' + | 'root_span_tip' + | 'llm_span_tip' + | 'confirm_delete_view' + | 'deletion_irreversible' + | 'default_view_not_editable' + | 'default_view_cannot_be_deleted' + | 'new_view_cannot_be_displayed' + | 'viewing_method' + | 'belong_to' + | 'data_source' + | 'viewing_method_data_source_linkage' + | 'data_expiration_time' + | 'sdk_reporting' + | 'customize' + | 'all_time' + | 'not_allowed_to_be_empty' + | 'view_name_exists' + | 'tos_url_not_exist'; diff --git a/frontend/packages/cozeloop/intl/__tests__/intl.test.ts b/frontend/packages/cozeloop/intl/__tests__/intl.test.ts index ceffb2dd5..8b17f288e 100644 --- a/frontend/packages/cozeloop/intl/__tests__/intl.test.ts +++ b/frontend/packages/cozeloop/intl/__tests__/intl.test.ts @@ -18,6 +18,7 @@ describe('I18n', () => { 'other {# photos.}}', error: 'Error: {msg}', moreError: 'Error: {msg1},{msg2}', + escape: "Hello '{{USERNAME}}", empty: '', }, }, @@ -40,8 +41,9 @@ describe('I18n', () => { expect(I18n.t('poem')).toBe('游园不值'); }); - it('should interpolate', () => { + it.only('should interpolate', () => { expect(I18n.t('error', { msg: '123' })).toBe('Error: 123'); + expect(I18n.t('escape')).toBe('Hello {{USERNAME}}'); expect(I18n.t('moreError', { msg1: '123', msg2: '321' })).toBe( 'Error: 123,321', ); diff --git a/frontend/packages/cozeloop/intl/src/intl-client.ts b/frontend/packages/cozeloop/intl/src/intl-client.ts index 9879c8bcb..0bd1baf2a 100644 --- a/frontend/packages/cozeloop/intl/src/intl-client.ts +++ b/frontend/packages/cozeloop/intl/src/intl-client.ts @@ -38,6 +38,11 @@ export class IntlClient { } t(key: string, defaultValue?: string): string; + t( + key: string, + interpolation?: Record, + defaultValue?: string, + ): string; t( key: string, interpolationOrDefaultValue?: Record | string, diff --git a/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/diff-content.tsx b/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/diff-content.tsx index e7d7a71c3..53ecc310f 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/diff-content.tsx +++ b/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/diff-content.tsx @@ -113,7 +113,7 @@ export function DiffContent({ } addDiffItem( - '回复随机性', + '生成随机性', baseItem.modelConfig?.temperature, currentItem.modelConfig?.temperature, ); diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/index.ts b/frontend/packages/cozeloop/resources/loop-lng/src/index.ts index f234eaf75..1eec1a949 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/index.ts +++ b/frontend/packages/cozeloop/resources/loop-lng/src/index.ts @@ -1,6 +1,57 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 -import localeZhCN from './locales/zh-CN.json'; -import localeEnUS from './locales/en-US.json'; +/* eslint-disable import/order -- skip*/ +import rootLocaleZhCN from './locales/zh-CN.json'; +import rootLocaleEnUS from './locales/en-US.json'; -export { localeZhCN, localeEnUS }; +// auth +import authLocaleZhCN from './locales/auth/zh-CN.json'; +import authLocaleEnUS from './locales/auth/en-US.json'; + +// base +import baseLocaleZhCN from './locales/base/zh-CN.json'; +import baseLocaleEnUS from './locales/base/en-US.json'; + +// common +import commonLocaleZhCN from './locales/common/zh-CN.json'; +import commonLocaleEnUS from './locales/common/en-US.json'; + +// components +import componentsLocaleZhCN from './locales/components/zh-CN.json'; +import componentsLocaleEnUS from './locales/components/en-US.json'; + +// evaluate +import evaluateLocaleZhCN from './locales/evaluate/zh-CN.json'; +import evaluateLocaleEnUS from './locales/evaluate/en-US.json'; + +// observation +import observationLocaleZhCN from './locales/observation/zh-CN.json'; +import observationLocaleEnUS from './locales/observation/en-US.json'; + +// prompt +import promptLocaleZhCN from './locales/prompt/zh-CN.json'; +import promptLocaleEnUS from './locales/prompt/en-US.json'; + +export const localeZhCN = Object.assign( + {}, + rootLocaleZhCN, + commonLocaleZhCN, + componentsLocaleZhCN, + baseLocaleZhCN, + authLocaleZhCN, + promptLocaleZhCN, + evaluateLocaleZhCN, + observationLocaleZhCN, +); + +export const localeEnUS = Object.assign( + {}, + rootLocaleEnUS, + commonLocaleEnUS, + componentsLocaleEnUS, + baseLocaleEnUS, + authLocaleEnUS, + promptLocaleEnUS, + evaluateLocaleEnUS, + observationLocaleEnUS, +); From 9c1b8526398953944e46e2e28b17bab1e05e6504 Mon Sep 17 00:00:00 2001 From: qihai Date: Wed, 16 Jul 2025 20:37:11 +0800 Subject: [PATCH 06/30] feat: replace base and auth i18n --- .../apps/cozeloop/src/assets/images/en-us.svg | 6 + .../apps/cozeloop/src/assets/images/zh-cn.svg | 6 + .../src/components/basic-layout/index.tsx | 9 +- .../src/components/breadcrumb/index.tsx | 4 +- .../src/components/navbar/footer-menus.tsx | 5 +- .../src/components/navbar/menu-config.tsx | 15 +- .../src/components/switch-lng/index.tsx | 37 ++ .../components/user-info-section/index.tsx | 7 +- .../user-info-section/settings-menu.tsx | 5 +- .../apps/cozeloop/src/routes/space-route.tsx | 8 +- .../src/components/account-setting/index.tsx | 7 +- .../src/components/login-panel/index.tsx | 39 +- .../src/components/pat-panel/columns.tsx | 14 +- .../src/components/pat-panel/index.tsx | 10 +- .../src/components/pat-panel/pat-detail.tsx | 13 +- .../src/components/pat-panel/pat-modal.tsx | 11 +- .../src/components/pat-panel/pat-op.tsx | 9 +- .../src/components/pat-panel/pat-table.tsx | 5 +- .../src/components/pat-panel/utils.ts | 20 +- .../components/user-info-panel/edit-wrap.tsx | 5 +- .../src/components/user-info-panel/index.tsx | 8 +- .../auth-pages/src/pages/login-page/index.tsx | 3 +- .../cozeloop/i18n/scripts/gen-i18n-types.ts | 2 +- .../cozeloop/i18n/src/locale-types.ts | 581 +++++++++++++++++- frontend/packages/cozeloop/i18n/src/types.ts | 8 +- .../loop-lng/src/locales/auth/en-US.json | 28 +- .../loop-lng/src/locales/auth/zh-CN.json | 20 +- .../loop-lng/src/locales/evaluate/en-US.json | 2 +- .../loop-lng/src/locales/evaluate/zh-CN.json | 2 +- 29 files changed, 783 insertions(+), 106 deletions(-) create mode 100644 frontend/apps/cozeloop/src/assets/images/en-us.svg create mode 100644 frontend/apps/cozeloop/src/assets/images/zh-cn.svg create mode 100644 frontend/apps/cozeloop/src/components/switch-lng/index.tsx diff --git a/frontend/apps/cozeloop/src/assets/images/en-us.svg b/frontend/apps/cozeloop/src/assets/images/en-us.svg new file mode 100644 index 000000000..060c1b83b --- /dev/null +++ b/frontend/apps/cozeloop/src/assets/images/en-us.svg @@ -0,0 +1,6 @@ + + + + diff --git a/frontend/apps/cozeloop/src/assets/images/zh-cn.svg b/frontend/apps/cozeloop/src/assets/images/zh-cn.svg new file mode 100644 index 000000000..3d15aecf0 --- /dev/null +++ b/frontend/apps/cozeloop/src/assets/images/zh-cn.svg @@ -0,0 +1,6 @@ + + + + + diff --git a/frontend/apps/cozeloop/src/components/basic-layout/index.tsx b/frontend/apps/cozeloop/src/components/basic-layout/index.tsx index 4a3625b5d..80d456018 100644 --- a/frontend/apps/cozeloop/src/components/basic-layout/index.tsx +++ b/frontend/apps/cozeloop/src/components/basic-layout/index.tsx @@ -4,6 +4,7 @@ import { Outlet, useLocation, useNavigate } from 'react-router-dom'; import { ErrorBoundary } from 'react-error-boundary'; import { Suspense } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { PageError, PageLoading, PageNotFound } from '@cozeloop/components'; import { useSpaceStore } from '@cozeloop/account'; import { Button } from '@coze-arch/coze-design'; @@ -22,7 +23,7 @@ export function BasicLayout() { switch (status) { case SetupSpaceStatus.NOT_FOUND: return ( - + ); case SetupSpaceStatus.FETCH_ERROR: return ( - + ); diff --git a/frontend/apps/cozeloop/src/components/breadcrumb/index.tsx b/frontend/apps/cozeloop/src/components/breadcrumb/index.tsx index db117ce0f..61d07b45a 100644 --- a/frontend/apps/cozeloop/src/components/breadcrumb/index.tsx +++ b/frontend/apps/cozeloop/src/components/breadcrumb/index.tsx @@ -9,6 +9,7 @@ import { Breadcrumb } from '@coze-arch/coze-design'; import { useMenuConfig } from '../navbar/menu-config'; import { getBreadcrumbMap } from './utils'; +import { SwitchLang } from '../switch-lng'; export function MainBreadcrumb() { const { app, subModule } = useApp(); @@ -51,7 +52,7 @@ export function MainBreadcrumb() { }, [breadcrumbConfig]); return ( -
+
/
} > @@ -72,6 +73,7 @@ export function MainBreadcrumb() { ))} +
); } diff --git a/frontend/apps/cozeloop/src/components/navbar/footer-menus.tsx b/frontend/apps/cozeloop/src/components/navbar/footer-menus.tsx index d6b065817..c7799fc22 100644 --- a/frontend/apps/cozeloop/src/components/navbar/footer-menus.tsx +++ b/frontend/apps/cozeloop/src/components/navbar/footer-menus.tsx @@ -3,6 +3,7 @@ import { type ReactNode, useState } from 'react'; import cls from 'classnames'; +import { I18n } from '@cozeloop/i18n-adapter'; import { IconCozDocument, IconCozArrowDown, @@ -37,13 +38,13 @@ export function FooterMenus({ isCollapsed, isHovered }: Props) { const [isShow, setIsShow] = useState(true); const menuItems: MenuItem[] = [ { - text: '文档', + text: I18n.t('document'), key: 'actions/doc', icon: , onClick: () => window.open(COZELOOP_DOC_URL), }, { - text: '飞书群', + text: I18n.t('lark_group'), key: 'actions/lark', icon: , onClick: () => window.open(COZELOOP_LARK_GROUP_URL), diff --git a/frontend/apps/cozeloop/src/components/navbar/menu-config.tsx b/frontend/apps/cozeloop/src/components/navbar/menu-config.tsx index 7e7d87e04..d129d55ec 100644 --- a/frontend/apps/cozeloop/src/components/navbar/menu-config.tsx +++ b/frontend/apps/cozeloop/src/components/navbar/menu-config.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { type ReactNode } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { type Space } from '@cozeloop/api-schema/foundation'; import { IconCozChat, @@ -38,12 +39,12 @@ export function useMenuConfig() { const menuConfig: MenuConfig[] = [ { itemKey: 'pe', - text: 'Prompt 工程', + text: I18n.t('prompt_engineering'), visible: ({ space }) => Boolean(space?.id), items: [ { itemKey: 'pe/prompts', - text: 'Prompt 开发', + text: I18n.t('prompt_development'), icon: , selectedIcon: , }, @@ -57,24 +58,24 @@ export function useMenuConfig() { }, { itemKey: 'evaluation', - text: '评测', + text: I18n.t('evaluation'), visible: ({ space }) => Boolean(space?.id), items: [ { itemKey: 'evaluation/datasets', - text: '评测集', + text: I18n.t('evaluation_set'), icon: , selectedIcon: , }, { itemKey: 'evaluation/evaluators', - text: '评估器', + text: I18n.t('evaluator'), icon: , selectedIcon: , }, { itemKey: 'evaluation/experiments', - text: '实验', + text: I18n.t('experiment'), icon: , selectedIcon: , }, @@ -82,7 +83,7 @@ export function useMenuConfig() { }, { itemKey: 'observation', - text: '观测', + text: I18n.t('observation'), visible: ({ space }) => Boolean(space?.id), items: [ { diff --git a/frontend/apps/cozeloop/src/components/switch-lng/index.tsx b/frontend/apps/cozeloop/src/components/switch-lng/index.tsx new file mode 100644 index 000000000..9d20c6392 --- /dev/null +++ b/frontend/apps/cozeloop/src/components/switch-lng/index.tsx @@ -0,0 +1,37 @@ +import { useState } from 'react'; + +import { I18n } from '@cozeloop/i18n-adapter'; +import { Switch } from '@coze-arch/coze-design'; + +import { ReactComponent as IconZhCN } from '@/assets/images/zh-cn.svg'; +import { ReactComponent as IconEnUS } from '@/assets/images/en-us.svg'; + +// TODO +export function SwitchLang() { + // 'zh-CN' | 'en-US' + const [lang, setLang] = useState(() => I18n.lang); + + const toggleLang = async () => { + const switchMap: Record = { + 'zh-CN': 'en-US', + 'en-US': 'zh-CN', + }; + const targetLang = switchMap[lang] ?? 'zh-CN'; + await I18n.setLang(switchMap[I18n.lang]); + setLang(targetLang); + }; + + return ( +
+ } + uncheckedText={} + /> + {lang === 'en-US' ? ( + + ) : ( + + )} +
+ ); +} diff --git a/frontend/apps/cozeloop/src/components/user-info-section/index.tsx b/frontend/apps/cozeloop/src/components/user-info-section/index.tsx index 9c4caeb21..c2d0d3539 100644 --- a/frontend/apps/cozeloop/src/components/user-info-section/index.tsx +++ b/frontend/apps/cozeloop/src/components/user-info-section/index.tsx @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { useState } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { AccountSetting } from '@cozeloop/auth-pages'; import { useLogout, useUserStore, useSpaceStore } from '@cozeloop/account'; import { Popover, Modal } from '@coze-arch/coze-design'; @@ -27,9 +28,9 @@ export function UserInfoSection({ isCollapsed }: Props) { switch (action) { case 'logout': Modal.confirm({ - title: '确认要退出登录吗?', - okText: '退出登录', - cancelText: '取消', + title: I18n.t('confirm_logout'), + okText: I18n.t('logout'), + cancelText: I18n.t('cancel'), type: 'modal', autoLoading: true, okButtonProps: { diff --git a/frontend/apps/cozeloop/src/components/user-info-section/settings-menu.tsx b/frontend/apps/cozeloop/src/components/user-info-section/settings-menu.tsx index beef6c2b1..937a12f65 100644 --- a/frontend/apps/cozeloop/src/components/user-info-section/settings-menu.tsx +++ b/frontend/apps/cozeloop/src/components/user-info-section/settings-menu.tsx @@ -1,6 +1,7 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 import classNames from 'classnames'; +import { I18n } from '@cozeloop/i18n-adapter'; import { useBaseURL } from '@cozeloop/biz-hooks-adapter'; import { PERSONAL_ENTERPRISE_ID } from '@cozeloop/account'; import { IconCozExit, IconCozSetting } from '@coze-arch/coze-design/icons'; @@ -18,7 +19,7 @@ export function SettingsMenu({ onAction }: Props) { const menus = [ { icon: , - text: '账户设置', + text: I18n.t('account_settings'), onClick: () => { onAction?.('setting'); }, @@ -26,7 +27,7 @@ export function SettingsMenu({ onAction }: Props) { }, { icon: , - text: '退出登录', + text: I18n.t('logout'), onClick: () => { onAction?.('logout'); }, diff --git a/frontend/apps/cozeloop/src/routes/space-route.tsx b/frontend/apps/cozeloop/src/routes/space-route.tsx index 4e1afd6d0..ec143a66f 100644 --- a/frontend/apps/cozeloop/src/routes/space-route.tsx +++ b/frontend/apps/cozeloop/src/routes/space-route.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { Navigate } from 'react-router-dom'; +import { I18n } from '@cozeloop/i18n-adapter'; import { PageNoContent } from '@cozeloop/components'; import { useSpaceStore } from '@cozeloop/account'; @@ -13,7 +14,12 @@ export function SpaceRoute({ index }: Props) { const space = useSpaceStore(s => s.space); if (!space?.id) { - return ; + return ( + + ); } const path = index ? `space/${space.id}` : space.id; diff --git a/frontend/packages/cozeloop/auth-pages/src/components/account-setting/index.tsx b/frontend/packages/cozeloop/auth-pages/src/components/account-setting/index.tsx index deb91f7e6..46e17f498 100644 --- a/frontend/packages/cozeloop/auth-pages/src/components/account-setting/index.tsx +++ b/frontend/packages/cozeloop/auth-pages/src/components/account-setting/index.tsx @@ -3,6 +3,7 @@ import { useState } from 'react'; import cls from 'classnames'; +import { I18n } from '@cozeloop/i18n-adapter'; import { Space, Typography } from '@coze-arch/coze-design'; import { UserInfoPanel } from '../user-info-panel'; @@ -23,8 +24,8 @@ interface Props { export function AccountSetting({ className, activeTab }: Props) { const [tabId, setTabId] = useState(activeTab || 'user-info'); const tabs: Tab[] = [ - { name: '账户设置', key: 'user-info' }, - { name: 'API 授权', key: 'pat' }, + { name: I18n.t('account_settings'), key: 'user-info' }, + { name: I18n.t('api_authorization'), key: 'pat' }, ]; const tabName = tabs.find(it => it.key === tabId)?.name; @@ -47,7 +48,7 @@ export function AccountSetting({ className, activeTab }: Props) { spacing={16} className={s['tab-bar']} > -
{'账户'}
+
{I18n.t('account')}
{tabs.map(({ name, key }) => (
- {'欢迎使用扣子罗盘-开源版'} + {I18n.t('welcome_to_cozeloop')}
-
+
{/*
@@ -78,17 +79,21 @@ export function LoginPanel({ loading, onLogin, onRegister }: Props) { onChange={e => setConsent(Boolean(e.target.checked))} disabled={loading} > + {I18n.t('please_agree_first', { + agreement: ( + { + e.stopPropagation(); + }} + > + {I18n.t('user_agreement')} + + ), + })} {'请先同意'} - { - e.stopPropagation(); - }} - > - 用户协议 -
*/}
diff --git a/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/columns.tsx b/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/columns.tsx index 6dde1a733..73910f82b 100644 --- a/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/columns.tsx +++ b/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/columns.tsx @@ -18,41 +18,41 @@ export function getColumns({ }: ColumnAction): ColumnProps[] { return [ { - title: I18n.t('coze_api_list1'), + title: I18n.t('name'), dataIndex: 'name', width: 120, render: (name: string) => {name}, }, { - title: I18n.t('coze_api_list3'), + title: I18n.t('create_time'), dataIndex: 'created_at', render: (createTime: number) => getDetailTime(createTime), }, { - title: I18n.t('coze_api_list4'), + title: I18n.t('last_used'), dataIndex: 'last_used_at', render: (lastUseTime: number) => getDetailTime(lastUseTime), }, { - title: I18n.t('expire_time_1'), // 状态 + title: I18n.t('expiration_time'), // 状态 dataIndex: 'expire_at', render: (expireTime: number) => getExpirationTime(expireTime), }, { - title: I18n.t('api_status_1'), + title: I18n.t('status'), dataIndex: 'id', width: 80, render: (_: string, record: PersonalAccessToken) => { const isActive = getStatus(record?.expire_at); return ( - {I18n.t(isActive ? 'api_status_active_1' : 'api_status_expired_1')} + {isActive ? I18n.t('active') : I18n.t('expired')} ); }, }, { - title: I18n.t('coze_api_list5'), + title: I18n.t('operation'), width: 120, render: (_, record) => ( diff --git a/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/index.tsx b/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/index.tsx index 452ea3993..18bf01cd3 100644 --- a/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/index.tsx +++ b/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/index.tsx @@ -58,7 +58,7 @@ export function PatPanel({ className }: Props) { reloadPatList(); setModalData({ visible: false }); Modal.info({ - title: I18n.t('new_pat_1'), + title: I18n.t('new_pat'), footer: false, width: 560, closable: true, @@ -101,17 +101,17 @@ export function PatPanel({ className }: Props) { type="primary" onClick={() => setModalData({ visible: true })} > - {I18n.t('add_new_token_button_1')} + {I18n.t('add_token')}

- {I18n.t('pat_reminder_1')} + {I18n.t('pat_introduction')} - {I18n.t('coze_api_instru')} + {I18n.t('api_instruction')}

-

{I18n.t('pat_reminder_2')}

+

{I18n.t('pat_reminder')}

-

- { - '此令牌仅显示一次。请将此密钥保存在安全且可获取的地方。不要与他人共享,也不要在浏览器或其他客户端代码中暴露它。' - } -

+

{I18n.t('token_show_only_once')}

-
{'名称'}
+
{I18n.t('name')}
{pat?.name}
-
{'过期时间'}
+
{I18n.t('expiration_time')}
{getExpirationTime(pat?.expire_at)}
-
{'令牌'}
+
{I18n.t('token')}
(); const dataOptionsList = getExpirationOptions(); const isCreate = !value; - const modalTitle = - title || isCreate ? I18n.t('add_new_pat_1') : I18n.t('edit_pat_1'); + const modalTitle = title || isCreate ? I18n.t('add_pat') : I18n.t('edit_pat'); const onOk = async () => { const values = await formApi.current?.getValues(); @@ -84,13 +83,13 @@ export function PatModal({ />
setDuration(v as PatInfo['duration'])} - placeholder={I18n.t('select_expired_time_1')} + placeholder={I18n.t('please_select', { + field: I18n.t('expiration_time'), + })} /> {duration === 'custom' ? ( onDelete?.(pat.id)} diff --git a/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/pat-table.tsx b/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/pat-table.tsx index 31d6a272d..8a3827ff4 100644 --- a/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/pat-table.tsx +++ b/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/pat-table.tsx @@ -34,10 +34,7 @@ export function PatTable({ loading, dataSource, onEdit, onDelete }: Props) { scroll: {}, }} empty={ - + } />
diff --git a/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/utils.ts b/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/utils.ts index aa554cf14..0a1a895f0 100644 --- a/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/utils.ts +++ b/frontend/packages/cozeloop/auth-pages/src/components/pat-panel/utils.ts @@ -39,14 +39,14 @@ export function formatDate( export function getExpirationOptions() { const dataOptionsList = [ - { label: '1天', value: DurationDay.Day1 }, - { label: '30天', value: DurationDay.Day30 }, - { label: '60天', value: DurationDay.Day60 }, - { label: '90天', value: DurationDay.Day90 }, - { label: '180天', value: DurationDay.Day180 }, - { label: '365天', value: DurationDay.Day365 }, - { label: '永久', value: DurationDay.Permanent }, - { label: I18n.t('customize_key_1'), value: 'custom' }, + { label: I18n.t('x_days', { num: 1 }), value: DurationDay.Day1 }, + { label: I18n.t('x_days', { num: 30 }), value: DurationDay.Day30 }, + { label: I18n.t('x_days', { num: 60 }), value: DurationDay.Day60 }, + { label: I18n.t('x_days', { num: 90 }), value: DurationDay.Day90 }, + { label: I18n.t('x_days', { num: 180 }), value: DurationDay.Day180 }, + { label: I18n.t('x_days', { num: 365 }), value: DurationDay.Day365 }, + { label: I18n.t('permanent'), value: DurationDay.Permanent }, + { label: I18n.t('customize'), value: 'custom' }, ]; const newOptions = dataOptionsList.map(item => { const { value } = item; @@ -59,7 +59,7 @@ export function getExpirationOptions() { label: value === DurationDay.Permanent ? 'Permanent' - : I18n.t('expired_time_days_1', { num: Number(value), date }), + : I18n.t('expired_time_days', { num: Number(value), date }), value, }; }); @@ -104,7 +104,7 @@ export function getExpirationTime(v?: number | string) { } if (d === -1) { - return I18n.t('api_status_permanent_1'); + return I18n.t('permanent'); } return formatDate(new Date(d * 1000)); diff --git a/frontend/packages/cozeloop/auth-pages/src/components/user-info-panel/edit-wrap.tsx b/frontend/packages/cozeloop/auth-pages/src/components/user-info-panel/edit-wrap.tsx index e54ad93e6..b1233ec78 100644 --- a/frontend/packages/cozeloop/auth-pages/src/components/user-info-panel/edit-wrap.tsx +++ b/frontend/packages/cozeloop/auth-pages/src/components/user-info-panel/edit-wrap.tsx @@ -7,6 +7,7 @@ import { IconCozEdit } from '@coze-arch/coze-design/icons'; import { IconButton, Button } from '@coze-arch/coze-design'; import s from './edit-wrap.module.less'; +import { I18n } from '@cozeloop/i18n-adapter'; interface Props { className?: string; @@ -26,8 +27,8 @@ export function EditWrap({ editableComponent, canSave, loading, - cancelText = 'Cancel', - saveText = 'Save', + cancelText = I18n.t('cancel'), + saveText = I18n.t('save'), onSave, onCancel, }: Props) { diff --git a/frontend/packages/cozeloop/auth-pages/src/components/user-info-panel/index.tsx b/frontend/packages/cozeloop/auth-pages/src/components/user-info-panel/index.tsx index 28e3db2b1..7b474e6f5 100644 --- a/frontend/packages/cozeloop/auth-pages/src/components/user-info-panel/index.tsx +++ b/frontend/packages/cozeloop/auth-pages/src/components/user-info-panel/index.tsx @@ -62,7 +62,7 @@ export function UserInfoPanel({ className }: Props) { {userInfo?.nick_name} - + setName(userInfo?.name)} /> - + setNickName(userInfo?.nick_name)} /> - - {userInfo?.email} - + {userInfo?.email}
UID: {userInfo?.user_id}
); diff --git a/frontend/packages/cozeloop/auth-pages/src/pages/login-page/index.tsx b/frontend/packages/cozeloop/auth-pages/src/pages/login-page/index.tsx index 104e2dfea..9313b8691 100644 --- a/frontend/packages/cozeloop/auth-pages/src/pages/login-page/index.tsx +++ b/frontend/packages/cozeloop/auth-pages/src/pages/login-page/index.tsx @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { useState, useEffect } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { $notification } from '@cozeloop/api-schema'; import { useLogin, useLoginStatus, useRegister } from '@cozeloop/account'; import { Toast } from '@coze-arch/coze-design'; @@ -40,7 +41,7 @@ export function LoginPage() { className: 'api-error-toast', content: ( - {'注册/登录失败,请检查邮箱或密码'} + {I18n.t('register_or_login_failed')} ), }); diff --git a/frontend/packages/cozeloop/i18n/scripts/gen-i18n-types.ts b/frontend/packages/cozeloop/i18n/scripts/gen-i18n-types.ts index df2590aee..41d9bc17a 100644 --- a/frontend/packages/cozeloop/i18n/scripts/gen-i18n-types.ts +++ b/frontend/packages/cozeloop/i18n/scripts/gen-i18n-types.ts @@ -35,7 +35,7 @@ function generateOptionsMap(localeData: Record) { ${withInterpolation.join('\n')} }`, noInterpolationKeys: `export type I18nKeysNoInterpolation = -${noInterpolationKeys.map(it => ` | '${it}'`).join('\n')};`, +${noInterpolationKeys.map(it => ` /** ${localeZhCN[it]} */\n | '${it}'`).join('\n')};`, }; } diff --git a/frontend/packages/cozeloop/i18n/src/locale-types.ts b/frontend/packages/cozeloop/i18n/src/locale-types.ts index 087f4b097..44aac17a5 100644 --- a/frontend/packages/cozeloop/i18n/src/locale-types.ts +++ b/frontend/packages/cozeloop/i18n/src/locale-types.ts @@ -98,6 +98,13 @@ export interface I18nWithInterpolation { /** number */ num: ReactNode; }; + /** {num, plural, other {{num}天({date})}} */ + expired_time_days: { + /** number */ + num: ReactNode; + /** string */ + date: ReactNode; + }; /** 字数: {num} */ num_words: { /** string */ @@ -166,7 +173,7 @@ export interface I18nWithInterpolation { num: ReactNode; }; /** {num, plural, zero {无} other {#条}} */ - x_items : { + x_items: { /** number */ item: ReactNode; }; @@ -244,546 +251,1118 @@ export interface I18nWithInterpolation { /** I18n keys without interpolation */ export type I18nKeysNoInterpolation = + /** 操作 */ | 'actions' + /** 点击按钮添加个人访问令牌 */ | 'add_api_token_1' + /** 添加新的个人访问令牌 */ | 'add_new_pat_1' + /** 添加新令牌 */ | 'add_new_token_button_1' + /** 添加 */ | 'add' + /** 图片不可访问 */ | 'analytics_image_error' + /** Arguments */ | 'analytics_trace_arguments' + /** Description */ | 'analytics_trace_description' + /** Metadata */ | 'analytics_trace_metadata' + /** Run */ | 'analytics_trace_run' + /** Runtime */ | 'analytics_trace_runtime' + /** Type */ | 'analytics_trace_type' + /** 状态 */ | 'api_status_1' + /** 有效 */ | 'api_status_active_1' + /** 已过期 */ | 'api_status_expired_1' + /** 永久有效 */ | 'api_status_permanent_1' + /** 个人访问令牌 */ | 'auth_tab_pat' + /** 取消 */ | 'Cancel' + /** 取消 */ | 'cancel' + /** 代码 */ | 'code' + /** 确认 */ | 'Confirm' + /** 确认 */ | 'confirm' + /** 内容 */ | 'Content' + /** 复制 */ | 'Copy' + /** 复制 */ | 'copy' + /** API 使用说明 */ | 'coze_api_instru' + /** 名称 */ | 'coze_api_list1' + /** 创建时间 */ | 'coze_api_list3' + /** 最近使用时间 */ | 'coze_api_list4' + /** 操作 */ | 'coze_api_list5' + /** 创作者 */ | 'creators' + /** 自定义 */ | 'customize_key_1' + /** 此操作不可撤回 */ | 'delete_desc' + /** 确认删除 */ | 'delete_title' + /** 删除 */ | 'Delete' + /** 删除 */ | 'delete' + /** 描述 */ | 'Description' + /** 编辑个人访问令牌 */ | 'edit_pat_1' + /** 编辑 */ | 'Edit' + /** 抱歉,发生了一些错误,请稍后重试。 */ | 'error' + /** 展开 */ | 'expand' + /** 过期时间 */ | 'expire_time_1' + /** 请谨慎选择过期时间,个人访问令牌生成后,将不支持修改 */ | 'expired_time_forbidden_1' + /** 抱歉,发生了一些错误... */ | 'failed' + /** 收起 */ | 'fornax_analytics_collapse' + /** 复制失败 */ | 'fornax_analytics_copy_fail' + /** 复制成功 */ | 'fornax_analytics_copy_success' + /** 暂无数据 */ | 'fornax_analytics_data_empty' + /** 数据不存在或异常 */ | 'fornax_analytics_empty_data_abnormal' + /** 未选中节点 */ | 'fornax_analytics_empty_node_unselected' + /** 渲染失败 */ | 'fornax_analytics_empty_run_tree_failure' + /** 请在左侧选中对应的节点查看详情 */ | 'fornax_analytics_empty_to_select_node' + /** 展开 */ | 'fornax_analytics_extend' + /** SpanID */ | 'fornax_analytics_query_detail_span_id' + /** 本月截止目前 */ | 'fornax_analytics_range_this_month' + /** StatusCode */ | 'fornax_analytics_status_code' + /** 调用树 */ | 'fornax_analytics_tab_run_tree' + /** 开发环境 */ | 'fornax_analytics_threads_options_dev' + /** 失败 */ | 'fornax_analytics_threads_options_fail' + /** 线上环境 */ | 'fornax_analytics_threads_options_online' + /** 成功 */ | 'fornax_analytics_threads_options_success' + /** 前天 */ | 'fornax_analytics_time_day_before_yesterday' + /** 过去3月 */ | 'fornax_analytics_time_past_3_months' + /** 过去一月 */ | 'fornax_analytics_time_past_month' + /** 过去一周 */ | 'fornax_analytics_time_past_week' + /** 过去一年 */ | 'fornax_analytics_time_past_year' + /** 今天截止目前 */ | 'fornax_analytics_time_today_so_far' + /** 本周截止目前 */ | 'fornax_analytics_time_week_so_far' + /** 昨天 */ | 'fornax_analytics_time_yesterday' + /** 节点详情 */ | 'fornax_analytics_title_span_detail' + /** 添加筛选组条件 */ | 'fornax_components_logic_expr_add_filter_group' + /** 添加筛选条件 */ | 'fornax_components_logic_expr_add_filter' + /** 且 */ | 'fornax_components_logic_expr_and' + /** 删除条件 */ | 'fornax_components_logic_expr_delete_filter' + /** 非 */ | 'fornax_components_logic_expr_not' + /** 或 */ | 'fornax_components_logic_expr_or' + /** go */ | 'go' + /** 导入 */ | 'import' + /** 输入 */ | 'Input' + /** 语言 */ | 'language' + /** 最新版本 */ | 'latest_version' + /** 加载完成 */ | 'loaded' + /** 加载中 */ | 'loading' + /** 加载中 */ | 'Loading' + /** 退出登录 */ | 'logout' + /** 我的 */ | 'Me' + /** 移动端 */ | 'mobile' + /** 模型家族 */ | 'model_family' + /** 模型信息 + */ | 'model_info' + /** 模型名称 */ | 'model_name' + /** 新的个人访问令牌 */ | 'new_pat_1' + /** 下一步 */ | 'next' + /** 还没有个人访问令牌 */ | 'no_api_token_1' + /** 或 */ | 'or' + /** 输出 */ | 'Output' + /** 参数 */ | 'parameters' + /** 用于其他应用程序和平台的个人访问令牌。详细说明请查看: */ | 'pat_reminder_1' + /** 不要与他人共享您的个人访问令牌,也不要在浏览器或其他客户端代码中暴露它,以保护您账户的安全。若在公开场合发现任何泄露的个人访问令牌,该令牌可能会被自动禁用。 */ | 'pat_reminder_2' + /** 扣子 */ | 'platform_name' + /** 插件 */ | 'Plugins' + /** 指令为必填项 */ | 'prompt_generate_instruction_validate' + /** 指令为必填项 */ | 'prompt_generate_statement_validate' + /** 停止回答 */ | 'prompt_generate_stop_responding' + /** 停止扩写 */ | 'prompt_generate_stop' + /** 提交 */ | 'prompt_submit' + /** 版本提交后即刻生效,确定要提交么 */ | 'prompt_version_submit' + /** Python */ | 'python' + /** 替换 */ | 'replace' + /** 必填 */ | 'required' + /** 响应回答中 */ | 'Responding' + /** 重试 */ | 'Retry' + /** 重试 */ | 'retry' + /** 保存 */ | 'Save' + /** 搜索 */ | 'Search' + /** 选择过期时间 */ | 'select_expired_time_1' + /** 空格 */ | 'space' + /** 成功 */ | 'Success' + /** 等于 */ | 'task_filter_eq' + /** 大于 */ | 'task_filter_gt' + /** 大于等于 */ | 'task_filter_gte' + /** 属于 */ | 'task_filter_in' + /** 为空 */ | 'task_filter_is_null' + /** 包含 */ | 'task_filter_like' + /** 小于 */ | 'task_filter_lt' + /** 小于等于 */ | 'task_filter_lte' + /** 不等于 */ | 'task_filter_not_eq' + /** 不属于 */ | 'task_filter_not_in' + /** 不为空 */ | 'task_filter_not_null' + /** 模板 */ | 'template_name' + /** 文本 */ | 'text' + /** 工具 */ | 'Tools' + /** 类型 */ | 'Type' + /** 类型 */ | 'type' + /** 未定义 */ | 'undefined' + /** 用户昵称 */ | 'user_info_custom_name' + /** 邮箱 */ | 'user_info_email' + /** 用户名 */ | 'user_info_username' + /** 版本 */ | 'version' + /** 工作流 */ | 'Workflow' + /** 账户 */ | 'account' + /** 返回 */ | 'back' + /** 清空 */ | 'clear' + /** 收起 */ | 'collapse' + /** 调试 */ | 'debug' + /** Demo 空间 */ | 'demo_space' + /** 描述 */ | 'description' + /** 详情 */ | 'detail' + /** 邮箱 */ | 'email' + /** 实验 */ | 'experiment' + /** 字段 */ | 'field' + /** 登录 */ | 'login' + /** 名称 */ | 'name' + /** 网络错误 */ | 'network_error' + /** 操作 */ | 'operation' + /** 密码 */ | 'password' + /** 永久 */ | 'permanent' + /** 预览 */ | 'preview' + /** 刷新 */ | 'refresh' + /** 注册 */ | 'register' + /** 移除 */ | 'remove' + /** 重试中 */ | 'retrying' + /** 运行 */ | 'run' + /** 保存 */ | 'save' + /** 提交 */ | 'submit' + /** 今天 */ | 'today' + /** 明天 */ | 'tomorrow' + /** 用户协议 */ | 'user_agreement' + /** 未知问题 */ | 'unknown_error' + /** 昨天 */ | 'yesterday' + /** 搜索创建人 */ | 'search_creator' + /** 当前用户 */ | 'current_user' + /** 重置为默认 */ | 'reset_to_default' + /** 拖动排序 */ | 'drag_to_sort' + /** 列管理 */ | 'column_management' + /** 复制 ID */ | 'copy_id' + /** 复制成功 */ | 'copy_success' + /** 复制失败 */ | 'copy_failed' + /** 查看详情 */ | 'view_detail' + /** 页面丢失了 */ | 'page_not_found' + /** 页面加载失败 */ | 'page_load_failed' + /** 暂无权限 */ | 'no_permission' + /** 点击升序 */ | 'click_ascending' + /** 点击降序 */ | 'click_descending' + /** 点击恢复默认排序 */ | 'restore_default_sort' + /** 复制内容 */ | 'copy_content' + /** 保存时间 */ | 'save_time' + /** 当前草稿 */ | 'current_draft' + /** 提交时间 */ | 'submit_time' + /** 提交人: */ | 'submitter' + /** 版本说明 */ | 'version_description' + /** 版本记录 */ | 'version_record' + /** 空间不存在 */ | 'space_not_exists' + /** 点击重试 */ | 'click_retry' + /** 文档 */ | 'document' + /** 飞书群 */ | 'lark_group' + /** Prompt 工程 */ | 'prompt_engineering' + /** Prompt 开发 */ | 'prompt_development' + /** 评测 */ | 'evaluation' + /** 评测集 */ | 'evaluation_set' + /** 评估器 */ | 'evaluator' + /** 观测 */ | 'observation' + /** 确认要退出登录吗? */ | 'confirm_logout' + /** 账户设置 */ | 'account_settings' + /** 暂无空间 */ | 'no_space' + /** 你未加入任何空间 */ | 'not_join_space' + /** API 授权 */ | 'api_authorization' + /** 欢迎使用扣子罗盘-社区版 */ | 'welcome_to_cozeloop' + /** 请输入邮箱 */ | 'please_input_email' + /** 请输入密码 */ | 'please_input_password' + /** 此令牌仅显示一次。请将此密钥保存在安全且可获取的地方。不要与他人共享,也不要在浏览器或其他客户端代码中暴露它。 */ | 'token_show_only_once' + /** 过期时间 */ | 'expiration_time' + /** 令牌 */ | 'token' + /** 删除令牌 */ | 'delete_token' + /** 移除后会影响所有正在使用 API 个人访问令牌的应用 */ | 'remove_will_affect_all_in_use' + /** 注册/登录失败,请检查邮箱或密码 */ | 'register_or_login_failed' + /** 最近使用 */ + | 'last_used' + /** 活跃 */ + | 'active' + /** 已过期 */ + | 'expired' + /** 新的个人访问令牌 */ + | 'new_pat' + /** 添加新令牌 */ + | 'add_token' + /** 添加个人访问令牌 */ + | 'add_pat' + /** 编辑个人访问令牌 */ + | 'edit_pat' + /** 用于其他应用程序和平台的个人访问令牌。详细说明请查看: */ + | 'pat_introduction' + /** API 使用说明 */ + | 'api_instruction' + /** 不要与他人共享您的个人访问令牌,也不要在浏览器或其他客户端代码中暴露它,以保护您账户的安全。若在公开场合发现任何泄露的个人访问令牌,该令牌可能会被自动禁用。 */ + | 'pat_reminder' + /** 请谨慎选择过期时间,个人访问令牌生成后,将不支持修改 */ + | 'expired_time_tip' + /** 暂无个人访问令牌 */ + | 'no_pat' + /** 用户名 */ + | 'username' + /** 用户昵称 */ + | 'user_custom_name' + /** Prompt */ | 'prompt' + /** 请输入内容,支持按此格式书写变量:'{{USER_NAME}} */ | 'please_input_with_vars' + /** 生成随机性 */ | 'temperature' + /** 最大回复长度 */ | 'max_tokens' + /** Top P */ | 'top_p' + /** Top K */ | 'top_k' + /** 存在惩罚 */ | 'presence_penalty' + /** 频率惩罚 */ | 'frequency_penalty' + /** 编辑 Prompt */ | 'edit_prompt' + /** 创建副本 */ | 'create_copy' + /** 创建 Prompt */ | 'create_prompt' + /** Prompt key */ | 'prompt_key' + /** 仅支持英文字母、数字、“_”、“.”,且仅支持英文字母开头 */ | 'prompt_key_format' + /** Prompt 名称 */ | 'prompt_name' + /** 仅支持英文字母、数字、中文,“-”,“_”,“.”,且仅支持英文字母、数字、中文开头 */ | 'prompt_name_format' + /** Prompt 描述 */ | 'prompt_description' + /** 支持输入英文字母和下划线,且首字母必须是字母 */ | 'prompt_var_format' + /** Placeholder 变量名 */ | 'placeholder_var_name' + /** 只允许输入英文、数字及下划线且首字母需为英文 */ | 'placeholder_format' + /** 文本变量名称已存在,请修改 Placeholder 变量名 */ | 'placeholder_name_exists' + /** Placeholder 变量不存在或命名错误 */ | 'placeholder_var_error' + /** 历史数据有空内容 */ | 'historical_data_has_empty_content' + /** 请添加 Prompt 模板或输入提问内容 */ | 'add_prompt_tpl_or_input_question' + /** 设置为基准组 */ | 'set_to_reference_group' + /** 删除对照组 */ | 'delete_control_group' + /** 加载更多 */ | 'load_more' + /** 暂无调试记录 */ | 'no_debug_record' + /** 调试历史 */ | 'debug_history' + /** 删除 Prompt 模板 */ | 'delete_prompt_template' + /** 确定删除当前 Prompt 模板? */ | 'confirm_delete_current_prompt_template' + /** 模拟值 */ | 'mock_value' + /** 已深度思考 */ | 'deeply_thought' + /** 深度思考中 */ | 'deep_thinking' + /** 编辑 */ | 'edit' + /** 删除消息 */ | 'delete_message' + /** 确认删除该消息吗? */ | 'confirm_delete_message' + /** 重新运行 */ | 'rerun' + /** 删除成功 */ | 'delete_success' + /** 删除Prompt */ | 'delete_prompt' + /** 复制 Prompt Key */ | 'copy_prompt_key' + /** 请输入 Prompt Key 再次确认 */ | 'prompt_key_again_confirm' + /** 编排 */ | 'orchestration' + /** 收起模型配置与变量区 */ | 'collapse_model_and_var_area' + /** 展开模型配置与变量区 */ | 'expand_model_and_var_area' + /** 展开预览与调试 */ | 'expand_preview_and_debug' + /** 收起预览与调试 */ | 'collapse_preview_and_debug' + /** 当前无草稿变更 */ | 'no_draft_change' + /** 已提交 */ | 'submitted' + /** Placeholder 变量名不存在或命名错误,无法创建 */ | 'placeholder_var_create_error' + /** 模型 ID */ | 'model_id' + /** 本次提交无版本差异 */ | 'submission_no_version_diff' + /** 打开 启用函数 */ | 'open_enable_function' + /** 关闭 启用函数 */ | 'close_enable_function' + /** 继续 */ | 'continue' + /** 关闭 */ | 'close' + /** 请输入版本号,版本号格式为a.b.c, 且每段为0-9999 */ | 'input_version_number' + /** 图片上传失败,请稍后重试 */ | 'image_upload_error' + /** 清空历史消息 */ | 'clear_history_messages' + /** 请输入问题测试大模型回复,回车发送,Shift+回车换行 */ | 'input_question_tip' + /** 删除函数 */ | 'delete_function' + /** 确认删除该函数吗? */ | 'confirm_delete_function' + /** 当前方法已经存在,请重新命名 */ | 'method_exists' + /** 新函数 */ | 'new_function' + /** 方法名称必须是 a-z、A-Z、0-9,或包含下划线和破折号,长度最长为 64。 */ | 'method_name_rule' + /** 在此处输入模拟值以模拟函数的返回值。 */ | 'input_mock_value_here' + /** Trace ID */ | 'trace_id' + /** 复制 Trace ID */ | 'copy_trace_id' + /** 复制变量名 */ | 'copy_variable_name' + /** 删除变量 */ | 'delete_variable' + /** 将删除 Prompt 模板中的该变量。确认删除吗? */ | 'confirm_delete_var_in_tpl' + /** 参数值 */ | 'param_value' + /** 模拟消息 */ | 'mock_message' + /** System */ | 'system_role' + /** Assistant */ | 'assistant_role' + /** User */ | 'user_role' + /** 回滚成功 */ | 'rollback_success' + /** 还原为此版本 */ | 'restore_to_this_version' + /** 还原后将覆盖最新编辑的提示词。确认还原为此版本? */ | 'restore_version_tip' + /** 还原 */ | 'restore' + /** 模型运行出错 */ | 'model_run_error' + /** 模型运行错误 */ | 'model_runtime_error' + /** promptID 不一致 */ | 'prompt_id_inconsistent' + /** 最近提交时间 */ | 'recent_submission_time' + /** 搜索 Prompt Key 或 Prompt 名称 */ | 'search_prompt_key_or_prompt_name' + /** 暂无 Prompt */ | 'no_prompt' + /** 需要提供 Prompt 版本号 */ | 'prompt_version_number_needed' + /** 版本号格式不正确 */ | 'incorrect_version_number' + /** 版本号不能小于当前版本 */ | 'version_number_lt_error' + /** 紧凑视图 */ | 'compact_view' + /** 宽松视图 */ | 'loose_view' + /** 草稿版本 */ | 'draft_version' + /** 修改未提交 */ | 'modify_not_submitted' + /** 去提交 */ | 'go_submit' + /** 选择实验 */ | 'select_experiment' + /** 发起实验对比 */ | 'initiate_experiment_comparison' + /** 仅评测集相同且已执行完成的实验可进行对比。 */ | 'only_experiments_with_same_evaluation_set_and_completed_can_be_compared' + /** 已选 */ | 'selected' + /** 创建人 */ | 'creator' + /** 评测对象类型 */ | 'evaluation_object_type' + /** 评测对象 */ | 'evaluation_object' + /** Coze Bot */ | 'coze_bot' + /** Coze 智能体 */ | 'coze_agent' + /** 评测集版本 */ | 'evaluation_set_version' + /** 状态 */ | 'status' + /** 这是一个 CozeBot */ | 'this_is_a_cozebot' + /** 查看实际输出的trace */ | 'view_actual_output_trace' + /** 实验名称 */ | 'experiment_name' + /** 该字段必填 */ | 'the_field_required' + /** 实验描述 */ | 'experiment_description' + /** 编辑实验 */ | 'edit_experiment' + /** 请选择模型 */ | 'choose_model' + /** 查看参数 */ | 'check_parameters' + /** 暂无数据 */ | 'no_data' + /** 关联实验 */ | 'associated_experiment' + /** 评估器类型 */ | 'evaluator_type' + /** 模型选择 */ | 'model_selection' + /** 预览与调试 */ | 'preview_and_debug' + /** 可通过构造测试数据,预览评估器的运行结果。 */ | 'construct_test_data_to_preview_evaluator_runtime_result' + /** 配置信息 */ | 'config_info' + /** 构造测试数据 */ | 'construct_test_data' + /** 试运行将产生资源点消耗 */ | 'testrun_require_fee' + /** 内容由AI生成,无法确保真实准确,仅供参考。 */ | 'generated_by_ai_tip' + /** 评估器缺少输入 */ | 'evaluator_lacks_input' + /** 信息未保存 */ | 'information_unsaved' + /** 离开当前页面,信息将不被保存。 */ | 'leave_page_tip' + /** 新建评估器 */ | 'new_evaluator' + /** 创建 */ | 'create' + /** 确认清空 Prompt? */ | 'confirm_clear_prompt' + /** System Prompt 不可为空 */ | 'system_prompt_not_empty' + /** 删除 User Prompt */ | 'delete_user_prompt' + /** 确认删除 User Prompt ? */ | 'confirm_delete_user_prompt' + /** 添加 User Prompt */ | 'add_user_prompt' + /** 提交新版本 */ | 'submit_new_version' + /** 创建评估器 */ | 'create_evaluator' + /** 版本号格式为a.b.c,且每段为0-9999 */ | 'version_number_format' + /** 版本号 */ | 'version_number' + /** 选择模板 */ | 'select_template' + /** 预置评估器 */ | 'preset_evaluator' + /** 编辑评估器 */ | 'edit_evaluator' + /** 草稿自动保存中 */ | 'draft_auto_saving' + /** 草稿自动保存失败 */ | 'draft_auto_save_failed' + /** 提交时间: */ | 'submission_time' + /** 版本提交成功 */ | 'version_submit_success' + /** 搜索名称 */ | 'search_name' + /** 复制评估器配置 */ | 'copy_evaluator_config' + /** 评估器名称 */ | 'evaluator_name' + /** 更新人 */ | 'updated_person' + /** 更新时间 */ | 'update_time' + /** 创建时间 */ | 'create_time' + /** 此操作不可逆,请慎重操作 */ | 'this_operation_is_irreversible_please_operate_carefully' + /** 未能找到相关结果 */ | 'failed_to_find_related_results' + /** 请尝试其他关键词或修改筛选项 */ | 'try_other_keywords_or_modify_filter_options' + /** 暂无评估器 */ | 'no_evaluator' + /** 点击右上角创建按钮进行创建 */ | 'click_to_create' + /** 基准组 */ | 'benchmark_group' + /** 移除实验组 */ | 'remove_experimental_group' + /** 评测对象的实际输出 */ | 'evaluation_object_actual_output' + /** 基准 */ | 'benchmark' + /** 基准实验切换成功 */ | 'benchmark_experiment_switch_success' + /** 数据明细 */ | 'data_detail' + /** 指标统计 */ | 'measure_stat' + /** 数据总量 */ | 'data_total_count' + /** 正在加载字段映射 */ | 'loading_field_mapping' + /** 请选择类型 */ | 'select_type' + /** 实际输出 */ | 'actual_output' + /** 接口遇到问题 */ | 'interface_problem' + /** 评测对象版本 */ | 'evaluation_object_version' + /** 请配置评测对象映射 */ | 'config_evaluation_object_mapping' + /** 至少添加一个评估器 */ | 'add_at_least_one_evaluator' + /** 最多添加5个评估器 */ | 'max_add_x_evaluators' + /** 名称和版本 */ | 'name_and_version' + /** 字段映射 */ | 'field_mapping' + /** 下一步:评测集 */ | 'next_step_evaluation_set' + /** 下一步:评测对象 */ | 'next_step_evaluation_object' + /** 下一步:评估器 */ | 'next_step_evaluator' + /** 确认实验配置 */ | 'confirm_experiment_config' + /** 发起实验 */ | 'initiate_experiment' + /** 新建实验 */ | 'new_experiment' + /** 所选字段数据类型不一致,请重新选择 */ | 'selected_fields_inconsistent' + /** 评测集字段、评测对象实际输出到评估器字段的映射,用于评估器准确获取输入进行评估。 */ | 'evaluation_set_field_mapping_tip' + /** 添加评估器 */ | 'add_evaluator' + /** 提交表单遇到问题 */ | 'submit_form_problems' + /** 更新评分成功 */ | 'update_rating_success' + /** 查看评估器 Trace */ | 'view_evaluator_trace' + /** 人工校准 */ | 'manual_calibration' + /** 得分明细 */ | 'score_details' + /** 得分 */ | 'score' + /** 实验完成后,再刷新重试 */ | 'refresh_after_experiment' + /** 聚合得分 */ | 'aggregation_score' + /** 得分明细 - 数据项分布 */ | 'score_details_data_item_distribution' + /** 指标 */ | 'indicator' + /** 实验初始化中 */ | 'experiment_initializing' + /** 得分理由 */ | 'score_reason' + /** 结束时间 */ | 'end_time' + /** 确认用于实验的评测集版本 */ | 'confirm_evaluation_set_version' + /** 当前草稿有修改未提交,已默认选择最新历史版本 */ | 'draft_unsubmitted_tip' + /** 至少保留一个数据项 */ | 'retain_one_data_item' + /** 折叠全部数据项 */ | 'collapse_all_data_items' + /** 展开全部数据项 */ | 'expand_all_data_items' + /** 执行结果 */ | 'execution_result' + /** 已知晓 */ | 'known' + /** 删除列 */ | 'delete_column' + /** 列名称 */ | 'column_name' + /** 列描述 */ | 'column_description' + /** 添加列 */ | 'add_column' + /** 基础信息 */ | 'basic_info' + /** 评测集名称 */ | 'evaluation_set_name' + /** 评测集描述 */ | 'evaluation_set_description' + /** 配置列 */ | 'configuration_column' + /** 评测集创建完成后,仍可修改列配置 */ | 'can_still_modify_column' + /** 数据类型 */ | 'data_type' + /** 查看格式 */ | 'view_format' + /** 暂无修改可提交 */ | 'no_modification_to_submit' + /** 版本格式为a.b.c,且每段为0-999 */ | 'version_format_and_range' + /** 点击右上角添加数据进行添加 */ | 'click_to_add_data' + /** 编辑评测集 */ | 'edit_evaluation_set' + /** 导入数据 */ | 'import_data' + /** 上传数据 */ | 'upload_data' + /** 点击上传或者拖拽文件至此处 */ | 'click_or_drag_file_to_upload' + /** 推荐使用模板上传1个文件,支持CSV格式 */ | 'recommend_template_upload_tip' + /** 下载模板 */ | 'download_template' + /** 请上传文件 */ | 'upload_file' + /** 如果待导入数据集的列没有配置映射关系,则该列不会被导入。 */ | 'no_mapping_no_import' + /** 列映射 */ | 'column_mapping' + /** 待导入数据的列名和当前评测集列名的映射关系。 */ | 'source_column_mapping' + /** 请配置最少一个导入列 */ | 'configure_at_least_one_import_column' + /** 导入方式 */ | 'import_method' + /** 暂无评测集 */ | 'no_evaluation_dataset' + /** 点击右上角新建评测集按钮进行创建 */ | 'click_to_create_evaluation_set' + /** 评测集列 */ | 'evaluation_set_column' + /** 请配置列映射 */ | 'configure_column_mapping' + /** 请选择导入方式 */ | 'select_import_method' + /** 确认选择全量覆盖 */ | 'confirm_select_full_coverage' + /** 继续导入数据将覆盖现有数据 */ | 'continue_will_override_existing_data' + /** 执行中 */ | 'execution_in_progress' + /** 数字 */ | 'number' + /** 字符串 */ | 'string' + /** 整数 */ | 'integer' + /** 请输入浮点数,至多小数点后4位 */ | 'input_float_with_precision' + /** 编辑数据项: */ | 'edit_data_item' + /** 查看数据项: */ | 'view_data_item' + /** 数据项 */ | 'data_item' + /** 删除评测集 */ | 'delete_evaluation_set' + /** 调试失败 */ | 'debug_failure' + /** 调试成功 */ | 'debugging_succeeded' + /** Prompt 详情 */ | 'prompt_detail' + /** 正在加载 Prompt 详情 */ | 'loading_prompt_detail' + /** 请选择评估器和版本号后再查看 */ | 'select_evaluator_and_version_number_to_view' + /** 模型 */ | 'model' + /** 输出 */ | 'output' + /** 通过 Function Call 从 LLM 中提取数据,固定评估器输出格式为“得分-原因”。 */ | 'extract_via_function_call' + /** 得分: */ | 'score_is' + /** 评分 */ | 'rating' + /** 请输入0-1的分值 */ | 'input_score_between_0_and_1' + /** 请输入0~1区间内的数字 */ | 'input_number_between_0_and_1' + /** 原因 */ | 'reason' + /** 查看评估器详情 */ | 'view_evaluator_details' + /** 批量删除实验 */ | 'batch_delete_experiment' + /** 在实验列表中,聚合统计各实验在指标上的得分。 */ | 'aggregate_statistics_score_on_metrics' + /** 折线图 */ | 'line_chart' + /** 柱状图 */ | 'bar_chart' + /** 暂无实验 */ | 'no_experiment' + /** 点击右上角新建实验按钮进行创建 */ | 'click_to_create_experiment' + /** schema 不匹配 */ | 'schema_mismatch' + /** 空数据 */ | 'empty_data' + /** 单条数据大小超限 */ | 'single_data_size_exceeded' + /** 数据集容量超限 */ | 'dataset_capacity_exceeded' + /** 文件格式错误 */ | 'file_format_error' + /** 系统错误 */ | 'system_error' + /** 包含非法内容 */ | 'contains_illegal_content' + /** 操作符 */ | 'operator' + /** 等于 */ | 'equal_to' + /** 不等于 */ | 'not_equal_to' + /** 包含 */ | 'contain' + /** 不包含 */ | 'not_contain' + /** 大于 */ | 'greater_than' + /** 大于等于 */ | 'greater_than_or_equal_to' + /** 小于 */ | 'less_than' + /** 小于等于 */ | 'less_than_or_equal_to' + /** 晚于 */ | 'later_than' + /** 早于 */ | 'earlier_than' + /** 新建评测集 */ | 'new_evaluation_set' + /** 为保证自动评测效果,评估器 Prompt 需至少有1个变量 */ | 'prompt_variable_to_ensure_effect' + /** 新建 Prompt */ | 'new_prompt' + /** 进行中 */ | 'in_progress' + /** 中止 */ | 'abort' + /** 待执行 */ | 'to_be_executed' + /** 折叠 */ | 'fold' + /** 仅针对执行失败的部分重新评测 */ | 're_evaluate_failed_only' + /** 复制实验配置并新建实验 */ | 'copy_and_create_experiment' + /** 关联评测集 */ | 'associated_evaluation_set' + /** 删除实验 */ | 'delete_experiment' + /** 重试实验 */ | 'retry_experiment' + /** 仅针对执行失败的部分重新评测。 */ | 'only_re_evaluate_failed_part' + /** 复制实验配置 */ | 'copy_experiment_config' + /** 评测集字段到评测对象字段的映射,用于评测对象准确获取输入。 */ | 'evaluation_set_field_to_evaluation_object_field_mapping' + /** 获取评测对象遇到错误 */ | 'get_evaluation_object_error' + /** 仅评测集相同且已执行完成的实验可进行对比。目前选择的实验有关联评测集不同的情况,请重新选择。 */ | 'experiments_compared_tip' + /** 仅已执行完成的实验可进行对比,请重新选择。 */ | 'only_completed_experiments_can_be_compared' + /** 实验对比发起失败 */ | 'experiment_comparison_initiation_failure' + /** 实验组 */ | 'experimental_group' + /** 仅支持英文字母、数字、中文开头 */ | 'only_support_english_letters_numbers_and_chinese_at_the_beginning' + /** 仅支持英文字母、数字、中文,“-”,“_”,“.” */ | 'only_support_english_letters_numbers_and_chinese_and_' + /** 仅支持英文、数字、下划线,且需要以字母开头 */ | 'only_support_english_numbers_and_underscores_and_start_with_a_letter' + /** 当前 Trace 已过期无法查看 */ | 'current_trace_expired_to_view' + /** 当前的角色权限暂时无法查看该 Trace 详情 */ | 'no_permission_to_view_trace' + /** 无权限查看 */ | 'no_permission_to_view' + /** 未找到上报的数据 */ | 'reported_data_not_found' + /** 请尝试在SDK数据上报时,写入Input和Output信息 */ | 'report_in_sdk' + /** 查询所有 SpanID,以上报埋点为粒度进行展示 */ | 'all_span_tip' + /** 根据 TraceID 查询,以调用入口为粒度进行展示 */ | 'root_span_tip' + /** 仅查询和模型调用相关的埋点 */ | 'llm_span_tip' + /** 确认删除该视图? */ | 'confirm_delete_view' + /** 删除后操作将不可逆 */ | 'deletion_irreversible' + /** 默认视图不可编辑 */ | 'default_view_not_editable' + /** 默认视图不可删除 */ | 'default_view_cannot_be_deleted' + /** 新视图无法展示, 请修改视图展示管理 */ | 'new_view_cannot_be_displayed' + /** 查看方式 */ | 'viewing_method' + /** 属于 */ | 'belong_to' + /** 数据来源 */ | 'data_source' + /** 查看方式、数据来源,和外侧的 Trace 列表和 SDK 上报下拉框联动。保存为视图时,需要设置这 2 项过滤条件 */ | 'viewing_method_data_source_linkage' + /** 数据到期时间 */ | 'data_expiration_time' + /** SDK 上报 */ | 'sdk_reporting' + /** 自定义 */ | 'customize' + /** 全部时间 */ | 'all_time' + /** 不允许为空 */ | 'not_allowed_to_be_empty' + /** 视图名称已存在 */ | 'view_name_exists' + /** TOS URL 不存在,请联系 Cozeloop */ | 'tos_url_not_exist'; diff --git a/frontend/packages/cozeloop/i18n/src/types.ts b/frontend/packages/cozeloop/i18n/src/types.ts index 8aca9c15f..d0904a090 100644 --- a/frontend/packages/cozeloop/i18n/src/types.ts +++ b/frontend/packages/cozeloop/i18n/src/types.ts @@ -5,6 +5,8 @@ import { type I18nWithInterpolation, } from './locale-types'; +import { type intlClient } from '@cozeloop/intl'; + interface I18nFunction { /** 🔵 I18n **with** interpolation */ ( @@ -12,7 +14,7 @@ interface I18nFunction { options: I18nWithInterpolation[K], fallbackText?: string, ): string; - /** 🟣 I18n **without** interpolation */ + /** 🟣 I18n **without** interpolation {@link I18nKeysNoInterpolation keys} */ (keys: K, fallbackText?: string): string; } @@ -25,7 +27,7 @@ interface UnsafeI18nFunction { ): string; } -export interface CozeloopI18n { +export type CozeloopI18n = Omit & { t: I18nFunction; unsafeT: UnsafeI18nFunction; -} +}; diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json index 31017b6f1..84fe98d0b 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/en-US.json @@ -1,9 +1,9 @@ { "api_authorization": "API Authorization", "account": "Account", - "welcome_to_cozeloop": "Welcome to Cozeloop - Community Edition.", - "please_input_email": "Please enter your email address.", - "please_input_password": "Please enter the password.", + "welcome_to_cozeloop": "Welcome to Cozeloop - Community", + "please_input_email": "Please enter your email address", + "please_input_password": "Please enter the password", "register": "Register", "login": "Login", "please_agree_first": "Please agree {agreement}.", @@ -13,9 +13,25 @@ "expiration_time": "Expiration time", "token": "Token", "delete_token": "Delete the token", - "remove_will_affect_all_in_use": "Removal will affect all ongoing uses.", - "confirm": "Confirm.", + "remove_will_affect_all_in_use": "Removal will affect all applications currently using API personal access tokens.", + "confirm": "Confirm", "x_days": "{num, plural, zero {0 day} one {1 day} other {# days}}", "permanent": "Permanent", - "register_or_login_failed": "Registration/Login failed. Please check your email or password." + "register_or_login_failed": "Registration/Login failed. Please check your email or password.", + "last_used": "Last used", + "active": "Active", + "expired": "Expired", + "new_pat": "New Personal Access Token", + "auth_tab_pat": "Personal Access Tokens", + "add_token": "Add token", + "add_pat": "Add Personal Access Token", + "edit_pat": "Edit Personal Access Token", + "pat_introduction": "Personal access tokens for other applications and platforms. For details, see:", + "api_instruction": "API instructions", + "pat_reminder": "For the security of your account, do not share your personal access token or expose it in browsers or other client codes, as it may be automatically disabled.", + "expired_time_tip": "Please select the expiration time carefully, as the personal access token cannot be modified once generated", + "expired_time_days": "{num, plural, one {# day ({date})} other {# days ({date})}}", + "no_pat": "No Personal Access Token", + "username": "Username", + "user_custom_name": "Alias" } diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/zh-CN.json index 3c7b18a1d..ed99f77c6 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/zh-CN.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/auth/zh-CN.json @@ -13,9 +13,25 @@ "expiration_time": "过期时间", "token": "令牌", "delete_token": "删除令牌", - "remove_will_affect_all_in_use": "移除后会影响所有正在使用", + "remove_will_affect_all_in_use": "移除后会影响所有正在使用 API 个人访问令牌的应用", "confirm": "确定", "x_days": "{num}天", "permanent": "永久", - "register_or_login_failed": "注册/登录失败,请检查邮箱或密码" + "register_or_login_failed": "注册/登录失败,请检查邮箱或密码", + "last_used": "最近使用", + "active": "活跃", + "expired": "已过期", + "new_pat": "新的个人访问令牌", + "auth_tab_pat": "个人访问令牌", + "add_token": "添加新令牌", + "add_pat": "添加个人访问令牌", + "edit_pat": "编辑个人访问令牌", + "pat_introduction": "用于其他应用程序和平台的个人访问令牌。详细说明请查看:", + "api_instruction": "API 使用说明", + "pat_reminder": "不要与他人共享您的个人访问令牌,也不要在浏览器或其他客户端代码中暴露它,以保护您账户的安全。若在公开场合发现任何泄露的个人访问令牌,该令牌可能会被自动禁用。", + "expired_time_tip": "请谨慎选择过期时间,个人访问令牌生成后,将不支持修改", + "expired_time_days": "{num, plural, other {{num}天({date})}}", + "no_pat": "暂无个人访问令牌", + "username": "用户名", + "user_custom_name": "用户昵称" } diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/en-US.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/en-US.json index 0c0bf1f10..804f41201 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/en-US.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/en-US.json @@ -124,7 +124,7 @@ "manual_calibration": "Manual calibration", "score_details": "Score detail", "score": "Score", - "x_items ": "{item, plural, zero {No item} one {1 item} other{# items}}", + "x_items": "{item, plural, zero {No item} one {1 item} other{# items}}", "refresh_after_experiment": "Refresh to retry once the experiment is completed", "aggregation_score": "Aggregation score", "score_details_data_item_distribution": "Score details - Data item distribution", diff --git a/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/zh-CN.json b/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/zh-CN.json index 31b9bb740..1f8c23c3a 100644 --- a/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/zh-CN.json +++ b/frontend/packages/cozeloop/resources/loop-lng/src/locales/evaluate/zh-CN.json @@ -125,7 +125,7 @@ "manual_calibration": "人工校准", "score_details": "得分明细", "score": "得分", - "x_items ": "{num, plural, zero {无} other {#条}}", + "x_items": "{num, plural, zero {无} other {#条}}", "refresh_after_experiment": "实验完成后,再刷新重试", "aggregation_score": "聚合得分", "score_details_data_item_distribution": "得分明细 - 数据项分布", From b15bddc25e451388a9bc7b30302b2e4bfd167de5 Mon Sep 17 00:00:00 2001 From: qihai Date: Thu, 17 Jul 2025 10:27:59 +0800 Subject: [PATCH 07/30] feat: replace components i18n --- .../config/subspaces/default/pnpm-lock.yaml | 3 +++ frontend/cspell.json | 1 + .../cozeloop/biz-components/package.json | 2 +- .../biz-components/src/user-select/index.tsx | 5 +++-- .../cozeloop/biz-hooks/src/constants/index.ts | 7 ------- .../base-search-select/base-search-select.tsx | 3 ++- .../components/src/columns-select/index.tsx | 18 ++++++++++++----- .../components/src/id-render/index.tsx | 7 ++++--- .../src/open-detail-button/index.tsx | 3 ++- .../components/src/page-content/index.tsx | 7 ++++--- .../components/src/table-header/index.tsx | 10 ++++++++-- .../components/src/table/sort-icon.tsx | 7 ++++--- .../components/src/text-with-copy/index.tsx | 6 +++++- .../cozeloop/components/src/utils/basic.ts | 5 +++-- .../src/version-list/version-descriptions.tsx | 20 +++++++++++++------ .../src/version-list/version-list.tsx | 3 ++- .../src/version-list/version-switch-panel.tsx | 3 ++- .../cozeloop/i18n/src/locale-types.ts | 5 +++++ .../loop-lng/src/locales/auth/en-US.json | 2 +- .../src/locales/components/en-US.json | 1 + .../src/locales/components/zh-CN.json | 1 + 21 files changed, 79 insertions(+), 40 deletions(-) diff --git a/common/config/subspaces/default/pnpm-lock.yaml b/common/config/subspaces/default/pnpm-lock.yaml index 010f6d8ad..49a65c6b6 100644 --- a/common/config/subspaces/default/pnpm-lock.yaml +++ b/common/config/subspaces/default/pnpm-lock.yaml @@ -1492,6 +1492,9 @@ importers: '@cozeloop/components': specifier: workspace:* version: link:../components + '@cozeloop/i18n-adapter': + specifier: workspace:* + version: link:../i18n classnames: specifier: ^2.3.2 version: 2.5.1 diff --git a/frontend/cspell.json b/frontend/cspell.json index 34405ba4d..541367b1f 100644 --- a/frontend/cspell.json +++ b/frontend/cspell.json @@ -19,6 +19,7 @@ "rspack", "rushstack", "rushx", + "sidesheet", "stylelint", "tailwindcss", "tanstack", diff --git a/frontend/packages/cozeloop/biz-components/package.json b/frontend/packages/cozeloop/biz-components/package.json index bddfee49c..75b576e97 100644 --- a/frontend/packages/cozeloop/biz-components/package.json +++ b/frontend/packages/cozeloop/biz-components/package.json @@ -14,6 +14,7 @@ "@cozeloop/api-schema": "workspace:*", "@cozeloop/biz-hooks-adapter": "workspace:*", "@cozeloop/components": "workspace:*", + "@cozeloop/i18n-adapter": "workspace:*", "classnames": "^2.3.2", "nanoid": "^4.0.2" }, @@ -37,4 +38,3 @@ "react-dom": ">=18.2.0" } } - diff --git a/frontend/packages/cozeloop/biz-components/src/user-select/index.tsx b/frontend/packages/cozeloop/biz-components/src/user-select/index.tsx index 432721931..c04111b62 100644 --- a/frontend/packages/cozeloop/biz-components/src/user-select/index.tsx +++ b/frontend/packages/cozeloop/biz-components/src/user-select/index.tsx @@ -1,6 +1,7 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 import cs from 'classnames'; +import { I18n } from '@cozeloop/i18n-adapter'; import { UserProfile } from '@cozeloop/components'; import { useUserInfo } from '@cozeloop/biz-hooks-adapter'; import { Select, type SelectProps, Tag } from '@coze-arch/coze-design'; @@ -61,7 +62,7 @@ export const UserSelect = ({ +
{refreshButtonPros ? ( - +
); diff --git a/frontend/packages/cozeloop/components/src/version-list/version-switch-panel.tsx b/frontend/packages/cozeloop/components/src/version-list/version-switch-panel.tsx index 3ab0712bc..3f88d67d4 100644 --- a/frontend/packages/cozeloop/components/src/version-list/version-switch-panel.tsx +++ b/frontend/packages/cozeloop/components/src/version-list/version-switch-panel.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { IconCozCross } from '@coze-arch/coze-design/icons'; import VersionList, { type VersionListProps } from './version-list'; @@ -18,7 +19,7 @@ export default function VersionSwitchPanel({ return (
-
版本记录
+
{I18n.t('version_record')}
Date: Thu, 17 Jul 2025 16:05:11 +0800 Subject: [PATCH 08/30] feat(cozeloop): switch lang --- .../config/subspaces/default/pnpm-lock.yaml | 3 ++ frontend/apps/cozeloop/src/app.tsx | 9 +++-- .../src/components/switch-lng/index.tsx | 27 +++------------ frontend/apps/cozeloop/src/hooks/index.ts | 2 ++ .../apps/cozeloop/src/hooks/use-locale.ts | 24 ++++++++++++++ .../apps/cozeloop/src/hooks/use-setup-i18n.ts | 15 +++++++++ .../apps/cozeloop/src/stores/i18n-store.ts | 33 +++++++++++++++++++ frontend/apps/cozeloop/src/stores/index.ts | 3 ++ frontend/packages/cozeloop/i18n/package.json | 1 + 9 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 frontend/apps/cozeloop/src/hooks/use-locale.ts create mode 100644 frontend/apps/cozeloop/src/hooks/use-setup-i18n.ts create mode 100644 frontend/apps/cozeloop/src/stores/i18n-store.ts create mode 100644 frontend/apps/cozeloop/src/stores/index.ts diff --git a/common/config/subspaces/default/pnpm-lock.yaml b/common/config/subspaces/default/pnpm-lock.yaml index 49a65c6b6..d652afe85 100644 --- a/common/config/subspaces/default/pnpm-lock.yaml +++ b/common/config/subspaces/default/pnpm-lock.yaml @@ -2175,6 +2175,9 @@ importers: '@formatjs/icu-messageformat-parser': specifier: ^2.11.2 version: 2.11.2 + '@types/react': + specifier: 18.2.37 + version: 18.2.37 '@vitest/coverage-v8': specifier: ~3.0.5 version: 3.0.9(vitest@3.0.9) diff --git a/frontend/apps/cozeloop/src/app.tsx b/frontend/apps/cozeloop/src/app.tsx index 143d3e8d0..03900fb09 100644 --- a/frontend/apps/cozeloop/src/app.tsx +++ b/frontend/apps/cozeloop/src/app.tsx @@ -5,19 +5,24 @@ import { Suspense } from 'react'; import { I18n } from '@cozeloop/i18n-adapter'; import { PageLoading } from '@cozeloop/components'; -import { zh_CN } from '@coze-arch/coze-design/locales'; import { CDLocaleProvider } from '@coze-arch/coze-design'; +import { useI18nStore } from './stores'; import { routeConfig } from './routes'; +import { useLocale, useSetupI18n } from './hooks'; import './index.css'; const router = createBrowserRouter(routeConfig); export function App() { + useSetupI18n(); + const lng = useI18nStore(s => s.lng); + const locale = useLocale(); + return ( }> - + diff --git a/frontend/apps/cozeloop/src/components/switch-lng/index.tsx b/frontend/apps/cozeloop/src/components/switch-lng/index.tsx index 9d20c6392..4ca44b38f 100644 --- a/frontend/apps/cozeloop/src/components/switch-lng/index.tsx +++ b/frontend/apps/cozeloop/src/components/switch-lng/index.tsx @@ -1,32 +1,15 @@ -import { useState } from 'react'; - -import { I18n } from '@cozeloop/i18n-adapter'; -import { Switch } from '@coze-arch/coze-design'; - +// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates +// SPDX-License-Identifier: Apache-2.0 +import { useI18nStore } from '@/stores'; import { ReactComponent as IconZhCN } from '@/assets/images/zh-cn.svg'; import { ReactComponent as IconEnUS } from '@/assets/images/en-us.svg'; -// TODO export function SwitchLang() { - // 'zh-CN' | 'en-US' - const [lang, setLang] = useState(() => I18n.lang); - - const toggleLang = async () => { - const switchMap: Record = { - 'zh-CN': 'en-US', - 'en-US': 'zh-CN', - }; - const targetLang = switchMap[lang] ?? 'zh-CN'; - await I18n.setLang(switchMap[I18n.lang]); - setLang(targetLang); - }; + const toggleLang = useI18nStore(s => s.toggleLng); + const lang = useI18nStore(s => s.lng); return (
- } - uncheckedText={} - /> {lang === 'en-US' ? ( ) : ( diff --git a/frontend/apps/cozeloop/src/hooks/index.ts b/frontend/apps/cozeloop/src/hooks/index.ts index ef82c1d42..f394ed87f 100644 --- a/frontend/apps/cozeloop/src/hooks/index.ts +++ b/frontend/apps/cozeloop/src/hooks/index.ts @@ -2,3 +2,5 @@ // SPDX-License-Identifier: Apache-2.0 export { useSetupSpace, SetupSpaceStatus } from './use-setup-space'; export { useApiErrorToast } from './use-api-error-toast'; +export { useLocale } from './use-locale'; +export { useSetupI18n } from './use-setup-i18n'; diff --git a/frontend/apps/cozeloop/src/hooks/use-locale.ts b/frontend/apps/cozeloop/src/hooks/use-locale.ts new file mode 100644 index 000000000..83e426459 --- /dev/null +++ b/frontend/apps/cozeloop/src/hooks/use-locale.ts @@ -0,0 +1,24 @@ +// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates +// SPDX-License-Identifier: Apache-2.0 +import { en_US, zh_CN } from '@coze-arch/coze-design/locales'; + +import { useI18nStore } from '@/stores'; + +function langToLocale(lang: string) { + if (!lang) { + return zh_CN; + } + switch (lang) { + case 'zh': + case 'zh-CN': + return zh_CN; + default: + return en_US; + } +} + +export function useLocale() { + const lng = useI18nStore(s => s.lng); + + return langToLocale(lng); +} diff --git a/frontend/apps/cozeloop/src/hooks/use-setup-i18n.ts b/frontend/apps/cozeloop/src/hooks/use-setup-i18n.ts new file mode 100644 index 000000000..0d7f65d2a --- /dev/null +++ b/frontend/apps/cozeloop/src/hooks/use-setup-i18n.ts @@ -0,0 +1,15 @@ +// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates +// SPDX-License-Identifier: Apache-2.0 +import { useEffect } from 'react'; + +import { I18n } from '@cozeloop/i18n-adapter'; + +import { useI18nStore } from '@/stores'; + +export function useSetupI18n() { + const setLng = useI18nStore(s => s.setLng); + + useEffect(() => { + setLng(I18n.lang); + }, []); +} diff --git a/frontend/apps/cozeloop/src/stores/i18n-store.ts b/frontend/apps/cozeloop/src/stores/i18n-store.ts new file mode 100644 index 000000000..ff94ada81 --- /dev/null +++ b/frontend/apps/cozeloop/src/stores/i18n-store.ts @@ -0,0 +1,33 @@ +// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates +// SPDX-License-Identifier: Apache-2.0 +import { create } from 'zustand'; +import { I18n } from '@cozeloop/i18n-adapter'; + +type I18nLang = 'zh-CN' | 'en-US'; + +interface I18nState { + lng: I18nLang; +} + +interface I18nAction { + setLng: (lng: string) => void; + toggleLng: () => void; + snapshot: () => I18nState; +} + +export const useI18nStore = create((set, get) => { + const setLng: I18nAction['setLng'] = (lang: string) => { + I18n.i18next.changeLanguage(lang, () => set({ lng: lang as I18nLang })); + }; + + return { + lng: I18n.lang as I18nLang, + setLng, + toggleLng: () => { + const target = get().lng === 'zh-CN' ? 'en-US' : 'zh-CN'; + + setLng(target); + }, + snapshot: () => get(), + }; +}); diff --git a/frontend/apps/cozeloop/src/stores/index.ts b/frontend/apps/cozeloop/src/stores/index.ts new file mode 100644 index 000000000..0923dcd38 --- /dev/null +++ b/frontend/apps/cozeloop/src/stores/index.ts @@ -0,0 +1,3 @@ +// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates +// SPDX-License-Identifier: Apache-2.0 +export { useI18nStore } from './i18n-store'; diff --git a/frontend/packages/cozeloop/i18n/package.json b/frontend/packages/cozeloop/i18n/package.json index cf667c9f0..a09ffe025 100644 --- a/frontend/packages/cozeloop/i18n/package.json +++ b/frontend/packages/cozeloop/i18n/package.json @@ -21,6 +21,7 @@ "@coze-arch/ts-config": "workspace:*", "@coze-arch/vitest-config": "workspace:*", "@formatjs/icu-messageformat-parser": "^2.11.2", + "@types/react": "18.2.37", "@vitest/coverage-v8": "~3.0.5", "react": "~18.2.0", "tsx": "^4.19.2", From 219f11c4e771b813ca33df0397daee0e3b3b53db Mon Sep 17 00:00:00 2001 From: qihai Date: Thu, 17 Jul 2025 16:13:28 +0800 Subject: [PATCH 09/30] feat: clean unused stories --- .../cozeloop/auth-pages/tsconfig.misc.json | 2 +- .../cozeloop/guard/tsconfig.misc.json | 2 +- .../observation-pages/tsconfig.misc.json | 2 +- .../trace-detail/.storybook/decorators.tsx | 105 ------------------ .../trace-detail/.storybook/main.js | 36 ------ .../trace-detail/.storybook/preview.ts | 19 ---- .../observation/trace-detail/scm_build.sh | 28 ----- .../trace-detail/stories/hello.mdx | 7 -- .../trace-detail/tsconfig.misc.json | 8 +- .../observation/trace-list/.storybook/main.js | 31 ------ .../trace-list/.storybook/preview.js | 14 --- .../trace-list/stories/demo.stories.tsx | 23 ---- .../observation/trace-list/stories/hello.mdx | 34 ------ .../observation/trace-list/tsconfig.misc.json | 2 +- .../trace-struct-data/.storybook/main.js | 31 ------ .../trace-struct-data/.storybook/preview.js | 14 --- .../stories/demo.stories.tsx | 23 ---- .../trace-struct-data/stories/hello.mdx | 34 ------ .../trace-struct-data/tsconfig.misc.json | 2 +- .../prompt-components/tsconfig.misc.json | 8 +- .../cozeloop/prompt-pages/tsconfig.misc.json | 2 +- 21 files changed, 8 insertions(+), 419 deletions(-) delete mode 100644 frontend/packages/cozeloop/observation/trace-detail/.storybook/decorators.tsx delete mode 100644 frontend/packages/cozeloop/observation/trace-detail/.storybook/main.js delete mode 100644 frontend/packages/cozeloop/observation/trace-detail/.storybook/preview.ts delete mode 100644 frontend/packages/cozeloop/observation/trace-detail/scm_build.sh delete mode 100644 frontend/packages/cozeloop/observation/trace-detail/stories/hello.mdx delete mode 100644 frontend/packages/cozeloop/observation/trace-list/.storybook/main.js delete mode 100644 frontend/packages/cozeloop/observation/trace-list/.storybook/preview.js delete mode 100644 frontend/packages/cozeloop/observation/trace-list/stories/demo.stories.tsx delete mode 100644 frontend/packages/cozeloop/observation/trace-list/stories/hello.mdx delete mode 100644 frontend/packages/cozeloop/observation/trace-struct-data/.storybook/main.js delete mode 100644 frontend/packages/cozeloop/observation/trace-struct-data/.storybook/preview.js delete mode 100644 frontend/packages/cozeloop/observation/trace-struct-data/stories/demo.stories.tsx delete mode 100644 frontend/packages/cozeloop/observation/trace-struct-data/stories/hello.mdx diff --git a/frontend/packages/cozeloop/auth-pages/tsconfig.misc.json b/frontend/packages/cozeloop/auth-pages/tsconfig.misc.json index 76fce28fb..69cde449f 100644 --- a/frontend/packages/cozeloop/auth-pages/tsconfig.misc.json +++ b/frontend/packages/cozeloop/auth-pages/tsconfig.misc.json @@ -13,7 +13,7 @@ "target": "ES2020", "moduleResolution": "bundler" }, - "include": ["__tests__", "vitest.config.ts", "stories"], + "include": ["__tests__", "vitest.config.ts"], "exclude": ["./dist"], "references": [ { diff --git a/frontend/packages/cozeloop/guard/tsconfig.misc.json b/frontend/packages/cozeloop/guard/tsconfig.misc.json index 7bc9c63e7..267b83c4f 100644 --- a/frontend/packages/cozeloop/guard/tsconfig.misc.json +++ b/frontend/packages/cozeloop/guard/tsconfig.misc.json @@ -10,7 +10,7 @@ "target": "ES2020", "moduleResolution": "bundler" }, - "include": ["__tests__", "vitest.config.ts", "stories"], + "include": ["__tests__", "vitest.config.ts"], "exclude": ["./dist"], "references": [ { diff --git a/frontend/packages/cozeloop/observation-pages/tsconfig.misc.json b/frontend/packages/cozeloop/observation-pages/tsconfig.misc.json index 76fce28fb..69cde449f 100644 --- a/frontend/packages/cozeloop/observation-pages/tsconfig.misc.json +++ b/frontend/packages/cozeloop/observation-pages/tsconfig.misc.json @@ -13,7 +13,7 @@ "target": "ES2020", "moduleResolution": "bundler" }, - "include": ["__tests__", "vitest.config.ts", "stories"], + "include": ["__tests__", "vitest.config.ts"], "exclude": ["./dist"], "references": [ { diff --git a/frontend/packages/cozeloop/observation/trace-detail/.storybook/decorators.tsx b/frontend/packages/cozeloop/observation/trace-detail/.storybook/decorators.tsx deleted file mode 100644 index b1f8e03ca..000000000 --- a/frontend/packages/cozeloop/observation/trace-detail/.storybook/decorators.tsx +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates -// SPDX-License-Identifier: Apache-2.0 -import { IconCozTransSwitch } from '@coze-arch/coze-design/icons'; -import { I18n, initIntl } from '@cozeloop/i18n-adapter'; -import { Dropdown, IconButton, Spin } from '@coze-arch/coze-design'; -import type { Preview } from '@storybook/react'; -import { useEffect, useState } from 'react'; - -const languages = [ - { - title: '中文', - value: 'zh-CN', - }, - { - title: 'English', - value: 'en-US', - }, -]; - -let hasInit = false; - -const I18nSwitchDropdown = () => { - const currentLang = languages.find( - lang => lang.value === I18n.language, - )?.title; - const handleSwitchLanguage = (lang: string) => { - I18n.setLang(lang); - location.reload(); - }; - return ( - - {languages.map(lang => ( - handleSwitchLanguage(lang.value)} - > - {lang.title} - - ))} - - } - > - }> - {currentLang} - - - ); -}; - -const useInitI18n = () => { - const [i18nStatus, setI18nStatus] = useState(false); - useEffect(() => { - if (!hasInit) { - initIntl({ - lng: 'zh-CN', - fallbackLng: ['zh-CN', 'en-US'], - thirdParamFallback: true, - }) - .then(() => { - setI18nStatus(true); - hasInit = true; - }) - .catch(err => { - setI18nStatus(false); - }); - } else { - setI18nStatus(true); - } - }, []); - - return { - i18nStatus, - }; -}; - -const decorators: Preview['decorators'] = [ - (Story, context) => { - const { i18nStatus } = useInitI18n(); - return i18nStatus ? ( - <> - {context.parameters.showI18nSwitch ? ( -
- -
- ) : null} - - - ) : ( - - ); - }, -]; - -export default decorators; diff --git a/frontend/packages/cozeloop/observation/trace-detail/.storybook/main.js b/frontend/packages/cozeloop/observation/trace-detail/.storybook/main.js deleted file mode 100644 index 0171ed078..000000000 --- a/frontend/packages/cozeloop/observation/trace-detail/.storybook/main.js +++ /dev/null @@ -1,36 +0,0 @@ -import { mergeConfig } from 'vite'; -import svgr from 'vite-plugin-svgr'; - -/** @type { import('@storybook/react-vite').StorybookConfig } */ -const config = { - stories: [ - '../stories/**/*.mdx', - '../stories/**/*.stories.tsx', - '../src/**/stories/*.stories.tsx', - '../src/**/stories/*.mdx', - ], - addons: [ - '@storybook/addon-links', - '@storybook/addon-essentials', - '@storybook/addon-onboarding', - '@storybook/addon-interactions', - ], - framework: { - name: '@storybook/react-vite', - options: {}, - }, - docs: { - autodocs: 'tag', - }, - viteFinal: config => - mergeConfig(config, { - plugins: [ - svgr({ - svgrOptions: { - native: false, - }, - }), - ], - }), -}; -export default config; diff --git a/frontend/packages/cozeloop/observation/trace-detail/.storybook/preview.ts b/frontend/packages/cozeloop/observation/trace-detail/.storybook/preview.ts deleted file mode 100644 index d4745d8bb..000000000 --- a/frontend/packages/cozeloop/observation/trace-detail/.storybook/preview.ts +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates -// SPDX-License-Identifier: Apache-2.0 -import type { Preview } from '@storybook/react'; -import decorators from './decorators'; - -const preview: Preview['parameters'] = { - decorators: decorators, - parameters: { - actions: { argTypesRegex: '^on[A-Z].*' }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, -}; - -export default preview; diff --git a/frontend/packages/cozeloop/observation/trace-detail/scm_build.sh b/frontend/packages/cozeloop/observation/trace-detail/scm_build.sh deleted file mode 100644 index 3e7ffa7d3..000000000 --- a/frontend/packages/cozeloop/observation/trace-detail/scm_build.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -# Switch cwd to the project folder -cd $(dirname "$0") - -# Import the utilities functions -source ../../../../scripts/scm_base.sh - -# Clean up the build directory -rm -rf output output_resource "${ROOT}"/output "${ROOT}"/output_resource - -# Prepare -prepare_environment - -# Install the dependencies -install_project_deps - -build_project - -npm run build:storybook - -mkdir -p "${ROOT_DIR}"/output -mkdir -p "${ROOT_DIR}"/output_resource - -cp -rf ./storybook-static/* "${ROOT_DIR}"/output/ -cp -rf ./storybook-static/* "${ROOT_DIR}"/output_resource/ diff --git a/frontend/packages/cozeloop/observation/trace-detail/stories/hello.mdx b/frontend/packages/cozeloop/observation/trace-detail/stories/hello.mdx deleted file mode 100644 index 8ef859c19..000000000 --- a/frontend/packages/cozeloop/observation/trace-detail/stories/hello.mdx +++ /dev/null @@ -1,7 +0,0 @@ -import { Meta } from '@storybook/blocks'; - - - -# Trace Components - -@cozeloop/observation-component-adapter diff --git a/frontend/packages/cozeloop/observation/trace-detail/tsconfig.misc.json b/frontend/packages/cozeloop/observation/trace-detail/tsconfig.misc.json index 53e222ea1..40408ae05 100644 --- a/frontend/packages/cozeloop/observation/trace-detail/tsconfig.misc.json +++ b/frontend/packages/cozeloop/observation/trace-detail/tsconfig.misc.json @@ -1,13 +1,7 @@ { "extends": "@coze-arch/ts-config/tsconfig.web.json", "$schema": "https://json.schemastore.org/tsconfig", - "include": [ - "__tests__", - "vitest.config.mts", - "tailwind.config.ts", - "stories", - ".storybook/*" - ], + "include": ["__tests__", "vitest.config.mts", "tailwind.config.ts"], "exclude": ["./dist"], "references": [ { diff --git a/frontend/packages/cozeloop/observation/trace-list/.storybook/main.js b/frontend/packages/cozeloop/observation/trace-list/.storybook/main.js deleted file mode 100644 index d5c408cbb..000000000 --- a/frontend/packages/cozeloop/observation/trace-list/.storybook/main.js +++ /dev/null @@ -1,31 +0,0 @@ -import { mergeConfig } from 'vite'; -import svgr from 'vite-plugin-svgr'; - -/** @type { import('@storybook/react-vite').StorybookConfig } */ -const config = { - stories: ['../stories/**/*.mdx', '../stories/**/*.stories.tsx'], - addons: [ - '@storybook/addon-links', - '@storybook/addon-essentials', - '@storybook/addon-onboarding', - '@storybook/addon-interactions', - ], - framework: { - name: '@storybook/react-vite', - options: {}, - }, - docs: { - autodocs: 'tag', - }, - viteFinal: config => - mergeConfig(config, { - plugins: [ - svgr({ - svgrOptions: { - native: false, - }, - }), - ], - }), -}; -export default config; diff --git a/frontend/packages/cozeloop/observation/trace-list/.storybook/preview.js b/frontend/packages/cozeloop/observation/trace-list/.storybook/preview.js deleted file mode 100644 index 1f07be963..000000000 --- a/frontend/packages/cozeloop/observation/trace-list/.storybook/preview.js +++ /dev/null @@ -1,14 +0,0 @@ -/** @type { import('@storybook/react').Preview } */ -const preview = { - parameters: { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, -}; - -export default preview; diff --git a/frontend/packages/cozeloop/observation/trace-list/stories/demo.stories.tsx b/frontend/packages/cozeloop/observation/trace-list/stories/demo.stories.tsx deleted file mode 100644 index b848cdfcb..000000000 --- a/frontend/packages/cozeloop/observation/trace-list/stories/demo.stories.tsx +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates -// SPDX-License-Identifier: Apache-2.0 -import { DemoComponent } from '../src'; - -export default { - title: 'Example/Demo', - component: DemoComponent, - parameters: { - // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout - layout: 'centered', - }, - // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs - tags: ['autodocs'], - // More on argTypes: https://storybook.js.org/docs/api/argtypes - argTypes: {}, -}; - -// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args -export const Base = { - args: { - name: 'tecvan', - }, -}; diff --git a/frontend/packages/cozeloop/observation/trace-list/stories/hello.mdx b/frontend/packages/cozeloop/observation/trace-list/stories/hello.mdx deleted file mode 100644 index 66edadc6d..000000000 --- a/frontend/packages/cozeloop/observation/trace-list/stories/hello.mdx +++ /dev/null @@ -1,34 +0,0 @@ -import { Meta } from "@storybook/blocks"; - - - -
-
- # Hello world - - Hello world -
-
- - diff --git a/frontend/packages/cozeloop/observation/trace-list/tsconfig.misc.json b/frontend/packages/cozeloop/observation/trace-list/tsconfig.misc.json index 7bc9c63e7..267b83c4f 100644 --- a/frontend/packages/cozeloop/observation/trace-list/tsconfig.misc.json +++ b/frontend/packages/cozeloop/observation/trace-list/tsconfig.misc.json @@ -10,7 +10,7 @@ "target": "ES2020", "moduleResolution": "bundler" }, - "include": ["__tests__", "vitest.config.ts", "stories"], + "include": ["__tests__", "vitest.config.ts"], "exclude": ["./dist"], "references": [ { diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/.storybook/main.js b/frontend/packages/cozeloop/observation/trace-struct-data/.storybook/main.js deleted file mode 100644 index d5c408cbb..000000000 --- a/frontend/packages/cozeloop/observation/trace-struct-data/.storybook/main.js +++ /dev/null @@ -1,31 +0,0 @@ -import { mergeConfig } from 'vite'; -import svgr from 'vite-plugin-svgr'; - -/** @type { import('@storybook/react-vite').StorybookConfig } */ -const config = { - stories: ['../stories/**/*.mdx', '../stories/**/*.stories.tsx'], - addons: [ - '@storybook/addon-links', - '@storybook/addon-essentials', - '@storybook/addon-onboarding', - '@storybook/addon-interactions', - ], - framework: { - name: '@storybook/react-vite', - options: {}, - }, - docs: { - autodocs: 'tag', - }, - viteFinal: config => - mergeConfig(config, { - plugins: [ - svgr({ - svgrOptions: { - native: false, - }, - }), - ], - }), -}; -export default config; diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/.storybook/preview.js b/frontend/packages/cozeloop/observation/trace-struct-data/.storybook/preview.js deleted file mode 100644 index 1f07be963..000000000 --- a/frontend/packages/cozeloop/observation/trace-struct-data/.storybook/preview.js +++ /dev/null @@ -1,14 +0,0 @@ -/** @type { import('@storybook/react').Preview } */ -const preview = { - parameters: { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, -}; - -export default preview; diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/stories/demo.stories.tsx b/frontend/packages/cozeloop/observation/trace-struct-data/stories/demo.stories.tsx deleted file mode 100644 index d1ad04c16..000000000 --- a/frontend/packages/cozeloop/observation/trace-struct-data/stories/demo.stories.tsx +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates -// SPDX-License-Identifier: Apache-2.0 -import { TraceStructData } from '../src'; - -export default { - title: 'TraceStructData', - component: TraceStructData, - parameters: { - // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout - layout: 'centered', - }, - // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs - tags: ['autodocs'], - // More on argTypes: https://storybook.js.org/docs/api/argtypes - argTypes: {}, -}; - -// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args -export const Base = { - args: { - name: 'tecvan', - }, -}; diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/stories/hello.mdx b/frontend/packages/cozeloop/observation/trace-struct-data/stories/hello.mdx deleted file mode 100644 index 66edadc6d..000000000 --- a/frontend/packages/cozeloop/observation/trace-struct-data/stories/hello.mdx +++ /dev/null @@ -1,34 +0,0 @@ -import { Meta } from "@storybook/blocks"; - - - -
-
- # Hello world - - Hello world -
-
- - diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/tsconfig.misc.json b/frontend/packages/cozeloop/observation/trace-struct-data/tsconfig.misc.json index f0d94b631..e56f732bb 100644 --- a/frontend/packages/cozeloop/observation/trace-struct-data/tsconfig.misc.json +++ b/frontend/packages/cozeloop/observation/trace-struct-data/tsconfig.misc.json @@ -10,7 +10,7 @@ "target": "ES2020", "moduleResolution": "bundler" }, - "include": ["__tests__", "vitest.config.ts", "stories", "tailwind.config.ts"], + "include": ["__tests__", "vitest.config.ts", "tailwind.config.ts"], "exclude": ["./dist"], "references": [ { diff --git a/frontend/packages/cozeloop/prompt-components/tsconfig.misc.json b/frontend/packages/cozeloop/prompt-components/tsconfig.misc.json index 53e222ea1..40408ae05 100644 --- a/frontend/packages/cozeloop/prompt-components/tsconfig.misc.json +++ b/frontend/packages/cozeloop/prompt-components/tsconfig.misc.json @@ -1,13 +1,7 @@ { "extends": "@coze-arch/ts-config/tsconfig.web.json", "$schema": "https://json.schemastore.org/tsconfig", - "include": [ - "__tests__", - "vitest.config.mts", - "tailwind.config.ts", - "stories", - ".storybook/*" - ], + "include": ["__tests__", "vitest.config.mts", "tailwind.config.ts"], "exclude": ["./dist"], "references": [ { diff --git a/frontend/packages/cozeloop/prompt-pages/tsconfig.misc.json b/frontend/packages/cozeloop/prompt-pages/tsconfig.misc.json index 76fce28fb..69cde449f 100644 --- a/frontend/packages/cozeloop/prompt-pages/tsconfig.misc.json +++ b/frontend/packages/cozeloop/prompt-pages/tsconfig.misc.json @@ -13,7 +13,7 @@ "target": "ES2020", "moduleResolution": "bundler" }, - "include": ["__tests__", "vitest.config.ts", "stories"], + "include": ["__tests__", "vitest.config.ts"], "exclude": ["./dist"], "references": [ { From 26db6e558342e851d04792334c4281738ebe39d2 Mon Sep 17 00:00:00 2001 From: qihai Date: Thu, 17 Jul 2025 17:09:47 +0800 Subject: [PATCH 10/30] feat: observation lng --- .../components/src/logic-expr/consts.ts | 4 +- .../src/logic-expr/expr-group-render.tsx | 4 +- .../components/src/logic-expr/expr-render.tsx | 2 +- .../components/src/logic-expr/logic-not.tsx | 2 +- .../cozeloop/i18n/src/locale-types.ts | 290 ++++++++++-------- .../biz/trace-detail/trace-error.tsx | 7 +- .../components/common/empty-status/index.tsx | 10 +- .../trace-detail/components/graphs/index.tsx | 2 +- .../graphs/trace-tree/node/index.tsx | 10 +- .../components/header/horizontal/index.tsx | 9 +- .../components/span-detail-list/index.tsx | 4 +- .../components/span-detail/field.tsx | 8 +- .../components/span-detail/index.tsx | 4 +- .../src/components/banner/index.tsx | 32 +- .../src/components/filter-bar/custom-view.tsx | 21 +- .../components/filter-bar/filter-select.tsx | 3 +- .../src/components/filter-bar/index.tsx | 11 +- .../src/components/filter-select-ui/index.tsx | 38 +-- .../src/components/logic-expr/consts.ts | 8 +- .../logic-expr/error-msg-render.tsx | 5 +- .../src/components/queries/table/index.tsx | 38 +-- .../src/components/table-cell-text/index.tsx | 3 +- .../trace-list/src/consts/filter.ts | 7 +- .../observation/trace-list/src/consts/time.ts | 60 ++-- .../src/hooks/use-fetch-meta-info.ts | 2 +- .../observation/trace-list/src/index.tsx | 13 +- .../src/components/image.tsx | 4 +- .../src/components/plain-text.tsx | 3 +- .../src/components/raw-content.tsx | 3 +- .../src/components/span-content-container.tsx | 8 +- .../src/components/span-field-render.tsx | 3 +- .../src/components/view-all.tsx | 5 +- .../src/span-definition/model/render.tsx | 2 +- .../loop-lng/src/locales/base/en-US.json | 2 +- .../loop-lng/src/locales/common/en-US.json | 1 + .../loop-lng/src/locales/common/zh-CN.json | 1 + .../resources/loop-lng/src/locales/en-US.json | 50 --- .../src/locales/observation/en-US.json | 72 ++++- .../src/locales/observation/zh-CN.json | 72 ++++- .../resources/loop-lng/src/locales/zh-CN.json | 50 --- 40 files changed, 487 insertions(+), 386 deletions(-) diff --git a/frontend/packages/cozeloop/components/src/logic-expr/consts.ts b/frontend/packages/cozeloop/components/src/logic-expr/consts.ts index 2e1c3a6fe..45ea5e192 100644 --- a/frontend/packages/cozeloop/components/src/logic-expr/consts.ts +++ b/frontend/packages/cozeloop/components/src/logic-expr/consts.ts @@ -1,6 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 export const LOGIC_OPTIONS = [ - { label: 'fornax_components_logic_expr_and', value: 'and' }, - { label: 'fornax_components_logic_expr_or', value: 'or' }, + { label: 'logic_expr_and', value: 'and' }, + { label: 'logic_expr_or', value: 'or' }, ]; diff --git a/frontend/packages/cozeloop/components/src/logic-expr/expr-group-render.tsx b/frontend/packages/cozeloop/components/src/logic-expr/expr-group-render.tsx index e549797c0..12b6f4cb6 100644 --- a/frontend/packages/cozeloop/components/src/logic-expr/expr-group-render.tsx +++ b/frontend/packages/cozeloop/components/src/logic-expr/expr-group-render.tsx @@ -95,7 +95,7 @@ export function ExprGroupRender({ type="primary" > - {I18n.t('fornax_components_logic_expr_add_filter')} + {I18n.t('logic_expr_add_filter')} {showAddGroupButton ? ( @@ -105,7 +105,7 @@ export function ExprGroupRender({ icon={} onClick={() => onAddGroup?.(path)} > - {I18n.t('fornax_components_logic_expr_add_filter_group')} + {I18n.t('logic_expr_add_filter_group')} ) : null} diff --git a/frontend/packages/cozeloop/components/src/logic-expr/expr-render.tsx b/frontend/packages/cozeloop/components/src/logic-expr/expr-render.tsx index eef15c1f1..e51a28ae6 100644 --- a/frontend/packages/cozeloop/components/src/logic-expr/expr-render.tsx +++ b/frontend/packages/cozeloop/components/src/logic-expr/expr-render.tsx @@ -192,7 +192,7 @@ export const ExprRender = ({ {isEdit ? ( - {I18n.t('fornax_components_logic_expr_not')} + {I18n.t('logic_expr_not')}
); } diff --git a/frontend/packages/cozeloop/i18n/src/locale-types.ts b/frontend/packages/cozeloop/i18n/src/locale-types.ts index 2f704d6f8..fd43652ae 100644 --- a/frontend/packages/cozeloop/i18n/src/locale-types.ts +++ b/frontend/packages/cozeloop/i18n/src/locale-types.ts @@ -13,41 +13,6 @@ export interface I18nWithInterpolation { /** string */ date: ReactNode; }; - /** 获取元数据信息失败:{msg} */ - fornax_analytics_fetch_meta_error: { - /** string */ - msg: ReactNode; - }; - /** 输入Tokens: {count} */ - fornax_analytics_input_tokens_count: { - /** string */ - count: ReactNode; - }; - /** 输出Tokens: {count} */ - fornax_analytics_output_tokens_count: { - /** string */ - count: ReactNode; - }; - /** 推理Tokens: {count} */ - fornax_analytics_reasoning_tokens_count: { - /** string */ - count: ReactNode; - }; - /** 过去 {count} 天 */ - fornax_analytics_time_last_days: { - /** string */ - count: ReactNode; - }; - /** 过去 {count} 小时 */ - fornax_analytics_time_last_hours: { - /** string */ - count: ReactNode; - }; - /** 过去{count}分钟 */ - fornax_analytics_time_last_minutes: { - /** string */ - count: ReactNode; - }; /** {field}已存在 */ field_exists: { /** string */ @@ -242,6 +207,11 @@ export interface I18nWithInterpolation { /** string */ num: ReactNode; }; + /** 请查看{manual}或尝试修改更大的时间范围,修改过滤器中的过滤条件 */ + trace_empty_tip: { + /** string */ + manual: ReactNode; + }; /** 最多展示{num}个视图 */ max_display_view_num: { /** string */ @@ -252,6 +222,46 @@ export interface I18nWithInterpolation { /** string */ num: ReactNode; }; + /** 了解数据是优化您应用的第一步,快点接入{sdk}上报数据吧,我保证这个操作真的很简单 */ + using_cozeloop_sdk_tip: { + /** string */ + sdk: ReactNode; + }; + /** 获取元数据信息失败:{msg} */ + observation_fetch_meta_error: { + /** string */ + msg: ReactNode; + }; + /** 输入Tokens: {count} */ + observation_input_tokens_count: { + /** string */ + count: ReactNode; + }; + /** 输出Tokens: {count} */ + observation_output_tokens_count: { + /** string */ + count: ReactNode; + }; + /** 推理Tokens: {count} */ + observation_reasoning_tokens_count: { + /** string */ + count: ReactNode; + }; + /** 过去 {count} 天 */ + observation_time_last_days: { + /** string */ + count: ReactNode; + }; + /** 过去 {count} 小时 */ + observation_time_last_hours: { + /** string */ + count: ReactNode; + }; + /** 过去{count}分钟 */ + observation_time_last_minutes: { + /** string */ + count: ReactNode; + }; } /** I18n keys without interpolation */ @@ -344,70 +354,6 @@ export type I18nKeysNoInterpolation = | 'expired_time_forbidden_1' /** 抱歉,发生了一些错误... */ | 'failed' - /** 收起 */ - | 'fornax_analytics_collapse' - /** 复制失败 */ - | 'fornax_analytics_copy_fail' - /** 复制成功 */ - | 'fornax_analytics_copy_success' - /** 暂无数据 */ - | 'fornax_analytics_data_empty' - /** 数据不存在或异常 */ - | 'fornax_analytics_empty_data_abnormal' - /** 未选中节点 */ - | 'fornax_analytics_empty_node_unselected' - /** 渲染失败 */ - | 'fornax_analytics_empty_run_tree_failure' - /** 请在左侧选中对应的节点查看详情 */ - | 'fornax_analytics_empty_to_select_node' - /** 展开 */ - | 'fornax_analytics_extend' - /** SpanID */ - | 'fornax_analytics_query_detail_span_id' - /** 本月截止目前 */ - | 'fornax_analytics_range_this_month' - /** StatusCode */ - | 'fornax_analytics_status_code' - /** 调用树 */ - | 'fornax_analytics_tab_run_tree' - /** 开发环境 */ - | 'fornax_analytics_threads_options_dev' - /** 失败 */ - | 'fornax_analytics_threads_options_fail' - /** 线上环境 */ - | 'fornax_analytics_threads_options_online' - /** 成功 */ - | 'fornax_analytics_threads_options_success' - /** 前天 */ - | 'fornax_analytics_time_day_before_yesterday' - /** 过去3月 */ - | 'fornax_analytics_time_past_3_months' - /** 过去一月 */ - | 'fornax_analytics_time_past_month' - /** 过去一周 */ - | 'fornax_analytics_time_past_week' - /** 过去一年 */ - | 'fornax_analytics_time_past_year' - /** 今天截止目前 */ - | 'fornax_analytics_time_today_so_far' - /** 本周截止目前 */ - | 'fornax_analytics_time_week_so_far' - /** 昨天 */ - | 'fornax_analytics_time_yesterday' - /** 节点详情 */ - | 'fornax_analytics_title_span_detail' - /** 添加筛选组条件 */ - | 'fornax_components_logic_expr_add_filter_group' - /** 添加筛选条件 */ - | 'fornax_components_logic_expr_add_filter' - /** 且 */ - | 'fornax_components_logic_expr_and' - /** 删除条件 */ - | 'fornax_components_logic_expr_delete_filter' - /** 非 */ - | 'fornax_components_logic_expr_not' - /** 或 */ - | 'fornax_components_logic_expr_or' /** go */ | 'go' /** 导入 */ @@ -491,28 +437,6 @@ export type I18nKeysNoInterpolation = | 'space' /** 成功 */ | 'Success' - /** 等于 */ - | 'task_filter_eq' - /** 大于 */ - | 'task_filter_gt' - /** 大于等于 */ - | 'task_filter_gte' - /** 属于 */ - | 'task_filter_in' - /** 为空 */ - | 'task_filter_is_null' - /** 包含 */ - | 'task_filter_like' - /** 小于 */ - | 'task_filter_lt' - /** 小于等于 */ - | 'task_filter_lte' - /** 不等于 */ - | 'task_filter_not_eq' - /** 不属于 */ - | 'task_filter_not_in' - /** 不为空 */ - | 'task_filter_not_null' /** 模板 */ | 'template_name' /** 文本 */ @@ -537,6 +461,8 @@ export type I18nKeysNoInterpolation = | 'Workflow' /** 账户 */ | 'account' + /** 应用 */ + | 'apply' /** 返回 */ | 'back' /** 清空 */ @@ -1329,6 +1255,8 @@ export type I18nKeysNoInterpolation = | 'no_permission_to_view_trace' /** 无权限查看 */ | 'no_permission_to_view' + /** 扣子罗盘 SDK 接入指南 */ + | 'cozeloop_sdk_manual' /** 未找到上报的数据 */ | 'reported_data_not_found' /** 请尝试在SDK数据上报时,写入Input和Output信息 */ @@ -1367,7 +1295,121 @@ export type I18nKeysNoInterpolation = | 'all_time' /** 不允许为空 */ | 'not_allowed_to_be_empty' - /** 视图名称已存在 */ - | 'view_name_exists' + /** 视图名称 */ + | 'view_name' /** TOS URL 不存在,请联系 Cozeloop */ - | 'tos_url_not_exist'; + | 'tos_url_not_exist' + /** 当前内容无法显示 */ + | 'current_content_unavailable' + /** 上一条 */ + | 'prev_item' + /** 下一条 */ + | 'next_item' + /** 扣子罗盘 SDK */ + | 'cozeloop_sdk' + /** 保存视图 */ + | 'save_view' + /** 另存为视图 */ + | 'save_as_view' + /** 保存至当前视图 */ + | 'save_to_current_view' + /** 自定义视图 */ + | 'custom_view' + /** 过滤器 */ + | 'filter' + /** 过滤项冲突 */ + | 'filter_item_conflict' + /** 查看全部 */ + | 'view_all' + /** 非法 JSON */ + | 'invalid_json' + /** 图片加载失败 */ + | 'image_load_failed' + /** 且 */ + | 'observation_and' + /** 收起 */ + | 'observation_collapse' + /** 复制失败 */ + | 'observation_copy_fail' + /** 复制成功 */ + | 'observation_copy_success' + /** 暂无数据 */ + | 'observation_data_empty' + /** 数据不存在或异常 */ + | 'observation_empty_data_abnormal' + /** 未选中节点 */ + | 'observation_empty_node_unselected' + /** 渲染失败 */ + | 'observation_empty_run_tree_failure' + /** 请在左侧选中对应的节点查看详情 */ + | 'observation_empty_to_select_node' + /** 展开 */ + | 'observation_extend' + /** SpanID */ + | 'observation_query_detail_span_id' + /** 本月截止目前 */ + | 'observation_range_this_month' + /** StatusCode */ + | 'observation_status_code' + /** 调用树 */ + | 'observation_tab_run_tree' + /** 开发环境 */ + | 'observation_threads_options_dev' + /** 失败 */ + | 'observation_threads_options_fail' + /** 线上环境 */ + | 'observation_threads_options_online' + /** 成功 */ + | 'observation_threads_options_success' + /** 前天 */ + | 'observation_time_day_before_yesterday' + /** 过去3月 */ + | 'observation_time_past_3_months' + /** 过去一月 */ + | 'observation_time_past_month' + /** 过去一周 */ + | 'observation_time_past_week' + /** 过去一年 */ + | 'observation_time_past_year' + /** 今天截止目前 */ + | 'observation_time_today_so_far' + /** 本周截止目前 */ + | 'observation_time_week_so_far' + /** 昨天 */ + | 'observation_time_yesterday' + /** 节点详情 */ + | 'observation_title_span_detail' + /** 添加筛选组条件 */ + | 'logic_expr_add_filter_group' + /** 添加筛选条件 */ + | 'logic_expr_add_filter' + /** 且 */ + | 'logic_expr_and' + /** 删除条件 */ + | 'logic_expr_delete_filter' + /** 非 */ + | 'logic_expr_not' + /** 或 */ + | 'logic_expr_or' + /** 等于 */ + | 'task_filter_eq' + /** 大于 */ + | 'task_filter_gt' + /** 大于等于 */ + | 'task_filter_gte' + /** 属于 */ + | 'task_filter_in' + /** 为空 */ + | 'task_filter_is_null' + /** 包含 */ + | 'task_filter_like' + /** 小于 */ + | 'task_filter_lt' + /** 小于等于 */ + | 'task_filter_lte' + /** 不等于 */ + | 'task_filter_not_eq' + /** 不属于 */ + | 'task_filter_not_in' + /** 不为空 */ + | 'task_filter_not_null'; diff --git a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/biz/trace-detail/trace-error.tsx b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/biz/trace-detail/trace-error.tsx index 44c6fd374..63b09549e 100644 --- a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/biz/trace-detail/trace-error.tsx +++ b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/biz/trace-detail/trace-error.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { IconCozIllusNone, IconCozIllusLock, @@ -16,15 +17,15 @@ export const getEmptyConfig = (statusCode: number) => { image: ( ), - description: '当前 Trace 已过期无法查看', + description: I18n.t('current_trace_expired_to_view'), }; default: return { image: ( ), - description: '当前的角色权限暂时无法查看该 Trace 详情', - title: '无权限查看', + description: I18n.t('no_permission_to_view_trace'), + title: I18n.t('no_permission_to_view'), }; } }; diff --git a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/common/empty-status/index.tsx b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/common/empty-status/index.tsx index a62bfaaf6..ea0dd831b 100644 --- a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/common/empty-status/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/common/empty-status/index.tsx @@ -1,18 +1,18 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { IconCozIllusEmpty, IconCozIllusError, } from '@coze-arch/coze-design/illustrations'; import { Empty } from '@coze-arch/coze-design'; -import { I18n } from '@cozeloop/i18n-adapter'; export const NodeDetailEmpty = () => ( } - title={I18n.t('fornax_analytics_empty_node_unselected')} - description={I18n.t('fornax_analytics_empty_to_select_node')} + title={I18n.t('observation_empty_node_unselected')} + description={I18n.t('observation_empty_to_select_node')} /> ); @@ -20,7 +20,7 @@ export const RunTreeEmpty = () => ( } - title={I18n.t('fornax_analytics_empty_run_tree_failure')} - description={I18n.t('fornax_analytics_empty_data_abnormal')} + title={I18n.t('observation_empty_run_tree_failure')} + description={I18n.t('observation_empty_data_abnormal')} /> ); diff --git a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/graphs/index.tsx b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/graphs/index.tsx index dbbc386b3..263741d6a 100644 --- a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/graphs/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/graphs/index.tsx @@ -60,7 +60,7 @@ export const TraceGraphs = ({ className={styles['trace-tabs']} > }> diff --git a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/graphs/trace-tree/node/index.tsx b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/graphs/trace-tree/node/index.tsx index 55dd4f74c..ccd5966b0 100644 --- a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/graphs/trace-tree/node/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/graphs/trace-tree/node/index.tsx @@ -100,8 +100,8 @@ export const CustomTreeNode = ({ theme="dark" content={ isCollapsed - ? I18n.t('fornax_analytics_extend') - : I18n.t('fornax_analytics_collapse') + ? I18n.t('observation_extend') + : I18n.t('observation_collapse') } position="right" > @@ -157,21 +157,21 @@ export const CustomTreeNode = ({ <> {input_tokens !== undefined && (
- {I18n.t('fornax_analytics_input_tokens_count', { + {I18n.t('observation_input_tokens_count', { count: Number(input_tokens), })}
)} {output_tokens !== undefined && (
- {I18n.t('fornax_analytics_output_tokens_count', { + {I18n.t('observation_output_tokens_count', { count: Number(output_tokens), })}
)} {reasoningTokens !== undefined && (
- {I18n.t('fornax_analytics_reasoning_tokens_count', { + {I18n.t('observation_reasoning_tokens_count', { count: Number(reasoningTokens), })}
diff --git a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/header/horizontal/index.tsx b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/header/horizontal/index.tsx index 3259ab939..d3c256c52 100644 --- a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/header/horizontal/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/header/horizontal/index.tsx @@ -20,6 +20,7 @@ import { import { type TraceHeaderProps } from '../typing'; import styles from './index.module.less'; +import { I18n } from '@cozeloop/i18n-adapter'; export const HorizontalTraceHeader = ({ rootSpan, @@ -83,10 +84,10 @@ export const HorizontalTraceHeader = ({ size="small" className="cursor-pointer coz-fg-primary text-[14px]" > - TraceID + {I18n.t('trace_id')} - + ) : null} diff --git a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/span-detail-list/index.tsx b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/span-detail-list/index.tsx index 516c47294..c8053c72c 100644 --- a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/span-detail-list/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/span-detail-list/index.tsx @@ -55,7 +55,7 @@ export const SpanFieldList = ({ ) : (
- {I18n.t('fornax_analytics_title_span_detail')} + {I18n.t('observation_title_span_detail')}
{input_tokens !== undefined && (
- {I18n.t('fornax_analytics_input_tokens_count', { + {I18n.t('observation_input_tokens_count', { count: Number(input_tokens), })}
)} {output_tokens !== undefined && (
- {I18n.t('fornax_analytics_output_tokens_count', { + {I18n.t('observation_output_tokens_count', { count: Number(output_tokens), })}
diff --git a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/span-detail/index.tsx b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/span-detail/index.tsx index 327e2f812..fe961fb92 100644 --- a/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/span-detail/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-detail/src/trace-detail/components/span-detail/index.tsx @@ -73,8 +73,8 @@ export const SpanDetail = ({ image={ } - title={'未找到上报的数据'} - description={'请尝试在SDK数据上报时,写入Input和Output信息'} + title={I18n.t('reported_data_not_found')} + description={I18n.t('report_in_sdk')} />
)} diff --git a/frontend/packages/cozeloop/observation/trace-list/src/components/banner/index.tsx b/frontend/packages/cozeloop/observation/trace-list/src/components/banner/index.tsx index f4c6c4243..61b2b4bf7 100644 --- a/frontend/packages/cozeloop/observation/trace-list/src/components/banner/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-list/src/components/banner/index.tsx @@ -1,8 +1,12 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 import { useLocalStorageState } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { useSpace, useUserInfo } from '@cozeloop/biz-hooks-adapter'; -import { IconCozInfoCircleFill, IconCozCross } from '@coze-arch/coze-design/icons'; +import { + IconCozInfoCircleFill, + IconCozCross, +} from '@coze-arch/coze-design/icons'; import { Typography, IconButton } from '@coze-arch/coze-design'; export const CozeLoopTraceBanner = () => { @@ -23,17 +27,21 @@ export const CozeLoopTraceBanner = () => {
- 了解数据是优化您应用的第一步,快点接入 - -  扣子罗盘 SDK  - - 上报数据吧,我保证这个操作真的很简单 + {I18n.t('using_cozeloop_sdk_tip', { + sdk: ( + + +  {I18n.t('cozeloop_sdk')}  + + + ), + })}
{ { setDeleteLoading(true); try { @@ -76,8 +77,8 @@ const ViewDelete = (props: ViewDeleteProps) => { } }} onCancel={() => setVisible(false)} - okText="确定" - cancelText="取消" + okText={I18n.t('confirm')} + cancelText={I18n.t('cancel')} visible={visible} trigger="custom" stopPropagation @@ -285,7 +286,7 @@ const CustomView = (props: CustomViewProps) => { !visibleViewIds.includes(view.id)) || templateShowView?.id === view.id } - content="最多展示 5 个视图" + content={I18n.t('max_display_view_num', { num: 5 })} >
)} @@ -357,7 +358,7 @@ const CustomView = (props: CustomViewProps) => { triggerRender={
@@ -385,7 +386,7 @@ const CustomView = (props: CustomViewProps) => {
@@ -405,7 +406,7 @@ const CustomView = (props: CustomViewProps) => { onClick={() => setViewListVisible(true)} > - 自定义视图 + {I18n.t('custom_view')} diff --git a/frontend/packages/cozeloop/observation/trace-list/src/components/filter-bar/filter-select.tsx b/frontend/packages/cozeloop/observation/trace-list/src/components/filter-bar/filter-select.tsx index 5604bc159..cdb635c68 100644 --- a/frontend/packages/cozeloop/observation/trace-list/src/components/filter-bar/filter-select.tsx +++ b/frontend/packages/cozeloop/observation/trace-list/src/components/filter-bar/filter-select.tsx @@ -23,6 +23,7 @@ import { } from '../logic-expr/logic-expr'; import { validateViewName } from '../../utils/name-validate'; import type { View } from './custom-view'; +import { I18n } from '@cozeloop/i18n-adapter'; interface FilterSelectProps { viewList: View[]; @@ -104,7 +105,7 @@ export const FilterSelect = (props: FilterSelectProps) => { }); if (viewList.length > 5) { - Toast.warning('新视图无法展示, 请修改视图展示管理'); + Toast.warning(I18n.t('new_view_cannot_be_displayed')); } setFilterPopupVisible(false); setApplyFilters(params.filters); diff --git a/frontend/packages/cozeloop/observation/trace-list/src/components/filter-bar/index.tsx b/frontend/packages/cozeloop/observation/trace-list/src/components/filter-bar/index.tsx index 02e77da2f..12d97b5b2 100644 --- a/frontend/packages/cozeloop/observation/trace-list/src/components/filter-bar/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-list/src/components/filter-bar/index.tsx @@ -4,10 +4,15 @@ /* eslint-disable @coze-arch/max-line-per-function */ import { forwardRef } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { ColumnSelector, type ColumnItem } from '@cozeloop/components'; import { PlatformType, SpanListType } from '@cozeloop/api-schema/observation'; import { IconCozRefresh } from '@coze-arch/coze-design/icons'; -import { Button, InputGroup, type DatePickerProps } from '@coze-arch/coze-design'; +import { + Button, + InputGroup, + type DatePickerProps, +} from '@coze-arch/coze-design'; import { type ConvertSpan } from '@/typings/span'; import { type SizedColumn } from '@/typings/index'; @@ -245,8 +250,8 @@ export const QueryFilterBar = forwardRef< {headerSlot} diff --git a/frontend/packages/cozeloop/observation/trace-list/src/components/filter-select-ui/index.tsx b/frontend/packages/cozeloop/observation/trace-list/src/components/filter-select-ui/index.tsx index d8cb1c888..77d202c51 100644 --- a/frontend/packages/cozeloop/observation/trace-list/src/components/filter-select-ui/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-list/src/components/filter-select-ui/index.tsx @@ -150,7 +150,7 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { refreshDeps: [localDataSource, localViewMethod], onError(e) { Toast.error( - I18n.t('fornax_analytics_fetch_meta_error', { + I18n.t('observation_fetch_meta_error', { msg: e.message || '', }), ); @@ -187,13 +187,13 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { <>
@@ -208,13 +208,13 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => {
@@ -232,10 +232,10 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { const renderSaveView = () => (
-
视图名称
+
{I18n.t('view_name')}
{ const trimValue = value.trim(); @@ -263,7 +263,7 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { setSaveViewVisible(false); }} > - 取消 + {I18n.t('cancel')}
@@ -327,12 +327,12 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => {
- 过滤器 + {I18n.t('filter')}
@@ -344,7 +344,7 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { setLocalFilters({}); }} > - 清空筛选 + {I18n.t('clear')}
{ 'calc((100% - ((100% - 80px) / 2) - 16px) / 2 + (100% - 80px) / 2 - 14px)', }} > - 且 + {I18n.t('observation_and')}
@@ -439,7 +439,7 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { }); }} > - 保存至当前视图 + {I18n.t('save_to_current_view')} { setSaveViewNameVisible(true); }} > - 另存为视图 + {I18n.t('save_as_view')} @@ -481,7 +481,7 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { }} >
- 保存视图 + {I18n.t('save_view')}
@@ -508,7 +508,7 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { setSaveViewNameVisible(true); }} > - 保存视图 + {I18n.t('save_view')} )} @@ -520,7 +520,7 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { onClick={handleApply} disabled={disableApply} > - 应用 + {I18n.t('apply')} )} @@ -545,7 +545,7 @@ export const FilterSelectUI = (props: FilterSelectUIProps) => { >
-
过滤器
+
{I18n.t('filter')}
> = { success: { - label: I18n.t('fornax_analytics_threads_options_success'), + label: I18n.t('observation_threads_options_success'), }, error: { - label: I18n.t('fornax_analytics_threads_options_fail'), + label: I18n.t('observation_threads_options_fail'), }, }; @@ -133,9 +133,9 @@ export const BOT_ENV_RECORDS: Partial< > > = { [BotEnv.DEV]: { - label: I18n.t('fornax_analytics_threads_options_dev'), + label: I18n.t('observation_threads_options_dev'), }, [BotEnv.ONLINE]: { - label: I18n.t('fornax_analytics_threads_options_online'), + label: I18n.t('observation_threads_options_online'), }, }; diff --git a/frontend/packages/cozeloop/observation/trace-list/src/components/logic-expr/error-msg-render.tsx b/frontend/packages/cozeloop/observation/trace-list/src/components/logic-expr/error-msg-render.tsx index 929b0c461..fdd794f7c 100644 --- a/frontend/packages/cozeloop/observation/trace-list/src/components/logic-expr/error-msg-render.tsx +++ b/frontend/packages/cozeloop/observation/trace-list/src/components/logic-expr/error-msg-render.tsx @@ -3,6 +3,7 @@ import { type OptionProps } from '@coze-arch/coze-design'; import { checkValueIsEmpty } from './right-render'; +import { I18n } from '@cozeloop/i18n-adapter'; interface ErrorMsgRenderProps { expr: { @@ -28,7 +29,7 @@ export const ErrorMsgRender = ({ if (isInvalidateExpr) { return (
- {leftname ?? left} 过滤项冲突 + {leftname ?? left} {I18n.t('filter_item_conflict')}
); } @@ -36,7 +37,7 @@ export const ErrorMsgRender = ({ if (checkValueIsEmpty(right) && left && valueChangeMap[left]) { return (
- 不允许为空 + {I18n.t('not_allowed_to_be_empty')}
); } diff --git a/frontend/packages/cozeloop/observation/trace-list/src/components/queries/table/index.tsx b/frontend/packages/cozeloop/observation/trace-list/src/components/queries/table/index.tsx index a7856ad8d..de7456626 100644 --- a/frontend/packages/cozeloop/observation/trace-list/src/components/queries/table/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-list/src/components/queries/table/index.tsx @@ -249,31 +249,27 @@ export const QueryTable = ({ } - title={I18n.t('fornax_analytics_data_empty')} + title={I18n.t('observation_data_empty')} description={
{traceListCode === TRACE_EXPIRED_CODE ? ( - 当前Trace已过期无法查看 + {I18n.t('current_trace_expired_to_view')} ) : ( - <> - {selectedPlatform === 'cozeloop' && ( - <> - 请查看 - - -  扣子罗盘 SDK 接入指南;  - - - 或 - - )} - 尝试修改更大的时间范围,修改过滤器中的过滤条件 - + selectedPlatform === 'cozeloop' && + I18n.t('trace_empty_tip', { + manual: ( + + +  {I18n.t('cozeloop_sdk_manual')}  + + + ), + }) )}
} diff --git a/frontend/packages/cozeloop/observation/trace-list/src/components/table-cell-text/index.tsx b/frontend/packages/cozeloop/observation/trace-list/src/components/table-cell-text/index.tsx index 667485ef7..e2326b92e 100644 --- a/frontend/packages/cozeloop/observation/trace-list/src/components/table-cell-text/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-list/src/components/table-cell-text/index.tsx @@ -7,6 +7,7 @@ import { type MouseEvent, } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { handleCopy as copy } from '@cozeloop/components'; import { IconCozCopy } from '@coze-arch/coze-design/icons'; import { type PopoverProps, type TooltipProps } from '@coze-arch/coze-design'; @@ -69,7 +70,7 @@ export const CustomTableTooltip = ({ {children !== undefined ? children : '-'} {enableCopy ? ( - + new Date(), }, [PresetRange.Min5]: { - text: I18n.t('fornax_analytics_time_last_minutes', { + text: I18n.t('observation_time_last_minutes', { count: 5, }), start: () => new Date(new Date().valueOf() - 1000 * 60 * 5), end: () => new Date(), }, [PresetRange.Min15]: { - text: I18n.t('fornax_analytics_time_last_minutes', { + text: I18n.t('observation_time_last_minutes', { count: 15, }), start: () => new Date(new Date().valueOf() - 1000 * 60 * 15), end: () => new Date(), }, [PresetRange.Min30]: { - text: I18n.t('fornax_analytics_time_last_minutes', { + text: I18n.t('observation_time_last_minutes', { count: 30, }), start: () => new Date(new Date().valueOf() - 1000 * 60 * 30), end: () => new Date(), }, [PresetRange.Hour1]: { - text: I18n.t('fornax_analytics_time_last_hours', { + text: I18n.t('observation_time_last_hours', { count: 1, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 1), end: () => new Date(), }, [PresetRange.Hour2]: { - text: I18n.t('fornax_analytics_time_last_hours', { + text: I18n.t('observation_time_last_hours', { count: 2, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 2), end: () => new Date(), }, [PresetRange.Hour3]: { - text: I18n.t('fornax_analytics_time_last_hours', { + text: I18n.t('observation_time_last_hours', { count: 3, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 3), end: () => new Date(), }, [PresetRange.Hour6]: { - text: I18n.t('fornax_analytics_time_last_hours', { + text: I18n.t('observation_time_last_hours', { count: 6, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 6), end: () => new Date(), }, [PresetRange.Hour12]: { - text: I18n.t('fornax_analytics_time_last_hours', { + text: I18n.t('observation_time_last_hours', { count: 12, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 12), end: () => new Date(), }, [PresetRange.Hour24]: { - text: I18n.t('fornax_analytics_time_last_hours', { + text: I18n.t('observation_time_last_hours', { count: 24, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 24), end: () => new Date(), }, [PresetRange.Day1]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 1, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 24), end: () => new Date(), }, [PresetRange.Day2]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 2, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 24 * 2), end: () => new Date(), }, [PresetRange.Day3]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 3, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 24 * 3), end: () => new Date(), }, [PresetRange.Day5]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 5, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 24 * 5), end: () => new Date(), }, [PresetRange.Day7]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 7, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 24 * 7), end: () => new Date(), }, [PresetRange.Day15]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 15, }), start: () => new Date(new Date().valueOf() - 1000 * 3600 * 24 * 15), end: () => new Date(), }, [PresetRange.Month1]: { - text: I18n.t('fornax_analytics_time_past_month'), + text: I18n.t('observation_time_past_month'), start: () => dayjs().subtract(1, 'month').toDate(), end: () => dayjs().toDate(), }, [PresetRange.Month3]: { - text: I18n.t('fornax_analytics_time_past_3_months'), + text: I18n.t('observation_time_past_3_months'), start: () => dayjs().subtract(3, 'month').toDate(), end: () => dayjs().toDate(), }, [PresetRange.DayToNow]: { - text: I18n.t('fornax_analytics_time_today_so_far'), + text: I18n.t('observation_time_today_so_far'), start: () => getDateAtZeroClock(new Date()), end: () => new Date(), }, [PresetRange.Yesterday]: { - text: I18n.t('fornax_analytics_time_yesterday'), + text: I18n.t('observation_time_yesterday'), start: () => getDateAtZeroClock(new Date(new Date().valueOf() - 1000 * 3600 * 24)), end: () => getDateAtZeroClock(new Date()), }, [PresetRange.BeforeYesterday]: { - text: I18n.t('fornax_analytics_time_day_before_yesterday'), + text: I18n.t('observation_time_day_before_yesterday'), start: () => getDateAtZeroClock(new Date(new Date().valueOf() - 1000 * 3600 * 24 * 2)), end: () => getDateAtZeroClock(new Date(new Date().valueOf() - 1000 * 3600 * 24)), }, [PresetRange.WeekToNow]: { - text: I18n.t('fornax_analytics_time_week_so_far'), + text: I18n.t('observation_time_week_so_far'), start: () => { const now = new Date(); const day = now.getDay(); @@ -202,55 +202,55 @@ export const timePickerPresets = { end: () => new Date(), }, [PresetRange.YesterdayExcludeToday]: { - text: I18n.t('fornax_analytics_time_yesterday'), + text: I18n.t('observation_time_yesterday'), start: () => getDateAtZeroClock(new Date(new Date().valueOf() - 1000 * 3600 * 24)), end: () => getDayjsEndOfYesterday().toDate(), }, [PresetRange.PastWeek]: { - text: I18n.t('fornax_analytics_time_past_week'), + text: I18n.t('observation_time_past_week'), start: () => getDayjsStartOfToday().subtract(7, 'day').toDate(), end: () => getDayjsEndOfYesterday().toDate(), }, [PresetRange.PastMonth]: { - text: I18n.t('fornax_analytics_time_past_month'), + text: I18n.t('observation_time_past_month'), start: () => getDayjsStartOfToday().subtract(1, 'month').toDate(), end: () => getDayjsEndOfYesterday().toDate(), }, [PresetRange.PastYear]: { - text: I18n.t('fornax_analytics_time_past_year'), + text: I18n.t('observation_time_past_year'), start: () => getDayjsStartOfToday().subtract(1, 'year').toDate(), end: () => getDayjsEndOfYesterday().toDate(), }, [PresetRange.MonthToNow]: { - text: I18n.t('fornax_analytics_range_this_month'), + text: I18n.t('observation_range_this_month'), start: () => dayjs().startOf('month').toDate(), end: () => dayjs().toDate(), }, [PresetRange.Day30]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 30, }), start: () => dayjs().subtract(30, 'd').toDate(), end: () => dayjs().toDate(), }, [PresetRange.Day90]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 90, }), start: () => dayjs().subtract(90, 'd').toDate(), end: () => dayjs().toDate(), }, [PresetRange.Day180]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 180, }), start: () => dayjs().subtract(180, 'd').toDate(), end: () => dayjs().toDate(), }, [PresetRange.Day365]: { - text: I18n.t('fornax_analytics_time_last_days', { + text: I18n.t('observation_time_last_days', { count: 365, }), start: () => dayjs().subtract(365, 'd').toDate(), diff --git a/frontend/packages/cozeloop/observation/trace-list/src/hooks/use-fetch-meta-info.ts b/frontend/packages/cozeloop/observation/trace-list/src/hooks/use-fetch-meta-info.ts index 4fb10508d..2f66eaf59 100644 --- a/frontend/packages/cozeloop/observation/trace-list/src/hooks/use-fetch-meta-info.ts +++ b/frontend/packages/cozeloop/observation/trace-list/src/hooks/use-fetch-meta-info.ts @@ -33,7 +33,7 @@ export const useFetchMetaInfo = () => { refreshDeps: [selectedPlatform, selectedSpanType], onError(e) { Toast.error( - I18n.t('fornax_analytics_fetch_meta_error', { + I18n.t('observation_fetch_meta_error', { msg: e.message || '', }), ); diff --git a/frontend/packages/cozeloop/observation/trace-list/src/index.tsx b/frontend/packages/cozeloop/observation/trace-list/src/index.tsx index 7ce4a6723..b5315ac18 100644 --- a/frontend/packages/cozeloop/observation/trace-list/src/index.tsx +++ b/frontend/packages/cozeloop/observation/trace-list/src/index.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { PrimaryPage } from '@cozeloop/components'; import { useTraceTimeRangeOptions } from '@/hooks/use-trace-time-range-options'; @@ -19,11 +20,11 @@ import { Queries } from './components/queries'; import { QueryFilterBar } from './components/filter-bar'; import { CozeLoopTraceBanner } from './components/banner'; -const TOOLTIP_CONTENT = { - all_span: '查询所有 SpanID,以上报埋点为粒度进行展示', - root_span: '根据 TraceID 查询,以调用入口为粒度进行展示', - llm_span: '仅查询和模型调用相关的埋点', -}; +const getTooltipContent = () => ({ + all_span: I18n.t('all_span_tip'), + root_span: I18n.t('root_span_tip'), + llm_span: I18n.t('llm_span_tip'), +}); const TraceListApp = () => { usePageStay(); @@ -60,7 +61,7 @@ const TraceListApp = () => { onColumnsChange={onColumnsChange} platformEnumOptionList={PLATFORM_ENUM_OPTION_LIST} spanListTypeEnumOptionList={SPAN_TAB_OPTION_LIST} - tooltipContent={TOOLTIP_CONTENT} + tooltipContent={getTooltipContent()} /> } className="!pb-0" diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/image.tsx b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/image.tsx index dacbf1cde..061041e65 100644 --- a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/image.tsx +++ b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/image.tsx @@ -1,8 +1,8 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { IconCozCrossCircleFill } from '@coze-arch/coze-design/icons'; import { Image, Tooltip, Tag } from '@coze-arch/coze-design'; -import { I18n } from '@cozeloop/i18n-adapter'; import { useFetchResource } from '../hooks/use-fetch-resource'; @@ -16,7 +16,7 @@ export const TraceImage = ({ url }: { url: string }) => { - 图片加载失败 + {I18n.t('image_load_failed')}
diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/plain-text.tsx b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/plain-text.tsx index 51a6b9286..c5703502d 100644 --- a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/plain-text.tsx +++ b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/plain-text.tsx @@ -3,6 +3,7 @@ import { isObject } from 'lodash-es'; import classNames from 'classnames'; import { JsonViewer, type JsonViewerProps } from '@textea/json-viewer'; +import { I18n } from '@cozeloop/i18n-adapter'; import { Tag } from '@coze-arch/coze-design'; import { JSON_VIEW_CONFIG } from '../consts/json-view'; @@ -34,7 +35,7 @@ export const renderJsonContent = ( ) : ( <> - 非法JSON + {I18n.t('invalid_json')} diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/raw-content.tsx b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/raw-content.tsx index 2292b827b..962c5de69 100644 --- a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/raw-content.tsx +++ b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/raw-content.tsx @@ -19,6 +19,7 @@ import { JSON_VIEW_CONFIG } from '../consts/json-view'; import { ViewAllModal } from './view-all'; import styles from './index.module.less'; +import { I18n } from '@cozeloop/i18n-adapter'; interface RawContentProps { structuredContent: string | object; tagType?: TagType; @@ -77,7 +78,7 @@ export const RawContent: React.FC = ({ className="!text-[rgb(var(--coze-up-brand-9))] text-xs leading-4 font-medium cursor-pointer" onClick={handleViewAll} > - 查看全部 + {I18n.t('view_all')}
) : null} diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/span-content-container.tsx b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/span-content-container.tsx index 4243baecc..7265a6002 100644 --- a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/span-content-container.tsx +++ b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/span-content-container.tsx @@ -5,6 +5,7 @@ import { useEffect, useState } from 'react'; import { isObject } from 'lodash-es'; import classNames from 'classnames'; import { type JsonViewerProps } from '@textea/json-viewer'; +import { I18n } from '@cozeloop/i18n-adapter'; import { handleCopy as copy } from '@cozeloop/components'; import { IconCozCopy, IconCozCorner } from '@coze-arch/coze-design/icons'; import { Button, SegmentTab, Tooltip } from '@coze-arch/coze-design'; @@ -82,7 +83,7 @@ export const SpanContentContainer = (props: SpanContentContainerProps) => {
{title} {structuredContent ? ( - +
) : null} diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/view-all.tsx b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/view-all.tsx index 648f0d41b..60132bcc0 100644 --- a/frontend/packages/cozeloop/observation/trace-struct-data/src/components/view-all.tsx +++ b/frontend/packages/cozeloop/observation/trace-struct-data/src/components/view-all.tsx @@ -10,6 +10,7 @@ import { Button, Divider, Spin, Typography, Empty } from '@coze-arch/coze-design import { TagType, type Span } from '../types'; import { useFetchResource } from '../hooks/use-fetch-resource'; +import { I18n } from '@cozeloop/i18n-adapter'; interface ViewAllProps { onViewAllClick: (show: boolean) => void; @@ -95,8 +96,8 @@ const InputOrOutputTextRender = (props: InputOrOutputTextProps) => { return ( } /> diff --git a/frontend/packages/cozeloop/observation/trace-struct-data/src/span-definition/model/render.tsx b/frontend/packages/cozeloop/observation/trace-struct-data/src/span-definition/model/render.tsx index 603fd65b1..c638b3bd9 100644 --- a/frontend/packages/cozeloop/observation/trace-struct-data/src/span-definition/model/render.tsx +++ b/frontend/packages/cozeloop/observation/trace-struct-data/src/span-definition/model/render.tsx @@ -65,7 +65,7 @@ const ModelTool = (tool?: Tool) => { {raw?.function?.name} - +
diff --git a/frontend/packages/cozeloop/prompt-pages/src/components/prompt-header/index.tsx b/frontend/packages/cozeloop/prompt-pages/src/components/prompt-header/index.tsx index 066733c0d..c28fecb55 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/components/prompt-header/index.tsx +++ b/frontend/packages/cozeloop/prompt-pages/src/components/prompt-header/index.tsx @@ -14,6 +14,7 @@ import { getPlaceholderErrorContent, PromptCreate, } from '@cozeloop/prompt-components'; +import { I18n } from '@cozeloop/i18n-adapter'; import { EditIconButton, getBaseUrl, @@ -178,7 +179,7 @@ export function PromptHeader() { loading={versionChangeLoading} disabled={streaming} > - 返回草稿版本 + {I18n.t('revert_draft_version')} ); } @@ -190,7 +191,9 @@ export function PromptHeader() { return ( - 提交新版本 + {I18n.t('submit_new_version')} ); @@ -263,11 +266,11 @@ export function PromptHeader() { className="!py-0.5" prefixIcon={} > - 草稿保存中... + {I18n.t('draft_saving')} ) : ( - 草稿已自动保存于 + {I18n.t('draft_auto_saved_in')} {promptInfo?.prompt_draft?.draft_info?.updated_at ? convertDisplayTime( promptInfo?.prompt_draft?.draft_info?.updated_at, @@ -315,7 +318,7 @@ export function PromptHeader() { @@ -328,14 +331,16 @@ export function PromptHeader() { color={isDraftEdit ? 'yellow' : 'brand'} className="!py-0.5" > - {isDraftEdit ? '修改未提交' : '已提交'} + {isDraftEdit + ? I18n.t('modify_not_submitted') + : I18n.t('submitted')} ) : ( - 修改未提交 + {I18n.t('modify_not_submitted')} )} {autoSaving ? ( @@ -344,11 +349,11 @@ export function PromptHeader() { className="!py-0.5" prefixIcon={} > - 草稿保存中... + {I18n.t('draft_saving')} ) : isDraftEdit ? ( - 草稿已自动保存于 + {I18n.t('draft_auto_saved_in')} {promptInfo?.prompt_draft?.draft_info?.updated_at || promptInfo?.prompt_commit?.commit_info?.committed_at ? convertDisplayTime( @@ -384,7 +389,7 @@ export function PromptHeader() { icon={} disabled={streaming || versionChangeLoading || readonly} > - 进入自由对比模式 + {I18n.t('enter_free_comparison_mode')} {promptInfo?.prompt_key ? ( ) : null} {promptInfo?.prompt_key ? null : ( @@ -424,7 +429,7 @@ export function PromptHeader() { }} disabled={hasPlaceholderError || streaming} > - 快捷创建 + {I18n.t('quick_create')} )} @@ -441,7 +446,7 @@ export function PromptHeader() { className="!px-2" onClick={() => setExecuteHistoryVisible(true)} > - 调试历史 + {I18n.t('debug_history')} {readonly ? ( - 创建副本 + {I18n.t('create_copy')} ) : null} onDeletePrompt(promptInfo)} disabled={streaming} > - 删除 + + {I18n.t('delete')} + } @@ -483,7 +490,7 @@ export function PromptHeader() { icon={} disabled={streaming} > - 退出自由对比模式 + {I18n.t('exit_free_comparison_mode')} )} diff --git a/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/diff-content.tsx b/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/diff-content.tsx index 53ecc310f..45ad2665c 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/diff-content.tsx +++ b/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/diff-content.tsx @@ -10,6 +10,7 @@ import { type ReactNode, useMemo } from 'react'; import { isEqual } from 'lodash-es'; import { useRequest } from 'ahooks'; import { PromptDiffEditor } from '@cozeloop/prompt-components'; +import { I18n } from '@cozeloop/i18n-adapter'; import { useSpace } from '@cozeloop/biz-hooks-adapter'; import { type Prompt, ToolChoiceType } from '@cozeloop/api-schema/prompt'; import { Scenario } from '@cozeloop/api-schema/llm-manage'; @@ -96,7 +97,7 @@ export function DiffContent({ }; addDiffItem( - '模型 ID', + I18n.t('model_id'), baseItem.modelConfig?.model_id, currentItem.modelConfig?.model_id, ); @@ -109,21 +110,25 @@ export function DiffContent({ ); if (baseModel?.name !== currentModel?.name) { - addDiffItem('模型名称', baseModel?.name || '', currentModel?.name || ''); + addDiffItem( + I18n.t('model_name'), + baseModel?.name || '', + currentModel?.name || '', + ); } addDiffItem( - '生成随机性', + I18n.t('temperature'), baseItem.modelConfig?.temperature, currentItem.modelConfig?.temperature, ); addDiffItem( - '最大回复长度', + I18n.t('max_tokens'), baseItem.modelConfig?.max_tokens, currentItem.modelConfig?.max_tokens, ); addDiffItem( - 'Top P', + I18n.t('top_p'), baseItem.modelConfig?.top_p, currentItem.modelConfig?.top_p, ); @@ -155,7 +160,7 @@ export function DiffContent({ key: item.key || '', value: (
- 删除 + {I18n.t('delete')} {item.key} @@ -169,7 +174,7 @@ export function DiffContent({ key: item.key || '', value: (
- 新增 + {I18n.t('add')} {item.key} @@ -193,7 +198,7 @@ export function DiffContent({ } darkModeIcon={} - title="本次提交无版本差异" + title={I18n.t('submission_no_version_diff')} />
); @@ -202,7 +207,9 @@ export function DiffContent({
{modelDiffData.length ? (
- 模型设置 + + {I18n.t('model_config')} +
{modelDiffData.map(it => (
@@ -215,7 +222,7 @@ export function DiffContent({ {!templateIsSame ? (
- Prompt 模板 + {I18n.t('prompt_template')}
@@ -231,7 +238,7 @@ export function DiffContent({ size="small" strong > - 草稿 + {I18n.t('draft')}
@@ -263,7 +270,9 @@ export function DiffContent({ ) : null} {variabdlesDiffData.length ? (
- 变量设置 + + {I18n.t('variable_setting')} +
{variabdlesDiffData.map(it => (
@@ -275,22 +284,24 @@ export function DiffContent({ ) : null} {!toolCallConfigIsSame || !toolsIsSame ? (
- 函数 + + {I18n.t('function')} + {toolCallConfigIsSame ? null : (
- 函数 + {I18n.t('function')} {baseItem.toolCallConfig?.tool_choice === ToolChoiceType.Auto - ? '打开 启用函数' - : '关闭 启用函数'} + ? I18n.t('open_enable_function') + : I18n.t('close_enable_function')} {currentItem.toolCallConfig?.tool_choice === ToolChoiceType.Auto - ? '打开 启用函数' - : '关闭 启用函数'} + ? I18n.t('open_enable_function') + : I18n.t('close_enable_function')}
@@ -311,7 +322,7 @@ export function DiffContent({ size="small" strong > - 草稿 + {I18n.t('draft')}
diff --git a/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/index.tsx b/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/index.tsx index e8215d747..da5a059f5 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/index.tsx +++ b/frontend/packages/cozeloop/prompt-pages/src/components/prompt-submit/index.tsx @@ -10,6 +10,7 @@ import { useShallow } from 'zustand/react/shallow'; import classNames from 'classnames'; import { useRequest } from 'ahooks'; import { EVENT_NAMES, sendEvent } from '@cozeloop/tea-adapter'; +import { I18n } from '@cozeloop/i18n-adapter'; import { getBaseUrl } from '@cozeloop/components'; import { useSpace } from '@cozeloop/biz-hooks-adapter'; import { type Prompt } from '@cozeloop/api-schema/prompt'; @@ -78,7 +79,7 @@ export function PromptSubmit({ const showSuccessModal = () => { const modal = Modal.info({ - title: '提交新版本', + title: I18n.t('submit_new_version'), width: 960, closable: true, content: ( @@ -88,13 +89,13 @@ export function PromptSubmit({ darkModeIcon={} title={ - 提交成功 + {I18n.t('version_submit_success')} } description={
- 接入 CozeLoop SDK 上报数据,进行数据观测 + {I18n.t('cozeloop_sdk_data_report_observation')} { @@ -102,11 +103,11 @@ export function PromptSubmit({ modal.destroy(); }} > - 立即前往 + {I18n.t('go_immediately')} - 对 Prompt 进行效果评估,提升应用效果 + {I18n.t('prompt_effect_evaluation')} { @@ -114,7 +115,7 @@ export function PromptSubmit({ modal.destroy(); }} > - 立即前往 + {I18n.t('go_immediately')}
@@ -122,7 +123,7 @@ export function PromptSubmit({ />
), - okText: '关闭', + okText: I18n.t('close'), }); }; @@ -173,7 +174,7 @@ export function PromptSubmit({ }); }); } else { - setOkButtonText('继续'); + setOkButtonText(I18n.t('continue')); setBasePrompt(undefined); setCurrentPrompt(undefined); formApi.current?.reset(); @@ -187,18 +188,20 @@ export function PromptSubmit({ > versionValidate(val, initVersion)} - placeholder="请输入版本号,版本号格式为a.b.c, 且每段为0-9999" + placeholder={I18n.t('input_version_number')} /> { - if (okButtonText === '继续') { - setOkButtonText('提交'); + if (okButtonText === I18n.t('continue')) { + setOkButtonText(I18n.t('submit')); } else { submitRunAsync(); } @@ -219,10 +222,10 @@ export function PromptSubmit({ className="min-h-[calc(100vh - 140px)]" width={900} visible={visible} - title="提交新版本" + title={I18n.t('submit_new_version')} onCancel={onCancel} - okText={basePrompt ? okButtonText : '提交'} - cancelText="取消" + okText={basePrompt ? okButtonText : I18n.t('submit')} + cancelText={I18n.t('cancel')} onOk={basePrompt ? handleSubmit : submitRunAsync} okButtonProps={{ loading: submitLoading }} height="fit-content" @@ -248,7 +251,7 @@ export function PromptSubmit({ 'cursor-pointer', )} icon={ - okButtonText === '提交' ? ( + okButtonText === I18n.t('submit') ? ( @@ -256,21 +259,21 @@ export function PromptSubmit({ 1 ) } - onClick={() => setOkButtonText('继续')} + onClick={() => setOkButtonText(I18n.t('continue'))} > - 确认版本差异 + {I18n.t('confirm_version_difference')} 2} > - 确认版本信息 + {I18n.t('confirm_version_info')}
- {okButtonText === '继续' ? ( + {okButtonText === I18n.t('continue') ? ( ) : ( submitForm diff --git a/frontend/packages/cozeloop/prompt-pages/src/components/send-msg-area/index.tsx b/frontend/packages/cozeloop/prompt-pages/src/components/send-msg-area/index.tsx index 07c63658e..9e920b866 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/components/send-msg-area/index.tsx +++ b/frontend/packages/cozeloop/prompt-pages/src/components/send-msg-area/index.tsx @@ -17,6 +17,7 @@ import { Prec, PromptBasicEditor, } from '@cozeloop/prompt-components'; +import { I18n } from '@cozeloop/i18n-adapter'; import { useSpace } from '@cozeloop/biz-hooks-adapter'; import { uploadFile } from '@cozeloop/biz-components-adapter'; import { @@ -187,7 +188,7 @@ export function SendMsgArea({ })); } catch (error) { console.info('error', error); - Toast.error('图片上传失败,请稍后重试'); + Toast.error(I18n.t('image_upload_error')); setQueryMsg(v => ({ ...v, parts: (v?.parts || []).filter((it: ContentPartLoop) => it.uid !== uid), @@ -211,13 +212,19 @@ export function SendMsgArea({ for (const item of Array.from(items)) { if (item.type.includes('image')) { if (isMaxImgSizeRef.current) { - Toast.warning(`最多上传${MAX_IMAGE_FILE}张图片`); + Toast.warning( + I18n.t('max_upload_picture_num', { num: MAX_IMAGE_FILE }), + ); return; } const file = item.getAsFile(); if (file) { if (file.size / 1024 > MAX_FILE_SIZE) { - Toast.error(`图片大小不能超过${MAX_FILE_SIZE_MB}MB`); + Toast.error( + I18n.t('image_size_not_exceed_num_mb', { + num: MAX_FILE_SIZE_MB, + }), + ); return; } uploadRef.current?.insert([file], 0); @@ -299,13 +306,13 @@ export function SendMsgArea({ size="mini" onClick={stopStreaming} > - 停止响应 + {I18n.t('stop_respond')} ) : null}
{isCompare ? null : ( - + } onClick={clearHistoricChat} @@ -362,7 +369,7 @@ export function SendMsgArea({ height={44} variables={variables?.filter(it => it.type === VariableType.String)} readOnly={streaming || inputReadonly} - linePlaceholder="请输入问题测试大模型回复,回车发送,Shift+回车换行" + linePlaceholder={I18n.t('input_question_tip')} customExtensions={extensions} onFocus={() => setEditorActive(true)} onBlur={() => setEditorActive(false)} @@ -371,7 +378,7 @@ export function SendMsgArea({
{isCompare ? ( - + } onClick={clearHistoricChat} @@ -390,9 +397,19 @@ export function SendMsgArea({ maxSize={MAX_FILE_SIZE} limit={canUploadFileSize} onSizeError={() => - Toast.error(`图片大小不能超过${MAX_FILE_SIZE_MB}MB`) + Toast.error( + Toast.error( + I18n.t('image_size_not_exceed_num_mb', { + num: MAX_FILE_SIZE_MB, + }), + ), + ) + } + onExceed={() => + Toast.warning( + I18n.t('max_upload_picture_num', { num: MAX_IMAGE_FILE }), + ) } - onExceed={() => Toast.warning(`最多上传${MAX_IMAGE_FILE}张图片`)} multiple fileList={imgParts.map(it => ({ uid: it.uid || '', @@ -418,7 +435,7 @@ export function SendMsgArea({ type="tertiary" icon={} > - 该模型不支持上传图片 + {I18n.t('model_not_support_picture')} )}
@@ -427,12 +444,12 @@ export function SendMsgArea({ onClick={handleSendMessage} disabled={executeDisabled} > - 运行 + {I18n.t('run')}
- 内容由AI生成,无法确保真实准确,仅供参考。 + {I18n.t('generated_by_ai_tip')}
); diff --git a/frontend/packages/cozeloop/prompt-pages/src/components/tools-card/index.tsx b/frontend/packages/cozeloop/prompt-pages/src/components/tools-card/index.tsx index cb2744d50..4871ff4af 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/components/tools-card/index.tsx +++ b/frontend/packages/cozeloop/prompt-pages/src/components/tools-card/index.tsx @@ -4,10 +4,14 @@ /* eslint-disable complexity */ import { useShallow } from 'zustand/react/shallow'; import { EVENT_NAMES, sendEvent } from '@cozeloop/tea-adapter'; +import { I18n } from '@cozeloop/i18n-adapter'; import { CollapseCard } from '@cozeloop/components'; import { useModalData } from '@cozeloop/base-hooks'; import { ToolChoiceType } from '@cozeloop/api-schema/prompt'; -import { IconCozPlus, IconCozWarningCircle } from '@coze-arch/coze-design/icons'; +import { + IconCozPlus, + IconCozWarningCircle, +} from '@coze-arch/coze-design/icons'; import { Button, Space, Switch, Tag, Typography } from '@coze-arch/coze-design'; import { usePromptStore } from '@/store/use-prompt-store'; @@ -82,11 +86,11 @@ export function ToolsCard({ uid, defaultVisible }: ToolsCardProps) { subInfo={ functionCallEnabled || !currentModel ? null : ( }> - 模型不支持 + {I18n.t('model_not_support')} ) } - title={函数} + title={{I18n.t('function')}} extra={
- 启用函数 + + {I18n.t('enable_function')} +
{isCompare ? null : (
- 单步调试 + + {I18n.t('single_step_debugging')} +
)}
@@ -163,7 +171,7 @@ export function ToolsCard({ uid, defaultVisible }: ToolsCardProps) { onClick={() => toolModal.open()} disabled={currentReadonly || !functionCallEnabled} > - 新增函数 + {I18n.t('new_function')}
diff --git a/frontend/packages/cozeloop/prompt-pages/src/components/tools-item/index.tsx b/frontend/packages/cozeloop/prompt-pages/src/components/tools-item/index.tsx index 162fbfd78..3a49a63ce 100644 --- a/frontend/packages/cozeloop/prompt-pages/src/components/tools-item/index.tsx +++ b/frontend/packages/cozeloop/prompt-pages/src/components/tools-item/index.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { type Tool } from '@cozeloop/api-schema/prompt'; import { IconCozTrashCan } from '@coze-arch/coze-design/icons'; import { IconButton, Popconfirm, Typography } from '@coze-arch/coze-design'; @@ -39,10 +40,10 @@ export function ToolItem({ {!showDelete ? null : ( { @@ -75,7 +76,7 @@ export function ToolItem({
- 模拟值: + {I18n.t('mock_value')}: @@ -250,7 +251,7 @@ export function ToolModal({ setMockValue('Sunny'); }} > - 插入模版 + {I18n.t('insert_template')} )}
@@ -265,7 +266,7 @@ export function ToolModal({
- 默认模拟值 + {I18n.t('default_mock_value')} { const item: EvaluationSet = { id: createId(), - name: `百科知识数据集 ${index}`, + name: I18n.t('pedia_dataset', { index }), base_info: { created_at: new Date().toLocaleString(), created_by: { @@ -133,7 +134,7 @@ export async function listEvaluationSetVersions( const item: EvaluationSetVersion = { id: createId(), version: `0.0.${index + 1}`, - description: '版本描述', + description: I18n.t('version_description'), }; return item; }); diff --git a/frontend/packages/cozeloop/evaluate/src/components/mapping-item-field/index.tsx b/frontend/packages/cozeloop/evaluate/src/components/mapping-item-field/index.tsx index d962593a0..eb9e84f97 100644 --- a/frontend/packages/cozeloop/evaluate/src/components/mapping-item-field/index.tsx +++ b/frontend/packages/cozeloop/evaluate/src/components/mapping-item-field/index.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { type FC } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { EqualItem, ReadonlyItem, @@ -74,7 +75,7 @@ export const MappingItemField: FC = 请选择模型 + {I18n.t('choose_model')} )}
{props.disabled ? (
- {'查看参数'} + {I18n.t('check_parameters')}
) : ( diff --git a/frontend/packages/cozeloop/evaluate/src/pages/dataset/detail/index.tsx b/frontend/packages/cozeloop/evaluate/src/pages/dataset/detail/index.tsx index fcc795333..a532562bb 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/dataset/detail/index.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/dataset/detail/index.tsx @@ -15,6 +15,7 @@ import { type Version } from '@cozeloop/components'; import { useSpace } from '@cozeloop/biz-hooks-adapter'; import { useBreadcrumb } from '@cozeloop/base-hooks'; import { Layout, Loading, Tabs } from '@coze-arch/coze-design'; +import { I18n } from '@cozeloop/i18n-adapter'; enum TabKey { EVAL = 'eval', @@ -52,7 +53,7 @@ export default function EvaluateSetDetailPage() { itemKey={TabKey.EVAL} tab={ <> - 评测集 + {I18n.t('evaluation_set')} ) : null} - + - {'调试'} + {I18n.t('debug')} {debugValue ? ( - {'预览与调试'} - + {I18n.t('preview_and_debug')} +
@@ -144,7 +154,7 @@ export function DebugModal({
- {'配置信息'} + {I18n.t('config_info')}
- {'构造测试数据'} + {I18n.t('construct_test_data')}
{variables.length ? (
@@ -194,7 +204,7 @@ export function DebugModal({ ) : ( )} @@ -210,7 +220,7 @@ export function DebugModal({ ); }} > - {'清空'} + {I18n.t('clear')} - {'运行'} + {I18n.t('run')}
@@ -236,14 +246,14 @@ export function DebugModal({ ) : null}
- {'内容由AI生成,无法确保真实准确,仅供参考。'} + {I18n.t('generated_by_ai_tip')}
) : ( } - title="评估器缺少输入" + title={I18n.t('evaluator_lacks_input')} /> )}
diff --git a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/evaluator-detail.tsx b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/evaluator-detail.tsx index 0112f84aa..e0be8efa7 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/evaluator-detail.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/evaluator-detail.tsx @@ -6,6 +6,7 @@ import { useEffect, useRef, useState } from 'react'; import { set } from 'lodash-es'; import { useRequest } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { GuardPoint, Guard } from '@cozeloop/guard'; import { sourceNameRuleValidator } from '@cozeloop/evaluate-components'; import { RouteBackAction } from '@cozeloop/components'; @@ -41,18 +42,18 @@ function EvaluatorCreatePage() { useEffect(() => { if (blocker.state === 'blocked') { Modal.warning({ - title: '信息未保存', - content: '离开当前页面,信息将不被保存。', - cancelText: '取消', + title: I18n.t('information_unsaved'), + content: I18n.t('leave_page_tip'), + cancelText: I18n.t('Cancel'), onCancel: blocker.reset, - okText: '确认', + okText: I18n.t('confirm'), onOk: blocker.proceed, }); } }, [blocker.state]); useBreadcrumb({ - text: '新建评估器', + text: I18n.t('new_evaluator'), }); const formRef = useRef(null); @@ -111,17 +112,20 @@ function EvaluatorCreatePage() { }} >
- {'基础信息'} + {'basic_info'}
- {'新建评估器'} + {I18n.t('new_evaluator')}
{sourceService.loading ? ( @@ -178,7 +184,7 @@ function EvaluatorCreatePage() { />
diff --git a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/prompt-config-field.tsx b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/prompt-config-field.tsx index 2c6a01608..1e2b8311f 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/prompt-config-field.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/prompt-config-field.tsx @@ -1,5 +1,7 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; + import { ConfigContent } from './config-content'; interface Props { @@ -11,7 +13,7 @@ export function PromptConfigField({ disabled, refreshEditorModelKey }: Props) { return ( <>
- {'配置信息'} + {I18n.t('config_info')}
} onClick={() => setTemplateVisible(true)} > - {`选择模板${ + {`${I18n.t('select_template')}${ promptEvaluator?.prompt_template_name ? `(${promptEvaluator.prompt_template_name})` : '' @@ -125,13 +126,13 @@ export function PromptField({ icon={} disabled={disabled} > - {'清空'} + {I18n.t('clear')} ) : ( { promptEvaluatorFieldApi.setValue({ @@ -156,7 +157,7 @@ export function PromptField({ className="!px-[3px] !h-5" icon={} > - {'清空'} + {I18n.t('clear')} )} @@ -171,7 +172,9 @@ export function PromptField({ } disabled={disabled} noLabel - rules={[{ required: true, message: 'System Prompt 不可为空' }]} + rules={[ + { required: true, message: I18n.t('system_prompt_not_empty') }, + ]} minHeight={300} maxHeight={500} dragBtnHidden @@ -206,7 +209,9 @@ export function PromptField({ } noLabel disabled={disabled} - rules={[{ required: true, message: 'User Prompt 不可为空' }]} + rules={[ + { required: true, message: I18n.t('user_prompt_not_empty') }, + ]} maxHeight={500} messageTypeDisabled={true} messageTypeList={messageTypeList} @@ -230,10 +235,10 @@ export function PromptField({ }} rightActionBtns={ { const messageList = promptEvaluator?.message_list || []; @@ -273,7 +278,7 @@ export function PromptField({ disabled={disabled} icon={} > - {'添加 User Prompt'} + {I18n.t('add_user_prompt')} )} diff --git a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/submit-version-modal.tsx b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/submit-version-modal.tsx index 7970e1748..9afd6a66c 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/submit-version-modal.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/submit-version-modal.tsx @@ -5,6 +5,7 @@ import { useEffect, useRef } from 'react'; import { nanoid } from 'nanoid'; import { merge } from 'lodash-es'; +import { I18n } from '@cozeloop/i18n-adapter'; import { useSpace } from '@cozeloop/biz-hooks-adapter'; import { EVENT_NAMES, sendEvent } from '@cozeloop/tea-adapter'; import { type Evaluator } from '@cozeloop/api-schema/evaluation'; @@ -100,36 +101,40 @@ export function SubmitVersionModal({ return ( + ), }} field="current_version.version" - placeholder={'请输入版本号'} + placeholder={I18n.t('please_input', { field: I18n.t('version') })} rules={[ { validator: (_rule, value) => { if (!value) { - return new Error('请输入版本号'); + return new Error( + I18n.t('please_input', { field: I18n.t('version') }), + ); } const reg = /^\d{1,4}\.\d{1,4}\.\d{1,4}$/; if (!reg.test(value)) { - return new Error('版本号格式为a.b.c,且每段为0-9999'); + return new Error(I18n.t('version_number_format')); } if (type === 'append') { const latestVersion = evaluator?.latest_version; @@ -138,7 +143,9 @@ export function SubmitVersionModal({ compareVersions(value, latestVersion) <= 0 ) { return new Error( - `版本号必须大于当前版本号:${latestVersion}`, + I18n.t('version_number_gt_current', { + version: latestVersion, + }), ); } } @@ -149,9 +156,11 @@ export function SubmitVersionModal({ ]} /> diff --git a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/template-modal.tsx b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/template-modal.tsx index b31889abb..3e39f78ba 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/template-modal.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-create/template-modal.tsx @@ -5,6 +5,7 @@ import { useEffect, useState } from 'react'; import classNames from 'classnames'; import { useRequest } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { TemplateInfo } from '@cozeloop/evaluate-components'; import { TemplateType, @@ -95,7 +96,7 @@ export function TemplateModal({ >
- {'选择模板'} + {I18n.t('select_template')}
{listService.loading ? ( @@ -108,7 +109,7 @@ export function TemplateModal({ ) : ( <>
- {'预置评估器'} + {I18n.t('preset_evaluator')}
{listService.data?.builtin_template_keys?.map((t, idx) => (
- {'预览'} + {I18n.t('preview')} } @@ -155,14 +156,14 @@ export function TemplateModal({
diff --git a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/base-info-modal.tsx b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/base-info-modal.tsx index b0faf3d4f..d3197eaa3 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/base-info-modal.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/base-info-modal.tsx @@ -3,6 +3,7 @@ import { useEffect, useRef } from 'react'; import { useRequest } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { useSpace } from '@cozeloop/biz-hooks-adapter'; import { sourceNameRuleValidator } from '@cozeloop/evaluate-components'; import { EvaluatorType, type Evaluator } from '@cozeloop/api-schema/evaluation'; @@ -63,11 +64,11 @@ export function BaseInfoModal({ return ( { @@ -92,7 +96,9 @@ export function BaseInfoModal({ name: value, }); if (!pass) { - throw new Error('名称已存在'); + throw new Error( + I18n.t('field_exists', { field: I18n.t('name') }), + ); } } }, @@ -100,9 +106,9 @@ export function BaseInfoModal({ ]} /> diff --git a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/header.tsx b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/header.tsx index c6dae6ca6..86f77edd1 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/header.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/header.tsx @@ -19,6 +19,7 @@ import { type DebugButtonProps, } from '../evaluator-create/debug-button'; import { type BaseInfo, BaseInfoModal } from './base-info-modal'; +import { I18n } from '@cozeloop/i18n-adapter'; export function Header({ evaluator, @@ -53,13 +54,17 @@ export function Header({ tagContent = ( <> - {'草稿自动保存中'} + {I18n.t('draft_auto_saving')} ); } else if (autoSaveService.error) { - tagContent = '草稿自动保存失败'; + tagContent = I18n.t('draft_auto_save_failed'); } else if (autoSaveService.data?.lastSaveTime) { - tagContent = `草稿已自动保存于 ${dayjs(Number(autoSaveService.data.lastSaveTime)).format('YYYY-MM-DD HH:mm:ss')}`; + tagContent = I18n.t('draft_auto_saved_date', { + date: dayjs(Number(autoSaveService.data.lastSaveTime)).format( + 'YYYY-MM-DD HH:mm:ss', + ), + }); } if (tagContent) { @@ -87,14 +92,14 @@ export function Header({
- {'提交时间:'} + {I18n.t('submission_time')} {dayjs(Number(selectedVersion.base_info?.created_at)).format( 'YYYY-MM-DD HH:mm:ss', )}
- {'提交人:'} + {I18n.t('submitter')} - {'修改未提交'} + {I18n.t('changes_not_submitted')} ) : null} @@ -135,7 +140,7 @@ export function Header({
- 描述:{evaluator?.description || '-'} + {I18n.t('description')}: {evaluator?.description || '-'}
{renderExtra()} @@ -144,13 +149,13 @@ export function Header({
{selectedVersion ? null : } {selectedVersion ? null : ( )} diff --git a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/index.tsx b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/index.tsx index 28ff0d1a1..42418de00 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/index.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/index.tsx @@ -5,6 +5,7 @@ import { useParams } from 'react-router-dom'; import { useRef, useState } from 'react'; import { useRequest } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { GuardPoint, useGuard } from '@cozeloop/guard'; import { ModelConfigInfo, TemplateInfo } from '@cozeloop/evaluate-components'; import { useDemoSpace, useSpace } from '@cozeloop/biz-hooks-adapter'; @@ -128,7 +129,7 @@ function EvaluatorDetailPage() { return (
- {'配置信息'} + {I18n.t('config_info')}
setSubmitModalVisible(false)} onSuccess={(_, newEvaluator) => { setSubmitModalVisible(false); - Toast.success('版本提交成功'); + Toast.success(I18n.t('version_submit_success')); service.mutate(() => newEvaluator); if (versionListVisible) { setVersionListRefreshFlag([]); diff --git a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/version-list-pane.tsx b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/version-list-pane.tsx index f501e8f70..0ad2634c6 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/version-list-pane.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-detail/version-list-pane.tsx @@ -1,6 +1,7 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 import { useRequest } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { VersionItem } from '@cozeloop/components'; import { type EvaluatorVersion, @@ -38,7 +39,9 @@ export function VersionListPane({ return (
-
{'版本记录'}
+
+ {I18n.t('version_record')} +
} field="search_name" - placeholder="搜索名称" + placeholder={I18n.t('search_name')} fieldClassName="!mr-0 !pr-0" className="!w-full" autoComplete="off" diff --git a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-list/evaluator-list-page.tsx b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-list/evaluator-list-page.tsx index 4460323c5..c876262c8 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-list/evaluator-list-page.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/evaluator/evaluator-list/evaluator-list-page.tsx @@ -8,6 +8,7 @@ import { useMemo, useState } from 'react'; import { isEmpty } from 'lodash-es'; import dayjs from 'dayjs'; import { usePagination, useRequest } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { GuardPoint, useGuards } from '@cozeloop/guard'; import { type ColumnItem, @@ -83,12 +84,14 @@ function EvaluatorListPage() { Modal.info({ size: 'large', className: 'w-[420px]', - title: '复制评估器配置', - content: `复制${record.name}配置,并新建评估器`, + title: 'copy_evaluator_config', + content: I18n.t('copy_and_create_evaluator', { + name: record.name, + }), onOk: () => navigate(`create/${record.evaluator_id}`), showCancelButton: true, - cancelText: '取消', - okText: '确认', + cancelText: I18n.t('Cancel'), + okText: I18n.t('confirm'), }); }; @@ -107,8 +110,8 @@ function EvaluatorListPage() { const columns: ColumnItem[] = useMemo(() => { const newDefaultColumns: ColumnItem[] = [ { - title: '评估器名称', - value: '评估器名称', + title: I18n.t('evaluator_name'), + value: I18n.t('evaluator_name'), dataIndex: 'name', key: 'name', width: 200, @@ -128,7 +131,7 @@ function EvaluatorListPage() { color="yellow" className="ml-2 flex-shrink-0 !h-5 !px-2 !py-[2px] rounded-[3px] " > - {'修改未提交'} + {I18n.t('changes_not_submitted')} ) : null}
@@ -137,8 +140,8 @@ function EvaluatorListPage() { disabled: true, }, { - title: '最新版本', - value: '最新版本', + title: I18n.t('latest_version'), + value: I18n.t('latest_version'), dataIndex: 'latest_version', key: 'latest_version', width: 100, @@ -173,8 +176,8 @@ function EvaluatorListPage() { // ), // }, { - title: '描述', - value: '描述', + title: I18n.t('description'), + value: I18n.t('description'), dataIndex: 'description', key: 'description', width: 285, @@ -189,8 +192,8 @@ function EvaluatorListPage() { checked: true, }, { - title: '更新人', - value: '更新人', + title: I18n.t('updated_person'), + value: I18n.t('updated_person'), dataIndex: 'base_info.updated_by', key: 'updated_by', width: 170, @@ -203,8 +206,8 @@ function EvaluatorListPage() { checked: true, }, { - title: '更新时间', - value: '更新时间', + title: I18n.t('update_time'), + value: I18n.t('update_time'), dataIndex: 'base_info.updated_at', sorter: true, key: 'updated_at', @@ -214,8 +217,8 @@ function EvaluatorListPage() { checked: true, }, { - title: '创建人', - value: '创建人', + title: I18n.t('creator'), + value: I18n.t('creator'), dataIndex: 'base_info.created_by', key: 'created_by', width: 170, @@ -228,8 +231,8 @@ function EvaluatorListPage() { checked: true, }, { - title: '创建时间', - value: '创建时间', + title: I18n.t('create_time'), + value: I18n.t('create_time'), dataIndex: 'base_info.created_at', key: 'created_at', sorter: true, @@ -239,8 +242,8 @@ function EvaluatorListPage() { checked: true, }, { - title: '操作', - value: '操作', + title: I18n.t('operation'), + value: I18n.t('operation'), key: 'action', width: 142, fixed: 'right', @@ -248,17 +251,17 @@ function EvaluatorListPage() { navigate(`${record.evaluator_id}`), }, { - label: '复制', + label: I18n.t('copy'), disabled: guards.data[GuardPoint['eval.evaluators.copy']].readonly, onClick: () => handleCopy(record), }, { - label: '删除', + label: I18n.t('delete'), type: 'danger', disabled: guards.data[GuardPoint['eval.evaluators.delete']].readonly, @@ -266,12 +269,14 @@ function EvaluatorListPage() { Modal.error({ size: 'large', className: 'w-[420px]', - title: `确定删除评估器:${record.name}?`, - content: '此操作不可逆,请慎重操作', + title: I18n.t('confirm_delete_evaluator', { + name: record.name, + }), + content: I18n.t('caution_of_operation'), onOk: () => deleteService.runAsync(record), showCancelButton: true, - cancelText: '取消', - okText: '删除', + cancelText: I18n.t('Cancel'), + okText: I18n.t('delete'), }), }, ]} @@ -295,7 +300,7 @@ function EvaluatorListPage() { return (
- +
@@ -376,15 +381,17 @@ function EvaluatorListPage() { } - title="未能找到相关结果" - description={'请尝试其他关键词或修改筛选项'} + title={I18n.t('failed_to_find_related_results')} + description={I18n.t( + 'try_other_keywords_or_modify_filter_options', + )} /> ) : ( } - title="暂无评估器" - description={'点击右上角创建按钮进行创建'} + title={I18n.t('no_evaluator')} + description={I18n.t('click_to_create')} /> ) } diff --git a/frontend/packages/cozeloop/evaluate/src/pages/experiment/contrast/components/add-contrast-experiment.tsx b/frontend/packages/cozeloop/evaluate/src/pages/experiment/contrast/components/add-contrast-experiment.tsx index 04868a85a..18d61bdc3 100644 --- a/frontend/packages/cozeloop/evaluate/src/pages/experiment/contrast/components/add-contrast-experiment.tsx +++ b/frontend/packages/cozeloop/evaluate/src/pages/experiment/contrast/components/add-contrast-experiment.tsx @@ -3,6 +3,7 @@ import { useState } from 'react'; import { EVENT_NAMES, sendEvent } from '@cozeloop/tea-adapter'; +import { I18n } from '@cozeloop/i18n-adapter'; import { ExptStatus, type Experiment } from '@cozeloop/api-schema/evaluation'; import { IconCozPlus } from '@coze-arch/coze-design/icons'; import { Button } from '@coze-arch/coze-design'; @@ -29,7 +30,7 @@ export default function AddContrastExperiment({ setVisible(true); }} > - 添加对比实验 + {I18n.t('add_comparison_experiment')} {visible ? ( -
对比{experimentCount}个实验
+
+ {I18n.t('compare_x_experiments', { num: experimentCount })} +
- 导入数据列 + {I18n.t('import_data_column')} } className="!w-[276px]" diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/index.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/index.tsx index 1d4a22cf7..8e010e056 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/index.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/index.tsx @@ -5,6 +5,7 @@ import { useRef, useState } from 'react'; import { debounce } from 'lodash-es'; import cs from 'classnames'; +import { I18n } from '@cozeloop/i18n-adapter'; import { GuardPoint, useGuard } from '@cozeloop/guard'; import { InfoTooltip } from '@cozeloop/components'; import { useSpace, useDataImportApi } from '@cozeloop/biz-hooks-adapter'; @@ -104,7 +105,7 @@ export const DatasetImportItemsModal = ({ return ( <> { if (fileList.length === 0) { @@ -150,14 +151,14 @@ export const DatasetImportItemsModal = ({ )} className={styles.upload} dragIcon={} - dragMainText="点击上传或者拖拽文件至此处" + dragMainText={I18n.t('click_or_drag_file_to_upload')} dragSubText={
- 推荐使用模板上传1个文件,支持CSV格式 + {I18n.t('recommend_template_upload_tip')} - 下载模板 + {I18n.t('download_template')}
} @@ -179,7 +180,7 @@ export const DatasetImportItemsModal = ({ rules={[ { required: true, - message: '请上传文件', + message: I18n.t('upload_file'), }, ]} >
@@ -193,15 +194,15 @@ export const DatasetImportItemsModal = ({ size="small" className="!coz-fg-secondary" > - 如果待导入数据集的列没有配置映射关系,则该列不会被导入。 + {I18n.t('no_mapping_no_import')} } label={
-
列映射
+
{I18n.t('column_mapping')}
} @@ -209,7 +210,7 @@ export const DatasetImportItemsModal = ({ rules={[ { required: true, - message: '请配置列映射', + message: I18n.t('configure_column_mapping'), }, { validator: (_, data) => { @@ -218,15 +219,22 @@ export const DatasetImportItemsModal = ({ } return true; }, - message: '请配置最少一个导入列', + message: I18n.t( + 'configure_at_least_one_import_column', + ), }, ]} /> ) : null}
@@ -237,7 +245,7 @@ export const DatasetImportItemsModal = ({ onCancel(); }} > - 取消 + {I18n.t('Cancel')}
diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/overwrite-field.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/overwrite-field.tsx index 3129abe8e..e5bc3f722 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/overwrite-field.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/overwrite-field.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { Modal, Radio, RadioGroup } from '@coze-arch/coze-design'; interface OverWriteFieldProps { @@ -13,10 +14,10 @@ export const OverWriteField = ({ value, onChange }: OverWriteFieldProps) => ( const newValue = e.target.value === 'true'; if (newValue) { Modal.confirm({ - title: '确认选择全量覆盖', - content: '继续导入数据将覆盖现有数据', - okText: '确认', - cancelText: '取消', + title: I18n.t('confirm_select_full_coverage'), + content: I18n.t('continue_will_override_existing_data'), + okText: I18n.t('confirm'), + cancelText: I18n.t('Cancel'), onOk: () => { onChange?.(true); }, @@ -32,7 +33,7 @@ export const OverWriteField = ({ value, onChange }: OverWriteFieldProps) => ( } }} > - 追加数据 - 全量覆盖 + {I18n.t('append_data')} + {I18n.t('overwrite_data')} ); diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/use-import-progress.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/use-import-progress.tsx index 4a5117ee4..9a2e042d1 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/use-import-progress.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-import-items-modal/use-import-progress.tsx @@ -3,6 +3,7 @@ import { useMemo, useState } from 'react'; import { useRequest } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { useSpace, useDataImportApi } from '@cozeloop/biz-hooks-adapter'; import { JobStatus } from '@cozeloop/api-schema/data'; import { Button, Loading, Modal } from '@coze-arch/coze-design'; @@ -57,7 +58,11 @@ export const useDatasetImportProgress = (onImportSuccess: () => void) => { width={420} title={
- {isFinish ? '执行结果' : '执行中'} + + {isFinish + ? I18n.t('execution_result') + : I18n.t('execution_in_progress')} +
} footer={ @@ -68,7 +73,7 @@ export const useDatasetImportProgress = (onImportSuccess: () => void) => { onImportSuccess(); }} > - 已知晓 + {I18n.t('known')} ) } diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item-expand/use-dataset-item-expand.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item-expand/use-dataset-item-expand.tsx index 53d1897d7..ae0b6cd6d 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item-expand/use-dataset-item-expand.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item-expand/use-dataset-item-expand.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { useState } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { IconCozLoose, IconCozTight } from '@coze-arch/coze-design/icons'; import { Radio, Tooltip } from '@coze-arch/coze-design'; @@ -14,12 +15,12 @@ export const useDatasetItemExpand = () => { value={expand ? 'expand' : 'shrink'} onChange={e => setExpand(e.target.value === 'expand' ? true : false)} > - + - + diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item-panel/index.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item-panel/index.tsx index f68312e62..bf49649a9 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item-panel/index.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item-panel/index.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { useRef, useState } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { GuardPoint, Guard } from '@cozeloop/guard'; import { ResizeSidesheet } from '@cozeloop/components'; import { useSpace } from '@cozeloop/biz-hooks-adapter'; @@ -10,7 +11,10 @@ import { type EvaluationSetItem, } from '@cozeloop/api-schema/evaluation'; import { StoneEvaluationApi } from '@cozeloop/api-schema'; -import { IconCozArrowLeft, IconCozArrowRight } from '@coze-arch/coze-design/icons'; +import { + IconCozArrowLeft, + IconCozArrowRight, +} from '@coze-arch/coze-design/icons'; import { Button, Form, type FormApi, Toast } from '@coze-arch/coze-design'; import IDWithCopy from '../id-with-copy'; @@ -61,7 +65,7 @@ export const DatasetItemPanel = ({ turns: newTurnsData, workspace_id: spaceID, }); - Toast.success('保存成功'); + Toast.success(I18n.t('save_success')); onSave(); } catch (error) { console.error(error); @@ -99,23 +103,23 @@ export const DatasetItemPanel = ({ }} disabled={loading} > - 保存 + {I18n.t('save')} ) : ( )}
} title={
- {isEdit ? '编辑数据项:' : '查看数据项:'} + {isEdit ? I18n.t('edit_data_item') : I18n.t('view_data_item')}
{switchConfig ? ( @@ -129,7 +133,7 @@ export const DatasetItemPanel = ({ switchConfig?.onSwith('pre'); }} > - 上一条 + {I18n.t('prev_item')}
) : null} diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/empty.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/empty.tsx index cfc30819d..1567fd4c4 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/empty.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/empty.tsx @@ -1,10 +1,11 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { IconCozEmpty } from '@coze-arch/coze-design/icons'; export const EmptyDatasetItem = () => (
- 暂无数据 + {I18n.t('no_data')}
); diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/bool/edit.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/bool/edit.tsx index c21625755..4fe997908 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/bool/edit.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/bool/edit.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { Radio } from '@coze-arch/coze-design'; import { saftJsonParse } from '../../util'; @@ -21,10 +22,10 @@ export const BoolDatasetItemEdit = ({ return (
handleChange(true)}> - 是 + {I18n.t('yes')} handleChange(false)}> - 否 + {I18n.t('no')}
); diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/float/edit.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/float/edit.tsx index 711660eb5..ad0f164cc 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/float/edit.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/float/edit.tsx @@ -1,14 +1,13 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { Input } from '@coze-arch/coze-design'; import { type DatasetItemProps } from '../../type'; -export const FloatDatasetItemEdit = ({ - fieldContent, - onChange, -}: DatasetItemProps) => ( + +export const FloatDatasetItemEdit = ({ fieldContent, onChange }: DatasetItemProps) => ( { diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/integer/edit.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/integer/edit.tsx index 1d60b4c52..8c6f061c5 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/integer/edit.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/integer/edit.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { Input } from '@coze-arch/coze-design'; import { type DatasetItemProps } from '../../type'; @@ -10,7 +11,7 @@ export const IntegerDatasetItemEdit = ({ }: DatasetItemProps) => ( <> { diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/string/code/index.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/string/code/index.tsx index 6f19bb87e..4b36e590b 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/string/code/index.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/text/string/code/index.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { useState } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { CodeEditor, handleCopy } from '@cozeloop/components'; import { IconCozCopy } from '@coze-arch/coze-design/icons'; import { Button, SemiSelect } from '@coze-arch/coze-design'; @@ -42,7 +43,7 @@ export const CodeDatasetItem = ({ color="primary" size="small" > - 复制 + {I18n.t('copy')}
diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/util.ts b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/util.ts index 6f4173d01..3fd2089fa 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/util.ts +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-item/util.ts @@ -3,6 +3,7 @@ /* eslint-disable @coze-arch/use-error-in-catch */ import JSONBig from 'json-bigint'; import Decimal from 'decimal.js'; +import { I18n } from '@cozeloop/i18n-adapter'; import { type FieldSchema } from '@cozeloop/api-schema/evaluation'; import { ContentType, COLUMN_TYPE_MAP, DataType } from './type'; @@ -113,6 +114,7 @@ export const validateAndFormat = ({ } }; +// eslint-disable-next-line complexity -- skip export const validarDatasetItem = ( value: string, callback: (error?: string) => void, @@ -123,7 +125,7 @@ export const validarDatasetItem = ( return true; } if (!/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(value)) { - callback('请输入数字'); + callback(I18n.t('please_input', { field: I18n.t('number') })); return false; } // 校验value 是否为数字; @@ -136,29 +138,33 @@ export const validarDatasetItem = ( const minValue = minimum ? new Decimal(minimum) : undefined; const maxValue = maximum ? new Decimal(maximum) : undefined; if (minValue && decimalValue.lt(minValue)) { - callback(`请输入大于等于${minimum}的数字`); + callback(I18n.t('input_num_gte', { num: I18n.t('number') })); return false; } if (maxValue && decimalValue.gt(maxValue)) { - callback(`请输入小于等于${maximum}的数字`); + callback(I18n.t('input_num_lte', { num: I18n.t('number') })); return false; } if (type === DataType.Integer && decimalValue.isInteger() === false) { - callback('请输入整数'); + callback(I18n.t('please_input', { field: I18n.t('integer') })); return false; } if (type === DataType.Float && multipleOf) { const multipleOfDecimal = new Decimal(multipleOf); const division = decimalValue.dividedBy(multipleOfDecimal); if (!division.isInteger()) { - callback(`仅支持精确到小数点后${multipleOfDecimal.decimalPlaces()}位`); + callback( + I18n.t('support_precision', { + precision: multipleOfDecimal.decimalPlaces(), + }), + ); return false; } } return true; } catch (error) { - callback('请输入数字'); + callback(I18n.t('please_input', { field: I18n.t('number') })); return false; } }; diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/column-config.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/column-config.tsx index d4f90cefb..a51614c39 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/column-config.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/column-config.tsx @@ -1,6 +1,7 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 import { formatTimestampToString } from '@cozeloop/toolkit'; +import { I18n } from '@cozeloop/i18n-adapter'; import { type ColumnItem, UserProfile } from '@cozeloop/components'; import { type UserInfo, @@ -28,8 +29,8 @@ export const DatasetColumnConfig: Record< ColumnProps > = { name: { - title: '名称', - displayName: '名称', + title: I18n.t('name'), + displayName: I18n.t('name'), key: 'name', disabled: true, dataIndex: 'name', @@ -43,30 +44,30 @@ export const DatasetColumnConfig: Record< size="small" className="!min-w-[70px] !h-[20px] !px-[4px] !font-normal" > - 修改未提交 + {I18n.t('changes_not_submitted')} ) : null}
), }, description: { - title: '描述', - displayName: '描述', + title: I18n.t('description'), + displayName: I18n.t('description'), key: 'description', dataIndex: 'description', width: 170, render: text => {text}, }, columns: { - title: '列名', - displayName: '列名', + title: I18n.t('column_name'), + displayName: I18n.t('column_name'), key: 'columns', width: 300, render: record => , }, item_count: { - title:
数据项
, - displayName: '数据项', + title:
{I18n.t('data_item')}
, + displayName: I18n.t('data_item'), key: 'item_count', dataIndex: 'item_count', width: 100, @@ -77,16 +78,16 @@ export const DatasetColumnConfig: Record< ), }, latest_version: { - title: '最新版本', + title: I18n.t('latest_version'), key: 'latest_version', - displayName: '最新版本', + displayName: I18n.t('latest_version'), dataIndex: 'latest_version', width: 100, render: text => (text ? {text} : '-'), }, updated_by: { - title: '更新人', - displayName: '更新人', + title: I18n.t('updated_person'), + displayName: I18n.t('updated_person'), key: 'updated_by', dataIndex: 'base_info.updated_by', width: 180, @@ -98,9 +99,9 @@ export const DatasetColumnConfig: Record< ), }, update_at: { - title: '更新时间', + title: I18n.t('update_time'), key: 'updated_at', - displayName: '更新时间', + displayName: I18n.t('update_time'), width: 180, dataIndex: 'base_info.updated_at', sorter: true, @@ -115,8 +116,8 @@ export const DatasetColumnConfig: Record< ), }, created_by: { - title: '创建人', - displayName: '创建人', + title: I18n.t('creator'), + displayName: I18n.t('creator'), key: 'created_by', dataIndex: 'base_info.created_by', @@ -129,8 +130,8 @@ export const DatasetColumnConfig: Record< ), }, created_at: { - title: '创建时间', - displayName: '创建时间', + title: I18n.t('create_time'), + displayName: I18n.t('create_time'), key: 'created_at', width: 180, render: (record?: EvaluationSet) => diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/column-name-list-tag.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/column-name-list-tag.tsx index c0aa756cc..f63b437a3 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/column-name-list-tag.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/column-name-list-tag.tsx @@ -1,11 +1,17 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 import cs from 'classnames'; +import { I18n } from '@cozeloop/i18n-adapter'; import { type FieldSchema, type EvaluationSet, } from '@cozeloop/api-schema/evaluation'; -import { Dropdown, OverflowList, Tag, Typography } from '@coze-arch/coze-design'; +import { + Dropdown, + OverflowList, + Tag, + Typography, +} from '@coze-arch/coze-design'; import { getColumnType } from '../dataset-item/util'; import { dataTypeMap } from '../dataset-item/type'; @@ -23,7 +29,7 @@ export const ColumnNameListTag = ({ set }: { set: EvaluationSet }) => { borderBottom: '1px solid var(--semi-color-border)', }} > - + {I18n.t('column')} {items.length} @@ -51,7 +57,7 @@ export const ColumnNameListTag = ({ set }: { set: EvaluationSet }) => {
- 数据类型 + {I18n.t('data_type')} {dataTypeMap[getColumnType(item)]} @@ -59,7 +65,7 @@ export const ColumnNameListTag = ({ set }: { set: EvaluationSet }) => {
- 描述 + {I18n.t('description')} { size: 'large', className: 'w-[420px]', type: 'dialog', - title: '删除评测集', + title: I18n.t('delete_evaluation_set'), content: ( - 确定删除评测集 - - {row.name} - - 吗?此修改将不可逆。 + {I18n.t('confirm_to_delete_evaluation_set', { + name: ( + + {row.name} + + ), + })} ), autoLoading: true, @@ -66,8 +69,8 @@ export const DatasetList = () => { service.refresh(); }, showCancelButton: true, - cancelText: '取消', - okText: '删除', + cancelText: I18n.t('Cancel'), + okText: I18n.t('delete'), }); }; @@ -79,7 +82,7 @@ export const DatasetList = () => { const allColumns: ColumnProps[] = [ ...columns, { - title: '操作', + title: I18n.t('operation'), key: 'actions', width: 100, fixed: 'right', @@ -87,11 +90,11 @@ export const DatasetList = () => { handleDatasetBaseInfoEdit(record), }, { - label: '删除', + label: I18n.t('delete'), type: 'danger', onClick: () => handleDelete(record), disabled: guards.data.readonly, @@ -105,12 +108,12 @@ export const DatasetList = () => { return (
- +
@@ -169,15 +172,17 @@ export const DatasetList = () => { } - title="未能找到相关结果" - description={'请尝试其他关键词或修改筛选项'} + title={I18n.t('failed_to_find_related_results')} + description={I18n.t( + 'try_other_keywords_or_modify_filter_options', + )} /> ) : ( } - title="暂无评测集" - description={'点击右上角新建评测集按钮进行创建'} + title={I18n.t('no_evaluation_dataset')} + description={I18n.t('click_to_create_evaluation_set')} /> ) } diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/list-filter/index.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/list-filter/index.tsx index f67505bea..21c4870e3 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/list-filter/index.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/list-filter/index.tsx @@ -1,6 +1,7 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 import { useDebounceFn } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { GuardPoint, useGuard } from '@cozeloop/guard'; import { UserSelect } from '@cozeloop/biz-components-adapter'; import { type ListEvaluationSetsRequest } from '@cozeloop/api-schema/evaluation'; @@ -41,7 +42,7 @@ export const ListFilter = ({ filter, setFilter }: ListFilterProps) => { field="name" fieldClassName="!mr-0 !pr-0" className="!w-full" - placeholder="搜索名称" + placeholder={I18n.t('search_name')} prefix={} convert={value => value?.slice(0, 100)} showClear diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/sort-icon.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/sort-icon.tsx index e74928d25..bc230d092 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/sort-icon.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-list/sort-icon.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { type SVGAttributes } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { IconButtonContainer } from '@cozeloop/components'; import { Tooltip } from '@coze-arch/coze-design'; @@ -51,11 +52,11 @@ export default function LoopTableSortIcon({ }: { sortOrder?: 'ascend' | 'descend' | boolean; }) { - let tooltip = '点击升序'; + let tooltip = I18n.t('click_ascending'); if (sortOrder === 'ascend') { - tooltip = '点击降序'; + tooltip = I18n.t('click_descending'); } else if (sortOrder === 'descend') { - tooltip = '点击恢复默认排序'; + tooltip = I18n.t('restore_default_sort'); } return ( diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-version-tag/index.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-version-tag/index.tsx index 3e7f751a1..5de5a8999 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/dataset-version-tag/index.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/dataset-version-tag/index.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { type Version } from '@cozeloop/components'; import { type EvaluationSet } from '@cozeloop/api-schema/evaluation'; import { Tag } from '@coze-arch/coze-design'; @@ -24,11 +25,11 @@ export const DatasetVersionTag = ({ } return datasetDetail?.change_uncommitted ? ( - 修改未提交 + {I18n.t('changes_not_submitted')} ) : ( - 草稿版本 + {I18n.t('draft_version')} ); }; diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/evaluator-select-card/evaluator-field-card.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/evaluator-select-card/evaluator-field-card.tsx index 1960a89b7..de6da83ac 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/evaluator-select-card/evaluator-field-card.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/evaluator-select-card/evaluator-field-card.tsx @@ -1,9 +1,11 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +/* eslint-disable @coze-arch/max-line-per-function */ import { forwardRef, useImperativeHandle, useState } from 'react'; import classNames from 'classnames'; import { useRequest } from 'ahooks'; +import { I18n } from '@cozeloop/i18n-adapter'; import { useSpace } from '@cozeloop/biz-hooks-adapter'; import { type Evaluator, @@ -82,7 +84,7 @@ function FieldMappingCard({ onClick={e => e.stopPropagation()} className="flex flex-row items-center gap-1 invisible group-hover:visible" > - +
{!isError ? (
- {evaluatorResult?.score} 分 + {I18n.t('x_score', { num: evaluatorResult?.score || '-' })} - 得分仅预览效果,非实际结果。 + {I18n.t('score_only_for_preview')}
) : null} @@ -48,7 +51,8 @@ export function EvaluatorTestRunResult({ rows: 3, }} > - {errorMsg || `原因:${evaluatorResult?.reasoning ?? '-'}`} + {errorMsg || + I18n.t('reason_is', { reason: evaluatorResult?.reasoning ?? '-' })}
); diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/evaluator-version-detail.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/evaluator-version-detail.tsx index fbadd5039..4bbd765bc 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/evaluator-version-detail.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/evaluator-version-detail.tsx @@ -3,6 +3,7 @@ import { useState } from 'react'; import classNames from 'classnames'; +import { I18n } from '@cozeloop/i18n-adapter'; import { type EvaluatorVersion } from '@cozeloop/api-schema/evaluation'; import { IconCozArrowRight, IconCozEmpty } from '@coze-arch/coze-design/icons'; import { EmptyState, Loading } from '@coze-arch/coze-design'; @@ -32,7 +33,7 @@ export function EvaluatorVersionDetail({ )} onClick={() => setOpen(pre => !pre)} > - {'Prompt 详情'} + {I18n.t('prompt_detail')}
@@ -56,7 +57,7 @@ export function EvaluatorVersionDetail({ } - title="暂无数据" + title={I18n.t('no_data')} className={emptyStyles['empty-state']} // description="请选择评估器和版本号后再查看" /> diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/model-config-info/index.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/model-config-info/index.tsx index 2757e3717..b7687c9f5 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/model-config-info/index.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/evaluator/model-config-info/index.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { type ModelConfig } from '@cozeloop/api-schema/evaluation'; import { useGlobalEvalConfig } from '@/stores/eval-global-config'; @@ -9,7 +10,9 @@ export function ModelConfigInfo({ data }: { data?: ModelConfig }) { return ( <> -
{'模型'}
+
+ {I18n.t('model')} +
{ModelConfigEditor && data ? (
- {'输出'} - + {I18n.t('output')} +
- {'得分:'} + {I18n.t('score_is')} {toolsDescription?.score}
- {'原因:'} + + {I18n.t('reason_is', { reason: '' })} + {toolsDescription?.reason}
diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/experiments/contrast-chart/index.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/experiments/contrast-chart/index.tsx index 005f1079b..8839382a6 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/experiments/contrast-chart/index.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/experiments/contrast-chart/index.tsx @@ -5,6 +5,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { isEqual } from 'lodash-es'; import { useRequest } from 'ahooks'; import { type ISpec } from '@visactor/vchart'; +import { I18n } from '@cozeloop/i18n-adapter'; import { type Experiment, type Evaluator, @@ -192,8 +193,8 @@ function EvaluatorChart({ } - title="暂无数据" - description="实验完成后,再刷新重试" + title={I18n.t('no_data')} + description={I18n.t('refresh_after_experiment')} /> ) : ( -
总览
+
{I18n.t('overview')}
@@ -184,7 +185,7 @@ export function DatasetRelatedExperiment({ updateChartConfig('chartType', e.target.value); }} > - + - +
- 已选 {experiments.length} 条数据{' '} + {I18n.t('x_data_item_selected', { num: experiments.length })} { onCancelSelect?.(); }} > - 取消选择 + {I18n.t('unselect')}
@@ -65,10 +66,12 @@ export function ExperimentRowSelectionActions({ return; } Modal.confirm({ - title: '批量删除实验', - content: `确认批量删除 ${experiments.length} 条实验数据吗?此修改将不可逆。`, - okText: '删除', - cancelText: '取消', + title: I18n.t('batch_delete_experiment'), + content: I18n.t('confirm_batch_delete_x_experiment', { + num: experiments.length, + }), + okText: I18n.t('delete'), + cancelText: I18n.t('Cancel'), okButtonColor: 'red', width: 420, autoLoading: true, @@ -82,7 +85,7 @@ export function ExperimentRowSelectionActions({ }); }} > - 删除 + {I18n.t('delete')} diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/experiments/previews/experiment-list-empty-state.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/experiments/previews/experiment-list-empty-state.tsx index bc5d8d2c7..73ee2ae08 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/experiments/previews/experiment-list-empty-state.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/experiments/previews/experiment-list-empty-state.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { IconCozIllusAdd } from '@coze-arch/coze-design/illustrations'; import { EmptyState } from '@coze-arch/coze-design'; @@ -12,11 +13,15 @@ export function ExperimentListEmptyState({ } - title={hasFilterCondition ? '未能找到相关结果' : '暂无实验'} + title={ + hasFilterCondition + ? I18n.t('failed_to_find_related_results') + : I18n.t('no_experiment') + } description={ hasFilterCondition - ? '请尝试其他关键词或修改筛选项' - : '点击右上角新建实验按钮进行创建' + ? I18n.t('try_other_keywords_or_modify_filter_options') + : I18n.t('click_to_create_experiment') } /> ); diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/experiments/previews/experiment-run-status.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/experiments/previews/experiment-run-status.tsx index c43ff17d4..5f22f556a 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/experiments/previews/experiment-run-status.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/experiments/previews/experiment-run-status.tsx @@ -1,5 +1,6 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: Apache-2.0 +import { I18n } from '@cozeloop/i18n-adapter'; import { type Experiment, ExptStatus } from '@cozeloop/api-schema/evaluation'; import { Divider, Popover, Tag, type TagProps } from '@coze-arch/coze-design'; @@ -71,21 +72,23 @@ export function ExperimentRunStatus({ position="top" content={
-
总条数 {totalCount || 0}
- 成功 {success_turn_cnt} + {I18n.t('total')} {totalCount || 0} +
+
+ {I18n.t('success')} {success_turn_cnt} - 失败 {fail_turn_cnt} + {I18n.t('failure')} {fail_turn_cnt} {terminated_turn_cnt ? ( <> - 中止 {terminated_turn_cnt} + {I18n.t('abort')} {terminated_turn_cnt} - 执行中 {processing_turn_cnt} + {I18n.t('execution_in_progress')} {processing_turn_cnt} ) : null} - 待执行 {pending_turn_cnt} + {I18n.t('to_be_executed')} {pending_turn_cnt}
} diff --git a/frontend/packages/cozeloop/evaluate-components/src/components/id-with-copy.tsx b/frontend/packages/cozeloop/evaluate-components/src/components/id-with-copy.tsx index a054d3b56..0d32827e3 100644 --- a/frontend/packages/cozeloop/evaluate-components/src/components/id-with-copy.tsx +++ b/frontend/packages/cozeloop/evaluate-components/src/components/id-with-copy.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { type ReactNode } from 'react'; +import { I18n } from '@cozeloop/i18n-adapter'; import { IconCozCopy } from '@coze-arch/coze-design/icons'; import { Button, Toast, Tooltip } from '@coze-arch/coze-design'; @@ -24,18 +25,18 @@ export default function IDWithCopy({ #{suffix || '-'} {prefix ? prefix : null} - 数据项 ID + {I18n.t('data_item_id')} - +
@@ -166,7 +167,7 @@ export default function LogicEditor({ }} >