feat(agent,report): 会话持久化与画像注入、报告反馈与预约留资——PM/开发双Agent迭代1-3
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:
xsl
2026-09-11 21:50:58 +08:00
parent 00ef56b08b
commit 7bcbb8d40b
25 changed files with 1860 additions and 25 deletions
+57
View File
@@ -17,7 +17,11 @@ from fastapi.responses import FileResponse
from apps.api.deps import BudgetGuardDep, CurrentUserId, SessionDep, SettingsDep
from packages.report.export_service import ReportExportService
from packages.report.feedback_service import FeedbackService
from packages.report.schemas import (
FeedbackCreateRequest,
FeedbackItem,
FeedbackUpsertResponse,
ReportCreateRequest,
ReportExportRequest,
ReportExportResponse,
@@ -88,6 +92,59 @@ def report_export_service_dep(
ReportExportServiceDep = Annotated[ReportExportService, Depends(report_export_service_dep)]
def feedback_service_dep(session: SessionDep) -> FeedbackService:
return FeedbackService(session)
FeedbackServiceDep = Annotated[FeedbackService, Depends(feedback_service_dep)]
@router.post(
"/{report_id}/feedback",
summary="报告维度结论反馈(T-P3-21:同维度重复 = 覆盖更新,upsert 语义)",
)
async def upsert_report_feedback(
report_id: int,
payload: FeedbackCreateRequest,
user_id: CurrentUserId,
service: FeedbackServiceDep,
) -> dict[str, object]:
upsert = await service.upsert_feedback(
user_id=user_id,
report_id=report_id,
dimension_key=payload.dimension_key,
verdict=payload.verdict,
correction=payload.correction,
)
return ok(
FeedbackUpsertResponse(
dimension_key=upsert.feedback.dimension_key,
verdict=upsert.feedback.verdict,
updated=upsert.updated,
).model_dump()
)
@router.get("/{report_id}/feedback", summary="报告已提交的维度反馈列表(归属校验)")
async def list_report_feedback(
report_id: int,
user_id: CurrentUserId,
service: FeedbackServiceDep,
) -> dict[str, object]:
rows = await service.list_feedback(user_id=user_id, report_id=report_id)
return ok(
[
FeedbackItem(
dimension_key=row.dimension_key,
verdict=row.verdict,
correction=row.correction,
created_at=row.created_at,
).model_dump()
for row in rows
]
)
@router.post("", summary="生成第一份美学报告(终身一次,走 report_basic 配额)")
async def create_report(
payload: ReportCreateRequest,