minimal-agent 0.11.0 → 0.13.0

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.
Files changed (181) hide show
  1. package/package.json +5 -1
  2. package/plugins/workflow-runner/plugin.js +27 -15
  3. package/plugins/workflow-runner/plugin.ts +34 -20
  4. package/plugins/workflow-runner/src/agentCommon.js +13 -12
  5. package/plugins/workflow-runner/src/agentCommon.ts +22 -13
  6. package/plugins/workflow-runner/src/expressions.js +29 -8
  7. package/plugins/workflow-runner/src/expressions.ts +28 -10
  8. package/plugins/workflow-runner/src/index.js +50 -20
  9. package/plugins/workflow-runner/src/index.ts +75 -31
  10. package/plugins/workflow-runner/src/multimodal.js +2 -1
  11. package/plugins/workflow-runner/src/multimodal.ts +2 -1
  12. package/plugins/workflow-runner/src/recovery.js +9 -2
  13. package/plugins/workflow-runner/src/recovery.ts +9 -2
  14. package/plugins/workflow-runner/src/runner.js +31 -5
  15. package/plugins/workflow-runner/src/runner.ts +33 -5
  16. package/plugins/workflow-runner/src/stepExecutors/assert.js +2 -1
  17. package/plugins/workflow-runner/src/stepExecutors/assert.ts +3 -1
  18. package/plugins/workflow-runner/src/stepExecutors/skill.js +5 -6
  19. package/plugins/workflow-runner/src/stepExecutors/skill.ts +12 -7
  20. package/plugins/workflow-runner/src/stepExecutors/tool.js +91 -61
  21. package/plugins/workflow-runner/src/stepExecutors/tool.ts +111 -71
  22. package/plugins/workflow-runner/src/stepExecutors/verify.js +6 -3
  23. package/plugins/workflow-runner/src/stepExecutors/verify.ts +7 -3
  24. package/plugins/workflow-runner/src/taskIdentity.js +197 -21
  25. package/plugins/workflow-runner/src/taskIdentity.ts +201 -20
  26. package/plugins/workflow-runner/src/toolRuntime.js +48 -0
  27. package/plugins/workflow-runner/src/toolRuntime.ts +64 -0
  28. package/plugins/workflow-runner/src/types.js +113 -7
  29. package/plugins/workflow-runner/src/types.ts +137 -14
  30. package/plugins/workflow-runner/src/workflowState.js +455 -54
  31. package/plugins/workflow-runner/src/workflowState.ts +508 -63
  32. package/plugins/workflow-runner/test/cli.e2e.test.ts +20 -0
  33. package/plugins/workflow-runner/test/context-files.test.ts +47 -16
  34. package/plugins/workflow-runner/test/e2eNewLayout.test.ts +314 -0
  35. package/plugins/workflow-runner/test/engineRobustness.test.ts +9 -1
  36. package/plugins/workflow-runner/test/expressions.test.ts +42 -0
  37. package/plugins/workflow-runner/test/hostCapability.test.ts +9 -3
  38. package/plugins/workflow-runner/test/illustrate.load.test.ts +2 -2
  39. package/plugins/workflow-runner/test/multimodal.test.ts +61 -10
  40. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +19 -0
  41. package/plugins/workflow-runner/test/ppt.load.test.ts +15 -15
  42. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +3 -2
  43. package/plugins/workflow-runner/test/research.load.test.ts +328 -0
  44. package/plugins/workflow-runner/test/runnerPreflight.test.ts +68 -11
  45. package/plugins/workflow-runner/test/stateLifecycle.test.ts +60 -12
  46. package/plugins/workflow-runner/test/taskArbitration.test.ts +19 -3
  47. package/plugins/workflow-runner/test/taskLifecycle.test.ts +61 -7
  48. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +168 -0
  49. package/plugins/workflow-runner/test/webppt.load.test.ts +4 -4
  50. package/plugins/workflow-runner/test/word.load.test.ts +9 -9
  51. package/skills/skill-creator/scripts/run_eval.py +3 -2
  52. package/src/cli/print.js +36 -4
  53. package/src/cli/print.ts +42 -4
  54. package/src/cli/streamJson.js +19 -4
  55. package/src/cli/streamJson.ts +17 -4
  56. package/src/config/configDefaults.js +25 -0
  57. package/src/config/configDefaults.ts +33 -0
  58. package/src/config/configFile.js +2 -21
  59. package/src/config/configFile.ts +11 -24
  60. package/src/config/configManagement.js +1 -1
  61. package/src/config/configManagement.ts +2 -2
  62. package/src/config/configService.js +24 -0
  63. package/src/config/configService.ts +23 -0
  64. package/src/context/compact.js +4 -0
  65. package/src/context/compact.ts +4 -0
  66. package/src/context/contextBundle.js +38 -13
  67. package/src/context/contextBundle.ts +47 -13
  68. package/src/harness/stallGuard.js +19 -4
  69. package/src/harness/stallGuard.ts +30 -7
  70. package/src/infra/verification.js +25 -18
  71. package/src/infra/verification.ts +50 -18
  72. package/src/loop.js +95 -11
  73. package/src/loop.ts +125 -16
  74. package/src/main.js +8 -1
  75. package/src/main.tsx +7 -1
  76. package/src/memory/constants.js +10 -0
  77. package/src/memory/constants.ts +13 -0
  78. package/src/memory/episodicMemory.js +274 -2
  79. package/src/memory/episodicMemory.ts +306 -1
  80. package/src/memory/fileStore.js +24 -4
  81. package/src/memory/fileStore.ts +22 -2
  82. package/src/memory/memoryService.js +79 -12
  83. package/src/memory/memoryService.ts +108 -9
  84. package/src/memory/repository.js +415 -85
  85. package/src/memory/repository.ts +437 -86
  86. package/src/memory/turnJournal.js +95 -0
  87. package/src/memory/turnJournal.ts +120 -0
  88. package/src/memory/types.ts +16 -0
  89. package/src/plugins/pluginApi.ts +30 -6
  90. package/src/plugins/pluginRunner.js +23 -8
  91. package/src/plugins/pluginRunner.ts +32 -13
  92. package/src/prompts/policyRegistry.js +55 -1
  93. package/src/prompts/policyRegistry.ts +55 -1
  94. package/src/prompts/promptAssembly.js +39 -7
  95. package/src/prompts/promptAssembly.ts +145 -59
  96. package/src/session/runAgentTurn.js +43 -21
  97. package/src/session/runAgentTurn.ts +68 -26
  98. package/src/session/runTurn.js +11 -46
  99. package/src/session/runTurn.ts +12 -46
  100. package/src/session/runtimeStore.js +149 -0
  101. package/src/session/runtimeStore.ts +197 -0
  102. package/src/session/sessionState.js +5 -0
  103. package/src/session/sessionState.ts +14 -0
  104. package/src/tools/advisor/advisor.js +76 -9
  105. package/src/tools/advisor/advisor.ts +79 -9
  106. package/src/tools/agent/agent.js +143 -14
  107. package/src/tools/agent/agent.ts +149 -14
  108. package/src/tools/agent/agentTaskService.js +60 -0
  109. package/src/tools/agent/agentTaskService.ts +113 -0
  110. package/src/tools/agent/agentTypes.js +5 -0
  111. package/src/tools/agent/agentTypes.ts +5 -0
  112. package/src/tools/bash/bash.js +80 -15
  113. package/src/tools/bash/bash.ts +83 -15
  114. package/src/tools/capabilities.js +5 -0
  115. package/src/tools/capabilities.ts +11 -1
  116. package/src/tools/edit/edit.js +7 -4
  117. package/src/tools/edit/edit.ts +7 -4
  118. package/src/tools/edit/multi-edit.js +4 -2
  119. package/src/tools/edit/multi-edit.ts +4 -2
  120. package/src/tools/glob/glob.js +156 -40
  121. package/src/tools/glob/glob.ts +185 -46
  122. package/src/tools/index.js +35 -17
  123. package/src/tools/index.ts +81 -20
  124. package/src/tools/lsp/lsp.js +165 -22
  125. package/src/tools/lsp/lsp.ts +206 -36
  126. package/src/tools/powershell/powershell.js +134 -27
  127. package/src/tools/powershell/powershell.ts +171 -30
  128. package/src/tools/presentresult/presentresult.js +10 -0
  129. package/src/tools/presentresult/presentresult.ts +10 -0
  130. package/src/tools/read/read.js +249 -29
  131. package/src/tools/read/read.ts +396 -59
  132. package/src/tools/shared/diffSummary.js +44 -0
  133. package/src/tools/shared/diffSummary.ts +63 -0
  134. package/src/tools/shared/fileActivity.js +2 -1
  135. package/src/tools/shared/fileActivity.ts +3 -0
  136. package/src/tools/shared/permanentDeleteGuard.js +57 -0
  137. package/src/tools/shared/permanentDeleteGuard.ts +71 -0
  138. package/src/tools/shared/toolOutputStore.js +97 -0
  139. package/src/tools/shared/toolOutputStore.ts +110 -0
  140. package/src/tools/skill/skill.js +86 -0
  141. package/src/tools/skill/skill.ts +94 -0
  142. package/src/tools/snip/snip.js +67 -0
  143. package/src/tools/snip/snip.ts +80 -0
  144. package/src/tools/tasks/backgroundTaskService.js +79 -28
  145. package/src/tools/tasks/backgroundTaskService.ts +165 -49
  146. package/src/tools/tasks/taskManagement.js +163 -0
  147. package/src/tools/tasks/taskManagement.ts +180 -0
  148. package/src/tools/tasks/taskOutput.js +64 -14
  149. package/src/tools/tasks/taskOutput.ts +102 -23
  150. package/src/tools/tasks/taskStop.js +48 -8
  151. package/src/tools/tasks/taskStop.ts +69 -9
  152. package/src/tools/tasks/taskStore.js +46 -0
  153. package/src/tools/tasks/taskStore.ts +77 -0
  154. package/src/tools/terminal/terminalCapture.js +167 -0
  155. package/src/tools/terminal/terminalCapture.ts +179 -0
  156. package/src/tools/trash/trash.js +233 -0
  157. package/src/tools/trash/trash.ts +283 -0
  158. package/src/tools/webbrowser/browserControl.js +5 -1
  159. package/src/tools/webbrowser/browserControl.ts +7 -1
  160. package/src/tools/webbrowser/webbrowser.js +8 -4
  161. package/src/tools/webbrowser/webbrowser.ts +8 -4
  162. package/src/tools/worktree/sessionWorktree.js +128 -0
  163. package/src/tools/worktree/sessionWorktree.ts +158 -0
  164. package/src/tools/write/write.js +6 -2
  165. package/src/tools/write/write.ts +6 -2
  166. package/src/types.ts +22 -4
  167. package/src/ui/hooks/useChat.js +31 -11
  168. package/src/ui/hooks/useChat.ts +31 -13
  169. package/src/web/protocol.ts +78 -3
  170. package/workflows/adaptive-research.yaml +5 -5
  171. package/workflows/book-review-short.yaml +5 -5
  172. package/workflows/e2e-write-greet.yaml +2 -2
  173. package/workflows/illustrate.yaml +12 -12
  174. package/workflows/plan.yaml +18 -18
  175. package/workflows/ppt.yaml +201 -201
  176. package/workflows/ralph-loop.yaml +3 -1
  177. package/workflows/research.md +449 -0
  178. package/workflows/research.yaml +873 -0
  179. package/workflows/webppt.yaml +47 -47
  180. package/workflows/word.yaml +80 -80
  181. package/workflows/youtube-shorts.yaml +25 -25
