Skip to content

feat(frontend): provider- and model-level Custom Headers UI - #1591

Open
0x0079 wants to merge 2 commits into
claude/provider-extension-fields-2nmxvhfrom
claude/provider-flags-frontend-2nmxvh
Open

0x0079 wants to merge 2 commits into
claude/provider-extension-fields-2nmxvhfrom
claude/provider-flags-frontend-2nmxvh

Conversation

@0x0079

@0x0079 0x0079 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stacked on #1590: the UI for provider- and model-level Custom Headers, which that PR exposes over the API. Registry-driven, reusing the HeadersEditor control shipped with the rule level in #1589 — no new control types, no per-flag branching, and no new fields on FlagSpec.

Key Changes

  • Provider level: ProviderPluginsBlock inside the edit dialog's Advanced accordion — a plugins card listing active flags with their concrete values (literal header names, not counts), opening the shared flag catalog dialog fed by GET /provider/flags/registry; same interaction as the rule Plugins card so both levels read as one mechanism.
  • Model level: hover trigger on ModelCard opening an anchored popover for that model's headers; overridden models carry an always-visible badge so overrides are discoverable while scanning the list.
  • Safe concurrent saves: the popover re-fetches the provider and rewrites the whole model_flags map, so editing one model never clobbers a sibling edited earlier in the session.
  • Plumbing: edit dialog seeds flags from the provider and submits them as a whole object; FlagCatalogDialog takes title/subtitle so the provider surface reuses it verbatim; MSW mock serves the provider registry.

Notes

  • CustomModelCard has no per-model entry yet; the backend matches custom model names the same way, so it can be added on demand.

@0x0079
0x0079 force-pushed the claude/provider-extension-fields-2nmxvh branch from fc87817 to 6833bcc Compare August 18, 2026 11:03
@0x0079
0x0079 force-pushed the claude/provider-flags-frontend-2nmxvh branch 3 times, most recently from 1e49af0 to dcedf9c Compare August 18, 2026 11:45
claude added 2 commits August 18, 2026 11:45
Backend half of the provider/model level (frontend follows in a separate
PR), completing the three-level Custom Headers control on top of the rule
level merged in #1589 and rebased onto the unified rule-flag path (#1592).

- ai.Provider gains Flags / ModelFlags, both typed ProviderFlags, so the
  service reads p.Flags.ExtraHeaders exactly the way it reads
  rule.Flags.ExtraHeaders. The package documents an admission rule to keep
  that struct narrow: only fields describing how to reach the upstream
  belong in ai; gateway product behaviour stays in rule flags.
- ProviderFlagRegistry is the same shape as RuleFlagRegistry — no scope or
  merge axis per spec, because merging is a property of the levels (model
  overrides provider), not of each flag.
- The supply side rides the client, not the request: wrapWithRuleFlags takes
  the model and resolves typ.SupplyExtraHeaders(provider, model) once per
  client — clients are already keyed by provider + model — so probe,
  model-list and vision-proxy paths get upstream headers too and dispatch
  needs no changes at all.
- Precedence provider < model < rule falls out of the transport write order
  (supply, then rule, then UA), so nothing merges all three levels and the
  rule-flag context key stays strictly the resolved RuleFlags — diagnostics
  never report provider config as a rule flag.
- Persistence: additive flags / model_flags columns (serializer:json, same
  pattern as credential and vmodel_detail), no migration script.
- api_key scope: Config.AddProvider/UpdateProvider reject on save, covering
  HTTP, CLI and import; wrapWithRuleFlags loads no supply headers for a
  non-api_key provider, and vendor chains mount nothing at all.
- Provider API exposes typed flags / model_flags with partial-update
  semantics (nil untouched, non-null replaces wholesale) plus
  GET /provider/flags/registry.
- The extra_headers e2e behavior case gains a three-level route.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KBYfVGevcaVk7PxCJRh69t
Frontend half of the provider/model level, on top of its backend PR.
Registry-driven throughout, reusing the rule-level HeadersEditor:

- ProviderPluginsBlock in the provider edit dialog Advanced accordion: a
  plugins card listing active provider-level flags with their concrete
  values, opening the shared flag catalog dialog scoped to provider specs
  from GET /provider/flags/registry — same interaction as the rule
  Plugins card so both levels share one mental model
- per-model overrides on ModelCard: hover trigger plus an anchored
  popover editing that model's headers, saved by re-fetching the provider
  and rewriting the whole model_flags map so concurrent edits to sibling
  models are not clobbered; overridden models carry an always-visible
  badge
- edit dialog seeds flags from the provider and submits them as a whole
  object; FlagCatalogDialog takes title/subtitle so the provider surface
  can reuse it; MSW mock serves the provider registry

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KBYfVGevcaVk7PxCJRh69t
@0x0079
0x0079 force-pushed the claude/provider-extension-fields-2nmxvh branch from d528aa8 to ea2bebf Compare August 18, 2026 11:46
@0x0079
0x0079 force-pushed the claude/provider-flags-frontend-2nmxvh branch from dcedf9c to 19af956 Compare August 18, 2026 11:46
@0x0079
0x0079 force-pushed the claude/provider-extension-fields-2nmxvh branch from cc12542 to 2534926 Compare August 24, 2026 07:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants