feat(api): 叙事 prompt、职业上下文、读路径章节、WS 解耦与错误脱敏
- 回忆录:事实边界补充允许清单;传记文体示例与 JSON 叙事要求对齐 - default 职业提示 occupation_context;cadre/military 退休语境 - GET 章节读路径零写入,prepare_chapter_read_view + markdown_for_response - 文本归一抽到 core/text_normalize;移除弃用 reply 策略与 recompose_chapters_for_story - ConversationService:WS 连接/用户段落/结束对话;对外错误固定文案 - 测试:HTTP 脱敏契约、章节读视图、occupation 与 background_voice
This commit is contained in:
@@ -95,6 +95,8 @@ def chapter_cover_to_dict(
|
||||
if not chapter_eligible_for_cover_by_inline_body_image_count(ch):
|
||||
return None
|
||||
m = primary_chapter_memoir_image(ch)
|
||||
if m and is_image_permanently_unavailable(m):
|
||||
m = None
|
||||
if m:
|
||||
return memoir_image_to_dict(m)
|
||||
asset_url_map = asset_url_map or {}
|
||||
@@ -120,8 +122,10 @@ def chapter_cover_to_dict(
|
||||
return None
|
||||
|
||||
|
||||
def _chapter_markdown(ch: Chapter) -> str:
|
||||
"""正文真源:canonical_markdown。"""
|
||||
def _chapter_markdown(ch: Chapter, *, override: str | None = None) -> str:
|
||||
"""正文:优先读路径临时物化串,否则 canonical_markdown。"""
|
||||
if override is not None and str(override).strip():
|
||||
return str(override).strip()
|
||||
md = getattr(ch, "canonical_markdown", None)
|
||||
if md and str(md).strip():
|
||||
return str(md).strip()
|
||||
@@ -129,12 +133,15 @@ def _chapter_markdown(ch: Chapter) -> str:
|
||||
|
||||
|
||||
def chapter_to_list_dict(
|
||||
ch: Chapter, asset_url_map: dict[str, str] | None = None
|
||||
ch: Chapter,
|
||||
asset_url_map: dict[str, str] | None = None,
|
||||
*,
|
||||
markdown_for_response: str | None = None,
|
||||
) -> dict:
|
||||
"""列表视图:与详情字段对齐的最小子集。"""
|
||||
cover = chapter_cover_to_dict(ch, asset_url_map=asset_url_map)
|
||||
cover_normalized = first_normalized_image_for_api(cover)
|
||||
canonical_raw = _chapter_markdown(ch)
|
||||
canonical_raw = _chapter_markdown(ch, override=markdown_for_response)
|
||||
wcount = len(canonical_raw.strip()) if canonical_raw else 0
|
||||
return {
|
||||
"id": ch.id,
|
||||
@@ -153,7 +160,12 @@ def chapter_to_list_dict(
|
||||
}
|
||||
|
||||
|
||||
def chapter_to_dict(ch: Chapter, asset_url_map: dict[str, str] | None = None) -> dict:
|
||||
def chapter_to_dict(
|
||||
ch: Chapter,
|
||||
asset_url_map: dict[str, str] | None = None,
|
||||
*,
|
||||
markdown_for_response: str | None = None,
|
||||
) -> dict:
|
||||
"""详情视图:stories-first 契约。asset_url_map 用于解析 asset:// 与 cover_asset_id。"""
|
||||
asset_url_map = asset_url_map or {}
|
||||
resolve = lambda aid: asset_url_map.get(aid) # noqa: E731
|
||||
@@ -161,7 +173,7 @@ def chapter_to_dict(ch: Chapter, asset_url_map: dict[str, str] | None = None) ->
|
||||
cover = chapter_cover_to_dict(ch, asset_url_map=asset_url_map)
|
||||
cover_normalized = first_normalized_image_for_api(cover)
|
||||
# 正文真源:优先 canonical_markdown
|
||||
canonical_md = _chapter_markdown(ch)
|
||||
canonical_md = _chapter_markdown(ch, override=markdown_for_response)
|
||||
canonical_md = resolve_asset_refs_in_markdown(canonical_md, resolve)
|
||||
reading_segments = resolve_reading_segments_for_chapter_detail(
|
||||
ch, asset_url_map=asset_url_map
|
||||
|
||||
Reference in New Issue
Block a user