@dbx-tools/shared-model-gateway 0.9.40 → 0.9.43
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/README.md +22 -0
- package/exports.ts +1 -0
- package/index.ts +5 -1
- package/lib/exports.d.ts +1 -0
- package/lib/exports.js +2 -1
- package/lib/index.d.ts +5 -1
- package/lib/index.js +5 -2
- package/lib/src/contracts.d.ts +72 -25
- package/lib/src/contracts.js +87 -73
- package/lib/src/models.d.ts +103 -11
- package/lib/src/models.js +2 -1
- package/lib/src/options.d.ts +42 -0
- package/lib/src/options.js +44 -0
- package/lib/src/upstream.d.ts +12 -0
- package/lib/src/upstream.js +32 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -2
- package/src/contracts.ts +107 -87
- package/src/models.ts +1 -0
- package/src/options.ts +59 -0
- package/src/upstream.ts +35 -0
package/src/contracts.ts
CHANGED
|
@@ -7,105 +7,125 @@
|
|
|
7
7
|
import { model } from "@dbx-tools/shared-model";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
"anthropic-messages",
|
|
15
|
-
"openai-embeddings",
|
|
16
|
-
]);
|
|
17
|
-
/** Client protocol accepted by the gateway. */
|
|
10
|
+
export const ClientProtocolSchema = z
|
|
11
|
+
.enum(["openai-responses", "openai-chat", "anthropic-messages", "openai-embeddings"])
|
|
12
|
+
.describe("Client protocol accepted by the gateway.");
|
|
13
|
+
|
|
18
14
|
export type ClientProtocol = z.infer<typeof ClientProtocolSchema>;
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
])
|
|
30
|
-
|
|
16
|
+
export const UpstreamProtocolSchema = z
|
|
17
|
+
.enum([
|
|
18
|
+
"databricks-ai-gateway-codex",
|
|
19
|
+
"databricks-responses",
|
|
20
|
+
"databricks-open-responses",
|
|
21
|
+
"databricks-chat",
|
|
22
|
+
"databricks-anthropic",
|
|
23
|
+
"databricks-embeddings",
|
|
24
|
+
"ai-sdk",
|
|
25
|
+
])
|
|
26
|
+
.describe("Upstream protocol selected by capability routing.");
|
|
27
|
+
|
|
31
28
|
export type UpstreamProtocol = z.infer<typeof UpstreamProtocolSchema>;
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
30
|
+
export const ModelCapabilitiesSchema = z
|
|
31
|
+
.object({
|
|
32
|
+
responses: z.boolean().describe("True when the model can serve the Databricks Responses API."),
|
|
33
|
+
openResponses: z.boolean().describe("True when the model can serve OpenAI Responses."),
|
|
34
|
+
chat: z.boolean().describe("True when the model can serve Chat Completions."),
|
|
35
|
+
anthropic: z.boolean().describe("True when the model can serve Anthropic Messages."),
|
|
36
|
+
embeddings: z.boolean().describe("True when the model can serve embeddings."),
|
|
37
|
+
aiGatewayCodex: z
|
|
38
|
+
.boolean()
|
|
39
|
+
.describe("True when the model is reachable through AI Gateway Codex."),
|
|
40
|
+
tools: z.boolean().describe("True when the model accepts tools."),
|
|
41
|
+
reasoning: z.boolean().describe("True when the model accepts reasoning effort."),
|
|
42
|
+
streaming: z.boolean().describe("True when the model can stream tokens."),
|
|
43
|
+
parallelTools: z.boolean().describe("True when the model can run multiple tools in one turn."),
|
|
44
|
+
customTools: z.boolean().describe("True when the model accepts custom tool definitions."),
|
|
45
|
+
structuredOutput: z.boolean().describe("True when the model can return structured output."),
|
|
46
|
+
webSearch: z.boolean().describe("True when the model can use web search."),
|
|
47
|
+
})
|
|
48
|
+
.describe("Capabilities used to determine whether a request can remain on a direct path.");
|
|
49
|
+
|
|
50
50
|
export type ModelCapabilities = z.infer<typeof ModelCapabilitiesSchema>;
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
52
|
+
export const ModelTargetSchema = z
|
|
53
|
+
.object({
|
|
54
|
+
id: z.string().min(1).describe("Canonical model id advertised by the gateway."),
|
|
55
|
+
aliases: z.array(z.string().min(1)).describe("Additional names that resolve to this model."),
|
|
56
|
+
displayName: z.string().min(1).describe("Human-readable label shown to clients."),
|
|
57
|
+
family: z.string().optional().describe("Detected model family used for grouping."),
|
|
58
|
+
modelServiceName: z
|
|
59
|
+
.string()
|
|
60
|
+
.optional()
|
|
61
|
+
.describe("Canonical model-service name for metadata lookup."),
|
|
62
|
+
endpoint: model.ServingEndpointSummarySchema.optional().describe(
|
|
63
|
+
"Normalized serving endpoint backing this target, when discovered.",
|
|
64
|
+
),
|
|
65
|
+
capabilities: ModelCapabilitiesSchema.describe(
|
|
66
|
+
"Protocol and feature capabilities for this target.",
|
|
67
|
+
),
|
|
68
|
+
reasoningEfforts: z
|
|
69
|
+
.array(model.ReasoningEffortSchema)
|
|
70
|
+
.describe("Reasoning effort values this target accepts."),
|
|
71
|
+
})
|
|
72
|
+
.describe("One discovered model plus every alias accepted by the gateway.");
|
|
73
|
+
|
|
64
74
|
export type ModelTarget = z.infer<typeof ModelTargetSchema>;
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
export const RequestedFeaturesSchema = z
|
|
77
|
+
.object({
|
|
78
|
+
background: z.boolean().describe("True when the client requested a background run."),
|
|
79
|
+
customTools: z.boolean().describe("True when the request includes custom tools."),
|
|
80
|
+
parallelTools: z.boolean().describe("True when the request asks for parallel tool calls."),
|
|
81
|
+
previousResponse: z.boolean().describe("True when the request continues a stored response."),
|
|
82
|
+
reasoning: z.boolean().describe("True when the request sets reasoning effort."),
|
|
83
|
+
storage: z
|
|
84
|
+
.boolean()
|
|
85
|
+
.describe("True when the request asks the provider to persist the response."),
|
|
86
|
+
structuredOutput: z.boolean().describe("True when the request requires structured output."),
|
|
87
|
+
tools: z.boolean().describe("True when the request includes tools."),
|
|
88
|
+
unsupportedOpenResponsesTools: z
|
|
89
|
+
.boolean()
|
|
90
|
+
.describe("True when tools cannot ride the Open Responses fast path."),
|
|
91
|
+
webSearch: z.boolean().describe("True when the request includes web search."),
|
|
92
|
+
})
|
|
93
|
+
.describe("Request features that constrain direct protocol routes.");
|
|
94
|
+
|
|
80
95
|
export type RequestedFeatures = z.infer<typeof RequestedFeaturesSchema>;
|
|
81
96
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
})
|
|
91
|
-
|
|
97
|
+
export const GatewayRouteSchema = z
|
|
98
|
+
.object({
|
|
99
|
+
clientProtocol: ClientProtocolSchema.describe("Protocol the caller used."),
|
|
100
|
+
upstreamProtocol: UpstreamProtocolSchema.describe("Protocol selected for the upstream call."),
|
|
101
|
+
target: ModelTargetSchema.describe("Discovered model this request will invoke."),
|
|
102
|
+
upstreamModel: z.string().min(1).describe("Model identifier sent to the upstream provider."),
|
|
103
|
+
translateRequest: z.boolean().describe("True when the request body must be translated."),
|
|
104
|
+
translateResponse: z.boolean().describe("True when the response body must be translated."),
|
|
105
|
+
})
|
|
106
|
+
.describe("Deterministic route selected for one gateway request.");
|
|
107
|
+
|
|
92
108
|
export type GatewayRoute = z.infer<typeof GatewayRouteSchema>;
|
|
93
109
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
110
|
+
export const ModelCapabilityOverrideSchema = z
|
|
111
|
+
.object({
|
|
112
|
+
model: z.string().min(1).describe("Model id or alias whose capabilities are overridden."),
|
|
113
|
+
capabilities: ModelCapabilitiesSchema.partial().describe(
|
|
114
|
+
"Capability flags to merge onto the discovered model.",
|
|
115
|
+
),
|
|
116
|
+
})
|
|
117
|
+
.describe("Typed capability changes for one dynamically discovered model.");
|
|
118
|
+
|
|
100
119
|
export type ModelCapabilityOverride = z.infer<typeof ModelCapabilityOverrideSchema>;
|
|
101
120
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
})
|
|
110
|
-
|
|
121
|
+
export const ResolveRouteInputSchema = z
|
|
122
|
+
.object({
|
|
123
|
+
clientProtocol: ClientProtocolSchema.describe("Protocol the caller used."),
|
|
124
|
+
requestedModel: z.string().min(1).describe("Model id or alias requested by the caller."),
|
|
125
|
+
originator: z.string().optional().describe("Optional Originator header, such as codex."),
|
|
126
|
+
features: RequestedFeaturesSchema.describe("Request features that constrain routing."),
|
|
127
|
+
target: ModelTargetSchema.describe("Discovered model selected for this request."),
|
|
128
|
+
})
|
|
129
|
+
.describe("Inputs required to select one deterministic gateway route.");
|
|
130
|
+
|
|
111
131
|
export type ResolveRouteInput = z.infer<typeof ResolveRouteInputSchema>;
|
package/src/models.ts
CHANGED
|
@@ -17,6 +17,7 @@ export const OpenAIModelCapabilitiesSchema = z.object({
|
|
|
17
17
|
embeddings: z.boolean(),
|
|
18
18
|
ai_gateway_codex: z.boolean(),
|
|
19
19
|
streaming: z.boolean(),
|
|
20
|
+
web_search: z.boolean(),
|
|
20
21
|
});
|
|
21
22
|
/** Capabilities published with an OpenAI-compatible model entry. */
|
|
22
23
|
export type OpenAIModelCapabilities = z.infer<typeof OpenAIModelCapabilitiesSchema>;
|
package/src/options.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe model-gateway runtime and CLI configuration.
|
|
3
|
+
*
|
|
4
|
+
* Field names and descriptions are the single source for derived Commander
|
|
5
|
+
* flags, environment names, generated help, JavaScript callers, and services.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { options } from "@dbx-tools/shared-core";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
export const ModelGatewayOptionsSchema = z
|
|
14
|
+
.object({
|
|
15
|
+
listen: options
|
|
16
|
+
.listenAddressSchema({ port: 4000, loopback: true })
|
|
17
|
+
.describe("Loopback listener address."),
|
|
18
|
+
profile: options.DatabricksOptionsSchema.shape.profile.describe(
|
|
19
|
+
"Databricks profile used for model discovery and requests.",
|
|
20
|
+
),
|
|
21
|
+
bodyLimit: z
|
|
22
|
+
.string()
|
|
23
|
+
.trim()
|
|
24
|
+
.min(1)
|
|
25
|
+
.default("100mb")
|
|
26
|
+
.describe("Maximum JSON request body size."),
|
|
27
|
+
})
|
|
28
|
+
.strict()
|
|
29
|
+
.describe("Model-gateway server configuration.");
|
|
30
|
+
|
|
31
|
+
export const ModelGatewayCliOptionsSchema = ModelGatewayOptionsSchema.extend({
|
|
32
|
+
runtimeInfo: z.boolean().default(false).describe("Print runtime implementation metadata."),
|
|
33
|
+
})
|
|
34
|
+
.refine((options) => options.listen.port > 0, {
|
|
35
|
+
message: "Port must be an integer from 1 through 65535.",
|
|
36
|
+
path: ["listen"],
|
|
37
|
+
})
|
|
38
|
+
.describe("Model-gateway command-line configuration.");
|
|
39
|
+
|
|
40
|
+
export type ModelGatewayOptions = z.input<typeof ModelGatewayOptionsSchema>;
|
|
41
|
+
|
|
42
|
+
export type ResolvedModelGatewayOptions = z.output<typeof ModelGatewayOptionsSchema>;
|
|
43
|
+
|
|
44
|
+
export type ModelGatewayCliOptions = z.output<typeof ModelGatewayCliOptionsSchema>;
|
|
45
|
+
|
|
46
|
+
/** Defaults parsed from the owning runtime schema. */
|
|
47
|
+
export const MODEL_GATEWAY_DEFAULTS = Object.freeze(ModelGatewayOptionsSchema.parse({}));
|
|
48
|
+
|
|
49
|
+
/** Validate and default model-gateway server options. */
|
|
50
|
+
export function resolveModelGatewayOptions(
|
|
51
|
+
options: ModelGatewayOptions = {},
|
|
52
|
+
): ResolvedModelGatewayOptions {
|
|
53
|
+
return ModelGatewayOptionsSchema.parse(options);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Validate and default model-gateway command-line options. */
|
|
57
|
+
export function resolveModelGatewayCliOptions(options: unknown): ModelGatewayCliOptions {
|
|
58
|
+
return ModelGatewayCliOptionsSchema.parse(options);
|
|
59
|
+
}
|
package/src/upstream.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe Databricks upstream URLs for deterministic gateway routes.
|
|
3
|
+
*
|
|
4
|
+
* This module owns direct-route URL construction for browser, edge, and Node
|
|
5
|
+
* consumers. Reuse {@link upstreamUrl} instead of duplicating Databricks model
|
|
6
|
+
* serving paths in transports or user interfaces.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { GatewayRoute } from "./contracts.ts";
|
|
12
|
+
|
|
13
|
+
/** Resolve the exact upstream URL for a deterministic direct route. */
|
|
14
|
+
export function upstreamUrl(host: string, route: GatewayRoute): string {
|
|
15
|
+
switch (route.upstreamProtocol) {
|
|
16
|
+
case "databricks-ai-gateway-codex":
|
|
17
|
+
return url(host, "/ai-gateway/codex/v1/responses");
|
|
18
|
+
case "databricks-responses":
|
|
19
|
+
return url(host, "/serving-endpoints/responses");
|
|
20
|
+
case "databricks-open-responses":
|
|
21
|
+
return url(host, "/serving-endpoints/open-responses");
|
|
22
|
+
case "databricks-chat":
|
|
23
|
+
return url(host, "/serving-endpoints/chat/completions");
|
|
24
|
+
case "databricks-anthropic":
|
|
25
|
+
return url(host, "/serving-endpoints/anthropic/v1/messages");
|
|
26
|
+
case "databricks-embeddings":
|
|
27
|
+
return url(host, `/serving-endpoints/${encodeURIComponent(route.upstreamModel)}/invocations`);
|
|
28
|
+
case "ai-sdk":
|
|
29
|
+
throw new Error("AI SDK routes do not use the direct Databricks transport");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function url(host: string, path: string): string {
|
|
34
|
+
return new URL(path, `${host.replace(/\/$/, "")}/`).toString();
|
|
35
|
+
}
|