-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschemas.py
More file actions
155 lines (113 loc) · 5.03 KB
/
schemas.py
File metadata and controls
155 lines (113 loc) · 5.03 KB
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
from typing import Dict, List, Optional
from pydantic import BaseModel, Field, field_validator, ConfigDict
import json
class ReadTransactionsInput(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
file_path: str = Field(..., description="Path to the transaction file")
class TransactionRecord(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
date: str = Field(..., description="Transaction date in ISO format")
description: str = Field(..., description="Transaction description")
amount: float = Field(
...,
description="Transaction amount (positive for income, negative for expense)",
)
category: Optional[str] = Field(default=None, description="Transaction category")
transaction_id: Optional[str] = Field(
default=None, description="Unique transaction identifier"
)
@field_validator("amount")
@classmethod
def amount_must_be_finite(cls, v: float) -> float:
if not isinstance(v, (int, float)) or not float("-inf") < v < float("inf"):
raise ValueError("Amount must be a finite number")
return float(v)
class CategorizationRequest(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
transactions: List[TransactionRecord] = Field(
..., description="List of transactions to categorize"
)
class BudgetSuggestionOutput(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
category: str = Field(..., description="Category name")
suggested_budget: float = Field(..., description="Suggested budget amount")
reasoning: str = Field(..., description="Reasoning for the budget suggestion")
@field_validator("suggested_budget")
@classmethod
def budget_must_be_non_negative(cls, v: float) -> float:
if v < 0:
raise ValueError("Budget must be non-negative")
return v
class AnomalyAlert(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
transaction_id: str = Field(..., description="ID of the anomalous transaction")
reason: str = Field(..., description="Reason for anomaly flag")
risk_score: float = Field(..., description="Risk score (0-1)")
@field_validator("risk_score")
@classmethod
def risk_score_must_be_valid(cls, v: float) -> float:
if not 0 <= v <= 1:
raise ValueError("Risk score must be between 0 and 1")
return v
class FinancialReport(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
total_income: float = Field(..., description="Total income")
total_expense: float = Field(..., description="Total expenses")
category_breakdown: Dict[str, float] = Field(
..., description="Breakdown by category"
)
savings_rate: float = Field(..., description="Savings rate as percentage")
budget_suggestions: List[BudgetSuggestionOutput] = Field(
..., description="Budget suggestions"
)
anomalies: List[AnomalyAlert] = Field(
default_factory=list, description="Detected anomalies"
)
@field_validator("savings_rate")
@classmethod
def savings_rate_must_be_valid(cls, v: float) -> float:
if not -100 <= v <= 100:
raise ValueError("Savings rate must be between -100 and 100")
return v
class CategoryBreakdownInput(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
transactions: List[TransactionRecord] = Field(
..., description="List of categorized transactions"
)
class BudgetRequest(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
category_spend: Dict[str, float] = Field(
..., description="Current spend by category"
)
total_income: float = Field(..., description="Total monthly income")
savings_target: float = Field(..., description="Target savings rate percentage")
@field_validator("total_income", "savings_target")
@classmethod
def values_must_be_non_negative(cls, v: float) -> float:
if v < 0:
raise ValueError("Value must be non-negative")
return v
class RiskScoreInput(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
transaction: TransactionRecord = Field(..., description="Transaction to score")
class AnomalyDetectionInput(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
transactions: List[TransactionRecord] = Field(
..., description="Transactions to analyze"
)
class LogEvent(BaseModel):
model_config = ConfigDict(extra="forbid", strict=True)
timestamp: str
session_id: str
state: str
agent_name: str
input_payload: str = Field(..., description="JSON string of input")
output_payload: str = Field(..., description="JSON string of output")
error_flag: bool = False
token_usage: Optional[int] = None
def serialize_payload(data: dict) -> str:
"""Serialize payload to JSON string."""
return json.dumps(data, sort_keys=True)
def deserialize_payload(json_str: str) -> dict:
"""Deserialize JSON string to dict."""
return json.loads(json_str)