@coze-workflow/base 包深度解析:Coze Studio 工作流基础层的 Hook、Store 与 API 架构
2026/9/14 14:58:53 网站建设 项目流程

@coze-workflow/base 包深度解析:Coze Studio 工作流基础层的 Hook、Store 与 API 架构

【免费下载链接】coze-studioAn AI agent development platform with all-in-one visual tools, simplifying agent creation, debugging, and deployment like never before. Coze your way to AI Agent creation.项目地址: https://gitcode.com/GitHub_Trending/co/coze-studio

导读

@coze-workflow/base是 Coze Studio 前端 monorepo 中 workflow 体系的基础包(base package),为整个工作流编辑器提供最底层的 Hook、Store 与 API 能力。在 Coze Studio 中,用户通过可视化画布编排"大模型节点、知识库检索、条件分支"等能力来构建 Agent,而@coze-workflow/base正是支撑这张画布运行的数据层与逻辑层基石。读完本文,你将掌握该包的安装方式、整体导出结构、各子模块(api / store / types / utils / hooks / entities / contexts)的真实实现细节,以及如何在自己的业务代码中正确引用它。

包定位:workflow 体系的"地基"

在 frontend/packages/workflow 目录下,工作流前端被拆分成了多个职责单一的子包,而base是其中最底层的基础包:

  • base:提供 hook、store、api 等基础能力(本文主角);
  • adapter/base:画布适配层(free-layout-editor 的桥接);
  • nodescomponentsrender:节点、通用组件与渲染层;
  • fabric-canvas:基于 Fabric.js 的画布实现;
  • playgroundtest-runtest-run-next:工作流调试与测试运行环境;
  • variablehistoryfeature-encapsulatesetters等:变量管理、历史记录、能力封装与表单设置器。

从依赖关系看(见 package.json),base依赖了@flowgram-adapter/free-layout-editor(底层流程图编辑器)、@coze-arch/bot-api(后端接口)、@tanstack/react-query(数据请求缓存)、zustand(状态管理)、io-ts(运行时类型校验)以及react。这意味着base并不是一个纯工具包,而是把"编辑器实体模型 + 后端接口 + 前端状态"三者打通的粘合层。

安装与引入

在 package.json 中声明依赖

在 Coze Studio 的 rush 工作区(monorepo)中,包之间通过workspace:*协议互相引用。在任意一个需要用到 workflow 基础能力的子包中添加:

{ "dependencies": { "@coze-workflow/base": "workspace:*" } }

然后执行依赖更新:

rush update

rush update会依据 rush.json 及common/config/rush下的配置解析工作区依赖并生成统一的 lockfile,是 Coze Studio 这类 pnpm-rush 混合 monorepo 的标准依赖安装方式。

按子路径引入(重要)

该包在 package.json 中通过exports声明了多个子路径导出,也就是说除了默认入口.之外,还支持按模块粒度引入,避免全量加载:

"exports": { ".": "./src/index.ts", "./api": "./src/api/index.ts", "./types": "./src/types/index.ts", "./store": "./src/store/index.ts", "./constants": "./src/constants/index.ts", "./services": "./src/services/index.ts" }

对应到代码中的写法:

import { workflowApi } from '@coze-workflow/base/api'; import type { WorkflowNode } from '@coze-workflow/base'; import { useWorkflowStore } from '@coze-workflow/base/store'; import { NODE_TEST_ID_PREFIX } from '@coze-workflow/base/constants';

值得说明的是,该包是一个纯源码包main字段直接指向./src/index.tsbuild脚本为exit 0,即不做编译产物,直接以 TS 源码形式被上层包消费(由上层构建链统一编译)。因此引入时无需关注 dist 产物路径。

导出结构:六个模块 + 两个实体

默认入口 src/index.ts 对外暴露了完整的 API 面:

export * from './types'; export * from './utils'; export * from './api'; export * from './store'; export * from './constants'; export * from './hooks'; export { WorkflowNode } from './entities'; export { WorkflowNodeContext } from './contexts';

对应 README 中 "Features: Hook / Store / Api" 以及 API Reference 中导出的WorkflowNodeWorkflowNodeContext。各模块职责如下表:

模块入口文件核心职责
typessrc/types/index.ts节点、VO、DTO、参数定义、LLM、数据库、视图变量树等类型
utilssrc/utils/index.ts表单助手、schema 提取器、节点结果提取器等工具函数
apisrc/api/index.tsworkflow 相关后端接口封装 + QueryClient 注入
storesrc/store/index.tszustand 工作流全局状态(节点/边)
constantssrc/constants/index.ts常量(变量名、命名规则、test-id 前缀等)
hookssrc/hooks/index.tsuseWorkflowNodeuseNodeTestId两个业务 Hook
entitiessrc/entities/workflow-node.tsWorkflowNode业务层节点类
contextssrc/contexts/workflow-node-context.tsxWorkflowNodeContextReact Context

