Documentation
¶
Overview ¶
Package models provides model management capabilities for the Aleutian CLI.
Overview ¶
This package handles model verification, download orchestration, and progress display for local AI model management. It integrates with the existing ModelEnsurer and OllamaClient components in the main package.
Components ¶
- ProgressRenderer: Abstracts progress display for TTY/non-TTY/silent modes
- ModelEnsurerFactory: Factory pattern for ModelEnsurer creation
- Integration functions: Wire ModelEnsurer into CLI startup flow
Thread Safety ¶
All exported types are safe for concurrent use unless otherwise documented.
Security ¶
This package handles network downloads from external model registries. All model names are validated against injection patterns before use. Progress output is sanitized to prevent terminal escape sequence injection.
Compliance ¶
Model download operations are logged for audit purposes. The package supports enterprise allowlists for model governance (GDPR, HIPAA, CCPA compliance).
Usage ¶
This package is internal to cmd/aleutian and should not be imported from outside the module. Use the public CLI interface instead.
Related Packages ¶
- cmd/aleutian (main): Contains ModelEnsurer, OllamaClient interfaces
- cmd/aleutian/config: Configuration types
Index ¶
- Variables
- func ParseParameterSize(size string) int64
- func ValidateModelName(name string) error
- type DefaultModelAuditLogger
- func (l *DefaultModelAuditLogger) IsEnabled() bool
- func (l *DefaultModelAuditLogger) LogModelBlock(event ModelAuditEvent) error
- func (l *DefaultModelAuditLogger) LogModelPull(event ModelAuditEvent) error
- func (l *DefaultModelAuditLogger) LogModelVerify(event ModelAuditEvent) error
- func (l *DefaultModelAuditLogger) SetEnabled(enabled bool)
- type DefaultModelInfoProvider
- func (p *DefaultModelInfoProvider) EstimateTotalSize(ctx context.Context, models []string) (int64, error)
- func (p *DefaultModelInfoProvider) GetLocalModelInfo(ctx context.Context, model string) (*ModelInfo, error)
- func (p *DefaultModelInfoProvider) GetModelInfo(ctx context.Context, model string) (*ModelInfo, error)
- func (p *DefaultModelInfoProvider) GetMultipleModelInfo(ctx context.Context, models []string) (map[string]*ModelInfo, error)
- type DefaultModelManager
- func (m *DefaultModelManager) EnsureModel(ctx context.Context, model string, opts EnsureOpts) (ModelResult, error)
- func (m *DefaultModelManager) GetModelStatus(ctx context.Context, model string) (ModelStatus, error)
- func (m *DefaultModelManager) InvalidateCache()
- func (m *DefaultModelManager) ListAvailableModels(ctx context.Context) ([]LocalModelInfo, error)
- func (m *DefaultModelManager) PullModelWithProgress(ctx context.Context, model string, progressCh chan<- PullProgress) error
- func (m *DefaultModelManager) SelectOptimalModel(ctx context.Context, purpose string) (string, error)
- func (m *DefaultModelManager) VerifyModel(ctx context.Context, model string) (VerificationResult, error)
- type DefaultModelSelector
- func (s *DefaultModelSelector) AddModel(category string, entry ModelCatalogEntry)
- func (s *DefaultModelSelector) FilterModels(category string, opts SelectionOpts) []ModelCatalogEntry
- func (s *DefaultModelSelector) GetModelCatalog(category string) []ModelCatalogEntry
- func (s *DefaultModelSelector) SelectModel(ctx context.Context, category string, opts SelectionOpts) (string, error)
- func (s *DefaultModelSelector) SelectModelWithFallbacks(ctx context.Context, category string, opts SelectionOpts, maxFallbacks int) (*FallbackChain, error)
- type DefaultProgressRenderer
- func (r *DefaultProgressRenderer) Complete(ctx context.Context, operation string, success bool, message string)
- func (r *DefaultProgressRenderer) IsTTY() bool
- func (r *DefaultProgressRenderer) Render(ctx context.Context, operation, status string, completed, total int64)
- func (r *DefaultProgressRenderer) SetOutput(w io.Writer)
- type EnsureOpts
- type FallbackChain
- type HardwareDetector
- type LineProgressRenderer
- func (r *LineProgressRenderer) Complete(ctx context.Context, operation string, success bool, message string)
- func (r *LineProgressRenderer) IsTTY() bool
- func (r *LineProgressRenderer) Render(ctx context.Context, operation, status string, completed, total int64)
- func (r *LineProgressRenderer) SetOutput(w io.Writer)
- type LocalModelInfo
- type LogWriter
- type MockCompleteCall
- type MockEnsureCall
- type MockHardwareDetector
- type MockLogEntry
- type MockLogWriter
- type MockModelAuditLogger
- func (m *MockModelAuditLogger) AllEvents() []ModelAuditEvent
- func (m *MockModelAuditLogger) LogModelBlock(event ModelAuditEvent) error
- func (m *MockModelAuditLogger) LogModelPull(event ModelAuditEvent) error
- func (m *MockModelAuditLogger) LogModelVerify(event ModelAuditEvent) error
- func (m *MockModelAuditLogger) Reset()
- type MockModelInfoProvider
- func (m *MockModelInfoProvider) EstimateTotalSize(ctx context.Context, models []string) (int64, error)
- func (m *MockModelInfoProvider) GetLocalModelInfo(ctx context.Context, model string) (*ModelInfo, error)
- func (m *MockModelInfoProvider) GetModelInfo(ctx context.Context, model string) (*ModelInfo, error)
- func (m *MockModelInfoProvider) GetMultipleModelInfo(ctx context.Context, models []string) (map[string]*ModelInfo, error)
- func (m *MockModelInfoProvider) Reset()
- type MockModelManager
- func (m *MockModelManager) EnsureModel(ctx context.Context, model string, opts EnsureOpts) (ModelResult, error)
- func (m *MockModelManager) GetModelStatus(ctx context.Context, model string) (ModelStatus, error)
- func (m *MockModelManager) InvalidateCache()
- func (m *MockModelManager) ListAvailableModels(ctx context.Context) ([]LocalModelInfo, error)
- func (m *MockModelManager) PullModelWithProgress(ctx context.Context, model string, progressCh chan<- PullProgress) error
- func (m *MockModelManager) Reset()
- func (m *MockModelManager) SelectOptimalModel(ctx context.Context, purpose string) (string, error)
- func (m *MockModelManager) VerifyModel(ctx context.Context, model string) (VerificationResult, error)
- type MockModelSelector
- func (m *MockModelSelector) FilterModels(category string, opts SelectionOpts) []ModelCatalogEntry
- func (m *MockModelSelector) GetModelCatalog(category string) []ModelCatalogEntry
- func (m *MockModelSelector) Reset()
- func (m *MockModelSelector) SelectModel(ctx context.Context, category string, opts SelectionOpts) (string, error)
- func (m *MockModelSelector) SelectModelWithFallbacks(ctx context.Context, category string, opts SelectionOpts, maxFallbacks int) (*FallbackChain, error)
- type MockProgressRenderer
- func (m *MockProgressRenderer) Complete(ctx context.Context, operation string, success bool, message string)
- func (m *MockProgressRenderer) CompleteCallCount() int
- func (m *MockProgressRenderer) IsTTY() bool
- func (m *MockProgressRenderer) Render(ctx context.Context, operation, status string, completed, total int64)
- func (m *MockProgressRenderer) RenderCallCount() int
- func (m *MockProgressRenderer) Reset()
- func (m *MockProgressRenderer) SetOutput(w io.Writer)
- type MockRenderCall
- type ModelAuditEvent
- type ModelAuditLogger
- type ModelCatalogEntry
- type ModelInfo
- type ModelInfoProvider
- type ModelManager
- type ModelManagerConfig
- type ModelResult
- type ModelSelector
- type ModelStatus
- type OllamaModelInfo
- type OllamaModelLister
- type PinnedModel
- type ProgressRenderer
- type PullProgress
- type RetryPolicy
- type SelectionOpts
- type SilentProgressRenderer
- func (r *SilentProgressRenderer) Complete(ctx context.Context, operation string, success bool, message string)
- func (r *SilentProgressRenderer) IsTTY() bool
- func (r *SilentProgressRenderer) Render(ctx context.Context, operation, status string, completed, total int64)
- func (r *SilentProgressRenderer) SetOutput(w io.Writer)
- type SystemHardwareDetector
- type VerificationResult
Constants ¶
This section is empty.
Variables ¶
var DefaultModelCatalog = map[string][]ModelCatalogEntry{ "llm": { {Name: "llama3:70b", Family: "llama", MinRAM_GB: 48, RecommendedRAM_GB: 64, ContextLength: 8192, Capabilities: []string{"general", "code", "math"}, Quantization: "Q4_K_M", Priority: 100}, {Name: "qwen2:72b", Family: "qwen", MinRAM_GB: 48, RecommendedRAM_GB: 64, ContextLength: 32768, Capabilities: []string{"general", "code", "math"}, Quantization: "Q4_K_M", Priority: 95}, {Name: "mixtral:8x7b", Family: "mistral", MinRAM_GB: 32, RecommendedRAM_GB: 48, ContextLength: 32768, Capabilities: []string{"general", "code"}, Quantization: "Q4_K_M", Priority: 90}, {Name: "llama3:8b", Family: "llama", MinRAM_GB: 8, RecommendedRAM_GB: 16, ContextLength: 8192, Capabilities: []string{"general", "code"}, Quantization: "Q4_K_M", Priority: 80}, {Name: "mistral:7b", Family: "mistral", MinRAM_GB: 8, RecommendedRAM_GB: 16, ContextLength: 8192, Capabilities: []string{"general", "code"}, Quantization: "Q4_K_M", Priority: 75}, {Name: "deepseek-coder:6.7b", Family: "deepseek", MinRAM_GB: 8, RecommendedRAM_GB: 16, ContextLength: 16384, Capabilities: []string{"code"}, Quantization: "Q4_K_M", Priority: 78}, {Name: "codellama:7b", Family: "llama", MinRAM_GB: 8, RecommendedRAM_GB: 16, ContextLength: 16384, Capabilities: []string{"code"}, Quantization: "Q4_K_M", Priority: 73}, {Name: "phi3:medium", Family: "phi", MinRAM_GB: 12, RecommendedRAM_GB: 16, ContextLength: 4096, Capabilities: []string{"general", "code"}, Quantization: "Q4_K_M", Priority: 60}, {Name: "phi3:mini", Family: "phi", MinRAM_GB: 4, RecommendedRAM_GB: 8, ContextLength: 4096, Capabilities: []string{"general"}, Quantization: "Q4_K_M", Priority: 50}, {Name: "tinyllama", Family: "llama", MinRAM_GB: 2, RecommendedRAM_GB: 4, ContextLength: 2048, Capabilities: []string{"general"}, Quantization: "Q4_K_M", Priority: 20}, {Name: "gemma:2b", Family: "gemma", MinRAM_GB: 2, RecommendedRAM_GB: 4, ContextLength: 8192, Capabilities: []string{"general"}, Quantization: "Q4_K_M", Priority: 25}, }, "embedding": { {Name: "nomic-embed-text-v2-moe", Family: "nomic", MinRAM_GB: 2, RecommendedRAM_GB: 4, ContextLength: 8192, Capabilities: []string{"text"}, Quantization: "", Priority: 100}, {Name: "mxbai-embed-large", Family: "mxbai", MinRAM_GB: 2, RecommendedRAM_GB: 4, ContextLength: 512, Capabilities: []string{"text"}, Quantization: "", Priority: 90}, {Name: "all-minilm", Family: "minilm", MinRAM_GB: 1, RecommendedRAM_GB: 2, ContextLength: 512, Capabilities: []string{"text"}, Quantization: "", Priority: 50}, }, "vision": { {Name: "llava:13b", Family: "llava", MinRAM_GB: 16, RecommendedRAM_GB: 24, ContextLength: 4096, Capabilities: []string{"vision", "general"}, Quantization: "Q4_K_M", Priority: 80}, {Name: "llava:7b", Family: "llava", MinRAM_GB: 8, RecommendedRAM_GB: 16, ContextLength: 4096, Capabilities: []string{"vision", "general"}, Quantization: "Q4_K_M", Priority: 60}, }, }
DefaultModelCatalog defines known models for auto-selection. Ordered by capability (best first within each category). Values based on community benchmarks and Ollama documentation.
var ErrAllFallbacksFailed = errors.New("all fallback models failed")
ErrAllFallbacksFailed indicates all fallback models failed.
var ErrInvalidModelName = errors.New("invalid model name")
ErrInvalidModelName indicates the model name is malformed.
var ErrModelBlocked = errors.New("model is blocked by policy")
ErrModelBlocked indicates a model is on the blocklist.
var ErrModelDigestMismatch = errors.New("model digest mismatch")
ErrModelDigestMismatch indicates the model digest doesn't match expected.
ErrModelInfoUnavailable indicates model info could not be retrieved.
var ErrModelNotFound = errors.New("model not found")
ErrModelNotFound indicates the requested model does not exist.
var ErrNoSuitableModel = errors.New("no suitable model found")
ErrNoSuitableModel indicates no model matches the selection criteria.
var ErrUnknownCategory = errors.New("unknown model category")
ErrUnknownCategory indicates the model category is not recognized.
var ErrVerificationFailed = errors.New("model verification failed")
ErrVerificationFailed indicates integrity check failed.
Functions ¶
func ParseParameterSize ¶
ParseParameterSize converts parameter size strings to numeric values.
Description ¶
Parses human-readable parameter sizes like "7B", "13B", "70B" into actual counts. Handles various formats from Ollama's API.
Inputs ¶
- size: Parameter size string (e.g., "7B", "7.1B", "7000M")
Outputs ¶
- int64: Parameter count (0 if parsing fails)
Examples ¶
count := ParseParameterSize("7B") // 7_000_000_000
count := ParseParameterSize("70M") // 70_000_000
count := ParseParameterSize("1.5B") // 1_500_000_000
Limitations ¶
- Returns 0 for unrecognized formats (does not error)
- Only handles K, M, B suffixes
func ValidateModelName ¶
ValidateModelName checks if a model name is valid.
Description ¶
Validates that the model name follows Ollama naming conventions. Model names must:
- Start with alphanumeric character
- Contain only alphanumeric, dash, underscore, dot
- Optionally have namespace prefix (name/model)
- Optionally have tag suffix (:tag)
- Be at most 256 characters
Inputs ¶
- name: Model name to validate
Outputs ¶
- error: nil if valid, ErrInvalidModelName with details if not
Examples ¶
if err := ValidateModelName("llama3:8b"); err != nil {
return err
}
Security ¶
This validation prevents injection attacks through model names. Always validate before using model names in URLs or paths.
Types ¶
type DefaultModelAuditLogger ¶
type DefaultModelAuditLogger struct {
// contains filtered or unexported fields
}
DefaultModelAuditLogger implements ModelAuditLogger using LogWriter.
Description ¶
Production implementation that writes audit events to the configured log destination. Events are formatted as structured JSON.
Thread Safety ¶
DefaultModelAuditLogger is safe for concurrent use.
Configuration ¶
Audit logging can be disabled via the enabled flag.
func NewDefaultModelAuditLogger ¶
func NewDefaultModelAuditLogger(writer LogWriter) *DefaultModelAuditLogger
NewDefaultModelAuditLogger creates an audit logger with the given writer.
Description ¶
Creates an enabled audit logger that writes to the provided LogWriter. If writer is nil, creates a no-op logger.
Inputs ¶
- writer: Log destination (nil for no-op)
Outputs ¶
- *DefaultModelAuditLogger: Ready-to-use logger
Examples ¶
logger := NewDefaultModelAuditLogger(diagnosticsCollector) logger.LogModelPull(event)
Assumptions ¶
- Writer is configured for appropriate log rotation
func (*DefaultModelAuditLogger) IsEnabled ¶
func (l *DefaultModelAuditLogger) IsEnabled() bool
IsEnabled returns whether audit logging is active.
Description ¶
Checks if audit logging is currently enabled.
Outputs ¶
- bool: True if logging is enabled
Examples ¶
if logger.IsEnabled() {
// Logging is active
}
func (*DefaultModelAuditLogger) LogModelBlock ¶
func (l *DefaultModelAuditLogger) LogModelBlock(event ModelAuditEvent) error
LogModelBlock records a blocked model request.
Description ¶
Writes a structured audit log entry for blocked model requests. These events are logged at "warn" level for visibility.
Inputs ¶
- event: Audit event details
Outputs ¶
- error: Always nil (logging failures are silent)
Examples ¶
logger.LogModelBlock(ModelAuditEvent{
Action: "block",
Model: "unauthorized",
Success: false,
ErrorMessage: "not in allowlist",
})
func (*DefaultModelAuditLogger) LogModelPull ¶
func (l *DefaultModelAuditLogger) LogModelPull(event ModelAuditEvent) error
LogModelPull records a model download operation.
Description ¶
Writes a structured audit log entry for model pull operations. Automatically adds timestamp and host info if not present.
Inputs ¶
- event: Audit event details
Outputs ¶
- error: Always nil (logging failures are silent)
Examples ¶
logger.LogModelPull(ModelAuditEvent{
Action: "pull_complete",
Model: "llama3:8b",
Success: true,
})
Limitations ¶
- Errors are silently ignored to not block operations
func (*DefaultModelAuditLogger) LogModelVerify ¶
func (l *DefaultModelAuditLogger) LogModelVerify(event ModelAuditEvent) error
LogModelVerify records an integrity verification operation.
Description ¶
Writes a structured audit log entry for model verification.
Inputs ¶
- event: Audit event details
Outputs ¶
- error: Always nil (logging failures are silent)
Examples ¶
logger.LogModelVerify(ModelAuditEvent{
Action: "verify",
Model: "llama3:8b",
Success: true,
Digest: "sha256:abc123",
})
func (*DefaultModelAuditLogger) SetEnabled ¶
func (l *DefaultModelAuditLogger) SetEnabled(enabled bool)
SetEnabled enables or disables audit logging.
Description ¶
Allows runtime control of audit logging. When disabled, all Log* methods become no-ops.
Inputs ¶
- enabled: Whether logging should be active
Examples ¶
logger.SetEnabled(false) // Disable audit logging logger.SetEnabled(true) // Re-enable
type DefaultModelInfoProvider ¶
type DefaultModelInfoProvider struct {
// contains filtered or unexported fields
}
DefaultModelInfoProvider implements ModelInfoProvider using Ollama.
Description ¶
Production implementation that retrieves model information from a local Ollama server. Uses the /api/tags endpoint for local models.
Thread Safety ¶
DefaultModelInfoProvider is safe for concurrent use via internal mutex.
Security ¶
- All model names are validated before use
- Network requests respect context cancellation
- No sensitive data is logged
func NewDefaultModelInfoProvider ¶
func NewDefaultModelInfoProvider(client OllamaModelLister) *DefaultModelInfoProvider
NewDefaultModelInfoProvider creates a ModelInfoProvider using Ollama.
Description ¶
Creates a provider that queries the local Ollama server for model information. Caches results for efficiency.
Inputs ¶
- client: OllamaModelLister for API access
Outputs ¶
- *DefaultModelInfoProvider: Ready-to-use provider
Examples ¶
client := NewOllamaClient("http://localhost:11434")
// Wrap to implement OllamaModelLister
provider := NewDefaultModelInfoProvider(wrappedClient)
Assumptions ¶
- Client is non-nil and configured
func (*DefaultModelInfoProvider) EstimateTotalSize ¶
func (p *DefaultModelInfoProvider) EstimateTotalSize(ctx context.Context, models []string) (int64, error)
EstimateTotalSize calculates total download size for models.
Description ¶
Sums the sizes of all models in the list, excluding models that are already installed locally.
Inputs ¶
- ctx: Context for cancellation
- models: List of model names to estimate
Outputs ¶
- int64: Total bytes to download
- error: If size estimation fails
Examples ¶
totalSize, err := provider.EstimateTotalSize(ctx, []string{"llama3:8b", "phi3"})
fmt.Printf("Will download approximately %s\n", formatBytes(totalSize))
Limitations ¶
- Returns 0 for unknown models (no error, assumes small)
func (*DefaultModelInfoProvider) GetLocalModelInfo ¶
func (p *DefaultModelInfoProvider) GetLocalModelInfo(ctx context.Context, model string) (*ModelInfo, error)
GetLocalModelInfo retrieves metadata for a locally installed model.
Description ¶
Gets information about a model already present on disk by querying the Ollama server's model list.
Inputs ¶
- ctx: Context for cancellation
- model: Model name
Outputs ¶
- *ModelInfo: Local model metadata
- error: ErrModelNotFound if not installed, other errors
Examples ¶
info, err := provider.GetLocalModelInfo(ctx, "llama3:8b")
if err != nil {
fmt.Println("Model not installed locally")
}
Limitations ¶
- Requires Ollama to be running
func (*DefaultModelInfoProvider) GetModelInfo ¶
func (p *DefaultModelInfoProvider) GetModelInfo(ctx context.Context, model string) (*ModelInfo, error)
GetModelInfo retrieves metadata for a model.
Description ¶
First checks if the model is available locally, then returns its info. For remote-only models, this implementation returns ErrModelNotFound as it only has access to local model information.
Inputs ¶
- ctx: Context for cancellation/timeout
- model: Model name (e.g., "llama3:8b")
Outputs ¶
- *ModelInfo: Model metadata (nil if not found)
- error: ErrModelNotFound, ErrInvalidModelName, or other errors
Examples ¶
info, err := provider.GetModelInfo(ctx, "llama3:8b")
if errors.Is(err, ErrModelNotFound) {
fmt.Println("Model not available")
}
Limitations ¶
- Only returns info for locally installed models
- Does not query remote registry
func (*DefaultModelInfoProvider) GetMultipleModelInfo ¶
func (p *DefaultModelInfoProvider) GetMultipleModelInfo(ctx context.Context, models []string) (map[string]*ModelInfo, error)
GetMultipleModelInfo retrieves metadata for multiple models.
Description ¶
Batch operation for getting info on multiple models. Uses a single cache refresh for efficiency.
Inputs ¶
- ctx: Context for cancellation
- models: List of model names
Outputs ¶
- map[string]*ModelInfo: Model name to info (nil entry if not found)
- error: General failures (individual model failures are nil entries)
Examples ¶
infos, err := provider.GetMultipleModelInfo(ctx, []string{"llama3:8b", "phi3"})
for name, info := range infos {
if info == nil {
fmt.Printf("%s: not found\n", name)
}
}
type DefaultModelManager ¶
type DefaultModelManager struct {
// contains filtered or unexported fields
}
DefaultModelManager implements ModelManager.
Description ¶
Production implementation that integrates ModelQuerier, ModelSelector, and ModelAuditLogger to provide complete model management.
Thread Safety ¶
DefaultModelManager is safe for concurrent use.
Caching ¶
ListAvailableModels results are cached for 24 hours.
func NewDefaultModelManager ¶
func NewDefaultModelManager(cfg ModelManagerConfig) (*DefaultModelManager, error)
NewDefaultModelManager creates a configured ModelManager.
Description ¶
Creates a DefaultModelManager with the provided configuration. Uses sensible defaults for optional fields.
Inputs ¶
- cfg: Configuration options
Outputs ¶
- *DefaultModelManager: Ready-to-use manager
- error: Configuration error
Examples ¶
manager, err := NewDefaultModelManager(ModelManagerConfig{
Querier: querier,
Selector: selector,
})
Limitations ¶
- Requires non-nil Querier and Selector
Assumptions ¶
- Ollama is running at BaseURL
func (*DefaultModelManager) EnsureModel ¶
func (m *DefaultModelManager) EnsureModel(ctx context.Context, model string, opts EnsureOpts) (ModelResult, error)
EnsureModel verifies a model exists, pulling if needed.
Description ¶
Implements ModelManager.EnsureModel with retry logic, fallback chains, and audit logging.
Inputs ¶
- ctx: Context for cancellation and timeout
- model: Model identifier
- opts: Configuration options
Outputs ¶
- ModelResult: Operation outcome
- error: Operation failure
Examples ¶
result, err := manager.EnsureModel(ctx, "llama3:8b", EnsureOpts{
AllowPull: true,
})
Limitations ¶
- Blocked models fail immediately without retry
Assumptions ¶
- Context deadline allows for retries
func (*DefaultModelManager) GetModelStatus ¶
func (m *DefaultModelManager) GetModelStatus(ctx context.Context, model string) (ModelStatus, error)
GetModelStatus returns current model status.
Description ¶
Checks model state including pull status and blocklist.
Inputs ¶
- ctx: Context for cancellation
- model: Model identifier
Outputs ¶
- ModelStatus: Current status
- error: Query failure
Examples ¶
status, err := manager.GetModelStatus(ctx, "llama3:8b")
Limitations ¶
- Status is point-in-time snapshot
Assumptions ¶
- Ollama API is available
func (*DefaultModelManager) InvalidateCache ¶
func (m *DefaultModelManager) InvalidateCache()
InvalidateCache clears the model list cache.
Description ¶
Forces the next ListAvailableModels call to query fresh data.
Inputs ¶
None.
Outputs ¶
None.
Examples ¶
manager.InvalidateCache()
Limitations ¶
- Does not affect in-flight requests
Assumptions ¶
- None
func (*DefaultModelManager) ListAvailableModels ¶
func (m *DefaultModelManager) ListAvailableModels(ctx context.Context) ([]LocalModelInfo, error)
ListAvailableModels returns all locally available models.
Description ¶
Queries Ollama for local models. Results are cached for 24 hours.
Inputs ¶
- ctx: Context for cancellation
Outputs ¶
- []LocalModelInfo: Available models
- error: Query failure
Examples ¶
models, err := manager.ListAvailableModels(ctx)
Limitations ¶
- Cache may be stale up to 24 hours
Assumptions ¶
- Ollama API is available
func (*DefaultModelManager) PullModelWithProgress ¶
func (m *DefaultModelManager) PullModelWithProgress(ctx context.Context, model string, progressCh chan<- PullProgress) error
PullModelWithProgress pulls a model with progress reporting.
Description ¶
Downloads a model and sends progress updates to the channel.
Inputs ¶
- ctx: Context for cancellation
- model: Model identifier
- progressCh: Channel for progress updates
Outputs ¶
- error: Download failure
Examples ¶
progressCh := make(chan PullProgress, 100) err := manager.PullModelWithProgress(ctx, "llama3:8b", progressCh)
Limitations ¶
- Caller must read from progressCh to prevent blocking
Assumptions ¶
- Sufficient disk space available
func (*DefaultModelManager) SelectOptimalModel ¶
func (m *DefaultModelManager) SelectOptimalModel(ctx context.Context, purpose string) (string, error)
SelectOptimalModel auto-selects the best model for a purpose.
Description ¶
Delegates to the configured ModelSelector and validates against allowlist.
Inputs ¶
- ctx: Context for cancellation
- purpose: Intended use case
Outputs ¶
- string: Selected model identifier
- error: Selection failure
Examples ¶
model, err := manager.SelectOptimalModel(ctx, "chat")
Limitations ¶
- Selected model may be blocked by allowlist
Assumptions ¶
- Selector is properly configured
func (*DefaultModelManager) VerifyModel ¶
func (m *DefaultModelManager) VerifyModel(ctx context.Context, model string) (VerificationResult, error)
VerifyModel checks model integrity using SHA-256.
Description ¶
Compares the model's digest against the expected value.
Inputs ¶
- ctx: Context for cancellation
- model: Model identifier
Outputs ¶
- VerificationResult: Verification outcome
- error: Operation failure
Examples ¶
result, err := manager.VerifyModel(ctx, "llama3:8b")
Limitations ¶
- Requires model to exist locally
Assumptions ¶
- Model was previously pulled
type DefaultModelSelector ¶
type DefaultModelSelector struct {
// contains filtered or unexported fields
}
DefaultModelSelector implements ModelSelector with a static catalog.
Description ¶
Production implementation that selects models based on:
- Available system RAM
- Required capabilities
- User preferences (quantization, family)
Thread Safety ¶
DefaultModelSelector is safe for concurrent use via internal mutex.
func NewDefaultModelSelector ¶
func NewDefaultModelSelector(hardware HardwareDetector) *DefaultModelSelector
NewDefaultModelSelector creates a selector with the default catalog.
Description ¶
Creates a selector using DefaultModelCatalog. If hardware is nil, a SystemHardwareDetector will be created to detect actual RAM.
Inputs ¶
- hardware: Hardware detector (nil for auto-detection)
Outputs ¶
- *DefaultModelSelector: Ready-to-use selector
Examples ¶
// Auto-detect hardware
selector := NewDefaultModelSelector(nil)
model, err := selector.SelectModel(ctx, "llm", SelectionOpts{})
// Custom hardware detector
detector := &MockHardwareDetector{TotalRAM: 32, AvailableRAM: 24}
selector := NewDefaultModelSelector(detector)
Assumptions ¶
- DefaultModelCatalog is populated
func NewDefaultModelSelectorWithCatalog ¶
func NewDefaultModelSelectorWithCatalog(catalog map[string][]ModelCatalogEntry, hardware HardwareDetector) *DefaultModelSelector
NewDefaultModelSelectorWithCatalog creates a selector with a custom catalog.
Description ¶
Allows providing a custom model catalog for testing or specialized use.
Inputs ¶
- catalog: Custom model catalog
- hardware: Hardware detector (nil for auto-detection)
Outputs ¶
- *DefaultModelSelector: Ready-to-use selector
Examples ¶
catalog := map[string][]ModelCatalogEntry{
"llm": {{Name: "custom:7b", MinRAM_GB: 8, Priority: 100}},
}
selector := NewDefaultModelSelectorWithCatalog(catalog, nil)
Assumptions ¶
- Catalog is non-nil and populated
func (*DefaultModelSelector) AddModel ¶
func (s *DefaultModelSelector) AddModel(category string, entry ModelCatalogEntry)
AddModel adds a model to the catalog.
Description ¶
Adds a new model entry to the specified category. Used for testing or dynamic catalog updates.
Inputs ¶
- category: Target category
- entry: Model to add
Examples ¶
selector.AddModel("llm", ModelCatalogEntry{
Name: "custom:7b",
MinRAM_GB: 8,
Priority: 50,
})
func (*DefaultModelSelector) FilterModels ¶
func (s *DefaultModelSelector) FilterModels(category string, opts SelectionOpts) []ModelCatalogEntry
FilterModels returns models matching the selection criteria.
Description ¶
Applies all constraints from opts to filter the catalog. Does not rank results, just returns all matches.
Inputs ¶
- category: Model category
- opts: Filter criteria
Outputs ¶
- []ModelCatalogEntry: Matching models
Examples ¶
matches := selector.FilterModels("llm", SelectionOpts{
MaxRAM_GB: 16,
RequiredCapabilities: []string{"code"},
})
Limitations ¶
- Returns nil for unknown categories
func (*DefaultModelSelector) GetModelCatalog ¶
func (s *DefaultModelSelector) GetModelCatalog(category string) []ModelCatalogEntry
GetModelCatalog returns the catalog for a category.
Description ¶
Returns a copy of the catalog entries for the given category. Unknown categories return nil.
Inputs ¶
- category: Model category (case-insensitive)
Outputs ¶
- []ModelCatalogEntry: Models in the catalog (copy)
Examples ¶
catalog := selector.GetModelCatalog("llm")
fmt.Printf("Found %d LLM models\n", len(catalog))
Limitations ¶
- Returns nil for unknown categories
func (*DefaultModelSelector) SelectModel ¶
func (s *DefaultModelSelector) SelectModel(ctx context.Context, category string, opts SelectionOpts) (string, error)
SelectModel chooses the best model for a category.
Description ¶
Filters catalog by constraints, sorts by priority, returns best match. Uses system RAM to determine which models can run.
Inputs ¶
- ctx: Context for cancellation
- category: Model category ("llm", "embedding")
- opts: Selection options
Outputs ¶
- string: Selected model name
- error: ErrNoSuitableModel if no matches
Examples ¶
model, err := selector.SelectModel(ctx, "llm", SelectionOpts{})
// model = "llama3:8b" (if 16GB RAM available)
Limitations ¶
- Returns error if no models match constraints
Assumptions ¶
- Category exists in catalog
func (*DefaultModelSelector) SelectModelWithFallbacks ¶
func (s *DefaultModelSelector) SelectModelWithFallbacks(ctx context.Context, category string, opts SelectionOpts, maxFallbacks int) (*FallbackChain, error)
SelectModelWithFallbacks selects a model with fallback options.
Description ¶
Returns the best model plus alternatives ordered by priority. Fallbacks are models that also meet criteria but have lower priority.
Inputs ¶
- ctx: Context for cancellation
- category: Model category
- opts: Selection options
- maxFallbacks: Maximum fallback models to return
Outputs ¶
- *FallbackChain: Primary model with fallbacks
- error: ErrNoSuitableModel if no matches
Examples ¶
chain, err := selector.SelectModelWithFallbacks(ctx, "llm", opts, 2) // chain.Primary = "llama3:8b" // chain.Fallbacks = ["phi3:mini", "tinyllama"]
Limitations ¶
- Returns at most maxFallbacks alternatives
Assumptions ¶
- maxFallbacks >= 0
type DefaultProgressRenderer ¶
type DefaultProgressRenderer struct {
// contains filtered or unexported fields
}
DefaultProgressRenderer displays progress with a visual progress bar.
Description ¶
This implementation is designed for interactive TTY terminals. It uses carriage returns to update progress in place and displays a visual progress bar with percentage, transfer rate, and ETA.
Use this when the terminal supports ANSI escape codes and carriage returns. For CI/non-interactive environments, use LineProgressRenderer instead.
Thread Safety ¶
Safe for concurrent use. Uses mutex to protect state.
Rate Limiting ¶
Updates are rate-limited to 10 per second to prevent terminal flicker.
func NewDefaultProgressRenderer ¶
func NewDefaultProgressRenderer(w io.Writer) *DefaultProgressRenderer
NewDefaultProgressRenderer creates a new TTY progress renderer.
Description ¶
Creates a renderer optimized for interactive terminals with progress bars. Assumes the output supports ANSI escape codes and carriage returns. Use LineProgressRenderer for CI/non-interactive environments.
Inputs ¶
- w: Writer for progress output (typically os.Stdout)
Outputs ¶
- *DefaultProgressRenderer: Configured renderer
Examples ¶
renderer := NewDefaultProgressRenderer(os.Stdout) renderer.Render(ctx, "download", "starting", 0, 100)
Limitations ¶
- Assumes terminal supports ANSI escape codes
- Use LineProgressRenderer for environments without ANSI support
Assumptions ¶
- Writer is valid and writable
- Terminal supports carriage return (\r) for in-place updates
func (*DefaultProgressRenderer) Complete ¶
func (r *DefaultProgressRenderer) Complete(ctx context.Context, operation string, success bool, message string)
Complete implements ProgressRenderer.
Description ¶
Marks an operation as finished and outputs final status.
Inputs ¶
- ctx: Context (unused but required by interface)
- operation: Operation identifier
- success: Whether operation succeeded
- message: Final status message
Outputs ¶
None (writes to configured output).
Examples ¶
renderer.Complete(ctx, "download", true, "completed successfully")
Limitations ¶
- Silently returns if output is nil
Assumptions ¶
- Operation was previously started with Render
func (*DefaultProgressRenderer) IsTTY ¶
func (r *DefaultProgressRenderer) IsTTY() bool
IsTTY implements ProgressRenderer.
Description ¶
Returns true because DefaultProgressRenderer is designed for TTY environments. Use LineProgressRenderer for non-TTY environments.
Inputs ¶
None.
Outputs ¶
- bool: Always true for DefaultProgressRenderer
Examples ¶
if renderer.IsTTY() {
// Use ANSI colors
}
Limitations ¶
None.
Assumptions ¶
- Caller has chosen this renderer because output supports TTY
func (*DefaultProgressRenderer) Render ¶
func (r *DefaultProgressRenderer) Render(ctx context.Context, operation, status string, completed, total int64)
Render implements ProgressRenderer.
Description ¶
Updates the progress display for the given operation. Handles rate limiting and delegates to TTY or non-TTY rendering based on terminal detection.
Inputs ¶
- ctx: Context for cancellation
- operation: Operation identifier
- status: Current status text
- completed: Bytes completed
- total: Total bytes (0 if unknown)
Outputs ¶
None (writes to configured output).
Examples ¶
renderer.Render(ctx, "pulling model", "downloading", 1024, 4096)
Limitations ¶
- Rate limited to 10 updates/second
- Silently returns if context is cancelled
- Silently returns if output is nil
Assumptions ¶
- Completed <= Total when Total > 0
- Operation names are reasonably short (<100 chars)
func (*DefaultProgressRenderer) SetOutput ¶
func (r *DefaultProgressRenderer) SetOutput(w io.Writer)
SetOutput implements ProgressRenderer.
Description ¶
Reconfigures the output destination.
Inputs ¶
- w: New output writer (nil disables output)
Outputs ¶
None (modifies internal state).
Examples ¶
renderer.SetOutput(os.Stderr) renderer.SetOutput(nil) // disable output
Limitations ¶
None.
Assumptions ¶
- Writer supports ANSI escape codes for TTY rendering
type EnsureOpts ¶
type EnsureOpts struct {
// AllowPull enables downloading if model not present.
// Default: true (when opts is zero-value)
AllowPull bool
// VerifyIntegrity enables SHA-256 verification after pull.
VerifyIntegrity bool
// FallbackModels lists alternatives to try if primary fails.
// Tried sequentially in order.
FallbackModels []string
// Timeout overrides default operation timeout.
// Zero uses manager's default timeout.
Timeout time.Duration
// ForceRefresh re-pulls even if model is present.
ForceRefresh bool
// RetryPolicy configures retry behavior for network failures.
// Nil uses default policy.
RetryPolicy *RetryPolicy
}
EnsureOpts configures model ensure behavior.
Description ¶
Options for controlling how EnsureModel behaves, including whether to pull missing models, verify integrity, and handle failures.
Defaults ¶
Zero-value EnsureOpts enables pulling but disables verification.
type FallbackChain ¶
type FallbackChain struct {
// Primary is the preferred model to use
Primary string
// Fallbacks are tried in order if primary fails
Fallbacks []string
// StopOnFirst stops at first successful model
// When false, verifies all models are available before proceeding
StopOnFirst bool
}
FallbackChain defines an ordered list of models to try.
Description ¶
When the primary model fails (download error, OOM, etc.), the system tries each fallback in order until one succeeds. This provides resilience for model availability.
Thread Safety ¶
FallbackChain is immutable after creation and safe for concurrent read access.
Configuration ¶
Fallback chains are configured in YAML:
fallback_chains:
llm:
primary: "llama3:70b"
fallbacks:
- "llama3:8b"
- "phi3:mini"
func (*FallbackChain) IsEmpty ¶
func (c *FallbackChain) IsEmpty() bool
IsEmpty returns true if the chain has no models.
Description ¶
Checks if both primary and fallbacks are empty.
Outputs ¶
- bool: True if no models configured
Examples ¶
chain := &FallbackChain{}
fmt.Println(chain.IsEmpty()) // true
func (*FallbackChain) Len ¶
func (c *FallbackChain) Len() int
Len returns the total number of models in the chain.
Description ¶
Returns count of primary (if set) plus all fallbacks.
Outputs ¶
- int: Total number of models
Examples ¶
chain := &FallbackChain{Primary: "llama3:8b", Fallbacks: []string{"phi3", "tinyllama"}}
fmt.Println(chain.Len()) // 3
func (*FallbackChain) Models ¶
func (c *FallbackChain) Models() []string
Models returns all models in the chain (primary + fallbacks).
Description ¶
Returns a slice containing the primary model followed by all fallbacks. The returned slice is a new allocation and can be safely modified.
Outputs ¶
- []string: All models in priority order
Examples ¶
chain := &FallbackChain{Primary: "llama3:8b", Fallbacks: []string{"phi3"}}
models := chain.Models() // ["llama3:8b", "phi3"]
func (*FallbackChain) Validate ¶
func (c *FallbackChain) Validate() error
Validate checks if the chain configuration is valid.
Description ¶
Validates that:
- At least one model is configured
- All model names are valid format
- No duplicate models in the chain
Outputs ¶
- error: Validation error, nil if valid
Examples ¶
if err := chain.Validate(); err != nil {
return fmt.Errorf("invalid fallback chain: %w", err)
}
type HardwareDetector ¶
type HardwareDetector interface {
// GetAvailableRAM_GB returns available RAM in gigabytes.
//
// # Description
//
// Returns the amount of RAM currently available for use.
// This accounts for memory already in use by other processes.
//
// # Outputs
//
// - int: Available RAM in GB (rounded down)
//
// # Limitations
//
// - Platform-specific implementation
// - Returns estimate, actual availability may vary
GetAvailableRAM_GB() int
// GetTotalRAM_GB returns total system RAM in gigabytes.
//
// # Description
//
// Returns the total physical RAM installed in the system.
//
// # Outputs
//
// - int: Total RAM in GB (rounded down)
//
// # Limitations
//
// - Does not account for reserved memory
GetTotalRAM_GB() int
}
HardwareDetector provides system hardware information.
Description ¶
Interface for detecting system resources. Used by ModelSelector to determine which models can run on the current hardware.
Thread Safety ¶
Implementations must be safe for concurrent use.
type LineProgressRenderer ¶
type LineProgressRenderer struct {
// contains filtered or unexported fields
}
LineProgressRenderer displays progress as individual log lines.
Description ¶
This implementation is designed for non-interactive environments like CI pipelines. It emits progress as separate lines without terminal escape codes.
Thread Safety ¶
Safe for concurrent use. Uses mutex to protect state.
Rate Limiting ¶
Updates are rate-limited to 1 per 5 seconds to prevent log flooding.
func NewLineProgressRenderer ¶
func NewLineProgressRenderer(w io.Writer) *LineProgressRenderer
NewLineProgressRenderer creates a new line-based progress renderer.
Description ¶
Creates a renderer for CI/non-TTY environments that emits progress as separate log lines with timestamps.
Inputs ¶
- w: Writer for progress output
Outputs ¶
- *LineProgressRenderer: Configured renderer
Examples ¶
renderer := NewLineProgressRenderer(os.Stdout)
Limitations ¶
- Rate limited to 1 update per 5 seconds per operation
Assumptions ¶
- Writer is valid and writable
func (*LineProgressRenderer) Complete ¶
func (r *LineProgressRenderer) Complete(ctx context.Context, operation string, success bool, message string)
Complete implements ProgressRenderer.
Description ¶
Outputs a final completion log line.
Inputs ¶
- ctx: Context (unused)
- operation: Operation identifier
- success: Whether operation succeeded
- message: Final status message
Outputs ¶
None (writes to configured output).
Examples ¶
renderer.Complete(ctx, "download", true, "completed")
Limitations ¶
- Silently returns if output is nil
Assumptions ¶
None.
func (*LineProgressRenderer) IsTTY ¶
func (r *LineProgressRenderer) IsTTY() bool
IsTTY implements ProgressRenderer.
Description ¶
Always returns false for line-based renderer.
Inputs ¶
None.
Outputs ¶
- bool: Always false
Examples ¶
isTTY := renderer.IsTTY() // false
Limitations ¶
None.
Assumptions ¶
None.
func (*LineProgressRenderer) Render ¶
func (r *LineProgressRenderer) Render(ctx context.Context, operation, status string, completed, total int64)
Render implements ProgressRenderer.
Description ¶
Outputs progress as timestamped log lines. Rate limited per operation.
Inputs ¶
- ctx: Context for cancellation
- operation: Operation identifier
- status: Current status text
- completed: Bytes completed
- total: Total bytes (0 if unknown)
Outputs ¶
None (writes to configured output).
Examples ¶
renderer.Render(ctx, "download", "downloading", 1024, 4096)
Limitations ¶
- Rate limited to 1 update per 5 seconds per operation
- Silently returns if context is cancelled
Assumptions ¶
- Completed <= Total when Total > 0
func (*LineProgressRenderer) SetOutput ¶
func (r *LineProgressRenderer) SetOutput(w io.Writer)
SetOutput implements ProgressRenderer.
Description ¶
Reconfigures the output destination.
Inputs ¶
- w: New output writer (nil disables output)
Outputs ¶
None (modifies internal state).
Examples ¶
renderer.SetOutput(os.Stderr)
Limitations ¶
None.
Assumptions ¶
None.
type LocalModelInfo ¶
type LocalModelInfo struct {
// Name is the model name (e.g., "llama3").
Name string
// Tag is the model tag (e.g., "8b", "latest").
Tag string
// Digest is the SHA-256 digest.
Digest string
// Size is the model size in bytes.
Size int64
// ModifiedAt is when the model was last modified.
ModifiedAt time.Time
// Families lists model families (e.g., ["llama"]).
Families []string
// Parameters describes parameter count (e.g., "8B").
Parameters string
// Quantization describes quantization level (e.g., "Q4_0").
Quantization string
}
LocalModelInfo describes a locally available model.
Description ¶
Contains metadata about a model that exists on the local system.
func (*LocalModelInfo) FullName ¶
func (m *LocalModelInfo) FullName() string
FullName returns the complete model identifier.
Description ¶
Combines Name and Tag into the standard format.
Inputs ¶
None.
Outputs ¶
- string: Full model name (e.g., "llama3:8b")
Examples ¶
info := LocalModelInfo{Name: "llama3", Tag: "8b"}
fmt.Println(info.FullName()) // "llama3:8b"
Limitations ¶
- Returns name only if tag is empty or "latest"
Assumptions ¶
- Name is non-empty
type LogWriter ¶
type LogWriter interface {
// WriteLog writes a log entry with the given level.
//
// # Inputs
//
// - level: Log level ("info", "warn", "error")
// - message: Log message
// - fields: Structured fields as JSON
WriteLog(level, message string, fields []byte)
}
LogWriter abstracts log output for audit events.
Description ¶
Interface for writing audit log entries. Allows plugging in different log destinations (file, syslog, DiagnosticsCollector).
Thread Safety ¶
Implementations must be safe for concurrent use.
type MockCompleteCall ¶
MockCompleteCall records a Complete call for test verification.
type MockEnsureCall ¶
type MockEnsureCall struct {
Model string
Opts EnsureOpts
}
MockEnsureCall records an EnsureModel call.
type MockHardwareDetector ¶
MockHardwareDetector implements HardwareDetector for testing.
Description ¶
Simple test double with configurable RAM values.
Examples ¶
mock := &MockHardwareDetector{TotalRAM: 32, AvailableRAM: 24}
selector := NewDefaultModelSelector(mock)
func (*MockHardwareDetector) GetAvailableRAM_GB ¶
func (m *MockHardwareDetector) GetAvailableRAM_GB() int
GetAvailableRAM_GB implements HardwareDetector.
func (*MockHardwareDetector) GetTotalRAM_GB ¶
func (m *MockHardwareDetector) GetTotalRAM_GB() int
GetTotalRAM_GB implements HardwareDetector.
type MockLogEntry ¶
MockLogEntry captures a single log write.
type MockLogWriter ¶
type MockLogWriter struct {
Entries []MockLogEntry
// contains filtered or unexported fields
}
MockLogWriter implements LogWriter for testing.
Description ¶
Simple test double that captures log entries.
func (*MockLogWriter) WriteLog ¶
func (w *MockLogWriter) WriteLog(level, message string, fields []byte)
WriteLog implements LogWriter.
type MockModelAuditLogger ¶
type MockModelAuditLogger struct {
// Function overrides
LogModelPullFunc func(event ModelAuditEvent) error
LogModelVerifyFunc func(event ModelAuditEvent) error
LogModelBlockFunc func(event ModelAuditEvent) error
// Recorded events
PullEvents []ModelAuditEvent
VerifyEvents []ModelAuditEvent
BlockEvents []ModelAuditEvent
// DefaultErr is returned if set and no func override
DefaultErr error
// contains filtered or unexported fields
}
MockModelAuditLogger implements ModelAuditLogger for testing.
Description ¶
Test double that records all logged events for verification. Does not write to any actual log destination.
Thread Safety ¶
MockModelAuditLogger is safe for concurrent use.
func NewMockModelAuditLogger ¶
func NewMockModelAuditLogger() *MockModelAuditLogger
NewMockModelAuditLogger creates a mock for testing.
Description ¶
Creates a mock that records all events for later inspection.
Outputs ¶
- *MockModelAuditLogger: Ready-to-use mock
Examples ¶
mock := NewMockModelAuditLogger() mock.LogModelPull(event) assert.Len(t, mock.PullEvents, 1)
func (*MockModelAuditLogger) AllEvents ¶
func (m *MockModelAuditLogger) AllEvents() []ModelAuditEvent
AllEvents returns all recorded events in order.
Description ¶
Returns a combined slice of all event types for convenience. Order is: pull events, then verify events, then block events.
Outputs ¶
- []ModelAuditEvent: All recorded events
Examples ¶
all := mock.AllEvents() assert.Len(t, all, 3)
func (*MockModelAuditLogger) LogModelBlock ¶
func (m *MockModelAuditLogger) LogModelBlock(event ModelAuditEvent) error
LogModelBlock implements ModelAuditLogger.
func (*MockModelAuditLogger) LogModelPull ¶
func (m *MockModelAuditLogger) LogModelPull(event ModelAuditEvent) error
LogModelPull implements ModelAuditLogger.
func (*MockModelAuditLogger) LogModelVerify ¶
func (m *MockModelAuditLogger) LogModelVerify(event ModelAuditEvent) error
LogModelVerify implements ModelAuditLogger.
func (*MockModelAuditLogger) Reset ¶
func (m *MockModelAuditLogger) Reset()
Reset clears all recorded events.
Description ¶
Clears all recorded events for reuse between test cases.
Examples ¶
mock.Reset() // All event slices are now empty
type MockModelInfoProvider ¶
type MockModelInfoProvider struct {
// Function overrides (nil uses default behavior)
GetModelInfoFunc func(ctx context.Context, model string) (*ModelInfo, error)
GetLocalModelInfoFunc func(ctx context.Context, model string) (*ModelInfo, error)
GetMultipleModelInfoFunc func(ctx context.Context, models []string) (map[string]*ModelInfo, error)
EstimateTotalSizeFunc func(ctx context.Context, models []string) (int64, error)
// Call tracking
GetModelInfoCalls []string
GetLocalModelInfoCalls []string
GetMultipleCalls [][]string
EstimateSizeCalls [][]string
// Preconfigured return values
Models map[string]*ModelInfo
SizeByName map[string]int64
DefaultErr error
// contains filtered or unexported fields
}
MockModelInfoProvider implements ModelInfoProvider for testing.
Description ¶
Test double that allows controlling return values and tracking calls. All methods can be overridden via function fields.
Thread Safety ¶
MockModelInfoProvider is safe for concurrent use via internal mutex.
func NewMockModelInfoProvider ¶
func NewMockModelInfoProvider() *MockModelInfoProvider
NewMockModelInfoProvider creates a mock for testing.
Description ¶
Creates a mock with empty maps. Add models using the Models field.
Outputs ¶
- *MockModelInfoProvider: Ready-to-use mock
Examples ¶
mock := NewMockModelInfoProvider()
mock.Models["llama3:8b"] = &ModelInfo{Name: "llama3:8b", Size: 4_000_000_000}
func (*MockModelInfoProvider) EstimateTotalSize ¶
func (m *MockModelInfoProvider) EstimateTotalSize(ctx context.Context, models []string) (int64, error)
EstimateTotalSize implements ModelInfoProvider.
func (*MockModelInfoProvider) GetLocalModelInfo ¶
func (m *MockModelInfoProvider) GetLocalModelInfo(ctx context.Context, model string) (*ModelInfo, error)
GetLocalModelInfo implements ModelInfoProvider.
func (*MockModelInfoProvider) GetModelInfo ¶
GetModelInfo implements ModelInfoProvider.
func (*MockModelInfoProvider) GetMultipleModelInfo ¶
func (m *MockModelInfoProvider) GetMultipleModelInfo(ctx context.Context, models []string) (map[string]*ModelInfo, error)
GetMultipleModelInfo implements ModelInfoProvider.
func (*MockModelInfoProvider) Reset ¶
func (m *MockModelInfoProvider) Reset()
Reset clears all call tracking.
Description ¶
Clears all recorded calls while preserving configured return values. Use between test cases.
Examples ¶
mock.Reset() // Now all call slices are empty
type MockModelManager ¶
type MockModelManager struct {
EnsureModelFunc func(ctx context.Context, model string, opts EnsureOpts) (ModelResult, error)
SelectOptimalModelFunc func(ctx context.Context, purpose string) (string, error)
VerifyModelFunc func(ctx context.Context, model string) (VerificationResult, error)
GetModelStatusFunc func(ctx context.Context, model string) (ModelStatus, error)
ListAvailableModelsFunc func(ctx context.Context) ([]LocalModelInfo, error)
PullModelWithProgressFunc func(ctx context.Context, model string, progressCh chan<- PullProgress) error
InvalidateCacheFunc func()
EnsureCalls []MockEnsureCall
DefaultErr error
// contains filtered or unexported fields
}
MockModelManager implements ModelManager for testing.
Description ¶
Test double that allows customizing behavior via function overrides.
Thread Safety ¶
MockModelManager is safe for concurrent use.
func NewMockModelManager ¶
func NewMockModelManager() *MockModelManager
NewMockModelManager creates a mock for testing.
Description ¶
Creates a mock that records calls and returns configurable results.
Inputs ¶
None.
Outputs ¶
- *MockModelManager: Ready-to-use mock
Examples ¶
mock := NewMockModelManager()
mock.EnsureModelFunc = func(...) { ... }
Limitations ¶
- Does not simulate real network behavior
Assumptions ¶
- Test code sets appropriate function overrides
func (*MockModelManager) EnsureModel ¶
func (m *MockModelManager) EnsureModel(ctx context.Context, model string, opts EnsureOpts) (ModelResult, error)
EnsureModel implements ModelManager.
Description ¶
Records the call and returns configured result.
Inputs ¶
- ctx: Context for cancellation
- model: Model identifier
- opts: Configuration options
Outputs ¶
- ModelResult: Configured result
- error: Configured error
func (*MockModelManager) GetModelStatus ¶
func (m *MockModelManager) GetModelStatus(ctx context.Context, model string) (ModelStatus, error)
GetModelStatus implements ModelManager.
Description ¶
Returns configured status result.
Inputs ¶
- ctx: Context for cancellation
- model: Model identifier
Outputs ¶
- ModelStatus: Configured status
- error: Configured error
func (*MockModelManager) InvalidateCache ¶
func (m *MockModelManager) InvalidateCache()
InvalidateCache implements ModelManager.
Description ¶
Executes configured invalidate function if set.
Inputs ¶
None.
Outputs ¶
None.
func (*MockModelManager) ListAvailableModels ¶
func (m *MockModelManager) ListAvailableModels(ctx context.Context) ([]LocalModelInfo, error)
ListAvailableModels implements ModelManager.
Description ¶
Returns configured model list.
Inputs ¶
- ctx: Context for cancellation
Outputs ¶
- []LocalModelInfo: Configured models
- error: Configured error
func (*MockModelManager) PullModelWithProgress ¶
func (m *MockModelManager) PullModelWithProgress(ctx context.Context, model string, progressCh chan<- PullProgress) error
PullModelWithProgress implements ModelManager.
Description ¶
Executes configured pull function or closes channel.
Inputs ¶
- ctx: Context for cancellation
- model: Model identifier
- progressCh: Progress channel
Outputs ¶
- error: Configured error
func (*MockModelManager) Reset ¶
func (m *MockModelManager) Reset()
Reset clears recorded calls.
Description ¶
Resets all recorded calls for test reuse.
Inputs ¶
None.
Outputs ¶
None.
Examples ¶
mock.Reset()
Limitations ¶
- Does not reset function overrides
Assumptions ¶
- Called between test cases
func (*MockModelManager) SelectOptimalModel ¶
SelectOptimalModel implements ModelManager.
Description ¶
Returns configured result or default.
Inputs ¶
- ctx: Context for cancellation
- purpose: Intended use case
Outputs ¶
- string: Selected model
- error: Configured error
func (*MockModelManager) VerifyModel ¶
func (m *MockModelManager) VerifyModel(ctx context.Context, model string) (VerificationResult, error)
VerifyModel implements ModelManager.
Description ¶
Returns configured verification result.
Inputs ¶
- ctx: Context for cancellation
- model: Model identifier
Outputs ¶
- VerificationResult: Configured result
- error: Configured error
type MockModelSelector ¶
type MockModelSelector struct {
// Function overrides
SelectModelFunc func(ctx context.Context, category string, opts SelectionOpts) (string, error)
SelectModelWithFallbacksFunc func(ctx context.Context, category string, opts SelectionOpts, maxFallbacks int) (*FallbackChain, error)
GetModelCatalogFunc func(category string) []ModelCatalogEntry
FilterModelsFunc func(category string, opts SelectionOpts) []ModelCatalogEntry
// Call tracking
SelectModelCalls []struct {
Category string
Opts SelectionOpts
}
SelectWithFallbacksCalls []struct {
Category string
Opts SelectionOpts
MaxFallbacks int
}
GetCatalogCalls []string
FilterCalls []struct {
Category string
Opts SelectionOpts
}
// Default return values
DefaultModel string
DefaultChain *FallbackChain
DefaultCatalog []ModelCatalogEntry
DefaultErr error
// contains filtered or unexported fields
}
MockModelSelector implements ModelSelector for testing.
Description ¶
Test double that allows controlling return values and tracking calls. All methods can be overridden via function fields.
Thread Safety ¶
MockModelSelector is safe for concurrent use via internal mutex.
func NewMockModelSelector ¶
func NewMockModelSelector() *MockModelSelector
NewMockModelSelector creates a mock for testing.
Description ¶
Creates a mock with sensible defaults. Override behavior using the function fields or default return values.
Outputs ¶
- *MockModelSelector: Ready-to-use mock
Examples ¶
mock := NewMockModelSelector()
mock.DefaultModel = "custom:7b"
model, _ := mock.SelectModel(ctx, "llm", SelectionOpts{})
// model = "custom:7b"
func (*MockModelSelector) FilterModels ¶
func (m *MockModelSelector) FilterModels(category string, opts SelectionOpts) []ModelCatalogEntry
FilterModels implements ModelSelector.
func (*MockModelSelector) GetModelCatalog ¶
func (m *MockModelSelector) GetModelCatalog(category string) []ModelCatalogEntry
GetModelCatalog implements ModelSelector.
func (*MockModelSelector) Reset ¶
func (m *MockModelSelector) Reset()
Reset clears all call tracking.
Description ¶
Clears all recorded calls while preserving configured return values. Use between test cases.
Examples ¶
mock.Reset() // Now all call slices are empty
func (*MockModelSelector) SelectModel ¶
func (m *MockModelSelector) SelectModel(ctx context.Context, category string, opts SelectionOpts) (string, error)
SelectModel implements ModelSelector.
func (*MockModelSelector) SelectModelWithFallbacks ¶
func (m *MockModelSelector) SelectModelWithFallbacks(ctx context.Context, category string, opts SelectionOpts, maxFallbacks int) (*FallbackChain, error)
SelectModelWithFallbacks implements ModelSelector.
type MockProgressRenderer ¶
type MockProgressRenderer struct {
// Function fields for behavior customization
RenderFunc func(ctx context.Context, operation, status string, completed, total int64)
CompleteFunc func(ctx context.Context, operation string, success bool, message string)
// Call tracking
RenderCalls []MockRenderCall
CompleteCalls []MockCompleteCall
// Configuration
TTYValue bool
Output io.Writer
// contains filtered or unexported fields
}
MockProgressRenderer is a test double for ProgressRenderer.
Description ¶
Captures all calls for test verification. Can be configured with custom behavior via function fields.
Thread Safety ¶
Safe for concurrent use.
func NewMockProgressRenderer ¶
func NewMockProgressRenderer() *MockProgressRenderer
NewMockProgressRenderer creates a new mock progress renderer.
Description ¶
Creates a mock renderer for testing that records all calls.
Inputs ¶
None.
Outputs ¶
- *MockProgressRenderer: Configured mock
Examples ¶
mock := NewMockProgressRenderer() // Use in tests assert.Equal(t, 1, mock.RenderCallCount())
Limitations ¶
None.
Assumptions ¶
None.
func (*MockProgressRenderer) Complete ¶
func (m *MockProgressRenderer) Complete(ctx context.Context, operation string, success bool, message string)
Complete implements ProgressRenderer.
Description ¶
Records the call and optionally invokes custom function.
Inputs ¶
- ctx: Context
- operation: Operation identifier
- success: Whether succeeded
- message: Final message
Outputs ¶
None (records call internally).
Examples ¶
mock.Complete(ctx, "download", true, "done") assert.Equal(t, 1, mock.CompleteCallCount())
Limitations ¶
None.
Assumptions ¶
None.
func (*MockProgressRenderer) CompleteCallCount ¶
func (m *MockProgressRenderer) CompleteCallCount() int
CompleteCallCount returns the number of Complete calls.
Description ¶
Returns count of recorded Complete calls for test assertions.
Inputs ¶
None.
Outputs ¶
- int: Number of Complete calls
Examples ¶
count := mock.CompleteCallCount()
Limitations ¶
None.
Assumptions ¶
None.
func (*MockProgressRenderer) IsTTY ¶
func (m *MockProgressRenderer) IsTTY() bool
IsTTY implements ProgressRenderer.
Description ¶
Returns configured TTY value.
Inputs ¶
None.
Outputs ¶
- bool: Configured TTYValue
Examples ¶
mock.TTYValue = true assert.True(t, mock.IsTTY())
Limitations ¶
None.
Assumptions ¶
None.
func (*MockProgressRenderer) Render ¶
func (m *MockProgressRenderer) Render(ctx context.Context, operation, status string, completed, total int64)
Render implements ProgressRenderer.
Description ¶
Records the call and optionally invokes custom function.
Inputs ¶
- ctx: Context
- operation: Operation identifier
- status: Status text
- completed: Bytes completed
- total: Total bytes
Outputs ¶
None (records call internally).
Examples ¶
mock.Render(ctx, "download", "downloading", 1024, 4096) assert.Equal(t, 1, mock.RenderCallCount())
Limitations ¶
None.
Assumptions ¶
None.
func (*MockProgressRenderer) RenderCallCount ¶
func (m *MockProgressRenderer) RenderCallCount() int
RenderCallCount returns the number of Render calls.
Description ¶
Returns count of recorded Render calls for test assertions.
Inputs ¶
None.
Outputs ¶
- int: Number of Render calls
Examples ¶
count := mock.RenderCallCount()
Limitations ¶
None.
Assumptions ¶
None.
func (*MockProgressRenderer) Reset ¶
func (m *MockProgressRenderer) Reset()
Reset clears all recorded calls.
Description ¶
Resets call tracking for reuse in tests.
Inputs ¶
None.
Outputs ¶
None (modifies internal state).
Examples ¶
mock.Reset() assert.Equal(t, 0, mock.RenderCallCount())
Limitations ¶
None.
Assumptions ¶
None.
type MockRenderCall ¶
MockRenderCall records a Render call for test verification.
type ModelAuditEvent ¶
type ModelAuditEvent struct {
// Timestamp of the event (UTC)
Timestamp time.Time `json:"timestamp"`
// Action is the operation type
// Values: "pull_start", "pull_complete", "verify", "block", "delete"
Action string `json:"action"`
// Model is the model identifier (e.g., "llama3:8b")
Model string `json:"model"`
// User is the system user who initiated the operation
// Populated from $USER environment variable
User string `json:"user,omitempty"`
// Hostname is the machine name
// Populated from os.Hostname()
Hostname string `json:"hostname,omitempty"`
// Success indicates if operation succeeded
Success bool `json:"success"`
// ErrorMessage contains failure reason if Success=false
ErrorMessage string `json:"error_message,omitempty"`
// BytesTotal is the total bytes transferred
BytesTotal int64 `json:"bytes_total,omitempty"`
// Duration is how long the operation took
Duration time.Duration `json:"-"`
// DurationMs is Duration in milliseconds for JSON serialization
DurationMs int64 `json:"duration_ms,omitempty"`
// Digest is the model hash (for verification)
// Format: "sha256:abc123..."
Digest string `json:"digest,omitempty"`
// Source is where the model came from (registry URL)
Source string `json:"source,omitempty"`
}
ModelAuditEvent records a model operation for audit.
Description ¶
Structured log entry for compliance and forensics. Contains all information needed to answer "who did what, when, with what result".
Thread Safety ¶
ModelAuditEvent is immutable after creation and safe for concurrent read.
JSON Format ¶
Events are serialized as JSON for machine parsing:
{
"timestamp": "2026-01-06T12:00:00Z",
"action": "pull_complete",
"model": "llama3:8b",
"user": "developer",
"hostname": "dev-machine",
"success": true,
"bytes_total": 4000000000,
"duration_ms": 300000,
"digest": "sha256:abc123..."
}
func (*ModelAuditEvent) String ¶
func (e *ModelAuditEvent) String() string
String returns a human-readable representation.
Description ¶
Formats the event for human-readable logs. Not intended for machine parsing - use ToJSON() for that.
Outputs ¶
- string: Human-readable event description
Examples ¶
fmt.Println(event.String()) // "2026-01-06T12:00:00Z [pull_complete] model=llama3:8b user=developer success=true"
func (*ModelAuditEvent) ToJSON ¶
func (e *ModelAuditEvent) ToJSON() []byte
ToJSON serializes the event to JSON.
Description ¶
Converts the event to a JSON byte slice for logging. Returns empty slice on error (should not happen with valid data).
Outputs ¶
- []byte: JSON representation
Examples ¶
jsonBytes := event.ToJSON() fmt.Println(string(jsonBytes))
Limitations ¶
- Returns empty slice on marshal error
func (ModelAuditEvent) WithDuration ¶
func (e ModelAuditEvent) WithDuration(d time.Duration) ModelAuditEvent
WithDuration sets the duration and DurationMs fields.
Description ¶
Sets both Duration (for Go code) and DurationMs (for JSON serialization).
Inputs ¶
- d: Duration to set
Outputs ¶
- ModelAuditEvent: The event with duration set
Examples ¶
event := ModelAuditEvent{Action: "pull_complete"}.WithDuration(5 * time.Minute)
// event.Duration = 5m, event.DurationMs = 300000
func (ModelAuditEvent) WithHostInfo ¶
func (e ModelAuditEvent) WithHostInfo() ModelAuditEvent
WithHostInfo populates User and Hostname from system.
Description ¶
Fills in User from $USER environment variable and Hostname from os.Hostname(). Errors are silently ignored (best-effort).
Outputs ¶
- ModelAuditEvent: The event with host info set
Examples ¶
event := ModelAuditEvent{Action: "pull_complete"}.WithHostInfo()
// event.User and event.Hostname are now populated
Limitations ¶
- User detection is best-effort ($USER may be empty)
- Hostname detection may fail on some systems
func (ModelAuditEvent) WithTimestamp ¶
func (e ModelAuditEvent) WithTimestamp(t time.Time) ModelAuditEvent
WithTimestamp sets the timestamp and returns the event.
Description ¶
Convenience method for builder-style event construction. If timestamp is zero, uses current UTC time.
Inputs ¶
- t: Timestamp to set (zero = now)
Outputs ¶
- ModelAuditEvent: The event with timestamp set
Examples ¶
event := ModelAuditEvent{Action: "pull_complete"}.WithTimestamp(time.Time{})
// event.Timestamp is now set to current UTC time
type ModelAuditLogger ¶
type ModelAuditLogger interface {
// LogModelPull records a model download operation.
//
// # Description
//
// Creates an audit log entry for a model pull operation.
// Should be called at start (Success=false) and completion (with actual values).
//
// # Inputs
//
// - event: Audit event details
//
// # Outputs
//
// - error: Logging failure (should not block operation)
//
// # Examples
//
// err := logger.LogModelPull(ModelAuditEvent{
// Action: "pull_complete",
// Model: "llama3:8b",
// Success: true,
// BytesTotal: 4_000_000_000,
// Duration: 5 * time.Minute,
// Digest: "sha256:abc123...",
// })
//
// # Limitations
//
// - Logging failures are non-fatal
// - User identification is best-effort
//
// # Assumptions
//
// - Log destination is configured and writable
LogModelPull(event ModelAuditEvent) error
// LogModelVerify records an integrity verification operation.
//
// # Description
//
// Creates an audit log entry when a model's digest is verified.
// Records whether verification passed or failed.
//
// # Inputs
//
// - event: Audit event details (Action should be "verify")
//
// # Outputs
//
// - error: Logging failure (non-fatal)
//
// # Examples
//
// err := logger.LogModelVerify(ModelAuditEvent{
// Action: "verify",
// Model: "llama3:8b",
// Success: true,
// Digest: "sha256:abc123...",
// })
//
// # Limitations
//
// - Logging failures are non-fatal
//
// # Assumptions
//
// - Event contains valid digest for successful verifications
LogModelVerify(event ModelAuditEvent) error
// LogModelBlock records a blocked model request.
//
// # Description
//
// Creates an audit log entry when a model request is blocked
// by the allowlist policy. Important for security monitoring.
//
// # Inputs
//
// - event: Audit event details (Action should be "block")
//
// # Outputs
//
// - error: Logging failure (non-fatal)
//
// # Examples
//
// err := logger.LogModelBlock(ModelAuditEvent{
// Action: "block",
// Model: "unauthorized-model",
// Success: false,
// ErrorMessage: "model not in allowlist",
// })
//
// # Limitations
//
// - Logging failures are non-fatal
//
// # Assumptions
//
// - ErrorMessage explains why model was blocked
LogModelBlock(event ModelAuditEvent) error
}
ModelAuditLogger records model operations for compliance.
Description ¶
This interface abstracts audit logging for model operations, enabling GDPR/HIPAA/CCPA compliance by tracking who downloaded what, when. All audit events are structured for machine parsing and compliance queries.
Security ¶
- Logs must not contain sensitive user data beyond identifiers
- Digest information is logged for forensics
- Timestamps must be accurate (UTC)
Thread Safety ¶
Implementations must be safe for concurrent use.
type ModelCatalogEntry ¶
type ModelCatalogEntry struct {
// Name is the model identifier (e.g., "llama3:8b")
Name string
// Family is the model family ("llama", "phi", "mistral")
Family string
// MinRAM_GB is minimum RAM required to load the model
MinRAM_GB int
// RecommendedRAM_GB is recommended RAM for good performance
RecommendedRAM_GB int
// ContextLength is the maximum context window size in tokens
ContextLength int
// Capabilities are model strengths
// Examples: ["general", "code", "math", "vision"]
Capabilities []string
// Quantization is the quantization level (e.g., "Q4_K_M", "F16")
Quantization string
// Priority is the selection priority (higher = preferred)
// Used to rank models with similar resource requirements
Priority int
}
ModelCatalogEntry describes a model in the selection catalog.
Description ¶
Contains all metadata needed for automatic model selection, including resource requirements and capabilities.
Thread Safety ¶
ModelCatalogEntry is immutable and safe for concurrent read access.
func (*ModelCatalogEntry) FitsRAM ¶
func (e *ModelCatalogEntry) FitsRAM(maxGB int) bool
FitsRAM checks if the model fits within the given RAM limit.
Description ¶
Compares MinRAM_GB against the provided limit. Zero limit means no constraint (always fits).
Inputs ¶
- maxGB: Maximum RAM in GB (0 = no limit)
Outputs ¶
- bool: True if model fits
Examples ¶
entry := ModelCatalogEntry{MinRAM_GB: 8}
fmt.Println(entry.FitsRAM(16)) // true
fmt.Println(entry.FitsRAM(4)) // false
fmt.Println(entry.FitsRAM(0)) // true (no limit)
func (*ModelCatalogEntry) HasAllCapabilities ¶
func (e *ModelCatalogEntry) HasAllCapabilities(caps []string) bool
HasAllCapabilities checks if the model has all specified capabilities.
Description ¶
Returns true only if every capability in the list is present. Empty list always returns true.
Inputs ¶
- caps: List of required capabilities
Outputs ¶
- bool: True if all capabilities present
Examples ¶
entry := ModelCatalogEntry{Capabilities: []string{"code", "math"}}
fmt.Println(entry.HasAllCapabilities([]string{"code"})) // true
fmt.Println(entry.HasAllCapabilities([]string{"vision"})) // false
func (*ModelCatalogEntry) HasCapability ¶
func (e *ModelCatalogEntry) HasCapability(cap string) bool
HasCapability checks if the model has a specific capability.
Description ¶
Performs case-insensitive search through the Capabilities slice.
Inputs ¶
- cap: Capability to check for (e.g., "code", "math")
Outputs ¶
- bool: True if capability is present
Examples ¶
entry := ModelCatalogEntry{Capabilities: []string{"code", "math"}}
fmt.Println(entry.HasCapability("CODE")) // true
func (*ModelCatalogEntry) MeetsContextRequirement ¶
func (e *ModelCatalogEntry) MeetsContextRequirement(minContext int) bool
MeetsContextRequirement checks if the model meets context window requirements.
Description ¶
Compares ContextLength against the minimum required. Zero requirement means no constraint (always meets).
Inputs ¶
- minContext: Minimum context window size (0 = no requirement)
Outputs ¶
- bool: True if requirement met
Examples ¶
entry := ModelCatalogEntry{ContextLength: 8192}
fmt.Println(entry.MeetsContextRequirement(4096)) // true
fmt.Println(entry.MeetsContextRequirement(16384)) // false
type ModelInfo ¶
type ModelInfo struct {
// Name is the model identifier (e.g., "llama3:8b")
// Format: name[:tag] where tag defaults to "latest"
Name string
// Size is the total size in bytes on disk
// This is the uncompressed size, actual download may be smaller
Size int64
// Digest is the SHA-256 hash of the model (for pinning/verification)
// Format: "sha256:abc123..."
// Empty string indicates digest is unknown
Digest string
// ModifiedAt is when the model was last updated in the registry
ModifiedAt time.Time
// Quantization is the quantization method (e.g., "Q4_K_M", "Q8_0", "F16")
// Empty string indicates unknown or full precision
Quantization string
// ParameterCount is the number of model parameters (e.g., 8_000_000_000)
// Zero indicates unknown
ParameterCount int64
// ContextLength is the maximum context window size in tokens
// Zero indicates unknown
ContextLength int
// Family is the model family (e.g., "llama", "phi", "mistral")
// Empty string indicates unknown
Family string
// IsLocal indicates if this model is installed locally
IsLocal bool
}
ModelInfo contains metadata about a model.
Description ¶
Holds all metadata needed for size estimation, version pinning, and integrity verification. This type is used by both the provider and the selector components.
Thread Safety ¶
ModelInfo is immutable after creation and safe for concurrent read access.
Security ¶
The Digest field contains security-critical information for version pinning. Ensure digests are validated before trusting them.
func (*ModelInfo) HasDigest ¶
HasDigest returns true if a digest is available.
Description ¶
Checks if the digest field is populated. Used to determine if integrity verification is possible.
Outputs ¶
- bool: True if digest is available
Examples ¶
if info.HasDigest() {
// Can verify integrity
}
func (*ModelInfo) MatchesDigest ¶
MatchesDigest checks if this model's digest matches the expected digest.
Description ¶
Compares digests in a case-insensitive manner. Both digests are normalized to lowercase before comparison.
Inputs ¶
- expected: The expected digest string
Outputs ¶
- bool: True if digests match
Examples ¶
if !info.MatchesDigest(pinned.Digest) {
return ErrModelDigestMismatch
}
Limitations ¶
- Returns false if either digest is empty
func (*ModelInfo) ParameterSizeString ¶
ParameterSizeString returns a human-readable parameter count.
Description ¶
Formats the parameter count with appropriate suffix (K, M, B). Returns "unknown" if parameter count is zero.
Outputs ¶
- string: Human-readable parameter count
Examples ¶
info := &ModelInfo{ParameterCount: 8_000_000_000}
fmt.Println(info.ParameterSizeString()) // "8B"
func (*ModelInfo) SizeGB ¶
SizeGB returns the size in gigabytes as a float.
Description ¶
Convenience method for displaying size in human-readable format. Uses 1 GB = 1,073,741,824 bytes (binary gigabyte).
Outputs ¶
- float64: Size in GB
Examples ¶
info := &ModelInfo{Size: 4_294_967_296}
fmt.Printf("%.1f GB\n", info.SizeGB()) // "4.0 GB"
type ModelInfoProvider ¶
type ModelInfoProvider interface {
// GetModelInfo retrieves metadata for a model from the registry.
//
// # Description
//
// Queries the model registry for size, digest, and other metadata.
// Does NOT download the model, only retrieves manifest information.
// For remote models, this may require a network request.
//
// # Inputs
//
// - ctx: Context for cancellation/timeout
// - model: Model name (e.g., "llama3:8b", "nomic-embed-text-v2-moe")
//
// # Outputs
//
// - *ModelInfo: Model metadata (nil if model not found)
// - error: Network errors, invalid model name, etc.
//
// # Examples
//
// info, err := provider.GetModelInfo(ctx, "llama3:8b")
// if err != nil {
// return fmt.Errorf("failed to get model info: %w", err)
// }
// fmt.Printf("Model size: %s\n", formatBytes(info.Size))
//
// # Limitations
//
// - Requires network connectivity for remote models
// - Model must exist in registry
// - Size may differ from actual download size (shared layers)
//
// # Assumptions
//
// - Model name has been validated
// - Ollama server is reachable
GetModelInfo(ctx context.Context, model string) (*ModelInfo, error)
// GetLocalModelInfo retrieves metadata for a locally installed model.
//
// # Description
//
// Gets information about a model already present on disk.
// Used for integrity verification and version checking.
// Does not require network connectivity.
//
// # Inputs
//
// - ctx: Context for cancellation
// - model: Model name
//
// # Outputs
//
// - *ModelInfo: Local model metadata (nil if not installed)
// - error: Filesystem errors, corrupt model, etc.
//
// # Examples
//
// info, err := provider.GetLocalModelInfo(ctx, "llama3:8b")
// if errors.Is(err, ErrModelNotFound) {
// fmt.Println("Model not installed locally")
// }
//
// # Limitations
//
// - Only works for locally installed models
// - Returns ErrModelNotFound if model not present
//
// # Assumptions
//
// - Ollama is running and accessible
GetLocalModelInfo(ctx context.Context, model string) (*ModelInfo, error)
// GetMultipleModelInfo retrieves metadata for multiple models.
//
// # Description
//
// Batch operation for getting info on multiple models. More efficient
// than individual GetModelInfo calls when checking many models.
//
// # Inputs
//
// - ctx: Context for cancellation
// - models: List of model names
//
// # Outputs
//
// - map[string]*ModelInfo: Model name to info (nil entry if not found)
// - error: General failures (individual model failures are nil entries)
//
// # Examples
//
// infos, err := provider.GetMultipleModelInfo(ctx, []string{"llama3:8b", "phi3"})
// for name, info := range infos {
// if info == nil {
// fmt.Printf("%s: not found\n", name)
// }
// }
//
// # Limitations
//
// - Individual model failures result in nil map entries, not errors
//
// # Assumptions
//
// - Model names have been validated
GetMultipleModelInfo(ctx context.Context, models []string) (map[string]*ModelInfo, error)
// EstimateTotalSize calculates total download size for a list of models.
//
// # Description
//
// Sums the sizes of all models in the list, accounting for models
// that are already installed (their size is not included).
//
// # Inputs
//
// - ctx: Context for cancellation
// - models: List of model names to estimate
//
// # Outputs
//
// - int64: Total bytes to download
// - error: If size estimation fails
//
// # Examples
//
// totalSize, err := provider.EstimateTotalSize(ctx, []string{"llama3:8b", "phi3"})
// if err != nil {
// return err
// }
// fmt.Printf("Will download approximately %s\n", formatBytes(totalSize))
//
// # Limitations
//
// - Estimate may be inaccurate due to shared layers between models
// - Uses size from manifest which may differ from actual download
//
// # Assumptions
//
// - Models that exist locally are not counted in the total
EstimateTotalSize(ctx context.Context, models []string) (int64, error)
}
ModelInfoProvider retrieves model metadata before download.
Description ¶
This interface abstracts model metadata retrieval, enabling size estimation, version pinning verification, and integrity checking. Used to query Ollama for model information without triggering a download.
Security ¶
- Model names must be validated before queries
- Digest information is security-sensitive (version pinning)
- All network requests respect context cancellation
Thread Safety ¶
Implementations must be safe for concurrent use.
type ModelManager ¶
type ModelManager interface {
// EnsureModel verifies a model exists, pulling if needed.
//
// # Description
//
// Checks if the specified model is available locally. If not present
// and AllowPull is true, downloads the model. Supports fallback chains
// and integrity verification. Retries on network failures with
// exponential backoff.
//
// # Inputs
//
// - ctx: Context for cancellation and timeout
// - model: Model identifier (e.g., "llama3:8b")
// - opts: Configuration options
//
// # Outputs
//
// - ModelResult: Operation outcome with model details
// - error: Operation failure
//
// # Examples
//
// result, err := manager.EnsureModel(ctx, "llama3:8b", EnsureOpts{
// AllowPull: true,
// VerifyIntegrity: true,
// FallbackModels: []string{"llama3:latest"},
// })
//
// # Limitations
//
// - Network failures may exhaust retry budget
// - Blocked models return error immediately
//
// # Assumptions
//
// - Ollama API is available
// - Model name is valid
EnsureModel(ctx context.Context, model string, opts EnsureOpts) (ModelResult, error)
// SelectOptimalModel auto-selects the best model for a purpose.
//
// # Description
//
// Uses hardware detection and model catalog to select the optimal
// model for the given purpose (e.g., "chat", "code", "embedding").
//
// # Inputs
//
// - ctx: Context for cancellation
// - purpose: Intended use case
//
// # Outputs
//
// - string: Selected model identifier
// - error: Selection failure
//
// # Examples
//
// model, err := manager.SelectOptimalModel(ctx, "code")
// // Returns "deepseek-coder:6.7b" on 16GB RAM system
//
// # Limitations
//
// - Hardware detection may fail on some systems
// - Unknown purposes return default model
//
// # Assumptions
//
// - Selector is properly configured
SelectOptimalModel(ctx context.Context, purpose string) (string, error)
// VerifyModel checks model integrity using SHA-256.
//
// # Description
//
// Computes and verifies the model's digest against the registry.
// Useful for detecting corruption or tampering.
//
// # Inputs
//
// - ctx: Context for cancellation
// - model: Model identifier
//
// # Outputs
//
// - VerificationResult: Verification outcome
// - error: Operation failure
//
// # Examples
//
// result, err := manager.VerifyModel(ctx, "llama3:8b")
// if !result.Verified {
// log.Printf("Digest mismatch: %s vs %s", result.Digest, result.ExpectedDigest)
// }
//
// # Limitations
//
// - Requires model to exist locally
//
// # Assumptions
//
// - Model was previously pulled
VerifyModel(ctx context.Context, model string) (VerificationResult, error)
// GetModelStatus returns current model status.
//
// # Description
//
// Checks whether a model is present, being pulled, blocked, etc.
//
// # Inputs
//
// - ctx: Context for cancellation
// - model: Model identifier
//
// # Outputs
//
// - ModelStatus: Current status
// - error: Query failure
//
// # Examples
//
// status, err := manager.GetModelStatus(ctx, "llama3:8b")
// if status == StatusPresent {
// // Model is ready to use
// }
//
// # Limitations
//
// - Status is point-in-time snapshot
//
// # Assumptions
//
// - Ollama API is available
GetModelStatus(ctx context.Context, model string) (ModelStatus, error)
// ListAvailableModels returns all locally available models.
//
// # Description
//
// Queries Ollama for all models present on the local system.
// Results are cached for 24 hours for performance.
//
// # Inputs
//
// - ctx: Context for cancellation
//
// # Outputs
//
// - []LocalModelInfo: Available models
// - error: Query failure
//
// # Examples
//
// models, err := manager.ListAvailableModels(ctx)
// for _, m := range models {
// fmt.Printf("%s (%d bytes)\n", m.Name, m.Size)
// }
//
// # Limitations
//
// - Cache may be stale up to 24 hours
//
// # Assumptions
//
// - Ollama API is available
ListAvailableModels(ctx context.Context) ([]LocalModelInfo, error)
// PullModelWithProgress pulls a model with progress reporting.
//
// # Description
//
// Downloads a model and sends progress updates to the provided channel.
// The channel is closed when the operation completes.
//
// # Inputs
//
// - ctx: Context for cancellation
// - model: Model identifier
// - progressCh: Channel for progress updates (caller must read)
//
// # Outputs
//
// - error: Download failure
//
// # Examples
//
// progressCh := make(chan PullProgress, 100)
// go func() {
// for p := range progressCh {
// fmt.Printf("\r%s: %.1f%%", p.Status, p.Percent)
// }
// }()
// err := manager.PullModelWithProgress(ctx, "llama3:8b", progressCh)
//
// # Limitations
//
// - Caller must read from progressCh to prevent blocking
//
// # Assumptions
//
// - Sufficient disk space available
PullModelWithProgress(ctx context.Context, model string, progressCh chan<- PullProgress) error
// InvalidateCache clears the model list cache.
//
// # Description
//
// Forces the next ListAvailableModels call to query fresh data.
// Useful after manual model operations.
//
// # Examples
//
// manager.InvalidateCache()
//
// # Limitations
//
// - Does not affect in-flight requests
//
// # Assumptions
//
// - None
InvalidateCache()
}
ModelManager is the unified API for model operations.
Description ¶
This interface provides a single entry point for all model management operations including ensuring models exist, auto-selection based on hardware, integrity verification, and progress-tracked downloads.
Thread Safety ¶
Implementations must be safe for concurrent use.
Compliance ¶
All operations are audit-logged for GDPR/HIPAA/CCPA compliance.
type ModelManagerConfig ¶
type ModelManagerConfig struct {
// Querier for registry operations (required)
Querier ModelInfoProvider
// Selector for auto-selection (required)
Selector ModelSelector
// AuditLogger for compliance (optional, nil = no-op)
AuditLogger ModelAuditLogger
// HTTPClient for API calls (optional, nil = default)
HTTPClient *http.Client
// BaseURL is the Ollama API endpoint (optional, default = http://localhost:11434)
BaseURL string
// Allowlist restricts permitted models (optional, nil = allow all)
Allowlist []string
// DefaultTimeout for operations (optional, default = 30m)
DefaultTimeout time.Duration
// DefaultRetryPolicy for network failures (optional)
DefaultRetryPolicy *RetryPolicy
// CacheTTL for model list cache (optional, default = 24h)
CacheTTL time.Duration
}
ModelManagerConfig configures DefaultModelManager.
Description ¶
Configuration options for creating a DefaultModelManager.
type ModelResult ¶
type ModelResult struct {
// Model is the final model name (may differ if fallback used).
Model string
// Digest is the SHA-256 digest of the model.
Digest string
// Size is the model size in bytes.
Size int64
// WasPulled is true if the model was downloaded.
WasPulled bool
// UsedFallback is true if a fallback model was used.
UsedFallback bool
// FallbackReason explains why fallback was needed.
FallbackReason string
// Duration is the total operation time.
Duration time.Duration
// VerificationPassed indicates integrity check result (if performed).
VerificationPassed *bool
}
ModelResult contains the outcome of an ensure operation.
Description ¶
Provides details about the model that was ensured, including whether it was pulled and if a fallback was used.
type ModelSelector ¶
type ModelSelector interface {
// SelectModel chooses the best model for a given category.
//
// # Description
//
// Analyzes available hardware and returns the optimal model.
// Categories include "llm", "embedding", "vision", etc.
//
// # Inputs
//
// - ctx: Context for cancellation
// - category: Model category ("llm", "embedding")
// - opts: Selection options (constraints, preferences)
//
// # Outputs
//
// - string: Selected model name
// - error: No suitable model found, hardware detection failed
//
// # Examples
//
// model, err := selector.SelectModel(ctx, "llm", SelectionOpts{
// MaxRAM_GB: 16,
// PreferQuantized: true,
// })
// if err != nil {
// return fmt.Errorf("no suitable model: %w", err)
// }
// fmt.Printf("Selected: %s\n", model)
//
// # Limitations
//
// - Selection based on RAM only (VRAM detection future work)
// - Limited to predefined model catalog
//
// # Assumptions
//
// - Hardware detection is accurate
// - Model catalog is up-to-date
SelectModel(ctx context.Context, category string, opts SelectionOpts) (string, error)
// SelectModelWithFallbacks selects a model and returns fallback options.
//
// # Description
//
// Returns the best model plus alternative models that would also work.
// Useful for creating FallbackChain configurations.
//
// # Inputs
//
// - ctx: Context for cancellation
// - category: Model category
// - opts: Selection options
// - maxFallbacks: Maximum number of fallback models to return
//
// # Outputs
//
// - *FallbackChain: Primary model with fallbacks
// - error: If no suitable models found
//
// # Examples
//
// chain, err := selector.SelectModelWithFallbacks(ctx, "llm", opts, 3)
// // chain.Primary = "llama3:70b"
// // chain.Fallbacks = ["llama3:8b", "phi3:mini"]
//
// # Limitations
//
// - Returns at most maxFallbacks alternatives
//
// # Assumptions
//
// - Category exists in catalog
SelectModelWithFallbacks(ctx context.Context, category string, opts SelectionOpts, maxFallbacks int) (*FallbackChain, error)
// GetModelCatalog returns available models for a category.
//
// # Description
//
// Returns the catalog of known models for selection, ordered by
// capability (largest/best first).
//
// # Inputs
//
// - category: Model category ("llm", "embedding")
//
// # Outputs
//
// - []ModelCatalogEntry: Available models with requirements
//
// # Examples
//
// catalog := selector.GetModelCatalog("llm")
// for _, entry := range catalog {
// fmt.Printf("%s requires %dGB RAM\n", entry.Name, entry.MinRAM_GB)
// }
//
// # Limitations
//
// - Catalog is statically defined
// - Unknown categories return empty slice
//
// # Assumptions
//
// - Category string is lowercase
GetModelCatalog(category string) []ModelCatalogEntry
// FilterModels returns models matching the given options.
//
// # Description
//
// Filters the catalog based on constraints. Does not rank or select,
// just returns all models that match the criteria.
//
// # Inputs
//
// - category: Model category
// - opts: Filter criteria
//
// # Outputs
//
// - []ModelCatalogEntry: Models matching criteria
//
// # Examples
//
// matches := selector.FilterModels("llm", SelectionOpts{
// MaxRAM_GB: 8,
// RequiredCapabilities: []string{"code"},
// })
//
// # Limitations
//
// - Does not rank results by quality
//
// # Assumptions
//
// - Category exists in catalog
FilterModels(category string, opts SelectionOpts) []ModelCatalogEntry
}
ModelSelector chooses optimal models based on hardware capabilities.
Description ¶
This interface abstracts model selection logic, enabling automatic selection based on available RAM/VRAM, or explicit selection via config. Integrates with ProfileResolver for hardware detection.
Use Cases ¶
- Auto-select largest model that fits in available RAM
- Select appropriate quantization based on hardware
- Provide fallback recommendations
- Filter by required capabilities
Thread Safety ¶
Implementations must be safe for concurrent use.
type ModelStatus ¶
type ModelStatus int
ModelStatus represents current model state.
Description ¶
Enumeration of possible model states.
const ( // StatusUnknown indicates status could not be determined. StatusUnknown ModelStatus = iota // StatusPresent indicates model is available locally. StatusPresent // StatusPulling indicates model download is in progress. StatusPulling // StatusNotFound indicates model is not available. StatusNotFound // StatusBlocked indicates model is on the blocklist. StatusBlocked )
func (ModelStatus) String ¶
func (s ModelStatus) String() string
String returns a human-readable status name.
Description ¶
Converts ModelStatus to string for logging and display.
Inputs ¶
None.
Outputs ¶
- string: Status name
Examples ¶
status := StatusPresent fmt.Println(status.String()) // "present"
Limitations ¶
- Unknown values return "unknown"
Assumptions ¶
- None
type OllamaModelInfo ¶
type OllamaModelInfo struct {
Name string
Size int64
Digest string
ModifiedAt time.Time
Family string
ParameterSize string
QuantizationLevel string
}
OllamaModelInfo represents model info from Ollama. This mirrors the fields needed from the main package's OllamaModel.
type OllamaModelLister ¶
type OllamaModelLister interface {
// ListModels returns all locally available models
ListModels(ctx context.Context) ([]OllamaModelInfo, error)
// GetModelSize returns the size for a model
GetModelSize(ctx context.Context, modelName string) (int64, error)
}
OllamaModelLister defines the subset of OllamaModelManager needed for info.
Description ¶
This interface allows ModelInfoProvider to work with OllamaClient without depending on the full OllamaModelManager interface. This enables easier testing and looser coupling.
type PinnedModel ¶
type PinnedModel struct {
// Name is the model identifier
Name string
// Digest is the required SHA-256 hash
// If set, download will fail if digest doesn't match
// Format: "sha256:abc123..."
Digest string
// AllowUpgrade permits newer versions if pinned version unavailable
// When true: warn on mismatch but proceed
// When false: fail on mismatch
AllowUpgrade bool
}
PinnedModel represents a model locked to a specific version.
Description ¶
Version pinning ensures reproducible deployments by locking to a specific model digest. When enabled, downloads fail if the registry digest doesn't match the pinned digest.
Thread Safety ¶
PinnedModel is immutable after creation and safe for concurrent read access.
Security ¶
Version pinning is a security feature. The digest provides cryptographic assurance that the model hasn't changed.
Configuration ¶
Pinned models are configured in YAML:
version_pinning:
enabled: true
models:
embedding:
name: "nomic-embed-text-v2-moe"
digest: "sha256:abc123..."
allow_upgrade: false
func (*PinnedModel) IsPinned ¶
func (p *PinnedModel) IsPinned() bool
IsPinned returns true if a specific digest is required.
Description ¶
Checks if version pinning is active for this model. Pinning is active when a non-empty digest is configured.
Outputs ¶
- bool: True if digest is specified
Examples ¶
if pinned.IsPinned() {
// Verify digest before using model
}
func (*PinnedModel) Verify ¶
func (p *PinnedModel) Verify(info *ModelInfo) error
Verify checks if the provided info matches the pinned specification.
Description ¶
Compares the provided model info against the pinned requirements. Returns nil if verification passes, error otherwise.
Inputs ¶
- info: Model info to verify against pin
Outputs ¶
- error: nil if matches, ErrModelDigestMismatch if not
Examples ¶
if err := pinned.Verify(downloadedInfo); err != nil {
if pinned.AllowUpgrade {
log.Warn("Digest mismatch, proceeding anyway")
} else {
return err
}
}
Limitations ¶
- Only verifies digest, not other fields
type ProgressRenderer ¶
type ProgressRenderer interface {
// Render displays progress for a named operation.
//
// # Description
//
// Updates the progress display for the given operation. May be called
// many times per second during active downloads. Implementations should
// handle rate limiting internally if needed.
//
// # Inputs
//
// - ctx: Context for cancellation
// - operation: Operation identifier (e.g., "pulling nomic-embed-text-v2-moe")
// - status: Current status text (e.g., "downloading layer 3/5")
// - completed: Bytes/units completed
// - total: Total bytes/units (0 if unknown)
//
// # Examples
//
// renderer.Render(ctx, "model:gpt-oss", "pulling manifest", 0, 0)
// renderer.Render(ctx, "model:gpt-oss", "downloading", 1024*1024, 4*1024*1024*1024)
//
// # Limitations
//
// - Completed/total may both be 0 for indeterminate progress
// - Operation names are not guaranteed unique across concurrent operations
Render(ctx context.Context, operation, status string, completed, total int64)
// Complete marks an operation as finished.
//
// # Description
//
// Called when an operation completes (success or failure).
// Implementations should clear/finalize the progress display.
//
// # Inputs
//
// - ctx: Context
// - operation: Operation identifier (same as passed to Render)
// - success: True if operation succeeded
// - message: Final status message
Complete(ctx context.Context, operation string, success bool, message string)
// SetOutput configures the output destination.
//
// # Description
//
// Allows runtime reconfiguration of where progress is written.
// Passing nil should disable output (silent mode).
//
// # Inputs
//
// - w: Writer for progress output (nil = silent)
SetOutput(w io.Writer)
// IsTTY returns true if output supports terminal features.
//
// # Description
//
// Used to determine if ANSI escape codes, carriage returns,
// and other terminal features can be used.
//
// # Outputs
//
// - bool: True if output supports TTY features
IsTTY() bool
}
ProgressRenderer displays progress for long-running operations.
Description ¶
This interface abstracts progress display, enabling different implementations for TTY (interactive), non-TTY (CI), and headless (API) environments. All model download progress flows through this interface.
Security ¶
- Implementations MUST NOT log model names to external services
- Progress data may contain network timing information (potential fingerprint)
- All output is sanitized to prevent terminal escape sequence injection
Thread Safety ¶
Implementations must be safe for concurrent Render calls from multiple goroutines (parallel downloads).
type PullProgress ¶
type PullProgress struct {
// Status describes current phase.
// Values: "pulling manifest", "downloading", "verifying", "complete", "error"
Status string
// Layer is the current layer being processed.
Layer string
// Completed is bytes downloaded so far.
Completed int64
// Total is total bytes to download.
Total int64
// Percent is completion percentage (0-100).
Percent float64
// Error contains failure details if Status is "error".
Error error
}
PullProgress reports download progress.
Description ¶
Sent through progress channel during model downloads.
type RetryPolicy ¶
type RetryPolicy struct {
// MaxRetries is the maximum number of retry attempts.
MaxRetries int
// InitialDelay is the delay before first retry.
InitialDelay time.Duration
// MaxDelay caps the exponential backoff.
MaxDelay time.Duration
// JitterFactor adds randomness (0.0 to 1.0).
// 0.1 means +/- 10% variation.
JitterFactor float64
}
RetryPolicy configures exponential backoff for retries.
Description ¶
Controls how network failures are retried with exponential backoff and optional jitter for distributed systems.
Defaults ¶
Default policy: 3 retries, 1s initial delay, 30s max delay, 0.1 jitter.
func DefaultRetryPolicy ¶
func DefaultRetryPolicy() *RetryPolicy
DefaultRetryPolicy returns the standard retry configuration.
Description ¶
Returns a policy with reasonable defaults for network operations: 3 retries, exponential backoff from 1s to 30s, 10% jitter.
Inputs ¶
None.
Outputs ¶
- *RetryPolicy: Default configuration
Examples ¶
opts := EnsureOpts{
RetryPolicy: DefaultRetryPolicy(),
}
Limitations ¶
- May be too aggressive for slow networks
Assumptions ¶
- Network failures are transient
func (*RetryPolicy) CalculateDelay ¶
func (p *RetryPolicy) CalculateDelay(attempt int) time.Duration
CalculateDelay computes the delay for a given attempt.
Description ¶
Uses exponential backoff with jitter: delay = min(initial * 2^attempt, max) * (1 +/- jitter).
Inputs ¶
- attempt: Zero-based attempt number
Outputs ¶
- time.Duration: Delay before next retry
Examples ¶
policy := DefaultRetryPolicy() delay := policy.CalculateDelay(0) // ~1s delay = policy.CalculateDelay(2) // ~4s
Limitations ¶
- Jitter introduces non-determinism
Assumptions ¶
- attempt >= 0
type SelectionOpts ¶
type SelectionOpts struct {
// MinContextWindow requires minimum context window size in tokens.
// Zero means no minimum requirement.
MinContextWindow int
// PreferQuantized favors quantized models over full precision.
// When true, Q4/Q8 models are preferred over F16.
PreferQuantized bool
// MaxRAM_GB limits selection to models fitting in this RAM.
// Zero means no RAM limit (use system RAM).
MaxRAM_GB int
// RequiredCapabilities filters by model capabilities.
// All listed capabilities must be present.
// Examples: ["code", "math", "vision"]
RequiredCapabilities []string
// PreferredFamily prefers models from a specific family.
// Examples: "llama", "phi", "mistral"
PreferredFamily string
// ExcludeModels is a list of model names to exclude.
// Useful for excluding known-broken models.
ExcludeModels []string
}
SelectionOpts configures model selection behavior.
Description ¶
Provides constraints and preferences for automatic model selection. All fields are optional; zero values mean "no constraint".
Thread Safety ¶
SelectionOpts is immutable and safe for concurrent read access.
func (*SelectionOpts) HasCapabilityRequirement ¶
func (o *SelectionOpts) HasCapabilityRequirement() bool
HasCapabilityRequirement returns true if any capabilities are required.
Description ¶
Checks if the RequiredCapabilities slice is non-empty.
Outputs ¶
- bool: True if capabilities filtering is active
Examples ¶
opts := SelectionOpts{RequiredCapabilities: []string{"code"}}
fmt.Println(opts.HasCapabilityRequirement()) // true
type SilentProgressRenderer ¶
type SilentProgressRenderer struct {
// contains filtered or unexported fields
}
SilentProgressRenderer suppresses all progress output.
Description ¶
This implementation is used for --quiet mode. It tracks state internally but produces no output during progress. Only the final Complete call produces a single summary line.
Thread Safety ¶
Safe for concurrent use. Uses mutex to protect state.
func NewSilentProgressRenderer ¶
func NewSilentProgressRenderer(w io.Writer) *SilentProgressRenderer
NewSilentProgressRenderer creates a new silent progress renderer.
Description ¶
Creates a renderer that suppresses progress output. Only emits a single line on completion.
Inputs ¶
- w: Writer for final completion message (nil = completely silent)
Outputs ¶
- *SilentProgressRenderer: Configured renderer
Examples ¶
renderer := NewSilentProgressRenderer(os.Stdout) renderer := NewSilentProgressRenderer(nil) // completely silent
Limitations ¶
- No progress output during operation
Assumptions ¶
None.
func (*SilentProgressRenderer) Complete ¶
func (r *SilentProgressRenderer) Complete(ctx context.Context, operation string, success bool, message string)
Complete implements ProgressRenderer.
Description ¶
Outputs a single completion line if output is configured.
Inputs ¶
- ctx: Context (unused)
- operation: Operation identifier
- success: Whether operation succeeded
- message: Final status message
Outputs ¶
None (writes to configured output if not nil).
Examples ¶
renderer.Complete(ctx, "download", true, "completed") // Output: "✓ download: completed (5s)"
Limitations ¶
- Only outputs if r.output is not nil
Assumptions ¶
None.
func (*SilentProgressRenderer) IsTTY ¶
func (r *SilentProgressRenderer) IsTTY() bool
IsTTY implements ProgressRenderer.
Description ¶
Always returns false for silent renderer.
Inputs ¶
None.
Outputs ¶
- bool: Always false
Examples ¶
isTTY := renderer.IsTTY() // false
Limitations ¶
None.
Assumptions ¶
None.
func (*SilentProgressRenderer) Render ¶
func (r *SilentProgressRenderer) Render(ctx context.Context, operation, status string, completed, total int64)
Render implements ProgressRenderer.
Description ¶
Tracks state internally but produces no output.
Inputs ¶
- ctx: Context for cancellation
- operation: Operation identifier
- status: Current status text
- completed: Bytes completed
- total: Total bytes (0 if unknown)
Outputs ¶
None (silent).
Examples ¶
renderer.Render(ctx, "download", "downloading", 1024, 4096) // no output
Limitations ¶
- Produces no output
Assumptions ¶
None.
func (*SilentProgressRenderer) SetOutput ¶
func (r *SilentProgressRenderer) SetOutput(w io.Writer)
SetOutput implements ProgressRenderer.
Description ¶
Reconfigures the output destination for completion messages.
Inputs ¶
- w: New output writer (nil = no output)
Outputs ¶
None (modifies internal state).
Examples ¶
renderer.SetOutput(os.Stderr) renderer.SetOutput(nil) // completely silent
Limitations ¶
None.
Assumptions ¶
None.
type SystemHardwareDetector ¶
type SystemHardwareDetector struct {
// contains filtered or unexported fields
}
SystemHardwareDetector detects actual system RAM.
Description ¶
Production implementation that queries the operating system for memory information. Uses platform-specific methods:
- macOS: sysctl hw.memsize
- Linux: /proc/meminfo
- Windows: runtime.MemStats (fallback)
Thread Safety ¶
SystemHardwareDetector is safe for concurrent use. Values are cached after first detection.
func NewSystemHardwareDetector ¶
func NewSystemHardwareDetector() *SystemHardwareDetector
NewSystemHardwareDetector creates a hardware detector.
Description ¶
Creates a detector that will query the system for RAM information on first use. Results are cached for performance.
Outputs ¶
- *SystemHardwareDetector: Ready-to-use detector
Examples ¶
detector := NewSystemHardwareDetector()
fmt.Printf("Total RAM: %d GB\n", detector.GetTotalRAM_GB())
func (*SystemHardwareDetector) GetAvailableRAM_GB ¶
func (d *SystemHardwareDetector) GetAvailableRAM_GB() int
GetAvailableRAM_GB returns available RAM in gigabytes.
Description ¶
Returns estimated available RAM. Uses platform-specific detection:
- macOS: vm_stat for free + inactive pages
- Linux: MemAvailable from /proc/meminfo
- Fallback: 75% of total RAM
Outputs ¶
- int: Available RAM in GB (minimum 1)
Examples ¶
detector := NewSystemHardwareDetector()
avail := detector.GetAvailableRAM_GB()
fmt.Printf("Available: %d GB\n", avail)
Limitations ¶
- Windows support is limited (uses fallback)
- Value is cached after first detection
func (*SystemHardwareDetector) GetTotalRAM_GB ¶
func (d *SystemHardwareDetector) GetTotalRAM_GB() int
GetTotalRAM_GB returns total system RAM in gigabytes.
Description ¶
Returns total physical RAM installed. Uses platform-specific detection:
- macOS: sysctl hw.memsize
- Linux: MemTotal from /proc/meminfo
- Fallback: runtime.MemStats
Outputs ¶
- int: Total RAM in GB (minimum 1)
Examples ¶
detector := NewSystemHardwareDetector()
total := detector.GetTotalRAM_GB()
fmt.Printf("Total: %d GB\n", total)
Limitations ¶
- Value is cached after first detection
type VerificationResult ¶
type VerificationResult struct {
// Model is the verified model name.
Model string
// Verified is true if digest matches.
Verified bool
// Digest is the computed digest.
Digest string
// ExpectedDigest is what the registry reports (on mismatch).
ExpectedDigest string
// Error contains verification failure details.
Error error
}
VerificationResult contains integrity check outcome.
Description ¶
Reports whether a model's digest matches the expected value.