@dbx-tools/appkit-model-gateway 0.9.36

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.
Files changed (44) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +63 -0
  3. package/index.ts +28 -0
  4. package/lib/index.d.ts +24 -0
  5. package/lib/index.js +21 -0
  6. package/lib/scripts/copy-manifest.d.ts +1 -0
  7. package/lib/scripts/copy-manifest.js +14 -0
  8. package/lib/src/gateway.d.ts +29 -0
  9. package/lib/src/gateway.js +127 -0
  10. package/lib/src/manifest.json +13 -0
  11. package/lib/src/models.d.ts +10 -0
  12. package/lib/src/models.js +119 -0
  13. package/lib/src/plugin.d.ts +32 -0
  14. package/lib/src/plugin.js +70 -0
  15. package/lib/src/protocols/decode.d.ts +17 -0
  16. package/lib/src/protocols/decode.js +262 -0
  17. package/lib/src/protocols/encode.d.ts +18 -0
  18. package/lib/src/protocols/encode.js +498 -0
  19. package/lib/src/reasoning-adapt.d.ts +27 -0
  20. package/lib/src/reasoning-adapt.js +61 -0
  21. package/lib/src/registry.d.ts +32 -0
  22. package/lib/src/registry.js +167 -0
  23. package/lib/src/router.d.ts +18 -0
  24. package/lib/src/router.js +139 -0
  25. package/lib/src/routes.d.ts +14 -0
  26. package/lib/src/routes.js +158 -0
  27. package/lib/src/translation.d.ts +8 -0
  28. package/lib/src/translation.js +156 -0
  29. package/lib/src/transport.d.ts +19 -0
  30. package/lib/src/transport.js +168 -0
  31. package/lib/tsconfig.tsbuildinfo +1 -0
  32. package/package.json +150 -0
  33. package/src/gateway.ts +167 -0
  34. package/src/manifest.json +13 -0
  35. package/src/models.ts +152 -0
  36. package/src/plugin.ts +95 -0
  37. package/src/protocols/decode.ts +281 -0
  38. package/src/protocols/encode.ts +515 -0
  39. package/src/reasoning-adapt.ts +87 -0
  40. package/src/registry.ts +225 -0
  41. package/src/router.ts +174 -0
  42. package/src/routes.ts +181 -0
  43. package/src/translation.ts +178 -0
  44. package/src/transport.ts +182 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Reasoning-effort adaptation for gateway round trips.
