@dbx-tools/model 0.9.19 → 0.9.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +61 -10
  2. package/index.ts +12 -2
  3. package/lib/exports.d.ts +1 -0
  4. package/lib/exports.js +2 -0
  5. package/lib/index.d.ts +12 -2
  6. package/lib/index.js +9 -2
  7. package/lib/src/_metadata-contract.d.ts +42 -0
  8. package/lib/src/_metadata-contract.js +11 -0
  9. package/lib/src/_metadata-generator.d.ts +7 -0
  10. package/lib/src/_metadata-generator.js +182 -0
  11. package/lib/src/_ranking.d.ts +20 -0
  12. package/lib/src/_ranking.js +226 -0
  13. package/lib/src/_selection.d.ts +23 -0
  14. package/lib/src/_selection.js +95 -0
  15. package/lib/src/classes.d.ts +2 -2
  16. package/lib/src/classes.js +10 -8
  17. package/lib/src/classify.d.ts +130 -0
  18. package/lib/src/classify.js +283 -0
  19. package/lib/src/fallback.d.ts +4 -4
  20. package/lib/src/fallback.js +7 -7
  21. package/lib/src/generated/model-capabilities.json +90 -0
  22. package/lib/src/generated/model-rate-limits.json +342 -0
  23. package/lib/src/generated/retired-models.json +32 -0
  24. package/lib/src/invoke.js +3 -3
  25. package/lib/src/metadata.d.ts +33 -0
  26. package/lib/src/metadata.js +120 -0
  27. package/lib/src/model-catalog.d.ts +4 -4
  28. package/lib/src/model-catalog.js +19 -24
  29. package/lib/src/model-client.d.ts +67 -0
  30. package/lib/src/model-client.js +181 -0
  31. package/lib/src/policy.d.ts +14 -8
  32. package/lib/src/policy.js +173 -14
  33. package/lib/src/python.d.ts +2 -0
  34. package/lib/src/python.js +3 -0
  35. package/lib/src/resolve.d.ts +10 -143
  36. package/lib/src/resolve.js +11 -196
  37. package/lib/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +15 -5
  39. package/src/_metadata-contract.ts +56 -0
  40. package/src/_metadata-generator.ts +199 -0
  41. package/src/_ranking.ts +260 -0
  42. package/src/_selection.ts +141 -0
  43. package/src/classes.ts +11 -7
  44. package/src/classify.ts +324 -0
  45. package/src/fallback.ts +11 -7
  46. package/src/generated/model-capabilities.json +90 -0
  47. package/src/generated/model-rate-limits.json +342 -0
  48. package/src/generated/retired-models.json +32 -0
  49. package/src/invoke.ts +2 -2
  50. package/src/metadata.ts +189 -0
  51. package/src/model-catalog.ts +26 -28
  52. package/src/model-client.ts +311 -0
  53. package/src/policy.ts +176 -19
  54. package/src/python.ts +2 -0
  55. package/src/resolve.ts +24 -270
  56. package/lib/src/_native.d.ts +0 -14
  57. package/lib/src/_native.js +0 -124
  58. package/src/_native.ts +0 -174
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Model-class classification for Databricks Model Serving endpoints.
3
+ *
4
+ * Chat capability bands are derived from the live workspace catalogue
5
+ * rather than a hand-maintained table. Databricks publishes
6
+ * per-endpoint `quality` / `speed` / `cost` scores (the AI Playground
7
+ * bars) on the serving list; {@link classifyEndpoints} buckets scored
8
+ * chat models into the chat {@link ModelClass} bands by the *relative*
9
+ * distribution of those scores (quantiles, not fixed cut-offs) so a
10
+ * brand-new model that lands outside today's score range still slots in
11
+ * next to its peers. Embedding endpoints (`task === "llm/v1/embeddings"`)
12
+ * are bucketed into {@link ModelClass.Embedding} by task, independent of
13
+ * any score.
14
+ *
15
+ * Unscored-but-recognizable chat endpoints are still placed by a small
16
+ * family heuristic ({@link classifyByFamily}) so a workspace whose
17
+ * models predate Foundation Model API scoring keeps working. The
18
+ * offline fallback floor - the hard-coded model list reached for when
19
+ * the live catalogue can't be read at all - is a server concern and
20
+ * lives in `@dbx-tools/model`, not here: a browser client never talks
21
+ * to Databricks directly, so it has nothing to fall back to.
22
+ *
23
+ * Pure (no Node-only imports), so a client can classify a `/models`
24
+ * response without server dependencies.
25
+ *
26
+ * @module
27
+ */
28
+ import { ModelClass as ModelClassValues, } from "@dbx-tools/shared-model/contracts";
29
+ const ModelClass = ModelClassValues;
30
+ /** Task hint Databricks stamps on chat completion endpoints. */
31
+ const CHAT_TASK = "llm/v1/chat";
32
+ /** Task hint Databricks stamps on embedding endpoints. */
33
+ const EMBEDDING_TASK = "llm/v1/embeddings";
34
+ /**
35
+ * Provider families verified against Databricks Responses/Open Responses with
36
+ * both a forced function call and a stateless `function_call_output` replay.
37
+ *
38
+ * Databricks' endpoint list/OpenAPI currently exposes no tools capability bit.
39
+ * Keep this conservative: an unknown chat family is not agent-safe until it is
40
+ * verified. Gemini is excluded because it emits a call but Open Responses
41
+ * cannot replay the required thought signature; GPT-OSS rejects Responses
42
+ * passthrough entirely.
43
+ */
44
+ export function supportsToolsByFamily(name) {
45
+ const n = name.toLowerCase();
46
+ if (n.includes("gemini") || n.includes("gpt-oss"))
47
+ return false;
48
+ return (n.includes("claude") ||
49
+ n.includes("gpt") ||
50
+ n.includes("qwen") ||
51
+ n.includes("glm") ||
52
+ n.includes("llama"));
53
+ }
54
+ /**
55
+ * Derive an endpoint's capabilities from its Databricks task hint and its
56
+ * classified {@link ModelClass}, so consumers filter on capability instead of
57
+ * re-deriving it from raw `task` / `class` strings.
58
+ *
59
+ * Either signal alone is enough: the task hint is authoritative when present,
60
+ * and the class covers endpoints Databricks left untasked but the classifier
61
+ * recognized. Embedding wins over chat when both point at it, since the two are
62
+ * not interchangeable.
63
+ */
64
+ export function endpointCapabilities(endpoint) {
65
+ const embedding = endpoint.task === EMBEDDING_TASK || endpoint.class === ModelClass.Embedding;
66
+ // Every non-embedding class is a chat band, so "classified but not embedding"
67
+ // is the class-side test for chat capability.
68
+ const chat = !embedding && (endpoint.task === CHAT_TASK || endpoint.class !== undefined);
69
+ const tools = chat && (endpoint.supportsTools ?? supportsToolsByFamily(endpoint.name));
70
+ return { chat, embedding, tools };
71
+ }
72
+ /**
73
+ * Numeric `[major, minor, patch]` version parsed from an endpoint
74
+ * name, used to order siblings within a family/tier. Starts at the
75
+ * first digit in the name, then reads successive separator-delimited,
76
+ * digit-prefixed chunks as the three components (missing ones default
77
+ * to `0`):
78
+ *
79
+ * - `databricks-claude-opus-4-8` -> `[4, 8, 0]`
80
+ * - `databricks-claude-opus-4-10` -> `[4, 10, 0]` (sorts above 4-8)
81
+ * - `databricks-meta-llama-3-3-70b`-> `[3, 3, 70]`
82
+ * - `databricks-bge-large-en` -> `[0, 0, 0]` (no digits)
83
+ *
84
+ * Component-wise comparison (not a decimal collapse) so `4.10` beats
85
+ * `4.8` - the bug a `major + minor/10` score would hit.
86
+ */
87
+ export function versionTuple(name) {
88
+ const start = name.search(/\d/);
89
+ if (start < 0)
90
+ return [0, 0, 0];
91
+ const nums = name
92
+ .slice(start)
93
+ .split(/[^a-z0-9]+/i)
94
+ .map((chunk) => chunk.match(/^\d+/)?.[0])
95
+ .filter((digits) => digits !== undefined)
96
+ .map(Number);
97
+ return [nums[0] ?? 0, nums[1] ?? 0, nums[2] ?? 0];
98
+ }
99
+ /** Compare two version tuples so the higher version sorts first (descending). */
100
+ function compareVersionDesc(a, b) {
101
+ for (let i = 0; i < 3; i++) {
102
+ const diff = (b[i] ?? 0) - (a[i] ?? 0);
103
+ if (diff !== 0)
104
+ return diff;
105
+ }
106
+ return 0;
107
+ }
108
+ /**
109
+ * Monotonic version key for ordering siblings within a family/tier
110
+ * (e.g. `opus-4-8` over `opus-4-7`). Encodes the {@link versionTuple}
111
+ * as a single number so callers that need a scalar rank (the family
112
+ * heuristic, the static fallback ordering) keep working; the encoding
113
+ * preserves component order without the decimal-collapse bug.
114
+ */
115
+ function versionScore(name) {
116
+ const [major, minor, patch] = versionTuple(name);
117
+ return major * 1_000_000 + minor * 1_000 + patch;
118
+ }
119
+ /**
120
+ * Best-effort chat capability band for an endpoint we have no live
121
+ * score for, keyed off provider family and the well-known variant words
122
+ * in the name (`opus`/`sonnet`/`haiku`, `pro`/`mini`/`nano`,
123
+ * `flash`/`flash-lite`, Llama parameter sizes, etc). Returns `null` for
124
+ * names we don't recognize so unknown custom endpoints are never
125
+ * auto-selected as a default. The accompanying `rank` orders siblings
126
+ * within a class. Only ever returns a chat band - embedding endpoints
127
+ * are classified by task, not name.
128
+ */
129
+ export function classifyByFamily(name) {
130
+ const n = name.toLowerCase();
131
+ const at = (cls) => ({ class: cls, rank: versionScore(n) });
132
+ // Anthropic Claude
133
+ if (n.includes("opus"))
134
+ return at(ModelClass.ChatThinking);
135
+ if (n.includes("sonnet"))
136
+ return at(ModelClass.ChatBalanced);
137
+ if (n.includes("haiku"))
138
+ return at(ModelClass.ChatFast);
139
+ // OpenAI open-weights (check before the generic gpt branch)
140
+ if (n.includes("gpt-oss")) {
141
+ return at(n.includes("120b") ? ModelClass.ChatBalanced : ModelClass.ChatFast);
142
+ }
143
+ // OpenAI GPT family
144
+ if (n.includes("gpt")) {
145
+ if (n.includes("pro"))
146
+ return at(ModelClass.ChatThinking);
147
+ if (n.includes("mini") || n.includes("nano"))
148
+ return at(ModelClass.ChatFast);
149
+ return at(ModelClass.ChatBalanced);
150
+ }
151
+ // Google Gemini / Gemma
152
+ if (n.includes("gemini")) {
153
+ if (n.includes("flash-lite"))
154
+ return at(ModelClass.ChatFast);
155
+ if (n.includes("pro"))
156
+ return at(ModelClass.ChatThinking);
157
+ return at(ModelClass.ChatBalanced);
158
+ }
159
+ if (n.includes("gemma"))
160
+ return at(ModelClass.ChatFast);
161
+ // Meta Llama
162
+ if (n.includes("llama")) {
163
+ if (n.includes("maverick") || n.includes("405b"))
164
+ return at(ModelClass.ChatThinking);
165
+ if (n.includes("70b"))
166
+ return at(ModelClass.ChatBalanced);
167
+ if (n.includes("8b") || n.includes("1b"))
168
+ return at(ModelClass.ChatFast);
169
+ return at(ModelClass.ChatBalanced);
170
+ }
171
+ // Alibaba Qwen
172
+ if (n.includes("qwen"))
173
+ return at(ModelClass.ChatBalanced);
174
+ return null;
175
+ }
176
+ /** Linear-interpolated quantile of an ascending-sorted numeric array. */
177
+ function quantile(sortedAsc, p) {
178
+ if (sortedAsc.length === 0)
179
+ return Number.NaN;
180
+ const idx = (sortedAsc.length - 1) * p;
181
+ const lo = Math.floor(idx);
182
+ const hi = Math.ceil(idx);
183
+ if (lo === hi)
184
+ return sortedAsc[lo];
185
+ return sortedAsc[lo] + (sortedAsc[hi] - sortedAsc[lo]) * (idx - lo);
186
+ }
187
+ function rankOrder(a, b) {
188
+ if (a.scored !== b.scored)
189
+ return a.scored ? -1 : 1;
190
+ if (b.sort !== a.sort)
191
+ return b.sort - a.sort;
192
+ if (a.tieCost !== b.tieCost)
193
+ return a.tieCost - b.tieCost;
194
+ if (b.tieSpeed !== a.tieSpeed)
195
+ return b.tieSpeed - a.tieSpeed;
196
+ // Same scored-ness, quality, cost, and speed (e.g. several Claude
197
+ // Opus point releases): prefer the newer parsed version so
198
+ // `opus-4-8` beats `opus-4-7`.
199
+ return compareVersionDesc(a.version, b.version);
200
+ }
201
+ /**
202
+ * Bucket live endpoints into {@link ModelClass}es, ranked best-first
203
+ * within each chat band.
204
+ *
205
+ * Embedding endpoints (`task === "llm/v1/embeddings"`) go into
206
+ * {@link ModelClass.Embedding} by task, in listing order (they carry no
207
+ * capability score to rank on).
208
+ *
209
+ * Chat endpoints (`task === "llm/v1/chat"`) split into the three chat
210
+ * bands. Scored endpoints (those carrying a `profile.quality`) drive
211
+ * the banding: the observed quality distribution is split at its 1/3
212
+ * and 2/3 quantiles, so the top third is {@link ModelClass.ChatThinking},
213
+ * the bottom third {@link ModelClass.ChatFast}, and the middle
214
+ * {@link ModelClass.ChatBalanced}. Because the thresholds come from the
215
+ * data, the split adapts as Databricks adds or rescores models -
216
+ * nothing is pinned to a fixed score band.
217
+ *
218
+ * Unscored chat endpoints are placed by {@link classifyByFamily} and
219
+ * ranked after the scored ones in their band; unrecognized, unscored
220
+ * endpoints (e.g. custom external models) are omitted entirely so they
221
+ * are never picked as an automatic default.
222
+ *
223
+ * Within a chat band, scored models sort by `quality` desc, then `cost`
224
+ * asc, then `speed` desc, then parsed name version desc; family-only
225
+ * models sort by version rank then parsed version. The version
226
+ * tie-break ({@link versionTuple}) is what separates point releases
227
+ * that share a score profile (e.g. `opus-4-8` ahead of `opus-4-7`).
228
+ */
229
+ export function classifyEndpoints(endpoints) {
230
+ const chat = endpoints.filter((e) => e.task === CHAT_TASK);
231
+ const qualities = chat
232
+ .map((e) => e.profile?.quality)
233
+ .filter((q) => Number.isFinite(q))
234
+ .sort((a, b) => a - b);
235
+ const low = quantile(qualities, 1 / 3);
236
+ const high = quantile(qualities, 2 / 3);
237
+ const buckets = {
238
+ [ModelClass.ChatThinking]: [],
239
+ [ModelClass.ChatBalanced]: [],
240
+ [ModelClass.ChatFast]: [],
241
+ [ModelClass.Embedding]: [],
242
+ };
243
+ for (const ep of chat) {
244
+ const q = ep.profile?.quality;
245
+ if (Number.isFinite(q)) {
246
+ const quality = q;
247
+ const cls = quality >= high
248
+ ? ModelClass.ChatThinking
249
+ : quality <= low
250
+ ? ModelClass.ChatFast
251
+ : ModelClass.ChatBalanced;
252
+ buckets[cls].push({
253
+ ep,
254
+ sort: quality,
255
+ scored: true,
256
+ tieCost: ep.profile?.cost ?? Number.POSITIVE_INFINITY,
257
+ tieSpeed: ep.profile?.speed ?? 0,
258
+ version: versionTuple(ep.name),
259
+ });
260
+ continue;
261
+ }
262
+ const family = classifyByFamily(ep.name);
263
+ if (!family)
264
+ continue;
265
+ buckets[family.class].push({
266
+ ep,
267
+ sort: family.rank,
268
+ scored: false,
269
+ tieCost: Number.POSITIVE_INFINITY,
270
+ tieSpeed: 0,
271
+ version: versionTuple(ep.name),
272
+ });
273
+ }
274
+ // Embeddings are bucketed by task in listing order - no score to rank.
275
+ const embeddings = endpoints.filter((e) => e.task === EMBEDDING_TASK);
276
+ return {
277
+ [ModelClass.ChatThinking]: buckets[ModelClass.ChatThinking].sort(rankOrder).map((x) => x.ep),
278
+ [ModelClass.ChatBalanced]: buckets[ModelClass.ChatBalanced].sort(rankOrder).map((x) => x.ep),
279
+ [ModelClass.ChatFast]: buckets[ModelClass.ChatFast].sort(rankOrder).map((x) => x.ep),
280
+ [ModelClass.Embedding]: embeddings,
281
+ };
282
+ }
283
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3NpZnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2xhc3NpZnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBRUgsT0FBTyxFQUNMLFVBQVUsSUFBSSxnQkFBZ0IsR0FHL0IsTUFBTSxtQ0FBbUMsQ0FBQztBQUczQyxNQUFNLFVBQVUsR0FBRyxnQkFBZ0IsQ0FBQztBQUVwQyxnRUFBZ0U7QUFDaEUsTUFBTSxTQUFTLEdBQUcsYUFBYSxDQUFDO0FBRWhDLDBEQUEwRDtBQUMxRCxNQUFNLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQztBQVkzQzs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQUMsSUFBWTtJQUNoRCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDN0IsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDaEUsT0FBTyxDQUNMLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1FBQ3BCLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQ2xCLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQ3BCLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLFFBQWdDO0lBQ25FLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxJQUFJLEtBQUssY0FBYyxJQUFJLFFBQVEsQ0FBQyxLQUFLLEtBQUssVUFBVSxDQUFDLFNBQVMsQ0FBQztJQUM5Riw4RUFBOEU7SUFDOUUsOENBQThDO0lBQzlD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LENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzVGLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxFQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUM1RixDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxPQUFPLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDcEYsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsVUFBVTtLQUNuQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kZWwtY2xhc3MgY2xhc3NpZmljYXRpb24gZm9yIERhdGFicmlja3MgTW9kZWwgU2VydmluZyBlbmRwb2ludHMuXG4gKlxuICogQ2hhdCBjYXBhYmlsaXR5IGJhbmRzIGFyZSBkZXJpdmVkIGZyb20gdGhlIGxpdmUgd29ya3NwYWNlIGNhdGFsb2d1ZVxuICogcmF0aGVyIHRoYW4gYSBoYW5kLW1haW50YWluZWQgdGFibGUuIERhdGFicmlja3MgcHVibGlzaGVzXG4gKiBwZXItZW5kcG9pbnQgYHF1YWxpdHlgIC8gYHNwZWVkYCAvIGBjb3N0YCBzY29yZXMgKHRoZSBBSSBQbGF5Z3JvdW5kXG4gKiBiYXJzKSBvbiB0aGUgc2VydmluZyBsaXN0OyB7QGxpbmsgY2xhc3NpZnlFbmRwb2ludHN9IGJ1Y2tldHMgc2NvcmVkXG4gKiBjaGF0IG1vZGVscyBpbnRvIHRoZSBjaGF0IHtAbGluayBNb2RlbENsYXNzfSBiYW5kcyBieSB0aGUgKnJlbGF0aXZlKlxuICogZGlzdHJpYnV0aW9uIG9mIHRob3NlIHNjb3JlcyAocXVhbnRpbGVzLCBub3QgZml4ZWQgY3V0LW9mZnMpIHNvIGFcbiAqIGJyYW5kLW5ldyBtb2RlbCB0aGF0IGxhbmRzIG91dHNpZGUgdG9kYXkncyBzY29yZSByYW5nZSBzdGlsbCBzbG90cyBpblxuICogbmV4dCB0byBpdHMgcGVlcnMuIEVtYmVkZGluZyBlbmRwb2ludHMgKGB0YXNrID09PSBcImxsbS92MS9lbWJlZGRpbmdzXCJgKVxuICogYXJlIGJ1Y2tldGVkIGludG8ge0BsaW5rIE1vZGVsQ2xhc3MuRW1iZWRkaW5nfSBieSB0YXNrLCBpbmRlcGVuZGVudCBvZlxuICogYW55IHNjb3JlLlxuICpcbiAqIFVuc2NvcmVkLWJ1dC1yZWNvZ25pemFibGUgY2hhdCBlbmRwb2ludHMgYXJlIHN0aWxsIHBsYWNlZCBieSBhIHNtYWxsXG4gKiBmYW1pbHkgaGV1cmlzdGljICh7QGxpbmsgY2xhc3NpZnlCeUZhbWlseX0pIHNvIGEgd29ya3NwYWNlIHdob3NlXG4gKiBtb2RlbHMgcHJlZGF0ZSBGb3VuZGF0aW9uIE1vZGVsIEFQSSBzY29yaW5nIGtlZXBzIHdvcmtpbmcuIFRoZVxuICogb2ZmbGluZSBmYWxsYmFjayBmbG9vciAtIHRoZSBoYXJkLWNvZGVkIG1vZGVsIGxpc3QgcmVhY2hlZCBmb3Igd2hlblxuICogdGhlIGxpdmUgY2F0YWxvZ3VlIGNhbid0IGJlIHJlYWQgYXQgYWxsIC0gaXMgYSBzZXJ2ZXIgY29uY2VybiBhbmRcbiAqIGxpdmVzIGluIGBAZGJ4LXRvb2xzL21vZGVsYCwgbm90IGhlcmU6IGEgYnJvd3NlciBjbGllbnQgbmV2ZXIgdGFsa3NcbiAqIHRvIERhdGFicmlja3MgZGlyZWN0bHksIHNvIGl0IGhhcyBub3RoaW5nIHRvIGZhbGwgYmFjayB0by5cbiAqXG4gKiBQdXJlIChubyBOb2RlLW9ubHkgaW1wb3J0cyksIHNvIGEgY2xpZW50IGNhbiBjbGFzc2lmeSBhIGAvbW9kZWxzYFxuICogcmVzcG9uc2Ugd2l0aG91dCBzZXJ2ZXIgZGVwZW5kZW5jaWVzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQge1xuICBNb2RlbENsYXNzIGFzIE1vZGVsQ2xhc3NWYWx1ZXMsXG4gIHR5cGUgTW9kZWxDbGFzcyBhcyBNb2RlbENsYXNzVHlwZSxcbiAgdHlwZSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5LFxufSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWwvY29udHJhY3RzXCI7XG5cbnR5cGUgTW9kZWxDbGFzcyA9IE1vZGVsQ2xhc3NUeXBlO1xuY29uc3QgTW9kZWxDbGFzcyA9IE1vZGVsQ2xhc3NWYWx1ZXM7XG5cbi8qKiBUYXNrIGhpbnQgRGF0YWJyaWNrcyBzdGFtcHMgb24gY2hhdCBjb21wbGV0aW9uIGVuZHBvaW50cy4gKi9cbmNvbnN0IENIQVRfVEFTSyA9IFwibGxtL3YxL2NoYXRcIjtcblxuLyoqIFRhc2sgaGludCBEYXRhYnJpY2tzIHN0YW1wcyBvbiBlbWJlZGRpbmcgZW5kcG9pbnRzLiAqL1xuY29uc3QgRU1CRURESU5HX1RBU0sgPSBcImxsbS92MS9lbWJlZGRpbmdzXCI7XG5cbi8qKiBXaGF0IGFuIGVuZHBvaW50IGNhbiBiZSBhc2tlZCB0byBkbywgYXMgZGVyaXZlZCBieSB7QGxpbmsgZW5kcG9pbnRDYXBhYmlsaXRpZXN9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbmRwb2ludENhcGFiaWxpdGllcyB7XG4gIC8qKiBPcGVuQUkgY2hhdC9jb21wbGV0aW9ucyArIFJlc3BvbnNlczogdGhlIHN1cmZhY2UgYSBjaGF0IGFnZW50IG5lZWRzLiAqL1xuICBjaGF0OiBib29sZWFuO1xuICAvKiogRW1iZWRkaW5nICh2ZWN0b3IpIGVuZHBvaW50LiAqL1xuICBlbWJlZGRpbmc6IGJvb2xlYW47XG4gIC8qKiBDb21wbGV0ZSBmdW5jdGlvbi10b29sIHJvdW5kLXRyaXAgKGNhbGwgcGx1cyBmdW5jdGlvbl9jYWxsX291dHB1dCByZXBsYXkpLiAqL1xuICB0b29sczogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBQcm92aWRlciBmYW1pbGllcyB2ZXJpZmllZCBhZ2FpbnN0IERhdGFicmlja3MgUmVzcG9uc2VzL09wZW4gUmVzcG9uc2VzIHdpdGhcbiAqIGJvdGggYSBmb3JjZWQgZnVuY3Rpb24gY2FsbCBhbmQgYSBzdGF0ZWxlc3MgYGZ1bmN0aW9uX2NhbGxfb3V0cHV0YCByZXBsYXkuXG4gKlxuICogRGF0YWJyaWNrcycgZW5kcG9pbnQgbGlzdC9PcGVuQVBJIGN1cnJlbnRseSBleHBvc2VzIG5vIHRvb2xzIGNhcGFiaWxpdHkgYml0LlxuICogS2VlcCB0aGlzIGNvbnNlcnZhdGl2ZTogYW4gdW5rbm93biBjaGF0IGZhbWlseSBpcyBub3QgYWdlbnQtc2FmZSB1bnRpbCBpdCBpc1xuICogdmVyaWZpZWQuIEdlbWluaSBpcyBleGNsdWRlZCBiZWNhdXNlIGl0IGVtaXRzIGEgY2FsbCBidXQgT3BlbiBSZXNwb25zZXNcbiAqIGNhbm5vdCByZXBsYXkgdGhlIHJlcXVpcmVkIHRob3VnaHQgc2lnbmF0dXJlOyBHUFQtT1NTIHJlamVjdHMgUmVzcG9uc2VzXG4gKiBwYXNzdGhyb3VnaCBlbnRpcmVseS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1cHBvcnRzVG9vbHNCeUZhbWlseShuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgbiA9IG5hbWUudG9Mb3dlckNhc2UoKTtcbiAgaWYgKG4uaW5jbHVkZXMoXCJnZW1pbmlcIikgfHwgbi5pbmNsdWRlcyhcImdwdC1vc3NcIikpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIChcbiAgICBuLmluY2x1ZGVzKFwiY2xhdWRlXCIpIHx8XG4gICAgbi5pbmNsdWRlcyhcImdwdFwiKSB8fFxuICAgIG4uaW5jbHVkZXMoXCJxd2VuXCIpIHx8XG4gICAgbi5pbmNsdWRlcyhcImdsbVwiKSB8fFxuICAgIG4uaW5jbHVkZXMoXCJsbGFtYVwiKVxuICApO1xufVxuXG4vKipcbiAqIERlcml2ZSBhbiBlbmRwb2ludCdzIGNhcGFiaWxpdGllcyBmcm9tIGl0cyBEYXRhYnJpY2tzIHRhc2sgaGludCBhbmQgaXRzXG4gKiBjbGFzc2lmaWVkIHtAbGluayBNb2RlbENsYXNzfSwgc28gY29uc3VtZXJzIGZpbHRlciBvbiBjYXBhYmlsaXR5IGluc3RlYWQgb2ZcbiAqIHJlLWRlcml2aW5nIGl0IGZyb20gcmF3IGB0YXNrYCAvIGBjbGFzc2Agc3RyaW5ncy5cbiAqXG4gKiBFaXRoZXIgc2lnbmFsIGFsb25lIGlzIGVub3VnaDogdGhlIHRhc2sgaGludCBpcyBhdXRob3JpdGF0aXZlIHdoZW4gcHJlc2VudCxcbiAqIGFuZCB0aGUgY2xhc3MgY292ZXJzIGVuZHBvaW50cyBEYXRhYnJpY2tzIGxlZnQgdW50YXNrZWQgYnV0IHRoZSBjbGFzc2lmaWVyXG4gKiByZWNvZ25pemVkLiBFbWJlZGRpbmcgd2lucyBvdmVyIGNoYXQgd2hlbiBib3RoIHBvaW50IGF0IGl0LCBzaW5jZSB0aGUgdHdvIGFyZVxuICogbm90IGludGVyY2hhbmdlYWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuZHBvaW50Q2FwYWJpbGl0aWVzKGVuZHBvaW50OiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5KTogRW5kcG9pbnRDYXBhYmlsaXRpZXMge1xuICBjb25zdCBlbWJlZGRpbmcgPSBlbmRwb2ludC50YXNrID09PSBFTUJFRERJTkdfVEFTSyB8fCBlbmRwb2ludC5jbGFzcyA9PT0gTW9kZWxDbGFzcy5FbWJlZGRpbmc7XG4gIC8vIEV2ZXJ5IG5vbi1lbWJlZGRpbmcgY2xhc3MgaXMgYSBjaGF0IGJhbmQsIHNvIFwiY2xhc3NpZmllZCBidXQgbm90IGVtYmVkZGluZ1wiXG4gIC8vIGlzIHRoZSBjbGFzcy1zaWRlIHRlc3QgZm9yIGNoYXQgY2FwYWJpbGl0eS5cbiAgY29uc3QgY2hhdCA9ICFlbWJlZGRpbmcgJiYgKGVuZHBvaW50LnRhc2sgPT09IENIQVRfVEFTSyB8fCBlbmRwb2ludC5jbGFzcyAhPT0gdW5kZWZpbmVkKTtcbiAgY29uc3QgdG9vbHMgPSBjaGF0ICYmIChlbmRwb2ludC5zdXBwb3J0c1Rvb2xzID8/IHN1cHBvcnRzVG9vbHNCeUZhbWlseShlbmRwb2ludC5uYW1lKSk7XG4gIHJldHVybiB7IGNoYXQsIGVtYmVkZGluZywgdG9vbHMgfTtcbn1cblxuLyoqIEZhbWlseS1oZXVyaXN0aWMgY2xhc3NpZmljYXRpb24gb2YgYSBzaW5nbGUgZW5kcG9pbnQgbmFtZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmFtaWx5Q2xhc3Mge1xuICAvKiogQ2hhdCBjYXBhYmlsaXR5IGJhbmQgdGhlIGZhbWlseSBtYXBzIHRvIChuZXZlciBlbWJlZGRpbmcpLiAqL1xuICBjbGFzczogTW9kZWxDbGFzcztcbiAgLyoqIEludHJhLWZhbWlseSBvcmRlcmluZyBoaW50IChoaWdoZXIgaXMgbmV3ZXIgLyBtb3JlIGNhcGFibGUpLiAqL1xuICByYW5rOiBudW1iZXI7XG59XG5cbi8qKlxuICogTnVtZXJpYyBgW21ham9yLCBtaW5vciwgcGF0Y2hdYCB2ZXJzaW9uIHBhcnNlZCBmcm9tIGFuIGVuZHBvaW50XG4gKiBuYW1lLCB1c2VkIHRvIG9yZGVyIHNpYmxpbmdzIHdpdGhpbiBhIGZhbWlseS90aWVyLiBTdGFydHMgYXQgdGhlXG4gKiBmaXJzdCBkaWdpdCBpbiB0aGUgbmFtZSwgdGhlbiByZWFkcyBzdWNjZXNzaXZlIHNlcGFyYXRvci1kZWxpbWl0ZWQsXG4gKiBkaWdpdC1wcmVmaXhlZCBjaHVua3MgYXMgdGhlIHRocmVlIGNvbXBvbmVudHMgKG1pc3Npbmcgb25lcyBkZWZhdWx0XG4gKiB0byBgMGApOlxuICpcbiAqICAgLSBgZGF0YWJyaWNrcy1jbGF1ZGUtb3B1cy00LThgICAgLT4gYFs0LCA4LCAwXWBcbiAqICAgLSBgZGF0YWJyaWNrcy1jbGF1ZGUtb3B1cy00LTEwYCAgLT4gYFs0LCAxMCwgMF1gIChzb3J0cyBhYm92ZSA0LTgpXG4gKiAgIC0gYGRhdGFicmlja3MtbWV0YS1sbGFtYS0zLTMtNzBiYC0+IGBbMywgMywgNzBdYFxuICogICAtIGBkYXRhYnJpY2tzLWJnZS1sYXJnZS1lbmAgICAgICAtPiBgWzAsIDAsIDBdYCAobm8gZGlnaXRzKVxuICpcbiAqIENvbXBvbmVudC13aXNlIGNvbXBhcmlzb24gKG5vdCBhIGRlY2ltYWwgY29sbGFwc2UpIHNvIGA0LjEwYCBiZWF0c1xuICogYDQuOGAgLSB0aGUgYnVnIGEgYG1ham9yICsgbWlub3IvMTBgIHNjb3JlIHdvdWxkIGhpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcnNpb25UdXBsZShuYW1lOiBzdHJpbmcpOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICBjb25zdCBzdGFydCA9IG5hbWUuc2VhcmNoKC9cXGQvKTtcbiAgaWYgKHN0YXJ0IDwgMCkgcmV0dXJuIFswLCAwLCAwXTtcbiAgY29uc3QgbnVtcyA9IG5hbWVcbiAgICAuc2xpY2Uoc3RhcnQpXG4gICAgLnNwbGl0KC9bXmEtejAtOV0rL2kpXG4gICAgLm1hcCgoY2h1bmspID0+IGNodW5rLm1hdGNoKC9eXFxkKy8pPy5bMF0pXG4gICAgLmZpbHRlcigoZGlnaXRzKTogZGlnaXRzIGlzIHN0cmluZyA9PiBkaWdpdHMgIT09IHVuZGVmaW5lZClcbiAgICAubWFwKE51bWJlcik7XG4gIHJldHVybiBbbnVtc1swXSA/PyAwLCBudW1zWzFdID8/IDAsIG51bXNbMl0gPz8gMF07XG59XG5cbi8qKiBDb21wYXJlIHR3byB2ZXJzaW9uIHR1cGxlcyBzbyB0aGUgaGlnaGVyIHZlcnNpb24gc29ydHMgZmlyc3QgKGRlc2NlbmRpbmcpLiAqL1xuZnVuY3Rpb24gY29tcGFyZVZlcnNpb25EZXNjKGE6IHJlYWRvbmx5IG51bWJlcltdLCBiOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlciB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgMzsgaSsrKSB7XG4gICAgY29uc3QgZGlmZiA9IChiW2ldID8/IDApIC0gKGFbaV0gPz8gMCk7XG4gICAgaWYgKGRpZmYgIT09IDApIHJldHVybiBkaWZmO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vKipcbiAqIE1vbm90b25pYyB2ZXJzaW9uIGtleSBmb3Igb3JkZXJpbmcgc2libGluZ3Mgd2l0aGluIGEgZmFtaWx5L3RpZXJcbiAqIChlLmcuIGBvcHVzLTQtOGAgb3ZlciBgb3B1cy00LTdgKS4gRW5jb2RlcyB0aGUge0BsaW5rIHZlcnNpb25UdXBsZX1cbiAqIGFzIGEgc2luZ2xlIG51bWJlciBzbyBjYWxsZXJzIHRoYXQgbmVlZCBhIHNjYWxhciByYW5rICh0aGUgZmFtaWx5XG4gKiBoZXVyaXN0aWMsIHRoZSBzdGF0aWMgZmFsbGJhY2sgb3JkZXJpbmcpIGtlZXAgd29ya2luZzsgdGhlIGVuY29kaW5nXG4gKiBwcmVzZXJ2ZXMgY29tcG9uZW50IG9yZGVyIHdpdGhvdXQgdGhlIGRlY2ltYWwtY29sbGFwc2UgYnVnLlxuICovXG5mdW5jdGlvbiB2ZXJzaW9uU2NvcmUobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgY29uc3QgW21ham9yLCBtaW5vciwgcGF0Y2hdID0gdmVyc2lvblR1cGxlKG5hbWUpO1xuICByZXR1cm4gbWFqb3IgKiAxXzAwMF8wMDAgKyBtaW5vciAqIDFfMDAwICsgcGF0Y2g7XG59XG5cbi8qKlxuICogQmVzdC1lZmZvcnQgY2hhdCBjYXBhYmlsaXR5IGJhbmQgZm9yIGFuIGVuZHBvaW50IHdlIGhhdmUgbm8gbGl2ZVxuICogc2NvcmUgZm9yLCBrZXllZCBvZmYgcHJvdmlkZXIgZmFtaWx5IGFuZCB0aGUgd2VsbC1rbm93biB2YXJpYW50IHdvcmRzXG4gKiBpbiB0aGUgbmFtZSAoYG9wdXNgL2Bzb25uZXRgL2BoYWlrdWAsIGBwcm9gL2BtaW5pYC9gbmFub2AsXG4gKiBgZmxhc2hgL2BmbGFzaC1saXRlYCwgTGxhbWEgcGFyYW1ldGVyIHNpemVzLCBldGMpLiBSZXR1cm5zIGBudWxsYCBmb3JcbiAqIG5hbWVzIHdlIGRvbid0IHJlY29nbml6ZSBzbyB1bmtub3duIGN1c3RvbSBlbmRwb2ludHMgYXJlIG5ldmVyXG4gKiBhdXRvLXNlbGVjdGVkIGFzIGEgZGVmYXVsdC4gVGhlIGFjY29tcGFueWluZyBgcmFua2Agb3JkZXJzIHNpYmxpbmdzXG4gKiB3aXRoaW4gYSBjbGFzcy4gT25seSBldmVyIHJldHVybnMgYSBjaGF0IGJhbmQgLSBlbWJlZGRpbmcgZW5kcG9pbnRzXG4gKiBhcmUgY2xhc3NpZmllZCBieSB0YXNrLCBub3QgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsYXNzaWZ5QnlGYW1pbHkobmFtZTogc3RyaW5nKTogRmFtaWx5Q2xhc3MgfCBudWxsIHtcbiAgY29uc3QgbiA9IG5hbWUudG9Mb3dlckNhc2UoKTtcbiAgY29uc3QgYXQgPSAoY2xzOiBNb2RlbENsYXNzKTogRmFtaWx5Q2xhc3MgPT4gKHsgY2xhc3M6IGNscywgcmFuazogdmVyc2lvblNjb3JlKG4pIH0pO1xuXG4gIC8vIEFudGhyb3BpYyBDbGF1ZGVcbiAgaWYgKG4uaW5jbHVkZXMoXCJvcHVzXCIpKSByZXR1cm4gYXQoTW9kZWxDbGFzcy5DaGF0VGhpbmtpbmcpO1xuICBpZiAobi5pbmNsdWRlcyhcInNvbm5ldFwiKSkgcmV0dXJuIGF0KE1vZGVsQ2xhc3MuQ2hhdEJhbGFuY2VkKTtcbiAgaWYgKG4uaW5jbHVkZXMoXCJoYWlrdVwiKSkgcmV0dXJuIGF0KE1vZGVsQ2xhc3MuQ2hhdEZhc3QpO1xuXG4gIC8vIE9wZW5BSSBvcGVuLXdlaWdodHMgKGNoZWNrIGJlZm9yZSB0aGUgZ2VuZXJpYyBncHQgYnJhbmNoKVxuICBpZiAobi5pbmNsdWRlcyhcImdwdC1vc3NcIikpIHtcbiAgICByZXR1cm4gYXQobi5pbmNsdWRlcyhcIjEyMGJcIikgPyBNb2RlbENsYXNzLkNoYXRCYWxhbmNlZCA6IE1vZGVsQ2xhc3MuQ2hhdEZhc3QpO1xuICB9XG4gIC8vIE9wZW5BSSBHUFQgZmFtaWx5XG4gIGlmIChuLmluY2x1ZGVzKFwiZ3B0XCIpKSB7XG4gICAgaWYgKG4uaW5jbHVkZXMoXCJwcm9cIikpIHJldHVybiBhdChNb2RlbENsYXNzLkNoYXRUaGlua2luZyk7XG4gICAgaWYgKG4uaW5jbHVkZXMoXCJtaW5pXCIpIHx8IG4uaW5jbHVkZXMoXCJuYW5vXCIpKSByZXR1cm4gYXQoTW9kZWxDbGFzcy5DaGF0RmFzdCk7XG4gICAgcmV0dXJuIGF0KE1vZGVsQ2xhc3MuQ2hhdEJhbGFuY2VkKTtcbiAgfVxuXG4gIC8vIEdvb2dsZSBHZW1pbmkgLyBHZW1tYVxuICBpZiAobi5pbmNsdWRlcyhcImdlbWluaVwiKSkge1xuICAgIGlmIChuLmluY2x1ZGVzKFwiZmxhc2gtbGl0ZVwiKSkgcmV0dXJuIGF0KE1vZGVsQ2xhc3MuQ2hhdEZhc3QpO1xuICAgIGlmIChuLmluY2x1ZGVzKFwicHJvXCIpKSByZXR1cm4gYXQoTW9kZWxDbGFzcy5DaGF0VGhpbmtpbmcpO1xuICAgIHJldHVybiBhdChNb2RlbENsYXNzLkNoYXRCYWxhbmNlZCk7XG4gIH1cbiAgaWYgKG4uaW5jbHVkZXMoXCJnZW1tYVwiKSkgcmV0dXJuIGF0KE1vZGVsQ2xhc3MuQ2hhdEZhc3QpO1xuXG4gIC8vIE1ldGEgTGxhbWFcbiAgaWYgKG4uaW5jbHVkZXMoXCJsbGFtYVwiKSkge1xuICAgIGlmIChuLmluY2x1ZGVzKFwibWF2ZXJpY2tcIikgfHwgbi5pbmNsdWRlcyhcIjQwNWJcIikpIHJldHVybiBhdChNb2RlbENsYXNzLkNoYXRUaGlua2luZyk7XG4gICAgaWYgKG4uaW5jbHVkZXMoXCI3MGJcIikpIHJldHVybiBhdChNb2RlbENsYXNzLkNoYXRCYWxhbmNlZCk7XG4gICAgaWYgKG4uaW5jbHVkZXMoXCI4YlwiKSB8fCBuLmluY2x1ZGVzKFwiMWJcIikpIHJldHVybiBhdChNb2RlbENsYXNzLkNoYXRGYXN0KTtcbiAgICByZXR1cm4gYXQoTW9kZWxDbGFzcy5DaGF0QmFsYW5jZWQpO1xuICB9XG5cbiAgLy8gQWxpYmFiYSBRd2VuXG4gIGlmIChuLmluY2x1ZGVzKFwicXdlblwiKSkgcmV0dXJuIGF0KE1vZGVsQ2xhc3MuQ2hhdEJhbGFuY2VkKTtcblxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqIExpbmVhci1pbnRlcnBvbGF0ZWQgcXVhbnRpbGUgb2YgYW4gYXNjZW5kaW5nLXNvcnRlZCBudW1lcmljIGFycmF5LiAqL1xuZnVuY3Rpb24gcXVhbnRpbGUoc29ydGVkQXNjOiByZWFkb25seSBudW1iZXJbXSwgcDogbnVtYmVyKTogbnVtYmVyIHtcbiAgaWYgKHNvcnRlZEFzYy5sZW5ndGggPT09IDApIHJldHVybiBOdW1iZXIuTmFOO1xuICBjb25zdCBpZHggPSAoc29ydGVkQXNjLmxlbmd0aCAtIDEpICogcDtcbiAgY29uc3QgbG8gPSBNYXRoLmZsb29yKGlkeCk7XG4gIGNvbnN0IGhpID0gTWF0aC5jZWlsKGlkeCk7XG4gIGlmIChsbyA9PT0gaGkpIHJldHVybiBzb3J0ZWRBc2NbbG9dITtcbiAgcmV0dXJuIHNvcnRlZEFzY1tsb10hICsgKHNvcnRlZEFzY1toaV0hIC0gc29ydGVkQXNjW2xvXSEpICogKGlkeCAtIGxvKTtcbn1cblxuLyoqIEludGVybmFsIHNvcnRhYmxlIHdyYXBwZXIgY2FycnlpbmcgdGhlIG9yZGVyaW5nIGtleXMgZm9yIGEgYnVja2V0IGVudHJ5LiAqL1xuaW50ZXJmYWNlIFJhbmtlZCB7XG4gIGVwOiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5O1xuICAvKiogUXVhbGl0eSAoc2NvcmVkKSBvciBmYW1pbHkgdmVyc2lvbiAodW5zY29yZWQpIC0gaGlnaGVyIGZpcnN0LiAqL1xuICBzb3J0OiBudW1iZXI7XG4gIC8qKiBTY29yZWQgZW5kcG9pbnRzIHJhbmsgYWhlYWQgb2YgZmFtaWx5LW9ubHkgZ3Vlc3Nlcy4gKi9cbiAgc2NvcmVkOiBib29sZWFuO1xuICB0aWVDb3N0OiBudW1iZXI7XG4gIHRpZVNwZWVkOiBudW1iZXI7XG4gIC8qKiBQYXJzZWQgbmFtZSB2ZXJzaW9uLCB0aGUgZmluYWwgdGllLWJyZWFrZXIgKG5ld2VyIHNpYmxpbmcgZmlyc3QpLiAqL1xuICB2ZXJzaW9uOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuZnVuY3Rpb24gcmFua09yZGVyKGE6IFJhbmtlZCwgYjogUmFua2VkKTogbnVtYmVyIHtcbiAgaWYgKGEuc2NvcmVkICE9PSBiLnNjb3JlZCkgcmV0dXJuIGEuc2NvcmVkID8gLTEgOiAxO1xuICBpZiAoYi5zb3J0ICE9PSBhLnNvcnQpIHJldHVybiBiLnNvcnQgLSBhLnNvcnQ7XG4gIGlmIChhLnRpZUNvc3QgIT09IGIudGllQ29zdCkgcmV0dXJuIGEudGllQ29zdCAtIGIudGllQ29zdDtcbiAgaWYgKGIudGllU3BlZWQgIT09IGEudGllU3BlZWQpIHJldHVybiBiLnRpZVNwZWVkIC0gYS50aWVTcGVlZDtcbiAgLy8gU2FtZSBzY29yZWQtbmVzcywgcXVhbGl0eSwgY29zdCwgYW5kIHNwZWVkIChlLmcuIHNldmVyYWwgQ2xhdWRlXG4gIC8vIE9wdXMgcG9pbnQgcmVsZWFzZXMpOiBwcmVmZXIgdGhlIG5ld2VyIHBhcnNlZCB2ZXJzaW9uIHNvXG4gIC8vIGBvcHVzLTQtOGAgYmVhdHMgYG9wdXMtNC03YC5cbiAgcmV0dXJuIGNvbXBhcmVWZXJzaW9uRGVzYyhhLnZlcnNpb24sIGIudmVyc2lvbik7XG59XG5cbi8qKlxuICogQnVja2V0IGxpdmUgZW5kcG9pbnRzIGludG8ge0BsaW5rIE1vZGVsQ2xhc3N9ZXMsIHJhbmtlZCBiZXN0LWZpcnN0XG4gKiB3aXRoaW4gZWFjaCBjaGF0IGJhbmQuXG4gKlxuICogRW1iZWRkaW5nIGVuZHBvaW50cyAoYHRhc2sgPT09IFwibGxtL3YxL2VtYmVkZGluZ3NcImApIGdvIGludG9cbiAqIHtAbGluayBNb2RlbENsYXNzLkVtYmVkZGluZ30gYnkgdGFzaywgaW4gbGlzdGluZyBvcmRlciAodGhleSBjYXJyeSBub1xuICogY2FwYWJpbGl0eSBzY29yZSB0byByYW5rIG9uKS5cbiAqXG4gKiBDaGF0IGVuZHBvaW50cyAoYHRhc2sgPT09IFwibGxtL3YxL2NoYXRcImApIHNwbGl0IGludG8gdGhlIHRocmVlIGNoYXRcbiAqIGJhbmRzLiBTY29yZWQgZW5kcG9pbnRzICh0aG9zZSBjYXJyeWluZyBhIGBwcm9maWxlLnF1YWxpdHlgKSBkcml2ZVxuICogdGhlIGJhbmRpbmc6IHRoZSBvYnNlcnZlZCBxdWFsaXR5IGRpc3RyaWJ1dGlvbiBpcyBzcGxpdCBhdCBpdHMgMS8zXG4gKiBhbmQgMi8zIHF1YW50aWxlcywgc28gdGhlIHRvcCB0aGlyZCBpcyB7QGxpbmsgTW9kZWxDbGFzcy5DaGF0VGhpbmtpbmd9LFxuICogdGhlIGJvdHRvbSB0aGlyZCB7QGxpbmsgTW9kZWxDbGFzcy5DaGF0RmFzdH0sIGFuZCB0aGUgbWlkZGxlXG4gKiB7QGxpbmsgTW9kZWxDbGFzcy5DaGF0QmFsYW5jZWR9LiBCZWNhdXNlIHRoZSB0aHJlc2hvbGRzIGNvbWUgZnJvbSB0aGVcbiAqIGRhdGEsIHRoZSBzcGxpdCBhZGFwdHMgYXMgRGF0YWJyaWNrcyBhZGRzIG9yIHJlc2NvcmVzIG1vZGVscyAtXG4gKiBub3RoaW5nIGlzIHBpbm5lZCB0byBhIGZpeGVkIHNjb3JlIGJhbmQuXG4gKlxuICogVW5zY29yZWQgY2hhdCBlbmRwb2ludHMgYXJlIHBsYWNlZCBieSB7QGxpbmsgY2xhc3NpZnlCeUZhbWlseX0gYW5kXG4gKiByYW5rZWQgYWZ0ZXIgdGhlIHNjb3JlZCBvbmVzIGluIHRoZWlyIGJhbmQ7IHVucmVjb2duaXplZCwgdW5zY29yZWRcbiAqIGVuZHBvaW50cyAoZS5nLiBjdXN0b20gZXh0ZXJuYWwgbW9kZWxzKSBhcmUgb21pdHRlZCBlbnRpcmVseSBzbyB0aGV5XG4gKiBhcmUgbmV2ZXIgcGlja2VkIGFzIGFuIGF1dG9tYXRpYyBkZWZhdWx0LlxuICpcbiAqIFdpdGhpbiBhIGNoYXQgYmFuZCwgc2NvcmVkIG1vZGVscyBzb3J0IGJ5IGBxdWFsaXR5YCBkZXNjLCB0aGVuIGBjb3N0YFxuICogYXNjLCB0aGVuIGBzcGVlZGAgZGVzYywgdGhlbiBwYXJzZWQgbmFtZSB2ZXJzaW9uIGRlc2M7IGZhbWlseS1vbmx5XG4gKiBtb2RlbHMgc29ydCBieSB2ZXJzaW9uIHJhbmsgdGhlbiBwYXJzZWQgdmVyc2lvbi4gVGhlIHZlcnNpb25cbiAqIHRpZS1icmVhayAoe0BsaW5rIHZlcnNpb25UdXBsZX0pIGlzIHdoYXQgc2VwYXJhdGVzIHBvaW50IHJlbGVhc2VzXG4gKiB0aGF0IHNoYXJlIGEgc2NvcmUgcHJvZmlsZSAoZS5nLiBgb3B1cy00LThgIGFoZWFkIG9mIGBvcHVzLTQtN2ApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xhc3NpZnlFbmRwb2ludHMoXG4gIGVuZHBvaW50czogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLFxuKTogUmVjb3JkPE1vZGVsQ2xhc3MsIFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXT4ge1xuICBjb25zdCBjaGF0ID0gZW5kcG9pbnRzLmZpbHRlcigoZSkgPT4gZS50YXNrID09PSBDSEFUX1RBU0spO1xuICBjb25zdCBxdWFsaXRpZXMgPSBjaGF0XG4gICAgLm1hcCgoZSkgPT4gZS5wcm9maWxlPy5xdWFsaXR5KVxuICAgIC5maWx0ZXIoKHEpOiBxIGlzIG51bWJlciA9PiBOdW1iZXIuaXNGaW5pdGUocSkpXG4gICAgLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgY29uc3QgbG93ID0gcXVhbnRpbGUocXVhbGl0aWVzLCAxIC8gMyk7XG4gIGNvbnN0IGhpZ2ggPSBxdWFudGlsZShxdWFsaXRpZXMsIDIgLyAzKTtcblxuICBjb25zdCBidWNrZXRzOiBSZWNvcmQ8TW9kZWxDbGFzcywgUmFua2VkW10+ID0ge1xuICAgIFtNb2RlbENsYXNzLkNoYXRUaGlua2luZ106IFtdLFxuICAgIFtNb2RlbENsYXNzLkNoYXRCYWxhbmNlZF06IFtdLFxuICAgIFtNb2RlbENsYXNzLkNoYXRGYXN0XTogW10sXG4gICAgW01vZGVsQ2xhc3MuRW1iZWRkaW5nXTogW10sXG4gIH07XG5cbiAgZm9yIChjb25zdCBlcCBvZiBjaGF0KSB7XG4gICAgY29uc3QgcSA9IGVwLnByb2ZpbGU/LnF1YWxpdHk7XG4gICAgaWYgKE51bWJlci5pc0Zpbml0ZShxKSkge1xuICAgICAgY29uc3QgcXVhbGl0eSA9IHEgYXMgbnVtYmVyO1xuICAgICAgY29uc3QgY2xzID1cbiAgICAgICAgcXVhbGl0eSA+PSBoaWdoXG4gICAgICAgICAgPyBNb2RlbENsYXNzLkNoYXRUaGlua2luZ1xuICAgICAgICAgIDogcXVhbGl0eSA8PSBsb3dcbiAgICAgICAgICAgID8gTW9kZWxDbGFzcy5DaGF0RmFzdFxuICAgICAgICAgICAgOiBNb2RlbENsYXNzLkNoYXRCYWxhbmNlZDtcbiAgICAgIGJ1Y2tldHNbY2xzXS5wdXNoKHtcbiAgICAgICAgZXAsXG4gICAgICAgIHNvcnQ6IHF1YWxpdHksXG4gICAgICAgIHNjb3JlZDogdHJ1ZSxcbiAgICAgICAgdGllQ29zdDogZXAucHJvZmlsZT8uY29zdCA/PyBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksXG4gICAgICAgIHRpZVNwZWVkOiBlcC5wcm9maWxlPy5zcGVlZCA/PyAwLFxuICAgICAgICB2ZXJzaW9uOiB2ZXJzaW9uVHVwbGUoZXAubmFtZSksXG4gICAgICB9KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBmYW1pbHkgPSBjbGFzc2lmeUJ5RmFtaWx5KGVwLm5hbWUpO1xuICAgIGlmICghZmFtaWx5KSBjb250aW51ZTtcbiAgICBidWNrZXRzW2ZhbWlseS5jbGFzc10ucHVzaCh7XG4gICAgICBlcCxcbiAgICAgIHNvcnQ6IGZhbWlseS5yYW5rLFxuICAgICAgc2NvcmVkOiBmYWxzZSxcbiAgICAgIHRpZUNvc3Q6IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxcbiAgICAgIHRpZVNwZWVkOiAwLFxuICAgICAgdmVyc2lvbjogdmVyc2lvblR1cGxlKGVwLm5hbWUpLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gRW1iZWRkaW5ncyBhcmUgYnVja2V0ZWQgYnkgdGFzayBpbiBsaXN0aW5nIG9yZGVyIC0gbm8gc2NvcmUgdG8gcmFuay5cbiAgY29uc3QgZW1iZWRkaW5ncyA9IGVuZHBvaW50cy5maWx0ZXIoKGUpID0+IGUudGFzayA9PT0gRU1CRURESU5HX1RBU0spO1xuXG4gIHJldHVybiB7XG4gICAgW01vZGVsQ2xhc3MuQ2hhdFRoaW5raW5nXTogYnVja2V0c1tNb2RlbENsYXNzLkNoYXRUaGlua2luZ10uc29ydChyYW5rT3JkZXIpLm1hcCgoeCkgPT4geC5lcCksXG4gICAgW01vZGVsQ2xhc3MuQ2hhdEJhbGFuY2VkXTogYnVja2V0c1tNb2RlbENsYXNzLkNoYXRCYWxhbmNlZF0uc29ydChyYW5rT3JkZXIpLm1hcCgoeCkgPT4geC5lcCksXG4gICAgW01vZGVsQ2xhc3MuQ2hhdEZhc3RdOiBidWNrZXRzW01vZGVsQ2xhc3MuQ2hhdEZhc3RdLnNvcnQocmFua09yZGVyKS5tYXAoKHgpID0+IHguZXApLFxuICAgIFtNb2RlbENsYXNzLkVtYmVkZGluZ106IGVtYmVkZGluZ3MsXG4gIH07XG59XG4iXX0=
@@ -5,7 +5,7 @@
5
5
  * token, the service principal can't list, or the workspace is unreachable -
