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 验证 画像注入与历史携带
125 lines
3.0 KiB
Python
Executable File
125 lines
3.0 KiB
Python
Executable File
"""Request/response schemas.
|
||
|
||
NFR-MAINT-01 契约先行: schema 先定义,客户端类型由 OpenAPI 生成。
|
||
Wire responses are wrapped by the unified envelope (架构文档 §9.2); these models
|
||
describe the ``data`` payload only.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from datetime import datetime
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
class DevTokenRequest(BaseModel):
|
||
device_key: str = Field(
|
||
default="local-dev",
|
||
min_length=1,
|
||
max_length=64,
|
||
description="任意稳定字符串;同一 device_key 复用同一测试用户",
|
||
)
|
||
|
||
|
||
class DevTokenResponse(BaseModel):
|
||
access_token: str
|
||
token_type: str = "Bearer"
|
||
expires_in: int
|
||
user_id: str = Field(description="雪花 ID 以字符串返回,避免 JS 精度丢失")
|
||
|
||
|
||
class ChatRequest(BaseModel):
|
||
message: str = Field(min_length=1, max_length=2000)
|
||
conversation_id: str | None = Field(
|
||
default=None,
|
||
max_length=32,
|
||
description="会话 ID(字符串;雪花 ID 超 2^53,JS Number 会丢精度)。"
|
||
"缺省时新建会话并在响应中返回 (FR-AGT-09)",
|
||
)
|
||
request_key: str | None = Field(
|
||
default=None,
|
||
max_length=128,
|
||
description="幂等键;相同键不会重复扣配额 (架构文档 §9.1)",
|
||
)
|
||
|
||
|
||
class ConversationResponse(BaseModel):
|
||
conversation_id: str = Field(description="雪花 ID 以字符串返回,避免 JS 精度丢失")
|
||
title: str
|
||
message_count: int
|
||
last_message_at: datetime | None
|
||
created_at: datetime
|
||
|
||
|
||
class ChatMessageItem(BaseModel):
|
||
message_id: str
|
||
role: str
|
||
content: str
|
||
model: str | None
|
||
call_id: str | None = Field(
|
||
description="assistant 消息关联的 ob_ai_call 行(复盘锚点);user 消息为 null"
|
||
)
|
||
created_at: datetime
|
||
|
||
|
||
class ChatUsage(BaseModel):
|
||
tokens_in: int
|
||
tokens_out: int
|
||
tokens_cached: int
|
||
latency_ms: int
|
||
cost_cents: str
|
||
|
||
|
||
class ChatResponse(BaseModel):
|
||
conversation_id: str
|
||
reply: str
|
||
provider: str
|
||
model: str
|
||
prompt_id: str | None
|
||
prompt_version: str | None
|
||
call_id: str
|
||
usage: ChatUsage
|
||
quota_remaining: int
|
||
|
||
|
||
class QuotaResponse(BaseModel):
|
||
quota_key: str
|
||
period_key: str
|
||
used: int
|
||
limit_value: int
|
||
bonus_granted: int
|
||
remaining: int
|
||
reset_at: datetime | None
|
||
|
||
|
||
class LedgerEntry(BaseModel):
|
||
tx_id: str
|
||
delta: int
|
||
tx_type: str
|
||
status: str
|
||
reason: str | None
|
||
quota_key: str | None
|
||
period_key: str | None
|
||
balance_after: int
|
||
created_at: datetime
|
||
|
||
|
||
class TaskSubmitRequest(BaseModel):
|
||
echo: str = Field(default="ping", max_length=200)
|
||
idempotency_key: str | None = Field(default=None, max_length=128)
|
||
|
||
|
||
class TaskResponse(BaseModel):
|
||
task_id: str
|
||
task_type: str
|
||
status: str
|
||
progress: int
|
||
stage_text: str | None
|
||
result: dict[str, object] | None
|
||
error_code: int | None
|
||
error_message: str | None
|
||
retry_count: int
|
||
submitted_at: datetime
|
||
started_at: datetime | None
|
||
finished_at: datetime | None
|