@@ -19,7 +19,7 @@
19
19
 
20
20
  import type { AskAnswer, AskOption, AskQuestionSpec, AskSource } from '../askBridge.js';
21
21
  import type { PluginEvent } from '../plugins/pluginApi.js';
22
- import type { AgentResultMetadata, ConversationFilePurpose, FileActivityMetadata, LoopEvent, Message, MessageAttachmentRef, MessageBrowserReference, ProgressStage, SubagentProgress, ToolCall, ToolProgressDetail, ToolResultMetadata } from '../types.js';
22
+ import type { AgentResultMetadata, ConversationFilePurpose, DeliverableManifest, FileActivityMetadata, LoopEvent, Message, MessageAttachmentRef, MessageBrowserReference, ProgressStage, SubagentProgress, ToolCall, ToolProgressDetail, ToolResultMetadata } from '../types.js';
23
23
  import type { ConversationSearchResult, MemoryCategory, MemoryDiagnostic, MemoryEditablePatch, MemoryRecord, MemorySettings, MemoryUpdate, PersonaDocument } from '../memory/memoryService.js';
24
24
  import type { HumanInterventionReason } from '../humanIntervention.js';
25
25
 
@@ -1067,7 +1067,7 @@ export interface GroupMessageAttachment {
1067
1067
  size: number;
1068
1068
  }
