fix: preserve live image job results

This commit is contained in:
mARTin-B78 2026-09-04 09:52:40 +02:00
parent 90e74149d9
commit 9b15dae205
4 changed files with 20 additions and 2 deletions

View File

@ -8,6 +8,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
## [Unreleased] ## [Unreleased]
### Added ### Added
- **Live Image Result Preservation.** Durable image artifact persistence now leaves the active in-memory pair
available to the current browser poll while storing only bounded download metadata for restart-safe history.
- **Resource Diagnostics.** Performance now exposes read-only server RSS, configured/temp disk usage, persisted-job - **Resource Diagnostics.** Performance now exposes read-only server RSS, configured/temp disk usage, persisted-job
count, DOM/audio counts, and browser heap when available; host Docker metrics remain explicitly outside the panel's scope. count, DOM/audio counts, and browser heap when available; host Docker metrics remain explicitly outside the panel's scope.
- **Throttled Desktop Smoke Coverage.** Chromium CDP now exercises app navigation at 4× CPU throttling and - **Throttled Desktop Smoke Coverage.** Chromium CDP now exercises app navigation at 4× CPU throttling and

View File

@ -1 +1 @@
1.24.6 1.24.7

View File

@ -205,7 +205,9 @@ def _persist_consistent_image_artifacts(job_id: str, result: dict) -> dict:
try: try:
payload = base64.b64decode(encoded, validate=True) payload = base64.b64decode(encoded, validate=True)
artifacts.append({"kind": key, **background_job_store_artifact(job_id, filename, payload, media_type)}) artifacts.append({"kind": key, **background_job_store_artifact(job_id, filename, payload, media_type)})
persisted.pop(key, None) # Keep the data URI in the short-lived in-memory job so the active
# browser can finish its current poll. background_job_update()
# applies its own field-level sanitizer before SQLite storage.
except Exception as exc: except Exception as exc:
persisted.pop(key, None) persisted.pop(key, None)
persisted.setdefault("artifact_error", "One or more generated images could not be persisted") persisted.setdefault("artifact_error", "One or more generated images could not be persisted")

View File

@ -4,6 +4,7 @@ from __future__ import annotations
import os import os
import json import json
import tempfile import tempfile
import shutil
import unittest import unittest
os.environ.setdefault("CONFIG_DIR", tempfile.mkdtemp(prefix="ttvc-conversation-test-config-")) os.environ.setdefault("CONFIG_DIR", tempfile.mkdtemp(prefix="ttvc-conversation-test-config-"))
@ -23,10 +24,23 @@ from routes.conversation import (
match_characters_voices, match_characters_voices,
_request_timeout_seconds, _request_timeout_seconds,
_response_error_text, _response_error_text,
_persist_consistent_image_artifacts,
) )
class AttributionParserTests(unittest.TestCase): class AttributionParserTests(unittest.TestCase):
def test_consistent_image_persistence_keeps_live_payload_and_adds_artifact_refs(self):
from core.database import _BACKGROUND_ARTIFACT_DIR
job_id = "live-image-artifact-test"
data_uri = "data:image/png;base64," + "AA=="
try:
result = _persist_consistent_image_artifacts(job_id, {"profile": data_uri, "reference": data_uri})
self.assertEqual(result["profile"], data_uri)
self.assertEqual(result["reference"], data_uri)
self.assertEqual([item["kind"] for item in result["artifacts"]], ["profile", "reference"])
finally:
shutil.rmtree(_BACKGROUND_ARTIFACT_DIR / job_id, ignore_errors=True)
def test_active_character_form_overlays_visual_identity_without_changing_record(self): def test_active_character_form_overlays_visual_identity_without_changing_record(self):
sheet = { sheet = {
"physical": "base form", "physical": "base form",