@dbx-tools/appkit-model-gateway 0.9.37 → 0.9.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,13 +1,11 @@
1
1
  # @dbx-tools/appkit-model-gateway
2
2
 
3
- Raw AppKit plugin for OpenAI, Anthropic, Codex, and Databricks AI Gateway model
4
- traffic.
3
+ Give OpenAI-, Anthropic-, and Codex-compatible clients one endpoint for the
4
+ models available in a Databricks workspace. The AppKit plugin discovers the
5
+ workspace catalogue, exposes familiar model APIs, and chooses a compatible
6
+ Databricks route for each request.
5
7
 
6
- The gateway discovers the active workspace model catalogue dynamically through
7
- `@dbx-tools/model`. AppKit supplies the service-context Databricks client and
8
- `@dbx-tools/auth` resolves its standard workspace profile and token lifecycle.
9
-
10
- ## AppKit plugin
8
+ ## Register The AppKit Plugin
11
9
 
12
10
  ```ts
13
11
  import { createApp, server } from "@databricks/appkit";
@@ -22,34 +20,49 @@ AppKit mounts the plugin routes under `/api/model-gateway/v1/*`. The
22
20
  `@dbx-tools/cli-model-gateway` package owns foreground server construction and
23
21
  standard root compatibility paths.
24
22
 
25
- ## Routing
23
+ ## Connect A Client
24
+
25
+ Use the standalone CLI when a tool expects an OpenAI-compatible base URL:
26
+
27
+ ```sh
28
+ dbx model-gateway --profile PROFILE --port 4000
29
+ ```
30
+
31
+ Configure the client with `http://127.0.0.1:4000/v1`. For an embedded AppKit
32
+ route, use the app origin plus `/api/model-gateway/v1`.
33
+
34
+ The gateway supports:
26
35
 
27
- Responses requests use direct streaming paths in this order:
36
+ - OpenAI Responses and Chat Completions;
37
+ - Anthropic Messages;
38
+ - OpenAI-compatible embeddings;
39
+ - Codex model discovery and Responses traffic.
28
40
 
29
- 1. `/serving-endpoints/responses` for native OpenAI Responses models.
30
- 2. `/ai-gateway/codex/v1/responses` for compatible model services such as Grok.
31
- 3. `/serving-endpoints/open-responses` for remaining cross-provider models.
32
- 4. Vercel AI SDK ProviderV4 translation when the caller and model protocols do
33
- not match.
41
+ ## Discover Models
34
42
 
35
- Chat Completions use `/serving-endpoints/chat/completions`. Native Claude
36
- Messages use `/serving-endpoints/anthropic/v1/messages`.
37
- Embeddings use the resolved endpoint's `/invocations` path.
43
+ ```ts
44
+ import { createModelGatewayClient } from "@dbx-tools/shared-model-gateway";
45
+
46
+ const client = createModelGatewayClient({ baseUrl: "http://127.0.0.1:4000/" });
47
+ const models = await client.listModels({ search: "sonnet" });
48
+ ```
38
49
 
39
- Direct paths do not decode or rebuild successful response streams. They preserve
40
- upstream SSE framing, backpressure, and cancellation. Translation paths use
41
- `@ai-sdk/open-responses`, `@ai-sdk/openai-compatible`, or
42
- `@ai-sdk/anthropic` for provider wire behavior and encode the requested client
43
- protocol as events arrive.
50
+ Use `{ codex: true }` when a Codex client needs its native catalogue shape.
51
+
52
+ ## Request Compatibility
53
+
54
+ Requests stay on a native streaming path when the selected model supports the
55
+ client protocol. When protocols differ, the gateway translates the request and
56
+ response while preserving streaming and cancellation behavior.
44
57
 
45
58
  The gateway rejects stateful Responses options it cannot preserve, including
46
59
  `previous_response_id`, `store: true`, and `background: true`.
47
60
 
48
- ## Codex
61
+ ## Configure Codex
49
62
 
50
63
  `GET /v1/models` includes Codex metadata when the request carries
51
64
  `Originator: codex`. Codex slugs prefer fully qualified Databricks model service
52
- names, which activates the Unity Gateway fast path.
65
+ names.
53
66
 
54
67
  Point a Codex provider at:
55
68
 
@@ -59,5 +72,10 @@ http://127.0.0.1:4000/v1
59
72
 
60
73
  Use `wire_api = "responses"` and `supports_websockets = false`.
61
74
 
62
- Browser applications can use `@dbx-tools/shared-model-gateway` to search and
63
- schema-validate model lists without importing Node or AppKit code.
75
+ ## Package API
76
+
77
+ - `modelGateway()` registers the AppKit plugin.
78
+ - `gateway` handles protocol-neutral gateway requests.
79
+ - `registry` discovers and resolves workspace models.
80
+ - `router` selects a compatible route from model capabilities.
81
+ - `transport` sends requests to Databricks model APIs.
package/index.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
 
5
5
  export const PACKAGE_IDENTIFIER = "@dbx-tools/appkit-model-gateway";
6
- export const PACKAGE_VERSION = "0.9.37";
6
+ export const PACKAGE_VERSION = "0.9.40";
7
7
  export * as gateway from "./src/gateway.ts";
8
8
  export * as models from "./src/models.ts";
9
9
  export * as plugin from "./src/plugin.ts";
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export declare const PACKAGE_IDENTIFIER = "@dbx-tools/appkit-model-gateway";
2
- export declare const PACKAGE_VERSION = "0.9.37";
2
+ export declare const PACKAGE_VERSION = "0.9.40";
3
3
  export * as gateway from "./src/gateway.ts";
4
4
  export * as models from "./src/models.ts";
5
5
  export * as plugin from "./src/plugin.ts";
package/lib/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Regenerated from the exporting modules in ./src.
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
  export const PACKAGE_IDENTIFIER = "@dbx-tools/appkit-model-gateway";
5
- export const PACKAGE_VERSION = "0.9.37";
5
+ export const PACKAGE_VERSION = "0.9.40";
6
6
  export * as gateway from "./src/gateway.js";
7
7
  export * as models from "./src/models.js";
8
8
  export * as plugin from "./src/plugin.js";
@@ -18,4 +18,4 @@ export { ModelGatewayError, ModelGateway } from "./src/gateway.js";
18
18
  export { ModelGatewayPlugin, modelGateway } from "./src/plugin.js";
19
19
  export { DatabricksModelRegistry } from "./src/registry.js";
20
20
  export { UnsupportedGatewayFeatureError } from "./src/router.js";
21
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxpQ0FBaUMsQ0FBQztBQUNwRSxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxlQUFlLE1BQU0sMkJBQTJCLENBQUM7QUFDN0QsT0FBTyxLQUFLLGVBQWUsTUFBTSwyQkFBMkIsQ0FBQztBQUM3RCxPQUFPLEtBQUssY0FBYyxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxXQUFXLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBS25FLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRTVELE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLGlCQUFpQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gR0VORVJBVEVEIGJ5IHByb2plbiB3YXRjaCAtIERPIE5PVCBFRElULlxuLy8gUmVnZW5lcmF0ZWQgZnJvbSB0aGUgZXhwb3J0aW5nIG1vZHVsZXMgaW4gLi9zcmMuXG4vLyBIYW5kIGVkaXRzIGFyZSBvdmVyd3JpdHRlbiBvbiB0aGUgbmV4dCB3YXRjaDsgdGhpcyBmaWxlIGlzIHJlYWQtb25seS5cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfSURFTlRJRklFUiA9IFwiQGRieC10b29scy9hcHBraXQtbW9kZWwtZ2F0ZXdheVwiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IFwiMC45LjM3XCI7XG5leHBvcnQgKiBhcyBnYXRld2F5IGZyb20gXCIuL3NyYy9nYXRld2F5LnRzXCI7XG5leHBvcnQgKiBhcyBtb2RlbHMgZnJvbSBcIi4vc3JjL21vZGVscy50c1wiO1xuZXhwb3J0ICogYXMgcGx1Z2luIGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCAqIGFzIHByb3RvY29sc0RlY29kZSBmcm9tIFwiLi9zcmMvcHJvdG9jb2xzL2RlY29kZS50c1wiO1xuZXhwb3J0ICogYXMgcHJvdG9jb2xzRW5jb2RlIGZyb20gXCIuL3NyYy9wcm90b2NvbHMvZW5jb2RlLnRzXCI7XG5leHBvcnQgKiBhcyByZWFzb25pbmdBZGFwdCBmcm9tIFwiLi9zcmMvcmVhc29uaW5nLWFkYXB0LnRzXCI7XG5leHBvcnQgKiBhcyByZWdpc3RyeSBmcm9tIFwiLi9zcmMvcmVnaXN0cnkudHNcIjtcbmV4cG9ydCAqIGFzIHJvdXRlciBmcm9tIFwiLi9zcmMvcm91dGVyLnRzXCI7XG5leHBvcnQgKiBhcyByb3V0ZXMgZnJvbSBcIi4vc3JjL3JvdXRlcy50c1wiO1xuZXhwb3J0ICogYXMgdHJhbnNsYXRpb24gZnJvbSBcIi4vc3JjL3RyYW5zbGF0aW9uLnRzXCI7XG5leHBvcnQgKiBhcyB0cmFuc3BvcnQgZnJvbSBcIi4vc3JjL3RyYW5zcG9ydC50c1wiO1xuZXhwb3J0IHsgTW9kZWxHYXRld2F5RXJyb3IsIE1vZGVsR2F0ZXdheSB9IGZyb20gXCIuL3NyYy9nYXRld2F5LnRzXCI7XG5leHBvcnQgdHlwZSB7IE1vZGVsR2F0ZXdheU9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvZ2F0ZXdheS50c1wiO1xuZXhwb3J0IHsgTW9kZWxHYXRld2F5UGx1Z2luLCBtb2RlbEdhdGV3YXkgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgdHlwZSB7IE1vZGVsR2F0ZXdheVBsdWdpbkNvbmZpZyB9IGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCB0eXBlIHsgRGVjb2RlZEdhdGV3YXlSZXF1ZXN0IH0gZnJvbSBcIi4vc3JjL3Byb3RvY29scy9kZWNvZGUudHNcIjtcbmV4cG9ydCB0eXBlIHsgQ29tcGxldGVkR2VuZXJhdGlvbiB9IGZyb20gXCIuL3NyYy9wcm90b2NvbHMvZW5jb2RlLnRzXCI7XG5leHBvcnQgdHlwZSB7IEFkYXB0ZWRJbmZlcmVuY2VCb2R5IH0gZnJvbSBcIi4vc3JjL3JlYXNvbmluZy1hZGFwdC50c1wiO1xuZXhwb3J0IHsgRGF0YWJyaWNrc01vZGVsUmVnaXN0cnkgfSBmcm9tIFwiLi9zcmMvcmVnaXN0cnkudHNcIjtcbmV4cG9ydCB0eXBlIHsgTW9kZWxSZWdpc3RyeVJlc29sdmVPcHRpb25zLCBNb2RlbFJlZ2lzdHJ5LCBNb2RlbFJlZ2lzdHJ5T3B0aW9ucyB9IGZyb20gXCIuL3NyYy9yZWdpc3RyeS50c1wiO1xuZXhwb3J0IHsgVW5zdXBwb3J0ZWRHYXRld2F5RmVhdHVyZUVycm9yIH0gZnJvbSBcIi4vc3JjL3JvdXRlci50c1wiO1xuZXhwb3J0IHR5cGUgeyBEYXRhYnJpY2tzVHJhbnNwb3J0UmVxdWVzdCB9IGZyb20gXCIuL3NyYy90cmFuc3BvcnQudHNcIjtcbiJdfQ==
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxpQ0FBaUMsQ0FBQztBQUNwRSxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxlQUFlLE1BQU0sMkJBQTJCLENBQUM7QUFDN0QsT0FBTyxLQUFLLGVBQWUsTUFBTSwyQkFBMkIsQ0FBQztBQUM3RCxPQUFPLEtBQUssY0FBYyxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxXQUFXLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBS25FLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRTVELE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLGlCQUFpQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gR0VORVJBVEVEIGJ5IHByb2plbiB3YXRjaCAtIERPIE5PVCBFRElULlxuLy8gUmVnZW5lcmF0ZWQgZnJvbSB0aGUgZXhwb3J0aW5nIG1vZHVsZXMgaW4gLi9zcmMuXG4vLyBIYW5kIGVkaXRzIGFyZSBvdmVyd3JpdHRlbiBvbiB0aGUgbmV4dCB3YXRjaDsgdGhpcyBmaWxlIGlzIHJlYWQtb25seS5cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfSURFTlRJRklFUiA9IFwiQGRieC10b29scy9hcHBraXQtbW9kZWwtZ2F0ZXdheVwiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IFwiMC45LjQwXCI7XG5leHBvcnQgKiBhcyBnYXRld2F5IGZyb20gXCIuL3NyYy9nYXRld2F5LnRzXCI7XG5leHBvcnQgKiBhcyBtb2RlbHMgZnJvbSBcIi4vc3JjL21vZGVscy50c1wiO1xuZXhwb3J0ICogYXMgcGx1Z2luIGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCAqIGFzIHByb3RvY29sc0RlY29kZSBmcm9tIFwiLi9zcmMvcHJvdG9jb2xzL2RlY29kZS50c1wiO1xuZXhwb3J0ICogYXMgcHJvdG9jb2xzRW5jb2RlIGZyb20gXCIuL3NyYy9wcm90b2NvbHMvZW5jb2RlLnRzXCI7XG5leHBvcnQgKiBhcyByZWFzb25pbmdBZGFwdCBmcm9tIFwiLi9zcmMvcmVhc29uaW5nLWFkYXB0LnRzXCI7XG5leHBvcnQgKiBhcyByZWdpc3RyeSBmcm9tIFwiLi9zcmMvcmVnaXN0cnkudHNcIjtcbmV4cG9ydCAqIGFzIHJvdXRlciBmcm9tIFwiLi9zcmMvcm91dGVyLnRzXCI7XG5leHBvcnQgKiBhcyByb3V0ZXMgZnJvbSBcIi4vc3JjL3JvdXRlcy50c1wiO1xuZXhwb3J0ICogYXMgdHJhbnNsYXRpb24gZnJvbSBcIi4vc3JjL3RyYW5zbGF0aW9uLnRzXCI7XG5leHBvcnQgKiBhcyB0cmFuc3BvcnQgZnJvbSBcIi4vc3JjL3RyYW5zcG9ydC50c1wiO1xuZXhwb3J0IHsgTW9kZWxHYXRld2F5RXJyb3IsIE1vZGVsR2F0ZXdheSB9IGZyb20gXCIuL3NyYy9nYXRld2F5LnRzXCI7XG5leHBvcnQgdHlwZSB7IE1vZGVsR2F0ZXdheU9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvZ2F0ZXdheS50c1wiO1xuZXhwb3J0IHsgTW9kZWxHYXRld2F5UGx1Z2luLCBtb2RlbEdhdGV3YXkgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgdHlwZSB7IE1vZGVsR2F0ZXdheVBsdWdpbkNvbmZpZyB9IGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCB0eXBlIHsgRGVjb2RlZEdhdGV3YXlSZXF1ZXN0IH0gZnJvbSBcIi4vc3JjL3Byb3RvY29scy9kZWNvZGUudHNcIjtcbmV4cG9ydCB0eXBlIHsgQ29tcGxldGVkR2VuZXJhdGlvbiB9IGZyb20gXCIuL3NyYy9wcm90b2NvbHMvZW5jb2RlLnRzXCI7XG5leHBvcnQgdHlwZSB7IEFkYXB0ZWRJbmZlcmVuY2VCb2R5IH0gZnJvbSBcIi4vc3JjL3JlYXNvbmluZy1hZGFwdC50c1wiO1xuZXhwb3J0IHsgRGF0YWJyaWNrc01vZGVsUmVnaXN0cnkgfSBmcm9tIFwiLi9zcmMvcmVnaXN0cnkudHNcIjtcbmV4cG9ydCB0eXBlIHsgTW9kZWxSZWdpc3RyeVJlc29sdmVPcHRpb25zLCBNb2RlbFJlZ2lzdHJ5LCBNb2RlbFJlZ2lzdHJ5T3B0aW9ucyB9IGZyb20gXCIuL3NyYy9yZWdpc3RyeS50c1wiO1xuZXhwb3J0IHsgVW5zdXBwb3J0ZWRHYXRld2F5RmVhdHVyZUVycm9yIH0gZnJvbSBcIi4vc3JjL3JvdXRlci50c1wiO1xuZXhwb3J0IHR5cGUgeyBEYXRhYnJpY2tzVHJhbnNwb3J0UmVxdWVzdCB9IGZyb20gXCIuL3NyYy90cmFuc3BvcnQudHNcIjtcbiJdfQ==
package/lib/src/models.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * @module
5
5
  */
