Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
32e632e
Render depth references as clay relief
KBRASK Oct 18, 2026
5c09dab
Unload idle ComfyUI models before a picture or the prompt model
KBRASK Oct 20, 2026
ae12141
Eight attention heads for the Windows small first pass up to 12 s
KBRASK Oct 21, 2026
0726702
Align the depth-only option with the sound option
KBRASK Oct 21, 2026
686691e
Keep the guide clip's sound on a guide-based result when requested
KBRASK Oct 22, 2026
b79aa97
Keep a finished video when the guide audio remux fails
KBRASK Oct 22, 2026
31813c1
Group the reference depth option with the sound option and put it first
KBRASK Oct 22, 2026
e7f0e96
Add Replace person to the Studio media section
KBRASK Oct 22, 2026
bf855bb
Polish Replace person Studio wording
KBRASK Oct 23, 2026
0a6ab73
Stub replace-person imports in the entry and reference test harnesses
KBRASK Oct 23, 2026
d216e98
Ship the agent skill with the install-skill command
KBRASK Oct 24, 2026
1f1b43a
Find the installer's own Git and restore long lists of files in batches
KBRASK Oct 24, 2026
d6fc6e6
Keep eight heads on the small first pass for requests without LoRA, a…
KBRASK Oct 25, 2026
280fef6
install-skill runs without loading the image libraries
KBRASK Oct 25, 2026
d282995
install-skill stages in a fresh folder beside the destination
KBRASK Oct 25, 2026
93b00be
Keep a foreign module's arguments out of the lock holder report
KBRASK Oct 25, 2026
84ca136
Confirm a recovered Windows video-memory budget at each pass boundary…
KBRASK Oct 21, 2026
81f6ffe
Restrict encoder source restoration to safe managed checkouts
KBRASK Oct 25, 2026
c622ae1
Keep converted decoder layers across requests in the resident process
KBRASK Oct 25, 2026
b300f1f
Word dependency folder errors plainly and tolerate an unlistable folder
KBRASK Oct 26, 2026
a467232
Let the built-in AI pick a white-model template instead of writing sc…
KBRASK Oct 26, 2026
397101c
Built-in AI picks a white-model scene from a typed sentence when no A…
KBRASK Oct 26, 2026
fd0d907
Keep pictures and prompt rewrites going when the ComfyUI unload fails
KBRASK Oct 26, 2026
8404403
Keep the decoder's converted streamed layers in RAM between clips whe…
KBRASK Oct 21, 2026
e4e7ed3
Default the media encoding base to the model root when --base is not …
KBRASK Oct 26, 2026
c7a98e6
Depth-only reference videos: convert with Depth Anything V2 Small, ca…
KBRASK Oct 17, 2026
9e42663
Continued parts may be five seconds, with fewer parts per video
KBRASK Oct 26, 2026
6febf08
White-model no-fit sentence names the next step, and attach is disabl…
KBRASK Oct 26, 2026
3194f11
Report a dependency folder too deep for Git as a long path
KBRASK Oct 26, 2026
1f96a89
Let only a missing encoder stop the pre-encoding check
KBRASK Oct 24, 2026
4682ec3
Editor: one wording for continued-part limits, and say the lengthened…
KBRASK Oct 26, 2026
b13c9d7
Judge pinned dependency checkouts by content and replace stale ones s…
KBRASK Oct 26, 2026
11a778b
install-skill keeps the installed skill folder readable by other users
KBRASK Oct 26, 2026
e6af26d
Support guide clips with character reference images
KBRASK Oct 22, 2026
23cc578
White-model request that fails to reach the built-in AI keeps the typ…
KBRASK Oct 26, 2026
b9e4601
White-model no-fit sentence keeps its last phrase together on narrow …
KBRASK Oct 26, 2026
5df0fea
Record which process holds the installation lock when generation cann…
KBRASK Oct 21, 2026
5ea9fdc
Normalise saved frames before comparing in reuse settings
KBRASK Oct 27, 2026
d6251e0
Skip the duration fill when the saved video has no duration
KBRASK Oct 27, 2026
1989604
Split long-video descriptions without replaying the story in every part
KBRASK Oct 27, 2026
dae8a95
Add prompt model download notice for multi-part videos
KBRASK Oct 27, 2026
116d2c3
Pause the prompt model download when a multi-part video starts
KBRASK Oct 27, 2026
ad573b4
Show the prompt model download as an outlined button on its own line
KBRASK Oct 27, 2026
9045b9a
Keep a running chain block's report id and mark a restarted run's rep…
KBRASK Oct 26, 2026
3e34ff3
Editor: say a description over the limit before sending, on a retry t…
KBRASK Oct 27, 2026
b21738c
Show each GPU check's failure reason when the check before an int8 mo…
KBRASK Oct 27, 2026
72a4657
Launcher: share the proxy hop secret with the ComfyUI it starts and t…
KBRASK Oct 26, 2026
c377f92
Agent MCP lists the common tools in full and reaches the large ones t…
KBRASK Oct 27, 2026
3e298d4
Register the entry module before loading it in the installation check
KBRASK Oct 27, 2026
d992a0d
Creation panel: reuse an earlier video's prompt and settings
KBRASK Oct 27, 2026
4b9d43f
Release notes for 0.4.24
KBRASK Oct 28, 2026
a2a6634
Release notes for 0.4.24: use a plain ellipsis in the English notes
KBRASK Oct 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ recursive-include web/fonts *.woff2
recursive-include web/tutorial *.webp *.mp4
recursive-include freevideo_engine/assets *.png *.ico
recursive-include freevideo_engine/launcher *.qml
recursive-include freevideo_engine/agent/skill *.txt
recursive-include freevideo_engine/launcher/licenses *.txt
recursive-include freevideo_engine/licenses *.txt
recursive-include constraints *.txt
Expand Down
1 change: 1 addition & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ FreeVideo code uses [Apache-2.0](LICENSE). Its dependencies and models retain th
| Component | License |
| --- | --- |
| [Three.js](https://threejs.org/) r160, © 2010–2023 three.js authors (bundled whitebox renderer) | [MIT](web/vendor/three/LICENSE) |
| [Depth Anything V2 Small](https://github.com/DepthAnything/Depth-Anything-V2/tree/a561b849ebae10a6f5ef49e26c83cbbcd36c71bf), © 2024 Depth Anything authors; DINOv2 © Meta Platforms, Inc. and affiliates. Small-only DPT/DINOv2 inference and preprocessing are adapted and bundled; Small weights are an optional download pinned at `03876f8651c73a60fe4c2c48294e09fcb6838fcf`. | [Apache-2.0 (code and Small weights)](freevideo_engine/licenses/Depth-Anything-V2-Apache-2.0.txt) |
| Qt, PySide6 and Shiboken6 | LGPL-3.0; [component notices](freevideo_engine/launcher/licenses/NOTICE.txt) |
| PyInstaller bootloader | GPL-2.0 with the bootloader exception |
| CPython / psutil | PSF / BSD-3-Clause |
Expand Down
6 changes: 5 additions & 1 deletion docs/zh-CN/使用说明.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
- 编号顺序是:先是上传的素材,再是从上到下连接的图片,最后是音频。参考视频的声音也占一个音频编号。
- 删除或关闭某张素材后,描述里指向它的标记会改成“[素材已移除]”,其余标记按新编号更新。

## 用一句话做白模

未连接外部 Agent 时,可开启聊天框中的白模按钮,用一句话描述镜头。有合适的现成场景时,会先生成白模供您确认。

## 做更长的视频

有三种做法,可以单独用,也可以搭配。
Expand All @@ -46,7 +50,7 @@

### 限制

- 两种做法一样,一条视频最多 8 段(第一段加 7 次接着生成);创作面板里时长最多填 60 秒。接续的每一段至少 10 秒,整条约 110 秒。剪辑视图里逐段生成同样适用。段数越多,衔接处越容易出现变化,适合切换镜头处,可直接切镜头,用对应的参考图开始新的一段。
- 两种做法一样,一条视频最多 8 段(第一段加 7 次接着生成),有短于 10 秒的段时最多 4 段;创作面板里时长最多填 60 秒。接续的每一段至少 5 秒,每段都是 10 秒以上时整条约 110 秒。剪辑视图里逐段生成同样适用。段数越多,衔接处越容易出现变化,适合切换镜头处,可直接切镜头,用对应的参考图开始新的一段。
- 接着生成使用轻量档,需要 NVIDIA 显卡或 Mac,也不能和“继续二采”同时使用。
- 单次生成的最长时长随画幅和显卡而不同,在创作面板的“可生成范围”中可查看各尺寸的最长时长和预计用时。
- 分段生成同样需要 NVIDIA 显卡或 Mac。
Expand Down
35 changes: 34 additions & 1 deletion freevideo_engine/agent/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
import sys

from .client import ApiError, Client
from . import schema, spec, errors
from . import errors


def read(path):
from . import schema
text = sys.stdin.read() if path == '-' else Path(path).read_text(encoding='utf-8')
value = json.loads(text)
schema.validate({'type': 'object'}, value)
Expand All @@ -40,13 +41,16 @@ def error(self, message):


def build_parser():
from . import schema
parser = Parser(prog='./freevideo agent', description='Drive FreeVideo through its agent API.')
parser.add_argument('--root', type=Path)
parser.add_argument('--url')
commands = parser.add_subparsers(dest='command', required=True)
commands.add_parser('status', help='Readiness, limits, LoRAs, VLM and queue')
commands.add_parser('guide', help='How to write H3 prompts')
commands.add_parser('schema', help='JSON Schemas of jobs')
command = commands.add_parser('install-skill', help='Copy the FreeVideo skill where Codex, Gemini CLI, Cursor and Claude Code read skills')
command.add_argument('--target', choices=('agents', 'claude'), action='append', help='Default: both')
command = commands.add_parser('capabilities', help='Read the studio capability cache')
schema.cli_arguments(command, schema.contracts()['GET', '/capabilities']['query'])
command = commands.add_parser('asset', help='Download a saved library video or thumbnail over HTTP')
Expand Down Expand Up @@ -159,10 +163,39 @@ def build_parser():
return parser


def install_skill(argv):
"""Run `install-skill` without the job schemas, whose import loads the image libraries (numpy, Pillow).

A deep installation folder on Windows cannot load those libraries by their full path, and copying
the skill needs none of them. None where the command line is anything else."""
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--root', type=Path)
parser.add_argument('--url')
parser.add_argument('command', nargs='?')
known, rest = parser.parse_known_args(argv)
if known.command != 'install-skill':
return None
parser = argparse.ArgumentParser(add_help=False, exit_on_error=False)
parser.add_argument('--target', choices=('agents', 'claude'), action='append')
try:
args, extra = parser.parse_known_args(rest)
except argparse.ArgumentError:
return None
if extra:
return None
from . import skill_install
print(json.dumps({'installed': skill_install.install(tuple(args.target or ('agents', 'claude')))}, indent=2))
return 0


def main(argv=None):
for stream in (sys.stdin, sys.stdout):
if hasattr(stream, 'reconfigure'):
stream.reconfigure(encoding='utf-8')
done = install_skill(sys.argv[1:] if argv is None else argv)
if done is not None:
return done
from . import schema, spec
parser = build_parser()
args = parser.parse_args(argv)
values = vars(args)
Expand Down
8 changes: 4 additions & 4 deletions freevideo_engine/agent/drama.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import time

from . import spec as specs
from ..chain_plan import MIN_PART_SECONDS
from ..chain_plan import CONTINUE_SECONDS

EXAMPLE = {
'title': '末班车', 'name': 'the-last-train', 'aspect': '9:16', 'quality': 'light',
Expand Down Expand Up @@ -451,9 +451,9 @@ def intent(play, shot):


def shot_seconds(play, shot):
"""A shot says its length; else the film does; else 6 s, and 10 s for a shot that continues the one before
(a part that continues another video is at least 10 s)."""
return shot.get('seconds', play.get('seconds', MIN_PART_SECONDS if shot.get('continue') else 6))
"""A shot says its length; else the film does; else 6 s, and CONTINUE_SECONDS for a shot that continues the
one before (a full continuing part, which keeps the video to the full number of parts)."""
return shot.get('seconds', play.get('seconds', CONTINUE_SECONDS if shot.get('continue') else 6))


def shot_job(play, shot, index, ref):
Expand Down
2 changes: 1 addition & 1 deletion freevideo_engine/agent/editor_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# Definition order only; evaluation starts at editor_actions like the page's
# import does. editor_model and editor_text_model import each other: the
# module still loading is reached only through a namespace import.
MODULES = ('editor_picture_fields', 'editor_transport_model', 'editor_audio_model', 'editor_speed_model',
MODULES = ('chain_rules', 'editor_picture_fields', 'editor_transport_model', 'editor_audio_model', 'editor_speed_model',
'editor_text_model', 'editor_model', 'editor_room', 'editor_actions', 'editor_generation', 'sampling_effort',
'chain_support', 'editor_store')
TIME_LIMIT = 5.0
Expand Down
3 changes: 3 additions & 0 deletions freevideo_engine/agent/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
'chain_missing': (409, True, 'The saved chain receipt is unavailable.', 'Restore the chain receipt and retry resume, or submit a new job.'),
'join_failed': (409, True, 'The generated blocks could not be joined; completed blocks are retained.', 'POST /freevideo/agent/v1/jobs/{id}/resume to retry joining the completed blocks.'),
'chain_too_long': (422, False, 'One continuous shot can have up to 8 parts. Make it shorter.', 'Submit a new job with a smaller seconds, or cut to a new shot with a new job without continue_from; continue_from counts the parts of the video it continues.'),
'chain_short_parts': (422, False, 'With a part shorter than 10 seconds, one continuous shot can have up to 4 parts. Make every part at least 10 seconds long, or use fewer parts.', 'Submit a new job whose continuing parts are at least 10 seconds, with fewer parts, or with first_frame_reference true; continue_from counts the parts of the video it continues.'),
'chain_rejected': (409, False, 'The continuous backend rejected this generation.', 'Read GET /freevideo/agent/v1/capabilities and submit a supported generation request.'),
'invalid_wait': (422, False, 'wait must be a finite nonnegative number of seconds.', 'Use wait=0 or wait=25; larger valid values are clamped to 25 seconds.'),
'invalid_resume': (422, False, 'resume accepts an empty object or an optional ref only.', 'Send {} or {"ref":"resume-1"}; submit a new job to change generation parameters.'),
Expand Down Expand Up @@ -302,6 +303,7 @@ def safe_details(value):
'invalid_dimensions': '图片尺寸超出了支持的范围',
'too_many_images': '参考图片数量超过了支持的范围',
'chain_too_long': '接续后的视频超过了支持的段数',
'chain_short_parts': '有短于 10 秒的段时,接续后的视频超过了支持的段数',
'chain_rejected': '生成服务无法使用这组参数',
'generation_failed': '生成没有完成',
'internal_error': '没有完成',
Expand Down Expand Up @@ -350,6 +352,7 @@ def safe_details(value):
'invalid_dimensions': 'The picture size is outside the supported range',
'too_many_images': 'There are more reference pictures than supported',
'chain_too_long': 'The continued video has more parts than supported',
'chain_short_parts': 'With a part shorter than 10 seconds, the continued video has more parts than supported',
'chain_rejected': 'The generation service cannot use these settings',
'generation_failed': 'Generation did not finish',
'internal_error': 'Did not finish',
Expand Down
17 changes: 10 additions & 7 deletions freevideo_engine/agent/guide.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
'timing': [
'Single-block frames are 24 fps on a 17n+5 grid (6 s -> 6.583 s, 10 s -> 10.125 s). '
'Under 30 s defaults to one generation when the device supports this size and quality; unknown limits use 15 s. '
'Otherwise it uses as few parts as possible, each at least 10 s; how many depends on how long this computer can generate in one run, and the parts continue and join automatically. '
'Otherwise it uses as few parts as possible, each continuing part 10 s or longer where the length allows and never under 5 s; how many depends on how long this computer can generate in one run, and the parts continue and join automatically. '
'Multiple blocks or continue_from need two-pass text generation: quality "light" or "medium" '
'or sampling.two_pass=true and no preview. Their only media is media.references with at most 3 pictures, '
'which every continuing part also sees (keeps the same people); first_frame_reference then gives way to them. '
Expand Down Expand Up @@ -250,9 +250,10 @@
'Cut by default. Wherever the film can change shot, make the new shot from the reference pictures it should '
'have (cast cards, scene pictures) instead of continuing the previous video. Continue a video only for a '
'long take that cannot be cut, an action that must stay unbroken, or sound that must stay unbroken, and '
'continuing again and again is not recommended. One video has at most 8 parts (the first and 7 '
'continuations), each continued part at least 10 seconds, about 110 seconds in all; filling that is not '
'recommended. Past it, cut to a new shot.',
'continuing again and again is not recommended. Each continued part is at least 5 seconds. One video has at '
'most 8 parts (the first and 7 continuations, about 110 seconds in all) when every continued part is at '
'least 10 seconds; with a continued part shorter than 10 seconds it has at most 4 parts, unless '
'first_frame_reference is true. Filling that is not recommended. Past it, cut to a new shot.',
'A question is not a request. When the user asks about progress or status ("is it working?", "what happened?") '
'answer it in one sentence from what you know or from the job and white-model status, and start nothing; never '
'use a question as a prompt. When a row carries "whitebox", the user was starting a white-model scene that is '
Expand Down Expand Up @@ -287,7 +288,8 @@
'先用 people(角色图和各自的位置)做出首帧,再用它生成视频。',
'默认切镜头。能切镜头的地方就切:新镜头直接用对应的参考图(人物卡、场景图)生成,不接上一段视频。'
'只有不能切镜的长镜头、必须连贯的动作、必须连贯的声音,才接着上一段生成,而且不建议一段接一段地连续接。'
'一条视频最多 8 段(第一段加 7 次接着生成),接着生成的每一段至少 10 秒,总长约 110 秒;不建议接满,超过就切镜头。',
'接着生成的每一段至少 5 秒。每段都不短于 10 秒时,一条视频最多 8 段(第一段加 7 次接着生成,总长约 110 秒);'
'有短于 10 秒的段时最多 4 段,first_frame_reference 为 true 时除外。不建议接满,超过就切镜头。',
'问话不是要求。用户问进度或状态(“在做吗”“怎么了”)时,用一句话照实回答,依据是你所知道的、任务和白模的状态,'
'什么都不要开始;不要把问句当提示词。某条 inbox 带有 whitebox 时,说明用户刚启动了白模场景,'
'它还在准备或已经失败:照实说是哪一种,再等用户回话。',
Expand Down Expand Up @@ -573,8 +575,9 @@ def connection_text(value):
'before uploading. Unknown fields are rejected and every batch is validated before it is recorded.',
'POST /plan gives the length supported for the current size and quality. Without continuation, only a '
'single block can run; unknown device limits use 15 s. Multiple blocks return continuation_unavailable.',
'One video has at most 8 parts (60 s in one request). continue_from counts the parts of the video it '
'continues; plan and submit refuse a longer one and name the longest seconds that still fits.',
'One video has at most 8 parts (60 s in one request), or 4 when a continued part is shorter than 10 s and '
'first_frame_reference is not true. continue_from counts the parts of the video it continues; plan and '
'submit refuse a longer one and name the longest seconds that still fits.',
'features in the status reply names what this installation offers; false means not usable now (for example '
'chain.auto while continuation is false), and a missing name means not offered here.',
]
Expand Down
Loading