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.
- package/docs/articles/logging.mdx +17 -0
- package/docs/articles/opentelemetry.mdx +38 -10
- package/docs/articles/performance-testing.mdx +44 -22
- package/docs/dev-portal/branding.mdx +49 -0
- package/docs/policies/_index.md +1 -0
- package/docs/policies/ai-gateway-metering-v2-inbound/doc.md +121 -0
- package/docs/policies/ai-gateway-metering-v2-inbound/schema.json +292 -0
- package/package.json +5 -5
|
@@ -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
|

|
|
@@ -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
|
-
|
|
241
|
-
latency-sensitive service-to-service calls, or
|
|
242
|
-
[load test](./performance-testing.mdx)
|
|
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
|
|
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
|
-
##
|
|
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
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
|
|
169
|
-
|
|
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
|
-
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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).
|
package/docs/policies/_index.md
CHANGED
|
@@ -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.
|
|
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.
|
|
23
|
-
"@zuplo/core": "6.73.
|
|
24
|
-
"@zuplo/runtime": "6.73.
|
|
25
|
-
"@zuplo/test": "1.4.
|
|
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
|
}
|