6
6
  import { isChatClass } from "@dbx-tools/model/classes";
7
- import { modelFamily } from "@dbx-tools/model/policy";
7
+ import { modelFamily, modelFamilyRank } from "@dbx-tools/model/policy";
8
8
  const CODEX_BASE_INSTRUCTIONS = "You are a coding agent. Follow the user's instructions and use the available tools to work in the current repository.";
9
9
  const REASONING_DESCRIPTIONS = {
10
10
  none: "Disable explicit reasoning",
@@ -89,15 +89,23 @@ function codexModel(target, priority) {
89
89
  };
90
90
  }
91
91
  /**
92
- * Order listed models in three groups: non-embedding models with a detected
93
- * family, the remaining non-embedding models, then embeddings. Each group is
94
- * sorted by the published label (`display_name` for Codex, `name` otherwise)
95
- * with numeric segments ordered naturally so "Veo 3.1" precedes "Veo 3.10".
92
+ * Order listed models in three groups: major-provider chat families, the
93
+ * remaining chat models, then embeddings. Families keep a fixed provider
94
+ * order; each family and the later groups sort by the published label
95
+ * (`display_name` for Codex, `name` otherwise). Numeric segments sort
96
+ * naturally so "Veo 3.1" precedes "Veo 3.10".
96
97
  */