下面逐模块展开实现细节。

API 层:后端接口的权限代理与请求客户端

workflowApi 的 Proxy 代理

src/api/index.ts 是 API 层的核心。它先全量 re-export 了@coze-arch/bot-api/workflow_api的所有接口,然后导出一个自定义的workflowApi

const workflowApi: typeof archWorkflowApi = new Proxy( {} as unknown as typeof archWorkflowApi, { get: (target, name: string) => { if (IS_BOT_OP && workflowOperationApiNameMap[name]) { return archWorkflowApi[workflowOperationApiNameMap[name]].bind(archWorkflowApi); } else { return archWorkflowApi[name].bind(archWorkflowApi); } }, }, );

这段代码解决了一个真实的工程问题:不同部署形态下同一接口对应不同的后端方法名workflowOperationApiNameMap建立了一张"普通接口名 → 运营平台(OP)接口名"的映射表,例如:

  • GetHistorySchemaOPGetHistorySchema
  • GetWorkFlowProcessOPGetWorkFlowProcess
  • GetCanvasInfoOPGetCanvasInfo
  • GetWorkflowDetailOPGetWorkflowDetail
  • VersionHistoryListOPVersionHistoryList
  • GetNodeExecuteHistoryOPGetNodeExecuteHistory
  • ListRootSpans/GetTraceSDK(链路追踪相关)

映射表覆盖了历史 schema、画布信息、引用关系、已发布工作流、API 详情、节点模板、灰度特性、提交版本校验、LLM 节点函数调用设置、触发器、节点执行历史、版本历史、ChatFlow 角色、根 Span 列表与 Trace SDK 等大量接口。注释中写明"Operating the interface platform will replace permission verification"(运营平台会替换权限校验),即当运行环境为IS_BOT_OP(运营平台)时,自动将调用路由到OP*前缀的同名接口,上层业务代码无需关心环境差异,直接调用workflowApi.xxx()即可。

withQueryClient:为组件注入 React Query 客户端

src/api/with-query-client.tsx 导出一个单例workflowQueryClient(基于@tanstack/react-query)以及一个高阶组件:

export function withQueryClient<T extends FC<any>>(Component: T): T { return function WrappedComponent(props) { return ( <QueryClientProvider client={workflowQueryClient}> <Component {...props} /> </QueryClientProvider> ); } as T; }

它解决了"某个组件需要在没有全局 QueryClientProvider 的环境下使用 useQuery"的场景。典型用法:

const MyNodePanel = () => { const { data } = useQuery({ queryKey: ['workflow-detail', id], queryFn: () => workflowApi.getWorkflowDetail(...) }); return <div>{/* ... */}</div>; }; export default withQueryClient(MyNodePanel);

对应测试见tests/api/with-query-client.test.tsx 与tests/api/api.test.ts。

Store 层:zustand 驱动的画布状态

src/store/workflow/index.ts 定义了useWorkflowStore,注释明确其职责:"currently holds the nodes and edges data of the flow"(当前持有流程的节点与边数据)。