3
+ *
4
+ * Proactively remaps client efforts onto the known ladder, then on a single
5
+ * unsupported-value 400 learns from the error and retries once with the
6
+ * updated ladder.
7
+ *
8
+ * @module
9
+ */
10
+ import { learnReasoningLevelsFromError, modelReasoningLevelsFor, } from "@dbx-tools/model/metadata";
11
+ import { adaptRequestReasoning, parseReasoningLevels, } from "@dbx-tools/model/reasoning-translation";
12
+ import { log } from "@dbx-tools/shared-core";
13
+ const logger = log.logger("appkit/model-gateway/reasoning");
14
+ /** Adapt a request body onto the current known ladder for `model`. */
15
+ export function adaptInferenceReasoning(model, body) {
16
+ const adapted = adaptRequestReasoning(body, modelReasoningLevelsFor(model));
17
+ if (adapted.changed) {
18
+ logger.debug("adapted reasoning effort before upstream", {
19
+ model,
20
+ effort: adapted.wireEffort,
21
+ });
22
+ }
23
+ return {
24
+ body: adapted.body,
25
+ wireEffort: adapted.wireEffort,
26
+ changed: adapted.changed,
27
+ };
28
+ }
29
+ /**
30
+ * On an unsupported-reasoning 400, learn once and optionally produce a
31
+ * remapped retry body. Returns `undefined` when no retry should occur.
32
+ */
33
+ export async function learnAndAdaptReasoningRetry(input) {
34
+ if (input.response.ok || input.response.status !== 400)
35
+ return undefined;
36
+ let errorBody;
37
+ try {
38
+ errorBody = JSON.parse(await input.response.clone().text());
39
+ }
40
+ catch {
41
+ return undefined;
42
+ }
43
+ if (parseReasoningLevels(errorBody).length === 0)
44
+ return undefined;
45
+ const levels = await learnReasoningLevelsFromError(input.model, errorBody);
46
+ logger.info("learned reasoning levels from upstream error", {
47
+ model: input.model,
48
+ levels,
49
+ });
50
+ const adapted = adaptRequestReasoning(input.body, levels);
51
+ if (adapted.wireEffort === undefined || adapted.wireEffort === input.previousWireEffort) {
52
+ return undefined;
53
+ }
54
+ logger.info("retrying with adapted reasoning effort", {
55
+ model: input.model,
56
+ from: input.previousWireEffort,
57
+ to: adapted.wireEffort,
58
+ });
59
+ return adapted.body;
60
+ }
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhc29uaW5nLWFkYXB0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JlYXNvbmluZy1hZGFwdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUVILE9BQU8sRUFDTCw2QkFBNkIsRUFDN0IsdUJBQXVCLEdBQ3hCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixvQkFBb0IsR0FDckIsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFN0MsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBUzVELHNFQUFzRTtBQUN0RSxNQUFNLFVBQVUsdUJBQXVCLENBQ3JDLEtBQWEsRUFDYixJQUF1QztJQUV2QyxNQUFNLE9BQU8sR0FBRyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUM1RSxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNwQixNQUFNLENBQUMsS0FBSyxDQUFDLDBDQUEwQyxFQUFFO1lBQ3ZELEtBQUs7WUFDTCxNQUFNLEVBQUUsT0FBTyxDQUFDLFVBQVU7U0FDM0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE9BQU87UUFDTCxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVO1FBQzlCLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTztLQUN6QixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsMkJBQTJCLENBQUMsS0FLakQ7SUFDQyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxLQUFLLEdBQUc7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUV6RSxJQUFJLFNBQWtCLENBQUM7SUFDdkIsSUFBSSxDQUFDO1FBQ0gsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCxJQUFJLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFFbkUsTUFBTSxNQUFNLEdBQUcsTUFBTSw2QkFBNkIsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzNFLE1BQU0sQ0FBQyxJQUFJLENBQUMsOENBQThDLEVBQUU7UUFDMUQsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO1FBQ2xCLE1BQU07S0FDUCxDQUFDLENBQUM7SUFFSCxNQUFNLE9BQU8sR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzFELElBQUksT0FBTyxDQUFDLFVBQVUsS0FBSyxTQUFTLElBQUksT0FBTyxDQUFDLFVBQVUsS0FBSyxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUN4RixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsTUFBTSxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsRUFBRTtRQUNwRCxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUs7UUFDbEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxrQkFBa0I7UUFDOUIsRUFBRSxFQUFFLE9BQU8sQ0FBQyxVQUFVO0tBQ3ZCLENBQUMsQ0FBQztJQUNILE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQztBQUN0QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZWFzb25pbmctZWZmb3J0IGFkYXB0YXRpb24gZm9yIGdhdGV3YXkgcm91bmQgdHJpcHMuXG4gKlxuICogUHJvYWN0aXZlbHkgcmVtYXBzIGNsaWVudCBlZmZvcnRzIG9udG8gdGhlIGtub3duIGxhZGRlciwgdGhlbiBvbiBhIHNpbmdsZVxuICogdW5zdXBwb3J0ZWQtdmFsdWUgNDAwIGxlYXJucyBmcm9tIHRoZSBlcnJvciBhbmQgcmV0cmllcyBvbmNlIHdpdGggdGhlXG4gKiB1cGRhdGVkIGxhZGRlci5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHtcbiAgbGVhcm5SZWFzb25pbmdMZXZlbHNGcm9tRXJyb3IsXG4gIG1vZGVsUmVhc29uaW5nTGV2ZWxzRm9yLFxufSBmcm9tIFwiQGRieC10b29scy9tb2RlbC9tZXRhZGF0YVwiO1xuaW1wb3J0IHtcbiAgYWRhcHRSZXF1ZXN0UmVhc29uaW5nLFxuICBwYXJzZVJlYXNvbmluZ0xldmVscyxcbn0gZnJvbSBcIkBkYngtdG9vbHMvbW9kZWwvcmVhc29uaW5nLXRyYW5zbGF0aW9uXCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiYXBwa2l0L21vZGVsLWdhdGV3YXkvcmVhc29uaW5nXCIpO1xuXG4vKiogUmVzdWx0IG9mIHRoZSBmaXJzdCBwcm9hY3RpdmUgYWRhcHRhdGlvbiBwYXNzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBZGFwdGVkSW5mZXJlbmNlQm9keSB7XG4gIHJlYWRvbmx5IGJvZHk6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcbiAgcmVhZG9ubHkgd2lyZUVmZm9ydD86IHN0cmluZztcbiAgcmVhZG9ubHkgY2hhbmdlZDogYm9vbGVhbjtcbn1cblxuLyoqIEFkYXB0IGEgcmVxdWVzdCBib2R5IG9udG8gdGhlIGN1cnJlbnQga25vd24gbGFkZGVyIGZvciBgbW9kZWxgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkYXB0SW5mZXJlbmNlUmVhc29uaW5nKFxuICBtb2RlbDogc3RyaW5nLFxuICBib2R5OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sXG4pOiBBZGFwdGVkSW5mZXJlbmNlQm9keSB7XG4gIGNvbnN0IGFkYXB0ZWQgPSBhZGFwdFJlcXVlc3RSZWFzb25pbmcoYm9keSwgbW9kZWxSZWFzb25pbmdMZXZlbHNGb3IobW9kZWwpKTtcbiAgaWYgKGFkYXB0ZWQuY2hhbmdlZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImFkYXB0ZWQgcmVhc29uaW5nIGVmZm9ydCBiZWZvcmUgdXBzdHJlYW1cIiwge1xuICAgICAgbW9kZWwsXG4gICAgICBlZmZvcnQ6IGFkYXB0ZWQud2lyZUVmZm9ydCxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGJvZHk6IGFkYXB0ZWQuYm9keSxcbiAgICB3aXJlRWZmb3J0OiBhZGFwdGVkLndpcmVFZmZvcnQsXG4gICAgY2hhbmdlZDogYWRhcHRlZC5jaGFuZ2VkLFxuICB9O1xufVxuXG4vKipcbiAqIE9uIGFuIHVuc3VwcG9ydGVkLXJlYXNvbmluZyA0MDAsIGxlYXJuIG9uY2UgYW5kIG9wdGlvbmFsbHkgcHJvZHVjZSBhXG4gKiByZW1hcHBlZCByZXRyeSBib2R5LiBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gbm8gcmV0cnkgc2hvdWxkIG9jY3VyLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbGVhcm5BbmRBZGFwdFJlYXNvbmluZ1JldHJ5KGlucHV0OiB7XG4gIHJlYWRvbmx5IG1vZGVsOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGJvZHk6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcbiAgcmVhZG9ubHkgcmVzcG9uc2U6IFJlc3BvbnNlO1xuICByZWFkb25seSBwcmV2aW91c1dpcmVFZmZvcnQ/OiBzdHJpbmc7XG59KTogUHJvbWlzZTxSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4gfCB1bmRlZmluZWQ+IHtcbiAgaWYgKGlucHV0LnJlc3BvbnNlLm9rIHx8IGlucHV0LnJlc3BvbnNlLnN0YXR1cyAhPT0gNDAwKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGxldCBlcnJvckJvZHk6IHVua25vd247XG4gIHRyeSB7XG4gICAgZXJyb3JCb2R5ID0gSlNPTi5wYXJzZShhd2FpdCBpbnB1dC5yZXNwb25zZS5jbG9uZSgpLnRleHQoKSk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAocGFyc2VSZWFzb25pbmdMZXZlbHMoZXJyb3JCb2R5KS5sZW5ndGggPT09IDApIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgbGV2ZWxzID0gYXdhaXQgbGVhcm5SZWFzb25pbmdMZXZlbHNGcm9tRXJyb3IoaW5wdXQubW9kZWwsIGVycm9yQm9keSk7XG4gIGxvZ2dlci5pbmZvKFwibGVhcm5lZCByZWFzb25pbmcgbGV2ZWxzIGZyb20gdXBzdHJlYW0gZXJyb3JcIiwge1xuICAgIG1vZGVsOiBpbnB1dC5tb2RlbCxcbiAgICBsZXZlbHMsXG4gIH0pO1xuXG4gIGNvbnN0IGFkYXB0ZWQgPSBhZGFwdFJlcXVlc3RSZWFzb25pbmcoaW5wdXQuYm9keSwgbGV2ZWxzKTtcbiAgaWYgKGFkYXB0ZWQud2lyZUVmZm9ydCA9PT0gdW5kZWZpbmVkIHx8IGFkYXB0ZWQud2lyZUVmZm9ydCA9PT0gaW5wdXQucHJldmlvdXNXaXJlRWZmb3J0KSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGxvZ2dlci5pbmZvKFwicmV0cnlpbmcgd2l0aCBhZGFwdGVkIHJlYXNvbmluZyBlZmZvcnRcIiwge1xuICAgIG1vZGVsOiBpbnB1dC5tb2RlbCxcbiAgICBmcm9tOiBpbnB1dC5wcmV2aW91c1dpcmVFZmZvcnQsXG4gICAgdG86IGFkYXB0ZWQud2lyZUVmZm9ydCxcbiAgfSk7XG4gIHJldHVybiBhZGFwdGVkLmJvZHk7XG59XG4iXX0=
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Request-scoped Databricks model discovery for the AppKit gateway.
3
+ *
4
+ * @module
5
+ */
6
+ import { type ResolveModelInput } from "@dbx-tools/shared-model/contracts";
7
+ import type { ModelCapabilityOverride, ModelTarget } from "@dbx-tools/shared-model-gateway";
8
+ /** Resolution controls passed through to the model policy owner. */
9
+ export type ModelRegistryResolveOptions = Pick<ResolveModelInput, "modelClass" | "requiresTools">;
10
+ /** Dynamic model catalogue used by request routing and model-list responses. */
11
+ export interface ModelRegistry {
12
+ list(): Promise<ModelTarget[]>;
13
+ search(query: string): Promise<ModelTarget[]>;
14
+ resolve(model: string, options?: ModelRegistryResolveOptions): Promise<ModelTarget | undefined>;
15
+ refresh(): Promise<void>;
16
+ }
17
+ /** Configuration for {@link DatabricksModelRegistry}. */
18
+ export interface ModelRegistryOptions {
19
+ readonly ttlMs?: number;
20
+ readonly overrides?: readonly ModelCapabilityOverride[];
21
+ }
22
+ /** Model registry backed by the active AppKit execution context. */
23
+ export declare class DatabricksModelRegistry implements ModelRegistry {
24
+ private readonly ttlMs;
25
+ private readonly overrides;
26
+ constructor(options?: ModelRegistryOptions);
27
+ list(): Promise<ModelTarget[]>;
28
+ resolve(model: string, options?: ModelRegistryResolveOptions): Promise<ModelTarget | undefined>;
29
+ search(query: string): Promise<ModelTarget[]>;
30
+ refresh(): Promise<void>;
31
+ private target;
32
+ }
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Request-scoped Databricks model discovery for the AppKit gateway.
3
+ *
4
+ * @module
5
+ */
6
+ import { getExecutionContext } from "@databricks/appkit";
7
+ import { metadata, modelCatalog, policy, resolve as modelResolve } from "@dbx-tools/model";
8
+ import { log } from "@dbx-tools/shared-core";
9
+ import { ModelClass, } from "@dbx-tools/shared-model/contracts";
10
+ const DEFAULT_CACHE_TTL_MS = 60_000;
11
+ const logger = log.logger("appkit/model-gateway/registry");
12
+ /** Model registry backed by the active AppKit execution context. */
13
+ export class DatabricksModelRegistry {
14
+ ttlMs;
15
+ overrides;
16
+ constructor(options = {}) {
17
+ this.ttlMs = positiveTtl(options.ttlMs);
18
+ this.overrides = options.overrides ?? [];
19
+ }
20
+ async list() {
21
+ const context = await registryContext();
22
+ logger.debug("loading catalogue", { host: context.host, ttlMs: this.ttlMs });
23
+ const endpoints = await modelCatalog.listServingEndpoints(context.client, context.host, {
24
+ cacheIdentity: context.identity,
25
+ ttlMs: this.ttlMs,
26
+ });
27
+ const targets = endpoints.map((endpoint) => this.target(endpoint));
28
+ logger.debug("loaded catalogue", {
29
+ endpointCount: endpoints.length,
30
+ host: context.host,
31
+ targetCount: targets.length,
32
+ });
33
+ return targets;
34
+ }
35
+ async resolve(model, options = {}) {
36
+ const requested = unqualifiedModel(model);
37
+ const targets = await this.list();
38
+ const exact = targets.find((target) => target.aliases.some((alias) => alias.localeCompare(requested, undefined, { sensitivity: "accent" }) === 0));
39
+ if (exact && matchesResolveOptions(exact, options)) {
40
+ logger.debug("resolved exact model", { requested, resolved: exact.id });
41
+ return exact;
42
+ }
43
+ const endpoints = targets
44
+ .map((target) => target.endpoint)
45
+ .filter((endpoint) => endpoint !== undefined);
46
+ const resolved = modelResolve.resolveModel(endpoints, {
47
+ explicit: requested,
48
+ ...options,
49
+ });
50
+ const target = targets.find((candidate) => candidate.id === resolved.modelId);
51
+ logger.debug("resolved fuzzy model", {
52
+ requested,
53
+ resolved: target?.id,
54
+ source: resolved.source,
55
+ });
56
+ return target;
57
+ }
58
+ async search(query) {
59
+ const targets = await this.list();
60
+ const byId = new Map(targets.map((target) => [target.id, target]));
61
+ const endpoints = targets
62
+ .map((target) => target.endpoint)
63
+ .filter((endpoint) => endpoint !== undefined);
64
+ const ranked = [
65
+ ...modelResolve.lookupModels(endpoints, { search: query }),
66
+ ...modelResolve.lookupModels(endpoints, {
67
+ search: query,
68
+ modelClass: ModelClass.Embedding,
69
+ }),
70
+ ].sort((left, right) => (left.score ?? 0) - (right.score ?? 0));
71
+ return ranked
72
+ .map(({ endpoint }) => byId.get(endpoint.name))
73
+ .filter((target) => target !== undefined)
74
+ .filter((target, index, all) => all.findIndex((candidate) => candidate.id === target.id) === index);
75
+ }
76
+ async refresh() {
77
+ const context = await registryContext();
78
+ logger.debug("clearing catalogue", { host: context.host });
79
+ await modelCatalog.clearServingEndpointsCache(context.host, context.identity);
80
+ await modelCatalog.listServingEndpoints(context.client, context.host, {
81
+ cacheIdentity: context.identity,
82
+ ttlMs: this.ttlMs,
83
+ });
84
+ logger.debug("refreshed catalogue", { host: context.host });
85
+ }
86
+ target(endpoint) {
87
+ const published = metadata.modelCapabilitiesFor(endpoint);
88
+ const family = endpoint.family?.toLowerCase();
89
+ const openAiFamily = family === "gpt" || family === "openai" || endpoint.name.includes("codex");
90
+ const modelServiceName = normalizedModelServiceName(endpoint.modelServiceName);
91
+ const embeddings = endpoint.class === ModelClass.Embedding || endpoint.task === "llm/v1/embeddings";
92
+ const capabilities = {
93
+ responses: !embeddings && (openAiFamily || published.responses),
94
+ openResponses: !embeddings && !openAiFamily,
95
+ chat: !embeddings,
96
+ anthropic: family === "claude",
97
+ embeddings,
98
+ aiGatewayCodex: !embeddings && Boolean(modelServiceName) && family !== "claude" && family !== "gemini",
99
+ tools: endpoint.supportsTools === true,
100
+ reasoning: policy.modelReasoningEfforts(endpoint.name).length > 0,
101
+ streaming: true,
102
+ parallelTools: endpoint.supportsTools === true,
103
+ customTools: published.applyPatch || endpoint.name.includes("codex"),
104
+ structuredOutput: true,
105
+ webSearch: published.webSearch,
106
+ };
107
+ const aliases = new Set([
108
+ endpoint.name,
109
+ endpoint.displayName,
110
+ endpoint.modelServiceName,
111
+ modelServiceName,
112
+ ...Object.values(endpoint.serviceNames ?? {}),
113
+ ].filter((value) => Boolean(value?.trim())));
114
+ const override = this.overrides.find((candidate) => candidate.model === endpoint.name ||
115
+ [...aliases].some((alias) => alias === candidate.model));
116
+ return {
117
+ id: endpoint.name,
118
+ aliases: [...aliases],
119
+ displayName: endpoint.displayName ?? endpoint.name,
120
+ ...(endpoint.family ? { family: endpoint.family } : {}),
121
+ ...(modelServiceName ? { modelServiceName } : {}),
122
+ endpoint,
123
+ capabilities: { ...capabilities, ...override?.capabilities },
124
+ reasoningEfforts: endpoint.reasoningEfforts ?? [],
125
+ };
126
+ }
127
+ }
128
+ async function registryContext() {
129
+ const context = getExecutionContext();
130
+ const host = (await context.client.config.getHost()).toString();
131
+ return {
132
+ client: context.client,
133
+ host,
134
+ identity: "userId" in context ? context.userId : context.serviceUserId,
135
+ };
136
+ }
137
+ function unqualifiedModel(model) {
138
+ return model.trim().replace(/^(?:dbx|databricks)\//i, "");
139
+ }
140
+ function positiveTtl(value = DEFAULT_CACHE_TTL_MS) {
141
+ if (!Number.isFinite(value) || value <= 0) {
142
+ throw new Error("Model registry ttlMs must be a positive finite number");
143
+ }
144
+ return value;
145
+ }
146
+ function normalizedModelServiceName(value) {
147
+ const normalized = value?.trim().replace(/^databricks\//, "");
148
+ if (!normalized)
149
+ return undefined;
150
+ if (normalized.startsWith("system.ai.databricks-")) {
151
+ return `system.ai.${normalized.slice("system.ai.databricks-".length)}`;
152
+ }
153
+ if (normalized.startsWith("databricks-")) {
154
+ return `system.ai.${normalized.slice("databricks-".length)}`;
155
+ }
156
+ return normalized;
157
+ }
158
+ function matchesResolveOptions(target, options) {
159
+ if (options.requiresTools && !target.capabilities.tools)
160
+ return false;
161
+ if (options.modelClass === ModelClass.Embedding)
162
+ return target.capabilities.embeddings;
163
+ if (options.modelClass !== undefined)
164
+ return target.capabilities.chat;
165
+ return true;
166
+ }
167
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVnaXN0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxtQkFBbUIsRUFBd0IsTUFBTSxvQkFBb0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsT0FBTyxJQUFJLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzNGLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM3QyxPQUFPLEVBQ0wsVUFBVSxHQUdYLE1BQU0sbUNBQW1DLENBQUM7QUFPM0MsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFDcEMsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0FBeUIzRCxvRUFBb0U7QUFDcEUsTUFBTSxPQUFPLHVCQUF1QjtJQUNqQixLQUFLLENBQVM7SUFDZCxTQUFTLENBQXFDO0lBRS9ELFlBQVksVUFBZ0MsRUFBRTtRQUM1QyxJQUFJLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBRUQsS0FBSyxDQUFDLElBQUk7UUFDUixNQUFNLE9BQU8sR0FBRyxNQUFNLGVBQWUsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDN0UsTUFBTSxTQUFTLEdBQUcsTUFBTSxZQUFZLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsSUFB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bnQiOlsiLyoqXG4gKiBSZXF1ZXN0LXNjb3BlZCBEYXRhYnJpY2tzIG1vZGVsIGRpc2NvdmVyeSBmb3IgdGhlIEFwcEtpdCBnYXRld2F5LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBnZXRFeGVjdXRpb25Db250ZXh0LCB0eXBlIFdvcmtzcGFjZUNsaWVudCB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IG1ldGFkYXRhLCBtb2RlbENhdGFsb2csIHBvbGljeSwgcmVzb2x2ZSBhcyBtb2RlbFJlc29sdmUgfSBmcm9tIFwiQGRieC10b29scy9tb2RlbFwiO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7XG4gIE1vZGVsQ2xhc3MsXG4gIHR5cGUgUmVzb2x2ZU1vZGVsSW5wdXQsXG4gIHR5cGUgU2VydmluZ0VuZHBvaW50U3VtbWFyeSxcbn0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1vZGVsL2NvbnRyYWN0c1wiO1xuaW1wb3J0IHR5cGUge1xuICBNb2RlbENhcGFiaWxpdGllcyxcbiAgTW9kZWxDYXBhYmlsaXR5T3ZlcnJpZGUsXG4gIE1vZGVsVGFyZ2V0LFxufSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWwtZ2F0ZXdheVwiO1xuXG5jb25zdCBERUZBVUxUX0NBQ0hFX1RUTF9NUyA9IDYwXzAwMDtcbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJhcHBraXQvbW9kZWwtZ2F0ZXdheS9yZWdpc3RyeVwiKTtcblxuLyoqIFJlc29sdXRpb24gY29udHJvbHMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIG1vZGVsIHBvbGljeSBvd25lci4gKi9cbmV4cG9ydCB0eXBlIE1vZGVsUmVnaXN0cnlSZXNvbHZlT3B0aW9ucyA9IFBpY2s8UmVzb2x2ZU1vZGVsSW5wdXQsIFwibW9kZWxDbGFzc1wiIHwgXCJyZXF1aXJlc1Rvb2xzXCI+O1xuXG4vKiogRHluYW1pYyBtb2RlbCBjYXRhbG9ndWUgdXNlZCBieSByZXF1ZXN0IHJvdXRpbmcgYW5kIG1vZGVsLWxpc3QgcmVzcG9uc2VzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb2RlbFJlZ2lzdHJ5IHtcbiAgbGlzdCgpOiBQcm9taXNlPE1vZGVsVGFyZ2V0W10+O1xuICBzZWFyY2gocXVlcnk6IHN0cmluZyk6IFByb21pc2U8TW9kZWxUYXJnZXRbXT47XG4gIHJlc29sdmUobW9kZWw6IHN0cmluZywgb3B0aW9ucz86IE1vZGVsUmVnaXN0cnlSZXNvbHZlT3B0aW9ucyk6IFByb21pc2U8TW9kZWxUYXJnZXQgfCB1bmRlZmluZWQ+O1xuICByZWZyZXNoKCk6IFByb21pc2U8dm9pZD47XG59XG5cbi8qKiBDb25maWd1cmF0aW9uIGZvciB7QGxpbmsgRGF0YWJyaWNrc01vZGVsUmVnaXN0cnl9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb2RlbFJlZ2lzdHJ5T3B0aW9ucyB7XG4gIHJlYWRvbmx5IHR0bE1zPzogbnVtYmVyO1xuICByZWFkb25seSBvdmVycmlkZXM/OiByZWFkb25seSBNb2RlbENhcGFiaWxpdHlPdmVycmlkZVtdO1xufVxuXG5pbnRlcmZhY2UgUmVnaXN0cnlDb250ZXh0IHtcbiAgcmVhZG9ubHkgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQ7XG4gIHJlYWRvbmx5IGhvc3Q6IHN0cmluZztcbiAgcmVhZG9ubHkgaWRlbnRpdHk6IHN0cmluZztcbn1cblxuLyoqIE1vZGVsIHJlZ2lzdHJ5IGJhY2tlZCBieSB0aGUgYWN0aXZlIEFwcEtpdCBleGVjdXRpb24gY29udGV4dC4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhYnJpY2tzTW9kZWxSZWdpc3RyeSBpbXBsZW1lbnRzIE1vZGVsUmVnaXN0cnkge1xuICBwcml2YXRlIHJlYWRvbmx5IHR0bE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgb3ZlcnJpZGVzOiByZWFkb25seSBNb2RlbENhcGFiaWxpdHlPdmVycmlkZVtdO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE1vZGVsUmVnaXN0cnlPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLnR0bE1zID0gcG9zaXRpdmVUdGwob3B0aW9ucy50dGxNcyk7XG4gICAgdGhpcy5vdmVycmlkZXMgPSBvcHRpb25zLm92ZXJyaWRlcyA/PyBbXTtcbiAgfVxuXG4gIGFzeW5jIGxpc3QoKTogUHJvbWlzZTxNb2RlbFRhcmdldFtdPiB7XG4gICAgY29uc3QgY29udGV4dCA9IGF3YWl0IHJlZ2lzdHJ5Q29udGV4dCgpO1xuICAgIGxvZ2dlci5kZWJ1ZyhcImxvYWRpbmcgY2F0YWxvZ3VlXCIsIHsgaG9zdDogY29udGV4dC5ob3N0LCB0dGxNczogdGhpcy50dGxNcyB9KTtcbiAgICBjb25zdCBlbmRwb2ludHMgPSBhd2FpdCBtb2RlbENhdGFsb2cubGlzdFNlcnZpbmdFbmRwb2ludHMoY29udGV4dC5jbGllbnQsIGNvbnRleHQuaG9zdCwge1xuICAgICAgY2FjaGVJZGVudGl0eTogY29udGV4dC5pZGVudGl0eSxcbiAgICAgIHR0bE1zOiB0aGlzLnR0bE1zLFxuICAgIH0pO1xuICAgIGNvbnN0IHRhcmdldHMgPSBlbmRwb2ludHMubWFwKChlbmRwb2ludCkgPT4gdGhpcy50YXJnZXQoZW5kcG9pbnQpKTtcbiAgICBsb2dnZXIuZGVidWcoXCJsb2FkZWQgY2F0YWxvZ3VlXCIsIHtcbiAgICAgIGVuZHBvaW50Q291bnQ6IGVuZHBvaW50cy5sZW5ndGgsXG4gICAgICBob3N0OiBjb250ZXh0Lmhvc3QsXG4gICAgICB0YXJnZXRDb3VudDogdGFyZ2V0cy5sZW5ndGgsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRhcmdldHM7XG4gIH1cblxuICBhc3luYyByZXNvbHZlKFxuICAgIG1vZGVsOiBzdHJpbmcsXG4gICAgb3B0aW9uczogTW9kZWxSZWdpc3RyeVJlc29sdmVPcHRpb25zID0ge30sXG4gICk6IFByb21pc2U8TW9kZWxUYXJnZXQgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCByZXF1ZXN0ZWQgPSB1bnF1YWxpZmllZE1vZGVsKG1vZGVsKTtcbiAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgdGhpcy5saXN0KCk7XG4gICAgY29uc3QgZXhhY3QgPSB0YXJnZXRzLmZpbmQoKHRhcmdldCkgPT5cbiAgICAgIHRhcmdldC5hbGlhc2VzLnNvbWUoXG4gICAgICAgIChhbGlhcykgPT4gYWxpYXMubG9jYWxlQ29tcGFyZShyZXF1ZXN0ZWQsIHVuZGVmaW5lZCwgeyBzZW5zaXRpdml0eTogXCJhY2NlbnRcIiB9KSA9PT0gMCxcbiAgICAgICksXG4gICAgKTtcbiAgICBpZiAoZXhhY3QgJiYgbWF0Y2hlc1Jlc29sdmVPcHRpb25zKGV4YWN0LCBvcHRpb25zKSkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwicmVzb2x2ZWQgZXhhY3QgbW9kZWxcIiwgeyByZXF1ZXN0ZWQsIHJlc29sdmVkOiBleGFjdC5pZCB9KTtcbiAgICAgIHJldHVybiBleGFjdDtcbiAgICB9XG5cbiAgICBjb25zdCBlbmRwb2ludHMgPSB0YXJnZXRzXG4gICAgICAubWFwKCh0YXJnZXQpID0+IHRhcmdldC5lbmRwb2ludClcbiAgICAgIC5maWx0ZXIoKGVuZHBvaW50KTogZW5kcG9pbnQgaXMgU2VydmluZ0VuZHBvaW50U3VtbWFyeSA9PiBlbmRwb2ludCAhPT0gdW5kZWZpbmVkKTtcbiAgICBjb25zdCByZXNvbHZlZCA9IG1vZGVsUmVzb2x2ZS5yZXNvbHZlTW9kZWwoZW5kcG9pbnRzLCB7XG4gICAgICBleHBsaWNpdDogcmVxdWVzdGVkLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgICBjb25zdCB0YXJnZXQgPSB0YXJnZXRzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLmlkID09PSByZXNvbHZlZC5tb2RlbElkKTtcbiAgICBsb2dnZXIuZGVidWcoXCJyZXNvbHZlZCBmdXp6eSBtb2RlbFwiLCB7XG4gICAgICByZXF1ZXN0ZWQsXG4gICAgICByZXNvbHZlZDogdGFyZ2V0Py5pZCxcbiAgICAgIHNvdXJjZTogcmVzb2x2ZWQuc291cmNlLFxuICAgIH0pO1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cblxuICBhc3luYyBzZWFyY2gocXVlcnk6IHN0cmluZyk6IFByb21pc2U8TW9kZWxUYXJnZXRbXT4ge1xuICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCB0aGlzLmxpc3QoKTtcbiAgICBjb25zdCBieUlkID0gbmV3IE1hcCh0YXJnZXRzLm1hcCgodGFyZ2V0KSA9PiBbdGFyZ2V0LmlkLCB0YXJnZXRdKSk7XG4gICAgY29uc3QgZW5kcG9pbnRzID0gdGFyZ2V0c1xuICAgICAgLm1hcCgodGFyZ2V0KSA9PiB0YXJnZXQuZW5kcG9pbnQpXG4gICAgICAuZmlsdGVyKChlbmRwb2ludCk6IGVuZHBvaW50IGlzIFNlcnZpbmdFbmRwb2ludFN1bW1hcnkgPT4gZW5kcG9pbnQgIT09IHVuZGVmaW5lZCk7XG4gICAgY29uc3QgcmFua2VkID0gW1xuICAgICAgLi4ubW9kZWxSZXNvbHZlLmxvb2t1cE1vZGVscyhlbmRwb2ludHMsIHsgc2VhcmNoOiBxdWVyeSB9KSxcbiAgICAgIC4uLm1vZGVsUmVzb2x2ZS5sb29rdXBNb2RlbHMoZW5kcG9pbnRzLCB7XG4gICAgICAgIHNlYXJjaDogcXVlcnksXG4gICAgICAgIG1vZGVsQ2xhc3M6IE1vZGVsQ2xhc3MuRW1iZWRkaW5nLFxuICAgICAgfSksXG4gICAgXS5zb3J0KChsZWZ0LCByaWdodCkgPT4gKGxlZnQuc2NvcmUgPz8gMCkgLSAocmlnaHQuc2NvcmUgPz8gMCkpO1xuICAgIHJldHVybiByYW5rZWRcbiAgICAgIC5tYXAoKHsgZW5kcG9pbnQgfSkgPT4gYnlJZC5nZXQoZW5kcG9pbnQubmFtZSkpXG4gICAgICAuZmlsdGVyKCh0YXJnZXQpOiB0YXJnZXQgaXMgTW9kZWxUYXJnZXQgPT4gdGFyZ2V0ICE9PSB1bmRlZmluZWQpXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAodGFyZ2V0LCBpbmRleCwgYWxsKSA9PiBhbGwuZmluZEluZGV4KChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gdGFyZ2V0LmlkKSA9PT0gaW5kZXgsXG4gICAgICApO1xuICB9XG5cbiAgYXN5bmMgcmVmcmVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgcmVnaXN0cnlDb250ZXh0KCk7XG4gICAgbG9nZ2VyLmRlYnVnKFwiY2xlYXJpbmcgY2F0YWxvZ3VlXCIsIHsgaG9zdDogY29udGV4dC5ob3N0IH0pO1xuICAgIGF3YWl0IG1vZGVsQ2F0YWxvZy5jbGVhclNlcnZpbmdFbmRwb2ludHNDYWNoZShjb250ZXh0Lmhvc3QsIGNvbnRleHQuaWRlbnRpdHkpO1xuICAgIGF3YWl0IG1vZGVsQ2F0YWxvZy5saXN0U2VydmluZ0VuZHBvaW50cyhjb250ZXh0LmNsaWVudCwgY29udGV4dC5ob3N0LCB7XG4gICAgICBjYWNoZUlkZW50aXR5OiBjb250ZXh0LmlkZW50aXR5LFxuICAgICAgdHRsTXM6IHRoaXMudHRsTXMsXG4gICAgfSk7XG4gICAgbG9nZ2VyLmRlYnVnKFwicmVmcmVzaGVkIGNhdGFsb2d1ZVwiLCB7IGhvc3Q6IGNvbnRleHQuaG9zdCB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdGFyZ2V0KGVuZHBvaW50OiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5KTogTW9kZWxUYXJnZXQge1xuICAgIGNvbnN0IHB1Ymxpc2hlZCA9IG1ldGFkYXRhLm1vZGVsQ2FwYWJpbGl0aWVzRm9yKGVuZHBvaW50KTtcbiAgICBjb25zdCBmYW1pbHkgPSBlbmRwb2ludC5mYW1pbHk/LnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3Qgb3BlbkFpRmFtaWx5ID0gZmFtaWx5ID09PSBcImdwdFwiIHx8IGZhbWlseSA9PT0gXCJvcGVuYWlcIiB8fCBlbmRwb2ludC5uYW1lLmluY2x1ZGVzKFwiY29kZXhcIik7XG4gICAgY29uc3QgbW9kZWxTZXJ2aWNlTmFtZSA9IG5vcm1hbGl6ZWRNb2RlbFNlcnZpY2VOYW1lKGVuZHBvaW50Lm1vZGVsU2VydmljZU5hbWUpO1xuICAgIGNvbnN0IGVtYmVkZGluZ3MgPVxuICAgICAgZW5kcG9pbnQuY2xhc3MgPT09IE1vZGVsQ2xhc3MuRW1iZWRkaW5nIHx8IGVuZHBvaW50LnRhc2sgPT09IFwibGxtL3YxL2VtYmVkZGluZ3NcIjtcbiAgICBjb25zdCBjYXBhYmlsaXRpZXM6IE1vZGVsQ2FwYWJpbGl0aWVzID0ge1xuICAgICAgcmVzcG9uc2VzOiAhZW1iZWRkaW5ncyAmJiAob3BlbkFpRmFtaWx5IHx8IHB1Ymxpc2hlZC5yZXNwb25zZXMpLFxuICAgICAgb3BlblJlc3BvbnNlczogIWVtYmVkZGluZ3MgJiYgIW9wZW5BaUZhbWlseSxcbiAgICAgIGNoYXQ6ICFlbWJlZGRpbmdzLFxuICAgICAgYW50aHJvcGljOiBmYW1pbHkgPT09IFwiY2xhdWRlXCIsXG4gICAgICBlbWJlZGRpbmdzLFxuICAgICAgYWlHYXRld2F5Q29kZXg6XG4gICAgICAgICFlbWJlZGRpbmdzICYmIEJvb2xlYW4obW9kZWxTZXJ2aWNlTmFtZSkgJiYgZmFtaWx5ICE9PSBcImNsYXVkZVwiICYmIGZhbWlseSAhPT0gXCJnZW1pbmlcIixcbiAgICAgIHRvb2xzOiBlbmRwb2ludC5zdXBwb3J0c1Rvb2xzID09PSB0cnVlLFxuICAgICAgcmVhc29uaW5nOiBwb2xpY3kubW9kZWxSZWFzb25pbmdFZmZvcnRzKGVuZHBvaW50Lm5hbWUpLmxlbmd0aCA+IDAsXG4gICAgICBzdHJlYW1pbmc6IHRydWUsXG4gICAgICBwYXJhbGxlbFRvb2xzOiBlbmRwb2ludC5zdXBwb3J0c1Rvb2xzID09PSB0cnVlLFxuICAgICAgY3VzdG9tVG9vbHM6IHB1Ymxpc2hlZC5hcHBseVBhdGNoIHx8IGVuZHBvaW50Lm5hbWUuaW5jbHVkZXMoXCJjb2RleFwiKSxcbiAgICAgIHN0cnVjdHVyZWRPdXRwdXQ6IHRydWUsXG4gICAgICB3ZWJTZWFyY2g6IHB1Ymxpc2hlZC53ZWJTZWFyY2gsXG4gICAgfTtcbiAgICBjb25zdCBhbGlhc2VzID0gbmV3IFNldChcbiAgICAgIFtcbiAgICAgICAgZW5kcG9pbnQubmFtZSxcbiAgICAgICAgZW5kcG9pbnQuZGlzcGxheU5hbWUsXG4gICAgICAgIGVuZHBvaW50Lm1vZGVsU2VydmljZU5hbWUsXG4gICAgICAgIG1vZGVsU2VydmljZU5hbWUsXG4gICAgICAgIC4uLk9iamVjdC52YWx1ZXMoZW5kcG9pbnQuc2VydmljZU5hbWVzID8/IHt9KSxcbiAgICAgIF0uZmlsdGVyKCh2YWx1ZSk6IHZhbHVlIGlzIHN0cmluZyA9PiBCb29sZWFuKHZhbHVlPy50cmltKCkpKSxcbiAgICApO1xuICAgIGNvbnN0IG92ZXJyaWRlID0gdGhpcy5vdmVycmlkZXMuZmluZChcbiAgICAgIChjYW5kaWRhdGUpID0+XG4gICAgICAgIGNhbmRpZGF0ZS5tb2RlbCA9PT0gZW5kcG9pbnQubmFtZSB8fFxuICAgICAgICBbLi4uYWxpYXNlc10uc29tZSgoYWxpYXMpID0+IGFsaWFzID09PSBjYW5kaWRhdGUubW9kZWwpLFxuICAgICk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBlbmRwb2ludC5uYW1lLFxuICAgICAgYWxpYXNlczogWy4uLmFsaWFzZXNdLFxuICAgICAgZGlzcGxheU5hbWU6IGVuZHBvaW50LmRpc3BsYXlOYW1lID8/IGVuZHBvaW50Lm5hbWUsXG4gICAgICAuLi4oZW5kcG9pbnQuZmFtaWx5ID8geyBmYW1pbHk6IGVuZHBvaW50LmZhbWlseSB9IDoge30pLFxuICAgICAgLi4uKG1vZGVsU2VydmljZU5hbWUgPyB7IG1vZGVsU2VydmljZU5hbWUgfSA6IHt9KSxcbiAgICAgIGVuZHBvaW50LFxuICAgICAgY2FwYWJpbGl0aWVzOiB7IC4uLmNhcGFiaWxpdGllcywgLi4ub3ZlcnJpZGU/LmNhcGFiaWxpdGllcyB9LFxuICAgICAgcmVhc29uaW5nRWZmb3J0czogZW5kcG9pbnQucmVhc29uaW5nRWZmb3J0cyA/PyBbXSxcbiAgICB9O1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlZ2lzdHJ5Q29udGV4dCgpOiBQcm9taXNlPFJlZ2lzdHJ5Q29udGV4dD4ge1xuICBjb25zdCBjb250ZXh0ID0gZ2V0RXhlY3V0aW9uQ29udGV4dCgpO1xuICBjb25zdCBob3N0ID0gKGF3YWl0IGNvbnRleHQuY2xpZW50LmNvbmZpZy5nZXRIb3N0KCkpLnRvU3RyaW5nKCk7XG4gIHJldHVybiB7XG4gICAgY2xpZW50OiBjb250ZXh0LmNsaWVudCxcbiAgICBob3N0LFxuICAgIGlkZW50aXR5OiBcInVzZXJJZFwiIGluIGNvbnRleHQgPyBjb250ZXh0LnVzZXJJZCA6IGNvbnRleHQuc2VydmljZVVzZXJJZCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gdW5xdWFsaWZpZWRNb2RlbChtb2RlbDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG1vZGVsLnRyaW0oKS5yZXBsYWNlKC9eKD86ZGJ4fGRhdGFicmlja3MpXFwvL2ksIFwiXCIpO1xufVxuXG5mdW5jdGlvbiBwb3NpdGl2ZVR0bCh2YWx1ZSA9IERFRkFVTFRfQ0FDSEVfVFRMX01TKTogbnVtYmVyIHtcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUodmFsdWUpIHx8IHZhbHVlIDw9IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJNb2RlbCByZWdpc3RyeSB0dGxNcyBtdXN0IGJlIGEgcG9zaXRpdmUgZmluaXRlIG51bWJlclwiKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZWRNb2RlbFNlcnZpY2VOYW1lKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBub3JtYWxpemVkID0gdmFsdWU/LnRyaW0oKS5yZXBsYWNlKC9eZGF0YWJyaWNrc1xcLy8sIFwiXCIpO1xuICBpZiAoIW5vcm1hbGl6ZWQpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmIChub3JtYWxpemVkLnN0YXJ0c1dpdGgoXCJzeXN0ZW0uYWkuZGF0YWJyaWNrcy1cIikpIHtcbiAgICByZXR1cm4gYHN5c3RlbS5haS4ke25vcm1hbGl6ZWQuc2xpY2UoXCJzeXN0ZW0uYWkuZGF0YWJyaWNrcy1cIi5sZW5ndGgpfWA7XG4gIH1cbiAgaWYgKG5vcm1hbGl6ZWQuc3RhcnRzV2l0aChcImRhdGFicmlja3MtXCIpKSB7XG4gICAgcmV0dXJuIGBzeXN0ZW0uYWkuJHtub3JtYWxpemVkLnNsaWNlKFwiZGF0YWJyaWNrcy1cIi5sZW5ndGgpfWA7XG4gIH1cbiAgcmV0dXJuIG5vcm1hbGl6ZWQ7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXNSZXNvbHZlT3B0aW9ucyh0YXJnZXQ6IE1vZGVsVGFyZ2V0LCBvcHRpb25zOiBNb2RlbFJlZ2lzdHJ5UmVzb2x2ZU9wdGlvbnMpOiBib29sZWFuIHtcbiAgaWYgKG9wdGlvbnMucmVxdWlyZXNUb29scyAmJiAhdGFyZ2V0LmNhcGFiaWxpdGllcy50b29scykgcmV0dXJuIGZhbHNlO1xuICBpZiAob3B0aW9ucy5tb2RlbENsYXNzID09PSBNb2RlbENsYXNzLkVtYmVkZGluZykgcmV0dXJuIHRhcmdldC5jYXBhYmlsaXRpZXMuZW1iZWRkaW5ncztcbiAgaWYgKG9wdGlvbnMubW9kZWxDbGFzcyAhPT0gdW5kZWZpbmVkKSByZXR1cm4gdGFyZ2V0LmNhcGFiaWxpdGllcy5jaGF0O1xuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Pure capability-driven route selection for model-gateway requests.
3
+ *
4
+ * @module
5
+ */
6
+ import type { GatewayRoute, RequestedFeatures, ResolveRouteInput } from "@dbx-tools/shared-model-gateway";
7
+ /** Error returned when preserving a requested protocol feature is impossible. */
8
+ export declare class UnsupportedGatewayFeatureError extends Error {
9
+ readonly features: readonly string[];
10
+ readonly status = 400;
11
+ constructor(features: readonly string[]);
12
+ }
13
+ /** Select the lowest-overhead upstream that preserves the client contract. */
14
+ export declare function resolveRoute(input: ResolveRouteInput): GatewayRoute;
15
+ /** Detect route-affecting features from an OpenAI or Anthropic request body. */
16
+ export declare function requestedFeatures(body: Readonly<Record<string, unknown>>): RequestedFeatures;
17
+ /** Return whether an Originator header selects Codex compatibility behavior. */
18
+ export declare function isCodexOriginator(originator: string | undefined): boolean;
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Pure capability-driven route selection for model-gateway requests.
3
+ *
4
+ * @module
5
+ */
6
+ /** Error returned when preserving a requested protocol feature is impossible. */
7
+ export class UnsupportedGatewayFeatureError extends Error {
8
+ features;
9
+ status = 400;
10
+ constructor(features) {
11
+ super(`The selected model cannot preserve requested features: ${features.join(", ")}`);
12
+ this.features = features;
13
+ this.name = "UnsupportedGatewayFeatureError";
14
+ }
15
+ }
16
+ /** Select the lowest-overhead upstream that preserves the client contract. */
17
+ export function resolveRoute(input) {
18
+ const { clientProtocol, requestedModel, features, target } = input;
19
+ if (clientProtocol === "openai-embeddings") {
20
+ if (!target.capabilities.embeddings) {
21
+ throw new UnsupportedGatewayFeatureError(["embeddings"]);
22
+ }
23
+ return directRoute(input, "databricks-embeddings", target.id);
24
+ }
25
+ if (clientProtocol === "openai-responses") {
26
+ rejectStatefulResponses(features);
27
+ if (isCodexOriginator(input.originator) &&
28
+ targetsModelService(requestedModel, target) &&
29
+ target.capabilities.aiGatewayCodex &&
30
+ supportsDirectResponses(target, features)) {
31
+ return directRoute(input, "databricks-ai-gateway-codex", target.modelServiceName);
32
+ }
33
+ if (target.capabilities.responses && supportsDirectResponses(target, features)) {
34
+ return directRoute(input, "databricks-responses", target.id);
35
+ }
36
+ if (target.capabilities.aiGatewayCodex &&
37
+ target.modelServiceName &&
38
+ supportsDirectResponses(target, features)) {
39
+ return directRoute(input, "databricks-ai-gateway-codex", target.modelServiceName);
40
+ }
41
+ if (target.capabilities.openResponses && supportsOpenResponses(target, features)) {
42
+ return directRoute(input, "databricks-open-responses", target.id);
43
+ }
44
+ return translatedRoute(input);
45
+ }
46
+ if (clientProtocol === "openai-chat") {
47
+ if (target.capabilities.chat && supportsTools(target, features)) {
48
+ return directRoute(input, "databricks-chat", target.id);
49
+ }
50
+ return translatedRoute(input);
51
+ }
52
+ if (target.capabilities.anthropic && supportsTools(target, features)) {
53
+ return directRoute(input, "databricks-anthropic", target.id);
54
+ }
55
+ return translatedRoute(input);
56
+ }
57
+ /** Detect route-affecting features from an OpenAI or Anthropic request body. */
58
+ export function requestedFeatures(body) {
59
+ const tools = Array.isArray(body.tools) ? body.tools : [];
60
+ const toolTypes = tools
61
+ .filter((tool) => isRecord(tool))
62
+ .map((tool) => tool.type);
63
+ const text = isRecord(body.text) ? body.text : {};
64
+ const format = isRecord(text.format) ? text.format.type : text.format;
65
+ return {
66
+ background: body.background === true,
67
+ customTools: toolTypes.some((type) => type === "custom"),
68
+ parallelTools: body.parallel_tool_calls === true,
69
+ previousResponse: typeof body.previous_response_id === "string" && body.previous_response_id.length > 0,
70
+ reasoning: isRecord(body.reasoning) || body.reasoning_effort !== undefined,
71
+ storage: body.store === true,
72
+ structuredOutput: format !== undefined && format !== "text",
73
+ tools: tools.length > 0,
74
+ unsupportedOpenResponsesTools: toolTypes.some((type) => type !== "function" && type !== "web_search" && type !== "web_search_preview"),
75
+ webSearch: toolTypes.some((type) => type === "web_search" || type === "web_search_preview"),
76
+ };
77
+ }
78
+ /** Return whether an Originator header selects Codex compatibility behavior. */
79
+ export function isCodexOriginator(originator) {
80
+ return originator?.toLowerCase().includes("codex") === true;
81
+ }
82
+ function directRoute(input, upstreamProtocol, upstreamModel) {
83
+ return {
84
+ clientProtocol: input.clientProtocol,
85
+ upstreamProtocol,
86
+ target: input.target,
87
+ upstreamModel,
88
+ translateRequest: false,
89
+ translateResponse: false,
90
+ };
91
+ }
92
+ function translatedRoute(input) {
93
+ return {
94
+ clientProtocol: input.clientProtocol,
95
+ upstreamProtocol: "ai-sdk",
96
+ target: input.target,
97
+ upstreamModel: input.target.id,
98
+ translateRequest: true,
99
+ translateResponse: true,
100
+ };
101
+ }
102
+ function supportsDirectResponses(target, features) {
103
+ return (supportsTools(target, features) &&
104
+ (!features.customTools || target.capabilities.customTools) &&
105
+ (!features.structuredOutput || target.capabilities.structuredOutput));
106
+ }
107
+ function supportsOpenResponses(target, features) {
108
+ return (supportsTools(target, features) &&
109
+ !features.customTools &&
110
+ !features.previousResponse &&
111
+ !features.storage &&
112
+ !features.background &&
113
+ !features.unsupportedOpenResponsesTools &&
114
+ (!features.webSearch || target.capabilities.webSearch) &&
115
+ (!features.structuredOutput || target.capabilities.structuredOutput));
116
+ }
117
+ function supportsTools(target, features) {
118
+ return ((!features.tools || target.capabilities.tools) &&
119
+ (!features.parallelTools || target.capabilities.parallelTools));
120
+ }
121
+ function rejectStatefulResponses(features) {
122
+ const unsupported = [
123
+ ...(features.previousResponse ? ["previous_response_id"] : []),
124
+ ...(features.storage ? ["store"] : []),
125
+ ...(features.background ? ["background"] : []),
126
+ ];
127
+ if (unsupported.length > 0)
128
+ throw new UnsupportedGatewayFeatureError(unsupported);
129
+ }
130
+ function targetsModelService(requestedModel, target) {
131
+ if (!target.modelServiceName)
132
+ return false;
133
+ const unqualified = requestedModel.trim().replace(/^(?:dbx|databricks)\//i, "");
134
+ return unqualified === target.modelServiceName;
135
+ }
136
+ function isRecord(value) {
137
+ return value !== null && typeof value === "object" && !Array.isArray(value);
138
+ }
139
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBVUgsaUZBQWlGO0FBQ2pGLE1BQU0sT0FBTyw4QkFBK0IsU0FBUSxLQUFLO0lBR2xDO0lBRlosTUFBTSxHQUFHLEdBQUcsQ0FBQztJQUV0QixZQUFxQixRQUEyQjtRQUM5QyxLQUFLLENBQUMsMERBQTBELFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRHBFLGFBQVEsR0FBUixRQUFRLENBQW1CO1FBRTlDLElBQUksQ0FBQyxJQUFJLEdBQUcsZ0NBQWdDLENBQUM7SUFDL0MsQ0FBQztDQUNGO0FBRUQsOEVBQThFO0FBQzlFLE1BQU0sVUFBVSxZQUFZLENBQUMsS0FBd0I7SUFDbkQsTUFBTSxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQztJQUNuRSxJQUFJLGNBQWMsS0FBSyxtQkFBbUIsRUFBRSxDQUFDO1FBQzNDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSw4QkFBOEIsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDM0QsQ0FBQztRQUNELE9BQU8sV0FBVyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUNELElBQUksY0FBYyxLQUFLLGtCQUFrQixFQUFFLENBQUM7UUFDMUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDbEMsSUFDRSxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1lBQ25DLG1CQUFtQixDQUFDLGNBQWMsRUFBRSxNQUFNLENBQUM7WUFDM0MsTUFBTSxDQUFDLFlBQVksQ0FBQyxjQUFjO1lBQ2xDLHVCQUF1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LFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUHVyZSBjYXBhYmlsaXR5LWRyaXZlbiByb3V0ZSBzZWxlY3Rpb24gZm9yIG1vZGVsLWdhdGV3YXkgcmVxdWVzdHMuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgR2F0ZXdheVJvdXRlLFxuICBNb2RlbFRhcmdldCxcbiAgUmVxdWVzdGVkRmVhdHVyZXMsXG4gIFJlc29sdmVSb3V0ZUlucHV0LFxuICBVcHN0cmVhbVByb3RvY29sLFxufSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWwtZ2F0ZXdheVwiO1xuXG4vKiogRXJyb3IgcmV0dXJuZWQgd2hlbiBwcmVzZXJ2aW5nIGEgcmVxdWVzdGVkIHByb3RvY29sIGZlYXR1cmUgaXMgaW1wb3NzaWJsZS4gKi9cbmV4cG9ydCBjbGFzcyBVbnN1cHBvcnRlZEdhdGV3YXlGZWF0dXJlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIHJlYWRvbmx5IHN0YXR1cyA9IDQwMDtcblxuICBjb25zdHJ1Y3RvcihyZWFkb25seSBmZWF0dXJlczogcmVhZG9ubHkgc3RyaW5nW10pIHtcbiAgICBzdXBlcihgVGhlIHNlbGVjdGVkIG1vZGVsIGNhbm5vdCBwcmVzZXJ2ZSByZXF1ZXN0ZWQgZmVhdHVyZXM6ICR7ZmVhdHVyZXMuam9pbihcIiwgXCIpfWApO1xuICAgIHRoaXMubmFtZSA9IFwiVW5zdXBwb3J0ZWRHYXRld2F5RmVhdHVyZUVycm9yXCI7XG4gIH1cbn1cblxuLyoqIFNlbGVjdCB0aGUgbG93ZXN0LW92ZXJoZWFkIHVwc3RyZWFtIHRoYXQgcHJlc2VydmVzIHRoZSBjbGllbnQgY29udHJhY3QuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVJvdXRlKGlucHV0OiBSZXNvbHZlUm91dGVJbnB1dCk6IEdhdGV3YXlSb3V0ZSB7XG4gIGNvbnN0IHsgY2xpZW50UHJvdG9jb2wsIHJlcXVlc3RlZE1vZGVsLCBmZWF0dXJlcywgdGFyZ2V0IH0gPSBpbnB1dDtcbiAgaWYgKGNsaWVudFByb3RvY29sID09PSBcIm9wZW5haS1lbWJlZGRpbmdzXCIpIHtcbiAgICBpZiAoIXRhcmdldC5jYXBhYmlsaXRpZXMuZW1iZWRkaW5ncykge1xuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkR2F0ZXdheUZlYXR1cmVFcnJvcihbXCJlbWJlZGRpbmdzXCJdKTtcbiAgICB9XG4gICAgcmV0dXJuIGRpcmVjdFJvdXRlKGlucHV0LCBcImRhdGFicmlja3MtZW1iZWRkaW5nc1wiLCB0YXJnZXQuaWQpO1xuICB9XG4gIGlmIChjbGllbnRQcm90b2NvbCA9PT0gXCJvcGVuYWktcmVzcG9uc2VzXCIpIHtcbiAgICByZWplY3RTdGF0ZWZ1bFJlc3BvbnNlcyhmZWF0dXJlcyk7XG4gICAgaWYgKFxuICAgICAgaXNDb2RleE9yaWdpbmF0b3IoaW5wdXQub3JpZ2luYXRvcikgJiZcbiAgICAgIHRhcmdldHNNb2RlbFNlcnZpY2UocmVxdWVzdGVkTW9kZWwsIHRhcmdldCkgJiZcbiAgICAgIHRhcmdldC5jYXBhYmlsaXRpZXMuYWlHYXRld2F5Q29kZXggJiZcbiAgICAgIHN1cHBvcnRzRGlyZWN0UmVzcG9uc2VzKHRhcmdldCwgZmVhdHVyZXMpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZGlyZWN0Um91dGUoaW5wdXQsIFwiZGF0YWJyaWNrcy1haS1nYXRld2F5LWNvZGV4XCIsIHRhcmdldC5tb2RlbFNlcnZpY2VOYW1lISk7XG4gICAgfVxuICAgIGlmICh0YXJnZXQuY2FwYWJpbGl0aWVzLnJlc3BvbnNlcyAmJiBzdXBwb3J0c0RpcmVjdFJlc3BvbnNlcyh0YXJnZXQsIGZlYXR1cmVzKSkge1xuICAgICAgcmV0dXJuIGRpcmVjdFJvdXRlKGlucHV0LCBcImRhdGFicmlja3MtcmVzcG9uc2VzXCIsIHRhcmdldC5pZCk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRhcmdldC5jYXBhYmlsaXRpZXMuYWlHYXRld2F5Q29kZXggJiZcbiAgICAgIHRhcmdldC5tb2RlbFNlcnZpY2VOYW1lICYmXG4gICAgICBzdXBwb3J0c0RpcmVjdFJlc3BvbnNlcyh0YXJnZXQsIGZlYXR1cmVzKVxuICAgICkge1xuICAgICAgcmV0dXJuIGRpcmVjdFJvdXRlKGlucHV0LCBcImRhdGFicmlja3MtYWktZ2F0ZXdheS1jb2RleFwiLCB0YXJnZXQubW9kZWxTZXJ2aWNlTmFtZSk7XG4gICAgfVxuICAgIGlmICh0YXJnZXQuY2FwYWJpbGl0aWVzLm9wZW5SZXNwb25zZXMgJiYgc3VwcG9ydHNPcGVuUmVzcG9uc2VzKHRhcmdldCwgZmVhdHVyZXMpKSB7XG4gICAgICByZXR1cm4gZGlyZWN0Um91dGUoaW5wdXQsIFwiZGF0YWJyaWNrcy1vcGVuLXJlc3BvbnNlc1wiLCB0YXJnZXQuaWQpO1xuICAgIH1cbiAgICByZXR1cm4gdHJhbnNsYXRlZFJvdXRlKGlucHV0KTtcbiAgfVxuXG4gIGlmIChjbGllbnRQcm90b2NvbCA9PT0gXCJvcGVuYWktY2hhdFwiKSB7XG4gICAgaWYgKHRhcmdldC5jYXBhYmlsaXRpZXMuY2hhdCAmJiBzdXBwb3J0c1Rvb2xzKHRhcmdldCwgZmVhdHVyZXMpKSB7XG4gICAgICByZXR1cm4gZGlyZWN0Um91dGUoaW5wdXQsIFwiZGF0YWJyaWNrcy1jaGF0XCIsIHRhcmdldC5pZCk7XG4gICAgfVxuICAgIHJldHVybiB0cmFuc2xhdGVkUm91dGUoaW5wdXQpO1xuICB9XG5cbiAgaWYgKHRhcmdldC5jYXBhYmlsaXRpZXMuYW50aHJvcGljICYmIHN1cHBvcnRzVG9vbHModGFyZ2V0LCBmZWF0dXJlcykpIHtcbiAgICByZXR1cm4gZGlyZWN0Um91dGUoaW5wdXQsIFwiZGF0YWJyaWNrcy1hbnRocm9waWNcIiwgdGFyZ2V0LmlkKTtcbiAgfVxuICByZXR1cm4gdHJhbnNsYXRlZFJvdXRlKGlucHV0KTtcbn1cblxuLyoqIERldGVjdCByb3V0ZS1hZmZlY3RpbmcgZmVhdHVyZXMgZnJvbSBhbiBPcGVuQUkgb3IgQW50aHJvcGljIHJlcXVlc3QgYm9keS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1ZXN0ZWRGZWF0dXJlcyhib2R5OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pOiBSZXF1ZXN0ZWRGZWF0dXJlcyB7XG4gIGNvbnN0IHRvb2xzID0gQXJyYXkuaXNBcnJheShib2R5LnRvb2xzKSA/IGJvZHkudG9vbHMgOiBbXTtcbiAgY29uc3QgdG9vbFR5cGVzID0gdG9vbHNcbiAgICAuZmlsdGVyKCh0b29sKTogdG9vbCBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PiBpc1JlY29yZCh0b29sKSlcbiAgICAubWFwKCh0b29sKSA9PiB0b29sLnR5cGUpO1xuICBjb25zdCB0ZXh0ID0gaXNSZWNvcmQoYm9keS50ZXh0KSA/IGJvZHkudGV4dCA6IHt9O1xuICBjb25zdCBmb3JtYXQgPSBpc1JlY29yZCh0ZXh0LmZvcm1hdCkgPyB0ZXh0LmZvcm1hdC50eXBlIDogdGV4dC5mb3JtYXQ7XG4gIHJldHVybiB7XG4gICAgYmFja2dyb3VuZDogYm9keS5iYWNrZ3JvdW5kID09PSB0cnVlLFxuICAgIGN1c3RvbVRvb2xzOiB0b29sVHlwZXMuc29tZSgodHlwZSkgPT4gdHlwZSA9PT0gXCJjdXN0b21cIiksXG4gICAgcGFyYWxsZWxUb29sczogYm9keS5wYXJhbGxlbF90b29sX2NhbGxzID09PSB0cnVlLFxuICAgIHByZXZpb3VzUmVzcG9uc2U6XG4gICAgICB0eXBlb2YgYm9keS5wcmV2aW91c19yZXNwb25zZV9pZCA9PT0gXCJzdHJpbmdcIiAmJiBib2R5LnByZXZpb3VzX3Jlc3BvbnNlX2lkLmxlbmd0aCA+IDAsXG4gICAgcmVhc29uaW5nOiBpc1JlY29yZChib2R5LnJlYXNvbmluZykgfHwgYm9keS5yZWFzb25pbmdfZWZmb3J0ICE9PSB1bmRlZmluZWQsXG4gICAgc3RvcmFnZTogYm9keS5zdG9yZSA9PT0gdHJ1ZSxcbiAgICBzdHJ1Y3R1cmVkT3V0cHV0OiBmb3JtYXQgIT09IHVuZGVmaW5lZCAmJiBmb3JtYXQgIT09IFwidGV4dFwiLFxuICAgIHRvb2xzOiB0b29scy5sZW5ndGggPiAwLFxuICAgIHVuc3VwcG9ydGVkT3BlblJlc3BvbnNlc1Rvb2xzOiB0b29sVHlwZXMuc29tZShcbiAgICAgICh0eXBlKSA9PiB0eXBlICE9PSBcImZ1bmN0aW9uXCIgJiYgdHlwZSAhPT0gXCJ3ZWJfc2VhcmNoXCIgJiYgdHlwZSAhPT0gXCJ3ZWJfc2VhcmNoX3ByZXZpZXdcIixcbiAgICApLFxuICAgIHdlYlNlYXJjaDogdG9vbFR5cGVzLnNvbWUoKHR5cGUpID0+IHR5cGUgPT09IFwid2ViX3NlYXJjaFwiIHx8IHR5cGUgPT09IFwid2ViX3NlYXJjaF9wcmV2aWV3XCIpLFxuICB9O1xufVxuXG4vKiogUmV0dXJuIHdoZXRoZXIgYW4gT3JpZ2luYXRvciBoZWFkZXIgc2VsZWN0cyBDb2RleCBjb21wYXRpYmlsaXR5IGJlaGF2aW9yLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ29kZXhPcmlnaW5hdG9yKG9yaWdpbmF0b3I6IHN0cmluZyB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICByZXR1cm4gb3JpZ2luYXRvcj8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhcImNvZGV4XCIpID09PSB0cnVlO1xufVxuXG5mdW5jdGlvbiBkaXJlY3RSb3V0ZShcbiAgaW5wdXQ6IFJlc29sdmVSb3V0ZUlucHV0LFxuICB1cHN0cmVhbVByb3RvY29sOiBFeGNsdWRlPFVwc3RyZWFtUHJvdG9jb2wsIFwiYWktc2RrXCI+LFxuICB1cHN0cmVhbU1vZGVsOiBzdHJpbmcsXG4pOiBHYXRld2F5Um91dGUge1xuICByZXR1cm4ge1xuICAgIGNsaWVudFByb3RvY29sOiBpbnB1dC5jbGllbnRQcm90b2NvbCxcbiAgICB1cHN0cmVhbVByb3RvY29sLFxuICAgIHRhcmdldDogaW5wdXQudGFyZ2V0LFxuICAgIHVwc3RyZWFtTW9kZWwsXG4gICAgdHJhbnNsYXRlUmVxdWVzdDogZmFsc2UsXG4gICAgdHJhbnNsYXRlUmVzcG9uc2U6IGZhbHNlLFxuICB9O1xufVxuXG5mdW5jdGlvbiB0cmFuc2xhdGVkUm91dGUoaW5wdXQ6IFJlc29sdmVSb3V0ZUlucHV0KTogR2F0ZXdheVJvdXRlIHtcbiAgcmV0dXJuIHtcbiAgICBjbGllbnRQcm90b2NvbDogaW5wdXQuY2xpZW50UHJvdG9jb2wsXG4gICAgdXBzdHJlYW1Qcm90b2NvbDogXCJhaS1zZGtcIixcbiAgICB0YXJnZXQ6IGlucHV0LnRhcmdldCxcbiAgICB1cHN0cmVhbU1vZGVsOiBpbnB1dC50YXJnZXQuaWQsXG4gICAgdHJhbnNsYXRlUmVxdWVzdDogdHJ1ZSxcbiAgICB0cmFuc2xhdGVSZXNwb25zZTogdHJ1ZSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3VwcG9ydHNEaXJlY3RSZXNwb25zZXModGFyZ2V0OiBNb2RlbFRhcmdldCwgZmVhdHVyZXM6IFJlcXVlc3RlZEZlYXR1cmVzKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgc3VwcG9ydHNUb29scyh0YXJnZXQsIGZlYXR1cmVzKSAmJlxuICAgICghZmVhdHVyZXMuY3VzdG9tVG9vbHMgfHwgdGFyZ2V0LmNhcGFiaWxpdGllcy5jdXN0b21Ub29scykgJiZcbiAgICAoIWZlYXR1cmVzLnN0cnVjdHVyZWRPdXRwdXQgfHwgdGFyZ2V0LmNhcGFiaWxpdGllcy5zdHJ1Y3R1cmVkT3V0cHV0KVxuICApO1xufVxuXG5mdW5jdGlvbiBzdXBwb3J0c09wZW5SZXNwb25zZXModGFyZ2V0OiBNb2RlbFRhcmdldCwgZmVhdHVyZXM6IFJlcXVlc3RlZEZlYXR1cmVzKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgc3VwcG9ydHNUb29scyh0YXJnZXQsIGZlYXR1cmVzKSAmJlxuICAgICFmZWF0dXJlcy5jdXN0b21Ub29scyAmJlxuICAgICFmZWF0dXJlcy5wcmV2aW91c1Jlc3BvbnNlICYmXG4gICAgIWZlYXR1cmVzLnN0b3JhZ2UgJiZcbiAgICAhZmVhdHVyZXMuYmFja2dyb3VuZCAmJlxuICAgICFmZWF0dXJlcy51bnN1cHBvcnRlZE9wZW5SZXNwb25zZXNUb29scyAmJlxuICAgICghZmVhdHVyZXMud2ViU2VhcmNoIHx8IHRhcmdldC5jYXBhYmlsaXRpZXMud2ViU2VhcmNoKSAmJlxuICAgICghZmVhdHVyZXMuc3RydWN0dXJlZE91dHB1dCB8fCB0YXJnZXQuY2FwYWJpbGl0aWVzLnN0cnVjdHVyZWRPdXRwdXQpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHN1cHBvcnRzVG9vbHModGFyZ2V0OiBNb2RlbFRhcmdldCwgZmVhdHVyZXM6IFJlcXVlc3RlZEZlYXR1cmVzKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgKCFmZWF0dXJlcy50b29scyB8fCB0YXJnZXQuY2FwYWJpbGl0aWVzLnRvb2xzKSAmJlxuICAgICghZmVhdHVyZXMucGFyYWxsZWxUb29scyB8fCB0YXJnZXQuY2FwYWJpbGl0aWVzLnBhcmFsbGVsVG9vbHMpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlamVjdFN0YXRlZnVsUmVzcG9uc2VzKGZlYXR1cmVzOiBSZXF1ZXN0ZWRGZWF0dXJlcyk6IHZvaWQge1xuICBjb25zdCB1bnN1cHBvcnRlZCA9IFtcbiAgICAuLi4oZmVhdHVyZXMucHJldmlvdXNSZXNwb25zZSA/IFtcInByZXZpb3VzX3Jlc3BvbnNlX2lkXCJdIDogW10pLFxuICAgIC4uLihmZWF0dXJlcy5zdG9yYWdlID8gW1wic3RvcmVcIl0gOiBbXSksXG4gICAgLi4uKGZlYXR1cmVzLmJhY2tncm91bmQgPyBbXCJiYWNrZ3JvdW5kXCJdIDogW10pLFxuICBdO1xuICBpZiAodW5zdXBwb3J0ZWQubGVuZ3RoID4gMCkgdGhyb3cgbmV3IFVuc3VwcG9ydGVkR2F0ZXdheUZlYXR1cmVFcnJvcih1bnN1cHBvcnRlZCk7XG59XG5cbmZ1bmN0aW9uIHRhcmdldHNNb2RlbFNlcnZpY2UocmVxdWVzdGVkTW9kZWw6IHN0cmluZywgdGFyZ2V0OiBNb2RlbFRhcmdldCk6IGJvb2xlYW4ge1xuICBpZiAoIXRhcmdldC5tb2RlbFNlcnZpY2VOYW1lKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IHVucXVhbGlmaWVkID0gcmVxdWVzdGVkTW9kZWwudHJpbSgpLnJlcGxhY2UoL14oPzpkYnh8ZGF0YWJyaWNrcylcXC8vaSwgXCJcIik7XG4gIHJldHVybiB1bnF1YWxpZmllZCA9PT0gdGFyZ2V0Lm1vZGVsU2VydmljZU5hbWU7XG59XG5cbmZ1bmN0aW9uIGlzUmVjb3JkKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cbiJdfQ==
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Express adapters for the shared model-gateway service.
3
+ *
4
+ * @module
5
+ */
6
+ import type { ClientProtocol } from "@dbx-tools/shared-model-gateway";
7
+ import type express from "express";
8
+ import { ModelGateway } from "./gateway.ts";
9
+ /** Send the lightweight compatibility health response. */
10
+ export declare function sendHealth(response: express.Response): void;
11
+ /** Send the active principal's dynamic model catalogue. */
12
+ export declare function sendModels(gateway: ModelGateway, request: express.Request, response: express.Response): Promise<void>;
13
+ /** Execute and stream one model request through Express with cancellation. */
14
+ export declare function sendInference(gateway: ModelGateway, protocol: ClientProtocol, request: express.Request, response: express.Response): Promise<void>;