回忆录 Story 流水线(同步) - 同步路径仅写入 Story 与章节关联,改为 mark_chapter_dirty_sync,不再内联 compose - 物化由 Celery recompose_chapter 异步完成;compose 不变量与异常时保留 dirty 的语义在 repo 中补充说明 - Evidence:大批次时降低 top_k;路由候选 story 携带 char_count/version_count;append 超长/版本过多时强制新开 story - 叙事 prompt:relevant_chunks 去重,减少重复证据噪声 - 叙事回退与忠实度 gate:返回 fallback 类型并记录结构化日志(含耗时、JSON 有效性等) Post-commit 与任务编排 - 新增 post_commit.enqueue_story_post_commit_effects:统一派发 generate_story_image(Redis 去重)、延迟 recompose_chapter、可选 memory compaction - memoir_tasks / story_service / story_image_tasks 改为调用 post-commit 入口;主图回填后按关联章节重算并调度物化与 compacs(锁委托、Redis 单例、ASR to_thread) - 更新 test_narrative_pipeline 以适配 _apply_narrative_fallbacks 返回值
66 lines
2.4 KiB
Python
66 lines
2.4 KiB
Python
"""叙事分区、口述过短回退、配图字数门闸(纯函数/无 DB)。"""
|
||
|
||
import pytest
|
||
|
||
from app.agents.memoir.prompts import format_narrative_user_content
|
||
from app.features.memoir import story_pipeline_sync as sps
|
||
|
||
|
||
def test_format_narrative_user_content_oral_only() -> None:
|
||
assert format_narrative_user_content("hello", "") == "【本段用户口述】\nhello"
|
||
|
||
|
||
def test_format_narrative_user_content_with_evidence() -> None:
|
||
out = format_narrative_user_content("口述A", "摘录B")
|
||
assert "【本段用户口述】" in out
|
||
assert "口述A" in out
|
||
assert "摘录B" in out
|
||
assert "非本段口述" in out
|
||
|
||
|
||
def test_should_fallback_to_transcript_short_md(
|
||
monkeypatch: pytest.MonkeyPatch,
|
||
) -> None:
|
||
monkeypatch.setattr(sps.settings, "memoir_narrative_fallback_body_ratio", 0.5)
|
||
monkeypatch.setattr(sps.settings, "memoir_narrative_fallback_min_chars", 20)
|
||
oral = "我一九九九年出生在上海,后来全家搬到苏州生活了好几年。"
|
||
assert sps._should_fallback_to_transcript("1999", oral) is True
|
||
assert sps._should_fallback_to_transcript(oral, oral) is False
|
||
|
||
|
||
def test_apply_narrative_fallbacks_merge_shrink_appends_oral() -> None:
|
||
"""整篇合并 JSON 输出过短:保留旧文并拼本段口述。"""
|
||
long_existing = "x" * 500
|
||
raw = '{"paragraphs": [{"content": "短"}]}'
|
||
out, _ft = sps._apply_narrative_fallbacks(
|
||
raw,
|
||
"新口述补充",
|
||
long_existing,
|
||
chapter_category="childhood",
|
||
)
|
||
assert long_existing in out
|
||
assert "新口述补充" in out
|
||
|
||
|
||
def test_apply_narrative_fallbacks_json_too_short_returns_oral(
|
||
monkeypatch: pytest.MonkeyPatch,
|
||
) -> None:
|
||
monkeypatch.setattr(sps.settings, "memoir_narrative_fallback_body_ratio", 0.5)
|
||
monkeypatch.setattr(sps.settings, "memoir_narrative_fallback_min_chars", 20)
|
||
oral = "我1999年出生在上海,小学时爷爷常带我去河边散步。"
|
||
raw = '{"paragraphs": [{"content": "1999"}]}'
|
||
out, _ft = sps._apply_narrative_fallbacks(
|
||
raw,
|
||
oral,
|
||
"",
|
||
chapter_category="childhood",
|
||
)
|
||
assert out.strip() == oral
|
||
|
||
|
||
def test_memoir_image_settings_min_body_field() -> None:
|
||
from app.features.memoir.memoir_images.settings import MemoirImageSettings
|
||
|
||
cfg = MemoirImageSettings(story_image_min_body_chars=799)
|
||
assert cfg.story_image_min_body_chars == 799
|