1069
1069
 
1070
- export type ConversationFileKind = 'workspace-file' | 'group-attachment' | 'agent-file';
1070
+ export type ConversationFileKind = 'workspace-file' | 'user-attachment' | 'group-attachment' | 'agent-file';
1071
1071
  export type ConversationFileActivity = 'referenced' | 'read' | 'created' | 'modified' | 'generated' | 'deleted';
1072
1072
 
1073
1073
  /** Safe metadata an Agent Node may publish to a group. Absolute paths and file bytes are forbidden. */
@@ -1105,6 +1105,65 @@ export interface ConversationFileRef {
1105
1105
  sha256?: string;
1106
1106
  modifiedAt?: number;
1107
1107
  contentChanged?: boolean;
1108
+ originalAvailable?: boolean;
1109
+ archivedAvailable?: boolean;
1110
+ previewSource?: 'original' | 'archive' | 'upload';
1111
+ }
1112
+
1113
+ /** A durable, turn-scoped formal delivery. File refs are resolved at read time. */
1114
+ export interface ConversationDelivery {
1115
+ id: string;
1116
+ turnId: string;
1117
+ toolCallId?: string;
1118
+ createdAt: number;
1119
+ manifest: DeliverableManifest;
1120
+ resolvedFiles: ConversationFileRef[];
1121
+ }
1122
+
1123
+ /** Durable user-supplied and formally delivered artifacts for one user turn. */
1124
+ export interface ConversationArtifactGroup {
1125
+ turnId: string;
1126
+ createdAt: number;
1127
+ compacted: boolean;
1128
+ userAttachments: MessageAttachmentRef[];
1129
+ deliveries: ConversationDelivery[];
1130
+ }
1131
+
1132
+ export type ConversationAssetCategory = 'document' | 'code' | 'image' | 'link' | 'other';
1133
+ export type ConversationAssetOrigin = 'user-upload' | 'user-reference' | 'ai-delivery';
1134
+ export type ConversationAssetKind = 'workspace-file' | 'user-attachment' | 'web-link';
1135
+
1136
+ /** A durable, session-scoped item explicitly supplied by the user or formally delivered by the Agent. */
1137
+ export interface ConversationAsset {
1138
+ id: string;
1139
+ conversationKey: string;
1140
+ kind: ConversationAssetKind;
1141
+ category: ConversationAssetCategory;
1142
+ name: string;
1143
+ origins: ConversationAssetOrigin[];
1144
+ firstTurnId: string;
1145
+ lastTurnId: string;
1146
+ firstSeenAt: number;
1147
+ lastSeenAt: number;
1148
+ pinned: boolean;
1149
+ available: boolean;
1150
+ previewable: boolean;
1151
+ relativePath?: string;
1152
+ url?: string;
1153
+ domain?: string;
1154
+ mime?: string;
1155
+ size?: number;
1156
+ previewUrl?: string;
1157
+ verification?: import('../types.js').FileVerification;
1158
+ sha256?: string;
1159
+ modifiedAt?: number;
1160
+ contentChanged?: boolean;
1161
+ /** The original workspace file still exists at its submitted path. */
1162
+ originalAvailable?: boolean;
1163
+ /** An immutable, content-addressed copy of the submitted file is available. */
1164
+ archivedAvailable?: boolean;
1165
+ /** Which bytes are opened by the default preview action. */
1166
+ previewSource?: 'original' | 'archive' | 'upload';
1108
1167
  }
