modelregistry

package
v0.16.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClaudeCapabilitiesProjection

func ClaudeCapabilitiesProjection(snap Snapshot, timestamp int64) claudeCapabilitiesCache

ClaudeCapabilitiesProjection builds the model-capabilities payload from the snapshot, using the given Unix timestamp. Only Anthropic entries are included. The models slice is ordered longest-ID-first, with ties broken lexicographically.

func ClaudeCodeOptionsNeedPublish

func ClaudeCodeOptionsNeedPublish(fsys fsutil.FileSystem, path string, snap Snapshot) (bool, error)

func ClaudeCodeOptionsProjection

func ClaudeCodeOptionsProjection(snap Snapshot) []modelOption

ClaudeCodeOptionsProjection returns the ModelOption entries cq injects for Claude Code's /model picker: Codex models plus Anthropic overlays. Native Anthropic models are already hard-coded by Claude Code itself.

func CodexModelsResponse

func CodexModelsResponse(snap Snapshot) codexModelsResponseOut

CodexModelsResponse builds the models response payload from the snapshot. Only Codex entries are included.

For native entries with raw JSON in CodexRawByID, the raw bytes are used verbatim (round-trip guarantee).

For overlay/non-native entries:

  • If CloneFrom refers to a native entry with raw JSON, the raw bytes are cloned and slug/display_name are overridden.
  • Otherwise a fallback synthetic object is built from the Entry fields.

func DiscoverCodexClientVersion

func DiscoverCodexClientVersion(fsys fsutil.FileSystem, path string) string

DiscoverCodexClientVersion returns the client_version recorded in an existing models_cache.json envelope at path. Returns an empty string when the file is missing, unreadable, malformed, or has no client_version set. Callers should supply their own fallback for that case.

func OverlayPath

func OverlayPath(env func(string) string, homeDir string) string

OverlayPath returns the path to the user overlay file. env is used to look up environment variables; homeDir is the fallback home directory. Resolves to $XDG_CONFIG_HOME/cq/models.json, else $homeDir/.config/cq/models.json.

func PruneOverlays

func PruneOverlays(overlays OverlayFile, natives []Entry) (OverlayFile, []Entry)

PruneOverlays removes overlay entries whose (provider, id) pair exists in natives. It returns the pruned OverlayFile (same version, only non-conflicting entries) and a slice of the removed entries.

func PublishClaudeCapabilities

func PublishClaudeCapabilities(fsys fsutil.FileSystem, path string, snap Snapshot, now time.Time) error

PublishClaudeCapabilities writes the model-capabilities cache to path using an atomic tmp+rename write. Parent directories are created with 0o700; the file is written with 0o600.

The existing cache is not read — the snapshot is the sole source of truth. Any previous string-formatted timestamp is replaced by a numeric Unix second.

func PublishClaudeCodeOptions

func PublishClaudeCodeOptions(fsys fsutil.FileSystem, path string, snap Snapshot) error

PublishClaudeCodeOptions merges cq-managed model options into ~/.claude.json without disturbing unrelated fields or user-added entries.

Algorithm:

  1. Read existing ~/.claude.json (treat missing file as empty object).
  2. Read previous cq-managed fingerprints.
  3. Remove only entries cq previously wrote, keeping user and malformed entries.
  4. Append the current cq-managed entries.
  5. Write the updated ownership fingerprints.
  6. Atomically write back via unique tmp+rename (0o600 file, 0o700 dir).

func PublishCodexCache

func PublishCodexCache(fsys fsutil.FileSystem, path string, snap Snapshot, now time.Time, clientVersion string) error

PublishCodexCache writes the Codex models_cache.json envelope to path using an atomic tmp+rename write. Parent directories are created with 0o700; the file is written with 0o600.

Existing envelope fields (etag, client_version) are preserved when the caller passes an empty clientVersion string. fetched_at is always updated to now. clientVersion, when non-empty, replaces the stored value.

func SaveOverlays

func SaveOverlays(fsys fsutil.FileSystem, path string, overlays OverlayFile) error

SaveOverlays writes overlays to path atomically using tmp+rename. Parent directories are created with 0o700; the file is written with 0o600. The .tmp file is removed on rename failure so no partial file is left behind.

func ValidateSnapshot

func ValidateSnapshot(snap Snapshot) error

ValidateSnapshot returns an error if snap contains the same non-empty model ID under two or more different providers. Comparison is case-insensitive: "Foo" and "foo" are considered the same ID. Duplicate IDs within the same provider are allowed.

The error message is deterministic: conflicts are sorted by the canonical (lower-cased) ID, and each conflict lists providers in alphabetical order.

Types

type AnthropicSource

type AnthropicSource struct {
	// Client is the HTTP doer used to make requests.
	Client httputil.Doer
	// BaseURL is the root URL, e.g. "https://api.anthropic.com".
	// Defaults to "https://api.anthropic.com" when empty.
	BaseURL string
	// Token returns a bearer token for the request.
	Token func(ctx context.Context) (string, error)
}

