Documentation
¶
Overview ¶
PolicyAllows answers "is this Model reachable through this Policy?" without picking a binding or a key — the question /v1/models needs to answer. Mirrors the allowed-paths logic in Resolve so the two stay in sync. Resolve is binding-aware (legacy + DSL + wildcard match against specific (provider, model, host) triples); PolicyAllows reduces to "is there *any* binding under this policy that would be allowed?"
Package routing resolves an inbound inference request to a fully-typed RequestPlan that the pipeline can consume. All catalog lookups happen here, against the in-memory snapshot. The pipeline itself is ignorant of the snapshot.
Resolution flow:
- Model: caller supplies a snapshot name (from the request body's `model` field); look it up via snapshot.SnapshotByName. The owning Model + the picked Snapshot are carried into the Plan.
- Policy: comes from the authenticated RelayKey's PolicyID. (No "default route" indirection in the new arch — RelayKey → Policy is direct. Anonymous traffic is served by a separate package.)
- Authorization: model must be allowed by the Policy. Allowed if its id is in Spec.ModelIDs, OR Spec.Models (modelref DSL) matches, OR — when both grant fields are empty — the policy is an implicit wildcard: any model reachable via its hostkeys is allowed. The hostkey-coverage check below is the real gate in that case.
- HostBinding: pick one of the model's HostBindings (snapshot. BindingsForModel) the operator has configured. v1 picks the first enabled binding; multi-host failover is a future feature.
- Host: lookup by binding.Spec.HostID for BaseURL.
- Keys: Policy.Spec.HostKeyIDs filtered to those whose Owner.ID is the chosen Host (a key authenticates against one host).
- RateLimit: Policy.Spec.RateLimitID, resolved to []pkgratelimit.Rule.
Each lookup is a snapshot.Get — no PG, no I/O. Resolve() is allocation- conscious where it matters but not micro-optimised; the hot-path budget dominates this.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrModelNotFound = errors.New("routing: model not found") ErrModelDisabled = errors.New("routing: model disabled") ErrPolicyNotFound = errors.New("routing: policy not found") ErrPolicyDisabled = errors.New("routing: policy disabled") ErrModelNotInPolicy = errors.New("routing: model not allowed by policy") ErrNoHostBinding = errors.New("routing: no enabled host binding for model") ErrHostNotFound = errors.New("routing: host not found") ErrNoKeys = errors.New("routing: no host keys available for this host") // ErrPolicyless is returned when a RelayKey has no PolicyID and the // inference settings forbid policy-less traffic. ErrPolicyless = errors.New("routing: relay key has no policy and policy-less traffic is disabled") )
Errors returned by Resolve. Each maps to a distinct HTTP status in the handler; routing keeps them as typed sentinels so handlers can errors.Is() rather than parse strings.
Functions ¶
func PolicyAllows ¶
PolicyAllows reports whether m is reachable through pol given snap's hostkey coverage. Used to enumerate accessible models for inventory endpoints. Single-shot; not optimised for tight loops.
Types ¶
type Plan ¶
type Plan struct {
Model *model.Model
Snapshot *model.Snapshot
Policy *policy.Policy
HostBinding *binding.Binding
Host *host.Host
Provider string
Keys []*hostkey.HostKey
// PayloadLoggingEnabled is the resolved opt-in for full request/response
// body capture: true when the matched Policy or the inbound RelayKey
// sets PayloadLoggingEnabled. Read by the inference entry to flag the
// lifecycle Context so the payloadlog observer captures bodies.
PayloadLoggingEnabled bool
}
Plan is the fully-resolved input the pipeline consumes. The handler converts this to pipeline.Request, dropping fields the pipeline doesn't need.
Snapshot is the resolved checkpoint. The handler rewrites the request body's `model` field to Snapshot.Upstream() before invoking the adapter.
type Request ¶
type Request struct {
// ModelName is the slug or upstream-name reference the caller asked
// for (typically from the body's "model" field).
ModelName string
// RelayKey is the authenticated key (already validated for auth).
// Its Spec.PolicyID drives policy selection.
RelayKey *relaykey.RelayKey
// SkipKeyCheck, when true, suppresses the Policy.HostKeyIDs → host
// coverage gate. Used by proxy mode: the caller brings their own
// upstream credentials, so the relay's keypool is irrelevant — only
// the (model, binding, host) tuple matters. Plan.Keys is nil in
// this mode.
SkipKeyCheck bool
}
Request carries the inbound resolution inputs.
type Resolver ¶
type Resolver struct {
// contains filtered or unexported fields
}
Resolver wraps a Catalog snapshot accessor and answers Resolve calls.
func New ¶
func New(cat *appcatalog.Catalog) *Resolver
New constructs a Resolver against the live catalog. The Resolver reads cat.Current() on every Resolve — picking up the latest snapshot after any NOTIFY-driven reload.