Skip to content

feat(catalog): per-key model selectors and metadata field patches - #12

Open
wignerStan wants to merge 5 commits into
origin652:mainfrom
wignerStan:feature/model-catalog-policy
Open

wignerStan wants to merge 5 commits into
origin652:mainfrom
wignerStan:feature/model-catalog-policy

Conversation

@wignerStan

@wignerStan wignerStan commented Sep 5, 2026 •

Copy link
Copy Markdown

Motivation

Different API keys may need different visible /v1/models catalogs, including stable aliases, model-family allow/deny rules, and corrected advertised metadata. The key-policy plugin is the right place to define that per-key view.

This feature uses the model-list response-interceptor support proposed in the companion CLIProxyAPI pull request: router-for-me/CLIProxyAPI#5552

Changes

  • add reusable catalog_groups selected by downstream policy key ID
  • support include_models and exclude_models with exact IDs or one trailing * prefix wildcard
  • deep-merge a group-level model-catalog patch into every retained entry
  • support group-level and per-model top-level remove
  • retain exact models entries for cloning a real CPA source model, exposing an alias, and applying model-specific overrides
  • support both OpenAI-compatible data[] and Codex/Pi models[] catalog shapes
  • preserve allow_models_endpoint as the coarse access gate
  • fail closed for unmatched plugin keys or invalid catalog shapes
  • leave native CPA keys and other frontend-auth providers untouched

Example

catalog_groups:
  - name: team-coding
    keys: ["team-*", "dev"]

    include_models:
      - "gpt-5-*"
      - "claude-*"
    exclude_models:
      - "gpt-5-codex-*"

    # Deep model-catalog field patch; this is not an HTTP PATCH operation.
    patch:
      context_window: 262144
      max_context_window: 262144
      max_tokens: 32768
    remove:
      - upgrade

    models:
      - id: fast
        source: gemini-3.8-flash-high
        patch:
          max_tokens: 16384
          display_name: "Fast"

Semantics

  • selector matching is case-insensitive
  • only exact values and a single trailing * are accepted
  • exclusions from every catalog group matched by the key are combined and always win
  • bulk-selected entries retain CPA order and their original id / slug
  • group patches deep-merge nested objects
  • exact model entries inherit the group patch, then apply their own patch so the model-specific value wins
  • include_unlisted: true includes all source entries while still applying group patches, removals, and exclusions
  • absent source models are omitted rather than synthesized with guessed capabilities

Validation

The final tree was produced through Git blob/tree operations and a temporary self-removing action, then squashed to one commit. It passed:

  • go test ./...
  • go vet ./...
  • selector normalization and invalid wildcard tests
  • include/exclude precedence across matching groups
  • deep catalog field-patch and removal tests
  • model-specific override precedence
  • OpenAI and Codex/Pi identity-preservation tests

@wignerStan
wignerStan force-pushed the feature/model-catalog-policy branch from 6bdc7ac to 0d3b6d4 Compare September 8, 2026 13:04
@wignerStan wignerStan changed the title feat(catalog): add per-key model catalogs and metadata patches feat(catalog): per-key model selectors and metadata field patches Sep 8, 2026
@wignerStan
wignerStan marked this pull request as ready for review September 10, 2026 05:24
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