6
6
  * the resolver still has to name *some* endpoint. This module holds that floor:
7
7
  * a small, hard-coded set of well-known Foundation Model API endpoint names,
8
- * each bucketed into a chat {@link ModelClass} by the Rust family policy
8
+ * each bucketed into a chat {@link ModelClass} by the TypeScript family policy
9
9
  * and ordered best-first.
10
10
  *
11
11
  * This is deliberately *server-only*. A browser client never talks to
@@ -15,8 +15,8 @@
15
15
  *
16
16
  * @module
17
17
  */
18
- import { model } from "@dbx-tools/shared-model";
19
- type ModelClass = model.ModelClass;
18
+ import { type ModelClass as ModelClassType } from "@dbx-tools/shared-model/contracts";
19
+ type ModelClass = ModelClassType;
20
20
  declare const ModelClass: {
21
21
  readonly ChatThinking: "chat-thinking";
22
22
  readonly ChatBalanced: "chat-balanced";
@@ -28,7 +28,7 @@ declare const ModelClass: {
28
28
  * {@link FALLBACK_MODEL_NAMES} list and ordered best-first by family rank. Sync
29
29
  * and workspace-independent: this is the *fallback opinion* used to seed default
30
30
  * lists or when the live catalogue is unreachable - live resolution prefers
31
- * the Rust-classified workspace catalogue. Returns `[]` for
31
+ * the classified workspace catalogue. Returns `[]` for
32
32
  * {@link ModelClass.Embedding} (the floor is chat-only).
33
33
  */
34
34
  export declare function modelsForClass(cls: ModelClass): readonly string[];
@@ -5,7 +5,7 @@
5
5
  * token, the service principal can't list, or the workspace is unreachable -
6
6
  * the resolver still has to name *some* endpoint. This module holds that floor:
7
7
  * a small, hard-coded set of well-known Foundation Model API endpoint names,
8
- * each bucketed into a chat {@link ModelClass} by the Rust family policy
8
+ * each bucketed into a chat {@link ModelClass} by the TypeScript family policy
9
9
  * and ordered best-first.
10
10
  *
11
11
  * This is deliberately *server-only*. A browser client never talks to
@@ -15,12 +15,12 @@
15
15
  *
16
16
  * @module
17
17
  */
18
- import { model } from "@dbx-tools/shared-model";
19
- import { rankEndpoints } from "./_native.js";
20
- const { ModelClass } = model;
18
+ import { ModelClass as ModelClassValues, } from "@dbx-tools/shared-model/contracts";
19
+ import { rankEndpoints } from "./_ranking.js";
20
+ const ModelClass = ModelClassValues;
21
21
  /**
22
22
  * Small, last-resort set of well-known Foundation Model API endpoint names,
23
- * ordered best-first within each class by the Rust model ranker.
23
+ * ordered best-first within each class by the model ranker.
24
24
  * Used only as the floor when the live `/serving-endpoints` catalogue can't be
25
25
  * read at resolve time; the live, score-driven classification supersedes it
26
26
  * whenever the workspace listing is available. Classes are not hard-coded here
@@ -46,7 +46,7 @@ const FALLBACK_ENDPOINTS = FALLBACK_MODEL_NAMES.map((name) => ({
46
46
  * {@link FALLBACK_MODEL_NAMES} list and ordered best-first by family rank. Sync
47
47
  * and workspace-independent: this is the *fallback opinion* used to seed default
48
48
  * lists or when the live catalogue is unreachable - live resolution prefers
49
- * the Rust-classified workspace catalogue. Returns `[]` for
49
+ * the classified workspace catalogue. Returns `[]` for
50
50
  * {@link ModelClass.Embedding} (the floor is chat-only).
51
51
  */
52
52
  export function modelsForClass(cls) {
@@ -68,4 +68,4 @@ export const FALLBACK_MODEL_IDS = [
68
68
  ...modelsForClass(ModelClass.ChatBalanced),
69
69
  ...modelsForClass(ModelClass.ChatFast),
70
70
  ];
71
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFsbGJhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmFsbGJhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFFSCxPQUFPLEVBQUUsS0FBSyxFQUErQixNQUFNLHlCQUF5QixDQUFDO0FBRTdFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHN0MsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLEtBQUssQ0FBQztBQUU3Qjs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxvQkFBb0IsR0FBc0I7SUFDOUMsNEJBQTRCO0lBQzVCLHdCQUF3QjtJQUN4QiwyQkFBMkI7SUFDM0IsOEJBQThCO0lBQzlCLG9CQUFvQjtJQUNwQix3Q0FBd0M7SUFDeEMsNkJBQTZCO0lBQzdCLHVCQUF1QjtJQUN2Qix1Q0FBdUM7Q0FDeEMsQ0FBQztBQUVGLE1BQU0sa0JBQWtCLEdBQXNDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNoRyxJQUFJO0lBQ0osSUFBSSxFQUFFLGFBQWE7Q0FDcEIsQ0FBQyxDQUFDLENBQUM7QUFFSjs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxHQUFlO0lBQzVDLE9BQU8sYUFBYSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxDQUFDO1NBQzFELE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVUsS0FBSyxHQUFHLENBQUM7U0FDN0MsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFFRCxxREFBcUQ7QUFDckQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxHQUFlO0lBQzNDLE9BQU8sY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBRSxDQUFDO0FBQ2pDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQXNCO0lBQ25ELEdBQUcsY0FBYyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUM7SUFDMUMsR0FBRyxjQUFjLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQztJQUMxQyxHQUFHLGNBQWMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDO0NBQ3ZDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNlcnZlci1zaWRlIG9mZmxpbmUgZmFsbGJhY2sgb3BpbmlvbiBmb3IgbW9kZWwgc2VsZWN0aW9uLlxuICpcbiAqIFdoZW4gdGhlIGxpdmUgYC9zZXJ2aW5nLWVuZHBvaW50c2AgY2F0YWxvZ3VlIGNhbid0IGJlIHJlYWQgYXQgYWxsIC0gbm8gdXNlclxuICogdG9rZW4sIHRoZSBzZXJ2aWNlIHByaW5jaXBhbCBjYW4ndCBsaXN0LCBvciB0aGUgd29ya3NwYWNlIGlzIHVucmVhY2hhYmxlIC1cbiAqIHRoZSByZXNvbHZlciBzdGlsbCBoYXMgdG8gbmFtZSAqc29tZSogZW5kcG9pbnQuIFRoaXMgbW9kdWxlIGhvbGRzIHRoYXQgZmxvb3I6XG4gKiBhIHNtYWxsLCBoYXJkLWNvZGVkIHNldCBvZiB3ZWxsLWtub3duIEZvdW5kYXRpb24gTW9kZWwgQVBJIGVuZHBvaW50IG5hbWVzLFxuICogZWFjaCBidWNrZXRlZCBpbnRvIGEgY2hhdCB7QGxpbmsgTW9kZWxDbGFzc30gYnkgdGhlIFJ1c3QgZmFtaWx5IHBvbGljeVxuICogYW5kIG9yZGVyZWQgYmVzdC1maXJzdC5cbiAqXG4gKiBUaGlzIGlzIGRlbGliZXJhdGVseSAqc2VydmVyLW9ubHkqLiBBIGJyb3dzZXIgY2xpZW50IG5ldmVyIHRhbGtzIHRvXG4gKiBEYXRhYnJpY2tzIGRpcmVjdGx5IC0gaXQgYWx3YXlzIGdvZXMgdGhyb3VnaCB0aGlzIHNlcnZlciAtIHNvIGl0IGhhcyBub3RoaW5nXG4gKiB0byBmYWxsIGJhY2sgdG8gYW5kIG11c3Qgbm90IGFzc3VtZSBhIHN0YWxlLCBiYWtlZC1pbiBtb2RlbCBsaXN0OyBpdCBjb25zdW1lc1xuICogdGhlIGNsYXNzaWZpZWQgbGl2ZSBgL21vZGVsc2AgcmVzcG9uc2UgaW5zdGVhZC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgbW9kZWwsIHR5cGUgU2VydmluZ0VuZHBvaW50U3VtbWFyeSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tb2RlbFwiO1xuXG5pbXBvcnQgeyByYW5rRW5kcG9pbnRzIH0gZnJvbSBcIi4vX25hdGl2ZS50c1wiO1xuXG50eXBlIE1vZGVsQ2xhc3MgPSBtb2RlbC5Nb2RlbENsYXNzO1xuY29uc3QgeyBNb2RlbENsYXNzIH0gPSBtb2RlbDtcblxuLyoqXG4gKiBTbWFsbCwgbGFzdC1yZXNvcnQgc2V0IG9mIHdlbGwta25vd24gRm91bmRhdGlvbiBNb2RlbCBBUEkgZW5kcG9pbnQgbmFtZXMsXG4gKiBvcmRlcmVkIGJlc3QtZmlyc3Qgd2l0aGluIGVhY2ggY2xhc3MgYnkgdGhlIFJ1c3QgbW9kZWwgcmFua2VyLlxuICogVXNlZCBvbmx5IGFzIHRoZSBmbG9vciB3aGVuIHRoZSBsaXZlIGAvc2VydmluZy1lbmRwb2ludHNgIGNhdGFsb2d1ZSBjYW4ndCBiZVxuICogcmVhZCBhdCByZXNvbHZlIHRpbWU7IHRoZSBsaXZlLCBzY29yZS1kcml2ZW4gY2xhc3NpZmljYXRpb24gc3VwZXJzZWRlcyBpdFxuICogd2hlbmV2ZXIgdGhlIHdvcmtzcGFjZSBsaXN0aW5nIGlzIGF2YWlsYWJsZS4gQ2xhc3NlcyBhcmUgbm90IGhhcmQtY29kZWQgaGVyZVxuICogLSBlYWNoIG5hbWUgaXMgY2xhc3NpZmllZCBieSBmYW1pbHkgaGV1cmlzdGljLlxuICovXG5jb25zdCBGQUxMQkFDS19NT0RFTF9OQU1FUzogcmVhZG9ubHkgc3RyaW5nW10gPSBbXG4gIFwiZGF0YWJyaWNrcy1jbGF1ZGUtb3B1cy00LThcIixcbiAgXCJkYXRhYnJpY2tzLWdwdC01LTUtcHJvXCIsXG4gIFwiZGF0YWJyaWNrcy1nZW1pbmktMy0xLXByb1wiLFxuICBcImRhdGFicmlja3MtY2xhdWRlLXNvbm5ldC00LTZcIixcbiAgXCJkYXRhYnJpY2tzLWdwdC01LTVcIixcbiAgXCJkYXRhYnJpY2tzLW1ldGEtbGxhbWEtMy0zLTcwYi1pbnN0cnVjdFwiLFxuICBcImRhdGFicmlja3MtY2xhdWRlLWhhaWt1LTQtNVwiLFxuICBcImRhdGFicmlja3MtZ3B0LTUtbmFub1wiLFxuICBcImRhdGFicmlja3MtbWV0YS1sbGFtYS0zLTEtOGItaW5zdHJ1Y3RcIixcbl07XG5cbmNvbnN0IEZBTExCQUNLX0VORFBPSU5UUzogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdID0gRkFMTEJBQ0tfTU9ERUxfTkFNRVMubWFwKChuYW1lKSA9PiAoe1xuICBuYW1lLFxuICB0YXNrOiBcImxsbS92MS9jaGF0XCIsXG59KSk7XG5cbi8qKlxuICogU3RhdGljIGZhbGxiYWNrIG1vZGVsIGlkcyBmb3IgYSBjaGF0IGNsYXNzLCBkcmF3biBmcm9tIHRoZSBzbWFsbCBidWlsdC1pblxuICoge0BsaW5rIEZBTExCQUNLX01PREVMX05BTUVTfSBsaXN0IGFuZCBvcmRlcmVkIGJlc3QtZmlyc3QgYnkgZmFtaWx5IHJhbmsuIFN5bmNcbiAqIGFuZCB3b3Jrc3BhY2UtaW5kZXBlbmRlbnQ6IHRoaXMgaXMgdGhlICpmYWxsYmFjayBvcGluaW9uKiB1c2VkIHRvIHNlZWQgZGVmYXVsdFxuICogbGlzdHMgb3Igd2hlbiB0aGUgbGl2ZSBjYXRhbG9ndWUgaXMgdW5yZWFjaGFibGUgLSBsaXZlIHJlc29sdXRpb24gcHJlZmVyc1xuICogdGhlIFJ1c3QtY2xhc3NpZmllZCB3b3Jrc3BhY2UgY2F0YWxvZ3VlLiBSZXR1cm5zIGBbXWAgZm9yXG4gKiB7QGxpbmsgTW9kZWxDbGFzcy5FbWJlZGRpbmd9ICh0aGUgZmxvb3IgaXMgY2hhdC1vbmx5KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vZGVsc0ZvckNsYXNzKGNsczogTW9kZWxDbGFzcyk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgcmV0dXJuIHJhbmtFbmRwb2ludHMoRkFMTEJBQ0tfRU5EUE9JTlRTLCB7IG1vZGVsQ2xhc3M6IGNscyB9KVxuICAgIC5maWx0ZXIoKHJhbmtlZCkgPT4gcmFua2VkLm1vZGVsQ2xhc3MgPT09IGNscylcbiAgICAubWFwKChyYW5rZWQpID0+IHJhbmtlZC5lbmRwb2ludC5uYW1lKTtcbn1cblxuLyoqIFRvcCBzdGF0aWMgZmFsbGJhY2sgbW9kZWwgaWQgZm9yIGEgY2hhdCBjbGFzcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbEZvckNsYXNzKGNsczogTW9kZWxDbGFzcyk6IHN0cmluZyB7XG4gIHJldHVybiBtb2RlbHNGb3JDbGFzcyhjbHMpWzBdITtcbn1cblxuLyoqXG4gKiBQcmlvcml0eS1vcmRlcmVkIGZhbGxiYWNrIGNoYWluIChDaGF0VGhpbmtpbmcgLT4gQ2hhdEJhbGFuY2VkIC0+IENoYXRGYXN0KVxuICogb3ZlciB0aGUgc21hbGwgYnVpbHQtaW4gbGlzdC4gVGhlIGZsb29yIHdhbGtlZCBhdCByZXNvbHZlIHRpbWUgd2hlbiBubyBhZ2VudFxuICogLyBwbHVnaW4gLyBlbnYgLyByZXF1ZXN0IG1vZGVsIGlzIHNldCAqYW5kKiB0aGUgbGl2ZSBjYXRhbG9ndWUgeWllbGRzIG5vdGhpbmcuXG4gKi9cbmV4cG9ydCBjb25zdCBGQUxMQkFDS19NT0RFTF9JRFM6IHJlYWRvbmx5IHN0cmluZ1tdID0gW1xuICAuLi5tb2RlbHNGb3JDbGFzcyhNb2RlbENsYXNzLkNoYXRUaGlua2luZyksXG4gIC4uLm1vZGVsc0ZvckNsYXNzKE1vZGVsQ2xhc3MuQ2hhdEJhbGFuY2VkKSxcbiAgLi4ubW9kZWxzRm9yQ2xhc3MoTW9kZWxDbGFzcy5DaGF0RmFzdCksXG5dO1xuIl19
71
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFsbGJhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmFsbGJhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFFSCxPQUFPLEVBQ0wsVUFBVSxJQUFJLGdCQUFnQixHQUcvQixNQUFNLG1DQUFtQyxDQUFDO0FBRTNDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHOUMsTUFBTSxVQUFVLEdBQUcsZ0JBQWdCLENBQUM7QUFFcEM7Ozs7Ozs7R0FPRztBQUNILE1BQU0sb0JBQW9CLEdBQXNCO0lBQzlDLDRCQUE0QjtJQUM1Qix3QkFBd0I7SUFDeEIsMkJBQTJCO0lBQzNCLDhCQUE4QjtJQUM5QixvQkFBb0I7SUFDcEIsd0NBQXdDO0lBQ3hDLDZCQUE2QjtJQUM3Qix1QkFBdUI7SUFDdkIsdUNBQXVDO0NBQ3hDLENBQUM7QUFFRixNQUFNLGtCQUFrQixHQUFzQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDaEcsSUFBSTtJQUNKLElBQUksRUFBRSxhQUFhO0NBQ3BCLENBQUMsQ0FBQyxDQUFDO0FBRUo7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsR0FBZTtJQUM1QyxPQUFPLGFBQWEsQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FBQztTQUMxRCxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEtBQUssR0FBRyxDQUFDO1NBQzdDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMzQyxDQUFDO0FBRUQscURBQXFEO0FBQ3JELE1BQU0sVUFBVSxhQUFhLENBQUMsR0FBZTtJQUMzQyxPQUFPLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUUsQ0FBQztBQUNqQyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFzQjtJQUNuRCxHQUFHLGNBQWMsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDO0lBQzFDLEdBQUcsY0FBYyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUM7SUFDMUMsR0FBRyxjQUFjLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQztDQUN2QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTZXJ2ZXItc2lkZSBvZmZsaW5lIGZhbGxiYWNrIG9waW5pb24gZm9yIG1vZGVsIHNlbGVjdGlvbi5cbiAqXG4gKiBXaGVuIHRoZSBsaXZlIGAvc2VydmluZy1lbmRwb2ludHNgIGNhdGFsb2d1ZSBjYW4ndCBiZSByZWFkIGF0IGFsbCAtIG5vIHVzZXJcbiAqIHRva2VuLCB0aGUgc2VydmljZSBwcmluY2lwYWwgY2FuJ3QgbGlzdCwgb3IgdGhlIHdvcmtzcGFjZSBpcyB1bnJlYWNoYWJsZSAtXG4gKiB0aGUgcmVzb2x2ZXIgc3RpbGwgaGFzIHRvIG5hbWUgKnNvbWUqIGVuZHBvaW50LiBUaGlzIG1vZHVsZSBob2xkcyB0aGF0IGZsb29yOlxuICogYSBzbWFsbCwgaGFyZC1jb2RlZCBzZXQgb2Ygd2VsbC1rbm93biBGb3VuZGF0aW9uIE1vZGVsIEFQSSBlbmRwb2ludCBuYW1lcyxcbiAqIGVhY2ggYnVja2V0ZWQgaW50byBhIGNoYXQge0BsaW5rIE1vZGVsQ2xhc3N9IGJ5IHRoZSBUeXBlU2NyaXB0IGZhbWlseSBwb2xpY3lcbiAqIGFuZCBvcmRlcmVkIGJlc3QtZmlyc3QuXG4gKlxuICogVGhpcyBpcyBkZWxpYmVyYXRlbHkgKnNlcnZlci1vbmx5Ki4gQSBicm93c2VyIGNsaWVudCBuZXZlciB0YWxrcyB0b1xuICogRGF0YWJyaWNrcyBkaXJlY3RseSAtIGl0IGFsd2F5cyBnb2VzIHRocm91Z2ggdGhpcyBzZXJ2ZXIgLSBzbyBpdCBoYXMgbm90aGluZ1xuICogdG8gZmFsbCBiYWNrIHRvIGFuZCBtdXN0IG5vdCBhc3N1bWUgYSBzdGFsZSwgYmFrZWQtaW4gbW9kZWwgbGlzdDsgaXQgY29uc3VtZXNcbiAqIHRoZSBjbGFzc2lmaWVkIGxpdmUgYC9tb2RlbHNgIHJlc3BvbnNlIGluc3RlYWQuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7XG4gIE1vZGVsQ2xhc3MgYXMgTW9kZWxDbGFzc1ZhbHVlcyxcbiAgdHlwZSBNb2RlbENsYXNzIGFzIE1vZGVsQ2xhc3NUeXBlLFxuICB0eXBlIFNlcnZpbmdFbmRwb2ludFN1bW1hcnksXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tb2RlbC9jb250cmFjdHNcIjtcblxuaW1wb3J0IHsgcmFua0VuZHBvaW50cyB9IGZyb20gXCIuL19yYW5raW5nLnRzXCI7XG5cbnR5cGUgTW9kZWxDbGFzcyA9IE1vZGVsQ2xhc3NUeXBlO1xuY29uc3QgTW9kZWxDbGFzcyA9IE1vZGVsQ2xhc3NWYWx1ZXM7XG5cbi8qKlxuICogU21hbGwsIGxhc3QtcmVzb3J0IHNldCBvZiB3ZWxsLWtub3duIEZvdW5kYXRpb24gTW9kZWwgQVBJIGVuZHBvaW50IG5hbWVzLFxuICogb3JkZXJlZCBiZXN0LWZpcnN0IHdpdGhpbiBlYWNoIGNsYXNzIGJ5IHRoZSBtb2RlbCByYW5rZXIuXG4gKiBVc2VkIG9ubHkgYXMgdGhlIGZsb29yIHdoZW4gdGhlIGxpdmUgYC9zZXJ2aW5nLWVuZHBvaW50c2AgY2F0YWxvZ3VlIGNhbid0IGJlXG4gKiByZWFkIGF0IHJlc29sdmUgdGltZTsgdGhlIGxpdmUsIHNjb3JlLWRyaXZlbiBjbGFzc2lmaWNhdGlvbiBzdXBlcnNlZGVzIGl0XG4gKiB3aGVuZXZlciB0aGUgd29ya3NwYWNlIGxpc3RpbmcgaXMgYXZhaWxhYmxlLiBDbGFzc2VzIGFyZSBub3QgaGFyZC1jb2RlZCBoZXJlXG4gKiAtIGVhY2ggbmFtZSBpcyBjbGFzc2lmaWVkIGJ5IGZhbWlseSBoZXVyaXN0aWMuXG4gKi9cbmNvbnN0IEZBTExCQUNLX01PREVMX05BTUVTOiByZWFkb25seSBzdHJpbmdbXSA9IFtcbiAgXCJkYXRhYnJpY2tzLWNsYXVkZS1vcHVzLTQtOFwiLFxuICBcImRhdGFicmlja3MtZ3B0LTUtNS1wcm9cIixcbiAgXCJkYXRhYnJpY2tzLWdlbWluaS0zLTEtcHJvXCIsXG4gIFwiZGF0YWJyaWNrcy1jbGF1ZGUtc29ubmV0LTQtNlwiLFxuICBcImRhdGFicmlja3MtZ3B0LTUtNVwiLFxuICBcImRhdGFicmlja3MtbWV0YS1sbGFtYS0zLTMtNzBiLWluc3RydWN0XCIsXG4gIFwiZGF0YWJyaWNrcy1jbGF1ZGUtaGFpa3UtNC01XCIsXG4gIFwiZGF0YWJyaWNrcy1ncHQtNS1uYW5vXCIsXG4gIFwiZGF0YWJyaWNrcy1tZXRhLWxsYW1hLTMtMS04Yi1pbnN0cnVjdFwiLFxuXTtcblxuY29uc3QgRkFMTEJBQ0tfRU5EUE9JTlRTOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10gPSBGQUxMQkFDS19NT0RFTF9OQU1FUy5tYXAoKG5hbWUpID0+ICh7XG4gIG5hbWUsXG4gIHRhc2s6IFwibGxtL3YxL2NoYXRcIixcbn0pKTtcblxuLyoqXG4gKiBTdGF0aWMgZmFsbGJhY2sgbW9kZWwgaWRzIGZvciBhIGNoYXQgY2xhc3MsIGRyYXduIGZyb20gdGhlIHNtYWxsIGJ1aWx0LWluXG4gKiB7QGxpbmsgRkFMTEJBQ0tfTU9ERUxfTkFNRVN9IGxpc3QgYW5kIG9yZGVyZWQgYmVzdC1maXJzdCBieSBmYW1pbHkgcmFuay4gU3luY1xuICogYW5kIHdvcmtzcGFjZS1pbmRlcGVuZGVudDogdGhpcyBpcyB0aGUgKmZhbGxiYWNrIG9waW5pb24qIHVzZWQgdG8gc2VlZCBkZWZhdWx0XG4gKiBsaXN0cyBvciB3aGVuIHRoZSBsaXZlIGNhdGFsb2d1ZSBpcyB1bnJlYWNoYWJsZSAtIGxpdmUgcmVzb2x1dGlvbiBwcmVmZXJzXG4gKiB0aGUgY2xhc3NpZmllZCB3b3Jrc3BhY2UgY2F0YWxvZ3VlLiBSZXR1cm5zIGBbXWAgZm9yXG4gKiB7QGxpbmsgTW9kZWxDbGFzcy5FbWJlZGRpbmd9ICh0aGUgZmxvb3IgaXMgY2hhdC1vbmx5KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vZGVsc0ZvckNsYXNzKGNsczogTW9kZWxDbGFzcyk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgcmV0dXJuIHJhbmtFbmRwb2ludHMoRkFMTEJBQ0tfRU5EUE9JTlRTLCB7IG1vZGVsQ2xhc3M6IGNscyB9KVxuICAgIC5maWx0ZXIoKHJhbmtlZCkgPT4gcmFua2VkLm1vZGVsQ2xhc3MgPT09IGNscylcbiAgICAubWFwKChyYW5rZWQpID0+IHJhbmtlZC5lbmRwb2ludC5uYW1lKTtcbn1cblxuLyoqIFRvcCBzdGF0aWMgZmFsbGJhY2sgbW9kZWwgaWQgZm9yIGEgY2hhdCBjbGFzcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbEZvckNsYXNzKGNsczogTW9kZWxDbGFzcyk6IHN0cmluZyB7XG4gIHJldHVybiBtb2RlbHNGb3JDbGFzcyhjbHMpWzBdITtcbn1cblxuLyoqXG4gKiBQcmlvcml0eS1vcmRlcmVkIGZhbGxiYWNrIGNoYWluIChDaGF0VGhpbmtpbmcgLT4gQ2hhdEJhbGFuY2VkIC0+IENoYXRGYXN0KVxuICogb3ZlciB0aGUgc21hbGwgYnVpbHQtaW4gbGlzdC4gVGhlIGZsb29yIHdhbGtlZCBhdCByZXNvbHZlIHRpbWUgd2hlbiBubyBhZ2VudFxuICogLyBwbHVnaW4gLyBlbnYgLyByZXF1ZXN0IG1vZGVsIGlzIHNldCAqYW5kKiB0aGUgbGl2ZSBjYXRhbG9ndWUgeWllbGRzIG5vdGhpbmcuXG4gKi9cbmV4cG9ydCBjb25zdCBGQUxMQkFDS19NT0RFTF9JRFM6IHJlYWRvbmx5IHN0cmluZ1tdID0gW1xuICAuLi5tb2RlbHNGb3JDbGFzcyhNb2RlbENsYXNzLkNoYXRUaGlua2luZyksXG4gIC4uLm1vZGVsc0ZvckNsYXNzKE1vZGVsQ2xhc3MuQ2hhdEJhbGFuY2VkKSxcbiAgLi4ubW9kZWxzRm9yQ2xhc3MoTW9kZWxDbGFzcy5DaGF0RmFzdCksXG5dO1xuIl19
@@ -0,0 +1,90 @@
1
+ {
2
+ "generatedAt": 1791150180,
3
+ "capabilities": {
4
+ "responses": [
5
+ "gpt-5",
6
+ "gpt-5-1",
7
+ "gpt-5-2",
8
+ "gpt-5-3-codex",
9
+ "gpt-5-4",
10
+ "gpt-5-4-mini",
11
+ "gpt-5-4-nano",
12
+ "gpt-5-5",
13
+ "gpt-5-5-pro",
14
+ "gpt-5-6-luna",
15
+ "gpt-5-6-sol",
16
+ "gpt-5-6-terra",
17
+ "gpt-5-mini",
18
+ "gpt-5-nano",
19
+ "gpt-6-1-sol",
20
+ "gpt-6-astra",
21
+ "gpt-6-luna",
22
+ "gpt-6-sol"
23
+ ],
24
+ "imageInput": [
25
+ "gpt-5",
26
+ "gpt-5-1",
27
+ "gpt-5-2",
28
+ "gpt-5-3-codex",
29
+ "gpt-5-4",
30
+ "gpt-5-4-mini",
31
+ "gpt-5-4-nano",
32
+ "gpt-5-5",
33
+ "gpt-5-5-pro",
34
+ "gpt-5-6-luna",
35
+ "gpt-5-6-sol",
36
+ "gpt-5-6-terra",
37
+ "gpt-5-mini",
38
+ "gpt-5-nano",
39
+ "gpt-6-1-sol",
40
+ "gpt-6-astra",
41
+ "gpt-6-luna",
42
+ "gpt-6-sol"
43
+ ],
44
+ "applyPatch": [
45
+ "gpt-5",
46
+ "gpt-5-1",
47
+ "gpt-5-2",
48
+ "gpt-5-3-codex",
49
+ "gpt-5-4",
50
+ "gpt-5-4-mini",
51
+ "gpt-5-4-nano",
52
+ "gpt-5-5",
53
+ "gpt-5-5-pro",
54
+ "gpt-5-6-luna",
55
+ "gpt-5-6-sol",
56
+ "gpt-5-6-terra",
57
+ "gpt-5-mini",
58
+ "gpt-5-nano",
59
+ "gpt-6-1-sol",
60
+ "gpt-6-astra",
61
+ "gpt-6-luna",
62
+ "gpt-6-sol"
63
+ ],
64
+ "webSearch": [
65
+ "gemini-2-5-flash",
66
+ "gemini-2-5-pro",
67
+ "gemini-3-1-flash-lite",
68
+ "gemini-3-1-pro",
69
+ "gemini-3-flash",
70
+ "gpt-5",
71
+ "gpt-5-1",
72
+ "gpt-5-2",
73
+ "gpt-5-3-codex",
74
+ "gpt-5-4",
75
+ "gpt-5-4-mini",
76
+ "gpt-5-4-nano",
77
+ "gpt-5-5",
78
+ "gpt-5-5-pro",
79
+ "gpt-5-6-luna",
80
+ "gpt-5-6-sol",
81
+ "gpt-5-6-terra",
82
+ "gpt-5-mini",
83
+ "gpt-5-nano",
84
+ "gpt-6-1-sol",
85
+ "gpt-6-astra",
86
+ "gpt-6-luna",
87
+ "gpt-6-sol"
88
+ ]
89
+ }
90
+ }