You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If you create an FMAPI-backed Unity Catalog model service in your own schema (e.g. my_catalog.anthropic.claude-opus-4-8), ucode can't see it. Both discovery paths exclude it. The UC model-services listing filters client-side to system.ai.*, and the AI Gateway /v1/models listing only returns databricks-claude-* ids. The gateway itself routes catalog-qualified model ids just fine, so the gap is purely in discovery and config.
The motivation is a governed catalog with schemas holding model services created via Catalog Explorer, either one schema per provider (<catalog>.anthropic, <catalog>.openai) or a single shared schema. That gives teams per-schema permissions, usage tracking, and policies instead of everyone sharing the system.ai namespace.
Reproduction
Against a workspace with model services in user schemas (verified 2026-07-22):
src/ucode/databricks.py:1097: _MODEL_SERVICE_REQUIRED_PREFIX = "system.ai." means _model_service_id returns None for every other schema, so list_model_services and discover_model_services never surface them.
src/ucode/databricks.py:1787 (discover_claude_models): the gateway /ai-gateway/anthropic/v1/models response doesn't include catalog-scoped services, and the function additionally filters to databricks-claude-<family>-*.
Relationship to existing PRs
Add --model launch flag for custom UC model services #224 adds a --model <catalog>.<schema>.<name> pin for a service you already know the name of, but it scopes the listing to parent=schemas/system.ai, so custom services still never show up in discovery or the model picker. This issue asks for the discovery half. Per-location parent= listing composes cleanly with Add --model launch flag for custom UC model services #224's scoping and avoids the 499-prone metastore-wide pagination.
Each location gets listed via parent=schemas/<catalog>.<schema>, and the discovered ids feed the existing family bucketing alongside the system.ai results: claude-<family>-* goes to the claude picker with ANTHROPIC_DEFAULT_*_MODEL set to the full UC name, gpt-* gets pinned verbatim for codex, and gemini-* plus the OSS families work the same way.
Design notes / known limitations
Naming contract. Substring bucketing means discovered services need to be named like the models they route to (claude-opus-*, gpt-5-*). Free-form names (claude_haiku, cheap-coder) won't bucket. Those should be reported as skipped at configure time rather than silently dropped. Worth noting: the singular GET (/model-services/<full_name>) exposes supported_api_types and the routing destination's underlying FMAPI model, so metadata-driven bucketing (per databricks: bucket UC model-services by supported_api_types #205) is a viable follow-up for arbitrary names.
Alias shadowing.ANTHROPIC_DEFAULT_OPUS_MODEL holds exactly one id. If a location and system.ai both contain the same model, precedence should be explicit (suggestion: opt-in location beats system.ai, later --location beats earlier) instead of the current reverse-string sort, which effectively picks alphabetically by catalog name.
[1m] suffix. Verified empirically: the suffix is a Claude Code client-side convention, not a gateway model id. The gateway returns 404 for system.ai.claude-opus-4-8[1m] (the exact value ucode writes to ANTHROPIC_DEFAULT_OPUS_MODEL today), so Claude Code must be stripping the suffix and sending the context-1m beta header, and the gateway accepts that header with a catalog-qualified id (HTTP 200 on <catalog>.<schema>.claude-opus-4-8 with anthropic-beta: context-1m-2025-08-07). The gap is in ucode itself: _maybe_add_1m_suffix's regex only matches system.ai. or databricks- prefixed ids, so custom ids never get the suffix and would silently lose 1M context. Fix is to match the family on the trailing name segment instead of the full id.
Traffic-split services. A service with multiple routing destinations (say an opus/sonnet split) has no single family. Those should stay pin-only via Add --model launch flag for custom UC model services #224's --model and never get family-aliased.
Dialect mismatch. A gpt-*-named service backed by a non-Responses destination fails at inference time instead of configure time. A cheap supported_api_types check on just the bucketed subset would catch this early.
Summary
If you create an FMAPI-backed Unity Catalog model service in your own schema (e.g.
my_catalog.anthropic.claude-opus-4-8), ucode can't see it. Both discovery paths exclude it. The UC model-services listing filters client-side tosystem.ai.*, and the AI Gateway/v1/modelslisting only returnsdatabricks-claude-*ids. The gateway itself routes catalog-qualified model ids just fine, so the gap is purely in discovery and config.The motivation is a governed catalog with schemas holding model services created via Catalog Explorer, either one schema per provider (
<catalog>.anthropic,<catalog>.openai) or a single shared schema. That gives teams per-schema permissions, usage tracking, and policies instead of everyone sharing thesystem.ainamespace.Reproduction
Against a workspace with model services in user schemas (verified 2026-07-22):
Meanwhile the same model id works through the gateway:
Root cause in the current code
src/ucode/databricks.py:1097:_MODEL_SERVICE_REQUIRED_PREFIX = "system.ai."means_model_service_idreturnsNonefor every other schema, solist_model_servicesanddiscover_model_servicesnever surface them.src/ucode/databricks.py:1787(discover_claude_models): the gateway/ai-gateway/anthropic/v1/modelsresponse doesn't include catalog-scoped services, and the function additionally filters todatabricks-claude-<family>-*.Relationship to existing PRs
--model <catalog>.<schema>.<name>pin for a service you already know the name of, but it scopes the listing toparent=schemas/system.ai, so custom services still never show up in discovery or the model picker. This issue asks for the discovery half. Per-locationparent=listing composes cleanly with Add --model launch flag for custom UC model services #224's scoping and avoids the 499-prone metastore-wide pagination.system.aiservices bysupported_api_types. The design notes below cover how custom-service discovery could later harden on the same metadata.Requested change
Opt-in discovery locations, mirroring the existing
configure mcp --location <catalog>.<schema>precedent:Each location gets listed via
parent=schemas/<catalog>.<schema>, and the discovered ids feed the existing family bucketing alongside thesystem.airesults:claude-<family>-*goes to the claude picker withANTHROPIC_DEFAULT_*_MODELset to the full UC name,gpt-*gets pinned verbatim for codex, andgemini-*plus the OSS families work the same way.Design notes / known limitations
claude-opus-*,gpt-5-*). Free-form names (claude_haiku,cheap-coder) won't bucket. Those should be reported as skipped at configure time rather than silently dropped. Worth noting: the singular GET (/model-services/<full_name>) exposessupported_api_typesand the routing destination's underlying FMAPI model, so metadata-driven bucketing (per databricks: bucket UC model-services by supported_api_types #205) is a viable follow-up for arbitrary names.ANTHROPIC_DEFAULT_OPUS_MODELholds exactly one id. If a location andsystem.aiboth contain the same model, precedence should be explicit (suggestion: opt-in location beatssystem.ai, later--locationbeats earlier) instead of the current reverse-string sort, which effectively picks alphabetically by catalog name.[1m]suffix. Verified empirically: the suffix is a Claude Code client-side convention, not a gateway model id. The gateway returns 404 forsystem.ai.claude-opus-4-8[1m](the exact value ucode writes toANTHROPIC_DEFAULT_OPUS_MODELtoday), so Claude Code must be stripping the suffix and sending thecontext-1mbeta header, and the gateway accepts that header with a catalog-qualified id (HTTP 200 on<catalog>.<schema>.claude-opus-4-8withanthropic-beta: context-1m-2025-08-07). The gap is in ucode itself:_maybe_add_1m_suffix's regex only matchessystem.ai.ordatabricks-prefixed ids, so custom ids never get the suffix and would silently lose 1M context. Fix is to match the family on the trailing name segment instead of the full id.--modeland never get family-aliased.gpt-*-named service backed by a non-Responses destination fails at inference time instead of configure time. A cheapsupported_api_typescheck on just the bucketed subset would catch this early.