zuplo 6.73.28 → 6.73.30

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.
@@ -113,3 +113,20 @@ request. If the property already exists, it will be overwritten.
113
113
  The log properties will be exported in a format native to the plugin you are
114
114
  using. For example, in the case of the OpenTelemetry plugin, the properties will
115
115
  be included in the `attributes` field of the log record.
116
+
117
+ ## Performance Under High Load
118
+
119
+ Logging costs compute and memory on every request. That's rarely noticeable on a
120
+ single response, but on an API running at a high request rate it shows up as
121
+ lower peak throughput and higher tail latency.
122
+
123
+ For high-traffic APIs, and before a [load test](./performance-testing.mdx):
124
+
125
+ - Log the events you'd act on rather than everything that happens. Verbose
126
+ `debug` logging on a hot path is the usual culprit.
127
+ - Keep custom log properties small. Identifiers cost far less than whole request
128
+ or response bodies.
129
+ - Add logging plugins deliberately. Each one is another copy of every record.
130
+
131
+ [OpenTelemetry tracing](./opentelemetry.mdx) carries a similar cost and supports
132
+ [sampling](./opentelemetry.mdx#performance-and-sampling) to bring it down.
@@ -60,6 +60,9 @@ export function runtimeInit(runtime: RuntimeExtensions) {
60
60
  }
61
61
  ```
62
62
 
63
+ When you created your project, Zuplo added this plugin with a
64
+ [sampling ratio](#sample-a-percentage-of-traces) already set.
65
+
63
66
  Deploy your project and open the **Observability** tab to see traces.
64
67
 
65
68
  ![Trace visualization](../../public/media/opentelemetry/image-1.png)
@@ -237,32 +240,45 @@ it consumes per request reduce the headroom available for the next one. On
237
240
  high-throughput APIs, that shows up as lower peak throughput and higher tail
238
241
  latency.
239
242
 
240
- For environments that need the most performance — high-RPS production traffic,
241
- latency-sensitive service-to-service calls, or a
242
- [load test](./performance-testing.mdx) sample tracing down or turn it off.
243
+ Sample traces on any API that runs at a high request rate — high-RPS production
244
+ traffic, latency-sensitive service-to-service calls, or an API you're about to
245
+ [load test](./performance-testing.mdx). A ratio of `0.1`, which keeps 10% of
246
+ traces, is the standard starting point: enough traffic to see how the API
247
+ behaves, without paying the export cost on every request. Tracing every request
248
+ is a reasonable default during development and for APIs at moderate request
249
+ rates.
243
250
 
244
251
  ### Sample a Percentage of Traces
245
252
 
246
- Set `sampling.headSampler.ratio` to export a fraction of traces. The ratio
247
- applies to every destination, including Zuplo's built-in storage:
253
+ Set `sampling.headSampler.ratio` to the fraction of traces to keep. The ratio
254
+ applies to every destination, including Zuplo's built-in storage. When you
255
+ created your project, Zuplo set it up this way: every request traced in your
256
+ working copy, 10% everywhere else.
248
257
 
249
- ```ts title="zuplo.runtime.ts"
258
+ ```ts title="modules/zuplo.runtime.ts"
250
259
  import { OpenTelemetryPlugin } from "@zuplo/otel";
251
- import { RuntimeExtensions } from "@zuplo/runtime";
260
+ import { environment, RuntimeExtensions } from "@zuplo/runtime";
252
261
 
253
262
  export function runtimeInit(runtime: RuntimeExtensions) {
263
+ const isWorkingCopy = environment.ZUPLO_ENVIRONMENT_STAGE === "working-copy";
264
+
254
265
  runtime.addPlugin(
255
266
  new OpenTelemetryPlugin({
256
267
  sampling: {
257
- headSampler: {
258
- ratio: 0.05, // Export 5% of traces
259
- },
268
+ headSampler: { ratio: isWorkingCopy ? 1 : 0.1 },
260
269
  },
261
270
  }),
262
271
  );
263
272
  }
264
273
  ```
265
274
 
275
+ Set `ratio` to a constant to use one value everywhere. Zuplo populates
276
+ `ZUPLO_ENVIRONMENT_STAGE`, which reads `working-copy` in your working copy and
277
+ `production`, `preview`, or `local` elsewhere, so local development
278
+ (`zuplo dev`) samples at 10% along with deployed environments. See
279
+ [system environment variables](./environment-variables.mdx#system-environment-variables)
280
+ for the full list.
281
+
266
282
  By default, traces whose root span ends in an error are exported whatever the
267
283
  ratio, so errors stay debuggable on a heavily sampled API. Supplying your own
268
284
  `sampling.tailSampler` replaces that behavior.
@@ -273,6 +289,10 @@ request, so sampling reduces the cost of tracing rather than removing it.
273
289
 
274
290
  ### Disable Tracing
275
291
 
292
+ Sampling leaves some per-request work in place. Where you need none of it —
293
+ measuring the gateway's raw capacity, or squeezing the last of the headroom out
294
+ of a high-RPS environment — turn tracing off instead.
295
+
276
296
  To remove the overhead entirely, don't register the plugin. Gate it on an
277
297
  [environment variable](./environment-variables.mdx) so you can control tracing
278
298
  per environment without changing code:
@@ -297,6 +317,14 @@ Where the plugin doesn't run, traces stop appearing in the **Observability** tab
297
317
  for that environment. Request analytics and logs come from a separate pipeline,
298
318
  so they aren't affected.
299
319
 
320
+ ### Account for Logging Too
321
+
322
+ [Logging](./logging.mdx) costs compute and memory per request the same way
323
+ tracing does. On a high-throughput API, log the events you'd act on rather than
324
+ everything that happens, and keep custom log properties small. Sampling traces
325
+ while logging verbosely on every request moves the cost rather than removing it.
326
+ See [Performance Under High Load](./logging.mdx#performance-under-high-load).
327
+
300
328
  ## Logging
301
329
 
302
330
  The plugin can also export logs in OpenTelemetry format. Logs are sent to your
@@ -152,7 +152,7 @@ performing complex transformations.
152
152
 
153
153
  :::
154
154
 
155
- ## Disable Tracing for Load Tests
155
+ ## Sample Tracing for Load Tests and High-Traffic APIs
156
156
 
157
157
  [OpenTelemetry tracing](./opentelemetry.mdx) instruments every request, opening
158
158
  spans for the request, each policy, the handler, and any `fetch` subrequests.
@@ -161,12 +161,42 @@ single response time, but the CPU and memory it consumes per request reduce the
161
161
  headroom available for the next one. Under sustained load, that shows up as
162
162
  lower peak throughput and higher tail latency.
163
163
 
164
- Zuplo recommends disabling OpenTelemetry before you run a load test. Otherwise
165
- you measure the gateway and the telemetry pipeline together, and the results
166
- understate the gateway's capacity.
164
+ Zuplo recommends sampling tracing down before you run a load test, and on any
165
+ API that serves a high request rate in production. A ratio of `0.1` keeps 10% of
166
+ traces, enough to see how the API behaves without spending most of the gateway's
167
+ headroom on telemetry:
167
168
 
168
- To disable tracing, remove the `OpenTelemetryPlugin` from `zuplo.runtime.ts`, or
169
- gate it on an [environment variable](./environment-variables.mdx) so you can
169
+ ```ts title="zuplo.runtime.ts"
170
+ import { OpenTelemetryPlugin } from "@zuplo/otel";
171
+ import { RuntimeExtensions } from "@zuplo/runtime";
172
+
173
+ export function runtimeInit(runtime: RuntimeExtensions) {
174
+ runtime.addPlugin(
175
+ new OpenTelemetryPlugin({
176
+ sampling: {
177
+ headSampler: {
178
+ ratio: 0.1, // Keep 10% of traces
179
+ },
180
+ },
181
+ }),
182
+ );
183
+ }
184
+ ```
185
+
186
+ When you created your project, Zuplo set this ratio for everything outside the
187
+ working copy, so check `modules/zuplo.runtime.ts` before you assume your test
188
+ environment traces every request.
189
+
190
+ Test with the ratio you plan to deploy. A pass that traces every request tells
191
+ you little about an API that will run at 10%, and the reverse understates what
192
+ tracing costs you. For the full sampling reference, see
193
+ [Performance and Sampling](./opentelemetry.mdx#performance-and-sampling).
194
+
195
+ ### Turn Tracing Off to Measure Raw Capacity
196
+
197
+ Sampling lowers the cost of tracing rather than removing it. To measure what the
198
+ gateway alone can do, remove the `OpenTelemetryPlugin` from `zuplo.runtime.ts`,
199
+ or gate it on an [environment variable](./environment-variables.mdx) so you can
170
200
  control it per environment without changing code:
171
201
 
172
202
  ```ts title="zuplo.runtime.ts"
@@ -181,24 +211,16 @@ export function runtimeInit(runtime: RuntimeExtensions) {
181
211
  ```
182
212
 
183
213
  Tracing runs only where you set `TRACING_ENABLED` to `true`, so leave the
184
- variable unset on the environment you test against.
185
-
186
- The same applies to any third-party logging or monitoring plugin you've added.
187
- Each one adds per-request work.
188
-
189
- :::tip
190
-
191
- Disable tracing in production too for environments that need the most
192
- performance, such as high-RPS traffic or latency-sensitive service-to-service
193
- calls. Where you want to keep some visibility, sample instead of disabling — see
194
- [Performance and Sampling](./opentelemetry.mdx#performance-and-sampling).
214
+ variable unset on the environment you test against. Running one untraced pass
215
+ next to your sampled pass tells you what telemetry costs at your target request
216
+ rate.
195
217
 
196
- :::
218
+ ### Account for Logging Too
197
219
 
198
- If you plan to run tracing in production, run one test pass with the same
199
- configuration you'll deploy, including the same sampling ratio. Comparing that
200
- pass against an untraced one tells you what the telemetry costs you at your
201
- target request rate.
220
+ The same applies to any logging or monitoring plugin you've added: each one adds
221
+ per-request work that eats into the throughput you're trying to measure. Trim
222
+ [logging](./logging.mdx) to the events you'd act on, and run the test with the
223
+ same logging configuration you plan to deploy.
202
224
 
203
225
  ## Performance Testing Best Practices
204
226
 
@@ -0,0 +1,49 @@
1
+ ---
2
+ title: Zuplo Branding
3
+ sidebar_label: Zuplo Branding
4
+ description:
5
+ Learn which plans show the "Powered by Zuplo" badge on the Developer Portal
6
+ and how to remove it.
7
+ ---
8
+
9
+ Developer Portals on Zuplo's self-serve plans display a "Powered by Zuplo"
10
+ badge. Whether the badge appears is controlled by your account's plan — it isn't
11
+ a setting in `zudoku.config.tsx`.
12
+
13
+ ## Which plans show the badge
14
+
15
+ | Plan | "Powered by Zuplo" badge |
16
+ | ------------- | ------------------------ |
17
+ | Free | Shown |
18
+ | Pay-as-you-go | Shown |
19
+ | Builder | Shown |
20
+ | Business | Shown |
21
+ | Enterprise | Hidden |
22
+
23
+ Upgrading from Free to a paid self-serve plan such as Builder doesn't remove the
24
+ badge. Removing Zuplo branding is an Enterprise entitlement.
25
+
26
+ ## Remove the badge
27
+
28
+ <EnterpriseFeature name="Developer Portal white-labeling" />
29
+
30
+ To remove Zuplo branding from your Developer Portal, contact
31
+ [sales@zuplo.com](mailto:sales@zuplo.com) or reach out to your account manager.
32
+ Your account team enables the entitlement on your account — you don't need to
33
+ change your project configuration.
34
+
35
+ :::note
36
+
37
+ The badge comes from your account's entitlements, not your portal configuration.
38
+ There's no configuration option, environment variable, or Developer API endpoint
39
+ that overrides it — editing your `zudoku.config.tsx` footer won't remove it.
40
+
41
+ :::
42
+
43
+ ## Customize the rest of the footer
44
+
45
+ The Zuplo badge is separate from the footer you control. On every plan you can
46
+ set your own columns, social links, copyright notice, and logo — see
47
+ [Footer Configuration](./zudoku/configuration/footer.mdx). To change colors,
48
+ fonts, and the overall look of the portal, see
49
+ [Colors and Theme](./zudoku/customization/colors-theme.mdx).
@@ -5,6 +5,7 @@
5
5
  | set-query-params-inbound | Add or Set Query Parameters | Adds or sets query parameters on the incoming request. | api-gateway |
6
6
  | set-headers-inbound | Add or Set Request Headers | Adds or sets headers on the incoming request. | api-gateway |
7
7
  | ai-gateway-fallback-model-v2-inbound | AI Gateway Fallback Model (v2) | Adds failure and quota fallbacks to an existing AI Gateway model selection. Place this policy after AI Gateway Model Filtering (v2). It never creates a model selection, so a misplaced policy cannot bypass filtering. | ai-gateway |
8
+ | ai-gateway-metering-v2-inbound | AI Gateway Metering (v2) | Meters AI Gateway v2 usage and enforces options-driven usage limits. The authentication policy must run before this policy so the app configuration id is available for meter storage and analytics. | ai-gateway |
8
9
  | ai-gateway-model-filtering-v2-inbound | AI Gateway Model Filtering (v2) | Matches AI Gateway requests against curated allow lists or open block lists, then stores the winning model reference for the route handler. | ai-gateway |
9
10
  | akamai-ai-firewall | Akamai AI Firewall | Akamai AI Firewall Inbound Policy | ai-gateway |
10
11
  | akamai-firewall-for-ai-outbound | Akamai Firewall for AI | Inspects each upstream response with Akamai's Firewall for AI detect API and replaces the response with a `403 Forbidden` if Akamai returns a `deny` rule. Useful behind AI-powered APIs to filter unsafe completions, sensitive data exposure, and toxic content before they reach the client. The body, headers, URL, and query string sent to Akamai are configurable; by default only the response body is captured. Bodies are read from a clone so the client still receives the original. | api-gateway |
@@ -0,0 +1,121 @@
1
+ # AI Gateway Metering (v2)
2
+
3
+ `ai-gateway-metering-v2-inbound` records AI Gateway usage and enforces daily or
4
+ monthly limits before the provider request runs. Declare the policy in
5
+ `policies.json`, then add it to an application's `inboundPolicyChain`.
6
+
7
+ ## Example
8
+
9
+ ```json
10
+ {
11
+ "name": "ai-gateway-metering-v2-inbound",
12
+ "options": {
13
+ "throwOnFailure": false,
14
+ "limits": {
15
+ "costs": {
16
+ "monthly": {
17
+ "enabled": true,
18
+ "limit": 100,
19
+ "warning": {
20
+ "enabled": true,
21
+ "threshold": 80
22
+ }
23
+ }
24
+ },
25
+ "requests": {
26
+ "daily": {
27
+ "enabled": true,
28
+ "limit": 1000
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ The supported meters are `costs`, `tokens`, and `requests`. Each meter can have
37
+ `daily` and `monthly` settings. A period is enforced only when `enabled` is
38
+ `true` and `limit` is present. Usage equal to the limit is blocked.
39
+
40
+ When `throwOnFailure` is `false`, metering failures pass the request through.
41
+ Set it to `true` to fail the request instead.
42
+
43
+ ## Set limits from custom code
44
+
45
+ Use a custom inbound policy to vary limits for individual requests. For example,
46
+ the following policy gives callers with a `pro` plan a higher daily request
47
+ limit:
48
+
49
+ ```typescript
50
+ import {
51
+ AIGatewayMeteringV2InboundPolicy,
52
+ type ZuploContext,
53
+ type ZuploRequest,
54
+ } from "@zuplo/runtime";
55
+
56
+ export default function applyPlanLimit(
57
+ request: ZuploRequest,
58
+ context: ZuploContext
59
+ ) {
60
+ const dailyRequestLimit = request.user?.data.plan === "pro" ? 10_000 : 1_000;
61
+
62
+ AIGatewayMeteringV2InboundPolicy.setLimits(context, {
63
+ requests: {
64
+ daily: {
65
+ enabled: true,
66
+ limit: dailyRequestLimit,
67
+ },
68
+ },
69
+ });
70
+
71
+ return request;
72
+ }
73
+ ```
74
+
75
+ Register the module as a custom policy:
76
+
77
+ ```json
78
+ {
79
+ "name": "plan-based-ai-limits",
80
+ "policyType": "custom-code-inbound",
81
+ "handler": {
82
+ "export": "default",
83
+ "module": "$import(./modules/plan-based-ai-limits)"
84
+ }
85
+ }
86
+ ```
87
+
88
+ Place it before metering in the application's inbound policy chain:
89
+
90
+ ```json
91
+ {
92
+ "inboundPolicyChain": [
93
+ {
94
+ "name": "plan-based-ai-limits"
95
+ },
96
+ {
97
+ "name": "ai-gateway-metering-v2-inbound"
98
+ }
99
+ ]
100
+ }
101
+ ```
102
+
103
+ `setLimits` changes only the fields supplied for the current request. Other
104
+ settings from the metering policy remain unchanged. For example, setting only
105
+ `requests.daily.limit` preserves `requests.daily.enabled`, its warning settings,
106
+ and all monthly limits. It does not update the policy configuration or affect
107
+ later requests.
108
+
109
+ The exported `AIGatewayMeteringV2LimitOverrides` interface can be used when a
110
+ custom policy builds the override object separately. Its shape matches the
111
+ `limits` option. These values are called overrides because they temporarily
112
+ replace matching policy settings for the current request:
113
+
114
+ - Choose a meter: `costs`, `tokens`, or `requests`.
115
+ - Choose a period: `daily` or `monthly`.
116
+ - Set one or more values: `enabled`, `limit`, or `warning`.
117
+
118
+ If model filtering and fallback-model policies selected a `quotaFallback`, an
119
+ exceeded limit activates that fallback instead of returning 429. The fallback
120
+ request is still metered. Order the chain as model filtering, fallback model,
121
+ metering, then policies that may short-circuit such as semantic cache.
@@ -0,0 +1,292 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft-07/schema",
3
+ "$id": "https://cdn.zuplo.com/policies/runtime/schemas/ai-gateway-metering-v2-inbound.json",
4
+ "type": "object",
5
+ "title": "AI Gateway Metering (v2)",
6
+ "isDeprecated": false,
7
+ "isPaidAddOn": false,
8
+ "isEnterprise": false,
9
+ "isInternal": false,
10
+ "isBeta": true,
11
+ "isHidden": false,
12
+ "requiresAI": true,
13
+ "products": ["ai-gateway"],
14
+ "description": "Meters AI Gateway v2 usage and enforces options-driven usage limits.\n\nThe authentication policy must run before this policy so the app configuration id is available for meter storage and analytics.",
15
+ "deprecatedMessage": "",
16
+ "required": ["handler"],
17
+ "properties": {
18
+ "handler": {
19
+ "type": "object",
20
+ "default": {},
21
+ "required": ["export", "module", "options"],
22
+ "properties": {
23
+ "export": {
24
+ "const": "AIGatewayMeteringV2InboundPolicy",
25
+ "description": "The name of the exported type"
26
+ },
27
+ "module": {
28
+ "const": "$import(@zuplo/runtime)",
29
+ "description": "The module containing the policy"
30
+ },
31
+ "options": {
32
+ "x-zuplo-policy-type": "ai-gateway-metering-v2",
33
+ "title": "AIGatewayMeteringV2InboundPolicyOptions",
34
+ "type": "object",
35
+ "description": "Options for metering AI Gateway v2 usage and enforcing request-time limits.",
36
+ "additionalProperties": false,
37
+ "required": [],
38
+ "properties": {
39
+ "throwOnFailure": {
40
+ "type": "boolean",
41
+ "default": false,
42
+ "description": "Throw when the metering service is unavailable instead of failing open."
43
+ },
44
+ "limits": {
45
+ "type": "object",
46
+ "description": "Usage limits grouped by meter.",
47
+ "additionalProperties": false,
48
+ "properties": {
49
+ "costs": {
50
+ "type": "object",
51
+ "minProperties": 1,
52
+ "additionalProperties": false,
53
+ "properties": {
54
+ "daily": {
55
+ "type": "object",
56
+ "additionalProperties": false,
57
+ "required": ["enabled"],
58
+ "properties": {
59
+ "enabled": {
60
+ "type": "boolean"
61
+ },
62
+ "limit": {
63
+ "type": "number",
64
+ "minimum": 0
65
+ },
66
+ "warning": {
67
+ "type": "object",
68
+ "additionalProperties": false,
69
+ "required": ["enabled"],
70
+ "properties": {
71
+ "enabled": {
72
+ "type": "boolean"
73
+ },
74
+ "threshold": {
75
+ "type": "number",
76
+ "minimum": 0,
77
+ "maximum": 100,
78
+ "description": "Percentage of the limit at which to emit a warning event."
79
+ }
80
+ }
81
+ }
82
+ }
83
+ },
84
+ "monthly": {
85
+ "type": "object",
86
+ "additionalProperties": false,
87
+ "required": ["enabled"],
88
+ "properties": {
89
+ "enabled": {
90
+ "type": "boolean"
91
+ },
92
+ "limit": {
93
+ "type": "number",
94
+ "minimum": 0
95
+ },
96
+ "warning": {
97
+ "type": "object",
98
+ "additionalProperties": false,
99
+ "required": ["enabled"],
100
+ "properties": {
101
+ "enabled": {
102
+ "type": "boolean"
103
+ },
104
+ "threshold": {
105
+ "type": "number",
106
+ "minimum": 0,
107
+ "maximum": 100,
108
+ "description": "Percentage of the limit at which to emit a warning event."
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+ },
116
+ "tokens": {
117
+ "type": "object",
118
+ "minProperties": 1,
119
+ "additionalProperties": false,
120
+ "properties": {
121
+ "daily": {
122
+ "type": "object",
123
+ "additionalProperties": false,
124
+ "required": ["enabled"],
125
+ "properties": {
126
+ "enabled": {
127
+ "type": "boolean"
128
+ },
129
+ "limit": {
130
+ "type": "number",
131
+ "minimum": 0
132
+ },
133
+ "warning": {
134
+ "type": "object",
135
+ "additionalProperties": false,
136
+ "required": ["enabled"],
137
+ "properties": {
138
+ "enabled": {
139
+ "type": "boolean"
140
+ },
141
+ "threshold": {
142
+ "type": "number",
143
+ "minimum": 0,
144
+ "maximum": 100,
145
+ "description": "Percentage of the limit at which to emit a warning event."
146
+ }
147
+ }
148
+ }
149
+ }
150
+ },
151
+ "monthly": {
152
+ "type": "object",
153
+ "additionalProperties": false,
154
+ "required": ["enabled"],
155
+ "properties": {
156
+ "enabled": {
157
+ "type": "boolean"
158
+ },
159
+ "limit": {
160
+ "type": "number",
161
+ "minimum": 0
162
+ },
163
+ "warning": {
164
+ "type": "object",
165
+ "additionalProperties": false,
166
+ "required": ["enabled"],
167
+ "properties": {
168
+ "enabled": {
169
+ "type": "boolean"
170
+ },
171
+ "threshold": {
172
+ "type": "number",
173
+ "minimum": 0,
174
+ "maximum": 100,
175
+ "description": "Percentage of the limit at which to emit a warning event."
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+ },
183
+ "requests": {
184
+ "type": "object",
185
+ "minProperties": 1,
186
+ "additionalProperties": false,
187
+ "properties": {
188
+ "daily": {
189
+ "type": "object",
190
+ "additionalProperties": false,
191
+ "required": ["enabled"],
192
+ "properties": {
193
+ "enabled": {
194
+ "type": "boolean"
195
+ },
196
+ "limit": {
197
+ "type": "number",
198
+ "minimum": 0
199
+ },
200
+ "warning": {
201
+ "type": "object",
202
+ "additionalProperties": false,
203
+ "required": ["enabled"],
204
+ "properties": {
205
+ "enabled": {
206
+ "type": "boolean"
207
+ },
208
+ "threshold": {
209
+ "type": "number",
210
+ "minimum": 0,
211
+ "maximum": 100,
212
+ "description": "Percentage of the limit at which to emit a warning event."
213
+ }
214
+ }
215
+ }
216
+ }
217
+ },
218
+ "monthly": {
219
+ "type": "object",
220
+ "additionalProperties": false,
221
+ "required": ["enabled"],
222
+ "properties": {
223
+ "enabled": {
224
+ "type": "boolean"
225
+ },
226
+ "limit": {
227
+ "type": "number",
228
+ "minimum": 0
229
+ },
230
+ "warning": {
231
+ "type": "object",
232
+ "additionalProperties": false,
233
+ "required": ["enabled"],
234
+ "properties": {
235
+ "enabled": {
236
+ "type": "boolean"
237
+ },
238
+ "threshold": {
239
+ "type": "number",
240
+ "minimum": 0,
241
+ "maximum": 100,
242
+ "description": "Percentage of the limit at which to emit a warning event."
243
+ }
244
+ }
245
+ }
246
+ }
247
+ }
248
+ }
249
+ }
250
+ }
251
+ }
252
+ }
253
+ }
254
+ },
255
+ "examples": [
256
+ {
257
+ "export": "AIGatewayMeteringV2InboundPolicy",
258
+ "module": "$import(@zuplo/runtime)",
259
+ "options": {
260
+ "limits": {
261
+ "costs": {
262
+ "daily": {
263
+ "warning": {}
264
+ },
265
+ "monthly": {
266
+ "warning": {}
267
+ }
268
+ },
269
+ "requests": {
270
+ "daily": {
271
+ "warning": {}
272
+ },
273
+ "monthly": {
274
+ "warning": {}
275
+ }
276
+ },
277
+ "tokens": {
278
+ "daily": {
279
+ "warning": {}
280
+ },
281
+ "monthly": {
282
+ "warning": {}
283
+ }
284
+ }
285
+ },
286
+ "throwOnFailure": false
287
+ }
288
+ }
289
+ ]
290
+ }
291
+ }
292
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zuplo",
3
- "version": "6.73.28",
3
+ "version": "6.73.30",
4
4
  "type": "module",
5
5
  "description": "The programmable API Gateway",
6
6
  "author": "Zuplo, Inc.",
@@ -19,9 +19,9 @@
19
19
  "zuplo": "zuplo.js"
20
20
  },
21
21
  "dependencies": {
22
- "@zuplo/cli": "6.73.28",
23
- "@zuplo/core": "6.73.28",
24
- "@zuplo/runtime": "6.73.28",
25
- "@zuplo/test": "1.4.0"
22
+ "@zuplo/cli": "6.73.30",
23
+ "@zuplo/core": "6.73.30",
24
+ "@zuplo/runtime": "6.73.30",
25
+ "@zuplo/test": "1.4.4"
26
26
  }
27
27
  }