@dbx-tools/model 0.9.32 → 0.9.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +3 -3
  2. package/exports.ts +1 -0
  3. package/index.ts +12 -8
  4. package/lib/index.d.ts +12 -8
  5. package/lib/index.js +8 -5
  6. package/lib/scripts/generate-metadata.d.ts +1 -0
  7. package/lib/scripts/generate-metadata.js +65 -0
  8. package/lib/src/_metadata-contract.d.ts +12 -6
  9. package/lib/src/_metadata-contract.js +3 -1
  10. package/lib/src/_metadata-generator.d.ts +3 -1
  11. package/lib/src/_metadata-generator.js +148 -1
  12. package/lib/src/_ranking.js +39 -12
  13. package/lib/src/_selection.d.ts +1 -17
  14. package/lib/src/_selection.js +1 -1
  15. package/lib/src/classify.d.ts +1 -17
  16. package/lib/src/classify.js +1 -1
  17. package/lib/src/generated/model-reasoning.json +147 -0
  18. package/lib/src/invoke.d.ts +8 -0
  19. package/lib/src/invoke.js +13 -1
  20. package/lib/src/metadata-cache.d.ts +84 -0
  21. package/lib/src/metadata-cache.js +226 -0
  22. package/lib/src/metadata.d.ts +52 -17
  23. package/lib/src/metadata.js +251 -18
  24. package/lib/src/model-catalog.d.ts +1 -19
  25. package/lib/src/model-catalog.js +9 -2
  26. package/lib/src/model-client.d.ts +11 -19
  27. package/lib/src/model-client.js +42 -24
  28. package/lib/src/reasoning-translation.d.ts +105 -0
  29. package/lib/src/reasoning-translation.js +444 -0
  30. package/lib/src/resolve.d.ts +2 -4
  31. package/lib/src/resolve.js +2 -2
  32. package/lib/src/serving-wire.d.ts +37 -0
  33. package/lib/src/serving-wire.js +211 -0
  34. package/lib/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +110 -17
  36. package/src/_metadata-contract.ts +17 -7
  37. package/src/_metadata-generator.ts +160 -0
  38. package/src/_ranking.ts +40 -11
  39. package/src/_selection.ts +4 -19
  40. package/src/classify.ts +2 -18
  41. package/src/generated/model-reasoning.json +147 -0
  42. package/src/invoke.ts +16 -0
  43. package/src/metadata-cache.ts +307 -0
  44. package/src/metadata.ts +334 -43
  45. package/src/model-catalog.ts +8 -25
  46. package/src/model-client.ts +67 -44
  47. package/src/reasoning-translation.ts +495 -0
  48. package/src/resolve.ts +10 -11
  49. package/src/serving-wire.ts +231 -0
  50. package/lib/src/python.d.ts +0 -2
  51. package/lib/src/python.js +0 -3
  52. package/src/python.ts +0 -2
@@ -41,6 +41,10 @@ export declare const OPEN_RESPONSES_PATH = "serving-endpoints/open-responses";
41
41
  * attaching a provider tool spec to whichever endpoint was resolved.
42
42
  */
43
43
  export declare const CHAT_COMPLETIONS_PATH = "serving-endpoints/chat/completions";
44
+ /** Unity Gateway OpenAI Responses path used by Codex-compatible model services. */
45
+ export declare const AI_GATEWAY_CODEX_RESPONSES_PATH = "ai-gateway/codex/v1/responses";
46
+ /** Workspace Anthropic Messages path for native Claude requests. */
47
+ export declare const ANTHROPIC_MESSAGES_PATH = "serving-endpoints/anthropic/v1/messages";
44
48
  /**
45
49
  * The OpenAI-compatible chat-completions invocations URL for an endpoint id.
46
50
  *
@@ -55,6 +59,10 @@ export declare function responsesUrl(host: string): string;
55
59
  export declare function openResponsesUrl(host: string): string;
56
60
  /** Workspace OpenAI Chat Completions URL (`POST`, model in the body). */
57
61
  export declare function chatCompletionsUrl(host: string): string;
62
+ /** Unity Gateway Codex Responses URL (`POST`, model service in the body). */
63
+ export declare function aiGatewayCodexResponsesUrl(host: string): string;
64
+ /** Workspace Anthropic Messages URL (`POST`, model in the body). */
65
+ export declare function anthropicMessagesUrl(host: string): string;
58
66
  /**
59
67
  * True when the endpoint is known to reject Chat Completions `/invocations`
60
68
  * and require the Responses API (Codex models today). Callers should route
package/lib/src/invoke.js CHANGED
@@ -42,6 +42,10 @@ export const OPEN_RESPONSES_PATH = "serving-endpoints/open-responses";
42
42
  * attaching a provider tool spec to whichever endpoint was resolved.
43
43
  */
44
44
  export const CHAT_COMPLETIONS_PATH = "serving-endpoints/chat/completions";
