@dbx-tools/model 0.9.19 → 0.9.28
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 +61 -10
- package/index.ts +12 -2
- package/lib/exports.d.ts +1 -0
- package/lib/exports.js +2 -0
- package/lib/index.d.ts +12 -2
- package/lib/index.js +9 -2
- package/lib/src/_metadata-contract.d.ts +42 -0
- package/lib/src/_metadata-contract.js +11 -0
- package/lib/src/_metadata-generator.d.ts +7 -0
- package/lib/src/_metadata-generator.js +182 -0
- package/lib/src/_ranking.d.ts +20 -0
- package/lib/src/_ranking.js +226 -0
- package/lib/src/_selection.d.ts +23 -0
- package/lib/src/_selection.js +95 -0
- package/lib/src/classes.d.ts +2 -2
- package/lib/src/classes.js +10 -8
- package/lib/src/classify.d.ts +130 -0
- package/lib/src/classify.js +283 -0
- package/lib/src/fallback.d.ts +4 -4
- package/lib/src/fallback.js +7 -7
- package/lib/src/generated/model-capabilities.json +90 -0
- package/lib/src/generated/model-rate-limits.json +342 -0
- package/lib/src/generated/retired-models.json +32 -0
- package/lib/src/invoke.js +3 -3
- package/lib/src/metadata.d.ts +33 -0
- package/lib/src/metadata.js +120 -0
- package/lib/src/model-catalog.d.ts +4 -4
- package/lib/src/model-catalog.js +19 -24
- package/lib/src/model-client.d.ts +67 -0
- package/lib/src/model-client.js +181 -0
- package/lib/src/policy.d.ts +14 -8
- package/lib/src/policy.js +173 -14
- package/lib/src/python.d.ts +2 -0
- package/lib/src/python.js +3 -0
- package/lib/src/resolve.d.ts +10 -143
- package/lib/src/resolve.js +11 -196
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -5
- package/src/_metadata-contract.ts +56 -0
- package/src/_metadata-generator.ts +199 -0
- package/src/_ranking.ts +260 -0
- package/src/_selection.ts +141 -0
- package/src/classes.ts +11 -7
- package/src/classify.ts +324 -0
- package/src/fallback.ts +11 -7
- package/src/generated/model-capabilities.json +90 -0
- package/src/generated/model-rate-limits.json +342 -0
- package/src/generated/retired-models.json +32 -0
- package/src/invoke.ts +2 -2
- package/src/metadata.ts +189 -0
- package/src/model-catalog.ts +26 -28
- package/src/model-client.ts +311 -0
- package/src/policy.ts +176 -19
- package/src/python.ts +2 -0
- package/src/resolve.ts +24 -270
- package/lib/src/_native.d.ts +0 -14
- package/lib/src/_native.js +0 -124
- package/src/_native.ts +0 -174
package/lib/src/model-catalog.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* `quality` / `speed` / `cost` profile when present, the classified
|
|
10
10
|
* {@link ModelClass}, and (for embedding endpoints) the measured vector
|
|
11
11
|
* `dimension` - and snaps loose, human-typed names to real endpoint ids
|
|
12
|
-
* through the
|
|
12
|
+
* through the TypeScript model ranker so tokens like `"claude sonnet"` resolve to
|
|
13
13
|
* `databricks-claude-sonnet-4-6`.
|
|
14
14
|
*
|
|
15
15
|
* The class stamp and embedding dimension are computed once per cache load:
|
|
@@ -24,12 +24,12 @@ import { createHash } from "node:crypto";
|
|
|
24
24
|
import { CacheManager } from "@databricks/appkit";
|
|
25
25
|
import { errorUtils, log } from "@dbx-tools/shared-core";
|
|
26
26
|
import { model } from "@dbx-tools/shared-model";
|
|
27
|
-
import { classifyEndpointClasses, normalizeEndpoints, rankEndpoints } from "./
|
|
27
|
+
import { classifyEndpointClasses, normalizeEndpoints, rankEndpoints } from "./_ranking.js";
|
|
28
28
|
const { ModelClass } = model;
|
|
29
29
|
const logger = log.logger("model/serving");
|
|
30
30
|
/** Default TTL for the in-memory endpoint cache. Matches the Databricks SDK's session lifetime budget. */
|
|
31
31
|
export const DEFAULT_MODEL_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
32
|
-
/** Default
|
|
32
|
+
/** Default fuzzy distance threshold below which a match is accepted. */
|
|
33
33
|
export const DEFAULT_FUZZY_THRESHOLD = 0.4;
|
|
34
34
|
/** Cache key parts under which endpoint listings are stored. */
|
|
35
35
|
const CACHE_KEY_NAMESPACE = "serving-endpoints";
|
|
@@ -82,41 +82,36 @@ export async function listServingEndpointsUncached(client) {
|
|
|
82
82
|
}
|
|
83
83
|
async function fetchEndpoints(client) {
|
|
84
84
|
const startedAt = Date.now();
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
await measureEmbeddingDimensions(client, out);
|
|
85
|
+
const classified = stampModelClasses(await listServingEndpointsUncached(client));
|
|
86
|
+
const out = await measureEmbeddingDimensions(client, classified);
|
|
88
87
|
logger.debug("listed", { count: out.length, elapsedMs: Date.now() - startedAt });
|
|
89
88
|
return out;
|
|
90
89
|
}
|
|
91
90
|
/**
|
|
92
91
|
* Stamp each summary's {@link ServingEndpointSummary.class} from the relative
|
|
93
|
-
* classification of the whole set.
|
|
94
|
-
*
|
|
95
|
-
* class.
|
|
92
|
+
* classification of the whole set. Endpoints the classifier doesn't recognize
|
|
93
|
+
* (custom, unscored, non-LLM) are left without a class.
|
|
96
94
|
*/
|
|
97
95
|
function stampModelClasses(summaries) {
|
|
98
96
|
const classOf = classifyEndpointClasses(summaries);
|
|
99
|
-
|
|
97
|
+
return summaries.map((summary) => {
|
|
100
98
|
const cls = classOf.get(summary.name);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
99
|
+
return cls === undefined ? summary : { ...summary, class: cls };
|
|
100
|
+
});
|
|
104
101
|
}
|
|
105
102
|
/**
|
|
106
103
|
* Measure the embedding vector dimension of every {@link ModelClass.Embedding}
|
|
107
|
-
* endpoint by pinging it once, all in parallel.
|
|
108
|
-
* in place with the resulting `dimension`. Runs only on a cache miss (it's
|
|
104
|
+
* endpoint by pinging it once, all in parallel. Runs only on a cache miss (it's
|
|
109
105
|
* called from {@link fetchEndpoints}), so the probe cost is amortized across the
|
|
110
|
-
* cached TTL window. Per-endpoint failures are swallowed (logged at warn) so
|
|
111
|
-
*
|
|
106
|
+
* cached TTL window. Per-endpoint failures are swallowed (logged at warn) so one
|
|
107
|
+
* unreachable embedding model never fails the listing.
|
|
112
108
|
*/
|
|
113
109
|
async function measureEmbeddingDimensions(client, summaries) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
return Promise.all(summaries.map(async (summary) => {
|
|
111
|
+
if (summary.class !== ModelClass.Embedding)
|
|
112
|
+
return summary;
|
|
117
113
|
const dimension = await pingEmbeddingDimension(client, summary.name);
|
|
118
|
-
|
|
119
|
-
summary.dimension = dimension;
|
|
114
|
+
return dimension === undefined ? summary : { ...summary, dimension };
|
|
120
115
|
}));
|
|
121
116
|
}
|
|
122
117
|
/**
|
|
@@ -160,7 +155,7 @@ export async function clearServingEndpointsCache(host, cacheIdentity) {
|
|
|
160
155
|
* (lowest score) first, keeping only those within `threshold`:
|
|
161
156
|
*
|
|
162
157
|
* 1. An exact name match short-circuits to a single `score: 0` result.
|
|
163
|
-
* 2. Otherwise
|
|
158
|
+
* 2. Otherwise the shared TypeScript policy tokenizes and scores every endpoint through the
|
|
164
159
|
* same fuzzy-distance policy used by {@link lookupModels}.
|
|
165
160
|
*
|
|
166
161
|
* Returns `[]` for an empty endpoint list or when `input` tokenizes to nothing,
|
|
@@ -195,4 +190,4 @@ export function resolveModelId(input, endpoints, options = {}) {
|
|
|
195
190
|
}
|
|
196
191
|
return { modelId: input, matched: false };
|
|
197
192
|
}
|
|
198
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtY2F0YWxvZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlbC1jYXRhbG9nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxLQUFLLEVBQStCLE1BQU0seUJBQXlCLENBQUM7QUFFN0UsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGtCQUFrQixFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUUxRixNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBRTdCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7QUFTM0MsMEdBQTBHO0FBQzFHLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRXhELDZFQUE2RTtBQUM3RSxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLENBQUM7QUFFM0MsZ0VBQWdFO0FBQ2hFLE1BQU0sbUJBQW1CLEdBQUcsbUJBQW1CLENBQUM7QUFvQmhELDRFQUE0RTtBQUM1RSxTQUFTLFlBQVksQ0FBQyxRQUFnQjtJQUNwQyxPQUFPLFNBQVMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztBQUN4RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLG9CQUFvQixDQUN4QyxNQUEyQixFQUMzQixJ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LENBQUMsS0FBSyxFQUFFLENBQUM7SUFDM0UsQ0FBQztJQUNELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBMaXZlIERhdGFicmlja3MgTW9kZWwgU2VydmluZyBjYXRhbG9ndWUgYWNjZXNzLlxuICpcbiAqIExpc3RzIHRoZSB3b3Jrc3BhY2UncyBgL3NlcnZpbmctZW5kcG9pbnRzYCBhbmQsIHdoZW4gdGhlIGNhbGxlciBzdXBwbGllcyBhXG4gKiB0cnVzdGVkIGNyZWRlbnRpYWwgaWRlbnRpdHksIGNhY2hlcyB0aGUgcmVzdWx0IHBlciBob3N0IGFuZCBpZGVudGl0eSB3aXRoIGFcbiAqIFRUTCB2aWEgQXBwS2l0J3MgYENhY2hlTWFuYWdlcmAuIENvbmN1cnJlbnQgY2FsbGVycyBpbiB0aGUgc2FtZSBzY29wZSBzaGFyZVxuICogb25lIGluLWZsaWdodCBwcm9taXNlLiBTdXJmYWNlcyBlYWNoIGVuZHBvaW50IGFzIGEgc3RhYmxlXG4gKiB7QGxpbmsgU2VydmluZ0VuZHBvaW50U3VtbWFyeX0gLSBpbmNsdWRpbmcgdGhlIEZvdW5kYXRpb24gTW9kZWwgQVBJXG4gKiBgcXVhbGl0eWAgLyBgc3BlZWRgIC8gYGNvc3RgIHByb2ZpbGUgd2hlbiBwcmVzZW50LCB0aGUgY2xhc3NpZmllZFxuICoge0BsaW5rIE1vZGVsQ2xhc3N9LCBhbmQgKGZvciBlbWJlZGRpbmcgZW5kcG9pbnRzKSB0aGUgbWVhc3VyZWQgdmVjdG9yXG4gKiBgZGltZW5zaW9uYCAtIGFuZCBzbmFwcyBsb29zZSwgaHVtYW4tdHlwZWQgbmFtZXMgdG8gcmVhbCBlbmRwb2ludCBpZHNcbiAqIHRocm91Z2ggdGhlIFJ1c3QgbW9kZWwgcmFua2VyIHNvIHRva2VucyBsaWtlIGBcImNsYXVkZSBzb25uZXRcImAgcmVzb2x2ZSB0b1xuICogYGRhdGFicmlja3MtY2xhdWRlLXNvbm5ldC00LTZgLlxuICpcbiAqIFRoZSBjbGFzcyBzdGFtcCBhbmQgZW1iZWRkaW5nIGRpbWVuc2lvbiBhcmUgY29tcHV0ZWQgb25jZSBwZXIgY2FjaGUgbG9hZDpcbiAqIGV2ZXJ5IGVtYmVkZGluZyBlbmRwb2ludCBpcyBcInBpbmdlZFwiIGluIHBhcmFsbGVsIGFuZCB0aGUgcmVzdWx0aW5nIHZlY3RvclxuICogbGVuZ3RoIHJlY29yZGVkLCBzbyB0aGUgY29zdCBpcyBwYWlkIG9uIGEgY2FjaGUgbWlzcywgbm90IHBlciByZWFkLiBUaGUgcGluZ1xuICogaXMgYmVzdC1lZmZvcnQgLSBhIGZhaWx1cmUgbG9ncyBhdCBkZWJ1ZyBhbmQgbGVhdmVzIGBkaW1lbnNpb25gIHVuc2V0IHJhdGhlclxuICogdGhhbiBmYWlsaW5nIHRoZSB3aG9sZSBsaXN0aW5nLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5pbXBvcnQgeyBDYWNoZU1hbmFnZXIgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBhcHBraXQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGVycm9yVXRpbHMsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgdHlwZSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1vZGVsXCI7XG5cbmltcG9ydCB7IGNsYXNzaWZ5RW5kcG9pbnRDbGFzc2VzLCBub3JtYWxpemVFbmRwb2ludHMsIHJhbmtFbmRwb2ludHMgfSBmcm9tIFwiLi9fbmF0aXZlLnRzXCI7XG5cbmNvbnN0IHsgTW9kZWxDbGFzcyB9ID0gbW9kZWw7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtb2RlbC9zZXJ2aW5nXCIpO1xuXG4vKipcbiAqIFN0cnVjdHVyYWwgdHlwZSBmb3IgdGhlIERhdGFicmlja3Mgd29ya3NwYWNlIGNsaWVudCwgcmUtZXhwb3J0ZWQgc28gdGhlIHJlc3RcbiAqIG9mIHRoaXMgcGFja2FnZSBjYW4ga2VlcCBpbXBvcnRpbmcgaXQgZnJvbSBoZXJlLiBTZWVcbiAqIGBhcHBraXQuV29ya3NwYWNlQ2xpZW50TGlrZWAgKG5vZGUtYXBwa2l0KSBmb3IgdGhlIGNhbm9uaWNhbCBkZWZpbml0aW9uLlxuICovXG5leHBvcnQgdHlwZSBXb3Jrc3BhY2VDbGllbnRMaWtlID0gUGljazxhcHBraXQuV29ya3NwYWNlQ2xpZW50TGlrZSwgXCJzZXJ2aW5nRW5kcG9pbnRzXCI+O1xuXG4vKiogRGVmYXVsdCBUVEwgZm9yIHRoZSBpbi1tZW1vcnkgZW5kcG9pbnQgY2FjaGUuIE1hdGNoZXMgdGhlIERhdGFicmlja3MgU0RLJ3Mgc2Vzc2lvbiBsaWZldGltZSBidWRnZXQuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9NT0RFTF9DQUNIRV9UVExfTVMgPSA1ICogNjAgKiAxMDAwO1xuXG4vKiogRGVmYXVsdCBSdXN0IGRpc3RhbmNlIHRocmVzaG9sZCBiZWxvdyB3aGljaCBhIGZ1enp5IG1hdGNoIGlzIGFjY2VwdGVkLiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRlVaWllfVEhSRVNIT0xEID0gMC40O1xuXG4vKiogQ2FjaGUga2V5IHBhcnRzIHVuZGVyIHdoaWNoIGVuZHBvaW50IGxpc3RpbmdzIGFyZSBzdG9yZWQuICovXG5jb25zdCBDQUNIRV9LRVlfTkFNRVNQQUNFID0gXCJzZXJ2aW5nLWVuZHBvaW50c1wiO1xuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rIGxpc3RTZXJ2aW5nRW5kcG9pbnRzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdFNlcnZpbmdFbmRwb2ludHNPcHRpb25zIHtcbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSBkZWZhdWx0IGNhY2hlIFRUTCBmb3IgdGhpcyBjYWxsLCBpbiBtaWxsaXNlY29uZHMuIEZvcndhcmRlZCB0b1xuICAgKiBgQ2FjaGVNYW5hZ2VyYCBhcyBzZWNvbmRzLlxuICAgKi9cbiAgdHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUcnVzdGVkIGlkZW50aXR5IG9mIHRoZSBjcmVkZW50aWFsIHVzZWQgYnkgYGNsaWVudGAuXG4gICAqXG4gICAqIFRoZSB2YWx1ZSBpcyBoYXNoZWQgYmVmb3JlIGl0IGVudGVycyB0aGUgY2FjaGUga2V5IGFuZCBpcyBuZXZlciBsb2dnZWQuXG4gICAqIE9taXQgaXQgd2hlbiB0aGUgY2FsbGVyIGNhbm5vdCBwcm92ZSB0aGUgY3JlZGVudGlhbCBpZGVudGl0eTsgdGhhdCBjYWxsXG4gICAqIGJ5cGFzc2VzIHNoYXJlZCBjYWNoaW5nIHNvIG9uZSBwcmluY2lwYWwgY2FuIG5ldmVyIHJlYWQgYW5vdGhlcidzXG4gICAqIGNhdGFsb2d1ZS5cbiAgICovXG4gIGNhY2hlSWRlbnRpdHk/OiBzdHJpbmc7XG59XG5cbi8qKiBIYXNoIGFuIG9wYXF1ZSBjcmVkZW50aWFsIGlkZW50aXR5IGJlZm9yZSBoYW5kaW5nIGl0IHRvIENhY2hlTWFuYWdlci4gKi9cbmZ1bmN0aW9uIGNhY2hlVXNlcktleShpZGVudGl0eTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBtb2RlbC0ke2NyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGlkZW50aXR5KS5kaWdlc3QoXCJoZXhcIil9YDtcbn1cblxuLyoqXG4gKiBMaXN0IE1vZGVsIFNlcnZpbmcgZW5kcG9pbnRzIGZvciB0aGUgd29ya3NwYWNlIG93bmluZyBgY2xpZW50YCwgcm91dGVkXG4gKiB0aHJvdWdoIEFwcEtpdCdzIGBDYWNoZU1hbmFnZXJgLiBUaGUgbWFuYWdlciBnaXZlcyB1cyBldmVyeXRoaW5nXG4gKiBgY2FjaGV0b29scy5UVExDYWNoZWAgcHJvdmlkZXMgcGx1cyB3aGF0IGBjYWNoZXRvb2xzLWFzeW5jYCBhZGRzIG9uIHRvcDpcbiAqIHBlci1lbnRyeSBUVEwsIGluLWZsaWdodCByZXF1ZXN0IGNvYWxlc2NpbmcgKGNvbmN1cnJlbnQgY2FsbGVycyBzaGFyZSBvbmVcbiAqIGZldGNoIHZpYSB0aGUgbWFuYWdlcidzIGludGVybmFsIGBpbkZsaWdodFJlcXVlc3RzYCBtYXApLCBib3VuZGVkIHNpemUsXG4gKiB0ZWxlbWV0cnkgc3BhbnMgKGBjYWNoZS5nZXRPckV4ZWN1dGVgKSwgYW5kIG9wdGlvbmFsIExha2ViYXNlIHBlcnNpc3RlbmNlIHNvXG4gKiB0aGUgY2F0YWxvZ3VlIHN1cnZpdmVzIHJlc3RhcnRzIHdoZW4gdGhlIGxha2ViYXNlIHBsdWdpbiBpcyB3aXJlZCB1cC5cbiAqXG4gKiBSZXR1cm5zIHBsYWluIHtAbGluayBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5fSBvYmplY3RzIChhIHN0YWJsZSBzdWJzZXQgb2YgdGhlXG4gKiBTREsgdHlwZSkgc28gY2FjaGUgaGl0cyBuZXZlciBleHBvc2Ugc3RhbGUgU0RLIGludGVybmFscy4gRXJyb3JzIGZyb21cbiAqIGBDYWNoZU1hbmFnZXJgIG9yIHRoZSBTREsgZmV0Y2ggcHJvcGFnYXRlIHRvIHRoZSBjYWxsZXIgLSB3ZSBkb24ndCBzd2FsbG93XG4gKiB0aGVtIHNvIHVzZXJzIHNlZSB0aGUgcmVhbCBhdXRoIC8gbmV0d29yayBpc3N1ZS5cbiAqXG4gKiBAcGFyYW0gaG9zdCAtIFdvcmtzcGFjZSBob3N0IHVzZWQgYXMgdGhlIGNhY2hlIGtleS4gUGFzcyB0aGUgdmFsdWUgcmVzb2x2ZWRcbiAqICAgZnJvbSBgY2xpZW50LmNvbmZpZy5nZXRIb3N0KClgIHNvIG11bHRpLWhvc3QgYXBwcyBzaGFyZSBvbmUgZW50cnkgcGVyXG4gKiAgIHdvcmtzcGFjZS5cbiAqIEBwYXJhbSBvcHRpb25zLnR0bE1zIC0gT3ZlcnJpZGUgdGhlIGRlZmF1bHQgVFRMIGp1c3QgZm9yIHRoaXMgY2FsbC4gRm9yd2FyZGVkXG4gKiAgIHRvIGBDYWNoZU1hbmFnZXJgIGFzIHNlY29uZHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsaXN0U2VydmluZ0VuZHBvaW50cyhcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuICBob3N0OiBzdHJpbmcsXG4gIG9wdGlvbnM6IExpc3RTZXJ2aW5nRW5kcG9pbnRzT3B0aW9ucyA9IHt9LFxuKTogUHJvbWlzZTxTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+IHtcbiAgaWYgKCFvcHRpb25zLmNhY2hlSWRlbnRpdHkpIHJldHVybiBmZXRjaEVuZHBvaW50cyhjbGllbnQpO1xuICBjb25zdCB0dGxTZWMgPSBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKChvcHRpb25zLnR0bE1zID8/IERFRkFVTFRfTU9ERUxfQ0FDSEVfVFRMX01TKSAvIDEwMDApKTtcbiAgcmV0dXJuIENhY2hlTWFuYWdlci5nZXRJbnN0YW5jZVN5bmMoKS5nZXRPckV4ZWN1dGUoXG4gICAgW0NBQ0hFX0tFWV9OQU1FU1BBQ0UsIGhvc3RdLFxuICAgICgpID0+IGZldGNoRW5kcG9pbnRzKGNsaWVudCksXG4gICAgY2FjaGVVc2VyS2V5KG9wdGlvbnMuY2FjaGVJZGVudGl0eSksXG4gICAgeyB0dGw6IHR0bFNlYyB9LFxuICApO1xufVxuXG4vKipcbiAqIExpc3QgdGhlIHdvcmtzcGFjZSdzIHNlcnZpbmcgZW5kcG9pbnRzIGFzIG1pbmltYWxcbiAqIHtAbGluayBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5fSBvYmplY3RzIHN0cmFpZ2h0IGZyb20gdGhlIFNESzogbm8gY2FjaGluZywgYW5kXG4gKiBub25lIG9mIHRoZSBjYWNoZS1sb2FkIGVucmljaG1lbnQgKHtAbGluayBsaXN0U2VydmluZ0VuZHBvaW50c30gYWRkcyB0aGVcbiAqIHtAbGluayBNb2RlbENsYXNzfSBzdGFtcCBhbmQgdGhlIGVtYmVkZGluZy1kaW1lbnNpb24gcHJvYmUpLiBVc2UgdGhpcyBmb3IgYVxuICogb25lLXNob3QsIGRlcGVuZGVuY3ktbGlnaHQgbGlzdGluZyAtIGUuZy4gYSBDTEkgdGhhdCBvbmx5IG5lZWRzIG5hbWVzL3Rhc2tzXG4gKiBmb3IgZnV6enkgcmVzb2x1dGlvbiBhbmQgZG9lc24ndCB3YW50IEFwcEtpdCdzIGBDYWNoZU1hbmFnZXJgIG9yIHRoZVxuICogcGVyLWVtYmVkZGluZyBwaW5nIGNvc3QuIFByZWZlciB7QGxpbmsgbGlzdFNlcnZpbmdFbmRwb2ludHN9IGZvciB0aGUgY2FjaGVkLFxuICogZW5yaWNoZWQgdmlldy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RTZXJ2aW5nRW5kcG9pbnRzVW5jYWNoZWQoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSxcbik6IFByb21pc2U8U2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPiB7XG4gIGNvbnN0IGVuZHBvaW50czogdW5rbm93bltdID0gW107XG4gIGZvciBhd2FpdCAoY29uc3QgZXAgb2YgY2xpZW50LnNlcnZpbmdFbmRwb2ludHMubGlzdCgpKSB7XG4gICAgZW5kcG9pbnRzLnB1c2goZXApO1xuICB9XG4gIHJldHVybiBub3JtYWxpemVFbmRwb2ludHMoZW5kcG9pbnRzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hFbmRwb2ludHMoY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlKTogUHJvbWlzZTxTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+IHtcbiAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgY29uc3Qgb3V0ID0gYXdhaXQgbGlzdFNlcnZpbmdFbmRwb2ludHNVbmNhY2hlZChjbGllbnQpO1xuICBzdGFtcE1vZGVsQ2xhc3NlcyhvdXQpO1xuICBhd2FpdCBtZWFzdXJlRW1iZWRkaW5nRGltZW5zaW9ucyhjbGllbnQsIG91dCk7XG4gIGxvZ2dlci5kZWJ1ZyhcImxpc3RlZFwiLCB7IGNvdW50OiBvdXQubGVuZ3RoLCBlbGFwc2VkTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQgfSk7XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogU3RhbXAgZWFjaCBzdW1tYXJ5J3Mge0BsaW5rIFNlcnZpbmdFbmRwb2ludFN1bW1hcnkuY2xhc3N9IGZyb20gdGhlIHJlbGF0aXZlXG4gKiBjbGFzc2lmaWNhdGlvbiBvZiB0aGUgd2hvbGUgc2V0LiBNdXRhdGVzIGBzdW1tYXJpZXNgIGluIHBsYWNlLiBFbmRwb2ludHMgdGhlXG4gKiBjbGFzc2lmaWVyIGRvZXNuJ3QgcmVjb2duaXplIChjdXN0b20sIHVuc2NvcmVkLCBub24tTExNKSBhcmUgbGVmdCB3aXRob3V0IGFcbiAqIGNsYXNzLlxuICovXG5mdW5jdGlvbiBzdGFtcE1vZGVsQ2xhc3NlcyhzdW1tYXJpZXM6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSk6IHZvaWQge1xuICBjb25zdCBjbGFzc09mID0gY2xhc3NpZnlFbmRwb2ludENsYXNzZXMoc3VtbWFyaWVzKTtcbiAgZm9yIChjb25zdCBzdW1tYXJ5IG9mIHN1bW1hcmllcykge1xuICAgIGNvbnN0IGNscyA9IGNsYXNzT2YuZ2V0KHN1bW1hcnkubmFtZSk7XG4gICAgaWYgKGNscyAhPT0gdW5kZWZpbmVkKSBzdW1tYXJ5LmNsYXNzID0gY2xzO1xuICB9XG59XG5cbi8qKlxuICogTWVhc3VyZSB0aGUgZW1iZWRkaW5nIHZlY3RvciBkaW1lbnNpb24gb2YgZXZlcnkge0BsaW5rIE1vZGVsQ2xhc3MuRW1iZWRkaW5nfVxuICogZW5kcG9pbnQgYnkgcGluZ2luZyBpdCBvbmNlLCBhbGwgaW4gcGFyYWxsZWwuIE11dGF0ZXMgdGhlIG1hdGNoaW5nIHN1bW1hcmllc1xuICogaW4gcGxhY2Ugd2l0aCB0aGUgcmVzdWx0aW5nIGBkaW1lbnNpb25gLiBSdW5zIG9ubHkgb24gYSBjYWNoZSBtaXNzIChpdCdzXG4gKiBjYWxsZWQgZnJvbSB7QGxpbmsgZmV0Y2hFbmRwb2ludHN9KSwgc28gdGhlIHByb2JlIGNvc3QgaXMgYW1vcnRpemVkIGFjcm9zcyB0aGVcbiAqIGNhY2hlZCBUVEwgd2luZG93LiBQZXItZW5kcG9pbnQgZmFpbHVyZXMgYXJlIHN3YWxsb3dlZCAobG9nZ2VkIGF0IHdhcm4pIHNvXG4gKiBvbmUgdW5yZWFjaGFibGUgZW1iZWRkaW5nIG1vZGVsIG5ldmVyIGZhaWxzIHRoZSBsaXN0aW5nLlxuICovXG5hc3luYyBmdW5jdGlvbiBtZWFzdXJlRW1iZWRkaW5nRGltZW5zaW9ucyhcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuICBzdW1tYXJpZXM6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbik6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBzdW1tYXJpZXNcbiAgICAgIC5maWx0ZXIoKHMpID0+IHMuY2xhc3MgPT09IE1vZGVsQ2xhc3MuRW1iZWRkaW5nKVxuICAgICAgLm1hcChhc3luYyAoc3VtbWFyeSkgPT4ge1xuICAgICAgICBjb25zdCBkaW1lbnNpb24gPSBhd2FpdCBwaW5nRW1iZWRkaW5nRGltZW5zaW9uKGNsaWVudCwgc3VtbWFyeS5uYW1lKTtcbiAgICAgICAgaWYgKGRpbWVuc2lvbiAhPT0gdW5kZWZpbmVkKSBzdW1tYXJ5LmRpbWVuc2lvbiA9IGRpbWVuc2lvbjtcbiAgICAgIH0pLFxuICApO1xufVxuXG4vKipcbiAqIEJlc3QtZWZmb3J0IGVtYmVkZGluZyBkaW1lbnNpb24gcHJvYmU6IHF1ZXJ5IGBuYW1lYCB3aXRoIGEgdGlueSBgXCJwaW5nXCJgXG4gKiBpbnB1dCBhbmQgcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIHJldHVybmVkIHZlY3Rvci4gUmV0dXJucyBgdW5kZWZpbmVkYCAoYW5kXG4gKiBsb2dzIGF0IHdhcm4pIHdoZW4gdGhlIGVuZHBvaW50IGNhbid0IGJlIHF1ZXJpZWQgb3IgcmV0dXJucyBubyB2ZWN0b3IgLSB0aGVcbiAqIGRpbWVuc2lvbiBpcyBpbmZvcm1hdGlvbmFsLCBuZXZlciByZXF1aXJlZC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcGluZ0VtYmVkZGluZ0RpbWVuc2lvbihcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuICBuYW1lOiBzdHJpbmcsXG4pOiBQcm9taXNlPG51bWJlciB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnNlcnZpbmdFbmRwb2ludHMucXVlcnkoeyBuYW1lLCBpbnB1dDogXCJwaW5nXCIgfSk7XG4gICAgY29uc3QgZGltZW5zaW9uID0gcmVzcG9uc2UuZGF0YT8uWzBdPy5lbWJlZGRpbmc/Lmxlbmd0aDtcbiAgICBpZiAodHlwZW9mIGRpbWVuc2lvbiA9PT0gXCJudW1iZXJcIiAmJiBkaW1lbnNpb24gPiAwKSByZXR1cm4gZGltZW5zaW9uO1xuICAgIGxvZ2dlci53YXJuKFwiZW1iZWRkaW5nIHBpbmcgcmV0dXJuZWQgbm8gdmVjdG9yXCIsIHsgbmFtZSB9KTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybihcImVtYmVkZGluZyBwaW5nIGZhaWxlZFwiLCB7IG5hbWUsIGVycm9yOiBlcnJvclV0aWxzLmVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBGb3JjZS1ldmljdCBjYWNoZWQgZW5kcG9pbnQgbGlzdGluZ3MgdmlhIEFwcEtpdCdzIGBDYWNoZU1hbmFnZXJgLiBBIGhvc3QgYW5kXG4gKiBpZGVudGl0eSBkZWxldGUgb25seSB0aGF0IHByaW5jaXBhbCdzIHdvcmtzcGFjZSBlbnRyeS4gQmVjYXVzZSBDYWNoZU1hbmFnZXJcbiAqIGNhbm5vdCBlbnVtZXJhdGUgYSBuYW1lc3BhY2UsIG9taXR0aW5nIGVpdGhlciB2YWx1ZSBjbGVhcnMgdGhlIGNvbXBsZXRlXG4gKiBtYW5hZ2VyIGFuZCBzaG91bGQgYmUgcmVzZXJ2ZWQgZm9yIHRlc3RzIG9yIGFkbWluaXN0cmF0aXZlIHJlZnJlc2hlcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFyU2VydmluZ0VuZHBvaW50c0NhY2hlKFxuICBob3N0Pzogc3RyaW5nLFxuICBjYWNoZUlkZW50aXR5Pzogc3RyaW5nLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGNhY2hlID0gQ2FjaGVNYW5hZ2VyLmdldEluc3RhbmNlU3luYygpO1xuICBpZiAoaG9zdCAmJiBjYWNoZUlkZW50aXR5KSB7XG4gICAgY29uc3Qga2V5ID0gY2FjaGUuZ2VuZXJhdGVLZXkoW0NBQ0hFX0tFWV9OQU1FU1BBQ0UsIGhvc3RdLCBjYWNoZVVzZXJLZXkoY2FjaGVJZGVudGl0eSkpO1xuICAgIGF3YWl0IGNhY2hlLmRlbGV0ZShrZXkpO1xuICB9IGVsc2Uge1xuICAgIGF3YWl0IGNhY2hlLmNsZWFyKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgZnV6enktcmVzb2x2aW5nIGEgdXNlci1zdXBwbGllZCBtb2RlbCBuYW1lIGFnYWluc3QgdGhlIGxpdmVcbiAqIGVuZHBvaW50IGxpc3QuIGBzY29yZWAgaXMgdGhlIFJ1c3QgcmFua2VyJ3MgZGlzdGFuY2UgKGAwYCBpcyBleGFjdCwgYDFgIGlzIG5vIG1hdGNoKTtcbiAqIGBtYXRjaGVkYCBpcyBgZmFsc2VgIHdoZW4gdGhlIHNjb3JlIGV4Y2VlZHMgdGhlIGNvbmZpZ3VyZWQgdGhyZXNob2xkIHNvXG4gKiBjYWxsZXJzIGNhbiBmYWxsIGJhY2sgdG8gdGhlIG9yaWdpbmFsIGlucHV0IChEYXRhYnJpY2tzIHdpbGwgdGhlbiByZXR1cm4gYVxuICogY2xlYW4gNDA0KS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZE1vZGVsIHtcbiAgbW9kZWxJZDogc3RyaW5nO1xuICBtYXRjaGVkOiBib29sZWFuO1xuICBzY29yZT86IG51bWJlcjtcbn1cblxuLyoqIE9wdGlvbnMgYWNjZXB0ZWQgYnkge0BsaW5rIHJlc29sdmVNb2RlbElkfSAvIHtAbGluayBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZU1vZGVsT3B0aW9ucyB7XG4gIC8qKiBGdXp6eSBkaXN0YW5jZSB0aHJlc2hvbGQgKDAgPSBleGFjdCwgMSA9IGFueXRoaW5nKS4gRGVmYXVsdCBgMC40YC4gKi9cbiAgdGhyZXNob2xkPzogbnVtYmVyO1xuICAvKiogUmVxdWlyZSBhIG1vZGVsIHZlcmlmaWVkIGZvciBhIGNvbXBsZXRlIGZ1bmN0aW9uLXRvb2wgcm91bmQtdHJpcC4gKi9cbiAgcmVxdWlyZXNUb29scz86IGJvb2xlYW47XG59XG5cbi8qKiBBIHNlcnZpbmcgZW5kcG9pbnQgcGFpcmVkIHdpdGggaXRzIGZ1enp5LW1hdGNoIGRpc3RhbmNlIGZvciBhIHF1ZXJ5LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTY29yZWRFbmRwb2ludCB7XG4gIGVuZHBvaW50OiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5O1xuICAvKiogRnV6enkgZGlzdGFuY2U6IGAwYCBpcyBleGFjdCwgYDFgIGlzIG5vIG1hdGNoLiAqL1xuICBzY29yZTogbnVtYmVyO1xufVxuXG4vKipcbiAqIEZ1enp5LXJhbmsgZW5kcG9pbnRzIGJ5IGhvdyBjbG9zZWx5IHRoZWlyIGBuYW1lYCBtYXRjaGVzIGBpbnB1dGAsIGJlc3RcbiAqIChsb3dlc3Qgc2NvcmUpIGZpcnN0LCBrZWVwaW5nIG9ubHkgdGhvc2Ugd2l0aGluIGB0aHJlc2hvbGRgOlxuICpcbiAqIDEuIEFuIGV4YWN0IG5hbWUgbWF0Y2ggc2hvcnQtY2lyY3VpdHMgdG8gYSBzaW5nbGUgYHNjb3JlOiAwYCByZXN1bHQuXG4gKiAyLiBPdGhlcndpc2UgUnVzdCB0b2tlbml6ZXMgdGhlIGlucHV0IGFuZCBzY29yZXMgZXZlcnkgZW5kcG9pbnQgdGhyb3VnaCB0aGVcbiAqICAgIHNhbWUgZnV6enktZGlzdGFuY2UgcG9saWN5IHVzZWQgYnkge0BsaW5rIGxvb2t1cE1vZGVsc30uXG4gKlxuICogUmV0dXJucyBgW11gIGZvciBhbiBlbXB0eSBlbmRwb2ludCBsaXN0IG9yIHdoZW4gYGlucHV0YCB0b2tlbml6ZXMgdG8gbm90aGluZyxcbiAqIHNvIGNhbGxlcnMgZmFsbCBiYWNrIHRvIHRoZSByYXcgaW5wdXQgYW5kIGxldCBEYXRhYnJpY2tzIHN1cmZhY2UgYSBjbGVhbiA0MDQuXG4gKiBUaGlzIG11bHRpLXJlc3VsdCBjb3JlIGlzIHNoYXJlZCBieSB7QGxpbmsgcmVzb2x2ZU1vZGVsSWR9IChzaW5nbGUgYmVzdCkgYW5kXG4gKiB0aGUgcmFua2VkIGBsb29rdXBNb2RlbHNgIHNlbGVjdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VhcmNoU2VydmluZ0VuZHBvaW50cyhcbiAgaW5wdXQ6IHN0cmluZyxcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIG9wdGlvbnM6IFJlc29sdmVNb2RlbE9wdGlvbnMgPSB7fSxcbik6IFNjb3JlZEVuZHBvaW50W10ge1xuICBpZiAoZW5kcG9pbnRzLmxlbmd0aCA9PT0gMCB8fCAhaW5wdXQudHJpbSgpKSByZXR1cm4gW107XG4gIHJldHVybiByYW5rRW5kcG9pbnRzKFxuICAgIGVuZHBvaW50cyxcbiAgICB7XG4gICAgICBzZWFyY2g6IGlucHV0LFxuICAgICAgLi4uKG9wdGlvbnMucmVxdWlyZXNUb29scyAhPT0gdW5kZWZpbmVkID8geyByZXF1aXJlc1Rvb2xzOiBvcHRpb25zLnJlcXVpcmVzVG9vbHMgfSA6IHt9KSxcbiAgICAgIHRocmVzaG9sZDogb3B0aW9ucy50aHJlc2hvbGQgPz8gREVGQVVMVF9GVVpaWV9USFJFU0hPTEQsXG4gICAgfSxcbiAgICB7XG4gICAgICBpbmNsdWRlRGVwcmVjYXRlZDogdHJ1ZSxcbiAgICAgIG1vZGVsQ2xhc3M6IG1vZGVsLk1vZGVsQ2xhc3MuQ2hhdEJhbGFuY2VkLFxuICAgICAgdGFzazogXCJsbG0vdjEvY2hhdFwiLFxuICAgIH0sXG4gICkubWFwKChyYW5rZWQpID0+ICh7IGVuZHBvaW50OiByYW5rZWQuZW5kcG9pbnQsIHNjb3JlOiByYW5rZWQuc2NvcmUgPz8gMCB9KSk7XG59XG5cbi8qKlxuICogU25hcCBhIHVzZXItc3VwcGxpZWQgbW9kZWwgbmFtZSB0byB0aGUgc2luZ2xlIGNsb3Nlc3QgY29uZmlndXJlZCBzZXJ2aW5nXG4gKiBlbmRwb2ludCB2aWEge0BsaW5rIHNlYXJjaFNlcnZpbmdFbmRwb2ludHN9LiBSZXR1cm5zIHRoZSBpbnB1dCB1bmNoYW5nZWQgd2l0aFxuICogYG1hdGNoZWQ6IGZhbHNlYCB3aGVuIG5vdGhpbmcgc2NvcmVzIHdpdGhpbiB0aGUgdGhyZXNob2xkIChvciB0aGUgY2F0YWxvZ3VlXG4gKiBpcyBlbXB0eSksIHNvIGEgZGVsaWJlcmF0ZSBtb2RlbCBpZCBpcyBuZXZlciBzaWxlbnRseSByZXdyaXR0ZW4gdG8gYVxuICogc2ltaWxhci1sb29raW5nIG5laWdoYm91ciBhbmQgdGhlIHVwc3RyZWFtIGNhbGwgc3VyZmFjZXMgdGhlIGNhbm9uaWNhbCA0MDQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTW9kZWxJZChcbiAgaW5wdXQ6IHN0cmluZyxcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIG9wdGlvbnM6IFJlc29sdmVNb2RlbE9wdGlvbnMgPSB7fSxcbik6IFJlc29sdmVkTW9kZWwge1xuICBjb25zdCBbYmVzdF0gPSBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzKGlucHV0LCBlbmRwb2ludHMsIG9wdGlvbnMpO1xuICBpZiAoYmVzdCkge1xuICAgIHJldHVybiB7IG1vZGVsSWQ6IGJlc3QuZW5kcG9pbnQubmFtZSwgbWF0Y2hlZDogdHJ1ZSwgc2NvcmU6IGJlc3Quc2NvcmUgfTtcbiAgfVxuICByZXR1cm4geyBtb2RlbElkOiBpbnB1dCwgbWF0Y2hlZDogZmFsc2UgfTtcbn1cbiJdfQ==
|
|
193
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtY2F0YWxvZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlbC1jYXRhbG9nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxLQUFLLEVBQStCLE1BQU0seUJBQXlCLENBQUM7QUFFN0UsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGtCQUFrQixFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzRixNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBRTdCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7QUFTM0MsMEdBQTBHO0FBQzFHLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRXhELHdFQUF3RTtBQUN4RSxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLENBQUM7QUFFM0MsZ0VBQWdFO0FBQ2hFLE1BQU0sbUJBQW1CLEdBQUcsbUJBQW1CLENBQUM7QUFvQmhELDRFQUE0RTtBQUM1RSxTQUFTLFlBQVksQ0FBQyxRQUFnQjtJQUNwQyxPQUFPLFNBQVMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztBQUN4RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLG9CQUFvQixDQUN4QyxNQUEyQixFQUMzQixJ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T0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDM0UsQ0FBQztJQUNELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBMaXZlIERhdGFicmlja3MgTW9kZWwgU2VydmluZyBjYXRhbG9ndWUgYWNjZXNzLlxuICpcbiAqIExpc3RzIHRoZSB3b3Jrc3BhY2UncyBgL3NlcnZpbmctZW5kcG9pbnRzYCBhbmQsIHdoZW4gdGhlIGNhbGxlciBzdXBwbGllcyBhXG4gKiB0cnVzdGVkIGNyZWRlbnRpYWwgaWRlbnRpdHksIGNhY2hlcyB0aGUgcmVzdWx0IHBlciBob3N0IGFuZCBpZGVudGl0eSB3aXRoIGFcbiAqIFRUTCB2aWEgQXBwS2l0J3MgYENhY2hlTWFuYWdlcmAuIENvbmN1cnJlbnQgY2FsbGVycyBpbiB0aGUgc2FtZSBzY29wZSBzaGFyZVxuICogb25lIGluLWZsaWdodCBwcm9taXNlLiBTdXJmYWNlcyBlYWNoIGVuZHBvaW50IGFzIGEgc3RhYmxlXG4gKiB7QGxpbmsgU2VydmluZ0VuZHBvaW50U3VtbWFyeX0gLSBpbmNsdWRpbmcgdGhlIEZvdW5kYXRpb24gTW9kZWwgQVBJXG4gKiBgcXVhbGl0eWAgLyBgc3BlZWRgIC8gYGNvc3RgIHByb2ZpbGUgd2hlbiBwcmVzZW50LCB0aGUgY2xhc3NpZmllZFxuICoge0BsaW5rIE1vZGVsQ2xhc3N9LCBhbmQgKGZvciBlbWJlZGRpbmcgZW5kcG9pbnRzKSB0aGUgbWVhc3VyZWQgdmVjdG9yXG4gKiBgZGltZW5zaW9uYCAtIGFuZCBzbmFwcyBsb29zZSwgaHVtYW4tdHlwZWQgbmFtZXMgdG8gcmVhbCBlbmRwb2ludCBpZHNcbiAqIHRocm91Z2ggdGhlIFR5cGVTY3JpcHQgbW9kZWwgcmFua2VyIHNvIHRva2VucyBsaWtlIGBcImNsYXVkZSBzb25uZXRcImAgcmVzb2x2ZSB0b1xuICogYGRhdGFicmlja3MtY2xhdWRlLXNvbm5ldC00LTZgLlxuICpcbiAqIFRoZSBjbGFzcyBzdGFtcCBhbmQgZW1iZWRkaW5nIGRpbWVuc2lvbiBhcmUgY29tcHV0ZWQgb25jZSBwZXIgY2FjaGUgbG9hZDpcbiAqIGV2ZXJ5IGVtYmVkZGluZyBlbmRwb2ludCBpcyBcInBpbmdlZFwiIGluIHBhcmFsbGVsIGFuZCB0aGUgcmVzdWx0aW5nIHZlY3RvclxuICogbGVuZ3RoIHJlY29yZGVkLCBzbyB0aGUgY29zdCBpcyBwYWlkIG9uIGEgY2FjaGUgbWlzcywgbm90IHBlciByZWFkLiBUaGUgcGluZ1xuICogaXMgYmVzdC1lZmZvcnQgLSBhIGZhaWx1cmUgbG9ncyBhdCBkZWJ1ZyBhbmQgbGVhdmVzIGBkaW1lbnNpb25gIHVuc2V0IHJhdGhlclxuICogdGhhbiBmYWlsaW5nIHRoZSB3aG9sZSBsaXN0aW5nLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5pbXBvcnQgeyBDYWNoZU1hbmFnZXIgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBhcHBraXQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGVycm9yVXRpbHMsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgdHlwZSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1vZGVsXCI7XG5cbmltcG9ydCB7IGNsYXNzaWZ5RW5kcG9pbnRDbGFzc2VzLCBub3JtYWxpemVFbmRwb2ludHMsIHJhbmtFbmRwb2ludHMgfSBmcm9tIFwiLi9fcmFua2luZy50c1wiO1xuXG5jb25zdCB7IE1vZGVsQ2xhc3MgfSA9IG1vZGVsO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwibW9kZWwvc2VydmluZ1wiKTtcblxuLyoqXG4gKiBTdHJ1Y3R1cmFsIHR5cGUgZm9yIHRoZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSBjbGllbnQsIHJlLWV4cG9ydGVkIHNvIHRoZSByZXN0XG4gKiBvZiB0aGlzIHBhY2thZ2UgY2FuIGtlZXAgaW1wb3J0aW5nIGl0IGZyb20gaGVyZS4gU2VlXG4gKiBgYXBwa2l0LldvcmtzcGFjZUNsaWVudExpa2VgIChub2RlLWFwcGtpdCkgZm9yIHRoZSBjYW5vbmljYWwgZGVmaW5pdGlvbi5cbiAqL1xuZXhwb3J0IHR5cGUgV29ya3NwYWNlQ2xpZW50TGlrZSA9IFBpY2s8YXBwa2l0LldvcmtzcGFjZUNsaWVudExpa2UsIFwic2VydmluZ0VuZHBvaW50c1wiPjtcblxuLyoqIERlZmF1bHQgVFRMIGZvciB0aGUgaW4tbWVtb3J5IGVuZHBvaW50IGNhY2hlLiBNYXRjaGVzIHRoZSBEYXRhYnJpY2tzIFNESydzIHNlc3Npb24gbGlmZXRpbWUgYnVkZ2V0LiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTU9ERUxfQ0FDSEVfVFRMX01TID0gNSAqIDYwICogMTAwMDtcblxuLyoqIERlZmF1bHQgZnV6enkgZGlzdGFuY2UgdGhyZXNob2xkIGJlbG93IHdoaWNoIGEgbWF0Y2ggaXMgYWNjZXB0ZWQuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9GVVpaWV9USFJFU0hPTEQgPSAwLjQ7XG5cbi8qKiBDYWNoZSBrZXkgcGFydHMgdW5kZXIgd2hpY2ggZW5kcG9pbnQgbGlzdGluZ3MgYXJlIHN0b3JlZC4gKi9cbmNvbnN0IENBQ0hFX0tFWV9OQU1FU1BBQ0UgPSBcInNlcnZpbmctZW5kcG9pbnRzXCI7XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgbGlzdFNlcnZpbmdFbmRwb2ludHN9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBMaXN0U2VydmluZ0VuZHBvaW50c09wdGlvbnMge1xuICAvKipcbiAgICogT3ZlcnJpZGUgdGhlIGRlZmF1bHQgY2FjaGUgVFRMIGZvciB0aGlzIGNhbGwsIGluIG1pbGxpc2Vjb25kcy4gRm9yd2FyZGVkIHRvXG4gICAqIGBDYWNoZU1hbmFnZXJgIGFzIHNlY29uZHMuXG4gICAqL1xuICB0dGxNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRydXN0ZWQgaWRlbnRpdHkgb2YgdGhlIGNyZWRlbnRpYWwgdXNlZCBieSBgY2xpZW50YC5cbiAgICpcbiAgICogVGhlIHZhbHVlIGlzIGhhc2hlZCBiZWZvcmUgaXQgZW50ZXJzIHRoZSBjYWNoZSBrZXkgYW5kIGlzIG5ldmVyIGxvZ2dlZC5cbiAgICogT21pdCBpdCB3aGVuIHRoZSBjYWxsZXIgY2Fubm90IHByb3ZlIHRoZSBjcmVkZW50aWFsIGlkZW50aXR5OyB0aGF0IGNhbGxcbiAgICogYnlwYXNzZXMgc2hhcmVkIGNhY2hpbmcgc28gb25lIHByaW5jaXBhbCBjYW4gbmV2ZXIgcmVhZCBhbm90aGVyJ3NcbiAgICogY2F0YWxvZ3VlLlxuICAgKi9cbiAgY2FjaGVJZGVudGl0eT86IHN0cmluZztcbn1cblxuLyoqIEhhc2ggYW4gb3BhcXVlIGNyZWRlbnRpYWwgaWRlbnRpdHkgYmVmb3JlIGhhbmRpbmcgaXQgdG8gQ2FjaGVNYW5hZ2VyLiAqL1xuZnVuY3Rpb24gY2FjaGVVc2VyS2V5KGlkZW50aXR5OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYG1vZGVsLSR7Y3JlYXRlSGFzaChcInNoYTI1NlwiKS51cGRhdGUoaWRlbnRpdHkpLmRpZ2VzdChcImhleFwiKX1gO1xufVxuXG4vKipcbiAqIExpc3QgTW9kZWwgU2VydmluZyBlbmRwb2ludHMgZm9yIHRoZSB3b3Jrc3BhY2Ugb3duaW5nIGBjbGllbnRgLCByb3V0ZWRcbiAqIHRocm91Z2ggQXBwS2l0J3MgYENhY2hlTWFuYWdlcmAuIFRoZSBtYW5hZ2VyIGdpdmVzIHVzIGV2ZXJ5dGhpbmdcbiAqIGBjYWNoZXRvb2xzLlRUTENhY2hlYCBwcm92aWRlcyBwbHVzIHdoYXQgYGNhY2hldG9vbHMtYXN5bmNgIGFkZHMgb24gdG9wOlxuICogcGVyLWVudHJ5IFRUTCwgaW4tZmxpZ2h0IHJlcXVlc3QgY29hbGVzY2luZyAoY29uY3VycmVudCBjYWxsZXJzIHNoYXJlIG9uZVxuICogZmV0Y2ggdmlhIHRoZSBtYW5hZ2VyJ3MgaW50ZXJuYWwgYGluRmxpZ2h0UmVxdWVzdHNgIG1hcCksIGJvdW5kZWQgc2l6ZSxcbiAqIHRlbGVtZXRyeSBzcGFucyAoYGNhY2hlLmdldE9yRXhlY3V0ZWApLCBhbmQgb3B0aW9uYWwgTGFrZWJhc2UgcGVyc2lzdGVuY2Ugc29cbiAqIHRoZSBjYXRhbG9ndWUgc3Vydml2ZXMgcmVzdGFydHMgd2hlbiB0aGUgbGFrZWJhc2UgcGx1Z2luIGlzIHdpcmVkIHVwLlxuICpcbiAqIFJldHVybnMgcGxhaW4ge0BsaW5rIFNlcnZpbmdFbmRwb2ludFN1bW1hcnl9IG9iamVjdHMgKGEgc3RhYmxlIHN1YnNldCBvZiB0aGVcbiAqIFNESyB0eXBlKSBzbyBjYWNoZSBoaXRzIG5ldmVyIGV4cG9zZSBzdGFsZSBTREsgaW50ZXJuYWxzLiBFcnJvcnMgZnJvbVxuICogYENhY2hlTWFuYWdlcmAgb3IgdGhlIFNESyBmZXRjaCBwcm9wYWdhdGUgdG8gdGhlIGNhbGxlciAtIHdlIGRvbid0IHN3YWxsb3dcbiAqIHRoZW0gc28gdXNlcnMgc2VlIHRoZSByZWFsIGF1dGggLyBuZXR3b3JrIGlzc3VlLlxuICpcbiAqIEBwYXJhbSBob3N0IC0gV29ya3NwYWNlIGhvc3QgdXNlZCBhcyB0aGUgY2FjaGUga2V5LiBQYXNzIHRoZSB2YWx1ZSByZXNvbHZlZFxuICogICBmcm9tIGBjbGllbnQuY29uZmlnLmdldEhvc3QoKWAgc28gbXVsdGktaG9zdCBhcHBzIHNoYXJlIG9uZSBlbnRyeSBwZXJcbiAqICAgd29ya3NwYWNlLlxuICogQHBhcmFtIG9wdGlvbnMudHRsTXMgLSBPdmVycmlkZSB0aGUgZGVmYXVsdCBUVEwganVzdCBmb3IgdGhpcyBjYWxsLiBGb3J3YXJkZWRcbiAqICAgdG8gYENhY2hlTWFuYWdlcmAgYXMgc2Vjb25kcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RTZXJ2aW5nRW5kcG9pbnRzKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4gIGhvc3Q6IHN0cmluZyxcbiAgb3B0aW9uczogTGlzdFNlcnZpbmdFbmRwb2ludHNPcHRpb25zID0ge30sXG4pOiBQcm9taXNlPFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXT4ge1xuICBpZiAoIW9wdGlvbnMuY2FjaGVJZGVudGl0eSkgcmV0dXJuIGZldGNoRW5kcG9pbnRzKGNsaWVudCk7XG4gIGNvbnN0IHR0bFNlYyA9IE1hdGgubWF4KDEsIE1hdGgucm91bmQoKG9wdGlvbnMudHRsTXMgPz8gREVGQVVMVF9NT0RFTF9DQUNIRV9UVExfTVMpIC8gMTAwMCkpO1xuICByZXR1cm4gQ2FjaGVNYW5hZ2VyLmdldEluc3RhbmNlU3luYygpLmdldE9yRXhlY3V0ZShcbiAgICBbQ0FDSEVfS0VZX05BTUVTUEFDRSwgaG9zdF0sXG4gICAgKCkgPT4gZmV0Y2hFbmRwb2ludHMoY2xpZW50KSxcbiAgICBjYWNoZVVzZXJLZXkob3B0aW9ucy5jYWNoZUlkZW50aXR5KSxcbiAgICB7IHR0bDogdHRsU2VjIH0sXG4gICk7XG59XG5cbi8qKlxuICogTGlzdCB0aGUgd29ya3NwYWNlJ3Mgc2VydmluZyBlbmRwb2ludHMgYXMgbWluaW1hbFxuICoge0BsaW5rIFNlcnZpbmdFbmRwb2ludFN1bW1hcnl9IG9iamVjdHMgc3RyYWlnaHQgZnJvbSB0aGUgU0RLOiBubyBjYWNoaW5nLCBhbmRcbiAqIG5vbmUgb2YgdGhlIGNhY2hlLWxvYWQgZW5yaWNobWVudCAoe0BsaW5rIGxpc3RTZXJ2aW5nRW5kcG9pbnRzfSBhZGRzIHRoZVxuICoge0BsaW5rIE1vZGVsQ2xhc3N9IHN0YW1wIGFuZCB0aGUgZW1iZWRkaW5nLWRpbWVuc2lvbiBwcm9iZSkuIFVzZSB0aGlzIGZvciBhXG4gKiBvbmUtc2hvdCwgZGVwZW5kZW5jeS1saWdodCBsaXN0aW5nIC0gZS5nLiBhIENMSSB0aGF0IG9ubHkgbmVlZHMgbmFtZXMvdGFza3NcbiAqIGZvciBmdXp6eSByZXNvbHV0aW9uIGFuZCBkb2Vzbid0IHdhbnQgQXBwS2l0J3MgYENhY2hlTWFuYWdlcmAgb3IgdGhlXG4gKiBwZXItZW1iZWRkaW5nIHBpbmcgY29zdC4gUHJlZmVyIHtAbGluayBsaXN0U2VydmluZ0VuZHBvaW50c30gZm9yIHRoZSBjYWNoZWQsXG4gKiBlbnJpY2hlZCB2aWV3LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbGlzdFNlcnZpbmdFbmRwb2ludHNVbmNhY2hlZChcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuKTogUHJvbWlzZTxTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+IHtcbiAgY29uc3QgZW5kcG9pbnRzOiB1bmtub3duW10gPSBbXTtcbiAgZm9yIGF3YWl0IChjb25zdCBlcCBvZiBjbGllbnQuc2VydmluZ0VuZHBvaW50cy5saXN0KCkpIHtcbiAgICBlbmRwb2ludHMucHVzaChlcCk7XG4gIH1cbiAgcmV0dXJuIG5vcm1hbGl6ZUVuZHBvaW50cyhlbmRwb2ludHMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmZXRjaEVuZHBvaW50cyhjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UpOiBQcm9taXNlPFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXT4ge1xuICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICBjb25zdCBjbGFzc2lmaWVkID0gc3RhbXBNb2RlbENsYXNzZXMoYXdhaXQgbGlzdFNlcnZpbmdFbmRwb2ludHNVbmNhY2hlZChjbGllbnQpKTtcbiAgY29uc3Qgb3V0ID0gYXdhaXQgbWVhc3VyZUVtYmVkZGluZ0RpbWVuc2lvbnMoY2xpZW50LCBjbGFzc2lmaWVkKTtcbiAgbG9nZ2VyLmRlYnVnKFwibGlzdGVkXCIsIHsgY291bnQ6IG91dC5sZW5ndGgsIGVsYXBzZWRNczogRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdCB9KTtcbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBTdGFtcCBlYWNoIHN1bW1hcnkncyB7QGxpbmsgU2VydmluZ0VuZHBvaW50U3VtbWFyeS5jbGFzc30gZnJvbSB0aGUgcmVsYXRpdmVcbiAqIGNsYXNzaWZpY2F0aW9uIG9mIHRoZSB3aG9sZSBzZXQuIEVuZHBvaW50cyB0aGUgY2xhc3NpZmllciBkb2Vzbid0IHJlY29nbml6ZVxuICogKGN1c3RvbSwgdW5zY29yZWQsIG5vbi1MTE0pIGFyZSBsZWZ0IHdpdGhvdXQgYSBjbGFzcy5cbiAqL1xuZnVuY3Rpb24gc3RhbXBNb2RlbENsYXNzZXMoXG4gIHN1bW1hcmllczogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLFxuKTogU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdIHtcbiAgY29uc3QgY2xhc3NPZiA9IGNsYXNzaWZ5RW5kcG9pbnRDbGFzc2VzKHN1bW1hcmllcyk7XG4gIHJldHVybiBzdW1tYXJpZXMubWFwKChzdW1tYXJ5KSA9PiB7XG4gICAgY29uc3QgY2xzID0gY2xhc3NPZi5nZXQoc3VtbWFyeS5uYW1lKTtcbiAgICByZXR1cm4gY2xzID09PSB1bmRlZmluZWQgPyBzdW1tYXJ5IDogeyAuLi5zdW1tYXJ5LCBjbGFzczogY2xzIH07XG4gIH0pO1xufVxuXG4vKipcbiAqIE1lYXN1cmUgdGhlIGVtYmVkZGluZyB2ZWN0b3IgZGltZW5zaW9uIG9mIGV2ZXJ5IHtAbGluayBNb2RlbENsYXNzLkVtYmVkZGluZ31cbiAqIGVuZHBvaW50IGJ5IHBpbmdpbmcgaXQgb25jZSwgYWxsIGluIHBhcmFsbGVsLiBSdW5zIG9ubHkgb24gYSBjYWNoZSBtaXNzIChpdCdzXG4gKiBjYWxsZWQgZnJvbSB7QGxpbmsgZmV0Y2hFbmRwb2ludHN9KSwgc28gdGhlIHByb2JlIGNvc3QgaXMgYW1vcnRpemVkIGFjcm9zcyB0aGVcbiAqIGNhY2hlZCBUVEwgd2luZG93LiBQZXItZW5kcG9pbnQgZmFpbHVyZXMgYXJlIHN3YWxsb3dlZCAobG9nZ2VkIGF0IHdhcm4pIHNvIG9uZVxuICogdW5yZWFjaGFibGUgZW1iZWRkaW5nIG1vZGVsIG5ldmVyIGZhaWxzIHRoZSBsaXN0aW5nLlxuICovXG5hc3luYyBmdW5jdGlvbiBtZWFzdXJlRW1iZWRkaW5nRGltZW5zaW9ucyhcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuICBzdW1tYXJpZXM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbik6IFByb21pc2U8U2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPiB7XG4gIHJldHVybiBQcm9taXNlLmFsbChcbiAgICBzdW1tYXJpZXMubWFwKGFzeW5jIChzdW1tYXJ5KSA9PiB7XG4gICAgICBpZiAoc3VtbWFyeS5jbGFzcyAhPT0gTW9kZWxDbGFzcy5FbWJlZGRpbmcpIHJldHVybiBzdW1tYXJ5O1xuICAgICAgY29uc3QgZGltZW5zaW9uID0gYXdhaXQgcGluZ0VtYmVkZGluZ0RpbWVuc2lvbihjbGllbnQsIHN1bW1hcnkubmFtZSk7XG4gICAgICByZXR1cm4gZGltZW5zaW9uID09PSB1bmRlZmluZWQgPyBzdW1tYXJ5IDogeyAuLi5zdW1tYXJ5LCBkaW1lbnNpb24gfTtcbiAgICB9KSxcbiAgKTtcbn1cblxuLyoqXG4gKiBCZXN0LWVmZm9ydCBlbWJlZGRpbmcgZGltZW5zaW9uIHByb2JlOiBxdWVyeSBgbmFtZWAgd2l0aCBhIHRpbnkgYFwicGluZ1wiYFxuICogaW5wdXQgYW5kIHJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSByZXR1cm5lZCB2ZWN0b3IuIFJldHVybnMgYHVuZGVmaW5lZGAgKGFuZFxuICogbG9ncyBhdCB3YXJuKSB3aGVuIHRoZSBlbmRwb2ludCBjYW4ndCBiZSBxdWVyaWVkIG9yIHJldHVybnMgbm8gdmVjdG9yIC0gdGhlXG4gKiBkaW1lbnNpb24gaXMgaW5mb3JtYXRpb25hbCwgbmV2ZXIgcmVxdWlyZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHBpbmdFbWJlZGRpbmdEaW1lbnNpb24oXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSxcbiAgbmFtZTogc3RyaW5nLFxuKTogUHJvbWlzZTxudW1iZXIgfCB1bmRlZmluZWQ+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5zZXJ2aW5nRW5kcG9pbnRzLnF1ZXJ5KHsgbmFtZSwgaW5wdXQ6IFwicGluZ1wiIH0pO1xuICAgIGNvbnN0IGRpbWVuc2lvbiA9IHJlc3BvbnNlLmRhdGE/LlswXT8uZW1iZWRkaW5nPy5sZW5ndGg7XG4gICAgaWYgKHR5cGVvZiBkaW1lbnNpb24gPT09IFwibnVtYmVyXCIgJiYgZGltZW5zaW9uID4gMCkgcmV0dXJuIGRpbWVuc2lvbjtcbiAgICBsb2dnZXIud2FybihcImVtYmVkZGluZyBwaW5nIHJldHVybmVkIG5vIHZlY3RvclwiLCB7IG5hbWUgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLndhcm4oXCJlbWJlZGRpbmcgcGluZyBmYWlsZWRcIiwgeyBuYW1lLCBlcnJvcjogZXJyb3JVdGlscy5lcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogRm9yY2UtZXZpY3QgY2FjaGVkIGVuZHBvaW50IGxpc3RpbmdzIHZpYSBBcHBLaXQncyBgQ2FjaGVNYW5hZ2VyYC4gQSBob3N0IGFuZFxuICogaWRlbnRpdHkgZGVsZXRlIG9ubHkgdGhhdCBwcmluY2lwYWwncyB3b3Jrc3BhY2UgZW50cnkuIEJlY2F1c2UgQ2FjaGVNYW5hZ2VyXG4gKiBjYW5ub3QgZW51bWVyYXRlIGEgbmFtZXNwYWNlLCBvbWl0dGluZyBlaXRoZXIgdmFsdWUgY2xlYXJzIHRoZSBjb21wbGV0ZVxuICogbWFuYWdlciBhbmQgc2hvdWxkIGJlIHJlc2VydmVkIGZvciB0ZXN0cyBvciBhZG1pbmlzdHJhdGl2ZSByZWZyZXNoZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGVhclNlcnZpbmdFbmRwb2ludHNDYWNoZShcbiAgaG9zdD86IHN0cmluZyxcbiAgY2FjaGVJZGVudGl0eT86IHN0cmluZyxcbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjYWNoZSA9IENhY2hlTWFuYWdlci5nZXRJbnN0YW5jZVN5bmMoKTtcbiAgaWYgKGhvc3QgJiYgY2FjaGVJZGVudGl0eSkge1xuICAgIGNvbnN0IGtleSA9IGNhY2hlLmdlbmVyYXRlS2V5KFtDQUNIRV9LRVlfTkFNRVNQQUNFLCBob3N0XSwgY2FjaGVVc2VyS2V5KGNhY2hlSWRlbnRpdHkpKTtcbiAgICBhd2FpdCBjYWNoZS5kZWxldGUoa2V5KTtcbiAgfSBlbHNlIHtcbiAgICBhd2FpdCBjYWNoZS5jbGVhcigpO1xuICB9XG59XG5cbi8qKlxuICogUmVzdWx0IG9mIGZ1enp5LXJlc29sdmluZyBhIHVzZXItc3VwcGxpZWQgbW9kZWwgbmFtZSBhZ2FpbnN0IHRoZSBsaXZlXG4gKiBlbmRwb2ludCBsaXN0LiBgc2NvcmVgIGlzIHRoZSByYW5rZXIncyBkaXN0YW5jZSAoYDBgIGlzIGV4YWN0LCBgMWAgaXMgbm8gbWF0Y2gpO1xuICogYG1hdGNoZWRgIGlzIGBmYWxzZWAgd2hlbiB0aGUgc2NvcmUgZXhjZWVkcyB0aGUgY29uZmlndXJlZCB0aHJlc2hvbGQgc29cbiAqIGNhbGxlcnMgY2FuIGZhbGwgYmFjayB0byB0aGUgb3JpZ2luYWwgaW5wdXQgKERhdGFicmlja3Mgd2lsbCB0aGVuIHJldHVybiBhXG4gKiBjbGVhbiA0MDQpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkTW9kZWwge1xuICBtb2RlbElkOiBzdHJpbmc7XG4gIG1hdGNoZWQ6IGJvb2xlYW47XG4gIHNjb3JlPzogbnVtYmVyO1xufVxuXG4vKiogT3B0aW9ucyBhY2NlcHRlZCBieSB7QGxpbmsgcmVzb2x2ZU1vZGVsSWR9IC8ge0BsaW5rIHNlYXJjaFNlcnZpbmdFbmRwb2ludHN9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlTW9kZWxPcHRpb25zIHtcbiAgLyoqIEZ1enp5IGRpc3RhbmNlIHRocmVzaG9sZCAoMCA9IGV4YWN0LCAxID0gYW55dGhpbmcpLiBEZWZhdWx0IGAwLjRgLiAqL1xuICB0aHJlc2hvbGQ/OiBudW1iZXI7XG4gIC8qKiBSZXF1aXJlIGEgbW9kZWwgdmVyaWZpZWQgZm9yIGEgY29tcGxldGUgZnVuY3Rpb24tdG9vbCByb3VuZC10cmlwLiAqL1xuICByZXF1aXJlc1Rvb2xzPzogYm9vbGVhbjtcbn1cblxuLyoqIEEgc2VydmluZyBlbmRwb2ludCBwYWlyZWQgd2l0aCBpdHMgZnV6enktbWF0Y2ggZGlzdGFuY2UgZm9yIGEgcXVlcnkuICovXG5leHBvcnQgaW50ZXJmYWNlIFNjb3JlZEVuZHBvaW50IHtcbiAgZW5kcG9pbnQ6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnk7XG4gIC8qKiBGdXp6eSBkaXN0YW5jZTogYDBgIGlzIGV4YWN0LCBgMWAgaXMgbm8gbWF0Y2guICovXG4gIHNjb3JlOiBudW1iZXI7XG59XG5cbi8qKlxuICogRnV6enktcmFuayBlbmRwb2ludHMgYnkgaG93IGNsb3NlbHkgdGhlaXIgYG5hbWVgIG1hdGNoZXMgYGlucHV0YCwgYmVzdFxuICogKGxvd2VzdCBzY29yZSkgZmlyc3QsIGtlZXBpbmcgb25seSB0aG9zZSB3aXRoaW4gYHRocmVzaG9sZGA6XG4gKlxuICogMS4gQW4gZXhhY3QgbmFtZSBtYXRjaCBzaG9ydC1jaXJjdWl0cyB0byBhIHNpbmdsZSBgc2NvcmU6IDBgIHJlc3VsdC5cbiAqIDIuIE90aGVyd2lzZSB0aGUgc2hhcmVkIFR5cGVTY3JpcHQgcG9saWN5IHRva2VuaXplcyBhbmQgc2NvcmVzIGV2ZXJ5IGVuZHBvaW50IHRocm91Z2ggdGhlXG4gKiAgICBzYW1lIGZ1enp5LWRpc3RhbmNlIHBvbGljeSB1c2VkIGJ5IHtAbGluayBsb29rdXBNb2RlbHN9LlxuICpcbiAqIFJldHVybnMgYFtdYCBmb3IgYW4gZW1wdHkgZW5kcG9pbnQgbGlzdCBvciB3aGVuIGBpbnB1dGAgdG9rZW5pemVzIHRvIG5vdGhpbmcsXG4gKiBzbyBjYWxsZXJzIGZhbGwgYmFjayB0byB0aGUgcmF3IGlucHV0IGFuZCBsZXQgRGF0YWJyaWNrcyBzdXJmYWNlIGEgY2xlYW4gNDA0LlxuICogVGhpcyBtdWx0aS1yZXN1bHQgY29yZSBpcyBzaGFyZWQgYnkge0BsaW5rIHJlc29sdmVNb2RlbElkfSAoc2luZ2xlIGJlc3QpIGFuZFxuICogdGhlIHJhbmtlZCBgbG9va3VwTW9kZWxzYCBzZWxlY3Rvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlYXJjaFNlcnZpbmdFbmRwb2ludHMoXG4gIGlucHV0OiBzdHJpbmcsXG4gIGVuZHBvaW50czogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLFxuICBvcHRpb25zOiBSZXNvbHZlTW9kZWxPcHRpb25zID0ge30sXG4pOiBTY29yZWRFbmRwb2ludFtdIHtcbiAgaWYgKGVuZHBvaW50cy5sZW5ndGggPT09IDAgfHwgIWlucHV0LnRyaW0oKSkgcmV0dXJuIFtdO1xuICByZXR1cm4gcmFua0VuZHBvaW50cyhcbiAgICBlbmRwb2ludHMsXG4gICAge1xuICAgICAgc2VhcmNoOiBpbnB1dCxcbiAgICAgIC4uLihvcHRpb25zLnJlcXVpcmVzVG9vbHMgIT09IHVuZGVmaW5lZCA/IHsgcmVxdWlyZXNUb29sczogb3B0aW9ucy5yZXF1aXJlc1Rvb2xzIH0gOiB7fSksXG4gICAgICB0aHJlc2hvbGQ6IG9wdGlvbnMudGhyZXNob2xkID8/IERFRkFVTFRfRlVaWllfVEhSRVNIT0xELFxuICAgIH0sXG4gICAge1xuICAgICAgaW5jbHVkZURlcHJlY2F0ZWQ6IHRydWUsXG4gICAgICBtb2RlbENsYXNzOiBtb2RlbC5Nb2RlbENsYXNzLkNoYXRCYWxhbmNlZCxcbiAgICAgIHRhc2s6IFwibGxtL3YxL2NoYXRcIixcbiAgICB9LFxuICApLm1hcCgocmFua2VkKSA9PiAoeyBlbmRwb2ludDogcmFua2VkLmVuZHBvaW50LCBzY29yZTogcmFua2VkLnNjb3JlID8/IDAgfSkpO1xufVxuXG4vKipcbiAqIFNuYXAgYSB1c2VyLXN1cHBsaWVkIG1vZGVsIG5hbWUgdG8gdGhlIHNpbmdsZSBjbG9zZXN0IGNvbmZpZ3VyZWQgc2VydmluZ1xuICogZW5kcG9pbnQgdmlhIHtAbGluayBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzfS4gUmV0dXJucyB0aGUgaW5wdXQgdW5jaGFuZ2VkIHdpdGhcbiAqIGBtYXRjaGVkOiBmYWxzZWAgd2hlbiBub3RoaW5nIHNjb3JlcyB3aXRoaW4gdGhlIHRocmVzaG9sZCAob3IgdGhlIGNhdGFsb2d1ZVxuICogaXMgZW1wdHkpLCBzbyBhIGRlbGliZXJhdGUgbW9kZWwgaWQgaXMgbmV2ZXIgc2lsZW50bHkgcmV3cml0dGVuIHRvIGFcbiAqIHNpbWlsYXItbG9va2luZyBuZWlnaGJvdXIgYW5kIHRoZSB1cHN0cmVhbSBjYWxsIHN1cmZhY2VzIHRoZSBjYW5vbmljYWwgNDA0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZU1vZGVsSWQoXG4gIGlucHV0OiBzdHJpbmcsXG4gIGVuZHBvaW50czogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLFxuICBvcHRpb25zOiBSZXNvbHZlTW9kZWxPcHRpb25zID0ge30sXG4pOiBSZXNvbHZlZE1vZGVsIHtcbiAgY29uc3QgW2Jlc3RdID0gc2VhcmNoU2VydmluZ0VuZHBvaW50cyhpbnB1dCwgZW5kcG9pbnRzLCBvcHRpb25zKTtcbiAgaWYgKGJlc3QpIHtcbiAgICByZXR1cm4geyBtb2RlbElkOiBiZXN0LmVuZHBvaW50Lm5hbWUsIG1hdGNoZWQ6IHRydWUsIHNjb3JlOiBiZXN0LnNjb3JlIH07XG4gIH1cbiAgcmV0dXJuIHsgbW9kZWxJZDogaW5wdXQsIG1hdGNoZWQ6IGZhbHNlIH07XG59XG4iXX0=
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication-aware Databricks Model Serving client.
|
|
3
|
+
*
|
|
4
|
+
* This is the portable entry point used by generated Python bindings. It keeps
|
|
5
|
+
* authentication, endpoint discovery, caching, normalization, ranking, route
|
|
6
|
+
* selection, and published metadata in Node while exposing one small client.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { type DatabricksAuthOptions, type DatabricksProfileSummary } from "@dbx-tools/auth";
|
|
11
|
+
import { type ModelQuery, type RankedModel, type ServingEndpointSummary } from "@dbx-tools/shared-model/contracts";
|
|
12
|
+
import { type ResolveModelInput, type ResolvedModelSelection } from "./_selection.ts";
|
|
13
|
+
import { type ModelMetadata } from "./metadata.ts";
|
|
14
|
+
/** Default lifetime for one live endpoint catalogue. */
|
|
15
|
+
export declare const DEFAULT_MODEL_CLIENT_CACHE_TTL_MS: number;
|
|
16
|
+
/** Construction options for {@link createModelClient}. */
|
|
17
|
+
export interface ModelClientOptions {
|
|
18
|
+
/** Databricks authentication and profile selection options. */
|
|
19
|
+
auth?: DatabricksAuthOptions;
|
|
20
|
+
/** In-memory endpoint catalogue TTL in milliseconds. */
|
|
21
|
+
cacheTtlMs?: number;
|
|
22
|
+
}
|
|
23
|
+
/** Secret-free runtime identity and cache configuration. */
|
|
24
|
+
export interface ModelClientStatus {
|
|
25
|
+
readonly profile: string;
|
|
26
|
+
readonly host: string;
|
|
27
|
+
readonly principal: string;
|
|
28
|
+
readonly workspaceId?: string;
|
|
29
|
+
readonly cacheTtlMs: number;
|
|
30
|
+
}
|
|
31
|
+
/** Serving protocol selected for one resolved model. */
|
|
32
|
+
export type ModelProtocol = "chat" | "responses" | "embeddings";
|
|
33
|
+
/** Model selection plus route controls. */
|
|
34
|
+
export interface ModelRouteInput extends ResolveModelInput {
|
|
35
|
+
/** Force a live endpoint catalogue refresh before selection. */
|
|
36
|
+
refresh?: boolean;
|
|
37
|
+
/** Requested upstream protocol. Defaults from endpoint task and model policy. */
|
|
38
|
+
protocol?: ModelProtocol;
|
|
39
|
+
/** Whether authentication may run an interactive login. */
|
|
40
|
+
login?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/** Fully resolved Databricks route for a model request. */
|
|
43
|
+
export interface ModelRoute {
|
|
44
|
+
readonly modelId: string;
|
|
45
|
+
readonly endpoint?: ServingEndpointSummary;
|
|
46
|
+
readonly source: ResolvedModelSelection["source"];
|
|
47
|
+
readonly protocol: ModelProtocol;
|
|
48
|
+
readonly host: string;
|
|
49
|
+
readonly apiBase: string;
|
|
50
|
+
readonly url: string;
|
|
51
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
52
|
+
readonly metadata: ModelMetadata;
|
|
53
|
+
}
|
|
54
|
+
/** Stable model facade shared by Node and generated language bindings. */
|
|
55
|
+
export interface ModelClient {
|
|
56
|
+
listModels(refresh?: boolean): Promise<ServingEndpointSummary[]>;
|
|
57
|
+
searchModels(query?: ModelQuery, refresh?: boolean): Promise<RankedModel[]>;
|
|
58
|
+
resolveModel(input?: ResolveModelInput, refresh?: boolean): Promise<ResolvedModelSelection>;
|
|
59
|
+
route(input?: ModelRouteInput): Promise<ModelRoute>;
|
|
60
|
+
authenticate(login?: boolean): Promise<Record<string, string>>;
|
|
61
|
+
metadata(model: string | ServingEndpointSummary): ModelMetadata;
|
|
62
|
+
status(): ModelClientStatus;
|
|
63
|
+
profile(name?: string): DatabricksProfileSummary;
|
|
64
|
+
listProfiles(refresh?: boolean): DatabricksProfileSummary[];
|
|
65
|
+
}
|
|
66
|
+
/** Create an authentication-aware Databricks model client. */
|
|
67
|
+
export declare function createModelClient(options?: ModelClientOptions): Promise<ModelClient>;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication-aware Databricks Model Serving client.
|
|
3
|
+
*
|
|
4
|
+
* This is the portable entry point used by generated Python bindings. It keeps
|
|
5
|
+
* authentication, endpoint discovery, caching, normalization, ranking, route
|
|
6
|
+
* selection, and published metadata in Node while exposing one small client.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { DatabricksClient, } from "@dbx-tools/auth";
|
|
11
|
+
import * as log from "@dbx-tools/shared-core/log";
|
|
12
|
+
import * as object from "@dbx-tools/shared-core/object";
|
|
13
|
+
import { ModelClass, } from "@dbx-tools/shared-model/contracts";
|
|
14
|
+
import { normalizeEndpoints } from "./_ranking.js";
|
|
15
|
+
import { lookupModels, resolveModel, } from "./_selection.js";
|
|
16
|
+
import { chatCompletionsUrl, invocationsUrl, responsesUpstreamUrl } from "./invoke.js";
|
|
17
|
+
import { modelMetadataFor } from "./metadata.js";
|
|
18
|
+
import { modelServingApi } from "./policy.js";
|
|
19
|
+
const logger = log.logger("model/client");
|
|
20
|
+
/** Default lifetime for one live endpoint catalogue. */
|
|
21
|
+
export const DEFAULT_MODEL_CLIENT_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
22
|
+
const catalogueCache = new Map();
|
|
23
|
+
class DefaultModelClient {
|
|
24
|
+
client;
|
|
25
|
+
cacheTtlMs;
|
|
26
|
+
constructor(client, cacheTtlMs) {
|
|
27
|
+
this.client = client;
|
|
28
|
+
this.cacheTtlMs = cacheTtlMs;
|
|
29
|
+
}
|
|
30
|
+
async listModels(refresh = false) {
|
|
31
|
+
return cloneEndpoints(await this.catalogue(refresh));
|
|
32
|
+
}
|
|
33
|
+
async searchModels(query = {}, refresh = false) {
|
|
34
|
+
return lookupModels(await this.catalogue(refresh), query).map(({ endpoint, ...ranked }) => ({
|
|
35
|
+
...ranked,
|
|
36
|
+
endpoint: cloneEndpoint(endpoint),
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
async resolveModel(input = {}, refresh = false) {
|
|
40
|
+
const catalogue = await this.catalogue(refresh);
|
|
41
|
+
const resolved = resolveModel(catalogue, input);
|
|
42
|
+
if (isUnmatchedExplicit(catalogue, input, resolved)) {
|
|
43
|
+
return resolveModel(await this.catalogue(true), input);
|
|
44
|
+
}
|
|
45
|
+
return resolved;
|
|
46
|
+
}
|
|
47
|
+
async route(input = {}) {
|
|
48
|
+
const { refresh = false, protocol: requestedProtocol, login, ...selection } = input;
|
|
49
|
+
const effectiveSelection = requestedProtocol === "embeddings" && selection.modelClass === undefined
|
|
50
|
+
? { ...selection, modelClass: ModelClass.Embedding }
|
|
51
|
+
: selection;
|
|
52
|
+
const catalogue = await this.catalogue(refresh);
|
|
53
|
+
let resolved = resolveModel(catalogue, effectiveSelection);
|
|
54
|
+
if (isUnmatchedExplicit(catalogue, effectiveSelection, resolved)) {
|
|
55
|
+
resolved = resolveModel(await this.catalogue(true), effectiveSelection);
|
|
56
|
+
}
|
|
57
|
+
const endpoint = (await this.catalogue(false)).find((candidate) => candidate.name === resolved.modelId);
|
|
58
|
+
const protocol = requestedProtocol ?? inferProtocol(endpoint, resolved.modelId);
|
|
59
|
+
const host = this.client.host();
|
|
60
|
+
const url = routeUrl(host, resolved.modelId, protocol);
|
|
61
|
+
const headers = await this.client.auth.requestHeadersForUrl(url, login);
|
|
62
|
+
return {
|
|
63
|
+
modelId: resolved.modelId,
|
|
64
|
+
...(endpoint ? { endpoint: cloneEndpoint(endpoint) } : {}),
|
|
65
|
+
source: resolved.source,
|
|
66
|
+
protocol,
|
|
67
|
+
host,
|
|
68
|
+
apiBase: new URL("serving-endpoints", `${host.replace(/\/$/, "")}/`).toString(),
|
|
69
|
+
url,
|
|
70
|
+
headers,
|
|
71
|
+
metadata: modelMetadataFor(endpoint ?? resolved.modelId),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
authenticate(login) {
|
|
75
|
+
return this.client.auth.authenticate(login);
|
|
76
|
+
}
|
|
77
|
+
metadata(model) {
|
|
78
|
+
return modelMetadataFor(model);
|
|
79
|
+
}
|
|
80
|
+
status() {
|
|
81
|
+
return {
|
|
82
|
+
profile: this.client.auth.status().profile,
|
|
83
|
+
host: this.client.host(),
|
|
84
|
+
principal: this.client.principal(),
|
|
85
|
+
...(this.client.workspaceId() ? { workspaceId: this.client.workspaceId() } : {}),
|
|
86
|
+
cacheTtlMs: this.cacheTtlMs,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
profile(name) {
|
|
90
|
+
return this.client.auth.profile(name);
|
|
91
|
+
}
|
|
92
|
+
listProfiles(refresh = false) {
|
|
93
|
+
return this.client.auth.listProfiles(refresh);
|
|
94
|
+
}
|
|
95
|
+
catalogue(refresh) {
|
|
96
|
+
const key = catalogueKey(this.client);
|
|
97
|
+
if (refresh)
|
|
98
|
+
catalogueCache.delete(key);
|
|
99
|
+
const current = catalogueCache.get(key);
|
|
100
|
+
if (current && Date.now() < current.expiresAt)
|
|
101
|
+
return current.promise;
|
|
102
|
+
const promise = this.fetchCatalogue();
|
|
103
|
+
const entry = { promise, expiresAt: Number.POSITIVE_INFINITY };
|
|
104
|
+
catalogueCache.set(key, entry);
|
|
105
|
+
void promise.then(() => {
|
|
106
|
+
entry.expiresAt = Date.now() + this.cacheTtlMs;
|
|
107
|
+
}, () => {
|
|
108
|
+
if (catalogueCache.get(key) === entry)
|
|
109
|
+
catalogueCache.delete(key);
|
|
110
|
+
});
|
|
111
|
+
return promise;
|
|
112
|
+
}
|
|
113
|
+
async fetchCatalogue() {
|
|
114
|
+
const startedAt = Date.now();
|
|
115
|
+
const response = await this.client.request("/api/2.0/serving-endpoints");
|
|
116
|
+
if (!object.isRecord(response) || !Array.isArray(response.endpoints)) {
|
|
117
|
+
throw new Error("Databricks serving-endpoints response is missing an endpoints array");
|
|
118
|
+
}
|
|
119
|
+
const endpoints = normalizeEndpoints(response.endpoints);
|
|
120
|
+
logger.debug("listed", {
|
|
121
|
+
count: endpoints.length,
|
|
122
|
+
host: this.client.host(),
|
|
123
|
+
elapsedMs: Date.now() - startedAt,
|
|
124
|
+
});
|
|
125
|
+
return endpoints;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/** Create an authentication-aware Databricks model client. */
|
|
129
|
+
export async function createModelClient(options = {}) {
|
|
130
|
+
const cacheTtlMs = validateCacheTtl(options.cacheTtlMs);
|
|
131
|
+
return new DefaultModelClient(await DatabricksClient.create(options.auth), cacheTtlMs);
|
|
132
|
+
}
|
|
133
|
+
/** @internal Construct a model client around a test or host-owned Databricks client. */
|
|
134
|
+
export function createModelClientWithDatabricksClient(client, cacheTtlMs = DEFAULT_MODEL_CLIENT_CACHE_TTL_MS) {
|
|
135
|
+
return new DefaultModelClient(client, validateCacheTtl(cacheTtlMs));
|
|
136
|
+
}
|
|
137
|
+
/** @internal Create a model client with injectable auth host capabilities. */
|
|
138
|
+
export async function createModelClientWithDependencies(options, dependencies) {
|
|
139
|
+
return new DefaultModelClient(await DatabricksClient.create(options.auth, dependencies), validateCacheTtl(options.cacheTtlMs));
|
|
140
|
+
}
|
|
141
|
+
function validateCacheTtl(value = DEFAULT_MODEL_CLIENT_CACHE_TTL_MS) {
|
|
142
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
143
|
+
throw new Error("Model client cacheTtlMs must be a positive finite number");
|
|
144
|
+
}
|
|
145
|
+
return value;
|
|
146
|
+
}
|
|
147
|
+
function catalogueKey(client) {
|
|
148
|
+
return [client.host(), client.workspaceId() ?? "", client.principal()].join("\u0000");
|
|
149
|
+
}
|
|
150
|
+
function inferProtocol(endpoint, modelId) {
|
|
151
|
+
if (endpoint?.task === "llm/v1/embeddings")
|
|
152
|
+
return "embeddings";
|
|
153
|
+
return modelServingApi(modelId);
|
|
154
|
+
}
|
|
155
|
+
function routeUrl(host, modelId, protocol) {
|
|
156
|
+
if (protocol === "responses")
|
|
157
|
+
return responsesUpstreamUrl(host, modelId);
|
|
158
|
+
if (protocol === "chat" && modelServingApi(modelId) === "responses") {
|
|
159
|
+
return chatCompletionsUrl(host);
|
|
160
|
+
}
|
|
161
|
+
return invocationsUrl(host, modelId);
|
|
162
|
+
}
|
|
163
|
+
function isUnmatchedExplicit(catalogue, input, resolved) {
|
|
164
|
+
return (input.explicit !== undefined &&
|
|
165
|
+
input.fuzzy !== false &&
|
|
166
|
+
resolved.modelId === input.explicit &&
|
|
167
|
+
!catalogue.some((endpoint) => endpoint.name === input.explicit));
|
|
168
|
+
}
|
|
169
|
+
function cloneEndpoints(endpoints) {
|
|
170
|
+
return endpoints.map(cloneEndpoint);
|
|
171
|
+
}
|
|
172
|
+
function cloneEndpoint(endpoint) {
|
|
173
|
+
return {
|
|
174
|
+
...endpoint,
|
|
175
|
+
...(endpoint.profile ? { profile: { ...endpoint.profile } } : {}),
|
|
176
|
+
...(endpoint.serviceNames ? { serviceNames: { ...endpoint.serviceNames } } : {}),
|
|
177
|
+
...(endpoint.reasoningEfforts ? { reasoningEfforts: [...endpoint.reasoningEfforts] } : {}),
|
|
178
|
+
...(endpoint.status ? { status: { ...endpoint.status } } : {}),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZGVsLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUNILE9BQU8sRUFDTCxnQkFBZ0IsR0FLakIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEtBQUssR0FBRyxNQUFNLDRCQUE0QixDQUFDO0FBQ2xELE9BQU8sS0FBSyxNQUFNLE1BQU0sK0JBQStCLENBQUM7QUFDeEQsT0FBTyxFQUNMLFVBQVUsR0FJWCxNQUFNLG1DQUFtQyxDQUFDO0FBRTNDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQ0wsWUFBWSxFQUdaLFlBQVksR0FDYixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdkYsT0FBTyxFQUFzQixnQkFBZ0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNyRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTlDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFFMUMsd0RBQXdEO0FBQ3hELE1BQU0sQ0FBQyxNQUFNLGlDQUFpQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBdUUvRCxNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsRUFBMEIsQ0FBQztBQUV6RCxNQUFNLGtCQUFrQjtJQUVIO0lBQ0E7SUFGbkIsWUFDbUIsTUFBNkIsRUFDN0IsVUFBa0I7UUFEbEIsV0FBTSxHQUFOLE1BQU0sQ0FBdUI7UUFDN0IsZUFBVSxHQUFWLFVBQVUsQ0FBUTtJQUNsQyxDQUFDO0lBRUosS0FBSyxDQUFDLFVBQVUsQ0FBQyxPQUFPLEdBQUcsS0FBSztRQUM5QixPQUFPLGNBQWMsQ0FB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QUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzFGLEdBQUcsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUMvRCxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXV0aGVudGljYXRpb24tYXdhcmUgRGF0YWJyaWNrcyBNb2RlbCBTZXJ2aW5nIGNsaWVudC5cbiAqXG4gKiBUaGlzIGlzIHRoZSBwb3J0YWJsZSBlbnRyeSBwb2ludCB1c2VkIGJ5IGdlbmVyYXRlZCBQeXRob24gYmluZGluZ3MuIEl0IGtlZXBzXG4gKiBhdXRoZW50aWNhdGlvbiwgZW5kcG9pbnQgZGlzY292ZXJ5LCBjYWNoaW5nLCBub3JtYWxpemF0aW9uLCByYW5raW5nLCByb3V0ZVxuICogc2VsZWN0aW9uLCBhbmQgcHVibGlzaGVkIG1ldGFkYXRhIGluIE5vZGUgd2hpbGUgZXhwb3Npbmcgb25lIHNtYWxsIGNsaWVudC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7XG4gIERhdGFicmlja3NDbGllbnQsXG4gIHR5cGUgQXV0aENsaWVudCxcbiAgdHlwZSBEYXRhYnJpY2tzQXV0aERlcGVuZGVuY2llcyxcbiAgdHlwZSBEYXRhYnJpY2tzQXV0aE9wdGlvbnMsXG4gIHR5cGUgRGF0YWJyaWNrc1Byb2ZpbGVTdW1tYXJ5LFxufSBmcm9tIFwiQGRieC10b29scy9hdXRoXCI7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmUvbG9nXCI7XG5pbXBvcnQgKiBhcyBvYmplY3QgZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmUvb2JqZWN0XCI7XG5pbXBvcnQge1xuICBNb2RlbENsYXNzLFxuICB0eXBlIE1vZGVsUXVlcnksXG4gIHR5cGUgUmFua2VkTW9kZWwsXG4gIHR5cGUgU2VydmluZ0VuZHBvaW50U3VtbWFyeSxcbn0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1vZGVsL2NvbnRyYWN0c1wiO1xuXG5pbXBvcnQgeyBub3JtYWxpemVFbmRwb2ludHMgfSBmcm9tIFwiLi9fcmFua2luZy50c1wiO1xuaW1wb3J0IHtcbiAgbG9va3VwTW9kZWxzLFxuICB0eXBlIFJlc29sdmVNb2RlbElucHV0LFxuICB0eXBlIFJlc29sdmVkTW9kZWxTZWxlY3Rpb24sXG4gIHJlc29sdmVNb2RlbCxcbn0gZnJvbSBcIi4vX3NlbGVjdGlvbi50c1wiO1xuaW1wb3J0IHsgY2hhdENvbXBsZXRpb25zVXJsLCBpbnZvY2F0aW9uc1VybCwgcmVzcG9uc2VzVXBzdHJlYW1VcmwgfSBmcm9tIFwiLi9pbnZva2UudHNcIjtcbmltcG9ydCB7IHR5cGUgTW9kZWxNZXRhZGF0YSwgbW9kZWxNZXRhZGF0YUZvciB9IGZyb20gXCIuL21ldGFkYXRhLnRzXCI7XG5pbXBvcnQgeyBtb2RlbFNlcnZpbmdBcGkgfSBmcm9tIFwiLi9wb2xpY3kudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcIm1vZGVsL2NsaWVudFwiKTtcblxuLyoqIERlZmF1bHQgbGlmZXRpbWUgZm9yIG9uZSBsaXZlIGVuZHBvaW50IGNhdGFsb2d1ZS4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX01PREVMX0NMSUVOVF9DQUNIRV9UVExfTVMgPSA1ICogNjAgKiAxMDAwO1xuXG4vKiogQ29uc3RydWN0aW9uIG9wdGlvbnMgZm9yIHtAbGluayBjcmVhdGVNb2RlbENsaWVudH0uICovXG5leHBvcnQgaW50ZXJmYWNlIE1vZGVsQ2xpZW50T3B0aW9ucyB7XG4gIC8qKiBEYXRhYnJpY2tzIGF1dGhlbnRpY2F0aW9uIGFuZCBwcm9maWxlIHNlbGVjdGlvbiBvcHRpb25zLiAqL1xuICBhdXRoPzogRGF0YWJyaWNrc0F1dGhPcHRpb25zO1xuICAvKiogSW4tbWVtb3J5IGVuZHBvaW50IGNhdGFsb2d1ZSBUVEwgaW4gbWlsbGlzZWNvbmRzLiAqL1xuICBjYWNoZVR0bE1zPzogbnVtYmVyO1xufVxuXG4vKiogU2VjcmV0LWZyZWUgcnVudGltZSBpZGVudGl0eSBhbmQgY2FjaGUgY29uZmlndXJhdGlvbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTW9kZWxDbGllbnRTdGF0dXMge1xuICByZWFkb25seSBwcm9maWxlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGhvc3Q6IHN0cmluZztcbiAgcmVhZG9ubHkgcHJpbmNpcGFsOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHdvcmtzcGFjZUlkPzogc3RyaW5nO1xuICByZWFkb25seSBjYWNoZVR0bE1zOiBudW1iZXI7XG59XG5cbi8qKiBTZXJ2aW5nIHByb3RvY29sIHNlbGVjdGVkIGZvciBvbmUgcmVzb2x2ZWQgbW9kZWwuICovXG5leHBvcnQgdHlwZSBNb2RlbFByb3RvY29sID0gXCJjaGF0XCIgfCBcInJlc3BvbnNlc1wiIHwgXCJlbWJlZGRpbmdzXCI7XG5cbi8qKiBNb2RlbCBzZWxlY3Rpb24gcGx1cyByb3V0ZSBjb250cm9scy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTW9kZWxSb3V0ZUlucHV0IGV4dGVuZHMgUmVzb2x2ZU1vZGVsSW5wdXQge1xuICAvKiogRm9yY2UgYSBsaXZlIGVuZHBvaW50IGNhdGFsb2d1ZSByZWZyZXNoIGJlZm9yZSBzZWxlY3Rpb24uICovXG4gIHJlZnJlc2g/OiBib29sZWFuO1xuICAvKiogUmVxdWVzdGVkIHVwc3RyZWFtIHByb3RvY29sLiBEZWZhdWx0cyBmcm9tIGVuZHBvaW50IHRhc2sgYW5kIG1vZGVsIHBvbGljeS4gKi9cbiAgcHJvdG9jb2w/OiBNb2RlbFByb3RvY29sO1xuICAvKiogV2hldGhlciBhdXRoZW50aWNhdGlvbiBtYXkgcnVuIGFuIGludGVyYWN0aXZlIGxvZ2luLiAqL1xuICBsb2dpbj86IGJvb2xlYW47XG59XG5cbi8qKiBGdWxseSByZXNvbHZlZCBEYXRhYnJpY2tzIHJvdXRlIGZvciBhIG1vZGVsIHJlcXVlc3QuICovXG5leHBvcnQgaW50ZXJmYWNlIE1vZGVsUm91dGUge1xuICByZWFkb25seSBtb2RlbElkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGVuZHBvaW50PzogU2VydmluZ0VuZHBvaW50U3VtbWFyeTtcbiAgcmVhZG9ubHkgc291cmNlOiBSZXNvbHZlZE1vZGVsU2VsZWN0aW9uW1wic291cmNlXCJdO1xuICByZWFkb25seSBwcm90b2NvbDogTW9kZWxQcm90b2NvbDtcbiAgcmVhZG9ubHkgaG9zdDogc3RyaW5nO1xuICByZWFkb25seSBhcGlCYXNlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVybDogc3RyaW5nO1xuICByZWFkb25seSBoZWFkZXJzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PjtcbiAgcmVhZG9ubHkgbWV0YWRhdGE6IE1vZGVsTWV0YWRhdGE7XG59XG5cbi8qKiBTdGFibGUgbW9kZWwgZmFjYWRlIHNoYXJlZCBieSBOb2RlIGFuZCBnZW5lcmF0ZWQgbGFuZ3VhZ2UgYmluZGluZ3MuICovXG5leHBvcnQgaW50ZXJmYWNlIE1vZGVsQ2xpZW50IHtcbiAgbGlzdE1vZGVscyhyZWZyZXNoPzogYm9vbGVhbik6IFByb21pc2U8U2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPjtcbiAgc2VhcmNoTW9kZWxzKHF1ZXJ5PzogTW9kZWxRdWVyeSwgcmVmcmVzaD86IGJvb2xlYW4pOiBQcm9taXNlPFJhbmtlZE1vZGVsW10+O1xuICByZXNvbHZlTW9kZWwoaW5wdXQ/OiBSZXNvbHZlTW9kZWxJbnB1dCwgcmVmcmVzaD86IGJvb2xlYW4pOiBQcm9taXNlPFJlc29sdmVkTW9kZWxTZWxlY3Rpb24+O1xuICByb3V0ZShpbnB1dD86IE1vZGVsUm91dGVJbnB1dCk6IFByb21pc2U8TW9kZWxSb3V0ZT47XG4gIGF1dGhlbnRpY2F0ZShsb2dpbj86IGJvb2xlYW4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+O1xuICBtZXRhZGF0YShtb2RlbDogc3RyaW5nIHwgU2VydmluZ0VuZHBvaW50U3VtbWFyeSk6IE1vZGVsTWV0YWRhdGE7XG4gIHN0YXR1cygpOiBNb2RlbENsaWVudFN0YXR1cztcbiAgcHJvZmlsZShuYW1lPzogc3RyaW5nKTogRGF0YWJyaWNrc1Byb2ZpbGVTdW1tYXJ5O1xuICBsaXN0UHJvZmlsZXMocmVmcmVzaD86IGJvb2xlYW4pOiBEYXRhYnJpY2tzUHJvZmlsZVN1bW1hcnlbXTtcbn1cblxuaW50ZXJmYWNlIERhdGFicmlja3NNb2RlbENsaWVudCB7XG4gIHJlYWRvbmx5IGF1dGg6IEF1dGhDbGllbnQ7XG4gIGhvc3QoKTogc3RyaW5nO1xuICBwcmluY2lwYWwoKTogc3RyaW5nO1xuICB3b3Jrc3BhY2VJZCgpOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHJlcXVlc3QocGF0aDogc3RyaW5nKTogUHJvbWlzZTx1bmtub3duPjtcbn1cblxuaW50ZXJmYWNlIENhdGFsb2d1ZUVudHJ5IHtcbiAgcmVhZG9ubHkgcHJvbWlzZTogUHJvbWlzZTxyZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+O1xuICBleHBpcmVzQXQ6IG51bWJlcjtcbn1cblxuY29uc3QgY2F0YWxvZ3VlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgQ2F0YWxvZ3VlRW50cnk+KCk7XG5cbmNsYXNzIERlZmF1bHRNb2RlbENsaWVudCBpbXBsZW1lbnRzIE1vZGVsQ2xpZW50IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IERhdGFicmlja3NNb2RlbENsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNhY2hlVHRsTXM6IG51bWJlcixcbiAgKSB7fVxuXG4gIGFzeW5jIGxpc3RNb2RlbHMocmVmcmVzaCA9IGZhbHNlKTogUHJvbWlzZTxTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+IHtcbiAgICByZXR1cm4gY2xvbmVFbmRwb2ludHMoYXdhaXQgdGhpcy5jYXRhbG9ndWUocmVmcmVzaCkpO1xuICB9XG5cbiAgYXN5bmMgc2VhcmNoTW9kZWxzKHF1ZXJ5OiBNb2RlbFF1ZXJ5ID0ge30sIHJlZnJlc2ggPSBmYWxzZSk6IFByb21pc2U8UmFua2VkTW9kZWxbXT4ge1xuICAgIHJldHVybiBsb29rdXBNb2RlbHMoYXdhaXQgdGhpcy5jYXRhbG9ndWUocmVmcmVzaCksIHF1ZXJ5KS5tYXAoKHsgZW5kcG9pbnQsIC4uLnJhbmtlZCB9KSA9PiAoe1xuICAgICAgLi4ucmFua2VkLFxuICAgICAgZW5kcG9pbnQ6IGNsb25lRW5kcG9pbnQoZW5kcG9pbnQpLFxuICAgIH0pKTtcbiAgfVxuXG4gIGFzeW5jIHJlc29sdmVNb2RlbChcbiAgICBpbnB1dDogUmVzb2x2ZU1vZGVsSW5wdXQgPSB7fSxcbiAgICByZWZyZXNoID0gZmFsc2UsXG4gICk6IFByb21pc2U8UmVzb2x2ZWRNb2RlbFNlbGVjdGlvbj4ge1xuICAgIGNvbnN0IGNhdGFsb2d1ZSA9IGF3YWl0IHRoaXMuY2F0YWxvZ3VlKHJlZnJlc2gpO1xuICAgIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZU1vZGVsKGNhdGFsb2d1ZSwgaW5wdXQpO1xuICAgIGlmIChpc1VubWF0Y2hlZEV4cGxpY2l0KGNhdGFsb2d1ZSwgaW5wdXQsIHJlc29sdmVkKSkge1xuICAgICAgcmV0dXJuIHJlc29sdmVNb2RlbChhd2FpdCB0aGlzLmNhdGFsb2d1ZSh0cnVlKSwgaW5wdXQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzb2x2ZWQ7XG4gIH1cblxuICBhc3luYyByb3V0ZShpbnB1dDogTW9kZWxSb3V0ZUlucHV0ID0ge30pOiBQcm9taXNlPE1vZGVsUm91dGU+IHtcbiAgICBjb25zdCB7IHJlZnJlc2ggPSBmYWxzZSwgcHJvdG9jb2w6IHJlcXVlc3RlZFByb3RvY29sLCBsb2dpbiwgLi4uc2VsZWN0aW9uIH0gPSBpbnB1dDtcbiAgICBjb25zdCBlZmZlY3RpdmVTZWxlY3Rpb24gPVxuICAgICAgcmVxdWVzdGVkUHJvdG9jb2wgPT09IFwiZW1iZWRkaW5nc1wiICYmIHNlbGVjdGlvbi5tb2RlbENsYXNzID09PSB1bmRlZmluZWRcbiAgICAgICAgPyB7IC4uLnNlbGVjdGlvbiwgbW9kZWxDbGFzczogTW9kZWxDbGFzcy5FbWJlZGRpbmcgfVxuICAgICAgICA6IHNlbGVjdGlvbjtcbiAgICBjb25zdCBjYXRhbG9ndWUgPSBhd2FpdCB0aGlzLmNhdGFsb2d1ZShyZWZyZXNoKTtcbiAgICBsZXQgcmVzb2x2ZWQgPSByZXNvbHZlTW9kZWwoY2F0YWxvZ3VlLCBlZmZlY3RpdmVTZWxlY3Rpb24pO1xuICAgIGlmIChpc1VubWF0Y2hlZEV4cGxpY2l0KGNhdGFsb2d1ZSwgZWZmZWN0aXZlU2VsZWN0aW9uLCByZXNvbHZlZCkpIHtcbiAgICAgIHJlc29sdmVkID0gcmVzb2x2ZU1vZGVsKGF3YWl0IHRoaXMuY2F0YWxvZ3VlKHRydWUpLCBlZmZlY3RpdmVTZWxlY3Rpb24pO1xuICAgIH1cbiAgICBjb25zdCBlbmRwb2ludCA9IChhd2FpdCB0aGlzLmNhdGFsb2d1ZShmYWxzZSkpLmZpbmQoXG4gICAgICAoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUubmFtZSA9PT0gcmVzb2x2ZWQubW9kZWxJZCxcbiAgICApO1xuICAgIGNvbnN0IHByb3RvY29sID0gcmVxdWVzdGVkUHJvdG9jb2wgPz8gaW5mZXJQcm90b2NvbChlbmRwb2ludCwgcmVzb2x2ZWQubW9kZWxJZCk7XG4gICAgY29uc3QgaG9zdCA9IHRoaXMuY2xpZW50Lmhvc3QoKTtcbiAgICBjb25zdCB1cmwgPSByb3V0ZVVybChob3N0LCByZXNvbHZlZC5tb2RlbElkLCBwcm90b2NvbCk7XG4gICAgY29uc3QgaGVhZGVycyA9IGF3YWl0IHRoaXMuY2xpZW50LmF1dGgucmVxdWVzdEhlYWRlcnNGb3JVcmwodXJsLCBsb2dpbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZGVsSWQ6IHJlc29sdmVkLm1vZGVsSWQsXG4gICAgICAuLi4oZW5kcG9pbnQgPyB7IGVuZHBvaW50OiBjbG9uZUVuZHBvaW50KGVuZHBvaW50KSB9IDoge30pLFxuICAgICAgc291cmNlOiByZXNvbHZlZC5zb3VyY2UsXG4gICAgICBwcm90b2NvbCxcbiAgICAgIGhvc3QsXG4gICAgICBhcGlCYXNlOiBuZXcgVVJMKFwic2VydmluZy1lbmRwb2ludHNcIiwgYCR7aG9zdC5yZXBsYWNlKC9cXC8kLywgXCJcIil9L2ApLnRvU3RyaW5nKCksXG4gICAgICB1cmwsXG4gICAgICBoZWFkZXJzLFxuICAgICAgbWV0YWRhdGE6IG1vZGVsTWV0YWRhdGFGb3IoZW5kcG9pbnQgPz8gcmVzb2x2ZWQubW9kZWxJZCksXG4gICAgfTtcbiAgfVxuXG4gIGF1dGhlbnRpY2F0ZShsb2dpbj86IGJvb2xlYW4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+IHtcbiAgICByZXR1cm4gdGhpcy5jbGllbnQuYXV0aC5hdXRoZW50aWNhdGUobG9naW4pO1xuICB9XG5cbiAgbWV0YWRhdGEobW9kZWw6IHN0cmluZyB8IFNlcnZpbmdFbmRwb2ludFN1bW1hcnkpOiBNb2RlbE1ldGFkYXRhIHtcbiAgICByZXR1cm4gbW9kZWxNZXRhZGF0YUZvcihtb2RlbCk7XG4gIH1cblxuICBzdGF0dXMoKTogTW9kZWxDbGllbnRTdGF0dXMge1xuICAgIHJldHVybiB7XG4gICAgICBwcm9maWxlOiB0aGlzLmNsaWVudC5hdXRoLnN0YXR1cygpLnByb2ZpbGUsXG4gICAgICBob3N0OiB0aGlzLmNsaWVudC5ob3N0KCksXG4gICAgICBwcmluY2lwYWw6IHRoaXMuY2xpZW50LnByaW5jaXBhbCgpLFxuICAgICAgLi4uKHRoaXMuY2xpZW50LndvcmtzcGFjZUlkKCkgPyB7IHdvcmtzcGFjZUlkOiB0aGlzLmNsaWVudC53b3Jrc3BhY2VJZCgpIH0gOiB7fSksXG4gICAgICBjYWNoZVR0bE1zOiB0aGlzLmNhY2hlVHRsTXMsXG4gICAgfTtcbiAgfVxuXG4gIHByb2ZpbGUobmFtZT86IHN0cmluZyk6IERhdGFicmlja3NQcm9maWxlU3VtbWFyeSB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50LmF1dGgucHJvZmlsZShuYW1lKTtcbiAgfVxuXG4gIGxpc3RQcm9maWxlcyhyZWZyZXNoID0gZmFsc2UpOiBEYXRhYnJpY2tzUHJvZmlsZVN1bW1hcnlbXSB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50LmF1dGgubGlzdFByb2ZpbGVzKHJlZnJlc2gpO1xuICB9XG5cbiAgcHJpdmF0ZSBjYXRhbG9ndWUocmVmcmVzaDogYm9vbGVhbik6IFByb21pc2U8cmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPiB7XG4gICAgY29uc3Qga2V5ID0gY2F0YWxvZ3VlS2V5KHRoaXMuY2xpZW50KTtcbiAgICBpZiAocmVmcmVzaCkgY2F0YWxvZ3VlQ2FjaGUuZGVsZXRlKGtleSk7XG4gICAgY29uc3QgY3VycmVudCA9IGNhdGFsb2d1ZUNhY2hlLmdldChrZXkpO1xuICAgIGlmIChjdXJyZW50ICYmIERhdGUubm93KCkgPCBjdXJyZW50LmV4cGlyZXNBdCkgcmV0dXJuIGN1cnJlbnQucHJvbWlzZTtcbiAgICBjb25zdCBwcm9taXNlID0gdGhpcy5mZXRjaENhdGFsb2d1ZSgpO1xuICAgIGNvbnN0IGVudHJ5OiBDYXRhbG9ndWVFbnRyeSA9IHsgcHJvbWlzZSwgZXhwaXJlc0F0OiBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgfTtcbiAgICBjYXRhbG9ndWVDYWNoZS5zZXQoa2V5LCBlbnRyeSk7XG4gICAgdm9pZCBwcm9taXNlLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGVudHJ5LmV4cGlyZXNBdCA9IERhdGUubm93KCkgKyB0aGlzLmNhY2hlVHRsTXM7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICBpZiAoY2F0YWxvZ3VlQ2FjaGUuZ2V0KGtleSkgPT09IGVudHJ5KSBjYXRhbG9ndWVDYWNoZS5kZWxldGUoa2V5KTtcbiAgICAgIH0sXG4gICAgKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hDYXRhbG9ndWUoKTogUHJvbWlzZTxyZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+IHtcbiAgICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQucmVxdWVzdChcIi9hcGkvMi4wL3NlcnZpbmctZW5kcG9pbnRzXCIpO1xuICAgIGlmICghb2JqZWN0LmlzUmVjb3JkKHJlc3BvbnNlKSB8fCAhQXJyYXkuaXNBcnJheShyZXNwb25zZS5lbmRwb2ludHMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEYXRhYnJpY2tzIHNlcnZpbmctZW5kcG9pbnRzIHJlc3BvbnNlIGlzIG1pc3NpbmcgYW4gZW5kcG9pbnRzIGFycmF5XCIpO1xuICAgIH1cbiAgICBjb25zdCBlbmRwb2ludHMgPSBub3JtYWxpemVFbmRwb2ludHMocmVzcG9uc2UuZW5kcG9pbnRzKTtcbiAgICBsb2dnZXIuZGVidWcoXCJsaXN0ZWRcIiwge1xuICAgICAgY291bnQ6IGVuZHBvaW50cy5sZW5ndGgsXG4gICAgICBob3N0OiB0aGlzLmNsaWVudC5ob3N0KCksXG4gICAgICBlbGFwc2VkTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQsXG4gICAgfSk7XG4gICAgcmV0dXJuIGVuZHBvaW50cztcbiAgfVxufVxuXG4vKiogQ3JlYXRlIGFuIGF1dGhlbnRpY2F0aW9uLWF3YXJlIERhdGFicmlja3MgbW9kZWwgY2xpZW50LiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZU1vZGVsQ2xpZW50KG9wdGlvbnM6IE1vZGVsQ2xpZW50T3B0aW9ucyA9IHt9KTogUHJvbWlzZTxNb2RlbENsaWVudD4ge1xuICBjb25zdCBjYWNoZVR0bE1zID0gdmFsaWRhdGVDYWNoZVR0bChvcHRpb25zLmNhY2hlVHRsTXMpO1xuICByZXR1cm4gbmV3IERlZmF1bHRNb2RlbENsaWVudChhd2FpdCBEYXRhYnJpY2tzQ2xpZW50LmNyZWF0ZShvcHRpb25zLmF1dGgpLCBjYWNoZVR0bE1zKTtcbn1cblxuLyoqIEBpbnRlcm5hbCBDb25zdHJ1Y3QgYSBtb2RlbCBjbGllbnQgYXJvdW5kIGEgdGVzdCBvciBob3N0LW93bmVkIERhdGFicmlja3MgY2xpZW50LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1vZGVsQ2xpZW50V2l0aERhdGFicmlja3NDbGllbnQoXG4gIGNsaWVudDogRGF0YWJyaWNrc01vZGVsQ2xpZW50LFxuICBjYWNoZVR0bE1zID0gREVGQVVMVF9NT0RFTF9DTElFTlRfQ0FDSEVfVFRMX01TLFxuKTogTW9kZWxDbGllbnQge1xuICByZXR1cm4gbmV3IERlZmF1bHRNb2RlbENsaWVudChjbGllbnQsIHZhbGlkYXRlQ2FjaGVUdGwoY2FjaGVUdGxNcykpO1xufVxuXG4vKiogQGludGVybmFsIENyZWF0ZSBhIG1vZGVsIGNsaWVudCB3aXRoIGluamVjdGFibGUgYXV0aCBob3N0IGNhcGFiaWxpdGllcy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVNb2RlbENsaWVudFdpdGhEZXBlbmRlbmNpZXMoXG4gIG9wdGlvbnM6IE1vZGVsQ2xpZW50T3B0aW9ucyxcbiAgZGVwZW5kZW5jaWVzOiBEYXRhYnJpY2tzQXV0aERlcGVuZGVuY2llcyxcbik6IFByb21pc2U8TW9kZWxDbGllbnQ+IHtcbiAgcmV0dXJuIG5ldyBEZWZhdWx0TW9kZWxDbGllbnQoXG4gICAgYXdhaXQgRGF0YWJyaWNrc0NsaWVudC5jcmVhdGUob3B0aW9ucy5hdXRoLCBkZXBlbmRlbmNpZXMpLFxuICAgIHZhbGlkYXRlQ2FjaGVUdGwob3B0aW9ucy5jYWNoZVR0bE1zKSxcbiAgKTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVDYWNoZVR0bCh2YWx1ZSA9IERFRkFVTFRfTU9ERUxfQ0xJRU5UX0NBQ0hFX1RUTF9NUyk6IG51bWJlciB7XG4gIGlmICghTnVtYmVyLmlzRmluaXRlKHZhbHVlKSB8fCB2YWx1ZSA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTW9kZWwgY2xpZW50IGNhY2hlVHRsTXMgbXVzdCBiZSBhIHBvc2l0aXZlIGZpbml0ZSBudW1iZXJcIik7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBjYXRhbG9ndWVLZXkoY2xpZW50OiBEYXRhYnJpY2tzTW9kZWxDbGllbnQpOiBzdHJpbmcge1xuICByZXR1cm4gW2NsaWVudC5ob3N0KCksIGNsaWVudC53b3Jrc3BhY2VJZCgpID8/IFwiXCIsIGNsaWVudC5wcmluY2lwYWwoKV0uam9pbihcIlxcdTAwMDBcIik7XG59XG5cbmZ1bmN0aW9uIGluZmVyUHJvdG9jb2woXG4gIGVuZHBvaW50OiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5IHwgdW5kZWZpbmVkLFxuICBtb2RlbElkOiBzdHJpbmcsXG4pOiBNb2RlbFByb3RvY29sIHtcbiAgaWYgKGVuZHBvaW50Py50YXNrID09PSBcImxsbS92MS9lbWJlZGRpbmdzXCIpIHJldHVybiBcImVtYmVkZGluZ3NcIjtcbiAgcmV0dXJuIG1vZGVsU2VydmluZ0FwaShtb2RlbElkKTtcbn1cblxuZnVuY3Rpb24gcm91dGVVcmwoaG9zdDogc3RyaW5nLCBtb2RlbElkOiBzdHJpbmcsIHByb3RvY29sOiBNb2RlbFByb3RvY29sKTogc3RyaW5nIHtcbiAgaWYgKHByb3RvY29sID09PSBcInJlc3BvbnNlc1wiKSByZXR1cm4gcmVzcG9uc2VzVXBzdHJlYW1VcmwoaG9zdCwgbW9kZWxJZCk7XG4gIGlmIChwcm90b2NvbCA9PT0gXCJjaGF0XCIgJiYgbW9kZWxTZXJ2aW5nQXBpKG1vZGVsSWQpID09PSBcInJlc3BvbnNlc1wiKSB7XG4gICAgcmV0dXJuIGNoYXRDb21wbGV0aW9uc1VybChob3N0KTtcbiAgfVxuICByZXR1cm4gaW52b2NhdGlvbnNVcmwoaG9zdCwgbW9kZWxJZCk7XG59XG5cbmZ1bmN0aW9uIGlzVW5tYXRjaGVkRXhwbGljaXQoXG4gIGNhdGFsb2d1ZTogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLFxuICBpbnB1dDogUmVzb2x2ZU1vZGVsSW5wdXQsXG4gIHJlc29sdmVkOiBSZXNvbHZlZE1vZGVsU2VsZWN0aW9uLFxuKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgaW5wdXQuZXhwbGljaXQgIT09IHVuZGVmaW5lZCAmJlxuICAgIGlucHV0LmZ1enp5ICE9PSBmYWxzZSAmJlxuICAgIHJlc29sdmVkLm1vZGVsSWQgPT09IGlucHV0LmV4cGxpY2l0ICYmXG4gICAgIWNhdGFsb2d1ZS5zb21lKChlbmRwb2ludCkgPT4gZW5kcG9pbnQubmFtZSA9PT0gaW5wdXQuZXhwbGljaXQpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNsb25lRW5kcG9pbnRzKGVuZHBvaW50czogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdKTogU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdIHtcbiAgcmV0dXJuIGVuZHBvaW50cy5tYXAoY2xvbmVFbmRwb2ludCk7XG59XG5cbmZ1bmN0aW9uIGNsb25lRW5kcG9pbnQoZW5kcG9pbnQ6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnkpOiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5lbmRwb2ludCxcbiAgICAuLi4oZW5kcG9pbnQucHJvZmlsZSA/IHsgcHJvZmlsZTogeyAuLi5lbmRwb2ludC5wcm9maWxlIH0gfSA6IHt9KSxcbiAgICAuLi4oZW5kcG9pbnQuc2VydmljZU5hbWVzID8geyBzZXJ2aWNlTmFtZXM6IHsgLi4uZW5kcG9pbnQuc2VydmljZU5hbWVzIH0gfSA6IHt9KSxcbiAgICAuLi4oZW5kcG9pbnQucmVhc29uaW5nRWZmb3J0cyA/IHsgcmVhc29uaW5nRWZmb3J0czogWy4uLmVuZHBvaW50LnJlYXNvbmluZ0VmZm9ydHNdIH0gOiB7fSksXG4gICAgLi4uKGVuZHBvaW50LnN0YXR1cyA/IHsgc3RhdHVzOiB7IC4uLmVuZHBvaW50LnN0YXR1cyB9IH0gOiB7fSksXG4gIH07XG59XG4iXX0=
|
package/lib/src/policy.d.ts
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* @module
|
|
5
|
-
*/
|
|
6
|
-
import { type ReasoningEffort, type ServingEndpointSummary } from "@dbx-tools/shared-model";
|
|
7
|
-
/** Return the normalized family parsed by the Rust model-name policy. */
|
|
1
|
+
/** TypeScript-owned model-family and serving capability policy. */
|
|
2
|
+
import { type ReasoningEffort, type ServingEndpointSummary } from "@dbx-tools/shared-model/contracts";
|
|
3
|
+
/** Return the normalized family parsed from a model identity. */
|
|
8
4
|
export declare function modelFamily(name: string): string | undefined;
|
|
5
|
+
/** Normalize a recognized model identity into family, version, and variant tokens. */
|
|
6
|
+
export declare function modelSearchQuery(name: string): string | undefined;
|
|
9
7
|
/** Return the reasoning efforts accepted by a model family. */
|
|
10
8
|
export declare function modelReasoningEfforts(name: string): ReasoningEffort[];
|
|
11
|
-
/** Return whether
|
|
9
|
+
/** Return whether policy verifies a complete tool-calling round trip. */
|
|
12
10
|
export declare function modelSupportsTools(name: string): boolean;
|
|
13
11
|
/** Return whether a discovered endpoint can be used for a tool-calling chat. */
|
|
14
12
|
export declare function endpointSupportsTools(endpoint: ServingEndpointSummary): boolean;
|
|
13
|
+
/** Return whether a model requires Databricks' native Responses endpoint. */
|
|
14
|
+
export declare function isResponsesOnly(name: string): boolean;
|
|
15
|
+
/** Return the Databricks inference protocol required by a model. */
|
|
16
|
+
export declare function modelServingApi(name: string): "chat" | "responses";
|
|
17
|
+
/** Return the Chat Completions effort required when function tools are present. */
|
|
18
|
+
export declare function chatToolReasoningEffort(name: string): ReasoningEffort | undefined;
|
|
19
|
+
/** Derive provider-specific model names from a Databricks model identity. */
|
|
20
|
+
export declare function modelServiceNames(name: string): Record<string, string>;
|