@dbx-tools/model 0.9.99 → 0.9.106

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 CHANGED
@@ -2,12 +2,22 @@
2
2
 
3
3
  Workspace-aware Databricks Model Serving selection.
4
4
 
5
- Import this package when server-side code needs to turn a loose model request
6
- like `"claude sonnet"` or `"chat-fast"` into a concrete serving endpoint in the
7
- current workspace. It lists `/serving-endpoints`, caches and enriches the
5
+ Turn a loose model request such as `"claude sonnet"` or `"chat-fast"` into a
6
+ concrete serving endpoint in the current workspace. The client lists
7
+ `/serving-endpoints`, caches and enriches the
8
8
  catalogue, classifies endpoints by capability, fuzzy-matches names, and falls
9
9
  back to a small static floor when the live catalogue is unavailable.
10
10
 
11
+ ## Quick Start
12
+
13
+ ```ts
14
+ import { createModelClient } from "@dbx-tools/model";
15
+
16
+ const models = await createModelClient();
17
+ const selected = await models.resolveModel({ explicit: "sonnet" });
18
+ console.log(selected.modelId);
19
+ ```
20
+
11
21
  Browser-safe request/result schemas and endpoint classification types live in
12
22
  [`@dbx-tools/shared-model`](../../shared/model).
13
23
 
@@ -33,7 +43,7 @@ Key features:
33
43
  - Provides a small static fallback floor for local tools and degraded workspace
34
44
  access.
35
45
 
36
- ## Why Not Just AppKit Serving?
46
+ ## Use With AppKit Model Serving
37
47
 
38
48
  Native AppKit's Model Serving plugin is the right choice when you already know
39
49
  the endpoint alias you want. It gives you authenticated invoke/stream routes,
@@ -53,7 +63,7 @@ endpoint:
53
63
  - keep local agents and CLIs working with a static fallback when catalogue
54
64
  access is unavailable.
55
65
 
56
- ## Use The Portable Model Client
66
+ ## Route Requests
57
67
 
