feat(api+app): 对话阶段化、回忆录流水线与客户端会话体验
- DB: segments 用户输入文本(Alembic 0002) - Chat: 阶段检测/阶段提示/回复限制,编排与访谈/画像 prompts 调整 - Memoir: 忠实度检查 agent,叙事与分类等链路更新 - Core: agent 日志、Alembic 启动、LangChain/日志/配置等 - Story: time_hints;Memory 检索与相关测试 - Expo: 助手头像、会话页与消息拆分、实时会话与文案/i18n - Docs/scripts/tests: 迁移脚本、LLM JSON/记忆检索文档、新增单测
This commit is contained in:
87
api/tests/test_story_time_hints.py
Normal file
87
api/tests/test_story_time_hints.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""人生时间键与章节排序键(纯函数)。"""
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from app.agents.memoir.prompts import (
|
||||
NARRATIVE_MERGE_EXISTING_MAX_CHARS,
|
||||
clip_existing_story_body_for_merge,
|
||||
)
|
||||
from app.features.story.time_hints import (
|
||||
infer_story_time_start,
|
||||
life_sort_key_parts,
|
||||
parse_time_start_year,
|
||||
parse_year_from_title,
|
||||
)
|
||||
|
||||
|
||||
def test_parse_year_from_title() -> None:
|
||||
assert parse_year_from_title("1999年 · 小学往事") == 1999
|
||||
assert parse_year_from_title("2005 · 标题") == 2005
|
||||
assert parse_year_from_title("无年份标题") is None
|
||||
|
||||
|
||||
def test_parse_time_start_year() -> None:
|
||||
assert parse_time_start_year("1999") == 1999
|
||||
assert parse_time_start_year("1999-03") == 1999
|
||||
assert parse_time_start_year(None) is None
|
||||
|
||||
|
||||
def test_infer_story_time_start_prefers_existing() -> None:
|
||||
assert (
|
||||
infer_story_time_start(
|
||||
title="2010 · x",
|
||||
canonical_markdown="",
|
||||
existing_time_start="2001",
|
||||
)
|
||||
== "2001"
|
||||
)
|
||||
|
||||
|
||||
def test_infer_story_time_start_from_title() -> None:
|
||||
assert (
|
||||
infer_story_time_start(
|
||||
title="2008年 · 某件事",
|
||||
canonical_markdown="正文没有年份",
|
||||
existing_time_start=None,
|
||||
)
|
||||
== "2008"
|
||||
)
|
||||
|
||||
|
||||
def test_infer_story_time_start_from_body() -> None:
|
||||
assert (
|
||||
infer_story_time_start(
|
||||
title="无年标题",
|
||||
canonical_markdown="那是2012年的夏天。",
|
||||
existing_time_start=None,
|
||||
)
|
||||
== "2012"
|
||||
)
|
||||
|
||||
|
||||
def test_clip_existing_story_body_for_merge_truncates() -> None:
|
||||
short = "a" * 100
|
||||
assert clip_existing_story_body_for_merge(short) == short
|
||||
long = "b" * (NARRATIVE_MERGE_EXISTING_MAX_CHARS + 50)
|
||||
clipped = clip_existing_story_body_for_merge(long)
|
||||
assert "省略" in clipped
|
||||
# 头+尾+提示语可能略长于原串若干字节,但应远小于未截断的线性增长
|
||||
assert len(clipped) <= len(long) + 400
|
||||
|
||||
|
||||
def test_life_sort_key_parts_order() -> None:
|
||||
t0 = datetime(2020, 1, 1, tzinfo=timezone.utc)
|
||||
t1 = datetime(2021, 1, 1, tzinfo=timezone.utc)
|
||||
a = life_sort_key_parts(
|
||||
time_start="1999",
|
||||
title=None,
|
||||
created_at=t1,
|
||||
story_id="b",
|
||||
)
|
||||
b = life_sort_key_parts(
|
||||
time_start="2005",
|
||||
title=None,
|
||||
created_at=t0,
|
||||
story_id="a",
|
||||
)
|
||||
assert a < b
|
||||
Reference in New Issue
Block a user