97
98
  function compareCatalogueTargets(left, right, label) {
98
99
  const group = catalogueGroup(left) - catalogueGroup(right);
99
100
  if (group !== 0)
100
101
  return group;
102
+ const leftFamily = catalogueFamily(left);
103
+ const rightFamily = catalogueFamily(right);
104
+ if (leftFamily && rightFamily) {
105
+ const familyOrder = modelFamilyRank(leftFamily) - modelFamilyRank(rightFamily);
106
+ if (familyOrder !== 0)
107
+ return familyOrder;
108
+ }
101
109
  return compareCatalogueLabel(label(left), label(right));
102
110
  }
103
111
  function catalogueGroup(target) {
@@ -105,12 +113,28 @@ function catalogueGroup(target) {
105
113
  return 2;
106
114
  return catalogueFamily(target) ? 0 : 1;
107
115
  }
116
+ const IDENTITY_PREFIXES = new Set(["databricks", "system", "ai", "meta", "google", "openai", "anthropic"]);
108
117
  function catalogueFamily(target) {
109
- const stamped = target.family?.trim() || target.endpoint?.family?.trim();
110
- return (modelFamily(target.displayName) ??
111
- modelFamily(target.id) ??
112
- (target.endpoint?.name ? modelFamily(target.endpoint.name) : undefined) ??
113
- (stamped ? modelFamily(stamped) : undefined));
118
+ if (isEmbeddingTarget(target))
119
+ return undefined;
120
+ for (const identity of [target.displayName, target.id, target.endpoint?.name]) {
121
+ if (!identity)
122
+ continue;
123
+ const family = catalogueFamilyFromIdentity(identity);
124
+ if (family)
125
+ return family;
126
+ }
127
+ return undefined;
128
+ }
129
+ function catalogueFamilyFromIdentity(identity) {
130
+ const tokens = identity.toLowerCase().match(/[a-z0-9]+/g) ?? [];
131
+ const start = tokens.find((token) => !IDENTITY_PREFIXES.has(token));
132
+ if (!start)
133
+ return undefined;
134
+ if (start === "veo")
135
+ return "gemini";
136
+ const family = modelFamily(identity);
137
+ return family && start === family ? family : undefined;
114
138
  }
115
139
  function isEmbeddingTarget(target) {
116
140
  return (target.capabilities.embeddings === true || target.endpoint?.task === "llm/v1/embeddings");
@@ -122,4 +146,4 @@ function hasChatClass(target) {
122
146
  const modelClass = target.endpoint?.class;
123
147
  return modelClass !== undefined && isChatClass(modelClass);
124
148
  }
125
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZGVscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQVV0RCxNQUFNLHVCQUF1QixHQUMzQix1SEFBdUgsQ0FBQztBQUUxSCxNQUFNLHNCQUFzQixHQUFxQztJQUMvRCxJQUFJLEVBQUUsNEJBQTRCO0lBQ2xDLE9BQU8sRUFBRSw2Q0FBNkM7SUFDdEQsR0FBRyxFQUFFLDRCQUE0QjtJQUNqQyxNQUFNLEVBQUUsK0JBQStCO0lBQ3ZDLElBQUksRUFBRSw2QkFBNkI7SUFDbkMsS0FBSyxFQUFFLG9DQUFvQztJQUMzQyxHQUFHLEVBQUUsNENBQTRDO0NBQ2xELENBQUM7QUFlRixNQUFNLFVBQVUsaUJBQWlCLENBQy9CLE9BQStCLEVBQy9CLFlBQXFCO0lBRXJCLE1BQU0sU0FBUyxHQUFHLE9BQU87U0FDdEIsTUFBTSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxVQUFVLEtBQUssSUFBSSxDQUFDO1NBQ2hFLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxZQUFZLElBQUksWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ3pELEtBQUssRUFBRTtTQUNQLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUNwQix1QkFBdUIsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQ3JFLENBQUM7SUFDSixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2pCLE9BQU87WUFDTCxNQUFNLEVBQUUsU0FBUyxDQUFDLEdBQUcs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QUFDO1FBQy9CLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ3RCLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDdkUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQzdDLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxNQUFtQjtJQUM1QyxPQUFPLENBQ0wsTUFBTSxDQUFDLFlBQVksQ0FBQyxVQUFVLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsSUFBSSxLQUFLLG1CQUFtQixDQUN6RixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQUMsSUFBWSxFQUFFLEtBQWE7SUFDeEQsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0FBQ3RGLENBQUM7QUFFRCxTQUFTLFlBQVksQ0FBQyxNQUFtQjtJQUN2QyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQztJQUMxQyxPQUFPLFVBQVUsS0FBSyxTQUFTLElBQUksV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzdELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE9wZW5BSSBhbmQgQ29kZXggbW9kZWwtbGlzdCBwYXlsb2FkcyBkZXJpdmVkIGZyb20gdGhlIGxpdmUgcmVnaXN0cnkuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGlzQ2hhdENsYXNzIH0gZnJvbSBcIkBkYngtdG9vbHMvbW9kZWwvY2xhc3Nlc1wiO1xuaW1wb3J0IHsgbW9kZWxGYW1pbHkgfSBmcm9tIFwiQGRieC10b29scy9tb2RlbC9wb2xpY3lcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ29kZXhNb2RlbCxcbiAgQ29kZXhNb2RlbExpc3RSZXNwb25zZSxcbiAgTW9kZWxMaXN0UmVzcG9uc2UsXG4gIE1vZGVsVGFyZ2V0LFxuICBPcGVuQUlNb2RlbCxcbiAgT3BlbkFJTW9kZWxMaXN0UmVzcG9uc2UsXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tb2RlbC1nYXRld2F5XCI7XG5cbmNvbnN0IENPREVYX0JBU0VfSU5TVFJVQ1RJT05TID1cbiAgXCJZb3UgYXJlIGEgY29kaW5nIGFnZW50LiBGb2xsb3cgdGhlIHVzZXIncyBpbnN0cnVjdGlvbnMgYW5kIHVzZSB0aGUgYXZhaWxhYmxlIHRvb2xzIHRvIHdvcmsgaW4gdGhlIGN1cnJlbnQgcmVwb3NpdG9yeS5cIjtcblxuY29uc3QgUkVBU09OSU5HX0RFU0NSSVBUSU9OUzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4gPSB7XG4gIG5vbmU6IFwiRGlzYWJsZSBleHBsaWNpdCByZWFzb25pbmdcIixcbiAgbWluaW1hbDogXCJVc2UgdGhlIHNtYWxsZXN0IGF2YWlsYWJsZSByZWFzb25pbmcgYnVkZ2V0XCIsXG4gIGxvdzogXCJVc2UgYSBsb3cgcmVhc29uaW5nIGJ1ZGdldFwiLFxuICBtZWRpdW06IFwiVXNlIGEgbWVkaXVtIHJlYXNvbmluZyBidWRnZXRcIixcbiAgaGlnaDogXCJVc2UgYSBoaWdoIHJlYXNvbmluZyBidWRnZXRcIixcbiAgeGhpZ2g6IFwiVXNlIGFuIGV4dHJhLWhpZ2ggcmVhc29uaW5nIGJ1ZGdldFwiLFxuICBtYXg6IFwiVXNlIHRoZSBsYXJnZXN0IGF2YWlsYWJsZSByZWFzb25pbmcgYnVkZ2V0XCIsXG59O1xuXG4vKiogQnVpbGQgdGhlIGNvbWJpbmVkIE9wZW5BSSBhbmQgb3B0aW9uYWwgQ29kZXggbW9kZWwgY2F0YWxvZ3VlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RNb2RlbHNQYXlsb2FkKFxuICB0YXJnZXRzOiByZWFkb25seSBNb2RlbFRhcmdldFtdLFxuICBpbmNsdWRlQ29kZXg6IHRydWUsXG4pOiBDb2RleE1vZGVsTGlzdFJlc3BvbnNlO1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RNb2RlbHNQYXlsb2FkKFxuICB0YXJnZXRzOiByZWFkb25seSBNb2RlbFRhcmdldFtdLFxuICBpbmNsdWRlQ29kZXg6IGZhbHNlLFxuKTogT3BlbkFJTW9kZWxMaXN0UmVzcG9uc2U7XG5leHBvcnQgZnVuY3Rpb24gbGlzdE1vZGVsc1BheWxvYWQoXG4gIHRhcmdldHM6IHJlYWRvbmx5IE1vZGVsVGFyZ2V0W10sXG4gIGluY2x1ZGVDb2RleDogYm9vbGVhbixcbik6IE1vZGVsTGlzdFJlc3BvbnNlO1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RNb2RlbHNQYXlsb2FkKFxuICB0YXJnZXRzOiByZWFkb25seSBNb2RlbFRhcmdldFtdLFxuICBpbmNsdWRlQ29kZXg6IGJvb2xlYW4sXG4pOiBNb2RlbExpc3RSZXNwb25zZSB7XG4gIGNvbnN0IGF2YWlsYWJsZSA9IHRhcmdldHNcbiAgICAuZmlsdGVyKCh0YXJnZXQpID0+IHRhcmdldC5lbmRwb2ludD8uc3RhdHVzPy5kZXByZWNhdGVkICE9PSB0cnVlKVxuICAgIC5maWx0ZXIoKHRhcmdldCkgPT4gIWluY2x1ZGVDb2RleCB8fCBoYXNDaGF0Q2xhc3ModGFyZ2V0KSlcbiAgICAuc2xpY2UoKVxuICAgIC5zb3J0KChsZWZ0LCByaWdodCkgPT5cbiAgICAgIGNvbXBhcmVDYXRhbG9ndWVUYXJnZXRzKGxlZnQsIHJpZ2h0LCAodGFyZ2V0KSA9PiB0YXJnZXQuZGlzcGxheU5hbWUpLFxuICAgICk7XG4gIGlmIChpbmNsdWRlQ29kZXgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbW9kZWxzOiBhdmFpbGFibGUubWFwKCh0YXJnZXQsIGluZGV4KSA9PiBjb2RleE1vZGVsKHRhcmdldCwgaW5kZXggKyAxKSksXG4gICAgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIG9iamVjdDogXCJsaXN0XCIsXG4gICAgZGF0YTogYXZhaWxhYmxlLm1hcChvcGVuQWlNb2RlbCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIG9wZW5BaU1vZGVsKHRhcmdldDogTW9kZWxUYXJnZXQpOiBPcGVuQUlNb2RlbCB7XG4gIHJldHVybiB7XG4gICAgaWQ6IHRhcmdldC5pZCxcbiAgICBvYmplY3Q6IFwibW9kZWxcIixcbiAgICBjcmVhdGVkOiAwLFxuICAgIG93bmVkX2J5OiBcImRhdGFicmlja3NcIixcbiAgICBuYW1lOiB0YXJnZXQuZGlzcGxheU5hbWUsXG4gICAgdGFzazogdGFyZ2V0LmVuZHBvaW50Py50YXNrLFxuICAgIHN0YXR1czogdGFyZ2V0LmVuZHBvaW50Py5zdGF0dXMgPz8geyBkZXByZWNhdGVkOiBmYWxzZSB9LFxuICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgdG9vbHM6IHRhcmdldC5jYXBhYmlsaXRpZXMudG9vbHMsXG4gICAgICByZWFzb25pbmc6IHRhcmdldC5yZWFzb25pbmdFZmZvcnRzLFxuICAgICAgcmVzcG9uc2VzOiB0YXJnZXQuY2FwYWJpbGl0aWVzLnJlc3BvbnNlcyxcbiAgICAgIG9wZW5fcmVzcG9uc2VzOiB0YXJnZXQuY2FwYWJpbGl0aWVzLm9wZW5SZXNwb25zZXMsXG4gICAgICBhbnRocm9waWM6IHRhcmdldC5jYXBhYmlsaXRpZXMuYW50aHJvcGljLFxuICAgICAgZW1iZWRkaW5nczogdGFyZ2V0LmNhcGFiaWxpdGllcy5lbWJlZGRpbmdzLFxuICAgICAgYWlfZ2F0ZXdheV9jb2RleDogdGFyZ2V0LmNhcGFiaWxpdGllcy5haUdhdGV3YXlDb2RleCxcbiAgICAgIHN0cmVhbWluZzogdGFyZ2V0LmNhcGFiaWxpdGllcy5zdHJlYW1pbmcsXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29kZXhNb2RlbCh0YXJnZXQ6IE1vZGVsVGFyZ2V0LCBwcmlvcml0eTogbnVtYmVyKTogQ29kZXhNb2RlbCB7XG4gIGNvbnN0IG1vZGVsID1cbiAgICB0YXJnZXQuY2FwYWJpbGl0aWVzLmFpR2F0ZXdheUNvZGV4ICYmIHRhcmdldC5tb2RlbFNlcnZpY2VOYW1lXG4gICAgICA/IHRhcmdldC5tb2RlbFNlcnZpY2VOYW1lXG4gICAgICA6IHRhcmdldC5pZDtcbiAgY29uc3QgZWZmb3J0cyA9IHRhcmdldC5yZWFzb25pbmdFZmZvcnRzO1xuICByZXR1cm4ge1xuICAgIHNsdWc6IGBkYXRhYnJpY2tzLyR7bW9kZWx9YCxcbiAgICBkaXNwbGF5X25hbWU6IHRhcmdldC5kaXNwbGF5TmFtZSxcbiAgICBkZXNjcmlwdGlvbjogdGFyZ2V0LmVuZHBvaW50Py5kZXNjcmlwdGlvbiA/PyBcIkRhdGFicmlja3MgbW9kZWwgc2VydmljZVwiLFxuICAgIGJhc2VfaW5zdHJ1Y3Rpb25zOiBDT0RFWF9CQVNFX0lOU1RSVUNUSU9OUyxcbiAgICBzdGF0dXM6IHRhcmdldC5lbmRwb2ludD8uc3RhdHVzID8/IHsgZGVwcmVjYXRlZDogZmFsc2UgfSxcbiAgICBzdXBwb3J0ZWRfcmVhc29uaW5nX2xldmVsczogZWZmb3J0cy5tYXAoKGVmZm9ydCkgPT4gKHtcbiAgICAgIGVmZm9ydCxcbiAgICAgIGRlc2NyaXB0aW9uOiBSRUFTT05JTkdfREVTQ1JJUFRJT05TW2VmZm9ydF0gPz8gYFVzZSB0aGUgJHtlZmZvcnR9IHJlYXNvbmluZyBidWRnZXRgLFxuICAgIH0pKSxcbiAgICAuLi4oZWZmb3J0cy5sZW5ndGggPiAwXG4gICAgICA/IHsgZGVmYXVsdF9yZWFzb25pbmdfbGV2ZWw6IGVmZm9ydHMuaW5jbHVkZXMoXCJtZWRpdW1cIikgPyBcIm1lZGl1bVwiIDogZWZmb3J0c1swXSB9XG4gICAgICA6IHt9KSxcbiAgICBzaGVsbF90eXBlOiBcInVuaWZpZWRfZXhlY1wiLFxuICAgIHZpc2liaWxpdHk6IFwibGlzdFwiLFxuICAgIHN1cHBvcnRlZF9pbl9hcGk6IHRydWUsXG4gICAgcHJpb3JpdHksXG4gICAgYXZhaWxhYmlsaXR5X251eDogbnVsbCxcbiAgICB1cGdyYWRlOiBudWxsLFxuICAgIHN1cHBvcnRfdmVyYm9zaXR5OiBmYWxzZSxcbiAgICBkZWZhdWx0X3ZlcmJvc2l0eTogbnVsbCxcbiAgICBhcHBseV9wYXRjaF90b29sX3R5cGU6IHRhcmdldC5jYXBhYmlsaXRpZXMuY3VzdG9tVG9vbHMgPyBcImZyZWVmb3JtXCIgOiBudWxsLFxuICAgIHRydW5jYXRpb25fcG9saWN5OiB7IG1vZGU6IFwidG9rZW5zXCIsIGxpbWl0OiAxMjhfMDAwIH0sXG4gICAgY29udGV4dF93aW5kb3c6IG51bGwsXG4gICAgZXhwZXJpbWVudGFsX3N1cHBvcnRlZF90b29sczogW10sXG4gICAgaW5wdXRfbW9kYWxpdGllczogW1widGV4dFwiXSxcbiAgICB3ZWJfc2VhcmNoX3Rvb2xfdHlwZTogXCJ0ZXh0XCIsXG4gICAgc3VwcG9ydHNfc2VhcmNoX3Rvb2w6IGZhbHNlLFxuICAgIHN1cHBvcnRzX2ltYWdlX2RldGFpbF9vcmlnaW5hbDogZmFsc2UsXG4gIH07XG59XG5cbi8qKlxuICogT3JkZXIgbGlzdGVkIG1vZGVscyBpbiB0aHJlZSBncm91cHM6IG5vbi1lbWJlZGRpbmcgbW9kZWxzIHdpdGggYSBkZXRlY3RlZFxuICogZmFtaWx5LCB0aGUgcmVtYWluaW5nIG5vbi1lbWJlZGRpbmcgbW9kZWxzLCB0aGVuIGVtYmVkZGluZ3MuIEVhY2ggZ3JvdXAgaXNcbiAqIHNvcnRlZCBieSB0aGUgcHVibGlzaGVkIGxhYmVsIChgZGlzcGxheV9uYW1lYCBmb3IgQ29kZXgsIGBuYW1lYCBvdGhlcndpc2UpXG4gKiB3aXRoIG51bWVyaWMgc2VnbWVudHMgb3JkZXJlZCBuYXR1cmFsbHkgc28gXCJWZW8gMy4xXCIgcHJlY2VkZXMgXCJWZW8gMy4xMFwiLlxuICovXG5mdW5jdGlvbiBjb21wYXJlQ2F0YWxvZ3VlVGFyZ2V0cyhcbiAgbGVmdDogTW9kZWxUYXJnZXQsXG4gIHJpZ2h0OiBNb2RlbFRhcmdldCxcbiAgbGFiZWw6ICh0YXJnZXQ6IE1vZGVsVGFyZ2V0KSA9PiBzdHJpbmcsXG4pOiBudW1iZXIge1xuICBjb25zdCBncm91cCA9IGNhdGFsb2d1ZUdyb3VwKGxlZnQpIC0gY2F0YWxvZ3VlR3JvdXAocmlnaHQpO1xuICBpZiAoZ3JvdXAgIT09IDApIHJldHVybiBncm91cDtcbiAgcmV0dXJuIGNvbXBhcmVDYXRhbG9ndWVMYWJlbChsYWJlbChsZWZ0KSwgbGFiZWwocmlnaHQpKTtcbn1cblxuZnVuY3Rpb24gY2F0YWxvZ3VlR3JvdXAodGFyZ2V0OiBNb2RlbFRhcmdldCk6IG51bWJlciB7XG4gIGlmIChpc0VtYmVkZGluZ1RhcmdldCh0YXJnZXQpKSByZXR1cm4gMjtcbiAgcmV0dXJuIGNhdGFsb2d1ZUZhbWlseSh0YXJnZXQpID8gMCA6IDE7XG59XG5cbmZ1bmN0aW9uIGNhdGFsb2d1ZUZhbWlseSh0YXJnZXQ6IE1vZGVsVGFyZ2V0KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc3RhbXBlZCA9IHRhcmdldC5mYW1pbHk/LnRyaW0oKSB8fCB0YXJnZXQuZW5kcG9pbnQ/LmZhbWlseT8udHJpbSgpO1xuICByZXR1cm4gKFxuICAgIG1vZGVsRmFtaWx5KHRhcmdldC5kaXNwbGF5TmFtZSkgPz9cbiAgICBtb2RlbEZhbWlseSh0YXJnZXQuaWQpID8/XG4gICAgKHRhcmdldC5lbmRwb2ludD8ubmFtZSA/IG1vZGVsRmFtaWx5KHRhcmdldC5lbmRwb2ludC5uYW1lKSA6IHVuZGVmaW5lZCkgPz9cbiAgICAoc3RhbXBlZCA/IG1vZGVsRmFtaWx5KHN0YW1wZWQpIDogdW5kZWZpbmVkKVxuICApO1xufVxuXG5mdW5jdGlvbiBpc0VtYmVkZGluZ1RhcmdldCh0YXJnZXQ6IE1vZGVsVGFyZ2V0KTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgdGFyZ2V0LmNhcGFiaWxpdGllcy5lbWJlZGRpbmdzID09PSB0cnVlIHx8IHRhcmdldC5lbmRwb2ludD8udGFzayA9PT0gXCJsbG0vdjEvZW1iZWRkaW5nc1wiXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNvbXBhcmVDYXRhbG9ndWVMYWJlbChsZWZ0OiBzdHJpbmcsIHJpZ2h0OiBzdHJpbmcpOiBudW1iZXIge1xuICByZXR1cm4gbGVmdC5sb2NhbGVDb21wYXJlKHJpZ2h0LCB1bmRlZmluZWQsIHsgbnVtZXJpYzogdHJ1ZSwgc2Vuc2l0aXZpdHk6IFwiYmFzZVwiIH0pO1xufVxuXG5mdW5jdGlvbiBoYXNDaGF0Q2xhc3ModGFyZ2V0OiBNb2RlbFRhcmdldCk6IGJvb2xlYW4ge1xuICBjb25zdCBtb2RlbENsYXNzID0gdGFyZ2V0LmVuZHBvaW50Py5jbGFzcztcbiAgcmV0dXJuIG1vZGVsQ2xhc3MgIT09IHVuZGVmaW5lZCAmJiBpc0NoYXRDbGFzcyhtb2RlbENsYXNzKTtcbn1cbiJdfQ==
149
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZGVscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFVdkUsTUFBTSx1QkFBdUIsR0FDM0IsdUhBQXVILENBQUM7QUFFMUgsTUFBTSxzQkFBc0IsR0FBcUM7SUFDL0QsSUFBSSxFQUFFLDRCQUE0QjtJQUNsQyxPQUFPLEVBQUUsNkNBQTZDO0lBQ3RELEdBQUcsRUFBRSw0QkFBNEI7SUFDakMsTUFBTSxFQUFFLCtCQUErQjtJQUN2QyxJQUFJLEVBQUUsNkJBQTZCO0lBQ25DLEtBQUssRUFBRSxvQ0FBb0M7SUFDM0MsR0FBRyxFQUFFLDRDQUE0QztDQUNsRCxDQUFDO0FBZUYsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixPQUErQixFQUMvQixZQUFxQjtJQUVyQixNQUFNLFNBQVMsR0FBRyxPQUFPO1NBQ3RCLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsVUFBVSxLQUFLLElBQUksQ0FBQztTQUNoRSxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsWUFBWSxJQUFJLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN6RCxLQUFLLEVBQUU7U0FDUCxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FDcEIsdUJBQXVCLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUNyRSxDQUFDO0lBQ0osSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNqQixPQUFPO1lBQ0wsTUFBTSxFQUFFLFNBQVMs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VyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JDLE9BQU8sTUFBTSxJQUFJLEtBQUssS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3pELENBQUM7QUFFRCxTQUFTLGlCQUFpQixDQUFDLE1BQW1CO0lBQzVDLE9BQU8sQ0FDTCxNQUFNLENBQUMsWUFBWSxDQUFDLFVBQVUsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRSxJQUFJLEtBQUssbUJBQW1CLENBQ3pGLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxxQkFBcUIsQ0FBQyxJQUFZLEVBQUUsS0FBYTtJQUN4RCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7QUFDdEYsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLE1BQW1CO0lBQ3ZDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDO0lBQzFDLE9BQU8sVUFBVSxLQUFLLFNBQVMsSUFBSSxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDN0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT3BlbkFJIGFuZCBDb2RleCBtb2RlbC1saXN0IHBheWxvYWRzIGRlcml2ZWQgZnJvbSB0aGUgbGl2ZSByZWdpc3RyeS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgaXNDaGF0Q2xhc3MgfSBmcm9tIFwiQGRieC10b29scy9tb2RlbC9jbGFzc2VzXCI7XG5pbXBvcnQgeyBtb2RlbEZhbWlseSwgbW9kZWxGYW1pbHlSYW5rIH0gZnJvbSBcIkBkYngtdG9vbHMvbW9kZWwvcG9saWN5XCI7XG5pbXBvcnQgdHlwZSB7XG4gIENvZGV4TW9kZWwsXG4gIENvZGV4TW9kZWxMaXN0UmVzcG9uc2UsXG4gIE1vZGVsTGlzdFJlc3BvbnNlLFxuICBNb2RlbFRhcmdldCxcbiAgT3BlbkFJTW9kZWwsXG4gIE9wZW5BSU1vZGVsTGlzdFJlc3BvbnNlLFxufSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWwtZ2F0ZXdheVwiO1xuXG5jb25zdCBDT0RFWF9CQVNFX0lOU1RSVUNUSU9OUyA9XG4gIFwiWW91IGFyZSBhIGNvZGluZyBhZ2VudC4gRm9sbG93IHRoZSB1c2VyJ3MgaW5zdHJ1Y3Rpb25zIGFuZCB1c2UgdGhlIGF2YWlsYWJsZSB0b29scyB0byB3b3JrIGluIHRoZSBjdXJyZW50IHJlcG9zaXRvcnkuXCI7XG5cbmNvbnN0IFJFQVNPTklOR19ERVNDUklQVElPTlM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+ID0ge1xuICBub25lOiBcIkRpc2FibGUgZXhwbGljaXQgcmVhc29uaW5nXCIsXG4gIG1pbmltYWw6IFwiVXNlIHRoZSBzbWFsbGVzdCBhdmFpbGFibGUgcmVhc29uaW5nIGJ1ZGdldFwiLFxuICBsb3c6IFwiVXNlIGEgbG93IHJlYXNvbmluZyBidWRnZXRcIixcbiAgbWVkaXVtOiBcIlVzZSBhIG1lZGl1bSByZWFzb25pbmcgYnVkZ2V0XCIsXG4gIGhpZ2g6IFwiVXNlIGEgaGlnaCByZWFzb25pbmcgYnVkZ2V0XCIsXG4gIHhoaWdoOiBcIlVzZSBhbiBleHRyYS1oaWdoIHJlYXNvbmluZyBidWRnZXRcIixcbiAgbWF4OiBcIlVzZSB0aGUgbGFyZ2VzdCBhdmFpbGFibGUgcmVhc29uaW5nIGJ1ZGdldFwiLFxufTtcblxuLyoqIEJ1aWxkIHRoZSBjb21iaW5lZCBPcGVuQUkgYW5kIG9wdGlvbmFsIENvZGV4IG1vZGVsIGNhdGFsb2d1ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXN0TW9kZWxzUGF5bG9hZChcbiAgdGFyZ2V0czogcmVhZG9ubHkgTW9kZWxUYXJnZXRbXSxcbiAgaW5jbHVkZUNvZGV4OiB0cnVlLFxuKTogQ29kZXhNb2RlbExpc3RSZXNwb25zZTtcbmV4cG9ydCBmdW5jdGlvbiBsaXN0TW9kZWxzUGF5bG9hZChcbiAgdGFyZ2V0czogcmVhZG9ubHkgTW9kZWxUYXJnZXRbXSxcbiAgaW5jbHVkZUNvZGV4OiBmYWxzZSxcbik6IE9wZW5BSU1vZGVsTGlzdFJlc3BvbnNlO1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RNb2RlbHNQYXlsb2FkKFxuICB0YXJnZXRzOiByZWFkb25seSBNb2RlbFRhcmdldFtdLFxuICBpbmNsdWRlQ29kZXg6IGJvb2xlYW4sXG4pOiBNb2RlbExpc3RSZXNwb25zZTtcbmV4cG9ydCBmdW5jdGlvbiBsaXN0TW9kZWxzUGF5bG9hZChcbiAgdGFyZ2V0czogcmVhZG9ubHkgTW9kZWxUYXJnZXRbXSxcbiAgaW5jbHVkZUNvZGV4OiBib29sZWFuLFxuKTogTW9kZWxMaXN0UmVzcG9uc2Uge1xuICBjb25zdCBhdmFpbGFibGUgPSB0YXJnZXRzXG4gICAgLmZpbHRlcigodGFyZ2V0KSA9PiB0YXJnZXQuZW5kcG9pbnQ/LnN0YXR1cz8uZGVwcmVjYXRlZCAhPT0gdHJ1ZSlcbiAgICAuZmlsdGVyKCh0YXJnZXQpID0+ICFpbmNsdWRlQ29kZXggfHwgaGFzQ2hhdENsYXNzKHRhcmdldCkpXG4gICAgLnNsaWNlKClcbiAgICAuc29ydCgobGVmdCwgcmlnaHQpID0+XG4gICAgICBjb21wYXJlQ2F0YWxvZ3VlVGFyZ2V0cyhsZWZ0LCByaWdodCwgKHRhcmdldCkgPT4gdGFyZ2V0LmRpc3BsYXlOYW1lKSxcbiAgICApO1xuICBpZiAoaW5jbHVkZUNvZGV4KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZGVsczogYXZhaWxhYmxlLm1hcCgodGFyZ2V0LCBpbmRleCkgPT4gY29kZXhNb2RlbCh0YXJnZXQsIGluZGV4ICsgMSkpLFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBvYmplY3Q6IFwibGlzdFwiLFxuICAgIGRhdGE6IGF2YWlsYWJsZS5tYXAob3BlbkFpTW9kZWwpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBvcGVuQWlNb2RlbCh0YXJnZXQ6IE1vZGVsVGFyZ2V0KTogT3BlbkFJTW9kZWwge1xuICByZXR1cm4ge1xuICAgIGlkOiB0YXJnZXQuaWQsXG4gICAgb2JqZWN0OiBcIm1vZGVsXCIsXG4gICAgY3JlYXRlZDogMCxcbiAgICBvd25lZF9ieTogXCJkYXRhYnJpY2tzXCIsXG4gICAgbmFtZTogdGFyZ2V0LmRpc3BsYXlOYW1lLFxuICAgIHRhc2s6IHRhcmdldC5lbmRwb2ludD8udGFzayxcbiAgICBzdGF0dXM6IHRhcmdldC5lbmRwb2ludD8uc3RhdHVzID8/IHsgZGVwcmVjYXRlZDogZmFsc2UgfSxcbiAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgIHRvb2xzOiB0YXJnZXQuY2FwYWJpbGl0aWVzLnRvb2xzLFxuICAgICAgcmVhc29uaW5nOiB0YXJnZXQucmVhc29uaW5nRWZmb3J0cyxcbiAgICAgIHJlc3BvbnNlczogdGFyZ2V0LmNhcGFiaWxpdGllcy5yZXNwb25zZXMsXG4gICAgICBvcGVuX3Jlc3BvbnNlczogdGFyZ2V0LmNhcGFiaWxpdGllcy5vcGVuUmVzcG9uc2VzLFxuICAgICAgYW50aHJvcGljOiB0YXJnZXQuY2FwYWJpbGl0aWVzLmFudGhyb3BpYyxcbiAgICAgIGVtYmVkZGluZ3M6IHRhcmdldC5jYXBhYmlsaXRpZXMuZW1iZWRkaW5ncyxcbiAgICAgIGFpX2dhdGV3YXlfY29kZXg6IHRhcmdldC5jYXBhYmlsaXRpZXMuYWlHYXRld2F5Q29kZXgsXG4gICAgICBzdHJlYW1pbmc6IHRhcmdldC5jYXBhYmlsaXRpZXMuc3RyZWFtaW5nLFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvZGV4TW9kZWwodGFyZ2V0OiBNb2RlbFRhcmdldCwgcHJpb3JpdHk6IG51bWJlcik6IENvZGV4TW9kZWwge1xuICBjb25zdCBtb2RlbCA9XG4gICAgdGFyZ2V0LmNhcGFiaWxpdGllcy5haUdhdGV3YXlDb2RleCAmJiB0YXJnZXQubW9kZWxTZXJ2aWNlTmFtZVxuICAgICAgPyB0YXJnZXQubW9kZWxTZXJ2aWNlTmFtZVxuICAgICAgOiB0YXJnZXQuaWQ7XG4gIGNvbnN0IGVmZm9ydHMgPSB0YXJnZXQucmVhc29uaW5nRWZmb3J0cztcbiAgcmV0dXJuIHtcbiAgICBzbHVnOiBgZGF0YWJyaWNrcy8ke21vZGVsfWAsXG4gICAgZGlzcGxheV9uYW1lOiB0YXJnZXQuZGlzcGxheU5hbWUsXG4gICAgZGVzY3JpcHRpb246IHRhcmdldC5lbmRwb2ludD8uZGVzY3JpcHRpb24gPz8gXCJEYXRhYnJpY2tzIG1vZGVsIHNlcnZpY2VcIixcbiAgICBiYXNlX2luc3RydWN0aW9uczogQ09ERVhfQkFTRV9JTlNUUlVDVElPTlMsXG4gICAgc3RhdHVzOiB0YXJnZXQuZW5kcG9pbnQ/LnN0YXR1cyA/PyB7IGRlcHJlY2F0ZWQ6IGZhbHNlIH0sXG4gICAgc3VwcG9ydGVkX3JlYXNvbmluZ19sZXZlbHM6IGVmZm9ydHMubWFwKChlZmZvcnQpID0+ICh7XG4gICAgICBlZmZvcnQsXG4gICAgICBkZXNjcmlwdGlvbjogUkVBU09OSU5HX0RFU0NSSVBUSU9OU1tlZmZvcnRdID8/IGBVc2UgdGhlICR7ZWZmb3J0fSByZWFzb25pbmcgYnVkZ2V0YCxcbiAgICB9KSksXG4gICAgLi4uKGVmZm9ydHMubGVuZ3RoID4gMFxuICAgICAgPyB7IGRlZmF1bHRfcmVhc29uaW5nX2xldmVsOiBlZmZvcnRzLmluY2x1ZGVzKFwibWVkaXVtXCIpID8gXCJtZWRpdW1cIiA6IGVmZm9ydHNbMF0gfVxuICAgICAgOiB7fSksXG4gICAgc2hlbGxfdHlwZTogXCJ1bmlmaWVkX2V4ZWNcIixcbiAgICB2aXNpYmlsaXR5OiBcImxpc3RcIixcbiAgICBzdXBwb3J0ZWRfaW5fYXBpOiB0cnVlLFxuICAgIHByaW9yaXR5LFxuICAgIGF2YWlsYWJpbGl0eV9udXg6IG51bGwsXG4gICAgdXBncmFkZTogbnVsbCxcbiAgICBzdXBwb3J0X3ZlcmJvc2l0eTogZmFsc2UsXG4gICAgZGVmYXVsdF92ZXJib3NpdHk6IG51bGwsXG4gICAgYXBwbHlfcGF0Y2hfdG9vbF90eXBlOiB0YXJnZXQuY2FwYWJpbGl0aWVzLmN1c3RvbVRvb2xzID8gXCJmcmVlZm9ybVwiIDogbnVsbCxcbiAgICB0cnVuY2F0aW9uX3BvbGljeTogeyBtb2RlOiBcInRva2Vuc1wiLCBsaW1pdDogMTI4XzAwMCB9LFxuICAgIGNvbnRleHRfd2luZG93OiBudWxsLFxuICAgIGV4cGVyaW1lbnRhbF9zdXBwb3J0ZWRfdG9vbHM6IFtdLFxuICAgIGlucHV0X21vZGFsaXRpZXM6IFtcInRleHRcIl0sXG4gICAgd2ViX3NlYXJjaF90b29sX3R5cGU6IFwidGV4dFwiLFxuICAgIHN1cHBvcnRzX3NlYXJjaF90b29sOiBmYWxzZSxcbiAgICBzdXBwb3J0c19pbWFnZV9kZXRhaWxfb3JpZ2luYWw6IGZhbHNlLFxuICB9O1xufVxuXG4vKipcbiAqIE9yZGVyIGxpc3RlZCBtb2RlbHMgaW4gdGhyZWUgZ3JvdXBzOiBtYWpvci1wcm92aWRlciBjaGF0IGZhbWlsaWVzLCB0aGVcbiAqIHJlbWFpbmluZyBjaGF0IG1vZGVscywgdGhlbiBlbWJlZGRpbmdzLiBGYW1pbGllcyBrZWVwIGEgZml4ZWQgcHJvdmlkZXJcbiAqIG9yZGVyOyBlYWNoIGZhbWlseSBhbmQgdGhlIGxhdGVyIGdyb3VwcyBzb3J0IGJ5IHRoZSBwdWJsaXNoZWQgbGFiZWxcbiAqIChgZGlzcGxheV9uYW1lYCBmb3IgQ29kZXgsIGBuYW1lYCBvdGhlcndpc2UpLiBOdW1lcmljIHNlZ21lbnRzIHNvcnRcbiAqIG5hdHVyYWxseSBzbyBcIlZlbyAzLjFcIiBwcmVjZWRlcyBcIlZlbyAzLjEwXCIuXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmVDYXRhbG9ndWVUYXJnZXRzKFxuICBsZWZ0OiBNb2RlbFRhcmdldCxcbiAgcmlnaHQ6IE1vZGVsVGFyZ2V0LFxuICBsYWJlbDogKHRhcmdldDogTW9kZWxUYXJnZXQpID0+IHN0cmluZyxcbik6IG51bWJlciB7XG4gIGNvbnN0IGdyb3VwID0gY2F0YWxvZ3VlR3JvdXAobGVmdCkgLSBjYXRhbG9ndWVHcm91cChyaWdodCk7XG4gIGlmIChncm91cCAhPT0gMCkgcmV0dXJuIGdyb3VwO1xuICBjb25zdCBsZWZ0RmFtaWx5ID0gY2F0YWxvZ3VlRmFtaWx5KGxlZnQpO1xuICBjb25zdCByaWdodEZhbWlseSA9IGNhdGFsb2d1ZUZhbWlseShyaWdodCk7XG4gIGlmIChsZWZ0RmFtaWx5ICYmIHJpZ2h0RmFtaWx5KSB7XG4gICAgY29uc3QgZmFtaWx5T3JkZXIgPSBtb2RlbEZhbWlseVJhbmsobGVmdEZhbWlseSkgLSBtb2RlbEZhbWlseVJhbmsocmlnaHRGYW1pbHkpO1xuICAgIGlmIChmYW1pbHlPcmRlciAhPT0gMCkgcmV0dXJuIGZhbWlseU9yZGVyO1xuICB9XG4gIHJldHVybiBjb21wYXJlQ2F0YWxvZ3VlTGFiZWwobGFiZWwobGVmdCksIGxhYmVsKHJpZ2h0KSk7XG59XG5cbmZ1bmN0aW9uIGNhdGFsb2d1ZUdyb3VwKHRhcmdldDogTW9kZWxUYXJnZXQpOiBudW1iZXIge1xuICBpZiAoaXNFbWJlZGRpbmdUYXJnZXQodGFyZ2V0KSkgcmV0dXJuIDI7XG4gIHJldHVybiBjYXRhbG9ndWVGYW1pbHkodGFyZ2V0KSA/IDAgOiAxO1xufVxuXG5jb25zdCBJREVOVElUWV9QUkVGSVhFUyA9IG5ldyBTZXQoW1wiZGF0YWJyaWNrc1wiLCBcInN5c3RlbVwiLCBcImFpXCIsIFwibWV0YVwiLCBcImdvb2dsZVwiLCBcIm9wZW5haVwiLCBcImFudGhyb3BpY1wiXSk7XG5cbmZ1bmN0aW9uIGNhdGFsb2d1ZUZhbWlseSh0YXJnZXQ6IE1vZGVsVGFyZ2V0KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKGlzRW1iZWRkaW5nVGFyZ2V0KHRhcmdldCkpIHJldHVybiB1bmRlZmluZWQ7XG4gIGZvciAoY29uc3QgaWRlbnRpdHkgb2YgW3RhcmdldC5kaXNwbGF5TmFtZSwgdGFyZ2V0LmlkLCB0YXJnZXQuZW5kcG9pbnQ/Lm5hbWVdKSB7XG4gICAgaWYgKCFpZGVudGl0eSkgY29udGludWU7XG4gICAgY29uc3QgZmFtaWx5ID0gY2F0YWxvZ3VlRmFtaWx5RnJvbUlkZW50aXR5KGlkZW50aXR5KTtcbiAgICBpZiAoZmFtaWx5KSByZXR1cm4gZmFtaWx5O1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGNhdGFsb2d1ZUZhbWlseUZyb21JZGVudGl0eShpZGVudGl0eTogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgdG9rZW5zID0gaWRlbnRpdHkudG9Mb3dlckNhc2UoKS5tYXRjaCgvW2EtejAtOV0rL2cpID8/IFtdO1xuICBjb25zdCBzdGFydCA9IHRva2Vucy5maW5kKCh0b2tlbikgPT4gIUlERU5USVRZX1BSRUZJWEVTLmhhcyh0b2tlbikpO1xuICBpZiAoIXN0YXJ0KSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAoc3RhcnQgPT09IFwidmVvXCIpIHJldHVybiBcImdlbWluaVwiO1xuICBjb25zdCBmYW1pbHkgPSBtb2RlbEZhbWlseShpZGVudGl0eSk7XG4gIHJldHVybiBmYW1pbHkgJiYgc3RhcnQgPT09IGZhbWlseSA/IGZhbWlseSA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNFbWJlZGRpbmdUYXJnZXQodGFyZ2V0OiBNb2RlbFRhcmdldCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIHRhcmdldC5jYXBhYmlsaXRpZXMuZW1iZWRkaW5ncyA9PT0gdHJ1ZSB8fCB0YXJnZXQuZW5kcG9pbnQ/LnRhc2sgPT09IFwibGxtL3YxL2VtYmVkZGluZ3NcIlxuICApO1xufVxuXG5mdW5jdGlvbiBjb21wYXJlQ2F0YWxvZ3VlTGFiZWwobGVmdDogc3RyaW5nLCByaWdodDogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIGxlZnQubG9jYWxlQ29tcGFyZShyaWdodCwgdW5kZWZpbmVkLCB7IG51bWVyaWM6IHRydWUsIHNlbnNpdGl2aXR5OiBcImJhc2VcIiB9KTtcbn1cblxuZnVuY3Rpb24gaGFzQ2hhdENsYXNzKHRhcmdldDogTW9kZWxUYXJnZXQpOiBib29sZWFuIHtcbiAgY29uc3QgbW9kZWxDbGFzcyA9IHRhcmdldC5lbmRwb2ludD8uY2xhc3M7XG4gIHJldHVybiBtb2RlbENsYXNzICE9PSB1bmRlZmluZWQgJiYgaXNDaGF0Q2xhc3MobW9kZWxDbGFzcyk7XG59XG4iXX0=
package/package.json CHANGED
@@ -31,11 +31,11 @@
31
31
  "@ai-sdk/open-responses": "^2.0.58",
32
32
  "@ai-sdk/openai-compatible": "^3.0.62",
33
33
  "@databricks/appkit": "0.81.0",
34
- "@dbx-tools/databricks": "^0.9.37",
35
- "@dbx-tools/model": "^0.9.37",
36
- "@dbx-tools/shared-core": "^0.9.37",
37
- "@dbx-tools/shared-model": "^0.9.37",
38
- "@dbx-tools/shared-model-gateway": "^0.9.37",
34
+ "@dbx-tools/databricks": "^0.9.40",
35
+ "@dbx-tools/model": "^0.9.40",
36
+ "@dbx-tools/shared-core": "^0.9.40",
37
+ "@dbx-tools/shared-model": "^0.9.40",
38
+ "@dbx-tools/shared-model-gateway": "^0.9.40",
39
39
  "ai": "^7.0.0",
40
40
  "zod": "4.3.6"
41
41
  },
@@ -89,7 +89,7 @@
89
89
  "./package.json": "./package.json"
90
90
  }
