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.
- package/package.json +5 -1
- package/plugins/workflow-runner/plugin.js +27 -15
- package/plugins/workflow-runner/plugin.ts +34 -20
- package/plugins/workflow-runner/src/agentCommon.js +13 -12
- package/plugins/workflow-runner/src/agentCommon.ts +22 -13
- package/plugins/workflow-runner/src/expressions.js +29 -8
- package/plugins/workflow-runner/src/expressions.ts +28 -10
- package/plugins/workflow-runner/src/index.js +50 -20
- package/plugins/workflow-runner/src/index.ts +75 -31
- package/plugins/workflow-runner/src/multimodal.js +2 -1
- package/plugins/workflow-runner/src/multimodal.ts +2 -1
- package/plugins/workflow-runner/src/recovery.js +9 -2
- package/plugins/workflow-runner/src/recovery.ts +9 -2
- package/plugins/workflow-runner/src/runner.js +31 -5
- package/plugins/workflow-runner/src/runner.ts +33 -5
- package/plugins/workflow-runner/src/stepExecutors/assert.js +2 -1
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +3 -1
- package/plugins/workflow-runner/src/stepExecutors/skill.js +5 -6
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +12 -7
- package/plugins/workflow-runner/src/stepExecutors/tool.js +91 -61
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +111 -71
- package/plugins/workflow-runner/src/stepExecutors/verify.js +6 -3
- package/plugins/workflow-runner/src/stepExecutors/verify.ts +7 -3
- package/plugins/workflow-runner/src/taskIdentity.js +197 -21
- package/plugins/workflow-runner/src/taskIdentity.ts +201 -20
- package/plugins/workflow-runner/src/toolRuntime.js +48 -0
- package/plugins/workflow-runner/src/toolRuntime.ts +64 -0
- package/plugins/workflow-runner/src/types.js +113 -7
- package/plugins/workflow-runner/src/types.ts +137 -14
- package/plugins/workflow-runner/src/workflowState.js +455 -54
- package/plugins/workflow-runner/src/workflowState.ts +508 -63
- package/plugins/workflow-runner/test/cli.e2e.test.ts +20 -0
- package/plugins/workflow-runner/test/context-files.test.ts +47 -16
- package/plugins/workflow-runner/test/e2eNewLayout.test.ts +314 -0
- package/plugins/workflow-runner/test/engineRobustness.test.ts +9 -1
- package/plugins/workflow-runner/test/expressions.test.ts +42 -0
- package/plugins/workflow-runner/test/hostCapability.test.ts +9 -3
- package/plugins/workflow-runner/test/illustrate.load.test.ts +2 -2
- package/plugins/workflow-runner/test/multimodal.test.ts +61 -10
- package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +19 -0
- package/plugins/workflow-runner/test/ppt.load.test.ts +15 -15
- package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +3 -2
- package/plugins/workflow-runner/test/research.load.test.ts +328 -0
- package/plugins/workflow-runner/test/runnerPreflight.test.ts +68 -11
- package/plugins/workflow-runner/test/stateLifecycle.test.ts +60 -12
- package/plugins/workflow-runner/test/taskArbitration.test.ts +19 -3
- package/plugins/workflow-runner/test/taskLifecycle.test.ts +61 -7
- package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +168 -0
- package/plugins/workflow-runner/test/webppt.load.test.ts +4 -4
- package/plugins/workflow-runner/test/word.load.test.ts +9 -9
- package/skills/skill-creator/scripts/run_eval.py +3 -2
- package/src/cli/print.js +36 -4
- package/src/cli/print.ts +42 -4
- package/src/cli/streamJson.js +19 -4
- package/src/cli/streamJson.ts +17 -4
- package/src/config/configDefaults.js +25 -0
- package/src/config/configDefaults.ts +33 -0
- package/src/config/configFile.js +2 -21
- package/src/config/configFile.ts +11 -24
- package/src/config/configManagement.js +1 -1
- package/src/config/configManagement.ts +2 -2
- package/src/config/configService.js +24 -0
- package/src/config/configService.ts +23 -0
- package/src/context/compact.js +4 -0
- package/src/context/compact.ts +4 -0
- package/src/context/contextBundle.js +38 -13
- package/src/context/contextBundle.ts +47 -13
- package/src/harness/stallGuard.js +19 -4
- package/src/harness/stallGuard.ts +30 -7
- package/src/infra/verification.js +25 -18
- package/src/infra/verification.ts +50 -18
- package/src/loop.js +95 -11
- package/src/loop.ts +125 -16
- package/src/main.js +8 -1
- package/src/main.tsx +7 -1
- package/src/memory/constants.js +10 -0
- package/src/memory/constants.ts +13 -0
- package/src/memory/episodicMemory.js +274 -2
- package/src/memory/episodicMemory.ts +306 -1
- package/src/memory/fileStore.js +24 -4
- package/src/memory/fileStore.ts +22 -2
- package/src/memory/memoryService.js +79 -12
- package/src/memory/memoryService.ts +108 -9
- package/src/memory/repository.js +415 -85
- package/src/memory/repository.ts +437 -86
- package/src/memory/turnJournal.js +95 -0
- package/src/memory/turnJournal.ts +120 -0
- package/src/memory/types.ts +16 -0
- package/src/plugins/pluginApi.ts +30 -6
- package/src/plugins/pluginRunner.js +23 -8
- package/src/plugins/pluginRunner.ts +32 -13
- package/src/prompts/policyRegistry.js +55 -1
- package/src/prompts/policyRegistry.ts +55 -1
- package/src/prompts/promptAssembly.js +39 -7
- package/src/prompts/promptAssembly.ts +145 -59
- package/src/session/runAgentTurn.js +43 -21
- package/src/session/runAgentTurn.ts +68 -26
- package/src/session/runTurn.js +11 -46
- package/src/session/runTurn.ts +12 -46
- package/src/session/runtimeStore.js +149 -0
- package/src/session/runtimeStore.ts +197 -0
- package/src/session/sessionState.js +5 -0
- package/src/session/sessionState.ts +14 -0
- package/src/tools/advisor/advisor.js +76 -9
- package/src/tools/advisor/advisor.ts +79 -9
- package/src/tools/agent/agent.js +143 -14
- package/src/tools/agent/agent.ts +149 -14
- package/src/tools/agent/agentTaskService.js +60 -0
- package/src/tools/agent/agentTaskService.ts +113 -0
- package/src/tools/agent/agentTypes.js +5 -0
- package/src/tools/agent/agentTypes.ts +5 -0
- package/src/tools/bash/bash.js +80 -15
- package/src/tools/bash/bash.ts +83 -15
- package/src/tools/capabilities.js +5 -0
- package/src/tools/capabilities.ts +11 -1
- package/src/tools/edit/edit.js +7 -4
- package/src/tools/edit/edit.ts +7 -4
- package/src/tools/edit/multi-edit.js +4 -2
- package/src/tools/edit/multi-edit.ts +4 -2
- package/src/tools/glob/glob.js +156 -40
- package/src/tools/glob/glob.ts +185 -46
- package/src/tools/index.js +35 -17
- package/src/tools/index.ts +81 -20
- package/src/tools/lsp/lsp.js +165 -22
- package/src/tools/lsp/lsp.ts +206 -36
- package/src/tools/powershell/powershell.js +134 -27
- package/src/tools/powershell/powershell.ts +171 -30
- package/src/tools/presentresult/presentresult.js +10 -0
- package/src/tools/presentresult/presentresult.ts +10 -0
- package/src/tools/read/read.js +249 -29
- package/src/tools/read/read.ts +396 -59
- package/src/tools/shared/diffSummary.js +44 -0
- package/src/tools/shared/diffSummary.ts +63 -0
- package/src/tools/shared/fileActivity.js +2 -1
- package/src/tools/shared/fileActivity.ts +3 -0
- package/src/tools/shared/permanentDeleteGuard.js +57 -0
- package/src/tools/shared/permanentDeleteGuard.ts +71 -0
- package/src/tools/shared/toolOutputStore.js +97 -0
- package/src/tools/shared/toolOutputStore.ts +110 -0
- package/src/tools/skill/skill.js +86 -0
- package/src/tools/skill/skill.ts +94 -0
- package/src/tools/snip/snip.js +67 -0
- package/src/tools/snip/snip.ts +80 -0
- package/src/tools/tasks/backgroundTaskService.js +79 -28
- package/src/tools/tasks/backgroundTaskService.ts +165 -49
- package/src/tools/tasks/taskManagement.js +163 -0
- package/src/tools/tasks/taskManagement.ts +180 -0
- package/src/tools/tasks/taskOutput.js +64 -14
- package/src/tools/tasks/taskOutput.ts +102 -23
- package/src/tools/tasks/taskStop.js +48 -8
- package/src/tools/tasks/taskStop.ts +69 -9
- package/src/tools/tasks/taskStore.js +46 -0
- package/src/tools/tasks/taskStore.ts +77 -0
- package/src/tools/terminal/terminalCapture.js +167 -0
- package/src/tools/terminal/terminalCapture.ts +179 -0
- package/src/tools/trash/trash.js +233 -0
- package/src/tools/trash/trash.ts +283 -0
- package/src/tools/webbrowser/browserControl.js +5 -1
- package/src/tools/webbrowser/browserControl.ts +7 -1
- package/src/tools/webbrowser/webbrowser.js +8 -4
- package/src/tools/webbrowser/webbrowser.ts +8 -4
- package/src/tools/worktree/sessionWorktree.js +128 -0
- package/src/tools/worktree/sessionWorktree.ts +158 -0
- package/src/tools/write/write.js +6 -2
- package/src/tools/write/write.ts +6 -2
- package/src/types.ts +22 -4
- package/src/ui/hooks/useChat.js +31 -11
- package/src/ui/hooks/useChat.ts +31 -13
- package/src/web/protocol.ts +78 -3
- package/workflows/adaptive-research.yaml +5 -5
- package/workflows/book-review-short.yaml +5 -5
- package/workflows/e2e-write-greet.yaml +2 -2
- package/workflows/illustrate.yaml +12 -12
- package/workflows/plan.yaml +18 -18
- package/workflows/ppt.yaml +201 -201
- package/workflows/ralph-loop.yaml +3 -1
- package/workflows/research.md +449 -0
- package/workflows/research.yaml +873 -0
- package/workflows/webppt.yaml +47 -47
- package/workflows/word.yaml +80 -80
- package/workflows/youtube-shorts.yaml +25 -25
package/workflows/word.yaml
CHANGED
|
@@ -10,7 +10,7 @@ description: >
|
|
|
10
10
|
version: "0.1"
|
|
11
11
|
|
|
12
12
|
artifacts:
|
|
13
|
-
- "
|
|
13
|
+
- "out/word/${session}/article.docx"
|
|
14
14
|
|
|
15
15
|
self_heal:
|
|
16
16
|
max_retries: 2
|
|
@@ -28,7 +28,7 @@ inputs:
|
|
|
28
28
|
description: "【素材文档·可选 --input】已有配图 Word、纯文字 Word、PPT、PDF、Excel、图片或混合素材路径。留空时解析 topic 中的文件线索,仍无明确素材则扫描当前目录支持格式。"
|
|
29
29
|
- name: out
|
|
30
30
|
type: string
|
|
31
|
-
default: "
|
|
31
|
+
default: "out/word/${session}/article.docx"
|
|
32
32
|
description: "【高级·可选 --input】输出 Word 文件路径。"
|
|
33
33
|
- name: image_intensity
|
|
34
34
|
type: enum
|
|
@@ -44,7 +44,7 @@ inputs:
|
|
|
44
44
|
type: enum
|
|
45
45
|
values: ["true", "false"]
|
|
46
46
|
default: "true"
|
|
47
|
-
description: "【调试·可选 --input】是否保留
|
|
47
|
+
description: "【调试·可选 --input】是否保留 out/word/${session}/build 中间产物。默认 true,便于检查 article.md、material.json、img_plan.json 和报告。"
|
|
48
48
|
|
|
49
49
|
steps:
|
|
50
50
|
- id: stage0_analyze
|
|
@@ -77,27 +77,27 @@ steps:
|
|
|
77
77
|
args:
|
|
78
78
|
command: |
|
|
79
79
|
set -e
|
|
80
|
-
mkdir -p
|
|
80
|
+
mkdir -p out/word/${session}/build out/word/${session}
|
|
81
81
|
rm -f \
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
rm -rf
|
|
100
|
-
mkdir -p
|
|
82
|
+
out/word/${session}/build/article.md \
|
|
83
|
+
out/word/${session}/build/article_outline.md \
|
|
84
|
+
out/word/${session}/build/build_complete \
|
|
85
|
+
out/word/${session}/build/export-summary.md \
|
|
86
|
+
out/word/${session}/build/img_plan.json \
|
|
87
|
+
out/word/${session}/build/image_map.json \
|
|
88
|
+
out/word/${session}/build/material.md \
|
|
89
|
+
out/word/${session}/build/material.json \
|
|
90
|
+
out/word/${session}/build/source_resolution.json \
|
|
91
|
+
out/word/${session}/build/source_assets.json \
|
|
92
|
+
out/word/${session}/build/source.md \
|
|
93
|
+
out/word/${session}/build/source_stats.json \
|
|
94
|
+
out/word/${session}/build/user_request.md \
|
|
95
|
+
out/word/${session}/build/word_topic_image_gate.json \
|
|
96
|
+
out/word/${session}/build/word_topic_image_gate.md \
|
|
97
|
+
out/word/${session}/build/word_customer_image_usage.json \
|
|
98
|
+
out/word/${session}/build/word_customer_image_usage.md
|
|
99
|
+
rm -rf out/word/${session}/build/assets out/word/${session}/build/vision out/word/${session}/build/generated-image-reviews
|
|
100
|
+
mkdir -p out/word/${session}/build/assets out/word/${session}/build/vision
|
|
101
101
|
|
|
102
102
|
RESOLVE="skills/ui-design/scripts/resolve_source_input.py"
|
|
103
103
|
EXTRACT="skills/ui-design/scripts/extract_source_assets.py"
|
|
@@ -114,16 +114,16 @@ steps:
|
|
|
114
114
|
--source "$RAW_SOURCE" \
|
|
115
115
|
--topic "$RAW_TOPIC" \
|
|
116
116
|
--cwd . \
|
|
117
|
-
--out
|
|
118
|
-
SOURCE="$(python3 -c 'import json; data=json.load(open("
|
|
117
|
+
--out out/word/${session}/build/source_resolution.json
|
|
118
|
+
SOURCE="$(python3 -c 'import json; data=json.load(open("out/word/${session}/build/source_resolution.json", encoding="utf-8")); print(data.get("resolved_path") or "")')"
|
|
119
119
|
if [ -n "$SOURCE" ]; then
|
|
120
|
-
python3 "$EXTRACT" "$SOURCE" --out
|
|
120
|
+
python3 "$EXTRACT" "$SOURCE" --out out/word/${session}/build -v
|
|
121
121
|
else
|
|
122
|
-
python3 "$EXTRACT" . --scan --out
|
|
122
|
+
python3 "$EXTRACT" . --scan --out out/word/${session}/build -v
|
|
123
123
|
fi
|
|
124
|
-
python3 -c 'import json,sys; r=json.load(open("
|
|
125
|
-
python3 "$STATS"
|
|
126
|
-
cat >
|
|
124
|
+
python3 -c 'import json,sys; r=json.load(open("out/word/${session}/build/source_resolution.json", encoding="utf-8")); a=json.load(open("out/word/${session}/build/source_assets.json", encoding="utf-8")); ok=not (r.get("requires_source") and not a.get("has_source")); print("WORD_SOURCE_REQUIRED_BUT_EMPTY: 用户明确要求使用素材文件,但抽取结果为空。", file=sys.stderr) if not ok else None; print(json.dumps(r, ensure_ascii=False, indent=2), file=sys.stderr) if not ok else None; sys.exit(0 if ok else 3)'
|
|
125
|
+
python3 "$STATS" out/word/${session}/build/assets --scan --json > out/word/${session}/build/source_stats.json
|
|
126
|
+
cat > out/word/${session}/build/user_request.md <<'EOF'
|
|
127
127
|
# 用户原始输入与目标
|
|
128
128
|
|
|
129
129
|
- 主题/指令:${inputs.topic}
|
|
@@ -144,14 +144,14 @@ steps:
|
|
|
144
144
|
4. 文生图只服务章节理解,不做无上下文装饰图。
|
|
145
145
|
EOF
|
|
146
146
|
echo "WORD_SOURCE_EXTRACT_READY"
|
|
147
|
-
test -f
|
|
147
|
+
test -f out/word/${session}/build/source_assets.json
|
|
148
148
|
onError: halt
|
|
149
149
|
|
|
150
150
|
- id: stage_vision_loop
|
|
151
151
|
title: "阶段3/13·逐图识图:客户图内容与文章落点"
|
|
152
|
-
when: "fileExists('
|
|
152
|
+
when: "fileExists('out/word/${session}/build/source_assets.json')"
|
|
153
153
|
type: loop
|
|
154
|
-
over: "${asArray(readJson('
|
|
154
|
+
over: "${asArray(readJson('out/word/${session}/build/source_assets.json', 'images'))}"
|
|
155
155
|
as: img
|
|
156
156
|
fresh_context: true
|
|
157
157
|
do:
|
|
@@ -171,7 +171,7 @@ steps:
|
|
|
171
171
|
- `enhance_recommended`:true/false。低清、比例不适合、背景杂乱、风格不统一时 true;信息密集图/截图/图表若增强会损失文字则 false。
|
|
172
172
|
- `enhance_prompt`:如果需要图生图增强,写英文提示词;必须保留原始主体、信息语义和构图重点,只改善清晰度、比例、光线、背景整洁度和 Word 文章配图质感。
|
|
173
173
|
- `use_rule`:必须写明“所有客户图必须使用,原图或增强后进入最终 Word”。
|
|
174
|
-
images: ["
|
|
174
|
+
images: ["out/word/${session}/build/assets/${img.file}"]
|
|
175
175
|
image_detail: high
|
|
176
176
|
capture:
|
|
177
177
|
text: vision_json
|
|
@@ -183,17 +183,17 @@ steps:
|
|
|
183
183
|
when: "length(vision_json) > 0"
|
|
184
184
|
tool: Write
|
|
185
185
|
args:
|
|
186
|
-
file_path: "
|
|
186
|
+
file_path: "out/word/${session}/build/vision/${img.file}.json"
|
|
187
187
|
content: "${vision_json}"
|
|
188
188
|
onError: continue
|
|
189
189
|
|
|
190
190
|
- id: sanitize_vision_json
|
|
191
191
|
title: "阶段3/13·校验识图 JSON ${img.file}"
|
|
192
|
-
when: "fileExists('
|
|
192
|
+
when: "fileExists('out/word/${session}/build/vision/${img.file}.json')"
|
|
193
193
|
tool: Bash
|
|
194
194
|
args:
|
|
195
195
|
command: |
|
|
196
|
-
python3 - "
|
|
196
|
+
python3 - "out/word/${session}/build/vision/${img.file}.json" <<'PYEOF'
|
|
197
197
|
import json, sys, os
|
|
198
198
|
path = sys.argv[1]
|
|
199
199
|
try:
|
|
@@ -220,7 +220,7 @@ steps:
|
|
|
220
220
|
import json, os
|
|
221
221
|
from pathlib import Path
|
|
222
222
|
|
|
223
|
-
build = Path("
|
|
223
|
+
build = Path("out/word/${session}/build")
|
|
224
224
|
assets = build / "assets"
|
|
225
225
|
vision_dir = build / "vision"
|
|
226
226
|
|
|
@@ -285,17 +285,17 @@ steps:
|
|
|
285
285
|
(build / "material.md").write_text("".join(md), encoding="utf-8")
|
|
286
286
|
print(f"WORD_MATERIAL_READY images={len(images)} chars={len(source_text)}")
|
|
287
287
|
PYEOF
|
|
288
|
-
test -f
|
|
289
|
-
test -f
|
|
288
|
+
test -f out/word/${session}/build/material.md
|
|
289
|
+
test -f out/word/${session}/build/material.json
|
|
290
290
|
onError: halt
|
|
291
291
|
|
|
292
292
|
- id: stage_outline
|
|
293
293
|
title: "阶段5/13·总结扩写大纲:知乎深度长文结构"
|
|
294
294
|
agent: |
|
|
295
|
-
基于以下材料写一份 Word 长文大纲,落盘到
|
|
296
|
-
-
|
|
297
|
-
-
|
|
298
|
-
-
|
|
295
|
+
基于以下材料写一份 Word 长文大纲,落盘到 `out/word/${session}/build/article_outline.md`:
|
|
296
|
+
- `out/word/${session}/build/user_request.md`
|
|
297
|
+
- `out/word/${session}/build/material.md`
|
|
298
|
+
- `out/word/${session}/build/material.json`
|
|
299
299
|
|
|
300
300
|
要求:
|
|
301
301
|
- 文章定位为**知乎深度文章**:有观点、有论证、有转折、有解释、有结论。
|
|
@@ -310,14 +310,14 @@ steps:
|
|
|
310
310
|
- 默认 `image_intensity=balanced` 至少 3 张;`rich` 至少 5 张;`minimal` 至少 1 张封面或核心概念图。
|
|
311
311
|
|
|
312
312
|
写完后简短汇报。
|
|
313
|
-
done_when: "fileExists('
|
|
313
|
+
done_when: "fileExists('out/word/${session}/build/article_outline.md')"
|
|
314
314
|
onError: halt
|
|
315
315
|
maxTurns: 18
|
|
316
316
|
|
|
317
317
|
- id: stage_write_article
|
|
318
318
|
title: "阶段6/13·写作 article.md:知乎深度长文正文"
|
|
319
319
|
agent: |
|
|
320
|
-
基于
|
|
320
|
+
基于 `out/word/${session}/build/article_outline.md`、`out/word/${session}/build/material.md`、`out/word/${session}/build/material.json` 写正文,落盘到 `out/word/${session}/build/article.md`。
|
|
321
321
|
|
|
322
322
|
写作要求:
|
|
323
323
|
- 风格是**知乎深度文章**,不是 PPT 文案,不是资料堆砌。
|
|
@@ -333,16 +333,16 @@ steps:
|
|
|
333
333
|
- 每个占位必须贴近对应章节观点,写清 purpose 和 caption。
|
|
334
334
|
- 图片附近必须有上下文解释,不能把图片孤零零塞进去。
|
|
335
335
|
- 文章中避免出现“作为 AI”“根据材料可知”这类过程话。
|
|
336
|
-
done_when: "fileExists('
|
|
336
|
+
done_when: "fileExists('out/word/${session}/build/article.md')"
|
|
337
337
|
onError: halt
|
|
338
338
|
maxTurns: 25
|
|
339
339
|
|
|
340
340
|
- id: stage_img_plan
|
|
341
341
|
title: "阶段7/13·图文混排计划 img_plan/image_map"
|
|
342
342
|
agent: |
|
|
343
|
-
基于
|
|
344
|
-
1.
|
|
345
|
-
2.
|
|
343
|
+
基于 `out/word/${session}/build/article.md`、`out/word/${session}/build/material.json`、`out/word/${session}/build/material.md` 生成两个文件:
|
|
344
|
+
1. `out/word/${session}/build/img_plan.json`
|
|
345
|
+
2. `out/word/${session}/build/image_map.json`
|
|
346
346
|
|
|
347
347
|
`img_plan.json` 是给 GenerateImage 工具使用的数组,只放需要实际生成/增强的图:
|
|
348
348
|
- 文生图:`{"file":"word_img_1.png","mode":"text-to-image","aspect":"16:9","prompt":"..."}`
|
|
@@ -371,7 +371,7 @@ steps:
|
|
|
371
371
|
- 有客户图时也可以按 `${inputs.image_intensity}` 给关键章节补充文生图,但不能替代客户图使用。
|
|
372
372
|
|
|
373
373
|
写完两个 JSON 后简短汇报。
|
|
374
|
-
done_when: "fileExists('
|
|
374
|
+
done_when: "fileExists('out/word/${session}/build/img_plan.json') && fileExists('out/word/${session}/build/image_map.json')"
|
|
375
375
|
onError: halt
|
|
376
376
|
maxTurns: 18
|
|
377
377
|
|
|
@@ -384,7 +384,7 @@ steps:
|
|
|
384
384
|
python3 - <<'PYEOF'
|
|
385
385
|
import json, sys
|
|
386
386
|
from pathlib import Path
|
|
387
|
-
build = Path("
|
|
387
|
+
build = Path("out/word/${session}/build")
|
|
388
388
|
for name, expect_array in [("img_plan.json", True), ("image_map.json", True)]:
|
|
389
389
|
path = build / name
|
|
390
390
|
data = json.loads(path.read_text(encoding="utf-8-sig"))
|
|
@@ -397,11 +397,11 @@ steps:
|
|
|
397
397
|
|
|
398
398
|
- id: stage_gen_images
|
|
399
399
|
title: "阶段8/13·客户图增强与章节配图生成"
|
|
400
|
-
when: "fileExists('
|
|
400
|
+
when: "fileExists('out/word/${session}/build/img_plan.json')"
|
|
401
401
|
tool: GenerateImage
|
|
402
402
|
args:
|
|
403
|
-
plan:
|
|
404
|
-
assets:
|
|
403
|
+
plan: out/word/${session}/build/img_plan.json
|
|
404
|
+
assets: out/word/${session}/build/assets
|
|
405
405
|
size: 2k
|
|
406
406
|
timeout_ms: 300000
|
|
407
407
|
wall_budget_ms: 3600000
|
|
@@ -411,15 +411,15 @@ steps:
|
|
|
411
411
|
|
|
412
412
|
- id: stage_image_quality_gate
|
|
413
413
|
title: "阶段8/13·补生成降级配图"
|
|
414
|
-
when: "fileExists('
|
|
414
|
+
when: "fileExists('out/word/${session}/build/image_generation_report.json')"
|
|
415
415
|
tool: GenerateImage
|
|
416
416
|
args:
|
|
417
|
-
plan:
|
|
418
|
-
assets:
|
|
417
|
+
plan: out/word/${session}/build/img_plan.json
|
|
418
|
+
assets: out/word/${session}/build/assets
|
|
419
419
|
size: 2k
|
|
420
420
|
timeout_ms: 300000
|
|
421
421
|
wall_budget_ms: 3600000
|
|
422
|
-
retry_degraded_report:
|
|
422
|
+
retry_degraded_report: out/word/${session}/build/image_generation_report.json
|
|
423
423
|
max_rounds: 1
|
|
424
424
|
concurrency: 2
|
|
425
425
|
onError: continue
|
|
@@ -427,7 +427,7 @@ steps:
|
|
|
427
427
|
|
|
428
428
|
- id: stage_generated_image_gate
|
|
429
429
|
title: "阶段8/13·配图成品硬闸门"
|
|
430
|
-
when: "fileExists('
|
|
430
|
+
when: "fileExists('out/word/${session}/build/image_generation_report.json')"
|
|
431
431
|
tool: Bash
|
|
432
432
|
args:
|
|
433
433
|
command: |
|
|
@@ -436,7 +436,7 @@ steps:
|
|
|
436
436
|
import json
|
|
437
437
|
from pathlib import Path
|
|
438
438
|
|
|
439
|
-
build = Path("
|
|
439
|
+
build = Path("out/word/${session}/build")
|
|
440
440
|
report = json.loads((build / "image_generation_report.json").read_text(encoding="utf-8"))
|
|
441
441
|
plan = json.loads((build / "img_plan.json").read_text(encoding="utf-8"))
|
|
442
442
|
assets = build / "assets"
|
|
@@ -459,18 +459,18 @@ steps:
|
|
|
459
459
|
- id: stage_finalize_markdown
|
|
460
460
|
title: "阶段9/13·Markdown 图文混排收口"
|
|
461
461
|
agent: |
|
|
462
|
-
更新
|
|
462
|
+
更新 `out/word/${session}/build/article.md`,把 `out/word/${session}/build/image_map.json` 中的图片按章节插入最终位置。
|
|
463
463
|
|
|
464
464
|
要求:
|
|
465
|
-
- 图片路径统一使用
|
|
465
|
+
- 图片路径统一使用 `out/word/${session}/build/assets/<final_file>`。
|
|
466
466
|
- 每张图必须有 Markdown 图片语法和紧随其后的图注,例如:
|
|
467
|
-
``
|
|
468
468
|
`*图:caption*`
|
|
469
469
|
- 删除临时 `<!-- image: ... -->` 占位。
|
|
470
470
|
- 保持知乎深度文章风格:图片前后要有解释段,说明它支持了哪个观点或案例。
|
|
471
471
|
- 统一标题层级、段落节奏、引用块、表格、结论。
|
|
472
472
|
- 不要加入 PPT 术语,不要提网页 deck、页面 JSON 设计稿、构图门或 fixed canvas。
|
|
473
|
-
done_when: "fileExists('
|
|
473
|
+
done_when: "fileExists('out/word/${session}/build/article.md')"
|
|
474
474
|
onError: halt
|
|
475
475
|
maxTurns: 18
|
|
476
476
|
|
|
@@ -484,7 +484,7 @@ steps:
|
|
|
484
484
|
import json, sys
|
|
485
485
|
from pathlib import Path
|
|
486
486
|
|
|
487
|
-
build = Path("
|
|
487
|
+
build = Path("out/word/${session}/build")
|
|
488
488
|
material = json.loads((build / "material.json").read_text(encoding="utf-8"))
|
|
489
489
|
customer = [img.get("file") for img in material.get("images", []) if img.get("file")]
|
|
490
490
|
if customer:
|
|
@@ -565,7 +565,7 @@ steps:
|
|
|
565
565
|
import json, re, sys
|
|
566
566
|
from pathlib import Path
|
|
567
567
|
|
|
568
|
-
build = Path("
|
|
568
|
+
build = Path("out/word/${session}/build")
|
|
569
569
|
material = json.loads((build / "material.json").read_text(encoding="utf-8"))
|
|
570
570
|
image_map = json.loads((build / "image_map.json").read_text(encoding="utf-8"))
|
|
571
571
|
article = (build / "article.md").read_text(encoding="utf-8")
|
|
@@ -598,15 +598,15 @@ steps:
|
|
|
598
598
|
skill: docx
|
|
599
599
|
input: |
|
|
600
600
|
本步骤是 `skill: docx` 必要节点。
|
|
601
|
-
请严格按当前 minimal-agent 自带 `skills/docx/SKILL.md` 的指引,把
|
|
601
|
+
请严格按当前 minimal-agent 自带 `skills/docx/SKILL.md` 的指引,把 `out/word/${session}/build/article.md` 转换为 Word 文件 `${inputs.out}`。
|
|
602
602
|
|
|
603
603
|
硬性要求:
|
|
604
|
-
- 优先使用 Markdown-first 路线:pandoc
|
|
604
|
+
- 优先使用 Markdown-first 路线:pandoc `out/word/${session}/build/article.md -f markdown-implicit_figures -t docx -o ${inputs.out} --wrap=preserve --standalone`。
|
|
605
605
|
- 必须关闭 pandoc implicit_figures,避免 Markdown 图片 alt 文本被渲染成额外可见图注;最终只保留 article.md 中显式的 `*图:...*` 图注。
|
|
606
606
|
- 如果 pandoc 不可用或图片/表格转换失败,按 docx skill 指引回退到 python-docx 或 docx-js。
|
|
607
607
|
- 若使用 docx-js,必须用 Node 运行脚本,不要用 Bun。
|
|
608
608
|
- 保留 Markdown 标题层级、列表、表格、引用块、图片、图注和正文段落。
|
|
609
|
-
- 图片来自
|
|
609
|
+
- 图片来自 `out/word/${session}/build/assets/<final_file>`,不要丢图。
|
|
610
610
|
- 最终必须生成 `${inputs.out}`。
|
|
611
611
|
onError: halt
|
|
612
612
|
maxTurns: 25
|
|
@@ -663,14 +663,14 @@ steps:
|
|
|
663
663
|
python3 - <<'PYEOF'
|
|
664
664
|
import json, os
|
|
665
665
|
from pathlib import Path
|
|
666
|
-
build = Path("
|
|
666
|
+
build = Path("out/word/${session}/build")
|
|
667
667
|
article = build / "article.md"
|
|
668
668
|
image_map = json.loads((build / "image_map.json").read_text(encoding="utf-8")) if (build / "image_map.json").exists() else []
|
|
669
669
|
usage = json.loads((build / "word_customer_image_usage.json").read_text(encoding="utf-8")) if (build / "word_customer_image_usage.json").exists() else {}
|
|
670
670
|
summary = [
|
|
671
671
|
"# Word 导出摘要\n\n",
|
|
672
672
|
f"- 输出文件:${inputs.out}\n",
|
|
673
|
-
f"- Markdown
|
|
673
|
+
f"- Markdown:out/word/${session}/build/article.md\n",
|
|
674
674
|
f"- 文章字符数:{len(article.read_text(encoding='utf-8')) if article.exists() else 0}\n",
|
|
675
675
|
f"- 图片映射数量:{len(image_map)}\n",
|
|
676
676
|
f"- 客户图数量:{usage.get('customer_count', 0)}\n",
|
|
@@ -679,7 +679,7 @@ steps:
|
|
|
679
679
|
(build / "export-summary.md").write_text("".join(summary), encoding="utf-8")
|
|
680
680
|
print("WORD_DOCX_VERIFY_OK")
|
|
681
681
|
PYEOF
|
|
682
|
-
touch
|
|
682
|
+
touch out/word/${session}/build/build_complete
|
|
683
683
|
onError: halt
|
|
684
684
|
|
|
685
685
|
- id: cleanup_intermediates
|
|
@@ -689,9 +689,9 @@ steps:
|
|
|
689
689
|
args:
|
|
690
690
|
command: |
|
|
691
691
|
set -e
|
|
692
|
-
mkdir -p
|
|
693
|
-
cp
|
|
694
|
-
rm -rf
|
|
692
|
+
mkdir -p out/word/${session}
|
|
693
|
+
cp out/word/${session}/build/export-summary.md out/word/${session}/word-export-summary.md 2>/dev/null || true
|
|
694
|
+
rm -rf out/word/${session}/build
|
|
695
695
|
echo "WORD_BUILD_CLEANED"
|
|
696
696
|
onError: continue
|
|
697
697
|
|
|
@@ -712,9 +712,9 @@ steps:
|
|
|
712
712
|
Word 长文已生成。
|
|
713
713
|
|
|
714
714
|
- 输出 Word:[${inputs.out}](${inputs.out})
|
|
715
|
-
- Markdown
|
|
716
|
-
-
|
|
717
|
-
-
|
|
718
|
-
-
|
|
715
|
+
- Markdown 草稿:out/word/${session}/build/article.md
|
|
716
|
+
- 统一材料:out/word/${session}/build/material.md / out/word/${session}/build/material.json
|
|
717
|
+
- 配图计划:out/word/${session}/build/img_plan.json / out/word/${session}/build/image_map.json
|
|
718
|
+
- 导出摘要:out/word/${session}/build/export-summary.md
|
|
719
719
|
|
|
720
720
|
流程:素材摄取 → 逐图识图 → 统一 material → 知乎深度文章大纲 → article.md 正文 → 图文混排计划 → 客户图增强/章节配图 → 客户图用尽闸门 → docx skill 导出 → OPC 校验。
|
|
@@ -10,8 +10,8 @@ version: "0.1"
|
|
|
10
10
|
# 声明产物:new-task 启动清理残留 / completed 报实际产物 / 同任务 resume 重写不被
|
|
11
11
|
# 内核「覆盖前先 Read」守卫挡(见 CLAUDE.md 任务身份语义)
|
|
12
12
|
artifacts:
|
|
13
|
-
- "
|
|
14
|
-
- "
|
|
13
|
+
- "out/youtube-shorts/${session}/assets/script.json"
|
|
14
|
+
- "out/youtube-shorts/${session}/shorts.mp4"
|
|
15
15
|
|
|
16
16
|
inputs:
|
|
17
17
|
- name: topic
|
|
@@ -59,9 +59,9 @@ steps:
|
|
|
59
59
|
title: "2/11·脚本落盘 script.json"
|
|
60
60
|
tool: Write
|
|
61
61
|
artifacts:
|
|
62
|
-
- "
|
|
62
|
+
- "out/youtube-shorts/${session}/assets/script.json"
|
|
63
63
|
args:
|
|
64
|
-
file_path: "
|
|
64
|
+
file_path: "out/youtube-shorts/${session}/assets/script.json"
|
|
65
65
|
content: "${script_json_text}"
|
|
66
66
|
|
|
67
67
|
# ---------- 3. 解析 script.json,拆出 prompts.txt / narrations.txt(每行一个) ----------
|
|
@@ -71,12 +71,12 @@ steps:
|
|
|
71
71
|
args:
|
|
72
72
|
command: |
|
|
73
73
|
set -euo pipefail
|
|
74
|
-
mkdir -p
|
|
75
|
-
jq -r '.scenes[].image_prompt'
|
|
76
|
-
jq -r '.scenes[].text'
|
|
74
|
+
mkdir -p out/youtube-shorts/${session}/assets out/youtube-shorts/${session}
|
|
75
|
+
jq -r '.scenes[].image_prompt' out/youtube-shorts/${session}/assets/script.json > out/youtube-shorts/${session}/assets/prompts.txt
|
|
76
|
+
jq -r '.scenes[].text' out/youtube-shorts/${session}/assets/script.json > out/youtube-shorts/${session}/assets/narrations.txt
|
|
77
77
|
# 把 narrations 转成 JSON 数组字符串,用于后续 subtitle-srt 调用
|
|
78
|
-
jq -c '[.scenes[].text]'
|
|
79
|
-
wc -l
|
|
78
|
+
jq -c '[.scenes[].text]' out/youtube-shorts/${session}/assets/script.json > out/youtube-shorts/${session}/assets/narrations_json.txt
|
|
79
|
+
wc -l out/youtube-shorts/${session}/assets/prompts.txt out/youtube-shorts/${session}/assets/narrations.txt
|
|
80
80
|
capture:
|
|
81
81
|
content: parse_log
|
|
82
82
|
|
|
@@ -84,9 +84,9 @@ steps:
|
|
|
84
84
|
title: "4/11·校验脚本拆分产物"
|
|
85
85
|
type: verify
|
|
86
86
|
checks:
|
|
87
|
-
- 'file_exists
|
|
88
|
-
- 'file_exists
|
|
89
|
-
onFail: "
|
|
87
|
+
- 'file_exists:out/youtube-shorts/${session}/assets/prompts.txt'
|
|
88
|
+
- 'file_exists:out/youtube-shorts/${session}/assets/narrations.txt'
|
|
89
|
+
onFail: "脚本解析失败:out/youtube-shorts/${session}/assets/prompts.txt 或 out/youtube-shorts/${session}/assets/narrations.txt 不存在"
|
|
90
90
|
|
|
91
91
|
# ---------- 4. 生成 5 张配图(loop 静态数组 + 每轮先读对应一行 prompt) ----------
|
|
92
92
|
# ⚠️ Bash 引号 footgun:${i} 是引擎插值(shell 之前发生)。曾写 1 基算术
|
|
@@ -102,13 +102,13 @@ steps:
|
|
|
102
102
|
title: "读第 ${i} 行画面提示词"
|
|
103
103
|
tool: Bash
|
|
104
104
|
args:
|
|
105
|
-
command: 'sed -n "${i}p"
|
|
105
|
+
command: 'sed -n "${i}p" out/youtube-shorts/${session}/assets/prompts.txt'
|
|
106
106
|
capture:
|
|
107
107
|
content: prompt_text
|
|
108
108
|
- id: gen_one_image
|
|
109
109
|
title: "生成第 ${i} 张配图"
|
|
110
110
|
skill: image-gen-openrouter
|
|
111
|
-
input: 'prompt=${prompt_text} output
|
|
111
|
+
input: 'prompt=${prompt_text} output=out/youtube-shorts/${session}/assets/img_${i}.png aspect=${inputs.aspect} key=${inputs.openrouter_key}'
|
|
112
112
|
|
|
113
113
|
# ---------- 5. 生成 5 段 TTS 音频(1 基序号,理由同 gen_images) ----------
|
|
114
114
|
- id: gen_audio
|
|
@@ -121,13 +121,13 @@ steps:
|
|
|
121
121
|
title: "读第 ${i} 句旁白"
|
|
122
122
|
tool: Bash
|
|
123
123
|
args:
|
|
124
|
-
command: 'sed -n "${i}p"
|
|
124
|
+
command: 'sed -n "${i}p" out/youtube-shorts/${session}/assets/narrations.txt'
|
|
125
125
|
capture:
|
|
126
126
|
content: narration_text
|
|
127
127
|
- id: gen_one_tts
|
|
128
128
|
title: "合成第 ${i} 段语音"
|
|
129
129
|
skill: tts-zh
|
|
130
|
-
input: 'text=${narration_text} output
|
|
130
|
+
input: 'text=${narration_text} output=out/youtube-shorts/${session}/assets/audio_${i}.mp3'
|
|
131
131
|
|
|
132
132
|
# ---------- 6. 探测各段音频时长,逗号串联 ----------
|
|
133
133
|
- id: probe_durations
|
|
@@ -136,7 +136,7 @@ steps:
|
|
|
136
136
|
args:
|
|
137
137
|
command: |
|
|
138
138
|
set -euo pipefail
|
|
139
|
-
for f in $(ls
|
|
139
|
+
for f in $(ls out/youtube-shorts/${session}/assets/audio_*.mp3 | sort); do
|
|
140
140
|
ffprobe -v error -show_entries format=duration -of csv=p=0 "$f"
|
|
141
141
|
done | paste -sd, -
|
|
142
142
|
capture:
|
|
@@ -151,18 +151,18 @@ steps:
|
|
|
151
151
|
set -euo pipefail
|
|
152
152
|
LIST=/tmp/audio_concat.txt
|
|
153
153
|
: > "$LIST"
|
|
154
|
-
for f in $(ls
|
|
154
|
+
for f in $(ls out/youtube-shorts/${session}/assets/audio_*.mp3 | sort); do
|
|
155
155
|
echo "file '$(pwd)/${f}'" >> "$LIST"
|
|
156
156
|
done
|
|
157
|
-
ffmpeg -y -f concat -safe 0 -i "$LIST" -c copy
|
|
158
|
-
ls -la
|
|
157
|
+
ffmpeg -y -f concat -safe 0 -i "$LIST" -c copy out/youtube-shorts/${session}/assets/audio.mp3
|
|
158
|
+
ls -la out/youtube-shorts/${session}/assets/audio.mp3
|
|
159
159
|
|
|
160
160
|
# ---------- 8. 读 narrations_json(前面 parse_script 已写好),作 SRT 文本输入 ----------
|
|
161
161
|
- id: read_narrations_json
|
|
162
162
|
title: "9/11·读取旁白清单"
|
|
163
163
|
tool: Read
|
|
164
164
|
args:
|
|
165
|
-
file_path: "
|
|
165
|
+
file_path: "out/youtube-shorts/${session}/assets/narrations_json.txt"
|
|
166
166
|
capture:
|
|
167
167
|
content: narrations_json
|
|
168
168
|
|
|
@@ -170,21 +170,21 @@ steps:
|
|
|
170
170
|
- id: make_srt
|
|
171
171
|
title: "10/11·生成字幕"
|
|
172
172
|
skill: subtitle-srt
|
|
173
|
-
input: 'texts=${narrations_json} durations=${durations} output
|
|
173
|
+
input: 'texts=${narrations_json} durations=${durations} output=out/youtube-shorts/${session}/assets/subs.srt'
|
|
174
174
|
|
|
175
175
|
# ---------- 10. 合成最终 mp4 ----------
|
|
176
176
|
- id: compose_video
|
|
177
177
|
title: "11/11·合成最终视频"
|
|
178
178
|
skill: video-compose
|
|
179
|
-
input: 'images_glob
|
|
179
|
+
input: 'images_glob=out/youtube-shorts/${session}/assets/img_*.png audio=out/youtube-shorts/${session}/assets/audio.mp3 srt=out/youtube-shorts/${session}/assets/subs.srt output=out/youtube-shorts/${session}/shorts.mp4 width=${inputs.width} height=${inputs.height}'
|
|
180
180
|
|
|
181
181
|
# ---------- 11. 守门 verify(升级自 assert) ----------
|
|
182
182
|
- id: verify_output
|
|
183
183
|
title: "完成·守门校验"
|
|
184
184
|
type: verify
|
|
185
185
|
checks:
|
|
186
|
-
- 'file_exists
|
|
187
|
-
onFail: "最终视频
|
|
186
|
+
- 'file_exists:out/youtube-shorts/${session}/shorts.mp4'
|
|
187
|
+
onFail: "最终视频 out/youtube-shorts/${session}/shorts.mp4 未生成,请检查 video-compose 日志"
|
|
188
188
|
|
|
189
189
|
__meta:
|
|
190
190
|
layout:
|