test: add book two attribution fixture
This commit is contained in:
parent
4300d22cd9
commit
8ed1f122a3
@ -33,6 +33,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
|
|||||||
status/cancellation endpoints with queue state, timeout and failure handling; existing synchronous callers remain compatible.
|
status/cancellation endpoints with queue state, timeout and failure handling; existing synchronous callers remain compatible.
|
||||||
- **Optional Background Casting.** `/api/match-characters-voices` now accepts `background: true` and exposes bounded
|
- **Optional Background Casting.** `/api/match-characters-voices` now accepts `background: true` and exposes bounded
|
||||||
job status/cancellation endpoints while reusing the existing casting validation, retries, and idempotency behavior.
|
job status/cancellation endpoints while reusing the existing casting validation, retries, and idempotency behavior.
|
||||||
|
- **Attribution Fixture Coverage.** Added a neutral multi-speaker Book 2-style fixture regression to verify parser
|
||||||
|
normalization across named speakers and narration without requiring a live provider.
|
||||||
- **STT Cancellation Safety.** Queued transcription cancels before consuming the single STT slot, and timed-out
|
- **STT Cancellation Safety.** Queued transcription cancels before consuming the single STT slot, and timed-out
|
||||||
requests keep the device slot held until the underlying worker actually exits.
|
requests keep the device slot held until the underlying worker actually exits.
|
||||||
- **Credential Boundary Review.** Provider credentials are now documented as server-only; only the explicitly
|
- **Credential Boundary Review.** Provider credentials are now documented as server-only; only the explicitly
|
||||||
|
|||||||
5
TODO.md
5
TODO.md
@ -65,8 +65,9 @@ the first block before investing in architecture or polish.
|
|||||||
- [ ] **L — Add background jobs and bounded queues.** Image generation already has the full interactive job path,
|
- [ ] **L — Add background jobs and bounded queues.** Image generation already has the full interactive job path,
|
||||||
and transcription, voice design, and casting now have optional ID/status/cancel/timeout paths while preserving
|
and transcription, voice design, and casting now have optional ID/status/cancel/timeout paths while preserving
|
||||||
synchronous callers. Durable persistence and retry policy still need to be added.
|
synchronous callers. Durable persistence and retry policy still need to be added.
|
||||||
- [ ] **L — Run the Book 2 generalization regression.** Confirm speaker-attribution and
|
- [ ] **L — Run the Book 2 generalization regression.** Added a neutral multi-speaker fixture and parser regression;
|
||||||
confidence rules are not overfit to *Der Sturm*.
|
a real Book 2 auto-cast/attribution output still needs to be captured and reviewed to confirm rules are not overfit
|
||||||
|
to *Der Sturm*.
|
||||||
- [x] **L — Add character forms inside one character record.** `sheet.forms[]` stores bounded alternate appearances,
|
- [x] **L — Add character forms inside one character record.** `sheet.forms[]` stores bounded alternate appearances,
|
||||||
prompts, and per-form visual assets; the detail-page switcher preserves one character ID and voice, and selected
|
prompts, and per-form visual assets; the detail-page switcher preserves one character ID and voice, and selected
|
||||||
forms feed prompt generation and identity fingerprints.
|
forms feed prompt generation and identity fingerprints.
|
||||||
|
|||||||
5
tests/fixtures/book2_attribution.json
vendored
Normal file
5
tests/fixtures/book2_attribution.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"book": "book-2-neutral-fixture",
|
||||||
|
"known_characters": ["Captain Vale", "Mira", "The Ferryman"],
|
||||||
|
"raw": "{\"segments\":[{\"speaker\":\"Narrator\",\"type\":\"narration\",\"text\":\"At dawn the ferry reached the northern lock.\",\"emotion\":\"\"},{\"speaker\":\"Captain Vale\",\"type\":\"dialogue\",\"text\":\"Keep the lanterns covered.\",\"emotion\":\"cautious\"},{\"speaker\":\"The Ferryman\",\"type\":\"dialogue\",\"text\":\"Then we cross before the tide turns.\",\"emotion\":\"firm\"},{\"speaker\":\"Mira\",\"type\":\"dialogue\",\"text\":\"I can hear bells beyond the reeds.\",\"emotion\":\"alert\"}]}"
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import json
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
@ -51,6 +52,17 @@ class AttributionParserTests(unittest.TestCase):
|
|||||||
self.assertTrue(dialogue["text"].endswith("Land. Lieblich bisweilen, mild und voll der guten Menschen. ‹"))
|
self.assertTrue(dialogue["text"].endswith("Land. Lieblich bisweilen, mild und voll der guten Menschen. ‹"))
|
||||||
self.assertEqual(narration["text"], "Zitiert aus dem Buch.")
|
self.assertEqual(narration["text"], "Zitiert aus dem Buch.")
|
||||||
|
|
||||||
|
def test_book2_neutral_fixture_preserves_multiple_speakers(self):
|
||||||
|
fixture_path = os.path.join(os.path.dirname(__file__), "fixtures", "book2_attribution.json")
|
||||||
|
with open(fixture_path, encoding="utf-8") as handle:
|
||||||
|
fixture = json.load(handle)
|
||||||
|
result = _attribution_parse(fixture["raw"], " ".join(fixture["known_characters"]))
|
||||||
|
self.assertEqual(
|
||||||
|
[segment["speaker"] for segment in result["segments"]],
|
||||||
|
["Narrator", "Captain Vale", "The Ferryman", "Mira"],
|
||||||
|
)
|
||||||
|
self.assertTrue(all(segment["type"] == "dialogue" for segment in result["segments"][1:]))
|
||||||
|
|
||||||
def test_consistent_image_job_can_be_cancelled(self):
|
def test_consistent_image_job_can_be_cancelled(self):
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
from server import app
|
from server import app
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user