Skip to content

ai-config: add a displayName field to custom provider entries #73

Description

@sharon-wang

Positron is adding UI for multiple named custom providers (posit-dev/positron#12747), where the user types a name at creation time. That name becomes the providers.custom key, and the key is also the provider id, so the name can't be changed afterwards without re-keying everything filed under it.

build-catalog.ts mints the id straight from the entry key, and there's no separate label:

for (const [name, entry] of Object.entries(customEntries)) {
    const customId = mintCustomProviderId(name);
    ...
    catalog.push({ id: customId, clientKind: entry.type, ... });
}

customProviderVariantSchema is .strict(), so a user can't hand-author a display label either.

What that costs today, in both products:

  • Renaming means rewriting the providers.custom key, re-keying the credential record, re-registering the auth provider, and rewriting any persisted default-model selection that names the provider. Every one of those can half-succeed.
  • Posit Assistant deferred rename in posit-dev/assistant#2056 for exactly this reason: "Rename requires coordinated provider-ID, credential, and default-model/settings migration; v1 remains delete and re-add."
  • Positron has the same request open as Assistant: provide way to rename Custom Provider positron#14141, unscheduled. Naming-at-creation covers the complaint that prompted it, so without this field the answer there is also delete and re-add, and that's an acceptable answer rather than a blocked one.
  • An admin shipping a providers.custom entry through a default or enforced layer has to encode the label in the key, so the key has to double as human-facing copy.

With a separate displayName, rename becomes cosmetic: the key stays put, credentials and model selections never move, and the UI is a plain text field with no migration behind it.

Proposed change in ai-config

  • Add displayName: z.string().min(1).optional() to customProviderVariantSchema, as a sibling of type rather than a connection field, and to customProviderEntryFragmentSchema so a fragment can set it alone. Regenerate providers.schema.json through scripts/generate-schema.ts.
  • Add readonly displayName: string | undefined to ResolvedProvider, and set it in the custom-provider loop in build-catalog.ts. mintCustomProviderId(name) keeps minting the id from the key, so ids and credentials are untouched.
  • Resolve it through the existing layer precedence like any other entry field, so a default layer can suggest a label and an enforced layer can pin one.

Consumers then render displayName ?? id, and nothing changes when the field is absent.

Not asking for

  • Id rename or any migration machinery. The point of the field is to make that unnecessary.
  • displayName on built-in provider blocks. Both products hard-code those names.
  • Uniqueness validation. The entry key stays the identity; two entries sharing a label is a UI concern, not a schema one.

Related: posit-dev/positron#14141, which is unscheduled. Nothing in Positron is waiting on this, so treat it as a schema improvement to take or leave on its own merits rather than a blocker.

Metadata

Metadata

Assignees

No one assigned

    Labels

    positronaffects positron or will be worked on by Positron team (if added to Positron project board)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions