mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Format Databricks model display names
Signed-off-by: kenny lopez <klopez4212@gmail.com>
This commit is contained in:
@@ -56,3 +56,21 @@ test("resolveAgentCardModelLabel — non-inherited agent with a blank resolved m
|
||||
});
|
||||
assert.equal(label, "Default model (claude-sonnet)");
|
||||
});
|
||||
|
||||
test("resolveAgentCardModelLabel — Databricks endpoint IDs render without the gateway prefix", () => {
|
||||
const label = resolveAgentCardModelLabel({
|
||||
agent: { modelSource: "definition", model: "databricks-claude-opus-4-7" },
|
||||
personaModel: null,
|
||||
defaultModel: "databricks-gpt-5-5",
|
||||
});
|
||||
assert.equal(label, "Claude Opus 4.7");
|
||||
});
|
||||
|
||||
test("resolveAgentCardModelLabel — inherited Databricks models render a clean name", () => {
|
||||
const label = resolveAgentCardModelLabel({
|
||||
agent: undefined,
|
||||
personaModel: null,
|
||||
defaultModel: "databricks-gpt-5-5",
|
||||
});
|
||||
assert.equal(label, "Default model (GPT-5.5)");
|
||||
});
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { formatAgentModelLabel } from "./formatAgentModelLabel";
|
||||
import {
|
||||
formatAgentModelLabel,
|
||||
formatModelDisplayName,
|
||||
} from "./formatAgentModelLabel";
|
||||
import type { ManagedAgent } from "@/shared/api/types";
|
||||
|
||||
/**
|
||||
@@ -39,6 +42,6 @@ export function resolveAgentCardModelLabel(input: {
|
||||
}
|
||||
|
||||
export function formatDefaultModelLabel(defaultModel: string) {
|
||||
const model = defaultModel.trim();
|
||||
const model = formatModelDisplayName(defaultModel);
|
||||
return model ? `Default model (${model})` : "Default model";
|
||||
}
|
||||
|
||||
@@ -1,8 +1,65 @@
|
||||
const DATABRICKS_PREFIX = "databricks-";
|
||||
|
||||
const MODEL_WORD_LABELS: Readonly<Record<string, string>> = {
|
||||
bge: "BGE",
|
||||
claude: "Claude",
|
||||
en: "EN",
|
||||
glm: "GLM",
|
||||
gpt: "GPT",
|
||||
gte: "GTE",
|
||||
llama: "Llama",
|
||||
meta: "Meta",
|
||||
mlflow: "MLflow",
|
||||
openai: "OpenAI",
|
||||
};
|
||||
|
||||
/**
|
||||
* Turns a Databricks gateway endpoint into its human-facing model name while
|
||||
* preserving the endpoint ID everywhere it is sent to the runtime.
|
||||
*
|
||||
* Examples:
|
||||
* - `databricks-claude-opus-4-7` → `Claude Opus 4.7`
|
||||
* - `databricks-gpt-5-5` → `GPT-5.5`
|
||||
*/
|
||||
export function formatModelDisplayName(model: string | null | undefined) {
|
||||
const trimmed = model?.trim();
|
||||
if (!trimmed) return "";
|
||||
|
||||
if (!trimmed.toLowerCase().startsWith(DATABRICKS_PREFIX)) {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
const parts = trimmed.slice(DATABRICKS_PREFIX.length).split("-");
|
||||
const labelParts: string[] = [];
|
||||
for (let index = 0; index < parts.length; index += 1) {
|
||||
const part = parts[index];
|
||||
const nextPart = parts[index + 1];
|
||||
|
||||
if (/^\d+$/.test(part) && nextPart && /^\d+$/.test(nextPart)) {
|
||||
labelParts.push(`${part}.${nextPart}`);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (/^\d+b$/i.test(part)) {
|
||||
labelParts.push(part.toUpperCase());
|
||||
continue;
|
||||
}
|
||||
|
||||
labelParts.push(
|
||||
MODEL_WORD_LABELS[part.toLowerCase()] ??
|
||||
`${part.slice(0, 1).toUpperCase()}${part.slice(1)}`,
|
||||
);
|
||||
}
|
||||
|
||||
const label = labelParts.join(" ");
|
||||
return label.replace(/^GPT (\d)/, "GPT-$1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable model label for an agent or persona, falling back to
|
||||
* "Auto" when no model is set (empty or whitespace-only).
|
||||
*/
|
||||
export function formatAgentModelLabel(model: string | null | undefined) {
|
||||
const trimmed = model?.trim();
|
||||
return trimmed && trimmed.length > 0 ? trimmed : "Auto";
|
||||
return formatModelDisplayName(model) || "Auto";
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import { cn } from "@/shared/lib/cn";
|
||||
import { Button } from "@/shared/ui/button";
|
||||
import { AgentConfigPanel } from "./AgentConfigPanel";
|
||||
import { friendlyAgentLastError } from "@/features/agents/lib/friendlyAgentLastError";
|
||||
import { formatModelDisplayName } from "@/features/agents/lib/formatAgentModelLabel";
|
||||
import { ManagedAgentLogPanel } from "./ManagedAgentLogPanel";
|
||||
import { PubKey } from "@/shared/ui/PubKey";
|
||||
import { SubsectionLabel } from "@/shared/ui/PageHeader";
|
||||
@@ -410,7 +411,9 @@ function RuntimeBlock({
|
||||
{runtimeSource || agent.model ? (
|
||||
<div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground">
|
||||
{runtimeSource ? <span>{runtimeSource}</span> : null}
|
||||
{agent.model ? <span>{agent.model}</span> : null}
|
||||
{agent.model ? (
|
||||
<span>{formatModelDisplayName(agent.model)}</span>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import type { AgentModelsResponse, ManagedAgent } from "@/shared/api/types";
|
||||
import { getAgentModels, updateManagedAgent } from "@/shared/api/tauri";
|
||||
import { switchManagedAgentModel } from "@/shared/api/agentControl";
|
||||
import { awaitLiveSwitchOutcome } from "@/features/agents/lib/liveSwitchOutcome";
|
||||
import { formatModelDisplayName } from "@/features/agents/lib/formatAgentModelLabel";
|
||||
import { subscribeControlResults } from "@/features/agents/observerRelayStore";
|
||||
import { useActiveAgentTurns } from "@/features/agents/activeAgentTurnsStore";
|
||||
import {
|
||||
@@ -83,9 +84,9 @@ export function ModelPicker({
|
||||
|
||||
const currentValue = agent.model ?? modelsData?.agentDefaultModel ?? "";
|
||||
const displayLabel =
|
||||
agent.model ??
|
||||
formatModelDisplayName(agent.model) ||
|
||||
(modelsData?.agentDefaultModel
|
||||
? `${modelsData.agentDefaultModel} (default)`
|
||||
? `${formatModelDisplayName(modelsData.agentDefaultModel)} (default)`
|
||||
: hasRequestedModels && loading
|
||||
? "Loading..."
|
||||
: "Auto");
|
||||
@@ -221,7 +222,9 @@ export function ModelPicker({
|
||||
<div className="px-3 py-2 text-sm text-muted-foreground">
|
||||
{agent.model ? (
|
||||
<>
|
||||
<p className="font-medium text-foreground">{agent.model}</p>
|
||||
<p className="font-medium text-foreground">
|
||||
{formatModelDisplayName(agent.model)}
|
||||
</p>
|
||||
<p className="mt-0.5 text-xs">
|
||||
This runtime does not support switching models.
|
||||
</p>
|
||||
@@ -237,7 +240,7 @@ export function ModelPicker({
|
||||
>
|
||||
{modelsData.models.map((model) => (
|
||||
<DropdownMenuRadioItem key={model.id} value={model.id}>
|
||||
{model.name ?? model.id}
|
||||
{formatModelDisplayName(model.name ?? model.id)}
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
|
||||
@@ -2,6 +2,7 @@ import type {
|
||||
AcpRuntimeCatalogEntry,
|
||||
GlobalAgentConfig,
|
||||
} from "@/shared/api/types";
|
||||
import { formatModelDisplayName } from "../lib/formatAgentModelLabel";
|
||||
import { BUZZ_AGENT_THINKING_EFFORT } from "./buzzAgentConfig";
|
||||
import type { RuntimeFileConfigSubset } from "@/shared/api/tauri";
|
||||
// Dialogs import getDefaultPersonaRuntime via this re-export; lib code imports
|
||||
@@ -335,7 +336,7 @@ export function getDefaultLlmProviderLabel(
|
||||
* Otherwise falls back to the generic `"Default model"` placeholder.
|
||||
*/
|
||||
export function getDefaultLlmModelLabel(globalModel?: string) {
|
||||
const trimmedGlobal = (globalModel ?? "").trim();
|
||||
const trimmedGlobal = formatModelDisplayName(globalModel);
|
||||
return trimmedGlobal
|
||||
? `Use agent defaults (${trimmedGlobal})`
|
||||
: "Default model";
|
||||
|
||||
@@ -61,6 +61,27 @@ test("default row shows the harness-reported current model when available", () =
|
||||
);
|
||||
});
|
||||
|
||||
test("Databricks endpoint IDs keep their value while using a clean display label", () => {
|
||||
const options = getDiscoveredPersonaModelOptions(
|
||||
response({
|
||||
agentDefaultModel: "databricks-gpt-5-5",
|
||||
models: [
|
||||
{
|
||||
id: "databricks-claude-opus-4-7",
|
||||
name: "databricks-claude-opus-4-7",
|
||||
description: null,
|
||||
},
|
||||
],
|
||||
}),
|
||||
"databricks_v2",
|
||||
);
|
||||
|
||||
assert.deepEqual(options, [
|
||||
{ id: "", label: "Default model (GPT-5.5)" },
|
||||
{ id: "databricks-claude-opus-4-7", label: "Claude Opus 4.7" },
|
||||
]);
|
||||
});
|
||||
|
||||
test("the 'default' id match is case-insensitive and trimmed", () => {
|
||||
const options = getDiscoveredPersonaModelOptions(
|
||||
response({
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
formatModelDiscoveryErrorStatus,
|
||||
type PersonaModelDiscoveryStatus,
|
||||
} from "./personaModelDiscoveryStatus";
|
||||
import { formatModelDisplayName } from "../lib/formatAgentModelLabel";
|
||||
import type { PersonaModelOption } from "./agentConfigOptions";
|
||||
import { providerRequiresExplicitModel } from "./agentConfigOptions";
|
||||
|
||||
@@ -64,7 +65,7 @@ export function getDiscoveredPersonaModelOptions(
|
||||
provider === "relay-mesh"
|
||||
? "Default (auto)"
|
||||
: agentDefaultModel
|
||||
? `Default model (${agentDefaultModel})`
|
||||
? `Default model (${formatModelDisplayName(agentDefaultModel)})`
|
||||
: "Default model",
|
||||
},
|
||||
];
|
||||
@@ -77,7 +78,7 @@ export function getDiscoveredPersonaModelOptions(
|
||||
...defaultModelOption,
|
||||
...explicitModels.map((model) => ({
|
||||
id: model.id,
|
||||
label: model.name?.trim() || model.id,
|
||||
label: formatModelDisplayName(model.name?.trim() || model.id),
|
||||
})),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import { useIsManagedAgent } from "@/features/agent-memory/hooks";
|
||||
import { useIdentityQuery } from "@/shared/api/hooks";
|
||||
import { useAgentWorking } from "@/features/agents/agentWorkingSignal";
|
||||
import { formatModelDisplayName } from "@/features/agents/lib/formatAgentModelLabel";
|
||||
import {
|
||||
formatOwnerLabel,
|
||||
ownsAuthorAgent,
|
||||
@@ -411,7 +412,9 @@ export function UserProfilePopover({
|
||||
<InfoBadge>{runtimeLabel(relayAgent.agentType)}</InfoBadge>
|
||||
) : null}
|
||||
{managedAgent?.model ? (
|
||||
<InfoBadge>{managedAgent.model}</InfoBadge>
|
||||
<InfoBadge>
|
||||
{formatModelDisplayName(managedAgent.model)}
|
||||
</InfoBadge>
|
||||
) : null}
|
||||
{managedAgent?.acpCommand ? (
|
||||
<InfoBadge>ACP: {managedAgent.acpCommand}</InfoBadge>
|
||||
|
||||
Reference in New Issue
Block a user