models

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Mar 11, 2026 License: AGPL-3.0 Imports: 19 Imported by: 0

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.

  • cmd/aleutian (main): Contains ModelEnsurer, OllamaClient interfaces
  • cmd/aleutian/config: Configuration types

Index

Constants

This section is empty.

Variables

View Source
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.

View Source
var ErrAllFallbacksFailed = errors.New("all fallback models failed")

ErrAllFallbacksFailed indicates all fallback models failed.

View Source
var ErrInvalidModelName = errors.New("invalid model name")

ErrInvalidModelName indicates the model name is malformed.

View Source
var ErrModelBlocked = errors.New("model is blocked by policy")

ErrModelBlocked indicates a model is on the blocklist.

View Source
var ErrModelDigestMismatch = errors.New("model digest mismatch")

ErrModelDigestMismatch indicates the model digest doesn't match expected.

View Source
var ErrModelInfoUnavailable = errors.New("model info unavailable")

ErrModelInfoUnavailable indicates model info could not be retrieved.

View Source
var ErrModelNotFound = errors.New("model not found")

ErrModelNotFound indicates the requested model does not exist.

View Source
var ErrNoSuitableModel = errors.New("no suitable model found")

ErrNoSuitableModel indicates no model matches the selection criteria.

View Source
var ErrUnknownCategory = errors.New("unknown model category")

ErrUnknownCategory indicates the model category is not recognized.

View Source
var ErrVerificationFailed = errors.New("model verification failed")

ErrVerificationFailed indicates integrity check failed.

Functions

func ParseParameterSize

func ParseParameterSize(size string) int64

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

func ValidateModelName(name string) error

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

type MockCompleteCall struct {
	Operation string
	Success   bool
	Message   string
}

MockCompleteCall records a Complete call for test verification.

type MockEnsureCall

type MockEnsureCall struct {
	Model string
	Opts  EnsureOpts
}

MockEnsureCall records an EnsureModel call.

type MockHardwareDetector

type MockHardwareDetector struct {
	TotalRAM     int
	AvailableRAM int
}

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

type MockLogEntry struct {
	Level   string
	Message string
	Fields  []byte
}

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) Reset

func (w *MockLogWriter) Reset()

Reset clears captured 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

func (m *MockModelInfoProvider) GetModelInfo(ctx context.Context, model string) (*ModelInfo, error)

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

func (m *MockModelManager) SelectOptimalModel(ctx context.Context, purpose string) (string, error)

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.

func (*MockProgressRenderer) SetOutput

func (m *MockProgressRenderer) SetOutput(w io.Writer)

SetOutput implements ProgressRenderer.

Description

Records the output writer.

Inputs

  • w: Output writer

Outputs

None.

Examples

mock.SetOutput(os.Stdout)

Limitations

None.

Assumptions

None.

type MockRenderCall

type MockRenderCall struct {
	Operation string
	Status    string
	Completed int64
	Total     int64
}

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

func (m *ModelInfo) HasDigest() bool

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

func (m *ModelInfo) MatchesDigest(expected string) bool

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

func (m *ModelInfo) ParameterSizeString() string

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

func (m *ModelInfo) SizeGB() float64

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.

Jump to

Keyboard shortcuts

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