V4.7 Phase 2: Evidence Model Simplification (part 2)

This commit is contained in:
zoltan57
2026-08-18 15:31:33 -05:00
parent 7285a87dfb
commit 11097b9cfe
15 changed files with 312 additions and 138 deletions
+29 -15
View File
@@ -6,9 +6,12 @@ from uuid import uuid4
import pytest
from PIL import Image
from sqlmodel import col
from sqlmodel import select
from transcription.config import Settings
from transcription.db.models import Document
from transcription.db.models import ExecutionAttempt
from transcription.db.models import JobSourceStatus
from transcription.db.models import JobStatus
from transcription.providers.base import ProviderUsage
@@ -20,6 +23,15 @@ from transcription.services.store import create_job_for_document
from transcription.services.workflows import advance_job
async def _attempts_for_job(session, job) -> list[ExecutionAttempt]:
"""Load execution attempts for a job; V4.7 moved evidence off JobSource."""
job_source_ids = [job_source.id for job_source in job.job_sources]
result = await session.exec(
select(ExecutionAttempt).where(col(ExecutionAttempt.job_source_id).in_(job_source_ids))
)
return list(result.all())
def _jpeg_bytes(color: str = "white") -> bytes:
output = io.BytesIO()
Image.new("RGB", (2, 2), color=color).save(output, format="JPEG")
@@ -116,21 +128,24 @@ class TestPipelineSuccessFlow:
assert processed is True
assert job is not None
assert job.status == JobStatus.TRANSCRIBED
assert any(job_source.raw_transcription == "Pipeline transcript" for job_source in job.job_sources)
attempts = await _attempts_for_job(async_session, job)
assert any(attempt.raw_transcription == "Pipeline transcript" for attempt in attempts)
assert job.prompt_name == "transcribe_document.md"
assert job.user_prompt is not None
assert job.temperature == 0.2
assert job.top_p == 0.85
assert any(
job_source.ai_metadata == {"finish_reason": "stop", "usage": {"total_tokens": 42}}
for job_source in job.job_sources
attempt.normalized_metadata is not None
and attempt.normalized_metadata["finish_reason"] == "stop"
and attempt.normalized_metadata["usage"] == {"total_tokens": 42}
for attempt in attempts
)
assert any(
job_source.raw_api_response
attempt.sdk_response_snapshot
== {"id": "resp_123", "choices": [{"message": {"content": "Pipeline transcript"}}]}
for job_source in job.job_sources
for attempt in attempts
)
assert all(job_source.error_detail is None for job_source in job.job_sources)
assert all(attempt.error_detail is None for attempt in attempts)
@pytest.mark.asyncio
async def test_worker_transcribes_all_sources_for_multi_page_job(
@@ -191,7 +206,8 @@ class TestPipelineSuccessFlow:
assert job.status == JobStatus.TRANSCRIBED
assert len(job.job_sources) == 3
assert all(job_source.status == JobSourceStatus.TRANSCRIBED for job_source in job.job_sources)
assert all(job_source.raw_transcription for job_source in job.job_sources)
attempts = await _attempts_for_job(async_session, job)
assert all(attempt.raw_transcription for attempt in attempts)
assert all(
job_source.source is not None and job_source.source.raw_transcription for job_source in job.job_sources
)
@@ -261,7 +277,8 @@ class TestPipelineSuccessFlow:
assert len(job.job_sources) == 2
statuses = {job_source.status for job_source in job.job_sources}
assert statuses == {JobSourceStatus.TRANSCRIBED, JobSourceStatus.FAILED}
assert any(job_source.error_detail is not None for job_source in job.job_sources)
attempts = await _attempts_for_job(async_session, job)
assert any(attempt.error_detail is not None for attempt in attempts)
@pytest.mark.asyncio
async def test_worker_skips_already_transcribed_sources_on_resubmit(
@@ -293,9 +310,7 @@ class TestPipelineSuccessFlow:
page_two = next(js for js in job.job_sources if js.source is not None and js.source.page_number == 2)
page_one.status = JobSourceStatus.TRANSCRIBED
page_one.raw_transcription = "existing transcript"
page_two.status = JobSourceStatus.PENDING
page_two.raw_transcription = None
await services.sources.update_job_source(job_source=page_one, session=async_session)
await services.sources.update_job_source(job_source=page_two, session=async_session)
await services.jobs.update_job_state(job_id=job.id, status=JobStatus.QUEUED, session=async_session)
@@ -387,11 +402,10 @@ class TestPipelineFailureFlow:
assert processed is True
assert job is not None
assert job.status == JobStatus.FAILED
assert all(job_source.raw_transcription is None for job_source in job.job_sources)
assert any(job_source.error_detail is not None for job_source in job.job_sources)
error_detail = next(
job_source.error_detail for job_source in job.job_sources if job_source.error_detail is not None
)
attempts = await _attempts_for_job(async_session, job)
assert all(attempt.raw_transcription is None for attempt in attempts)
assert any(attempt.error_detail is not None for attempt in attempts)
error_detail = next(attempt.error_detail for attempt in attempts if attempt.error_detail is not None)
assert "pipeline provider failure" in error_detail
assert "[internal_unexpected_error]" in error_detail
assert "error_id=" in error_detail