Skip to content

feat(providers): custom icon URL for compatible providers#2166

Open
whale9820 wants to merge 1 commit into
decolua:masterfrom
whale9820:feat/custom-provider-icon
Open

feat(providers): custom icon URL for compatible providers#2166
whale9820 wants to merge 1 commit into
decolua:masterfrom
whale9820:feat/custom-provider-icon

Conversation

@whale9820

Copy link
Copy Markdown
Contributor

What

Lets users set their own icon for OpenAI/Anthropic-compatible (custom) providers via an optional Icon URL field in the Add and Edit modals. The image shows up in the provider card grid and the provider detail header, falling back to the existing text badge (OC/AC) if unset or if it fails to load.

/cc @decolua — quick note on why this is trivial to land: see "Why this is a 1-click add" below.

Why

Custom providers currently can only show a hardcoded OC/AC text badge, or a non-existent bundled asset (/providers/<id>.png → 404 → text fallback). There was no way to brand a self-hosted / custom endpoint. This adds the missing optional iconUrl field end-to-end.

Changes (8 files, +43/-4)

Data layericonUrl is stored in the provider node's existing JSON data blob, so no schema migration and it round-trips through backups automatically:

  • src/lib/db/repos/nodesRepo.jscreateProviderNode now persists iconUrl (was dropped by the hardcoded field list; updateProviderNode already spread extras).
  • POST /api/provider-nodes (route.js) — destructure + pass iconUrl through to all three node types (openai-compatible, anthropic-compatible, custom-embedding).
  • PUT /api/provider-nodes/[id] — pass iconUrl through in updates.

UI — one optional Input ("Icon URL") in each modal:

  • AddCompatibleModal.js — field + send on create.
  • EditCompatibleNodeModal.js — field + send on save.

Render — prefer iconUrl as the icon src:

  • providers/page.js — both card components + the custom-node mappings now carry iconUrl.
  • providers/[id]/page.js — header icon; uses ProviderIcon (plain <img>) for the remote case to avoid next/image remotePatterns config, keeps next/image for bundled assets.
  • shared/components/index.js — export the existing ProviderIcon (it already supported src + text fallback).

Why this is a 1-click add

The infrastructure already existed — ProviderIcon has supported a remote src with a text fallback since day one, and provider nodes are stored as a flexible JSON blob that already round-trips arbitrary fields through updateProviderNode. The only reason custom icons didn't work was a field whitelist: the API routes and createProviderNode explicitly enumerated {name, prefix, apiType, baseUrl} and silently dropped everything else, and the render sites hardcoded src={/providers/\${id}.png}. So this PR is almost entirely "stop dropping the field + add one text input + src={iconUrl || existing}" — no new abstractions, no DB migration, no image upload/storage, no config. The hardest decision (Next.js remote image config) is sidestepped by reusing the existing <img>-based ProviderIcon for remote URLs.

Verification

  • node --check passes on all 8 edited files.
  • No new dependencies.
  • Backward compatible: iconUrl is optional; unset nodes behave exactly as before (text badge fallback).

Out of scope (deliberately)

  • No image upload/storage (URL only) — keeps the PR dependency-free. Upload can be a follow-up if desired.
  • No next/image remotePatterns changes — remote icons go through ProviderIcon's plain <img>.

OpenAI/Anthropic-compatible (custom) providers could only ever show a
hardcoded text badge (OC/AC) or a non-existent bundled icon — there was
no way to set your own. This adds an optional 'Icon URL' field to the
Add and Edit modals; the image is shown in the provider card grid and
the provider detail header, falling back to the text badge if unset or
the image fails to load.

- New optional iconUrl field on provider nodes (stored in the existing
  JSON data blob, no schema migration)
- POST/PUT /api/provider-nodes pass iconUrl through (previously dropped
  by field whitelisting)
- nodesRepo.createProviderNode persists iconUrl
- AddCompatibleModal + EditCompatibleNodeModal: one Input field each
- providers list page + detail page: prefer iconUrl as the icon src
- ProviderIcon already supported a remote src + text fallback; exported
  it from the components barrel and reused it for the remote case to
  avoid next/image remotePatterns config
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.

1 participant