Files
xsl 7bcbb8d40b
CI / lint / typecheck / import-linter / tests / secrets (push) Canceled after 0s
feat(agent,report): 会话持久化与画像注入、报告反馈与预约留资——PM/开发双Agent迭代1-3
- 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 验证
  画像注入与历史携带
2026-09-11 21:50:58 +08:00

44 lines
1.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""预约留资服务(T-P3-22)。
topic 预留通用性,首期只有 full_report(全面报告上线提醒)。
幂等口径:UniqueConstraint(user_id, topic)——重复预约返回已有记录
(created=false,HTTP 仍 200),绝不堆行。
指标口径:预约率 = rp_reservation(topic='full_report') 行数 ÷ 埋点
full_report.card_view 去重曝光数;决策门槛 ≥8%(产品方案 §2.2.3)。
"""
from __future__ import annotations
from dataclasses import dataclass
from sqlalchemy.ext.asyncio import AsyncSession
from packages.domain.ids import next_id
from packages.report import repo
from packages.shared.models import RpReservation
@dataclass(frozen=True, slots=True)
class ReservationResult:
reservation: RpReservation
created: bool # false=幂等命中已有记录
class ReservationService:
def __init__(self, session: AsyncSession) -> None:
self._session = session
async def reserve(self, *, user_id: int, topic: str) -> ReservationResult:
"""幂等预约:同 user+topic 已存在即返回原记录。"""
existing = await repo.get_reservation(self._session, user_id=user_id, topic=topic)
if existing is not None:
return ReservationResult(reservation=existing, created=False)
row = RpReservation(reservation_id=next_id(), user_id=user_id, topic=topic)
self._session.add(row)
await self._session.flush()
return ReservationResult(reservation=row, created=True)
async def list_topics(self, *, user_id: int, topic: str | None = None) -> list[str]:
return await repo.list_reservation_topics(self._session, user_id=user_id, topic=topic)