feat(catalog): replace Databricks model-label tokenizer with models.dev registry lookup

The frontend heuristic in #3586 title-cased every word and converted adjacent
digit pairs to decimals for any string starting with 'databricks-'. This
invented false labels for custom workspace endpoints: 'databricks-team-2025-01'
→ 'Team 2025.01', 'databricks-finance-2025-01-30' → 'Finance 2025.01 30'.

Replace with a lookup-and-pass-through approach drawn from the same design
goose uses in production:

- Generator script (scripts/generate-databricks-model-names.py) fetches
  https://models.dev/api.json and emits a sorted Rust static slice of
  (id, name) pairs under crates/buzz-agent/src/databricks_model_names.rs.
  Refresh by rerunning the script and committing the diff.

- catalog.rs consults the table via databricks_model_name(id): known managed
  endpoints get curated names (e.g. 'databricks-gpt-5-5' → 'GPT-5.5'),
  unknown/custom endpoints return their raw ID unchanged. Applied to all
  ModelEntry construction paths: v1/v2 discovery, the empty-list fallback,
  and discovery_failure_fallback.

- Frontend: a matching TS registry (desktop/src/features/agents/lib/
  databricksModelNames.ts) covers persisted raw IDs on cards, rows, and
  popovers that render before discovery data is available. formatAgentModelLabel
  and formatDefaultModelLabel use the registry; no heuristic string mangling
  exists anywhere in the TS layer.

- AGENTS.md documents the three-tier label precedence: API/runtime name first,
  table-backed fallback second, raw ID last.

Supersedes #3586 (kennylopez-model-display-labels).

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This commit is contained in:
npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7
2026-07-29 15:03:47 -04:00
co-authored by Will Pfleger
parent 324bd6b464
commit 144ef4d9d0
12 changed files with 385 additions and 10 deletions
+72
View File
@@ -0,0 +1,72 @@
#!/usr/bin/env python3
"""Generate crates/buzz-agent/src/databricks_model_names.rs from models.dev.
Usage:
python3 scripts/generate-databricks-model-names.py \
> crates/buzz-agent/src/databricks_model_names.rs
Fetches https://models.dev/api.json, extracts providers.databricks.models (the
authoritative curated name registry used by goose and others), and emits a
static Rust slice of (id, display_name) pairs sorted by ID.
Re-run whenever Databricks ships a new managed endpoint and commit the diff.
"""
import json
import subprocess
import sys
URL = "https://models.dev/api.json"
def fetch(url: str) -> bytes:
# urllib blocks with HTTP 403 without a browser User-Agent; use curl when
# available so the script works in hermit environments where curl is pinned.
result = subprocess.run(
["curl", "-s", "-A", "Mozilla/5.0", url],
capture_output=True,
check=True,
)
return result.stdout
def rust_str(s: str) -> str:
"""Emit a Rust string literal with double quotes."""
escaped = s.replace("\\", "\\\\").replace('"', '\\"')
return f'"{escaped}"'
def main() -> None:
raw = fetch(URL)
data = json.loads(raw)
models: dict = data["databricks"]["models"]
entries = sorted(
(k, v["name"] if isinstance(v, dict) else k) for k, v in models.items()
)
lines = [
"// GENERATED by scripts/generate-databricks-model-names.py",
"// Source: https://models.dev/api.json -- providers.databricks.models",
"// Refresh: python3 scripts/generate-databricks-model-names.py \\",
"// > crates/buzz-agent/src/databricks_model_names.rs",
"//",
"// Do not hand-edit -- rerun the script to update.",
"",
"/// Curated display names for known Databricks AI Gateway endpoints.",
"///",
"/// Keys are endpoint IDs returned verbatim by the discovery APIs.",
"/// Values are human-readable display names sourced from models.dev.",
"///",
"/// Unknown endpoint IDs are displayed as their raw ID -- no guessing.",
"pub(crate) static DATABRICKS_MODEL_NAMES: &[(&str, &str)] = &[",
]
for id_, name in entries:
lines.append(f" ({rust_str(id_)}, {rust_str(name)}),")
lines += ["];", ""]
sys.stdout.write("\n".join(lines))
if __name__ == "__main__":
main()