AnthropicSource fetches the Anthropic model catalogue from the upstream API. All fields are injected for testability.

func (*AnthropicSource) Fetch

Fetch implements NativeSource.

type Catalog

type Catalog struct {
	// contains filtered or unexported fields
}

Catalog is a concurrency-safe store for the current registry Snapshot. Callers exchange the entire snapshot atomically; there is no partial update.

func NewCatalog

func NewCatalog(initial Snapshot) *Catalog

NewCatalog returns a new Catalog pre-loaded with initial. The initial snapshot is deep-copied on ingress.

func (*Catalog) Replace

func (c *Catalog) Replace(s Snapshot)

Replace atomically swaps the stored snapshot with s. s is deep-copied on ingress so the caller may reuse or mutate it freely.

func (*Catalog) Snapshot

func (c *Catalog) Snapshot() Snapshot

Snapshot returns a deep copy of the current snapshot so the caller cannot inadvertently alias internal state.

type CodexSource

type CodexSource struct {
	// Client is the HTTP doer used to make requests.
	Client httputil.Doer
	// BaseURL is the root URL, e.g. "https://api.openai.com".
	// Defaults to "https://api.openai.com" when empty.
	BaseURL string
	// Token returns a bearer token for the request.
	Token func(ctx context.Context) (string, error)
	// ClientVersion is sent as the client_version query parameter.
	ClientVersion string
}

CodexSource fetches the Codex model catalogue from the upstream API. All fields are injected for testability.

func (*CodexSource) Fetch

func (s *CodexSource) Fetch(ctx context.Context) (SourceResult, error)

Fetch implements NativeSource.

type Entry

type Entry struct {
	Provider         Provider `json:"provider"`
	ID               string   `json:"id"`
	Aliases          []string `json:"aliases,omitempty"`
	DisplayName      string   `json:"display_name,omitempty"`
	Description      string   `json:"description,omitempty"`
	ContextWindow    int      `json:"context_window,omitempty"`
	MaxContextWindow int      `json:"max_context_window,omitempty"`
	MaxOutputTokens  int      `json:"max_output_tokens,omitempty"`
	Visibility       string   `json:"visibility,omitempty"`
	Priority         int      `json:"priority,omitempty"`
	Source           Source   `json:"source"`
	CloneFrom        string   `json:"clone_from,omitempty"`
	InferredFrom     string   `json:"inferred_from,omitempty"`
	// Raw holds the original provider JSON for pass-through use.
	Raw json.RawMessage `json:"raw,omitempty"`
}

Entry is a single model record in the registry.

func InferClone

func InferClone(overlay Entry, natives []Entry) (Entry, bool)

InferClone determines the best native entry to use as a clone source for overlay.

Rules (in priority order):

  1. If overlay.CloneFrom is set, look for a same-provider native with that ID. Return it if found; return (Entry{}, false) if not found.
  2. Otherwise score every same-provider native by token similarity and return the best match if it meets the confidence threshold.

Tokenisation: the model ID is split on '-', '_', and '.'. Tokens that are entirely numeric or look like an 8-digit date (YYYYMMDD) are treated as version/date signals and weighted less than family tokens.

The returned Entry has InferredFrom set to the source native's ID so callers can annotate the overlay without mutating the original.

func LoadClaudeEntriesFromCapabilities

func LoadClaudeEntriesFromCapabilities(fsys fsutil.FileSystem, path string) ([]Entry, error)

LoadClaudeEntriesFromCapabilities reads Claude Code's model-capabilities cache and returns the models as native Entry records. A missing file returns (nil, nil). Malformed JSON returns an error.

func LoadCodexEntriesFromCache

func LoadCodexEntriesFromCache(fsys fsutil.FileSystem, path string) ([]Entry, error)

LoadCodexEntriesFromCache reads a previously-published Codex models_cache.json envelope and returns the models as native Entry records. A missing file returns (nil, nil). Malformed JSON returns an error.

func (Entry) Validate

func (e Entry) Validate() error

Validate returns an error if the entry is missing required fields or contains unrecognised enumeration values.

type FileOverlayStore

type FileOverlayStore struct {
	FS   fsutil.FileSystem
	Path string
}

FileOverlayStore loads overlay models from the on-disk overlay file.

func (FileOverlayStore) Load

func (s FileOverlayStore) Load() ([]Entry, error)

type MergeResult

type MergeResult struct {
	// Active is the merged set of entries to be stored in the Catalog.
	// It contains all native entries plus overlay entries that have no native counterpart.
	Active []Entry
	// Prunable contains overlay entries that were shadowed by a native entry.
	// Callers may persist a pruned overlay file to disk to remove stale entries.
	Prunable []Entry
}

MergeResult is the output of Merge.

func Merge

func Merge(natives, overlays []Entry) MergeResult

