refactor(video): accept video and audio references in the shared core

The core took reference images only, so no api caller could send the video and
audio references the ref2va workflow conditions on, and the marshalling that
handles them existed solely in the MiniMax tab.

validate_references now gates on the workflow and hands the entries to the
architecture that owns them, which accepts decoded images and local file paths
in any mix and preserves their order, since order fixes the labels a prompt
addresses. reference_caps exposes the same limits the validation enforces, so a
client reads them instead of mirroring the numbers.

- MAX_IMAGE_REFERENCES is gone: the limits now cover all three kinds and a total
- the run body no longer builds reference objects or knows their class
- an image is converted where it is built rather than at the call site, so a
  reference decoded from a file and one posted as base64 arrive the same way
- pipeline args summarize a reference list by kind, since a decoded video would
  otherwise print its frames into the per-generation log line
- the video endpoint documents what it actually accepts: images alone, because
  video and audio decode from files rather than from the wire, and an upload
  reference only where an extension provides the store that resolves one
This commit is contained in:
CalamitousFelicitousness
2026-08-16 07:34:35 +01:00
parent 9892a3f05f
commit 005fc5c86e
4 changed files with 79 additions and 26 deletions
+52
View File
@@ -556,6 +556,47 @@ def test_short_video_is_rejected_after_the_decode():
return expect_error(lambda: refs.resolve('ref2va', [image(), fn]), 'video too short')
# ============================================================
# Core seam
# ============================================================
def test_core_serves_the_caps():
from modules.video_models import video_run
assert video_run.reference_caps('ref2va') is caps(), 'the core served different caps than the resolver'
assert video_run.reference_caps('fl2va') is None, 'fl2va reported reference limits'
assert video_run.reference_caps(None) is None, 'a missing workflow reported reference limits'
def test_core_gate_and_caps_table_agree():
from modules.video_models import video_run
assert set(video_run.REFERENCE_WORKFLOWS) == set(refs.REFERENCE_CAPS), f'{video_run.REFERENCE_WORKFLOWS} vs {sorted(refs.REFERENCE_CAPS)}'
def test_core_gate_names_workflows_the_registry_carries():
from modules.video_models import models_def, video_run
known = {row.workflow for rows in models_def.models.values() for row in rows if getattr(row, 'workflow', None)}
assert set(video_run.REFERENCE_WORKFLOWS) <= known, f'{video_run.REFERENCE_WORKFLOWS} not among {sorted(known)}'
def test_core_rejects_references_on_a_keyframe_model():
from modules.video_models import models_def, video_run
row = models_def.Model(name='test keyframe', workflow='fl2va')
expect_error(lambda: video_run.validate_references(row, [image()], None), 'requires a reference workflow')
assert video_run.validate_references(row, None, None) is None, 'a keyframe model resolved references'
assert video_run.validate_references(row, [], image()) is None, 'a keyframe model claimed its init image'
def test_core_resolves_a_reference_model():
from modules.video_models import models_def, video_run
row = models_def.Model(name='test reference', workflow='ref2va')
expect_error(lambda: video_run.validate_references(row, None, None), 'No reference media provided')
if not has_diffusers():
return 'diffusers not installed'
built = video_run.validate_references(row, None, image()) # the init image stands in for a single reference
assert len(built) == 1 and built[0].kind == 'image', f'{built}'
return True
# ============================================================
# Runner
# ============================================================
@@ -655,6 +696,17 @@ def run_all():
]:
run_test(cat, fn)
log.warning('=== core seam ===')
cat = category('core')
for fn in [
test_core_serves_the_caps,
test_core_gate_and_caps_table_agree,
test_core_gate_names_workflows_the_registry_carries,
test_core_rejects_references_on_a_keyframe_model,
test_core_resolves_a_reference_model,
]:
run_test(cat, fn)
log.warning('=== Results ===')
total_passed = 0
total_failed = 0