初始化提交
This commit is contained in:
commit
887c1f449e
963 files changed
+166869
No files matched your search
@@ -0,0 +1,95 @@
|
||||
"""大周天内驱力抽取纯函数测试。"""
|
||||
|
||||
from app.modules.drive.extract import (
|
||||
CuriosityDraft,
|
||||
SubgoalDraft,
|
||||
parse_curiosities,
|
||||
)
|
||||
|
||||
|
||||
def test_parse_standard_with_subgoals() -> None:
|
||||
raw = (
|
||||
'[{"question":"用户为何频繁提到项目X","source":"memory_gap",'
|
||||
'"expected_value":0.7,"urgency":0.5,"risk_level":"L2",'
|
||||
'"related_entities":["项目X"],'
|
||||
'"subgoals":[{"title":"询问项目X目标","description":"主动询问用户",'
|
||||
'"expected_information_gain":0.6,"interruption_cost":0.3,"risk_level":"L2"}]}]'
|
||||
)
|
||||
drafts = parse_curiosities(raw)
|
||||
assert len(drafts) == 1
|
||||
c = drafts[0]
|
||||
assert c.question == "用户为何频繁提到项目X"
|
||||
assert c.source == "memory_gap"
|
||||
assert c.expected_value == 0.7
|
||||
assert c.risk_level == "L2"
|
||||
assert c.related_entities == ["项目X"]
|
||||
assert len(c.subgoals) == 1
|
||||
sg = c.subgoals[0]
|
||||
assert sg.title == "询问项目X目标"
|
||||
assert sg.expected_information_gain == 0.6
|
||||
assert sg.interruption_cost == 0.3
|
||||
|
||||
|
||||
def test_parse_markdown_block() -> None:
|
||||
raw = '```json\n[{"question":"q"}]\n```'
|
||||
drafts = parse_curiosities(raw)
|
||||
assert len(drafts) == 1
|
||||
assert drafts[0].question == "q"
|
||||
|
||||
|
||||
def test_parse_invalid_returns_empty() -> None:
|
||||
assert parse_curiosities("不是JSON") == []
|
||||
assert parse_curiosities("[]") == []
|
||||
|
||||
|
||||
def test_skip_missing_question() -> None:
|
||||
raw = '[{"source":"memory_gap"},{"question":"q"}]'
|
||||
drafts = parse_curiosities(raw)
|
||||
assert len(drafts) == 1
|
||||
assert drafts[0].question == "q"
|
||||
|
||||
|
||||
def test_defaults_use_safe_pessimistic_values() -> None:
|
||||
"""缺省取最严格默认:risk_level=L4、source=reflection。"""
|
||||
raw = '[{"question":"q"}]'
|
||||
c = parse_curiosities(raw)[0]
|
||||
assert c.source == "reflection"
|
||||
assert c.risk_level == "L4"
|
||||
assert c.expected_value == 0.5
|
||||
assert c.urgency == 0.5
|
||||
assert c.related_entities == []
|
||||
assert c.subgoals == []
|
||||
|
||||
|
||||
def test_clamp_values() -> None:
|
||||
raw = '[{"question":"q","expected_value":1.5,"urgency":-0.2}]'
|
||||
c = parse_curiosities(raw)[0]
|
||||
assert c.expected_value == 1.0
|
||||
assert c.urgency == 0.0
|
||||
|
||||
|
||||
def test_invalid_source_defaults() -> None:
|
||||
raw = '[{"question":"q","source":"unknown_source"}]'
|
||||
assert parse_curiosities(raw)[0].source == "reflection"
|
||||
|
||||
|
||||
def test_invalid_risk_level_defaults() -> None:
|
||||
raw = '[{"question":"q","risk_level":"L9"}]'
|
||||
assert parse_curiosities(raw)[0].risk_level == "L4"
|
||||
|
||||
|
||||
def test_subgoal_defaults_and_types() -> None:
|
||||
raw = '[{"question":"q","subgoals":[{"title":"t","description":"d"}]}]'
|
||||
c = parse_curiosities(raw)[0]
|
||||
assert isinstance(c, CuriosityDraft)
|
||||
sg = c.subgoals[0]
|
||||
assert isinstance(sg, SubgoalDraft)
|
||||
assert sg.risk_level == "L4" # 安全默认
|
||||
assert sg.expected_information_gain == 0.5
|
||||
assert sg.interruption_cost == 0.5
|
||||
|
||||
|
||||
def test_skip_subgoal_missing_title_or_description() -> None:
|
||||
raw = '[{"question":"q","subgoals":[{"title":"t"},{"description":"d"},{"title":"t","description":"d"}]}]'
|
||||
c = parse_curiosities(raw)[0]
|
||||
assert len(c.subgoals) == 1 # 只有完整的保留
|
||||
@@ -0,0 +1,47 @@
|
||||
"""大周天内驱力 prompt 构建纯函数测试。"""
|
||||
|
||||
from app.modules.big_cycle.prompts import EvaluationSnapshot
|
||||
from app.modules.drive.prompts import build_drive_extraction_messages
|
||||
|
||||
|
||||
def _snapshot() -> EvaluationSnapshot:
|
||||
return EvaluationSnapshot(
|
||||
character_id="character_x",
|
||||
memory_count=15,
|
||||
recent_memories=[("用户偏好简洁", "用户偏好简洁直接的回答")],
|
||||
personality_summary="身份:魂镜",
|
||||
world_entity_count=4,
|
||||
conclusion="近期对话偏技术,存在项目背景缺口",
|
||||
)
|
||||
|
||||
|
||||
def test_messages_return_system_user_pair() -> None:
|
||||
system, user = build_drive_extraction_messages(_snapshot())
|
||||
assert isinstance(system, str) and isinstance(user, str)
|
||||
assert system and user
|
||||
|
||||
|
||||
def test_system_describes_contract_fields() -> None:
|
||||
system, _ = build_drive_extraction_messages(_snapshot())
|
||||
for token in (
|
||||
"question",
|
||||
"source",
|
||||
"expected_value",
|
||||
"urgency",
|
||||
"risk_level",
|
||||
"subgoals",
|
||||
):
|
||||
assert token in system
|
||||
|
||||
|
||||
def test_system_lists_sources() -> None:
|
||||
system, _ = build_drive_extraction_messages(_snapshot())
|
||||
for src in ("world_uncertainty", "memory_gap", "reflection", "goal_tension"):
|
||||
assert src in system
|
||||
|
||||
|
||||
def test_user_includes_snapshot_signals() -> None:
|
||||
_, user = build_drive_extraction_messages(_snapshot())
|
||||
assert "用户偏好简洁" in user
|
||||
assert "身份:魂镜" in user
|
||||
assert "15" in user
|
||||
Reference in new issue
Block a user