Merge combines native entries with overlay entries into a single authoritative list.

Rules:

  1. Native entries always win over overlays with the same (provider, id) pair. The overlay is added to MergeResult.Prunable.
  2. Overlay entries with no native counterpart remain active. If the overlay entry has missing metadata (DisplayName, Description, ContextWindow, MaxOutputTokens, Visibility, Priority), InferClone is used to find the best matching native and copy those fields. The overlay ID/Provider/Source/CloneFrom are never changed.
  3. Entries with the same ID but different providers never conflict.

type NativeSource

type NativeSource interface {
	Fetch(ctx context.Context) (SourceResult, error)
}

NativeSource is the interface implemented by provider-specific model catalogues.

type OverlayFile

type OverlayFile struct {
	Version int     `json:"version"`
	Models  []Entry `json:"models"`
}

OverlayFile is the on-disk representation of the user overlay file.

func LoadOverlays

func LoadOverlays(fsys fsutil.FileSystem, path string) (OverlayFile, error)

LoadOverlays reads the overlay file at path. A missing file returns an empty OverlayFile (version 1) and nil error. A malformed JSON file returns a wrapped error. Entries whose Source is empty have SourceOverlay applied.

type OverlayStore

type OverlayStore interface {
	Load() ([]Entry, error)
}

OverlayStore is the read-only interface Refresher uses to load overlay entries. Implementations may load from disk or return a fixed slice for tests.

type Provider

type Provider string

Provider identifies the upstream API provider for a model.

const (
	ProviderAnthropic Provider = "anthropic"
	ProviderCodex     Provider = "codex"
)

type RefreshDiagnostics

type RefreshDiagnostics struct {
	// Counts is the number of native entries fetched per provider.
	Counts map[string]int
	// Prunable contains overlay entries that conflicted with native entries.
	Prunable []Entry
	// SourceErrors records fetch errors for providers that failed. Only failing
	// providers are stored; successful providers are absent from the map (nil
	// errors are never inserted).
	SourceErrors map[Provider]error
	// MalformedCounts records the number of skipped malformed model entries per
	// provider. Only providers with at least one malformed entry appear here.
	MalformedCounts map[Provider]int
}

RefreshDiagnostics summarises what happened during a Refresh call.

type Refresher

type Refresher struct {
	// Catalog is the target store updated after each successful refresh.
	Catalog *Catalog
	// Overlays is an optional overlay loader. May be nil.
	Overlays OverlayStore
	// Anthropic fetches the Anthropic model catalogue. May be nil to skip.
	Anthropic NativeSource
	// Codex fetches the Codex model catalogue. May be nil to skip.
	Codex NativeSource
	// Now returns the current time. Defaults to time.Now when nil.
	Now func() time.Time
	// contains filtered or unexported fields
}

Refresher fetches fresh model data from all configured sources and updates the Catalog atomically. It is safe for concurrent use; concurrent Refresh calls are coalesced via an internal mutex so sources are not called in parallel by multiple callers.

func (*Refresher) Refresh

func (r *Refresher) Refresh(ctx context.Context) (RefreshDiagnostics, error)

Refresh fetches fresh data from all sources, merges the results with any overlay entries, and atomically replaces the Catalog snapshot.

Partial failures are tolerated: if a source fails, the previous snapshot's entries for that provider are preserved in the new snapshot. If all sources fail, the existing snapshot is left unchanged and the errors are returned in RefreshDiagnostics.

type Snapshot

type Snapshot struct {
	Entries          []Entry
	CodexRawByID     map[string]json.RawMessage
	AnthropicRawByID map[string]json.RawMessage
	FetchedAt        time.Time
}

Snapshot is an immutable point-in-time view of the registry.

type Source

type Source string

Source indicates where a registry entry originated.

const (
	SourceNative  Source = "native"
	SourceOverlay Source = "overlay"
)

type SourceFunc

type SourceFunc func(context.Context) (SourceResult, error)

SourceFunc is a function adapter for NativeSource.

func (SourceFunc) Fetch

func (f SourceFunc) Fetch(ctx context.Context) (SourceResult, error)

Fetch implements NativeSource.

type SourceResult

type SourceResult struct {
	// Entries are the parsed model entries from the upstream provider.
	Entries []Entry
	// CodexRawByID holds the full upstream JSON keyed by model slug/ID.
	// Populated only by CodexSource.
	CodexRawByID map[string]json.RawMessage
	// AnthropicRawByID holds the full upstream JSON keyed by model ID.
	// Populated only by AnthropicSource.
	AnthropicRawByID map[string]json.RawMessage
	// FetchedAt is the wall-clock time the data was retrieved.
	FetchedAt time.Time
	// MalformedEntries is the count of raw model entries that were skipped
	// because they failed to unmarshal or had an empty slug/ID.
	MalformedEntries int
}

SourceResult is the output of a NativeSource.Fetch call.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL