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
+55
View File
@@ -0,0 +1,55 @@
"""``POST /reservations``、``GET /reservations``(T-P3-22 预约留资)。
topic 预留通用性,首期只有 full_report(全面报告上线提醒)。
幂等口径:重复预约返回已有记录(created=false,HTTP 仍 200)。
"""
from __future__ import annotations
from typing import Annotated
from fastapi import APIRouter, Depends, Query
from apps.api.deps import CurrentUserId, SessionDep
from packages.report.reservation_service import ReservationService
from packages.report.schemas import (
ReservationCreateRequest,
ReservationListResponse,
ReservationResponse,
)
from packages.shared.response import ok
router = APIRouter(prefix="/reservations", tags=["reservations"])
def reservation_service_dep(session: SessionDep) -> ReservationService:
return ReservationService(session)
ReservationServiceDep = Annotated[ReservationService, Depends(reservation_service_dep)]
@router.post("", summary="预约留资(幂等:重复预约 created=false)")
async def create_reservation(
payload: ReservationCreateRequest,
user_id: CurrentUserId,
service: ReservationServiceDep,
) -> dict[str, object]:
result = await service.reserve(user_id=user_id, topic=payload.topic)
return ok(
ReservationResponse(
topic=result.reservation.topic,
created=result.created,
created_at=result.reservation.created_at,
).model_dump()
)
@router.get("", summary="我的预约主题列表(topic 可选,缺省返回全部)")
async def list_reservations(
user_id: CurrentUserId,
service: ReservationServiceDep,
topic: str | None = Query(default=None, max_length=32),
) -> dict[str, object]:
topics = await service.list_topics(user_id=user_id, topic=topic)
return ok(ReservationListResponse(topics=topics).model_dump())