File size: 3,757 Bytes
29fd274
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
from typing import Literal

from pydantic import BaseModel, Field


class TeamInfo(BaseModel):
    name: str
    code: str


class Wicket(BaseModel):
    batter: str
    kind: str


class BallEvent(BaseModel):
    index: int
    over: int
    ball_in_over: int
    over_label: str
    bowler: str
    striker: str
    non_striker: str
    runs_off_bat: int
    extras: int
    total_runs: int
    is_legal: bool
    outcome: str
    wicket: Wicket | None = None
    commentary: str


class StoryItem(BaseModel):
    kind: Literal["momentum", "wicket", "partnership", "over"]
    title: str
    detail: str
    over_label: str
    ball_index: int = Field(ge=1)

class Match(BaseModel):
    match_id: str
    tournament: str
    match_number: str
    teams: tuple[TeamInfo, TeamInfo]
    venue: str
    match_date: str
    format: Literal["T20"] = "T20"
    status: Literal["upcoming", "in_progress", "completed"] = "completed"
    current_innings: Literal[1, 2] = 2
    total_balls_per_innings: int = 120
    is_demo: bool = True


class BatterLine(BaseModel):
    name: str
    runs: int
    balls: int
    fours: int
    sixes: int
    strike_rate: float
    is_out: bool
    is_on_strike: bool


class BowlerLine(BaseModel):
    name: str
    overs: str
    runs: int
    wickets: int
    economy: float


class Partnership(BaseModel):
    runs: int
    balls: int
    batters: tuple[str, str]


class MatchState(BaseModel):
    match_id: str
    ball_index: int
    total_deliveries: int
    innings: Literal[1, 2]
    batting_team: str
    bowling_team: str
    score: int
    wickets: int
    overs: str
    legal_balls: int
    current_run_rate: float
    required_run_rate: float | None
    target: int | None
    remaining_runs: int | None
    remaining_balls: int | None
    batting_pair: tuple[BatterLine, BatterLine]
    current_bowler: BowlerLine
    partnership: Partnership
    recent_events: list[BallEvent]
    last_ball: BallEvent | None
    result: str | None


class TimelineEntry(BaseModel):
    over: int
    balls: list[BallEvent]
    runs: int
    wickets: int
    cumulative_runs: int
    cumulative_wickets: int
    run_rate: float
    target_pace: float | None


class ReplayAdvanceRequest(BaseModel):
    from_index: int = Field(ge=0)
    steps: int = Field(ge=-1000, le=1000)


class ChatRequest(BaseModel):
    match_id: str
    question: str = Field(min_length=1, max_length=2000)
    ball_index: int = Field(ge=0)
    conversation_id: str | None = None


class CatchUpRequest(BaseModel):
    match_id: str
    ball_index: int = Field(ge=0)
    overs: int = Field(default=3, ge=1, le=20)


class ComputedFact(BaseModel):
    label: str
    value: str


class EvidenceItem(BaseModel):
    kind: str
    title: str
    detail: str
    over_range: str | None = None
    ball_index: int | None = None


class Citation(BaseModel):
    title: str
    source: str
    excerpt: str
    url: str | None = None


class ChatResponse(BaseModel):
    answer: str
    intent: str
    computed_facts: list[ComputedFact]
    evidence: list[EvidenceItem]
    citations: list[Citation]
    confidence: str | None
    warnings: list[str]
    source: str = "backend"
    last_processed_ball_index: int
    match_id: str


class KeyMoment(BaseModel):
    title: str
    detail: str
    over_label: str
    tone: str


class CatchUpStatistic(BaseModel):
    label: str
    value: str


class CatchUpResponse(BaseModel):
    match_id: str
    from_over: str
    to_over: str
    headline: str
    summary: str
    key_moments: list[KeyMoment]
    important_events: list[BallEvent]
    statistics: list[CatchUpStatistic]
    key_players: list[BatterLine]
    evidence: list[EvidenceItem]
    source: str = "backend"
    last_processed_ball_index: int