Skip to content

@dbx-tools/shared-model

Browser-safe model-selection contract and classifier.

Import this package when UI code, route handlers, tools, or tests need to validate model lookup requests, type ranked model responses, or classify serving endpoints without talking to Databricks. Live workspace listing and fuzzy resolution live in @dbx-tools/model.

Key features:

  • Shared ModelClass taxonomy for chat-thinking, chat-balanced, chat-fast, and embedding workloads.
  • Browser-safe zod schemas for lookup requests, endpoint summaries, ranked results, and profile metadata.
  • Endpoint classifier that groups serving endpoints by score profile and family naming conventions, plus classify.endpointCapabilities for chat / embedding / tool-calling capability flags.
  • Version/family parsing helpers for model catalogues and tests.
  • Human-readable endpoint display names via display.toModelDisplayName.
  • OpenAI wire contracts: chat message/tool-call types plus a Responses API translator, so a proxy, a route, and a UI all speak the same payload shapes.
  • Types that match the server selection API without depending on the Databricks SDK.
import { display } from "@dbx-tools/shared-model";
display.toModelDisplayName("databricks-claude-sonnet-4-6"); // "Claude Sonnet 4.6"
display.toModelDisplayName("system.ai.bge_large_en"); // "BGE Large En"
display.toModelDisplayName("x", "Claude 4.6 (Preview)"); // provided name wins

ServingEndpointSummary.displayName is the optional friendly label for the picker; name stays the invoke id. A Databricks-provided name (a display_name/displayName/name endpoint tag, or an external-model name — extracted in @dbx-tools/model’s serving.ts) wins; otherwise the pure helper strips leading vendor prefixes and title-cases via @dbx-tools/shared-core’s tokenizer. It flows through GET /models automatically, and the UI picker shows displayName ?? name.

import { model } from "@dbx-tools/shared-model";
const query = model.ModelQuerySchema.parse({
search: "claude sonnet",
modelClass: "chat-balanced",
requiresTools: true,
limit: 5,
});

Use model.ModelQuerySchema for route query/body validation and agent tool inputs. It keeps client model pickers and backend resolution endpoints on the same request shape.

import { model, type RankedModel } from "@dbx-tools/shared-model";
const ranked: RankedModel = model.RankedModelSchema.parse(response);

model.ServingEndpointSummarySchema describes the stable endpoint fields exposed to clients: endpoint name, task, state, optional profile scores, classified class, supportsTools, and embedding dimension. requiresTools: true filters search/ranking to endpoints that can complete both a function call and the subsequent function_call_output replay.

import { classify, model } from "@dbx-tools/shared-model";
const byClass = classify.classifyEndpoints(endpoints);
const fast = byClass[model.ModelClass.ChatFast];
const agentModels = endpoints.filter((endpoint) => classify.endpointCapabilities(endpoint).tools);

Databricks currently exposes no tool-capability attribute in the endpoint list or OpenAPI schema. supportsTools therefore uses a conservative, live-verified provider-family policy: GPT (except GPT-OSS), Claude, Qwen, GLM, and Llama. Gemini is excluded because its Open Responses tool-result replay requires a thought signature the wire does not currently accept; GPT-OSS rejects Responses passthrough. An explicit supportsTools stamp overrides the family fallback.

The classifier uses Foundation Model API quality/speed/cost scores when present and family-name heuristics when scores are missing. This is useful for client grouping, tests, and offline catalogue analysis.

const family = classify.classifyByFamily("databricks-claude-sonnet-4-6");
const version = classify.versionTuple("llama-3-1-70b");

Family parsing helps callers bucket custom lists or explain why an endpoint landed in a class before the live workspace scores are available.

const caps = classify.endpointCapabilities(endpoint);
if (caps.chat) offerInChatPicker(endpoint);

Capability comes from the Databricks task hint (llm/v1/chat / llm/v1/embeddings) with the classified class as the fallback for endpoints Databricks left untagged. Filter on this rather than comparing raw task strings, so every picker, CLI, and route agrees on what “chat-capable” means.

import { openaiResponses } from "@dbx-tools/shared-model";
const { chat, stream } = openaiResponses.responsesToChat(requestBody);
// ... POST `chat` to the endpoint's invocations URL ...
const response = openaiResponses.chatToResponse(completion, modelId);

Databricks serving endpoints speak Chat Completions; some clients (the Codex CLI, for one) speak only the Responses API. openaiResponses bridges the two in both directions, including a streaming translator (createResponsesStreamTranslator) that lifts chat.completion.chunk SSE into the Responses event stream, and readResponsesOutput for pulling the answer and its citations back out of a native Responses reply. Pure functions over plain JSON, so the same translation runs in a proxy, a server route, or a test.

import { openaiResponses } from "@dbx-tools/shared-model";
const body = openaiResponses.sanitizeOpenResponsesRequest(requestBody);

/open-responses (the cross-provider path used for Claude and Gemini) rejects content parts that its own previous turn produced: an output_text part replayed as input fails with Open Responses input content part type 'output_text' is not supported. sanitizeOpenResponsesRequest rewrites output_* parts back to their input_* form and drops extended-thinking parts before the body goes out.

The thinking-block types live in one exported constant, openaiResponses.REASONING_TYPES. Both wire sanitizers (this one and the Chat Completions sanitizer in @dbx-tools/appkit-mastra) must strip exactly the same set: Anthropic signs redacted_thinking blocks, so a replay in which one path mutates a block the other preserved is rejected outright. Import the constant rather than re-listing the types.

import { openaiChat } from "@dbx-tools/shared-model";
const dropped = openaiChat.stripUnsupportedChatFields(body); // mutates `body`

Databricks Model Serving validates the chat body strictly: one unrecognized top-level key fails the entire turn rather than being ignored. An OpenAI client that sends parallel_tool_calls gets back parallel_tool_calls: Extra inputs are not permitted and no completion at all.

stripUnsupportedChatFields deletes the known offenders in place and returns what it removed, so a caller can log the difference. Reach for it on any path that forwards a client body largely as-is; a translator that copies fields one-by-one (openaiResponses.responsesToChat) already can’t leak them. Pass extra names to cover a workspace that rejects something not yet in openaiChat.UNSUPPORTED_CHAT_FIELDS.

  • model - ModelClass, zod schemas, and inferred types for profiles, endpoint summaries, lookup requests, and ranked results.
  • classify - family parsing, version tuple parsing, endpoint classification, and capability flags.
  • display - human-readable endpoint labels.
  • openaiChat - Chat Completions message / tool-call types, chatContentToText, and stripUnsupportedChatFields.
  • openaiResponses - Responses API translation in both directions, plus sanitizeOpenResponsesRequest and the shared REASONING_TYPES constant.

Server-side selection, cache, and fuzzy endpoint matching are in @dbx-tools/model.