Skip to content

feat: add modelNameTemplate for discovered model display names - #55

Merged
yuseferi merged 4 commits into
mainfrom
feat/model-name-template
Nov 3, 2026
Merged

yuseferi merged 4 commits into
mainfrom
feat/model-name-template

Conversation

@yuseferi

@yuseferi yuseferi commented Nov 2, 2026 •

Copy link
Copy Markdown
Owner

Closes #52.

Adds an optional modelNameTemplate setting per provider. Every discovered model's display name is built from it, so two providers backed by the same proxy and different keys stop showing identical entries in the picker.

"litellm-team-a": {
  "name": "Team A",
  "settings": { "modelNameTemplate": "{name} ({provider_name})" }
}

Behaviour

  • Placeholders: {name} (today's formatted name, or the raw id with formatModelNames: false), {id}, {provider_id}, {provider_name}.
  • Default is "{name}", so behaviour is unchanged. It also normalizes to "unset", so existing cache keys stay warm instead of rediscovering on upgrade.
  • An explicit models.<id>.name still wins and is never templated.
  • Unknown placeholders are left as literal text; empty, whitespace-only and non-string values are ignored.
  • Substitution is single-pass, so a value that itself contains {id} is inserted literally rather than expanded again.
  • {provider_name} is the provider's configured name, or its id when none is set.
  • On OpenCode 1, Responses models are served by a <provider>-responses sibling, so {provider_id}/{provider_name} resolve to that sibling for those models (the sibling's generated label is <base name or id> Responses). The cached entries stay as discovered, because OpenCode 2 reads the same cache with a single provider.
  • Part of the cache identity alongside formatModelNames: the template and the resolved provider name go into the fingerprint, so a template change or a provider rename triggers a fresh discovery instead of serving stale names. Without a template the key is byte-identical to today's.
  • Works on OpenCode 2 and OpenCode 1, including background refresh.

Implementation

  • applyModelNameTemplate / ModelNaming in src/utils/format-model-name.ts; readModelNameTemplate next to readFormatModelNames.
  • Applied once in toConfigModel; the Responses sibling re-renders its own names at injection time without mutating the cache.
  • Naming threaded through discoverModels, refreshContexts and the v2 ProviderSource.
  • buildCacheKey takes ModelNaming and appends the template + resolved provider name to the fingerprint only when a template is set.
  • runtimeSettings strips the plugin-level modelNameTemplate option, so a plugin option never lands in the host's provider settings. A template already present in provider.settings is preserved — it is the host's own config and later reconciles re-derive the naming and cache key from it.

Tests

  • test/to-config-model.test.ts: every placeholder, raw-id composition, unknown placeholders, single-pass substitution, provider-name fallback, empty template, reader normalization.
  • test/model-cache.test.ts: key changes on template or provider rename, and stays plain when no template is set.
  • test/plugin-v1.test.ts: templated injection, curated names preserved, cache keyed by the template, sibling placeholders for named and unnamed bases.
  • test/plugin-v2.test.ts: templated model registration from provider.settings, curated name preserved, setting preserved, plugin-level option kept out of info.settings, {provider_name} id fallback, cache keyed by the template.

npm run typecheck clean; npm test 186/186.

Summary by CodeRabbit

  • New Features
    • Customize discovered model display names with templates using {name}, {id}, {provider_id}, and {provider_name}. Templates are applied after existing name formatting; explicitly configured model names remain unchanged.
    • Unknown placeholders are left as written, and substitutions are applied once. For Responses API models in OpenCode 1, provider placeholders use the Responses sibling’s identity.
  • Bug Fixes
    • Model lists now reflect discovery changes while preserving customized entries. Naming settings are included in cache identity to prevent stale names from being reused.
  • Documentation
    • Added guidance on template placeholders, default behavior, provider-name fallback, and interaction with existing name formatting. Empty or non-string template settings are ignored.

@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Caution

Review failed

The pull request is closed.

No actionable comments were generated in the recent review.

Walkthrough

The change adds modelNameTemplate for discovered model names in both plugin versions. Templates support model and provider placeholders. Naming settings pass through discovery and refresh, affect cache identity, and apply to Responses models. The v2 plugin also tracks published model snapshots during provider replacement.

Changes: Discovered Model Name Templates

Layer / File(s) Summary
Template definition and model conversion
src/utils/format-model-name.ts, src/plugin/index.ts, test/to-config-model.test.ts
Adds shared naming options and placeholder substitution for discovered model names. Tests cover supported and unknown placeholders, single-pass substitution, formatting options, and invalid template values.
Provider discovery and cache identity
src/plugin/index.ts, src/utils/model-cache.ts, test/plugin-v1.test.ts, test/model-cache.test.ts, test/auth-v1.test.ts, README.md, CHANGELOG.md
Both plugin versions pass naming settings through discovery and refresh. Responses models use the sibling provider's identity for template values. Cache keys include configured templates and provider names. Tests and documentation cover these behaviors.
Provider replacement and model provenance
src/plugin/v2.ts, test/plugin-v2.test.ts
Provider sources retain snapshots of published models and snapshots inherited during replacement. Merging compares live entries with those snapshots to determine whether entries are replaced, removed, or preserved.

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant ConfigHook
  participant buildCacheKey
  participant discoverModels
  participant toConfigModel
  ConfigHook->>buildCacheKey: naming settings
  ConfigHook->>discoverModels: naming settings
  discoverModels->>toConfigModel: model and provider values
Loading

Possibly related PRs

Suggested reviewers: alexanderwillner, mkowalski

Merge Risk: Moderate · up to b4e8f

A transient discovery failure during provider takeover can leave the provider without models until refresh succeeds. Preserve the last-good inventory and replacement provenance before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 78.95% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: adding the modelNameTemplate feature for discovered model display names.
Linked Issues check Passed Issue #52 is the only active direct target. The change adds provider-level modelNameTemplate handling and applies it after formatted or raw model naming. applyModelNameTemplate supports {name}, …
Out of Scope Changes check Passed The changes stay within Issue #52. The OpenCode 1 Responses-sibling handling, background-refresh threading, cache updates, documentation, and tests support provider-specific discovered names. The Open…
Full details: Linked Issues check

Explanation

Issue #52 is the only active direct target. The change adds provider-level modelNameTemplate handling and applies it after formatted or raw model naming. applyModelNameTemplate supports {name}, {id}, {provider_id}, and {provider_name}, performs single-pass replacement, preserves unknown placeholders, and ignores invalid or blank settings. Explicit curated names remain unchanged. The provider name falls back to the provider ID. Cache identity includes the template and resolved provider name when a template is set, while the default remains compatible with existing keys. OpenCode 1, OpenCode 2, discovery, refresh, and source replacement paths carry the naming data. Tests cover the required naming, cache, override, fallback, and refresh behavior.

Full details: Out of Scope Changes check

Explanation

The changes stay within Issue #52. The OpenCode 1 Responses-sibling handling, background-refresh threading, cache updates, documentation, and tests support provider-specific discovered names. The OpenCode 2 provenance and replacement logic re-renders stale generated names when a provider source changes and preserves curated entries during that update. No unrelated change is established.

Full details: Docstring Coverage

Explanation

Docstring coverage is 78.95% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 19 functions across 8 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9b764a77-26de-414f-b1e4-ddbe05cb2bbc
Commits

Reviewing files that changed from the base of the PR and between 52687d0 and 1ca824d.

Files selected for processing: 2
  • src/plugin/v2.ts
  • test/plugin-v2.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread src/plugin/index.ts Resolved
Comment thread src/plugin/v2.ts Resolved
Comment thread src/plugin/v2.ts Resolved

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread src/plugin/v2.ts Resolved
Adds a per-provider template that wraps every discovered model's display
name with that provider's context, so several providers backed by the
same LiteLLM proxy stay distinguishable in the picker.

Placeholders are {name}, {id}, {provider_id} and {provider_name}. The
default is "{name}", normalized to "unset" so existing cache keys stay
warm. An explicit models.<id>.name still wins and is never templated.

The template is applied once in toConfigModel, so the chat provider and
the Responses sibling inherit it, and it is threaded through cold
discovery, background refresh and the OpenCode 2 provider source. The
template and the resolved provider name are part of the cache identity,
so changing either starts a fresh discovery instead of serving stale
names.

Closes #52
- Re-render Responses-sibling names on OpenCode 1 so `{provider_id}` and
  `{provider_name}` resolve to the provider the model is selected through,
  without mutating the cached discovery entries OpenCode 2 shares.
- Derive the sibling's generated label from the base provider's name, or
  its id when unnamed, so its label and `{provider_name}` agree.
- Use the provider id as the `{provider_name}` fallback when no name is
  configured, instead of the shared `LiteLLM (proxy)` label.
- Keep the host's own `modelNameTemplate` setting intact (later
  reconciles re-derive naming from it); plugin-level options still never
  reach provider settings.
- Widen `formatModelName` to `Pick<LiteLLMModel, 'id'>` and share one
  base-name helper between discovery and the sibling rename.
- Tests for the sibling placeholders (named and unnamed base), the v2
  provider-settings path, and the plugin-option stripping path.
Rebase of the SSO credential keying (main) onto the sibling placeholder
resolution (#55) crossed exactly here: a sign-in's Responses sibling must
both re-render its models with the sibling's own provider identity and
keep the sign-in runtime fetch with the placeholder key its runtime
package insists on. Extends the existing auth-v1 sibling test to hold
both behaviors at once, so neither side of the merge can regress alone.
@yuseferi
yuseferi force-pushed the feat/model-name-template branch from 1ca824d to b4e8f0f Compare November 3, 2026 09:17
@yuseferi
yuseferi merged commit fbac09e into main Nov 3, 2026
5 of 6 checks passed
github-actions Bot pushed a commit that referenced this pull request Nov 3, 2026
# [1.10.0](v1.9.0...v1.10.0) (2026-11-03)

### Features

* add modelNameTemplate for discovered model display names ([#55](#55)) ([fbac09e](fbac09e)), closes [#52](#52)
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.

Feature: modelNameTemplate setting for discovered model display names

1 participant