feat(short): el ejemplo del prompt habla, y por eso los specs vuelven a hablar
Build & Deploy ResearchOwl / build-and-push (push) Successful in 10s
Build & Deploy ResearchOwl / build-and-push (push) Successful in 10s
La primera generación con narración viva narró 5 de 7 planos. La siguiente, ya con la sección de presupuestos de ancho en el prompt, narró 1 de 8. La causa no era la sección 3b sino la 5: el ejemplo trabajado — un spec completo de 8 planos presentado como "el que produjo un buen vídeo" — no llevaba ni una narración, porque es anterior a la voz. Contra esa señal de formato, una regla en prosa que además dice "no todos los planos necesitan una" pierde siempre. Ahora el ejemplo narra 6 de sus 8 y calla en los dos que dibujan una cita, donde la voz sólo competiría con palabras que ya están en pantalla. Sus duraciones suben para pagar lo que habla: un plano que se queda corto para su propia voz enseñaría a infradeclarar, y el render no corta la voz, alarga el plano. La ventana de silencio se recoloca porque seguía a document_quote por tiempo. El aviso de ancho ya no cita el hueco de 16 caracteres de quote_a: shortsmith envuelve esas citas en dos líneas y el presupuesto vivo es 31. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
129f436fd2
commit
cfe4a6d754
@@ -113,6 +113,38 @@ def test_prompt_includes_the_worked_example_in_full():
|
||||
assert "counter_close" in prompt
|
||||
|
||||
|
||||
def test_the_worked_example_narrates_most_of_its_shots():
|
||||
"""El ejemplo es la señal de formato más fuerte del prompt, más que cualquier
|
||||
regla en prosa. Sin narración en él, el modelo escribía specs mudos aunque la
|
||||
sección 3b le dijera lo contrario: en la primera generación tras añadir la voz
|
||||
narró 1 de 8 planos. Si alguien vuelve a dejar el ejemplo mudo, esto salta.
|
||||
"""
|
||||
example = json.loads(EXAMPLE.read_text())
|
||||
shots = example["shots"]
|
||||
spoken = [s for s in shots if s.get("narration")]
|
||||
|
||||
assert len(spoken) >= len(shots) * 0.6, "el ejemplo enseña a no narrar"
|
||||
|
||||
# Y el silencio del ejemplo es una decisión, no un olvido: calla justo donde
|
||||
# la plantilla ya dibuja una cita.
|
||||
silent = {s["template"] for s in shots if not s.get("narration")}
|
||||
assert silent == {"scale_bars", "document_quote"}
|
||||
|
||||
|
||||
def test_the_worked_example_declares_time_for_its_own_narration():
|
||||
"""Un plano que se queda corto para su propia voz enseña a infradeclarar: el
|
||||
render no corta la voz, alarga el plano, y el total se va del objetivo."""
|
||||
from src.generator.spec_contract import NARRATION_CHARS_PER_SECOND
|
||||
|
||||
example = json.loads(EXAMPLE.read_text())
|
||||
for i, shot in enumerate(example["shots"]):
|
||||
narration = shot.get("narration", "")
|
||||
if not narration:
|
||||
continue
|
||||
needs = len(narration) / NARRATION_CHARS_PER_SECOND
|
||||
assert shot["duration"] >= needs, f"shot {i} declara menos de lo que habla"
|
||||
|
||||
|
||||
def test_prompt_says_out_loud_that_there_is_no_article_yet():
|
||||
w, _ = writer("{}")
|
||||
assert "No article URL yet" in w.build_prompt("X", "m", None, "X.TEST")
|
||||
|
||||
Reference in New Issue
Block a user