@dbx-tools/model 0.1.42 → 0.1.48
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 +76 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/src/classes.d.ts +51 -0
- package/dist/src/classes.js +71 -0
- package/dist/src/fallback.d.ts +17 -16
- package/dist/src/fallback.js +24 -23
- package/dist/src/resolve.d.ts +79 -28
- package/dist/src/resolve.js +142 -56
- package/dist/src/serving.d.ts +57 -31
- package/dist/src/serving.js +118 -55
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/index.ts +2 -1
- package/package.json +3 -3
- package/src/classes.ts +75 -0
- package/src/fallback.ts +28 -23
- package/src/resolve.ts +182 -73
- package/src/serving.ts +160 -67
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# @dbx-tools/model
|
|
2
|
+
|
|
3
|
+
Workspace-aware model selection for Databricks Model Serving: list a
|
|
4
|
+
workspace's `/serving-endpoints` (cached), fuzzy-match loose names like
|
|
5
|
+
`"claude sonnet"` to real endpoint ids, rank endpoints by capability
|
|
6
|
+
class, and resolve a single usable model id with an offline fallback
|
|
7
|
+
floor.
|
|
8
|
+
|
|
9
|
+
This is the server-side package (it holds a `WorkspaceClient` and
|
|
10
|
+
AppKit's cache). Browser consumers want the pure
|
|
11
|
+
[`@dbx-tools/model-shared`](../model-shared) surface, which this package
|
|
12
|
+
re-exports.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @dbx-tools/model
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Peer: `@databricks/appkit` (provides the cache the listing runs through).
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
Hold a `WorkspaceClient` and just want a usable model id? `selectModel`
|
|
25
|
+
lists the catalogue (cached) and resolves in one call. An `explicit`
|
|
26
|
+
name is fuzzy-matched; without one, a `modelClass` ceiling (or the
|
|
27
|
+
operator `fallbacks`, then the static floor) decides.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { WorkspaceClient } from "@databricks/sdk-experimental";
|
|
31
|
+
import { selectModel, searchModels } from "@dbx-tools/model";
|
|
32
|
+
|
|
33
|
+
const client = new WorkspaceClient({});
|
|
34
|
+
const host = (await client.config.getHost()).toString();
|
|
35
|
+
|
|
36
|
+
// Fuzzy name -> real endpoint id (+ how it was reached).
|
|
37
|
+
const { modelId, source } = await selectModel(client, host, {
|
|
38
|
+
explicit: "claude sonnet",
|
|
39
|
+
}); // -> { modelId: "databricks-claude-sonnet-4-6", source: "fuzzy-match" }
|
|
40
|
+
|
|
41
|
+
// Best balanced-or-cheaper chat model the workspace actually has.
|
|
42
|
+
const fast = await selectModel(client, host, { modelClass: "chat-balanced" });
|
|
43
|
+
|
|
44
|
+
// Or get the full ranked list (model picker / CLI).
|
|
45
|
+
const ranked = await searchModels(client, host, { search: "opus", limit: 5 });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The capability class acts as a **ceiling**: `chat-balanced` can fall to
|
|
49
|
+
`chat-fast` but never escalate to `chat-thinking`. Embedding endpoints
|
|
50
|
+
surface only when `modelClass` is explicitly `embedding`.
|
|
51
|
+
|
|
52
|
+
### Pure helpers (no I/O)
|
|
53
|
+
|
|
54
|
+
If you already hold the endpoint list (e.g. from a cached `/models`
|
|
55
|
+
response), use the pure functions directly:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { resolveModelId, rankModels, resolveModel } from "@dbx-tools/model";
|
|
59
|
+
|
|
60
|
+
resolveModelId("claude sonnet", endpoints); // single best fuzzy match
|
|
61
|
+
rankModels(endpoints, { search: "opus", limit: 3 }); // ranked list
|
|
62
|
+
resolveModel(endpoints, { modelClass: "chat-fast" }); // single id + source
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## How resolution works
|
|
66
|
+
|
|
67
|
+
1. **Explicit ask** - fuzzy-matched within the optional class ceiling
|
|
68
|
+
(or returned verbatim when `fuzzy: false`).
|
|
69
|
+
2. **No explicit ask** - an operator-pinned `fallback` that exists in
|
|
70
|
+
the live catalogue wins first, then the ranked live catalogue, then a
|
|
71
|
+
small static `FALLBACK_MODEL_IDS` floor when the catalogue yields
|
|
72
|
+
nothing in range (so a model id is always returned even offline).
|
|
73
|
+
|
|
74
|
+
Capability bands are derived from the live workspace catalogue (the
|
|
75
|
+
Foundation Model API quality/speed/cost scores), not a hand-maintained
|
|
76
|
+
table - see `@dbx-tools/model-shared` for the classifier.
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Bundles the package's Node-side Model Serving access (cached
|
|
5
5
|
* `/serving-endpoints` listing plus fuzzy name resolution), the
|
|
6
6
|
* workspace-aware {@link resolveModel} selector, and the server-only
|
|
7
|
-
* offline fallback opinion (`FALLBACK_MODEL_IDS` / `
|
|
7
|
+
* offline fallback opinion (`FALLBACK_MODEL_IDS` / `modelsForClass`)
|
|
8
8
|
* with a re-export of the pure `@dbx-tools/model-shared` surface
|
|
9
9
|
* (capability tiers, the score profile, the endpoint descriptor, and
|
|
10
10
|
* the tier classifier) so a single `from "@dbx-tools/model"` import
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* pure (types + sync functions) and safe for any runtime.
|
|
17
17
|
*/
|
|
18
18
|
export * from "@dbx-tools/model-shared";
|
|
19
|
+
export * from "./src/classes.js";
|
|
19
20
|
export * from "./src/fallback.js";
|
|
20
21
|
export * from "./src/resolve.js";
|
|
21
22
|
export * from "./src/serving.js";
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Bundles the package's Node-side Model Serving access (cached
|
|
5
5
|
* `/serving-endpoints` listing plus fuzzy name resolution), the
|
|
6
6
|
* workspace-aware {@link resolveModel} selector, and the server-only
|
|
7
|
-
* offline fallback opinion (`FALLBACK_MODEL_IDS` / `
|
|
7
|
+
* offline fallback opinion (`FALLBACK_MODEL_IDS` / `modelsForClass`)
|
|
8
8
|
* with a re-export of the pure `@dbx-tools/model-shared` surface
|
|
9
9
|
* (capability tiers, the score profile, the endpoint descriptor, and
|
|
10
10
|
* the tier classifier) so a single `from "@dbx-tools/model"` import
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* pure (types + sync functions) and safe for any runtime.
|
|
17
17
|
*/
|
|
18
18
|
export * from "@dbx-tools/model-shared";
|
|
19
|
+
export * from "./src/classes.js";
|
|
19
20
|
export * from "./src/fallback.js";
|
|
20
21
|
export * from "./src/resolve.js";
|
|
21
22
|
export * from "./src/serving.js";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-class ordering for the model service.
|
|
3
|
+
*
|
|
4
|
+
* `@dbx-tools/model-shared` declares the {@link ModelClass} values and
|
|
5
|
+
* their schema; the *behavior* over those values - the chat capability
|
|
6
|
+
* order, the "this class and below" ceiling, and coercing loose request
|
|
7
|
+
* input to a class - lives here in the service so the shared
|
|
8
|
+
* wire-format surface stays purely declarative.
|
|
9
|
+
*/
|
|
10
|
+
import { ModelClass } from "@dbx-tools/model-shared";
|
|
11
|
+
/**
|
|
12
|
+
* Chat capability ladder in descending order - most capable
|
|
13
|
+
* ({@link ModelClass.ChatThinking}) first, least
|
|
14
|
+
* ({@link ModelClass.ChatFast}) last. {@link ModelClass.Embedding} is a
|
|
15
|
+
* separate modality and is deliberately absent: the ceiling never spans
|
|
16
|
+
* it. This is the order used to filter "this class and below" and to
|
|
17
|
+
* break ranking ties toward the more capable model.
|
|
18
|
+
*/
|
|
19
|
+
export declare const CHAT_CLASS_ORDER: readonly ModelClass[];
|
|
20
|
+
/**
|
|
21
|
+
* Every class in display order: the chat ladder followed by
|
|
22
|
+
* {@link ModelClass.Embedding}. Used when flattening a full
|
|
23
|
+
* classification (e.g. stamping the class onto each cached endpoint).
|
|
24
|
+
*/
|
|
25
|
+
export declare const MODEL_CLASS_ORDER: readonly ModelClass[];
|
|
26
|
+
/** Whether `cls` is one of the chat capability bands (vs. embedding). */
|
|
27
|
+
export declare function isChatClass(cls: ModelClass): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Coerce an arbitrary value (query string, header, body field) to a
|
|
30
|
+
* {@link ModelClass}, returning `null` when it isn't a known class.
|
|
31
|
+
* Lets a route accept a class request without throwing on junk input.
|
|
32
|
+
*
|
|
33
|
+
* Matches the full slug first (`"chat-fast"`, `"embedding"`), then -
|
|
34
|
+
* for a bare chat band - retries with a `chat-` prefix, so the shorthand
|
|
35
|
+
* `"thinking"` / `"balanced"` / `"fast"` resolves to the corresponding
|
|
36
|
+
* `chat-*` class.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseModelClass(value: unknown): ModelClass | null;
|
|
39
|
+
/**
|
|
40
|
+
* Classes at or below `cls` in chat capability: the class itself plus
|
|
41
|
+
* every less-capable chat band, in {@link CHAT_CLASS_ORDER}. Treats a
|
|
42
|
+
* chat `cls` as a ceiling - requesting {@link ModelClass.ChatBalanced}
|
|
43
|
+
* yields `[ChatBalanced, ChatFast]`, never
|
|
44
|
+
* {@link ModelClass.ChatThinking} - so a class ask can degrade downward
|
|
45
|
+
* to a smaller chat model but never escalate to a larger one.
|
|
46
|
+
*
|
|
47
|
+
* {@link ModelClass.Embedding} is its own modality, not a rung on the
|
|
48
|
+
* chat ladder, so it yields just `[Embedding]`. An unrecognized class
|
|
49
|
+
* yields the full chat ladder.
|
|
50
|
+
*/
|
|
51
|
+
export declare function classesAtOrBelow(cls: ModelClass): ModelClass[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-class ordering for the model service.
|
|
3
|
+
*
|
|
4
|
+
* `@dbx-tools/model-shared` declares the {@link ModelClass} values and
|
|
5
|
+
* their schema; the *behavior* over those values - the chat capability
|
|
6
|
+
* order, the "this class and below" ceiling, and coercing loose request
|
|
7
|
+
* input to a class - lives here in the service so the shared
|
|
8
|
+
* wire-format surface stays purely declarative.
|
|
9
|
+
*/
|
|
10
|
+
import { ModelClass, ModelClassSchema } from "@dbx-tools/model-shared";
|
|
11
|
+
/**
|
|
12
|
+
* Chat capability ladder in descending order - most capable
|
|
13
|
+
* ({@link ModelClass.ChatThinking}) first, least
|
|
14
|
+
* ({@link ModelClass.ChatFast}) last. {@link ModelClass.Embedding} is a
|
|
15
|
+
* separate modality and is deliberately absent: the ceiling never spans
|
|
16
|
+
* it. This is the order used to filter "this class and below" and to
|
|
17
|
+
* break ranking ties toward the more capable model.
|
|
18
|
+
*/
|
|
19
|
+
export const CHAT_CLASS_ORDER = [
|
|
20
|
+
ModelClass.ChatThinking,
|
|
21
|
+
ModelClass.ChatBalanced,
|
|
22
|
+
ModelClass.ChatFast,
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Every class in display order: the chat ladder followed by
|
|
26
|
+
* {@link ModelClass.Embedding}. Used when flattening a full
|
|
27
|
+
* classification (e.g. stamping the class onto each cached endpoint).
|
|
28
|
+
*/
|
|
29
|
+
export const MODEL_CLASS_ORDER = [
|
|
30
|
+
...CHAT_CLASS_ORDER,
|
|
31
|
+
ModelClass.Embedding,
|
|
32
|
+
];
|
|
33
|
+
/** Whether `cls` is one of the chat capability bands (vs. embedding). */
|
|
34
|
+
export function isChatClass(cls) {
|
|
35
|
+
return CHAT_CLASS_ORDER.includes(cls);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Coerce an arbitrary value (query string, header, body field) to a
|
|
39
|
+
* {@link ModelClass}, returning `null` when it isn't a known class.
|
|
40
|
+
* Lets a route accept a class request without throwing on junk input.
|
|
41
|
+
*
|
|
42
|
+
* Matches the full slug first (`"chat-fast"`, `"embedding"`), then -
|
|
43
|
+
* for a bare chat band - retries with a `chat-` prefix, so the shorthand
|
|
44
|
+
* `"thinking"` / `"balanced"` / `"fast"` resolves to the corresponding
|
|
45
|
+
* `chat-*` class.
|
|
46
|
+
*/
|
|
47
|
+
export function parseModelClass(value) {
|
|
48
|
+
const exact = ModelClassSchema.safeParse(value);
|
|
49
|
+
if (exact.success)
|
|
50
|
+
return exact.data;
|
|
51
|
+
const prefixed = ModelClassSchema.safeParse(`chat-${value}`);
|
|
52
|
+
return prefixed.success ? prefixed.data : null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Classes at or below `cls` in chat capability: the class itself plus
|
|
56
|
+
* every less-capable chat band, in {@link CHAT_CLASS_ORDER}. Treats a
|
|
57
|
+
* chat `cls` as a ceiling - requesting {@link ModelClass.ChatBalanced}
|
|
58
|
+
* yields `[ChatBalanced, ChatFast]`, never
|
|
59
|
+
* {@link ModelClass.ChatThinking} - so a class ask can degrade downward
|
|
60
|
+
* to a smaller chat model but never escalate to a larger one.
|
|
61
|
+
*
|
|
62
|
+
* {@link ModelClass.Embedding} is its own modality, not a rung on the
|
|
63
|
+
* chat ladder, so it yields just `[Embedding]`. An unrecognized class
|
|
64
|
+
* yields the full chat ladder.
|
|
65
|
+
*/
|
|
66
|
+
export function classesAtOrBelow(cls) {
|
|
67
|
+
if (cls === ModelClass.Embedding)
|
|
68
|
+
return [ModelClass.Embedding];
|
|
69
|
+
const index = CHAT_CLASS_ORDER.indexOf(cls);
|
|
70
|
+
return index < 0 ? [...CHAT_CLASS_ORDER] : [...CHAT_CLASS_ORDER.slice(index)];
|
|
71
|
+
}
|
package/dist/src/fallback.d.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* no user token, the service principal can't list, or the workspace is
|
|
6
6
|
* unreachable - the resolver still has to name *some* endpoint. This
|
|
7
7
|
* module holds that floor: a small, hard-coded set of well-known
|
|
8
|
-
* Foundation Model API endpoint names, each bucketed into a
|
|
9
|
-
* {@link
|
|
10
|
-
* (no
|
|
8
|
+
* Foundation Model API endpoint names, each bucketed into a chat
|
|
9
|
+
* {@link ModelClass} by the shared {@link classifyByFamily} heuristic
|
|
10
|
+
* (no classes are hard-coded here) and ordered best-first.
|
|
11
11
|
*
|
|
12
12
|
* This is deliberately *server-only*. A browser client never talks to
|
|
13
13
|
* Databricks directly - it always goes through this server - so it has
|
|
@@ -15,21 +15,22 @@
|
|
|
15
15
|
* list; it consumes the live `/models` response instead. The pure
|
|
16
16
|
* classifier ({@link classifyEndpoints}) is what the client shares.
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
18
|
+
import { ModelClass } from "@dbx-tools/model-shared";
|
|
19
19
|
/**
|
|
20
|
-
* Static fallback model ids for a
|
|
21
|
-
* {@link FALLBACK_MODEL_NAMES} list and ordered best-first by
|
|
22
|
-
* rank. Sync and workspace-independent: this is the *fallback
|
|
23
|
-
* used to seed default lists or when the live catalogue is
|
|
24
|
-
* - live resolution prefers `classifyEndpoints`.
|
|
20
|
+
* Static fallback model ids for a chat class, drawn from the small
|
|
21
|
+
* built-in {@link FALLBACK_MODEL_NAMES} list and ordered best-first by
|
|
22
|
+
* family rank. Sync and workspace-independent: this is the *fallback
|
|
23
|
+
* opinion* used to seed default lists or when the live catalogue is
|
|
24
|
+
* unreachable - live resolution prefers `classifyEndpoints`. Returns
|
|
25
|
+
* `[]` for {@link ModelClass.Embedding} (the floor is chat-only).
|
|
25
26
|
*/
|
|
26
|
-
export declare function
|
|
27
|
-
/** Top static fallback model id for a
|
|
28
|
-
export declare function
|
|
27
|
+
export declare function modelsForClass(cls: ModelClass): readonly string[];
|
|
28
|
+
/** Top static fallback model id for a chat class. */
|
|
29
|
+
export declare function modelForClass(cls: ModelClass): string;
|
|
29
30
|
/**
|
|
30
|
-
* Priority-ordered fallback chain (
|
|
31
|
-
* the small built-in list. The floor walked at resolve
|
|
32
|
-
* agent / plugin / env / request model is set *and* the
|
|
33
|
-
* catalogue yields nothing.
|
|
31
|
+
* Priority-ordered fallback chain (ChatThinking -> ChatBalanced ->
|
|
32
|
+
* ChatFast) over the small built-in list. The floor walked at resolve
|
|
33
|
+
* time when no agent / plugin / env / request model is set *and* the
|
|
34
|
+
* live catalogue yields nothing.
|
|
34
35
|
*/
|
|
35
36
|
export declare const FALLBACK_MODEL_IDS: readonly string[];
|
package/dist/src/fallback.js
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* no user token, the service principal can't list, or the workspace is
|
|
6
6
|
* unreachable - the resolver still has to name *some* endpoint. This
|
|
7
7
|
* module holds that floor: a small, hard-coded set of well-known
|
|
8
|
-
* Foundation Model API endpoint names, each bucketed into a
|
|
9
|
-
* {@link
|
|
10
|
-
* (no
|
|
8
|
+
* Foundation Model API endpoint names, each bucketed into a chat
|
|
9
|
+
* {@link ModelClass} by the shared {@link classifyByFamily} heuristic
|
|
10
|
+
* (no classes are hard-coded here) and ordered best-first.
|
|
11
11
|
*
|
|
12
12
|
* This is deliberately *server-only*. A browser client never talks to
|
|
13
13
|
* Databricks directly - it always goes through this server - so it has
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
* list; it consumes the live `/models` response instead. The pure
|
|
16
16
|
* classifier ({@link classifyEndpoints}) is what the client shares.
|
|
17
17
|
*/
|
|
18
|
-
import { classifyByFamily,
|
|
18
|
+
import { classifyByFamily, ModelClass, } from "@dbx-tools/model-shared";
|
|
19
19
|
/**
|
|
20
20
|
* Small, last-resort set of well-known Foundation Model API endpoint
|
|
21
|
-
* names, ordered best-first within each
|
|
21
|
+
* names, ordered best-first within each class by {@link classifyByFamily}.
|
|
22
22
|
* Used only as the floor when the live `/serving-endpoints` catalogue
|
|
23
23
|
* can't be read at resolve time; the live, score-driven classification
|
|
24
|
-
* supersedes it whenever the workspace listing is available.
|
|
24
|
+
* supersedes it whenever the workspace listing is available. Classes are
|
|
25
25
|
* not hard-coded here - each name is classified by family heuristic.
|
|
26
26
|
*/
|
|
27
27
|
const FALLBACK_MODEL_NAMES = [
|
|
@@ -36,30 +36,31 @@ const FALLBACK_MODEL_NAMES = [
|
|
|
36
36
|
"databricks-meta-llama-3-1-8b-instruct",
|
|
37
37
|
];
|
|
38
38
|
/**
|
|
39
|
-
* Static fallback model ids for a
|
|
40
|
-
* {@link FALLBACK_MODEL_NAMES} list and ordered best-first by
|
|
41
|
-
* rank. Sync and workspace-independent: this is the *fallback
|
|
42
|
-
* used to seed default lists or when the live catalogue is
|
|
43
|
-
* - live resolution prefers `classifyEndpoints`.
|
|
39
|
+
* Static fallback model ids for a chat class, drawn from the small
|
|
40
|
+
* built-in {@link FALLBACK_MODEL_NAMES} list and ordered best-first by
|
|
41
|
+
* family rank. Sync and workspace-independent: this is the *fallback
|
|
42
|
+
* opinion* used to seed default lists or when the live catalogue is
|
|
43
|
+
* unreachable - live resolution prefers `classifyEndpoints`. Returns
|
|
44
|
+
* `[]` for {@link ModelClass.Embedding} (the floor is chat-only).
|
|
44
45
|
*/
|
|
45
|
-
export function
|
|
46
|
+
export function modelsForClass(cls) {
|
|
46
47
|
return FALLBACK_MODEL_NAMES.map((name) => ({ name, c: classifyByFamily(name) }))
|
|
47
|
-
.filter((x) => x.c !== null && x.c.
|
|
48
|
+
.filter((x) => x.c !== null && x.c.class === cls)
|
|
48
49
|
.sort((a, b) => b.c.rank - a.c.rank)
|
|
49
50
|
.map((x) => x.name);
|
|
50
51
|
}
|
|
51
|
-
/** Top static fallback model id for a
|
|
52
|
-
export function
|
|
53
|
-
return
|
|
52
|
+
/** Top static fallback model id for a chat class. */
|
|
53
|
+
export function modelForClass(cls) {
|
|
54
|
+
return modelsForClass(cls)[0];
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
56
|
-
* Priority-ordered fallback chain (
|
|
57
|
-
* the small built-in list. The floor walked at resolve
|
|
58
|
-
* agent / plugin / env / request model is set *and* the
|
|
59
|
-
* catalogue yields nothing.
|
|
57
|
+
* Priority-ordered fallback chain (ChatThinking -> ChatBalanced ->
|
|
58
|
+
* ChatFast) over the small built-in list. The floor walked at resolve
|
|
59
|
+
* time when no agent / plugin / env / request model is set *and* the
|
|
60
|
+
* live catalogue yields nothing.
|
|
60
61
|
*/
|
|
61
62
|
export const FALLBACK_MODEL_IDS = [
|
|
62
|
-
...
|
|
63
|
-
...
|
|
64
|
-
...
|
|
63
|
+
...modelsForClass(ModelClass.ChatThinking),
|
|
64
|
+
...modelsForClass(ModelClass.ChatBalanced),
|
|
65
|
+
...modelsForClass(ModelClass.ChatFast),
|
|
65
66
|
];
|
package/dist/src/resolve.d.ts
CHANGED
|
@@ -1,26 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workspace-aware model selection.
|
|
3
3
|
*
|
|
4
|
-
* Given a caller's intent
|
|
5
|
-
* {@link
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Given a caller's intent - a search string, a capability
|
|
5
|
+
* {@link ModelClass} ceiling, both, or nothing - the toolkit returns
|
|
6
|
+
* matching endpoints ranked by match quality then class, or collapses
|
|
7
|
+
* to the single best id the workspace actually has, degrading from
|
|
8
|
+
* "best in range" down to the static fallback floor. Selection is
|
|
9
|
+
* chat-only: embedding endpoints surface only when `modelClass` is
|
|
10
|
+
* explicitly {@link ModelClass.Embedding}.
|
|
8
11
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Ranking entry points (return a ranked list):
|
|
13
|
+
*
|
|
14
|
+
* - {@link rankModels} is the pure ranker over an endpoint list you
|
|
15
|
+
* already hold. A chat `modelClass` acts as a ceiling: only that
|
|
16
|
+
* band and the less-capable chat bands below it are eligible (see
|
|
17
|
+
* {@link classesAtOrBelow}), so a `chat-balanced` ask can fall to
|
|
18
|
+
* `chat-fast` but never escalate to `chat-thinking`.
|
|
19
|
+
* - {@link searchModels} is the I/O wrapper: hand it a
|
|
20
|
+
* `WorkspaceClient` and it lists `/serving-endpoints` (cached) then
|
|
21
|
+
* ranks in one step.
|
|
22
|
+
*
|
|
23
|
+
* Single-selection entry points (return one id + how it was reached):
|
|
24
|
+
*
|
|
25
|
+
* - {@link resolveModel} is the pure selector; it delegates to
|
|
26
|
+
* {@link rankModels} with `limit: 1` and adds the operator-pinned
|
|
27
|
+
* fallback / static-floor safety net.
|
|
28
|
+
* - {@link selectModel} is the I/O wrapper over {@link resolveModel}.
|
|
15
29
|
*/
|
|
16
|
-
import {
|
|
30
|
+
import { ModelClass, type ModelQuery, type RankedModel, type ServingEndpointSummary } from "@dbx-tools/model-shared";
|
|
17
31
|
import { type WorkspaceClientLike } from "./serving.js";
|
|
18
32
|
/** Caller intent passed to {@link resolveModel}. */
|
|
19
33
|
export interface ResolveModelInput {
|
|
20
34
|
/**
|
|
21
35
|
* Explicit model id / loose name (per-request override, agent /
|
|
22
|
-
* plugin default, or env var). When set it wins over `
|
|
23
|
-
* `fallbacks`.
|
|
36
|
+
* plugin default, or env var). When set it wins over `modelClass`
|
|
37
|
+
* and `fallbacks`.
|
|
24
38
|
*/
|
|
25
39
|
explicit?: string;
|
|
26
40
|
/**
|
|
@@ -33,15 +47,15 @@ export interface ResolveModelInput {
|
|
|
33
47
|
/** Fuse.js threshold forwarded to {@link resolveModelId}. */
|
|
34
48
|
threshold?: number;
|
|
35
49
|
/**
|
|
36
|
-
*
|
|
37
|
-
* live catalogue is classified by its Foundation Model API scores
|
|
38
|
-
* and the top available model in the
|
|
39
|
-
*
|
|
50
|
+
* Chat capability class to resolve when no `explicit` id is given.
|
|
51
|
+
* The live catalogue is classified by its Foundation Model API scores
|
|
52
|
+
* and the top available model in the class (and the chat bands below
|
|
53
|
+
* it) wins, falling back to the class's small static list.
|
|
40
54
|
*/
|
|
41
|
-
|
|
55
|
+
modelClass?: ModelClass;
|
|
42
56
|
/**
|
|
43
57
|
* Operator-supplied fallback ids tried *first* in the no-explicit,
|
|
44
|
-
* no-
|
|
58
|
+
* no-class path (e.g. a regulated workspace pinned to an approved
|
|
45
59
|
* subset), ahead of the auto-classified catalogue.
|
|
46
60
|
*/
|
|
47
61
|
fallbacks?: readonly string[];
|
|
@@ -49,13 +63,50 @@ export interface ResolveModelInput {
|
|
|
49
63
|
/** Outcome of {@link resolveModel}: the chosen id plus how it was reached. */
|
|
50
64
|
export interface ResolvedModelSelection {
|
|
51
65
|
modelId: string;
|
|
52
|
-
source: "explicit" | "fuzzy-match" | "
|
|
66
|
+
source: "explicit" | "fuzzy-match" | "class" | "fallback";
|
|
53
67
|
}
|
|
54
68
|
/** Intent + catalogue knobs passed to {@link selectModel}. */
|
|
55
69
|
export interface SelectModelInput extends ResolveModelInput {
|
|
56
70
|
/** TTL override for the cached `/serving-endpoints` listing, in ms. */
|
|
57
71
|
ttlMs?: number;
|
|
58
72
|
}
|
|
73
|
+
/** TTL override merged into a {@link ModelQuery} for {@link searchModels}. */
|
|
74
|
+
export interface SearchModelsInput extends ModelQuery {
|
|
75
|
+
/** TTL override for the cached `/serving-endpoints` listing, in ms. */
|
|
76
|
+
ttlMs?: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Rank the live catalogue against a {@link ModelQuery}, best-first.
|
|
80
|
+
*
|
|
81
|
+
* Candidates are the classified endpoints in the eligible classes:
|
|
82
|
+
* {@link classesAtOrBelow} the requested `modelClass`, or - when none is
|
|
83
|
+
* given - the chat bands only ({@link CHAT_CLASS_ORDER}), so a general
|
|
84
|
+
* ask never surfaces an embedding endpoint. Each class bucket is
|
|
85
|
+
* already best-first from {@link classifyEndpoints}. Ranking is **match
|
|
86
|
+
* then class**:
|
|
87
|
+
*
|
|
88
|
+
* 1. With a `search`, only endpoints matching it survive, ordered by
|
|
89
|
+
* match distance (bucketed via {@link matchBucket} so near-identical
|
|
90
|
+
* scores tie), then by class (more capable first), then by the stable
|
|
91
|
+
* within-class rank.
|
|
92
|
+
* 2. Without a `search`, the class-then-rank candidate order stands.
|
|
93
|
+
*
|
|
94
|
+
* A `limit` truncates the result. Returns `[]` when nothing is
|
|
95
|
+
* eligible or matches - callers layer their own fallback.
|
|
96
|
+
*/
|
|
97
|
+
export declare function rankModels(endpoints: readonly ServingEndpointSummary[], query?: ModelQuery): RankedModel[];
|
|
98
|
+
/**
|
|
99
|
+
* Rank a workspace's catalogue in one call: list its
|
|
100
|
+
* `/serving-endpoints` (cached) and run {@link rankModels} over the
|
|
101
|
+
* result. The list counterpart to {@link selectModel}, for a consumer
|
|
102
|
+
* that wants the full ranked set (a model picker, a CLI) rather than a
|
|
103
|
+
* single id. Catalogue fetches fail loud: network / auth errors
|
|
104
|
+
* propagate so the caller sees the real SDK message.
|
|
105
|
+
*
|
|
106
|
+
* @param host - Workspace host used as the cache key. Pass the value
|
|
107
|
+
* resolved from `client.config.getHost()`.
|
|
108
|
+
*/
|
|
109
|
+
export declare function searchModels(client: WorkspaceClientLike, host: string, input?: SearchModelsInput): Promise<RankedModel[]>;
|
|
59
110
|
/**
|
|
60
111
|
* Resolve a model id for a workspace in one call: list its
|
|
61
112
|
* `/serving-endpoints` (cached) and run {@link resolveModel} over the
|
|
@@ -74,15 +125,15 @@ export interface SelectModelInput extends ResolveModelInput {
|
|
|
74
125
|
*/
|
|
75
126
|
export declare function selectModel(client: WorkspaceClientLike, host: string, input?: SelectModelInput): Promise<ResolvedModelSelection>;
|
|
76
127
|
/**
|
|
77
|
-
* Resolve a model id from the live catalogue and caller intent
|
|
128
|
+
* Resolve a single model id from the live catalogue and caller intent,
|
|
129
|
+
* delegating the live selection to {@link rankModels} with `limit: 1`.
|
|
78
130
|
*
|
|
79
131
|
* 1. **Explicit ask**: with `fuzzy` off, returned verbatim; otherwise
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* the
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* the static floor, and return the first id actually present.
|
|
132
|
+
* fuzzy-ranked within the (optional) class ceiling and the best taken,
|
|
133
|
+
* falling back to the input verbatim when nothing matches.
|
|
134
|
+
* 2. **No explicit ask**: an operator-pinned `fallback` that exists in
|
|
135
|
+
* the live catalogue wins first; then the ranked live catalogue
|
|
136
|
+
* (class ceiling applied); then the static {@link FALLBACK_MODEL_IDS}
|
|
137
|
+
* floor when the catalogue yields nothing in range.
|
|
87
138
|
*/
|
|
88
139
|
export declare function resolveModel(endpoints: readonly ServingEndpointSummary[], input?: ResolveModelInput): ResolvedModelSelection;
|