Documentation
¶
Overview ¶
Package modelcatalog holds source-neutral model capability facts, match metadata, and consumer-owned snapshot ports used by the core catalog runtime. It must not import provider SDKs, backend plugins, frontend plugins, or concrete HTTP/filesystem adapters (those live under internal/infra).
Matching and resolution: DefaultMatcher (exact then normalized catalog ids), OverrideResolver for administrator pair/model overrides, CatalogResolverImpl (from NewCatalogResolver) for effective capabilities vs backend caps, and DefaultVendorResolver (from NewVendorResolver) for catalog-backed vendor/model canonicalization with optional VendorPolicy hooks for provider-specific alias and keyword rules.
Lifecycle: CatalogRuntime loads the local cache; the composition root runs periodic refresh via SnapshotSource / SnapshotCache, and publishes an immutable active Snapshot for readers.
Request sizing and routing: DefaultSizeEstimator and NewEligibilityResolver implement conservative pre-upstream context-limit eligibility on top of already-resolved EffectiveFacts.
Constructor shape: NewCatalogResolver, NewEligibilityResolver, and NewOverrideResolver return narrow interface types (ports) rather than concrete structs. That intentionally trades the usual “return structs, accept interfaces” rule for a smaller, sealed substitution surface at the composition root.
Index ¶
- Constants
- func CloneBackendCaps(b lipapi.BackendCaps) lipapi.BackendCaps
- func NormalizeStripOneProviderPrefix(s string) string
- func RedactSourceURL(raw string) string
- func SuffixLookupKeys(suffix string) []string
- func WithBoundView(ctx context.Context, v BoundView) context.Context
- func WithSessionSizeContribution(ctx context.Context, contributionBytes int64) context.Context
- type ActiveSnapshotProvider
- type BoundView
- type CapabilityTriState
- type CatalogDiagnosticsJSON
- type CatalogDiagnosticsStatus
- type CatalogResolverImpl
- type CatalogRuntime
- func (r *CatalogRuntime) Active() (Snapshot, bool)
- func (r *CatalogRuntime) ActiveIndex() (*SnapshotIndex, SnapshotRef)
- func (r *CatalogRuntime) BoundView() BoundView
- func (r *CatalogRuntime) Close() error
- func (r *CatalogRuntime) LastRefreshFailure() RefreshFailureCategory
- func (r *CatalogRuntime) PublishSnapshot(snap Snapshot)
- func (r *CatalogRuntime) RunRefresh(ctx context.Context)
- func (r *CatalogRuntime) Start(parent context.Context) error
- type CatalogSnapshotDiagnostics
- type CatalogStatusHandlerConfig
- type DefaultMatcher
- type DefaultSizeEstimator
- type DefaultVendorResolver
- type EffectiveFacts
- type EligibilityDecision
- type EligibilityReason
- type EligibilityResolverImpl
- type FactSource
- type LimitFact
- type LimitTriState
- type MatchKind
- type MatchResult
- type Matcher
- type ModelFacts
- type OverrideResolver
- type OverrideSet
- type RefreshFailureCategory
- type RuntimeConfig
- type SizeEstimate
- type Snapshot
- type SnapshotCache
- type SnapshotIndex
- type SnapshotRef
- type SnapshotSource
- type StaticActiveSnapshotProvider
- type VendorPolicy
- type VendorResolveKind
- type VendorResolveResult
- type VendorResolver
Constants ¶
const ( EstimateBasisCanonicalUTF8 = "canonical_utf8_bytes" EstimateBasisCanonicalUTF8AndTools = "canonical_utf8_bytes+tools_json_bytes" EstimateBasisCanonicalUTF8AndSession = "canonical_utf8_bytes+session_bytes" )
EstimateBasis documents how SizeEstimate.Input was derived (requirement 7.7).
Variables ¶
This section is empty.
Functions ¶
func CloneBackendCaps ¶
func CloneBackendCaps(b lipapi.BackendCaps) lipapi.BackendCaps
CloneBackendCaps returns a shallow copy of caps for safe in-place mutation, or nil when caps is nil.
func NormalizeStripOneProviderPrefix ¶
NormalizeStripOneProviderPrefix removes one leading `provider/` segment (first '/'). If there is no '/', the string is returned trimmed unchanged.
func RedactSourceURL ¶
RedactSourceURL returns a userinfo-free URL string for operator display, or empty when input is empty.
func SuffixLookupKeys ¶
func WithBoundView ¶
WithBoundView attaches v to ctx for request-scoped consumers.
func WithSessionSizeContribution ¶
WithSessionSizeContribution attaches a proxy-known byte contribution for resumed or continuous sessions. When the call carries session or continuity hints, this value must be present for an available estimate.
Types ¶
type ActiveSnapshotProvider ¶
type ActiveSnapshotProvider interface {
ActiveIndex() (*SnapshotIndex, SnapshotRef)
}
ActiveSnapshotProvider supplies the current immutable catalog index for each CatalogResolverImpl.Resolve call. Implementations typically read an atomically published snapshot (CatalogRuntime) so refresh updates affect subsequent routing decisions without per-resolve I/O.
type BoundView ¶
type BoundView struct {
// contains filtered or unexported fields
}
BoundView is an immutable, request-scoped catalog publication. It freezes the active snapshot index/generation (or explicit no-snapshot state) so a later CatalogRuntime refresh cannot alter an in-flight request.
BoundView never exposes the mutable CatalogRuntime, its mutexes, or atomics.
func BoundViewFromContext ¶
BoundViewFromContext returns the request-bound catalog view when present.
func EmptyBoundView ¶
func EmptyBoundView() BoundView
EmptyBoundView returns a safe empty view (nil/unavailable runtime).
func (BoundView) ActiveIndex ¶
func (v BoundView) ActiveIndex() (*SnapshotIndex, SnapshotRef)
ActiveIndex implements ActiveSnapshotProvider for the frozen snapshot.
func (BoundView) Generation ¶
Generation returns the frozen catalog snapshot generation.
type CapabilityTriState ¶
type CapabilityTriState uint8
CapabilityTriState is an explicit tri-state for protocol-neutral capabilities (unknown vs explicit false).
const ( // CapabilityUnknown means the catalog or override did not establish support or denial. CapabilityUnknown CapabilityTriState = iota // CapabilityUnsupported means the model is explicitly known not to support the capability. CapabilityUnsupported // CapabilitySupported means the model is explicitly known to support the capability. CapabilitySupported )
type CatalogDiagnosticsJSON ¶
type CatalogDiagnosticsJSON struct {
UsageEnabled bool `json:"usage_enabled"`
// Status is disabled when model_catalog.enabled is false; otherwise reflects snapshot presence and freshness.
Status CatalogDiagnosticsStatus `json:"status"`
// Snapshot is set when a valid local/remote catalog snapshot is active in the runtime.
Snapshot *CatalogSnapshotDiagnostics `json:"snapshot,omitempty"`
// LastRefreshErrorCategory is empty when the last refresh completed successfully.
LastRefreshErrorCategory RefreshFailureCategory `json:"last_refresh_error_category,omitempty"`
// SourceURLRedacted never includes userinfo (requirement 10.4).
SourceURLRedacted string `json:"source_url_redacted,omitempty"`
ExternalUpdatesEnabled bool `json:"external_updates_enabled"`
// UpdateIntervalSeconds is 0 when unset or invalid in config.
UpdateIntervalSeconds float64 `json:"update_interval_seconds,omitempty"`
// Aggregate model-view identity (req 9.6); set only when PreferBound + identity present.
ModelViewDigest string `json:"model_view_digest,omitempty"`
ConfigGeneration string `json:"config_generation,omitempty"`
ConfigFingerprint string `json:"config_fingerprint,omitempty"`
RegistryGeneration string `json:"registry_generation,omitempty"`
}
CatalogDiagnosticsJSON is the operator JSON for GET model_catalog.diagnostics_path (not a stable public API).
func BuildCatalogDiagnosticsJSON ¶
func BuildCatalogDiagnosticsJSON(cfg CatalogStatusHandlerConfig) CatalogDiagnosticsJSON
BuildCatalogDiagnosticsJSON builds the JSON DTO for the current moment (no prompt/session content). When PreferBound is set, the request-bound snapshot is used instead of the live runtime.
type CatalogDiagnosticsStatus ¶
type CatalogDiagnosticsStatus string
CatalogDiagnosticsStatus is the high-level operator-visible catalog state (requirements 9.1).
const ( CatalogDiagDisabled CatalogDiagnosticsStatus = "disabled" CatalogDiagStale CatalogDiagnosticsStatus = "stale" CatalogDiagEnabled CatalogDiagnosticsStatus = "enabled" )
type CatalogResolverImpl ¶
type CatalogResolverImpl struct {
// contains filtered or unexported fields
}
CatalogResolverImpl combines overrides, catalog matching, and backend capability intersection. Wire it into github.com/matdev83/go-llm-interactive-proxy/internal/core/runtime.Executor.CatalogResolver.
func NewCatalogResolver ¶
func NewCatalogResolver( m Matcher, ovr OverrideResolver, catalogEnabled bool, active ActiveSnapshotProvider, ) *CatalogResolverImpl
NewCatalogResolver builds a resolver. When catalogEnabled is false, catalog matching is skipped and effective capabilities mirror backend declarations. active may be nil (no snapshot) or supply a nil index when no valid local catalog is published (Req 1.4).
func (*CatalogResolverImpl) Resolve ¶
func (c *CatalogResolverImpl) Resolve( ctx context.Context, candidate routing.AttemptCandidate, call lipapi.Call, backend lipapi.BackendCaps, ) EffectiveFacts
Resolve implements the executor catalog merge contract. When a request-bound catalog view is present on ctx it is preferred so failover/parallel attempts observe one immutable snapshot (req 9.4-9.5). Compatibility callers without a bound view still read the live provider.
type CatalogRuntime ¶
type CatalogRuntime struct {
// contains filtered or unexported fields
}
CatalogRuntime coordinates local cache loading and publication of the active immutable snapshot for request-time readers. Background refresh ticks are started by the composition root (see internal/infra/runtimebundle), which calls CatalogRuntime.RunRefresh on a schedule.
func NewCatalogRuntime ¶
func NewCatalogRuntime(cfg RuntimeConfig) *CatalogRuntime
NewCatalogRuntime builds a coordinator. Source and Cache may be nil when updates are disabled and no cache load is required (callers should still pass non-nil cache for typical startup).
func (*CatalogRuntime) Active ¶
func (r *CatalogRuntime) Active() (Snapshot, bool)
Active returns the current immutable snapshot handle for routing-time use. The second result is false when no snapshot has been published yet.
func (*CatalogRuntime) ActiveIndex ¶
func (r *CatalogRuntime) ActiveIndex() (*SnapshotIndex, SnapshotRef)
ActiveIndex implements ActiveSnapshotProvider: the current catalog index and generation for routing.
func (*CatalogRuntime) BoundView ¶
func (r *CatalogRuntime) BoundView() BoundView
BoundView captures the current catalog snapshot pointer exactly once. A nil receiver returns an empty view.
func (*CatalogRuntime) Close ¶
func (r *CatalogRuntime) Close() error
Close marks the runtime stopped. External refresh workers must be stopped separately by the composition root.
func (*CatalogRuntime) LastRefreshFailure ¶
func (r *CatalogRuntime) LastRefreshFailure() RefreshFailureCategory
LastRefreshFailure returns the failure category from the most recent refresh attempt.
func (*CatalogRuntime) PublishSnapshot ¶
func (r *CatalogRuntime) PublishSnapshot(snap Snapshot)
PublishSnapshot atomically publishes snap as the active catalog view. Production refresh uses CatalogRuntime.RunRefresh; this helper supports composition-root seeding and deterministic tests without network I/O.
func (*CatalogRuntime) RunRefresh ¶
func (r *CatalogRuntime) RunRefresh(ctx context.Context)
RunRefresh fetches a remote snapshot when a source is configured, validates it, persists via cache, and publishes the active view. ctx governs fetch/save cancellation.
func (*CatalogRuntime) Start ¶
func (r *CatalogRuntime) Start(parent context.Context) error
Start loads the local cache once and publishes a valid snapshot when present. It does not run network refresh; the composition root calls CatalogRuntime.RunRefresh when configured.
type CatalogSnapshotDiagnostics ¶
type CatalogSnapshotDiagnostics struct {
Generation string `json:"generation"`
FetchedAt time.Time `json:"fetched_at"`
ContentHash string `json:"content_hash,omitempty"`
}
CatalogSnapshotDiagnostics is non-request content: generation and fetch metadata only.
type CatalogStatusHandlerConfig ¶
type CatalogStatusHandlerConfig struct {
Runtime *CatalogRuntime
UsageEnabled bool
ExternalUpdatesEnabled bool
UpdateInterval time.Duration
SourceURL string
// Now defaults to time.Now if nil (tests may inject a fixed clock).
Now func() time.Time
// PreferBound uses BoundSnapshot instead of rereading Runtime when true.
PreferBound bool
// BoundSnapshot is the request-bound catalog view (ignored unless PreferBound).
BoundSnapshot BoundView
// ModelViewIdentity attaches safe aggregate identity fields when set.
ModelViewIdentity map[string]string
}
CatalogStatusHandlerConfig configures BuildCatalogDiagnosticsJSON for the operator HTTP handler (internal/stdhttp: NewCatalogStatusHandler).
type DefaultMatcher ¶
type DefaultMatcher struct{}
DefaultMatcher implements exact-then-normalized deterministic matching.
func (DefaultMatcher) Match ¶
func (DefaultMatcher) Match(candidate routing.AttemptCandidate, index *SnapshotIndex) MatchResult
Match implements Matcher.
type DefaultSizeEstimator ¶
type DefaultSizeEstimator struct{}
DefaultSizeEstimator implements conservative sizing using UTF-8 byte counts of canonical message content plus tool declaration JSON-ish footprint. Non-text parts use deterministic byte proxies.
func (DefaultSizeEstimator) Estimate ¶
func (DefaultSizeEstimator) Estimate(ctx context.Context, call lipapi.Call) SizeEstimate
func (DefaultSizeEstimator) EstimateRequestTokens ¶
func (e DefaultSizeEstimator) EstimateRequestTokens(ctx context.Context, call lipapi.Call) SizeEstimate
type DefaultVendorResolver ¶
type DefaultVendorResolver struct {
// contains filtered or unexported fields
}
func NewVendorResolver ¶
func NewVendorResolver(active ActiveSnapshotProvider, keywordFallback bool, policy VendorPolicy) *DefaultVendorResolver
func (*DefaultVendorResolver) Resolve ¶
func (r *DefaultVendorResolver) Resolve(model string) VendorResolveResult
type EffectiveFacts ¶
type EffectiveFacts struct {
Facts ModelFacts
BackendCaps lipapi.BackendCaps
EffectiveCaps lipapi.BackendCaps
Matched bool
Match MatchResult
Snapshot SnapshotRef
}
EffectiveFacts is the source-aware capability surface for one candidate (design §CatalogResolver).
type EligibilityDecision ¶
type EligibilityDecision struct {
IsEligible bool `json:"eligible"`
Reason EligibilityReason `json:"reason,omitempty"`
Facts EffectiveFacts `json:"facts,omitzero"`
Estimate SizeEstimate `json:"estimate,omitzero"`
}
EligibilityDecision is the routing-time outcome for context limits before backend open.
type EligibilityReason ¶
type EligibilityReason uint8
EligibilityReason is a compact routing-time outcome for context limits (executor integration later).
const ( EligibilityUnknown EligibilityReason = iota EligibilityEligible EligibilityContextLimitExceeded )
func (EligibilityReason) String ¶
func (r EligibilityReason) String() string
String returns a stable eligibility reason label.
type EligibilityResolverImpl ¶
type EligibilityResolverImpl struct {
// contains filtered or unexported fields
}
EligibilityResolverImpl decides context-limit eligibility from already-resolved EffectiveFacts (design §EligibilityResolver). Wire it into github.com/matdev83/go-llm-interactive-proxy/internal/core/runtime.Executor.EligibilityResolver.
func NewEligibilityResolver ¶
func NewEligibilityResolver(est sizeEstimator) *EligibilityResolverImpl
NewEligibilityResolver returns a resolver that never performs capability negotiation; it only compares a conservative size estimate to a known context limit from facts.
func (*EligibilityResolverImpl) Check ¶
func (e *EligibilityResolverImpl) Check( ctx context.Context, candidate routing.AttemptCandidate, call lipapi.Call, facts EffectiveFacts, ) EligibilityDecision
Check implements the executor eligibility contract.
type FactSource ¶
type FactSource uint8
FactSource identifies where effective model facts originated (requirement 9.7).
const ( // FactSourceNone means no catalog or override facts apply for this evaluation branch. FactSourceNone FactSource = iota // FactSourcePairOverride is a backend+model administrator override. FactSourcePairOverride // FactSourceModelOverride is a model-name-only administrator override. FactSourceModelOverride // FactSourceCatalog is a matching models.dev catalog entry after normalization. FactSourceCatalog // FactSourceBackendDeclaration is the backend adapter capability surface only. FactSourceBackendDeclaration )
func (FactSource) String ¶
func (f FactSource) String() string
String returns a stable label for operator diagnostics (not localized).
type LimitFact ¶
type LimitFact struct {
State LimitTriState
Tokens int64
}
LimitFact carries limit state separate from "unknown" (requirement 3.6).
type LimitTriState ¶
type LimitTriState uint8
LimitTriState distinguishes unknown limits, explicit lack of a limit concept, and a known numeric limit.
const ( // LimitUnknown means no reliable limit was derived from catalog or overrides. LimitUnknown LimitTriState = iota // LimitUnsupported means the source explicitly indicates no context limit applies for this model path. LimitUnsupported // LimitPresent means Tokens holds a positive context token budget (or provider-normalized unit). LimitPresent )
type MatchKind ¶
type MatchKind uint8
MatchKind classifies catalog model id matching for diagnostics (requirements 4.x).
const ( // MatchNone means no catalog match classification applies (backend-only path). MatchNone MatchKind = iota // MatchNoMatch means no catalog entry matched the route model. MatchNoMatch // MatchExact is a full string identity match against catalog model ids. MatchExact // MatchNonExact is a deterministic normalized match with a single catalog candidate. MatchNonExact // MatchAmbiguous means normalized matching produced multiple catalog ids. MatchAmbiguous )
type MatchResult ¶
MatchResult classifies catalog matching for a route model (design §Matcher).
type Matcher ¶
type Matcher interface {
Match(candidate routing.AttemptCandidate, index *SnapshotIndex) MatchResult
}
Matcher resolves route model strings to catalog entries without mutating the candidate.
type ModelFacts ¶
type ModelFacts struct {
Tools CapabilityTriState
StructuredOutputs CapabilityTriState
Reasoning CapabilityTriState
Vision CapabilityTriState
Documents CapabilityTriState
ContextLimit LimitFact
InputLimit LimitFact
OutputLimit LimitFact
Source FactSource
MatchKind MatchKind
}
ModelFacts is protocol-neutral state used for compatibility and diagnostics (design §ModelFacts).
type OverrideResolver ¶
type OverrideResolver interface {
Resolve(candidate routing.AttemptCandidate) (ModelFacts, bool)
}
OverrideResolver applies pair-then-model override precedence (design §OverrideResolver).
func NewOverrideResolver ¶
func NewOverrideResolver(set OverrideSet) OverrideResolver
NewOverrideResolver returns a resolver for the given set (nil maps are treated as empty).
type OverrideSet ¶
type OverrideSet struct {
Pair map[string]ModelFacts
Model map[string]ModelFacts
}
OverrideSet holds administrator facts keyed by backend:model pair or model name only. Pair keys use routing.Primary backend and model with surrounding space trimmed; query params are ignored.
type RefreshFailureCategory ¶
type RefreshFailureCategory string
RefreshFailureCategory classifies the last catalog refresh failure for diagnostics.
const ( // RefreshFailureNone means no failure since the last successful refresh (or startup). RefreshFailureNone RefreshFailureCategory = "" // RefreshFailureFetch indicates a transport or HTTP-layer failure from the snapshot source. RefreshFailureFetch RefreshFailureCategory = "fetch" // RefreshFailureParse indicates decode, validation, or unsupported schema from fetched bytes. RefreshFailureParse RefreshFailureCategory = "parse" // RefreshFailureCache indicates a local persistence failure after a successful fetch. RefreshFailureCache RefreshFailureCategory = "cache" )
type RuntimeConfig ¶
type RuntimeConfig struct {
Source SnapshotSource
Cache SnapshotCache
}
RuntimeConfig wires optional catalog refresh for CatalogRuntime.
type SizeEstimate ¶
SizeEstimate is a deterministic, diagnostics-friendly size view (design §SizeEstimate).
type Snapshot ¶
type Snapshot struct {
Generation string
FetchedAt time.Time
ContentHash string
Index *SnapshotIndex
// WirePayload holds the original catalog JSON object bytes used to build this snapshot for disk cache round-trips.
WirePayload []byte
}
Snapshot is an immutable, validated catalog view for one refresh generation.
type SnapshotCache ¶
type SnapshotCache interface {
Load(ctx context.Context) (Snapshot, error)
Save(ctx context.Context, snapshot Snapshot) error
}
SnapshotCache loads and persists validated snapshots locally. Implementations live outside this package.
type SnapshotIndex ¶
type SnapshotIndex struct {
// contains filtered or unexported fields
}
SnapshotIndex is a read-only view of catalog model ids to facts for deterministic matching.
func NewSnapshotIndex ¶
func NewSnapshotIndex(catalog map[string]ModelFacts) *SnapshotIndex
NewSnapshotIndex returns an index backed by a defensive copy of catalog entries.
func (*SnapshotIndex) CatalogIDsForSuffixLookup ¶
func (s *SnapshotIndex) CatalogIDsForSuffixLookup(suffix string) []string
CatalogIDsForSuffixLookup returns sorted catalog ids whose model suffix matches lookup keys (including dotted/dashed numeric variants). Nil when the index or suffix is empty.
func (*SnapshotIndex) FactsByCatalogModelID ¶
func (s *SnapshotIndex) FactsByCatalogModelID(catalogModelID string) (ModelFacts, bool)
FactsByCatalogModelID returns catalog-derived facts for an exact catalog model id key.
type SnapshotRef ¶
type SnapshotRef struct {
Generation string
}
SnapshotRef is a lightweight handle to the snapshot generation used for a routing decision.
type SnapshotSource ¶
SnapshotSource fetches a remote catalog snapshot. Implementations live outside this package (infra).
type StaticActiveSnapshotProvider ¶
type StaticActiveSnapshotProvider struct {
Index *SnapshotIndex
Ref SnapshotRef
}
StaticActiveSnapshotProvider returns a fixed index/ref (tests and static catalogs).
func (StaticActiveSnapshotProvider) ActiveIndex ¶
func (s StaticActiveSnapshotProvider) ActiveIndex() (*SnapshotIndex, SnapshotRef)
ActiveIndex implements ActiveSnapshotProvider.
type VendorPolicy ¶
type VendorResolveKind ¶
type VendorResolveKind uint8
const ( VendorResolveNoMatch VendorResolveKind = iota VendorResolveExact VendorResolveCatalogSuffix VendorResolveVendorAlias VendorResolveAmbiguous VendorResolveKeywordFallback )
func (VendorResolveKind) String ¶
func (k VendorResolveKind) String() string
type VendorResolveResult ¶
type VendorResolver ¶
type VendorResolver interface {
Resolve(model string) VendorResolveResult
}