@dbx-tools/model 0.3.37 → 0.3.39

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/package.json CHANGED
@@ -13,22 +13,26 @@
13
13
  "dependencies": {
14
14
  "@databricks/appkit": "^0.43.0",
15
15
  "fuse.js": "^7.4.2",
16
- "@dbx-tools/shared-model": "0.3.37",
17
- "@dbx-tools/appkit": "0.3.37",
18
- "@dbx-tools/shared-core": "0.3.37"
16
+ "@dbx-tools/appkit": "0.3.39",
17
+ "@dbx-tools/shared-model": "0.3.39",
18
+ "@dbx-tools/shared-core": "0.3.39"
19
19
  },
20
20
  "main": "index.ts",
21
21
  "license": "UNLICENSED",
22
22
  "publishConfig": {
23
23
  "access": "public"
24
24
  },
25
- "version": "0.3.37",
25
+ "version": "0.3.39",
26
26
  "types": "index.ts",
27
27
  "type": "module",
28
28
  "exports": {
29
29
  ".": "./index.ts",
30
30
  "./package.json": "./package.json"
31
31
  },
32
+ "files": [
33
+ "index.ts",
34
+ "src"
35
+ ],
32
36
  "dbxToolsConfig": {
33
37
  "tags": [
34
38
  "node"
@@ -1,74 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { describe, it } from "node:test";
3
-
4
- import { model } from "@dbx-tools/shared-model";
5
-
6
- import {
7
- CHAT_CLASS_ORDER,
8
- classesAtOrBelow,
9
- isChatClass,
10
- MODEL_CLASS_ORDER,
11
- parseModelClass,
12
- } from "../src/classes";
13
-
14
- const { ModelClass } = model;
15
-
16
- describe("CHAT_CLASS_ORDER / MODEL_CLASS_ORDER", () => {
17
- it("orders chat bands most-capable first, embedding excluded from the ladder", () => {
18
- assert.deepEqual(CHAT_CLASS_ORDER, [
19
- ModelClass.ChatThinking,
20
- ModelClass.ChatBalanced,
21
- ModelClass.ChatFast,
22
- ]);
23
- assert.deepEqual(MODEL_CLASS_ORDER, [
24
- ModelClass.ChatThinking,
25
- ModelClass.ChatBalanced,
26
- ModelClass.ChatFast,
27
- ModelClass.Embedding,
28
- ]);
29
- });
30
- });
31
-
32
- describe("isChatClass", () => {
33
- it("is true for chat bands and false for embedding", () => {
34
- assert.equal(isChatClass(ModelClass.ChatThinking), true);
35
- assert.equal(isChatClass(ModelClass.ChatFast), true);
36
- assert.equal(isChatClass(ModelClass.Embedding), false);
37
- });
38
- });
39
-
40
- describe("classesAtOrBelow", () => {
41
- it("treats a chat band as a ceiling - the band and everything below it", () => {
42
- assert.deepEqual(classesAtOrBelow(ModelClass.ChatThinking), [
43
- ModelClass.ChatThinking,
44
- ModelClass.ChatBalanced,
45
- ModelClass.ChatFast,
46
- ]);
47
- assert.deepEqual(classesAtOrBelow(ModelClass.ChatBalanced), [
48
- ModelClass.ChatBalanced,
49
- ModelClass.ChatFast,
50
- ]);
51
- assert.deepEqual(classesAtOrBelow(ModelClass.ChatFast), [ModelClass.ChatFast]);
52
- });
53
-
54
- it("keeps embedding to itself - it is not a rung on the chat ladder", () => {
55
- assert.deepEqual(classesAtOrBelow(ModelClass.Embedding), [ModelClass.Embedding]);
56
- });
57
- });
58
-
59
- describe("parseModelClass", () => {
60
- it("accepts full slugs and rejects junk", () => {
61
- assert.equal(parseModelClass("chat-thinking"), ModelClass.ChatThinking);
62
- assert.equal(parseModelClass("chat-balanced"), ModelClass.ChatBalanced);
63
- assert.equal(parseModelClass("chat-fast"), ModelClass.ChatFast);
64
- assert.equal(parseModelClass("embedding"), ModelClass.Embedding);
65
- assert.equal(parseModelClass("medium"), null);
66
- assert.equal(parseModelClass(undefined), null);
67
- });
68
-
69
- it("resolves a bare chat band via the chat- prefix shorthand", () => {
70
- assert.equal(parseModelClass("thinking"), ModelClass.ChatThinking);
71
- assert.equal(parseModelClass("balanced"), ModelClass.ChatBalanced);
72
- assert.equal(parseModelClass("fast"), ModelClass.ChatFast);
73
- });
74
- });
@@ -1,169 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { describe, it } from "node:test";
3
-
4
- import { model, type ServingEndpointSummary } from "@dbx-tools/shared-model";
5
-
6
- import { FALLBACK_MODEL_IDS, modelsForClass } from "../src/fallback";
7
- import { rankModels, resolveModel } from "../src/resolve";
8
- import { resolveModelId, searchServingEndpoints } from "../src/serving";
9
-
10
- const { ModelClass } = model;
11
-
12
- const CHAT_TASK = "llm/v1/chat";
13
- const EMBEDDING_TASK = "llm/v1/embeddings";
14
-
15
- /**
16
- * Unscored chat endpoints classify deterministically by family name (opus ->
17
- * ChatThinking, sonnet -> ChatBalanced, haiku -> ChatFast), so class membership
18
- * in these tests doesn't depend on quality quantiles.
19
- */
20
- function chat(name: string): ServingEndpointSummary {
21
- return { name, task: CHAT_TASK };
22
- }
23
-
24
- /** An embedding endpoint - classified into ModelClass.Embedding by task. */
25
- function embedding(name: string): ServingEndpointSummary {
26
- return { name, task: EMBEDDING_TASK };
27
- }
28
-
29
- const OPUS_8 = "databricks-claude-opus-4-8";
30
- const OPUS_7 = "databricks-claude-opus-4-7";
31
- const OPUS_6 = "databricks-claude-opus-4-6";
32
- const SONNET = "databricks-claude-sonnet-4-6";
33
- const HAIKU_5 = "databricks-claude-haiku-4-5";
34
- const HAIKU_3 = "databricks-claude-haiku-4-3";
35
- const GTE = "databricks-gte-large-en";
36
- const BGE = "databricks-bge-large-en";
37
-
38
- /** opus (ChatThinking) / sonnet (ChatBalanced) / haiku (ChatFast) - one per band. */
39
- const TIERED = [chat(OPUS_8), chat(SONNET), chat(HAIKU_5)];
40
-
41
- function names(models: { endpoint: ServingEndpointSummary }[]): string[] {
42
- return models.map((m) => m.endpoint.name);
43
- }
44
-
45
- describe("searchServingEndpoints / resolveModelId", () => {
46
- const endpoints = [chat(OPUS_8), chat(SONNET), chat(HAIKU_5)];
47
-
48
- it("short-circuits an exact name to score 0", () => {
49
- const [best] = searchServingEndpoints(SONNET, endpoints);
50
- assert.equal(best?.endpoint.name, SONNET);
51
- assert.equal(best?.score, 0);
52
- });
53
-
54
- it("tokenized fuzzy-matches a loose name", () => {
55
- const result = resolveModelId("claude sonnet", endpoints);
56
- assert.equal(result.matched, true);
57
- assert.equal(result.modelId, SONNET);
58
- });
59
-
60
- it("returns the input verbatim when nothing matches", () => {
61
- const result = resolveModelId("zzz-no-such-model", endpoints);
62
- assert.equal(result.matched, false);
63
- assert.equal(result.modelId, "zzz-no-such-model");
64
- });
65
-
66
- it("returns [] for an empty catalogue", () => {
67
- assert.deepEqual(searchServingEndpoints("opus", []), []);
68
- });
69
- });
70
-
71
- describe("rankModels", () => {
72
- it("ranks a search match-then-class, version breaking the tie", () => {
73
- const ranked = rankModels([chat(OPUS_6), chat(OPUS_8), chat(OPUS_7)], {
74
- search: "opus",
75
- });
76
- assert.deepEqual(names(ranked), [OPUS_8, OPUS_7, OPUS_6]);
77
- });
78
-
79
- it("with no search, orders by class then within-class rank", () => {
80
- const ranked = rankModels(TIERED);
81
- assert.deepEqual(names(ranked), [OPUS_8, SONNET, HAIKU_5]);
82
- assert.deepEqual(
83
- ranked.map((m) => m.modelClass),
84
- [ModelClass.ChatThinking, ModelClass.ChatBalanced, ModelClass.ChatFast],
85
- );
86
- });
87
-
88
- it("excludes embeddings from the default (chat-only) ranking", () => {
89
- const ranked = rankModels([chat(OPUS_8), embedding(GTE), embedding(BGE)]);
90
- assert.deepEqual(names(ranked), [OPUS_8]);
91
- });
92
-
93
- it("ranks embeddings only when ModelClass.Embedding is requested", () => {
94
- const ranked = rankModels([chat(OPUS_8), embedding(GTE), embedding(BGE)], {
95
- modelClass: ModelClass.Embedding,
96
- });
97
- assert.deepEqual(names(ranked), [GTE, BGE]); // no chat model leaks in
98
- });
99
-
100
- it("treats a chat class as a ceiling: that band and below, never above", () => {
101
- const ranked = rankModels(TIERED, { modelClass: ModelClass.ChatBalanced });
102
- assert.deepEqual(names(ranked), [SONNET, HAIKU_5]); // no opus (ChatThinking)
103
- });
104
-
105
- it("degrades to a lower band when the requested band is empty", () => {
106
- // "medium" requested but only "small" exists -> the highest small is
107
- // returned, never a "large".
108
- const ranked = rankModels([chat(OPUS_8), chat(HAIKU_5), chat(HAIKU_3)], {
109
- modelClass: ModelClass.ChatBalanced,
110
- limit: 1,
111
- });
112
- assert.deepEqual(names(ranked), [HAIKU_5]);
113
- });
114
-
115
- it("scopes a search to the class ceiling", () => {
116
- const ranked = rankModels(TIERED, {
117
- search: "claude",
118
- modelClass: ModelClass.ChatFast,
119
- });
120
- assert.deepEqual(names(ranked), [HAIKU_5]); // opus / sonnet excluded by ceiling
121
- });
122
-
123
- it("applies a limit", () => {
124
- assert.equal(rankModels(TIERED, { limit: 2 }).length, 2);
125
- });
126
- });
127
-
128
- describe("resolveModel", () => {
129
- it("fuzzy-resolves an explicit name to the best ranked match (limit 1)", () => {
130
- const result = resolveModel([chat(OPUS_6), chat(OPUS_8), chat(OPUS_7)], {
131
- explicit: "opus",
132
- });
133
- assert.deepEqual(result, { modelId: OPUS_8, source: "fuzzy-match" });
134
- });
135
-
136
- it("returns an explicit name verbatim when fuzzy is off", () => {
137
- const result = resolveModel(TIERED, { explicit: "my-pinned-model", fuzzy: false });
138
- assert.deepEqual(result, { modelId: "my-pinned-model", source: "explicit" });
139
- });
140
-
141
- it("resolves a class ask to the top of that band and below", () => {
142
- const result = resolveModel(TIERED, { modelClass: ModelClass.ChatBalanced });
143
- assert.deepEqual(result, { modelId: SONNET, source: "class" });
144
- });
145
-
146
- it("never selects an embedding model for a general (chat) ask", () => {
147
- const result = resolveModel([embedding(GTE), chat(SONNET)]);
148
- assert.equal(result.modelId, SONNET);
149
- });
150
-
151
- it("lets an operator-pinned fallback present in the catalogue win", () => {
152
- const pinned = "databricks-approved-custom";
153
- const result = resolveModel([...TIERED, chat(pinned)], { fallbacks: [pinned] });
154
- assert.deepEqual(result, { modelId: pinned, source: "fallback" });
155
- });
156
-
157
- it("falls back to the class's static floor for an empty catalogue", () => {
158
- const result = resolveModel([], { modelClass: ModelClass.ChatBalanced });
159
- assert.deepEqual(result, {
160
- modelId: modelsForClass(ModelClass.ChatBalanced)[0]!,
161
- source: "class",
162
- });
163
- });
164
-
165
- it("falls back to the static floor with no intent and an empty catalogue", () => {
166
- const result = resolveModel([], {});
167
- assert.deepEqual(result, { modelId: FALLBACK_MODEL_IDS[0]!, source: "fallback" });
168
- });
169
- });
@@ -1,14 +0,0 @@
1
- // ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen".
2
- {
3
- "extends": "../tsconfig.json",
4
- "compilerOptions": {
5
- "noEmit": true,
6
- "rootDir": ".."
7
- },
8
- "include": [
9
- "**/*.ts"
10
- ],
11
- "exclude": [
12
- "node_modules"
13
- ]
14
- }
package/tsconfig.json DELETED
@@ -1,41 +0,0 @@
1
- // ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen".
2
- {
3
- "compilerOptions": {
4
- "rootDir": "src",
5
- "outDir": "lib",
6
- "alwaysStrict": true,
7
- "declaration": true,
8
- "esModuleInterop": true,
9
- "experimentalDecorators": true,
10
- "inlineSourceMap": true,
11
- "inlineSources": true,
12
- "lib": [
13
- "ES2022"
14
- ],
15
- "module": "ESNext",
16
- "noEmitOnError": false,
17
- "noFallthroughCasesInSwitch": true,
18
- "noImplicitAny": true,
19
- "noImplicitReturns": true,
20
- "noImplicitThis": true,
21
- "noUnusedLocals": true,
22
- "noUnusedParameters": true,
23
- "resolveJsonModule": true,
24
- "strict": true,
25
- "strictNullChecks": true,
26
- "strictPropertyInitialization": true,
27
- "stripInternal": true,
28
- "target": "ES2022",
29
- "types": [
30
- "node"
31
- ],
32
- "moduleResolution": "bundler",
33
- "skipLibCheck": true
34
- },
35
- "include": [
36
- "src/**/*.ts"
37
- ],
38
- "exclude": [
39
- "node_modules"
40
- ]
41
- }