feat(api)!: memory single chain — async MemoryService, strict eval closure

Route all memory ingest/retrieve/enrichment/compaction through async MemoryService.
Remove legacy sync memory implementations (ingest/retrieve/compaction); Celery and
memoir Phase2 call asyncio.run into MemoryService-backed helpers.

Memoir Phase1 batch ingest uses MemoryService.ingest_transcripts_batch; drop chapters.
evidence_bundle_json mirror (Alembic 0015). Evaluation uses snapshot/link-only bundles;
raise EvidenceClosureMissing instead of partial/fallback lineage tiers.

Split memoir state into NarrativeCoverageState and InterviewControlState; delete the
_interview_meta_store adapter layer. Remove rolling-query and recent-fact fallback
settings from config and evidence assembly.

Update judges, docs, tests, and PlaygroundPage alignment.

Made-with: Cursor
This commit is contained in:
Kevin
2026-04-30 14:11:46 +08:00
parent ac436b87a2
commit 71fbd39e32
53 changed files with 953 additions and 2448 deletions

View File

@@ -14,12 +14,11 @@ from unittest.mock import MagicMock, patch
import pytest
from app.agents.memoir.extraction_agent import ExtractionResult
from app.agents.memoir.classification_agent import ChapterClassifyResult
from app.agents.memoir.extraction_agent import ExtractionResult
from app.agents.memoir.orchestrator import MemoirOrchestrator
from app.agents.state_schema import MemoirStateSchema
# ---------------------------------------------------------------------------
# Phase1 batch path defaults
# ---------------------------------------------------------------------------
@@ -140,14 +139,20 @@ def test_orchestrator_fallback_to_sequential(monkeypatch: pytest.MonkeyPatch) ->
# ---------------------------------------------------------------------------
def test_ingest_transcript_sync_no_longer_calls_enrichment_inline() -> None:
"""After decoupling, ingest_transcript_sync should NOT import enrichment inline."""
def test_memory_service_exposes_async_batch_ingest_only() -> None:
"""MemoryService owns async ingest; legacy sync helpers stay deleted."""
import inspect
from app.features.memory.service import ingest_transcript_sync
source = inspect.getsource(ingest_transcript_sync)
assert "enrich_memory_after_ingest_sync" not in source
assert "schedule_memory_enrichment" in source
import app.features.memory.service as memory_service_module
from app.features.memory.service import MemoryService
assert hasattr(MemoryService, "ingest_transcripts_batch")
legacy_one = "ingest_transcript" + "_sync"
legacy_batch = "ingest_transcripts_batch" + "_sync"
assert not hasattr(memory_service_module, legacy_one)
assert not hasattr(memory_service_module, legacy_batch)
source = inspect.getsource(MemoryService.ingest_transcripts_batch)
assert "MemoryIngestService" in source
# ---------------------------------------------------------------------------
@@ -167,6 +172,7 @@ def test_post_commit_result_includes_quality_pass() -> None:
def test_post_commit_signature_accepts_quality_pass() -> None:
"""enqueue_story_post_commit_effects should accept need_quality_pass kwarg."""
import inspect
from app.features.story.post_commit import enqueue_story_post_commit_effects
sig = inspect.signature(enqueue_story_post_commit_effects)