create-zuplo-api 6.73.25 → 6.73.26
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/dist/index.js +1 -1
- package/dist/templates/ai-gateway-v2/README-template.md +26 -0
- package/dist/templates/ai-gateway-v2/config/ai.oas.json +54 -0
- package/dist/templates/ai-gateway-v2/config/policies.json +112 -0
- package/dist/templates/ai-gateway-v2/env.example +19 -0
- package/dist/templates/ai-gateway-v2/gitignore +8 -0
- package/dist/templates/ai-gateway-v2/tsconfig.json +20 -0
- package/dist/templates/ai-gateway-v2/zuplo.jsonc +4 -0
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# AI Gateway
|
|
2
|
+
|
|
3
|
+
This project is a Zuplo AI Gateway. It exposes the canonical AI Gateway
|
|
4
|
+
operations (`/v1/chat/completions`, `/v1/messages`, `/v1/responses`, and
|
|
5
|
+
`/v1/embeddings`) through `aiGatewayHandlerV2` and authenticates every request
|
|
6
|
+
with an AI Gateway application API key (`ai-gateway-auth-v2-inbound`).
|
|
7
|
+
|
|
8
|
+
Each route then invokes `ai-gateway-configuration-executor-v2-inbound`. The
|
|
9
|
+
executor reads the authenticated application's `inboundPolicyChain` and runs
|
|
10
|
+
the selected policies in order. Applications may select only from the policies
|
|
11
|
+
pre-declared in `config/policies.json`.
|
|
12
|
+
|
|
13
|
+
## Customizing the gateway
|
|
14
|
+
|
|
15
|
+
- Declare additional selectable policies (including custom code policies) in
|
|
16
|
+
`config/policies.json`. Keep credentials in the declared policy's
|
|
17
|
+
`handler.options` using `$env(...)` references so they are resolved at build
|
|
18
|
+
time and never stored in application configuration.
|
|
19
|
+
- Pushes to your default branch deploy the gateway to production.
|
|
20
|
+
|
|
21
|
+
## Environment variables
|
|
22
|
+
|
|
23
|
+
The pre-declared firewall and tracing policies read their credentials from
|
|
24
|
+
environment variables (see `.env.example`). Configure them in your project's
|
|
25
|
+
Environment Variables settings before adding those policies to an
|
|
26
|
+
application's policy chain.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.1.0",
|
|
3
|
+
"info": {
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"title": "AI Gateway API",
|
|
6
|
+
"description": "A unified API gateway for multiple AI providers. All OpenAI-compatible ops are served under /{app_id}/v1/*."
|
|
7
|
+
},
|
|
8
|
+
"paths": {
|
|
9
|
+
"/:app_id/v1/(.*)": {
|
|
10
|
+
"x-zuplo-path": {
|
|
11
|
+
"pathMode": "url-pattern"
|
|
12
|
+
},
|
|
13
|
+
"get,post,delete": {
|
|
14
|
+
"summary": "AI Gateway catch-all",
|
|
15
|
+
"description": "Routes AI requests under /{app_id}/v1/* to the AI Gateway handler. The app_id path segment must match the API key's configuration id. Supported suffixes: /v1/chat/completions, /v1/embeddings, /v1/messages, /v1/responses and its sub-resources.",
|
|
16
|
+
"operationId": "aiGatewayCatchAll",
|
|
17
|
+
"responses": {
|
|
18
|
+
"200": {
|
|
19
|
+
"description": "Successful AI Gateway response"
|
|
20
|
+
},
|
|
21
|
+
"400": {
|
|
22
|
+
"description": "Bad request"
|
|
23
|
+
},
|
|
24
|
+
"401": {
|
|
25
|
+
"description": "Unauthorized"
|
|
26
|
+
},
|
|
27
|
+
"403": {
|
|
28
|
+
"description": "Forbidden — API key does not match app_id"
|
|
29
|
+
},
|
|
30
|
+
"404": {
|
|
31
|
+
"description": "Unsupported AI Gateway endpoint"
|
|
32
|
+
},
|
|
33
|
+
"500": {
|
|
34
|
+
"description": "Internal server error"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"x-zuplo-route": {
|
|
38
|
+
"corsPolicy": "none",
|
|
39
|
+
"handler": {
|
|
40
|
+
"export": "aiGatewayHandlerV2",
|
|
41
|
+
"module": "$import(@zuplo/runtime)",
|
|
42
|
+
"options": {}
|
|
43
|
+
},
|
|
44
|
+
"policies": {
|
|
45
|
+
"inbound": [
|
|
46
|
+
"ai-gateway-auth-v2-inbound",
|
|
47
|
+
"ai-gateway-configuration-executor-v2-inbound"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
{
|
|
2
|
+
"policies": [
|
|
3
|
+
{
|
|
4
|
+
"handler": {
|
|
5
|
+
"export": "AIGatewayAuthV2InboundPolicy",
|
|
6
|
+
"module": "$import(@zuplo/runtime)",
|
|
7
|
+
"options": {}
|
|
8
|
+
},
|
|
9
|
+
"name": "ai-gateway-auth-v2-inbound",
|
|
10
|
+
"policyType": "ai-gateway-auth-v2"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"handler": {
|
|
14
|
+
"export": "AIGatewayConfigurationExecutorV2InboundPolicy",
|
|
15
|
+
"module": "$import(@zuplo/runtime)",
|
|
16
|
+
"options": {}
|
|
17
|
+
},
|
|
18
|
+
"name": "ai-gateway-configuration-executor-v2-inbound",
|
|
19
|
+
"policyType": "ai-gateway-configuration-executor-v2"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"handler": {
|
|
23
|
+
"export": "AIGatewayMeteringInboundPolicy",
|
|
24
|
+
"module": "$import(@zuplo/runtime)",
|
|
25
|
+
"options": {}
|
|
26
|
+
},
|
|
27
|
+
"name": "ai-gateway-metering",
|
|
28
|
+
"policyType": "ai-gateway-metering-inbound"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"handler": {
|
|
32
|
+
"export": "AIGatewayModelFilteringV2InboundPolicy",
|
|
33
|
+
"module": "$import(@zuplo/runtime)",
|
|
34
|
+
"options": {
|
|
35
|
+
"models": {
|
|
36
|
+
"completions": {
|
|
37
|
+
"allowList": ["openai/gpt-4o-mini"]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"name": "ai-gateway-model-filtering-v2-inbound",
|
|
43
|
+
"policyType": "ai-gateway-model-filtering-v2"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"handler": {
|
|
47
|
+
"export": "AIGatewayFallbackModelV2InboundPolicy",
|
|
48
|
+
"module": "$import(@zuplo/runtime)",
|
|
49
|
+
"options": {
|
|
50
|
+
"models": {
|
|
51
|
+
"completions": {
|
|
52
|
+
"fallback": "openai/gpt-4o-mini"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"fallbackTimeoutSeconds": 60
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"name": "ai-gateway-fallback-model-v2-inbound",
|
|
59
|
+
"policyType": "ai-gateway-fallback-model-v2"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"handler": {
|
|
63
|
+
"export": "AIGatewaySemanticCacheV2InboundPolicy",
|
|
64
|
+
"module": "$import(@zuplo/runtime)",
|
|
65
|
+
"options": {
|
|
66
|
+
"semanticTolerance": 0.4,
|
|
67
|
+
"expirationSecondsTtl": 3600
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"name": "ai-gateway-semantic-cache-v2-inbound",
|
|
71
|
+
"policyType": "ai-gateway-semantic-cache-v2-inbound"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"handler": {
|
|
75
|
+
"export": "AkamaiAIFirewallV2InboundPolicy",
|
|
76
|
+
"module": "$import(@zuplo/runtime)",
|
|
77
|
+
"options": {
|
|
78
|
+
"configurationId": "$env(AKAMAI_FIREWALL_CONFIGURATION_ID)",
|
|
79
|
+
"api-key": "$env(AKAMAI_FIREWALL_API_KEY)"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"name": "akamai-ai-firewall-v2-inbound",
|
|
83
|
+
"policyType": "akamai-ai-firewall-v2-inbound"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"handler": {
|
|
87
|
+
"export": "CometOpikTracingV2InboundPolicy",
|
|
88
|
+
"module": "$import(@zuplo/runtime)",
|
|
89
|
+
"options": {
|
|
90
|
+
"apiKey": "$env(OPIK_API_KEY)",
|
|
91
|
+
"projectName": "$env(OPIK_PROJECT_NAME)",
|
|
92
|
+
"workspace": "$env(OPIK_WORKSPACE)"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"name": "comet-opik-tracing-v2-inbound",
|
|
96
|
+
"policyType": "comet-opik-tracing-v2-inbound"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"handler": {
|
|
100
|
+
"export": "GalileoTracingV2InboundPolicy",
|
|
101
|
+
"module": "$import(@zuplo/runtime)",
|
|
102
|
+
"options": {
|
|
103
|
+
"apiKey": "$env(GALILEO_API_KEY)",
|
|
104
|
+
"projectId": "$env(GALILEO_PROJECT_ID)",
|
|
105
|
+
"logStreamId": "$env(GALILEO_LOG_STREAM_ID)"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
"name": "galileo-tracing-v2-inbound",
|
|
109
|
+
"policyType": "galileo-tracing-v2-inbound"
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Optional credentials for the pre-declared AI Gateway policies in
|
|
2
|
+
# config/policies.json. Only required when an application's policy chain
|
|
3
|
+
# selects the matching policy. Configure these as environment variables on
|
|
4
|
+
# your Zuplo project (Settings -> Environment Variables) for deployed
|
|
5
|
+
# environments.
|
|
6
|
+
|
|
7
|
+
# akamai-ai-firewall-v2-inbound
|
|
8
|
+
AKAMAI_FIREWALL_CONFIGURATION_ID=
|
|
9
|
+
AKAMAI_FIREWALL_API_KEY=
|
|
10
|
+
|
|
11
|
+
# comet-opik-tracing-v2-inbound
|
|
12
|
+
OPIK_API_KEY=
|
|
13
|
+
OPIK_PROJECT_NAME=
|
|
14
|
+
OPIK_WORKSPACE=
|
|
15
|
+
|
|
16
|
+
# galileo-tracing-v2-inbound
|
|
17
|
+
GALILEO_API_KEY=
|
|
18
|
+
GALILEO_PROJECT_ID=
|
|
19
|
+
GALILEO_LOG_STREAM_ID=
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": ["modules/**/*", ".zuplo/**/*"],
|
|
3
|
+
"exclude": ["./node_modules", "./dist", "./docs", "./examples"],
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"target": "ES2022",
|
|
7
|
+
"lib": ["ESNext", "WebWorker", "Webworker.Iterable"],
|
|
8
|
+
"preserveConstEnums": true,
|
|
9
|
+
"moduleResolution": "Bundler",
|
|
10
|
+
"useUnknownInCatchVariables": false,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"importHelpers": true,
|
|
13
|
+
"removeComments": true,
|
|
14
|
+
"esModuleInterop": true,
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
"skipLibCheck": true,
|
|
17
|
+
"strictNullChecks": true,
|
|
18
|
+
"experimentalDecorators": true
|
|
19
|
+
}
|
|
20
|
+
}
|