@dbx-tools/shared-model 0.1.22 → 0.1.24
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 +19 -0
- package/index.ts +1 -0
- package/package.json +2 -2
- package/src/display.ts +110 -0
- package/src/model.ts +6 -0
package/README.md
CHANGED
|
@@ -16,9 +16,28 @@ Key features:
|
|
|
16
16
|
- Endpoint classifier that groups serving endpoints by score profile and family
|
|
17
17
|
naming conventions.
|
|
18
18
|
- Version/family parsing helpers for model catalogues and tests.
|
|
19
|
+
- Human-readable endpoint display names via `display.toModelDisplayName`.
|
|
19
20
|
- Types that match the server selection API without depending on the Databricks
|
|
20
21
|
SDK.
|
|
21
22
|
|
|
23
|
+
## Human-Readable Display Names
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { display } from "@dbx-tools/shared-model";
|
|
27
|
+
|
|
28
|
+
display.toModelDisplayName("databricks-claude-sonnet-4-6"); // "Claude Sonnet 4 6"
|
|
29
|
+
display.toModelDisplayName("system.ai.bge_large_en"); // "Bge Large En"
|
|
30
|
+
display.toModelDisplayName("x", "Claude 4.6 (Preview)"); // provided name wins
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`ServingEndpointSummary.displayName` is the optional friendly label for the
|
|
34
|
+
picker; `name` stays the invoke id. A Databricks-provided name (a
|
|
35
|
+
`display_name`/`displayName`/`name` endpoint tag, or an external-model name —
|
|
36
|
+
extracted in [`@dbx-tools/model`](../../node/model)'s `serving.ts`) wins;
|
|
37
|
+
otherwise the pure helper strips leading vendor prefixes and title-cases via
|
|
38
|
+
`@dbx-tools/shared-core`'s tokenizer. It flows through `GET /models`
|
|
39
|
+
automatically, and the UI picker shows `displayName ?? name`.
|
|
40
|
+
|
|
22
41
|
## Validate A Model Lookup Request
|
|
23
42
|
|
|
24
43
|
```ts
|
package/index.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export * as classify from "./src/classify";
|
|
6
|
+
export * as display from "./src/display";
|
|
6
7
|
export * as model from "./src/model";
|
|
7
8
|
export type { FamilyClass } from "./src/classify";
|
|
8
9
|
export type { ModelProfile, ServingEndpointSummary, ModelQuery, RankedModel } from "./src/model";
|
package/package.json
CHANGED
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"zod": "^4.3.6",
|
|
15
|
-
"@dbx-tools/shared-core": "0.1.
|
|
15
|
+
"@dbx-tools/shared-core": "0.1.24"
|
|
16
16
|
},
|
|
17
17
|
"main": "index.ts",
|
|
18
18
|
"license": "UNLICENSED",
|
|
19
19
|
"publishConfig": {
|
|
20
20
|
"access": "public"
|
|
21
21
|
},
|
|
22
|
-
"version": "0.1.
|
|
22
|
+
"version": "0.1.24",
|
|
23
23
|
"types": "index.ts",
|
|
24
24
|
"type": "module",
|
|
25
25
|
"exports": {
|
package/src/display.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-readable model display names. Pure (no Node-only imports) so a
|
|
3
|
+
* browser client can label a `/models` response without server deps.
|
|
4
|
+
*
|
|
5
|
+
* The endpoint `name` is the invoke id (e.g. `databricks-claude-sonnet-4-6`);
|
|
6
|
+
* this derives a friendly label from it. Prefer a Databricks-provided name
|
|
7
|
+
* (a display-name tag or an external-model name) when the server has one -
|
|
8
|
+
* see `@dbx-tools/model`'s serving lister, which passes it as `provided`.
|
|
9
|
+
*/
|
|
10
|
+
import { string } from "@dbx-tools/shared-core";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Vendor / namespace prefixes stripped from a tokenized endpoint name
|
|
14
|
+
* before title-casing. Lowercased tokens; matched only as leading tokens
|
|
15
|
+
* so a legitimate mid-name token is never dropped. `ai` is stripped ONLY
|
|
16
|
+
* as the second half of the `system.ai.*` builtin namespace (handled
|
|
17
|
+
* below), never on its own - so a model literally named `...-ai-...`
|
|
18
|
+
* keeps its "AI" word via the tokenizer's built-in casing override.
|
|
19
|
+
*/
|
|
20
|
+
const STRIP_LEADING_TOKENS = new Set(["databricks", "system", "dbx"]);
|
|
21
|
+
|
|
22
|
+
/** `ai` is stripped only as the `system.ai.*` namespace half (after `system`). */
|
|
23
|
+
const NAMESPACE_SECOND_TOKENS: Record<string, string> = { system: "ai" };
|
|
24
|
+
|
|
25
|
+
/** Segment-internal tokens rendered fully uppercased (acronyms), not title-cased. */
|
|
26
|
+
const ACRONYMS = new Set(["gpt", "gte", "bge", "dbrx", "oss", "ai", "llm", "moe"]);
|
|
27
|
+
|
|
28
|
+
/** Parameter-count unit letters glued to a preceding number (`120b` -> `120B`). */
|
|
29
|
+
const SIZE_UNITS = new Set(["b", "m", "k"]);
|
|
30
|
+
|
|
31
|
+
const SEGMENT_SPLIT = /[-_.\s/]+/;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Derive a human-readable display name for a serving endpoint.
|
|
35
|
+
*
|
|
36
|
+
* When `provided` is a non-blank string (a Databricks display-name tag or
|
|
37
|
+
* external-model name), it wins verbatim (trimmed). Otherwise the endpoint
|
|
38
|
+
* `name` is humanized: leading vendor prefixes (`databricks`, the
|
|
39
|
+
* `system.ai` namespace, `dbx`) are dropped, then each `-`/`_`/`.`-separated
|
|
40
|
+
* segment is title-cased (acronyms like GPT/GTE/BGE uppercased, "AI" kept),
|
|
41
|
+
* runs of purely-numeric segments are joined into a dotted version
|
|
42
|
+
* (`...-4-6` -> "4.6"), and a size unit glued to its number (`120b` ->
|
|
43
|
+
* "120B"). Falls back to the trimmed raw `name` if stripping leaves nothing.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* toModelDisplayName("databricks-claude-sonnet-4-6") // "Claude Sonnet 4.6"
|
|
47
|
+
* toModelDisplayName("databricks-gpt-oss-120b") // "GPT OSS 120B"
|
|
48
|
+
* toModelDisplayName("system.ai.bge_large_en") // "BGE Large En"
|
|
49
|
+
* toModelDisplayName("x", "Claude 4.6 (Preview)") // provided wins
|
|
50
|
+
*/
|
|
51
|
+
export function toModelDisplayName(name: string, provided?: string | null): string {
|
|
52
|
+
const providedTrimmed = string.trimToNull(provided);
|
|
53
|
+
if (providedTrimmed) return providedTrimmed;
|
|
54
|
+
|
|
55
|
+
const segments = name.split(SEGMENT_SPLIT).filter(Boolean);
|
|
56
|
+
// Drop known vendor/namespace prefixes only while they lead the list.
|
|
57
|
+
let start = 0;
|
|
58
|
+
while (start < segments.length) {
|
|
59
|
+
const lower = segments[start]!.toLowerCase();
|
|
60
|
+
if (!STRIP_LEADING_TOKENS.has(lower)) break;
|
|
61
|
+
// Consume the namespace's second token too (e.g. the `ai` of `system.ai`).
|
|
62
|
+
if (NAMESPACE_SECOND_TOKENS[lower] === segments[start + 1]?.toLowerCase()) {
|
|
63
|
+
start += 1;
|
|
64
|
+
}
|
|
65
|
+
start += 1;
|
|
66
|
+
}
|
|
67
|
+
const kept = segments.slice(start);
|
|
68
|
+
const source = kept.length > 0 ? kept : segments;
|
|
69
|
+
|
|
70
|
+
const pieces: string[] = [];
|
|
71
|
+
let versionRun: string[] = [];
|
|
72
|
+
const flushVersion = () => {
|
|
73
|
+
if (versionRun.length > 0) {
|
|
74
|
+
pieces.push(versionRun.join("."));
|
|
75
|
+
versionRun = [];
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
for (const segment of source) {
|
|
79
|
+
if (/^\d+$/.test(segment)) {
|
|
80
|
+
versionRun.push(segment);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
flushVersion();
|
|
84
|
+
pieces.push(renderSegment(segment));
|
|
85
|
+
}
|
|
86
|
+
flushVersion();
|
|
87
|
+
|
|
88
|
+
return pieces.join(" ") || name.trim();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Title-case one name segment, uppercasing acronyms and gluing size units. */
|
|
92
|
+
function renderSegment(segment: string): string {
|
|
93
|
+
const tokens = [...string.tokenizeWithOptions({ capitalize: true }, segment)];
|
|
94
|
+
const out: string[] = [];
|
|
95
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
96
|
+
const token = tokens[i]!;
|
|
97
|
+
const lower = token.toLowerCase();
|
|
98
|
+
// Glue a size unit onto the preceding number: `120` + `b` -> `120B`.
|
|
99
|
+
if (
|
|
100
|
+
SIZE_UNITS.has(lower) &&
|
|
101
|
+
out.length > 0 &&
|
|
102
|
+
/^\d+$/.test(out[out.length - 1]!)
|
|
103
|
+
) {
|
|
104
|
+
out[out.length - 1] = `${out[out.length - 1]}${lower.toUpperCase()}`;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
out.push(ACRONYMS.has(lower) ? lower.toUpperCase() : token);
|
|
108
|
+
}
|
|
109
|
+
return out.join(" ");
|
|
110
|
+
}
|
package/src/model.ts
CHANGED
|
@@ -74,6 +74,12 @@ export const ServingEndpointSummarySchema = z.object({
|
|
|
74
74
|
.describe(
|
|
75
75
|
"Endpoint name as listed by the Model Serving REST API; the id used to invoke the model.",
|
|
76
76
|
),
|
|
77
|
+
displayName: z
|
|
78
|
+
.string()
|
|
79
|
+
.optional()
|
|
80
|
+
.describe(
|
|
81
|
+
"Human-readable label for the endpoint: a Databricks-provided name when present (a display-name tag or external-model name), else a title-cased rendering of `name` with vendor prefixes stripped. `name` remains the invoke id.",
|
|
82
|
+
),
|
|
77
83
|
task: z.string().optional().describe("Task hint, e.g. 'llm/v1/chat' or 'llm/v1/embeddings'."),
|
|
78
84
|
state: z.string().optional().describe("Deployment state, e.g. ready, updating, or failed."),
|
|
79
85
|
description: z.string().optional().describe("Free-form endpoint description; informational."),
|