ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

InvokeAI Call Saved Workflow 架构深度解析:从调用边界到嵌套执行的工作流复用引擎

InvokeAI Call Saved Workflow 架构深度解析:从调用边界到嵌套执行的工作流复用引擎 InvokeAI Call Saved Workflow 架构深度解析从调用边界到嵌套执行的工作流复用引擎【免费下载链接】InvokeAIInvoke is a leading creative engine for Stable Diffusion models, empowering professionals, artists, and enthusiasts to generate and create visual media using the latest AI-driven technologies. The solution offers an industry leading WebUI, and serves as the foundation for multiple commercial products.项目地址: https://gitcode.com/GitHub_Trending/in/InvokeAI导读本文基于 InvokeAI 仓库中的 调用已保存工作流架构文档完整讲解 InvokeAI 如何将call_saved_workflow打造成引擎原生的工作流调用边界父工作流按 ID 调用一个已保存工作流、编辑器根据子工作流暴露的表单字段动态重绘调用节点、运行时在调用节点处挂起父工作流、以独立依赖执行的方式运行子工作流、捕获显式命名返回值后再恢复父工作流。读完本文你将掌握这一特性的节点模型、执行契约、队列生命周期、批量展开规则、嵌套与递归约束以及对应的源码实现位置可直接在真实项目中复现与验证这套架构。一、背景与设计目标为什么需要工作流调用在 InvokeAI 中工作流是用户在编辑器中绘制的节点图可保存到工作流库供后续复用。此前复用一个已保存工作流的方式局限于前端动态节点或编译期图内联二者都有明显缺陷前端动态节点可调用逻辑依附于前端外部提交的图无法复用编译期图内联graph inliner把子工作流整个展开进父图会导致执行图膨胀、破坏工作流边界且难以表达显式返回值。因此本特性的长期目标是让CallSavedWorkflowInvocation成为引擎原生的工作流调用边界call boundary具体能力包括父工作流按workflow_id调用一个已保存工作流调用节点根据所选工作流暴露的表单字段在编辑器中动态重绘父节点的值与入边连接作为调用参数绑定到这些暴露字段执行在调用节点处挂起将所选工作流作为依赖的子工作流执行运行捕获显式返回值后恢复父工作流架构同时服务于前端图与使用同一节点类型的外部提交图。该特性的核心节点与运行时脚手架在源码中均已就位真正的调用节点位于 call_saved_workflow.py真正的返回节点位于 workflow_return.py运行时协调逻辑位于 workflow_call_runtime.py。实现优先级正确架构优先于最快路径设计文档明确要求每个增量都必须满足三点可在隔离环境中测试、与长期架构兼容、不破坏既有代码与现有工作流执行行为。速度不是本阶段的首要目标首要目标是走向持久化设计避免引入日后需要回退的一次性执行语义。二、当前实现状态总览已实现的节点与编辑器能力真实调用节点call_saved_workflow与真实返回节点workflow_return均已存在通过workflow_return_value构造单个命名返回值、workflow_return汇总返回、调用侧的workflow_return_get按键提取实现命名返回workflow_return可接受一个键值返回成员或一个收集好的返回成员列表然后输出命名的values: dict[str, Any]映射每个工作流只允许一个workflow_return节点前端校验与 Python 校验双重强制前端提供基于可复用SavedWorkflowFieldUI 类型的已保存工作流选择器节点根据所选已保存工作流的暴露表单字段动态重绘动态字段值随父工作流持久化切换工作流时具有匹配暴露字段标识与兼容类型的入边被保留不兼容或不再暴露的入边在编辑器中移除后端已实现workflow_id的存在性与访问权限校验。已实现的运行时脚手架GraphExecutionState持久化了工作流调用运行时状态新增字段包括workflow_call_stack、workflow_call_history、workflow_call_parent、waiting_workflow_call、waiting_workflow_call_execution、waiting_workflow_call_child_session、max_workflow_call_depth。这些字段定义于 graph.py其中max_workflow_call_depth默认值为4作为嵌套与递归调用的运行时深度上限。核心运行时行为嵌套与递归调用由调用栈表示运行时深度上限为 4父子调用身份在运行时状态中显式化父会话等待期间跟踪活动WorkflowCallExecution记录已完成与失败的调用保留在workflow_call_history子会话携带workflow_call_parent引用回父调用关系父会话等待子调用期间GraphExecutionState.next()不返回任何可运行节点is_complete()保持falseDefaultSessionRunner.run_node()将call_saved_workflow视为调用边界而非普通可执行节点见 session_processor_default.py进入边界时runner 校验所选工作流、构建调用帧、将已保存工作流 JSON 转换为后端Graph、校验并应用父调用参数、创建子GraphExecutionState、将子会话挂到等待中的父会话上。队列生命周期与批量能力WorkflowCallCoordinator负责调用专用设置构建子图、应用父参数、创建子状态、挂起父会话并入队子队列项WorkflowCallQueueLifecycle负责队列可见的父子生命周期运行子队列项、子成功后恢复等待中的父、以子workflow_return值完成父调用节点、子失败时级联失败子SessionQueueItem携带workflow_call_id、parent_item_id、parent_session_id、root_item_id、workflow_call_depth等关系元数据session_queue表也有对应持久化列父队列项在挂起期间进入真正的waiting状态动态调用参数端到端执行字面量动态值在构图期序列化进隐藏的workflow_inputs负载过期的隐藏值被忽略类型兼容时保留既有动态输入值类型变化则重置为子工作流当前初始值连接的动态值作为调用边界专用边在运行时从父结果解析队列生命周期语义完整父挂起waiting、子成功恢复父、子失败向上级联、取消父级联取消子孙、取消子级联取消等待中的父、批量失败后取消剩余兄弟项、删除链上任一项即删除整条链、cancel_all_except_current/delete_all_except_current保留活动项及其祖先/后代链、重试以根为导向UI 上子队列行只保留Cancel、隐藏Retry子队列行创建为失败即清理若边界设置失败时已插入部分子行先删除这些子行再失败父调用子队列扇出受剩余队列容量约束而非仅全局队列大小超出剩余 pending 容量的调用直接失败子插入与 pending 容量重检在同一数据库事务内完成。转换辅助与兼容性门禁workflow_graph_builder.py 将已保存工作流 JSON 转换为可执行后端Graph目前支持本特性所需的 invocation 节点子集扁平化 connector 节点并在存在连接时省略显式目标字段值与前端构图语义一致它同时充当首个显式可调用工作流兼容性门禁所选工作流必须恰好含一个workflow_return节点普通非生成器上游节点产生的连接批量输入会以清晰的 unsupported-feature 错误提前失败畸形批量输入布线含一个批量字段多个连接输入报告为unsupported_batch_input兼容性错误混合受支持批量节点与无关生成器节点的子工作流被拒绝不支持的被调用工作流在任何子队列行创建前即被拒绝兼容性元数据通过工作流库 API 暴露工作流列表项与详情响应包含call_saved_workflow_compatibility列表项使用结构化的生成器批量检查以避免枚举 board 中每张图片选择器用该元数据禁用不支持的工作流被选中的不支持工作流仍可渲染并显示明确的不支持状态与本地化原因。尚未实现的部分由普通非生成器上游节点产生批量值的连接批量子输入仍不支持须以清晰领域错误失败混合受支持批量节点与无关生成器节点的子工作流仍不支持更广泛的子工作流兼容性覆盖仍需从真实的不支持形态扩展而非试图通过当前 graph-builder 路径解释每个仅前端的工作流表示当前工作流调用队列生命周期仍通过专用运行时类实现尚未泛化为完整父子调度器模型。文档的结论是编辑器契约与父侧运行时调用边界已基本就位子执行、参数转发、显式子返回捕获、父挂起状态、队列可见子行与向上失败级联均可工作剩余主要运行时工作是加固并泛化父子调度器模型。三、核心节点模型调用节点与返回节点3.1 CallSavedWorkflowInvocation调用节点定义在 call_saved_workflow.py注册类型为call_saved_workflow标注为Classification.Betause_cacheFalse调用结果不可缓存。其核心字段workflow_id: str所选已保存工作流 ID由编辑器 UI 管理ui_typeUIType.SavedWorkflowworkflow_inputs: dict[str, Any]所选工作流暴露输入的字面量值由编辑器 UI 管理ui_hiddenTrue隐藏。动态输入字段名以saved_workflow_input::为前缀常量CALL_SAVED_WORKFLOW_DYNAMIC_FIELD_PREFIX形如saved_workflow_input::{nodeId}::{fieldName}。is_call_saved_workflow_dynamic_input()与parse_call_saved_workflow_dynamic_input()分别用于判断与解析这类字段解析出子工作流中的node_id与input_field_name。validate_selected_workflow()执行双重校验先通过workflow_records.get(workflow_id)确认工作流存在WorkflowNotFoundError转为清晰的 ValueError在多用户模式下再校验访问权——用户必须是工作流所有者、工作流是 Default 类别、工作流公开或用户是管理员否则抛出所选已保存工作流对该用户不可访问错误。该访问控制逻辑与设计文档运行时必须强制与别处相同的已保存工作流访问规则完全一致。注意invoke()本身只做校验并返回空values{}的WorkflowReturnOutput——真正的执行由 runner 的边界逻辑接管这也印证了调用节点不是普通可执行节点的设计。3.2 命名返回节点族返回节点全部定义在 workflow_return.py节点/输出类型职责WorkflowReturnOutput输出values: dict[str, Any]即显式命名返回值映射WorkflowReturnValueField一个命名返回项含key: str与value: Anyworkflow_return_value由 key 与连接的值构造单个WorkflowReturnValueFieldkey 为空时报错workflow_return接受单个或列表形式的返回成员合并为命名映射同一执行内重复 key 直接报错workflow_return_get调用侧提取节点从命名映射中按键取值缺失 key 明确失败workflow_return的合并逻辑值得注意输入既可以是单个WorkflowReturnValueField也可以是列表对应编辑器里一个返回节点直接接收一个返回值或收集多个返回值后连接列表两种布线方式最终输出WorkflowReturnOutput(valuesnamed_values)其中空 key 与重复 key 都会抛出明确错误。3.3 返回值流设计文档定义了严格的返回值流转路径且明确返回值不应写回已保存工作流记录也不应从前端状态推导子工作流像普通节点输出一样计算命名返回成员子工作流将单个返回成员直接连到workflow_return.values或收集多个返回成员后把列表连到workflow_return.values子工作流到达workflow_return时运行时把解析出的命名映射捕获为子工作流结果子工作流结果存入子执行状态该结果交还给挂起的父调用帧父call_saved_workflow节点以该命名映射完成父图恢复执行。四、执行契约详解4.1 可调用接口已保存工作流的可调用接口由其已保存工作流 JSON 定义主来源是workflow.form旧工作流回退到workflow.exposedFields。只有子工作流表单暴露的字段才是可调用输入图中存在但未暴露的内部输入不属于公共调用接口。在 workflow_graph_builder.py 中_collect_exposed_inputs_from_form()从表单根元素出发广度优先遍历node-field元素把fieldIdentifier中的nodeId与fieldName组合成动态输入名get_exposed_workflow_input_names()则是兼容性分析中枚举暴露输入的入口。4.2 输入参数与运行时绑定call_saved_workflow根据所选工作流的可调用接口在编辑器中暴露动态输入。保存工作流选择器会把类型化搜索文本发送到工作流列表端点保证大工作流库即使尚未加载进 combobox 分页也能被发现。每个动态输入必须具备稳定的外部句柄名类型子工作流定义时的默认值若有可用的用户可见标签与描述若有。当前快速路径身份基于子nodeId fieldName在编辑器中短期可接受但如果子工作流频繁复制或重构长期应引入稳定的接口 ID。运行时父节点到达call_saved_workflow时引擎解析workflow_id→ 加载所选子工作流记录 → 从保存 JSON 重建可调用接口 → 从父节点动态输入收集参数值 → 启动依赖的子工作流执行。参数值来源有二父字面量字段值、解析后的入边连接到调用节点动态输入。对批量感知的子工作流父调用边界仍传递普通暴露表单输入批量应从子工作流自身的内部批量节点或生成器涌现而非单独的调用侧批量协议。4.3 子工作流执行语义子工作流作为独立的依赖执行上下文运行而非父图的内联副本。期望语义父在调用节点暂停 → 子执行在适当处继承上下文 → 子完成或失败 → 仅在子成功时父恢复。这要求队列/会话/运行时层存在显式的父子执行关系。当前限制graph-builder 路径仍只重建子工作流的普通 invocation 子集直接批量专用子工作流与生成器驱动批量子工作流已绕过该路径使用队列批量展开连接批量输入非生成器上游产生仍不支持当前队列可见子执行路径仍依赖WorkflowCallCoordinator直接恢复/失败父而非更通用的队列调度抽象。4.4 队列生命周期契约这是当前用户可见契约的核心部分根/父队列项在子调用挂起期间进入waiting子工作流执行是携带显式父子关系元数据的真实队列行子完成恢复挂起的父并交还正常队列执行子失败使挂起的父调用节点失败并通过祖先链向上级联取消操作是链感知的取消等待中的父会取消后代取消子会取消等待中的祖先批量兄弟项中一个失败后取消其余会包含这些兄弟项的嵌套后代除当前外全部取消/删除保留活动项及其父/子链含处理器交接窗口期waiting父 pending子同时仍取消/删除无关等待链重试操作是根感知的重试根项创建新的根执行后端把对子项的重试规范化为对根的重试重试与整链删除的授权按根队列项所有者校验子队列行不暴露直接重试入口重试 websocket 投递按所有者隔离——管理员重试多个用户拥有的根时每个非管理员用户只收到自己根的重试 item id工作流实时更新 socket 在认证多用户与未认证单用户模式下都加入工作流事件房间单用户模式下 CRUD 事件只发给 admin 房间以避免重复投递公开转私有过渡发出 schema 定义的workflow_access_revoked事件给共享订阅者非所有者/非管理员客户端清除引用所有者与管理员保留访问选择器分别查询自有/默认工作流与公开共享工作流按工作流 id 合并并在 combobox 菜单到达末尾时翻页队列状态事件必须保持用户隔离QueueItemStatusChangedEvent.queue_status可保留全局聚合计数但内嵌的当前项标识item_id、session_id、batch_id只有在当前进行项属于事件所有者或构建于 admin/全局上下文时才出现工作流调用子入队事件使用与普通状态转换相同的所有者感知脱敏。4.5 批量子工作流Batch Child Workflows当前实现支持四类直接批量专用子工作流image_batch、string_batch、integer_batch、float_batch并支持生成器驱动的批量子工作流integer_generator、float_generator、string_generator、image_generator使用image_generator_images_from_board。当前语义批量专用节点在普通图校验前从可执行子图中移除为这些节点供数的受支持生成器节点同样被移除它们的出边被转换为队列批量替换batch substitutions未分组批量节点按笛卡尔积展开分组批量节点按batch_group_id按位拉链zip每次展开创建一条子队列行一个批量会话受支持生成器的值形状在队列批量展开前解析为具体批量项声明的生成器计数在解析前若超出剩余子容量即被拒绝笛卡尔积大小在生成会话前用算术计算而非物化乘积批量输出可直接喂给命名workflow_return_value.value每个展开的子返回该 key 的一个值父恢复会等待该调用关联的所有子行父返回聚合产生values: dict[str, list[Any]]每个 key 对应每个子行的一个值一次批量调用中所有子行必须返回相同 key 集合key 不匹配会明确失败父调用任一子行失败时取消其余兄弟子行并失败父调用生成器驱动图片批量必须尊重 board 访问调用者可展开自有 board管理员可展开任意 board共享/公开 board 可被其他用户展开不可访问的私有 board 必须在图片展开前失败避免跨用户泄露 board 内容。当前生成器覆盖范围整数生成器算术序列、线性分布、解析字符串、带种子的均匀随机分布浮点生成器算术序列、线性分布、解析字符串、带种子的均匀随机分布字符串生成器解析字符串、动态提示组合dynamic prompts combinatorial、动态提示随机图片生成器从 board 取图。仍然不支持批量值由非生成器上游节点产生的连接批量输入。文档给出的批量调用通俗流程父工作流到达call_saved_workflow→ 父暂停进入waiting→ 执行前检查子工作流 → 若含受支持批量输入一次调用展开为多次子执行 → 每次展开成为自己的队列行 → 每个子队列行保留替换后的批量field_values与普通批量队列行一致→ 子队列行独立运行 → 父在所有子队列行完成后才恢复 → 每个子执行产生自己的命名workflow_return.values→ 父聚合为values: dict[str, list[Any]]→ 调用节点以该命名映射完成父继续。展开规则示例文档原例未分组输入[1, 2]与[10, 20]产生 4 个子执行(1,10)、(1,20)、(2,10)、(2,20)相同batch_group_id的分组输入[1,2,3]与[10,20,30]产生 3 个子执行(1,10)、(2,20)、(3,30)。4.6 易错点Tricky Areas契约中以下语义最容易误读代码与测试中必须保持显式等待与恢复waiting状态的父队列行是挂起而非完成父只有在关联该调用的每个子队列行都达到终态后才恢复返回聚合每个子队列行返回自己的命名workflow_return.values批量调用时父节点输出为values: dict[str, list[Any]]一次批量调用内所有子行必须返回相同 key 集合以保证每个列表按行对齐非批量子若需在单个 key 下返回多张图片须先把图片收集进一个列表值再返回该 key兄弟失败行为批量调用中一个子队列行失败 → 取消同一调用的其余兄弟子行父返回聚合拒绝某已完成子行 → 同样取消其余兄弟子行兄弟取消后父调用失败若该父本身是另一调用的子失败继续沿祖先链向上取消行为取消等待中的父会取消后代子行取消子行会取消等待中的祖先取消就是取消不应改写成普通失败语义启动恢复会取消任何中断的in_progress或waiting调用链含 pending 后代防止重启后挂起父永远等不到不会回报的子行重试行为重试以根为导向UI 不应直接重试子队列行后端对子 id 的重试应规范化为根调用链而非创建孤立的仅子重跑。4.7 错误传播子执行失败时调用节点失败除非后续设计加入显式错误处理语义父工作流失败。首个实现中失败传播保持简单且严格。4.8 访问控制运行时必须强制与已保存工作流其他使用处相同的访问规则——调用者只有在其被允许在运行时访问该已保存工作流时才能执行子工作流。这一点即使父工作流是在子工作流曾经可见的上下文中编写的也依然成立即运行时复查而非信任创作期可见性。源码中CallSavedWorkflowInvocation.validate_selected_workflow()正是这一规则的实现。4.9 递归与嵌套嵌套与递归的call_saved_workflow执行被允许但有界允许嵌套调用允许递归调用最大调用深度上限为 4 个调用帧深度上限在运行时基于活动调用栈强制而非仅静态校验。这在 graph.py 的build_workflow_call_frame()中体现next_depth get_workflow_call_depth() 1超过max_workflow_call_depth默认 4即抛Maximum workflow call depth exceeded错误。这样既允许合法的递归或有条件终止的工作流结构又防止无界调用增长。五、运行时组件与源码落点5.1 调用边界入口DefaultSessionRunner在 session_processor_default.py 的run_node()路径中检测到CallSavedWorkflowInvocation时不再走普通invoke_internal执行而是先validate_selected_workflow(context)再调用workflow_call_coordinator.begin_workflow_call_boundary(invocation, queue_item, workflow_record)后返回——这是调用边界在引擎执行栈中的权威落点保证外部提交图与前端图走同一路径。5.2 WorkflowCallCoordinator定义于 workflow_call_runtime.py负责调用专用设置容量预检max_queue_size - pending计算剩余容量不足即失败build_workflow_call_frame()构建调用帧含深度检查_collect_call_saved_workflow_inputs()收集字面量workflow_inputs与已解析的动态入边连接值build_child_workflow_session_results()构建子会话见 5.5begin_waiting_on_workflow_call()挂起父会话并附加子会话在同一事务内保存父会话、逐条enqueue_workflow_call_child()入队子行、记录子行 id、suspend_queue_item()挂起父失败即清理若部分子行已插入而后失败先delete_queue_items_by_id()删除这些子行再让父失败。build_child_queue_item()展示了子队列行的关系元数据构造workflow_call_id、parent_item_id、parent_session_id、root_item_id无祖先时回退为自身 item_id、workflow_call_depth、field_values。5.3 WorkflowCallQueueLifecycle同文件中的WorkflowCallQueueLifecycle负责队列可见的父子生命周期核心方法get_waiting_workflow_call_invocation()从waiting_workflow_call帧定位父节点上的调用节点get_child_workflow_return_output()从子会话的source_prepared_mapping定位唯一的workflow_return执行并取出WorkflowReturnOutput_resume_parent_from_completed_child()子完成后读取返回输出调用父会话的record_waiting_workflow_call_child_completion()记录并判断是否所有子行均完成聚合失败时取消其余子并失败父全部完成后以聚合值complete()父调用节点、complete_queue_item()或resume_queue_item()恢复父若父自身也是子则递归向上恢复_fail_parent_from_failed_child()子失败时取消该调用其余子、以子错误消息失败父、并沿parent_item_id链向上级联_cancel_parent_from_canceled_child()子取消时取消等待中的父run_queue_item()作为子队列行的统一执行入口——先run()子会话再根据子终态completed/failed/canceled分派到上述恢复/失败/取消逻辑父链上某项已被删除如清空队列则安全返回。5.4 GraphExecutionState 的调用栈graph.py 中的WorkflowCallFrame表示嵌套调用链中的一个帧含prepared_call_node_id、source_call_node_id、workflow_id、depth等GraphExecutionState用workflow_call_stack、workflow_call_history、waiting_workflow_call、waiting_workflow_call_execution、waiting_workflow_call_child_session等字段描述等待状态并通过is_waiting_on_workflow_call()waiting_workflow_call is not None、get_workflow_call_depth()、create_child_workflow_execution_state()支撑嵌套执行——后者把[当前调用栈 新帧]与继承的max_workflow_call_depth传给子状态。父会话等待期间next()返回无可运行节点、is_complete()为 false 的实现也在此。5.5 WorkflowGraphBuilder 与批量会话构建workflow_graph_builder.py 是已保存工作流 JSON → 后端 Graph的转换器只处理 invocation 节点子集扁平化 connector 节点常量CONNECTOR_INPUT_HANDLE in、CONNECTOR_OUTPUT_HANDLE out存在连接时省略显式目标字段值异常类型UnsupportedWorkflowNodeError与InvalidWorkflowInputError分别对应不支持节点与非法输入。与之配套的 workflow_call_batch.py 提供build_child_workflow_sessions()/build_child_workflow_session_results()实现批量展开、生成器值解析、笛卡尔积算术计算与每个展开子会话的构建。5.6 兼容性元数据workflow_call_compatibility.py 实现get_workflow_call_compatibility()先统计workflow_return节点数0 个 →MissingWorkflowReturn多个 →MultipleWorkflowReturn再通过_build_compatibility_workflow_inputs()为必需暴露输入合成占位值str→、int→0、float→0.0、bool→False、list→[]、dict→{}、ImageField→占位图片名等保证调用者一旦提供暴露值即有效的工作流不会被过早禁用随后尝试构建子会话将InvalidWorkflowInputError、UnsupportedWorkflowNodeError含批量相关消息归类为UnsupportedBatchInput、TooManySessionsError→ExceedsCapacity映射为结构化WorkflowCallCompatibilityReason。该结果随工作流库 API 响应列表项与详情暴露给前端选择器。六、命名返回实现阶段设计文档把命名返回拆为五个阶段并给出每阶段的契约与先写测试清单Stage 1 后端返回契约已实现有后端 invocation 测试WorkflowReturnValueField存一个key: strvalue: Anyworkflow_return_value构造单个字段workflow_return接受单成员或成员列表WorkflowReturnOutput暴露values: dict[str, Any]非批量单次执行中重复 key 无效。测试覆盖单键值对发射、单/多成员命名映射、重复 key 拒绝。Stage 2 调用侧提取原语已实现workflow_return_get接受命名映射与 key输出Any缺失 key 清晰失败。测试覆盖提取既有 key、缺失 key 报错、Any值可经既有连接兼容规则喂给下游类型化节点。Stage 3 运行时传播已实现非批量子执行返回values: dict[str, Any]call_saved_workflow在输出暴露该映射失败/取消/重试生命周期行为不变。测试覆盖{image: ...}完成父输出、提取节点在父恢复后消费、缺失/非法workflow_return节点以既有清晰错误失败。Stage 4 批量返回聚合已实现每个子行一个命名映射父聚合为dict[str, list[Any]]同调用内 key 集合一致跨子行重复 key 是正常聚合路径单子行内重复 key 仍非法。测试覆盖批量子产出{image: [image_1, image_2, ...]}、兄弟失败取消与父失败、单行重复 key 拒绝而非静默聚合。Stage 5 前端 schema/UI/文档基本实现生成 schema/类型含返回字段、返回值节点与提取节点可见 UI 字符串经en.json本地化call_saved_workflow暴露命名返回映射输出用户可把它接到workflow_return_get。前端连接/类型测试覆盖返回收集布线、workflow_return_value.value → workflow_return.values直连、call_saved_workflow.values → workflow_return_get.values。七、前端职责与后续演进长期设计中前端只负责编辑器期行为选择已保存工作流按子可调用接口重绘动态输入持久化动态字段及其值切换选择时保留兼容入边以可预测方式清理不兼容边与失效选择利用后端兼容性元数据避免把不支持的工作流呈现为可调用选项兼容性分析已通过合成占位值容忍必需暴露输入。潜在未来优化增加返回规范化可调用工作流接口的后端端点让前端免于重新解析完整保存负载来重绘节点并为漂移检测提供后端权威的接口哈希。八、测试覆盖与下一步已覆盖的测试对应文档Tests Needed Going Forward清单GraphExecutionState上的调用栈与等待状态深度上限强制等待阻塞调度等待中父会话不完成runner 边界入口校验失败与深度失败仍走普通节点错误路径子工作流 JSON 转后端Graph子图构建失败不使父残留部分等待状态子状态挂到等待中的父会话协调器负责的子执行完成父队列项而非卡在in_progress字面量与连接动态参数运行时应用到子图未暴露动态参数运行时被拒子workflow_return输出捕获并成为父调用输出命名返回值的构造、传播、按键提取与dict[str, list[Any]]批量聚合无workflow_return节点的子工作流被调用时干净失败子SessionQueueItem事件携带稳定调用关系元数据父子恢复与失败经队列可见子行传播有界栈深度的嵌套运行直接与生成器驱动批量专用子工作流经子行展开暴露输入、缺失/多返回、命名批量返回形态与不支持批量布线的兼容性元数据。后续增量仍需任何新支持的批量/生成器形态在契约变化时的聚焦测试仅在另一特性需要可复用依赖队列项时才考虑把专用工作流调用队列生命周期迁移到更通用的调度器/队列生命周期模型。设计文档给出的推荐立即下一步是停止添加特性切片除非关闭具体正确性缺口或解锁真实用户工作流通过评审、定向测试运行与清理过时设计文档措辞来稳定当前分支把从WorkflowCallQueueLifecycle到泛化父子队列生命周期的迁移视为更大的架构切片而非琐碎跟进工作。结语当前分支已到关键节点父调用边界状态存在可从所选已保存工作流创建子执行状态子执行、参数转发、显式返回传播、父挂起状态、队列可见子行与向上失败级联都通过现有 coordinator queue 路径工作但长期泛化的父子调度语义仍未实现。若你需要在 InvokeAI 上继续开发该特性建议从阅读 call_saved_workflow.py、workflow_return.py、workflow_call_runtime.py 与 workflow_graph_builder.py 四份源码入手配合tests/app/invocations/与tests/app/services/下的相关测试用例验证执行契约再按队列生命周期契约一节逐步验证取消、重试、批量与级联失败行为。【免费下载链接】InvokeAIInvoke is a leading creative engine for Stable Diffusion models, empowering professionals, artists, and enthusiasts to generate and create visual media using the latest AI-driven technologies. The solution offers an industry leading WebUI, and serves as the foundation for multiple commercial products.项目地址: https://gitcode.com/GitHub_Trending/in/InvokeAI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表