1109
1168
 
1110
1169
  export interface GroupChatMessage {
@@ -1244,8 +1303,13 @@ export type ClientFrame =
1244
1303
  | { t: 'plain/rename'; sessionId: string; title: string }
1245
1304
  | { t: 'plain/delete'; sessionId: string }
1246
1305
  | { t: 'resource/files/list'; dir: string; sessionId: string }
1306
+ | { t: 'resource/assets/list'; requestId: string; target: ConversationTarget & { sessionId: string } }
1307
+ | { t: 'resource/assets/pin'; requestId: string; target: ConversationTarget & { sessionId: string }; assetId: string; pinned: boolean }
1308
+ | { t: 'resource/assets/open'; requestId: string; target: ConversationTarget & { sessionId: string }; assetId: string; source?: 'default' | 'original' | 'archive' }
1309
+ | { t: 'resource/assets/reveal'; requestId: string; target: ConversationTarget & { sessionId: string }; assetId: string; source?: 'original' | 'archive' }
1310
+ | { t: 'resource/files/open'; requestId: string; target: ConversationTarget & { sessionId: string }; relativePath: string }
1247
1311
  | { t: 'resource/files/pin'; dir: string; sessionId: string; relativePath: string; pinned: boolean }
1248
- | { t: 'resource/files/reveal'; dir: string; relativePath: string }
1312
+ | { t: 'resource/files/reveal'; requestId?: string; dir?: string; target?: ConversationTarget & { sessionId: string }; relativePath: string }
1249
1313
  | { t: 'resource/memories/list'; workspaceId?: string; query?: string }
1250
1314
  | { t: 'resource/memories/settings/update'; autoRemember: boolean; workspaceId?: string }
1251
1315
  | { t: 'resource/memories/update'; id: string; scope: 'personal' | 'workspace'; expectedVersion: string; patch: MemoryUpdate; workspaceId?: string }
@@ -1519,10 +1583,21 @@ export type ServerFrame =
1519
1583
  conversationKey: string;
1520
1584
  historyRevision: string;
1521
1585
  messages: Message[];
1586
+ deliveries?: ConversationDelivery[];
1587
+ assets?: ConversationAsset[];
1588
+ artifactGroups?: ConversationArtifactGroup[];
1522
1589
  runSnapshot?: ConversationRunSnapshot;
1523
1590
  contextUsage?: Extract<LoopEvent, { type: 'context_usage' }>;
1524
1591
  }
1592
+ | { t: 'conversation/delivery/changed'; conversationKey: string; delivery: ConversationDelivery }
1593
+ | { t: 'conversation/assets/changed'; conversationKey: string; assets: ConversationAsset[] }
1525
1594
  | { t: 'resource/files/list'; dir: string; sessionId: string; files: ConversationFileRef[] }
