ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s

This commit is contained in:
2026-08-20 13:12:50 +00:00
commit b119135836
10275 changed files with 3284984 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

@@ -0,0 +1,186 @@
{
"request": "Cut out the shot of the large white rabbit walking alone in the sunny meadow, slow it to 1.5x duration, and add the subtitle BIG BUNNY along the bottom.",
"target": "the single continuous shot showing the large white rabbit walking alone in a sunny green meadow, after the ONE BIG RABBIT title and before the THREE RODENTS title",
"coarse_interval_s": 10,
"coarse_frames": [
{
"timestamp_s": 0.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-000.00.png",
"sha256": "cdd5c7f27f84347a40eb467c356c5a2fda3facdad9057f246034e355b89dcfdd",
"bytes": 1580
},
{
"timestamp_s": 10.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-010.00.png",
"sha256": "bdf01683fab23e1e98099d0f6e19596eabcd96ddb1c643b3d0c6749b5f2995a9",
"bytes": 288771
},
{
"timestamp_s": 20.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-020.00.png",
"sha256": "713c2f7a5db41b01640dbae71ef4d5057c382dd1480d9e31bcc3f6d05c9da52b",
"bytes": 183618
},
{
"timestamp_s": 30.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-030.00.png",
"sha256": "ce5d5733e716607000f9d6aef75dbb9b31279dd50e7db7c6c1e714819624224a",
"bytes": 264372
},
{
"timestamp_s": 31.495,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-031.50.png",
"sha256": "57e555d305ac18228155454935f9a411a9e21ccc092348997f8e3299d4011b89",
"bytes": 40146
}
],
"coarse_result": {
"start": 10.0,
"end": 20.0,
"reason": "The 10.00s frame shows the large white rabbit standing alone in a sunny green meadow with rolling hills and a clear sky, matching the target description. The next frame at 20.00s transitions to three rodents in a darker forested area (likely the 'THREE RODENTS' title content), indicating the rabbit shot is continuous between these timestamps."
},
"fine_interval_s": 1,
"fine_window": [
5,
25
],
"fine_frames": [
{
"timestamp_s": 5.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-005.00.png",
"sha256": "7bf0f2f437e8781ac96e6a27b41f975189c3784dbd3368672d43fd4b2d92813a",
"bytes": 451029
},
{
"timestamp_s": 6.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-006.00.png",
"sha256": "618ee855deb607995c0be98d0a64db5614c4f851837af105e0672822947fe361",
"bytes": 451002
},
{
"timestamp_s": 7.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-007.00.png",
"sha256": "40e9724ee1834abee7d12002cd83a4120738b0ffd0a294741c25c2135edb02b8",
"bytes": 196294
},
{
"timestamp_s": 8.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-008.00.png",
"sha256": "1da6191f1a0c6ccc987a8e5d0682d7e664aa4ce8b8ce31d232bec5ae695b0c4e",
"bytes": 25229
},
{
"timestamp_s": 9.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-009.00.png",
"sha256": "c0358569f2defb8cfdcd0c73393fc2e75cab6168920819a7c0d28395389132b7",
"bytes": 26259
},
{
"timestamp_s": 10.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-010.00.png",
"sha256": "bdf01683fab23e1e98099d0f6e19596eabcd96ddb1c643b3d0c6749b5f2995a9",
"bytes": 288771
},
{
"timestamp_s": 11.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-011.00.png",
"sha256": "c1abe47a8bd0e10472b75a472cea78ff24613c64ccc74ffba9b566d71336c4f4",
"bytes": 290263
},
{
"timestamp_s": 12.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-012.00.png",
"sha256": "5833475f37ad6ccc7f98c953193368b11c4f3390d1633e224b0a43514c7aa2ec",
"bytes": 23585
},
{
"timestamp_s": 13.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-013.00.png",
"sha256": "f14dca5370861a1b1f1ee95d1e00172314f27e60ec9f3451a16e08efb46cabf4",
"bytes": 24310
},
{
"timestamp_s": 14.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-014.00.png",
"sha256": "ab5ed49e0a1267d80e53bc524db96a521aedf419d4a2e766463bd58fc2cbd96a",
"bytes": 290328
},
{
"timestamp_s": 15.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-015.00.png",
"sha256": "101c7a220045bdad559ffabcf2345a307c4b2a8ace71c1f289f861cb5ac8dfcf",
"bytes": 337454
},
{
"timestamp_s": 16.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-016.00.png",
"sha256": "6b674c7689ae86485ce112daa9a14cbd4334d3c41cbc12bcc8a06b0c34c3d0bd",
"bytes": 118937
},
{
"timestamp_s": 17.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-017.00.png",
"sha256": "44134f20bffcd9fb57c3ca421a7be03fa2596962423a955140bf44e3d5c2582b",
"bytes": 24201
},
{
"timestamp_s": 18.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-018.00.png",
"sha256": "bf44d8b974343063293c92d2933edd0e9a711802d44753f5c0c8b4f4cf3406aa",
"bytes": 25412
},
{
"timestamp_s": 19.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-019.00.png",
"sha256": "7d2fdecd1cff9d025880e069d111c9e8aa0c488dd1e570b62f5147a136543271",
"bytes": 78776
},
{
"timestamp_s": 20.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-020.00.png",
"sha256": "713c2f7a5db41b01640dbae71ef4d5057c382dd1480d9e31bcc3f6d05c9da52b",
"bytes": 183618
},
{
"timestamp_s": 21.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-021.00.png",
"sha256": "c9758159919eb5f8612e3af01258d1c7792d446ca5c08add2ff3dcd3b97e7617",
"bytes": 96371
},
{
"timestamp_s": 22.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-022.00.png",
"sha256": "54b41278b256654341515bee8f7adb3166bdb15c90f3da9f7f47eb72cad77d33",
"bytes": 192864
},
{
"timestamp_s": 23.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-023.00.png",
"sha256": "3e49ae19ac287a5acdcff0db46d93d3ca77f98d039d9c53f07210466a323b5b3",
"bytes": 22428
},
{
"timestamp_s": 24.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-024.00.png",
"sha256": "6eb1ae362db441052be6685922270fcd86572c8b223e99a41a519424ac113c0d",
"bytes": 24410
},
{
"timestamp_s": 25.0,
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-025.00.png",
"sha256": "354595be0073fcaed614da1ff41177f01e54f74b63f5614ed5033a9c00e0a773",
"bytes": 211411
}
],
"fine_result": {
"start": 9.0,
"end": 12.0,
"reason": "Starts immediately after the 'ONE BIG RABBIT' title (ends at 9.00s) and ends just before the 'THREE RODENTS' title (starts at 12.00s), with continuous visuals of the large white rabbit in the sunny green meadow at 10.00s and 11.00s."
},
"ground_truth": {
"start": 9.08,
"end": 11.2
},
"start_error_s": 0.08,
"end_error_s": 0.8
}
@@ -0,0 +1,546 @@
{
"calls": [
{
"purpose": "coarse_10_second_visual_localization",
"provider": "ark",
"endpoint": "https://ark.cn-beijing.volces.com/api/v3",
"request": {
"model": "doubao-seed-1-6-250615",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "These are frames from one contiguous real trailer sampled about every 10 seconds.\nLocate this target: the single continuous shot showing the large white rabbit walking alone in a sunny green meadow, after the ONE BIG RABBIT title and before the THREE RODENTS title.\nReturn JSON {\"start\":seconds,\"end\":seconds,\"reason\":\"visual evidence\"} with a rough continuous interval. Use timestamps and visual content only."
},
{
"type": "text",
"text": "timestamp=0.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-000.00.png",
"sha256": "cdd5c7f27f84347a40eb467c356c5a2fda3facdad9057f246034e355b89dcfdd",
"bytes": 1580
},
{
"type": "text",
"text": "timestamp=10.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-010.00.png",
"sha256": "bdf01683fab23e1e98099d0f6e19596eabcd96ddb1c643b3d0c6749b5f2995a9",
"bytes": 288771
},
{
"type": "text",
"text": "timestamp=20.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-020.00.png",
"sha256": "713c2f7a5db41b01640dbae71ef4d5057c382dd1480d9e31bcc3f6d05c9da52b",
"bytes": 183618
},
{
"type": "text",
"text": "timestamp=30.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-030.00.png",
"sha256": "ce5d5733e716607000f9d6aef75dbb9b31279dd50e7db7c6c1e714819624224a",
"bytes": 264372
},
{
"type": "text",
"text": "timestamp=31.50s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/coarse/frame-031.50.png",
"sha256": "57e555d305ac18228155454935f9a411a9e21ccc092348997f8e3299d4011b89",
"bytes": 40146
}
]
}
],
"temperature": 0,
"max_tokens": 700,
"response_format": {
"type": "json_object"
}
},
"response": {
"id": "02178536012758415b00b15f7b15a122bee0bef9a71075862cfbb",
"model": "doubao-seed-1-6-250615",
"finish_reason": "stop",
"content": "{\"start\":10.00,\"end\":20.00,\"reason\":\"The 10.00s frame shows the large white rabbit standing alone in a sunny green meadow with rolling hills and a clear sky, matching the target description. The next frame at 20.00s transitions to three rodents in a darker forested area (likely the 'THREE RODENTS' title content), indicating the rabbit shot is continuous between these timestamps.\"}"
},
"usage": {
"prompt_tokens": 1686,
"completion_tokens": 734,
"total_tokens": 2420
},
"latency_s": 20.057
},
{
"purpose": "fine_1_second_visual_localization",
"provider": "ark",
"endpoint": "https://ark.cn-beijing.volces.com/api/v3",
"request": {
"model": "doubao-seed-1-6-250615",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "These are one-second samples from the narrowed window [5.0, 25.0] seconds of the same real trailer.\nPrecisely locate the boundaries of this one continuous target shot: the single continuous shot showing the large white rabbit walking alone in a sunny green meadow, after the ONE BIG RABBIT title and before the THREE RODENTS title.\nReturn JSON {\"start\":seconds,\"end\":seconds,\"reason\":\"visual boundary evidence\"}. The answer may interpolate between adjacent one-second samples; do not include either neighboring title card."
},
{
"type": "text",
"text": "timestamp=5.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-005.00.png",
"sha256": "7bf0f2f437e8781ac96e6a27b41f975189c3784dbd3368672d43fd4b2d92813a",
"bytes": 451029
},
{
"type": "text",
"text": "timestamp=6.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-006.00.png",
"sha256": "618ee855deb607995c0be98d0a64db5614c4f851837af105e0672822947fe361",
"bytes": 451002
},
{
"type": "text",
"text": "timestamp=7.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-007.00.png",
"sha256": "40e9724ee1834abee7d12002cd83a4120738b0ffd0a294741c25c2135edb02b8",
"bytes": 196294
},
{
"type": "text",
"text": "timestamp=8.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-008.00.png",
"sha256": "1da6191f1a0c6ccc987a8e5d0682d7e664aa4ce8b8ce31d232bec5ae695b0c4e",
"bytes": 25229
},
{
"type": "text",
"text": "timestamp=9.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-009.00.png",
"sha256": "c0358569f2defb8cfdcd0c73393fc2e75cab6168920819a7c0d28395389132b7",
"bytes": 26259
},
{
"type": "text",
"text": "timestamp=10.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-010.00.png",
"sha256": "bdf01683fab23e1e98099d0f6e19596eabcd96ddb1c643b3d0c6749b5f2995a9",
"bytes": 288771
},
{
"type": "text",
"text": "timestamp=11.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-011.00.png",
"sha256": "c1abe47a8bd0e10472b75a472cea78ff24613c64ccc74ffba9b566d71336c4f4",
"bytes": 290263
},
{
"type": "text",
"text": "timestamp=12.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-012.00.png",
"sha256": "5833475f37ad6ccc7f98c953193368b11c4f3390d1633e224b0a43514c7aa2ec",
"bytes": 23585
},
{
"type": "text",
"text": "timestamp=13.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-013.00.png",
"sha256": "f14dca5370861a1b1f1ee95d1e00172314f27e60ec9f3451a16e08efb46cabf4",
"bytes": 24310
},
{
"type": "text",
"text": "timestamp=14.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-014.00.png",
"sha256": "ab5ed49e0a1267d80e53bc524db96a521aedf419d4a2e766463bd58fc2cbd96a",
"bytes": 290328
},
{
"type": "text",
"text": "timestamp=15.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-015.00.png",
"sha256": "101c7a220045bdad559ffabcf2345a307c4b2a8ace71c1f289f861cb5ac8dfcf",
"bytes": 337454
},
{
"type": "text",
"text": "timestamp=16.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-016.00.png",
"sha256": "6b674c7689ae86485ce112daa9a14cbd4334d3c41cbc12bcc8a06b0c34c3d0bd",
"bytes": 118937
},
{
"type": "text",
"text": "timestamp=17.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-017.00.png",
"sha256": "44134f20bffcd9fb57c3ca421a7be03fa2596962423a955140bf44e3d5c2582b",
"bytes": 24201
},
{
"type": "text",
"text": "timestamp=18.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-018.00.png",
"sha256": "bf44d8b974343063293c92d2933edd0e9a711802d44753f5c0c8b4f4cf3406aa",
"bytes": 25412
},
{
"type": "text",
"text": "timestamp=19.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-019.00.png",
"sha256": "7d2fdecd1cff9d025880e069d111c9e8aa0c488dd1e570b62f5147a136543271",
"bytes": 78776
},
{
"type": "text",
"text": "timestamp=20.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-020.00.png",
"sha256": "713c2f7a5db41b01640dbae71ef4d5057c382dd1480d9e31bcc3f6d05c9da52b",
"bytes": 183618
},
{
"type": "text",
"text": "timestamp=21.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-021.00.png",
"sha256": "c9758159919eb5f8612e3af01258d1c7792d446ca5c08add2ff3dcd3b97e7617",
"bytes": 96371
},
{
"type": "text",
"text": "timestamp=22.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-022.00.png",
"sha256": "54b41278b256654341515bee8f7adb3166bdb15c90f3da9f7f47eb72cad77d33",
"bytes": 192864
},
{
"type": "text",
"text": "timestamp=23.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-023.00.png",
"sha256": "3e49ae19ac287a5acdcff0db46d93d3ca77f98d039d9c53f07210466a323b5b3",
"bytes": 22428
},
{
"type": "text",
"text": "timestamp=24.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-024.00.png",
"sha256": "6eb1ae362db441052be6685922270fcd86572c8b223e99a41a519424ac113c0d",
"bytes": 24410
},
{
"type": "text",
"text": "timestamp=25.00s"
},
{
"type": "image_artifact",
"path": "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/frames/fine/frame-025.00.png",
"sha256": "354595be0073fcaed614da1ff41177f01e54f74b63f5614ed5033a9c00e0a773",
"bytes": 211411
}
]
}
],
"temperature": 0,
"max_tokens": 700,
"response_format": {
"type": "json_object"
}
},
"response": {
"id": "02178536014931215b00b15f7b15a122bee0bef9a7107589f12c6",
"model": "doubao-seed-1-6-250615",
"finish_reason": "stop",
"content": "{\"start\":9.0,\"end\":12.0,\"reason\":\"Starts immediately after the 'ONE BIG RABBIT' title (ends at 9.00s) and ends just before the 'THREE RODENTS' title (starts at 12.00s), with continuous visuals of the large white rabbit in the sunny green meadow at 10.00s and 11.00s.\"}"
},
"usage": {
"prompt_tokens": 6555,
"completion_tokens": 1158,
"total_tokens": 7713
},
"latency_s": 31.727
},
{
"purpose": "blender_script_negative-control_attempt_1",
"provider": "ark",
"endpoint": "https://ark.cn-beijing.volces.com/api/v3",
"request": {
"model": "doubao-seed-1-6-250615",
"messages": [
{
"role": "system",
"content": "You are a Blender VSE engineer. Return one JSON object only."
},
{
"role": "user",
"content": "Generate a complete Blender 4.3 Python script for this video edit.\n\nInput movie: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov\nOutput MP4: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4\nSource FPS: 25\nSource size: 853x480; render at 854x480 (one-pixel even-width pad required by H.264)\nTrim interval: [0.000, 3.000] seconds\nEffects: slow playback so output duration is 1.5 times the trimmed interval; add bottom-centered subtitle BIG BUNNY with a visible semi-transparent dark box.\n\nRequirements:\n- Use bpy and Blender's Video Sequence Editor, including new_movie, new_sound when available, frame_offset_start/frame_final_duration, a SPEED effect, and a TEXT effect.\n- Render exactly 854x480 at 25 fps through Blender to MPEG-4 H.264 with AAC audio.\n- Set the scene frame range to the slowed duration and call bpy.ops.render.render(animation=True).\n- Create only the requested output. Do not invoke ffmpeg, subprocesses, a shell, the network, or read credentials.\n- Use APIs available in Blender 4.3 (scene.sequence_editor_create().sequences).\n- In Blender 4.3, SpeedControlSequence has no use_audio property. Never read or assign use_audio, and do not apply a SPEED effect to the sound strip. A valid movie slow-motion pattern is speed_control='MULTIPLY', speed_factor=1/1.5, and extending the movie/render duration; the sound strip may remain normally trimmed.\n- For the subtitle background, prefer the TEXT strip's use_box=True and box_color=(0,0,0,0.6); do not assume a COLOR strip has text-layout properties.\n\nReturn one JSON object only: {\"code\":\"complete executable Python source\"}.\n"
}
],
"temperature": 0,
"max_tokens": 7000,
"response_format": {
"type": "json_object"
}
},
"response": {
"id": "02178536018101615b00b15f7b15a122bee0bef9a710758b49a93",
"model": "doubao-seed-1-6-250615",
"finish_reason": "stop",
"content": "{\"code\":\"import bpy\\n\\n# Clear existing objects to start fresh\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete()\\n\\n# Configuration paths and parameters\\nINPUT_MOVIE = \\\"/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov\\\"\\nOUTPUT_MP4 = \\\"/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4\\\"\\nSOURCE_FPS = 25\\nTRIM_DURATION_SECONDS = 3.0\\nSLOW_FACTOR = 1.5\\nRENDER_RESOLUTION = (854, 480)\\n\\n# Calculate frame values\\ntrim_frames = int(TRIM_DURATION_SECONDS * SOURCE_FPS)\\nslowed_frames = int(trim_frames * SLOW_FACTOR)\\nscene = bpy.context.scene\\n\\n# Create sequence editor\\nseq_ed = scene.sequence_editor_create()\\n\\n# Add movie strip with trim\\nmovie_strip = seq_ed.sequences.new_movie(\\n name=\\\"SourceVideo\\\",\\n filepath=INPUT_MOVIE,\\n channel=1,\\n frame_start=1\\n)\\nmovie_strip.frame_offset_start = 0 # Start at beginning of source\\nmovie_strip.frame_final_duration = trim_frames # Trim to 3 seconds\\n\\n# Locate and trim audio strip (auto-created with movie)\\nsound_strip = None\\nfor strip in seq_ed.sequences:\\n if strip.type == 'SOUND' and strip.channel == 2 and strip.frame_start == 1:\\n sound_strip = strip\\nif sound_strip:\\n sound_strip.frame_final_duration = trim_frames # Keep audio at original speed\\n\\n# Add speed effect to video (slow motion)\\nspeed_strip = seq_ed.sequences.new_effect(\\n name=\\\"SlowMotion\\\",\\n type='SPEED',\\n channel=3,\\n frame_start=1,\\n frame_end=1 + slowed_frames - 1,\\n target=movie_strip\\n)\\nspeed_strip.speed_control = 'MULTIPLY'\\nspeed_strip.speed_factor = 1 / SLOW_FACTOR # 1/1.5 speed factor\\n\\n# Add subtitle text strip with background box\\ntext_strip = seq_ed.sequences.new_text(\\n name=\\\"Subtitle\\\",\\n text=\\\"BIG BUNNY\\\",\\n channel=4,\\n frame_start=1,\\n frame_end=1 + slowed_frames - 1\\n)\\ntext_strip.align_x = 'CENTER'\\ntext_strip.align_y = 'BOTTOM'\\ntext_strip.use_box = True\\ntext_strip.box_color = (0.0, 0.0, 0.0, 0.6) # Black semi-transparent box\\ntext_strip.font_size = 48 # Visible size for 854x480 resolution\\n\\n# Configure render settings\\nscene.render.resolution_x = RENDER_RESOLUTION[0]\\nscene.render.resolution_y = RENDER_RESOLUTION[1]\\nscene.render.resolution_percentage = 100\\nscene.render.fps = SOURCE_FPS\\nscene.render.fps_base = 1.0\\nscene.render.image_settings.file_format = 'FFMPEG'\\nscene.render.ffmpeg.format = 'MPEG4'\\nscene.render.ffmpeg.codec = 'H264'\\nscene.render.ffmpeg.audio_codec = 'AAC'\\nscene.render.filepath = OUTPUT_MP4\\n\\n# Set render frame range\\nscene.frame_start = 1\\nscene.frame_end = 1 + slowed_frames - 1\\n\\n# Execute render\\nbpy.ops.render.render(animation=True)\"}"
},
"usage": {
"prompt_tokens": 614,
"completion_tokens": 6404,
"total_tokens": 7018
},
"latency_s": 153.914
},
{
"purpose": "blender_script_negative-control_attempt_2",
"provider": "ark",
"endpoint": "https://ark.cn-beijing.volces.com/api/v3",
"request": {
"model": "doubao-seed-1-6-250615",
"messages": [
{
"role": "system",
"content": "You are a Blender VSE engineer. Return one JSON object only."
},
{
"role": "user",
"content": "Generate a complete Blender 4.3 Python script for this video edit.\n\nInput movie: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov\nOutput MP4: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4\nSource FPS: 25\nSource size: 853x480; render at 854x480 (one-pixel even-width pad required by H.264)\nTrim interval: [0.000, 3.000] seconds\nEffects: slow playback so output duration is 1.5 times the trimmed interval; add bottom-centered subtitle BIG BUNNY with a visible semi-transparent dark box.\n\nRequirements:\n- Use bpy and Blender's Video Sequence Editor, including new_movie, new_sound when available, frame_offset_start/frame_final_duration, a SPEED effect, and a TEXT effect.\n- Render exactly 854x480 at 25 fps through Blender to MPEG-4 H.264 with AAC audio.\n- Set the scene frame range to the slowed duration and call bpy.ops.render.render(animation=True).\n- Create only the requested output. Do not invoke ffmpeg, subprocesses, a shell, the network, or read credentials.\n- Use APIs available in Blender 4.3 (scene.sequence_editor_create().sequences).\n- In Blender 4.3, SpeedControlSequence has no use_audio property. Never read or assign use_audio, and do not apply a SPEED effect to the sound strip. A valid movie slow-motion pattern is speed_control='MULTIPLY', speed_factor=1/1.5, and extending the movie/render duration; the sound strip may remain normally trimmed.\n- For the subtitle background, prefer the TEXT strip's use_box=True and box_color=(0,0,0,0.6); do not assume a COLOR strip has text-layout properties.\n\nReturn one JSON object only: {\"code\":\"complete executable Python source\"}.\n\nPrior executable feedback:\nStatic safety/API validation failed: ValueError: generated script omits requested Blender API operations: ['TEXT']"
}
],
"temperature": 0,
"max_tokens": 7000,
"response_format": {
"type": "json_object"
}
},
"response": {
"id": "02178536033493315b00b15f7b15a122bee0bef9a710758de0884",
"model": "doubao-seed-1-6-250615",
"finish_reason": "stop",
"content": "{\"code\":\"import bpy\\n\\n# Clear existing data\\nbpy.ops.wm.read_factory_settings(use_empty=True)\\nscene = bpy.context.scene\\n\\n# Scene settings\\nscene.render.resolution_x = 854\\nscene.render.resolution_y = 480\\nscene.render.resolution_percentage = 100\\nscene.render.fps = 25\\nscene.render.fps_base = 1.0\\n\\n# Create sequence editor\\nif not scene.sequence_editor:\\n scene.sequence_editor_create()\\nseq_ed = scene.sequence_editor\\nsequences = seq_ed.sequences\\n\\n# File paths\\ninput_movie = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov'\\noutput_mp4 = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4'\\n\\n# Add movie strip (3 seconds = 75 frames at 25fps)\\nmov_strip = sequences.new_movie(\\n name='SourceMovie',\\n filepath=input_movie,\\n frame_start=1,\\n channel=1\\n)\\nmov_strip.frame_offset_start = 0\\nmov_strip.frame_final_duration = 75 # 3s * 25fps\\n\\n# Locate and trim sound strip\\nsound_strip = next((s for s in sequences if s.type == 'SOUND' and s.frame_start == mov_strip.frame_start), None)\\nif sound_strip:\\n sound_strip.frame_final_duration = 75 # Keep original audio duration\\n\\n# Add speed effect (1.5x slowdown)\\nspeed_strip = sequences.new_effect(\\n name='SlowMotion',\\n type='SPEED',\\n frame_start=1,\\n channel=2,\\n input_1=mov_strip\\n)\\nspeed_strip.speed_control = 'MULTIPLY'\\nspeed_strip.speed_factor = 1 / 1.5\\n\\n# Calculate slowed duration (4.5s = 112.5 frames → 113 frames)\\nslowed_frames = int(4.5 * 25) + 1\\nscene.frame_start = 1\\nscene.frame_end = slowed_frames\\n\\n# Add subtitle text strip\\ntext_strip = sequences.new_effect(\\n name='Subtitle',\\n type='TEXT',\\n frame_start=1,\\n frame_end=scene.frame_end,\\n channel=3\\n)\\ntext_strip.text = 'BIG BUNNY'\\ntext_strip.align_x = 'CENTER'\\ntext_strip.align_y = 'BOTTOM'\\ntext_strip.use_box = True\\ntext_strip.box_color = (0, 0, 0, 0.6)\\ntext_strip.font_size = 48\\n\\n# Render settings\\nscene.render.filepath = output_mp4\\nscene.render.image_settings.file_format = 'FFMPEG'\\nscene.render.ffmpeg.format = 'MPEG4'\\nscene.render.ffmpeg.codec = 'H264'\\nscene.render.ffmpeg.audio_codec = 'AAC'\\nscene.render.ffmpeg.constant_rate_factor = 'MEDIUM'\\n\\n# Render animation\\nbpy.ops.render.render(animation=True)\"}"
},
"usage": {
"prompt_tokens": 641,
"completion_tokens": 4682,
"total_tokens": 5323
},
"latency_s": 103.993
},
{
"purpose": "blender_script_negative-control_attempt_3",
"provider": "ark",
"endpoint": "https://ark.cn-beijing.volces.com/api/v3",
"request": {
"model": "doubao-seed-1-6-250615",
"messages": [
{
"role": "system",
"content": "You are a Blender VSE engineer. Return one JSON object only."
},
{
"role": "user",
"content": "Generate a complete Blender 4.3 Python script for this video edit.\n\nInput movie: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov\nOutput MP4: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4\nSource FPS: 25\nSource size: 853x480; render at 854x480 (one-pixel even-width pad required by H.264)\nTrim interval: [0.000, 3.000] seconds\nEffects: slow playback so output duration is 1.5 times the trimmed interval; add bottom-centered subtitle BIG BUNNY with a visible semi-transparent dark box.\n\nRequirements:\n- Use bpy and Blender's Video Sequence Editor, including new_movie, new_sound when available, frame_offset_start/frame_final_duration, a SPEED effect, and a TEXT effect.\n- Render exactly 854x480 at 25 fps through Blender to MPEG-4 H.264 with AAC audio.\n- Set the scene frame range to the slowed duration and call bpy.ops.render.render(animation=True).\n- Create only the requested output. Do not invoke ffmpeg, subprocesses, a shell, the network, or read credentials.\n- Use APIs available in Blender 4.3 (scene.sequence_editor_create().sequences).\n- In Blender 4.3, SpeedControlSequence has no use_audio property. Never read or assign use_audio, and do not apply a SPEED effect to the sound strip. A valid movie slow-motion pattern is speed_control='MULTIPLY', speed_factor=1/1.5, and extending the movie/render duration; the sound strip may remain normally trimmed.\n- For the subtitle background, prefer the TEXT strip's use_box=True and box_color=(0,0,0,0.6); do not assume a COLOR strip has text-layout properties.\n\nReturn one JSON object only: {\"code\":\"complete executable Python source\"}.\n\nPrior executable feedback:\nBlender exit=0; output_exists=False. Tail of real Blender log:\nBlender 4.3.2 (hash 32f5fdce0a0a built 2024-12-17 02:14:25)\nTraceback (most recent call last):\n File \"/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/scripts/negative-control-attempt-2.py\", line 40, in <module>\n speed_strip = sequences.new_effect(\n ^^^^^^^^^^^^^^^^^^^^^\nTypeError: SequencesTopLevel.new_effect(): was called with invalid keyword argument(s) (input_1), expected (name, type, channel, frame_start, frame_end, seq1, seq2)\n\nBlender quit"
}
],
"temperature": 0,
"max_tokens": 7000,
"response_format": {
"type": "json_object"
}
},
"response": {
"id": "02178536043966315b00b15f7b15a122bee0bef9a710758ef6add",
"model": "doubao-seed-1-6-250615",
"finish_reason": "stop",
"content": "{\"code\":\"import bpy\\nimport os\\n\\n# Clear default objects\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete()\\n\\n# Set up scene\\nscene = bpy.context.scene\\nscene.render.fps = 25\\nscene.render.fps_base = 1.0\\nscene.render.resolution_x = 854\\nscene.render.resolution_y = 480\\nscene.render.resolution_percentage = 100\\n\\n# Configure output settings\\nscene.render.image_settings.file_format = 'FFMPEG'\\nscene.render.ffmpeg.format = 'MPEG4'\\nscene.render.ffmpeg.codec = 'H264'\\nscene.render.ffmpeg.audio_codec = 'AAC'\\nscene.render.ffmpeg.audio_bitrate = 192\\noutput_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4'\\nscene.render.filepath = output_path\\n\\n# Create sequence editor\\nscene.sequence_editor_create()\\nsequences = scene.sequence_editor.sequences\\n\\n# Import source movie and sound\\nsource_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov'\\nmovie_strip = sequences.new_movie(name='SourceMovie', filepath=source_path, channel=1, frame_start=0)\\n\\nsound_strip = None\\nfor strip in sequences:\\n if strip.type == 'SOUND' and strip.name.startswith('SourceMovie'):\\n sound_strip = strip\\n break\\nif not sound_strip:\\n sound_strip = sequences.new_sound(name='SourceAudio', filepath=source_path, channel=2, frame_start=0)\\n\\n# Trim to 3-second interval (75 frames at 25fps)\\ntrim_frames = 75 # 3.0s * 25fps\\nmovie_strip.frame_start = 0\\nmovie_strip.frame_final_duration = trim_frames\\nsound_strip.frame_start = 0\\nsound_strip.frame_final_duration = trim_frames\\n\\n# Apply speed effect (1.5x slowdown = 4.5s output)\\nspeed_strip = sequences.new_effect(\\n name='SpeedControl',\\n type='SPEED',\\n channel=2,\\n frame_start=0,\\n frame_end=113, # 75 frames * 1.5 = 112.5 → 113 frames\\n seq1=movie_strip,\\n seq2=None\\n)\\nspeed_strip.speed_control = 'MULTIPLY'\\nspeed_strip.speed_factor = 1/1.5\\n\\n# Set scene frame range\\nduration_frames = 113 # 4.5s * 25fps = 112.5 → 113 frames\\nscene.frame_start = 0\\nscene.frame_end = duration_frames\\n\\n# Add subtitle with background box\\ntext_strip = sequences.new_effect(\\n name='Subtitle',\\n type='TEXT',\\n channel=3,\\n frame_start=0,\\n frame_end=duration_frames,\\n seq1=None,\\n seq2=None\\n)\\ntext_strip.text = 'BIG BUNNY'\\ntext_strip.align_x = 'CENTER'\\ntext_strip.align_y = 'BOTTOM'\\ntext_strip.use_box = True\\ntext_strip.box_color = (0.0, 0.0, 0.0, 0.6)\\ntext_strip.font_size = 48\\n\\n# Render animation\\nbpy.ops.render.render(animation=True)\"}"
},
"usage": {
"prompt_tokens": 821,
"completion_tokens": 5369,
"total_tokens": 6190
},
"latency_s": 111.15
},
{
"purpose": "blender_script_negative-control_attempt_4",
"provider": "ark",
"endpoint": "https://ark.cn-beijing.volces.com/api/v3",
"request": {
"model": "doubao-seed-1-6-250615",
"messages": [
{
"role": "system",
"content": "You are a Blender VSE engineer. Return one JSON object only."
},
{
"role": "user",
"content": "Generate a complete Blender 4.3 Python script for this video edit.\n\nInput movie: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov\nOutput MP4: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4\nSource FPS: 25\nSource size: 853x480; render at 854x480 (one-pixel even-width pad required by H.264)\nTrim interval: [0.000, 3.000] seconds\nEffects: slow playback so output duration is 1.5 times the trimmed interval; add bottom-centered subtitle BIG BUNNY with a visible semi-transparent dark box.\n\nRequirements:\n- Use bpy and Blender's Video Sequence Editor, including new_movie, new_sound when available, frame_offset_start/frame_final_duration, a SPEED effect, and a TEXT effect.\n- Render exactly 854x480 at 25 fps through Blender to MPEG-4 H.264 with AAC audio.\n- Set the scene frame range to the slowed duration and call bpy.ops.render.render(animation=True).\n- Create only the requested output. Do not invoke ffmpeg, subprocesses, a shell, the network, or read credentials.\n- Use APIs available in Blender 4.3 (scene.sequence_editor_create().sequences).\n- In Blender 4.3, SpeedControlSequence has no use_audio property. Never read or assign use_audio, and do not apply a SPEED effect to the sound strip. A valid movie slow-motion pattern is speed_control='MULTIPLY', speed_factor=1/1.5, and extending the movie/render duration; the sound strip may remain normally trimmed.\n- For the subtitle background, prefer the TEXT strip's use_box=True and box_color=(0,0,0,0.6); do not assume a COLOR strip has text-layout properties.\n\nReturn one JSON object only: {\"code\":\"complete executable Python source\"}.\n\nPrior executable feedback:\nStatic safety/API validation failed: ValueError: generated script omits requested Blender API operations: ['frame_offset_start']"
}
],
"temperature": 0,
"max_tokens": 7000,
"response_format": {
"type": "json_object"
}
},
"response": {
"id": "02178536055081715b00b15f7b15a122bee0bef9a71075821cc7c",
"model": "doubao-seed-1-6-250615",
"finish_reason": "stop",
"content": "{\"code\":\"import bpy\\nimport os\\n\\n# Clear existing data\\nbpy.ops.wm.read_factory_settings(use_empty=True)\\n\\n# Get the current scene\\nscene = bpy.context.scene\\n\\n# Set render resolution (854x480 for H.264 even width)\\nscene.render.resolution_x = 854\\nscene.render.resolution_y = 480\\nscene.render.resolution_percentage = 100\\n\\n# Set frame rate (25 FPS)\\nscene.render.fps = 25\\nscene.render.fps_base = 1.0\\n\\n# Output settings\\noutput_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4'\\nscene.render.filepath = output_path\\nscene.render.image_settings.file_format = 'FFMPEG'\\nscene.render.ffmpeg.format = 'MPEG4'\\nscene.render.ffmpeg.codec = 'H.264'\\nscene.render.ffmpeg.audio_codec = 'AAC'\\nscene.render.ffmpeg.audio_mixrate = 44100\\nscene.render.ffmpeg.audio_bitrate = 192\\nscene.render.use_audio = True\\n\\n# Create sequence editor\\nscene.sequence_editor_create()\\nseq_ed = scene.sequence_editor\\n\\n# Source movie path\\nsource_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov'\\n\\n# Add video strip with trim (0.000-3.000s = 75 frames @25FPS)\\nvideo_strip = seq_ed.sequences.new_movie(\\n name='Video',\\n filepath=source_path,\\n channel=1,\\n frame_start=1\\n)\\nvideo_strip.frame_offset_start = 0 # Start at 0s of source\\nvideo_strip.frame_final_duration = 75 # Trim to 3s (75 frames)\\n\\n# Add SPEED effect for slow motion (1.5x duration)\\n speed_effect = seq_ed.sequences.new_effect(\\n name='SpeedControl',\\n type='SPEED',\\n channel=2,\\n frame_start=1,\\n seq1=video_strip\\n)\\nspeed_effect.speed_control = 'MULTIPLY'\\nspeed_effect.speed_factor = 1/1.5 # Slow playback speed\\n\\n# Extend video duration to 1.5x trimmed interval (4.5s = 112.5 frames → 113 frames)\\nvideo_strip.frame_final_duration = 113\\n\\n# Configure audio strip (trim to original 3s duration)\\nsound_strip = None\\nfor strip in seq_ed.sequences:\\n if strip.type == 'SOUND' and strip.name.startswith('Audio'):\\n sound_strip = strip\\nif sound_strip:\\n sound_strip.frame_offset_start = 0 # Start at 0s of source audio\\n sound_strip.frame_final_duration = 75 # Keep original 3s duration\\n\\n# Add subtitle text strip with background box\\ntext_strip = seq_ed.sequences.new_effect(\\n name='Subtitle',\\n type='TEXT',\\n channel=3,\\n frame_start=1,\\n frame_final_duration=113\\n)\\ntext_strip.text = 'BIG BUNNY'\\ntext_strip.align_x = 'CENTER'\\ntext_strip.align_y = 'BOTTOM'\\ntext_strip.use_box = True\\ntext_strip.box_color = (0, 0, 0, 0.6) # Semi-transparent black box\\ntext_strip.font_size = 48\\n\\n# Set scene frame range to match slowed video duration\\nscene.frame_start = 1\\nscene.frame_end = 113\\n\\n# Render the animation\\nbpy.ops.render.render(animation=True)\"}"
},
"usage": {
"prompt_tokens": 643,
"completion_tokens": 4515,
"total_tokens": 5158
},
"latency_s": 97.508
},
{
"purpose": "blender_script_negative-control_attempt_5",
"provider": "ark",
"endpoint": "https://ark.cn-beijing.volces.com/api/v3",
"request": {
"model": "doubao-seed-1-6-250615",
"messages": [
{
"role": "system",
"content": "You are a Blender VSE engineer. Return one JSON object only."
},
{
"role": "user",
"content": "Generate a complete Blender 4.3 Python script for this video edit.\n\nInput movie: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov\nOutput MP4: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4\nSource FPS: 25\nSource size: 853x480; render at 854x480 (one-pixel even-width pad required by H.264)\nTrim interval: [0.000, 3.000] seconds\nEffects: slow playback so output duration is 1.5 times the trimmed interval; add bottom-centered subtitle BIG BUNNY with a visible semi-transparent dark box.\n\nRequirements:\n- Use bpy and Blender's Video Sequence Editor, including new_movie, new_sound when available, frame_offset_start/frame_final_duration, a SPEED effect, and a TEXT effect.\n- Render exactly 854x480 at 25 fps through Blender to MPEG-4 H.264 with AAC audio.\n- Set the scene frame range to the slowed duration and call bpy.ops.render.render(animation=True).\n- Create only the requested output. Do not invoke ffmpeg, subprocesses, a shell, the network, or read credentials.\n- Use APIs available in Blender 4.3 (scene.sequence_editor_create().sequences).\n- In Blender 4.3, SpeedControlSequence has no use_audio property. Never read or assign use_audio, and do not apply a SPEED effect to the sound strip. A valid movie slow-motion pattern is speed_control='MULTIPLY', speed_factor=1/1.5, and extending the movie/render duration; the sound strip may remain normally trimmed.\n- For the subtitle background, prefer the TEXT strip's use_box=True and box_color=(0,0,0,0.6); do not assume a COLOR strip has text-layout properties.\n\nReturn one JSON object only: {\"code\":\"complete executable Python source\"}.\n\nPrior executable feedback:\nStatic safety/API validation failed: IndentationError: unexpected indent (<unknown>, line 48)"
}
],
"temperature": 0,
"max_tokens": 7000,
"response_format": {
"type": "json_object"
}
},
"response": {
"id": "02178536064833115b00b15f7b15a122bee0bef9a710758d5fc02",
"model": "doubao-seed-1-6-250615",
"finish_reason": "stop",
"content": "{\"code\":\"import bpy\\n\\n# Clear existing data\\nbpy.ops.wm.read_factory_settings(use_empty=True)\\n\\n# Get the scene\\nscene = bpy.context.scene\\n\\n# Set render resolution and FPS\\nscene.render.resolution_x = 854\\nscene.render.resolution_y = 480\\nscene.render.resolution_percentage = 100\\nscene.render.fps = 25\\nscene.render.fps_base = 1.0\\n\\n# Set output settings\\noutput_path = \\\"/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4\\\"\\nscene.render.filepath = output_path\\nscene.render.image_settings.file_format = 'FFMPEG'\\nscene.render.ffmpeg.format = 'MPEG4'\\nscene.render.ffmpeg.codec = 'H264'\\nscene.render.ffmpeg.audio_codec = 'AAC'\\nscene.render.ffmpeg.constant_rate_factor = 'MEDIUM'\\n\\n# Create sequence editor\\nseq_ed = scene.sequence_editor_create()\\n\\n# Import movie strip\\nmovie_path = \\\"/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov\\\"\\nmovie_strip = seq_ed.sequences.new_movie(\\n name=\\\"SourceMovie\\\",\\n filepath=movie_path,\\n channel=1,\\n frame_start=0\\n)\\n\\n# Trim movie to [0.000, 3.000] seconds (75 frames at 25 FPS)\\nmovie_strip.frame_offset_start = 0\\nmovie_strip.frame_final_duration = 75\\n\\n# Add speed control effect\\nspeed_strip = seq_ed.sequences.new_effect(\\n name=\\\"SpeedControl\\\",\\n type='SPEED',\\n channel=2,\\n frame_start=0,\\n frame_end=movie_strip.frame_start + movie_strip.frame_final_duration,\\n seq1=movie_strip\\n)\\nspeed_strip.speed_control = 'MULTIPLY'\\nspeed_strip.speed_factor = 1 / 1.5 # Slow down by 1.5x\\n\\n# Find sound strip and trim it\\nsound_strip = None\\nfor strip in seq_ed.sequences:\\n if strip.type == 'SOUND' and strip.frame_start == movie_strip.frame_start:\\n sound_strip = strip\\n break\\nif sound_strip:\\n sound_strip.frame_offset_start = 0\\n sound_strip.frame_final_duration = 75 # Keep sound at normal duration\\n\\n# Calculate render duration: 3s * 1.5 = 4.5s = 112.5 frames → 113 frames (0-112)\\nscene.frame_start = 0\\nscene.frame_end = 113 # 113 frames total\\n\\n# Add subtitle text strip\\ntext_strip = seq_ed.sequences.new_effect(\\n name=\\\"Subtitle\\\",\\n type='TEXT',\\n channel=3,\\n frame_start=0,\\n frame_end=scene.frame_end\\n)\\ntext_strip.text = \\\"BIG BUNNY\\\"\\ntext_strip.align_x = 'CENTER'\\ntext_strip.align_y = 'BOTTOM'\\ntext_strip.font_size = 48\\ntext_strip.color = (1, 1, 1, 1) # White text\\ntext_strip.use_box = True\\ntext_strip.box_color = (0, 0, 0, 0.6) # Dark semi-transparent box\\n\\n# Render animation\\nscene.render.engine = 'BLENDER_EEVEE'\\nbpy.ops.render.render(animation=True)\"}"
},
"usage": {
"prompt_tokens": 641,
"completion_tokens": 6960,
"total_tokens": 7601
},
"latency_s": 139.053
},
{
"purpose": "blender_script_negative-control_attempt_6",
"provider": "ark",
"endpoint": "https://ark.cn-beijing.volces.com/api/v3",
"request": {
"model": "doubao-seed-1-6-250615",
"messages": [
{
"role": "system",
"content": "You are a Blender VSE engineer. Return one JSON object only."
},
{
"role": "user",
"content": "Generate a complete Blender 4.3 Python script for this video edit.\n\nInput movie: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov\nOutput MP4: /Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4\nSource FPS: 25\nSource size: 853x480; render at 854x480 (one-pixel even-width pad required by H.264)\nTrim interval: [0.000, 3.000] seconds\nEffects: slow playback so output duration is 1.5 times the trimmed interval; add bottom-centered subtitle BIG BUNNY with a visible semi-transparent dark box.\n\nRequirements:\n- Use bpy and Blender's Video Sequence Editor, including new_movie, new_sound when available, frame_offset_start/frame_final_duration, a SPEED effect, and a TEXT effect.\n- Render exactly 854x480 at 25 fps through Blender to MPEG-4 H.264 with AAC audio.\n- Set the scene frame range to the slowed duration and call bpy.ops.render.render(animation=True).\n- Create only the requested output. Do not invoke ffmpeg, subprocesses, a shell, the network, or read credentials.\n- Use APIs available in Blender 4.3 (scene.sequence_editor_create().sequences).\n- In Blender 4.3, SpeedControlSequence has no use_audio property. Never read or assign use_audio, and do not apply a SPEED effect to the sound strip. A valid movie slow-motion pattern is speed_control='MULTIPLY', speed_factor=1/1.5, and extending the movie/render duration; the sound strip may remain normally trimmed.\n- For the subtitle background, prefer the TEXT strip's use_box=True and box_color=(0,0,0,0.6); do not assume a COLOR strip has text-layout properties.\n\nReturn one JSON object only: {\"code\":\"complete executable Python source\"}.\n\nPrior executable feedback:\nBlender exit=0; output_exists=False. Tail of real Blender log:\nBlender 4.3.2 (hash 32f5fdce0a0a built 2024-12-17 02:14:25)\nTraceback (most recent call last):\n File \"/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/scripts/negative-control-attempt-5.py\", line 42, in <module>\n speed_strip = seq_ed.sequences.new_effect(\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nTypeError: SequencesTopLevel.new_effect(): error with keyword argument \"frame_end\" - Function.frame_end expected an int type, not float\n\nBlender quit"
}
],
"temperature": 0,
"max_tokens": 7000,
"response_format": {
"type": "json_object"
}
},
"response": {
"id": "02178536078809715b00b15f7b15a122bee0bef9a710758656f73",
"model": "doubao-seed-1-6-250615",
"finish_reason": "stop",
"content": "{\"code\":\"import bpy\\nimport math\\n\\n# Clear existing objects\\nbpy.ops.object.select_all(action='SELECT')\\nbpy.ops.object.delete()\\n\\n# File paths\\ninput_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov'\\noutput_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4'\\n\\n# Scene setup\\nscene = bpy.context.scene\\n\\n# Render settings\\nscene.render.fps = 25\\nscene.render.fps_base = 1.0\\nscene.render.resolution_x = 854\\nscene.render.resolution_y = 480\\nscene.render.resolution_percentage = 100\\n\\n# Output format settings\\nscene.render.image_settings.file_format = 'MPEG4'\\nscene.render.ffmpeg.format = 'MPEG4'\\nscene.render.ffmpeg.codec = 'H264'\\nscene.render.ffmpeg.audio_codec = 'AAC'\\nscene.render.filepath = output_path\\n\\n# VSE setup\\nscene.sequence_editor_create()\\nseq_ed = scene.sequence_editor\\n\\n# Add video strip\\nvideo_strip = seq_ed.sequences.new_movie(\\n name='Video',\\n filepath=input_path,\\n frame_start=0,\\n channel=1\\n)\\nvideo_strip.frame_final_duration = 75 # 3s * 25fps\\n\\n# Add speed effect (1.5x slowdown)\\noriginal_duration = 75\\nnew_duration = math.ceil(original_duration * 1.5) # 113 frames (4.52s)\\nspeed_strip = seq_ed.sequences.new_effect(\\n name='SpeedControl',\\n type='SPEED',\\n channel=2,\\n frame_start=0,\\n frame_end=new_duration,\\n seq1=video_strip\\n)\\nspeed_strip.speed_control = 'MULTIPLY'\\nspeed_strip.speed_factor = 1/1.5\\n\\n# Add audio strip\\naudio_strip = seq_ed.sequences.new_sound(\\n name='Audio',\\n filepath=input_path,\\n frame_start=0,\\n channel=3\\n)\\naudio_strip.frame_final_duration = 75 # Keep original audio duration\\n\\n# Add subtitle text strip\\ntext_strip = seq_ed.sequences.new_effect(\\n name='Subtitle',\\n type='TEXT',\\n channel=4,\\n frame_start=0,\\n frame_end=new_duration\\n)\\ntext_strip.text = 'BIG BUNNY'\\ntext_strip.align_x = 'CENTER'\\ntext_strip.align_y = 'BOTTOM'\\ntext_strip.font_size = 48\\ntext_strip.use_box = True\\ntext_strip.box_color = (0, 0, 0, 0.6) # Semi-transparent black box\\n\\n# Set render frame range\\nscene.frame_start = 1\\nscene.frame_end = new_duration\\n\\n# Render animation\\nbpy.ops.render.render(animation=True)\"}"
},
"usage": {
"prompt_tokens": 812,
"completion_tokens": 6780,
"total_tokens": 7592
},
"latency_s": 129.381
}
]
}
@@ -0,0 +1,84 @@
import bpy
# Clear existing objects to start fresh
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# Configuration paths and parameters
INPUT_MOVIE = "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov"
OUTPUT_MP4 = "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4"
SOURCE_FPS = 25
TRIM_DURATION_SECONDS = 3.0
SLOW_FACTOR = 1.5
RENDER_RESOLUTION = (854, 480)
# Calculate frame values
trim_frames = int(TRIM_DURATION_SECONDS * SOURCE_FPS)
slowed_frames = int(trim_frames * SLOW_FACTOR)
scene = bpy.context.scene
# Create sequence editor
seq_ed = scene.sequence_editor_create()
# Add movie strip with trim
movie_strip = seq_ed.sequences.new_movie(
name="SourceVideo",
filepath=INPUT_MOVIE,
channel=1,
frame_start=1
)
movie_strip.frame_offset_start = 0 # Start at beginning of source
movie_strip.frame_final_duration = trim_frames # Trim to 3 seconds
# Locate and trim audio strip (auto-created with movie)
sound_strip = None
for strip in seq_ed.sequences:
if strip.type == 'SOUND' and strip.channel == 2 and strip.frame_start == 1:
sound_strip = strip
if sound_strip:
sound_strip.frame_final_duration = trim_frames # Keep audio at original speed
# Add speed effect to video (slow motion)
speed_strip = seq_ed.sequences.new_effect(
name="SlowMotion",
type='SPEED',
channel=3,
frame_start=1,
frame_end=1 + slowed_frames - 1,
target=movie_strip
)
speed_strip.speed_control = 'MULTIPLY'
speed_strip.speed_factor = 1 / SLOW_FACTOR # 1/1.5 speed factor
# Add subtitle text strip with background box
text_strip = seq_ed.sequences.new_text(
name="Subtitle",
text="BIG BUNNY",
channel=4,
frame_start=1,
frame_end=1 + slowed_frames - 1
)
text_strip.align_x = 'CENTER'
text_strip.align_y = 'BOTTOM'
text_strip.use_box = True
text_strip.box_color = (0.0, 0.0, 0.0, 0.6) # Black semi-transparent box
text_strip.font_size = 48 # Visible size for 854x480 resolution
# Configure render settings
scene.render.resolution_x = RENDER_RESOLUTION[0]
scene.render.resolution_y = RENDER_RESOLUTION[1]
scene.render.resolution_percentage = 100
scene.render.fps = SOURCE_FPS
scene.render.fps_base = 1.0
scene.render.image_settings.file_format = 'FFMPEG'
scene.render.ffmpeg.format = 'MPEG4'
scene.render.ffmpeg.codec = 'H264'
scene.render.ffmpeg.audio_codec = 'AAC'
scene.render.filepath = OUTPUT_MP4
# Set render frame range
scene.frame_start = 1
scene.frame_end = 1 + slowed_frames - 1
# Execute render
bpy.ops.render.render(animation=True)
@@ -0,0 +1,79 @@
import bpy
# Clear existing data
bpy.ops.wm.read_factory_settings(use_empty=True)
scene = bpy.context.scene
# Scene settings
scene.render.resolution_x = 854
scene.render.resolution_y = 480
scene.render.resolution_percentage = 100
scene.render.fps = 25
scene.render.fps_base = 1.0
# Create sequence editor
if not scene.sequence_editor:
scene.sequence_editor_create()
seq_ed = scene.sequence_editor
sequences = seq_ed.sequences
# File paths
input_movie = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov'
output_mp4 = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4'
# Add movie strip (3 seconds = 75 frames at 25fps)
mov_strip = sequences.new_movie(
name='SourceMovie',
filepath=input_movie,
frame_start=1,
channel=1
)
mov_strip.frame_offset_start = 0
mov_strip.frame_final_duration = 75 # 3s * 25fps
# Locate and trim sound strip
sound_strip = next((s for s in sequences if s.type == 'SOUND' and s.frame_start == mov_strip.frame_start), None)
if sound_strip:
sound_strip.frame_final_duration = 75 # Keep original audio duration
# Add speed effect (1.5x slowdown)
speed_strip = sequences.new_effect(
name='SlowMotion',
type='SPEED',
frame_start=1,
channel=2,
input_1=mov_strip
)
speed_strip.speed_control = 'MULTIPLY'
speed_strip.speed_factor = 1 / 1.5
# Calculate slowed duration (4.5s = 112.5 frames → 113 frames)
slowed_frames = int(4.5 * 25) + 1
scene.frame_start = 1
scene.frame_end = slowed_frames
# Add subtitle text strip
text_strip = sequences.new_effect(
name='Subtitle',
type='TEXT',
frame_start=1,
frame_end=scene.frame_end,
channel=3
)
text_strip.text = 'BIG BUNNY'
text_strip.align_x = 'CENTER'
text_strip.align_y = 'BOTTOM'
text_strip.use_box = True
text_strip.box_color = (0, 0, 0, 0.6)
text_strip.font_size = 48
# Render settings
scene.render.filepath = output_mp4
scene.render.image_settings.file_format = 'FFMPEG'
scene.render.ffmpeg.format = 'MPEG4'
scene.render.ffmpeg.codec = 'H264'
scene.render.ffmpeg.audio_codec = 'AAC'
scene.render.ffmpeg.constant_rate_factor = 'MEDIUM'
# Render animation
bpy.ops.render.render(animation=True)
@@ -0,0 +1,84 @@
import bpy
import os
# Clear default objects
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# Set up scene
scene = bpy.context.scene
scene.render.fps = 25
scene.render.fps_base = 1.0
scene.render.resolution_x = 854
scene.render.resolution_y = 480
scene.render.resolution_percentage = 100
# Configure output settings
scene.render.image_settings.file_format = 'FFMPEG'
scene.render.ffmpeg.format = 'MPEG4'
scene.render.ffmpeg.codec = 'H264'
scene.render.ffmpeg.audio_codec = 'AAC'
scene.render.ffmpeg.audio_bitrate = 192
output_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4'
scene.render.filepath = output_path
# Create sequence editor
scene.sequence_editor_create()
sequences = scene.sequence_editor.sequences
# Import source movie and sound
source_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov'
movie_strip = sequences.new_movie(name='SourceMovie', filepath=source_path, channel=1, frame_start=0)
sound_strip = None
for strip in sequences:
if strip.type == 'SOUND' and strip.name.startswith('SourceMovie'):
sound_strip = strip
break
if not sound_strip:
sound_strip = sequences.new_sound(name='SourceAudio', filepath=source_path, channel=2, frame_start=0)
# Trim to 3-second interval (75 frames at 25fps)
trim_frames = 75 # 3.0s * 25fps
movie_strip.frame_start = 0
movie_strip.frame_final_duration = trim_frames
sound_strip.frame_start = 0
sound_strip.frame_final_duration = trim_frames
# Apply speed effect (1.5x slowdown = 4.5s output)
speed_strip = sequences.new_effect(
name='SpeedControl',
type='SPEED',
channel=2,
frame_start=0,
frame_end=113, # 75 frames * 1.5 = 112.5 → 113 frames
seq1=movie_strip,
seq2=None
)
speed_strip.speed_control = 'MULTIPLY'
speed_strip.speed_factor = 1/1.5
# Set scene frame range
duration_frames = 113 # 4.5s * 25fps = 112.5 → 113 frames
scene.frame_start = 0
scene.frame_end = duration_frames
# Add subtitle with background box
text_strip = sequences.new_effect(
name='Subtitle',
type='TEXT',
channel=3,
frame_start=0,
frame_end=duration_frames,
seq1=None,
seq2=None
)
text_strip.text = 'BIG BUNNY'
text_strip.align_x = 'CENTER'
text_strip.align_y = 'BOTTOM'
text_strip.use_box = True
text_strip.box_color = (0.0, 0.0, 0.0, 0.6)
text_strip.font_size = 48
# Render animation
bpy.ops.render.render(animation=True)
@@ -0,0 +1,90 @@
import bpy
import os
# Clear existing data
bpy.ops.wm.read_factory_settings(use_empty=True)
# Get the current scene
scene = bpy.context.scene
# Set render resolution (854x480 for H.264 even width)
scene.render.resolution_x = 854
scene.render.resolution_y = 480
scene.render.resolution_percentage = 100
# Set frame rate (25 FPS)
scene.render.fps = 25
scene.render.fps_base = 1.0
# Output settings
output_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4'
scene.render.filepath = output_path
scene.render.image_settings.file_format = 'FFMPEG'
scene.render.ffmpeg.format = 'MPEG4'
scene.render.ffmpeg.codec = 'H.264'
scene.render.ffmpeg.audio_codec = 'AAC'
scene.render.ffmpeg.audio_mixrate = 44100
scene.render.ffmpeg.audio_bitrate = 192
scene.render.use_audio = True
# Create sequence editor
scene.sequence_editor_create()
seq_ed = scene.sequence_editor
# Source movie path
source_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov'
# Add video strip with trim (0.000-3.000s = 75 frames @25FPS)
video_strip = seq_ed.sequences.new_movie(
name='Video',
filepath=source_path,
channel=1,
frame_start=1
)
video_strip.frame_offset_start = 0 # Start at 0s of source
video_strip.frame_final_duration = 75 # Trim to 3s (75 frames)
# Add SPEED effect for slow motion (1.5x duration)
speed_effect = seq_ed.sequences.new_effect(
name='SpeedControl',
type='SPEED',
channel=2,
frame_start=1,
seq1=video_strip
)
speed_effect.speed_control = 'MULTIPLY'
speed_effect.speed_factor = 1/1.5 # Slow playback speed
# Extend video duration to 1.5x trimmed interval (4.5s = 112.5 frames → 113 frames)
video_strip.frame_final_duration = 113
# Configure audio strip (trim to original 3s duration)
sound_strip = None
for strip in seq_ed.sequences:
if strip.type == 'SOUND' and strip.name.startswith('Audio'):
sound_strip = strip
if sound_strip:
sound_strip.frame_offset_start = 0 # Start at 0s of source audio
sound_strip.frame_final_duration = 75 # Keep original 3s duration
# Add subtitle text strip with background box
text_strip = seq_ed.sequences.new_effect(
name='Subtitle',
type='TEXT',
channel=3,
frame_start=1,
frame_final_duration=113
)
text_strip.text = 'BIG BUNNY'
text_strip.align_x = 'CENTER'
text_strip.align_y = 'BOTTOM'
text_strip.use_box = True
text_strip.box_color = (0, 0, 0, 0.6) # Semi-transparent black box
text_strip.font_size = 48
# Set scene frame range to match slowed video duration
scene.frame_start = 1
scene.frame_end = 113
# Render the animation
bpy.ops.render.render(animation=True)
@@ -0,0 +1,85 @@
import bpy
# Clear existing data
bpy.ops.wm.read_factory_settings(use_empty=True)
# Get the scene
scene = bpy.context.scene
# Set render resolution and FPS
scene.render.resolution_x = 854
scene.render.resolution_y = 480
scene.render.resolution_percentage = 100
scene.render.fps = 25
scene.render.fps_base = 1.0
# Set output settings
output_path = "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4"
scene.render.filepath = output_path
scene.render.image_settings.file_format = 'FFMPEG'
scene.render.ffmpeg.format = 'MPEG4'
scene.render.ffmpeg.codec = 'H264'
scene.render.ffmpeg.audio_codec = 'AAC'
scene.render.ffmpeg.constant_rate_factor = 'MEDIUM'
# Create sequence editor
seq_ed = scene.sequence_editor_create()
# Import movie strip
movie_path = "/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov"
movie_strip = seq_ed.sequences.new_movie(
name="SourceMovie",
filepath=movie_path,
channel=1,
frame_start=0
)
# Trim movie to [0.000, 3.000] seconds (75 frames at 25 FPS)
movie_strip.frame_offset_start = 0
movie_strip.frame_final_duration = 75
# Add speed control effect
speed_strip = seq_ed.sequences.new_effect(
name="SpeedControl",
type='SPEED',
channel=2,
frame_start=0,
frame_end=movie_strip.frame_start + movie_strip.frame_final_duration,
seq1=movie_strip
)
speed_strip.speed_control = 'MULTIPLY'
speed_strip.speed_factor = 1 / 1.5 # Slow down by 1.5x
# Find sound strip and trim it
sound_strip = None
for strip in seq_ed.sequences:
if strip.type == 'SOUND' and strip.frame_start == movie_strip.frame_start:
sound_strip = strip
break
if sound_strip:
sound_strip.frame_offset_start = 0
sound_strip.frame_final_duration = 75 # Keep sound at normal duration
# Calculate render duration: 3s * 1.5 = 4.5s = 112.5 frames → 113 frames (0-112)
scene.frame_start = 0
scene.frame_end = 113 # 113 frames total
# Add subtitle text strip
text_strip = seq_ed.sequences.new_effect(
name="Subtitle",
type='TEXT',
channel=3,
frame_start=0,
frame_end=scene.frame_end
)
text_strip.text = "BIG BUNNY"
text_strip.align_x = 'CENTER'
text_strip.align_y = 'BOTTOM'
text_strip.font_size = 48
text_strip.color = (1, 1, 1, 1) # White text
text_strip.use_box = True
text_strip.box_color = (0, 0, 0, 0.6) # Dark semi-transparent box
# Render animation
scene.render.engine = 'BLENDER_EEVEE'
bpy.ops.render.render(animation=True)
@@ -0,0 +1,85 @@
import bpy
import math
# Clear existing objects
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# File paths
input_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/source.mov'
output_path = '/Users/boj/book/ai-agent-book/chapter5/video-edit/validation/runs/exp5-6-real-blender-20260730-052206/negative_control.mp4'
# Scene setup
scene = bpy.context.scene
# Render settings
scene.render.fps = 25
scene.render.fps_base = 1.0
scene.render.resolution_x = 854
scene.render.resolution_y = 480
scene.render.resolution_percentage = 100
# Output format settings
scene.render.image_settings.file_format = 'MPEG4'
scene.render.ffmpeg.format = 'MPEG4'
scene.render.ffmpeg.codec = 'H264'
scene.render.ffmpeg.audio_codec = 'AAC'
scene.render.filepath = output_path
# VSE setup
scene.sequence_editor_create()
seq_ed = scene.sequence_editor
# Add video strip
video_strip = seq_ed.sequences.new_movie(
name='Video',
filepath=input_path,
frame_start=0,
channel=1
)
video_strip.frame_final_duration = 75 # 3s * 25fps
# Add speed effect (1.5x slowdown)
original_duration = 75
new_duration = math.ceil(original_duration * 1.5) # 113 frames (4.52s)
speed_strip = seq_ed.sequences.new_effect(
name='SpeedControl',
type='SPEED',
channel=2,
frame_start=0,
frame_end=new_duration,
seq1=video_strip
)
speed_strip.speed_control = 'MULTIPLY'
speed_strip.speed_factor = 1/1.5
# Add audio strip
audio_strip = seq_ed.sequences.new_sound(
name='Audio',
filepath=input_path,
frame_start=0,
channel=3
)
audio_strip.frame_final_duration = 75 # Keep original audio duration
# Add subtitle text strip
text_strip = seq_ed.sequences.new_effect(
name='Subtitle',
type='TEXT',
channel=4,
frame_start=0,
frame_end=new_duration
)
text_strip.text = 'BIG BUNNY'
text_strip.align_x = 'CENTER'
text_strip.align_y = 'BOTTOM'
text_strip.font_size = 48
text_strip.use_box = True
text_strip.box_color = (0, 0, 0, 0.6) # Semi-transparent black box
# Set render frame range
scene.frame_start = 1
scene.frame_end = new_duration
# Render animation
bpy.ops.render.render(animation=True)
@@ -0,0 +1,42 @@
{
"url": "https://download.blender.org/peach/trailer/trailer_480p.mov",
"title": "Big Buck Bunny trailer (Blender Foundation Peach Open Movie Project)",
"license": "Creative Commons Attribution 3.0",
"license_url": "https://creativecommons.org/licenses/by/3.0/",
"sha256": "36801b74638c12be9aa587e93cd18edfc9bc51a1c089ab2a19ee42beed9f497d",
"probe": {
"programs": [],
"stream_groups": [],
"streams": [
{
"index": 0,
"codec_name": "h264",
"codec_type": "video",
"width": 853,
"height": 480,
"r_frame_rate": "25/1"
},
{
"index": 1,
"codec_name": "aac",
"codec_type": "audio",
"sample_rate": "48000",
"channels": 6,
"r_frame_rate": "0/0"
}
],
"format": {
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
"duration": "32.995000",
"size": "11061011"
}
},
"naturally_occurring_scenes": true,
"ground_truth": {
"start": 9.08,
"end": 11.2,
"target": "the single continuous shot showing the large white rabbit walking alone in a sunny green meadow, after the ONE BIG RABBIT title and before the THREE RODENTS title",
"method": "Human-labeled target shot bounded by ffmpeg scene-change frames; source inspection found transitions at 9.08 and 11.20 seconds.",
"ffmpeg_scene_threshold": 0.35
}
}