policy/types.bend
cswap-bend-cli@0.1.0.0 · 201 lines · 26 definitions
1import Base
2
3
4
5
6
7
8
9
10
11
12
13type AcctKind is Data:
14 SetupToken{}
15 FullLogin{}
16 ApiKey{}
17
18type Account is Data:
19 Account{slot: Nat, email: String, kind: AcctKind, disabled: Bool}
20
21
22type Scoped is Data:
23 Scoped{name: String, pct: Nat, reset: Maybe<&2, Nat>}
24
25type ErrKind is Data:
26 ErrNone{}
27 ErrHttp429{}
28 ErrOther{}
29
30
31
32
33
34def failing(+e: ErrKind) -> Nat:
35 match e:
36 case ErrNone{}:
37 0n
38 case o:
39 1n
40
41type Sentinel is Data:
42 NoSentinel{}
43 TokenExpired{}
44 OtherSentinel{}
45
46
47
48type Usage is Data:
49 Usage{slot: Nat, five: Maybe<&2, Nat>, five_reset: Maybe<&2, Nat>, seven: Maybe<&2, Nat>, seven_reset: Maybe<&2, Nat>, scoped: List<&2, Scoped>, fetched_at: Maybe<&2, Nat>, backoff_until: Nat, last_error: ErrKind, failures: Nat, next_poll_at: Maybe<&2, Nat>, poll_interval: Nat, auth_dead: Nat, held_until: Nat, claim_until: Nat, sentinel: Sentinel}
50
51
52type Win is Data:
53 Win{pct: Nat, reset: Maybe<&2, Nat>}
54
55type Strategy is Data:
56 Best{}
57 ConsumeFirst{}
58
59type Config is Data:
60 Config{
61 threshold: Nat,
62 models: List<&2, String>,
63 strategy: Strategy,
64 interval: Nat,
65 cooldown: Nat,
66 hysteresis: Nat,
67 serve_ttl: Nat,
68 unhealthy_ticks: Nat,
69 include_api: Bool
70 }
71
72type Trigger is Data:
73 Proactive{}
74 AtLimit{}
75 Failover{}
76 ConsumeFirstT{}
77
78
79
80
81type Snap is Data:
82 NoSnap{}
83 Snap{headroom: Maybe<&2, Nat>, recovery: Maybe<&2, Nat>, trigger: Maybe<&2, Trigger>}
84
85type State is Data:
86 State{last_at: Maybe<&2, Nat>, last_to: Maybe<&2, Nat>, last_from: Maybe<&2, Nat>, snap: Snap}
87
88
89
90type Mem is Data:
91 Mem{unhealthy: Nat, idle_since: Maybe<&2, Nat>}
92
93type Reason is Data:
94 UnmanagedActive{}
95 ActiveApiKey{}
96 BelowThreshold{}
97 ActiveIdle{}
98 ActiveUsageUnknown{}
99 Cooldown{}
100 NoCandidates{}
101 NoComparison{}
102 ResetUnknown{}
103 AlreadyConsumingSoonest{}
104 NoQualifyingCandidate{}
105 AllExhausted{earliest: Maybe<&2, Nat>}
106
107
108
109
110
111type Mode is Data:
112 MHead{}
113 MReset{}
114 MRec0{}
115 MRec1{}
116 MFallback{}
117 MApiLast{}
118
119
120
121type Decision is Data:
122 NoSwitch{reason: Reason, detail: String}
123 Switch{to: Nat, trigger: Trigger, reason: String, headroom: Nat, mode: Mode, rec: Maybe<&2, Nat>, bar: Maybe<&2, Nat>}
124
125def full() -> Nat:
126 10000n
127
128def default_config() -> Config:
129 Config{9000n, Nil{}, Best{}, 60n, 300n, 1000n, 180n, 3n, False{}}
130
131def fresh_state() -> State:
132 State{None{}, None{}, None{}, NoSnap{}}
133
134def fresh_mem() -> Mem:
135 Mem{0n, None{}}
136
137
138
139def reason.name.more(+r: Reason) -> String:
140 match r:
141 case Cooldown{}:
142 "cooldown"
143 case NoCandidates{}:
144 "no-candidates"
145 case NoComparison{}:
146 "no-comparison"
147 case ResetUnknown{}:
148 "reset-unknown"
149 case AlreadyConsumingSoonest{}:
150 "already-consuming-soonest"
151 case NoQualifyingCandidate{}:
152 "no-qualifying-candidate"
153 case o:
154 "all-exhausted"
155
156def reason.name(+r: Reason) -> String:
157 match r:
158 case UnmanagedActive{}:
159 "unmanaged-active-account"
160 case ActiveApiKey{}:
161 "active-api-key"
162 case BelowThreshold{}:
163 "below-threshold"
164 case ActiveIdle{}:
165 "active-idle"
166 case ActiveUsageUnknown{}:
167 "active-usage-unknown"
168 case o:
169 reason.name.more(o)
170
171def trigger.name(+t: Trigger) -> String:
172 match t:
173 case Proactive{}:
174 "proactive"
175 case AtLimit{}:
176 "at-limit"
177 case Failover{}:
178 "failover"
179 case ConsumeFirstT{}:
180 "consume-first"
181
182
183def reason.exit(+r: Reason) -> U32:
184 match r:
185 case NoCandidates{}:
186 3
187 case NoComparison{}:
188 3
189 case NoQualifyingCandidate{}:
190 3
191 case AllExhausted{e}:
192 3
193 case o:
194 2
195
196def exit_code(+d: Decision) -> U32:
197 match d:
198 case NoSwitch{r, detail}:
199 reason.exit(r)
200 case Switch{to, t, why, h, mode, rec, bar}:
201 0