58
68
  ```ts
59
69
  import { createModelClient } from "@dbx-tools/model";
@@ -243,7 +253,7 @@ a property of the model (see `isResponsesOnly()` and `responsesUpstreamUrl()`),
243
253
  so a hard-coded string in one package silently diverges when that routing
244
254
  changes. `isResponsesOnly()` covers Codex and GPT 5.4+ endpoints, which reject
245
255
  tool-bearing Chat Completions, while keeping GPT-OSS on its supported Chat path.
246
- The TypeScript helper owns this policy so every Node consumer shares one version
256
+ The TypeScript helper applies this policy so every Node consumer shares one version
247
257
  threshold without loading a native library.
248
258
 
249
259
  ## Read Published Model Metadata
package/index.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
 
5
5
  export const PACKAGE_IDENTIFIER = "@dbx-tools/model";
6
- export const PACKAGE_VERSION = "0.9.99";
6
+ export const PACKAGE_VERSION = "0.9.106";
7
7
  export * as bindings from "./src/bindings.ts";
8
8
  export * as classes from "./src/classes.ts";
9
9
  export * as classify from "./src/classify.ts";
@@ -16,10 +16,9 @@ export * as modelClient from "./src/model-client.ts";
16
16
  export * as policy from "./src/policy.ts";
17
17
  export * as reasoningTranslation from "./src/reasoning-translation.ts";
18
18
  export * as resolve from "./src/resolve.ts";
19
- export * as servingWire from "./src/serving-wire.ts";
20
19
  export { CHAT_CLASS_ORDER, MODEL_CLASS_ORDER } from "./src/classes.ts";
21
20
  export { FALLBACK_MODEL_IDS } from "./src/fallback.ts";
22
- export { INVOCATIONS_SUFFIX, RESPONSES_PATH, OPEN_RESPONSES_PATH, CHAT_COMPLETIONS_PATH, AI_GATEWAY_CODEX_RESPONSES_PATH, ANTHROPIC_MESSAGES_PATH } from "./src/invoke.ts";
21
+ export { INVOCATIONS_SUFFIX, SERVING_ENDPOINTS_PATH, RESPONSES_PATH, OPEN_RESPONSES_PATH, CHAT_COMPLETIONS_PATH, AI_GATEWAY_CODEX_RESPONSES_PATH, ANTHROPIC_BASE_PATH, ANTHROPIC_MESSAGES_PATH } from "./src/invoke.ts";
23
22
  export type { AuthenticatingClientLike } from "./src/invoke.ts";
24
23
  export { MODEL_METADATA_TTL_MS, MODEL_RATE_LIMITS_URL, OPENAI_RESPONSES_MODELS_URL, QUERY_REASON_MODELS_URL, RETIRED_MODELS_URL, WEB_SEARCH_MODELS_URL } from "./src/metadata.ts";
25
24
  export type { MetadataCacheRecord, MetadataCacheOptions, MetadataCacheMergeInput, MetadataCache } from "./src/metadata-cache.ts";
@@ -31,5 +30,4 @@ export { ModelFamily } from "./src/policy.ts";
31
30
  export { REASONING_LEVELS } from "./src/reasoning-translation.ts";
32
31
  export type { ReasoningLevel, ReasoningModelCatalogue, AdaptedRequestReasoning } from "./src/reasoning-translation.ts";
33
32
  export type { SelectModelInput, SearchModelsInput } from "./src/resolve.ts";
34
- export type { ServingChatMessage, RewrittenServingRequest } from "./src/serving-wire.ts";
35
33
  export * from "./exports.ts";
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export declare const PACKAGE_IDENTIFIER = "@dbx-tools/model";
2
- export declare const PACKAGE_VERSION = "0.9.99";
2
+ export declare const PACKAGE_VERSION = "0.9.106";
3
3
  export * as bindings from "./src/bindings.ts";
4
4
  export * as classes from "./src/classes.ts";
5
5
  export * as classify from "./src/classify.ts";
@@ -12,10 +12,9 @@ export * as modelClient from "./src/model-client.ts";
12
12
  export * as policy from "./src/policy.ts";
13
13
  export * as reasoningTranslation from "./src/reasoning-translation.ts";
14
14
  export * as resolve from "./src/resolve.ts";
15
- export * as servingWire from "./src/serving-wire.ts";
16
15
  export { CHAT_CLASS_ORDER, MODEL_CLASS_ORDER } from "./src/classes.ts";
17
16
  export { FALLBACK_MODEL_IDS } from "./src/fallback.ts";
18
- export { INVOCATIONS_SUFFIX, RESPONSES_PATH, OPEN_RESPONSES_PATH, CHAT_COMPLETIONS_PATH, AI_GATEWAY_CODEX_RESPONSES_PATH, ANTHROPIC_MESSAGES_PATH } from "./src/invoke.ts";
17
+ export { INVOCATIONS_SUFFIX, SERVING_ENDPOINTS_PATH, RESPONSES_PATH, OPEN_RESPONSES_PATH, CHAT_COMPLETIONS_PATH, AI_GATEWAY_CODEX_RESPONSES_PATH, ANTHROPIC_BASE_PATH, ANTHROPIC_MESSAGES_PATH } from "./src/invoke.ts";
19
18
  export type { AuthenticatingClientLike } from "./src/invoke.ts";
20
19
  export { MODEL_METADATA_TTL_MS, MODEL_RATE_LIMITS_URL, OPENAI_RESPONSES_MODELS_URL, QUERY_REASON_MODELS_URL, RETIRED_MODELS_URL, WEB_SEARCH_MODELS_URL } from "./src/metadata.ts";
21
20
  export type { MetadataCacheRecord, MetadataCacheOptions, MetadataCacheMergeInput, MetadataCache } from "./src/metadata-cache.ts";
@@ -27,5 +26,4 @@ export { ModelFamily } from "./src/policy.ts";
27
26
  export { REASONING_LEVELS } from "./src/reasoning-translation.ts";
28
27
  export type { ReasoningLevel, ReasoningModelCatalogue, AdaptedRequestReasoning } from "./src/reasoning-translation.ts";
29
28
  export type { SelectModelInput, SearchModelsInput } from "./src/resolve.ts";
30
- export type { ServingChatMessage, RewrittenServingRequest } from "./src/serving-wire.ts";
31
29
  export * from "./exports.ts";
package/lib/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Regenerated from the exporting modules in ./src.
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
  export const PACKAGE_IDENTIFIER = "@dbx-tools/model";
5
- export const PACKAGE_VERSION = "0.9.99";
5
+ export const PACKAGE_VERSION = "0.9.106";
6
6
  export * as bindings from "./src/bindings.js";
7
7
  export * as classes from "./src/classes.js";
8
8
  export * as classify from "./src/classify.js";
@@ -15,14 +15,13 @@ export * as modelClient from "./src/model-client.js";
15
15
  export * as policy from "./src/policy.js";
16
16
  export * as reasoningTranslation from "./src/reasoning-translation.js";
17
17
  export * as resolve from "./src/resolve.js";
18
- export * as servingWire from "./src/serving-wire.js";
19
18
  export { CHAT_CLASS_ORDER, MODEL_CLASS_ORDER } from "./src/classes.js";
20
19
  export { FALLBACK_MODEL_IDS } from "./src/fallback.js";
21
- export { INVOCATIONS_SUFFIX, RESPONSES_PATH, OPEN_RESPONSES_PATH, CHAT_COMPLETIONS_PATH, AI_GATEWAY_CODEX_RESPONSES_PATH, ANTHROPIC_MESSAGES_PATH } from "./src/invoke.js";
20
+ export { INVOCATIONS_SUFFIX, SERVING_ENDPOINTS_PATH, RESPONSES_PATH, OPEN_RESPONSES_PATH, CHAT_COMPLETIONS_PATH, AI_GATEWAY_CODEX_RESPONSES_PATH, ANTHROPIC_BASE_PATH, ANTHROPIC_MESSAGES_PATH } from "./src/invoke.js";
22
21
  export { MODEL_METADATA_TTL_MS, MODEL_RATE_LIMITS_URL, OPENAI_RESPONSES_MODELS_URL, QUERY_REASON_MODELS_URL, RETIRED_MODELS_URL, WEB_SEARCH_MODELS_URL } from "./src/metadata.js";
23
22
  export { DEFAULT_MODEL_CACHE_TTL_MS, DEFAULT_FUZZY_THRESHOLD } from "./src/model-catalog.js";
24
23
  export { DEFAULT_MODEL_CLIENT_CACHE_TTL_MS } from "./src/model-client.js";
25
24
  export { ModelFamily } from "./src/policy.js";
26
25
  export { REASONING_LEVELS } from "./src/reasoning-translation.js";
27
26
  export * from "./exports.js";
28
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztBQUNyRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxhQUFhLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxLQUFLLFlBQVksTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEtBQUssV0FBVyxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLG9CQUFvQixNQUFNLGdDQUFnQyxDQUFDO0FBQ3ZFLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLFdBQVcsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLG1CQUFtQixFQUFFLHFCQUFxQixFQUFFLCtCQUErQixFQUFFLHVCQUF1QixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFM0ssT0FBTyxFQUFFLHFCQUFxQixFQUFFLHFCQUFxQixFQUFFLDJCQUEyQixFQUFFLHVCQUF1QixFQUFFLGtCQUFrQixFQUFFLHFCQUFxQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFbEwsT0FBTyxFQUFFLDBCQUEwQixFQUFFLHVCQUF1QixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFN0YsT0FBTyxFQUFFLGlDQUFpQyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFMUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBSWxFLGNBQWMsY0FBYyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gR0VORVJBVEVEIGJ5IHByb2plbiB3YXRjaCAtIERPIE5PVCBFRElULlxuLy8gUmVnZW5lcmF0ZWQgZnJvbSB0aGUgZXhwb3J0aW5nIG1vZHVsZXMgaW4gLi9zcmMuXG4vLyBIYW5kIGVkaXRzIGFyZSBvdmVyd3JpdHRlbiBvbiB0aGUgbmV4dCB3YXRjaDsgdGhpcyBmaWxlIGlzIHJlYWQtb25seS5cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfSURFTlRJRklFUiA9IFwiQGRieC10b29scy9tb2RlbFwiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IFwiMC45Ljk5XCI7XG5leHBvcnQgKiBhcyBiaW5kaW5ncyBmcm9tIFwiLi9zcmMvYmluZGluZ3MudHNcIjtcbmV4cG9ydCAqIGFzIGNsYXNzZXMgZnJvbSBcIi4vc3JjL2NsYXNzZXMudHNcIjtcbmV4cG9ydCAqIGFzIGNsYXNzaWZ5IGZyb20gXCIuL3NyYy9jbGFzc2lmeS50c1wiO1xuZXhwb3J0ICogYXMgZmFsbGJhY2sgZnJvbSBcIi4vc3JjL2ZhbGxiYWNrLnRzXCI7XG5leHBvcnQgKiBhcyBpbnZva2UgZnJvbSBcIi4vc3JjL2ludm9rZS50c1wiO1xuZXhwb3J0ICogYXMgbWV0YWRhdGEgZnJvbSBcIi4vc3JjL21ldGFkYXRhLnRzXCI7XG5leHBvcnQgKiBhcyBtZXRhZGF0YUNhY2hlIGZyb20gXCIuL3NyYy9tZXRhZGF0YS1jYWNoZS50c1wiO1xuZXhwb3J0ICogYXMgbW9kZWxDYXRhbG9nIGZyb20gXCIuL3NyYy9tb2RlbC1jYXRhbG9nLnRzXCI7XG5leHBvcnQgKiBhcyBtb2RlbENsaWVudCBmcm9tIFwiLi9zcmMvbW9kZWwtY2xpZW50LnRzXCI7XG5leHBvcnQgKiBhcyBwb2xpY3kgZnJvbSBcIi4vc3JjL3BvbGljeS50c1wiO1xuZXhwb3J0ICogYXMgcmVhc29uaW5nVHJhbnNsYXRpb24gZnJvbSBcIi4vc3JjL3JlYXNvbmluZy10cmFuc2xhdGlvbi50c1wiO1xuZXhwb3J0ICogYXMgcmVzb2x2ZSBmcm9tIFwiLi9zcmMvcmVzb2x2ZS50c1wiO1xuZXhwb3J0ICogYXMgc2VydmluZ1dpcmUgZnJvbSBcIi4vc3JjL3NlcnZpbmctd2lyZS50c1wiO1xuZXhwb3J0IHsgQ0hBVF9DTEFTU19PUkRFUiwgTU9ERUxfQ0xBU1NfT1JERVIgfSBmcm9tIFwiLi9zcmMvY2xhc3Nlcy50c1wiO1xuZXhwb3J0IHsgRkFMTEJBQ0tfTU9ERUxfSURTIH0gZnJvbSBcIi4vc3JjL2ZhbGxiYWNrLnRzXCI7XG5leHBvcnQgeyBJTlZPQ0FUSU9OU19TVUZGSVgsIFJFU1BPTlNFU19QQVRILCBPUEVOX1JFU1BPTlNFU19QQVRILCBDSEFUX0NPTVBMRVRJT05TX1BBVEgsIEFJX0dBVEVXQVlfQ09ERVhfUkVTUE9OU0VTX1BBVEgsIEFOVEhST1BJQ19NRVNTQUdFU19QQVRIIH0gZnJvbSBcIi4vc3JjL2ludm9rZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBBdXRoZW50aWNhdGluZ0NsaWVudExpa2UgfSBmcm9tIFwiLi9zcmMvaW52b2tlLnRzXCI7XG5leHBvcnQgeyBNT0RFTF9NRVRBREFUQV9UVExfTVMsIE1PREVMX1JBVEVfTElNSVRTX1VSTCwgT1BFTkFJX1JFU1BPTlNFU19NT0RFTFNfVVJMLCBRVUVSWV9SRUFTT05fTU9ERUxTX1VSTCwgUkVUSVJFRF9NT0RFTFNfVVJMLCBXRUJfU0VBUkNIX01PREVMU19VUkwgfSBmcm9tIFwiLi9zcmMvbWV0YWRhdGEudHNcIjtcbmV4cG9ydCB0eXBlIHsgTWV0YWRhdGFDYWNoZVJlY29yZCwgTWV0YWRhdGFDYWNoZU9wdGlvbnMsIE1ldGFkYXRhQ2FjaGVNZXJnZUlucHV0LCBNZXRhZGF0YUNhY2hlIH0gZnJvbSBcIi4vc3JjL21ldGFkYXRhLWNhY2hlLnRzXCI7XG5leHBvcnQgeyBERUZBVUxUX01PREVMX0NBQ0hFX1RUTF9NUywgREVGQVVMVF9GVVpaWV9USFJFU0hPTEQgfSBmcm9tIFwiLi9zcmMvbW9kZWwtY2F0YWxvZy50c1wiO1xuZXhwb3J0IHR5cGUgeyBXb3Jrc3BhY2VDbGllbnRMaWtlLCBMaXN0U2VydmluZ0VuZHBvaW50c09wdGlvbnMgfSBmcm9tIFwiLi9zcmMvbW9kZWwtY2F0YWxvZy50c1wiO1xuZXhwb3J0IHsgREVGQVVMVF9NT0RFTF9DTElFTlRfQ0FDSEVfVFRMX01TIH0gZnJvbSBcIi4vc3JjL21vZGVsLWNsaWVudC50c1wiO1xuZXhwb3J0IHR5cGUgeyBNb2RlbEF1dGhPcHRpb25zLCBNb2RlbENsaWVudE9wdGlvbnMsIE1vZGVsQ2xpZW50U3RhdHVzLCBNb2RlbFByb3RvY29sLCBNb2RlbFJvdXRlSW5wdXQsIE1vZGVsUm91dGUsIE1vZGVsQ2xpZW50IH0gZnJvbSBcIi4vc3JjL21vZGVsLWNsaWVudC50c1wiO1xuZXhwb3J0IHsgTW9kZWxGYW1pbHkgfSBmcm9tIFwiLi9zcmMvcG9saWN5LnRzXCI7XG5leHBvcnQgeyBSRUFTT05JTkdfTEVWRUxTIH0gZnJvbSBcIi4vc3JjL3JlYXNvbmluZy10cmFuc2xhdGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBSZWFzb25pbmdMZXZlbCwgUmVhc29uaW5nTW9kZWxDYXRhbG9ndWUsIEFkYXB0ZWRSZXF1ZXN0UmVhc29uaW5nIH0gZnJvbSBcIi4vc3JjL3JlYXNvbmluZy10cmFuc2xhdGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBTZWxlY3RNb2RlbElucHV0LCBTZWFyY2hNb2RlbHNJbnB1dCB9IGZyb20gXCIuL3NyYy9yZXNvbHZlLnRzXCI7XG5leHBvcnQgdHlwZSB7IFNlcnZpbmdDaGF0TWVzc2FnZSwgUmV3cml0dGVuU2VydmluZ1JlcXVlc3QgfSBmcm9tIFwiLi9zcmMvc2VydmluZy13aXJlLnRzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9leHBvcnRzLnRzXCI7XG4iXX0=
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztBQUNyRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxhQUFhLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxLQUFLLFlBQVksTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEtBQUssV0FBVyxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLG9CQUFvQixNQUFNLGdDQUFnQyxDQUFDO0FBQ3ZFLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLHNCQUFzQixFQUFFLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxxQkFBcUIsRUFBRSwrQkFBK0IsRUFBRSxtQkFBbUIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXhOLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxxQkFBcUIsRUFBRSwyQkFBMkIsRUFBRSx1QkFBdUIsRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWxMLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTdGLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUdsRSxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvbW9kZWxcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuOS4xMDZcIjtcbmV4cG9ydCAqIGFzIGJpbmRpbmdzIGZyb20gXCIuL3NyYy9iaW5kaW5ncy50c1wiO1xuZXhwb3J0ICogYXMgY2xhc3NlcyBmcm9tIFwiLi9zcmMvY2xhc3Nlcy50c1wiO1xuZXhwb3J0ICogYXMgY2xhc3NpZnkgZnJvbSBcIi4vc3JjL2NsYXNzaWZ5LnRzXCI7XG5leHBvcnQgKiBhcyBmYWxsYmFjayBmcm9tIFwiLi9zcmMvZmFsbGJhY2sudHNcIjtcbmV4cG9ydCAqIGFzIGludm9rZSBmcm9tIFwiLi9zcmMvaW52b2tlLnRzXCI7XG5leHBvcnQgKiBhcyBtZXRhZGF0YSBmcm9tIFwiLi9zcmMvbWV0YWRhdGEudHNcIjtcbmV4cG9ydCAqIGFzIG1ldGFkYXRhQ2FjaGUgZnJvbSBcIi4vc3JjL21ldGFkYXRhLWNhY2hlLnRzXCI7XG5leHBvcnQgKiBhcyBtb2RlbENhdGFsb2cgZnJvbSBcIi4vc3JjL21vZGVsLWNhdGFsb2cudHNcIjtcbmV4cG9ydCAqIGFzIG1vZGVsQ2xpZW50IGZyb20gXCIuL3NyYy9tb2RlbC1jbGllbnQudHNcIjtcbmV4cG9ydCAqIGFzIHBvbGljeSBmcm9tIFwiLi9zcmMvcG9saWN5LnRzXCI7XG5leHBvcnQgKiBhcyByZWFzb25pbmdUcmFuc2xhdGlvbiBmcm9tIFwiLi9zcmMvcmVhc29uaW5nLXRyYW5zbGF0aW9uLnRzXCI7XG5leHBvcnQgKiBhcyByZXNvbHZlIGZyb20gXCIuL3NyYy9yZXNvbHZlLnRzXCI7XG5leHBvcnQgeyBDSEFUX0NMQVNTX09SREVSLCBNT0RFTF9DTEFTU19PUkRFUiB9IGZyb20gXCIuL3NyYy9jbGFzc2VzLnRzXCI7XG5leHBvcnQgeyBGQUxMQkFDS19NT0RFTF9JRFMgfSBmcm9tIFwiLi9zcmMvZmFsbGJhY2sudHNcIjtcbmV4cG9ydCB7IElOVk9DQVRJT05TX1NVRkZJWCwgU0VSVklOR19FTkRQT0lOVFNfUEFUSCwgUkVTUE9OU0VTX1BBVEgsIE9QRU5fUkVTUE9OU0VTX1BBVEgsIENIQVRfQ09NUExFVElPTlNfUEFUSCwgQUlfR0FURVdBWV9DT0RFWF9SRVNQT05TRVNfUEFUSCwgQU5USFJPUElDX0JBU0VfUEFUSCwgQU5USFJPUElDX01FU1NBR0VTX1BBVEggfSBmcm9tIFwiLi9zcmMvaW52b2tlLnRzXCI7XG5leHBvcnQgdHlwZSB7IEF1dGhlbnRpY2F0aW5nQ2xpZW50TGlrZSB9IGZyb20gXCIuL3NyYy9pbnZva2UudHNcIjtcbmV4cG9ydCB7IE1PREVMX01FVEFEQVRBX1RUTF9NUywgTU9ERUxfUkFURV9MSU1JVFNfVVJMLCBPUEVOQUlfUkVTUE9OU0VTX01PREVMU19VUkwsIFFVRVJZX1JFQVNPTl9NT0RFTFNfVVJMLCBSRVRJUkVEX01PREVMU19VUkwsIFdFQl9TRUFSQ0hfTU9ERUxTX1VSTCB9IGZyb20gXCIuL3NyYy9tZXRhZGF0YS50c1wiO1xuZXhwb3J0IHR5cGUgeyBNZXRhZGF0YUNhY2hlUmVjb3JkLCBNZXRhZGF0YUNhY2hlT3B0aW9ucywgTWV0YWRhdGFDYWNoZU1lcmdlSW5wdXQsIE1ldGFkYXRhQ2FjaGUgfSBmcm9tIFwiLi9zcmMvbWV0YWRhdGEtY2FjaGUudHNcIjtcbmV4cG9ydCB7IERFRkFVTFRfTU9ERUxfQ0FDSEVfVFRMX01TLCBERUZBVUxUX0ZVWlpZX1RIUkVTSE9MRCB9IGZyb20gXCIuL3NyYy9tb2RlbC1jYXRhbG9nLnRzXCI7XG5leHBvcnQgdHlwZSB7IFdvcmtzcGFjZUNsaWVudExpa2UsIExpc3RTZXJ2aW5nRW5kcG9pbnRzT3B0aW9ucyB9IGZyb20gXCIuL3NyYy9tb2RlbC1jYXRhbG9nLnRzXCI7XG5leHBvcnQgeyBERUZBVUxUX01PREVMX0NMSUVOVF9DQUNIRV9UVExfTVMgfSBmcm9tIFwiLi9zcmMvbW9kZWwtY2xpZW50LnRzXCI7XG5leHBvcnQgdHlwZSB7IE1vZGVsQXV0aE9wdGlvbnMsIE1vZGVsQ2xpZW50T3B0aW9ucywgTW9kZWxDbGllbnRTdGF0dXMsIE1vZGVsUHJvdG9jb2wsIE1vZGVsUm91dGVJbnB1dCwgTW9kZWxSb3V0ZSwgTW9kZWxDbGllbnQgfSBmcm9tIFwiLi9zcmMvbW9kZWwtY2xpZW50LnRzXCI7XG5leHBvcnQgeyBNb2RlbEZhbWlseSB9IGZyb20gXCIuL3NyYy9wb2xpY3kudHNcIjtcbmV4cG9ydCB7IFJFQVNPTklOR19MRVZFTFMgfSBmcm9tIFwiLi9zcmMvcmVhc29uaW5nLXRyYW5zbGF0aW9uLnRzXCI7XG5leHBvcnQgdHlwZSB7IFJlYXNvbmluZ0xldmVsLCBSZWFzb25pbmdNb2RlbENhdGFsb2d1ZSwgQWRhcHRlZFJlcXVlc3RSZWFzb25pbmcgfSBmcm9tIFwiLi9zcmMvcmVhc29uaW5nLXRyYW5zbGF0aW9uLnRzXCI7XG5leHBvcnQgdHlwZSB7IFNlbGVjdE1vZGVsSW5wdXQsIFNlYXJjaE1vZGVsc0lucHV0IH0gZnJvbSBcIi4vc3JjL3Jlc29sdmUudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2V4cG9ydHMudHNcIjtcbiJdfQ==
package/lib/package.json CHANGED
@@ -95,14 +95,10 @@
95
95
  "types": "./lib/src/resolve.d.ts",
96
96
  "default": "./lib/src/resolve.js"
97
97
  },
98
- "./serving-wire": {
99
- "types": "./lib/src/serving-wire.d.ts",
100
- "default": "./lib/src/serving-wire.js"
101
- },
102
98
  "./package.json": "./package.json"
103
99
  }
104
100
  },
105
- "version": "0.9.99",
101
+ "version": "0.9.106",
106
102
  "types": "index.ts",
107
103
  "dbxToolsConfig": {
108
104
  "tags": [
@@ -124,7 +120,6 @@
124
120
  "./policy": "./src/policy.ts",
125
121
  "./reasoning-translation": "./src/reasoning-translation.ts",
126
122
  "./resolve": "./src/resolve.ts",
127
- "./serving-wire": "./src/serving-wire.ts",
128
123
  "./package.json": "./package.json"
129
124
  },
130
125
  "files": [
@@ -24,6 +24,8 @@
24
24
  * models (notably Codex) reject this path and require {@link responsesUrl}.
25
25
  */
26
26
  export declare const INVOCATIONS_SUFFIX = "invocations";
27
+ /** Workspace Model Serving root path used by provider base URLs. */
28
+ export declare const SERVING_ENDPOINTS_PATH = "serving-endpoints";
27
29
  /**
28
30
  * Workspace-level OpenAI Responses API path. Body carries `model` (endpoint
29
31
  * id); used by GPT / Codex models that speak Responses natively.
@@ -43,8 +45,12 @@ export declare const OPEN_RESPONSES_PATH = "serving-endpoints/open-responses";
43
45
  export declare const CHAT_COMPLETIONS_PATH = "serving-endpoints/chat/completions";
44
46
  /** Unity Gateway OpenAI Responses path used by Codex-compatible model services. */
45
47
  export declare const AI_GATEWAY_CODEX_RESPONSES_PATH = "ai-gateway/codex/v1/responses";
48
+ /** Workspace Anthropic provider root path. */
49
+ export declare const ANTHROPIC_BASE_PATH = "serving-endpoints/anthropic/v1";
46
50
  /** Workspace Anthropic Messages path for native Claude requests. */
47
51
  export declare const ANTHROPIC_MESSAGES_PATH = "serving-endpoints/anthropic/v1/messages";
52
+ /** Workspace Model Serving root URL used by OpenAI-compatible providers. */
53
+ export declare function servingEndpointsUrl(host: string): string;
48
54
  /**
49
55
  * The OpenAI-compatible chat-completions invocations URL for an endpoint id.
50
56
  *
@@ -63,6 +69,8 @@ export declare function chatCompletionsUrl(host: string): string;
63
69
  export declare function aiGatewayCodexResponsesUrl(host: string): string;
64
70
  /** Workspace Anthropic Messages URL (`POST`, model in the body). */
65
71
  export declare function anthropicMessagesUrl(host: string): string;
72
+ /** Workspace Anthropic provider base URL used by AI SDK providers. */
73
+ export declare function anthropicBaseUrl(host: string): string;
66
74
  /**
67
75
  * True when the endpoint is known to reject Chat Completions `/invocations`
68
76
  * and require the Responses API (Codex models today). Callers should route
package/lib/src/invoke.js CHANGED
@@ -25,27 +25,35 @@ import { isResponsesOnly as isResponsesOnlyByPolicy } from "./policy.js";
25
25
  * models (notably Codex) reject this path and require {@link responsesUrl}.
26
26
  */
27
27
  export const INVOCATIONS_SUFFIX = "invocations";
28
+ /** Workspace Model Serving root path used by provider base URLs. */
29
+ export const SERVING_ENDPOINTS_PATH = "serving-endpoints";
28
30
  /**
29
31
  * Workspace-level OpenAI Responses API path. Body carries `model` (endpoint
30
32
  * id); used by GPT / Codex models that speak Responses natively.
31
33
  */
32
- export const RESPONSES_PATH = "serving-endpoints/responses";
34
+ export const RESPONSES_PATH = `${SERVING_ENDPOINTS_PATH}/responses`;
33
35
  /**
34
36
  * Workspace-level Open Responses API path - the cross-provider Responses
35
37
  * surface (Claude, Gemini, …) that OpenAI `/responses` does not cover.
36
38
  */
37
- export const OPEN_RESPONSES_PATH = "serving-endpoints/open-responses";
39
+ export const OPEN_RESPONSES_PATH = `${SERVING_ENDPOINTS_PATH}/open-responses`;
38
40
  /**
39
41
  * Workspace-level OpenAI Chat Completions path. Body carries `model` (endpoint
40
42
  * id), unlike {@link invocationsUrl} which names the endpoint in the URL. Use
41
43
  * this when the caller has a model id rather than a per-endpoint route - e.g.
42
44
  * attaching a provider tool spec to whichever endpoint was resolved.
43
45
  */
44
- export const CHAT_COMPLETIONS_PATH = "serving-endpoints/chat/completions";
46
+ export const CHAT_COMPLETIONS_PATH = `${SERVING_ENDPOINTS_PATH}/chat/completions`;
45
47
  /** Unity Gateway OpenAI Responses path used by Codex-compatible model services. */
46
48
  export const AI_GATEWAY_CODEX_RESPONSES_PATH = "ai-gateway/codex/v1/responses";
49
+ /** Workspace Anthropic provider root path. */
50
+ export const ANTHROPIC_BASE_PATH = `${SERVING_ENDPOINTS_PATH}/anthropic/v1`;
47
51
  /** Workspace Anthropic Messages path for native Claude requests. */
48
- export const ANTHROPIC_MESSAGES_PATH = "serving-endpoints/anthropic/v1/messages";
52
+ export const ANTHROPIC_MESSAGES_PATH = `${ANTHROPIC_BASE_PATH}/messages`;
53
+ /** Workspace Model Serving root URL used by OpenAI-compatible providers. */
54
+ export function servingEndpointsUrl(host) {
55
+ return new URL(SERVING_ENDPOINTS_PATH, host).toString().replace(/\/$/, "");
56
+ }
49
57
  /**
50
58
  * The OpenAI-compatible chat-completions invocations URL for an endpoint id.
51
59
  *
@@ -54,7 +62,7 @@ export const ANTHROPIC_MESSAGES_PATH = "serving-endpoints/anthropic/v1/messages"
54
62
  * @param endpoint - Endpoint id (already resolved; not fuzzy-matched here).
55
63
  */
56
64
  export function invocationsUrl(host, endpoint) {
57
- return new URL(`serving-endpoints/${encodeURIComponent(endpoint)}/${INVOCATIONS_SUFFIX}`, host).toString();
65
+ return new URL(`${SERVING_ENDPOINTS_PATH}/${encodeURIComponent(endpoint)}/${INVOCATIONS_SUFFIX}`, host).toString();
58
66
  }
59
67
  /** Workspace OpenAI Responses API URL (`POST`, model in the body). */
60
68
  export function responsesUrl(host) {
@@ -76,6 +84,10 @@ export function aiGatewayCodexResponsesUrl(host) {
76
84
  export function anthropicMessagesUrl(host) {
77
85
  return new URL(ANTHROPIC_MESSAGES_PATH, host).toString();
78
86
  }
87
+ /** Workspace Anthropic provider base URL used by AI SDK providers. */
88
+ export function anthropicBaseUrl(host) {
89
+ return new URL(ANTHROPIC_BASE_PATH, host).toString().replace(/\/$/, "");
90
+ }
79
91
  /**
80
92
  * True when the endpoint is known to reject Chat Completions `/invocations`
81
93
  * and require the Responses API (Codex models today). Callers should route
@@ -114,4 +126,4 @@ export async function authHeaders(client) {
114
126
  });
115
127
  return out;
116
128
  }
117
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52b2tlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludm9rZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLGVBQWUsSUFBSSx1QkFBdUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUV6RTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLGFBQWEsQ0FBQztBQUVoRDs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsNkJBQTZCLENBQUM7QUFFNUQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsa0NBQWtDLENBQUM7QUFFdEU7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxvQ0FBb0MsQ0FBQztBQUUxRSxtRkFBbUY7QUFDbkYsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQUcsK0JBQStCLENBQUM7QUFFL0Usb0VBQW9FO0FBQ3BFLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLHlDQUF5QyxDQUFDO0FBRWpGOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsSUFBWSxFQUFFLFFBQWdCO0lBQzNELE9BQU8sSUFBSSxHQUFHLENBQ1oscUJBQXFCLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxJQUFJLGtCQUFrQixFQUFFLEVBQ3pFLElBQUksQ0FDTCxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ2YsQ0FBQztBQUVELHNFQUFzRTtBQUN0RSxNQUFNLFVBQVUsWUFBWSxDQUFDLElBQVk7SUFDdkMsT0FBTyxJQUFJLEdBQUcsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDbEQsQ0FBQztBQUVELG9FQUFvRTtBQUNwRSxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsSUFBWTtJQUMzQyxPQUFPLElBQUksR0FBRyxDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ3ZELENBQUM7QUFFRCx5RUFBeUU7QUFDekUsTUFBTSxVQUFVLGtCQUFrQixDQUFDLElBQVk7SUFDN0MsT0FBTyxJQUFJLEdBQUcsQ0FBQyxxQkFBcUIsRUFBRSxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUN6RCxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxJQUFZO0lBQ3JELE9BQU8sSUFBSSxHQUFHLENBQUMsK0JBQStCLEVBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDbkUsQ0FBQztBQUVELG9FQUFvRTtBQUNwRSxNQUFNLFVBQVUsb0JBQW9CLENBQUMsSUFBWTtJQUMvQyxPQUFPLElBQUksR0FBRyxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQzNELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxRQUFnQjtJQUM5QyxPQUFPLHVCQUF1QixDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLElBQVksRUFBRSxRQUFnQjtJQUNqRSxPQUFPLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNoRixDQUFDO0FBRUQsK0VBQStFO0FBQy9FLFNBQVMsY0FBYyxDQUFDLFFBQWdCO0lBQ3RDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNqQyxPQUFPLENBQ0wsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDakIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7UUFDbkIsNEJBQTRCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNwQyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUNyQixDQUFDO0FBQ0osQ0FBQztBQWNEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFdBQVcsQ0FDL0IsTUFBZ0M7SUFFaEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztJQUM5QixNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFDLE1BQU0sR0FBRyxHQUEyQixFQUFFLENBQUM7SUFDdkMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUM3QixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ25CLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDYWxsaW5nIGEgTW9kZWwgU2VydmluZyBlbmRwb2ludCBkaXJlY3RseSBvdmVyIEhUVFAuXG4gKlxuICogVGhlIFNESydzIGBzZXJ2aW5nRW5kcG9pbnRzLnF1ZXJ5YCBjb3ZlcnMgdGhlIHR5cGVkIHJlcXVlc3Qgc2hhcGVzLCBidXQgYW5cbiAqIE9wZW5BSS1jb21wYXRpYmxlIGNhbGxlciAoYSBwcm94eSwgYSBwYXNzdGhyb3VnaCByb3V0ZSwgYSBzdHJlYW1pbmcgY2xpZW50KVxuICogbmVlZHMgdG8gaXNzdWUgaXRzIG93biBgZmV0Y2hgIGFnYWluc3QgRGF0YWJyaWNrcycgT3BlbkFJLXNoYXBlZCBVUkxzIHdpdGhcbiAqIGFuIE9wZW5BSSBib2R5LiBUaGF0IG5lZWRzIGV4YWN0bHkgdHdvIHRoaW5ncyB0aGUgU0RLIGRvZXNuJ3QgaGFuZCBvdXRcbiAqIGRpcmVjdGx5OiB0aGUgVVJMICh7QGxpbmsgaW52b2NhdGlvbnNVcmx9IC8ge0BsaW5rIHJlc3BvbnNlc1VybH0gL1xuICoge0BsaW5rIG9wZW5SZXNwb25zZXNVcmx9KSBhbmQgYSBjdXJyZW50bHktdmFsaWQgc2V0IG9mIGF1dGggaGVhZGVyc1xuICogKHtAbGluayBhdXRoSGVhZGVyc30pLlxuICpcbiAqIEF1dGggaXMgZGVsZWdhdGVkIGVudGlyZWx5IHRvIHRoZSBEYXRhYnJpY2tzIFNESzogYGNvbmZpZy5hdXRoZW50aWNhdGVgXG4gKiByZS1ydW5zIHRoZSBjb25maWd1cmVkIGNyZWRlbnRpYWwgcHJvdmlkZXIgb24gZXZlcnkgY2FsbCBhbmQgcmVmcmVzaGVzIHRoZVxuICogdW5kZXJseWluZyBPQXV0aCAvIFBBVCB0b2tlbiB3aGVuIGl0IGlzIGNsb3NlIHRvIGV4cGlyeSwgc28gYSBjYWxsZXIgbmV2ZXJcbiAqIG1hbmFnZXMgdG9rZW4gbGlmZXRpbWVzIGl0c2VsZiAtIG1pbnQgaGVhZGVycyBwZXIgcmVxdWVzdCBhbmQgZWFjaCBvbmUgaXNcbiAqIHNpZ25lZCB3aXRoIGEgdmFsaWQgYmVhcmVyIHRva2VuLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBpc1Jlc3BvbnNlc09ubHkgYXMgaXNSZXNwb25zZXNPbmx5QnlQb2xpY3kgfSBmcm9tIFwiLi9wb2xpY3kudHNcIjtcblxuLyoqXG4gKiBQYXRoIHNlZ21lbnQgYXBwZW5kZWQgdG8gYSBzZXJ2aW5nIGVuZHBvaW50IGZvciBPcGVuQUktY29tcGF0aWJsZSBjaGF0XG4gKiByZXF1ZXN0cy4gRGF0YWJyaWNrcyByb3V0ZXMgYC9zZXJ2aW5nLWVuZHBvaW50cy88bmFtZT4vaW52b2NhdGlvbnNgIHRvIHRoZVxuICogZW5kcG9pbnQncyBDaGF0IENvbXBsZXRpb25zIHN1cmZhY2UgKGBtZXNzYWdlc2AgaW4sIGBjaG9pY2VzYCBvdXQpLiBTb21lXG4gKiBtb2RlbHMgKG5vdGFibHkgQ29kZXgpIHJlamVjdCB0aGlzIHBhdGggYW5kIHJlcXVpcmUge0BsaW5rIHJlc3BvbnNlc1VybH0uXG4gKi9cbmV4cG9ydCBjb25zdCBJTlZPQ0FUSU9OU19TVUZGSVggPSBcImludm9jYXRpb25zXCI7XG5cbi8qKlxuICogV29ya3NwYWNlLWxldmVsIE9wZW5BSSBSZXNwb25zZXMgQVBJIHBhdGguIEJvZHkgY2FycmllcyBgbW9kZWxgIChlbmRwb2ludFxuICogaWQpOyB1c2VkIGJ5IEdQVCAvIENvZGV4IG1vZGVscyB0aGF0IHNwZWFrIFJlc3BvbnNlcyBuYXRpdmVseS5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFU1BPTlNFU19QQVRIID0gXCJzZXJ2aW5nLWVuZHBvaW50cy9yZXNwb25zZXNcIjtcblxuLyoqXG4gKiBXb3Jrc3BhY2UtbGV2ZWwgT3BlbiBSZXNwb25zZXMgQVBJIHBhdGggLSB0aGUgY3Jvc3MtcHJvdmlkZXIgUmVzcG9uc2VzXG4gKiBzdXJmYWNlIChDbGF1ZGUsIEdlbWluaSwg4oCmKSB0aGF0IE9wZW5BSSBgL3Jlc3BvbnNlc2AgZG9lcyBub3QgY292ZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBPUEVOX1JFU1BPTlNFU19QQVRIID0gXCJzZXJ2aW5nLWVuZHBvaW50cy9vcGVuLXJlc3BvbnNlc1wiO1xuXG4vKipcbiAqIFdvcmtzcGFjZS1sZXZlbCBPcGVuQUkgQ2hhdCBDb21wbGV0aW9ucyBwYXRoLiBCb2R5IGNhcnJpZXMgYG1vZGVsYCAoZW5kcG9pbnRcbiAqIGlkKSwgdW5saWtlIHtAbGluayBpbnZvY2F0aW9uc1VybH0gd2hpY2ggbmFtZXMgdGhlIGVuZHBvaW50IGluIHRoZSBVUkwuIFVzZVxuICogdGhpcyB3aGVuIHRoZSBjYWxsZXIgaGFzIGEgbW9kZWwgaWQgcmF0aGVyIHRoYW4gYSBwZXItZW5kcG9pbnQgcm91dGUgLSBlLmcuXG4gKiBhdHRhY2hpbmcgYSBwcm92aWRlciB0b29sIHNwZWMgdG8gd2hpY2hldmVyIGVuZHBvaW50IHdhcyByZXNvbHZlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IENIQVRfQ09NUExFVElPTlNfUEFUSCA9IFwic2VydmluZy1lbmRwb2ludHMvY2hhdC9jb21wbGV0aW9uc1wiO1xuXG4vKiogVW5pdHkgR2F0ZXdheSBPcGVuQUkgUmVzcG9uc2VzIHBhdGggdXNlZCBieSBDb2RleC1jb21wYXRpYmxlIG1vZGVsIHNlcnZpY2VzLiAqL1xuZXhwb3J0IGNvbnN0IEFJX0dBVEVXQVlfQ09ERVhfUkVTUE9OU0VTX1BBVEggPSBcImFpLWdhdGV3YXkvY29kZXgvdjEvcmVzcG9uc2VzXCI7XG5cbi8qKiBXb3Jrc3BhY2UgQW50aHJvcGljIE1lc3NhZ2VzIHBhdGggZm9yIG5hdGl2ZSBDbGF1ZGUgcmVxdWVzdHMuICovXG5leHBvcnQgY29uc3QgQU5USFJPUElDX01FU1NBR0VTX1BBVEggPSBcInNlcnZpbmctZW5kcG9pbnRzL2FudGhyb3BpYy92MS9tZXNzYWdlc1wiO1xuXG4vKipcbiAqIFRoZSBPcGVuQUktY29tcGF0aWJsZSBjaGF0LWNvbXBsZXRpb25zIGludm9jYXRpb25zIFVSTCBmb3IgYW4gZW5kcG9pbnQgaWQuXG4gKlxuICogQHBhcmFtIGhvc3QgLSBXb3Jrc3BhY2UgaG9zdCwgZS5nLiBgaHR0cHM6Ly9teS13b3Jrc3BhY2UuY2xvdWQuZGF0YWJyaWNrcy5jb20vYC5cbiAqICAgUGFzcyB0aGUgdmFsdWUgcmVzb2x2ZWQgZnJvbSBgY2xpZW50LmNvbmZpZy5nZXRIb3N0KClgLlxuICogQHBhcmFtIGVuZHBvaW50IC0gRW5kcG9pbnQgaWQgKGFscmVhZHkgcmVzb2x2ZWQ7IG5vdCBmdXp6eS1tYXRjaGVkIGhlcmUpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW52b2NhdGlvbnNVcmwoaG9zdDogc3RyaW5nLCBlbmRwb2ludDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldyBVUkwoXG4gICAgYHNlcnZpbmctZW5kcG9pbnRzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGVuZHBvaW50KX0vJHtJTlZPQ0FUSU9OU19TVUZGSVh9YCxcbiAgICBob3N0LFxuICApLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBXb3Jrc3BhY2UgT3BlbkFJIFJlc3BvbnNlcyBBUEkgVVJMIChgUE9TVGAsIG1vZGVsIGluIHRoZSBib2R5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNwb25zZXNVcmwoaG9zdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldyBVUkwoUkVTUE9OU0VTX1BBVEgsIGhvc3QpLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBXb3Jrc3BhY2UgT3BlbiBSZXNwb25zZXMgQVBJIFVSTCAoYFBPU1RgLCBtb2RlbCBpbiB0aGUgYm9keSkuICovXG5leHBvcnQgZnVuY3Rpb24gb3BlblJlc3BvbnNlc1VybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChPUEVOX1JFU1BPTlNFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKiogV29ya3NwYWNlIE9wZW5BSSBDaGF0IENvbXBsZXRpb25zIFVSTCAoYFBPU1RgLCBtb2RlbCBpbiB0aGUgYm9keSkuICovXG5leHBvcnQgZnVuY3Rpb24gY2hhdENvbXBsZXRpb25zVXJsKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKENIQVRfQ09NUExFVElPTlNfUEFUSCwgaG9zdCkudG9TdHJpbmcoKTtcbn1cblxuLyoqIFVuaXR5IEdhdGV3YXkgQ29kZXggUmVzcG9uc2VzIFVSTCAoYFBPU1RgLCBtb2RlbCBzZXJ2aWNlIGluIHRoZSBib2R5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhaUdhdGV3YXlDb2RleFJlc3BvbnNlc1VybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChBSV9HQVRFV0FZX0NPREVYX1JFU1BPTlNFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKiogV29ya3NwYWNlIEFudGhyb3BpYyBNZXNzYWdlcyBVUkwgKGBQT1NUYCwgbW9kZWwgaW4gdGhlIGJvZHkpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFudGhyb3BpY01lc3NhZ2VzVXJsKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKEFOVEhST1BJQ19NRVNTQUdFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKipcbiAqIFRydWUgd2hlbiB0aGUgZW5kcG9pbnQgaXMga25vd24gdG8gcmVqZWN0IENoYXQgQ29tcGxldGlvbnMgYC9pbnZvY2F0aW9uc2BcbiAqIGFuZCByZXF1aXJlIHRoZSBSZXNwb25zZXMgQVBJIChDb2RleCBtb2RlbHMgdG9kYXkpLiBDYWxsZXJzIHNob3VsZCByb3V0ZVxuICogdGhvc2UgdG8ge0BsaW5rIHJlc3BvbnNlc1VybH0gaW5zdGVhZCBvZiB7QGxpbmsgaW52b2NhdGlvbnNVcmx9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNSZXNwb25zZXNPbmx5KGVuZHBvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGlzUmVzcG9uc2VzT25seUJ5UG9saWN5KGVuZHBvaW50KTtcbn1cblxuLyoqXG4gKiBQaWNrIHRoZSBEYXRhYnJpY2tzIFJlc3BvbnNlcyB1cHN0cmVhbSBmb3IgYW4gZW5kcG9pbnQgaWQ6IE9wZW5BSS1mYW1pbHlcbiAqIG1vZGVscyB1c2UgYC9zZXJ2aW5nLWVuZHBvaW50cy9yZXNwb25zZXNgOyBldmVyeXRoaW5nIGVsc2UgdXNlcyB0aGVcbiAqIGNyb3NzLXByb3ZpZGVyIGAvc2VydmluZy1lbmRwb2ludHMvb3Blbi1yZXNwb25zZXNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzcG9uc2VzVXBzdHJlYW1VcmwoaG9zdDogc3RyaW5nLCBlbmRwb2ludDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGlzT3BlbkFpRmFtaWx5KGVuZHBvaW50KSA/IHJlc3BvbnNlc1VybChob3N0KSA6IG9wZW5SZXNwb25zZXNVcmwoaG9zdCk7XG59XG5cbi8qKiBHUFQgLyBDb2RleCAvIG8tc2VyaWVzIHN0eWxlIGVuZHBvaW50IG5hbWVzIHRoYXQgc3BlYWsgT3BlbkFJIFJlc3BvbnNlcy4gKi9cbmZ1bmN0aW9uIGlzT3BlbkFpRmFtaWx5KGVuZHBvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgbiA9IGVuZHBvaW50LnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiAoXG4gICAgbi5pbmNsdWRlcyhcImdwdFwiKSB8fFxuICAgIG4uaW5jbHVkZXMoXCJjb2RleFwiKSB8fFxuICAgIC8oXnxbXmEtel0pb1sxLTldKFteYS16XXwkKS8udGVzdChuKSB8fFxuICAgIG4uaW5jbHVkZXMoXCJvcGVuYWlcIilcbiAgKTtcbn1cblxuLyoqXG4gKiBNaW5pbWFsIHN0cnVjdHVyYWwgc2hhcGUge0BsaW5rIGF1dGhIZWFkZXJzfSBuZWVkcy4gRGVjbGFyZWQgbmFycm93bHkgcmF0aGVyXG4gKiB0aGFuIGFzIGEgZnVsbCBgV29ya3NwYWNlQ2xpZW50TGlrZWAgc28gYSBjYWxsZXIgaG9sZGluZyBpdHMgb3duXG4gKiBgQGRhdGFicmlja3Mvc2RrLWV4cGVyaW1lbnRhbGAgYFdvcmtzcGFjZUNsaWVudGAgc2F0aXNmaWVzIGl0IHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoaWNoIFNESyB2ZXJzaW9uIHJlc29sdmVkIGluIGl0cyB0cmVlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhlbnRpY2F0aW5nQ2xpZW50TGlrZSB7XG4gIGNvbmZpZzoge1xuICAgIGF1dGhlbnRpY2F0ZShoZWFkZXJzOiBIZWFkZXJzKTogUHJvbWlzZTx2b2lkPjtcbiAgfTtcbn1cblxuLyoqXG4gKiBNaW50IGF1dGggaGVhZGVycyBmb3Igb25lIHVwc3RyZWFtIHJlcXVlc3QgYXMgYSBwbGFpbiBvYmplY3QsIHJlYWR5IHRvIHNwcmVhZFxuICogaW50byBhIGBmZXRjaGAgaW5pdC4gQ2FsbCBpdCBwZXIgcmVxdWVzdDogdGhlIFNESyByZWZyZXNoZXMgdGhlIHVuZGVybHlpbmdcbiAqIHRva2VuIHdoZW4gbmVlZGVkLCBzbyBhIGxvbmctbGl2ZWQgcHJvY2VzcyBuZXZlciBoYXMgdG8gdHJhY2sgZXhwaXJ5IGl0c2VsZi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGF1dGhIZWFkZXJzKFxuICBjbGllbnQ6IEF1dGhlbnRpY2F0aW5nQ2xpZW50TGlrZSxcbik6IFByb21pc2U8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4ge1xuICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgYXdhaXQgY2xpZW50LmNvbmZpZy5hdXRoZW50aWNhdGUoaGVhZGVycyk7XG4gIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBoZWFkZXJzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICBvdXRba2V5XSA9IHZhbHVlO1xuICB9KTtcbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ==
129
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52b2tlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludm9rZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLGVBQWUsSUFBSSx1QkFBdUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUV6RTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLGFBQWEsQ0FBQztBQUVoRCxvRUFBb0U7QUFDcEUsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsbUJBQW1CLENBQUM7QUFFMUQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLEdBQUcsc0JBQXNCLFlBQVksQ0FBQztBQUVwRTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxHQUFHLHNCQUFzQixpQkFBaUIsQ0FBQztBQUU5RTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLEdBQUcsc0JBQXNCLG1CQUFtQixDQUFDO0FBRWxGLG1GQUFtRjtBQUNuRixNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBRywrQkFBK0IsQ0FBQztBQUUvRSw4Q0FBOEM7QUFDOUMsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxzQkFBc0IsZUFBZSxDQUFDO0FBRTVFLG9FQUFvRTtBQUNwRSxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLG1CQUFtQixXQUFXLENBQUM7QUFFekUsNEVBQTRFO0FBQzVFLE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxJQUFZO0lBQzlDLE9BQU8sSUFBSSxHQUFHLENBQUMsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM3RSxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxJ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LyoqXG4gKiBDYWxsaW5nIGEgTW9kZWwgU2VydmluZyBlbmRwb2ludCBkaXJlY3RseSBvdmVyIEhUVFAuXG4gKlxuICogVGhlIFNESydzIGBzZXJ2aW5nRW5kcG9pbnRzLnF1ZXJ5YCBjb3ZlcnMgdGhlIHR5cGVkIHJlcXVlc3Qgc2hhcGVzLCBidXQgYW5cbiAqIE9wZW5BSS1jb21wYXRpYmxlIGNhbGxlciAoYSBwcm94eSwgYSBwYXNzdGhyb3VnaCByb3V0ZSwgYSBzdHJlYW1pbmcgY2xpZW50KVxuICogbmVlZHMgdG8gaXNzdWUgaXRzIG93biBgZmV0Y2hgIGFnYWluc3QgRGF0YWJyaWNrcycgT3BlbkFJLXNoYXBlZCBVUkxzIHdpdGhcbiAqIGFuIE9wZW5BSSBib2R5LiBUaGF0IG5lZWRzIGV4YWN0bHkgdHdvIHRoaW5ncyB0aGUgU0RLIGRvZXNuJ3QgaGFuZCBvdXRcbiAqIGRpcmVjdGx5OiB0aGUgVVJMICh7QGxpbmsgaW52b2NhdGlvbnNVcmx9IC8ge0BsaW5rIHJlc3BvbnNlc1VybH0gL1xuICoge0BsaW5rIG9wZW5SZXNwb25zZXNVcmx9KSBhbmQgYSBjdXJyZW50bHktdmFsaWQgc2V0IG9mIGF1dGggaGVhZGVyc1xuICogKHtAbGluayBhdXRoSGVhZGVyc30pLlxuICpcbiAqIEF1dGggaXMgZGVsZWdhdGVkIGVudGlyZWx5IHRvIHRoZSBEYXRhYnJpY2tzIFNESzogYGNvbmZpZy5hdXRoZW50aWNhdGVgXG4gKiByZS1ydW5zIHRoZSBjb25maWd1cmVkIGNyZWRlbnRpYWwgcHJvdmlkZXIgb24gZXZlcnkgY2FsbCBhbmQgcmVmcmVzaGVzIHRoZVxuICogdW5kZXJseWluZyBPQXV0aCAvIFBBVCB0b2tlbiB3aGVuIGl0IGlzIGNsb3NlIHRvIGV4cGlyeSwgc28gYSBjYWxsZXIgbmV2ZXJcbiAqIG1hbmFnZXMgdG9rZW4gbGlmZXRpbWVzIGl0c2VsZiAtIG1pbnQgaGVhZGVycyBwZXIgcmVxdWVzdCBhbmQgZWFjaCBvbmUgaXNcbiAqIHNpZ25lZCB3aXRoIGEgdmFsaWQgYmVhcmVyIHRva2VuLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBpc1Jlc3BvbnNlc09ubHkgYXMgaXNSZXNwb25zZXNPbmx5QnlQb2xpY3kgfSBmcm9tIFwiLi9wb2xpY3kudHNcIjtcblxuLyoqXG4gKiBQYXRoIHNlZ21lbnQgYXBwZW5kZWQgdG8gYSBzZXJ2aW5nIGVuZHBvaW50IGZvciBPcGVuQUktY29tcGF0aWJsZSBjaGF0XG4gKiByZXF1ZXN0cy4gRGF0YWJyaWNrcyByb3V0ZXMgYC9zZXJ2aW5nLWVuZHBvaW50cy88bmFtZT4vaW52b2NhdGlvbnNgIHRvIHRoZVxuICogZW5kcG9pbnQncyBDaGF0IENvbXBsZXRpb25zIHN1cmZhY2UgKGBtZXNzYWdlc2AgaW4sIGBjaG9pY2VzYCBvdXQpLiBTb21lXG4gKiBtb2RlbHMgKG5vdGFibHkgQ29kZXgpIHJlamVjdCB0aGlzIHBhdGggYW5kIHJlcXVpcmUge0BsaW5rIHJlc3BvbnNlc1VybH0uXG4gKi9cbmV4cG9ydCBjb25zdCBJTlZPQ0FUSU9OU19TVUZGSVggPSBcImludm9jYXRpb25zXCI7XG5cbi8qKiBXb3Jrc3BhY2UgTW9kZWwgU2VydmluZyByb290IHBhdGggdXNlZCBieSBwcm92aWRlciBiYXNlIFVSTHMuICovXG5leHBvcnQgY29uc3QgU0VSVklOR19FTkRQT0lOVFNfUEFUSCA9IFwic2VydmluZy1lbmRwb2ludHNcIjtcblxuLyoqXG4gKiBXb3Jrc3BhY2UtbGV2ZWwgT3BlbkFJIFJlc3BvbnNlcyBBUEkgcGF0aC4gQm9keSBjYXJyaWVzIGBtb2RlbGAgKGVuZHBvaW50XG4gKiBpZCk7IHVzZWQgYnkgR1BUIC8gQ29kZXggbW9kZWxzIHRoYXQgc3BlYWsgUmVzcG9uc2VzIG5hdGl2ZWx5LlxuICovXG5leHBvcnQgY29uc3QgUkVTUE9OU0VTX1BBVEggPSBgJHtTRVJWSU5HX0VORFBPSU5UU19QQVRIfS9yZXNwb25zZXNgO1xuXG4vKipcbiAqIFdvcmtzcGFjZS1sZXZlbCBPcGVuIFJlc3BvbnNlcyBBUEkgcGF0aCAtIHRoZSBjcm9zcy1wcm92aWRlciBSZXNwb25zZXNcbiAqIHN1cmZhY2UgKENsYXVkZSwgR2VtaW5pLCDigKYpIHRoYXQgT3BlbkFJIGAvcmVzcG9uc2VzYCBkb2VzIG5vdCBjb3Zlci5cbiAqL1xuZXhwb3J0IGNvbnN0IE9QRU5fUkVTUE9OU0VTX1BBVEggPSBgJHtTRVJWSU5HX0VORFBPSU5UU19QQVRIfS9vcGVuLXJlc3BvbnNlc2A7XG5cbi8qKlxuICogV29ya3NwYWNlLWxldmVsIE9wZW5BSSBDaGF0IENvbXBsZXRpb25zIHBhdGguIEJvZHkgY2FycmllcyBgbW9kZWxgIChlbmRwb2ludFxuICogaWQpLCB1bmxpa2Uge0BsaW5rIGludm9jYXRpb25zVXJsfSB3aGljaCBuYW1lcyB0aGUgZW5kcG9pbnQgaW4gdGhlIFVSTC4gVXNlXG4gKiB0aGlzIHdoZW4gdGhlIGNhbGxlciBoYXMgYSBtb2RlbCBpZCByYXRoZXIgdGhhbiBhIHBlci1lbmRwb2ludCByb3V0ZSAtIGUuZy5cbiAqIGF0dGFjaGluZyBhIHByb3ZpZGVyIHRvb2wgc3BlYyB0byB3aGljaGV2ZXIgZW5kcG9pbnQgd2FzIHJlc29sdmVkLlxuICovXG5leHBvcnQgY29uc3QgQ0hBVF9DT01QTEVUSU9OU19QQVRIID0gYCR7U0VSVklOR19FTkRQT0lOVFNfUEFUSH0vY2hhdC9jb21wbGV0aW9uc2A7XG5cbi8qKiBVbml0eSBHYXRld2F5IE9wZW5BSSBSZXNwb25zZXMgcGF0aCB1c2VkIGJ5IENvZGV4LWNvbXBhdGlibGUgbW9kZWwgc2VydmljZXMuICovXG5leHBvcnQgY29uc3QgQUlfR0FURVdBWV9DT0RFWF9SRVNQT05TRVNfUEFUSCA9IFwiYWktZ2F0ZXdheS9jb2RleC92MS9yZXNwb25zZXNcIjtcblxuLyoqIFdvcmtzcGFjZSBBbnRocm9waWMgcHJvdmlkZXIgcm9vdCBwYXRoLiAqL1xuZXhwb3J0IGNvbnN0IEFOVEhST1BJQ19CQVNFX1BBVEggPSBgJHtTRVJWSU5HX0VORFBPSU5UU19QQVRIfS9hbnRocm9waWMvdjFgO1xuXG4vKiogV29ya3NwYWNlIEFudGhyb3BpYyBNZXNzYWdlcyBwYXRoIGZvciBuYXRpdmUgQ2xhdWRlIHJlcXVlc3RzLiAqL1xuZXhwb3J0IGNvbnN0IEFOVEhST1BJQ19NRVNTQUdFU19QQVRIID0gYCR7QU5USFJPUElDX0JBU0VfUEFUSH0vbWVzc2FnZXNgO1xuXG4vKiogV29ya3NwYWNlIE1vZGVsIFNlcnZpbmcgcm9vdCBVUkwgdXNlZCBieSBPcGVuQUktY29tcGF0aWJsZSBwcm92aWRlcnMuICovXG5leHBvcnQgZnVuY3Rpb24gc2VydmluZ0VuZHBvaW50c1VybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChTRVJWSU5HX0VORFBPSU5UU19QQVRILCBob3N0KS50b1N0cmluZygpLnJlcGxhY2UoL1xcLyQvLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBUaGUgT3BlbkFJLWNvbXBhdGlibGUgY2hhdC1jb21wbGV0aW9ucyBpbnZvY2F0aW9ucyBVUkwgZm9yIGFuIGVuZHBvaW50IGlkLlxuICpcbiAqIEBwYXJhbSBob3N0IC0gV29ya3NwYWNlIGhvc3QsIGUuZy4gYGh0dHBzOi8vbXktd29ya3NwYWNlLmNsb3VkLmRhdGFicmlja3MuY29tL2AuXG4gKiAgIFBhc3MgdGhlIHZhbHVlIHJlc29sdmVkIGZyb20gYGNsaWVudC5jb25maWcuZ2V0SG9zdCgpYC5cbiAqIEBwYXJhbSBlbmRwb2ludCAtIEVuZHBvaW50IGlkIChhbHJlYWR5IHJlc29sdmVkOyBub3QgZnV6enktbWF0Y2hlZCBoZXJlKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGludm9jYXRpb25zVXJsKGhvc3Q6IHN0cmluZywgZW5kcG9pbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKFxuICAgIGAke1NFUlZJTkdfRU5EUE9JTlRTX1BBVEh9LyR7ZW5jb2RlVVJJQ29tcG9uZW50KGVuZHBvaW50KX0vJHtJTlZPQ0FUSU9OU19TVUZGSVh9YCxcbiAgICBob3N0LFxuICApLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBXb3Jrc3BhY2UgT3BlbkFJIFJlc3BvbnNlcyBBUEkgVVJMIChgUE9TVGAsIG1vZGVsIGluIHRoZSBib2R5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNwb25zZXNVcmwoaG9zdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldyBVUkwoUkVTUE9OU0VTX1BBVEgsIGhvc3QpLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBXb3Jrc3BhY2UgT3BlbiBSZXNwb25zZXMgQVBJIFVSTCAoYFBPU1RgLCBtb2RlbCBpbiB0aGUgYm9keSkuICovXG5leHBvcnQgZnVuY3Rpb24gb3BlblJlc3BvbnNlc1VybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChPUEVOX1JFU1BPTlNFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKiogV29ya3NwYWNlIE9wZW5BSSBDaGF0IENvbXBsZXRpb25zIFVSTCAoYFBPU1RgLCBtb2RlbCBpbiB0aGUgYm9keSkuICovXG5leHBvcnQgZnVuY3Rpb24gY2hhdENvbXBsZXRpb25zVXJsKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKENIQVRfQ09NUExFVElPTlNfUEFUSCwgaG9zdCkudG9TdHJpbmcoKTtcbn1cblxuLyoqIFVuaXR5IEdhdGV3YXkgQ29kZXggUmVzcG9uc2VzIFVSTCAoYFBPU1RgLCBtb2RlbCBzZXJ2aWNlIGluIHRoZSBib2R5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhaUdhdGV3YXlDb2RleFJlc3BvbnNlc1VybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChBSV9HQVRFV0FZX0NPREVYX1JFU1BPTlNFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKiogV29ya3NwYWNlIEFudGhyb3BpYyBNZXNzYWdlcyBVUkwgKGBQT1NUYCwgbW9kZWwgaW4gdGhlIGJvZHkpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFudGhyb3BpY01lc3NhZ2VzVXJsKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKEFOVEhST1BJQ19NRVNTQUdFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKiogV29ya3NwYWNlIEFudGhyb3BpYyBwcm92aWRlciBiYXNlIFVSTCB1c2VkIGJ5IEFJIFNESyBwcm92aWRlcnMuICovXG5leHBvcnQgZnVuY3Rpb24gYW50aHJvcGljQmFzZVVybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChBTlRIUk9QSUNfQkFTRV9QQVRILCBob3N0KS50b1N0cmluZygpLnJlcGxhY2UoL1xcLyQvLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBUcnVlIHdoZW4gdGhlIGVuZHBvaW50IGlzIGtub3duIHRvIHJlamVjdCBDaGF0IENvbXBsZXRpb25zIGAvaW52b2NhdGlvbnNgXG4gKiBhbmQgcmVxdWlyZSB0aGUgUmVzcG9uc2VzIEFQSSAoQ29kZXggbW9kZWxzIHRvZGF5KS4gQ2FsbGVycyBzaG91bGQgcm91dGVcbiAqIHRob3NlIHRvIHtAbGluayByZXNwb25zZXNVcmx9IGluc3RlYWQgb2Yge0BsaW5rIGludm9jYXRpb25zVXJsfS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUmVzcG9uc2VzT25seShlbmRwb2ludDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBpc1Jlc3BvbnNlc09ubHlCeVBvbGljeShlbmRwb2ludCk7XG59XG5cbi8qKlxuICogUGljayB0aGUgRGF0YWJyaWNrcyBSZXNwb25zZXMgdXBzdHJlYW0gZm9yIGFuIGVuZHBvaW50IGlkOiBPcGVuQUktZmFtaWx5XG4gKiBtb2RlbHMgdXNlIGAvc2VydmluZy1lbmRwb2ludHMvcmVzcG9uc2VzYDsgZXZlcnl0aGluZyBlbHNlIHVzZXMgdGhlXG4gKiBjcm9zcy1wcm92aWRlciBgL3NlcnZpbmctZW5kcG9pbnRzL29wZW4tcmVzcG9uc2VzYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc3BvbnNlc1Vwc3RyZWFtVXJsKGhvc3Q6IHN0cmluZywgZW5kcG9pbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBpc09wZW5BaUZhbWlseShlbmRwb2ludCkgPyByZXNwb25zZXNVcmwoaG9zdCkgOiBvcGVuUmVzcG9uc2VzVXJsKGhvc3QpO1xufVxuXG4vKiogR1BUIC8gQ29kZXggLyBvLXNlcmllcyBzdHlsZSBlbmRwb2ludCBuYW1lcyB0aGF0IHNwZWFrIE9wZW5BSSBSZXNwb25zZXMuICovXG5mdW5jdGlvbiBpc09wZW5BaUZhbWlseShlbmRwb2ludDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG4gPSBlbmRwb2ludC50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gKFxuICAgIG4uaW5jbHVkZXMoXCJncHRcIikgfHxcbiAgICBuLmluY2x1ZGVzKFwiY29kZXhcIikgfHxcbiAgICAvKF58W15hLXpdKW9bMS05XShbXmEtel18JCkvLnRlc3QobikgfHxcbiAgICBuLmluY2x1ZGVzKFwib3BlbmFpXCIpXG4gICk7XG59XG5cbi8qKlxuICogTWluaW1hbCBzdHJ1Y3R1cmFsIHNoYXBlIHtAbGluayBhdXRoSGVhZGVyc30gbmVlZHMuIERlY2xhcmVkIG5hcnJvd2x5IHJhdGhlclxuICogdGhhbiBhcyBhIGZ1bGwgYFdvcmtzcGFjZUNsaWVudExpa2VgIHNvIGEgY2FsbGVyIGhvbGRpbmcgaXRzIG93blxuICogYEBkYXRhYnJpY2tzL3Nkay1leHBlcmltZW50YWxgIGBXb3Jrc3BhY2VDbGllbnRgIHNhdGlzZmllcyBpdCByZWdhcmRsZXNzIG9mXG4gKiB3aGljaCBTREsgdmVyc2lvbiByZXNvbHZlZCBpbiBpdHMgdHJlZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdXRoZW50aWNhdGluZ0NsaWVudExpa2Uge1xuICBjb25maWc6IHtcbiAgICBhdXRoZW50aWNhdGUoaGVhZGVyczogSGVhZGVycyk6IFByb21pc2U8dm9pZD47XG4gIH07XG59XG5cbi8qKlxuICogTWludCBhdXRoIGhlYWRlcnMgZm9yIG9uZSB1cHN0cmVhbSByZXF1ZXN0IGFzIGEgcGxhaW4gb2JqZWN0LCByZWFkeSB0byBzcHJlYWRcbiAqIGludG8gYSBgZmV0Y2hgIGluaXQuIENhbGwgaXQgcGVyIHJlcXVlc3Q6IHRoZSBTREsgcmVmcmVzaGVzIHRoZSB1bmRlcmx5aW5nXG4gKiB0b2tlbiB3aGVuIG5lZWRlZCwgc28gYSBsb25nLWxpdmVkIHByb2Nlc3MgbmV2ZXIgaGFzIHRvIHRyYWNrIGV4cGlyeSBpdHNlbGYuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhdXRoSGVhZGVycyhcbiAgY2xpZW50OiBBdXRoZW50aWNhdGluZ0NsaWVudExpa2UsXG4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+IHtcbiAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gIGF3YWl0IGNsaWVudC5jb25maWcuYXV0aGVudGljYXRlKGhlYWRlcnMpO1xuICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgaGVhZGVycy5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgb3V0W2tleV0gPSB2YWx1ZTtcbiAgfSk7XG4gIHJldHVybiBvdXQ7XG59XG4iXX0=
@@ -1 +1 @@
1
- {"root":["../src/_metadata-contract.ts","../src/_metadata-generator.ts","../src/_ranking.ts","../src/_retirement.ts","../src/_selection.ts","../src/bindings.ts","../src/classes.ts","../src/classify.ts","../src/fallback.ts","../src/invoke.ts","../src/metadata-cache.ts","../src/metadata.ts","../src/model-catalog.ts","../src/model-client.ts","../src/policy.ts","../src/reasoning-translation.ts","../src/resolve.ts","../src/serving-wire.ts","../scripts/generate-metadata.ts","../index.ts"],"version":"5.9.3"}
1
+ {"root":["../src/_metadata-contract.ts","../src/_metadata-generator.ts","../src/_ranking.ts","../src/_retirement.ts","../src/_selection.ts","../src/bindings.ts","../src/classes.ts","../src/classify.ts","../src/fallback.ts","../src/invoke.ts","../src/metadata-cache.ts","../src/metadata.ts","../src/model-catalog.ts","../src/model-client.ts","../src/policy.ts","../src/reasoning-translation.ts","../src/resolve.ts","../scripts/generate-metadata.ts","../index.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -26,11 +26,11 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@databricks/appkit": "0.81.0",
29
- "@dbx-tools/appkit": "^0.9.99",
30
- "@dbx-tools/auth": "^0.9.99",
31
- "@dbx-tools/shared-auth": "^0.9.99",
32
- "@dbx-tools/shared-core": "^0.9.99",
33
- "@dbx-tools/shared-model": "^0.9.99",
29
+ "@dbx-tools/appkit": "^0.9.106",
30
+ "@dbx-tools/auth": "^0.9.106",
31
+ "@dbx-tools/shared-auth": "^0.9.106",
32
+ "@dbx-tools/shared-core": "^0.9.106",
33
+ "@dbx-tools/shared-model": "^0.9.106",
34
34
  "cacache": "^21.0.1",
35
35
  "cheerio": "^1.2.0",
36
36
  "env-paths": "^4.0.0",
@@ -95,14 +95,10 @@
95
95
  "types": "./lib/src/resolve.d.ts",
96
96
  "default": "./lib/src/resolve.js"
97
97
  },
98
- "./serving-wire": {
99
- "types": "./lib/src/serving-wire.d.ts",
100
- "default": "./lib/src/serving-wire.js"
101
- },
102
98
  "./package.json": "./package.json"
103
99
  }
104
100
  },
105
- "version": "0.9.99",
101
+ "version": "0.9.106",
106
102
  "types": "./lib/index.d.ts",
107
103
  "dbxToolsConfig": {
108
104
  "tags": [
@@ -163,10 +159,6 @@
163
159
  "types": "./lib/src/resolve.d.ts",
164
160
  "default": "./lib/src/resolve.js"
165
161
  },
166
- "./serving-wire": {
167
- "types": "./lib/src/serving-wire.d.ts",
168
- "default": "./lib/src/serving-wire.js"
169
- },
170
162
  "./package.json": "./package.json"
171
163
  },
172
164
  "files": [
package/src/invoke.ts CHANGED
@@ -28,17 +28,20 @@ import { isResponsesOnly as isResponsesOnlyByPolicy } from "./policy.ts";
28
28
  */
29
29
  export const INVOCATIONS_SUFFIX = "invocations";
30
30
 
31
+ /** Workspace Model Serving root path used by provider base URLs. */
32
+ export const SERVING_ENDPOINTS_PATH = "serving-endpoints";
33
+
31
34
  /**
32
35
  * Workspace-level OpenAI Responses API path. Body carries `model` (endpoint
33
36
  * id); used by GPT / Codex models that speak Responses natively.
34
37
  */
35
- export const RESPONSES_PATH = "serving-endpoints/responses";
38
+ export const RESPONSES_PATH = `${SERVING_ENDPOINTS_PATH}/responses`;
36
39
 
37
40
  /**
38
41
  * Workspace-level Open Responses API path - the cross-provider Responses
39
42
  * surface (Claude, Gemini, …) that OpenAI `/responses` does not cover.
40
43
  */
41
- export const OPEN_RESPONSES_PATH = "serving-endpoints/open-responses";
44
+ export const OPEN_RESPONSES_PATH = `${SERVING_ENDPOINTS_PATH}/open-responses`;
42
45
 
43
46
  /**
44
47
  * Workspace-level OpenAI Chat Completions path. Body carries `model` (endpoint
@@ -46,13 +49,21 @@ export const OPEN_RESPONSES_PATH = "serving-endpoints/open-responses";
46
49
  * this when the caller has a model id rather than a per-endpoint route - e.g.
47
50
  * attaching a provider tool spec to whichever endpoint was resolved.
48
51
  */
49
- export const CHAT_COMPLETIONS_PATH = "serving-endpoints/chat/completions";
52
+ export const CHAT_COMPLETIONS_PATH = `${SERVING_ENDPOINTS_PATH}/chat/completions`;
50
53
 
51
54
  /** Unity Gateway OpenAI Responses path used by Codex-compatible model services. */
52
55
  export const AI_GATEWAY_CODEX_RESPONSES_PATH = "ai-gateway/codex/v1/responses";
53
56
 
57
+ /** Workspace Anthropic provider root path. */
58
+ export const ANTHROPIC_BASE_PATH = `${SERVING_ENDPOINTS_PATH}/anthropic/v1`;
59
+
54
60
  /** Workspace Anthropic Messages path for native Claude requests. */
55
- export const ANTHROPIC_MESSAGES_PATH = "serving-endpoints/anthropic/v1/messages";
61
+ export const ANTHROPIC_MESSAGES_PATH = `${ANTHROPIC_BASE_PATH}/messages`;
62
+
63
+ /** Workspace Model Serving root URL used by OpenAI-compatible providers. */
64
+ export function servingEndpointsUrl(host: string): string {
65
+ return new URL(SERVING_ENDPOINTS_PATH, host).toString().replace(/\/$/, "");
66
+ }
56
67
 
57
68
  /**
58
69
  * The OpenAI-compatible chat-completions invocations URL for an endpoint id.
@@ -63,7 +74,7 @@ export const ANTHROPIC_MESSAGES_PATH = "serving-endpoints/anthropic/v1/messages"
63
74
  */
64
75
  export function invocationsUrl(host: string, endpoint: string): string {
65
76
  return new URL(
66
- `serving-endpoints/${encodeURIComponent(endpoint)}/${INVOCATIONS_SUFFIX}`,
77
+ `${SERVING_ENDPOINTS_PATH}/${encodeURIComponent(endpoint)}/${INVOCATIONS_SUFFIX}`,
67
78
  host,
68
79
  ).toString();
69
80
  }
@@ -93,6 +104,11 @@ export function anthropicMessagesUrl(host: string): string {
93
104
  return new URL(ANTHROPIC_MESSAGES_PATH, host).toString();
94
105
  }
95
106
 
107
+ /** Workspace Anthropic provider base URL used by AI SDK providers. */
108
+ export function anthropicBaseUrl(host: string): string {
109
+ return new URL(ANTHROPIC_BASE_PATH, host).toString().replace(/\/$/, "");
110
+ }
111
+
96
112
  /**
97
113
  * True when the endpoint is known to reject Chat Completions `/invocations`
98
114
  * and require the Responses API (Codex models today). Callers should route
@@ -1,37 +0,0 @@
1
- /**
2
- * Framework-neutral repairs for OpenAI Chat traffic sent through Databricks
3
- * Model Serving.
4
- *
5
- * @module
6
- */
7
- import { type ChatMessage, type ChatRole } from "@dbx-tools/shared-model";
8
- /** Chat message plus provider reasoning fields emitted by Databricks models. */
9
- export interface ServingChatMessage extends ChatMessage {
10
- role: ChatRole | "reasoning";
11
- reasoning?: unknown;
12
- reasoning_content?: unknown;
13
- }
14
- /** Prepared fetch arguments and the sanitized request body. */
15
- export interface RewrittenServingRequest {
16
- input: Parameters<typeof fetch>[0];
17
- init: Parameters<typeof fetch>[1];
18
- body: string;
19
- }
20
- /** Sanitize a serialized Chat Completions request when provider quirks require it. */
21
- export declare function rewriteServingBody(body: string): string;
22
- /** Read and sanitize a Chat Completions request without retaining stale byte headers. */
23
- export declare function rewriteServingRequest(input: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]): Promise<RewrittenServingRequest>;
24
- /** Normalize Chat Completions reasoning for GPT tool calls. */
25
- export declare function applyToolReasoningCompatibility(body: Record<string, unknown>): boolean;
26
- /** Remove provider reasoning blocks that cannot be replayed safely. */
27
- export declare function stripReasoningFromServingMessages(messages: ServingChatMessage[]): boolean;
28
- /** Fold a trailing assistant prefill back into its preceding tool-call turn. */
29
- export declare function repairAssistantPrefill(messages: ServingChatMessage[]): boolean;
30
- /** Normalize array-valued content in a non-streaming Chat Completions response. */
31
- export declare function rewriteServingResponseBody(body: string): string;
32
- /** Normalize array-valued content in an SSE stream without buffering the stream. */
33
- export declare function rewriteServingResponseStream(body: ReadableStream<Uint8Array>): ReadableStream<Uint8Array>;
34
- /** Flatten Chat Completions `choices[].message.content` arrays to strings. */
35
- export declare function flattenChoiceMessageContent(payload: Record<string, unknown>): boolean;
36
- /** Flatten Chat Completions `choices[].delta.content` arrays to strings. */
37
- export declare function flattenChoiceDeltaContent(payload: Record<string, unknown>): boolean;
@@ -1,211 +0,0 @@
1
- /**
2
- * Framework-neutral repairs for OpenAI Chat traffic sent through Databricks
3
- * Model Serving.
4
- *
5
- * @module
6
- */
7
- import { json, stringUtils } from "@dbx-tools/shared-core";
8
- import { openaiChat } from "@dbx-tools/shared-model";
9
- import { chatToolReasoningEffort } from "./policy.js";
10
- const REASONING_PART_TYPES = new Set([
11
- "reasoning",
12
- "thinking",
13
- "redacted_thinking",
14
- ]);
15
- /** Sanitize a serialized Chat Completions request when provider quirks require it. */
16
- export function rewriteServingBody(body) {
17
- const parsed = json.parseRecord(body);
18
- if (!parsed)
19
- return body;
20
- let changed = openaiChat.stripUnsupportedChatFields(parsed).length > 0 ||
21
- applyToolReasoningCompatibility(parsed);
22
- if (Array.isArray(parsed.messages)) {
23
- const messages = parsed.messages;
24
- const stripped = stripReasoningFromServingMessages(messages);
25
- const repaired = repairAssistantPrefill(messages);
26
- changed = changed || stripped || repaired;
27
- }
28
- return changed ? JSON.stringify(parsed) : body;
29
- }
30
- /** Read and sanitize a Chat Completions request without retaining stale byte headers. */
31
- export async function rewriteServingRequest(input, init) {
32
- const request = new Request(input, init);
33
- const body = await request.clone().text();
34
- const rewritten = rewriteServingBody(body);
35
- if (rewritten === body)
36
- return { input, init, body };
37
- const headers = new Headers(request.headers);
38
- headers.delete("content-length");
39
- headers.delete("content-encoding");
40
- return {
41
- input: new Request(request, { body: rewritten, headers }),
42
- init: undefined,
43
- body: rewritten,
44
- };
45
- }
46
- /** Normalize Chat Completions reasoning for GPT tool calls. */
47
- export function applyToolReasoningCompatibility(body) {
48
- if (!Array.isArray(body.tools) || body.tools.length === 0)
49
- return false;
50
- const model = stringUtils.trimToNull(body.model);
51
- if (!model || chatToolReasoningEffort(model) !== "none")
52
- return false;
53
- if (body.reasoning_effort === "none")
54
- return false;
55
- body.reasoning_effort = "none";
56
- return true;
57
- }
58
- /** Remove provider reasoning blocks that cannot be replayed safely. */
59
- export function stripReasoningFromServingMessages(messages) {
60
- let changed = false;
61
- for (let index = messages.length - 1; index >= 0; index--) {
62
- const message = messages[index];
63
- if (!message)
64
- continue;
65
- if (message.role === "reasoning") {
66
- messages.splice(index, 1);
67
- changed = true;
68
- continue;
69
- }
70
- if (message.reasoning !== undefined) {
71
- delete message.reasoning;
72
- changed = true;
73
- }
74
- if (message.reasoning_content !== undefined) {
75
- delete message.reasoning_content;
76
- changed = true;
77
- }
78
- const parts = openaiChat.chatContentParts(message.content);
79
- if (!parts)
80
- continue;
81
- const filtered = parts.filter((part) => {
82
- const type = part?.type;
83
- if (typeof type !== "string" || !REASONING_PART_TYPES.has(type))
84
- return true;
85
- changed = true;
86
- return false;
87
- });
88
- if (filtered.length !== parts.length)
89
- message.content = filtered;
90
- const hasToolCalls = Array.isArray(message.tool_calls) && message.tool_calls.length > 0;
91
- if (message.role === "assistant" && !hasToolCalls && isEmptyServingContent(message.content)) {
92
- messages.splice(index, 1);
93
- changed = true;
94
- }
95
- }
96
- return changed;
97
- }
98
- /** Fold a trailing assistant prefill back into its preceding tool-call turn. */
99
- export function repairAssistantPrefill(messages) {
100
- if (messages.length < 2)
101
- return false;
102
- const last = messages[messages.length - 1];
103
- if (!last || last.role !== "assistant" || (last.tool_calls && last.tool_calls.length > 0)) {
104
- return false;
105
- }
106
- let index = messages.length - 2;
107
- while (index >= 0 && messages[index]?.role === "tool")
108
- index--;
109
- const opener = messages[index];
110
- if (!opener ||
111
- opener.role !== "assistant" ||
112
- !opener.tool_calls ||
113
- opener.tool_calls.length === 0) {
114
- return false;
115
- }
116
- opener.content = [
117
- stringUtils.trimToNull(textFromServingContent(opener.content)),
118
- stringUtils.trimToNull(textFromServingContent(last.content)),
119
- ]
120
- .filter((value) => value !== null)
121
- .join("\n\n");
122
- messages.pop();
123
- return true;
124
- }
125
- /** Normalize array-valued content in a non-streaming Chat Completions response. */
126
- export function rewriteServingResponseBody(body) {
127
- const parsed = json.parseRecord(body);
128
- if (!parsed)
129
- return body;
130
- return flattenChoiceMessageContent(parsed) ? JSON.stringify(parsed) : body;
131
- }
132
- /** Normalize array-valued content in an SSE stream without buffering the stream. */
133
- export function rewriteServingResponseStream(body) {
134
- const decoder = new TextDecoder();
135
- const encoder = new TextEncoder();
136
- let buffer = "";
137
- return body.pipeThrough(new TransformStream({
138
- transform(chunk, controller) {
139
- buffer += decoder.decode(chunk, { stream: true });
140
- let newline = buffer.indexOf("\n");
141
- while (newline >= 0) {
142
- const line = buffer.slice(0, newline + 1);
143
- buffer = buffer.slice(newline + 1);
144
- controller.enqueue(encoder.encode(rewriteServingResponseStreamLine(line)));
145
- newline = buffer.indexOf("\n");
146
- }
147
- },
148
- flush(controller) {
149
- buffer += decoder.decode();
150
- if (buffer)
151
- controller.enqueue(encoder.encode(rewriteServingResponseStreamLine(buffer)));
152
- },
153
- }));
154
- }
155
- /** Flatten Chat Completions `choices[].message.content` arrays to strings. */
156
- export function flattenChoiceMessageContent(payload) {
157
- return flattenChoiceContent(payload, "message");
158
- }
159
- /** Flatten Chat Completions `choices[].delta.content` arrays to strings. */
160
- export function flattenChoiceDeltaContent(payload) {
161
- return flattenChoiceContent(payload, "delta");
162
- }
163
- function rewriteServingResponseStreamLine(line) {
164
- const lineEnding = line.endsWith("\r\n") ? "\r\n" : line.endsWith("\n") ? "\n" : "";
165
- const content = lineEnding ? line.slice(0, -lineEnding.length) : line;
166
- const match = /^(data:\s*)(.*)$/.exec(content);
167
- if (!match || match[2] === "[DONE]")
168
- return line;
169
- const parsed = json.parseRecord(match[2]);
170
- if (!parsed || !flattenChoiceDeltaContent(parsed))
171
- return line;
172
- return `${match[1]}${JSON.stringify(parsed)}${lineEnding}`;
173
- }
174
- function flattenChoiceContent(payload, field) {
175
- if (!Array.isArray(payload.choices))
176
- return false;
177
- let changed = false;
178
- for (const choice of payload.choices) {
179
- if (!choice || typeof choice !== "object")
180
- continue;
181
- const container = choice[field];
182
- if (!container || typeof container !== "object")
183
- continue;
184
- const target = container;
185
- const parts = openaiChat.chatContentParts(target.content);
186
- if (!parts)
187
- continue;
188
- target.content = openaiChat.chatContentToText(parts, { types: ["text"] });
189
- changed = true;
190
- }
191
- return changed;
192
- }
193
- function textFromServingContent(content) {
194
- return openaiChat.chatContentToText(content, { separator: "\n\n", types: ["text"] });
195
- }
196
- function isEmptyServingContent(content) {
197
- if (content === undefined)
198
- return true;
199
- if (typeof content === "string")
200
- return content.trim().length === 0;
201
- const parts = openaiChat.chatContentParts(content);
202
- if (!parts)
203
- return true;
204
- return parts.every((part) => {
205
- if (part?.type === "text") {
206
- return typeof part.text !== "string" || part.text.trim().length === 0;
207
- }
208
- return false;
209
- });
210
- }
211
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmluZy13aXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpbmctd2lyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDM0QsT0FBTyxFQUFtQyxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV0RixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFnQnRELE1BQU0sb0JBQW9CLEdBQXdCLElBQUksR0FBRyxDQUFDO0lBQ3hELFdBQVc7SUFDWCxVQUFVO0lBQ1YsbUJBQW1CO0NBQ3BCLENBQUMsQ0FBQztBQUVILHNGQUFzRjtBQUN0RixNQUFNLFVBQVUsa0JBQWtCLENBQUMsSUFBWTtJQUM3QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDekIsSUFBSSxPQUFPLEdBQ1QsVUFBVSxDQUFDLDBCQUEwQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQ3hELCtCQUErQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUNuQyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBZ0MsQ0FBQztRQUN6RCxNQUFNLFFBQVEsR0FBRyxpQ0FBaUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3RCxNQUFNLFFBQVEsR0FBRyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNsRCxPQUFPLEdBQUcsT0FBTyxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUM7SUFDNUMsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDakQsQ0FBQztBQUVELHlGQUF5RjtBQUN6RixNQUFNLENBQUMsS0FBSyxVQUFVLHFCQUFxQixDQUN6QyxLQUFrQyxFQUNsQyxJQUFrQztJQUVsQyxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDekMsTUFBTSxJQUFJLEdBQUcsTUFBTSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDMUMsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0MsSUFBSSxTQUFTLEtBQUssSUFBSTtRQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ3JELE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QyxPQUFPLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDakMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ25DLE9BQU87UUFDTCxLQUFLLEVBQUUsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUN6RCxJQUFJLEVBQUUsU0FBUztRQUNmLElBQUksRUFBRSxTQUFTO0tBQ2hCLENBQUM7QUFDSixDQUFDO0FBRUQsK0RBQStEO0FBQy9ELE1BQU0sVUFBVSwrQkFBK0IsQ0FBQyxJQUE2QjtJQUMzRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3hFLE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pELElBQUksQ0FBQyxLQUFLLElBQUksdUJBQXVCLENBQUMsS0FBSyxDQUFDLEtBQUssTUFBTTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3RFLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLE1BQU07UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNuRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDO0lBQy9CLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVELHVFQUF1RTtBQUN2RSxNQUFNLFVBQVUsaUNBQWlDLENBQUMsUUFBOEI7SUFDOUUsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQ3BCLEtBQUssSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQzFELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsT0FBTztZQUFFLFNBQVM7UUFDdkIsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2pDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzFCLE9BQU8sR0FBRyxJQUFJLENBQUM7WUFDZixTQUFTO1FBQ1gsQ0FBQztRQUNELElBQUksT0FBTyxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNwQyxPQUFPLE9BQU8sQ0FBQyxTQUFTLENBQUM7WUFDekIsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNqQixDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsaUJBQWlCLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDNUMsT0FBTyxPQUFPLENBQUMsaUJBQWlCLENBQUM7WUFDakMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNqQixDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsS0FBSztZQUFFLFNBQVM7UUFDckIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ3JDLE1BQU0sSUFBSSxHQUFHLElBQUksRUFBRSxJQUFJLENBQUM7WUFDeEIsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBQzdFLE9BQU8sR0FBRyxJQUFJLENBQUM7WUFDZixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxNQUFNO1lBQUUsT0FBTyxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7UUFDakUsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ3hGLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxXQUFXLElBQUksQ0FBQyxZQUFZLElBQUkscUJBQXFCLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDNUYsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDMUIsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNqQixDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxnRkFBZ0Y7QUFDaEYsTUFBTSxVQUFVLHNCQUFzQixDQUFDLFFBQThCO0lBQ25FLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDdEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDM0MsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMxRixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNoQyxPQUFPLEtBQUssSUFBSSxDQUFDLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksS0FBSyxNQUFNO1FBQUUsS0FBSyxFQUFFLENBQUM7SUFDL0QsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQy9CLElBQ0UsQ0FBQyxNQUFNO1FBQ1AsTUFBTSxDQUFDLElBQUksS0FBSyxXQUFXO1FBQzNCLENBQUMsTUFBTSxDQUFDLFVBQVU7UUFDbEIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUM5QixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsTUFBTSxDQUFDLE9BQU8sR0FBRztRQUNmLFdBQVcsQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlELFdBQVcsQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0tBQzdEO1NBQ0UsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFtQixFQUFFLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQztTQUNsRCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEIsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ2YsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsbUZBQW1GO0FBQ25GLE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxJQUFZO0lBQ3JELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEMsSUFBSSxDQUFDLE1BQU07UUFBRSxPQUFPLElBQUksQ0FBQztJQUN6QixPQUFPLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDN0UsQ0FBQztBQUVELG9GQUFvRjtBQUNwRixNQUFNLFVBQVUsNEJBQTRCLENBQzFDLElBQWdDO0lBRWhDLE1BQU0sT0FBTyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7SUFDbEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztJQUNsQyxJQUFJLE1BQU0sR0FBRyxFQUFFLENBQUM7SUFDaEIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUNyQixJQUFJLGVBQWUsQ0FBeUI7UUFDMUMsU0FBUyxDQUFDLEtBQUssRUFBRSxVQUFVO1lBQ3pCLE1BQU0sSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ2xELElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbkMsT0FBTyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDMUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxVQUFVLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsZ0NBQWdDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMzRSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNqQyxDQUFDO1FBQ0gsQ0FBQztRQUNELEtBQUssQ0FBQyxVQUFVO1lBQ2QsTUFBTSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMzQixJQUFJLE1BQU07Z0JBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGdDQUFnQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzRixDQUFDO0tBQ0YsQ0FBQyxDQUNILENBQUM7QUFDSixDQUFDO0FBRUQsOEVBQThFO0FBQzlFLE1BQU0sVUFBVSwyQkFBMkIsQ0FBQyxPQUFnQztJQUMxRSxPQUFPLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztBQUNsRCxDQUFDO0FBRUQsNEVBQTRFO0FBQzVFLE1BQU0sVUFBVSx5QkFBeUIsQ0FBQyxPQUFnQztJQUN4RSxPQUFPLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQsU0FBUyxnQ0FBZ0MsQ0FBQyxJQUFZO0lBQ3BELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDcEYsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3RFLE1BQU0sS0FBSyxHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMvQyxJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDakQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMseUJBQXlCLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDL0QsT0FBTyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLFVBQVUsRUFBRSxDQUFDO0FBQzdELENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUMzQixPQUFnQyxFQUNoQyxLQUEwQjtJQUUxQixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDbEQsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQ3BCLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUTtZQUFFLFNBQVM7UUFDcEQsTUFBTSxTQUFTLEdBQUksTUFBa0MsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsU0FBUyxJQUFJLE9BQU8sU0FBUyxLQUFLLFFBQVE7WUFBRSxTQUFTO1FBQzFELE1BQU0sTUFBTSxHQUFHLFNBQWtDLENBQUM7UUFDbEQsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsS0FBSztZQUFFLFNBQVM7UUFDckIsTUFBTSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sR0FBRyxJQUFJLENBQUM7SUFDakIsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxTQUFTLHNCQUFzQixDQUFDLE9BQXNDO0lBQ3BFLE9BQU8sVUFBVSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZGLENBQUM7QUFFRCxTQUFTLHFCQUFxQixDQUFDLE9BQXNDO0lBQ25FLElBQUksT0FBTyxLQUFLLFNBQVM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN2QyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVE7UUFBRSxPQUFPLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO0lBQ3BFLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3hCLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1FBQzFCLElBQUksSUFBSSxFQUFFLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUMxQixPQUFPLE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRnJhbWV3b3JrLW5ldXRyYWwgcmVwYWlycyBmb3IgT3BlbkFJIENoYXQgdHJhZmZpYyBzZW50IHRocm91Z2ggRGF0YWJyaWNrc1xuICogTW9kZWwgU2VydmluZy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsganNvbiwgc3RyaW5nVXRpbHMgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgdHlwZSBDaGF0TWVzc2FnZSwgdHlwZSBDaGF0Um9sZSwgb3BlbmFpQ2hhdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tb2RlbFwiO1xuXG5pbXBvcnQgeyBjaGF0VG9vbFJlYXNvbmluZ0VmZm9ydCB9IGZyb20gXCIuL3BvbGljeS50c1wiO1xuXG4vKiogQ2hhdCBtZXNzYWdlIHBsdXMgcHJvdmlkZXIgcmVhc29uaW5nIGZpZWxkcyBlbWl0dGVkIGJ5IERhdGFicmlja3MgbW9kZWxzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZXJ2aW5nQ2hhdE1lc3NhZ2UgZXh0ZW5kcyBDaGF0TWVzc2FnZSB7XG4gIHJvbGU6IENoYXRSb2xlIHwgXCJyZWFzb25pbmdcIjtcbiAgcmVhc29uaW5nPzogdW5rbm93bjtcbiAgcmVhc29uaW5nX2NvbnRlbnQ/OiB1bmtub3duO1xufVxuXG4vKiogUHJlcGFyZWQgZmV0Y2ggYXJndW1lbnRzIGFuZCB0aGUgc2FuaXRpemVkIHJlcXVlc3QgYm9keS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmV3cml0dGVuU2VydmluZ1JlcXVlc3Qge1xuICBpbnB1dDogUGFyYW1ldGVyczx0eXBlb2YgZmV0Y2g+WzBdO1xuICBpbml0OiBQYXJhbWV0ZXJzPHR5cGVvZiBmZXRjaD5bMV07XG4gIGJvZHk6IHN0cmluZztcbn1cblxuY29uc3QgUkVBU09OSU5HX1BBUlRfVFlQRVM6IFJlYWRvbmx5U2V0PHN0cmluZz4gPSBuZXcgU2V0KFtcbiAgXCJyZWFzb25pbmdcIixcbiAgXCJ0aGlua2luZ1wiLFxuICBcInJlZGFjdGVkX3RoaW5raW5nXCIsXG5dKTtcblxuLyoqIFNhbml0aXplIGEgc2VyaWFsaXplZCBDaGF0IENvbXBsZXRpb25zIHJlcXVlc3Qgd2hlbiBwcm92aWRlciBxdWlya3MgcmVxdWlyZSBpdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXdyaXRlU2VydmluZ0JvZHkoYm9keTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcGFyc2VkID0ganNvbi5wYXJzZVJlY29yZChib2R5KTtcbiAgaWYgKCFwYXJzZWQpIHJldHVybiBib2R5O1xuICBsZXQgY2hhbmdlZCA9XG4gICAgb3BlbmFpQ2hhdC5zdHJpcFVuc3VwcG9ydGVkQ2hhdEZpZWxkcyhwYXJzZWQpLmxlbmd0aCA+IDAgfHxcbiAgICBhcHBseVRvb2xSZWFzb25pbmdDb21wYXRpYmlsaXR5KHBhcnNlZCk7XG4gIGlmIChBcnJheS5pc0FycmF5KHBhcnNlZC5tZXNzYWdlcykpIHtcbiAgICBjb25zdCBtZXNzYWdlcyA9IHBhcnNlZC5tZXNzYWdlcyBhcyBTZXJ2aW5nQ2hhdE1lc3NhZ2VbXTtcbiAgICBjb25zdCBzdHJpcHBlZCA9IHN0cmlwUmVhc29uaW5nRnJvbVNlcnZpbmdNZXNzYWdlcyhtZXNzYWdlcyk7XG4gICAgY29uc3QgcmVwYWlyZWQgPSByZXBhaXJBc3Npc3RhbnRQcmVmaWxsKG1lc3NhZ2VzKTtcbiAgICBjaGFuZ2VkID0gY2hhbmdlZCB8fCBzdHJpcHBlZCB8fCByZXBhaXJlZDtcbiAgfVxuICByZXR1cm4gY2hhbmdlZCA/IEpTT04uc3RyaW5naWZ5KHBhcnNlZCkgOiBib2R5O1xufVxuXG4vKiogUmVhZCBhbmQgc2FuaXRpemUgYSBDaGF0IENvbXBsZXRpb25zIHJlcXVlc3Qgd2l0aG91dCByZXRhaW5pbmcgc3RhbGUgYnl0ZSBoZWFkZXJzLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJld3JpdGVTZXJ2aW5nUmVxdWVzdChcbiAgaW5wdXQ6IFBhcmFtZXRlcnM8dHlwZW9mIGZldGNoPlswXSxcbiAgaW5pdD86IFBhcmFtZXRlcnM8dHlwZW9mIGZldGNoPlsxXSxcbik6IFByb21pc2U8UmV3cml0dGVuU2VydmluZ1JlcXVlc3Q+IHtcbiAgY29uc3QgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KGlucHV0LCBpbml0KTtcbiAgY29uc3QgYm9keSA9IGF3YWl0IHJlcXVlc3QuY2xvbmUoKS50ZXh0KCk7XG4gIGNvbnN0IHJld3JpdHRlbiA9IHJld3JpdGVTZXJ2aW5nQm9keShib2R5KTtcbiAgaWYgKHJld3JpdHRlbiA9PT0gYm9keSkgcmV0dXJuIHsgaW5wdXQsIGluaXQsIGJvZHkgfTtcbiAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKHJlcXVlc3QuaGVhZGVycyk7XG4gIGhlYWRlcnMuZGVsZXRlKFwiY29udGVudC1sZW5ndGhcIik7XG4gIGhlYWRlcnMuZGVsZXRlKFwiY29udGVudC1lbmNvZGluZ1wiKTtcbiAgcmV0dXJuIHtcbiAgICBpbnB1dDogbmV3IFJlcXVlc3QocmVxdWVzdCwgeyBib2R5OiByZXdyaXR0ZW4sIGhlYWRlcnMgfSksXG4gICAgaW5pdDogdW5kZWZpbmVkLFxuICAgIGJvZHk6IHJld3JpdHRlbixcbiAgfTtcbn1cblxuLyoqIE5vcm1hbGl6ZSBDaGF0IENvbXBsZXRpb25zIHJlYXNvbmluZyBmb3IgR1BUIHRvb2wgY2FsbHMuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlUb29sUmVhc29uaW5nQ29tcGF0aWJpbGl0eShib2R5OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IGJvb2xlYW4ge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoYm9keS50b29scykgfHwgYm9keS50b29scy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgY29uc3QgbW9kZWwgPSBzdHJpbmdVdGlscy50cmltVG9OdWxsKGJvZHkubW9kZWwpO1xuICBpZiAoIW1vZGVsIHx8IGNoYXRUb29sUmVhc29uaW5nRWZmb3J0KG1vZGVsKSAhPT0gXCJub25lXCIpIHJldHVybiBmYWxzZTtcbiAgaWYgKGJvZHkucmVhc29uaW5nX2VmZm9ydCA9PT0gXCJub25lXCIpIHJldHVybiBmYWxzZTtcbiAgYm9keS5yZWFzb25pbmdfZWZmb3J0ID0gXCJub25lXCI7XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogUmVtb3ZlIHByb3ZpZGVyIHJlYXNvbmluZyBibG9ja3MgdGhhdCBjYW5ub3QgYmUgcmVwbGF5ZWQgc2FmZWx5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmlwUmVhc29uaW5nRnJvbVNlcnZpbmdNZXNzYWdlcyhtZXNzYWdlczogU2VydmluZ0NoYXRNZXNzYWdlW10pOiBib29sZWFuIHtcbiAgbGV0IGNoYW5nZWQgPSBmYWxzZTtcbiAgZm9yIChsZXQgaW5kZXggPSBtZXNzYWdlcy5sZW5ndGggLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IG1lc3NhZ2VzW2luZGV4XTtcbiAgICBpZiAoIW1lc3NhZ2UpIGNvbnRpbnVlO1xuICAgIGlmIChtZXNzYWdlLnJvbGUgPT09IFwicmVhc29uaW5nXCIpIHtcbiAgICAgIG1lc3NhZ2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZS5yZWFzb25pbmcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZGVsZXRlIG1lc3NhZ2UucmVhc29uaW5nO1xuICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgfVxuICAgIGlmIChtZXNzYWdlLnJlYXNvbmluZ19jb250ZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlbGV0ZSBtZXNzYWdlLnJlYXNvbmluZ19jb250ZW50O1xuICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgfVxuICAgIGNvbnN0IHBhcnRzID0gb3BlbmFpQ2hhdC5jaGF0Q29udGVudFBhcnRzKG1lc3NhZ2UuY29udGVudCk7XG4gICAgaWYgKCFwYXJ0cykgY29udGludWU7XG4gICAgY29uc3QgZmlsdGVyZWQgPSBwYXJ0cy5maWx0ZXIoKHBhcnQpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSBwYXJ0Py50eXBlO1xuICAgICAgaWYgKHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiIHx8ICFSRUFTT05JTkdfUEFSVF9UWVBFUy5oYXModHlwZSkpIHJldHVybiB0cnVlO1xuICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSk7XG4gICAgaWYgKGZpbHRlcmVkLmxlbmd0aCAhPT0gcGFydHMubGVuZ3RoKSBtZXNzYWdlLmNvbnRlbnQgPSBmaWx0ZXJlZDtcbiAgICBjb25zdCBoYXNUb29sQ2FsbHMgPSBBcnJheS5pc0FycmF5KG1lc3NhZ2UudG9vbF9jYWxscykgJiYgbWVzc2FnZS50b29sX2NhbGxzLmxlbmd0aCA+IDA7XG4gICAgaWYgKG1lc3NhZ2Uucm9sZSA9PT0gXCJhc3Npc3RhbnRcIiAmJiAhaGFzVG9vbENhbGxzICYmIGlzRW1wdHlTZXJ2aW5nQ29udGVudChtZXNzYWdlLmNvbnRlbnQpKSB7XG4gICAgICBtZXNzYWdlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBjaGFuZ2VkO1xufVxuXG4vKiogRm9sZCBhIHRyYWlsaW5nIGFzc2lzdGFudCBwcmVmaWxsIGJhY2sgaW50byBpdHMgcHJlY2VkaW5nIHRvb2wtY2FsbCB0dXJuLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcGFpckFzc2lzdGFudFByZWZpbGwobWVzc2FnZXM6IFNlcnZpbmdDaGF0TWVzc2FnZVtdKTogYm9vbGVhbiB7XG4gIGlmIChtZXNzYWdlcy5sZW5ndGggPCAyKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IGxhc3QgPSBtZXNzYWdlc1ttZXNzYWdlcy5sZW5ndGggLSAxXTtcbiAgaWYgKCFsYXN0IHx8IGxhc3Qucm9sZSAhPT0gXCJhc3Npc3RhbnRcIiB8fCAobGFzdC50b29sX2NhbGxzICYmIGxhc3QudG9vbF9jYWxscy5sZW5ndGggPiAwKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBsZXQgaW5kZXggPSBtZXNzYWdlcy5sZW5ndGggLSAyO1xuICB3aGlsZSAoaW5kZXggPj0gMCAmJiBtZXNzYWdlc1tpbmRleF0/LnJvbGUgPT09IFwidG9vbFwiKSBpbmRleC0tO1xuICBjb25zdCBvcGVuZXIgPSBtZXNzYWdlc1tpbmRleF07XG4gIGlmIChcbiAgICAhb3BlbmVyIHx8XG4gICAgb3BlbmVyLnJvbGUgIT09IFwiYXNzaXN0YW50XCIgfHxcbiAgICAhb3BlbmVyLnRvb2xfY2FsbHMgfHxcbiAgICBvcGVuZXIudG9vbF9jYWxscy5sZW5ndGggPT09IDBcbiAgKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIG9wZW5lci5jb250ZW50ID0gW1xuICAgIHN0cmluZ1V0aWxzLnRyaW1Ub051bGwodGV4dEZyb21TZXJ2aW5nQ29udGVudChvcGVuZXIuY29udGVudCkpLFxuICAgIHN0cmluZ1V0aWxzLnRyaW1Ub051bGwodGV4dEZyb21TZXJ2aW5nQ29udGVudChsYXN0LmNvbnRlbnQpKSxcbiAgXVxuICAgIC5maWx0ZXIoKHZhbHVlKTogdmFsdWUgaXMgc3RyaW5nID0+IHZhbHVlICE9PSBudWxsKVxuICAgIC5qb2luKFwiXFxuXFxuXCIpO1xuICBtZXNzYWdlcy5wb3AoKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKiBOb3JtYWxpemUgYXJyYXktdmFsdWVkIGNvbnRlbnQgaW4gYSBub24tc3RyZWFtaW5nIENoYXQgQ29tcGxldGlvbnMgcmVzcG9uc2UuICovXG5leHBvcnQgZnVuY3Rpb24gcmV3cml0ZVNlcnZpbmdSZXNwb25zZUJvZHkoYm9keTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcGFyc2VkID0ganNvbi5wYXJzZVJlY29yZChib2R5KTtcbiAgaWYgKCFwYXJzZWQpIHJldHVybiBib2R5O1xuICByZXR1cm4gZmxhdHRlbkNob2ljZU1lc3NhZ2VDb250ZW50KHBhcnNlZCkgPyBKU09OLnN0cmluZ2lmeShwYXJzZWQpIDogYm9keTtcbn1cblxuLyoqIE5vcm1hbGl6ZSBhcnJheS12YWx1ZWQgY29udGVudCBpbiBhbiBTU0Ugc3RyZWFtIHdpdGhvdXQgYnVmZmVyaW5nIHRoZSBzdHJlYW0uICovXG5leHBvcnQgZnVuY3Rpb24gcmV3cml0ZVNlcnZpbmdSZXNwb25zZVN0cmVhbShcbiAgYm9keTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4sXG4pOiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PiB7XG4gIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICBsZXQgYnVmZmVyID0gXCJcIjtcbiAgcmV0dXJuIGJvZHkucGlwZVRocm91Z2goXG4gICAgbmV3IFRyYW5zZm9ybVN0cmVhbTxVaW50OEFycmF5LCBVaW50OEFycmF5Pih7XG4gICAgICB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgYnVmZmVyICs9IGRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTtcbiAgICAgICAgbGV0IG5ld2xpbmUgPSBidWZmZXIuaW5kZXhPZihcIlxcblwiKTtcbiAgICAgICAgd2hpbGUgKG5ld2xpbmUgPj0gMCkge1xuICAgICAgICAgIGNvbnN0IGxpbmUgPSBidWZmZXIuc2xpY2UoMCwgbmV3bGluZSArIDEpO1xuICAgICAgICAgIGJ1ZmZlciA9IGJ1ZmZlci5zbGljZShuZXdsaW5lICsgMSk7XG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGVuY29kZXIuZW5jb2RlKHJld3JpdGVTZXJ2aW5nUmVzcG9uc2VTdHJlYW1MaW5lKGxpbmUpKSk7XG4gICAgICAgICAgbmV3bGluZSA9IGJ1ZmZlci5pbmRleE9mKFwiXFxuXCIpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZmx1c2goY29udHJvbGxlcikge1xuICAgICAgICBidWZmZXIgKz0gZGVjb2Rlci5kZWNvZGUoKTtcbiAgICAgICAgaWYgKGJ1ZmZlcikgY29udHJvbGxlci5lbnF1ZXVlKGVuY29kZXIuZW5jb2RlKHJld3JpdGVTZXJ2aW5nUmVzcG9uc2VTdHJlYW1MaW5lKGJ1ZmZlcikpKTtcbiAgICAgIH0sXG4gICAgfSksXG4gICk7XG59XG5cbi8qKiBGbGF0dGVuIENoYXQgQ29tcGxldGlvbnMgYGNob2ljZXNbXS5tZXNzYWdlLmNvbnRlbnRgIGFycmF5cyB0byBzdHJpbmdzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW5DaG9pY2VNZXNzYWdlQ29udGVudChwYXlsb2FkOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IGJvb2xlYW4ge1xuICByZXR1cm4gZmxhdHRlbkNob2ljZUNvbnRlbnQocGF5bG9hZCwgXCJtZXNzYWdlXCIpO1xufVxuXG4vKiogRmxhdHRlbiBDaGF0IENvbXBsZXRpb25zIGBjaG9pY2VzW10uZGVsdGEuY29udGVudGAgYXJyYXlzIHRvIHN0cmluZ3MuICovXG5leHBvcnQgZnVuY3Rpb24gZmxhdHRlbkNob2ljZURlbHRhQ29udGVudChwYXlsb2FkOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IGJvb2xlYW4ge1xuICByZXR1cm4gZmxhdHRlbkNob2ljZUNvbnRlbnQocGF5bG9hZCwgXCJkZWx0YVwiKTtcbn1cblxuZnVuY3Rpb24gcmV3cml0ZVNlcnZpbmdSZXNwb25zZVN0cmVhbUxpbmUobGluZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbGluZUVuZGluZyA9IGxpbmUuZW5kc1dpdGgoXCJcXHJcXG5cIikgPyBcIlxcclxcblwiIDogbGluZS5lbmRzV2l0aChcIlxcblwiKSA/IFwiXFxuXCIgOiBcIlwiO1xuICBjb25zdCBjb250ZW50ID0gbGluZUVuZGluZyA/IGxpbmUuc2xpY2UoMCwgLWxpbmVFbmRpbmcubGVuZ3RoKSA6IGxpbmU7XG4gIGNvbnN0IG1hdGNoID0gL14oZGF0YTpcXHMqKSguKikkLy5leGVjKGNvbnRlbnQpO1xuICBpZiAoIW1hdGNoIHx8IG1hdGNoWzJdID09PSBcIltET05FXVwiKSByZXR1cm4gbGluZTtcbiAgY29uc3QgcGFyc2VkID0ganNvbi5wYXJzZVJlY29yZChtYXRjaFsyXSk7XG4gIGlmICghcGFyc2VkIHx8ICFmbGF0dGVuQ2hvaWNlRGVsdGFDb250ZW50KHBhcnNlZCkpIHJldHVybiBsaW5lO1xuICByZXR1cm4gYCR7bWF0Y2hbMV19JHtKU09OLnN0cmluZ2lmeShwYXJzZWQpfSR7bGluZUVuZGluZ31gO1xufVxuXG5mdW5jdGlvbiBmbGF0dGVuQ2hvaWNlQ29udGVudChcbiAgcGF5bG9hZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIGZpZWxkOiBcIm1lc3NhZ2VcIiB8IFwiZGVsdGFcIixcbik6IGJvb2xlYW4ge1xuICBpZiAoIUFycmF5LmlzQXJyYXkocGF5bG9hZC5jaG9pY2VzKSkgcmV0dXJuIGZhbHNlO1xuICBsZXQgY2hhbmdlZCA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IGNob2ljZSBvZiBwYXlsb2FkLmNob2ljZXMpIHtcbiAgICBpZiAoIWNob2ljZSB8fCB0eXBlb2YgY2hvaWNlICE9PSBcIm9iamVjdFwiKSBjb250aW51ZTtcbiAgICBjb25zdCBjb250YWluZXIgPSAoY2hvaWNlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtmaWVsZF07XG4gICAgaWYgKCFjb250YWluZXIgfHwgdHlwZW9mIGNvbnRhaW5lciAhPT0gXCJvYmplY3RcIikgY29udGludWU7XG4gICAgY29uc3QgdGFyZ2V0ID0gY29udGFpbmVyIGFzIHsgY29udGVudD86IHVua25vd24gfTtcbiAgICBjb25zdCBwYXJ0cyA9IG9wZW5haUNoYXQuY2hhdENvbnRlbnRQYXJ0cyh0YXJnZXQuY29udGVudCk7XG4gICAgaWYgKCFwYXJ0cykgY29udGludWU7XG4gICAgdGFyZ2V0LmNvbnRlbnQgPSBvcGVuYWlDaGF0LmNoYXRDb250ZW50VG9UZXh0KHBhcnRzLCB7IHR5cGVzOiBbXCJ0ZXh0XCJdIH0pO1xuICAgIGNoYW5nZWQgPSB0cnVlO1xuICB9XG4gIHJldHVybiBjaGFuZ2VkO1xufVxuXG5mdW5jdGlvbiB0ZXh0RnJvbVNlcnZpbmdDb250ZW50KGNvbnRlbnQ6IFNlcnZpbmdDaGF0TWVzc2FnZVtcImNvbnRlbnRcIl0pOiBzdHJpbmcge1xuICByZXR1cm4gb3BlbmFpQ2hhdC5jaGF0Q29udGVudFRvVGV4dChjb250ZW50LCB7IHNlcGFyYXRvcjogXCJcXG5cXG5cIiwgdHlwZXM6IFtcInRleHRcIl0gfSk7XG59XG5cbmZ1bmN0aW9uIGlzRW1wdHlTZXJ2aW5nQ29udGVudChjb250ZW50OiBTZXJ2aW5nQ2hhdE1lc3NhZ2VbXCJjb250ZW50XCJdKTogYm9vbGVhbiB7XG4gIGlmIChjb250ZW50ID09PSB1bmRlZmluZWQpIHJldHVybiB0cnVlO1xuICBpZiAodHlwZW9mIGNvbnRlbnQgPT09IFwic3RyaW5nXCIpIHJldHVybiBjb250ZW50LnRyaW0oKS5sZW5ndGggPT09IDA7XG4gIGNvbnN0IHBhcnRzID0gb3BlbmFpQ2hhdC5jaGF0Q29udGVudFBhcnRzKGNvbnRlbnQpO1xuICBpZiAoIXBhcnRzKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIHBhcnRzLmV2ZXJ5KChwYXJ0KSA9PiB7XG4gICAgaWYgKHBhcnQ/LnR5cGUgPT09IFwidGV4dFwiKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHBhcnQudGV4dCAhPT0gXCJzdHJpbmdcIiB8fCBwYXJ0LnRleHQudHJpbSgpLmxlbmd0aCA9PT0gMDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KTtcbn1cbiJdfQ==
@@ -1,231 +0,0 @@
1
- /**
2
- * Framework-neutral repairs for OpenAI Chat traffic sent through Databricks
3
- * Model Serving.
4
- *
5
- * @module
6
- */
7
-
8
- import { json, stringUtils } from "@dbx-tools/shared-core";
9
- import { type ChatMessage, type ChatRole, openaiChat } from "@dbx-tools/shared-model";
10
-
11
- import { chatToolReasoningEffort } from "./policy.ts";
12
-
13
- /** Chat message plus provider reasoning fields emitted by Databricks models. */
14
- export interface ServingChatMessage extends ChatMessage {
15
- role: ChatRole | "reasoning";
16
- reasoning?: unknown;
17
- reasoning_content?: unknown;
18
- }
19
-
20
- /** Prepared fetch arguments and the sanitized request body. */
21
- export interface RewrittenServingRequest {
22
- input: Parameters<typeof fetch>[0];
23
- init: Parameters<typeof fetch>[1];
24
- body: string;
25
- }
26
-
27
- const REASONING_PART_TYPES: ReadonlySet<string> = new Set([
28
- "reasoning",
29
- "thinking",
30
- "redacted_thinking",
31
- ]);
32
-
33
- /** Sanitize a serialized Chat Completions request when provider quirks require it. */
34
- export function rewriteServingBody(body: string): string {
35
- const parsed = json.parseRecord(body);
36
- if (!parsed) return body;
37
- let changed =
38
- openaiChat.stripUnsupportedChatFields(parsed).length > 0 ||
39
- applyToolReasoningCompatibility(parsed);
40
- if (Array.isArray(parsed.messages)) {
41
- const messages = parsed.messages as ServingChatMessage[];
42
- const stripped = stripReasoningFromServingMessages(messages);
43
- const repaired = repairAssistantPrefill(messages);
44
- changed = changed || stripped || repaired;
45
- }
46
- return changed ? JSON.stringify(parsed) : body;
47
- }
48
-
49
- /** Read and sanitize a Chat Completions request without retaining stale byte headers. */
50
- export async function rewriteServingRequest(
51
- input: Parameters<typeof fetch>[0],
52
- init?: Parameters<typeof fetch>[1],
53
- ): Promise<RewrittenServingRequest> {
54
- const request = new Request(input, init);
55
- const body = await request.clone().text();
56
- const rewritten = rewriteServingBody(body);
57
- if (rewritten === body) return { input, init, body };
58
- const headers = new Headers(request.headers);
59
- headers.delete("content-length");
60
- headers.delete("content-encoding");
61
- return {
62
- input: new Request(request, { body: rewritten, headers }),
63
- init: undefined,
64
- body: rewritten,
65
- };
66
- }
67
-
68
- /** Normalize Chat Completions reasoning for GPT tool calls. */
69
- export function applyToolReasoningCompatibility(body: Record<string, unknown>): boolean {
70
- if (!Array.isArray(body.tools) || body.tools.length === 0) return false;
71
- const model = stringUtils.trimToNull(body.model);
72
- if (!model || chatToolReasoningEffort(model) !== "none") return false;
73
- if (body.reasoning_effort === "none") return false;
74
- body.reasoning_effort = "none";
75
- return true;
76
- }
77
-
78
- /** Remove provider reasoning blocks that cannot be replayed safely. */
79
- export function stripReasoningFromServingMessages(messages: ServingChatMessage[]): boolean {
80
- let changed = false;
81
- for (let index = messages.length - 1; index >= 0; index--) {
82
- const message = messages[index];
83
- if (!message) continue;
84
- if (message.role === "reasoning") {
85
- messages.splice(index, 1);
86
- changed = true;
87
- continue;
88
- }
89
- if (message.reasoning !== undefined) {
90
- delete message.reasoning;
91
- changed = true;
92
- }
93
- if (message.reasoning_content !== undefined) {
94
- delete message.reasoning_content;
95
- changed = true;
96
- }
97
- const parts = openaiChat.chatContentParts(message.content);
98
- if (!parts) continue;
99
- const filtered = parts.filter((part) => {
100
- const type = part?.type;
101
- if (typeof type !== "string" || !REASONING_PART_TYPES.has(type)) return true;
102
- changed = true;
103
- return false;
104
- });
105
- if (filtered.length !== parts.length) message.content = filtered;
106
- const hasToolCalls = Array.isArray(message.tool_calls) && message.tool_calls.length > 0;
107
- if (message.role === "assistant" && !hasToolCalls && isEmptyServingContent(message.content)) {
108
- messages.splice(index, 1);
109
- changed = true;
110
- }
111
- }
112
- return changed;
113
- }
114
-
115
- /** Fold a trailing assistant prefill back into its preceding tool-call turn. */
116
- export function repairAssistantPrefill(messages: ServingChatMessage[]): boolean {
117
- if (messages.length < 2) return false;
118
- const last = messages[messages.length - 1];
119
- if (!last || last.role !== "assistant" || (last.tool_calls && last.tool_calls.length > 0)) {
120
- return false;
121
- }
122
- let index = messages.length - 2;
123
- while (index >= 0 && messages[index]?.role === "tool") index--;
124
- const opener = messages[index];
125
- if (
126
- !opener ||
127
- opener.role !== "assistant" ||
128
- !opener.tool_calls ||
129
- opener.tool_calls.length === 0
130
- ) {
131
- return false;
132
- }
133
- opener.content = [
134
- stringUtils.trimToNull(textFromServingContent(opener.content)),
135
- stringUtils.trimToNull(textFromServingContent(last.content)),
136
- ]
137
- .filter((value): value is string => value !== null)
138
- .join("\n\n");
139
- messages.pop();
140
- return true;
141
- }
142
-
143
- /** Normalize array-valued content in a non-streaming Chat Completions response. */
144
- export function rewriteServingResponseBody(body: string): string {
145
- const parsed = json.parseRecord(body);
146
- if (!parsed) return body;
147
- return flattenChoiceMessageContent(parsed) ? JSON.stringify(parsed) : body;
148
- }
149
-
150
- /** Normalize array-valued content in an SSE stream without buffering the stream. */
151
- export function rewriteServingResponseStream(
152
- body: ReadableStream<Uint8Array>,
153
- ): ReadableStream<Uint8Array> {
154
- const decoder = new TextDecoder();
155
- const encoder = new TextEncoder();
156
- let buffer = "";
157
- return body.pipeThrough(
158
- new TransformStream<Uint8Array, Uint8Array>({
159
- transform(chunk, controller) {
160
- buffer += decoder.decode(chunk, { stream: true });
161
- let newline = buffer.indexOf("\n");
162
- while (newline >= 0) {
163
- const line = buffer.slice(0, newline + 1);
164
- buffer = buffer.slice(newline + 1);
165
- controller.enqueue(encoder.encode(rewriteServingResponseStreamLine(line)));
166
- newline = buffer.indexOf("\n");
167
- }
168
- },
169
- flush(controller) {
170
- buffer += decoder.decode();
171
- if (buffer) controller.enqueue(encoder.encode(rewriteServingResponseStreamLine(buffer)));
172
- },
173
- }),
174
- );
175
- }
176
-
177
- /** Flatten Chat Completions `choices[].message.content` arrays to strings. */
178
- export function flattenChoiceMessageContent(payload: Record<string, unknown>): boolean {
179
- return flattenChoiceContent(payload, "message");
180
- }
181
-
182
- /** Flatten Chat Completions `choices[].delta.content` arrays to strings. */
183
- export function flattenChoiceDeltaContent(payload: Record<string, unknown>): boolean {
184
- return flattenChoiceContent(payload, "delta");
185
- }
186
-
187
- function rewriteServingResponseStreamLine(line: string): string {
188
- const lineEnding = line.endsWith("\r\n") ? "\r\n" : line.endsWith("\n") ? "\n" : "";
189
- const content = lineEnding ? line.slice(0, -lineEnding.length) : line;
190
- const match = /^(data:\s*)(.*)$/.exec(content);
191
- if (!match || match[2] === "[DONE]") return line;
192
- const parsed = json.parseRecord(match[2]);
193
- if (!parsed || !flattenChoiceDeltaContent(parsed)) return line;
194
- return `${match[1]}${JSON.stringify(parsed)}${lineEnding}`;
195
- }
196
-
197
- function flattenChoiceContent(
198
- payload: Record<string, unknown>,
199
- field: "message" | "delta",
200
- ): boolean {
201
- if (!Array.isArray(payload.choices)) return false;
202
- let changed = false;
203
- for (const choice of payload.choices) {
204
- if (!choice || typeof choice !== "object") continue;
205
- const container = (choice as Record<string, unknown>)[field];
206
- if (!container || typeof container !== "object") continue;
207
- const target = container as { content?: unknown };
208
- const parts = openaiChat.chatContentParts(target.content);
209
- if (!parts) continue;
210
- target.content = openaiChat.chatContentToText(parts, { types: ["text"] });
211
- changed = true;
212
- }
213
- return changed;
214
- }
215
-
216
- function textFromServingContent(content: ServingChatMessage["content"]): string {
217
- return openaiChat.chatContentToText(content, { separator: "\n\n", types: ["text"] });
218
- }
219
-
220
- function isEmptyServingContent(content: ServingChatMessage["content"]): boolean {
221
- if (content === undefined) return true;
222
- if (typeof content === "string") return content.trim().length === 0;
223
- const parts = openaiChat.chatContentParts(content);
224
- if (!parts) return true;
225
- return parts.every((part) => {
226
- if (part?.type === "text") {
227
- return typeof part.text !== "string" || part.text.trim().length === 0;
228
- }
229
- return false;
230
- });
231
- }