feat: complete phase 4 -- conversation replay API + analytics dashboard
- Replay models: StepType enum, ReplayStep, ReplayPage frozen dataclasses
- Checkpoint transformer: PostgresSaver JSONB -> structured timeline steps
- Replay API: GET /api/conversations (paginated), GET /api/replay/{thread_id}
- Analytics models: AgentUsage, InterruptStats, AnalyticsResult
- Analytics event recorder: Protocol + PostgresAnalyticsRecorder + NoOp
- Analytics queries: resolution_rate, agent_usage, escalation_rate, cost, interrupts
- Analytics API: GET /api/analytics?range=Xd with envelope response
- DB migration: analytics_events table + conversations column additions
- 74 new tests, 399 total passing, 92.87% coverage
This commit is contained in:
38
backend/app/analytics/models.py
Normal file
38
backend/app/analytics/models.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""Value objects for analytics dashboard."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class AgentUsage:
|
||||
"""Agent usage statistics within a time range."""
|
||||
|
||||
agent: str
|
||||
count: int
|
||||
percentage: float
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class InterruptStats:
|
||||
"""Interrupt approval/rejection statistics within a time range."""
|
||||
|
||||
total: int = 0
|
||||
approved: int = 0
|
||||
rejected: int = 0
|
||||
expired: int = 0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class AnalyticsResult:
|
||||
"""Full analytics result for a given time range."""
|
||||
|
||||
range: str
|
||||
total_conversations: int
|
||||
resolution_rate: float
|
||||
escalation_rate: float
|
||||
avg_turns_per_conversation: float
|
||||
avg_cost_per_conversation_usd: float
|
||||
agent_usage: tuple[AgentUsage, ...]
|
||||
interrupt_stats: InterruptStats
|
||||
Reference in New Issue
Block a user