chore: replace all cn comments of fe to en version by volc api (#320)

This commit is contained in:
tecvan
2025-07-31 10:32:15 +08:00
committed by GitHub
parent 716ec0cba8
commit 71f6245a01
2960 changed files with 15545 additions and 15545 deletions

View File

@@ -14,13 +14,13 @@
* limitations under the License.
*/
/** 预置的特殊的 key */
/** Preset special key */
export enum LogObjSpecialKey {
Error = '$error',
Warning = '$warning',
}
/** log 中 value 的显示样式类型 */
/** Display style type of value in log */
export enum LogValueStyleType {
Default,
Number,

View File

@@ -22,7 +22,7 @@ import { shallow } from 'zustand/shallow';
import { type StoreApi } from 'zustand';
export interface DataViewerState {
// 折叠展开的状态
// Folded and unfolded state
expand: Record<string, boolean> | null;
setExpand: (key: string, v: boolean) => void;
}

View File

@@ -29,7 +29,7 @@ export const DataViewerProvider: React.FC<
> = ({ children, fields }) => {
const store = useMemo(() => createDataViewerStore(), []);
// 根只有一项且其可以下钻时,默认展开它
// When the root has only one item and it can be drilled down, it is expanded by default
useEffect(() => {
if (
store.getState().expand === null &&

View File

@@ -5,7 +5,7 @@
width: 100%;
user-select: text;
/** 高度限制 */
/** height limit */
max-height: 272px;
min-height: 24px;
overflow-y: scroll;

View File

@@ -27,7 +27,7 @@ import { DataViewerProvider } from './context';
import css from './data-viewer.module.less';
export interface DataViewerProps {
/** 支持对象或者纯文本渲染 */
/** Supports object or plain text rendering */
data: JsonValueType;
mdPreview?: boolean;
className?: string;

View File

@@ -30,7 +30,7 @@ export const useValue = (value: Field['value']) => {
type: LogValueStyleType.Default,
};
} else if (isObject(value)) {
// 大数字返回数字类型,值用字符串
// Large number Returns the numeric type, and the value is a string.
if (isBigNumber(value)) {
return {
value: bigNumberToString(value),

View File

@@ -32,10 +32,10 @@ import styles from './json-field.module.less';
const SPACE_WIDTH = 14;
/* JSON 类型数据渲染 */
/* JSON type data rendering */
const FieldValue: React.FC<{
value: Field['value'];
/** 是否是 markdown 格式 */
/** Is it in markdown format? */
isMarkdown?: boolean;
onMarkdownPreview?: () => void;
}> = ({ value, isMarkdown, onMarkdownPreview }) => {
@@ -52,7 +52,7 @@ const FieldValue: React.FC<{
>
{current}
</span>
{/* 预览 */}
{/* preview */}
{isMarkdown ? (
<Button
className={styles['value-button']}

View File

@@ -15,21 +15,21 @@
*/
/*******************************************************************************
* log 相关的类型
* Log related types
*/
/** 线可能存在的几种状态 */
/** The possible states of a line */
export enum LineStatus {
/** 完全隐藏,最后一个父属性嵌套的子属性同列将不会有线 */
/** Completely hidden, the last parent attribute nested child attribute will not be wired in the same column */
Hidden,
/** 完全显示,仅出现在属性相邻的线 */
/** Full display, appearing only on adjacent lines of properties */
Visible,
/** 半显示,非相邻的线 */
/** Semi-display, non-adjacent lines */
Half,
/** 最后属性的相邻线 */
/** Adjacent line of last property */
Last,
}
/** JsonViewer 中的 value 可能值 */
/** Possible values in JsonViewer */
export type JsonValueType =
| string
| null
@@ -39,12 +39,12 @@ export type JsonValueType =
| undefined;
export interface Field {
/** 使用数组而不是 'a.b.c' 是因为可能存在 key='a.b' 会产生错误嵌套 */
/** The use of arrays instead of'a.b.c 'is due to the possibility that key =' a.b 'will generate false nesting */
path: string[];
lines: LineStatus[];
/** 这里 value 可能是任意值,这里是不完全枚举 */
/** Here value can be any value, here is an incomplete enumeration */
value: JsonValueType;
children: Field[];
/** 是否是可下钻的对象(包含数组) */
/** Whether it is a drillable object (containing an array) */
isObj: boolean;
}

View File

@@ -17,7 +17,7 @@
import BigNumber from 'bignumber.js';
/**
* 是不是大数字
* Is it a big number?
* @param value
* @returns
*/
@@ -26,7 +26,7 @@ export function isBigNumber(value: unknown): value is BigNumber {
}
/**
* 大数字转字符串
* Large number to string
* @param value
* @returns
*/

View File

@@ -20,29 +20,29 @@ import { LineStatus, type JsonValueType, type Field } from '../types';
import { isBigNumber } from './big-number';
/**
* 通过父元素的线条状态推到子元素的线条状态
* Push through the line state of the parent element to the line state of the child element
*/
const getLineByParent2Child = (pLine: LineStatus): LineStatus => {
switch (pLine) {
/** 表示父节点也是从父父节点下钻而来,此处的子节点只需要把线延续下去即可 */
/** It means that the parent node is also drilled from the parent node, and the sub-node here only needs to continue the line. */
case LineStatus.Visible:
return LineStatus.Half;
/** 表示父节点是父父节点的最后一个节点,子节点无需再延续,渲染空白即可 */
/** Indicates that the parent node is the last node of the parent node, and the sub-node does not need to continue, just render blank. */
case LineStatus.Last:
return LineStatus.Hidden;
/** 其他的情况完全继承父节点的线 */
/** Other cases fully inherit the line of the parent node */
default:
return pLine;
}
};
/**
* object 解析成可以循环渲染的 fields
* 1. object 非复杂类型,则返回长度为 1 的 fields 只渲染一项
* 2. object = {},则返回长度为 0 的 fields渲染层需要做好兜底
* Parse objects into fields that can be cycled
* 1. If object is not a complex type, fields of length 1 are returned to render only one item
* 2. If object = {}, fields of length 0 are returned, and the rendering layer needs to be well covered
*/
const generateFields = (object: JsonValueType): Field[] => {
/** object 非复杂类型 */
/** If the object is not a complex type */
if (!isObject(object) || isBigNumber(object)) {
return [
{
@@ -55,17 +55,17 @@ const generateFields = (object: JsonValueType): Field[] => {
];
}
/** 递归计算时缓存一下计算好的线,没别的意义,降低一些时间复杂度 */
/** Cache the calculated line during recursive calculation, which is meaningless and reduces some time complexity */
const lineMap = new Map<string[], LineStatus[]>();
/** 递归解析 object fields */
/** Recursive parsing of object as fields */
const dfs = ($object: object, $parentPath: string[] = []): Field[] => {
// 如果不是对象,直接返回空数组,兜底异常情况
// If it is not an object, return an empty array directly to cover the exception
if (!isObject($object)) {
return [];
}
// 如果是大数字,直接返回空数组
// If it is a large number, return an empty array directly
if (isBigNumber($object)) {
return [];
}
@@ -79,12 +79,12 @@ const generateFields = (object: JsonValueType): Field[] => {
const path = $parentPath.concat(key);
const last = idx === keys.length - 1;
/**
* 根据父节点的线推导子节点的线
* Derive the sub-node's line from the parent's line
*/
const lines = parentLines
.map<LineStatus>(getLineByParent2Child)
/**
* 最后拼接上子节点自己的线,最后一个节点和普通的节点有样式区分
* Finally, splice the sub-node's own line, and the last node is distinguished from the ordinary node by style.
*/
.concat(last ? LineStatus.Last : LineStatus.Visible);
lineMap.set(path, lines);

View File

@@ -14,7 +14,7 @@
.image-item {
max-height: 280px;
aspect-ratio: 1 / 1; /* 宽高比为1:1 */
aspect-ratio: 1 / 1; /* The aspect ratio is 1:1. */
display: flex;
align-items: center;
justify-content: center;

View File

@@ -21,43 +21,43 @@ import { type LogValueType } from '../../../types';
const REASONING_CONTENT_NAME = 'reasoning_content';
interface isDifferentOutputArgs {
/** 节点输出 */
/** Node output */
nodeOutput: LogValueType;
/** 原始输出 */
/** raw output */
rawOutput: LogValueType;
/** 是否是大模型节点 */
/** Is it a large model node? */
isLLM?: boolean;
}
/**
* 通用的节点输出判异
* General Node Output Decision
*/
const isDifferentCommonOutput = (args: isDifferentOutputArgs) => {
const { nodeOutput, rawOutput } = args;
/**
* case1: rawOutput === undefined
* 可以无须比较,直接返回假
* You can directly return to the fake without comparison.
*/
if (isUndefined(rawOutput)) {
return false;
}
const nodeOutputType = typeof nodeOutput;
const rawOutputType = typeof rawOutput;
/** case2: 两者类型不同 */
/** Case2: The two types are different */
if (nodeOutputType !== rawOutputType) {
return true;
}
/** case4: 深度比较 */
/** Case4: Depth comparison */
return !isEqual(nodeOutput, rawOutput);
};
/**
* 大模型节点特有的判断逻辑
* The Unique Judgment Logic of Large Model Nodes
*/
const isDifferentLLMOutput = (args: isDifferentOutputArgs) => {
const { nodeOutput } = args;
/** 如果节点输出是对象,则去除系统字段 */
/** If the node output is an object, remove the system field */
const readNodeOutput = isObject(nodeOutput)
? omit(nodeOutput, [REASONING_CONTENT_NAME])
: nodeOutput;
@@ -65,21 +65,21 @@ const isDifferentLLMOutput = (args: isDifferentOutputArgs) => {
...args,
nodeOutput: readNodeOutput,
});
/** 常规判断已经判同,则直接返回 */
/** If the conventional judgment has been approved, it will return directly. */
if (!isDiffCommon) {
return isDiffCommon;
}
/** 如果不是节点输出不是对象,直接判异 */
/** If it is not a node, the output is not an object, and the direct judgment is */
if (!isObject(readNodeOutput)) {
return true;
}
const arr = Object.entries(readNodeOutput);
/** 如果排除系统字段,仍然超过多个字段,则无须进一步比较,直接判异 */
/** If the system field is excluded and there are still more than one field, there is no need for further comparison and a direct judgment is made */
if (arr.length !== 1) {
return true;
}
/** 用唯一的值与节点输出做异同判断 */
/** Use unique values to judge similarities and differences with node outputs */
return isDifferentCommonOutput({
...args,
nodeOutput: arr[0][1],
@@ -87,22 +87,22 @@ const isDifferentLLMOutput = (args: isDifferentOutputArgs) => {
};
/**
* 精细的判断节点输出和原始输出是否相同
* Fine determination of whether the node output and the original output are the same
*/
export const isDifferentOutput = (
args: isDifferentOutputArgs,
): [boolean, any] => {
/**
* nodeOutput 可能值:
* Possible nodeOutput values:
* 1. undefined
* 2. string
* 3. 包涵一个自定义字段、reasoning_contentLogObjSpecialKey
* 4. 包涵多个自定义字段
* rawOutput 可能值:
* 3. Includes a custom field, reasoning_content, LogObjSpecialKey
* 4. Include multiple custom fields
* rawOutput possible values:
* 1. undefined
* 2. string
* 4. 任意对象
* 5. 任意数组
* 4. Any object
* 5. Arbitrary array
*/
try {
const { isLLM } = args;
@@ -111,7 +111,7 @@ export const isDifferentOutput = (
: isDifferentCommonOutput(args);
return [result, undefined];
} catch (err) {
/** 该函数会深入解析日志结构,不排除出现异常的可能性,出现异常则判异, */
/** This function will deeply analyze the log structure and do not rule out the possibility of abnormalities. */
return [true, err];
}
};

View File

@@ -82,7 +82,7 @@ const updateOutputWithNewType = (
};
export const useSyncOutput = (outputPath: string, node: FlowNodeEntity) => {
// TODO: 改到 effects 中实现 ,依赖节点引擎支持自定义事件触发 effects
// TODO: Changed to effects, relying on the node engine to support custom event triggering effects
const updateOutput = (output: ParsedOutput[]) => {
if (outputPath) {
const formModel =

View File

@@ -32,7 +32,7 @@ const LLM_TEXT = {
const DEFAULT_TEXT = {
tabLabel: I18n.t('workflow_detail_testrun_panel_raw_output'),
};
/** 一些特化节点的文案 */
/** Copywriting for some specialized nodes */
const TEXT = {
Code: CODE_TEXT,
LLM: LLM_TEXT,
@@ -46,7 +46,7 @@ export enum TabValue {
export const useOutputLog = (log: OutputLog) => {
const [tab, setTab] = useState(TabValue.Output);
const reporter = useTestRunReporterService();
/** 是否渲染原始输出 */
/** Whether to render the original output */
const showRawOutput = useMemo(() => {
const [result, err] = isDifferentOutput({
nodeOutput: log.data,

View File

@@ -30,7 +30,7 @@ interface NodeStatusBarProps {
hasExecuteResult?: boolean;
needAuth?: boolean;
/**
* 是否包含会话处理
* Is session handling included?
*/
hasConversation?: boolean;
onAuth?: () => void;
@@ -73,9 +73,9 @@ export const NodeStatusBar: React.FC<
return (
<div
className={styles['node-status-bar']}
// 必须要禁止 down 冒泡,防止判定圈选和 node hover不支持多边形
// It is necessary to disable down bubbling to prevent judgment circling and node hovering (polygons are not supported)
onMouseDown={e => e.stopPropagation()}
// 其他事件统一走点击事件,且也需要阻止冒泡
// Other events uniformly go to the click event, and it is also necessary to prevent bubbling.
onClick={handleToggleShowDetail}
>
<div

View File

@@ -88,7 +88,7 @@ export const falseValue = {
[ConditionType.False]: () => I18n.t('workflow_detail_condition_select_false'),
};
// 等于、不等于、长度大于、长度大于等于、长度小于、长度小于等于、包含、不包含、为空、不为空
// equal to, not equal to, length greater than, length greater than or equal to, length less than, length less than or equal to, contain, do not contain, empty, not empty
export const stringConditionValueMap = merge(
{},
equalValue,
@@ -103,7 +103,7 @@ export const stringConditionValueMap = merge(
notEmptyValue,
);
// 等于、不等于、大于、大于等于、小于、小于等于、为空、不为空
// equal to, not equal to, greater than, greater than or equal to, less than, less than or equal to, empty, not empty
export const intConditionValueMap = merge(
{},
equalValue,
@@ -116,7 +116,7 @@ export const intConditionValueMap = merge(
smallerEqualValue,
);
// 等于、不等于、为True、为False、为空、不为空
// Equal to, not equal to, True, False, Null, Not Null
export const booleanConditionValueMap = merge(
{},
equalValue,
@@ -127,7 +127,7 @@ export const booleanConditionValueMap = merge(
falseValue,
);
// 等于、不等于、大于等于、小于等于、大于、小于、为空、不为空
// equal to, not equal to, greater than or equal to, less than or equal to, greater than, less than, empty, not empty
export const numberConditionValueMap = merge(
{},
equalValue,
@@ -140,7 +140,7 @@ export const numberConditionValueMap = merge(
notEmptyValue,
);
// 包含、不包含、为空、不为空
// Include, do not contain, empty, not empty
export const objectConditionValueMap = merge(
{},
includeValue,
@@ -149,7 +149,7 @@ export const objectConditionValueMap = merge(
notEmptyValue,
);
// 长度大于、长度大于等于、长度小于、长度小于等于、包含、不包含、为空、不为空
// Length greater than, length greater than or equal to, length less than, length less than or equal to, contain, do not contain, empty, not empty
export const arrayConditionValueMap = merge(
{},
lengthBiggerValue,
@@ -162,7 +162,7 @@ export const arrayConditionValueMap = merge(
notEmptyValue,
);
// 所有的值的集合
// The set of all values
export const totalConditionValueMap = merge(
{},
equalValue,

View File

@@ -20,21 +20,21 @@ export {
logicTextMap,
} from './condition';
/** 日志类型 */
/** log type */
export enum LogType {
/** 输入 */
/** input */
Input,
/** 输出 */
/** output */
Output,
/** 批处理数据 */
/** batch data */
Batch,
/** Condition */
Condition,
/** 大模型推理过程 */
/** Large model reasoning process */
Reasoning,
/** 大模型Function过程 */
/** Large Model Function Process */
FunctionCall,
/** 子流程跳转连接 */
/** Subprocess jump connection */
WorkflowLink,
}

View File

@@ -18,7 +18,7 @@ import { type WorkflowLinkLogData } from '@/types';
import { type LogType } from './constants';
/** log 中的 value 可能值 */
/** Possible values in the log */
export type LogValueType =
| string
| null
@@ -27,7 +27,7 @@ export type LogValueType =
| boolean
| undefined;
/** 通常的日志结构 */
/** Normal log structure */
export interface BaseLog {
label: string;
data: LogValueType;
@@ -37,7 +37,7 @@ export interface BaseLog {
}
/**
* condition 的值
* Value of condition
*/
export interface ConditionData {
leftData: LogValueType;
@@ -51,7 +51,7 @@ export interface ConditionGroup {
logicData: string;
}
/** condition 的日志结构 */
/** Log structure for conditions */
export interface ConditionLog {
conditions: ConditionGroup[];
type: LogType.Condition;
@@ -72,14 +72,14 @@ export interface FunctionCallLog {
}
/**
* 输出的日志结构
* Output log structure
*/
export interface OutputLog {
label: string;
data: LogValueType;
copyTooltip?: string;
type: LogType.Output;
/** 节点类型 */
/** Node type */
nodeType: string;
mockInfo?: {
isHit: boolean;

View File

@@ -24,21 +24,21 @@ import {
} from '../types';
import { LogType } from '../constants';
/** 是否是输出日志 */
/** Is it an output log? */
export const isOutputLog = (log: Log): log is OutputLog =>
log.type === LogType.Output;
/** 是否是 condition 输入 */
/** Is it condition input? */
export const isConditionLog = (log: Log): log is ConditionLog =>
log.type === LogType.Condition;
/** 是否是大模型推理日志 */
/** Is it a large model inference log? */
export const isReasoningLog = (log: Log): log is BaseLog =>
log.type === LogType.Reasoning;
export const isFunctionCallLog = (log: Log): log is FunctionCallLog =>
log.type === LogType.FunctionCall;
/** 是否是子流程跳转连接 */
/** Is it a subprocess jump connection? */
export const isWorkflowLinkLog = (log: Log): log is WorkflowLinkLog =>
log.type === LogType.WorkflowLink;

View File

@@ -75,20 +75,20 @@ const generateBatchData = (result: NodeResult): Log => {
const generateInput = (logs: Log[], result: NodeResult) => {
const { NodeType: type } = result;
/** input 不可能是 string所以使用 {} 兜底,异常情况直接展示空即可 */
/** The input cannot be a string, so use {} to cover the bottom, and the exception can be directly displayed empty. */
const inputData = (typeSafeJSONParse(result.input, {
emptyValue: result.input,
enableBigInt,
}) || {}) as LogValueType;
/** step 1.1: condition 节点单独处理 */
/** Step 1.1: condition node handled separately */
if (type === 'If') {
const normalizeConditions = normalizeConditionInputData(inputData);
const conditions = normalizeConditions.map(branch => ({
conditions: branch.conditions.map(condition => {
/** 右值不一定存在 */
/** An rvalue doesn't necessarily exist */
const { left, right = {}, operator } = condition;
const operatorFn = totalConditionValueMap[operator];
/** 后端的 operator 枚举值通过 i18n 转化为文本 */
/** Back-end operator enumeration values are converted to text via i18n */
const operatorData = isFunction(operatorFn) ? operatorFn() : operator;
const leftData = left?.key ? { [left?.key]: left?.value } : left?.value;
const rightData =
@@ -108,7 +108,7 @@ const generateInput = (logs: Log[], result: NodeResult) => {
}));
logs.push({ conditions, type: LogType.Condition });
} else {
/** end、Message 节点的 label 不同,输入即输出 */
/** Different labels of end and message nodes, input is output */
const isOutputNode = type === 'End' || type === 'Message';
const label = isOutputNode
? I18n.t('workflow_detail_end_output')
@@ -142,26 +142,26 @@ const generateOutput = (
const { hitStatus: mockHitStatus, mockSetName } =
(typeSafeJSONParse(mockHitInfo) as any) || {};
/**
* case1: output 解析成功,可能是对象或者字符串
* case2: output 解析失败,可能是字符串
* case3: output 为空值,兜底展示空对象
* Case1: output parsed successfully, may be an object or string
* Case2: output parsing failed, possibly string
* Case3: output is null, the empty object is displayed at the bottom
*/
let outputData =
typeSafeJSONParse(result.output, { enableBigInt }) || result.output || {};
/** step 2.1: 处理 rawOutput */
/** Step 2.1: Handling rawOutput */
/**
* case1: output 解析成功,可能是对象或者字符串
* case2: output 解析失败,可能是字符串,由于是原始输出空值也视为有意义
* Case1: output parsed successfully, may be an object or string
* Case2: output parsing failed, it may be a string, because it is the original output null value, it is also considered meaningful
*/
const rawData =
typeSafeJSONParse(result.raw_output, { enableBigInt }) || result.raw_output;
/** CodeLlm 节点需要展示 raw */
/** Code, Llm nodes need to display raw */
const textHasRawout = type === 'Text' && hasStringOutput(rawData);
const hasRawOutput =
(type && ['Code', 'LLM', 'Question'].includes(type)) || textHasRawout;
/** step 2.2: 处理 errorInfo */
/** Step 2.2: Handling errorInfo */
if (errorInfo) {
const errorData = {
[errorLevel === 'Error'
@@ -169,9 +169,9 @@ const generateOutput = (
: LogObjSpecialKey.Warning]: errorInfo,
};
/**
* 错误放到 output 中展示,output 的展示优先级最高
* output 为对象则直接 assign error
* 否则 output 需要被赋值到 output 字段并和 error 组成一个对象
* Errors are displayed in output, and output has the highest priority
* If the output is an object, directly assign error
* Otherwise, output needs to be assigned to the output field and formed into an object with error
*/
outputData = isObject(outputData)
? {
@@ -269,19 +269,19 @@ export const generateLog = (
const logs: Log[] = [];
/** step 0: 处理 batch data */
/** Step 0: Processing batch data */
if (isBatch) {
logs.push(generateBatchData(result));
}
/** step 1: 处理 input */
/** Step 1: Process the input */
generateInput(logs, result);
/** step 2: 处理 output */
/** Step 2: Process the output */
generateOutput(logs, result, node);
/** step 3: 对于子工作流节点,生成额外的跳转链接 */
/** Step 3: For child workflow nodes, generate additional jump links */
generateExternalLink(logs, result, node);
return {

View File

@@ -19,10 +19,10 @@ import remarkParse from 'remark-parse';
import { isString } from 'lodash-es';
/**
* 是否符合渲染为 markdown
* 1. ast > 1
* 2. ast = 1 且类型不为普通段落
* 2. ast = 1 且类型为普通段落,但段落中超过两个或者仅有一项但不为 text
* Is it consistent with rendering as markdown?
* 1. ast > 1 or
* 2. ast = 1 and the type is not a normal paragraph
* 2. ast = 1 and the type is normal paragraph, but there are more than two paragraphs or only one item in the paragraph but not text
*/
export const isPreviewMarkdown = (str: unknown) => {
if (!isString(str)) {

View File

@@ -194,7 +194,7 @@ export function parseFunctionCall(
const type = get(output, 'msg_type');
const skills = getNodeSkills(node);
// 知识库类型
// Knowledge base type
if (type === 'knowledge_recall') {
const data: FunctionCallKnowledgeOutput = JSON.parse(
get(output, 'data', '{}') as string,
@@ -202,12 +202,12 @@ export function parseFunctionCall(
return getDatasetLogItem(data, skills);
}
// 插件类型
// plugin type
if (input?.plugin_type === LLMNodeDataSkillType.Plugin) {
return getPluginLogItem(input, output, skills);
}
// Workflow类型
// Workflow Type
if (input?.plugin_type === LLMNodeDataSkillType.Workflow) {
return getWorkflowLogItem(input, output, skills);
}