@dbx-tools/model 0.3.44 → 0.4.1
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/lib/index.d.ts +13 -0
- package/lib/index.js +14 -0
- package/lib/src/classes.d.ts +54 -0
- package/lib/src/classes.js +70 -0
- package/lib/src/fallback.d.ts +40 -0
- package/lib/src/fallback.js +69 -0
- package/lib/src/invoke.d.ts +86 -0
- package/lib/src/invoke.js +104 -0
- package/lib/src/resolve.d.ts +156 -0
- package/lib/src/resolve.js +227 -0
- package/lib/src/serving.d.ts +130 -0
- package/lib/src/serving.js +286 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +12 -8
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * as classes from "./src/classes.js";
|
|
2
|
+
export * as fallback from "./src/fallback.js";
|
|
3
|
+
export * as invoke from "./src/invoke.js";
|
|
4
|
+
export * as resolve from "./src/resolve.js";
|
|
5
|
+
export * as serving from "./src/serving.js";
|
|
6
|
+
export { CHAT_CLASS_ORDER, MODEL_CLASS_ORDER, isChatClass, parseModelClass, classesAtOrBelow } from "./src/classes.js";
|
|
7
|
+
export { modelsForClass, modelForClass, FALLBACK_MODEL_IDS } from "./src/fallback.js";
|
|
8
|
+
export { INVOCATIONS_SUFFIX, RESPONSES_PATH, OPEN_RESPONSES_PATH, CHAT_COMPLETIONS_PATH, invocationsUrl, responsesUrl, openResponsesUrl, chatCompletionsUrl, isResponsesOnly, responsesUpstreamUrl, authHeaders } from "./src/invoke.js";
|
|
9
|
+
export type { AuthenticatingClientLike } from "./src/invoke.js";
|
|
10
|
+
export { rankModels, rankModelId, rankModelIdLive, searchModels, selectModel, resolveModel } from "./src/resolve.js";
|
|
11
|
+
export type { ResolveModelInput, ResolvedModelSelection, SelectModelInput, SearchModelsInput } from "./src/resolve.js";
|
|
12
|
+
export { DEFAULT_MODEL_CACHE_TTL_MS, DEFAULT_FUZZY_THRESHOLD, listServingEndpoints, listServingEndpointsUncached, clearServingEndpointsCache, searchServingEndpoints, resolveModelId } from "./src/serving.js";
|
|
13
|
+
export type { WorkspaceClientLike, ListServingEndpointsOptions, ResolvedModel, ResolveModelOptions, ScoredEndpoint } from "./src/serving.js";
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// GENERATED by projen watch - DO NOT EDIT.
|
|
2
|
+
// Regenerated from the exporting modules in ./src.
|
|
3
|
+
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
|
+
export * as classes from "./src/classes.js";
|
|
5
|
+
export * as fallback from "./src/fallback.js";
|
|
6
|
+
export * as invoke from "./src/invoke.js";
|
|
7
|
+
export * as resolve from "./src/resolve.js";
|
|
8
|
+
export * as serving from "./src/serving.js";
|
|
9
|
+
export { CHAT_CLASS_ORDER, MODEL_CLASS_ORDER, isChatClass, parseModelClass, classesAtOrBelow } from "./src/classes.js";
|
|
10
|
+
export { modelsForClass, modelForClass, FALLBACK_MODEL_IDS } from "./src/fallback.js";
|
|
11
|
+
export { INVOCATIONS_SUFFIX, RESPONSES_PATH, OPEN_RESPONSES_PATH, CHAT_COMPLETIONS_PATH, invocationsUrl, responsesUrl, openResponsesUrl, chatCompletionsUrl, isResponsesOnly, responsesUpstreamUrl, authHeaders } from "./src/invoke.js";
|
|
12
|
+
export { rankModels, rankModelId, rankModelIdLive, searchModels, selectModel, resolveModel } from "./src/resolve.js";
|
|
13
|
+
export { DEFAULT_MODEL_CACHE_TTL_MS, DEFAULT_FUZZY_THRESHOLD, listServingEndpoints, listServingEndpointsUncached, clearServingEndpointsCache, searchServingEndpoints, resolveModelId } from "./src/serving.js";
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssUUFBUSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sS0FBSyxNQUFNLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BILE9BQU8sRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxxQkFBcUIsRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFdE8sT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRWxILE9BQU8sRUFBRSwwQkFBMEIsRUFBRSx1QkFBdUIsRUFBRSxvQkFBb0IsRUFBRSw0QkFBNEIsRUFBRSwwQkFBMEIsRUFBRSxzQkFBc0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBjbGFzc2VzIGZyb20gXCIuL3NyYy9jbGFzc2VzXCI7XG5leHBvcnQgKiBhcyBmYWxsYmFjayBmcm9tIFwiLi9zcmMvZmFsbGJhY2tcIjtcbmV4cG9ydCAqIGFzIGludm9rZSBmcm9tIFwiLi9zcmMvaW52b2tlXCI7XG5leHBvcnQgKiBhcyByZXNvbHZlIGZyb20gXCIuL3NyYy9yZXNvbHZlXCI7XG5leHBvcnQgKiBhcyBzZXJ2aW5nIGZyb20gXCIuL3NyYy9zZXJ2aW5nXCI7XG5leHBvcnQgeyBDSEFUX0NMQVNTX09SREVSLCBNT0RFTF9DTEFTU19PUkRFUiwgaXNDaGF0Q2xhc3MsIHBhcnNlTW9kZWxDbGFzcywgY2xhc3Nlc0F0T3JCZWxvdyB9IGZyb20gXCIuL3NyYy9jbGFzc2VzXCI7XG5leHBvcnQgeyBtb2RlbHNGb3JDbGFzcywgbW9kZWxGb3JDbGFzcywgRkFMTEJBQ0tfTU9ERUxfSURTIH0gZnJvbSBcIi4vc3JjL2ZhbGxiYWNrXCI7XG5leHBvcnQgeyBJTlZPQ0FUSU9OU19TVUZGSVgsIFJFU1BPTlNFU19QQVRILCBPUEVOX1JFU1BPTlNFU19QQVRILCBDSEFUX0NPTVBMRVRJT05TX1BBVEgsIGludm9jYXRpb25zVXJsLCByZXNwb25zZXNVcmwsIG9wZW5SZXNwb25zZXNVcmwsIGNoYXRDb21wbGV0aW9uc1VybCwgaXNSZXNwb25zZXNPbmx5LCByZXNwb25zZXNVcHN0cmVhbVVybCwgYXV0aEhlYWRlcnMgfSBmcm9tIFwiLi9zcmMvaW52b2tlXCI7XG5leHBvcnQgdHlwZSB7IEF1dGhlbnRpY2F0aW5nQ2xpZW50TGlrZSB9IGZyb20gXCIuL3NyYy9pbnZva2VcIjtcbmV4cG9ydCB7IHJhbmtNb2RlbHMsIHJhbmtNb2RlbElkLCByYW5rTW9kZWxJZExpdmUsIHNlYXJjaE1vZGVscywgc2VsZWN0TW9kZWwsIHJlc29sdmVNb2RlbCB9IGZyb20gXCIuL3NyYy9yZXNvbHZlXCI7XG5leHBvcnQgdHlwZSB7IFJlc29sdmVNb2RlbElucHV0LCBSZXNvbHZlZE1vZGVsU2VsZWN0aW9uLCBTZWxlY3RNb2RlbElucHV0LCBTZWFyY2hNb2RlbHNJbnB1dCB9IGZyb20gXCIuL3NyYy9yZXNvbHZlXCI7XG5leHBvcnQgeyBERUZBVUxUX01PREVMX0NBQ0hFX1RUTF9NUywgREVGQVVMVF9GVVpaWV9USFJFU0hPTEQsIGxpc3RTZXJ2aW5nRW5kcG9pbnRzLCBsaXN0U2VydmluZ0VuZHBvaW50c1VuY2FjaGVkLCBjbGVhclNlcnZpbmdFbmRwb2ludHNDYWNoZSwgc2VhcmNoU2VydmluZ0VuZHBvaW50cywgcmVzb2x2ZU1vZGVsSWQgfSBmcm9tIFwiLi9zcmMvc2VydmluZ1wiO1xuZXhwb3J0IHR5cGUgeyBXb3Jrc3BhY2VDbGllbnRMaWtlLCBMaXN0U2VydmluZ0VuZHBvaW50c09wdGlvbnMsIFJlc29sdmVkTW9kZWwsIFJlc29sdmVNb2RlbE9wdGlvbnMsIFNjb3JlZEVuZHBvaW50IH0gZnJvbSBcIi4vc3JjL3NlcnZpbmdcIjtcbiJdfQ==
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-class ordering for the model service.
|
|
3
|
+
*
|
|
4
|
+
* `@dbx-tools/shared-model` declares the {@link ModelClass} values and their
|
|
5
|
+
* schema; the *behavior* over those values - the chat capability order, the
|
|
6
|
+
* "this class and below" ceiling, and coercing loose request input to a class -
|
|
7
|
+
* lives here in the service so the shared wire-format surface stays purely
|
|
8
|
+
* declarative.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { model } from "@dbx-tools/shared-model";
|
|
13
|
+
type ModelClass = model.ModelClass;
|
|
14
|
+
declare const ModelClass: typeof model.ModelClass;
|
|
15
|
+
/**
|
|
16
|
+
* Chat capability ladder in descending order - most capable
|
|
17
|
+
* ({@link ModelClass.ChatThinking}) first, least ({@link ModelClass.ChatFast})
|
|
18
|
+
* last. {@link ModelClass.Embedding} is a separate modality and is deliberately
|
|
19
|
+
* absent: the ceiling never spans it. This is the order used to filter "this
|
|
20
|
+
* class and below" and to break ranking ties toward the more capable model.
|
|
21
|
+
*/
|
|
22
|
+
export declare const CHAT_CLASS_ORDER: readonly ModelClass[];
|
|
23
|
+
/**
|
|
24
|
+
* Every class in display order: the chat ladder followed by
|
|
25
|
+
* {@link ModelClass.Embedding}. Used when flattening a full classification
|
|
26
|
+
* (e.g. stamping the class onto each cached endpoint).
|
|
27
|
+
*/
|
|
28
|
+
export declare const MODEL_CLASS_ORDER: readonly ModelClass[];
|
|
29
|
+
/** Whether `cls` is one of the chat capability bands (vs. embedding). */
|
|
30
|
+
export declare function isChatClass(cls: ModelClass): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Coerce an arbitrary value (query string, header, body field) to a
|
|
33
|
+
* {@link ModelClass}, returning `null` when it isn't a known class. Lets a
|
|
34
|
+
* route accept a class request without throwing on junk input.
|
|
35
|
+
*
|
|
36
|
+
* Matches the full slug first (`"chat-fast"`, `"embedding"`), then - for a bare
|
|
37
|
+
* chat band - retries with a `chat-` prefix, so the shorthand `"thinking"` /
|
|
38
|
+
* `"balanced"` / `"fast"` resolves to the corresponding `chat-*` class.
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseModelClass(value: unknown): ModelClass | null;
|
|
41
|
+
/**
|
|
42
|
+
* Classes at or below `cls` in chat capability: the class itself plus every
|
|
43
|
+
* less-capable chat band, in {@link CHAT_CLASS_ORDER}. Treats a chat `cls` as a
|
|
44
|
+
* ceiling - requesting {@link ModelClass.ChatBalanced} yields
|
|
45
|
+
* `[ChatBalanced, ChatFast]`, never {@link ModelClass.ChatThinking} - so a
|
|
46
|
+
* class ask can degrade downward to a smaller chat model but never escalate to
|
|
47
|
+
* a larger one.
|
|
48
|
+
*
|
|
49
|
+
* {@link ModelClass.Embedding} is its own modality, not a rung on the chat
|
|
50
|
+
* ladder, so it yields just `[Embedding]`. An unrecognized class yields the
|
|
51
|
+
* full chat ladder.
|
|
52
|
+
*/
|
|
53
|
+
export declare function classesAtOrBelow(cls: ModelClass): ModelClass[];
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-class ordering for the model service.
|
|
3
|
+
*
|
|
4
|
+
* `@dbx-tools/shared-model` declares the {@link ModelClass} values and their
|
|
5
|
+
* schema; the *behavior* over those values - the chat capability order, the
|
|
6
|
+
* "this class and below" ceiling, and coercing loose request input to a class -
|
|
7
|
+
* lives here in the service so the shared wire-format surface stays purely
|
|
8
|
+
* declarative.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { model } from "@dbx-tools/shared-model";
|
|
13
|
+
const { ModelClass, ModelClassSchema } = model;
|
|
14
|
+
/**
|
|
15
|
+
* Chat capability ladder in descending order - most capable
|
|
16
|
+
* ({@link ModelClass.ChatThinking}) first, least ({@link ModelClass.ChatFast})
|
|
17
|
+
* last. {@link ModelClass.Embedding} is a separate modality and is deliberately
|
|
18
|
+
* absent: the ceiling never spans it. This is the order used to filter "this
|
|
19
|
+
* class and below" and to break ranking ties toward the more capable model.
|
|
20
|
+
*/
|
|
21
|
+
export const CHAT_CLASS_ORDER = [
|
|
22
|
+
ModelClass.ChatThinking,
|
|
23
|
+
ModelClass.ChatBalanced,
|
|
24
|
+
ModelClass.ChatFast,
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* Every class in display order: the chat ladder followed by
|
|
28
|
+
* {@link ModelClass.Embedding}. Used when flattening a full classification
|
|
29
|
+
* (e.g. stamping the class onto each cached endpoint).
|
|
30
|
+
*/
|
|
31
|
+
export const MODEL_CLASS_ORDER = [...CHAT_CLASS_ORDER, ModelClass.Embedding];
|
|
32
|
+
/** Whether `cls` is one of the chat capability bands (vs. embedding). */
|
|
33
|
+
export function isChatClass(cls) {
|
|
34
|
+
return CHAT_CLASS_ORDER.includes(cls);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Coerce an arbitrary value (query string, header, body field) to a
|
|
38
|
+
* {@link ModelClass}, returning `null` when it isn't a known class. Lets a
|
|
39
|
+
* route accept a class request without throwing on junk input.
|
|
40
|
+
*
|
|
41
|
+
* Matches the full slug first (`"chat-fast"`, `"embedding"`), then - for a bare
|
|
42
|
+
* chat band - retries with a `chat-` prefix, so the shorthand `"thinking"` /
|
|
43
|
+
* `"balanced"` / `"fast"` resolves to the corresponding `chat-*` class.
|
|
44
|
+
*/
|
|
45
|
+
export function parseModelClass(value) {
|
|
46
|
+
const exact = ModelClassSchema.safeParse(value);
|
|
47
|
+
if (exact.success)
|
|
48
|
+
return exact.data;
|
|
49
|
+
const prefixed = ModelClassSchema.safeParse(`chat-${value}`);
|
|
50
|
+
return prefixed.success ? prefixed.data : null;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Classes at or below `cls` in chat capability: the class itself plus every
|
|
54
|
+
* less-capable chat band, in {@link CHAT_CLASS_ORDER}. Treats a chat `cls` as a
|
|
55
|
+
* ceiling - requesting {@link ModelClass.ChatBalanced} yields
|
|
56
|
+
* `[ChatBalanced, ChatFast]`, never {@link ModelClass.ChatThinking} - so a
|
|
57
|
+
* class ask can degrade downward to a smaller chat model but never escalate to
|
|
58
|
+
* a larger one.
|
|
59
|
+
*
|
|
60
|
+
* {@link ModelClass.Embedding} is its own modality, not a rung on the chat
|
|
61
|
+
* ladder, so it yields just `[Embedding]`. An unrecognized class yields the
|
|
62
|
+
* full chat ladder.
|
|
63
|
+
*/
|
|
64
|
+
export function classesAtOrBelow(cls) {
|
|
65
|
+
if (cls === ModelClass.Embedding)
|
|
66
|
+
return [ModelClass.Embedding];
|
|
67
|
+
const index = CHAT_CLASS_ORDER.indexOf(cls);
|
|
68
|
+
return index < 0 ? [...CHAT_CLASS_ORDER] : [...CHAT_CLASS_ORDER.slice(index)];
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGFzc2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7O0dBVUc7QUFFSCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHaEQsTUFBTSxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLEtBQUssQ0FBQztBQUUvQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBMEI7SUFDckQsVUFBVSxDQUFDLFlBQVk7SUFDdkIsVUFBVSxDQUFDLFlBQVk7SUFDdkIsVUFBVSxDQUFDLFFBQVE7Q0FDcEIsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBMEIsQ0FBQyxHQUFHLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUVwRyx5RUFBeUU7QUFDekUsTUFBTSxVQUFVLFdBQVcsQ0FBQyxHQUFlO0lBQ3pDLE9BQU8sZ0JBQWdCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsS0FBYztJQUM1QyxNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEQsSUFBSSxLQUFLLENBQUMsT0FBTztRQUFFLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQztJQUNyQyxNQUFNLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsUUFBUSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQzdELE9BQU8sUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ2pELENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxHQUFlO0lBQzlDLElBQUksR0FBRyxLQUFLLFVBQVUsQ0FBQyxTQUFTO1FBQUUsT0FBTyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNoRSxNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUMsT0FBTyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1vZGVsLWNsYXNzIG9yZGVyaW5nIGZvciB0aGUgbW9kZWwgc2VydmljZS5cbiAqXG4gKiBgQGRieC10b29scy9zaGFyZWQtbW9kZWxgIGRlY2xhcmVzIHRoZSB7QGxpbmsgTW9kZWxDbGFzc30gdmFsdWVzIGFuZCB0aGVpclxuICogc2NoZW1hOyB0aGUgKmJlaGF2aW9yKiBvdmVyIHRob3NlIHZhbHVlcyAtIHRoZSBjaGF0IGNhcGFiaWxpdHkgb3JkZXIsIHRoZVxuICogXCJ0aGlzIGNsYXNzIGFuZCBiZWxvd1wiIGNlaWxpbmcsIGFuZCBjb2VyY2luZyBsb29zZSByZXF1ZXN0IGlucHV0IHRvIGEgY2xhc3MgLVxuICogbGl2ZXMgaGVyZSBpbiB0aGUgc2VydmljZSBzbyB0aGUgc2hhcmVkIHdpcmUtZm9ybWF0IHN1cmZhY2Ugc3RheXMgcHVyZWx5XG4gKiBkZWNsYXJhdGl2ZS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgbW9kZWwgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWxcIjtcblxudHlwZSBNb2RlbENsYXNzID0gbW9kZWwuTW9kZWxDbGFzcztcbmNvbnN0IHsgTW9kZWxDbGFzcywgTW9kZWxDbGFzc1NjaGVtYSB9ID0gbW9kZWw7XG5cbi8qKlxuICogQ2hhdCBjYXBhYmlsaXR5IGxhZGRlciBpbiBkZXNjZW5kaW5nIG9yZGVyIC0gbW9zdCBjYXBhYmxlXG4gKiAoe0BsaW5rIE1vZGVsQ2xhc3MuQ2hhdFRoaW5raW5nfSkgZmlyc3QsIGxlYXN0ICh7QGxpbmsgTW9kZWxDbGFzcy5DaGF0RmFzdH0pXG4gKiBsYXN0LiB7QGxpbmsgTW9kZWxDbGFzcy5FbWJlZGRpbmd9IGlzIGEgc2VwYXJhdGUgbW9kYWxpdHkgYW5kIGlzIGRlbGliZXJhdGVseVxuICogYWJzZW50OiB0aGUgY2VpbGluZyBuZXZlciBzcGFucyBpdC4gVGhpcyBpcyB0aGUgb3JkZXIgdXNlZCB0byBmaWx0ZXIgXCJ0aGlzXG4gKiBjbGFzcyBhbmQgYmVsb3dcIiBhbmQgdG8gYnJlYWsgcmFua2luZyB0aWVzIHRvd2FyZCB0aGUgbW9yZSBjYXBhYmxlIG1vZGVsLlxuICovXG5leHBvcnQgY29uc3QgQ0hBVF9DTEFTU19PUkRFUjogcmVhZG9ubHkgTW9kZWxDbGFzc1tdID0gW1xuICBNb2RlbENsYXNzLkNoYXRUaGlua2luZyxcbiAgTW9kZWxDbGFzcy5DaGF0QmFsYW5jZWQsXG4gIE1vZGVsQ2xhc3MuQ2hhdEZhc3QsXG5dO1xuXG4vKipcbiAqIEV2ZXJ5IGNsYXNzIGluIGRpc3BsYXkgb3JkZXI6IHRoZSBjaGF0IGxhZGRlciBmb2xsb3dlZCBieVxuICoge0BsaW5rIE1vZGVsQ2xhc3MuRW1iZWRkaW5nfS4gVXNlZCB3aGVuIGZsYXR0ZW5pbmcgYSBmdWxsIGNsYXNzaWZpY2F0aW9uXG4gKiAoZS5nLiBzdGFtcGluZyB0aGUgY2xhc3Mgb250byBlYWNoIGNhY2hlZCBlbmRwb2ludCkuXG4gKi9cbmV4cG9ydCBjb25zdCBNT0RFTF9DTEFTU19PUkRFUjogcmVhZG9ubHkgTW9kZWxDbGFzc1tdID0gWy4uLkNIQVRfQ0xBU1NfT1JERVIsIE1vZGVsQ2xhc3MuRW1iZWRkaW5nXTtcblxuLyoqIFdoZXRoZXIgYGNsc2AgaXMgb25lIG9mIHRoZSBjaGF0IGNhcGFiaWxpdHkgYmFuZHMgKHZzLiBlbWJlZGRpbmcpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ2hhdENsYXNzKGNsczogTW9kZWxDbGFzcyk6IGJvb2xlYW4ge1xuICByZXR1cm4gQ0hBVF9DTEFTU19PUkRFUi5pbmNsdWRlcyhjbHMpO1xufVxuXG4vKipcbiAqIENvZXJjZSBhbiBhcmJpdHJhcnkgdmFsdWUgKHF1ZXJ5IHN0cmluZywgaGVhZGVyLCBib2R5IGZpZWxkKSB0byBhXG4gKiB7QGxpbmsgTW9kZWxDbGFzc30sIHJldHVybmluZyBgbnVsbGAgd2hlbiBpdCBpc24ndCBhIGtub3duIGNsYXNzLiBMZXRzIGFcbiAqIHJvdXRlIGFjY2VwdCBhIGNsYXNzIHJlcXVlc3Qgd2l0aG91dCB0aHJvd2luZyBvbiBqdW5rIGlucHV0LlxuICpcbiAqIE1hdGNoZXMgdGhlIGZ1bGwgc2x1ZyBmaXJzdCAoYFwiY2hhdC1mYXN0XCJgLCBgXCJlbWJlZGRpbmdcImApLCB0aGVuIC0gZm9yIGEgYmFyZVxuICogY2hhdCBiYW5kIC0gcmV0cmllcyB3aXRoIGEgYGNoYXQtYCBwcmVmaXgsIHNvIHRoZSBzaG9ydGhhbmQgYFwidGhpbmtpbmdcImAgL1xuICogYFwiYmFsYW5jZWRcImAgLyBgXCJmYXN0XCJgIHJlc29sdmVzIHRvIHRoZSBjb3JyZXNwb25kaW5nIGBjaGF0LSpgIGNsYXNzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VNb2RlbENsYXNzKHZhbHVlOiB1bmtub3duKTogTW9kZWxDbGFzcyB8IG51bGwge1xuICBjb25zdCBleGFjdCA9IE1vZGVsQ2xhc3NTY2hlbWEuc2FmZVBhcnNlKHZhbHVlKTtcbiAgaWYgKGV4YWN0LnN1Y2Nlc3MpIHJldHVybiBleGFjdC5kYXRhO1xuICBjb25zdCBwcmVmaXhlZCA9IE1vZGVsQ2xhc3NTY2hlbWEuc2FmZVBhcnNlKGBjaGF0LSR7dmFsdWV9YCk7XG4gIHJldHVybiBwcmVmaXhlZC5zdWNjZXNzID8gcHJlZml4ZWQuZGF0YSA6IG51bGw7XG59XG5cbi8qKlxuICogQ2xhc3NlcyBhdCBvciBiZWxvdyBgY2xzYCBpbiBjaGF0IGNhcGFiaWxpdHk6IHRoZSBjbGFzcyBpdHNlbGYgcGx1cyBldmVyeVxuICogbGVzcy1jYXBhYmxlIGNoYXQgYmFuZCwgaW4ge0BsaW5rIENIQVRfQ0xBU1NfT1JERVJ9LiBUcmVhdHMgYSBjaGF0IGBjbHNgIGFzIGFcbiAqIGNlaWxpbmcgLSByZXF1ZXN0aW5nIHtAbGluayBNb2RlbENsYXNzLkNoYXRCYWxhbmNlZH0geWllbGRzXG4gKiBgW0NoYXRCYWxhbmNlZCwgQ2hhdEZhc3RdYCwgbmV2ZXIge0BsaW5rIE1vZGVsQ2xhc3MuQ2hhdFRoaW5raW5nfSAtIHNvIGFcbiAqIGNsYXNzIGFzayBjYW4gZGVncmFkZSBkb3dud2FyZCB0byBhIHNtYWxsZXIgY2hhdCBtb2RlbCBidXQgbmV2ZXIgZXNjYWxhdGUgdG9cbiAqIGEgbGFyZ2VyIG9uZS5cbiAqXG4gKiB7QGxpbmsgTW9kZWxDbGFzcy5FbWJlZGRpbmd9IGlzIGl0cyBvd24gbW9kYWxpdHksIG5vdCBhIHJ1bmcgb24gdGhlIGNoYXRcbiAqIGxhZGRlciwgc28gaXQgeWllbGRzIGp1c3QgYFtFbWJlZGRpbmddYC4gQW4gdW5yZWNvZ25pemVkIGNsYXNzIHlpZWxkcyB0aGVcbiAqIGZ1bGwgY2hhdCBsYWRkZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGFzc2VzQXRPckJlbG93KGNsczogTW9kZWxDbGFzcyk6IE1vZGVsQ2xhc3NbXSB7XG4gIGlmIChjbHMgPT09IE1vZGVsQ2xhc3MuRW1iZWRkaW5nKSByZXR1cm4gW01vZGVsQ2xhc3MuRW1iZWRkaW5nXTtcbiAgY29uc3QgaW5kZXggPSBDSEFUX0NMQVNTX09SREVSLmluZGV4T2YoY2xzKTtcbiAgcmV0dXJuIGluZGV4IDwgMCA/IFsuLi5DSEFUX0NMQVNTX09SREVSXSA6IFsuLi5DSEFUX0NMQVNTX09SREVSLnNsaWNlKGluZGV4KV07XG59XG4iXX0=
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side offline fallback opinion for model selection.
|
|
3
|
+
*
|
|
4
|
+
* When the live `/serving-endpoints` catalogue can't be read at all - no user
|
|
5
|
+
* token, the service principal can't list, or the workspace is unreachable -
|
|
6
|
+
* the resolver still has to name *some* endpoint. This module holds that floor:
|
|
7
|
+
* a small, hard-coded set of well-known Foundation Model API endpoint names,
|
|
8
|
+
* each bucketed into a chat {@link ModelClass} by the shared
|
|
9
|
+
* {@link classify.classifyByFamily} heuristic (no classes are hard-coded here)
|
|
10
|
+
* and ordered best-first.
|
|
11
|
+
*
|
|
12
|
+
* This is deliberately *server-only*. A browser client never talks to
|
|
13
|
+
* Databricks directly - it always goes through this server - so it has nothing
|
|
14
|
+
* to fall back to and must not assume a stale, baked-in model list; it consumes
|
|
15
|
+
* the live `/models` response instead. The pure classifier
|
|
16
|
+
* ({@link classify.classifyEndpoints}) is what the client shares.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
import { model } from "@dbx-tools/shared-model";
|
|
21
|
+
type ModelClass = model.ModelClass;
|
|
22
|
+
declare const ModelClass: typeof model.ModelClass;
|
|
23
|
+
/**
|
|
24
|
+
* Static fallback model ids for a chat class, drawn from the small built-in
|
|
25
|
+
* {@link FALLBACK_MODEL_NAMES} list and ordered best-first by family rank. Sync
|
|
26
|
+
* and workspace-independent: this is the *fallback opinion* used to seed default
|
|
27
|
+
* lists or when the live catalogue is unreachable - live resolution prefers
|
|
28
|
+
* {@link classify.classifyEndpoints}. Returns `[]` for
|
|
29
|
+
* {@link ModelClass.Embedding} (the floor is chat-only).
|
|
30
|
+
*/
|
|
31
|
+
export declare function modelsForClass(cls: ModelClass): readonly string[];
|
|
32
|
+
/** Top static fallback model id for a chat class. */
|
|
33
|
+
export declare function modelForClass(cls: ModelClass): string;
|
|
34
|
+
/**
|
|
35
|
+
* Priority-ordered fallback chain (ChatThinking -> ChatBalanced -> ChatFast)
|
|
36
|
+
* over the small built-in list. The floor walked at resolve time when no agent
|
|
37
|
+
* / plugin / env / request model is set *and* the live catalogue yields nothing.
|
|
38
|
+
*/
|
|
39
|
+
export declare const FALLBACK_MODEL_IDS: readonly string[];
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side offline fallback opinion for model selection.
|
|
3
|
+
*
|
|
4
|
+
* When the live `/serving-endpoints` catalogue can't be read at all - no user
|
|
5
|
+
* token, the service principal can't list, or the workspace is unreachable -
|
|
6
|
+
* the resolver still has to name *some* endpoint. This module holds that floor:
|
|
7
|
+
* a small, hard-coded set of well-known Foundation Model API endpoint names,
|
|
8
|
+
* each bucketed into a chat {@link ModelClass} by the shared
|
|
9
|
+
* {@link classify.classifyByFamily} heuristic (no classes are hard-coded here)
|
|
10
|
+
* and ordered best-first.
|
|
11
|
+
*
|
|
12
|
+
* This is deliberately *server-only*. A browser client never talks to
|
|
13
|
+
* Databricks directly - it always goes through this server - so it has nothing
|
|
14
|
+
* to fall back to and must not assume a stale, baked-in model list; it consumes
|
|
15
|
+
* the live `/models` response instead. The pure classifier
|
|
16
|
+
* ({@link classify.classifyEndpoints}) is what the client shares.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
import { classify, model } from "@dbx-tools/shared-model";
|
|
21
|
+
const { ModelClass } = model;
|
|
22
|
+
/**
|
|
23
|
+
* Small, last-resort set of well-known Foundation Model API endpoint names,
|
|
24
|
+
* ordered best-first within each class by {@link classify.classifyByFamily}.
|
|
25
|
+
* Used only as the floor when the live `/serving-endpoints` catalogue can't be
|
|
26
|
+
* read at resolve time; the live, score-driven classification supersedes it
|
|
27
|
+
* whenever the workspace listing is available. Classes are not hard-coded here
|
|
28
|
+
* - each name is classified by family heuristic.
|
|
29
|
+
*/
|
|
30
|
+
const FALLBACK_MODEL_NAMES = [
|
|
31
|
+
"databricks-claude-opus-4-8",
|
|
32
|
+
"databricks-gpt-5-5-pro",
|
|
33
|
+
"databricks-gemini-3-1-pro",
|
|
34
|
+
"databricks-claude-sonnet-4-6",
|
|
35
|
+
"databricks-gpt-5-5",
|
|
36
|
+
"databricks-meta-llama-3-3-70b-instruct",
|
|
37
|
+
"databricks-claude-haiku-4-5",
|
|
38
|
+
"databricks-gpt-5-nano",
|
|
39
|
+
"databricks-meta-llama-3-1-8b-instruct",
|
|
40
|
+
];
|
|
41
|
+
/**
|
|
42
|
+
* Static fallback model ids for a chat class, drawn from the small built-in
|
|
43
|
+
* {@link FALLBACK_MODEL_NAMES} list and ordered best-first by family rank. Sync
|
|
44
|
+
* and workspace-independent: this is the *fallback opinion* used to seed default
|
|
45
|
+
* lists or when the live catalogue is unreachable - live resolution prefers
|
|
46
|
+
* {@link classify.classifyEndpoints}. Returns `[]` for
|
|
47
|
+
* {@link ModelClass.Embedding} (the floor is chat-only).
|
|
48
|
+
*/
|
|
49
|
+
export function modelsForClass(cls) {
|
|
50
|
+
return FALLBACK_MODEL_NAMES.map((name) => ({ name, c: classify.classifyByFamily(name) }))
|
|
51
|
+
.filter((x) => x.c !== null && x.c.class === cls)
|
|
52
|
+
.sort((a, b) => b.c.rank - a.c.rank)
|
|
53
|
+
.map((x) => x.name);
|
|
54
|
+
}
|
|
55
|
+
/** Top static fallback model id for a chat class. */
|
|
56
|
+
export function modelForClass(cls) {
|
|
57
|
+
return modelsForClass(cls)[0];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Priority-ordered fallback chain (ChatThinking -> ChatBalanced -> ChatFast)
|
|
61
|
+
* over the small built-in list. The floor walked at resolve time when no agent
|
|
62
|
+
* / plugin / env / request model is set *and* the live catalogue yields nothing.
|
|
63
|
+
*/
|
|
64
|
+
export const FALLBACK_MODEL_IDS = [
|
|
65
|
+
...modelsForClass(ModelClass.ChatThinking),
|
|
66
|
+
...modelsForClass(ModelClass.ChatBalanced),
|
|
67
|
+
...modelsForClass(ModelClass.ChatFast),
|
|
68
|
+
];
|
|
69
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFsbGJhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmFsbGJhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUVILE9BQU8sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFvQixNQUFNLHlCQUF5QixDQUFDO0FBRzVFLE1BQU0sRUFBRSxVQUFVLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFFN0I7Ozs7Ozs7R0FPRztBQUNILE1BQU0sb0JBQW9CLEdBQXNCO0lBQzlDLDRCQUE0QjtJQUM1Qix3QkFBd0I7SUFDeEIsMkJBQTJCO0lBQzNCLDhCQUE4QjtJQUM5QixvQkFBb0I7SUFDcEIsd0NBQXdDO0lBQ3hDLDZCQUE2QjtJQUM3Qix1QkFBdUI7SUFDdkIsdUNBQXVDO0NBQ3hDLENBQUM7QUFFRjs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxHQUFlO0lBQzVDLE9BQU8sb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxRQUFRLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ3RGLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBeUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEdBQUcsQ0FBQztTQUN2RixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztTQUNuQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN4QixDQUFDO0FBRUQscURBQXFEO0FBQ3JELE1BQU0sVUFBVSxhQUFhLENBQUMsR0FBZTtJQUMzQyxPQUFPLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUUsQ0FBQztBQUNqQyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFzQjtJQUNuRCxHQUFHLGNBQWMsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDO0lBQzFDLEdBQUcsY0FBYyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUM7SUFDMUMsR0FBRyxjQUFjLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQztDQUN2QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTZXJ2ZXItc2lkZSBvZmZsaW5lIGZhbGxiYWNrIG9waW5pb24gZm9yIG1vZGVsIHNlbGVjdGlvbi5cbiAqXG4gKiBXaGVuIHRoZSBsaXZlIGAvc2VydmluZy1lbmRwb2ludHNgIGNhdGFsb2d1ZSBjYW4ndCBiZSByZWFkIGF0IGFsbCAtIG5vIHVzZXJcbiAqIHRva2VuLCB0aGUgc2VydmljZSBwcmluY2lwYWwgY2FuJ3QgbGlzdCwgb3IgdGhlIHdvcmtzcGFjZSBpcyB1bnJlYWNoYWJsZSAtXG4gKiB0aGUgcmVzb2x2ZXIgc3RpbGwgaGFzIHRvIG5hbWUgKnNvbWUqIGVuZHBvaW50LiBUaGlzIG1vZHVsZSBob2xkcyB0aGF0IGZsb29yOlxuICogYSBzbWFsbCwgaGFyZC1jb2RlZCBzZXQgb2Ygd2VsbC1rbm93biBGb3VuZGF0aW9uIE1vZGVsIEFQSSBlbmRwb2ludCBuYW1lcyxcbiAqIGVhY2ggYnVja2V0ZWQgaW50byBhIGNoYXQge0BsaW5rIE1vZGVsQ2xhc3N9IGJ5IHRoZSBzaGFyZWRcbiAqIHtAbGluayBjbGFzc2lmeS5jbGFzc2lmeUJ5RmFtaWx5fSBoZXVyaXN0aWMgKG5vIGNsYXNzZXMgYXJlIGhhcmQtY29kZWQgaGVyZSlcbiAqIGFuZCBvcmRlcmVkIGJlc3QtZmlyc3QuXG4gKlxuICogVGhpcyBpcyBkZWxpYmVyYXRlbHkgKnNlcnZlci1vbmx5Ki4gQSBicm93c2VyIGNsaWVudCBuZXZlciB0YWxrcyB0b1xuICogRGF0YWJyaWNrcyBkaXJlY3RseSAtIGl0IGFsd2F5cyBnb2VzIHRocm91Z2ggdGhpcyBzZXJ2ZXIgLSBzbyBpdCBoYXMgbm90aGluZ1xuICogdG8gZmFsbCBiYWNrIHRvIGFuZCBtdXN0IG5vdCBhc3N1bWUgYSBzdGFsZSwgYmFrZWQtaW4gbW9kZWwgbGlzdDsgaXQgY29uc3VtZXNcbiAqIHRoZSBsaXZlIGAvbW9kZWxzYCByZXNwb25zZSBpbnN0ZWFkLiBUaGUgcHVyZSBjbGFzc2lmaWVyXG4gKiAoe0BsaW5rIGNsYXNzaWZ5LmNsYXNzaWZ5RW5kcG9pbnRzfSkgaXMgd2hhdCB0aGUgY2xpZW50IHNoYXJlcy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgY2xhc3NpZnksIG1vZGVsLCB0eXBlIEZhbWlseUNsYXNzIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1vZGVsXCI7XG5cbnR5cGUgTW9kZWxDbGFzcyA9IG1vZGVsLk1vZGVsQ2xhc3M7XG5jb25zdCB7IE1vZGVsQ2xhc3MgfSA9IG1vZGVsO1xuXG4vKipcbiAqIFNtYWxsLCBsYXN0LXJlc29ydCBzZXQgb2Ygd2VsbC1rbm93biBGb3VuZGF0aW9uIE1vZGVsIEFQSSBlbmRwb2ludCBuYW1lcyxcbiAqIG9yZGVyZWQgYmVzdC1maXJzdCB3aXRoaW4gZWFjaCBjbGFzcyBieSB7QGxpbmsgY2xhc3NpZnkuY2xhc3NpZnlCeUZhbWlseX0uXG4gKiBVc2VkIG9ubHkgYXMgdGhlIGZsb29yIHdoZW4gdGhlIGxpdmUgYC9zZXJ2aW5nLWVuZHBvaW50c2AgY2F0YWxvZ3VlIGNhbid0IGJlXG4gKiByZWFkIGF0IHJlc29sdmUgdGltZTsgdGhlIGxpdmUsIHNjb3JlLWRyaXZlbiBjbGFzc2lmaWNhdGlvbiBzdXBlcnNlZGVzIGl0XG4gKiB3aGVuZXZlciB0aGUgd29ya3NwYWNlIGxpc3RpbmcgaXMgYXZhaWxhYmxlLiBDbGFzc2VzIGFyZSBub3QgaGFyZC1jb2RlZCBoZXJlXG4gKiAtIGVhY2ggbmFtZSBpcyBjbGFzc2lmaWVkIGJ5IGZhbWlseSBoZXVyaXN0aWMuXG4gKi9cbmNvbnN0IEZBTExCQUNLX01PREVMX05BTUVTOiByZWFkb25seSBzdHJpbmdbXSA9IFtcbiAgXCJkYXRhYnJpY2tzLWNsYXVkZS1vcHVzLTQtOFwiLFxuICBcImRhdGFicmlja3MtZ3B0LTUtNS1wcm9cIixcbiAgXCJkYXRhYnJpY2tzLWdlbWluaS0zLTEtcHJvXCIsXG4gIFwiZGF0YWJyaWNrcy1jbGF1ZGUtc29ubmV0LTQtNlwiLFxuICBcImRhdGFicmlja3MtZ3B0LTUtNVwiLFxuICBcImRhdGFicmlja3MtbWV0YS1sbGFtYS0zLTMtNzBiLWluc3RydWN0XCIsXG4gIFwiZGF0YWJyaWNrcy1jbGF1ZGUtaGFpa3UtNC01XCIsXG4gIFwiZGF0YWJyaWNrcy1ncHQtNS1uYW5vXCIsXG4gIFwiZGF0YWJyaWNrcy1tZXRhLWxsYW1hLTMtMS04Yi1pbnN0cnVjdFwiLFxuXTtcblxuLyoqXG4gKiBTdGF0aWMgZmFsbGJhY2sgbW9kZWwgaWRzIGZvciBhIGNoYXQgY2xhc3MsIGRyYXduIGZyb20gdGhlIHNtYWxsIGJ1aWx0LWluXG4gKiB7QGxpbmsgRkFMTEJBQ0tfTU9ERUxfTkFNRVN9IGxpc3QgYW5kIG9yZGVyZWQgYmVzdC1maXJzdCBieSBmYW1pbHkgcmFuay4gU3luY1xuICogYW5kIHdvcmtzcGFjZS1pbmRlcGVuZGVudDogdGhpcyBpcyB0aGUgKmZhbGxiYWNrIG9waW5pb24qIHVzZWQgdG8gc2VlZCBkZWZhdWx0XG4gKiBsaXN0cyBvciB3aGVuIHRoZSBsaXZlIGNhdGFsb2d1ZSBpcyB1bnJlYWNoYWJsZSAtIGxpdmUgcmVzb2x1dGlvbiBwcmVmZXJzXG4gKiB7QGxpbmsgY2xhc3NpZnkuY2xhc3NpZnlFbmRwb2ludHN9LiBSZXR1cm5zIGBbXWAgZm9yXG4gKiB7QGxpbmsgTW9kZWxDbGFzcy5FbWJlZGRpbmd9ICh0aGUgZmxvb3IgaXMgY2hhdC1vbmx5KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vZGVsc0ZvckNsYXNzKGNsczogTW9kZWxDbGFzcyk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgcmV0dXJuIEZBTExCQUNLX01PREVMX05BTUVTLm1hcCgobmFtZSkgPT4gKHsgbmFtZSwgYzogY2xhc3NpZnkuY2xhc3NpZnlCeUZhbWlseShuYW1lKSB9KSlcbiAgICAuZmlsdGVyKCh4KTogeCBpcyB7IG5hbWU6IHN0cmluZzsgYzogRmFtaWx5Q2xhc3MgfSA9PiB4LmMgIT09IG51bGwgJiYgeC5jLmNsYXNzID09PSBjbHMpXG4gICAgLnNvcnQoKGEsIGIpID0+IGIuYy5yYW5rIC0gYS5jLnJhbmspXG4gICAgLm1hcCgoeCkgPT4geC5uYW1lKTtcbn1cblxuLyoqIFRvcCBzdGF0aWMgZmFsbGJhY2sgbW9kZWwgaWQgZm9yIGEgY2hhdCBjbGFzcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbEZvckNsYXNzKGNsczogTW9kZWxDbGFzcyk6IHN0cmluZyB7XG4gIHJldHVybiBtb2RlbHNGb3JDbGFzcyhjbHMpWzBdITtcbn1cblxuLyoqXG4gKiBQcmlvcml0eS1vcmRlcmVkIGZhbGxiYWNrIGNoYWluIChDaGF0VGhpbmtpbmcgLT4gQ2hhdEJhbGFuY2VkIC0+IENoYXRGYXN0KVxuICogb3ZlciB0aGUgc21hbGwgYnVpbHQtaW4gbGlzdC4gVGhlIGZsb29yIHdhbGtlZCBhdCByZXNvbHZlIHRpbWUgd2hlbiBubyBhZ2VudFxuICogLyBwbHVnaW4gLyBlbnYgLyByZXF1ZXN0IG1vZGVsIGlzIHNldCAqYW5kKiB0aGUgbGl2ZSBjYXRhbG9ndWUgeWllbGRzIG5vdGhpbmcuXG4gKi9cbmV4cG9ydCBjb25zdCBGQUxMQkFDS19NT0RFTF9JRFM6IHJlYWRvbmx5IHN0cmluZ1tdID0gW1xuICAuLi5tb2RlbHNGb3JDbGFzcyhNb2RlbENsYXNzLkNoYXRUaGlua2luZyksXG4gIC4uLm1vZGVsc0ZvckNsYXNzKE1vZGVsQ2xhc3MuQ2hhdEJhbGFuY2VkKSxcbiAgLi4ubW9kZWxzRm9yQ2xhc3MoTW9kZWxDbGFzcy5DaGF0RmFzdCksXG5dO1xuIl19
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calling a Model Serving endpoint directly over HTTP.
|
|
3
|
+
*
|
|
4
|
+
* The SDK's `servingEndpoints.query` covers the typed request shapes, but an
|
|
5
|
+
* OpenAI-compatible caller (a proxy, a passthrough route, a streaming client)
|
|
6
|
+
* needs to issue its own `fetch` against Databricks' OpenAI-shaped URLs with
|
|
7
|
+
* an OpenAI body. That needs exactly two things the SDK doesn't hand out
|
|
8
|
+
* directly: the URL ({@link invocationsUrl} / {@link responsesUrl} /
|
|
9
|
+
* {@link openResponsesUrl}) and a currently-valid set of auth headers
|
|
10
|
+
* ({@link authHeaders}).
|
|
11
|
+
*
|
|
12
|
+
* Auth is delegated entirely to the Databricks SDK: `config.authenticate`
|
|
13
|
+
* re-runs the configured credential provider on every call and refreshes the
|
|
14
|
+
* underlying OAuth / PAT token when it is close to expiry, so a caller never
|
|
15
|
+
* manages token lifetimes itself - mint headers per request and each one is
|
|
16
|
+
* signed with a valid bearer token.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Path segment appended to a serving endpoint for OpenAI-compatible chat
|
|
22
|
+
* requests. Databricks routes `/serving-endpoints/<name>/invocations` to the
|
|
23
|
+
* endpoint's Chat Completions surface (`messages` in, `choices` out). Some
|
|
24
|
+
* models (notably Codex) reject this path and require {@link responsesUrl}.
|
|
25
|
+
*/
|
|
26
|
+
export declare const INVOCATIONS_SUFFIX = "invocations";
|
|
27
|
+
/**
|
|
28
|
+
* Workspace-level OpenAI Responses API path. Body carries `model` (endpoint
|
|
29
|
+
* id); used by GPT / Codex models that speak Responses natively.
|
|
30
|
+
*/
|
|
31
|
+
export declare const RESPONSES_PATH = "serving-endpoints/responses";
|
|
32
|
+
/**
|
|
33
|
+
* Workspace-level Open Responses API path - the cross-provider Responses
|
|
34
|
+
* surface (Claude, Gemini, …) that OpenAI `/responses` does not cover.
|
|
35
|
+
*/
|
|
36
|
+
export declare const OPEN_RESPONSES_PATH = "serving-endpoints/open-responses";
|
|
37
|
+
/**
|
|
38
|
+
* Workspace-level OpenAI Chat Completions path. Body carries `model` (endpoint
|
|
39
|
+
* id), unlike {@link invocationsUrl} which names the endpoint in the URL. Use
|
|
40
|
+
* this when the caller has a model id rather than a per-endpoint route - e.g.
|
|
41
|
+
* attaching a provider tool spec to whichever endpoint was resolved.
|
|
42
|
+
*/
|
|
43
|
+
export declare const CHAT_COMPLETIONS_PATH = "serving-endpoints/chat/completions";
|
|
44
|
+
/**
|
|
45
|
+
* The OpenAI-compatible chat-completions invocations URL for an endpoint id.
|
|
46
|
+
*
|
|
47
|
+
* @param host - Workspace host, e.g. `https://my-workspace.cloud.databricks.com/`.
|
|
48
|
+
* Pass the value resolved from `client.config.getHost()`.
|
|
49
|
+
* @param endpoint - Endpoint id (already resolved; not fuzzy-matched here).
|
|
50
|
+
*/
|
|
51
|
+
export declare function invocationsUrl(host: string, endpoint: string): string;
|
|
52
|
+
/** Workspace OpenAI Responses API URL (`POST`, model in the body). */
|
|
53
|
+
export declare function responsesUrl(host: string): string;
|
|
54
|
+
/** Workspace Open Responses API URL (`POST`, model in the body). */
|
|
55
|
+
export declare function openResponsesUrl(host: string): string;
|
|
56
|
+
/** Workspace OpenAI Chat Completions URL (`POST`, model in the body). */
|
|
57
|
+
export declare function chatCompletionsUrl(host: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* True when the endpoint is known to reject Chat Completions `/invocations`
|
|
60
|
+
* and require the Responses API (Codex models today). Callers should route
|
|
61
|
+
* those to {@link responsesUrl} instead of {@link invocationsUrl}.
|
|
62
|
+
*/
|
|
63
|
+
export declare function isResponsesOnly(endpoint: string): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Pick the Databricks Responses upstream for an endpoint id: OpenAI-family
|
|
66
|
+
* models use `/serving-endpoints/responses`; everything else uses the
|
|
67
|
+
* cross-provider `/serving-endpoints/open-responses`.
|
|
68
|
+
*/
|
|
69
|
+
export declare function responsesUpstreamUrl(host: string, endpoint: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Minimal structural shape {@link authHeaders} needs. Declared narrowly rather
|
|
72
|
+
* than as a full `WorkspaceClientLike` so a caller holding its own
|
|
73
|
+
* `@databricks/sdk-experimental` `WorkspaceClient` satisfies it regardless of
|
|
74
|
+
* which SDK version resolved in its tree.
|
|
75
|
+
*/
|
|
76
|
+
export interface AuthenticatingClientLike {
|
|
77
|
+
config: {
|
|
78
|
+
authenticate(headers: Headers): Promise<void>;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Mint auth headers for one upstream request as a plain object, ready to spread
|
|
83
|
+
* into a `fetch` init. Call it per request: the SDK refreshes the underlying
|
|
84
|
+
* token when needed, so a long-lived process never has to track expiry itself.
|
|
85
|
+
*/
|
|
86
|
+
export declare function authHeaders(client: AuthenticatingClientLike): Promise<Record<string, string>>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calling a Model Serving endpoint directly over HTTP.
|
|
3
|
+
*
|
|
4
|
+
* The SDK's `servingEndpoints.query` covers the typed request shapes, but an
|
|
5
|
+
* OpenAI-compatible caller (a proxy, a passthrough route, a streaming client)
|
|
6
|
+
* needs to issue its own `fetch` against Databricks' OpenAI-shaped URLs with
|
|
7
|
+
* an OpenAI body. That needs exactly two things the SDK doesn't hand out
|
|
8
|
+
* directly: the URL ({@link invocationsUrl} / {@link responsesUrl} /
|
|
9
|
+
* {@link openResponsesUrl}) and a currently-valid set of auth headers
|
|
10
|
+
* ({@link authHeaders}).
|
|
11
|
+
*
|
|
12
|
+
* Auth is delegated entirely to the Databricks SDK: `config.authenticate`
|
|
13
|
+
* re-runs the configured credential provider on every call and refreshes the
|
|
14
|
+
* underlying OAuth / PAT token when it is close to expiry, so a caller never
|
|
15
|
+
* manages token lifetimes itself - mint headers per request and each one is
|
|
16
|
+
* signed with a valid bearer token.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Path segment appended to a serving endpoint for OpenAI-compatible chat
|
|
22
|
+
* requests. Databricks routes `/serving-endpoints/<name>/invocations` to the
|
|
23
|
+
* endpoint's Chat Completions surface (`messages` in, `choices` out). Some
|
|
24
|
+
* models (notably Codex) reject this path and require {@link responsesUrl}.
|
|
25
|
+
*/
|
|
26
|
+
export const INVOCATIONS_SUFFIX = "invocations";
|
|
27
|
+
/**
|
|
28
|
+
* Workspace-level OpenAI Responses API path. Body carries `model` (endpoint
|
|
29
|
+
* id); used by GPT / Codex models that speak Responses natively.
|
|
30
|
+
*/
|
|
31
|
+
export const RESPONSES_PATH = "serving-endpoints/responses";
|
|
32
|
+
/**
|
|
33
|
+
* Workspace-level Open Responses API path - the cross-provider Responses
|
|
34
|
+
* surface (Claude, Gemini, …) that OpenAI `/responses` does not cover.
|
|
35
|
+
*/
|
|
36
|
+
export const OPEN_RESPONSES_PATH = "serving-endpoints/open-responses";
|
|
37
|
+
/**
|
|
38
|
+
* Workspace-level OpenAI Chat Completions path. Body carries `model` (endpoint
|
|
39
|
+
* id), unlike {@link invocationsUrl} which names the endpoint in the URL. Use
|
|
40
|
+
* this when the caller has a model id rather than a per-endpoint route - e.g.
|
|
41
|
+
* attaching a provider tool spec to whichever endpoint was resolved.
|
|
42
|
+
*/
|
|
43
|
+
export const CHAT_COMPLETIONS_PATH = "serving-endpoints/chat/completions";
|
|
44
|
+
/**
|
|
45
|
+
* The OpenAI-compatible chat-completions invocations URL for an endpoint id.
|
|
46
|
+
*
|
|
47
|
+
* @param host - Workspace host, e.g. `https://my-workspace.cloud.databricks.com/`.
|
|
48
|
+
* Pass the value resolved from `client.config.getHost()`.
|
|
49
|
+
* @param endpoint - Endpoint id (already resolved; not fuzzy-matched here).
|
|
50
|
+
*/
|
|
51
|
+
export function invocationsUrl(host, endpoint) {
|
|
52
|
+
return new URL(`serving-endpoints/${encodeURIComponent(endpoint)}/${INVOCATIONS_SUFFIX}`, host).toString();
|
|
53
|
+
}
|
|
54
|
+
/** Workspace OpenAI Responses API URL (`POST`, model in the body). */
|
|
55
|
+
export function responsesUrl(host) {
|
|
56
|
+
return new URL(RESPONSES_PATH, host).toString();
|
|
57
|
+
}
|
|
58
|
+
/** Workspace Open Responses API URL (`POST`, model in the body). */
|
|
59
|
+
export function openResponsesUrl(host) {
|
|
60
|
+
return new URL(OPEN_RESPONSES_PATH, host).toString();
|
|
61
|
+
}
|
|
62
|
+
/** Workspace OpenAI Chat Completions URL (`POST`, model in the body). */
|
|
63
|
+
export function chatCompletionsUrl(host) {
|
|
64
|
+
return new URL(CHAT_COMPLETIONS_PATH, host).toString();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* True when the endpoint is known to reject Chat Completions `/invocations`
|
|
68
|
+
* and require the Responses API (Codex models today). Callers should route
|
|
69
|
+
* those to {@link responsesUrl} instead of {@link invocationsUrl}.
|
|
70
|
+
*/
|
|
71
|
+
export function isResponsesOnly(endpoint) {
|
|
72
|
+
return /codex/i.test(endpoint);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Pick the Databricks Responses upstream for an endpoint id: OpenAI-family
|
|
76
|
+
* models use `/serving-endpoints/responses`; everything else uses the
|
|
77
|
+
* cross-provider `/serving-endpoints/open-responses`.
|
|
78
|
+
*/
|
|
79
|
+
export function responsesUpstreamUrl(host, endpoint) {
|
|
80
|
+
return isOpenAiFamily(endpoint) ? responsesUrl(host) : openResponsesUrl(host);
|
|
81
|
+
}
|
|
82
|
+
/** GPT / Codex / o-series style endpoint names that speak OpenAI Responses. */
|
|
83
|
+
function isOpenAiFamily(endpoint) {
|
|
84
|
+
const n = endpoint.toLowerCase();
|
|
85
|
+
return (n.includes("gpt") ||
|
|
86
|
+
n.includes("codex") ||
|
|
87
|
+
/(^|[^a-z])o[1-9]([^a-z]|$)/.test(n) ||
|
|
88
|
+
n.includes("openai"));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Mint auth headers for one upstream request as a plain object, ready to spread
|
|
92
|
+
* into a `fetch` init. Call it per request: the SDK refreshes the underlying
|
|
93
|
+
* token when needed, so a long-lived process never has to track expiry itself.
|
|
94
|
+
*/
|
|
95
|
+
export async function authHeaders(client) {
|
|
96
|
+
const headers = new Headers();
|
|
97
|
+
await client.config.authenticate(headers);
|
|
98
|
+
const out = {};
|
|
99
|
+
headers.forEach((value, key) => {
|
|
100
|
+
out[key] = value;
|
|
101
|
+
});
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52b2tlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludm9rZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUg7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxhQUFhLENBQUM7QUFFaEQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLDZCQUE2QixDQUFDO0FBRTVEOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLGtDQUFrQyxDQUFDO0FBRXRFOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsb0NBQW9DLENBQUM7QUFFMUU7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxJQUFZLEVBQUUsUUFBZ0I7SUFDM0QsT0FBTyxJQUFJLEdBQUcsQ0FDWixxQkFBcUIsa0JBQWtCLENBQUMsUUFBUSxDQUFDLElBQUksa0JBQWtCLEVBQUUsRUFDekUsSUFBSSxDQUNMLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDZixDQUFDO0FBRUQsc0VBQXNFO0FBQ3RFLE1BQU0sVUFBVSxZQUFZLENBQUMsSUFBWTtJQUN2QyxPQUFPLElBQUksR0FBRyxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUNsRCxDQUFDO0FBRUQsb0VBQW9FO0FBQ3BFLE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxJQUFZO0lBQzNDLE9BQU8sSUFBSSxHQUFHLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDdkQsQ0FBQztBQUVELHlFQUF5RTtBQUN6RSxNQUFNLFVBQVUsa0JBQWtCLENBQUMsSUFBWTtJQUM3QyxPQUFPLElBQUksR0FBRyxDQUFDLHFCQUFxQixFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ3pELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxRQUFnQjtJQUM5QyxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsSUFBWSxFQUFFLFFBQWdCO0lBQ2pFLE9BQU8sY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2hGLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsU0FBUyxjQUFjLENBQUMsUUFBZ0I7SUFDdEMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ2pDLE9BQU8sQ0FDTCxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUNqQixDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztRQUNuQiw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQ3JCLENBQUM7QUFDSixDQUFDO0FBY0Q7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsV0FBVyxDQUMvQixNQUFnQztJQUVoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQzlCLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUMsTUFBTSxHQUFHLEdBQTJCLEVBQUUsQ0FBQztJQUN2QyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFO1FBQzdCLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDbkIsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENhbGxpbmcgYSBNb2RlbCBTZXJ2aW5nIGVuZHBvaW50IGRpcmVjdGx5IG92ZXIgSFRUUC5cbiAqXG4gKiBUaGUgU0RLJ3MgYHNlcnZpbmdFbmRwb2ludHMucXVlcnlgIGNvdmVycyB0aGUgdHlwZWQgcmVxdWVzdCBzaGFwZXMsIGJ1dCBhblxuICogT3BlbkFJLWNvbXBhdGlibGUgY2FsbGVyIChhIHByb3h5LCBhIHBhc3N0aHJvdWdoIHJvdXRlLCBhIHN0cmVhbWluZyBjbGllbnQpXG4gKiBuZWVkcyB0byBpc3N1ZSBpdHMgb3duIGBmZXRjaGAgYWdhaW5zdCBEYXRhYnJpY2tzJyBPcGVuQUktc2hhcGVkIFVSTHMgd2l0aFxuICogYW4gT3BlbkFJIGJvZHkuIFRoYXQgbmVlZHMgZXhhY3RseSB0d28gdGhpbmdzIHRoZSBTREsgZG9lc24ndCBoYW5kIG91dFxuICogZGlyZWN0bHk6IHRoZSBVUkwgKHtAbGluayBpbnZvY2F0aW9uc1VybH0gLyB7QGxpbmsgcmVzcG9uc2VzVXJsfSAvXG4gKiB7QGxpbmsgb3BlblJlc3BvbnNlc1VybH0pIGFuZCBhIGN1cnJlbnRseS12YWxpZCBzZXQgb2YgYXV0aCBoZWFkZXJzXG4gKiAoe0BsaW5rIGF1dGhIZWFkZXJzfSkuXG4gKlxuICogQXV0aCBpcyBkZWxlZ2F0ZWQgZW50aXJlbHkgdG8gdGhlIERhdGFicmlja3MgU0RLOiBgY29uZmlnLmF1dGhlbnRpY2F0ZWBcbiAqIHJlLXJ1bnMgdGhlIGNvbmZpZ3VyZWQgY3JlZGVudGlhbCBwcm92aWRlciBvbiBldmVyeSBjYWxsIGFuZCByZWZyZXNoZXMgdGhlXG4gKiB1bmRlcmx5aW5nIE9BdXRoIC8gUEFUIHRva2VuIHdoZW4gaXQgaXMgY2xvc2UgdG8gZXhwaXJ5LCBzbyBhIGNhbGxlciBuZXZlclxuICogbWFuYWdlcyB0b2tlbiBsaWZldGltZXMgaXRzZWxmIC0gbWludCBoZWFkZXJzIHBlciByZXF1ZXN0IGFuZCBlYWNoIG9uZSBpc1xuICogc2lnbmVkIHdpdGggYSB2YWxpZCBiZWFyZXIgdG9rZW4uXG4gKlxuICogQG1vZHVsZVxuICovXG5cbi8qKlxuICogUGF0aCBzZWdtZW50IGFwcGVuZGVkIHRvIGEgc2VydmluZyBlbmRwb2ludCBmb3IgT3BlbkFJLWNvbXBhdGlibGUgY2hhdFxuICogcmVxdWVzdHMuIERhdGFicmlja3Mgcm91dGVzIGAvc2VydmluZy1lbmRwb2ludHMvPG5hbWU+L2ludm9jYXRpb25zYCB0byB0aGVcbiAqIGVuZHBvaW50J3MgQ2hhdCBDb21wbGV0aW9ucyBzdXJmYWNlIChgbWVzc2FnZXNgIGluLCBgY2hvaWNlc2Agb3V0KS4gU29tZVxuICogbW9kZWxzIChub3RhYmx5IENvZGV4KSByZWplY3QgdGhpcyBwYXRoIGFuZCByZXF1aXJlIHtAbGluayByZXNwb25zZXNVcmx9LlxuICovXG5leHBvcnQgY29uc3QgSU5WT0NBVElPTlNfU1VGRklYID0gXCJpbnZvY2F0aW9uc1wiO1xuXG4vKipcbiAqIFdvcmtzcGFjZS1sZXZlbCBPcGVuQUkgUmVzcG9uc2VzIEFQSSBwYXRoLiBCb2R5IGNhcnJpZXMgYG1vZGVsYCAoZW5kcG9pbnRcbiAqIGlkKTsgdXNlZCBieSBHUFQgLyBDb2RleCBtb2RlbHMgdGhhdCBzcGVhayBSZXNwb25zZXMgbmF0aXZlbHkuXG4gKi9cbmV4cG9ydCBjb25zdCBSRVNQT05TRVNfUEFUSCA9IFwic2VydmluZy1lbmRwb2ludHMvcmVzcG9uc2VzXCI7XG5cbi8qKlxuICogV29ya3NwYWNlLWxldmVsIE9wZW4gUmVzcG9uc2VzIEFQSSBwYXRoIC0gdGhlIGNyb3NzLXByb3ZpZGVyIFJlc3BvbnNlc1xuICogc3VyZmFjZSAoQ2xhdWRlLCBHZW1pbmksIOKApikgdGhhdCBPcGVuQUkgYC9yZXNwb25zZXNgIGRvZXMgbm90IGNvdmVyLlxuICovXG5leHBvcnQgY29uc3QgT1BFTl9SRVNQT05TRVNfUEFUSCA9IFwic2VydmluZy1lbmRwb2ludHMvb3Blbi1yZXNwb25zZXNcIjtcblxuLyoqXG4gKiBXb3Jrc3BhY2UtbGV2ZWwgT3BlbkFJIENoYXQgQ29tcGxldGlvbnMgcGF0aC4gQm9keSBjYXJyaWVzIGBtb2RlbGAgKGVuZHBvaW50XG4gKiBpZCksIHVubGlrZSB7QGxpbmsgaW52b2NhdGlvbnNVcmx9IHdoaWNoIG5hbWVzIHRoZSBlbmRwb2ludCBpbiB0aGUgVVJMLiBVc2VcbiAqIHRoaXMgd2hlbiB0aGUgY2FsbGVyIGhhcyBhIG1vZGVsIGlkIHJhdGhlciB0aGFuIGEgcGVyLWVuZHBvaW50IHJvdXRlIC0gZS5nLlxuICogYXR0YWNoaW5nIGEgcHJvdmlkZXIgdG9vbCBzcGVjIHRvIHdoaWNoZXZlciBlbmRwb2ludCB3YXMgcmVzb2x2ZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBDSEFUX0NPTVBMRVRJT05TX1BBVEggPSBcInNlcnZpbmctZW5kcG9pbnRzL2NoYXQvY29tcGxldGlvbnNcIjtcblxuLyoqXG4gKiBUaGUgT3BlbkFJLWNvbXBhdGlibGUgY2hhdC1jb21wbGV0aW9ucyBpbnZvY2F0aW9ucyBVUkwgZm9yIGFuIGVuZHBvaW50IGlkLlxuICpcbiAqIEBwYXJhbSBob3N0IC0gV29ya3NwYWNlIGhvc3QsIGUuZy4gYGh0dHBzOi8vbXktd29ya3NwYWNlLmNsb3VkLmRhdGFicmlja3MuY29tL2AuXG4gKiAgIFBhc3MgdGhlIHZhbHVlIHJlc29sdmVkIGZyb20gYGNsaWVudC5jb25maWcuZ2V0SG9zdCgpYC5cbiAqIEBwYXJhbSBlbmRwb2ludCAtIEVuZHBvaW50IGlkIChhbHJlYWR5IHJlc29sdmVkOyBub3QgZnV6enktbWF0Y2hlZCBoZXJlKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGludm9jYXRpb25zVXJsKGhvc3Q6IHN0cmluZywgZW5kcG9pbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKFxuICAgIGBzZXJ2aW5nLWVuZHBvaW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChlbmRwb2ludCl9LyR7SU5WT0NBVElPTlNfU1VGRklYfWAsXG4gICAgaG9zdCxcbiAgKS50b1N0cmluZygpO1xufVxuXG4vKiogV29ya3NwYWNlIE9wZW5BSSBSZXNwb25zZXMgQVBJIFVSTCAoYFBPU1RgLCBtb2RlbCBpbiB0aGUgYm9keSkuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzcG9uc2VzVXJsKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKFJFU1BPTlNFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKiogV29ya3NwYWNlIE9wZW4gUmVzcG9uc2VzIEFQSSBVUkwgKGBQT1NUYCwgbW9kZWwgaW4gdGhlIGJvZHkpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wZW5SZXNwb25zZXNVcmwoaG9zdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldyBVUkwoT1BFTl9SRVNQT05TRVNfUEFUSCwgaG9zdCkudG9TdHJpbmcoKTtcbn1cblxuLyoqIFdvcmtzcGFjZSBPcGVuQUkgQ2hhdCBDb21wbGV0aW9ucyBVUkwgKGBQT1NUYCwgbW9kZWwgaW4gdGhlIGJvZHkpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoYXRDb21wbGV0aW9uc1VybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChDSEFUX0NPTVBMRVRJT05TX1BBVEgsIGhvc3QpLnRvU3RyaW5nKCk7XG59XG5cbi8qKlxuICogVHJ1ZSB3aGVuIHRoZSBlbmRwb2ludCBpcyBrbm93biB0byByZWplY3QgQ2hhdCBDb21wbGV0aW9ucyBgL2ludm9jYXRpb25zYFxuICogYW5kIHJlcXVpcmUgdGhlIFJlc3BvbnNlcyBBUEkgKENvZGV4IG1vZGVscyB0b2RheSkuIENhbGxlcnMgc2hvdWxkIHJvdXRlXG4gKiB0aG9zZSB0byB7QGxpbmsgcmVzcG9uc2VzVXJsfSBpbnN0ZWFkIG9mIHtAbGluayBpbnZvY2F0aW9uc1VybH0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1Jlc3BvbnNlc09ubHkoZW5kcG9pbnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gL2NvZGV4L2kudGVzdChlbmRwb2ludCk7XG59XG5cbi8qKlxuICogUGljayB0aGUgRGF0YWJyaWNrcyBSZXNwb25zZXMgdXBzdHJlYW0gZm9yIGFuIGVuZHBvaW50IGlkOiBPcGVuQUktZmFtaWx5XG4gKiBtb2RlbHMgdXNlIGAvc2VydmluZy1lbmRwb2ludHMvcmVzcG9uc2VzYDsgZXZlcnl0aGluZyBlbHNlIHVzZXMgdGhlXG4gKiBjcm9zcy1wcm92aWRlciBgL3NlcnZpbmctZW5kcG9pbnRzL29wZW4tcmVzcG9uc2VzYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc3BvbnNlc1Vwc3RyZWFtVXJsKGhvc3Q6IHN0cmluZywgZW5kcG9pbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBpc09wZW5BaUZhbWlseShlbmRwb2ludCkgPyByZXNwb25zZXNVcmwoaG9zdCkgOiBvcGVuUmVzcG9uc2VzVXJsKGhvc3QpO1xufVxuXG4vKiogR1BUIC8gQ29kZXggLyBvLXNlcmllcyBzdHlsZSBlbmRwb2ludCBuYW1lcyB0aGF0IHNwZWFrIE9wZW5BSSBSZXNwb25zZXMuICovXG5mdW5jdGlvbiBpc09wZW5BaUZhbWlseShlbmRwb2ludDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG4gPSBlbmRwb2ludC50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gKFxuICAgIG4uaW5jbHVkZXMoXCJncHRcIikgfHxcbiAgICBuLmluY2x1ZGVzKFwiY29kZXhcIikgfHxcbiAgICAvKF58W15hLXpdKW9bMS05XShbXmEtel18JCkvLnRlc3QobikgfHxcbiAgICBuLmluY2x1ZGVzKFwib3BlbmFpXCIpXG4gICk7XG59XG5cbi8qKlxuICogTWluaW1hbCBzdHJ1Y3R1cmFsIHNoYXBlIHtAbGluayBhdXRoSGVhZGVyc30gbmVlZHMuIERlY2xhcmVkIG5hcnJvd2x5IHJhdGhlclxuICogdGhhbiBhcyBhIGZ1bGwgYFdvcmtzcGFjZUNsaWVudExpa2VgIHNvIGEgY2FsbGVyIGhvbGRpbmcgaXRzIG93blxuICogYEBkYXRhYnJpY2tzL3Nkay1leHBlcmltZW50YWxgIGBXb3Jrc3BhY2VDbGllbnRgIHNhdGlzZmllcyBpdCByZWdhcmRsZXNzIG9mXG4gKiB3aGljaCBTREsgdmVyc2lvbiByZXNvbHZlZCBpbiBpdHMgdHJlZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdXRoZW50aWNhdGluZ0NsaWVudExpa2Uge1xuICBjb25maWc6IHtcbiAgICBhdXRoZW50aWNhdGUoaGVhZGVyczogSGVhZGVycyk6IFByb21pc2U8dm9pZD47XG4gIH07XG59XG5cbi8qKlxuICogTWludCBhdXRoIGhlYWRlcnMgZm9yIG9uZSB1cHN0cmVhbSByZXF1ZXN0IGFzIGEgcGxhaW4gb2JqZWN0LCByZWFkeSB0byBzcHJlYWRcbiAqIGludG8gYSBgZmV0Y2hgIGluaXQuIENhbGwgaXQgcGVyIHJlcXVlc3Q6IHRoZSBTREsgcmVmcmVzaGVzIHRoZSB1bmRlcmx5aW5nXG4gKiB0b2tlbiB3aGVuIG5lZWRlZCwgc28gYSBsb25nLWxpdmVkIHByb2Nlc3MgbmV2ZXIgaGFzIHRvIHRyYWNrIGV4cGlyeSBpdHNlbGYuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhdXRoSGVhZGVycyhcbiAgY2xpZW50OiBBdXRoZW50aWNhdGluZ0NsaWVudExpa2UsXG4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+IHtcbiAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gIGF3YWl0IGNsaWVudC5jb25maWcuYXV0aGVudGljYXRlKGhlYWRlcnMpO1xuICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgaGVhZGVycy5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgb3V0W2tleV0gPSB2YWx1ZTtcbiAgfSk7XG4gIHJldHVybiBvdXQ7XG59XG4iXX0=
|