1595
+ | { t: 'resource/assets/list'; requestId: string; conversationKey: string; assets?: ConversationAsset[]; error?: string }
1596
+ | { t: 'resource/assets/pinned'; requestId: string; ok: boolean; error?: string }
1597
+ | { t: 'resource/assets/opened'; requestId: string; ref?: ConversationFileRef; error?: string }
1598
+ | { t: 'resource/assets/revealed'; requestId: string; ok: boolean; error?: string }
1599
+ | { t: 'resource/files/opened'; requestId: string; ref?: ConversationFileRef; error?: string }
1600
+ | { t: 'resource/files/revealed'; requestId: string; ok: boolean; error?: string }
1526
1601
  | { t: 'resource/memories'; records: MemoryRecord[]; settings: MemorySettings; workspaceId?: string; reviewRecords?: MemoryRecord[]; persona?: PersonaDocument | null }
1527
1602
  | { t: 'resource/memories/conversations'; requestId: string; results: ConversationSearchResult[]; error?: string }
1528
1603
  | { t: 'resource/memories/manage/state'; requestId: string; state: MemoryManagementState }
@@ -21,11 +21,11 @@ steps:
21
21
  title: "1/3·自主调研写笔记"
22
22
  agent: |
23
23
  调研主题「${inputs.topic}」:用你手上的工具搜集 3-5 个关键要点,
24
- 整理成简洁的中文 markdown,写到 ./out/notes.md(目录不存在就先创建)。
24
+ 整理成简洁的中文 markdown,写到 out/adaptive-research/${session}/notes.md(目录不存在就先创建)。
25
25
  写完后用 Read 自检文件确实写好了再收尾。
26
26
  allowed_tools: [Read, Write, Edit, Bash, Grep, Glob]
27
27
  # 确定性完成条件:模型「宣告要写却没写」时引擎自动提醒续跑(announce-not-do 兜底)
28
- done_when: "fileExists('./out/notes.md')"
28
+ done_when: "fileExists('out/adaptive-research/${session}/notes.md')"
29
29
  capture:
30
30
  # agent 步 raw 只有 text/result(无 content)——曾绑 content 导致 notes 恒 undefined
31
31
  text: notes
@@ -35,7 +35,7 @@ steps:
35
35
  title: "2/3·统计笔记行数"
36
36
  tool: Bash
37
37
  args:
38
- command: "wc -l ./out/notes.md"
38
+ command: "wc -l out/adaptive-research/${session}/notes.md"
39
39
  onError: recover
40
40
  recover_hint: "文件不存在或路径不对,就先用 Glob/Read 定位 notes.md 再统计行数"
41
41
  capture:
@@ -46,5 +46,5 @@ steps:
46
46
  title: "3/3·守门校验"
47
47
  type: verify
48
48
  checks:
49
- - 'file_exists:./out/notes.md'
50
- onFail: "调研笔记 ./out/notes.md 未生成,检查 research 步"
49
+ - 'file_exists:out/adaptive-research/${session}/notes.md'
50
+ onFail: "调研笔记 out/adaptive-research/${session}/notes.md 未生成,检查 research 步"
@@ -56,7 +56,7 @@ steps:
56
56
  title: "3/7·脚本落盘"
57
57
  tool: Write
58
58
  args:
59
- file_path: "videos/${inputs.book}/script.txt"
59
+ file_path: "out/book-review-short/${session}/script.txt"
60
60
  content: "${script_text}"
61
61
 
62
62
  # 4. 生成 3 个钩子标题(loop + llm)—— P1 启用
@@ -97,7 +97,7 @@ steps:
97
97
  - id: gen_thumbnail
98
98
  title: "5/7·生成缩略图(可降级)"
99
99
  skill: image-gen-openrouter
100
- input: 'prompt=${thumb_prompt} output=videos/${inputs.book}/thumbnail.png aspect=9:16'
100
+ input: 'prompt=${thumb_prompt} output=out/book-review-short/${session}/thumbnail.png aspect=9:16'
101
101
  onError: continue
102
102
 
103
103
  # 6. 元数据汇总(确定性工具)
@@ -106,7 +106,7 @@ steps:
106
106
  title: "6/7·汇总 meta.json"
107
107
  tool: Write
108
108
  args:
109
- file_path: "videos/${inputs.book}/meta.json"
109
+ file_path: "out/book-review-short/${session}/meta.json"
110
110
  content: |
