Renecto commited on
Commit
6a2306e
·
verified ·
1 Parent(s): b28fdd8

upload: bridge_models.py

Browse files
Files changed (1) hide show
  1. bridge_models.py +84 -0
bridge_models.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Pydantic models for Level Bridge Chat API.
3
+ Strict JSON Schema -- MCP-wrappable without modification.
4
+ """
5
+
6
+ from __future__ import annotations
7
+ from typing import Optional
8
+ from pydantic import BaseModel, Field, field_validator
9
+ import base64
10
+
11
+
12
+ class Metrics(BaseModel):
13
+ cvr: Optional[float] = Field(None, description="CVR (%)")
14
+ ctr: Optional[float] = Field(None, description="CTR (%)")
15
+ cpa: Optional[float] = Field(None, description="CPA (円)")
16
+
17
+ def has_any(self) -> bool:
18
+ return any(v is not None for v in [self.cvr, self.ctr, self.cpa])
19
+
20
+
21
+ class DashboardContext(BaseModel):
22
+ campaign_name: Optional[str] = None
23
+ industry: Optional[str] = None
24
+ metrics: Optional[Metrics] = None
25
+ image_base64: Optional[str] = None
26
+
27
+ @field_validator("image_base64")
28
+ @classmethod
29
+ def validate_image_size(cls, v: Optional[str]) -> Optional[str]:
30
+ if v is None:
31
+ return v
32
+ import os
33
+ max_mb = float(os.environ.get("MAX_IMAGE_SIZE_MB", "5"))
34
+ size_bytes = len(v.encode("utf-8")) * 3 / 4 # base64 -> bytes approx
35
+ if size_bytes > max_mb * 1024 * 1024:
36
+ raise ValueError(f"image_base64 exceeds {max_mb}MB limit")
37
+ return v
38
+
39
+
40
+ class BridgeRequest(BaseModel):
41
+ session_id: Optional[str] = None
42
+ message: str = Field(default="", description="User message (can be empty on Turn 1)")
43
+ dashboard_context: Optional[DashboardContext] = None
44
+
45
+
46
+ class NeededInfo(BaseModel):
47
+ key: str
48
+ label: str
49
+ example: str
50
+
51
+
52
+ class BestNow(BaseModel):
53
+ summary: str
54
+ actions: list[str]
55
+ confidence: str = Field(..., pattern="^(low|mid|high)$")
56
+ reasoning_basis: list[str]
57
+
58
+
59
+ class NextLevelPreview(BaseModel):
60
+ current_level: str
61
+ next_level: Optional[str]
62
+ needed_info: list[NeededInfo]
63
+ what_will_be_possible: list[str]
64
+ expected_impact: str
65
+
66
+
67
+ class BridgeResponse(BaseModel):
68
+ ok: bool = True
69
+ session_id: str
70
+ turn_number: int
71
+ inferred_level: str
72
+ level_confidence: str = Field(..., pattern="^(low|mid|high)$")
73
+ level_reason: str
74
+ best_now: BestNow
75
+ next_level_preview: NextLevelPreview
76
+ follow_up_question: Optional[str] = None
77
+
78
+
79
+ class BridgeErrorResponse(BaseModel):
80
+ ok: bool = False
81
+ session_id: Optional[str] = None
82
+ error_code: str
83
+ message: str
84
+ fallback: Optional[dict] = None