45
+ /** Unity Gateway OpenAI Responses path used by Codex-compatible model services. */
46
+ export const AI_GATEWAY_CODEX_RESPONSES_PATH = "ai-gateway/codex/v1/responses";
47
+ /** Workspace Anthropic Messages path for native Claude requests. */
48
+ export const ANTHROPIC_MESSAGES_PATH = "serving-endpoints/anthropic/v1/messages";
45
49
  /**
46
50
  * The OpenAI-compatible chat-completions invocations URL for an endpoint id.
47
51
  *
@@ -64,6 +68,14 @@ export function openResponsesUrl(host) {
64
68
  export function chatCompletionsUrl(host) {
65
69
  return new URL(CHAT_COMPLETIONS_PATH, host).toString();
66
70
  }
71
+ /** Unity Gateway Codex Responses URL (`POST`, model service in the body). */
72
+ export function aiGatewayCodexResponsesUrl(host) {
73
+ return new URL(AI_GATEWAY_CODEX_RESPONSES_PATH, host).toString();
74
+ }
75
+ /** Workspace Anthropic Messages URL (`POST`, model in the body). */
76
+ export function anthropicMessagesUrl(host) {
77
+ return new URL(ANTHROPIC_MESSAGES_PATH, host).toString();
78
+ }
67
79
  /**
68
80
  * True when the endpoint is known to reject Chat Completions `/invocations`
69
81
  * and require the Responses API (Codex models today). Callers should route
@@ -102,4 +114,4 @@ export async function authHeaders(client) {
102
114
  });
103
115
  return out;
104
116
  }
105
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52b2tlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludm9rZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLGVBQWUsSUFBSSx1QkFBdUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUV6RTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLGFBQWEsQ0FBQztBQUVoRDs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsNkJBQTZCLENBQUM7QUFFNUQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsa0NBQWtDLENBQUM7QUFFdEU7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxvQ0FBb0MsQ0FBQztBQUUxRTs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLElBQVksRUFBRSxRQUFnQjtJQUMzRCxPQUFPLElBQUksR0FBRyxDQUNaLHFCQUFxQixrQkFBa0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxrQkFBa0IsRUFBRSxFQUN6RSxJQUFJLENBQ0wsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUNmLENBQUM7QUFFRCxzRUFBc0U7QUFDdEUsTUFBTSxVQUFVLFlBQVksQ0FBQyxJQUFZO0lBQ3ZDLE9BQU8sSUFBSSxHQUFHLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ2xELENBQUM7QUFFRCxvRUFBb0U7QUFDcEUsTUFBTSxVQUFVLGdCQUFnQixDQUFDLElBQVk7SUFDM0MsT0FBTyxJQUFJLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUN2RCxDQUFDO0FBRUQseUVBQXlFO0FBQ3pFLE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxJQUFZO0lBQzdDLE9BQU8sSUFBSSxHQUFHLENBQUMscUJBQXFCLEVBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDekQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUFDLFFBQWdCO0lBQzlDLE9BQU8sdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDM0MsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsSUFBWSxFQUFFLFFBQWdCO0lBQ2pFLE9BQU8sY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2hGLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsU0FBUyxjQUFjLENBQUMsUUFBZ0I7SUFDdEMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ2pDLE9BQU8sQ0FDTCxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUNqQixDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztRQUNuQiw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQ3JCLENBQUM7QUFDSixDQUFDO0FBY0Q7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsV0FBVyxDQUMvQixNQUFnQztJQUVoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQzlCLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUMsTUFBTSxHQUFHLEdBQTJCLEVBQUUsQ0FBQztJQUN2QyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFO1FBQzdCLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDbkIsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENhbGxpbmcgYSBNb2RlbCBTZXJ2aW5nIGVuZHBvaW50IGRpcmVjdGx5IG92ZXIgSFRUUC5cbiAqXG4gKiBUaGUgU0RLJ3MgYHNlcnZpbmdFbmRwb2ludHMucXVlcnlgIGNvdmVycyB0aGUgdHlwZWQgcmVxdWVzdCBzaGFwZXMsIGJ1dCBhblxuICogT3BlbkFJLWNvbXBhdGlibGUgY2FsbGVyIChhIHByb3h5LCBhIHBhc3N0aHJvdWdoIHJvdXRlLCBhIHN0cmVhbWluZyBjbGllbnQpXG4gKiBuZWVkcyB0byBpc3N1ZSBpdHMgb3duIGBmZXRjaGAgYWdhaW5zdCBEYXRhYnJpY2tzJyBPcGVuQUktc2hhcGVkIFVSTHMgd2l0aFxuICogYW4gT3BlbkFJIGJvZHkuIFRoYXQgbmVlZHMgZXhhY3RseSB0d28gdGhpbmdzIHRoZSBTREsgZG9lc24ndCBoYW5kIG91dFxuICogZGlyZWN0bHk6IHRoZSBVUkwgKHtAbGluayBpbnZvY2F0aW9uc1VybH0gLyB7QGxpbmsgcmVzcG9uc2VzVXJsfSAvXG4gKiB7QGxpbmsgb3BlblJlc3BvbnNlc1VybH0pIGFuZCBhIGN1cnJlbnRseS12YWxpZCBzZXQgb2YgYXV0aCBoZWFkZXJzXG4gKiAoe0BsaW5rIGF1dGhIZWFkZXJzfSkuXG4gKlxuICogQXV0aCBpcyBkZWxlZ2F0ZWQgZW50aXJlbHkgdG8gdGhlIERhdGFicmlja3MgU0RLOiBgY29uZmlnLmF1dGhlbnRpY2F0ZWBcbiAqIHJlLXJ1bnMgdGhlIGNvbmZpZ3VyZWQgY3JlZGVudGlhbCBwcm92aWRlciBvbiBldmVyeSBjYWxsIGFuZCByZWZyZXNoZXMgdGhlXG4gKiB1bmRlcmx5aW5nIE9BdXRoIC8gUEFUIHRva2VuIHdoZW4gaXQgaXMgY2xvc2UgdG8gZXhwaXJ5LCBzbyBhIGNhbGxlciBuZXZlclxuICogbWFuYWdlcyB0b2tlbiBsaWZldGltZXMgaXRzZWxmIC0gbWludCBoZWFkZXJzIHBlciByZXF1ZXN0IGFuZCBlYWNoIG9uZSBpc1xuICogc2lnbmVkIHdpdGggYSB2YWxpZCBiZWFyZXIgdG9rZW4uXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGlzUmVzcG9uc2VzT25seSBhcyBpc1Jlc3BvbnNlc09ubHlCeVBvbGljeSB9IGZyb20gXCIuL3BvbGljeS50c1wiO1xuXG4vKipcbiAqIFBhdGggc2VnbWVudCBhcHBlbmRlZCB0byBhIHNlcnZpbmcgZW5kcG9pbnQgZm9yIE9wZW5BSS1jb21wYXRpYmxlIGNoYXRcbiAqIHJlcXVlc3RzLiBEYXRhYnJpY2tzIHJvdXRlcyBgL3NlcnZpbmctZW5kcG9pbnRzLzxuYW1lPi9pbnZvY2F0aW9uc2AgdG8gdGhlXG4gKiBlbmRwb2ludCdzIENoYXQgQ29tcGxldGlvbnMgc3VyZmFjZSAoYG1lc3NhZ2VzYCBpbiwgYGNob2ljZXNgIG91dCkuIFNvbWVcbiAqIG1vZGVscyAobm90YWJseSBDb2RleCkgcmVqZWN0IHRoaXMgcGF0aCBhbmQgcmVxdWlyZSB7QGxpbmsgcmVzcG9uc2VzVXJsfS5cbiAqL1xuZXhwb3J0IGNvbnN0IElOVk9DQVRJT05TX1NVRkZJWCA9IFwiaW52b2NhdGlvbnNcIjtcblxuLyoqXG4gKiBXb3Jrc3BhY2UtbGV2ZWwgT3BlbkFJIFJlc3BvbnNlcyBBUEkgcGF0aC4gQm9keSBjYXJyaWVzIGBtb2RlbGAgKGVuZHBvaW50XG4gKiBpZCk7IHVzZWQgYnkgR1BUIC8gQ29kZXggbW9kZWxzIHRoYXQgc3BlYWsgUmVzcG9uc2VzIG5hdGl2ZWx5LlxuICovXG5leHBvcnQgY29uc3QgUkVTUE9OU0VTX1BBVEggPSBcInNlcnZpbmctZW5kcG9pbnRzL3Jlc3BvbnNlc1wiO1xuXG4vKipcbiAqIFdvcmtzcGFjZS1sZXZlbCBPcGVuIFJlc3BvbnNlcyBBUEkgcGF0aCAtIHRoZSBjcm9zcy1wcm92aWRlciBSZXNwb25zZXNcbiAqIHN1cmZhY2UgKENsYXVkZSwgR2VtaW5pLCDigKYpIHRoYXQgT3BlbkFJIGAvcmVzcG9uc2VzYCBkb2VzIG5vdCBjb3Zlci5cbiAqL1xuZXhwb3J0IGNvbnN0IE9QRU5fUkVTUE9OU0VTX1BBVEggPSBcInNlcnZpbmctZW5kcG9pbnRzL29wZW4tcmVzcG9uc2VzXCI7XG5cbi8qKlxuICogV29ya3NwYWNlLWxldmVsIE9wZW5BSSBDaGF0IENvbXBsZXRpb25zIHBhdGguIEJvZHkgY2FycmllcyBgbW9kZWxgIChlbmRwb2ludFxuICogaWQpLCB1bmxpa2Uge0BsaW5rIGludm9jYXRpb25zVXJsfSB3aGljaCBuYW1lcyB0aGUgZW5kcG9pbnQgaW4gdGhlIFVSTC4gVXNlXG4gKiB0aGlzIHdoZW4gdGhlIGNhbGxlciBoYXMgYSBtb2RlbCBpZCByYXRoZXIgdGhhbiBhIHBlci1lbmRwb2ludCByb3V0ZSAtIGUuZy5cbiAqIGF0dGFjaGluZyBhIHByb3ZpZGVyIHRvb2wgc3BlYyB0byB3aGljaGV2ZXIgZW5kcG9pbnQgd2FzIHJlc29sdmVkLlxuICovXG5leHBvcnQgY29uc3QgQ0hBVF9DT01QTEVUSU9OU19QQVRIID0gXCJzZXJ2aW5nLWVuZHBvaW50cy9jaGF0L2NvbXBsZXRpb25zXCI7XG5cbi8qKlxuICogVGhlIE9wZW5BSS1jb21wYXRpYmxlIGNoYXQtY29tcGxldGlvbnMgaW52b2NhdGlvbnMgVVJMIGZvciBhbiBlbmRwb2ludCBpZC5cbiAqXG4gKiBAcGFyYW0gaG9zdCAtIFdvcmtzcGFjZSBob3N0LCBlLmcuIGBodHRwczovL215LXdvcmtzcGFjZS5jbG91ZC5kYXRhYnJpY2tzLmNvbS9gLlxuICogICBQYXNzIHRoZSB2YWx1ZSByZXNvbHZlZCBmcm9tIGBjbGllbnQuY29uZmlnLmdldEhvc3QoKWAuXG4gKiBAcGFyYW0gZW5kcG9pbnQgLSBFbmRwb2ludCBpZCAoYWxyZWFkeSByZXNvbHZlZDsgbm90IGZ1enp5LW1hdGNoZWQgaGVyZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnZvY2F0aW9uc1VybChob3N0OiBzdHJpbmcsIGVuZHBvaW50OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChcbiAgICBgc2VydmluZy1lbmRwb2ludHMvJHtlbmNvZGVVUklDb21wb25lbnQoZW5kcG9pbnQpfS8ke0lOVk9DQVRJT05TX1NVRkZJWH1gLFxuICAgIGhvc3QsXG4gICkudG9TdHJpbmcoKTtcbn1cblxuLyoqIFdvcmtzcGFjZSBPcGVuQUkgUmVzcG9uc2VzIEFQSSBVUkwgKGBQT1NUYCwgbW9kZWwgaW4gdGhlIGJvZHkpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc3BvbnNlc1VybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChSRVNQT05TRVNfUEFUSCwgaG9zdCkudG9TdHJpbmcoKTtcbn1cblxuLyoqIFdvcmtzcGFjZSBPcGVuIFJlc3BvbnNlcyBBUEkgVVJMIChgUE9TVGAsIG1vZGVsIGluIHRoZSBib2R5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcGVuUmVzcG9uc2VzVXJsKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKE9QRU5fUkVTUE9OU0VTX1BBVEgsIGhvc3QpLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBXb3Jrc3BhY2UgT3BlbkFJIENoYXQgQ29tcGxldGlvbnMgVVJMIChgUE9TVGAsIG1vZGVsIGluIHRoZSBib2R5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGF0Q29tcGxldGlvbnNVcmwoaG9zdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldyBVUkwoQ0hBVF9DT01QTEVUSU9OU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKipcbiAqIFRydWUgd2hlbiB0aGUgZW5kcG9pbnQgaXMga25vd24gdG8gcmVqZWN0IENoYXQgQ29tcGxldGlvbnMgYC9pbnZvY2F0aW9uc2BcbiAqIGFuZCByZXF1aXJlIHRoZSBSZXNwb25zZXMgQVBJIChDb2RleCBtb2RlbHMgdG9kYXkpLiBDYWxsZXJzIHNob3VsZCByb3V0ZVxuICogdGhvc2UgdG8ge0BsaW5rIHJlc3BvbnNlc1VybH0gaW5zdGVhZCBvZiB7QGxpbmsgaW52b2NhdGlvbnNVcmx9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNSZXNwb25zZXNPbmx5KGVuZHBvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGlzUmVzcG9uc2VzT25seUJ5UG9saWN5KGVuZHBvaW50KTtcbn1cblxuLyoqXG4gKiBQaWNrIHRoZSBEYXRhYnJpY2tzIFJlc3BvbnNlcyB1cHN0cmVhbSBmb3IgYW4gZW5kcG9pbnQgaWQ6IE9wZW5BSS1mYW1pbHlcbiAqIG1vZGVscyB1c2UgYC9zZXJ2aW5nLWVuZHBvaW50cy9yZXNwb25zZXNgOyBldmVyeXRoaW5nIGVsc2UgdXNlcyB0aGVcbiAqIGNyb3NzLXByb3ZpZGVyIGAvc2VydmluZy1lbmRwb2ludHMvb3Blbi1yZXNwb25zZXNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzcG9uc2VzVXBzdHJlYW1VcmwoaG9zdDogc3RyaW5nLCBlbmRwb2ludDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGlzT3BlbkFpRmFtaWx5KGVuZHBvaW50KSA/IHJlc3BvbnNlc1VybChob3N0KSA6IG9wZW5SZXNwb25zZXNVcmwoaG9zdCk7XG59XG5cbi8qKiBHUFQgLyBDb2RleCAvIG8tc2VyaWVzIHN0eWxlIGVuZHBvaW50IG5hbWVzIHRoYXQgc3BlYWsgT3BlbkFJIFJlc3BvbnNlcy4gKi9cbmZ1bmN0aW9uIGlzT3BlbkFpRmFtaWx5KGVuZHBvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgbiA9IGVuZHBvaW50LnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiAoXG4gICAgbi5pbmNsdWRlcyhcImdwdFwiKSB8fFxuICAgIG4uaW5jbHVkZXMoXCJjb2RleFwiKSB8fFxuICAgIC8oXnxbXmEtel0pb1sxLTldKFteYS16XXwkKS8udGVzdChuKSB8fFxuICAgIG4uaW5jbHVkZXMoXCJvcGVuYWlcIilcbiAgKTtcbn1cblxuLyoqXG4gKiBNaW5pbWFsIHN0cnVjdHVyYWwgc2hhcGUge0BsaW5rIGF1dGhIZWFkZXJzfSBuZWVkcy4gRGVjbGFyZWQgbmFycm93bHkgcmF0aGVyXG4gKiB0aGFuIGFzIGEgZnVsbCBgV29ya3NwYWNlQ2xpZW50TGlrZWAgc28gYSBjYWxsZXIgaG9sZGluZyBpdHMgb3duXG4gKiBgQGRhdGFicmlja3Mvc2RrLWV4cGVyaW1lbnRhbGAgYFdvcmtzcGFjZUNsaWVudGAgc2F0aXNmaWVzIGl0IHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoaWNoIFNESyB2ZXJzaW9uIHJlc29sdmVkIGluIGl0cyB0cmVlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhlbnRpY2F0aW5nQ2xpZW50TGlrZSB7XG4gIGNvbmZpZzoge1xuICAgIGF1dGhlbnRpY2F0ZShoZWFkZXJzOiBIZWFkZXJzKTogUHJvbWlzZTx2b2lkPjtcbiAgfTtcbn1cblxuLyoqXG4gKiBNaW50IGF1dGggaGVhZGVycyBmb3Igb25lIHVwc3RyZWFtIHJlcXVlc3QgYXMgYSBwbGFpbiBvYmplY3QsIHJlYWR5IHRvIHNwcmVhZFxuICogaW50byBhIGBmZXRjaGAgaW5pdC4gQ2FsbCBpdCBwZXIgcmVxdWVzdDogdGhlIFNESyByZWZyZXNoZXMgdGhlIHVuZGVybHlpbmdcbiAqIHRva2VuIHdoZW4gbmVlZGVkLCBzbyBhIGxvbmctbGl2ZWQgcHJvY2VzcyBuZXZlciBoYXMgdG8gdHJhY2sgZXhwaXJ5IGl0c2VsZi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGF1dGhIZWFkZXJzKFxuICBjbGllbnQ6IEF1dGhlbnRpY2F0aW5nQ2xpZW50TGlrZSxcbik6IFByb21pc2U8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4ge1xuICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgYXdhaXQgY2xpZW50LmNvbmZpZy5hdXRoZW50aWNhdGUoaGVhZGVycyk7XG4gIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBoZWFkZXJzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICBvdXRba2V5XSA9IHZhbHVlO1xuICB9KTtcbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ==
117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52b2tlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludm9rZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLGVBQWUsSUFBSSx1QkFBdUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUV6RTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLGFBQWEsQ0FBQztBQUVoRDs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsNkJBQTZCLENBQUM7QUFFNUQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsa0NBQWtDLENBQUM7QUFFdEU7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxvQ0FBb0MsQ0FBQztBQUUxRSxtRkFBbUY7QUFDbkYsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQUcsK0JBQStCLENBQUM7QUFFL0Usb0VBQW9FO0FBQ3BFLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLHlDQUF5QyxDQUFDO0FBRWpGOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsSUFBWSxFQUFFLFFBQWdCO0lBQzNELE9BQU8sSUFBSSxHQUFHLENBQ1oscUJBQXFCLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxJQUFJLGtCQUFrQixFQUFFLEVBQ3pFLElBQUksQ0FDTCxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ2YsQ0FBQztBQUVELHNFQUFzRTtBQUN0RSxNQUFNLFVBQVUsWUFBWSxDQUFDLElBQVk7SUFDdkMsT0FBTyxJQUFJLEdBQUcsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDbEQsQ0FBQztBQUVELG9FQUFvRTtBQUNwRSxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsSUFBWTtJQUMzQyxPQUFPLElBQUksR0FBRyxDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ3ZELENBQUM7QUFFRCx5RUFBeUU7QUFDekUsTUFBTSxVQUFVLGtCQUFrQixDQUFDLElBQVk7SUFDN0MsT0FBTyxJQUFJLEdBQUcsQ0FBQyxxQkFBcUIsRUFBRSxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUN6RCxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxJQUFZO0lBQ3JELE9BQU8sSUFBSSxHQUFHLENBQUMsK0JBQStCLEVBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDbkUsQ0FBQztBQUVELG9FQUFvRTtBQUNwRSxNQUFNLFVBQVUsb0JBQW9CLENBQUMsSUFBWTtJQUMvQyxPQUFPLElBQUksR0FBRyxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQzNELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxRQUFnQjtJQUM5QyxPQUFPLHVCQUF1QixDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLElBQVksRUFBRSxRQUFnQjtJQUNqRSxPQUFPLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNoRixDQUFDO0FBRUQsK0VBQStFO0FBQy9FLFNBQVMsY0FBYyxDQUFDLFFBQWdCO0lBQ3RDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNqQyxPQUFPLENBQ0wsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDakIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7UUFDbkIsNEJBQTRCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNwQyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUNyQixDQUFDO0FBQ0osQ0FBQztBQWNEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFdBQVcsQ0FDL0IsTUFBZ0M7SUFFaEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztJQUM5QixNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFDLE1BQU0sR0FBRyxHQUEyQixFQUFFLENBQUM7SUFDdkMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUM3QixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ25CLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDYWxsaW5nIGEgTW9kZWwgU2VydmluZyBlbmRwb2ludCBkaXJlY3RseSBvdmVyIEhUVFAuXG4gKlxuICogVGhlIFNESydzIGBzZXJ2aW5nRW5kcG9pbnRzLnF1ZXJ5YCBjb3ZlcnMgdGhlIHR5cGVkIHJlcXVlc3Qgc2hhcGVzLCBidXQgYW5cbiAqIE9wZW5BSS1jb21wYXRpYmxlIGNhbGxlciAoYSBwcm94eSwgYSBwYXNzdGhyb3VnaCByb3V0ZSwgYSBzdHJlYW1pbmcgY2xpZW50KVxuICogbmVlZHMgdG8gaXNzdWUgaXRzIG93biBgZmV0Y2hgIGFnYWluc3QgRGF0YWJyaWNrcycgT3BlbkFJLXNoYXBlZCBVUkxzIHdpdGhcbiAqIGFuIE9wZW5BSSBib2R5LiBUaGF0IG5lZWRzIGV4YWN0bHkgdHdvIHRoaW5ncyB0aGUgU0RLIGRvZXNuJ3QgaGFuZCBvdXRcbiAqIGRpcmVjdGx5OiB0aGUgVVJMICh7QGxpbmsgaW52b2NhdGlvbnNVcmx9IC8ge0BsaW5rIHJlc3BvbnNlc1VybH0gL1xuICoge0BsaW5rIG9wZW5SZXNwb25zZXNVcmx9KSBhbmQgYSBjdXJyZW50bHktdmFsaWQgc2V0IG9mIGF1dGggaGVhZGVyc1xuICogKHtAbGluayBhdXRoSGVhZGVyc30pLlxuICpcbiAqIEF1dGggaXMgZGVsZWdhdGVkIGVudGlyZWx5IHRvIHRoZSBEYXRhYnJpY2tzIFNESzogYGNvbmZpZy5hdXRoZW50aWNhdGVgXG4gKiByZS1ydW5zIHRoZSBjb25maWd1cmVkIGNyZWRlbnRpYWwgcHJvdmlkZXIgb24gZXZlcnkgY2FsbCBhbmQgcmVmcmVzaGVzIHRoZVxuICogdW5kZXJseWluZyBPQXV0aCAvIFBBVCB0b2tlbiB3aGVuIGl0IGlzIGNsb3NlIHRvIGV4cGlyeSwgc28gYSBjYWxsZXIgbmV2ZXJcbiAqIG1hbmFnZXMgdG9rZW4gbGlmZXRpbWVzIGl0c2VsZiAtIG1pbnQgaGVhZGVycyBwZXIgcmVxdWVzdCBhbmQgZWFjaCBvbmUgaXNcbiAqIHNpZ25lZCB3aXRoIGEgdmFsaWQgYmVhcmVyIHRva2VuLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBpc1Jlc3BvbnNlc09ubHkgYXMgaXNSZXNwb25zZXNPbmx5QnlQb2xpY3kgfSBmcm9tIFwiLi9wb2xpY3kudHNcIjtcblxuLyoqXG4gKiBQYXRoIHNlZ21lbnQgYXBwZW5kZWQgdG8gYSBzZXJ2aW5nIGVuZHBvaW50IGZvciBPcGVuQUktY29tcGF0aWJsZSBjaGF0XG4gKiByZXF1ZXN0cy4gRGF0YWJyaWNrcyByb3V0ZXMgYC9zZXJ2aW5nLWVuZHBvaW50cy88bmFtZT4vaW52b2NhdGlvbnNgIHRvIHRoZVxuICogZW5kcG9pbnQncyBDaGF0IENvbXBsZXRpb25zIHN1cmZhY2UgKGBtZXNzYWdlc2AgaW4sIGBjaG9pY2VzYCBvdXQpLiBTb21lXG4gKiBtb2RlbHMgKG5vdGFibHkgQ29kZXgpIHJlamVjdCB0aGlzIHBhdGggYW5kIHJlcXVpcmUge0BsaW5rIHJlc3BvbnNlc1VybH0uXG4gKi9cbmV4cG9ydCBjb25zdCBJTlZPQ0FUSU9OU19TVUZGSVggPSBcImludm9jYXRpb25zXCI7XG5cbi8qKlxuICogV29ya3NwYWNlLWxldmVsIE9wZW5BSSBSZXNwb25zZXMgQVBJIHBhdGguIEJvZHkgY2FycmllcyBgbW9kZWxgIChlbmRwb2ludFxuICogaWQpOyB1c2VkIGJ5IEdQVCAvIENvZGV4IG1vZGVscyB0aGF0IHNwZWFrIFJlc3BvbnNlcyBuYXRpdmVseS5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFU1BPTlNFU19QQVRIID0gXCJzZXJ2aW5nLWVuZHBvaW50cy9yZXNwb25zZXNcIjtcblxuLyoqXG4gKiBXb3Jrc3BhY2UtbGV2ZWwgT3BlbiBSZXNwb25zZXMgQVBJIHBhdGggLSB0aGUgY3Jvc3MtcHJvdmlkZXIgUmVzcG9uc2VzXG4gKiBzdXJmYWNlIChDbGF1ZGUsIEdlbWluaSwg4oCmKSB0aGF0IE9wZW5BSSBgL3Jlc3BvbnNlc2AgZG9lcyBub3QgY292ZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBPUEVOX1JFU1BPTlNFU19QQVRIID0gXCJzZXJ2aW5nLWVuZHBvaW50cy9vcGVuLXJlc3BvbnNlc1wiO1xuXG4vKipcbiAqIFdvcmtzcGFjZS1sZXZlbCBPcGVuQUkgQ2hhdCBDb21wbGV0aW9ucyBwYXRoLiBCb2R5IGNhcnJpZXMgYG1vZGVsYCAoZW5kcG9pbnRcbiAqIGlkKSwgdW5saWtlIHtAbGluayBpbnZvY2F0aW9uc1VybH0gd2hpY2ggbmFtZXMgdGhlIGVuZHBvaW50IGluIHRoZSBVUkwuIFVzZVxuICogdGhpcyB3aGVuIHRoZSBjYWxsZXIgaGFzIGEgbW9kZWwgaWQgcmF0aGVyIHRoYW4gYSBwZXItZW5kcG9pbnQgcm91dGUgLSBlLmcuXG4gKiBhdHRhY2hpbmcgYSBwcm92aWRlciB0b29sIHNwZWMgdG8gd2hpY2hldmVyIGVuZHBvaW50IHdhcyByZXNvbHZlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IENIQVRfQ09NUExFVElPTlNfUEFUSCA9IFwic2VydmluZy1lbmRwb2ludHMvY2hhdC9jb21wbGV0aW9uc1wiO1xuXG4vKiogVW5pdHkgR2F0ZXdheSBPcGVuQUkgUmVzcG9uc2VzIHBhdGggdXNlZCBieSBDb2RleC1jb21wYXRpYmxlIG1vZGVsIHNlcnZpY2VzLiAqL1xuZXhwb3J0IGNvbnN0IEFJX0dBVEVXQVlfQ09ERVhfUkVTUE9OU0VTX1BBVEggPSBcImFpLWdhdGV3YXkvY29kZXgvdjEvcmVzcG9uc2VzXCI7XG5cbi8qKiBXb3Jrc3BhY2UgQW50aHJvcGljIE1lc3NhZ2VzIHBhdGggZm9yIG5hdGl2ZSBDbGF1ZGUgcmVxdWVzdHMuICovXG5leHBvcnQgY29uc3QgQU5USFJPUElDX01FU1NBR0VTX1BBVEggPSBcInNlcnZpbmctZW5kcG9pbnRzL2FudGhyb3BpYy92MS9tZXNzYWdlc1wiO1xuXG4vKipcbiAqIFRoZSBPcGVuQUktY29tcGF0aWJsZSBjaGF0LWNvbXBsZXRpb25zIGludm9jYXRpb25zIFVSTCBmb3IgYW4gZW5kcG9pbnQgaWQuXG4gKlxuICogQHBhcmFtIGhvc3QgLSBXb3Jrc3BhY2UgaG9zdCwgZS5nLiBgaHR0cHM6Ly9teS13b3Jrc3BhY2UuY2xvdWQuZGF0YWJyaWNrcy5jb20vYC5cbiAqICAgUGFzcyB0aGUgdmFsdWUgcmVzb2x2ZWQgZnJvbSBgY2xpZW50LmNvbmZpZy5nZXRIb3N0KClgLlxuICogQHBhcmFtIGVuZHBvaW50IC0gRW5kcG9pbnQgaWQgKGFscmVhZHkgcmVzb2x2ZWQ7IG5vdCBmdXp6eS1tYXRjaGVkIGhlcmUpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW52b2NhdGlvbnNVcmwoaG9zdDogc3RyaW5nLCBlbmRwb2ludDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldyBVUkwoXG4gICAgYHNlcnZpbmctZW5kcG9pbnRzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGVuZHBvaW50KX0vJHtJTlZPQ0FUSU9OU19TVUZGSVh9YCxcbiAgICBob3N0LFxuICApLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBXb3Jrc3BhY2UgT3BlbkFJIFJlc3BvbnNlcyBBUEkgVVJMIChgUE9TVGAsIG1vZGVsIGluIHRoZSBib2R5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNwb25zZXNVcmwoaG9zdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldyBVUkwoUkVTUE9OU0VTX1BBVEgsIGhvc3QpLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBXb3Jrc3BhY2UgT3BlbiBSZXNwb25zZXMgQVBJIFVSTCAoYFBPU1RgLCBtb2RlbCBpbiB0aGUgYm9keSkuICovXG5leHBvcnQgZnVuY3Rpb24gb3BlblJlc3BvbnNlc1VybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChPUEVOX1JFU1BPTlNFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKiogV29ya3NwYWNlIE9wZW5BSSBDaGF0IENvbXBsZXRpb25zIFVSTCAoYFBPU1RgLCBtb2RlbCBpbiB0aGUgYm9keSkuICovXG5leHBvcnQgZnVuY3Rpb24gY2hhdENvbXBsZXRpb25zVXJsKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKENIQVRfQ09NUExFVElPTlNfUEFUSCwgaG9zdCkudG9TdHJpbmcoKTtcbn1cblxuLyoqIFVuaXR5IEdhdGV3YXkgQ29kZXggUmVzcG9uc2VzIFVSTCAoYFBPU1RgLCBtb2RlbCBzZXJ2aWNlIGluIHRoZSBib2R5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhaUdhdGV3YXlDb2RleFJlc3BvbnNlc1VybChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFVSTChBSV9HQVRFV0FZX0NPREVYX1JFU1BPTlNFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKiogV29ya3NwYWNlIEFudGhyb3BpYyBNZXNzYWdlcyBVUkwgKGBQT1NUYCwgbW9kZWwgaW4gdGhlIGJvZHkpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFudGhyb3BpY01lc3NhZ2VzVXJsKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVVJMKEFOVEhST1BJQ19NRVNTQUdFU19QQVRILCBob3N0KS50b1N0cmluZygpO1xufVxuXG4vKipcbiAqIFRydWUgd2hlbiB0aGUgZW5kcG9pbnQgaXMga25vd24gdG8gcmVqZWN0IENoYXQgQ29tcGxldGlvbnMgYC9pbnZvY2F0aW9uc2BcbiAqIGFuZCByZXF1aXJlIHRoZSBSZXNwb25zZXMgQVBJIChDb2RleCBtb2RlbHMgdG9kYXkpLiBDYWxsZXJzIHNob3VsZCByb3V0ZVxuICogdGhvc2UgdG8ge0BsaW5rIHJlc3BvbnNlc1VybH0gaW5zdGVhZCBvZiB7QGxpbmsgaW52b2NhdGlvbnNVcmx9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNSZXNwb25zZXNPbmx5KGVuZHBvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGlzUmVzcG9uc2VzT25seUJ5UG9saWN5KGVuZHBvaW50KTtcbn1cblxuLyoqXG4gKiBQaWNrIHRoZSBEYXRhYnJpY2tzIFJlc3BvbnNlcyB1cHN0cmVhbSBmb3IgYW4gZW5kcG9pbnQgaWQ6IE9wZW5BSS1mYW1pbHlcbiAqIG1vZGVscyB1c2UgYC9zZXJ2aW5nLWVuZHBvaW50cy9yZXNwb25zZXNgOyBldmVyeXRoaW5nIGVsc2UgdXNlcyB0aGVcbiAqIGNyb3NzLXByb3ZpZGVyIGAvc2VydmluZy1lbmRwb2ludHMvb3Blbi1yZXNwb25zZXNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzcG9uc2VzVXBzdHJlYW1VcmwoaG9zdDogc3RyaW5nLCBlbmRwb2ludDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGlzT3BlbkFpRmFtaWx5KGVuZHBvaW50KSA/IHJlc3BvbnNlc1VybChob3N0KSA6IG9wZW5SZXNwb25zZXNVcmwoaG9zdCk7XG59XG5cbi8qKiBHUFQgLyBDb2RleCAvIG8tc2VyaWVzIHN0eWxlIGVuZHBvaW50IG5hbWVzIHRoYXQgc3BlYWsgT3BlbkFJIFJlc3BvbnNlcy4gKi9cbmZ1bmN0aW9uIGlzT3BlbkFpRmFtaWx5KGVuZHBvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgbiA9IGVuZHBvaW50LnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiAoXG4gICAgbi5pbmNsdWRlcyhcImdwdFwiKSB8fFxuICAgIG4uaW5jbHVkZXMoXCJjb2RleFwiKSB8fFxuICAgIC8oXnxbXmEtel0pb1sxLTldKFteYS16XXwkKS8udGVzdChuKSB8fFxuICAgIG4uaW5jbHVkZXMoXCJvcGVuYWlcIilcbiAgKTtcbn1cblxuLyoqXG4gKiBNaW5pbWFsIHN0cnVjdHVyYWwgc2hhcGUge0BsaW5rIGF1dGhIZWFkZXJzfSBuZWVkcy4gRGVjbGFyZWQgbmFycm93bHkgcmF0aGVyXG4gKiB0aGFuIGFzIGEgZnVsbCBgV29ya3NwYWNlQ2xpZW50TGlrZWAgc28gYSBjYWxsZXIgaG9sZGluZyBpdHMgb3duXG4gKiBgQGRhdGFicmlja3Mvc2RrLWV4cGVyaW1lbnRhbGAgYFdvcmtzcGFjZUNsaWVudGAgc2F0aXNmaWVzIGl0IHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoaWNoIFNESyB2ZXJzaW9uIHJlc29sdmVkIGluIGl0cyB0cmVlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhlbnRpY2F0aW5nQ2xpZW50TGlrZSB7XG4gIGNvbmZpZzoge1xuICAgIGF1dGhlbnRpY2F0ZShoZWFkZXJzOiBIZWFkZXJzKTogUHJvbWlzZTx2b2lkPjtcbiAgfTtcbn1cblxuLyoqXG4gKiBNaW50IGF1dGggaGVhZGVycyBmb3Igb25lIHVwc3RyZWFtIHJlcXVlc3QgYXMgYSBwbGFpbiBvYmplY3QsIHJlYWR5IHRvIHNwcmVhZFxuICogaW50byBhIGBmZXRjaGAgaW5pdC4gQ2FsbCBpdCBwZXIgcmVxdWVzdDogdGhlIFNESyByZWZyZXNoZXMgdGhlIHVuZGVybHlpbmdcbiAqIHRva2VuIHdoZW4gbmVlZGVkLCBzbyBhIGxvbmctbGl2ZWQgcHJvY2VzcyBuZXZlciBoYXMgdG8gdHJhY2sgZXhwaXJ5IGl0c2VsZi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGF1dGhIZWFkZXJzKFxuICBjbGllbnQ6IEF1dGhlbnRpY2F0aW5nQ2xpZW50TGlrZSxcbik6IFByb21pc2U8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4ge1xuICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgYXdhaXQgY2xpZW50LmNvbmZpZy5hdXRoZW50aWNhdGUoaGVhZGVycyk7XG4gIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBoZWFkZXJzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICBvdXRba2V5XSA9IHZhbHVlO1xuICB9KTtcbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ==
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Agnostic daily metadata cache on {@link https://www.npmjs.com/package/cacache | cacache}.
3
+ *
4
+ * Uses cacache's built-in memory memoization (`memoize: true` on put; gets read
5
+ * the in-memory layer by default) with content-addressed disk under
6
+ * `env-paths("dbx-tools").cache/model-gateway/<version>/`. Disk persistence is
7
+ * disabled inside a Databricks App ({@link environmentUtils.isDatabricksAppEnv});
8
+ * those processes keep a process-local Map only.
9
+ *
10
+ * Each cache owns a key, hard-coded fallback, optional network loader, and a
11
+ * merger that combines fresh / previous / fallback values. Freshness is the
12
+ * envelope `refreshedAt` window (default one day), not cacache's short LRU TTL.
13
+ *
14
+ * @module
15
+ */
16
+ /** Envelope stored as JSON bytes in cacache for every key. */
17
+ export interface MetadataCacheRecord<T> {
18
+ readonly refreshedAt: number;
19
+ readonly value: T;
20
+ }
21
+ /** Factory inputs for one named metadata cache. */
22
+ export interface MetadataCacheOptions<T> {
23
+ /** Stable cacache key. */
24
+ readonly key: string;
25
+ /** Hard-coded / committed baseline used when store and load both miss. */
26
+ readonly fallback: T;
27
+ /**
28
+ * Refresh source. When omitted the cache only serves store + fallback and
29
+ * {@link MetadataCache.update} mutations (for example error-learned values).
30
+ */
31
+ readonly load?: () => Promise<T>;
32
+ /** Combine a fresh load, prior store value, and the hard-coded fallback. */
33
+ readonly merge: (input: MetadataCacheMergeInput<T>) => T;
34
+ /** Freshness window; defaults to {@link MODEL_METADATA_TTL_MS} (one day). */
35
+ readonly ttlMs?: number;
36
+ /** Package version segment in the cache path. Defaults to this package. */
37
+ readonly version?: string;
38
+ /** Override the cacache root directory (tests). */
39
+ readonly cacheDir?: string;
40
+ /**
41
+ * Force disk on/off. Defaults to off inside Databricks Apps, on otherwise.
42
+ */
43
+ readonly disk?: boolean;
44
+ /** Clock override for tests. */
45
+ readonly now?: () => number;
46
+ }
47
+ /** Arguments passed to a cache merger. */
48
+ export interface MetadataCacheMergeInput<T> {
49
+ readonly fresh: T | undefined;
50
+ readonly previous: T | undefined;
51
+ readonly fallback: T;
52
+ }
53
+ /** One versioned metadata cache (cacache memory + optional disk). */
54
+ export interface MetadataCache<T> {
55
+ /** Absolute cacache root for this package version (unused when disk is off). */
56
+ readonly path: string;
57
+ /** Whether cacache disk persistence is enabled for this instance. */
58
+ readonly diskEnabled: boolean;
59
+ /** Return a fresh-or-fallback value, refreshing when stale. */
60
+ get(): Promise<T>;
61
+ /** Read memory / disk without refreshing. */
62
+ peek(): Promise<T | undefined>;
63
+ /** Mutate the cached value and persist it. */
64
+ update(mutator: (current: T) => T): Promise<T>;
65
+ /** Force a refresh attempt even when the entry is still fresh. */
66
+ refresh(): Promise<T>;
67
+ }
68
+ /** Default cacache root for a package version under the dbx-tools cache dir. */
69
+ export declare function defaultMetadataCacheDir(version: string): string;
70
+ /** Whether metadata caches should persist to disk in this process. */
71
+ export declare function metadataCacheDiskEnabled(environment?: NodeJS.ProcessEnv): boolean;
72
+ /**
73
+ * Create one daily cache backed by cacache memoization, with optional disk.
74
+ */
75
+ export declare function createMetadataCache<T>(options: MetadataCacheOptions<T>): MetadataCache<T>;
76
+ /** Prefer a non-empty fresh array, else previous, else fallback. */
77
+ export declare function mergePreferFreshList<T>(input: MetadataCacheMergeInput<readonly T[]>): T[];
78
+ /**
79
+ * Shallow-merge record catalogues: fallback, then previous, then fresh keys.
80
+ * Fresh values win per key.
81
+ */
82
+ export declare function mergePreferFreshRecord<T>(input: MetadataCacheMergeInput<Readonly<Record<string, T>>>): Record<string, T>;
83
+ /** Test helper: wipe a cacache root and clear cacache memoization. */
84
+ export declare function resetMetadataCacheDir(cacheDir: string): Promise<void>;
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Agnostic daily metadata cache on {@link https://www.npmjs.com/package/cacache | cacache}.
3
+ *
4
+ * Uses cacache's built-in memory memoization (`memoize: true` on put; gets read
5
+ * the in-memory layer by default) with content-addressed disk under
6
+ * `env-paths("dbx-tools").cache/model-gateway/<version>/`. Disk persistence is
7
+ * disabled inside a Databricks App ({@link environmentUtils.isDatabricksAppEnv});
8
+ * those processes keep a process-local Map only.
9
+ *
10
+ * Each cache owns a key, hard-coded fallback, optional network loader, and a
11
+ * merger that combines fresh / previous / fallback values. Freshness is the
12
+ * envelope `refreshedAt` window (default one day), not cacache's short LRU TTL.
13
+ *
14
+ * @module
15
+ */
16
+ import { resolve } from "node:path";
17
+ import * as environmentUtils from "@dbx-tools/shared-core/environment-utils";
18
+ import * as log from "@dbx-tools/shared-core/log";
19
+ import cacache from "cacache";
20
+ import envPaths from "env-paths";
21
+ import { MODEL_METADATA_TTL_MS } from "./_metadata-contract.js";
22
+ const logger = log.logger("model/metadata-cache");
23
+ const inflight = new Map();
24
+ /** Default cacache root for a package version under the dbx-tools cache dir. */
25
+ export function defaultMetadataCacheDir(version) {
26
+ const cacheDirectory = envPaths("dbx-tools", { suffix: "" }).cache;
27
+ return resolve(cacheDirectory, "model-gateway", version);
28
+ }
29
+ /** Whether metadata caches should persist to disk in this process. */
30
+ export function metadataCacheDiskEnabled(environment = process.env) {
31
+ return !environmentUtils.isDatabricksAppEnv(environment);
32
+ }
33
+ /**
34
+ * Create one daily cache backed by cacache memoization, with optional disk.
35
+ */
36
+ export function createMetadataCache(options) {
37
+ const ttlMs = options.ttlMs ?? MODEL_METADATA_TTL_MS;
38
+ const diskEnabled = options.disk ?? metadataCacheDiskEnabled();
39
+ const now = options.now ?? Date.now;
40
+ const pathPromise = resolveCacheDir(options);
41
+ let path = options.cacheDir;
42
+ const flightKey = (cachePath, suffix = "") => `${cachePath}::${options.key}${suffix}`;
43
+ /** Process-local store used when disk is off (Databricks Apps). */
44
+ const memoryOnly = new Map();
45
+ const resolveValue = (input) => options.merge(input);
46
+ const isFresh = (record) => Boolean(record && now() - record.refreshedAt < ttlMs);
47
+ const cachePath = async () => {
48
+ path ??= await pathPromise;
49
+ return path;
50
+ };
51
+ const readRecord = async () => {
52
+ if (!diskEnabled)
53
+ return memoryOnly.get(options.key);
54
+ const resolvedPath = await cachePath();
55
+ try {
56
+ // cacache reads its in-memory memo first unless memoize is false
57
+ const entry = await cacache.get(resolvedPath, options.key);
58
+ return decodeRecord(entry.data);
59
+ }
60
+ catch (error) {
61
+ if (isCacheMiss(error))
62
+ return undefined;
63
+ logger.warn("metadata cache cacache read failed", {
64
+ key: options.key,
65
+ path: resolvedPath,
66
+ error,
67
+ });
68
+ return undefined;
69
+ }
70
+ };
71
+ const writeRecord = async (record) => {
72
+ if (!diskEnabled) {
73
+ memoryOnly.set(options.key, record);
74
+ return;
75
+ }
76
+ const resolvedPath = await cachePath();
77
+ try {
78
+ await cacache.put(resolvedPath, options.key, `${JSON.stringify(record)}\n`, {
79
+ memoize: true,
80
+ metadata: { refreshedAt: record.refreshedAt },
81
+ });
82
+ }
83
+ catch (error) {
84
+ logger.warn("metadata cache cacache write failed", {
85
+ key: options.key,
86
+ path: resolvedPath,
87
+ error,
88
+ });
89
+ }
90
+ };
91
+ const persist = async (value, refreshedAt = now()) => {
92
+ await writeRecord({ refreshedAt, value });
93
+ return value;
94
+ };
95
+ const refresh = async (force) => {
96
+ const resolvedPath = await cachePath();
97
+ return coalesce(flightKey(resolvedPath), async () => {
98
+ const previous = await readRecord();
99
+ if (!force && isFresh(previous)) {
100
+ return resolveValue({
101
+ fresh: undefined,
102
+ previous: previous?.value,
103
+ fallback: options.fallback,
104
+ });
105
+ }
106
+ let fresh;
107
+ if (options.load) {
108
+ try {
109
+ fresh = await options.load();
110
+ }
111
+ catch (error) {
112
+ logger.warn("metadata cache refresh failed; keeping last known good", {
113
+ key: options.key,
114
+ error,
115
+ path: resolvedPath,
116
+ diskEnabled,
117
+ });
118
+ }
119
+ }
120
+ const value = resolveValue({
121
+ fresh,
122
+ previous: previous?.value,
123
+ fallback: options.fallback,
124
+ });
125
+ if (fresh !== undefined || !previous) {
126
+ await persist(value);
127
+ }
128
+ return value;
129
+ });
130
+ };
131
+ return {
132
+ get path() {
133
+ if (!path) {
134
+ throw new Error("metadata cache path is not resolved until the first cache read");
135
+ }
136
+ return path;
137
+ },
138
+ diskEnabled,
139
+ get: () => refresh(false),
140
+ peek: async () => (await readRecord())?.value,
141
+ refresh: () => refresh(true),
142
+ update: async (mutator) => {
143
+ const resolvedPath = await cachePath();
144
+ return coalesce(flightKey(resolvedPath, ":update"), async () => {
145
+ const previous = await readRecord();
146
+ const baseline = resolveValue({
147
+ fresh: undefined,
148
+ previous: previous?.value,
149
+ fallback: options.fallback,
150
+ });
151
+ return persist(mutator(baseline));
152
+ });
153
+ },
154
+ };
155
+ }
156
+ async function resolveCacheDir(options) {
157
+ if (options.cacheDir)
158
+ return options.cacheDir;
159
+ const version = options.version ?? (await import("../index.js")).PACKAGE_VERSION;
160
+ return defaultMetadataCacheDir(version);
161
+ }
162
+ /** Prefer a non-empty fresh array, else previous, else fallback. */
163
+ export function mergePreferFreshList(input) {
164
+ if (input.fresh && input.fresh.length > 0)
165
+ return [...input.fresh];
166
+ if (input.previous && input.previous.length > 0)
167
+ return [...input.previous];
168
+ return [...input.fallback];
169
+ }
170
+ /**
171
+ * Shallow-merge record catalogues: fallback, then previous, then fresh keys.
172
+ * Fresh values win per key.
173
+ */
174
+ export function mergePreferFreshRecord(input) {
175
+ return {
176
+ ...input.fallback,
177
+ ...(input.previous ?? {}),
178
+ ...(input.fresh ?? {}),
179
+ };
180
+ }
181
+ /** Test helper: wipe a cacache root and clear cacache memoization. */
182
+ export async function resetMetadataCacheDir(cacheDir) {
183
+ try {
184
+ await cacache.rm.all(cacheDir);
185
+ }
186
+ catch {
187
+ // empty / missing cache is fine
188
+ }
189
+ cacache.clearMemoized();
190
+ for (const key of [...inflight.keys()]) {
191
+ if (key.startsWith(`${cacheDir}::`))
192
+ inflight.delete(key);
193
+ }
194
+ }
195
+ function coalesce(key, work) {
196
+ const existing = inflight.get(key);
197
+ if (existing)
198
+ return existing;
199
+ const pending = work().finally(() => {
200
+ if (inflight.get(key) === pending)
201
+ inflight.delete(key);
202
+ });
203
+ inflight.set(key, pending);
204
+ return pending;
205
+ }
206
+ function decodeRecord(data) {
207
+ try {
208
+ const parsed = JSON.parse(data.toString("utf8"));
209
+ if (!parsed ||
210
+ typeof parsed !== "object" ||
211
+ typeof parsed.refreshedAt !== "number") {
212
+ return undefined;
213
+ }
214
+ return parsed;
215
+ }
216
+ catch {
217
+ return undefined;
218
+ }
219
+ }
220
+ function isCacheMiss(error) {
221
+ return Boolean(error &&
222
+ typeof error === "object" &&
223
+ "code" in error &&
224
+ error.code === "ENOENT");
225
+ }
226
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YWRhdGEtY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWV0YWRhdGEtY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXBDLE9BQU8sS0FBSyxnQkFBZ0IsTUFBTSwwQ0FBMEMsQ0FBQztBQUM3RSxPQUFPLEtBQUssR0FBRyxNQUFNLDRCQUE0QixDQUFDO0FBQ2xELE9BQU8sT0FBTyxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLFFBQVEsTUFBTSxXQUFXLENBQUM7QUFFakMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFaEUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBMERsRCxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBNEIsQ0FBQztBQUVyRCxnRkFBZ0Y7QUFDaEYsTUFBTSxVQUFVLHVCQUF1QixDQUFDLE9BQWU7SUFDckQsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUNuRSxPQUFPLE9BQU8sQ0FBQyxjQUFjLEVBQUUsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFFRCxzRUFBc0U7QUFDdEUsTUFBTSxVQUFVLHdCQUF3QixDQUFDLGNBQWlDLE9BQU8sQ0FBQyxHQUFHO0lBQ25GLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQUksT0FBZ0M7SUFDckUsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssSUFBSSxxQkFBcUIsQ0FBQztJQUNyRCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxJQUFJLHdCQUF3QixFQUFFLENBQUM7SUFDL0QsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ3BDLE1BQU0sV0FBVyxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO0lBRTVCLE1BQU0sU0FBUyxHQUFHLENBQUMsU0FBaUIsRUFBRSxNQUFNLEdBQUcsRUFBRSxFQUFVLEVBQUUsQ0FDM0QsR0FBRyxTQUFTLEtBQUssT0FBTyxDQUFDLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQztJQUUxQyxtRUFBbUU7SUFDbkUsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQWtDLENBQUM7SUFFN0QsTUFBTSxZQUFZLEdBQUcsQ0FBQyxLQUFpQyxFQUFLLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRXBGLE1BQU0sT0FBTyxHQUFHLENBQUMsTUFBMEMsRUFBVyxFQUFFLENBQ3RFLE9BQU8sQ0FBQyxNQUFNLElBQUksR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsQ0FBQztJQUV4RCxNQUFNLFNBQVMsR0FBRyxLQUFLLElBQXFCLEVBQUU7UUFDNUMsSUFBSSxLQUFLLE1BQU0sV0FBVyxDQUFDO1FBQzNCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQyxDQUFDO0lBRUYsTUFBTSxVQUFVLEdBQUcsS0FBSyxJQUFpRCxFQUFFO1FBQ3pFLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTyxVQUFVLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyRCxNQUFNLFlBQVksR0FBRyxNQUFNLFNBQVMsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQztZQUNILGlFQUFpRTtZQUNqRSxNQUFNLEtBQUssR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzRCxPQUFPLFlBQVksQ0FBSSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUM7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDekMsTUFBTSxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsRUFBRTtnQkFDaEQsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHO2dCQUNoQixJQUFJLEVBQUUsWUFBWTtnQkFDbEIsS0FBSzthQUNOLENBQUMsQ0FBQztZQUNILE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRixNQUFNLFdBQVcsR0FBRyxLQUFLLEVBQUUsTUFBOEIsRUFBaUIsRUFBRTtRQUMxRSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsVUFBVSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxZQUFZLEdBQUcsTUFBTSxTQUFTLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUM7WUFDSCxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUU7Z0JBQzFFLE9BQU8sRUFBRSxJQUFJO2dCQUNiLFFBQVEsRUFBRSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFO2FBQzlDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsRUFBRTtnQkFDakQsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHO2dCQUNoQixJQUFJLEVBQUUsWUFBWTtnQkFDbEIsS0FBSzthQUNOLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRixNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsS0FBUSxFQUFFLFdBQVcsR0FBRyxHQUFHLEVBQUUsRUFBYyxFQUFFO1FBQ2xFLE1BQU0sV0FBVyxDQUFDLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDMUMsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDLENBQUM7SUFFRixNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsS0FBYyxFQUFjLEVBQUU7UUFDbkQsTUFBTSxZQUFZLEdBQUcsTUFBTSxTQUFTLEVBQUUsQ0FBQztRQUN2QyxPQUFPLFFBQVEsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDbEQsTUFBTSxRQUFRLEdBQUcsTUFBTSxVQUFVLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsS0FBSyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUNoQyxPQUFPLFlBQVksQ0FBQztvQkFDbEIsS0FBSyxFQUFFLFNBQVM7b0JBQ2hCLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSztvQkFDekIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO2lCQUMzQixDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsSUFBSSxLQUFvQixDQUFDO1lBQ3pCLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNqQixJQUFJLENBQUM7b0JBQ0gsS0FBSyxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUMvQixDQUFDO2dCQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7b0JBQ2YsTUFBTSxDQUFDLElBQUksQ0FBQyx3REFBd0QsRUFBRTt3QkFDcEUsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHO3dCQUNoQixLQUFLO3dCQUNMLElBQUksRUFBRSxZQUFZO3dCQUNsQixXQUFXO3FCQUNaLENBQUMsQ0FBQztnQkFDTCxDQUFDO1lBQ0gsQ0FBQztZQUVELE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQztnQkFDekIsS0FBSztnQkFDTCxRQUFRLEVBQUUsUUFBUSxFQUFFLEtBQUs7Z0JBQ3pCLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUTthQUMzQixDQUFDLENBQUM7WUFDSCxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkIsQ0FBQztZQUNELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUM7SUFFRixPQUFPO1FBQ0wsSUFBSSxJQUFJO1lBQ04sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNWLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0VBQWdFLENBQUMsQ0FBQztZQUNwRixDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsV0FBVztRQUNYLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQ3pCLElBQUksRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxVQUFVLEVBQUUsQ0FBQyxFQUFFLEtBQUs7UUFDN0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDNUIsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUN4QixNQUFNLFlBQVksR0FBRyxNQUFNLFNBQVMsRUFBRSxDQUFDO1lBQ3ZDLE9BQU8sUUFBUSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsU0FBUyxDQUFDLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQzdELE1BQU0sUUFBUSxHQUFHLE1BQU0sVUFBVSxFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQztvQkFDNUIsS0FBSyxFQUFFLFNBQVM7b0JBQ2hCLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSztvQkFDekIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO2lCQUMzQixDQUFDLENBQUM7Z0JBQ0gsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRCxLQUFLLFVBQVUsZUFBZSxDQUFDLE9BRzlCO0lBQ0MsSUFBSSxPQUFPLENBQUMsUUFBUTtRQUFFLE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQztJQUM5QyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxJQUFJLENBQUMsTUFBTSxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUM7SUFDakYsT0FBTyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUMxQyxDQUFDO0FBRUQsb0VBQW9FO0FBQ3BFLE1BQU0sVUFBVSxvQkFBb0IsQ0FBSSxLQUE0QztJQUNsRixJQUFJLEtBQUssQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQztRQUFFLE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNuRSxJQUFJLEtBQUssQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQztRQUFFLE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1RSxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDN0IsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxzQkFBc0IsQ0FDcEMsS0FBMkQ7SUFFM0QsT0FBTztRQUNMLEdBQUcsS0FBSyxDQUFDLFFBQVE7UUFDakIsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDO1FBQ3pCLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztLQUN2QixDQUFDO0FBQ0osQ0FBQztBQUVELHNFQUFzRTtBQUN0RSxNQUFNLENBQUMsS0FBSyxVQUFVLHFCQUFxQixDQUFDLFFBQWdCO0lBQzFELElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLGdDQUFnQztJQUNsQyxDQUFDO0lBQ0QsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3hCLEtBQUssTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDdkMsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsUUFBUSxJQUFJLENBQUM7WUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVELENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUksR0FBVyxFQUFFLElBQXNCO0lBQ3RELE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbkMsSUFBSSxRQUFRO1FBQUUsT0FBTyxRQUFzQixDQUFDO0lBQzVDLE1BQU0sT0FBTyxHQUFHLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7UUFDbEMsSUFBSSxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLE9BQU87WUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzFELENBQUMsQ0FBQyxDQUFDO0lBQ0gsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDM0IsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFJLElBQVk7SUFDbkMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFZLENBQUM7UUFDNUQsSUFDRSxDQUFDLE1BQU07WUFDUCxPQUFPLE1BQU0sS0FBSyxRQUFRO1lBQzFCLE9BQVEsTUFBaUMsQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUNsRSxDQUFDO1lBQ0QsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUNELE9BQU8sTUFBZ0MsQ0FBQztJQUMxQyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxLQUFjO0lBQ2pDLE9BQU8sT0FBTyxDQUNaLEtBQUs7UUFDTCxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQ3pCLE1BQU0sSUFBSSxLQUFLO1FBQ2QsS0FBMkIsQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUMvQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQWdub3N0aWMgZGFpbHkgbWV0YWRhdGEgY2FjaGUgb24ge0BsaW5rIGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2NhY2FjaGUgfCBjYWNhY2hlfS5cbiAqXG4gKiBVc2VzIGNhY2FjaGUncyBidWlsdC1pbiBtZW1vcnkgbWVtb2l6YXRpb24gKGBtZW1vaXplOiB0cnVlYCBvbiBwdXQ7IGdldHMgcmVhZFxuICogdGhlIGluLW1lbW9yeSBsYXllciBieSBkZWZhdWx0KSB3aXRoIGNvbnRlbnQtYWRkcmVzc2VkIGRpc2sgdW5kZXJcbiAqIGBlbnYtcGF0aHMoXCJkYngtdG9vbHNcIikuY2FjaGUvbW9kZWwtZ2F0ZXdheS88dmVyc2lvbj4vYC4gRGlzayBwZXJzaXN0ZW5jZSBpc1xuICogZGlzYWJsZWQgaW5zaWRlIGEgRGF0YWJyaWNrcyBBcHAgKHtAbGluayBlbnZpcm9ubWVudFV0aWxzLmlzRGF0YWJyaWNrc0FwcEVudn0pO1xuICogdGhvc2UgcHJvY2Vzc2VzIGtlZXAgYSBwcm9jZXNzLWxvY2FsIE1hcCBvbmx5LlxuICpcbiAqIEVhY2ggY2FjaGUgb3ducyBhIGtleSwgaGFyZC1jb2RlZCBmYWxsYmFjaywgb3B0aW9uYWwgbmV0d29yayBsb2FkZXIsIGFuZCBhXG4gKiBtZXJnZXIgdGhhdCBjb21iaW5lcyBmcmVzaCAvIHByZXZpb3VzIC8gZmFsbGJhY2sgdmFsdWVzLiBGcmVzaG5lc3MgaXMgdGhlXG4gKiBlbnZlbG9wZSBgcmVmcmVzaGVkQXRgIHdpbmRvdyAoZGVmYXVsdCBvbmUgZGF5KSwgbm90IGNhY2FjaGUncyBzaG9ydCBMUlUgVFRMLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuXG5pbXBvcnQgKiBhcyBlbnZpcm9ubWVudFV0aWxzIGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlL2Vudmlyb25tZW50LXV0aWxzXCI7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmUvbG9nXCI7XG5pbXBvcnQgY2FjYWNoZSBmcm9tIFwiY2FjYWNoZVwiO1xuaW1wb3J0IGVudlBhdGhzIGZyb20gXCJlbnYtcGF0aHNcIjtcblxuaW1wb3J0IHsgTU9ERUxfTUVUQURBVEFfVFRMX01TIH0gZnJvbSBcIi4vX21ldGFkYXRhLWNvbnRyYWN0LnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtb2RlbC9tZXRhZGF0YS1jYWNoZVwiKTtcblxuLyoqIEVudmVsb3BlIHN0b3JlZCBhcyBKU09OIGJ5dGVzIGluIGNhY2FjaGUgZm9yIGV2ZXJ5IGtleS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0YWRhdGFDYWNoZVJlY29yZDxUPiB7XG4gIHJlYWRvbmx5IHJlZnJlc2hlZEF0OiBudW1iZXI7XG4gIHJlYWRvbmx5IHZhbHVlOiBUO1xufVxuXG4vKiogRmFjdG9yeSBpbnB1dHMgZm9yIG9uZSBuYW1lZCBtZXRhZGF0YSBjYWNoZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0YWRhdGFDYWNoZU9wdGlvbnM8VD4ge1xuICAvKiogU3RhYmxlIGNhY2FjaGUga2V5LiAqL1xuICByZWFkb25seSBrZXk6IHN0cmluZztcbiAgLyoqIEhhcmQtY29kZWQgLyBjb21taXR0ZWQgYmFzZWxpbmUgdXNlZCB3aGVuIHN0b3JlIGFuZCBsb2FkIGJvdGggbWlzcy4gKi9cbiAgcmVhZG9ubHkgZmFsbGJhY2s6IFQ7XG4gIC8qKlxuICAgKiBSZWZyZXNoIHNvdXJjZS4gV2hlbiBvbWl0dGVkIHRoZSBjYWNoZSBvbmx5IHNlcnZlcyBzdG9yZSArIGZhbGxiYWNrIGFuZFxuICAgKiB7QGxpbmsgTWV0YWRhdGFDYWNoZS51cGRhdGV9IG11dGF0aW9ucyAoZm9yIGV4YW1wbGUgZXJyb3ItbGVhcm5lZCB2YWx1ZXMpLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9hZD86ICgpID0+IFByb21pc2U8VD47XG4gIC8qKiBDb21iaW5lIGEgZnJlc2ggbG9hZCwgcHJpb3Igc3RvcmUgdmFsdWUsIGFuZCB0aGUgaGFyZC1jb2RlZCBmYWxsYmFjay4gKi9cbiAgcmVhZG9ubHkgbWVyZ2U6IChpbnB1dDogTWV0YWRhdGFDYWNoZU1lcmdlSW5wdXQ8VD4pID0+IFQ7XG4gIC8qKiBGcmVzaG5lc3Mgd2luZG93OyBkZWZhdWx0cyB0byB7QGxpbmsgTU9ERUxfTUVUQURBVEFfVFRMX01TfSAob25lIGRheSkuICovXG4gIHJlYWRvbmx5IHR0bE1zPzogbnVtYmVyO1xuICAvKiogUGFja2FnZSB2ZXJzaW9uIHNlZ21lbnQgaW4gdGhlIGNhY2hlIHBhdGguIERlZmF1bHRzIHRvIHRoaXMgcGFja2FnZS4gKi9cbiAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcbiAgLyoqIE92ZXJyaWRlIHRoZSBjYWNhY2hlIHJvb3QgZGlyZWN0b3J5ICh0ZXN0cykuICovXG4gIHJlYWRvbmx5IGNhY2hlRGlyPzogc3RyaW5nO1xuICAvKipcbiAgICogRm9yY2UgZGlzayBvbi9vZmYuIERlZmF1bHRzIHRvIG9mZiBpbnNpZGUgRGF0YWJyaWNrcyBBcHBzLCBvbiBvdGhlcndpc2UuXG4gICAqL1xuICByZWFkb25seSBkaXNrPzogYm9vbGVhbjtcbiAgLyoqIENsb2NrIG92ZXJyaWRlIGZvciB0ZXN0cy4gKi9cbiAgcmVhZG9ubHkgbm93PzogKCkgPT4gbnVtYmVyO1xufVxuXG4vKiogQXJndW1lbnRzIHBhc3NlZCB0byBhIGNhY2hlIG1lcmdlci4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0YWRhdGFDYWNoZU1lcmdlSW5wdXQ8VD4ge1xuICByZWFkb25seSBmcmVzaDogVCB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgcHJldmlvdXM6IFQgfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IGZhbGxiYWNrOiBUO1xufVxuXG4vKiogT25lIHZlcnNpb25lZCBtZXRhZGF0YSBjYWNoZSAoY2FjYWNoZSBtZW1vcnkgKyBvcHRpb25hbCBkaXNrKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0YWRhdGFDYWNoZTxUPiB7XG4gIC8qKiBBYnNvbHV0ZSBjYWNhY2hlIHJvb3QgZm9yIHRoaXMgcGFja2FnZSB2ZXJzaW9uICh1bnVzZWQgd2hlbiBkaXNrIGlzIG9mZikuICovXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcbiAgLyoqIFdoZXRoZXIgY2FjYWNoZSBkaXNrIHBlcnNpc3RlbmNlIGlzIGVuYWJsZWQgZm9yIHRoaXMgaW5zdGFuY2UuICovXG4gIHJlYWRvbmx5IGRpc2tFbmFibGVkOiBib29sZWFuO1xuICAvKiogUmV0dXJuIGEgZnJlc2gtb3ItZmFsbGJhY2sgdmFsdWUsIHJlZnJlc2hpbmcgd2hlbiBzdGFsZS4gKi9cbiAgZ2V0KCk6IFByb21pc2U8VD47XG4gIC8qKiBSZWFkIG1lbW9yeSAvIGRpc2sgd2l0aG91dCByZWZyZXNoaW5nLiAqL1xuICBwZWVrKCk6IFByb21pc2U8VCB8IHVuZGVmaW5lZD47XG4gIC8qKiBNdXRhdGUgdGhlIGNhY2hlZCB2YWx1ZSBhbmQgcGVyc2lzdCBpdC4gKi9cbiAgdXBkYXRlKG11dGF0b3I6IChjdXJyZW50OiBUKSA9PiBUKTogUHJvbWlzZTxUPjtcbiAgLyoqIEZvcmNlIGEgcmVmcmVzaCBhdHRlbXB0IGV2ZW4gd2hlbiB0aGUgZW50cnkgaXMgc3RpbGwgZnJlc2guICovXG4gIHJlZnJlc2goKTogUHJvbWlzZTxUPjtcbn1cblxuY29uc3QgaW5mbGlnaHQgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx1bmtub3duPj4oKTtcblxuLyoqIERlZmF1bHQgY2FjYWNoZSByb290IGZvciBhIHBhY2thZ2UgdmVyc2lvbiB1bmRlciB0aGUgZGJ4LXRvb2xzIGNhY2hlIGRpci4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0TWV0YWRhdGFDYWNoZURpcih2ZXJzaW9uOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBjYWNoZURpcmVjdG9yeSA9IGVudlBhdGhzKFwiZGJ4LXRvb2xzXCIsIHsgc3VmZml4OiBcIlwiIH0pLmNhY2hlO1xuICByZXR1cm4gcmVzb2x2ZShjYWNoZURpcmVjdG9yeSwgXCJtb2RlbC1nYXRld2F5XCIsIHZlcnNpb24pO1xufVxuXG4vKiogV2hldGhlciBtZXRhZGF0YSBjYWNoZXMgc2hvdWxkIHBlcnNpc3QgdG8gZGlzayBpbiB0aGlzIHByb2Nlc3MuICovXG5leHBvcnQgZnVuY3Rpb24gbWV0YWRhdGFDYWNoZURpc2tFbmFibGVkKGVudmlyb25tZW50OiBOb2RlSlMuUHJvY2Vzc0VudiA9IHByb2Nlc3MuZW52KTogYm9vbGVhbiB7XG4gIHJldHVybiAhZW52aXJvbm1lbnRVdGlscy5pc0RhdGFicmlja3NBcHBFbnYoZW52aXJvbm1lbnQpO1xufVxuXG4vKipcbiAqIENyZWF0ZSBvbmUgZGFpbHkgY2FjaGUgYmFja2VkIGJ5IGNhY2FjaGUgbWVtb2l6YXRpb24sIHdpdGggb3B0aW9uYWwgZGlzay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1ldGFkYXRhQ2FjaGU8VD4ob3B0aW9uczogTWV0YWRhdGFDYWNoZU9wdGlvbnM8VD4pOiBNZXRhZGF0YUNhY2hlPFQ+IHtcbiAgY29uc3QgdHRsTXMgPSBvcHRpb25zLnR0bE1zID8/IE1PREVMX01FVEFEQVRBX1RUTF9NUztcbiAgY29uc3QgZGlza0VuYWJsZWQgPSBvcHRpb25zLmRpc2sgPz8gbWV0YWRhdGFDYWNoZURpc2tFbmFibGVkKCk7XG4gIGNvbnN0IG5vdyA9IG9wdGlvbnMubm93ID8/IERhdGUubm93O1xuICBjb25zdCBwYXRoUHJvbWlzZSA9IHJlc29sdmVDYWNoZURpcihvcHRpb25zKTtcbiAgbGV0IHBhdGggPSBvcHRpb25zLmNhY2hlRGlyO1xuXG4gIGNvbnN0IGZsaWdodEtleSA9IChjYWNoZVBhdGg6IHN0cmluZywgc3VmZml4ID0gXCJcIik6IHN0cmluZyA9PlxuICAgIGAke2NhY2hlUGF0aH06OiR7b3B0aW9ucy5rZXl9JHtzdWZmaXh9YDtcblxuICAvKiogUHJvY2Vzcy1sb2NhbCBzdG9yZSB1c2VkIHdoZW4gZGlzayBpcyBvZmYgKERhdGFicmlja3MgQXBwcykuICovXG4gIGNvbnN0IG1lbW9yeU9ubHkgPSBuZXcgTWFwPHN0cmluZywgTWV0YWRhdGFDYWNoZVJlY29yZDxUPj4oKTtcblxuICBjb25zdCByZXNvbHZlVmFsdWUgPSAoaW5wdXQ6IE1ldGFkYXRhQ2FjaGVNZXJnZUlucHV0PFQ+KTogVCA9PiBvcHRpb25zLm1lcmdlKGlucHV0KTtcblxuICBjb25zdCBpc0ZyZXNoID0gKHJlY29yZDogTWV0YWRhdGFDYWNoZVJlY29yZDxUPiB8IHVuZGVmaW5lZCk6IGJvb2xlYW4gPT5cbiAgICBCb29sZWFuKHJlY29yZCAmJiBub3coKSAtIHJlY29yZC5yZWZyZXNoZWRBdCA8IHR0bE1zKTtcblxuICBjb25zdCBjYWNoZVBhdGggPSBhc3luYyAoKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICBwYXRoID8/PSBhd2FpdCBwYXRoUHJvbWlzZTtcbiAgICByZXR1cm4gcGF0aDtcbiAgfTtcblxuICBjb25zdCByZWFkUmVjb3JkID0gYXN5bmMgKCk6IFByb21pc2U8TWV0YWRhdGFDYWNoZVJlY29yZDxUPiB8IHVuZGVmaW5lZD4gPT4ge1xuICAgIGlmICghZGlza0VuYWJsZWQpIHJldHVybiBtZW1vcnlPbmx5LmdldChvcHRpb25zLmtleSk7XG4gICAgY29uc3QgcmVzb2x2ZWRQYXRoID0gYXdhaXQgY2FjaGVQYXRoKCk7XG4gICAgdHJ5IHtcbiAgICAgIC8vIGNhY2FjaGUgcmVhZHMgaXRzIGluLW1lbW9yeSBtZW1vIGZpcnN0IHVubGVzcyBtZW1vaXplIGlzIGZhbHNlXG4gICAgICBjb25zdCBlbnRyeSA9IGF3YWl0IGNhY2FjaGUuZ2V0KHJlc29sdmVkUGF0aCwgb3B0aW9ucy5rZXkpO1xuICAgICAgcmV0dXJuIGRlY29kZVJlY29yZDxUPihlbnRyeS5kYXRhKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGlzQ2FjaGVNaXNzKGVycm9yKSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIGxvZ2dlci53YXJuKFwibWV0YWRhdGEgY2FjaGUgY2FjYWNoZSByZWFkIGZhaWxlZFwiLCB7XG4gICAgICAgIGtleTogb3B0aW9ucy5rZXksXG4gICAgICAgIHBhdGg6IHJlc29sdmVkUGF0aCxcbiAgICAgICAgZXJyb3IsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHdyaXRlUmVjb3JkID0gYXN5bmMgKHJlY29yZDogTWV0YWRhdGFDYWNoZVJlY29yZDxUPik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmICghZGlza0VuYWJsZWQpIHtcbiAgICAgIG1lbW9yeU9ubHkuc2V0KG9wdGlvbnMua2V5LCByZWNvcmQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXNvbHZlZFBhdGggPSBhd2FpdCBjYWNoZVBhdGgoKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY2FjYWNoZS5wdXQocmVzb2x2ZWRQYXRoLCBvcHRpb25zLmtleSwgYCR7SlNPTi5zdHJpbmdpZnkocmVjb3JkKX1cXG5gLCB7XG4gICAgICAgIG1lbW9pemU6IHRydWUsXG4gICAgICAgIG1ldGFkYXRhOiB7IHJlZnJlc2hlZEF0OiByZWNvcmQucmVmcmVzaGVkQXQgfSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihcIm1ldGFkYXRhIGNhY2hlIGNhY2FjaGUgd3JpdGUgZmFpbGVkXCIsIHtcbiAgICAgICAga2V5OiBvcHRpb25zLmtleSxcbiAgICAgICAgcGF0aDogcmVzb2x2ZWRQYXRoLFxuICAgICAgICBlcnJvcixcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBwZXJzaXN0ID0gYXN5bmMgKHZhbHVlOiBULCByZWZyZXNoZWRBdCA9IG5vdygpKTogUHJvbWlzZTxUPiA9PiB7XG4gICAgYXdhaXQgd3JpdGVSZWNvcmQoeyByZWZyZXNoZWRBdCwgdmFsdWUgfSk7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xuXG4gIGNvbnN0IHJlZnJlc2ggPSBhc3luYyAoZm9yY2U6IGJvb2xlYW4pOiBQcm9taXNlPFQ+ID0+IHtcbiAgICBjb25zdCByZXNvbHZlZFBhdGggPSBhd2FpdCBjYWNoZVBhdGgoKTtcbiAgICByZXR1cm4gY29hbGVzY2UoZmxpZ2h0S2V5KHJlc29sdmVkUGF0aCksIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHByZXZpb3VzID0gYXdhaXQgcmVhZFJlY29yZCgpO1xuICAgICAgaWYgKCFmb3JjZSAmJiBpc0ZyZXNoKHByZXZpb3VzKSkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZVZhbHVlKHtcbiAgICAgICAgICBmcmVzaDogdW5kZWZpbmVkLFxuICAgICAgICAgIHByZXZpb3VzOiBwcmV2aW91cz8udmFsdWUsXG4gICAgICAgICAgZmFsbGJhY2s6IG9wdGlvbnMuZmFsbGJhY2ssXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBsZXQgZnJlc2g6IFQgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAob3B0aW9ucy5sb2FkKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZnJlc2ggPSBhd2FpdCBvcHRpb25zLmxvYWQoKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBsb2dnZXIud2FybihcIm1ldGFkYXRhIGNhY2hlIHJlZnJlc2ggZmFpbGVkOyBrZWVwaW5nIGxhc3Qga25vd24gZ29vZFwiLCB7XG4gICAgICAgICAgICBrZXk6IG9wdGlvbnMua2V5LFxuICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICBwYXRoOiByZXNvbHZlZFBhdGgsXG4gICAgICAgICAgICBkaXNrRW5hYmxlZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCB2YWx1ZSA9IHJlc29sdmVWYWx1ZSh7XG4gICAgICAgIGZyZXNoLFxuICAgICAgICBwcmV2aW91czogcHJldmlvdXM/LnZhbHVlLFxuICAgICAgICBmYWxsYmFjazogb3B0aW9ucy5mYWxsYmFjayxcbiAgICAgIH0pO1xuICAgICAgaWYgKGZyZXNoICE9PSB1bmRlZmluZWQgfHwgIXByZXZpb3VzKSB7XG4gICAgICAgIGF3YWl0IHBlcnNpc3QodmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgZ2V0IHBhdGgoKSB7XG4gICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWV0YWRhdGEgY2FjaGUgcGF0aCBpcyBub3QgcmVzb2x2ZWQgdW50aWwgdGhlIGZpcnN0IGNhY2hlIHJlYWRcIik7XG4gICAgICB9XG4gICAgICByZXR1cm4gcGF0aDtcbiAgICB9LFxuICAgIGRpc2tFbmFibGVkLFxuICAgIGdldDogKCkgPT4gcmVmcmVzaChmYWxzZSksXG4gICAgcGVlazogYXN5bmMgKCkgPT4gKGF3YWl0IHJlYWRSZWNvcmQoKSk/LnZhbHVlLFxuICAgIHJlZnJlc2g6ICgpID0+IHJlZnJlc2godHJ1ZSksXG4gICAgdXBkYXRlOiBhc3luYyAobXV0YXRvcikgPT4ge1xuICAgICAgY29uc3QgcmVzb2x2ZWRQYXRoID0gYXdhaXQgY2FjaGVQYXRoKCk7XG4gICAgICByZXR1cm4gY29hbGVzY2UoZmxpZ2h0S2V5KHJlc29sdmVkUGF0aCwgXCI6dXBkYXRlXCIpLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzID0gYXdhaXQgcmVhZFJlY29yZCgpO1xuICAgICAgICBjb25zdCBiYXNlbGluZSA9IHJlc29sdmVWYWx1ZSh7XG4gICAgICAgICAgZnJlc2g6IHVuZGVmaW5lZCxcbiAgICAgICAgICBwcmV2aW91czogcHJldmlvdXM/LnZhbHVlLFxuICAgICAgICAgIGZhbGxiYWNrOiBvcHRpb25zLmZhbGxiYWNrLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBlcnNpc3QobXV0YXRvcihiYXNlbGluZSkpO1xuICAgICAgfSk7XG4gICAgfSxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUNhY2hlRGlyKG9wdGlvbnM6IHtcbiAgcmVhZG9ubHkgY2FjaGVEaXI/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZlcnNpb24/OiBzdHJpbmc7XG59KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgaWYgKG9wdGlvbnMuY2FjaGVEaXIpIHJldHVybiBvcHRpb25zLmNhY2hlRGlyO1xuICBjb25zdCB2ZXJzaW9uID0gb3B0aW9ucy52ZXJzaW9uID8/IChhd2FpdCBpbXBvcnQoXCIuLi9pbmRleC50c1wiKSkuUEFDS0FHRV9WRVJTSU9OO1xuICByZXR1cm4gZGVmYXVsdE1ldGFkYXRhQ2FjaGVEaXIodmVyc2lvbik7XG59XG5cbi8qKiBQcmVmZXIgYSBub24tZW1wdHkgZnJlc2ggYXJyYXksIGVsc2UgcHJldmlvdXMsIGVsc2UgZmFsbGJhY2suICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VQcmVmZXJGcmVzaExpc3Q8VD4oaW5wdXQ6IE1ldGFkYXRhQ2FjaGVNZXJnZUlucHV0PHJlYWRvbmx5IFRbXT4pOiBUW10ge1xuICBpZiAoaW5wdXQuZnJlc2ggJiYgaW5wdXQuZnJlc2gubGVuZ3RoID4gMCkgcmV0dXJuIFsuLi5pbnB1dC5mcmVzaF07XG4gIGlmIChpbnB1dC5wcmV2aW91cyAmJiBpbnB1dC5wcmV2aW91cy5sZW5ndGggPiAwKSByZXR1cm4gWy4uLmlucHV0LnByZXZpb3VzXTtcbiAgcmV0dXJuIFsuLi5pbnB1dC5mYWxsYmFja107XG59XG5cbi8qKlxuICogU2hhbGxvdy1tZXJnZSByZWNvcmQgY2F0YWxvZ3VlczogZmFsbGJhY2ssIHRoZW4gcHJldmlvdXMsIHRoZW4gZnJlc2gga2V5cy5cbiAqIEZyZXNoIHZhbHVlcyB3aW4gcGVyIGtleS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlUHJlZmVyRnJlc2hSZWNvcmQ8VD4oXG4gIGlucHV0OiBNZXRhZGF0YUNhY2hlTWVyZ2VJbnB1dDxSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBUPj4+LFxuKTogUmVjb3JkPHN0cmluZywgVD4ge1xuICByZXR1cm4ge1xuICAgIC4uLmlucHV0LmZhbGxiYWNrLFxuICAgIC4uLihpbnB1dC5wcmV2aW91cyA/PyB7fSksXG4gICAgLi4uKGlucHV0LmZyZXNoID8/IHt9KSxcbiAgfTtcbn1cblxuLyoqIFRlc3QgaGVscGVyOiB3aXBlIGEgY2FjYWNoZSByb290IGFuZCBjbGVhciBjYWNhY2hlIG1lbW9pemF0aW9uLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc2V0TWV0YWRhdGFDYWNoZURpcihjYWNoZURpcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgY2FjYWNoZS5ybS5hbGwoY2FjaGVEaXIpO1xuICB9IGNhdGNoIHtcbiAgICAvLyBlbXB0eSAvIG1pc3NpbmcgY2FjaGUgaXMgZmluZVxuICB9XG4gIGNhY2FjaGUuY2xlYXJNZW1vaXplZCgpO1xuICBmb3IgKGNvbnN0IGtleSBvZiBbLi4uaW5mbGlnaHQua2V5cygpXSkge1xuICAgIGlmIChrZXkuc3RhcnRzV2l0aChgJHtjYWNoZURpcn06OmApKSBpbmZsaWdodC5kZWxldGUoa2V5KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb2FsZXNjZTxUPihrZXk6IHN0cmluZywgd29yazogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICBjb25zdCBleGlzdGluZyA9IGluZmxpZ2h0LmdldChrZXkpO1xuICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZyBhcyBQcm9taXNlPFQ+O1xuICBjb25zdCBwZW5kaW5nID0gd29yaygpLmZpbmFsbHkoKCkgPT4ge1xuICAgIGlmIChpbmZsaWdodC5nZXQoa2V5KSA9PT0gcGVuZGluZykgaW5mbGlnaHQuZGVsZXRlKGtleSk7XG4gIH0pO1xuICBpbmZsaWdodC5zZXQoa2V5LCBwZW5kaW5nKTtcbiAgcmV0dXJuIHBlbmRpbmc7XG59XG5cbmZ1bmN0aW9uIGRlY29kZVJlY29yZDxUPihkYXRhOiBCdWZmZXIpOiBNZXRhZGF0YUNhY2hlUmVjb3JkPFQ+IHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGRhdGEudG9TdHJpbmcoXCJ1dGY4XCIpKSBhcyB1bmtub3duO1xuICAgIGlmIChcbiAgICAgICFwYXJzZWQgfHxcbiAgICAgIHR5cGVvZiBwYXJzZWQgIT09IFwib2JqZWN0XCIgfHxcbiAgICAgIHR5cGVvZiAocGFyc2VkIGFzIE1ldGFkYXRhQ2FjaGVSZWNvcmQ8VD4pLnJlZnJlc2hlZEF0ICE9PSBcIm51bWJlclwiXG4gICAgKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VkIGFzIE1ldGFkYXRhQ2FjaGVSZWNvcmQ8VD47XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNDYWNoZU1pc3MoZXJyb3I6IHVua25vd24pOiBib29sZWFuIHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgZXJyb3IgJiZcbiAgICB0eXBlb2YgZXJyb3IgPT09IFwib2JqZWN0XCIgJiZcbiAgICBcImNvZGVcIiBpbiBlcnJvciAmJlxuICAgIChlcnJvciBhcyB7IGNvZGU/OiBzdHJpbmcgfSkuY29kZSA9PT0gXCJFTk9FTlRcIixcbiAgKTtcbn1cblxuIl19
@@ -1,33 +1,68 @@
1
- import type { ModelStatus, ServingEndpointSummary } from "@dbx-tools/shared-model/contracts";
2
- import { MODEL_METADATA_TTL_MS, MODEL_RATE_LIMITS_URL, OPENAI_RESPONSES_MODELS_URL, RETIRED_MODELS_URL, WEB_SEARCH_MODELS_URL, type ModelRateLimits } from "./_metadata-contract.ts";
3
- export { MODEL_METADATA_TTL_MS, MODEL_RATE_LIMITS_URL, OPENAI_RESPONSES_MODELS_URL, RETIRED_MODELS_URL, WEB_SEARCH_MODELS_URL, };
4
- export type { ModelCapabilitiesSnapshot, ModelCapabilityCatalogue, ModelRateLimitCatalogue, ModelRateLimits, ModelRateLimitsSnapshot, RetiredModelsSnapshot, } from "./_metadata-contract.ts";
5
- /** Documented capabilities resolved for one model identity. */
6
- export interface ModelCapabilities {
7
- readonly responses: boolean;
8
- readonly imageInput: boolean;
9
- readonly applyPatch: boolean;
10
- readonly webSearch: boolean;
11
- }
12
- /** Combined build-generated metadata resolved for one model identity. */
13
- export interface ModelMetadata {
14
- readonly status: ModelStatus;
15
- readonly capabilities: ModelCapabilities;
16
- readonly rateLimits?: ModelRateLimits;
1
+ import type { ModelCapabilities, ModelMetadata, ModelRateLimits, ModelStatus, ServingEndpointSummary } from "@dbx-tools/shared-model/contracts";
2
+ import { MODEL_METADATA_TTL_MS, MODEL_RATE_LIMITS_URL, OPENAI_RESPONSES_MODELS_URL, QUERY_REASON_MODELS_URL, RETIRED_MODELS_URL, WEB_SEARCH_MODELS_URL, type ModelCapabilityCatalogue } from "./_metadata-contract.ts";
3
+ import { type ReasoningLevel, type ReasoningModelCatalogue } from "./reasoning-translation.ts";
4
+ export { MODEL_METADATA_TTL_MS, MODEL_RATE_LIMITS_URL, OPENAI_RESPONSES_MODELS_URL, QUERY_REASON_MODELS_URL, RETIRED_MODELS_URL, WEB_SEARCH_MODELS_URL, };
5
+ interface MetadataIndex {
6
+ readonly retiredNames: readonly string[];
7
+ readonly retiredKeys: ReadonlySet<string>;
8
+ readonly capabilities: {
9
+ readonly [Key in keyof ModelCapabilityCatalogue]: ReadonlySet<string>;
10
+ };
11
+ readonly rateLimits: ReadonlyMap<string, ModelRateLimits>;
12
+ readonly reasoning: ReasoningModelCatalogue;
13
+ readonly learnedReasoning: ReasoningModelCatalogue;
17
14
  }
15
+ /**
16
+ * Hydrate or refresh documentation + learned caches into the process index.
17
+ *
18
+ * Safe to call on gateway startup. Concurrent callers share one refresh.
19
+ */
20
+ export declare function refreshModelMetadata(): Promise<MetadataIndex>;
21
+ /** Load cacache / memory entries without forcing a network refresh. */
22
+ export declare function hydrateModelMetadata(): Promise<MetadataIndex>;
23
+ /** Absolute cacache root used by the documentation / learned caches. */
24
+ export declare function modelMetadataCachePath(): string;
18
25
  /** Return the committed retired-model names. The array is cached and immutable. */
19
26
  export declare function retiredModelNames(): readonly string[];
27
+ /** Return the committed reasoning-effort catalogue. Cached per process. */
28
+ export declare function reasoningModelCatalogue(): ReasoningModelCatalogue;
29
+ /** Return error-learned reasoning ladders persisted in the metadata cache. */
30
+ export declare function learnedReasoningCatalogue(): ReasoningModelCatalogue;
31
+ /**
32
+ * Store levels learned from an upstream error and persist them write-through.
33
+ *
34
+ * Empty lists are ignored so a failed parse cannot wipe defaults. Error bodies
35
+ * themselves are never stored - only the parsed ladder.
36
+ */
37
+ export declare function rememberReasoningLevels(model: string, levels: readonly ReasoningLevel[]): Promise<ReasoningLevel[]>;
38
+ /**
39
+ * Parse an upstream error body and persist the supported ladder for `model`.
40
+ *
41
+ * Accepts the same nested Databricks envelopes as {@link parseReasoningLevels}.
42
+ * Returns the levels that were stored (or the current lookup when parse yields
43
+ * nothing). The raw error body is never written to disk.
44
+ */
45
+ export declare function learnReasoningLevelsFromError(model: string, body: unknown): Promise<ReasoningLevel[]>;
20
46
  /** Resolve whether any supplied identity is listed in the retirement snapshot. */
21
47
  export declare function modelStatusFor(...models: readonly (string | ServingEndpointSummary)[]): ModelStatus;
22
48
  /** Resolve documented model capabilities from a name or endpoint summary. */
23
49
  export declare function modelCapabilitiesFor(model: string | ServingEndpointSummary): ModelCapabilities;
24
50
  /** Resolve published ITPM, OTPM, and QPH limits from a model identity. */
25
51
  export declare function modelRateLimitsFor(model: string | ServingEndpointSummary): ModelRateLimits | undefined;
52
+ /**
53
+ * Resolve reasoning levels: learned from errors, then documentation, then
54
+ * family defaults.
55
+ *
56
+ * Does not parse error bodies; callers should use {@link parseReasoningLevels}
57
+ * and then {@link rememberReasoningLevels}.
58
+ */
59
+ export declare function modelReasoningLevelsFor(model: string | ServingEndpointSummary): ReasoningLevel[];
26
60
  /** Resolve retirement, capability, and rate-limit metadata together. */
27
61
  export declare function modelMetadataFor(model: string | ServingEndpointSummary): ModelMetadata;
28
- /** Return generation timestamps for the three committed metadata snapshots. */
62
+ /** Return generation timestamps for the committed metadata snapshots. */
29
63
  export declare function modelMetadataGeneratedAt(): Readonly<{
30
64
  retiredModels: number;
31
65
  capabilities: number;
32
66
  rateLimits: number;
67
+ reasoning: number;
33
68
  }>;