interface WorkflowStoreState { nodes: WorkflowNodeJSON[]; // 节点数据 edges: WorkflowEdgeJSON[]; // 边数据 isCreatingWorkflow: boolean; // 是否正在创建工作流 }

其状态与动作:

状态字段含义动作行为
nodes画布上的全部节点(JSON 形态)setNodes替换节点数组,null时回退为空数组
edges节点间连线(JSON 形态)setEdges替换边数组,null时回退为空数组
isCreatingWorkflow是否处于"创建工作流"流程中setIsCreatingWorkflow设置布尔标记

nodes/edges的类型WorkflowNodeJSON/WorkflowEdgeJSON来自@flowgram-adapter/free-layout-editor,保证了与画布编辑器的数据契约一致;store 通过 zustand 的devtools中间件包装,便于在 Redux DevTools 中调试状态变化:

export const useWorkflowStore = create<WorkflowStoreState & WorkflowStoreAction>()( devtools(set => ({ ...initialStore, setNodes: ..., setEdges: ..., setIsCreatingWorkflow: ... })), );

组件内使用:

import { useWorkflowStore } from '@coze-workflow/base/store'; const nodes = useWorkflowStore(state => state.nodes); const setNodes = useWorkflowStore(state => state.setNodes);

对应的测试位于tests/store/workflow/index.test.ts。

常量层:工作流命名的"硬规则"

src/constants/index.ts 集中定义了一批被全工作流复用的常量,是理解业务规则的关键:

常量业务含义
EmptyFunction/EmptyAsyncFunction空函数 / 异步空函数作为默认回调,避免 undefined 调用
PUBLIC_SPACE_ID'999999'公共空间 ID
BOT_USER_INPUT'BOT_USER_INPUT'Bot 用户输入变量名
USER_INPUT'USER_INPUT'新版用户输入参数,与BOT_USER_INPUT功能相同,为 Coze 2.0 Chatflow 引入
CONVERSATION_NAME'CONVERSATION_NAME'起始节点会话名称导入参数
WORKFLOW_NAME_MAX_LEN30工作流名称最大字符数
WORKFLOW_NAME_REGEX/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/工作流命名正则(字母开头,可含数字与下划线,最长 64 字符)
NODE_TEST_ID_PREFIX'playground.node'节点 test-id 前缀

WORKFLOW_NAME_REGEXWORKFLOW_NAME_MAX_LEN共同约束了工作流/节点名称的合法范围:必须字母开头、总长度不超过 64 个字符(名称本身再受 30 字符的业务上限约束)。这在创建节点、重命名节点等场景下会被表单校验逻辑复用。

Hooks 层:节点上下文与测试标识

src/hooks/index.ts 导出两个 Hook。

useWorkflowNode:从 Context 取节点实体

export function useWorkflowNode() { const workflowNode = useContext(WorkflowNodeContext) as WorkflowNode; return workflowNode; }

它从WorkflowNodeContext中取出当前节点实体(WorkflowNode),必须在 Provider 内调用。测试见tests/hooks/use-workflow-node.test.tsx。

useNodeTestId:节点定位与自动化测试标识

src/hooks/use-node-test-id.ts 专为工作流节点内部的 UI 自动化测试定位而设计:

export const useNodeTestId: UseNodeTestId = () => { const node = useCurrentEntity(); if (!node?.id) { throw new CustomError('useNodeTestId must be called in a workflow node', ''); } const getNodeTestId = () => concatTestId(NODE_TEST_ID_PREFIX, node.id); return { getNodeTestId, // 'playground.node.11001' getNodeSetterId: setterName => concatTestId(getNodeTestId(), setterName), // 'playground.node.11001.llm' concatTestId, }; };

返回的三个能力:

  • getNodeTestId():返回当前节点 test-id,形如playground.node.11001
  • getNodeSetterId('llm'):返回当前节点下某个设置器的 test-id,自动带上节点前缀,形如playground.node.11001.llm
  • concatTestId('a', 'b'):连接两个 test-id 生成a.b

该 Hook 通过useCurrentEntity拿到当前画布实体,若脱离节点上下文调用会抛出CustomError,保证了使用约束。测试见tests/hooks/use-node-test-id.test.tsx,工具函数concatTestId的单测见tests/utils/concat-test-id.test.ts。

实体层:WorkflowNode 业务节点类

src/entities/workflow-node.ts 中的WorkflowNode业务层流程节点类,注释标明它是"encapsulation of node business rules"(节点业务规则的封装)。它包住一个底层FlowNodeEntity(来自 free-layout-editor),对外提供业务语义的访问器:

成员类型/签名说明
registrygetter返回节点注册表WorkflowNodeRegistry
typegetter节点类型(StandardNodeType
inputParametersgetter节点输入参数InputValueVO[],优先走 registry 的getNodeInputParameters,其次走inputParametersPath元数据,最后回退到/inputParameters路径取值
outputsgetter节点输出OutputValueVO[],优先 registry 的getNodeOutputs,否则读data.outputs
error/isErrorgetter节点错误信息与是否有错
setError(error)方法写入节点错误
isInitializedgetter表单是否已初始化
datagetter根路径/的表单值
setData(data)方法写入节点数据;兼容 FormV2(逐 keysetValueIn)与旧版表单(整体赋值)两种形态
getValueByPath(pathname)方法按路径读取表单值(基于 FormV2 的getValueIn
icon/title/descriptiongetter读取data.nodeMeta下的元信息

关键设计点有二:其一,inputParameters三级取值策略(registry 回调 → 元数据路径 → 约定路径回退)保证了不同节点形态都能正确取到输入参数;其二,setData内部用isFormV2(node)区分新版(FormModelV2 逐字段写入)与旧版(formItem 整体赋值)表单模型,向后兼容。对应的测试见tests/entities/workflow-node.test.ts。

Contexts 层:节点上下文桥

src/contexts/workflow-node-context.tsx 只做一件事——创建一个默认值为undefined的 Context:

export const WorkflowNodeContext = createContext<WorkflowNode | undefined>(undefined);

它是useWorkflowNode的数据来源,也是画布渲染层向节点内部组件注入"当前节点实体"的通道。测试见tests/contexts/workflow-node-context.test.tsx。

Types 与 Utils:类型体系与数据处理管线

Types

src/types/index.ts 汇总了工作流前端庞大的类型体系,包括:

  • 节点相关:node.ts、node-type.ts(StandardNodeType标准节点类型);
  • 数据结构:vo.ts(InputValueVO/OutputValueVO等)、dto.ts、block-input-dto.ts;
  • 参数定义:param-definition.ts;
  • 条件与数据集:condition.ts、data-set.ts、database.ts;
  • LLM 相关:llm.ts;
  • 视图变量树:view-variable-tree.ts、view-variable-type.ts;
  • 注册表与工作流:registry.ts、workflow.ts。

对应单测覆盖了 node-type、node、param-definition、view-variable-tree、vo、block-input-dto 等(见tests/types 目录)。

Utils

src/utils/index.ts 暴露了三个子目录的工具集与若干独立函数:

  • schema-extractor(src/utils/schema-extractor):负责从工作流配置/表单中提取 schema,包含 30 余个 parser,覆盖表达式解析(expression-parser.ts)、输入参数(input-parameters.ts)、输出(outputs.ts)、数据集参数(dataset-param.ts)、数据库字段与条件(db-fields.ts/db-conditions.ts)、意图(intents.ts)、JSON 字符串解析(json-string-parser.ts)、图片引用(image-reference.ts)、拼接/分隔字符(concat-result.ts/custom-array-concat-char.ts/custom-split-char.ts)等,并配套了完整的 parser 单测与 workflow/imageflow 两种 schema 的测试资源(见 src/utils/schema-extractor/tests);
  • node-result-extractor(src/utils/node-result-extractor):节点运行结果的提取与默认解析器(default-parser.ts),用于把后端返回的节点输出规整为前端可展示结构;
  • 独立工具函数:concat-test-id.ts(test-id 拼接)、form-helpers.ts(表单辅助)、is-general-workflow.ts(是否通用工作流判断)、output-image-parser.ts(输出图片解析)、start-params.ts(起始参数处理)、get-file-accept.ts(文件接受类型)等。

工程配套:测试、代码质量与构建

该包的开发配套体现了 Coze Studio 前端工程化的统一规范:

  • 测试:基于 Vitest,测试命令为vitest --run --passWithNoTests,测试覆盖 api、store、hooks、contexts、entities、types、utils 全模块(tests目录);
  • 代码质量:ESLint 走@coze-arch/eslint-config工作区配置(eslint.config.js);
  • TypeScript 配置:继承@coze-arch/ts-config(tsconfig.json);
  • rush 集成:包级别构建配置见 config/rush-project.json,由根目录 rush.json 统一调度。

由于是纯源码包(build脚本为空操作),修改源码后上层包在构建/开发时即可直接感知变化,无需先产出 dist。

总结:一张图看懂 base 包在 workflow 体系中的位置

综合以上源码分析,可以归纳出@coze-workflow/base的核心价值:

  1. 数据契约层types定义了节点、VO、DTO 等全链路类型,store用 zustand 持有画布 nodes/edges 状态,constants固化命名规则与特殊变量名;
  2. 接口层api通过 Proxy 自动适配普通环境与运营平台(OP)环境的接口差异,并用withQueryClient为局部组件注入 React Query 客户端;
  3. 业务模型层WorkflowNode封装节点业务规则(输入输出、错误、表单读写),WorkflowNodeContext+useWorkflowNode打通"画布实体 → 组件"的数据流,useNodeTestId则为自动化测试提供稳定的 DOM 定位标识;
  4. 数据处理层schema-extractornode-result-extractor支撑表单 schema 提取与节点运行结果解析。

它是上层nodescomponentsrenderplayground等子包共同依赖的地基——任何想深入 Coze Studio 工作流前端源码的开发者,都应从理解这个包开始。阅读时建议配合 README.md(本包说明)、package.json(依赖与导出)以及各模块的__tests__单测文件,先看导出、再读实现、最后用测试反向验证行为预期。

【免费下载链接】coze-studioAn AI agent development platform with all-in-one visual tools, simplifying agent creation, debugging, and deployment like never before. Coze your way to AI Agent creation.项目地址: https://gitcode.com/GitHub_Trending/co/coze-studio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询