Repository navigation
V41: retrofit provider brand icons onto existing model-catalog nodes - #413
Conversation
Follow-up to the model-icon change: the live seeder now stamps a brand icon at create time, but existing catalog nodes are seeded ExcludeThisAndChildren so the importer never overwrites them — a deployed catalog keeps its old Sparkle/Key icons on upgrade. This one-time backfill patches the mesh_nodes.icon column for LanguageModel/ModelProvider nodes across every partition schema (catalog lives under Provider/Admin-Provider across versions; BYO nodes live in user schemas — iterating by node_type finds them all). Non-destructive + idempotent: only rows still on a generic icon (Sparkle/Key or the sparkle/key SVG defaults, or NULL) are touched, never an admin's custom icon; only when a brand resolves and differs. The brand CASE mirrors ModelProviderIcons as a frozen point-in-time snapshot (a migration must not depend on evolving live code). Verified against a throwaway Postgres: gateway-hosted Claude → Anthropic, unknown providers left untouched, admin custom icons preserved, second run = 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a one-time DB migration (V41) to backfill provider brand icons onto already-seeded LanguageModel and ModelProvider catalog nodes, ensuring upgraded deployments display the correct branded icons rather than legacy generic Sparkle/Key defaults.
Changes:
- Registers
V41_RetrofitModelCatalogIconsin the migration runner. - Implements V41 migration to iterate all partition schemas and update
mesh_nodes.icononly for rows still using generic icons (or NULL), using a session-local SQL resolver that mirrorsModelProviderIconstoken ordering.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| memex/aspire/Memex.Database.Migration/Program.cs | Adds V41 to the ordered migration list so it executes during upgrades. |
| memex/aspire/Memex.Database.Migration/Migrations/V41_RetrofitModelCatalogIcons.cs | Performs per-schema, idempotent backfill of mesh_nodes.icon for LanguageModel/ModelProvider rows still on generic icons, using a migration-local brand resolver. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Test Results (shard 4) 9 files ± 0 9 suites ±0 3m 6s ⏱️ -11s Results for commit dc834e4. ± Comparison against base commit 3454a24. This pull request removes 77 tests. |
Test Results 58 files ±0 58 suites ±0 23m 6s ⏱️ -25s Results for commit dc834e4. ± Comparison against base commit 3454a24. This pull request removes 77 and adds 83 tests. Note that renamed tests count towards both. |
Follow-up to #407 (provider brand icons). The live seeder now stamps a brand icon at create time, but existing catalog nodes are seeded
ExcludeThisAndChildren, so the importer never overwrites them — a deployed catalog keeps its old Sparkle/Key icons on upgrade. This one-time DB migration backfills them.What it does
V41_RetrofitModelCatalogIconspatches themesh_nodes.iconcolumn (a top-level column, notcontent) forLanguageModel/ModelProvidernodes, across every partition schema — the catalog has lived underProviderandAdmin/Provideracross versions, and users' bring-your-own provider/model nodes live in their own schemas, so iterating bynode_typefinds them all (also retrofits existing BYO nodes for free).The brand is resolved by a session-local SQL function that mirrors
ModelProviderIcons(model id first, then provider — so a Claude served through AzureFoundry/OpenRouter still gets the Anthropic mark). It's a deliberate point-in-time snapshot: a migration is a frozen artifact and must not depend on evolving live code.Safety
Sparkle/Key, thesparkle.svg/key.svgdefaults, or NULL) are touched — an admin's custom icon is never clobbered.V29_PinDocsForExistingUsers.Verification
Ran the exact SQL against a throwaway Postgres 16 with representative rows:
claude-3-5-sonnetunder providerAzureFoundry→anthropic.svg(model id wins over the gateway) ✓CustomCo) → left onSparkle/Key✓/static/storage/...) → not clobbered ✓sparkle.svgdefault → retrofitted ✓UPDATE 0(idempotent) ✓What's New
Skipped — the user-facing entry shipped with #407; this is the deployment mechanism for the same feature, not a new one.
🤖 Generated with Claude Code