chore: replace all cn comments of fe to en version by volc api (#320)
This commit is contained in:
@@ -27,7 +27,7 @@ import {
|
||||
|
||||
describe('with-query-client.tsx', () => {
|
||||
beforeEach(() => {
|
||||
// 清理 QueryClient 缓存
|
||||
// Clean up the QueryClient cache
|
||||
workflowQueryClient.clear();
|
||||
});
|
||||
|
||||
@@ -89,10 +89,10 @@ describe('with-query-client.tsx', () => {
|
||||
const WrappedComponent = withQueryClient(TestComponent);
|
||||
const { container } = render(<WrappedComponent />);
|
||||
|
||||
// 初始加载状态
|
||||
// initial loading state
|
||||
expect(container.innerHTML).toContain('Loading...');
|
||||
|
||||
// 等待数据加载完成
|
||||
// Wait for data loading to complete
|
||||
await waitFor(() => {
|
||||
expect(container.innerHTML).toContain('test data');
|
||||
});
|
||||
@@ -198,10 +198,10 @@ describe('with-query-client.tsx', () => {
|
||||
const WrappedComponent = withQueryClient(ParentComponent);
|
||||
const { container } = render(<WrappedComponent />);
|
||||
|
||||
// 初始加载状态
|
||||
// initial loading state
|
||||
expect(container.innerHTML).toContain('Loading Parent...');
|
||||
|
||||
// 等待所有查询完成
|
||||
// Wait for all queries to complete
|
||||
await waitFor(() => {
|
||||
expect(container.innerHTML).toContain('parent data');
|
||||
expect(container.innerHTML).toContain('child data');
|
||||
|
||||
@@ -28,7 +28,7 @@ vi.mock('../../src/entities', async () => {
|
||||
const actual = await vi.importActual('../../src/entities');
|
||||
return {
|
||||
...actual,
|
||||
// 如果需要mock其他实体,可以在这里添加
|
||||
// If you need to mock other entities, you can add them here.
|
||||
};
|
||||
});
|
||||
|
||||
@@ -198,7 +198,7 @@ describe('WorkflowNode', () => {
|
||||
const newData = { test: 'new data' };
|
||||
workflowNode.setData(newData);
|
||||
|
||||
// 验证原始数据没有被修改
|
||||
// Verify that the original data source has not been modified
|
||||
expect(newData).toEqual({ test: 'new data' });
|
||||
expect(mockFormItem.value).toEqual({ test: 'new data' });
|
||||
});
|
||||
|
||||
@@ -56,7 +56,7 @@ vi.mock('../../src/utils', () => ({
|
||||
describe('useNodeTestId', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
// 设置 concatTestId 的默认行为
|
||||
// Set the default behavior of concatTestId
|
||||
mockConcatTestId.mockImplementation((...args: string[]) => args.join('.'));
|
||||
});
|
||||
|
||||
@@ -99,8 +99,8 @@ describe('useNodeTestId', () => {
|
||||
it('应该返回正确的节点设置器 ID', () => {
|
||||
mockUseCurrentEntity.mockReturnValue({ id: '123' });
|
||||
mockConcatTestId
|
||||
.mockReturnValueOnce('playground.node.123') // 用于 getNodeTestId
|
||||
.mockReturnValueOnce('playground.node.123.llm'); // 用于 getNodeSetterId
|
||||
.mockReturnValueOnce('playground.node.123') // For getNodeTestId
|
||||
.mockReturnValueOnce('playground.node.123.llm'); // For getNodeSetterId
|
||||
|
||||
const { result } = renderHook(() => useNodeTestId());
|
||||
|
||||
@@ -140,7 +140,7 @@ describe('useNodeTestId', () => {
|
||||
});
|
||||
|
||||
it('应该在多个组件中返回不同的节点测试 ID', () => {
|
||||
// 第一个组件
|
||||
// The first component
|
||||
mockUseCurrentEntity.mockReturnValue({ id: '123' });
|
||||
mockConcatTestId.mockReturnValueOnce('playground.node.123');
|
||||
|
||||
@@ -148,7 +148,7 @@ describe('useNodeTestId', () => {
|
||||
expect(result1.current.getNodeTestId()).toBe('playground.node.123');
|
||||
expect(mockConcatTestId).toHaveBeenCalledWith('playground.node', '123');
|
||||
|
||||
// 第二个组件
|
||||
// The second component
|
||||
mockUseCurrentEntity.mockReturnValue({ id: '456' });
|
||||
mockConcatTestId.mockReturnValueOnce('playground.node.456');
|
||||
|
||||
@@ -158,11 +158,11 @@ describe('useNodeTestId', () => {
|
||||
});
|
||||
|
||||
it('应该在多个组件中返回不同的节点设置器 ID', () => {
|
||||
// 第一个组件
|
||||
// The first component
|
||||
mockUseCurrentEntity.mockReturnValue({ id: '123' });
|
||||
mockConcatTestId
|
||||
.mockReturnValueOnce('playground.node.123') // 用于 getNodeTestId
|
||||
.mockReturnValueOnce('playground.node.123.llm'); // 用于 getNodeSetterId
|
||||
.mockReturnValueOnce('playground.node.123') // For getNodeTestId
|
||||
.mockReturnValueOnce('playground.node.123.llm'); // For getNodeSetterId
|
||||
|
||||
const { result: result1 } = renderHook(() => useNodeTestId());
|
||||
expect(result1.current.getNodeSetterId('llm')).toBe(
|
||||
@@ -179,11 +179,11 @@ describe('useNodeTestId', () => {
|
||||
'llm',
|
||||
);
|
||||
|
||||
// 第二个组件
|
||||
// The second component
|
||||
mockUseCurrentEntity.mockReturnValue({ id: '456' });
|
||||
mockConcatTestId
|
||||
.mockReturnValueOnce('playground.node.456') // 用于 getNodeTestId
|
||||
.mockReturnValueOnce('playground.node.456.llm'); // 用于 getNodeSetterId
|
||||
.mockReturnValueOnce('playground.node.456') // For getNodeTestId
|
||||
.mockReturnValueOnce('playground.node.456.llm'); // For getNodeSetterId
|
||||
|
||||
const { result: result2 } = renderHook(() => useNodeTestId());
|
||||
expect(result2.current.getNodeSetterId('llm')).toBe(
|
||||
|
||||
@@ -22,7 +22,7 @@ import { useWorkflowStore } from '../../../src/store/workflow';
|
||||
|
||||
describe('useWorkflowStore', () => {
|
||||
beforeEach(() => {
|
||||
// 重置 store 状态
|
||||
// Reset store state
|
||||
useWorkflowStore.setState({
|
||||
nodes: [],
|
||||
edges: [],
|
||||
@@ -63,7 +63,7 @@ describe('useWorkflowStore', () => {
|
||||
});
|
||||
|
||||
it('应该能够重置为空数组', () => {
|
||||
// 先设置一些数据
|
||||
// Let's set up some data.
|
||||
useWorkflowStore.getState().setNodes([
|
||||
{
|
||||
id: '1',
|
||||
@@ -75,7 +75,7 @@ describe('useWorkflowStore', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
// 设置为空数组
|
||||
// Set to empty array
|
||||
useWorkflowStore.getState().setNodes([]);
|
||||
expect(useWorkflowStore.getState().nodes).toEqual([]);
|
||||
});
|
||||
@@ -99,7 +99,7 @@ describe('useWorkflowStore', () => {
|
||||
});
|
||||
|
||||
it('应该能够重置为空数组', () => {
|
||||
// 先设置一些数据
|
||||
// Let's set up some data.
|
||||
useWorkflowStore.getState().setEdges([
|
||||
{
|
||||
sourceNodeID: '1',
|
||||
@@ -107,7 +107,7 @@ describe('useWorkflowStore', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
// 设置为空数组
|
||||
// Set to empty array
|
||||
useWorkflowStore.getState().setEdges([]);
|
||||
expect(useWorkflowStore.getState().edges).toEqual([]);
|
||||
});
|
||||
@@ -115,11 +115,11 @@ describe('useWorkflowStore', () => {
|
||||
|
||||
describe('setIsCreatingWorkflow', () => {
|
||||
it('应该正确设置创建状态', () => {
|
||||
// 设置为 true
|
||||
// Set to true
|
||||
useWorkflowStore.getState().setIsCreatingWorkflow(true);
|
||||
expect(useWorkflowStore.getState().isCreatingWorkflow).toBe(true);
|
||||
|
||||
// 设置为 false
|
||||
// Set to false
|
||||
useWorkflowStore.getState().setIsCreatingWorkflow(false);
|
||||
expect(useWorkflowStore.getState().isCreatingWorkflow).toBe(false);
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
describe('node-type', () => {
|
||||
describe('StandardNodeType', () => {
|
||||
it('应该包含所有预定义的节点类型', () => {
|
||||
// 测试一些关键的节点类型
|
||||
// Test some key node types
|
||||
expect(StandardNodeType.Start).toBe('1');
|
||||
expect(StandardNodeType.End).toBe('2');
|
||||
expect(StandardNodeType.LLM).toBe('3');
|
||||
|
||||
@@ -29,7 +29,7 @@ describe('is-general-workflow', () => {
|
||||
});
|
||||
|
||||
it('应该在 flowMode 为其他值时返回 false', () => {
|
||||
// 测试其他可能的 WorkflowMode 值
|
||||
// Test other possible WorkflowMode values
|
||||
expect(isGeneralWorkflow(WorkflowMode.Imageflow)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,17 +27,17 @@ vi.mock('@coze-arch/bot-utils', () => ({
|
||||
typeSafeJSONParse: (str: string) => {
|
||||
try {
|
||||
const result = JSON.parse(str);
|
||||
// 如果是批处理数据,确保返回数组类型
|
||||
// If it is batch data, make sure to return an array type
|
||||
if (str === 'invalid json') {
|
||||
return str;
|
||||
}
|
||||
// 如果是批处理数据,确保返回数组类型
|
||||
// If it is batch data, make sure to return an array type
|
||||
if (str.includes('batch')) {
|
||||
return Array.isArray(result) ? result : [];
|
||||
}
|
||||
return result;
|
||||
} catch {
|
||||
// 如果是批处理数据,返回空数组
|
||||
// If it is batch data, return an empty array
|
||||
if (str.includes('batch')) {
|
||||
return [];
|
||||
}
|
||||
@@ -110,7 +110,7 @@ describe('default-parser', () => {
|
||||
expect(result.nodeType).toBe(StandardNodeType.LLM);
|
||||
expect(result.isBatch).toBe(false);
|
||||
expect(result.caseResult).toHaveLength(1);
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(3); // 输入、原始输出、最终输出
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(3); // Input, original output, final output
|
||||
});
|
||||
|
||||
it('应该正确解析 Code 节点结果', () => {
|
||||
@@ -122,7 +122,7 @@ describe('default-parser', () => {
|
||||
const result = defaultParser(nodeResult, workflowSchema);
|
||||
|
||||
expect(result.nodeType).toBe(StandardNodeType.Code);
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(3); // 输入、原始输出、最终输出
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(3); // Input, original output, final output
|
||||
});
|
||||
|
||||
it('应该正确解析 Start 节点结果', () => {
|
||||
@@ -134,7 +134,7 @@ describe('default-parser', () => {
|
||||
const result = defaultParser(nodeResult, workflowSchema);
|
||||
|
||||
expect(result.nodeType).toBe(StandardNodeType.Start);
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(1); // 只有输入
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(1); // input only
|
||||
});
|
||||
|
||||
it('应该正确解析 End 节点结果', () => {
|
||||
@@ -154,7 +154,7 @@ describe('default-parser', () => {
|
||||
const result = defaultParser(nodeResult, workflowSchema);
|
||||
|
||||
expect(result.nodeType).toBe(StandardNodeType.End);
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(2); // 输出变量、回答内容
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(2); // Output variables, answer content
|
||||
});
|
||||
|
||||
it('应该正确解析 Message 节点结果', () => {
|
||||
@@ -166,7 +166,7 @@ describe('default-parser', () => {
|
||||
const result = defaultParser(nodeResult, workflowSchema);
|
||||
|
||||
expect(result.nodeType).toBe(StandardNodeType.Output);
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(2); // 输出变量、回答内容
|
||||
expect(result.caseResult?.[0].dataList).toHaveLength(2); // Output variables, answer content
|
||||
});
|
||||
|
||||
it('应该正确解析包含图片的输出', () => {
|
||||
@@ -256,7 +256,7 @@ describe('default-parser', () => {
|
||||
|
||||
it('应该正确处理 Text 节点的原始输出', () => {
|
||||
const nodeResult = createMockNodeResult('1', {
|
||||
raw_output: '{"key": "value"}', // 即使是有效的 JSON 字符串也应该保持原样
|
||||
raw_output: '{"key": "value"}', // Even valid JSON strings should remain intact
|
||||
});
|
||||
const workflowSchema = createMockWorkflowSchema(
|
||||
'1',
|
||||
@@ -272,7 +272,7 @@ describe('default-parser', () => {
|
||||
|
||||
it('应该正确处理不存在的节点类型', () => {
|
||||
const nodeResult = createMockNodeResult('1');
|
||||
const workflowSchema = createMockWorkflowSchema('2'); // 不同的节点 ID
|
||||
const workflowSchema = createMockWorkflowSchema('2'); // Different node IDs
|
||||
const result = defaultParser(nodeResult, workflowSchema);
|
||||
|
||||
expect(result.nodeType).toBeUndefined();
|
||||
|
||||
@@ -184,7 +184,7 @@ describe('ref-input-parameters-parser', () => {
|
||||
param4: undefined,
|
||||
param5: {
|
||||
type: 'string',
|
||||
value: {}, // 空的 value 对象
|
||||
value: {}, // Empty value object
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -21,7 +21,7 @@ export * from '@coze-arch/bot-api/workflow_api';
|
||||
|
||||
export { withQueryClient, workflowQueryClient } from './with-query-client';
|
||||
|
||||
/** 运营接口平台,会替换权限验证 */
|
||||
/** Operating the interface platform will replace permission verification */
|
||||
const workflowOperationApiNameMap = {
|
||||
GetHistorySchema: 'OPGetHistorySchema',
|
||||
GetWorkFlowProcess: 'OPGetWorkFlowProcess',
|
||||
|
||||
@@ -14,35 +14,35 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 空方法 */
|
||||
/** empty method */
|
||||
export const EmptyFunction = () => {
|
||||
/** 空方法 */
|
||||
/** empty method */
|
||||
};
|
||||
export const EmptyAsyncFunction = () => Promise.resolve();
|
||||
|
||||
/** 公共空间 ID */
|
||||
/** Public space ID */
|
||||
export const PUBLIC_SPACE_ID = '999999';
|
||||
|
||||
/** BOT_USER_INPUT 变量名 */
|
||||
/** BOT_USER_INPUT variable name */
|
||||
export const BOT_USER_INPUT = 'BOT_USER_INPUT';
|
||||
|
||||
/** USER_INPUT 参数,新版 BOT_USER_INPUT 参数,作用和 BOT_USER_INPUT 相同,Coze2.0 Chatflow 需求引入 */
|
||||
/** USER_INPUT parameters, the new version BOT_USER_INPUT parameters, the same function as BOT_USER_INPUT, Coze2.0 Chatflow requirements are introduced */
|
||||
export const USER_INPUT = 'USER_INPUT';
|
||||
|
||||
/** CONVERSATION_NAME 变量名,start 节点会话名称入参 */
|
||||
/** CONVERSATION_NAME variable name, start node session name imported parameter */
|
||||
export const CONVERSATION_NAME = 'CONVERSATION_NAME';
|
||||
|
||||
/**
|
||||
* workflow 名称最大字符数
|
||||
* Workflow name Maximum number of characters
|
||||
*/
|
||||
export const WORKFLOW_NAME_MAX_LEN = 30;
|
||||
|
||||
/**
|
||||
* 工作流命名正则
|
||||
* workflow naming regular
|
||||
*/
|
||||
export const WORKFLOW_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9_]{0,63}$/;
|
||||
|
||||
/**
|
||||
* 节点测试ID前缀
|
||||
* Node test ID prefix
|
||||
*/
|
||||
export const NODE_TEST_ID_PREFIX = 'playground.node';
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* 业务层流程节点类 (对节点业务规则的封装)
|
||||
* Business layer process node class (encapsulation of node business rules)
|
||||
*/
|
||||
import {
|
||||
FlowNodeErrorData,
|
||||
@@ -69,7 +69,7 @@ export class WorkflowNode {
|
||||
}
|
||||
}
|
||||
|
||||
// 这个方法建议暂时先不要使用 原因是该方法没有体现业务逻辑 只是底层方法的简化
|
||||
// This method is recommended not to be used for the time being, because it does not reflect business logic, but is a simplification of the underlying method
|
||||
protected getFormValueByPathEnds<T = unknown>(
|
||||
pathEnds: string,
|
||||
): T | undefined {
|
||||
|
||||
@@ -21,21 +21,21 @@ import { concatTestId } from '../utils';
|
||||
import { NODE_TEST_ID_PREFIX } from '../constants';
|
||||
|
||||
/**
|
||||
* 仅限在 node 内使用
|
||||
* Only used within the node
|
||||
*/
|
||||
type UseNodeTestId = () => {
|
||||
/**
|
||||
* 返回当前节点的 test-id,也就是当前节点的 node id
|
||||
* Returns the test-id of the current node, which is the node id of the current node.
|
||||
* 'playground.11001
|
||||
*/
|
||||
getNodeTestId: () => string;
|
||||
/**
|
||||
* 返回当前 setter 的 test-id,会自动带上节点的 test-id
|
||||
* Returns the test-id of the current setter, which will automatically bring the test-id of the node.
|
||||
* 'playground.11001.llm'
|
||||
*/
|
||||
getNodeSetterId: (setterName: string) => string;
|
||||
/**
|
||||
* 连接两个 test-id,生成一个新的 test-id
|
||||
* Connect two test-ids to generate a new test-id.
|
||||
* ('a', 'b') => 'a.b'
|
||||
*/
|
||||
concatTestId: typeof concatTestId;
|
||||
@@ -55,17 +55,17 @@ export const useNodeTestId: UseNodeTestId = () => {
|
||||
|
||||
return {
|
||||
/**
|
||||
* 返回当前节点的 test-id,也就是当前节点的 node id
|
||||
* Returns the test-id of the current node, which is the node id of the current node.
|
||||
* 'playground.11001
|
||||
*/
|
||||
getNodeTestId,
|
||||
/**
|
||||
* 返回当前 setter 的 test-id,会自动带上节点的 test-id
|
||||
* Returns the test-id of the current setter, which will automatically bring the test-id of the node.
|
||||
* 'playground.11001.llm'
|
||||
*/
|
||||
getNodeSetterId: setterName => concatTestId(getNodeTestId(), setterName),
|
||||
/**
|
||||
* 连接两个 test-id,生成一个新的 test-id
|
||||
* Connect two test-ids to generate a new test-id.
|
||||
* ('a', 'b') => 'a.b'
|
||||
*/
|
||||
concatTestId,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* 抽象类
|
||||
* abstract class
|
||||
*/
|
||||
export {
|
||||
ValidationService,
|
||||
|
||||
@@ -29,20 +29,20 @@ export const useValidationServiceStore = <T>(
|
||||
) => useValidationService().store(selector);
|
||||
|
||||
export interface ValidateError {
|
||||
// 错误描述
|
||||
// error description
|
||||
errorInfo: string;
|
||||
// 错误等级
|
||||
// error level
|
||||
errorLevel: FeedbackStatus;
|
||||
// 错误类型: 节点 / 连线
|
||||
// Error Type: Node/Connection
|
||||
errorType: 'node' | 'line';
|
||||
// 节点id
|
||||
// Node ID
|
||||
nodeId: string;
|
||||
// 若为连线错误,还需要目标节点来确认这条连线
|
||||
// In the case of a connection error, the target node is also required to confirm the connection
|
||||
targetNodeId?: string;
|
||||
}
|
||||
export interface WorkflowValidateError {
|
||||
workflowId: string;
|
||||
/** 流程名 */
|
||||
/** process name */
|
||||
name?: string;
|
||||
errors: ValidateErrorMap;
|
||||
}
|
||||
@@ -61,12 +61,12 @@ export interface ValidateResultV2 {
|
||||
|
||||
export interface ValidationState {
|
||||
/**
|
||||
* @deprecated 请使用 errorsV2
|
||||
* @deprecated Please use errorsV2
|
||||
*/
|
||||
errors: ValidateErrorMap;
|
||||
/** 按照流程归属分类的错误 */
|
||||
/** Errors classified by process attribution */
|
||||
errorsV2: WorkflowValidateErrorMap;
|
||||
/** 正在校验中 */
|
||||
/** Verifying now. */
|
||||
validating: boolean;
|
||||
}
|
||||
|
||||
@@ -74,48 +74,48 @@ export interface ValidationService {
|
||||
store: UseBoundStoreWithEqualityFn<StoreApi<ValidationState>>;
|
||||
|
||||
/**
|
||||
* 前端流程校验,包括节点、表单、端口等
|
||||
* Front-end process validation, including nodes, forms, ports, etc
|
||||
*/
|
||||
validateWorkflow: () => Promise<ValidateResult>;
|
||||
|
||||
/**
|
||||
* 对节点的校验,包括表单、端口等
|
||||
* Verification of nodes, including forms, ports, etc
|
||||
*/
|
||||
validateNode: (node: WorkflowNodeEntity) => Promise<ValidateResult>;
|
||||
|
||||
/**
|
||||
* @deprecated 请使用 validateSchemaV2
|
||||
* 流程定义合法性校验,通常为后端校验
|
||||
* @Deprecated please use validateSchemaV2
|
||||
* Process definition validation, usually backend validation
|
||||
*/
|
||||
validateSchema: () => Promise<ValidateResult>;
|
||||
/**
|
||||
* 流程定义合法性校验,通常为后端校验
|
||||
* Process definition validation, usually backend validation
|
||||
*/
|
||||
validateSchemaV2: () => Promise<ValidateResultV2>;
|
||||
|
||||
/**
|
||||
* 获取指定 id 的错误列表
|
||||
* Gets the error list for the specified id
|
||||
*/
|
||||
getErrors: (id: string) => ValidateError[];
|
||||
/**
|
||||
* @deprecated 请使用 setErrorsV2
|
||||
* 设置错误
|
||||
* @deprecated Please use setErrorsV2
|
||||
* setting error
|
||||
* @param errors
|
||||
* @param force 强制覆盖所有错误
|
||||
* @param force to overwrite all errors
|
||||
*/
|
||||
setErrors: (errors: ValidationState['errors'], force?: boolean) => void;
|
||||
|
||||
/**
|
||||
* 设置错误
|
||||
* setting error
|
||||
* @param errors
|
||||
* @returns
|
||||
*/
|
||||
setErrorsV2: (errors: ValidationState['errorsV2']) => void;
|
||||
/**
|
||||
* 清空所有错误
|
||||
* Clear all errors
|
||||
*/
|
||||
clearErrors: () => void;
|
||||
/** 线条是否存在错误 */
|
||||
/** Is there an error in the line? */
|
||||
isLineError: (fromId: string, toId?: string) => boolean;
|
||||
|
||||
get validating(): boolean;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// workflow store,目前保存 flow 的 nodes 和 edges 数据
|
||||
// Workflow store, currently holds the nodes and edges data of the flow
|
||||
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { create } from 'zustand';
|
||||
@@ -24,13 +24,13 @@ import {
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
interface WorkflowStoreState {
|
||||
/** 节点数据 */
|
||||
/** node data */
|
||||
nodes: WorkflowNodeJSON[];
|
||||
|
||||
/** 边数据 */
|
||||
/** edge data */
|
||||
edges: WorkflowEdgeJSON[];
|
||||
|
||||
/** 是否在创建 workflow */
|
||||
/** Are you creating a workflow? */
|
||||
isCreatingWorkflow: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@ import { ViewVariableType } from './view-variable-type';
|
||||
import { type DTODefine, type InputValueDTO } from './dto';
|
||||
|
||||
/**
|
||||
* BlockInput是后端定义的类型,对应的就是 InputValueDTO
|
||||
* BlockInput is a type defined by the backend, which corresponds to InputValueDTO.
|
||||
*/
|
||||
export type BlockInput = InputValueDTO;
|
||||
|
||||
/**
|
||||
* BlockInput 转换方法
|
||||
* BlockInput conversion method
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace BlockInput {
|
||||
|
||||
@@ -26,7 +26,7 @@ export enum ConditionLogicDTO {
|
||||
|
||||
export type ConditionOperator =
|
||||
| 'EQUAL' // "="
|
||||
| 'NOT_EQUAL' // "<>" 或 "!="
|
||||
| 'NOT_EQUAL' // "< >" or "! ="
|
||||
| 'GREATER_THAN' // ">"
|
||||
| 'LESS_THAN' // "<"
|
||||
| 'GREATER_EQUAL' // ">="
|
||||
@@ -35,7 +35,7 @@ export type ConditionOperator =
|
||||
| 'NOT_IN' // "NOT IN"
|
||||
| 'IS_NULL' // "IS NULL"
|
||||
| 'IS_NOT_NULL' // "IS NOT NULL"
|
||||
| 'LIKE' // "LIKE" 模糊匹配字符串
|
||||
| 'NOT_LIKE' // "NOT LIKE" 反向模糊匹配
|
||||
| 'BE_TRUE' // "BE TRUE" 布尔值为 true
|
||||
| 'BE_FALSE'; // "BE FALSE" 布尔值为 false
|
||||
| 'LIKE' // "LIKE" fuzzy match string
|
||||
| 'NOT_LIKE' // "NOT LIKE" inverse fuzzy match
|
||||
| 'BE_TRUE' // "BE TRUE" is true
|
||||
| 'BE_FALSE'; // "BE FALSE" Boolean value false
|
||||
|
||||
@@ -37,7 +37,7 @@ export interface WorkflowDatabase {
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库配置字段
|
||||
* Database configuration field
|
||||
*/
|
||||
export interface DatabaseSettingField {
|
||||
fieldID: number;
|
||||
@@ -66,7 +66,7 @@ export type DatabaseSettingFieldDTO = [
|
||||
];
|
||||
|
||||
/**
|
||||
* 数据库条件
|
||||
* database conditions
|
||||
*/
|
||||
export type DatabaseConditionOperator = ConditionOperator;
|
||||
export type DatabaseConditionLeft = string;
|
||||
@@ -89,7 +89,7 @@ export interface DatabaseConditionLeftDTO {
|
||||
}
|
||||
|
||||
export interface DatabaseConditionOperatorDTO {
|
||||
// 对操作符的翻译前后端没有统一
|
||||
// Translation of operators is not uniform between front and back ends
|
||||
name: 'operation';
|
||||
input: {
|
||||
type: 'string';
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* 这些是迁移的变量定义,可以不用关注
|
||||
* These are the variable definitions for migration, you can ignore them.
|
||||
*/
|
||||
|
||||
import { type ValueExpressionRawMeta } from './vo';
|
||||
@@ -63,7 +63,7 @@ export namespace DTODefine {
|
||||
rawMeta?: ValueExpressionRawMeta;
|
||||
}
|
||||
|
||||
// 当 schema 为 string 时表示原始的 FDL 类型export type ListVariableSchema = VariableTypeDef & Omit<VariableOption, 'name'>
|
||||
// Represents the original FDL type when schema is string export type ListVariableSchema = VariableTypeDef & Omit < VariableOption, 'name' >
|
||||
export type ObjectVariableSchema = InputVariableDTO[];
|
||||
export type ListVariableSchema = VariableTypeDef &
|
||||
Omit<VariableOption, 'name'>;
|
||||
@@ -109,21 +109,21 @@ export namespace DTODefine {
|
||||
}
|
||||
|
||||
/**
|
||||
* 后端定义的表达式格式
|
||||
* Expression formats defined by the backend
|
||||
* @example
|
||||
* - literal
|
||||
* {
|
||||
* type: 'string',
|
||||
* value: {
|
||||
* type: 'liteal',
|
||||
* content: '浙江'
|
||||
* Content: 'Zhejiang'
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* - ref
|
||||
* // 普通引用类型
|
||||
* //Common reference typery reference type
|
||||
* {
|
||||
* type: 'string', // 由引用的变量类型判断
|
||||
* Type: 'string',//Determined by the type of the referenced variable the type of variable being referenced
|
||||
* value: {
|
||||
* type: 'ref',
|
||||
* content: {
|
||||
@@ -134,10 +134,10 @@ export namespace DTODefine {
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // list or object 引用类型
|
||||
* //list or object reference typerence type
|
||||
* {
|
||||
* type: 'list', // 由引用的变量路径的最后一个值类型判断, 如果list.a.c, 则为c的格式
|
||||
* schema: { // 只有list和object有schema
|
||||
* Type: 'list',//Determined by the last value type of the referenced variable path, if list.a.c, the format of che referenced variable path, if list.a.c, the format of c
|
||||
* Schema : { // only list and object have schemasts have schemas
|
||||
* type: 'object',
|
||||
* schema: [
|
||||
* { name: 'role', type: 'string' },
|
||||
@@ -149,7 +149,7 @@ export namespace DTODefine {
|
||||
* content: {
|
||||
* source: 'block-output',
|
||||
* blockID: '1002',
|
||||
* name: 'list.a.c' // 这里存的是引用的路径
|
||||
* Name: 'list.a.c'//Here is the path of the referencee path to the reference
|
||||
* },
|
||||
* }
|
||||
* }
|
||||
@@ -168,7 +168,7 @@ export interface ValueExpressionDTO {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace ValueExpressionDTO {
|
||||
/**
|
||||
* 空引用
|
||||
* null reference
|
||||
*/
|
||||
export function createEmpty(): ValueExpressionDTO {
|
||||
return {
|
||||
@@ -219,7 +219,7 @@ export enum AssistTypeDTO {
|
||||
}
|
||||
|
||||
/**
|
||||
* 后端的变量格式
|
||||
* Variable format for the backend
|
||||
* @example
|
||||
* 1. simple
|
||||
* {
|
||||
@@ -256,19 +256,19 @@ export enum AssistTypeDTO {
|
||||
*/
|
||||
export interface VariableMetaDTO {
|
||||
/**
|
||||
* 变量类型
|
||||
* Variable type
|
||||
*/
|
||||
type: VariableTypeDTO;
|
||||
/**
|
||||
* 辅助类型,如:string 类型的变量可以是 file 或者 image
|
||||
* Auxiliary types, such as: string type variables can be file or image
|
||||
*/
|
||||
assistType?: AssistTypeDTO;
|
||||
/**
|
||||
* 变量名,在节点内不可重复
|
||||
* Variable names are not repeatable within a node
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 变量数据结构,仅object 和 list 类型变量有
|
||||
* Variable data structures, only object and list variables are available
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
schema?: any; // BlockVariableDefine.ObjectVariableSchema | BlockVariableDefine.ListVariableSchema
|
||||
@@ -282,7 +282,7 @@ export interface VariableMetaDTO {
|
||||
export interface BatchDTOInputList {
|
||||
name?: string;
|
||||
input: ValueExpressionDTO;
|
||||
// 初始化后存在,服务端数据不存在
|
||||
// Exists after initialization, server level data does not exist
|
||||
id?: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ export {
|
||||
type BasicStandardNodeTypes,
|
||||
} from './node-type';
|
||||
export { type WorkflowJSON, type WorkflowNodeJSON } from './node';
|
||||
// !Notice data-set.ts 在用 io-ts 做运行时类型检查,禁止直接导出,避免 io-ts 被打到其它页面中
|
||||
// ! Notice data-set.ts is using io-ts for runtime type checking, and direct export is prohibited to avoid io-ts being hit into other pages
|
||||
// export { datasetParams, type DatasetParams } from './data-set';
|
||||
import { InputType } from '@coze-arch/bot-api/developer_api';
|
||||
|
||||
@@ -78,7 +78,7 @@ import {
|
||||
import { AssistTypeDTO } from './dto';
|
||||
|
||||
export { type ValueOf, type WithCustomStyle } from './utils';
|
||||
// 和后端定义撞了,注释
|
||||
// Bumped with the back-end definition, comment
|
||||
export { type WorkflowInfo as FrontWorkflowInfo } from './workflow';
|
||||
|
||||
export {
|
||||
@@ -88,8 +88,8 @@ export {
|
||||
} from './registry';
|
||||
|
||||
/**
|
||||
* 参数类型展示文案
|
||||
* @tips workflow 编辑页请使用 {PARAM_TYPE_ALIAS_MAP}
|
||||
* Parameter type display copy
|
||||
* @Tips workflow edit page please use {PARAM_TYPE_ALIAS_MAP}
|
||||
*/
|
||||
export const PARAM_TYPE_LABEL_MAP: Record<InputType, string> = {
|
||||
[InputType.String]: 'String',
|
||||
@@ -116,9 +116,9 @@ export const STRING_ASSIST_TYPE_LABEL_MAP = {
|
||||
|
||||
export enum WorkflowExecStatus {
|
||||
DEFAULT = 'default',
|
||||
/** 执行中 */
|
||||
/** in progress */
|
||||
EXECUTING = 'executing',
|
||||
/** 执行结束(此时依然有执行结束 banner,且工作流为 disable 状态) */
|
||||
/** End of execution (there is still an end of execution banner at this time, and the workflow is disabled) */
|
||||
DONE = 'done',
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// 跟后端约定好的协议,workflow 后端不感知。对应 api/bot/get_type_list 接口中 response.data.modal_list[*].model_params[*].default 的 key
|
||||
// The agreement agreed with the backend is not perceived by the workflow backend. Corresponding to the key response.data modal_list [*] .model_params [*] .default in the api/bot/get_type_list interface
|
||||
export enum GenerationDiversity {
|
||||
Customize = 'default_val',
|
||||
Creative = 'creative',
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* 节点基础类型定义
|
||||
* Node base type definition
|
||||
*/
|
||||
export enum StandardNodeType {
|
||||
Start = '1',
|
||||
@@ -38,32 +38,32 @@ export enum StandardNodeType {
|
||||
SetVariable = '20',
|
||||
Loop = '21',
|
||||
Intent = '22',
|
||||
// 对于新节点,可以使用文本的形式来编写 StandardNodeType,不再依赖 NodeTemplateType
|
||||
// For new nodes, StandardNodeType can be written in text form, without relying on NodeTemplateType.
|
||||
ImageCanvas = '23',
|
||||
SceneChat = '25',
|
||||
SceneVariable = '24',
|
||||
|
||||
/** 长期记忆,long term memory */
|
||||
/** Long term memory */
|
||||
LTM = '26',
|
||||
/** 数据库写入节点 */
|
||||
/** database write node */
|
||||
DatasetWrite = '27',
|
||||
Batch = '28',
|
||||
|
||||
Continue = '29',
|
||||
// 输入节点
|
||||
// input node
|
||||
Input = '30',
|
||||
|
||||
Comment = '31',
|
||||
// 变量聚合
|
||||
// variable aggregation
|
||||
VariableMerge = '32',
|
||||
// 查询消息列表
|
||||
// Query message list
|
||||
QueryMessageList = '37',
|
||||
// 清空上下文节点
|
||||
// clear the context node
|
||||
ClearContext = '38',
|
||||
// 创建会话节点
|
||||
// Create a session node
|
||||
CreateConversation = '39',
|
||||
|
||||
// 触发器 CURD 4个节点
|
||||
// Trigger CURD 4 nodes
|
||||
// TriggerCreate = '33',
|
||||
// TriggerUpdate = '34',
|
||||
TriggerUpsert = '34',
|
||||
@@ -72,34 +72,34 @@ export enum StandardNodeType {
|
||||
|
||||
VariableAssign = '40',
|
||||
|
||||
// http 节点
|
||||
// HTTP Node
|
||||
Http = '45',
|
||||
// 数据库 crud 节点
|
||||
// Database crud node
|
||||
|
||||
DatabaseUpdate = '42',
|
||||
DatabaseQuery = '43',
|
||||
DatabaseDelete = '44',
|
||||
DatabaseCreate = '46',
|
||||
|
||||
// 更新会话
|
||||
// Update session
|
||||
UpdateConversation = '51',
|
||||
|
||||
// 删除会话
|
||||
// Delete session
|
||||
DeleteConversation = '52',
|
||||
|
||||
// 查询会话列表
|
||||
// Query session list
|
||||
QueryConversationList = '53',
|
||||
|
||||
// 查询会话历史
|
||||
// Query session history
|
||||
QueryConversationHistory = '54',
|
||||
|
||||
// 创建消息(某个会话)
|
||||
// Create a message (a conversation)
|
||||
CreateMessage = '55',
|
||||
|
||||
// 更新消息(某个会话的某个消息)
|
||||
// Update message (a message for a session)
|
||||
UpdateMessage = '56',
|
||||
|
||||
// 删除消息(某个会话的某个消息)
|
||||
// Delete a message (a message for a session)
|
||||
DeleteMessage = '57',
|
||||
|
||||
JsonStringify = '58',
|
||||
@@ -107,7 +107,7 @@ export enum StandardNodeType {
|
||||
}
|
||||
|
||||
/**
|
||||
* 除了 Api、SubWorkflow、Imageflow 之外的基础节点类型
|
||||
* Basic node types other than APIs, SubWorkflow, and Imageflow
|
||||
*/
|
||||
export type BasicStandardNodeTypes = Exclude<
|
||||
StandardNodeType,
|
||||
@@ -116,7 +116,7 @@ export type BasicStandardNodeTypes = Exclude<
|
||||
| StandardNodeType.SubWorkflow
|
||||
>;
|
||||
|
||||
/** 节点展示排序 */
|
||||
/** Node display sorting */
|
||||
export const NODE_ORDER = {
|
||||
[StandardNodeType.Start]: 1,
|
||||
[StandardNodeType.End]: 2,
|
||||
@@ -148,7 +148,7 @@ export const NODE_ORDER = {
|
||||
[StandardNodeType.TriggerDelete]: 28,
|
||||
};
|
||||
|
||||
/** 会话类节点 */
|
||||
/** session class node */
|
||||
export const CONVERSATION_NODES = [
|
||||
StandardNodeType.CreateConversation,
|
||||
StandardNodeType.UpdateConversation,
|
||||
@@ -156,7 +156,7 @@ export const CONVERSATION_NODES = [
|
||||
StandardNodeType.QueryConversationList,
|
||||
];
|
||||
|
||||
/** 消息类节点 */
|
||||
/** message class node */
|
||||
export const MESSAGE_NODES = [
|
||||
StandardNodeType.CreateMessage,
|
||||
StandardNodeType.UpdateMessage,
|
||||
@@ -164,7 +164,7 @@ export const MESSAGE_NODES = [
|
||||
StandardNodeType.QueryMessageList,
|
||||
];
|
||||
|
||||
/** 会话历史类节点 */
|
||||
/** session history class node */
|
||||
export const CONVERSATION_HISTORY_NODES = [
|
||||
StandardNodeType.QueryConversationHistory,
|
||||
StandardNodeType.ClearContext,
|
||||
|
||||
@@ -37,5 +37,5 @@ export interface WorkflowJSON {
|
||||
edges: WorkflowEdgeJSON[];
|
||||
}
|
||||
|
||||
// 节点模版类型
|
||||
// Node template type
|
||||
export { NodeTemplateType } from '@coze-arch/bot-api/workflow_api';
|
||||
|
||||
@@ -17,26 +17,26 @@
|
||||
import { type ViewVariableType } from './view-variable-type';
|
||||
|
||||
/**
|
||||
* 参数定义
|
||||
* parameter definition
|
||||
*
|
||||
* 递归定义,包含了复杂类型的层级结构
|
||||
* Recursive definition, including a hierarchy of complex types
|
||||
*/
|
||||
export interface RecursedParamDefinition {
|
||||
name?: string;
|
||||
/** Tree 组件要求每一个节点都有 key,而 key 不适合用名称(前后缀)等任何方式赋值,最终确定由接口转换层一次性提供随机 key */
|
||||
/** The Tree component requires each node to have a key, and the key is not suitable for assignment in any way such as name (before and after). Finally, the interface conversion layer provides a random key at one time. */
|
||||
fieldRandomKey?: string;
|
||||
desc?: string;
|
||||
required?: boolean;
|
||||
type: ViewVariableType;
|
||||
children?: RecursedParamDefinition[];
|
||||
// region 参数值定义
|
||||
// 输入参数的值可以来自上游变量引用,也可以是用户输入的定值(复杂类型则只允许引用)
|
||||
// 如果是定值,传 fixedValue
|
||||
// 如果是引用,传 quotedValue
|
||||
// Region parameter value definition
|
||||
// The value of the input parameter can come from an upstream variable reference, or it can be a fixed value entered by the user (for complex types, only references are allowed).
|
||||
// If it is a fixed value, pass the fixedValue.
|
||||
// If it is a reference, pass the quotedValue.
|
||||
isQuote?: ParamValueType;
|
||||
/** 参数定值 */
|
||||
/** parameter setting */
|
||||
fixedValue?: string;
|
||||
/** 参数引用 */
|
||||
/** parameter reference */
|
||||
quotedValue?: [nodeId: string, ...path: string[]]; // string[]
|
||||
// endregion
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ import { type StandardNodeType } from './node-type';
|
||||
|
||||
export interface WorkflowNodeVariablesMeta {
|
||||
/**
|
||||
* 输出变量路径, 默认 ['outputs']
|
||||
* Output variable path, default ['outputs']
|
||||
*/
|
||||
outputsPathList?: string[];
|
||||
/**
|
||||
* 输入变量路径,默认 ['inputs.inputParameters']
|
||||
* Input variable path, default ['input.inputParameters']
|
||||
*/
|
||||
inputsPathList?: string[];
|
||||
batchInputListPath?: string;
|
||||
@@ -56,7 +56,7 @@ export interface NodeMeta<NodeTest = any> {
|
||||
isStart?: boolean;
|
||||
isNodeEnd?: boolean;
|
||||
deleteDisable?: boolean;
|
||||
copyDisable?: boolean; // 无法复制
|
||||
copyDisable?: boolean; // Unable to copy
|
||||
nodeDTOType: StandardNodeType;
|
||||
nodeMetaPath?: string;
|
||||
batchPath?: string;
|
||||
@@ -65,41 +65,41 @@ export interface NodeMeta<NodeTest = any> {
|
||||
renderKey?: string;
|
||||
style?: any;
|
||||
errorStyle?: any;
|
||||
size?: { width: number; height: number }; // 初始化时候的默认大小
|
||||
size?: { width: number; height: number }; // Default size at initialization
|
||||
defaultPorts?: Array<any>;
|
||||
useDynamicPort?: boolean;
|
||||
disableSideSheet?: boolean;
|
||||
subCanvas?: (node: WorkflowNodeEntity) => WorkflowSubCanvas | undefined;
|
||||
|
||||
/** 是否展示触发器 icon */
|
||||
/** Whether to show trigger icon */
|
||||
showTrigger?: (props: { projectId?: string }) => boolean;
|
||||
/** 是否隐藏测试 */
|
||||
/** Whether to hide the test */
|
||||
hideTest?: boolean;
|
||||
/** 获取卡片输入变量标签 */
|
||||
/** Get card input variable label */
|
||||
getInputVariableTag?: (
|
||||
/** 变量名称 */
|
||||
/** variable name */
|
||||
variableName: string | undefined,
|
||||
/** 输入值或变量 */
|
||||
/** Input value or variable */
|
||||
input: ValueExpression,
|
||||
/** 附加参数 */
|
||||
/** additional parameters */
|
||||
extra?: {
|
||||
/**
|
||||
* 变量服务,从 '@coze-workflow/variable' 导入的 WorkflowVariableService
|
||||
* 这里不写上类型,是为了避免循环引用,另外 base 包引用 variable 包内容也不合理
|
||||
* Variable service, WorkflowVariableService imported from '@code-workflow/variable'
|
||||
* The type is not written here to avoid circular references. In addition, it is unreasonable for the base package to refer to the content of the variable package.
|
||||
*/
|
||||
variableService: any;
|
||||
|
||||
/** 当前节点 */
|
||||
/** current node */
|
||||
node: WorkflowNodeEntity;
|
||||
},
|
||||
) => VariableTagProps;
|
||||
|
||||
/** 是否支持单节点调试copilot生成表单参数 */
|
||||
/** Whether to support single-node debugging copilot generation form parameters */
|
||||
enableCopilotGenerateTestNodeForm?: boolean;
|
||||
/**
|
||||
* 获取llm ids,所有需要用到大模型选择的的节点必须实现该方法
|
||||
* 因为用户可能存在账户升级或者模型下架,正常拉到的列表数据可能没有该id
|
||||
* 所以模型列表获取需要遍历所有节点拿到被用过的模型id
|
||||
* Get llm ids, all nodes that require large model selection must implement this method
|
||||
* Because the user may have an account upgrade or the model is removed from the shelves, the list data pulled normally may not have this id.
|
||||
* Therefore, to obtain the model list, you need to traverse all nodes to get the used model IDs.
|
||||
* @param nodeJSON
|
||||
* @returns
|
||||
*/
|
||||
@@ -107,17 +107,17 @@ export interface NodeMeta<NodeTest = any> {
|
||||
nodeJSON: WorkflowNodeJSON,
|
||||
) => string[] | undefined | string | number | number[];
|
||||
/**
|
||||
* 节点 header 不可编辑 & 隐藏 ... 按钮
|
||||
* Node header not editable & hide... button
|
||||
*/
|
||||
headerReadonly?: boolean;
|
||||
headerReadonlyAllowDeleteOperation?: boolean;
|
||||
|
||||
/**
|
||||
* 节点帮助文档
|
||||
* Node Help Documentation
|
||||
*/
|
||||
helpLink?: string | ((props: { apiName: string }) => string);
|
||||
/**
|
||||
* 节点测试相关数据
|
||||
* Node test related data
|
||||
*/
|
||||
test?: NodeTest;
|
||||
}
|
||||
@@ -128,14 +128,14 @@ export interface WorkflowNodeRegistry<NodeTestMeta = any>
|
||||
meta: NodeMeta<NodeTestMeta>;
|
||||
|
||||
/**
|
||||
* 特化:根据节点获取输入 Parameters 的值,默认通过 /inputParameters 字段判断
|
||||
* Specialization: Get the value of the input Parameters according to the node, and judge by /inputParameters field by default
|
||||
* @param node
|
||||
* @returns
|
||||
*/
|
||||
getNodeInputParameters?: (node: FlowNodeEntity) => InputValueVO[] | undefined;
|
||||
|
||||
/**
|
||||
* 获取舞台节点右侧更多菜单的额外操作,目前在子流程节点和插件节点中使用
|
||||
* Get additional actions for the More menu to the right of the Stage node, currently used in the Subprocess node and the Plugin node
|
||||
* @returns
|
||||
*/
|
||||
getHeaderExtraOperation?: (
|
||||
@@ -144,39 +144,39 @@ export interface WorkflowNodeRegistry<NodeTestMeta = any>
|
||||
) => React.ReactNode;
|
||||
|
||||
/**
|
||||
* 特化:根据节点获取输出 Outputs 的值,默认通过 /outputs 字段判断
|
||||
* Specialization: Get the value of Outputs according to the node, and judge by /outputs field by default
|
||||
*/
|
||||
getNodeOutputs?: (node: FlowNodeEntity) => OutputValueVO[] | undefined;
|
||||
|
||||
/**
|
||||
* 节点提交前最后一次转化,这个方法在 `formMeta.transformOnSubmit` 之后执行
|
||||
* @param node 节点数据
|
||||
* @param 转化后的节点数据
|
||||
* The last conversion before the node commits, this method is executed after'formMeta.transformOnSubmit'
|
||||
* @param node data
|
||||
* @Param converted node data
|
||||
*/
|
||||
beforeNodeSubmit?: (node: WorkflowNodeJSON) => WorkflowNodeJSON;
|
||||
|
||||
/**
|
||||
* - 节点 Registry 初始化,可以在这里获取初始化数据,然后再进行表单渲染,注意此时 node 还没有创建
|
||||
* - 目前适用于 v2 表单引擎节点
|
||||
* @param nodeJSON 节点初始化数据(点击添加时,或者从后端获取时的节点数据)
|
||||
* @param context WorkflowPlaygroundContext,参见 packages/workflow/playground/src/workflow-playground-context.ts
|
||||
* - Node Registry initialization, you can get the initialization data here, and then render the form. Note that the node has not been created at this time
|
||||
* - Currently works with v2 form engine nodes
|
||||
* @Param nodeJSON node initialization data (when clicking Add, or when fetching from the backend)
|
||||
* @Param context WorkflowPlaygroundContext, see packages/workflow/playground/src/workflow-playground-context
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
onInit?: (nodeJSON: WorkflowNodeJSON, context: any) => Promise<void>;
|
||||
|
||||
/**
|
||||
* - 是否有错误信息(从 service 中拿),如果有错误信息返回错误信息,否则返回空串或者 undefined
|
||||
* - 目前在 node-context-provider.tsx 中消费,监听当前节点错误信息,如果有,更新 FlowNodeErrorData 数据,从而触发节点渲染错误状态
|
||||
* - 目前适用于 v2 表单引擎节点
|
||||
* @param nodeJSON 节点初始化数据(点击添加时,或者从后端获取时的节点数据)
|
||||
* @param context WorkflowPlaygroundContext,参见 packages/workflow/playground/src/workflow-playground-context.ts
|
||||
* - Whether there is an error message (taken from the service), if there is an error message, return an error message, otherwise return an empty string or undefined
|
||||
* - Currently consumed in node-context-provider, monitor the current node error message, if any, update the FlowNodeErrorData data, thereby triggering the node to render the error state
|
||||
* - Currently works with v2 form engine nodes
|
||||
* @Param nodeJSON node initialization data (when clicking Add, or when fetching from the backend)
|
||||
* @Param context WorkflowPlaygroundContext, see packages/workflow/playground/src/workflow-playground-context
|
||||
*/
|
||||
checkError?: (nodeJSON: WorkflowNodeJSON, context: any) => string | undefined;
|
||||
|
||||
/**
|
||||
* - 节点销毁时调用,用于做一些清理工作,例如将相关节点的错误信息清空,回收资源
|
||||
* - 目前适用于 v2 表单引擎节点
|
||||
* @param node 节点
|
||||
* - Called when the node is destroyed, used to do some cleaning work, such as clearing the error information of the joint point and recycling resources
|
||||
* - Currently works with v2 form engine nodes
|
||||
* @param node
|
||||
* @param context workflow-playground-context
|
||||
* @returns
|
||||
*/
|
||||
|
||||
@@ -23,11 +23,11 @@ export interface ViewVariableTreeNode {
|
||||
children?: ViewVariableTreeNode[];
|
||||
required?: boolean;
|
||||
description?: string;
|
||||
// 标识该条参数是内置参数,默认为 false
|
||||
// Identifies that the parameter is a built-in parameter, and the default is false.
|
||||
isPreset?: boolean;
|
||||
// 标识该条参数是否启用,默认为 false
|
||||
// Identifies whether the parameter is enabled, the default is false
|
||||
enabled?: boolean;
|
||||
// 用户自定义节点名展示
|
||||
// user-defined node name display
|
||||
label?: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
defaultValue?: any;
|
||||
@@ -37,13 +37,13 @@ export interface ViewVariableMeta extends ViewVariableTreeNode {
|
||||
required?: boolean;
|
||||
description?: string;
|
||||
readonly?: boolean;
|
||||
mutable?: boolean; // 是否可以被 Set 节点的左值选中
|
||||
mutable?: boolean; // Can be selected by the lvalue of the Set node
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace ViewVariableTreeNode {
|
||||
/**
|
||||
* 通过path 查询 子节点
|
||||
* Query sub-node via path
|
||||
* @param node
|
||||
*/
|
||||
export function getVariableTreeNodeByPath(
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
/**
|
||||
* 前端变量类型
|
||||
* Front-end variable type
|
||||
*/
|
||||
export enum ViewVariableType {
|
||||
String = 1,
|
||||
@@ -38,7 +38,7 @@ export enum ViewVariableType {
|
||||
Svg,
|
||||
Voice,
|
||||
Time,
|
||||
// 上面是 api 中定义的 InputType。下面是整合后的。从 99 开始,避免和后端定义撞车
|
||||
// The above is the InputType defined in the api. The following is the integrated one. Start from 99 to avoid collisions with the backend definition.
|
||||
ArrayString = 99,
|
||||
ArrayInteger,
|
||||
ArrayBoolean,
|
||||
@@ -59,7 +59,7 @@ export enum ViewVariableType {
|
||||
ArrayTime,
|
||||
}
|
||||
/**
|
||||
* 使用 JSON 表示值的变量类型
|
||||
* Variable types that use JSON to represent values
|
||||
*/
|
||||
export const JSON_INPUT_TYPES = [
|
||||
ViewVariableType.Object,
|
||||
@@ -99,7 +99,7 @@ export const FILE_TYPES = [
|
||||
ViewVariableType.ArrayVoice,
|
||||
];
|
||||
|
||||
// 基础类型,及其对应数组类型的配对
|
||||
// Base types, and pairing with their corresponding array types
|
||||
export const BASE_ARRAY_PAIR: [ViewVariableType, ViewVariableType][] = [
|
||||
[ViewVariableType.String, ViewVariableType.ArrayString],
|
||||
[ViewVariableType.Integer, ViewVariableType.ArrayInteger],
|
||||
@@ -170,8 +170,8 @@ export namespace ViewVariableType {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有变量类型的补集
|
||||
* 该函数由GPT生成
|
||||
* Get the complement of all variable types
|
||||
* This function is generated by GPT
|
||||
* @param inputTypes
|
||||
*/
|
||||
export function getComplement(inputTypes: ViewVariableType[]) {
|
||||
@@ -203,7 +203,7 @@ export namespace ViewVariableType {
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 JSON 表示值的变量类型
|
||||
* Variable types that use JSON to represent values
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
@@ -244,30 +244,30 @@ export namespace ViewVariableType {
|
||||
export interface InputVariable {
|
||||
name: string;
|
||||
/**
|
||||
* id 不一定有,非前后端约定,前端强加上的。风险:workflowSchema 结构化时可能会删掉此属性
|
||||
* 如需 id ,要在 nodes schema 中定义 :
|
||||
* The id does not necessarily have a front-end and back-end convention, imposed by the front-end. Risk: This property may be deleted when workflowSchema is structured
|
||||
* If you need an id, define it in the nodes schema:
|
||||
* getDefaultAppendValue: () => ({
|
||||
id: nanoid(),
|
||||
}),
|
||||
* 参考 packages/workflow/nodes/src/workflow-nodes/image-canvas/index.ts
|
||||
* 只能保证同一节点内唯一,只能保证同一节点内唯一,只能保证同一节点内唯一
|
||||
* 因为节点可以创建副本
|
||||
* Reference packages/workflow/nodes/src/workflow-nodes/image-canvas/index.ts
|
||||
* It can only be guaranteed to be unique within the same node, it can only be guaranteed to be unique within the same node, and it can only be guaranteed to be unique within the same node.
|
||||
* Because nodes can create replicas
|
||||
*/
|
||||
id?: string;
|
||||
type: ViewVariableType;
|
||||
/**
|
||||
* 索引
|
||||
* index
|
||||
*/
|
||||
index: number;
|
||||
}
|
||||
|
||||
/** 卡片上的变量展示标签 */
|
||||
/** Variable display labels on cards */
|
||||
export interface VariableTagProps {
|
||||
key?: string;
|
||||
/* 变量类型 */
|
||||
/* Variable type */
|
||||
type?: ViewVariableType;
|
||||
/* 变量名,为空时会展示为 Undefined/未定义 */
|
||||
/* Variable name, when empty, is displayed as Undefined/Undefined */
|
||||
label?: ReactNode;
|
||||
/** 是否有效 */
|
||||
/** Is it valid? */
|
||||
invalid?: boolean;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* 这个文件定义的是前端消费的数据, 用 VO (view object) 来表示
|
||||
* This file defines the data consumed by the front end and is represented by VO (view object)
|
||||
*/
|
||||
import { isNil, isUndefined } from 'lodash-es';
|
||||
|
||||
@@ -23,13 +23,13 @@ import type { ViewVariableType } from './view-variable-type';
|
||||
|
||||
export interface RefExpressionContent {
|
||||
/**
|
||||
* 引用值是一个变量的 key 路径
|
||||
* The reference value is the key path of a variable
|
||||
*/
|
||||
keyPath: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 值表达式类型
|
||||
* value expression type
|
||||
*/
|
||||
export enum ValueExpressionType {
|
||||
LITERAL = 'literal',
|
||||
@@ -37,7 +37,7 @@ export enum ValueExpressionType {
|
||||
OBJECT_REF = 'object_ref',
|
||||
}
|
||||
/**
|
||||
* 用来存储 ValueExpression 的原始数据供前端消费
|
||||
* Used to store ValueExpression's original data source for front-end consumption
|
||||
*/
|
||||
export interface ValueExpressionRawMeta {
|
||||
type?: ViewVariableType;
|
||||
@@ -46,7 +46,7 @@ export interface ValueExpressionRawMeta {
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本表达式
|
||||
* Text expression
|
||||
*/
|
||||
export interface LiteralExpression {
|
||||
type: ValueExpressionType.LITERAL;
|
||||
@@ -55,7 +55,7 @@ export interface LiteralExpression {
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象表达式
|
||||
* object expression
|
||||
*/
|
||||
export interface ObjectRefExpression {
|
||||
type: ValueExpressionType.OBJECT_REF;
|
||||
@@ -64,20 +64,20 @@ export interface ObjectRefExpression {
|
||||
}
|
||||
|
||||
/**
|
||||
* 引用变量
|
||||
* reference variable
|
||||
*/
|
||||
export interface RefExpression {
|
||||
type: ValueExpressionType.REF;
|
||||
content?: RefExpressionContent;
|
||||
/**
|
||||
* rawMeta 记录了该 ref expression 的类型
|
||||
* 可能和所引用变量类型不同,此时会触发类型自动转换: [Workflow 类型自动转换]()
|
||||
* rawMeta records the type of the ref expression
|
||||
* May be different from the referenced variable type, which triggers automatic type conversion: [Workflow type automatic conversion] ()
|
||||
*/
|
||||
rawMeta?: ValueExpressionRawMeta;
|
||||
}
|
||||
|
||||
/**
|
||||
* 前端输入值表达式
|
||||
* Front-end input value expression
|
||||
*/
|
||||
export type ValueExpression =
|
||||
| RefExpression
|
||||
@@ -116,12 +116,12 @@ export namespace ValueExpression {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果 value 不是对象或者函数,也就是原生类型,在插件自定义组件中会存在
|
||||
// If value is not an object or function, that is, a native type, it will exist in the plug-in custom component
|
||||
if (typeof value !== 'object' && typeof value !== 'function') {
|
||||
return isNil(value);
|
||||
}
|
||||
|
||||
// value.content 有多种类型,可能是 false
|
||||
// Value.content has multiple types and may be false
|
||||
if (value?.content === '' || isNil(value?.content)) {
|
||||
return true;
|
||||
}
|
||||
@@ -138,7 +138,7 @@ export namespace ValueExpression {
|
||||
}
|
||||
|
||||
/**
|
||||
* 前端的value 输入值
|
||||
* Front end value input value
|
||||
* {
|
||||
* name: '',
|
||||
* input: {
|
||||
|
||||
@@ -22,10 +22,10 @@ export const concatTestId = (...testIds: string[]) =>
|
||||
testIds.filter(id => !!id).join('.');
|
||||
|
||||
/**
|
||||
* 生成节点的测试id
|
||||
* Generate the test ID of the node.
|
||||
* @example concatNodeTestId(node, 'right-panel') => playground.node.100001.right-panel
|
||||
* @param node 节点
|
||||
* @param testIds 其它id
|
||||
* @param node
|
||||
* @param testIds other id
|
||||
* @returns
|
||||
*/
|
||||
export const concatNodeTestId = (node: FlowNodeEntity, ...testIds: string[]) =>
|
||||
|
||||
@@ -20,7 +20,7 @@ import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
import { type FlowNodeEntity } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
/**
|
||||
* 找到以 pathEnds 为结尾的 FormItem,并获取它的值
|
||||
* Find the FormItem ending in pathEnds and get its value
|
||||
* @param node
|
||||
* @param pathEnds
|
||||
* @returns
|
||||
@@ -76,12 +76,12 @@ const findValueByPathEnds = <T = unknown>(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// 检查当前路径是否以 pathEnds 结尾
|
||||
// Check if the current path ends with pathEnds
|
||||
if (currentPath.endsWith(pathEnds)) {
|
||||
return obj as T;
|
||||
}
|
||||
|
||||
// 处理对象
|
||||
// processing object
|
||||
if (typeof obj === 'object' && !Array.isArray(obj)) {
|
||||
for (const key in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
@@ -91,7 +91,7 @@ const findValueByPathEnds = <T = unknown>(
|
||||
return obj[key] as T;
|
||||
}
|
||||
|
||||
// 递归查找子对象
|
||||
// recursive search for child objects
|
||||
const result = findValueByPathEnds(obj[key], pathEnds, newPath);
|
||||
if (result !== undefined) {
|
||||
return result as T;
|
||||
@@ -100,7 +100,7 @@ const findValueByPathEnds = <T = unknown>(
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数组
|
||||
// Processing Array
|
||||
if (Array.isArray(obj)) {
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
const newPath = `${currentPath}/${i}`;
|
||||
@@ -109,7 +109,7 @@ const findValueByPathEnds = <T = unknown>(
|
||||
return obj[i] as T;
|
||||
}
|
||||
|
||||
// 递归查找数组元素
|
||||
// Recursive lookup of array elements
|
||||
const result = findValueByPathEnds(obj[i], pathEnds, newPath);
|
||||
if (result !== undefined) {
|
||||
return result as T;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { WorkflowMode } from '@coze-arch/bot-api/workflow_api';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param flowMode 是否广义上的 workflow,包含原来的 Workflow 和 Coze 2.0 新增的 Chatflow
|
||||
* @Param flowMode Whether it is a workflow in a broad sense, including the original Workflow and the Chatflow added by Coze 2.0
|
||||
* @returns
|
||||
*/
|
||||
export const isGeneralWorkflow = (flowMode: WorkflowMode) =>
|
||||
|
||||
@@ -91,14 +91,14 @@ const parseData = (
|
||||
nodeSchema?.type === StandardNodeType.Text &&
|
||||
isString(rawOutput) &&
|
||||
rawOutput?.length > 0;
|
||||
// 文本节点的 raw_out 不需要反序列化,一定是 string,badcase:用户拼接的 json 字符串如 '{}'、'123',反序列化后会变成object 和 number
|
||||
// The raw_out of the text node does not need to be deserialized, it must be a string, badcase: the json string spliced by the user such as '{}'、' 123 'will become object and number after deserialization
|
||||
const rawOutputData = textHasRawout
|
||||
? rawOutput?.toString?.()
|
||||
: rawOutput
|
||||
? typeSafeJSONParse(rawOutput) || rawOutput?.toString?.()
|
||||
: undefined;
|
||||
|
||||
/** Code、Llm 节点需要展示 raw */
|
||||
/** Code, Llm nodes need to display raw */
|
||||
const hasRawOutput =
|
||||
(Boolean(nodeSchema?.type) &&
|
||||
[
|
||||
@@ -107,7 +107,7 @@ const parseData = (
|
||||
StandardNodeType.Question,
|
||||
].includes(nodeSchema?.type as StandardNodeType)) ||
|
||||
textHasRawout;
|
||||
// Start、Input 节点只展示输入
|
||||
// Start and Input nodes only display input
|
||||
const hasOutput =
|
||||
nodeSchema?.type !== StandardNodeType.Start &&
|
||||
nodeSchema?.type !== StandardNodeType.Input;
|
||||
@@ -151,7 +151,7 @@ const parseData = (
|
||||
return {
|
||||
dataList,
|
||||
imgList: parseImagesFromOutputData({
|
||||
// batch data 的 output 下钻了一层,需要再包一层和 output 的 schema 保持一致
|
||||
// The output of batch data is drilled down one layer, and another layer needs to be wrapped to be consistent with the schema of the output.
|
||||
outputData: isBatch
|
||||
? {
|
||||
outputList: [typeSafeJSONParse(outputJsonString)].filter(Boolean),
|
||||
|
||||
@@ -69,10 +69,10 @@ function getImgList(data: unknown, schema: Schema): string[] {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从节点 output data 中解析图片链接
|
||||
* @param outputData 节点输出数据 JSON 序列化后的字符串
|
||||
* @param nodeSchema 节点 schema
|
||||
* @param excludeNodeTypes 不解析该类型节点的图片链接
|
||||
* Parse image links from node output data
|
||||
* @Param outputData node output data JSON serialized string
|
||||
* @param nodeSchema
|
||||
* @Param excludeNodeTypes does not resolve image links for nodes of this type
|
||||
*/
|
||||
export function parseImagesFromOutputData({
|
||||
outputData,
|
||||
|
||||
@@ -69,10 +69,10 @@ it('extract schema with dataset param parser', () => {
|
||||
],
|
||||
});
|
||||
const extractedSchema = schemaExtractor.extract({
|
||||
// knowledge 知识库节点 6
|
||||
// Knowledge Base Node 6
|
||||
[StandardNodeType.Dataset]: [
|
||||
{
|
||||
// 对应知识库名称
|
||||
// Corresponding knowledge base name
|
||||
name: 'datasetParam',
|
||||
path: 'inputs.datasetParam',
|
||||
parser: SchemaExtractorParserName.DATASET_PARAM,
|
||||
|
||||
@@ -41,10 +41,10 @@ it('extract schema with default parser', () => {
|
||||
],
|
||||
});
|
||||
const extractedSchema = schemaExtractor.extract({
|
||||
// end 结束节点 2
|
||||
// End End Node 2
|
||||
[StandardNodeType.End]: [
|
||||
{
|
||||
// 对应输出指定内容
|
||||
// Corresponding output specified content
|
||||
name: 'content',
|
||||
path: 'inputs.content.value.content',
|
||||
},
|
||||
|
||||
@@ -73,10 +73,10 @@ it('extract schema with inputParameters parser', () => {
|
||||
],
|
||||
});
|
||||
const extractedSchema = schemaExtractor.extract({
|
||||
// llm 大模型节点 3
|
||||
// LLM Large Model Node 3
|
||||
[StandardNodeType.LLM]: [
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
|
||||
@@ -94,10 +94,10 @@ it('extract schema with intents param parser', () => {
|
||||
],
|
||||
});
|
||||
const extractedSchema = schemaExtractor.extract({
|
||||
// end 结束节点 2
|
||||
// End End Node 2
|
||||
[StandardNodeType.Intent]: [
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
|
||||
@@ -38,10 +38,10 @@ it('extract schema with json string parser', () => {
|
||||
],
|
||||
});
|
||||
const extractedSchema = schemaExtractor.extract({
|
||||
// end 结束节点 2
|
||||
// End End Node 2
|
||||
[StandardNodeType.SceneChat]: [
|
||||
{
|
||||
// 对应输出指定内容
|
||||
// Corresponding output specified content
|
||||
name: 'messages',
|
||||
path: 'inputs.Messages',
|
||||
parser: SchemaExtractorParserName.JSON_STRING_PARSER,
|
||||
|
||||
@@ -61,10 +61,10 @@ it('extract schema with outputs parser', () => {
|
||||
],
|
||||
});
|
||||
const extractedSchema = schemaExtractor.extract({
|
||||
// code 代码节点 5
|
||||
// Code Code Node 5
|
||||
[StandardNodeType.Code]: [
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
|
||||
@@ -125,7 +125,7 @@ it('extract schema with variableAssign parser', () => {
|
||||
const extractedSchema = schemaExtractor.extract({
|
||||
[StandardNodeType.SetVariable]: [
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.VARIABLE_ASSIGN,
|
||||
@@ -165,7 +165,7 @@ it('variableAssign parser with empty inputParameters', () => {
|
||||
const extractedSchema = schemaExtractor.extract({
|
||||
[StandardNodeType.SetVariable]: [
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.VARIABLE_ASSIGN,
|
||||
@@ -253,7 +253,7 @@ it('variableAssign parser with invalid schema', () => {
|
||||
const extractedSchema = schemaExtractor.extract({
|
||||
[StandardNodeType.SetVariable]: [
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.VARIABLE_ASSIGN,
|
||||
|
||||
@@ -20,10 +20,10 @@ import { SchemaExtractorParserName } from '../../constant';
|
||||
import { StandardNodeType } from '../../../../types';
|
||||
|
||||
export const imageflowExtractorConfig: SchemaExtractorConfig = {
|
||||
// api 节点 4
|
||||
// API Node 4
|
||||
[StandardNodeType.Api]: [
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
|
||||
@@ -19,211 +19,211 @@ import { SchemaExtractorParserName } from '../../constant';
|
||||
import { StandardNodeType } from '../../../../types';
|
||||
|
||||
export const workflowExtractorConfig: SchemaExtractorConfig = {
|
||||
// Start 开始节点 1
|
||||
// Start Start Node 1
|
||||
[StandardNodeType.Start]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应 input name / description
|
||||
// Corresponding input name/description
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// End 结束节点 2
|
||||
// End End Node 2
|
||||
[StandardNodeType.End]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应输出指定内容
|
||||
// Corresponding output specified content
|
||||
name: 'content',
|
||||
path: 'inputs.content.value.content',
|
||||
},
|
||||
],
|
||||
// LLM 大模型节点 3
|
||||
// LLM Large Model Node 3
|
||||
[StandardNodeType.LLM]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应batch value / batch description
|
||||
// Corresponding batch value/batch description
|
||||
name: 'batch',
|
||||
path: 'inputs.batch.inputLists',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应提示词
|
||||
// Cue word
|
||||
name: 'llmParam',
|
||||
path: 'inputs.llmParam',
|
||||
parser: SchemaExtractorParserName.LLM_PARAM,
|
||||
},
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// Plugin 节点 4
|
||||
// Plugin Node 4
|
||||
[StandardNodeType.Api]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应batch value / batch description
|
||||
// Corresponding batch value/batch description
|
||||
name: 'batch',
|
||||
path: 'inputs.batch.inputLists',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应input value / input description
|
||||
// Corresponding input value/input description
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// Code 代码节点 5
|
||||
// Code Node 5
|
||||
[StandardNodeType.Code]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input value / input description
|
||||
// Corresponding input value/input description
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应code内容
|
||||
// Corresponding code content
|
||||
name: 'code',
|
||||
path: 'inputs.code',
|
||||
},
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// Knowledge 知识库节点 6
|
||||
// Knowledge Base Node 6
|
||||
[StandardNodeType.Dataset]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应知识库名称
|
||||
// Corresponding knowledge base name
|
||||
name: 'datasetParam',
|
||||
path: 'inputs.datasetParam',
|
||||
parser: SchemaExtractorParserName.DATASET_PARAM,
|
||||
},
|
||||
],
|
||||
// If 判断节点 8
|
||||
// If the decision node 8
|
||||
[StandardNodeType.If]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'branches',
|
||||
path: 'inputs.branches',
|
||||
parser: SchemaExtractorParserName.DEFAULT,
|
||||
},
|
||||
],
|
||||
// Sub Workflow 工作流节点 9
|
||||
// Sub Workflow Node 9
|
||||
[StandardNodeType.SubWorkflow]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应batch value / batch description
|
||||
// Corresponding batch value/batch description
|
||||
name: 'batch',
|
||||
path: 'inputs.batch.inputLists',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应input value / input description
|
||||
// Corresponding input value/input description
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// Variable 变量节点 11
|
||||
// Variable Node 11
|
||||
[StandardNodeType.Variable]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// Database 数据库节点 12
|
||||
// Database Node 12
|
||||
[StandardNodeType.Database]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
@@ -234,21 +234,21 @@ export const workflowExtractorConfig: SchemaExtractorConfig = {
|
||||
path: 'inputs.sql',
|
||||
},
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// Message 消息节点 13
|
||||
// Message Node 13
|
||||
[StandardNodeType.Output]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
@@ -259,78 +259,78 @@ export const workflowExtractorConfig: SchemaExtractorConfig = {
|
||||
path: 'inputs.content.value.content',
|
||||
},
|
||||
],
|
||||
// Sub Imageflow 图像流节点 14
|
||||
// Sub ImageFlow Node 14
|
||||
[StandardNodeType.Imageflow]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应batch value / batch description
|
||||
// Corresponding batch value/batch description
|
||||
name: 'batch',
|
||||
path: 'inputs.batch.inputLists',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应input value / input description
|
||||
// Corresponding input value/input description
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// Text 文本处理节点 15
|
||||
// Text processing node 15
|
||||
[StandardNodeType.Text]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 拼接结果,以及拼接字符串
|
||||
// Splicing results, and splicing strings
|
||||
name: 'concatResult',
|
||||
path: 'inputs.concatParams',
|
||||
parser: SchemaExtractorParserName.CONCAT_RESULT,
|
||||
},
|
||||
{
|
||||
// 自定义数组拼接符号
|
||||
// Custom array stitching symbols
|
||||
name: 'arrayConcatChar',
|
||||
path: 'inputs.concatParams',
|
||||
parser: SchemaExtractorParserName.CUSTOM_ARRAY_CONCAT_CHAR,
|
||||
},
|
||||
{
|
||||
// 自定义分隔符
|
||||
// custom separator
|
||||
name: 'splitChar',
|
||||
path: 'inputs.splitParams',
|
||||
parser: SchemaExtractorParserName.CUSTOM_SPLIT_CHAR,
|
||||
},
|
||||
],
|
||||
// Question 问题节点 18
|
||||
// Question Node 18
|
||||
[StandardNodeType.Question]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// question 问题
|
||||
// Question question
|
||||
name: 'question',
|
||||
path: 'inputs.question',
|
||||
},
|
||||
{
|
||||
// answer_type 回答类型 option|text
|
||||
// answer_type answer type option | text
|
||||
name: 'answerType',
|
||||
path: 'inputs.answer_type',
|
||||
},
|
||||
@@ -340,69 +340,69 @@ export const workflowExtractorConfig: SchemaExtractorConfig = {
|
||||
path: 'inputs.options',
|
||||
},
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// Break 终止循环节点 19
|
||||
// Break Stop Loop Node 19
|
||||
[StandardNodeType.Break]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
],
|
||||
// Set Variable 设置变量节点 20
|
||||
// Set Variables Set Variables Node 20
|
||||
[StandardNodeType.SetVariable]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.VARIABLE_ASSIGN,
|
||||
},
|
||||
],
|
||||
// Loop 循环节点 21
|
||||
// Loop node 21
|
||||
[StandardNodeType.Loop]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应variable name
|
||||
// Corresponding variable name
|
||||
name: 'variables',
|
||||
path: 'inputs.variableParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应output name
|
||||
// Corresponding output name
|
||||
name: 'outputs',
|
||||
path: 'outputs',
|
||||
parser: SchemaExtractorParserName.OUTPUTS,
|
||||
},
|
||||
],
|
||||
// Intent 意图识别节点 22
|
||||
// Intent recognition node 22
|
||||
[StandardNodeType.Intent]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
@@ -419,21 +419,21 @@ export const workflowExtractorConfig: SchemaExtractorConfig = {
|
||||
path: 'inputs.llmParam.systemPrompt.value.content',
|
||||
},
|
||||
],
|
||||
// Knowledge Write 知识库写入节点 27
|
||||
// Knowledge Writing Knowledge Base Writing Node 27
|
||||
[StandardNodeType.DatasetWrite]: [
|
||||
{
|
||||
// 节点自定义名称
|
||||
// Node custom name
|
||||
name: 'title',
|
||||
path: 'nodeMeta.title',
|
||||
},
|
||||
{
|
||||
// 对应input name
|
||||
// Corresponding input name
|
||||
name: 'inputs',
|
||||
path: 'inputs.inputParameters',
|
||||
parser: SchemaExtractorParserName.INPUT_PARAMETERS,
|
||||
},
|
||||
{
|
||||
// 对应知识库名称
|
||||
// Corresponding knowledge base name
|
||||
name: 'datasetParam',
|
||||
path: 'inputs.datasetParam',
|
||||
parser: SchemaExtractorParserName.DATASET_PARAM,
|
||||
|
||||
@@ -51,10 +51,10 @@ export class SchemaExtractor {
|
||||
}
|
||||
public extract(config: SchemaExtractorConfig): SchemaExtracted[] {
|
||||
this.bindParser(config);
|
||||
// 1. 遍历schema中node数组,对每个node做处理
|
||||
// 1. Traverse the node array in the schema and process each node
|
||||
return this.schema.nodes
|
||||
.map((node: WorkflowNodeJSON): SchemaExtracted | null => {
|
||||
// 2. 获取节点对应的配置
|
||||
// 2. Get the configuration corresponding to the node
|
||||
const nodeConfigs: SchemaExtractorNodeConfig[] = config[node.type];
|
||||
if (!nodeConfigs) {
|
||||
return null;
|
||||
@@ -76,13 +76,13 @@ export class SchemaExtractor {
|
||||
extractedConfig: Record<string, unknown>,
|
||||
nodeConfig: SchemaExtractorNodeConfig,
|
||||
): Record<string, unknown> => {
|
||||
// 3. 根据节点配置路径获取属性值
|
||||
// 3. Get the attribute value according to the node configuration path
|
||||
const rawData: unknown = this.extractProperties(
|
||||
nodeData,
|
||||
nodeConfig.path,
|
||||
);
|
||||
if (nodeConfig.parser && typeof nodeConfig.parser === 'function') {
|
||||
// 4. 使用解析器对属性值进行转换
|
||||
// 4. Use the parser to convert the property value
|
||||
extractedConfig[nodeConfig.name] = nodeConfig.parser(rawData);
|
||||
}
|
||||
return extractedConfig;
|
||||
@@ -121,7 +121,7 @@ export class SchemaExtractor {
|
||||
const flattenNodeJSONs: WorkflowNodeJSON[] = [...rootNodes];
|
||||
const flattenEdgeJSONs: WorkflowEdgeJSON[] = [...rootEdges];
|
||||
|
||||
// 如需支持多层结构,以下部分改为递归
|
||||
// To support multi-layer structures, the following section is changed to recursive
|
||||
rootNodes.forEach(nodeJSON => {
|
||||
const { blocks, edges } = nodeJSON;
|
||||
if (blocks) {
|
||||
|
||||
@@ -18,7 +18,7 @@ import { isWorkflowImageTypeURL } from '../utils';
|
||||
import { type SchemaExtractorOutputsParser } from '../type';
|
||||
import { AssistTypeDTO, VariableTypeDTO } from '../../../types/dto';
|
||||
export const outputsParser: SchemaExtractorOutputsParser = outputs => {
|
||||
// 判断是否为数组
|
||||
// Determine whether it is an array
|
||||
if (!Array.isArray(outputs)) {
|
||||
return [];
|
||||
}
|
||||
@@ -31,7 +31,7 @@ export const outputsParser: SchemaExtractorOutputsParser = outputs => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
value?: any;
|
||||
isImage?: boolean;
|
||||
// 默认值里包含图片时,图片信息单独放到这里
|
||||
// When the default value includes pictures, the picture information is put here separately.
|
||||
images?: string[];
|
||||
} = {
|
||||
name: output.name || '',
|
||||
@@ -45,7 +45,7 @@ export const outputsParser: SchemaExtractorOutputsParser = outputs => {
|
||||
if (output.type === 'list' && Array.isArray(output.schema?.schema)) {
|
||||
parsed.children = outputsParser(output.schema.schema);
|
||||
}
|
||||
// Start 节点默认值放到 value 上
|
||||
// Start node default value put on value
|
||||
if (output.defaultValue) {
|
||||
parsed.value = output.defaultValue;
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ export const variableAssignParser: SchemaExtractorVariableAssignParser =
|
||||
.map(variableAssign => {
|
||||
const leftContent = getValueExpressionName(variableAssign.left);
|
||||
const rightContent = getValueExpressionName(variableAssign.right);
|
||||
// 变量赋值节点的右值字段
|
||||
// Rvalue field of variable assignment node
|
||||
const inputContent = variableAssign.input
|
||||
? getValueExpressionName(variableAssign.input)
|
||||
: null;
|
||||
|
||||
@@ -29,7 +29,7 @@ export type SchemaExtractorConfig = Partial<
|
||||
|
||||
export interface SchemaExtractorNodeConfig {
|
||||
name: string;
|
||||
/** lodash.get 入参格式 */
|
||||
/** Lodash.get imported parameter format */
|
||||
path: string;
|
||||
parser?: SchemaExtractorParserName | Function;
|
||||
displayName?: string;
|
||||
@@ -93,7 +93,7 @@ export type SchemaExtractorOutputsParser = (outputs: VariableMetaDTO[]) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
value?: any;
|
||||
isImage?: boolean;
|
||||
// 默认值里包含图片时,图片信息单独放到这里
|
||||
// When the default value includes pictures, the picture information is put here separately.
|
||||
images?: string[];
|
||||
}[];
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ import { get } from 'lodash-es';
|
||||
|
||||
import { type ValueExpressionDTO } from '../../types';
|
||||
|
||||
// 是否我们自己上传生成的url, 这是个临时方案,等修复 schema 中的 type:string -> type:image 后,删掉此逻辑
|
||||
// Whether we upload the generated url ourselves, this is a temporary solution, after fixing the type: string - > type: image in the schema, delete this logic
|
||||
export function isWorkflowImageTypeURL(str: string): boolean {
|
||||
// base64 加工
|
||||
// base64 processing
|
||||
const hostWhiteList = [
|
||||
'cC1ib3Qtd29ya2Zsb3ctc2lnbi5ieXRlZGFuY2UubmV0',
|
||||
'cC1ib3Qtd29ya2Zsb3cuYnl0ZWQub3Jn',
|
||||
|
||||
@@ -18,14 +18,14 @@ import { reporter as infraReporter } from '@coze-arch/logger';
|
||||
const namespace = 'workflow';
|
||||
|
||||
/**
|
||||
* 流程使用的 slardar 上报实例
|
||||
* The slardar reporting instance used by the process
|
||||
*/
|
||||
export const reporter = infraReporter.createReporterWithPreset({
|
||||
namespace,
|
||||
});
|
||||
|
||||
/**
|
||||
* 异常捕获,会被当js error上报
|
||||
* Exception capture will be reported as a js error
|
||||
* @param exception
|
||||
* @param importErrorInfo
|
||||
*/
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
import { BOT_USER_INPUT, CONVERSATION_NAME, USER_INPUT } from '../constants';
|
||||
/**
|
||||
* 是否预设的开始节点的输入参数
|
||||
* Whether to preset the input parameters of the start node
|
||||
*/
|
||||
export const isPresetStartParams = (name?: string): boolean =>
|
||||
[BOT_USER_INPUT, USER_INPUT, CONVERSATION_NAME].includes(name ?? '');
|
||||
|
||||
/**
|
||||
* Start 节点参数是 BOT 聊天时用户的输入内容
|
||||
* The Start node parameter is the user's input during BOT chat
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
|
||||
@@ -38,9 +38,9 @@ export interface TraverseContext {
|
||||
export type TraverseHandler = (context: TraverseContext) => void;
|
||||
|
||||
/**
|
||||
* 深度遍历对象,对每个值做处理
|
||||
* @param value 遍历对象
|
||||
* @param handle 处理函数
|
||||
* Traverse the object in depth, processing each value
|
||||
* @param value over object
|
||||
* @param handling function
|
||||
*/
|
||||
export const traverse = <T extends TraverseValue = TraverseValue>(
|
||||
value: T,
|
||||
@@ -57,9 +57,9 @@ export const traverse = <T extends TraverseValue = TraverseValue>(
|
||||
|
||||
namespace TraverseUtils {
|
||||
/**
|
||||
* 深度遍历对象,对每个值做处理
|
||||
* @param node 遍历节点
|
||||
* @param handle 处理函数
|
||||
* Traverse the object in depth, processing each value
|
||||
* @param node traverse node
|
||||
* @param handling function
|
||||
*/
|
||||
export const traverseNodes = (
|
||||
node: TraverseNode,
|
||||
@@ -67,11 +67,11 @@ namespace TraverseUtils {
|
||||
): void => {
|
||||
const { value } = node;
|
||||
if (!value) {
|
||||
// 异常处理
|
||||
// exception handling
|
||||
return;
|
||||
}
|
||||
if (Object.prototype.toString.call(value) === '[object Object]') {
|
||||
// 对象,遍历对象的每个属性
|
||||
// Object, iterate through each property of the object
|
||||
Object.entries(value).forEach(([key, item]) =>
|
||||
traverseNodes(
|
||||
{
|
||||
@@ -84,8 +84,8 @@ namespace TraverseUtils {
|
||||
),
|
||||
);
|
||||
} else if (Array.isArray(value)) {
|
||||
// 数组,遍历数组的每个元素
|
||||
// 从数组的末尾开始遍历,这样即使中途移除了某个元素,也不会影响到未处理的元素的索引
|
||||
// Array, iterate through each element of the array
|
||||
// The iteration starts at the end of the array, so that even if an element is removed halfway through, it will not affect the index of the unprocessed element
|
||||
for (let index = value.length - 1; index >= 0; index--) {
|
||||
const item: string = value[index];
|
||||
traverseNodes(
|
||||
@@ -117,14 +117,14 @@ namespace TraverseUtils {
|
||||
});
|
||||
|
||||
const setValue = (node: TraverseNode, value: unknown) => {
|
||||
// 设置值函数
|
||||
// 引用类型,需要借助父元素修改值
|
||||
// 由于是递归遍历,所以需要根据node来判断是给对象的哪个属性赋值,还是给数组的哪个元素赋值
|
||||
// Set Value Function
|
||||
// Reference type, you need to modify the value with the help of the parent element
|
||||
// Since it is a recursive traversal, it is necessary to determine which property of the object to assign a value to, or which element of the array to assign a value to, according to node
|
||||
if (!value || !node) {
|
||||
return;
|
||||
}
|
||||
node.value = value;
|
||||
// 从上级作用域node中取出container,key,index
|
||||
// Remove container, key, index from upper scope node
|
||||
const { container, key, index } = node;
|
||||
if (key && container) {
|
||||
container[key] = value;
|
||||
@@ -162,7 +162,7 @@ namespace TraverseUtils {
|
||||
if (typeof pathItem === 'string') {
|
||||
const re = /\W/g;
|
||||
if (re.test(pathItem)) {
|
||||
// 包含特殊字符
|
||||
// Contains special characters
|
||||
return `${stringifyPath}["${pathItem}"]`;
|
||||
}
|
||||
return `${stringifyPath}.${pathItem}`;
|
||||
|
||||
Reference in New Issue
Block a user