Files
buzz/desktop
5e0efb0bb9 fix(desktop): disambiguate provider API key labels and annotate mint key (#4406)
Two different credentials were presented under the same name throughout
the app. The top-level credential field for non-Anthropic providers
(OpenAI, OpenAI-compatible, OpenRouter) was labeled "OpenAI API Key" via
a hardcoded binary ternary repeated in three dialogs. The card-minting
key (`OPENAI_API_KEY`) and the runtime credential
(`OPENAI_COMPAT_API_KEY`) have independent endpoint namespaces and
consumers (`OPENAI_COMPAT_BASE_URL`/`OPENAI_COMPAT_API_KEY` for runtime,
`OPENAI_BASE_URL`/`OPENAI_API_KEY` for minting) and must remain separate
— either may require a different credential. This PR makes them
impossible to confuse in the UI.

## Changes

**Provider-accurate labels from the credential table.**
`PROVIDER_CREDENTIAL_CONFIG` entries now carry an `apiKeyLabel` paired
with `secretEnvVar` as a discriminated union (both present or neither —
a future provider cannot ship a secret field with no label).
`getProviderApiKeyLabel(providerId)` is the single source of truth. The
three hardcoded ternaries in `AgentConfigFields`,
`AgentInstanceEditDialog`, and `AgentDefinitionDialog` are replaced by
this helper. Labels: `openai` → "OpenAI Runtime API Key",
`openai-compat` → "OpenAI-compatible Runtime API Key", `openrouter` →
"OpenRouter API Key" (was incorrectly "OpenAI API Key"), `anthropic` →
"Anthropic API Key" (unchanged).

**Field names its backing env var.** `PersonaProviderApiKeyField`
renders the env var name as a monospace hint beneath the label with
`aria-describedby` wiring. All three call sites pass their
`secretEnvVar`. A user who sees `OPENAI_API_KEY` in the mint dialog can
now confirm at a glance that the credential field shows
`OPENAI_COMPAT_API_KEY` — a different key.

**Signpost visible at the decision point.** `CARD_MINT_KEY_ANNOTATIONS`
is exported from `agentConfigOptions.tsx` (single source) and passed as
`keyAnnotations` to all three generic env editors: both `EnvVarsEditor`
branches in Agent Defaults, `EditAgentAdvancedFields`, and
`PersonaAdvancedFields`. `CardMintKeyCue` — a new small component —
renders an always-visible muted cue beneath the Advanced toggle when
`OPENAI_API_KEY` is present in global env (Advanced is collapsed by
default, so the per-row annotation is invisible until the cue guides the
user to open it).

**Model discovery error copy.** The `OPENAI_COMPAT_API_KEY required`
message now reads "Enter an OpenAI runtime API key
(OPENAI_COMPAT_API_KEY) to load OpenAI models." — naming the env var
explicitly so it cannot be confused with the mint key.

## Tests

- `getProviderApiKeyLabel` helper: pinned correct label per provider
including the new distinct labels for `openai` and `openai-compat`
- `PersonaProviderApiKeyField` render: semantic label present; env-var
hint rendered when `envVarName` provided; `aria-describedby` wired to
hint id; hint and describedby absent when prop omitted
- `EnvVarsEditor` render: annotation appears exactly once on the
matching row; absent for non-matching rows
- `personaModelDiscoveryStatus`: pinned new copy naming
`OPENAI_COMPAT_API_KEY` explicitly
- Playwright: stale `"OpenAI API Key"` selectors updated; new
`card-mint-key-cue-visible-and-annotation-in-advanced` test covers
Will's exact path (databricks_v2 global provider + saved
`OPENAI_API_KEY` → cue visible before opening Advanced → annotation
present after opening)

## File sizes (post-format)

| File | Lines |
|------|-------|
| `AgentConfigFields.tsx` | 994 (≤ 996) |
| `AgentInstanceEditDialog.tsx` | 1228 (≤ 1228) |
| `AgentDefinitionDialog.tsx` | 1045 (≤ 1047) |

Related: [#4140](https://github.com/block/buzz/pull/4140)

---------

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1ng3jzsaqxdhrfq22dg85j3lpr0zsh3jp7g2h9jyxl59wraayapnsu6kvfg <9a232143a0336e34814a6a0f4947e11bc50bc641f21572c886fd0ae1f7a4e867@buzz.block.builderlab.xyz>
2026-08-03 11:12:34 -04:00
..
2026-06-11 15:06:24 +00:00

Buzz

Desktop chat shell with:

  • Tauri + React + TypeScript + Vite
  • Tailwind CSS
  • shadcn/ui-ready shared components
  • Biome (lint/format/check)
  • Feature-driven frontend structure

Scripts

  • pnpm dev - run the web frontend
  • pnpm tauri dev - run the desktop app
  • pnpm build - typecheck and build frontend
  • pnpm typecheck - TypeScript checks
  • pnpm lint - Biome lint
  • pnpm format - Biome format (write)
  • pnpm check - Biome check

Structure

  • src/shared - reusable app-wide code (ui, lib, styles)
  • src/features - feature modules (vertical slices)
  • src/app - top-level app composition