Skip to content

Feature: AI 生成状态机

一句话目标

用户在任意节点点击生成后,系统调用 AI API 完成生成,结果自动填充节点,全程有明确的状态反馈。

行为约束

约束 1:状态转换规则

节点生成状态仅允许以下转换,任何其他转换为非法:

  • idlegenerating(点击生成按钮)
  • generatingdone(API 成功返回)
  • generatingerror(API 抛出异常)
  • doneidle(用户修改 prompt 或重新生成时隐式重置)
  • errorgenerating(用户重试)

约束 2:generating 期间禁止重复提交

前置条件: 节点状态为 generating行为: 当前请求被取消,新请求立即发起 后置条件: 旧请求的回调被忽略,不更新节点状态

约束 3:generating 期间展示 loading

前置条件: 节点状态为 generating行为: 节点内容区显示 loading 状态 后置条件: 生成完成(done/error)后 loading 消失

约束 4:生成结果填充

前置条件: API 成功返回且请求未被 abort 行为: 结果写入节点数据(TextNode → content,ImageNode → imageUrl/results,VideoNode → videoUrl) 后置条件: 节点状态变为 done

约束 5:API 错误不丢失用户输入

前置条件: API 调用失败(网络错误或 ApiError) 行为: 节点状态变为 error,显示 toast 错误信息 后置条件: prompt、现有内容、已上传的文件均保持不变

约束 6:不兼容上游输入的处理

前置条件: 下游节点有上游连线,但上游节点类型与当前模型不兼容 行为: 生成时忽略不兼容的上游输入,toast 提示用户(如"当前模型不支持视频输入") 后置条件: 生成正常发起,仅携带兼容的上游输入和用户自身的 prompt

详见 ADR-008

约束 7:组件卸载时清理

前置条件: 用户在 generating 期间离开画布或删除节点 行为: onUnmounted 中 abort 当前请求 后置条件: 不会有悬挂的 Promise 回调更新已卸载的组件

状态机

idle ──[点击生成]-→ generating ──[成功]-→ done
  ↑                     │
  │                     └──[失败]-→ error
  │                                   │
  └──────[修改重试]───────────────────┘
done ──[重新生成]-→ generating

Acceptance Criteria

  • [x] AC-01:节点初始状态为 idle
  • [x] AC-02:点击生成后立即进入 generating,按钮禁用
  • [ ] AC-03generating 期间节点内容区显示 loading
  • [x] AC-04:API 成功后进入 done,结果写入节点,loading 消失
  • [x] AC-05:API 失败后进入 error,不丢失用户输入,loading 消失
  • [x] AC-06:连续点击生成时,abort 旧请求,发起新请求
  • [x] AC-07:组件卸载时 abort 进行中的请求
  • [x] AC-08:生成时注入上游节点数据到请求参数 → 详见 data-flow
  • [x] AC-09:不兼容的上游输入被静默跳过 → 详见 data-flow 约束 6

BDD Scenarios

gherkin
Feature: AI 生成状态机

  Scenario: 正常生成文本
    Given 一个文本节点处于 idle 状态
    And 已输入 prompt "写一段产品介绍"
    When 用户点击生成按钮
    Then 节点状态变为 generating
    And 生成按钮变为禁用
    When AI 生成成功返回
    Then 节点状态变为 done
    And 内容区显示生成结果

  Scenario: 生成失败保持用户输入
    Given 一个文本节点处于 idle 状态
    And 已输入 prompt "测试失败"
    When 用户点击生成按钮
    And API 请求失败
    Then 节点状态变为 error
    And prompt 输入保持 "测试失败" 不变
    And 显示错误 toast

  Scenario: 连续点击 abort 旧请求
    Given 一个文本节点处于 generating 状态(第一次请求)
    When 用户再次点击生成
    Then 第一次请求被 abort
    And 发起新的生成请求

TDD 单元测试要点

针对各节点的 onGenerate 逻辑:

  • [x] idle → generating 状态转换正确
  • [x] 成功后 status=done 且 result 被写入
  • [x] 失败后 status=error 且 prompt 保持不变
  • [ ] abort 后旧回调不更新状态

Out of Scope

  • 生成结果的版本历史
  • 多变体并行生成的进度展示
  • 流式生成(streaming)