@ghyper9023/pi-dev-workflow 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.pi-dev-output/pi-grill/answers/answer-mpfe77f1-20260521-1913.md +58 -0
- package/.pi-dev-output/pi-grill/answers/answer-mpfh37wu-20260521-2034.md +13 -0
- package/.pi-dev-output/pi-grill/answers/answer-mpfi5q4c-20260521-2104.md +13 -0
- package/.pi-dev-output/pi-grill/answers/answer-mpfizccb-20260521-2127.md +13 -0
- package/.pi-dev-output/pi-grill/answers/answer-mpfjk78k-20260521-2143.md +13 -0
- package/.pi-dev-output/pi-grill/questions/questions-mpfdz1tz-20260521-1907.json +94 -0
- package/.pi-dev-output/pi-plans/20260521-113000-fix-loopcount-timeout.md +215 -0
- package/.pi-dev-output/pi-plans/20260521-1730-grill-input-wrap-back-fix.md +240 -0
- package/.pi-dev-output/pi-plans/20260521-230000-fix-timeout-display-loopcount-gitdiff.md +253 -0
- package/.pi-dev-output/pi-plans/20260521-230500-esc-double-press-confirm-workflow.md +137 -0
- package/.pi-dev-output/pi-plans/20260521-235000-fix-gitdiff-loopcount.md +258 -0
- package/.pi-dev-output/pi-review/html/20260521-2305-review-workflow-index.html +196 -0
- package/.pi-dev-output/pi-review/md/review-20260520-100000.md +91 -0
- package/.pi-dev-output/pi-review/md/review-20260521-140000.md +191 -0
- package/.pi-dev-output/pi-review/md/review-20260521-190000.md +189 -0
- package/.pi-dev-output/pi-review/md/review-20260521-204500.md +241 -0
- package/.pi-dev-output/pi-review/md/review-20260521-214500.md +270 -0
- package/.pi-dev-output/pi-review/md/review-20260521-215158.md +214 -0
- package/.pi-dev-output/pi-review/md/review-20260521-234500.md +201 -0
- package/.pi-dev-output/pi-review/md/review-20260521-235500.md +422 -0
- package/.pi-dev-output/pi-review/md/review-20260522-000000.md +212 -0
- package/.pi-dev-output/pi-review/md/review-20260522-003000.md +377 -0
- package/.pi-dev-output/pi-review/md/review-20260522-003500.md +296 -0
- package/.pi-dev-output/pi-workflow/checkpoint-20260521-113000-fix-loopcount-timeout.json +402 -0
- package/.pi-dev-output/pi-workflow/checkpoint-20260521-1730-grill-input-wrap-back-fix.json +447 -0
- package/.pi-dev-output/pi-workflow/checkpoint-20260521-230000-fix-timeout-display-loopcount-gitdiff.json +708 -0
- package/.pi-dev-output/pi-workflow/checkpoint-20260521-230500-esc-double-press-confirm-workflow.json +365 -0
- package/.pi-dev-output/pi-workflow/checkpoint-20260521-235000-fix-gitdiff-loopcount.json +395 -0
- package/.pi-dev-output/pi-workflow/checkpoint-archive-mpfhyxc5.json +30 -0
- package/.pi-dev-output/pi-workflow/checkpoint-archive-mpfi2unc.json +49 -0
- package/.pi-dev-output/pi-workflow/checkpoint-archive-mpfi382e.json +59 -0
- package/.pi-dev-output/pi-workflow/checkpoint-archive-mpfi5r22.json +76 -0
- package/extensions/dev-prompts.ts +16 -8
- package/extensions/grill-me-agent.ts +23 -7
- package/extensions/ui-helpers.ts +59 -7
- package/extensions/workflow-engine.ts +80 -32
- package/package.json +1 -1
- package/tests/test-loopcount-timeout-fix.mjs +336 -0
- package/themes/oh-my-pi-titanium.json +90 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[fix] 修复 extensions/workflow-engine.ts 中的 Workflow的loop循环,进入第2,3,4循环时候,ui仍然是第1次循环,计数没有+=1. 超时时间问题:worker review是一个loop组,超时时间应该是独自的,现在ui显示的超时时间是显示在loop组长的,且worker和reviewer用的一个超时时间,需要检查这部分逻辑,超时时间应该交给子代理而不是loop组,如果只是ui显示错误就修复ui问题。trimmer的默认超时时间较短,给20分钟,worker给30分钟 ,reviewer给15分钟。
|
|
2
|
+
|
|
3
|
+
**背景**:
|
|
4
|
+
- 输入:见代码上下文
|
|
5
|
+
- 预期行为:修复问题,确保原有功能,其他功能不被破坏。
|
|
6
|
+
- 当前错误:请描述当前错误
|
|
7
|
+
**任务**:
|
|
8
|
+
1. 不要仅仅消除报错(Suppress),要解决根本原因。
|
|
9
|
+
2. 先读取相关代码和日志,诊断根因(多步推理,不要先给结论)。
|
|
10
|
+
3. 提供至少一种修复方案,并说明为什么这样做。
|
|
11
|
+
4. 编写测试用例复现该 Bug 并确认修复有效。
|
|
12
|
+
**输出**:提供 diff 和两句话的根因分析。
|
|
13
|
+
**约束**:只修 bug,不做重构;最小化改动;不要假设错误是微不足道的。
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
## 设计评审记录
|
|
17
|
+
|
|
18
|
+
以下是在开发前进行的设计评审问答,所有决策已确认:
|
|
19
|
+
|
|
20
|
+
[评审问题 1]
|
|
21
|
+
问题: 关于 loopCount UI 不同步问题:executeLoopGroup() 内部的 while 循环中,每次迭代完成后(loopCount++ 之后),是否应该立即调用 updateWidgetStep() 更新 UI 中的 loopCount?还是你认为只在 executeLoopGroup 返回后由外层 executeWorkflowBackground 统一更新即可?
|
|
22
|
+
回答: a[推荐] 在 executeLoopGroup 的 while 循环内,每次 loopCount++ 之后立即调用 updateWidgetStep() 更新 UI 当前循环次数
|
|
23
|
+
|
|
24
|
+
[评审问题 2]
|
|
25
|
+
问题: 关于超时时间分离问题:executeLoopGroup() 中 reviewer 和 loopAgent 使用相同的 step.timeoutMs。你希望 reviewer 使用独立的超时时间,还是认为只需在 UI 上把显示的超时时间区分开即可?
|
|
26
|
+
回答: a[推荐] 给 WorkflowStepDef 增加 reviewTimeoutMs 字段,reviewer 使用独立的超时时间
|
|
27
|
+
|
|
28
|
+
[评审问题 3]
|
|
29
|
+
问题: 关于默认超时时间调整:当前配置中 worker 是 900000ms (15min),trimmer 是 300000ms (5min),reviewer 是 900000ms(loop-group中) 或 300000ms(独立步骤)。根据需求,worker 应改为 30min (1800000ms),trimmer 应改为 20min (1200000ms),reviewer 保持 15min (900000ms)。这些超时是硬编码在 dev-prompts.ts 的 WorkflowStepDef 中的,还是有其他来源?
|
|
30
|
+
回答: a[推荐] 直接在 dev-prompts.ts 中修改各个 WorkflowStepDef 的 timeoutMs 值
|
|
31
|
+
|
|
32
|
+
[评审问题 4]
|
|
33
|
+
问题: 关于超时时间的粒度:如果给 reviewer 独立超时,是每个 loop-group 内的 reviewer 都用固定 15min?还是不同 loop-group(worker-reviewer vs trimmer-reviewer)中的 reviewer 应该有不同的超时值?
|
|
34
|
+
回答: a[推荐] 所有 reviewer 统一使用固定的超时时间 15min(900000ms)
|
|
35
|
+
|
|
36
|
+
[评审问题 5]
|
|
37
|
+
问题: 确认一下:当前 executeLoopGroup() 中,loopAgent(worker/trimmer)和 reviewer 都用同一个 step.timeoutMs 传给 runAgentWithProgress。如果要分离超时,你建议 reviewer 的超时时间从哪里读取?
|
|
38
|
+
回答: a[推荐] 从 WorkflowStepDef 的新字段 reviewTimeoutMs 读取
|
|
39
|
+
|
|
40
|
+
[评审问题 6]
|
|
41
|
+
问题: 关于 loopCount 显示细节:当前 buildWidgetLines 中,当 loop-group 处于 running 状态时,loopStr 固定显示 "第 1 次循环"。进入第 2, 3, 4 次循环时 UI 仍然是 "第 1 次循环"。除了上面第 1 问提到的在循环中更新 UI,widget 端是否也需要调整 loopStr 的判断逻辑?
|
|
42
|
+
回答: a[推荐] 同时修改两端:executeLoopGroup 每次循环后更新 widget,同时 buildWidgetLines 中直接从 s.loopCount 读取显示
|
|
43
|
+
|
|
44
|
+
[评审问题 7]
|
|
45
|
+
问题: 关于 runAgentWithProgress 的超时传递:注意 reviewer 在 executeLoopGroup 中调用时传的是 step.timeoutMs。如果要给 reviewer 用独立超时,runAgentWithProgress 调用的第二个参数需要改。你能确认一下 reviewer 和 loopAgent 的超时分别应该是什么值吗?
|
|
46
|
+
回答: a[推荐] worker loopAgent=30min(1800000ms), reviewer=15min(900000ms); trimmer loopAgent=20min(1200000ms), reviewer=15min(900000ms)
|
|
47
|
+
|
|
48
|
+
[评审问题 8]
|
|
49
|
+
问题: 关于超时显示在 UI 上的位置:当前 UI 在 loop-group 的 row 上显示超时(如 "/超时时间15m"),但 bug 描述说 "超时时间应该交给子代理而不是 loop 组"。你认为 loop-group 的 UI row 上还应该显示超时时间吗?还是只在子代理(worker/reviewer)的 sub-step 级别显示各自的超时?
|
|
50
|
+
回答: a[推荐] loop-group 行不显示超时时间,在 worker 和 reviewer 的 sub-step 中分别显示各自的超时时间
|
|
51
|
+
|
|
52
|
+
[评审问题 9]
|
|
53
|
+
问题: 关于 trimmer 默认超时 20 分钟:当前 trimmer 的 timeoutMs 是 300000 (5min)。改为 1200000 (20min) 是否合理?请确认这个改动是否会影响其他步骤的规划。
|
|
54
|
+
回答: a[推荐] 合理,仅改 dev-prompts.ts 中所有 trimmer 相关步骤的 timeoutMs 为 1200000
|
|
55
|
+
|
|
56
|
+
[评审问题 10]
|
|
57
|
+
问题: 关于测试验证:如果要验证修复是否有效,是否有现成的测试文件或测试框架可用?还是需要新建测试?
|
|
58
|
+
回答: a[推荐] 在 test/ 目录下新建测试文件,模拟 workflow engine 执行并检查 UI state 的 loopCount 和 timeoutMs
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[fix] 修复 extensions文件夹 中的 问题: 1.dev-*命令输入,grill提问环节自定义输入等地方的输入不会自动换行,全部内容都在一行。 2.grill的提问回答环节,提问问题现在正确换行了,但是回答选项a/b/c...在字数较多时候没有换行,无法看到超出ui部分的内容,所有文件都在一行。 3.grill的提问回答环节,<-左方向键位功能是要求回到上一个问题,但是现在左方向键功能没有实现,按下后没反应。
|
|
2
|
+
|
|
3
|
+
**背景**:
|
|
4
|
+
- 输入:见代码上下文
|
|
5
|
+
- 预期行为:预期要求: 1.dev-*命令输入,grill提问环节自定义输入等地方需要自动换行。 2.grill的提问回答环节,选项也需要自动换行,a/b/c...以及自定义内容。 3.grill的提问回答环节,<-左方向键位功能修复,能够回到上一个问题,且保留了上一个问题的选择(<上次选择)。 4.严格完成以上任务要求,不得破坏原有其他功能,不得偷懒省略,以最小改动实现。
|
|
6
|
+
- 当前错误:请描述当前错误
|
|
7
|
+
**任务**:
|
|
8
|
+
1. 不要仅仅消除报错(Suppress),要解决根本原因。
|
|
9
|
+
2. 先读取相关代码和日志,诊断根因(多步推理,不要先给结论)。
|
|
10
|
+
3. 提供至少一种修复方案,并说明为什么这样做。
|
|
11
|
+
4. 编写测试用例复现该 Bug 并确认修复有效。
|
|
12
|
+
**输出**:提供 diff 和两句话的根因分析。
|
|
13
|
+
**约束**:只修 bug,不做重构;最小化改动;不要假设错误是微不足道的。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[fix] 修复 当前目录 中的 问题: 1.commit提交哈希:01413c9edb1dee3af525bfabdb4f55de7f0a3b4b里面的改动, 现在的超时时间显示位置: ``` ▶ ⠏ 🔧 修复代码 → 审查 (52.6s) |__ ⠏ worker · |__ 超时时间60m ``` 2.问题2,`第 0 次循环`只在排队时候显示了,等loop组开始工作连`第 1 次循环`的提示都不见了 2.根据git diff --name-status获取的文件变动信息,是通过正则筛选的,但很明显git diff --name-status给的结果如下: ```git diff --name-statusM .gitignoreM Cargo.lock ``` 非常的规整,正则现在会识别出来一些无关东西,判断不出来是哪里来的,git diff --name-status直接拿到的信息`X 空格 filepath 换行`只需要简单的string处理即可,无需复杂正则,而且正则效果不好。
|
|
2
|
+
|
|
3
|
+
**背景**:
|
|
4
|
+
- 输入:见代码上下文
|
|
5
|
+
- 预期行为:预期: 1.超时时间显示位置: ``` ▶ ⠏ 🔧 修复代码 → 审查 |__ ⠏ worker · (52.6s/超时时间60m ) |__ reviewer · (0s/超时时间60m) ``` 超时时间应该跟在计时的后面(当前计时/超时时间xm),且位于子代理名称后面 2.恢复`第 x 次循环`的显示,上次fix的模板是x计数不更新,但是修改后直接导致`第 x 次循环`不见了,恢复显示并修复x计数和更新ui逻辑。 3.将正则匹配改成普通的string处理 3.严格完成以上任务要求,不得破坏原有其他功能,不得偷懒省略,以最小改动实现。
|
|
6
|
+
- 当前错误:请描述当前错误
|
|
7
|
+
**任务**:
|
|
8
|
+
1. 不要仅仅消除报错(Suppress),要解决根本原因。
|
|
9
|
+
2. 先读取相关代码和日志,诊断根因(多步推理,不要先给结论)。
|
|
10
|
+
3. 提供至少一种修复方案,并说明为什么这样做。
|
|
11
|
+
4. 编写测试用例复现该 Bug 并确认修复有效。
|
|
12
|
+
**输出**:提供 diff 和两句话的根因分析。
|
|
13
|
+
**约束**:只修 bug,不做重构;最小化改动;不要假设错误是微不足道的。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[fix] 修复 当前目录 中的 问题: 1.Workflow工作期间,ecs是中断当前工作流,容易误触
|
|
2
|
+
|
|
3
|
+
**背景**:
|
|
4
|
+
- 输入:见代码上下文
|
|
5
|
+
- 预期行为:预期要求: 1.Workflow工作期间,ecs第一次,显示提示:“再次按下ecs键,停止Workflow”,俩次ecs间隔<5s才退出,5s之后,提示内容“再次按下ecs键,停止Workflow”去掉,需要重新监听ecs按下和重新计时。 2.严格完成以上任务要求,不得破坏原有其他功能,不得偷懒省略,以最小改动实现。
|
|
6
|
+
- 当前错误:请描述当前错误
|
|
7
|
+
**任务**:
|
|
8
|
+
1. 不要仅仅消除报错(Suppress),要解决根本原因。
|
|
9
|
+
2. 先读取相关代码和日志,诊断根因(多步推理,不要先给结论)。
|
|
10
|
+
3. 提供至少一种修复方案,并说明为什么这样做。
|
|
11
|
+
4. 编写测试用例复现该 Bug 并确认修复有效。
|
|
12
|
+
**输出**:提供 diff 和两句话的根因分析。
|
|
13
|
+
**约束**:只修 bug,不做重构;最小化改动;不要假设错误是微不足道的。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[fix] 修复 当前目录 中的 问题: 1.commit提交哈希f98799d17f561127ff31156653f717526fc28fbb中的修改,把git diff改成简单的string操作,这是修复后的运行ui情况:``` fix - 修复 当前目录 中的 问题:1.Workflow工作期间,ecs是中断当前工作流,容易误触 ⠧ 工作流 · 完全值守模式 · 4m33s ✓ 📋 分析根因并制定修复计划 (1m33s/超时时间15m) |__ ✓ planner · (4m33s/超时时间15m) | M checkpoint-${planId}.json | M src/main.rs | M path/to/file.ts | M file.ts | D file\n | A file\n\t\t\t\t\ttry | A .pi-dev-output/pi-plans/20260521-230500-esc-double-press-confirm-workflow.md | A .pi-dev-output/pi-workflow/checkpoint.json | output:.pi-dev-output/pi-plans/xxx.md |__ output:review-20260520-162800.md ▶ ⠧ 🔧 修复代码 → 审查 · 第 1 次循环 (1m59s) |__ ⠧ worker · (1m59s/超时时间60m) | M [],\n\t\t\t\toutputs: | M path\\\") | M [],\n\t\t\t\toutputs: | M [],\n\t\t\toutputs: | M [],\n\t\t\t\toutputs: | M path\\\") | M path\\\") | M [],\\n\\t\\t\\toutputs: | M [],\\n\\t\\t\\toutputs: | M [],\\n\\t\\t\\toutputs: | M [],\\n\\t\\t\\toutputs: | M [],\\n\\t\\t\\toutputs: | M [],\\n\\t\\t\\ | M [],\\n\\t\\t\\t\\toutputs: | M [],\\n\\t\\t\\t\\toutputs: | M [],\\n\\t\\t\\t\\toutputs: | M [],\\n\\t\\t\\t\\toutputs: | M [],\\n\\t\\t\\t\\toutputs: | M [],\\n\\t\\t\\t\\toutputs: |__ M [],\\n\\ |__ ◦ reviewer · |__ 正在排队 27 tools Ctrl+O 展开详情 | Escape 取消```出现了一些M checkpoint-${planId}.json,A file\n\t\t\t\t\ttry ,M [],\\n\\t\\t\\t\\toutputs:完全不知道是哪里来的东西。2.问题2,`第 0 次循环`出现在pedding时候(正确),当第一次loop时候(即从planner进入loop)显示`第 · 次循环`(正确),但是遇到reviewer触发严重bug,需要循环一次时候,仍然显示`第 1 次循环`,如果再进一次循环才会显示`第 2 次循环`,也就是本该`第 0 次循环`->`第 1 次循环`->`第 2 次循环`->`第 3 次循环`,现在却是:`第 0 次循环`->`第 1 次循环`->`第 1 次循环`->`第 2 次循环`
|
|
2
|
+
|
|
3
|
+
**背景**:
|
|
4
|
+
- 输入:见代码上下文
|
|
5
|
+
- 预期行为:预期:1.找到根本问题所在,彻底修复。2.严格完成任务要求,不得破坏原有其他功能,不得偷懒省略,以最小改动实现。
|
|
6
|
+
- 当前错误:请描述当前错误
|
|
7
|
+
**任务**:
|
|
8
|
+
1. 不要仅仅消除报错(Suppress),要解决根本原因。
|
|
9
|
+
2. 先读取相关代码和日志,诊断根因(多步推理,不要先给结论)。
|
|
10
|
+
3. 提供至少一种修复方案,并说明为什么这样做。
|
|
11
|
+
4. 编写测试用例复现该 Bug 并确认修复有效。
|
|
12
|
+
**输出**:提供 diff 和两句话的根因分析。
|
|
13
|
+
**约束**:只修 bug,不做重构;最小化改动;不要假设错误是微不足道的。
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"questions": [
|
|
3
|
+
{
|
|
4
|
+
"id": 1,
|
|
5
|
+
"question": "关于 loopCount UI 不同步问题:executeLoopGroup() 内部的 while 循环中,每次迭代完成后(loopCount++ 之后),是否应该立即调用 updateWidgetStep() 更新 UI 中的 loopCount?还是你认为只在 executeLoopGroup 返回后由外层 executeWorkflowBackground 统一更新即可?",
|
|
6
|
+
"options": [
|
|
7
|
+
"a[推荐] 在 executeLoopGroup 的 while 循环内,每次 loopCount++ 之后立即调用 updateWidgetStep() 更新 UI 当前循环次数",
|
|
8
|
+
"b 不需要改 UI 逻辑,是 UI 构建函数 buildWidgetLines 中的 loopStr 渲染条件太严格导致",
|
|
9
|
+
"c 在外层 executeWorkflowBackground 的 for 循环内增加额外逻辑来刷新 loopGroup 的 UI"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": 2,
|
|
14
|
+
"question": "关于超时时间分离问题:executeLoopGroup() 中 reviewer 和 loopAgent 使用相同的 step.timeoutMs。你希望 reviewer 使用独立的超时时间,还是认为只需在 UI 上把显示的超时时间区分开即可?",
|
|
15
|
+
"options": [
|
|
16
|
+
"a[推荐] 给 WorkflowStepDef 增加 reviewTimeoutMs 字段,reviewer 使用独立的超时时间",
|
|
17
|
+
"b 不需要增加字段,只是在 UI 上正确显示各自的超时时间(当前问题只是 UI 显示问题)",
|
|
18
|
+
"c 在 loop-group 的配置项中新增 reviewer 专用的超时配置"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": 3,
|
|
23
|
+
"question": "关于默认超时时间调整:当前配置中 worker 是 900000ms (15min),trimmer 是 300000ms (5min),reviewer 是 900000ms(loop-group中) 或 300000ms(独立步骤)。根据需求,worker 应改为 30min (1800000ms),trimmer 应改为 20min (1200000ms),reviewer 保持 15min (900000ms)。这些超时是硬编码在 dev-prompts.ts 的 WorkflowStepDef 中的,还是有其他来源?",
|
|
24
|
+
"options": [
|
|
25
|
+
"a[推荐] 直接在 dev-prompts.ts 中修改各个 WorkflowStepDef 的 timeoutMs 值",
|
|
26
|
+
"b 需要通过配置文件或环境变量来设置",
|
|
27
|
+
"c 从 agent 定义(sub-agents.ts 中的 AgentDef)中动态读取超时时间"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": 4,
|
|
32
|
+
"question": "关于超时时间的粒度:如果给 reviewer 独立超时,是每个 loop-group 内的 reviewer 都用固定 15min?还是不同 loop-group(worker-reviewer vs trimmer-reviewer)中的 reviewer 应该有不同的超时值?",
|
|
33
|
+
"options": [
|
|
34
|
+
"a[推荐] 所有 reviewer 统一使用固定的超时时间 15min(900000ms)",
|
|
35
|
+
"b worker-reviewer 中的 reviewer 用 15min,trimmer-reviewer 中的 reviewer 用 10min",
|
|
36
|
+
"c 在 WorkflowStepDef 中为 reviewer 单独配置不同的超时值"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": 5,
|
|
41
|
+
"question": "确认一下:当前 executeLoopGroup() 中,loopAgent(worker/trimmer)和 reviewer 都用同一个 step.timeoutMs 传给 runAgentWithProgress。如果要分离超时,你建议 reviewer 的超时时间从哪里读取?",
|
|
42
|
+
"options": [
|
|
43
|
+
"a[推荐] 从 WorkflowStepDef 的新字段 reviewTimeoutMs 读取",
|
|
44
|
+
"b 从 agentMap.get(reviewAgentName!).timeoutMs 读取(AgentDef 上的超时)",
|
|
45
|
+
"c 固定写 900000ms 硬编码在 executeLoopGroup 中"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": 6,
|
|
50
|
+
"question": "关于 loopCount 显示细节:当前 buildWidgetLines 中,当 loop-group 处于 running 状态时,loopStr 固定显示 \"第 1 次循环\"。进入第 2, 3, 4 次循环时 UI 仍然是 \"第 1 次循环\"。除了上面第 1 问提到的在循环中更新 UI,widget 端是否也需要调整 loopStr 的判断逻辑?",
|
|
51
|
+
"options": [
|
|
52
|
+
"a[推荐] 同时修改两端:executeLoopGroup 每次循环后更新 widget,同时 buildWidgetLines 中直接从 s.loopCount 读取显示",
|
|
53
|
+
"b 只需修 executeLoopGroup 端,UI widget 渲染逻辑已经能正确处理 loopCount>0 的情况",
|
|
54
|
+
"c 只需修 UI widget 端,让它在 running 状态下也能正确渲染变化的 loopCount"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": 7,
|
|
59
|
+
"question": "关于 runAgentWithProgress 的超时传递:注意 reviewer 在 executeLoopGroup 中调用时传的是 step.timeoutMs。如果要给 reviewer 用独立超时,runAgentWithProgress 调用的第二个参数需要改。你能确认一下 reviewer 和 loopAgent 的超时分别应该是什么值吗?",
|
|
60
|
+
"options": [
|
|
61
|
+
"a[推荐] worker loopAgent=30min(1800000ms), reviewer=15min(900000ms); trimmer loopAgent=20min(1200000ms), reviewer=15min(900000ms)",
|
|
62
|
+
"b worker loopAgent=15min, reviewer=15min; trimmer loopAgent=5min, reviewer=5min — 只需要在 UI 上修正显示",
|
|
63
|
+
"c worker loopAgent=30min, reviewer=10min; trimmer loopAgent=20min, reviewer=5min"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": 8,
|
|
68
|
+
"question": "关于超时显示在 UI 上的位置:当前 UI 在 loop-group 的 row 上显示超时(如 \"/超时时间15m\"),但 bug 描述说 \"超时时间应该交给子代理而不是 loop 组\"。你认为 loop-group 的 UI row 上还应该显示超时时间吗?还是只在子代理(worker/reviewer)的 sub-step 级别显示各自的超时?",
|
|
69
|
+
"options": [
|
|
70
|
+
"a[推荐] loop-group 行不显示超时时间,在 worker 和 reviewer 的 sub-step 中分别显示各自的超时时间",
|
|
71
|
+
"b loop-group 行仍然显示整体超时,同时子代理也显示各自的超时",
|
|
72
|
+
"c 只需修复 ui 显示错误,不在子代理级别显示超时"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"id": 9,
|
|
77
|
+
"question": "关于 trimmer 默认超时 20 分钟:当前 trimmer 的 timeoutMs 是 300000 (5min)。改为 1200000 (20min) 是否合理?请确认这个改动是否会影响其他步骤的规划。",
|
|
78
|
+
"options": [
|
|
79
|
+
"a[推荐] 合理,仅改 dev-prompts.ts 中所有 trimmer 相关步骤的 timeoutMs 为 1200000",
|
|
80
|
+
"b 改为 600000 (10min) 更合理",
|
|
81
|
+
"c trimmer 不应该改超时,问题在其他地方"
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": 10,
|
|
86
|
+
"question": "关于测试验证:如果要验证修复是否有效,是否有现成的测试文件或测试框架可用?还是需要新建测试?",
|
|
87
|
+
"options": [
|
|
88
|
+
"a[推荐] 在 test/ 目录下新建测试文件,模拟 workflow engine 执行并检查 UI state 的 loopCount 和 timeoutMs",
|
|
89
|
+
"b 已有测试文件,可以扩展",
|
|
90
|
+
"c 不需要测试"
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# 修复 Workflow loopCount UI 不同步 & 超时时间分离 — 实施计划
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
修复 workflow-engine.ts 中三个相互关联的 Bug:
|
|
6
|
+
|
|
7
|
+
1. **loopCount UI 不同步**:`executeLoopGroup()` 在 while 循环中每次迭代后 `loopCount++`,但未调用 `updateWidgetStep()` 更新 widget 状态,导致 widget 中的 `loopStr` 在第 2、3、4 次循环时仍显示"第 1 次循环"。
|
|
8
|
+
2. **reviewer 与 loopAgent 共用超时**:`executeLoopGroup()` 中 reviewer 调用 `runAgentWithProgress()` 时传的是 `step.timeoutMs`,未使用独立超时时间。
|
|
9
|
+
3. **默认超时值不准确**:worker 应为 30min、trimmer 应为 20min、reviewer 应为 15min。
|
|
10
|
+
|
|
11
|
+
## 根因分析
|
|
12
|
+
|
|
13
|
+
### Bug 1: loopCount UI 不同步
|
|
14
|
+
- `executeLoopGroup()` (workflow-engine.ts L1197-1270) 中,`loopCount++` (L1243) 之后没有任何 `updateWidgetStep()` 调用。
|
|
15
|
+
- 外层的 `executeWorkflowBackground()` 只在步骤完成时(done/failed)调用 `updateWidgetStep()` 更新 `loopCount`,因此中间迭代的 loopCount 从未通知 widget。
|
|
16
|
+
- Widget 端 `buildWidgetLines()` (ui-helpers.ts L460-470) 中,`loopStr` 显示逻辑依赖于 `s.loopCount`,且当 `isRunning && s.loopCount == null` 时硬编码显示"第 1 次循环"——这进一步掩盖了问题。
|
|
17
|
+
|
|
18
|
+
### Bug 2: reviewer 超时未分离
|
|
19
|
+
- `WorkflowStepDef` 接口没有 `reviewTimeoutMs` 字段。
|
|
20
|
+
- `executeLoopGroup()` L1224 行:`runAgentWithProgress(reviewAgent, reviewTask, stepIndex, step.reviewAgentName!, step.timeoutMs)` — reviewer 和 loopAgent 使用同一个 `step.timeoutMs`。
|
|
21
|
+
|
|
22
|
+
### Bug 3: 默认超时值不正确
|
|
23
|
+
- `dev-prompts.ts` 中所有 `worker` 相关的 loop-group 的 `timeoutMs` 都是 `900_000` (15min),应为 `1_800_000` (30min)。
|
|
24
|
+
- `trimmer` 相关的 loop-group 的 `timeoutMs` 是 `300_000` (5min),应为 `1_200_000` (20min)。
|
|
25
|
+
- reviewer 的独立超时(通过 `reviewTimeoutMs`)应为 `900_000` (15min)。
|
|
26
|
+
|
|
27
|
+
## 文件清单
|
|
28
|
+
|
|
29
|
+
### 修改文件
|
|
30
|
+
| 文件路径 | 改动描述 | 风险等级 |
|
|
31
|
+
|---------|---------|---------|
|
|
32
|
+
| `extensions/workflow-engine.ts` | 1) 给 `WorkflowStepDef` 增加 `reviewTimeoutMs` 字段;2) `executeLoopGroup()` 中 loopCount++ 后调用 `updateWidgetStep()`;3) reviewer 调用 `runAgentWithProgress()` 使用 `reviewTimeoutMs`;4) loop-group 行不显示 timeout | 中 |
|
|
33
|
+
| `extensions/dev-prompts.ts` | 1) 修改所有 loop-group 的 `timeoutMs` 默认值;2) 为所有 loop-group 添加 `reviewTimeoutMs` 字段 | 低 |
|
|
34
|
+
| `extensions/ui-helpers.ts` | 1) `buildWidgetLines()` 中 loop-group 行不显示超时时间;2) sub-step 级别显示各自的超时时间 | 低 |
|
|
35
|
+
|
|
36
|
+
### 新增文件
|
|
37
|
+
| 文件路径 | 用途说明 |
|
|
38
|
+
|---------|---------|
|
|
39
|
+
| `tests/test-loopcount-timeout-fix.mjs` | 测试 loopCount 同步、reviewer 独立超时、默认值修改 |
|
|
40
|
+
|
|
41
|
+
## 实施步骤
|
|
42
|
+
|
|
43
|
+
### 步骤 1:修改 `WorkflowStepDef` 接口,增加 `reviewTimeoutMs` 字段
|
|
44
|
+
- **前置条件**:无
|
|
45
|
+
- **改动文件**:`extensions/workflow-engine.ts`
|
|
46
|
+
- **改动内容**:在 `WorkflowStepDef` 接口中增加可选字段 `reviewTimeoutMs?: number;`(第 49-58 行)
|
|
47
|
+
- **验证方式**:TypeScript 编译不报错
|
|
48
|
+
|
|
49
|
+
### 步骤 2:修改 `dev-prompts.ts` 中所有 loop-group 的默认超时值
|
|
50
|
+
- **前置条件**:步骤 1 完成
|
|
51
|
+
- **改动文件**:`extensions/dev-prompts.ts`
|
|
52
|
+
- **改动内容**:
|
|
53
|
+
|
|
54
|
+
1. **FEAT_WORKFLOW_STEPS** (第 369-401 行)
|
|
55
|
+
- `worker-reviewer` 的 `timeoutMs`: `900_000` → `1_800_000`,新增 `reviewTimeoutMs: 900_000`
|
|
56
|
+
- `trimmer-reviewer` 的 `timeoutMs`: `300_000` → `1_200_000`,新增 `reviewTimeoutMs: 900_000`
|
|
57
|
+
|
|
58
|
+
2. **FIX_WORKFLOW_STEPS** (第 404-428 行)
|
|
59
|
+
- `worker-reviewer` 的 `timeoutMs`: `900_000` → `1_800_000`,新增 `reviewTimeoutMs: 900_000`
|
|
60
|
+
|
|
61
|
+
3. **REFACTOR_WORKFLOW_STEPS** (第 430-456 行)
|
|
62
|
+
- `worker-reviewer` 的 `timeoutMs`: `900_000` → `1_800_000`,新增 `reviewTimeoutMs: 900_000`
|
|
63
|
+
- `trimmer-reviewer` 的 `timeoutMs`: `300_000` → `1_200_000`,新增 `reviewTimeoutMs: 900_000`
|
|
64
|
+
|
|
65
|
+
4. **PERF_WORKFLOW_STEPS** (第 458-475 行)
|
|
66
|
+
- `worker-reviewer` 的 `timeoutMs`: `900_000` → `1_800_000`,新增 `reviewTimeoutMs: 900_000`
|
|
67
|
+
|
|
68
|
+
5. **TEST_WORKFLOW_STEPS** (第 477-494 行)
|
|
69
|
+
- `worker-reviewer` 的 `timeoutMs`: `900_000` → `1_800_000`,新增 `reviewTimeoutMs: 900_000`
|
|
70
|
+
|
|
71
|
+
6. **STYLE_WORKFLOW_STEPS** (第 513-523 行)
|
|
72
|
+
- `trimmer-reviewer` 的 `timeoutMs`: `300_000` → `1_200_000`,新增 `reviewTimeoutMs: 900_000`
|
|
73
|
+
|
|
74
|
+
- **验证方式**:检查所有 loop-group 配置都有对应的 `reviewTimeoutMs`,超时值符合需求
|
|
75
|
+
|
|
76
|
+
### 步骤 3:修改 `executeLoopGroup()` 中 reviewer 使用独立超时 + 每次循环后更新 UI
|
|
77
|
+
- **前置条件**:步骤 1、2 完成
|
|
78
|
+
- **改动文件**:`extensions/workflow-engine.ts`
|
|
79
|
+
- **改动内容**(在 `executeLoopGroup` 函数内,约第 1197-1270 行):
|
|
80
|
+
|
|
81
|
+
1. **取出 reviewTimeoutMs**:在 while 循环之前,定义 `const reviewTimeoutMs = step.reviewTimeoutMs ?? step.timeoutMs;`
|
|
82
|
+
|
|
83
|
+
2. **修改 reviewer 的超时传递**:将 `runAgentWithProgress(reviewAgent, reviewTask, stepIndex, step.reviewAgentName!, step.timeoutMs)` 改为 `runAgentWithProgress(reviewAgent, reviewTask, stepIndex, step.reviewAgentName!, reviewTimeoutMs)`
|
|
84
|
+
|
|
85
|
+
3. **loopCount++ 后立即更新 UI**:在 `loopCount++;`(第 1243 行)之后,添加:
|
|
86
|
+
```typescript
|
|
87
|
+
// 立即更新 UI 显示当前循环次数
|
|
88
|
+
state.loopCount = loopCount;
|
|
89
|
+
updateWidgetStep(stepIndex, step.label, "running", {
|
|
90
|
+
loopCount,
|
|
91
|
+
maxLoops: step.maxLoops,
|
|
92
|
+
timeoutMs: step.timeoutMs,
|
|
93
|
+
startedAt: step.startTime || Date.now(),
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
注意:`step.startTime` 需要从外部传入或在函数内维护。`executeLoopGroup` 当前没有 `startTime` 参数。需要在 `executeWorkflowBackground` 中(第 1405 行)调用 `updateWidgetStep` 时已传入了 `startedAt`。方案是在 `executeLoopGroup` 中也接收 `startedAt` 或让 loop-group 步骤的 `startedAt` 能通过 `_widgetSteps[stepIndex]` 访问。
|
|
97
|
+
|
|
98
|
+
更优的方案:在 `executeLoopGroup` 中直接通过 `_widgetSteps[stepIndex]` 读取 `startedAt`。但模块变量 `_widgetSteps` 是 `workflow-engine.ts` 的私有变量,直接在 `executeLoopGroup` 中引用是合理的(已在同一模块中)。
|
|
99
|
+
|
|
100
|
+
4. **还原子步骤的 pending 状态**:在每次循环重新开始前,将 worker/reviewer 的 sub-step 状态重置为 "pending",以便 UI 显示新的迭代。
|
|
101
|
+
```typescript
|
|
102
|
+
// 每次循环开始时重置 sub-step 状态
|
|
103
|
+
setWidgetSubStepStatus(stepIndex, step.loopAgentName!, "pending");
|
|
104
|
+
setWidgetSubStepStatus(stepIndex, step.reviewAgentName!, "pending");
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- **验证方式**:运行测试,检查 widget 状态在每次循环后是否正确更新
|
|
108
|
+
|
|
109
|
+
### 步骤 4:修改 `ui-helpers.ts` 中 loop-group 行的超时显示
|
|
110
|
+
- **前置条件**:无
|
|
111
|
+
- **改动文件**:`extensions/ui-helpers.ts`
|
|
112
|
+
- **改动内容**(在 `buildWidgetLines` 函数中,约第 455-456 行):
|
|
113
|
+
|
|
114
|
+
1. **loop-group 行不显示超时时间**:修改超时显示逻辑,当步骤是 loop-group 类型时跳过 timeout 显示。但由于 `buildWidgetLines` 不直接知道步骤类型,且 `WorkflowStepWidgetState` 中没有 `type` 字段,有两种方案:
|
|
115
|
+
- **方案 A(推荐)**:在 `updateWidgetStep` 调用 loop-group 的 running/done 状态时,不传入 `timeoutMs`(设为 `undefined`),这样 `buildWidgetLines` 中 `s.timeoutMs` 为 `undefined`,`timeout` 字符串为空。
|
|
116
|
+
- **方案 B**:在 `WorkflowStepWidgetState` 中增加 `type` 字段,但需要修改多个地方。
|
|
117
|
+
|
|
118
|
+
采用方案 A:`executeLoopGroup` 的 `updateWidgetStep` 调用中不传 `timeoutMs`,而在 worker/reviewer 的 sub-step 级别显示各自的超时。
|
|
119
|
+
|
|
120
|
+
2. **sub-step 级别显示超时**:在 sub-step 的 label 行(如 "worker ·" / "reviewer ·")后面附加超时时间。sub-step 的 `detail` 字段可用于此目的。在 `runAgentWithProgress` 中设置 sub-step 的 `detail` 或通过 `setWidgetSubStepStatus` 扩展接口。
|
|
121
|
+
|
|
122
|
+
具体做法:在 `runAgentWithProgress` 初始化 sub-step 时,将超时信息写入 `detail` 字段,例如 `worker · 超时时间30m`。
|
|
123
|
+
|
|
124
|
+
- **验证方式**:视觉检查 widget 输出,确认 loop-group 行不再显示超时,sub-step 行显示正确
|
|
125
|
+
|
|
126
|
+
### 步骤 5:修改 `executeWorkflowBackground` 中 loop-group 步骤的 `updateWidgetStep` 调用
|
|
127
|
+
- **前置条件**:步骤 4 完成
|
|
128
|
+
- **改动文件**:`extensions/workflow-engine.ts`
|
|
129
|
+
- **改动内容**:
|
|
130
|
+
|
|
131
|
+
在第 1405 行,当步骤类型为 `loop-group` 时,不传入 `timeoutMs`:
|
|
132
|
+
```typescript
|
|
133
|
+
updateWidgetStep(currentStepIndex, step.label, "running", {
|
|
134
|
+
maxLoops: step.maxLoops,
|
|
135
|
+
startedAt: stepStartTime,
|
|
136
|
+
// loop-group 行不显示 timeoutMs,由子代理 sub-step 显示
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
在 done 状态更新时(第 1418 行),也不传 `timeoutMs`。
|
|
141
|
+
|
|
142
|
+
- **验证方式**:在 widget 中确认 loop-group 行没有超时显示
|
|
143
|
+
|
|
144
|
+
### 步骤 6:更新 `runAgentWithProgress` 在 sub-step 中显示超时
|
|
145
|
+
- **前置条件**:步骤 4 完成
|
|
146
|
+
- **改动文件**:`extensions/workflow-engine.ts`
|
|
147
|
+
- **改动内容**:
|
|
148
|
+
|
|
149
|
+
修改 `runAgentWithProgress` 函数中初始化 sub-step 的代码(约第 739-758 行),在 sub-step 的 `detail` 字段中写入超时时间。
|
|
150
|
+
|
|
151
|
+
由于 `runAgentWithProgress` 没有直接接收超时参数用于 UI 显示,可以在 sub-step 初始化时添加:
|
|
152
|
+
```typescript
|
|
153
|
+
if (!existing) {
|
|
154
|
+
step.subSteps.push({
|
|
155
|
+
agent: agentName,
|
|
156
|
+
status: "running",
|
|
157
|
+
tools: [],
|
|
158
|
+
outputs: [],
|
|
159
|
+
startedAt: agentStartTime,
|
|
160
|
+
detail: `超时时间${formatTimeout(timeoutMs)}`,
|
|
161
|
+
});
|
|
162
|
+
refreshWidget();
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
注意需要 import `formatTimeout` 到 workflow-engine.ts,或将其从 ui-helpers.ts 导出。
|
|
167
|
+
|
|
168
|
+
- **验证方式**:widget 中 sub-step 行应显示各自的超时时间
|
|
169
|
+
|
|
170
|
+
### 步骤 7:导出 `formatTimeout` 供 workflow-engine.ts 使用
|
|
171
|
+
- **前置条件**:步骤 6 中的设计决策
|
|
172
|
+
- **改动文件**:`extensions/ui-helpers.ts`
|
|
173
|
+
- **改动内容**:
|
|
174
|
+
|
|
175
|
+
将 `formatTimeout` 函数前面加上 `export`(约第 427 行),使其可被其他模块导入使用。
|
|
176
|
+
|
|
177
|
+
- **验证方式**:TypeScript 编译通过
|
|
178
|
+
|
|
179
|
+
### 步骤 8:编写测试文件 `test-loopcount-timeout-fix.mjs`
|
|
180
|
+
- **前置条件**:所有代码修改完成
|
|
181
|
+
- **改动文件**:`tests/test-loopcount-timeout-fix.mjs`(新增)
|
|
182
|
+
- **改动内容**:编写测试覆盖以下场景:
|
|
183
|
+
1. **loopCount 更新测试**:模拟 `executeLoopGroup` 的 while 循环,验证每次 `loopCount++` 后 `updateWidgetStep` 被调用,且传入正确的 `loopCount` 值
|
|
184
|
+
2. **reviewer 独立超时测试**:验证 reviewer 调用 `runAgentWithProgress` 时使用 `reviewTimeoutMs` 而非 `step.timeoutMs`
|
|
185
|
+
3. **默认超时值测试**:静态分析 `dev-prompts.ts` 中所有 loop-group 配置,验证超时值是否符合需求(worker=30min, trimmer=20min, reviewer=15min)
|
|
186
|
+
4. **loop-group 行不显示 timeout 测试**:验证 `updateWidgetStep` 对 loop-group 步骤不传 `timeoutMs`
|
|
187
|
+
5. **sub-step 显示 timeout 测试**:验证 `runAgentWithProgress` 在新 sub-step 的 `detail` 中写入超时信息
|
|
188
|
+
6. **回归测试**:确保原有功能(非 loop-group 步骤的超时显示、完成状态等)不受影响
|
|
189
|
+
- **验证方式**:运行 `node tests/test-loopcount-timeout-fix.mjs`
|
|
190
|
+
|
|
191
|
+
## 依赖关系
|
|
192
|
+
|
|
193
|
+
- 步骤 1 是步骤 2、3 的前置条件(接口先定义才能使用)
|
|
194
|
+
- 步骤 2 是步骤 3 的前置条件(配置中的 `reviewTimeoutMs` 值在步骤 3 中使用)
|
|
195
|
+
- 步骤 4、5、6、7 可并行进行设计,但应顺序实施(步骤 4 → 步骤 7 → 步骤 6 → 步骤 5)
|
|
196
|
+
- 步骤 8 在所有代码修改完成后进行
|
|
197
|
+
|
|
198
|
+
## 测试策略
|
|
199
|
+
|
|
200
|
+
- **单元测试**:通过静态分析源代码模拟函数行为,验证 loopCount 更新逻辑、超时分离逻辑
|
|
201
|
+
- **集成测试**:模拟完整的 `executeLoopGroup` 执行流程,检查 widget state 的每个字段
|
|
202
|
+
- **回归测试**:运行已有的 `test-workflow-engine.mjs` 和 `test-workflow-engine-bugs.mjs`,确保无破坏
|
|
203
|
+
- **手动测试**:在 TUI 中运行 `/dev-fix` 命令,观察 widget 中 loop-count 和超时显示是否正确
|
|
204
|
+
|
|
205
|
+
## 注意事项
|
|
206
|
+
|
|
207
|
+
1. **loopCount 初始值**:`executeLoopGroup` 中 `loopCount` 从 `loopCounts[step.id] ?? 0` 开始(第 1199 行)。这意味着第一次循环时 `loopCount` 为 0,在 `loopCount++` 后变为 1。UI 中第一次显示应该是"第 1 次循环",与现有 `buildWidgetLines` 中的硬编码一致。
|
|
208
|
+
|
|
209
|
+
2. **`_widgetSteps` 的访问**:`executeLoopGroup` 中需要读取 `_widgetSteps[stepIndex]` 来获取 `startedAt`。由于 `_widgetSteps` 是模块级变量,直接在函数中引用即可。
|
|
210
|
+
|
|
211
|
+
3. **sub-step 的重置**:每次循环开始时,需要将 worker 和 reviewer 的 sub-step 状态重置为 "pending",否则 UI 会显示上次循环的已完成状态。这通过 `setWidgetSubStepStatus` 实现。
|
|
212
|
+
|
|
213
|
+
4. **超时 UI 显示**:根据设计评审第 8 问的决策,loop-group 行不显示超时时间,超时只显示在 sub-step 级别。worker sub-step 显示"超时时间30m",reviewer sub-step 显示"超时时间15m"。
|
|
214
|
+
|
|
215
|
+
5. **`WORKFLOW_SUB_STEP_WIDGET_STATE.detail`**:利用现有的 `detail` 字段来显示 sub-step 的超时信息,无需添加新字段。
|