@dbx-tools/shared-model 0.1.23 → 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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/display.ts +72 -21
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.23"
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.23",
22
+ "version": "0.1.24",
23
23
  "types": "index.ts",
24
24
  "type": "module",
25
25
  "exports": {
package/src/display.ts CHANGED
@@ -19,41 +19,92 @@ import { string } from "@dbx-tools/shared-core";
19
19
  */
20
20
  const STRIP_LEADING_TOKENS = new Set(["databricks", "system", "dbx"]);
21
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
+
22
33
  /**
23
34
  * Derive a human-readable display name for a serving endpoint.
24
35
  *
25
36
  * When `provided` is a non-blank string (a Databricks display-name tag or
26
- * external-model name), it wins verbatim (trimmed). Otherwise `name` is
27
- * tokenized with the shared-core tokenizer (which title-cases and
28
- * special-cases "AI"), known leading vendor prefixes are dropped, and the
29
- * remaining tokens are joined with spaces. Falls back to the trimmed raw
30
- * `name` if stripping leaves nothing.
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.
31
44
  *
32
45
  * @example
33
- * toModelDisplayName("databricks-claude-sonnet-4-6") // "Claude Sonnet 4 6"
34
- * toModelDisplayName("system.ai.bge_large_en") // "Bge Large En"
35
- * toModelDisplayName("x", "GPT-5 (Preview)") // "GPT-5 (Preview)"
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
36
50
  */
37
51
  export function toModelDisplayName(name: string, provided?: string | null): string {
38
52
  const providedTrimmed = string.trimToNull(provided);
39
53
  if (providedTrimmed) return providedTrimmed;
40
54
 
41
- const tokens = [...string.tokenizeWithOptions({ capitalize: true }, name)];
42
- // Drop known vendor/namespace prefixes only while they lead the list, so
43
- // a model literally named after one of these words mid-string is kept.
55
+ const segments = name.split(SEGMENT_SPLIT).filter(Boolean);
56
+ // Drop known vendor/namespace prefixes only while they lead the list.
44
57
  let start = 0;
45
- while (start < tokens.length && STRIP_LEADING_TOKENS.has(tokens[start]!.toLowerCase())) {
46
- // `system` is followed by `ai` in the `system.ai.*` builtin namespace;
47
- // consume that `ai` too (but only right after `system`, never alone).
48
- if (
49
- tokens[start]!.toLowerCase() === "system" &&
50
- tokens[start + 1]?.toLowerCase() === "ai"
51
- ) {
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()) {
52
63
  start += 1;
53
64
  }
54
65
  start += 1;
55
66
  }
56
- const kept = tokens.slice(start);
57
- const label = (kept.length > 0 ? kept : tokens).join(" ");
58
- return label || name.trim();
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(" ");
59
110
  }