111
111
  {
112
112
  "book": ${json(inputs.book)},
@@ -120,6 +120,6 @@ steps:
120
120
  title: "7/7·守门校验"
121
121
  type: verify
122
122
  checks:
123
- - 'file_exists:videos/${inputs.book}/script.txt'
124
- - 'file_exists:videos/${inputs.book}/meta.json'
123
+ - 'file_exists:out/book-review-short/${session}/script.txt'
124
+ - 'file_exists:out/book-review-short/${session}/meta.json'
125
125
  onFail: "脚本或 meta 未写盘,请检查 Write 工具"
@@ -12,7 +12,7 @@ steps:
12
12
  title: "1/3·写入便签"
13
13
  tool: Write
14
14
  args:
15
- file_path: "out/${inputs.topic}/note.txt"
15
+ file_path: "out/e2e-write-greet/${session}/note.txt"
16
16
  content: "topic=${inputs.topic} ok"
17
17
  capture:
18
18
  args.content: note_body
@@ -21,7 +21,7 @@ steps:
21
21
  title: "2/3·校验落盘"
22
22
  type: verify
23
23
  checks:
24
- - 'file_exists:out/${inputs.topic}/note.txt'
24
+ - 'file_exists:out/e2e-write-greet/${session}/note.txt'
25
25
  onFail: "note.txt 未落盘"
26
26
 
27
27
  - id: verify_capture
@@ -8,7 +8,7 @@ version: "0.1"
8
8
 
9
9
  # 最终交付物(new-task 清旧 / completed 报产物 / 完成闸门校验落盘)。中间候选图与分文件不声明(scratch)。
10
10
  artifacts:
11
- - "./build/illustrations.json"
11
+ - "out/illustrate/${session}/build/illustrations.json"
12
12
 
13
13
  # 自愈:浏览器/网络瞬态故障 in-run 重跑。
14
14
  self_heal:
@@ -154,7 +154,7 @@ steps:
154
154
  tool: Download
155
155
  args:
156
156
  url: "${u}"
157
- path: "./build/illustrations/cand_${u_idx}.img"
157
+ path: "out/illustrate/${session}/build/illustrations/cand_${u_idx}.img"
158
158
  timeout: 30000
159
159
  headers:
160
160
  User-Agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36"
@@ -170,7 +170,7 @@ steps:
170
170
  do:
171
171
  - id: score_one
172
172
  title: "配图·打分 #${u_idx}"
173
- when: "fileExists('./build/illustrations/cand_' + u_idx + '.img')"
173
+ when: "fileExists('out/illustrate/${session}/build/illustrations/cand_' + u_idx + '.img')"
174
174
  llm: |
175
175
  下方附上一张候选配图(用于主题:「${inputs.topic}」)。请**只看这张图**给出客观评估,输出 JSON。
176
176
  - relevance:0-10,图片内容与主题的契合度(画的东西是否切题)。
@@ -178,7 +178,7 @@ steps:
178
178
  - is_ad:true/false——这是不是**广告/促销/带营销文案或店铺水印/比价图**等不适合当配图的图。
179
179
  - reason:一句话理由(中文)。
180
180
  只输出 JSON 对象本身,不要 markdown 代码块、不要解释。
181
- images: ["./build/illustrations/cand_${u_idx}.img"]
181
+ images: ["out/illustrate/${session}/build/illustrations/cand_${u_idx}.img"]
182
182
  image_detail: high
183
183
  capture:
184
184
  text: score_text
@@ -186,10 +186,10 @@ steps:
186
186
  max_retries: 1
187
187
  - id: write_score
188
188
  title: "配图·记录分数 #${u_idx}"
189
- when: "fileExists('./build/illustrations/cand_' + u_idx + '.img')"
189
+ when: "fileExists('out/illustrate/${session}/build/illustrations/cand_' + u_idx + '.img')"
190
190
  tool: Write
191
191
  args:
192
- file_path: "./build/illustrations/score_${u_idx}.json"
192
+ file_path: "out/illustrate/${session}/build/illustrations/score_${u_idx}.json"
193
193
  content: |
194
194
  {"index": ${u_idx}, "url": ${json(u)}, "engine": ${json(engine_used)}, "path": "build/illustrations/cand_${u_idx}.img", "score": ${score_text}}
195
195
  onError: continue
@@ -198,24 +198,24 @@ steps:
198
198
  - id: select
199
199
  title: "配图·选出最合适的 ${inputs.count} 张"
200
200
  agent: |
201
- 你是配图验收员。**唯一任务**:从已打分的候选里选出最合适的 ${inputs.count} 张配图,写 `./build/illustrations.json`。不要做别的。
201
+ 你是配图验收员。**唯一任务**:从已打分的候选里选出最合适的 ${inputs.count} 张配图,写 `out/illustrate/${session}/build/illustrations.json`。不要做别的。
202
202
 
203
- 1. 用 Glob 列出 `./build/illustrations/score_*.json`,逐个 Read。每个文件形如
203
+ 1. 用 Glob 列出 `out/illustrate/${session}/build/illustrations/score_*.json`,逐个 Read。每个文件形如
204
204
  `{"index","url","engine","path","score":{"relevance","quality","is_ad","reason"}}`(坏文件/缺 score 的跳过)。
205
205
  2. **先剔除 `score.is_ad == true` 的**(广告/促销/水印图绝不入选)。
206
206
  3. 其余按 **relevance×quality 降序**排序,取前 ${inputs.count} 张(不足就有几张给几张)。
207
- 4. 用 Write 写 `./build/illustrations.json`(严格 JSON、无注释、无 ``` 包裹):
207
+ 4. 用 Write 写 `out/illustrate/${session}/build/illustrations.json`(严格 JSON、无注释、无 ``` 包裹):
208
208
  `{"topic": "...", "engine_used": "${engine_used}", "count": <实际入选数>,
209
209
  "picks": [{"path","url","engine","relevance","quality","reason"}, ...]}`
210
210
  path 用 score 文件里的 path(如 build/illustrations/cand_3.img)。
211
211
  完成后简述:扫了几个候选、剔了几张广告、最终选了哪几张(序号 + 一句理由)。
212
212
  allowed_tools: [Glob, Read, Write]
213
213
  maxTurns: 12
214
- done_when: "fileExists('./build/illustrations.json')"
214
+ done_when: "fileExists('out/illustrate/${session}/build/illustrations.json')"
215
215
  onError: halt
216
216
  max_retries: 1
217
217
  artifacts:
218
- - "./build/illustrations.json"
218
+ - "out/illustrate/${session}/build/illustrations.json"
219
219
 
220
220
  # ---------- 阶段7:完成报告(确定性输出,不烧 LLM)----------
221
221
  - id: report
@@ -223,5 +223,5 @@ steps:
223
223
  type: echo
224
224
  message: |
225
225
  ✅ 配图完成(主题:${inputs.topic},来源:${engine_used})。
226
- 选中的图片清单见 ./build/illustrations.json(每条含 path/url/engine/分数)。
226
+ 选中的图片清单见 out/illustrate/${session}/build/illustrations.json(每条含 path/url/engine/分数)。
227
227
  下游 PPT/文章工作流可读 illustrations.json 取用这 ${inputs.count} 张配图。
@@ -30,7 +30,7 @@ self_heal:
30
30
  # 3s 级重试必撞同一个故障窗口(2026-06-12 实跑:两次重试全死在拥塞波里)
31
31
 
32
32
  artifacts:
33
- - PLAN.md # 核心产出:实现计划文档(仅在 stage4 定稿时落盘一次)
33
+ - out/plan/${session}/PLAN.md # 核心产出:实现计划文档(仅在 stage4 定稿时落盘一次)
34
34
 
35
35
  steps:
36
36
  # ================================================================
@@ -129,7 +129,7 @@ steps:
129
129
  - id: stage2_draft_plan
130
130
  title: 阶段2/6·起草实现计划
131
131
  llm: |
132
- 你负责把目标和探索结果写成**可直接执行的实现计划正文**(将原样写入 ./PLAN.md)。
132
+ 你负责把目标和探索结果写成**可直接执行的实现计划正文**(将原样写入 out/plan/${session}/out/plan/${session}/PLAN.md)。
133
133
 
134
134
  ${learnings_text != '' ? '这是用户方向性打回后的重做。用户审批反馈(必须遵从):\n' + learnings_text : ''}
135
135
 
@@ -178,9 +178,9 @@ steps:
178
178
 
179
179
  # ----------------------------------------------------------------
180
180
  # 阶段 4:方案重构确定 + 人工审批闸门(反馈分类路由)
181
- # revise 产终版正文 → Write 落盘 ./PLAN.md → 审批小循环:
181
+ # revise 产终版正文 → Write 落盘 out/plan/${session}/out/plan/${session}/PLAN.md → 审批小循环:
182
182
  # 空反馈(选继续)→ 批准放行
183
- # minor 反馈 → 就地修订 PLAN.md → 下一轮再确认
183
+ # minor 反馈 → 就地修订 out/plan/${session}/PLAN.md → 下一轮再确认
184
184
  # fundamental 反馈 → 记入教训 + continue 打回 plan_loop 重新规划
185
185
  # ----------------------------------------------------------------
186
186
  - id: stage4_revise
@@ -202,13 +202,13 @@ steps:
202
202
  max_retries: 2
203
203
 
204
204
  - id: stage4_write_plan
205
- title: 阶段4/6·写入 PLAN.md
205
+ title: 阶段4/6·写入 out/plan/${session}/PLAN.md
206
206
  tool: Write
207
207
  args:
208
- file_path: ./PLAN.md
208
+ file_path: out/plan/${session}/out/plan/${session}/PLAN.md
209
209
  content: "${final_plan_text}"
210
210
  artifacts:
211
- - PLAN.md
211
+ - out/plan/${session}/PLAN.md
212
212
  max_retries: 1
213
213
 
214
214
  - id: stage4_approval
@@ -222,9 +222,9 @@ steps:
222
222
  type: pause
223
223
  free_text: approve # 自由输入不 halt:捕获后由分类步决定走向
224
224
  prompt: |
225
- 📋 计划已定稿:./PLAN.md —— 请 review 后选择。
225
+ 📋 计划已定稿:out/plan/${session}/out/plan/${session}/PLAN.md —— 请 review 后选择。
226
226
  选「继续执行」进入执行阶段;选「停止」保留现场(同目标重跑可断点续跑);
227
- 选「其他」输入修改意见:小调整会就地改 PLAN.md 再请你确认,
227
+ 选「其他」输入修改意见:小调整会就地改 out/plan/${session}/PLAN.md 再请你确认,
228
228
  方向性变化会带着你的意见回到规划阶段重来。
229
229
  capture:
230
230
  free_text: approval_notes
@@ -281,11 +281,11 @@ steps:
281
281
  type: continue
282
282
  target: plan_loop
283
283
  else:
284
- # 局部调整:就地修订 PLAN.md,审批小循环自然进入下一轮再请确认
284
+ # 局部调整:就地修订 out/plan/${session}/PLAN.md,审批小循环自然进入下一轮再请确认
285
285
  - id: revise_with_feedback
286
286
  title: 阶段4/6·按反馈修订计划
287
287
  llm: |
288
- 用户审批计划时给了修改意见。请把意见合入计划,输出**更新后的完整 PLAN.md 正文**。
288
+ 用户审批计划时给了修改意见。请把意见合入计划,输出**更新后的完整 out/plan/${session}/PLAN.md 正文**。
289
289
 
290
290
  ## 用户修改意见
291
291
  ${approval_notes}
@@ -301,13 +301,13 @@ steps:
301
301
  text: final_plan_text
302
302
  max_retries: 2
303
303
  - id: write_revised_plan
304
- title: 阶段4/6·回写 PLAN.md
304
+ title: 阶段4/6·回写 out/plan/${session}/PLAN.md
305
305
  tool: Write
306
306
  args:
307
- file_path: ./PLAN.md
307
+ file_path: out/plan/${session}/out/plan/${session}/PLAN.md
308
308
  content: "${final_plan_text}"
309
309
  artifacts:
310
- - PLAN.md
310
+ - out/plan/${session}/PLAN.md
311
311
  max_retries: 1
312
312
 
313
313
  # 审批小循环 5 轮仍无明确同意 → 诚实停(现场保留可续跑)
@@ -332,7 +332,7 @@ steps:
332
332
  - id: stage5_execute
333
333
  title: 阶段5/6·执行计划
334
334
  agent: |
335
- 你是资深工程师,执行一份已通过审批的实现计划。先 Read ./PLAN.md 了解全部步骤。
335
+ 你是资深工程师,执行一份已通过审批的实现计划。先 Read out/plan/${session}/out/plan/${session}/PLAN.md 了解全部步骤。
336
336
 
337
337
  ${exec_feedback != '' ? '## ⚠️ 上轮执行验收未通过(本轮必须重点补完,产物已部分存在时增量补齐,不要从零重做)\n' + exec_feedback : ''}
338
338
 
@@ -369,7 +369,7 @@ steps:
369
369
  对照"成功标准"和当前文件系统,判断用户目标是否**真实达成**。
370
370
 
371
371
  请严格执行:
372
- 1. 先 Read ./PLAN.md,按其中的成功标准和产出物清单核验。
372
+ 1. 先 Read out/plan/${session}/out/plan/${session}/PLAN.md,按其中的成功标准和产出物清单核验。
373
373
  2. 用 Bash/Read/Glob 亲自核实核心产物是否真实存在、是否满足每条成功标准。
374
374
  3. 产物是 pptx/docx/pdf/xlsx 等 OOXML 时,**必须用忠实的 OPC 合规校验**
375
375
  (检查无 ZIP 目录条目、[Content_Types].xml 在首位、关系都解析、无 0 字节媒体),
@@ -383,7 +383,7 @@ steps:
383
383
 
384
384
  只输出 JSON 对象本身(不要 markdown、不要解释正文)。
385
385
  context_files:
386
- - path: ./PLAN.md
386
+ - path: out/plan/${session}/out/plan/${session}/PLAN.md
387
387
  hint: 实现计划与产出物清单
388
388
  allowed_tools: [Read, Bash, Glob]
389
389
  output_schema:
@@ -443,7 +443,7 @@ steps:
443
443
  title: 阶段5-6·执行兜底检查
444
444
  type: assert
445
445
  condition: "qualified == true"
446
- onFail: "已批准的计划执行 3 轮仍未通过验收,工作流诚实停止(现场与 PLAN.md 保留,重跑同目标可从断点续跑;也可调整目标后重来)。最后阻塞原因:${blocking_reason}"
446
+ onFail: "已批准的计划执行 3 轮仍未通过验收,工作流诚实停止(现场与 out/plan/${session}/PLAN.md 保留,重跑同目标可从断点续跑;也可调整目标后重来)。最后阻塞原因:${blocking_reason}"
447
447
 
448
448
  # ================================================================
449
449
  # 出循环后:唯一正常到达路径 = exec_gate 验收通过 break 穿透至此。