feat(agent,report): 会话持久化与画像注入、报告反馈与预约留资——PM/开发双Agent迭代1-3
CI / lint / typecheck / import-linter / tests / secrets (push) Canceled after 0s
CI / lint / typecheck / import-linter / tests / secrets (push) Canceled after 0s
- agent: ag_conversation/ag_message 表(迁移0007),上下文组装注入最近报告画像摘要 (report.profile.latest_profile_summary 经 apps 层闭包注入,同层不互调),历史带最近 AGENT_HISTORY_TURNS=10 轮;POST/GET /agent/conversations 与消息历史接口 - agent 修复:ChatRequest.conversation_id 改 str(雪花ID超2^53,JS Number丢精度); _build_context 挪进 reserve commit 后同一 try,异常走 refund 兜底 - report: rp_feedback(维度反馈 upsert,认同率/修正率 SQL 可算,T-P3-21 最小版—— L1 记忆未建,不回写结论)+ rp_reservation(预约留资幂等,T-P3-22,预约率口径 行数/full_report.card_view 去重曝光,门槛≥8%),迁移0008 - 测试:全量 606 passed;ruff/mypy/lint-imports 全绿;E2E 真实 deepseek-v4-flash 验证 画像注入与历史携带
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
"""报告结论反馈的纯函数与 schema 校验(T-P3-21 最小可用版,不连库)。
|
||||
|
||||
覆盖:ok_dimension_keys 的可反馈维度集合口径(status=ok 才可选)、
|
||||
FeedbackCreateRequest 的 verdict 枚举与 correction 长度上限。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from packages.report.feedback_service import ok_dimension_keys
|
||||
from packages.report.schemas import FeedbackCreateRequest
|
||||
|
||||
|
||||
def _result(dimensions: list[dict[str, object]]) -> dict[str, object]:
|
||||
return {"diagnosis": {"dimensions": dimensions, "coverage": {"total": len(dimensions)}}}
|
||||
|
||||
|
||||
class TestOkDimensionKeys:
|
||||
def test_only_status_ok_dimensions_are_feedbackable(self) -> None:
|
||||
result = _result(
|
||||
[
|
||||
{"key": "body_shape", "status": "ok"},
|
||||
{"key": "color_season", "status": "skipped"},
|
||||
{"key": "style_type", "status": "ok"},
|
||||
]
|
||||
)
|
||||
assert ok_dimension_keys(result) == {"body_shape", "style_type"}
|
||||
|
||||
def test_empty_or_missing_diagnosis_yields_empty(self) -> None:
|
||||
assert ok_dimension_keys({}) == set()
|
||||
assert ok_dimension_keys({"diagnosis": {}}) == set()
|
||||
assert ok_dimension_keys({"diagnosis": {"dimensions": "not-a-list"}}) == set()
|
||||
|
||||
def test_malformed_items_are_ignored(self) -> None:
|
||||
result = _result(
|
||||
[
|
||||
"garbage",
|
||||
{"status": "ok"}, # 缺 key
|
||||
{"key": 123, "status": "ok"}, # key 非字符串
|
||||
{"key": "face_shape", "status": "ok"},
|
||||
]
|
||||
)
|
||||
assert ok_dimension_keys(result) == {"face_shape"}
|
||||
|
||||
|
||||
class TestFeedbackCreateRequest:
|
||||
def test_verdict_enum_rejects_unknown_value(self) -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
FeedbackCreateRequest.model_validate(
|
||||
{"dimension_key": "body_shape", "verdict": "kind-of"}
|
||||
)
|
||||
|
||||
def test_correction_max_200_chars(self) -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
FeedbackCreateRequest.model_validate(
|
||||
{
|
||||
"dimension_key": "body_shape",
|
||||
"verdict": "inaccurate",
|
||||
"correction": "长" * 201,
|
||||
}
|
||||
)
|
||||
|
||||
def test_minimal_valid_payload(self) -> None:
|
||||
req = FeedbackCreateRequest.model_validate(
|
||||
{"dimension_key": "body_shape", "verdict": "accurate"}
|
||||
)
|
||||
assert req.correction is None
|
||||
Reference in New Issue
Block a user