chore: replace all cn comments of fe to en version by volc api (#320)
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
width: 100%;
|
||||
user-select: text;
|
||||
|
||||
/** 高度限制 */
|
||||
/** height limit */
|
||||
max-height: 272px;
|
||||
min-height: 24px;
|
||||
overflow-y: scroll;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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']}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_content、LogObjSpecialKey
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
/** Code、Llm 节点需要展示 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 {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user