zuplo 7.7.8 → 7.7.10
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/ai-gateway/azure-ai.mdx +466 -0
- package/docs/ai-gateway/bedrock-mantle.mdx +5 -1
- package/docs/ai-gateway/integrations/claude-code.mdx +166 -11
- package/docs/ai-gateway/managing-providers.mdx +10 -6
- package/docs/ai-gateway/overview.mdx +3 -2
- package/docs/ai-gateway/providers.mdx +39 -0
- package/docs/ai-gateway/universal-api.mdx +6 -6
- package/docs/ai-gateway/vertex-ai.mdx +6 -1
- package/docs/policies/_index.md +1 -1
- package/docs/policies/ai-gateway-auth-v2-inbound/doc.md +65 -3
- package/docs/policies/ai-gateway-auth-v2-inbound/schema.json +29 -4
- package/docs/policies/ai-gateway-configuration-executor-v2-inbound/doc.md +54 -30
- package/docs/policies/ai-gateway-fallback-model-v2-inbound/doc.md +6 -3
- package/docs/policies/ai-gateway-metering-v2-inbound/doc.md +32 -19
- package/docs/policies/ai-gateway-model-filtering-v2-inbound/doc.md +55 -0
- package/package.json +5 -5
|
@@ -27,13 +27,38 @@ The gateway owner remains in control:
|
|
|
27
27
|
| `inboundPolicyChain` contains entries | Entries run in the listed order |
|
|
28
28
|
| An entry has `enabled: false` | That entry is skipped |
|
|
29
29
|
|
|
30
|
-
If a policy returns a response,
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
If a policy returns a response, later entries do not run. Successful 2xx
|
|
31
|
+
responses still receive the budget check described below before they are sent.
|
|
32
|
+
Other responses, including authentication failures, remain unchanged. If a chain
|
|
33
|
+
is invalid, the request fails closed with an error that identifies the entry to
|
|
34
|
+
fix.
|
|
33
35
|
|
|
34
36
|
This inbound executor does not run `outboundPolicyChain`. That field is reserved
|
|
35
37
|
for an outbound configuration executor on the response pipeline.
|
|
36
38
|
|
|
39
|
+
## Automatic budget enforcement
|
|
40
|
+
|
|
41
|
+
The executor enforces budgets configured on the application, its parent teams,
|
|
42
|
+
and the gateway. This does not require a Metering policy and applies even when
|
|
43
|
+
the application's policy chain is empty. An application cannot override a shared
|
|
44
|
+
budget with a higher limit of its own.
|
|
45
|
+
|
|
46
|
+
Request logs indicate when automatic budget checks run, including when the
|
|
47
|
+
application has no Metering policy. Warnings identify exceeded budgets, blocked
|
|
48
|
+
requests, fallback decisions, and checks that could not be completed.
|
|
49
|
+
|
|
50
|
+
When a budget blocks a provider request, the gateway uses the configured quota
|
|
51
|
+
fallback model or returns `429 Too Many Requests`. Successful responses from
|
|
52
|
+
policies, including Semantic Cache hits, are also subject to budgets. A blocked
|
|
53
|
+
response returns `429 Too Many Requests` without using a fallback model.
|
|
54
|
+
Warning-only budgets do not block responses. Authentication failures and other
|
|
55
|
+
non-2xx policy responses are preserved.
|
|
56
|
+
|
|
57
|
+
Place Metering before Semantic Cache to count cache hits toward request limits.
|
|
58
|
+
Budget changes can take time to take effect, and concurrent requests can exceed
|
|
59
|
+
a budget before further requests are blocked. If a budget check is unavailable,
|
|
60
|
+
requests can proceed unless a budget has already been determined to block them.
|
|
61
|
+
|
|
37
62
|
## Build an AI Gateway from scratch
|
|
38
63
|
|
|
39
64
|
### 1. Declare the policies
|
|
@@ -171,8 +196,7 @@ chain:
|
|
|
171
196
|
}
|
|
172
197
|
```
|
|
173
198
|
|
|
174
|
-
|
|
175
|
-
configuration when the channel is empty.
|
|
199
|
+
If you omit the loader, the executor loads the application configuration.
|
|
176
200
|
|
|
177
201
|
Authentication is optional and placement controls its scope:
|
|
178
202
|
|
|
@@ -205,14 +229,19 @@ An application can inherit the options from `policies.json`. Include
|
|
|
205
229
|
{
|
|
206
230
|
"name": "ai-gateway-metering-v2-inbound",
|
|
207
231
|
"options": {
|
|
208
|
-
"
|
|
209
|
-
|
|
210
|
-
"
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
232
|
+
"budgetRules": [
|
|
233
|
+
{
|
|
234
|
+
"budgetBy": "app",
|
|
235
|
+
"meters": [
|
|
236
|
+
{
|
|
237
|
+
"meter": "requests",
|
|
238
|
+
"period": "daily",
|
|
239
|
+
"value": 1000,
|
|
240
|
+
"action": "block"
|
|
241
|
+
}
|
|
242
|
+
]
|
|
214
243
|
}
|
|
215
|
-
|
|
244
|
+
]
|
|
216
245
|
}
|
|
217
246
|
},
|
|
218
247
|
{
|
|
@@ -347,10 +376,10 @@ canonical forms when writing application configuration:
|
|
|
347
376
|
| A key requiring brackets | `request.user.data["team-id"]` |
|
|
348
377
|
|
|
349
378
|
The `expression` field contains the complete expression. Do not wrap it in an
|
|
350
|
-
interpolation marker such as `${...}`.
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
redeploying the gateway.
|
|
379
|
+
interpolation marker such as `${...}`. Expressions use values from the request
|
|
380
|
+
and context, including values set by earlier policies. Place policies that set
|
|
381
|
+
these values before Semantic Cache. You can change an expression in the
|
|
382
|
+
application configuration without rebuilding or redeploying the gateway.
|
|
354
383
|
|
|
355
384
|
JSON encoding and expression syntax are separate. When writing raw JSON, escape
|
|
356
385
|
the double quotes required by a bracket segment:
|
|
@@ -393,10 +422,8 @@ The selectable data model is:
|
|
|
393
422
|
| `request` | `url`, `method`, `headers`, `user.sub`, `user.data`, `query`, `searchParams`, `params`, and the scalar Fetch request metadata `bodyUsed`, `cache`, `credentials`, `destination`, `integrity`, `keepalive`, `mode`, `redirect`, `referrer`, and `referrerPolicy` |
|
|
394
423
|
| `context` | `contextId`, `requestId`, `custom`, `route`, and `incomingRequestProperties` |
|
|
395
424
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
plain-data snapshot of the selected root. It never receives the live request or
|
|
399
|
-
context object.
|
|
425
|
+
Expressions cannot read the request body, call logging or policy methods, or
|
|
426
|
+
access properties outside this table.
|
|
400
427
|
|
|
401
428
|
Expressions have these limits:
|
|
402
429
|
|
|
@@ -413,9 +440,8 @@ Expressions have these limits:
|
|
|
413
440
|
It does not traverse arrays, class instances, inherited properties, or the
|
|
414
441
|
property names `__proto__`, `constructor`, and `prototype`.
|
|
415
442
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
earlier in the chain can derive a value and place it in a request header:
|
|
443
|
+
An authentication policy can populate `request.user`. A custom policy earlier in
|
|
444
|
+
the chain can derive a value and place it in a request header:
|
|
419
445
|
|
|
420
446
|
```ts
|
|
421
447
|
import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
|
|
@@ -446,14 +472,12 @@ value to well-formed NFC Unicode and ignores it when it exceeds 256 UTF-8 bytes
|
|
|
446
472
|
or contains control characters, U+2028, or U+2029. A missing or invalid value
|
|
447
473
|
does not contribute to the rule for that request.
|
|
448
474
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
same value.
|
|
475
|
+
Use consistent spelling for each expression. Different spellings, such as single
|
|
476
|
+
quotes and double quotes, identify different budget rules even when they select
|
|
477
|
+
the same value.
|
|
453
478
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
other valid rules continue to run.
|
|
479
|
+
Invalid budget rules and unsupported expressions are logged and skipped. Other
|
|
480
|
+
valid rules continue to apply.
|
|
457
481
|
|
|
458
482
|
## Write a custom policy for the chain
|
|
459
483
|
|
|
@@ -70,9 +70,12 @@ not override. A configured `fallback` replaces an existing backup and timeout; a
|
|
|
70
70
|
configured `quotaFallback` replaces an existing quota fallback.
|
|
71
71
|
|
|
72
72
|
Retry and timeout fallback is available for translated Chat Completions and
|
|
73
|
-
Embeddings requests. Native `/v1/messages` and
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
Embeddings requests. Native create requests at `/v1/messages` and
|
|
74
|
+
`/v1/responses` use a compatible completions backup only after the primary
|
|
75
|
+
exhausts its upstream 429 retries; they do not inherit `fallbackTimeoutSeconds`
|
|
76
|
+
or transport/5xx fallback. Responses management operations do not retry a backup
|
|
77
|
+
because stored response IDs belong to the provider that created them. Quota
|
|
78
|
+
fallback remains a separate, metering-driven path.
|
|
76
79
|
|
|
77
80
|
## Write your own fallback policy
|
|
78
81
|
|
|
@@ -5,13 +5,19 @@ budgets before the provider request runs. It meters spend, tokens, and requests.
|
|
|
5
5
|
Budget rules can cover the whole application or each distinct value of an
|
|
6
6
|
expression.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
returns `429 Too Many Requests`.
|
|
8
|
+
Application, team, and gateway budgets are enforced even when this policy is not
|
|
9
|
+
included in the application's policy chain.
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
Request logs indicate when automatic budget checks run and when a budget blocks
|
|
12
|
+
a request or selects a fallback model.
|
|
13
|
+
|
|
14
|
+
When a budget blocks a provider request, the gateway uses the configured quota
|
|
15
|
+
fallback model or returns `429 Too Many Requests`. Cached responses are also
|
|
16
|
+
subject to budgets: a blocked cache hit returns `429 Too Many Requests` without
|
|
17
|
+
using a fallback model.
|
|
18
|
+
|
|
19
|
+
Place Metering after Model Filtering and Fallback Model. Place it before
|
|
20
|
+
Semantic Cache so cache hits count toward request limits.
|
|
15
21
|
|
|
16
22
|
## Example
|
|
17
23
|
|
|
@@ -62,19 +68,26 @@ value of its expression. An action of `"warn"` notifies without blocking. An
|
|
|
62
68
|
action of `"block"` activates the configured quota fallback or returns
|
|
63
69
|
`429 Too Many Requests` when usage reaches the value.
|
|
64
70
|
|
|
65
|
-
> **Budgets fail open by default.** When `throwOnFailure` is `false`, a metering
|
|
66
|
-
> service failure lets the request proceed unmetered and no limit is checked.
|
|
67
|
-
> Set it to `true` to reject the request instead.
|
|
68
|
-
|
|
69
71
|
## Team limits
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
Application budgets apply only to that application. Parent team and gateway
|
|
74
|
+
budgets apply across their applications, even when an application does not
|
|
75
|
+
include Metering. An application cannot override a shared budget with a higher
|
|
76
|
+
limit of its own.
|
|
77
|
+
|
|
78
|
+
For example, two applications that spend $40 and $10 exhaust their team's $50
|
|
79
|
+
monthly budget. An application outside that team does not share its budget.
|
|
80
|
+
|
|
81
|
+
Team policy templates provide defaults for application policies. To set a shared
|
|
82
|
+
team budget, configure the budget on the team itself.
|
|
83
|
+
|
|
84
|
+
## Budget availability
|
|
85
|
+
|
|
86
|
+
Budget changes can take time to take effect. Usage is recorded asynchronously,
|
|
87
|
+
so concurrent requests can exceed a budget before further requests are blocked.
|
|
76
88
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
policy
|
|
80
|
-
|
|
89
|
+
If a budget check is unavailable, requests can proceed unless a budget has
|
|
90
|
+
already been determined to block them. The `throwOnFailure` option controls
|
|
91
|
+
whether this policy rejects requests when its metering operations fail; it does
|
|
92
|
+
not change how application, team, or gateway `budgetRules` handle unavailable
|
|
93
|
+
checks.
|
|
@@ -253,3 +253,58 @@ Policy order determines precedence:
|
|
|
253
253
|
|
|
254
254
|
Prefer one policy as the primary selector so the route's intent is easy to
|
|
255
255
|
understand.
|
|
256
|
+
|
|
257
|
+
## Model discovery
|
|
258
|
+
|
|
259
|
+
Authenticated `GET /v1/models` and `GET /v1/models/{providerName/model}` use the
|
|
260
|
+
same app URL as inference. Select the inference endpoint with the optional
|
|
261
|
+
`x-zuplo-models-endpoint` request header:
|
|
262
|
+
|
|
263
|
+
| Value | Eligible models | Response format |
|
|
264
|
+
| ------------------ | ----------------------------------------------------------------------------------------------- | --------------- |
|
|
265
|
+
| `chat-completions` | Active completion models supported by Chat Completions adapters, including existing translation | OpenAI |
|
|
266
|
+
| `messages` | Active completion models supported by native Messages passthrough | Anthropic |
|
|
267
|
+
| `responses` | Active completion models supported by the resolved Responses adapter | OpenAI |
|
|
268
|
+
| `embeddings` | Active embedding models supported by the resolved embedding adapter | OpenAI |
|
|
269
|
+
|
|
270
|
+
An explicit header wins. Otherwise, the presence of `anthropic-version` selects
|
|
271
|
+
`messages`; other requests default to `chat-completions`. Empty, unknown, and
|
|
272
|
+
multiple selector values return an actionable 400. The selector affects
|
|
273
|
+
discovery only. Embedding discovery is opt-in. Messages never translates to Chat
|
|
274
|
+
Completions.
|
|
275
|
+
|
|
276
|
+
Discovery applies the first Model Filtering policy's parsed rules, matching
|
|
277
|
+
inference's selection precedence. A capability omitted from that policy lists no
|
|
278
|
+
models. Without Model Filtering, discovery lists the eligible catalog. Inactive
|
|
279
|
+
models, unavailable adapters, and assignments without locally resolvable
|
|
280
|
+
credentials are excluded. List and retrieve use identical eligibility rules;
|
|
281
|
+
unknown, filtered-out, and wrong-endpoint IDs return the same 404.
|
|
282
|
+
|
|
283
|
+
IDs retain the exact model-name casing; only the provider assignment label is
|
|
284
|
+
normalized. OpenAI entries contain `id`, `object`, `created`, and `owned_by`.
|
|
285
|
+
`owned_by` means the provider assignment namespace, not the model's developer.
|
|
286
|
+
Anthropic entries contain `id`, `type`, `display_name`, and `created_at`, with
|
|
287
|
+
unknown required nullable metadata set to `null`. Unknown creation dates use the
|
|
288
|
+
epoch; optional unknown metadata is omitted.
|
|
289
|
+
|
|
290
|
+
OpenAI lists return every eligible model and ignore pagination parameters.
|
|
291
|
+
Anthropic lists default to 20 entries, accept `limit` from 1–1000, and accept
|
|
292
|
+
either `after_id` or `before_id` from a previous page. Follow `has_more` and
|
|
293
|
+
`last_id` for forward pagination. Invalid cursors return 400; restart without a
|
|
294
|
+
cursor.
|
|
295
|
+
|
|
296
|
+
Discovery uses the existing 60-second catalog cache. An uncached lookup,
|
|
297
|
+
including legacy fallback, has a two-second budget; failure returns a
|
|
298
|
+
sanitized 503. A successfully loaded catalog with no eligible models returns an
|
|
299
|
+
empty 200. Responses use `Cache-Control: private, no-store` and vary on both
|
|
300
|
+
selector headers. Only GET is supported. POST, PUT, PATCH, DELETE, and HEAD
|
|
301
|
+
return 405 with `Allow: GET`. OPTIONS is handled by the gateway’s existing CORS
|
|
302
|
+
preflight handler before app routing.
|
|
303
|
+
|
|
304
|
+
Authentication and general abuse protections still apply. Discovery skips prompt
|
|
305
|
+
inspection, semantic caching, and inference-budget blocking, and records one
|
|
306
|
+
baseline request. Eligibility describes the catalog, adapters, and declared
|
|
307
|
+
filtering rules; it does not guarantee upstream availability, provider
|
|
308
|
+
acceptance of credentials, or acceptance by prompt-dependent custom policies.
|
|
309
|
+
Existing Chat Completions translation does not promise full feature parity. Keep
|
|
310
|
+
a qualified model configured when a client's picker does not consume discovery.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zuplo",
|
|
3
|
-
"version": "7.7.
|
|
3
|
+
"version": "7.7.10",
|
|
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.7.
|
|
36
|
-
"@zuplo/core": "7.7.
|
|
37
|
-
"@zuplo/runtime": "7.7.
|
|
38
|
-
"@zuplo/test": "7.7.
|
|
35
|
+
"@zuplo/cli": "7.7.10",
|
|
36
|
+
"@zuplo/core": "7.7.10",
|
|
37
|
+
"@zuplo/runtime": "7.7.10",
|
|
38
|
+
"@zuplo/test": "7.7.10"
|
|
39
39
|
}
|
|
40
40
|
}
|