# -*- coding: utf-8 -*- """ 管理端 — AI 监控后台 Pydantic Schema。 覆盖:Dashboard 总览、调度任务、调用记录、缓存失效、Token 预算、批量执行、告警管理。 需求: A1.1, A2.1, A4.1, A5.1, A6.1, A7.1, A8.1 """ from __future__ import annotations from pydantic import BaseModel # ── Dashboard ───────────────────────────────────────────── class DailyTrend(BaseModel): """近 7 天按日聚合趋势项。""" date: str # YYYY-MM-DD calls: int success_rate: float class AppDistItem(BaseModel): """各 App 调用占比分布项。""" app_type: str count: int percentage: float class BudgetInfo(BaseModel): """日/月 Token 预算进度。""" daily_used: int daily_limit: int daily_pct: float monthly_used: int monthly_limit: int monthly_pct: float class AlertItem(BaseModel): """告警事件项(失败/超时/熔断)。""" id: int app_type: str status: str # failed / timeout / circuit_open alert_status: str | None # pending / acknowledged / ignored error_message: str | None created_at: str class AppHealthItem(BaseModel): """各 App 最近一次调用状态。""" app_type: str last_status: str | None last_call_at: str | None class DashboardResponse(BaseModel): """Dashboard 总览统计响应。""" today_calls: int today_success_rate: float # 0.0 ~ 1.0 today_tokens: int today_avg_latency_ms: float trend_7d: list[DailyTrend] app_distribution: list[AppDistItem] budget: BudgetInfo recent_alerts: list[AlertItem] app_health: list[AppHealthItem] # ── 调度任务 ────────────────────────────────────────────── class TriggerJobItem(BaseModel): """调度任务列表项。""" id: int event_type: str member_id: int | None status: str app_chain: str | None is_forced: bool site_id: int started_at: str | None finished_at: str | None created_at: str class TriggerJobListResponse(BaseModel): """调度任务分页列表响应。""" items: list[TriggerJobItem] total: int page: int page_size: int today_skipped_duplicates: int # 今日去重跳过数 class TriggerJobDetailResponse(TriggerJobItem): """调度任务详情响应(含 payload、error_message)。""" payload: dict | None error_message: str | None connector_type: str class RetryResponse(BaseModel): """手动重跑响应。""" trigger_job_id: int status: str # "pending" # ── 调用记录 ────────────────────────────────────────────── class RunLogItem(BaseModel): """调用记录列表项。""" id: int app_type: str trigger_type: str member_id: int | None tokens_used: int latency_ms: int | None status: str site_id: int created_at: str class RunLogListResponse(BaseModel): """调用记录分页列表响应。""" items: list[RunLogItem] total: int page: int page_size: int class RunLogDetailResponse(RunLogItem): """调用记录详情响应(含完整 prompt/response,不脱敏)。""" request_prompt: str | None response_text: str | None error_message: str | None session_id: str | None finished_at: str | None # ── 缓存失效 ───────────────────────────────────────────── class CacheInvalidateRequest(BaseModel): """缓存失效请求(site_id 必填)。""" site_id: int app_type: str | None = None member_id: int | None = None class CacheInvalidateResponse(BaseModel): """缓存失效响应。""" affected_count: int # ── Token 预算 ──────────────────────────────────────────── class BudgetResponse(BaseModel): """Token 预算使用情况响应。""" daily_used: int daily_limit: int daily_pct: float monthly_used: int monthly_limit: int monthly_pct: float # ── 批量执行 ────────────────────────────────────────────── class BatchRunRequest(BaseModel): """批量执行请求。""" app_types: list[str] member_ids: list[int] site_id: int class BatchRunEstimate(BaseModel): """批量执行预估响应(不立即执行)。""" batch_id: str estimated_calls: int estimated_tokens: int class BatchRunConfirm(BaseModel): """批量执行确认请求。""" batch_id: str class BatchRunConfirmResponse(BaseModel): """批量执行确认响应。""" status: str # "started" # ── 按需单 App 执行(/run/{app_type})────────────────────── class RunAppRequest(BaseModel): """按需执行单个 App 请求体。 context 字段根据 app_type 不同有不同约束: - app2_finance: site_id + time_dimension + area(area 默认 all) - app3_clue / app7_customer: site_id + member_id - app4_analysis / app5_tactics: site_id + member_id + assistant_id - app6_note: site_id + member_id + note_content + noted_by_name - app8_consolidation: site_id + member_id """ site_id: int member_id: int | None = None assistant_id: int | None = None time_dimension: str | None = None area: str | None = None # App2 专用,默认 all note_content: str | None = None noted_by_name: str | None = None noted_by_created_at: str | None = None class RunAppResponse(BaseModel): """按需执行单个 App 响应。""" app_type: str success: bool result: dict | None = None # 百炼返回的 JSON(成功时) error: str | None = None # 错误描述(失败时) # ── 告警 ────────────────────────────────────────────────── class AlertListResponse(BaseModel): """告警分页列表响应。""" items: list[AlertItem] total: int page: int page_size: int class AlertActionResponse(BaseModel): """告警操作(确认/忽略)响应。""" id: int alert_status: str # ── 触发器管理(biz.trigger_jobs)───────────────────────── class TriggerItem(BaseModel): """触发器单条记录。""" id: int job_name: str job_type: str trigger_condition: str # event / cron / interval trigger_config: dict # {"event_name": ...} 或 {"cron_expression": ...} status: str # enabled / disabled description: str | None = None last_run_at: str | None = None next_run_at: str | None = None last_error: str | None = None class TriggerUpdateRequest(BaseModel): """触发器更新请求(3 个字段至少填一个)。""" status: str | None = None # enabled / disabled cron_expression: str | None = None # 标准 5 段 cron description: str | None = None # ── 预热进度(app2_finance 72 组合)─────────────────────── class PrewarmMissingItem(BaseModel): """缺失的预热组合项。""" target_id: str # this_month__all time_dimension: str area: str class PrewarmProgressResponse(BaseModel): """app2_finance 预热进度响应。""" total: int # 固定 72 done: int missing: list[PrewarmMissingItem] last_updated: str | None = None # ── 手动事件触发(越过去重)─────────────────────────────── class ManualTriggerRequest(BaseModel): """手动触发 AI 事件请求。""" event_type: str # consumption / dws_completed / note_created / task_assigned site_id: int member_id: int | None = None assistant_id: int | None = None payload: dict | None = None is_forced: bool = True # 默认跳过去重 class ManualTriggerResponse(BaseModel): """手动事件触发响应。""" trigger_job_id: int status: str = "pending"