Documentation
¶
Overview ¶
Package models manages AI model resources: an inference engine (Ollama, vLLM, llama.cpp) running as a container on a GPU node, with an OpenAI-compatible endpoint fronted by an API-key gateway.
Index ¶
- Constants
- Variables
- func AllowedRoutes(engine string) []string
- func CacheUnusedDays() int
- func Command(m Spec, gpus int) []string
- func ContainerPrefix(prefix, name string) string
- func ControllerName(name string) string
- func DefaultIdleTTL() time.Duration
- func EngineMetricsInterval() time.Duration
- func EngineNames() []string
- func Env(m Spec, hfToken string) map[string]string
- func EstimateWeightBytes(engine, ref, quant string) (int64, bool)
- func HashAPIKey(plaintext string) string
- func IdleTTL(m store.Model) time.Duration
- func KeyMatches(plaintext, storedHash string) bool
- func KeyRotationGrace() time.Duration
- func MaxUsageWindow() time.Duration
- func ModelClaim(m store.Model) gpu.Claim
- func ModelClaimName(name string) string
- func NewAPIKey() (plaintext, hash, prefix string, err error)
- func NewKeyID() (string, error)
- func ParseHFRepo(in string) (repo, quant string, ok bool)
- func ParseParamsBillions(ref string) (float64, bool)
- func QuantName(path string) string
- func ResidencyActive(m store.Model, now time.Time) bool
- func ServiceClaim(svc store.DesiredService) (gpu.Claim, bool)
- func ServiceClaimName(name string) string
- func ShmBytes(engine string) int64
- func ValidateAllowPaths(engine string, paths []string) (string, bool)
- func VolumeName(prefix, name string) string
- type CacheBackend
- type CacheEntry
- type CacheNode
- type CachePruneResult
- type CacheReport
- type CacheSkip
- type Controller
- type CreateInput
- type CreateKeyInput
- type Created
- type CreatedKey
- type DiskFactsFunc
- type Engine
- type EngineHealth
- type EngineMetricPoint
- type EngineMetricSeries
- type EngineMetricsCollector
- type EngineMetricsReader
- type EngineMetricsReport
- type EngineMetricsStore
- type FitConfig
- type FitDetail
- type FitInput
- type FitParams
- type FitReport
- type FitRequest
- type GPUNode
- type Gateway
- func (g *Gateway) Handle(w http.ResponseWriter, r *http.Request) bool
- func (g *Gateway) InFlight() map[string]int
- func (g *Gateway) Invalidate()
- func (g *Gateway) Middleware(next http.Handler) http.Handler
- func (g *Gateway) SetLimits(l GatewayLimits)
- func (g *Gateway) SetWakeHook(fn func())
- func (g *Gateway) StartMetering(ctx context.Context, st UsageStore)
- type GatewayLimits
- type GatewayLimitsSummary
- type GatewayStore
- type HFClient
- type HFConfig
- type HFError
- type HFFile
- type HFRepo
- type HTTPProber
- type HostLister
- type HostResolver
- type KeyLimits
- type KeyStatus
- type KeyUsage
- type KeyView
- type MeterConfig
- type NodeFit
- type NodeInfo
- type Nodes
- type Option
- type Phase
- type PreflightDisk
- type PreflightFile
- type PreflightInput
- type PreflightNode
- type PreflightResult
- type PreflightSelection
- type Prober
- type Quant
- type SampleWriter
- type SecretWriter
- type Secrets
- type Service
- func (s *Service) CacheEnabled() bool
- func (s *Service) CacheList(ctx context.Context) (CacheReport, error)
- func (s *Service) CachePrune(ctx context.Context, volumes []string, dryRun bool) (CachePruneResult, error)
- func (s *Service) Create(ctx context.Context, in CreateInput) (Created, error)
- func (s *Service) CreateKey(ctx context.Context, model string, in CreateKeyInput) (CreatedKey, error)
- func (s *Service) Delete(ctx context.Context, name string) error
- func (s *Service) EngineMetrics(ctx context.Context, name string, window time.Duration) (EngineMetricsReport, error)
- func (s *Service) FitCheck(ctx context.Context, req FitRequest) (FitReport, error)
- func (s *Service) GPUNodes(ctx context.Context) ([]GPUNode, error)
- func (s *Service) Get(ctx context.Context, name string) (View, error)
- func (s *Service) List(ctx context.Context) ([]View, error)
- func (s *Service) ListKeys(ctx context.Context, model string) ([]KeyView, error)
- func (s *Service) ModelFit(ctx context.Context, name string) (FitReport, error)
- func (s *Service) NodeGPU(ctx context.Context, nodeID string) (info gpu.Info, known bool, err error)
- func (s *Service) Preflight(ctx context.Context, in PreflightInput) (PreflightResult, error)
- func (s *Service) PreflightEnabled() bool
- func (s *Service) Restart(ctx context.Context, name string) error
- func (s *Service) RevokeKey(ctx context.Context, model, id string) error
- func (s *Service) RotateKey(ctx context.Context, name string) (string, error)
- func (s *Service) RotateKeyByID(ctx context.Context, model, id, actor string, grace *time.Duration) (CreatedKey, error)
- func (s *Service) SetCacheBackend(b CacheBackend, prefix string)
- func (s *Service) SetDiskFacts(fn DiskFactsFunc)
- func (s *Service) SetEngineMetricsReader(r EngineMetricsReader)
- func (s *Service) SetHFToken(ctx context.Context, name, token string) error
- func (s *Service) SetHuggingFace(c *HFClient, fit FitConfig)
- func (s *Service) SetKeyChangeHook(fn func())
- func (s *Service) SetLiveStats(fn func() map[string]int)
- func (s *Service) SetLocalNodeID(id string)
- func (s *Service) SetResidency(ctx context.Context, name, residency string, idleTTL time.Duration) error
- func (s *Service) SetSwapGroup(ctx context.Context, name, group string) error
- func (s *Service) Sleep(ctx context.Context, name string) error
- func (s *Service) UnplacedWorkloads(ctx context.Context) ([]Unplaced, error)
- func (s *Service) Usage(ctx context.Context, model string, window time.Duration) (UsageReport, error)
- func (s *Service) Wake(ctx context.Context, name string) error
- type ServiceStore
- type Spec
- type Status
- type Store
- type Unplaced
- type UsagePoint
- type UsageReport
- type UsageStore
- type UsageTotals
- type View
- type WakeStore
Constants ¶
const ( MetricEngineKVCachePercent = "engine_kv_cache_percent" MetricEngineRunning = "engine_requests_running" MetricEngineWaiting = "engine_requests_waiting" MetricEnginePrefixHitPct = "engine_prefix_cache_hit_percent" MetricEngineGenRate = "engine_tokens_per_second" MetricEngineTTFTSeconds = "engine_ttft_seconds" MetricEngineVRAMBytes = "engine_vram_bytes" MetricEngineOffloadPercent = "engine_offload_percent" )
Sample metric names written for a model's engine under resource "model:<name>".
const ( EngineHealthOK = "ok" EngineHealthWarn = "warn" EngineHealthUnknown = "unknown" )
Engine health states.
const ( EngineOllama = "ollama" EngineVLLM = "vllm" EngineLlamaCpp = "llamacpp" )
Supported engines.
const ( WeightsExact = "exact" WeightsEstimated = "estimated" WeightsUnknown = "unknown" )
Source of the weight size behind a fit result.
const ( HFStatusOK = "ok" HFStatusNotFound = "not_found" HFStatusGated = "gated" HFStatusRateLimited = "rate_limited" HFStatusUnsupported = "unsupported" )
Hub statuses reported by Preflight.
const ( FitFits = "fits" FitTight = "tight" FitWontFit = "wont_fit" FitUnknown = "unknown" )
Fit verdicts. FitUnknown means the node facts needed to judge are missing.
const CacheNote = "Each model keeps its weights in its own Docker volume, so the cache is listed per volume, not per file. " +
"Last used comes from gateway traffic when a model has any, else from the model's last change. " +
"Only the control plane's own host is inspected; remote nodes are not listed yet."
CacheNote states what the cache listing can and cannot see.
const FitNote = "Fit figures are estimates: weights plus a flat overhead for the KV cache and compute buffers. " +
"Real usage depends on context length, batch size, engine and driver."
FitNote states the limits of every fit number.
const FitNoteVRAM = "This is an estimate, not a guarantee: weights are sized from the model name and quantization (exact when the Hugging Face file sizes are known), " +
"the KV cache is approximated from the parameter count and context length, and engine overhead is a flat allowance. " +
"Real usage depends on the engine version, batch size and driver."
FitNoteVRAM states the limits of the per-node VRAM check.
const LocalNodeName = "local"
LocalNodeName labels the control plane's own host in GPU listings.
const UsageNote = "Tokens are counted only for responses that carry a usage object: non-streaming responses, and streams " +
"opened with stream_options.include_usage. Other requests are counted as requests only, and nothing is estimated. " +
"Figures lag the gateway by up to one flush interval."
UsageNote explains the limits of the token counts.
Variables ¶
var ( ErrInvalid = errors.New("models: invalid request") ErrNodeNotFound = errors.New("models: node not found") )
Errors returned by Service, distinguishable by callers to pick an HTTP status.
var ErrKeyExists = errors.New("models: a key with this name already exists")
ErrKeyExists is returned when a live key of the model already has the name.
var ErrKeyNotFound = errors.New("models: key not found")
ErrKeyNotFound is returned when a model has no such key.
Functions ¶
func AllowedRoutes ¶
AllowedRoutes lists the "METHOD path" pairs the gateway forwards for an engine; a trailing slash marks a prefix.
func CacheUnusedDays ¶
func CacheUnusedDays() int
CacheUnusedDays is APP_MODEL_CACHE_UNUSED_DAYS (default 30).
func Command ¶
Command returns the engine container's command line. gpus is the resolved number of GPUs the container will see.
func ContainerPrefix ¶
ContainerPrefix is the name prefix shared by every container of model name, across config revisions.
func ControllerName ¶
ControllerName is the reconcile_status name for model name.
func EngineMetricsInterval ¶
EngineMetricsInterval reads APP_MODEL_ENGINE_METRICS_INTERVAL.
func EstimateWeightBytes ¶
EstimateWeightBytes sizes a model's weights from its name and quantization alone.
func HashAPIKey ¶
HashAPIKey returns the SHA-256 hex digest stored for a key.
func IdleTTL ¶
IdleTTL is how long an on-demand model may go unused before its engine stops: its own setting, else the platform default.
func KeyMatches ¶
KeyMatches reports whether plaintext hashes to storedHash, in constant time.
func KeyRotationGrace ¶
KeyRotationGrace returns the grace window used when a rotation names none.
func MaxUsageWindow ¶
MaxUsageWindow is the longest window Usage serves: the retention, or a year when retention is unlimited.
func ModelClaim ¶
ModelClaim is the GPU reservation of a model.
func ModelClaimName ¶
ModelClaimName is the reservation label of a model.
func NewAPIKey ¶
NewAPIKey returns a fresh plaintext key, its SHA-256 hex hash, and a short non-secret prefix for display. The plaintext is shown once.
func ParseHFRepo ¶
ParseHFRepo splits a repo reference into "owner/name" and an optional quant, accepting huggingface.co and hf.co URL prefixes.
func ParseParamsBillions ¶
ParseParamsBillions extracts the parameter count (in billions) from a model reference such as "llama3.1:8b" or "org/Mixtral-8x7B-GGUF". MoE references count every expert, since all of them stay resident.
func QuantName ¶
QuantName extracts the quantization label from a GGUF file path, or "" when there is none or the file is not a weight file.
func ResidencyActive ¶
ResidencyActive reports whether an on-demand model should have its engine running at now: it was used or woken within its idle TTL.
func ServiceClaim ¶
func ServiceClaim(svc store.DesiredService) (gpu.Claim, bool)
ServiceClaim is the GPU reservation of an app, ok false when it asks for none.
func ServiceClaimName ¶
ServiceClaimName is the reservation label of an app.
func ShmBytes ¶
ShmBytes is the /dev/shm size the engine needs (vLLM tensor parallelism exchanges tensors through shared memory). 0 keeps Docker's default.
func ValidateAllowPaths ¶
ValidateAllowPaths reports the first entry that is not a path the engine's gateway allowlist forwards.
func VolumeName ¶
VolumeName is the persistent model-cache volume of model name.
Types ¶
type CacheBackend ¶
type CacheBackend interface {
ListVolumesByPrefix(ctx context.Context, prefix string) ([]docker.NamedVolume, error)
RemoveVolume(ctx context.Context, name string) error
}
CacheBackend is the Docker surface the cache manager needs.
type CacheEntry ¶
type CacheEntry struct {
Volume string `json:"volume"`
Model string `json:"model,omitempty"`
Engine string `json:"engine,omitempty"`
ModelRef string `json:"model_ref,omitempty"`
SizeBytes *int64 `json:"size_bytes"`
LastUsedAt *time.Time `json:"last_used_at"`
LastUsedSource string `json:"last_used_source"`
UnusedDays int `json:"unused_days"`
Unused bool `json:"unused"`
InUse bool `json:"in_use"`
Configured bool `json:"configured"`
// DuplicateOf names the volume holding the same weights that is
// counted in UniqueBytes instead of this one.
DuplicateOf string `json:"duplicate_of,omitempty"`
Prunable bool `json:"prunable"`
KeepReason string `json:"keep_reason,omitempty"`
}
CacheEntry is one cached weights volume.
type CacheNode ¶
type CacheNode struct {
NodeID string `json:"node_id"`
Name string `json:"name"`
IsLocal bool `json:"is_local"`
Supported bool `json:"supported"`
Message string `json:"message,omitempty"`
Entries []CacheEntry `json:"entries"`
TotalBytes int64 `json:"total_bytes"`
UniqueBytes int64 `json:"unique_bytes"`
ReclaimableBytes int64 `json:"reclaimable_bytes"`
DiskFreeBytes *int64 `json:"disk_free_bytes"`
}
CacheNode is one node's cache.
type CachePruneResult ¶
type CachePruneResult struct {
DryRun bool `json:"dry_run"`
Candidates []CacheEntry `json:"candidates"`
Removed []string `json:"removed"`
Skipped []CacheSkip `json:"skipped"`
ReclaimedBytes int64 `json:"reclaimed_bytes"`
}
CachePruneResult reports a prune. With DryRun set nothing was removed and Candidates is what a real run would remove.
type CacheReport ¶
type CacheReport struct {
UnusedDays int `json:"unused_days"`
Nodes []CacheNode `json:"nodes"`
Note string `json:"note"`
}
CacheReport lists every node's model cache.
type Controller ¶
type Controller struct {
// contains filtered or unexported fields
}
Controller converges one model row to a running engine container.
type CreateInput ¶
type CreateInput struct {
Spec Spec
NodeID string
Domain string
HFToken string
// Residency is "always" (default) or "on_demand". IdleTTL 0 uses the
// platform default.
Residency string
IdleTTL time.Duration
// SwapGroup is empty (no group) or a name shared by other models on
// the same node/GPU; see store.Model.SwapGroup.
SwapGroup string
}
CreateInput is a request to deploy a model.
type CreateKeyInput ¶
CreateKeyInput is a request for a new virtual key.
type CreatedKey ¶
CreatedKey is a new key; Plaintext is shown once and never stored.
type DiskFactsFunc ¶
DiskFactsFunc reports free and total bytes of the disk holding a node's model cache. nodeID is "" for the control plane host. ok is false when the disk cannot be measured.
type Engine ¶
type Engine struct {
Name string
DefaultImage string
Port int
// CachePath is where the engine keeps downloaded weights inside the
// container; it is backed by a persistent volume.
CachePath string
// RefHelp explains the model reference format for error messages.
RefHelp string
// contains filtered or unexported fields
}
Engine describes how one inference engine runs as a container.
type EngineHealth ¶
type EngineHealth struct {
State string `json:"state"`
Summary string `json:"summary"`
Reasons []string `json:"reasons"`
}
EngineHealth is a one-line reading of the latest samples.
type EngineMetricPoint ¶
EngineMetricPoint is one stored reading.
type EngineMetricSeries ¶
type EngineMetricSeries struct {
ID string `json:"id"`
Label string `json:"label"`
Unit string `json:"unit"`
Supported bool `json:"supported"`
Latest *float64 `json:"latest"`
Points []EngineMetricPoint `json:"points"`
}
EngineMetricSeries is one metric over the window. Supported is false when the model's engine cannot expose it.
type EngineMetricsCollector ¶
type EngineMetricsCollector struct {
// contains filtered or unexported fields
}
EngineMetricsCollector scrapes each running engine's metrics endpoint and writes the readings to the telemetry store. It reaches engines the same way the readiness prober does.
func NewEngineMetricsCollector ¶
func NewEngineMetricsCollector(st EngineMetricsStore, sink SampleWriter, client *http.Client, logger *slog.Logger) *EngineMetricsCollector
NewEngineMetricsCollector builds a collector. client may be nil.
type EngineMetricsReader ¶
type EngineMetricsReader interface {
Query(ctx context.Context, resourceID, metric string, from, to time.Time) ([]telemetry.Sample, error)
}
EngineMetricsReader reads stored samples. *telemetry.DB satisfies it.
type EngineMetricsReport ¶
type EngineMetricsReport struct {
Model string `json:"model"`
Engine string `json:"engine"`
From time.Time `json:"from"`
To time.Time `json:"to"`
Collecting bool `json:"collecting"`
Note string `json:"note"`
Health EngineHealth `json:"health"`
Series []EngineMetricSeries `json:"series"`
}
EngineMetricsReport is a model's engine metrics over a window.
type EngineMetricsStore ¶
EngineMetricsStore is the model listing the collector needs.
type FitConfig ¶
type FitConfig struct {
// OverheadPercent is added to weight bytes for KV cache and buffers.
OverheadPercent float64
// FitPercent is the share of free VRAM a model may use to count as
// "fits"; above it (up to 100%) it is "tight".
FitPercent float64
// DiskHeadroomPercent is extra free disk required beyond the download.
DiskHeadroomPercent float64
}
FitConfig holds the estimation knobs.
func LoadFitConfig ¶
func LoadFitConfig() FitConfig
LoadFitConfig reads APP_MODEL_FIT_OVERHEAD_PERCENT, APP_MODEL_FIT_PERCENT and APP_MODEL_DISK_HEADROOM_PERCENT.
func (FitConfig) DiskOK ¶
DiskOK reports whether downloading bytes leaves the configured headroom. freeDisk < 0 means unknown, which counts as OK (the caller reports it).
func (FitConfig) FitVerdict ¶
FitVerdict judges weightBytes against free VRAM. freeVRAMBytes < 0 means unknown.
func (FitConfig) MarkFits ¶
func (c FitConfig) MarkFits(quants []Quant, freeVRAMBytes, freeDiskBytes int64) (name, reason string)
MarkFits sets Fit on every quant and Recommended on the best one, and returns the recommended name with a one-line reason. It picks the largest quantized variant that fits VRAM and disk, then the largest that is tight. With no VRAM facts it falls back to the conventional default.
type FitDetail ¶
type FitDetail struct {
Verdict string `json:"verdict"`
WeightsSource string `json:"weights_source"`
WeightsBytes int64 `json:"weights_bytes"`
KVBytes int64 `json:"kv_bytes"`
OverheadBytes int64 `json:"overhead_bytes"`
NeedBytes int64 `json:"need_bytes"`
FreeBytes int64 `json:"free_bytes"`
ContextTokens int `json:"context_tokens"`
ContextAssumed bool `json:"context_assumed"`
Arithmetic string `json:"arithmetic"`
Reason string `json:"reason,omitempty"`
Suggestions []string `json:"suggestions"`
}
FitDetail is the arithmetic behind a verdict.
type FitInput ¶
type FitInput struct {
Engine string
ModelRef string
Quantization string
ContextLength int
// WeightsBytes is the exact download size when known; 0 means estimate.
WeightsBytes int64
// GPUs is how many GPUs the model spreads over.
GPUs int
// FreeBytes is the total free VRAM across those GPUs; MinFreeBytes and
// MinTotalBytes describe the tightest single GPU.
FreeBytes int64
MinFreeBytes int64
MinTotalBytes int64
}
FitInput describes one model against one set of GPUs.
type FitParams ¶
type FitParams struct {
// GPUOverheadMiB is reserved per GPU for the CUDA context and buffers.
GPUOverheadMiB int64
// VLLMExtraMiB is added per GPU for vLLM's CUDA graphs and torch context.
VLLMExtraMiB int64
// DefaultContext is assumed when a model sets no context length.
DefaultContext int
// VLLMUtilization is the share of each GPU vLLM pre-allocates.
VLLMUtilization float64
// KVKiBPerToken overrides the parameter-count heuristic when positive.
KVKiBPerToken float64
}
FitParams are the VRAM estimation knobs, all environment driven.
func LoadFitParams ¶
func LoadFitParams() FitParams
LoadFitParams reads APP_MODEL_FIT_GPU_OVERHEAD_MIB, APP_MODEL_FIT_VLLM_EXTRA_MIB, APP_MODEL_FIT_DEFAULT_CONTEXT, APP_MODEL_VLLM_GPU_UTILIZATION and APP_MODEL_FIT_KV_KIB_PER_TOKEN.
type FitReport ¶
type FitReport struct {
Model string `json:"model,omitempty"`
Nodes []NodeFit `json:"nodes"`
Note string `json:"note"`
}
FitReport ranks nodes for a model, best first.
type FitRequest ¶
type FitRequest struct {
Engine string
ModelRef string
Quantization string
ContextLength int
GPUCount int
GPUDeviceIDs []string
// WeightsBytes is the exact size from a preflight, 0 to estimate.
WeightsBytes int64
// NodeID limits the check to one node; nil checks every GPU node.
NodeID *string
}
FitRequest asks whether a model fits on GPU nodes.
type GPUNode ¶
type GPUNode struct {
NodeID string
Name string
IsLocal bool
Info gpu.Info
UpdatedAt time.Time
ModelCount int
// PlacementID is the node ID as services and models record it: "" for
// the control plane's own host.
PlacementID string
Schedulable bool
Online bool
Claims []gpu.Claim
}
GPUNode is one node's GPU snapshot plus the models placed on it.
type Gateway ¶
type Gateway struct {
// contains filtered or unexported fields
}
Gateway authenticates OpenAI-compatible requests addressed to a model's host with one of the model's virtual API keys and reverse proxies them to the engine, enforcing the key's limits and metering its usage. Only an allowlist of inference and listing routes is forwarded, so engine admin APIs (Ollama pull and delete, vLLM LoRA loading) are never exposed. Request size, generation length, concurrency and upstream timeouts are bounded by GatewayLimits.
func NewGateway ¶
func NewGateway(st GatewayStore, hosts *HostResolver, logger *slog.Logger) *Gateway
NewGateway builds a Gateway. hosts maps a model to the hostnames it is served on.
func (*Gateway) Handle ¶
Handle serves r when its Host belongs to a model, returning true. It returns false without touching w for every other host.
func (*Gateway) Invalidate ¶
func (g *Gateway) Invalidate()
Invalidate makes the next request reload models and keys, so a revoked key stops working at once instead of after the cache TTL.
func (*Gateway) Middleware ¶
Middleware wraps next so requests for model hosts are handled by the gateway.
func (*Gateway) SetLimits ¶
func (g *Gateway) SetLimits(l GatewayLimits)
SetLimits replaces the request limits. Call it before serving.
func (*Gateway) SetWakeHook ¶
func (g *Gateway) SetWakeHook(fn func())
SetWakeHook registers a function called (repeatedly, cheaply) while a request waits for a model to wake, typically the reconciler's Nudge.
func (*Gateway) StartMetering ¶
func (g *Gateway) StartMetering(ctx context.Context, st UsageStore)
StartMetering flushes usage to st every flush interval until ctx ends.
type GatewayLimits ¶
type GatewayLimits struct {
MaxBodyBytes int64
MaxN int
MaxTokens int
MaxInflight int
RetryAfter time.Duration
DialTimeout time.Duration
HeaderTimeout time.Duration
IdleTimeout time.Duration
// WakeWait bounds how long a request to a sleeping on-demand model is
// held while its engine loads; zero fails fast with Retry-After.
WakeWait time.Duration
WakeRetryAfter time.Duration
// TouchInterval throttles how often gateway activity is written.
TouchInterval time.Duration
}
GatewayLimits bounds what one request may cost the engine. The limits are global: they apply to every model.
func DefaultGatewayLimits ¶
func DefaultGatewayLimits() GatewayLimits
DefaultGatewayLimits are the limits used when no environment override is set.
func LoadGatewayLimits ¶
func LoadGatewayLimits() GatewayLimits
LoadGatewayLimits reads the limits from the environment, falling back to the defaults for unset or unparsable values.
func (GatewayLimits) Summary ¶
func (l GatewayLimits) Summary() GatewayLimitsSummary
Summary returns the limits as shown to operators.
type GatewayLimitsSummary ¶
type GatewayLimitsSummary struct {
MaxBodyBytes int64 `json:"max_body_bytes"`
MaxN int `json:"max_n"`
MaxTokens int `json:"max_tokens"`
MaxInflight int `json:"max_inflight_requests"`
ResponseHeaderTimeoutS int `json:"response_header_timeout_seconds"`
StreamIdleTimeoutS int `json:"stream_idle_timeout_seconds"`
}
GatewayLimitsSummary is the read-only view of the limits shown on the model resource. A zero value means the limit is disabled.
type GatewayStore ¶
type GatewayStore interface {
ListModels(ctx context.Context) ([]store.Model, error)
ListActiveModelKeys(ctx context.Context) ([]store.ModelKey, error)
}
GatewayStore is the store surface the gateway reads.
type HFClient ¶
type HFClient struct {
// contains filtered or unexported fields
}
HFClient queries the Hub's public metadata API. It refuses internal addresses and never logs or returns the token it is given.
func NewHFClient ¶
NewHFClient builds a client. httpClient nil uses the SSRF-guarded client.
type HFConfig ¶
type HFConfig struct {
BaseURL string
Timeout time.Duration
CacheTTL time.Duration
MaxResponseBytes int64
CacheEntries int
}
HFConfig tunes the Hugging Face Hub client.
func LoadHFConfig ¶
func LoadHFConfig() HFConfig
LoadHFConfig reads APP_HF_BASE_URL, APP_HF_TIMEOUT, APP_HF_CACHE_TTL and APP_HF_MAX_RESPONSE_BYTES, falling back to defaults on missing or bad values.
type HFRepo ¶
type HFRepo struct {
ID string
Gated string
Private bool
License string
Files []HFFile
// Access is "granted", "denied" or "unknown" for a gated repo, and
// "not_required" otherwise.
Access string
}
HFRepo is the Hub metadata Preflight needs.
type HTTPProber ¶
type HTTPProber struct {
// contains filtered or unexported fields
}
HTTPProber probes engines over their HTTP API and drives Ollama model pulls in the background so a reconcile pass never blocks on a download.
type HostLister ¶
type HostLister struct {
Store GatewayStore
Hosts *HostResolver
}
HostLister is what the ingress controller needs to route model hosts.
func (HostLister) ModelHosts ¶
func (l HostLister) ModelHosts(ctx context.Context) ([]string, error)
ModelHosts returns every hostname of every live model.
type HostResolver ¶
type HostResolver struct {
// contains filtered or unexported fields
}
HostResolver computes the hostnames a model is served on: its configured domain, or the zero-config fallback derived from the control plane's public host.
func NewHostResolver ¶
func NewHostResolver(publicHost string, fallback func(publicHost, label string) (string, bool)) *HostResolver
NewHostResolver builds a HostResolver. fallback may be nil (no fallback hostnames).
type KeyLimits ¶
type KeyLimits struct {
RPM int
TPM int
TPD int
MaxParallel int
AllowPaths []string
AllowModels []string
}
KeyLimits are the optional per-key limits. Zero means unlimited and empty allow lists mean anything the engine allowlist forwards.
type KeyUsage ¶
type KeyUsage struct {
KeyID string `json:"key_id"`
Name string `json:"name"`
KeyPrefix string `json:"key_prefix"`
Status string `json:"status"`
InFlight int `json:"in_flight"`
UsageTotals
}
KeyUsage is one key's share of the window.
type MeterConfig ¶
type MeterConfig struct {
FlushInterval time.Duration
BatchSize int
MaxBuffered int
Retention time.Duration
ScanBytes int
}
MeterConfig bounds usage metering. A non-positive Retention keeps rows forever; a non-positive ScanBytes turns off token parsing.
func DefaultMeterConfig ¶
func DefaultMeterConfig() MeterConfig
DefaultMeterConfig returns the metering defaults.
func LoadMeterConfig ¶
func LoadMeterConfig() MeterConfig
LoadMeterConfig reads the metering config from the environment.
type NodeFit ¶
type NodeFit struct {
NodeID string `json:"node_id"`
Name string `json:"name"`
IsLocal bool `json:"is_local"`
Eligible bool `json:"eligible"`
// Current marks the node a deployed model already runs on.
Current bool `json:"current"`
GPUs int `json:"gpus"`
TotalBytes int64 `json:"total_bytes"`
// ReservedBytes is VRAM estimated for other models placed here that are
// not loaded yet, already subtracted from free.
ReservedBytes int64 `json:"reserved_bytes"`
FitDetail
}
NodeFit is the verdict for one node.
type NodeInfo ¶
type NodeInfo struct {
GPU gpu.Info
// BindIP is the address the engine's port is published on.
BindIP string
// DialHost is the address the control plane reaches BindIP at. Empty
// means the node is remote and not on the mesh.
DialHost string
}
NodeInfo is what the controller needs to know about a model's node.
type Option ¶
type Option func(*Controller)
Option configures a Controller.
func WithContainerPrefix ¶
WithContainerPrefix sets the container and volume name prefix (typically brand.ShortName).
func WithImages ¶
WithImages overrides engine images by engine name.
func WithSecrets ¶
WithSecrets enables resolving the model's HuggingFace token and deleting its secrets on teardown. Without it, a model with a token set stays blocked.
type PreflightDisk ¶
type PreflightDisk struct {
Status string `json:"status"`
RequiredBytes int64 `json:"required_bytes"`
FreeBytes *int64 `json:"free_bytes"`
Message string `json:"message"`
}
PreflightDisk is the disk check for the selected download.
type PreflightFile ¶
PreflightFile is one repository file.
type PreflightInput ¶
type PreflightInput struct {
// Repo is "owner/name", optionally ":quant", or a huggingface.co URL.
Repo string
Engine string
File string
Quant string
NodeID string
// GPUCount is how many GPUs the model will use; 0 or less means all.
GPUCount int
// Token is used for this request only and never stored or logged.
Token string
}
PreflightInput is a request to check a repository before deploying.
type PreflightNode ¶
type PreflightNode struct {
NodeID string `json:"node_id"`
GPUPresent bool `json:"gpu_present"`
VRAMTotalBytes *int64 `json:"vram_total_bytes"`
VRAMFreeBytes *int64 `json:"vram_free_bytes"`
DiskFreeBytes *int64 `json:"disk_free_bytes"`
DiskTotalBytes *int64 `json:"disk_total_bytes"`
}
PreflightNode is the target node's facts. Nil numbers are unknown.
type PreflightResult ¶
type PreflightResult struct {
Repo string `json:"repo"`
Status string `json:"status"`
Exists bool `json:"exists"`
Message string `json:"message"`
NextStep string `json:"next_step,omitempty"`
RetryAfterSeconds int `json:"retry_after_seconds,omitempty"`
Gated string `json:"gated,omitempty"`
Access string `json:"access,omitempty"`
Private bool `json:"private"`
License string `json:"license,omitempty"`
TotalBytes int64 `json:"total_bytes"`
FileCount int `json:"file_count"`
Files []PreflightFile `json:"files"`
FilesTruncated bool `json:"files_truncated"`
HasGGUF bool `json:"has_gguf"`
HasSafetensors bool `json:"has_safetensors"`
CompatibleEngines []string `json:"compatible_engines"`
EngineHint string `json:"engine_hint"`
Quants []Quant `json:"quants"`
RecommendedQuant string `json:"recommended_quant,omitempty"`
RecommendationNote string `json:"recommendation_note,omitempty"`
Selected *PreflightSelection `json:"selected,omitempty"`
Node PreflightNode `json:"node"`
Disk PreflightDisk `json:"disk"`
Warnings []string `json:"warnings"`
EstimateNote string `json:"estimate_note"`
Cached bool `json:"cached"`
}
PreflightResult is the outcome of Preflight. It always describes the repository as far as the Hub allowed, with Status saying how far that was.
type PreflightSelection ¶
type PreflightSelection struct {
Label string `json:"label"`
Bytes int64 `json:"bytes"`
Fit string `json:"fit"`
}
PreflightSelection is what a deploy would download.
type Quant ¶
type Quant struct {
Name string `json:"name"`
Bytes int64 `json:"bytes"`
Files []string `json:"files"`
Fit string `json:"fit"`
Recommended bool `json:"recommended"`
}
Quant is one GGUF quantization of a repository: all shards of one variant summed.
func DetectQuants ¶
DetectQuants groups GGUF files by quantization, smallest first. Split shards of one variant are summed.
type SampleWriter ¶
SampleWriter persists telemetry samples.
type SecretWriter ¶
type SecretWriter interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
DeleteAll(ctx context.Context, serviceName string) error
}
SecretWriter stores the HuggingFace token.
type Secrets ¶
type Secrets interface {
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
DeleteAll(ctx context.Context, serviceName string) error
}
Secrets is the narrow secrets surface the controller needs.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service implements model management for the API, CLI and MCP surfaces.
func NewService ¶
func NewService(st ServiceStore, secrets SecretWriter, hosts *HostResolver, localNodeID string) *Service
NewService builds a Service. secrets may be nil (HuggingFace tokens are then rejected). localNodeID identifies the control plane's own node so its GPU snapshot is found under the local key.
func (*Service) CacheEnabled ¶
CacheEnabled reports whether the cache manager is available.
func (*Service) CacheList ¶
func (s *Service) CacheList(ctx context.Context) (CacheReport, error)
CacheList reports model weight volumes with size, last use and whether each is safe to prune.
func (*Service) CachePrune ¶
func (s *Service) CachePrune(ctx context.Context, volumes []string, dryRun bool) (CachePruneResult, error)
CachePrune removes prunable volumes: not mounted, not owned by any configured model, and unused for CacheUnusedDays. volumes narrows the candidates; empty means all. With dryRun nothing is removed.
func (*Service) CreateKey ¶
func (s *Service) CreateKey(ctx context.Context, model string, in CreateKeyInput) (CreatedKey, error)
CreateKey adds a named key to a model and returns its plaintext once.
func (*Service) EngineMetrics ¶
func (s *Service) EngineMetrics(ctx context.Context, name string, window time.Duration) (EngineMetricsReport, error)
EngineMetrics returns the model's engine metrics over window.
func (*Service) GPUNodes ¶
GPUNodes lists every node that has reported a GPU snapshot, the local host first.
func (*Service) NodeGPU ¶
func (s *Service) NodeGPU(ctx context.Context, nodeID string) (info gpu.Info, known bool, err error)
NodeGPU returns the GPU snapshot of nodeID ("" or the local node ID is the control plane's host). known is false when the node has not reported yet.
func (*Service) Preflight ¶
func (s *Service) Preflight(ctx context.Context, in PreflightInput) (PreflightResult, error)
Preflight checks a Hugging Face repository against a node before a model is created. Hub failures come back as a Status, not an error.
func (*Service) PreflightEnabled ¶
PreflightEnabled reports whether Preflight can run.
func (*Service) RotateKeyByID ¶
func (s *Service) RotateKeyByID(ctx context.Context, model, id, actor string, grace *time.Duration) (CreatedKey, error)
RotateKeyByID issues a replacement for a key with the same name, limits and expiry. The old key keeps working for grace (KeyRotationGrace when nil, no grace when zero) and is then dead.
func (*Service) SetCacheBackend ¶
func (s *Service) SetCacheBackend(b CacheBackend, prefix string)
SetCacheBackend enables the cache manager. prefix is the container and volume name prefix the model controller uses.
func (*Service) SetDiskFacts ¶
func (s *Service) SetDiskFacts(fn DiskFactsFunc)
SetDiskFacts registers the source of node disk facts.
func (*Service) SetEngineMetricsReader ¶
func (s *Service) SetEngineMetricsReader(r EngineMetricsReader)
SetEngineMetricsReader enables EngineMetrics. Call once at startup.
func (*Service) SetHFToken ¶
SetHFToken stores a new HuggingFace token and restarts the model so it takes effect.
func (*Service) SetHuggingFace ¶
SetHuggingFace enables Preflight. Call once at startup.
func (*Service) SetKeyChangeHook ¶
func (s *Service) SetKeyChangeHook(fn func())
SetKeyChangeHook registers fn to run after any key is created, revoked or rotated, so the gateway can drop its cached key list.
func (*Service) SetLiveStats ¶
SetLiveStats registers a source of running request counts per key id.
func (*Service) SetLocalNodeID ¶
SetLocalNodeID tells the service which node ID is the control plane's own host. Call once at startup before serving requests.
func (*Service) SetResidency ¶
func (s *Service) SetResidency(ctx context.Context, name, residency string, idleTTL time.Duration) error
SetResidency changes a model's residency mode and idle TTL (0 keeps the platform default). Switching to on-demand counts as activity.
func (*Service) SetSwapGroup ¶
SetSwapGroup changes a model's swap group. Empty clears it.
func (*Service) Sleep ¶
Sleep marks an on-demand model idle so its engine stops on the next reconcile pass.
func (*Service) UnplacedWorkloads ¶
UnplacedWorkloads lists GPU apps and models whose own node cannot serve them and for which no other eligible GPU node has enough free GPUs.
type ServiceStore ¶
type ServiceStore interface {
SaveModel(ctx context.Context, m store.Model) error
GetModel(ctx context.Context, name string) (*store.Model, error)
ListModels(ctx context.Context) ([]store.Model, error)
DeleteModel(ctx context.Context, name string) error
MarkModelDeleting(ctx context.Context, name string) error
RotateModelAPIKey(ctx context.Context, name, hash, prefix string) error
ListModelKeys(ctx context.Context, model string) ([]store.ModelKey, error)
GetModelKey(ctx context.Context, model, id string) (*store.ModelKey, error)
CreateModelKey(ctx context.Context, k store.ModelKey) error
RevokeModelKey(ctx context.Context, model, id string, now time.Time) error
RotateModelKey(ctx context.Context, model, oldID string, next store.ModelKey, graceUntil *time.Time, now time.Time) error
ListModelUsage(ctx context.Context, model string, from, to time.Time) ([]store.ModelUsage, error)
RestartModel(ctx context.Context, name string) error
SetModelHFTokenSet(ctx context.Context, name string, set bool) error
SetModelResidency(ctx context.Context, name, residency string, idleTTLSeconds int, now time.Time) error
TouchModel(ctx context.Context, name string, at time.Time) error
SleepModel(ctx context.Context, name string) error
SetModelSwapGroup(ctx context.Context, name, group string) error
ListModelsInSwapGroup(ctx context.Context, group string) ([]store.Model, error)
GetConditions(ctx context.Context, controllerName string) ([]reconcile.Condition, error)
GetConditionsForControllers(ctx context.Context, controllerNames []string) (map[string][]reconcile.Condition, error)
GetNode(ctx context.Context, id string) (*store.Node, error)
GetNodeGPU(ctx context.Context, nodeID string) (store.NodeGPU, bool, error)
ListNodes(ctx context.Context) ([]store.Node, error)
ListNodeGPUs(ctx context.Context) (map[string]store.NodeGPU, error)
ListDesiredServices(ctx context.Context) ([]store.DesiredService, error)
}
ServiceStore is the store surface Service uses. *store.DB satisfies it.
type Spec ¶
type Spec struct {
Name string
Engine string
ModelRef string
GPUCount int
GPUDeviceIDs []string
ContextLength int
Quantization string
}
Spec is the validated user input for a model.
func SpecFromModel ¶
SpecFromModel converts a stored model into its Spec.
type Store ¶
type Store interface {
GetModel(ctx context.Context, name string) (*store.Model, error)
SetModelEndpoint(ctx context.Context, name, dial string) error
SetModelResidencyState(ctx context.Context, name, state string) error
DeleteModel(ctx context.Context, name string) error
// ListModelsInSwapGroup backs swap group eviction (residency.go's
// waitForGPUWithSwap): finding a resident sibling to stop before
// waking a model that would otherwise not fit.
ListModelsInSwapGroup(ctx context.Context, group string) ([]store.Model, error)
}
Store is the narrow store surface the controller needs.
type UsagePoint ¶
type UsagePoint struct {
Hour time.Time `json:"hour"`
UsageTotals
}
UsagePoint is one hour of usage across all keys.
type UsageReport ¶
type UsageReport struct {
Model string `json:"model"`
From time.Time `json:"from"`
To time.Time `json:"to"`
Totals UsageTotals `json:"totals"`
Series []UsagePoint `json:"series"`
Keys []KeyUsage `json:"keys"`
InFlight int `json:"in_flight"`
Note string `json:"note"`
}
UsageReport is a model's gateway usage over a window.
type UsageStore ¶
type UsageStore interface {
AddModelUsage(ctx context.Context, rows []store.ModelUsage) error
TouchModelKeys(ctx context.Context, used map[string]time.Time) error
PruneModelUsage(ctx context.Context, before time.Time) (int64, error)
}
UsageStore is the store surface the meter flushes to.
type UsageTotals ¶
type UsageTotals struct {
Requests int64 `json:"requests"`
Status2xx int64 `json:"status_2xx"`
Status4xx int64 `json:"status_4xx"`
Status5xx int64 `json:"status_5xx"`
RateLimited int64 `json:"rate_limited"`
UsageRequests int64 `json:"usage_requests"`
InputTokens int64 `json:"input_tokens"`
OutputTokens int64 `json:"output_tokens"`
BytesOut int64 `json:"bytes_out"`
AvgDurationMs int64 `json:"avg_duration_ms"`
AvgTTFTMs int64 `json:"avg_ttft_ms"`
// contains filtered or unexported fields
}
UsageTotals sums gateway usage over a set of hourly rows.
type View ¶
type View struct {
Model store.Model
Ready bool
Reason string
Message string
BaseURL string
// SwapGroup on the same node, excluding this one.
SharesGPUWith []string
}
View is a model with its reconcile status and endpoint.
type WakeStore ¶
type WakeStore interface {
GetModel(ctx context.Context, name string) (*store.Model, error)
TouchModel(ctx context.Context, name string, at time.Time) error
}
WakeStore is the optional store surface that lets the gateway wake and keep alive on-demand models. *store.DB satisfies it; a store without it leaves on-demand models unreachable while asleep.
Source Files
¶
- apikey.go
- cache.go
- controller.go
- controller_residency.go
- enginemetrics_collect.go
- enginemetrics_parse.go
- enginemetrics_report.go
- engines.go
- fit.go
- fit_service.go
- gateway.go
- gateway_keys.go
- gateway_limits.go
- gateway_meter.go
- gateway_observe.go
- gateway_paths.go
- gateway_proxy.go
- gateway_wake.go
- gpunodes.go
- hf.go
- hf_quant.go
- hosts.go
- keys.go
- preflight.go
- prober.go
- residency.go
- service.go
- swap_lock.go
- usage.go