91
91
  },
92
- "version": "0.9.37",
92
+ "version": "0.9.40",
93
93
  "types": "./lib/index.d.ts",
94
94
  "dbxToolsConfig": {
95
95
  "tags": [
package/src/models.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { isChatClass } from "@dbx-tools/model/classes";
8
- import { modelFamily } from "@dbx-tools/model/policy";
8
+ import { modelFamily, modelFamilyRank } from "@dbx-tools/model/policy";
9
9
  import type {
10
10
  CodexModel,
11
11
  CodexModelListResponse,
@@ -124,10 +124,11 @@ function codexModel(target: ModelTarget, priority: number): CodexModel {
124
124
  }
125
125
 
126
126
  /**
127
- * Order listed models in three groups: non-embedding models with a detected
128
- * family, the remaining non-embedding models, then embeddings. Each group is
129
- * sorted by the published label (`display_name` for Codex, `name` otherwise)
130
- * with numeric segments ordered naturally so "Veo 3.1" precedes "Veo 3.10".
127
+ * Order listed models in three groups: major-provider chat families, the
128
+ * remaining chat models, then embeddings. Families keep a fixed provider
129
+ * order; each family and the later groups sort by the published label
130
+ * (`display_name` for Codex, `name` otherwise). Numeric segments sort
131
+ * naturally so "Veo 3.1" precedes "Veo 3.10".
131
132
  */
132
133
  function compareCatalogueTargets(
133
134
  left: ModelTarget,
@@ -136,6 +137,12 @@ function compareCatalogueTargets(
136
137
  ): number {
137
138
  const group = catalogueGroup(left) - catalogueGroup(right);
138
139
  if (group !== 0) return group;
140
+ const leftFamily = catalogueFamily(left);
141
+ const rightFamily = catalogueFamily(right);
142
+ if (leftFamily && rightFamily) {
143
+ const familyOrder = modelFamilyRank(leftFamily) - modelFamilyRank(rightFamily);
144
+ if (familyOrder !== 0) return familyOrder;
145
+ }
139
146
  return compareCatalogueLabel(label(left), label(right));
140
147
  }
141
148
 
@@ -144,14 +151,25 @@ function catalogueGroup(target: ModelTarget): number {
144
151
  return catalogueFamily(target) ? 0 : 1;
145
152
  }
146
153
 
154
+ const IDENTITY_PREFIXES = new Set(["databricks", "system", "ai", "meta", "google", "openai", "anthropic"]);
155
+
147
156
  function catalogueFamily(target: ModelTarget): string | undefined {
148
- const stamped = target.family?.trim() || target.endpoint?.family?.trim();
149
- return (
150
- modelFamily(target.displayName) ??
151
- modelFamily(target.id) ??
152
- (target.endpoint?.name ? modelFamily(target.endpoint.name) : undefined) ??
153
- (stamped ? modelFamily(stamped) : undefined)
154
- );
157
+ if (isEmbeddingTarget(target)) return undefined;
158
+ for (const identity of [target.displayName, target.id, target.endpoint?.name]) {
159
+ if (!identity) continue;
160
+ const family = catalogueFamilyFromIdentity(identity);
161
+ if (family) return family;
162
+ }
163
+ return undefined;
164
+ }
165
+
166
+ function catalogueFamilyFromIdentity(identity: string): string | undefined {
167
+ const tokens = identity.toLowerCase().match(/[a-z0-9]+/g) ?? [];
168
+ const start = tokens.find((token) => !IDENTITY_PREFIXES.has(token));
169
+ if (!start) return undefined;
170
+ if (start === "veo") return "gemini";
171
+ const family = modelFamily(identity);
172
+ return family && start === family ? family : undefined;
155
173
  }
156
174
 
157
175
  function isEmbeddingTarget(target: ModelTarget): boolean {