zuplo 7.6.7 → 7.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -118,13 +118,13 @@ at $80, block at $100. The warn amount has to be the lower of the two.
118
118
  The **Overview** tab charts daily and monthly usage only. Hourly and weekly rows
119
119
  are enforced, but no meter on that tab tracks them.
120
120
 
121
- :::note
121
+ :::note{title="Budget rule periods follow the UTC calendar"}
122
122
 
123
- Periods are anchored to your gateway, not the calendar. Every period rolls over
124
- relative to the time (UTC) the gateway was created, so a daily period resets at
125
- that hour rather than at midnight, and a monthly one on that day of the month.
126
- Teams and apps created later use the same anchor. Changing a limit mid-period
127
- doesn't reset the period's usage.
123
+ Hourly periods reset at the top of each hour, daily at 00:00 UTC, weekly on
124
+ Monday at 00:00 UTC, and monthly on the first of the month. A rule added
125
+ mid-period gets the full allowance for the rest of that period—the limit isn't
126
+ prorated—and resets at the next boundary. Changing a limit mid-period doesn't
127
+ reset the period's usage. Custom anchors aren't configurable.
128
128
 
129
129
  :::
130
130
 
@@ -184,6 +184,56 @@ App rules are stored in `options.budgetRules` on the app's own Budgets and Costs
184
184
  policy entry. For the app rule schema, see the
185
185
  [Budgets and Costs policy reference](../policies/ai-gateway-metering-v2-inbound.mdx).
186
186
 
187
+ This rule set budgets each user, each organization, and the app as a whole:
188
+
189
+ ```json
190
+ {
191
+ "budgetRules": [
192
+ {
193
+ "budgetBy": "expression",
194
+ "expression": "request.headers.get(\"x-user\")",
195
+ "meters": [
196
+ {
197
+ "meter": "tokens",
198
+ "period": "hourly",
199
+ "value": 20000,
200
+ "action": "block"
201
+ }
202
+ ]
203
+ },
204
+ {
205
+ "budgetBy": "expression",
206
+ "expression": "request.headers.get(\"x-organization\")",
207
+ "meters": [
208
+ { "meter": "cost", "period": "daily", "value": 50, "action": "block" }
209
+ ]
210
+ },
211
+ {
212
+ "budgetBy": "app",
213
+ "meters": [
214
+ {
215
+ "meter": "cost",
216
+ "period": "monthly",
217
+ "value": 2000,
218
+ "action": "warn"
219
+ },
220
+ {
221
+ "meter": "cost",
222
+ "period": "monthly",
223
+ "value": 2500,
224
+ "action": "block"
225
+ }
226
+ ]
227
+ }
228
+ ]
229
+ }
230
+ ```
231
+
232
+ Every distinct `x-user` value gets its own 20,000 tokens per hour, resetting at
233
+ the top of the hour. Every distinct `x-organization` value gets its own $50 per
234
+ day, resetting at 00:00 UTC. The `app` rule caps the whole app at $2,500 per
235
+ month, warning at $2,000, resetting on the first of the month.
236
+
187
237
  ## Setting team and gateway limits
188
238
 
189
239
  Team and gateway limits cover the node's own usage and all descendant usage.
@@ -24,6 +24,8 @@ invalid options fail open: the original request is forwarded.
24
24
  - `classifierAppApiKey` — bearer token for that app. Use
25
25
  `$env(CLASSIFIER_APP_API_KEY)`.
26
26
  - `classifierModel` — `providerName/model` sent on the classifier request.
27
+ - `modelsByComplexity` — `providerName/model` for each of `low`, `medium`, and
28
+ `high`. Used for routing when `smartRoutingEnabled` is true.
27
29
 
28
30
  Omit `intents` and `classifierPrompt` to use the built-in taxonomy (code,
29
31
  summarization, translation, qa, conversation, classification, creative_writing,
@@ -38,7 +38,8 @@
38
38
  "required": [
39
39
  "classifierAppID",
40
40
  "classifierAppApiKey",
41
- "classifierModel"
41
+ "classifierModel",
42
+ "modelsByComplexity"
42
43
  ],
43
44
  "examples": [
44
45
  {
@@ -82,8 +83,9 @@
82
83
  "modelsByComplexity": {
83
84
  "type": "object",
84
85
  "title": "Models By Complexity",
85
- "description": "Optional `providerName/model` routing by classified complexity. Used only when `smartRoutingEnabled` is true.",
86
+ "description": "`providerName/model` routing by classified complexity. All of `low`, `medium`, and `high` are required. Used only when `smartRoutingEnabled` is true.",
86
87
  "additionalProperties": false,
88
+ "required": ["low", "medium", "high"],
87
89
  "properties": {
88
90
  "low": {
89
91
  "type": "string",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zuplo",
3
- "version": "7.6.7",
3
+ "version": "7.6.8",
4
4
  "type": "module",
5
5
  "description": "The official Zuplo CLI for local development and platform management",
6
6
  "homepage": "https://zuplo.com/docs/cli/overview",
@@ -32,9 +32,9 @@
32
32
  "zuplo": "zuplo.js"
33
33
  },
34
34
  "dependencies": {
35
- "@zuplo/cli": "7.6.7",
36
- "@zuplo/core": "7.6.7",
37
- "@zuplo/runtime": "7.6.7",
38
- "@zuplo/test": "7.6.7"
35
+ "@zuplo/cli": "7.6.8",
36
+ "@zuplo/core": "7.6.8",
37
+ "@zuplo/runtime": "7.6.8",
38
+ "@zuplo/test": "7.6.8"
39
39
  }
40
40
  }