memory

package
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Apr 20, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

README

Memory Package

The memory package provides persistent storage for routing decisions, provider quirks, and user preferences. This enables switchAILocal to learn from past decisions and improve routing over time.

Overview

The memory system is a core component of the Clawd Patterns Integration that transforms switchAILocal from a stateless proxy into an intelligent, learning gateway. It stores:

  • Routing History: All routing decisions with their outcomes
  • Provider Quirks: Known issues and workarounds for providers
  • User Preferences: Learned preferences per API key
  • Daily Logs: Time-series data for analytics
  • Analytics: Aggregated metrics and performance data

Directory Structure

The memory system creates the following directory structure:

.switchailocal/memory/
├── routing-history.jsonl       # All routing decisions with outcomes
├── provider-quirks.md           # Known issues and workarounds
├── user-preferences/            # Per-API-key preferences
│   ├── sha256-abc123.json
│   └── sha256-def456.json
├── daily/                       # Daily operation logs
│   ├── 2026-02-01.jsonl
│   └── 2026-02-02.jsonl
└── analytics/                   # Aggregated metrics
    ├── provider-stats.json
    └── model-performance.json

Usage

Initializing the Directory Structure
import "github.com/traylinx/switchAILocal/internal/memory"

// Create directory structure manager
ds := memory.NewDirectoryStructure(".switchailocal/memory")

// Initialize the directory structure
if err := ds.Initialize(); err != nil {
    log.Fatalf("Failed to initialize memory structure: %v", err)
}

// Validate the structure
if err := ds.Validate(); err != nil {
    log.Fatalf("Validation failed: %v", err)
}
Getting Paths
// Get path to routing history file
historyPath := ds.GetRoutingHistoryPath()

// Get path to provider quirks file
quirksPath := ds.GetProviderQuirksPath()

// Get path to user preferences directory
prefsDir := ds.GetUserPreferencesDir()

// Get path to specific user's preferences
userPrefsPath := ds.GetUserPreferencePath("sha256:abc123")

// Get path to daily log file
dailyLogPath := ds.GetDailyLogPath("2026-02-02")
Configuration
// Get default configuration
config := memory.DefaultMemoryConfig()

// Customize configuration
config.Enabled = true
config.BaseDir = "/custom/path/memory"
config.RetentionDays = 30
config.MaxLogSizeMB = 50
config.Compression = false

Data Types

RoutingDecision

Represents a complete routing decision with its outcome:

decision := &memory.RoutingDecision{
    Timestamp:  time.Now(),
    APIKeyHash: "sha256:abc123",
    Request: memory.RequestInfo{
        Model:         "auto",
        Intent:        "coding",
        ContentHash:   "sha256:def456",
        ContentLength: 1234,
    },
    Routing: memory.RoutingInfo{
        Tier:          "semantic",
        SelectedModel: "claudecli:claude-sonnet-4",
        Confidence:    0.92,
        LatencyMs:     15,
    },
    Outcome: memory.OutcomeInfo{
        Success:        true,
        ResponseTimeMs: 2340,
        QualityScore:   0.88,
    },
}
UserPreferences

Represents learned preferences for a specific API key:

prefs := &memory.UserPreferences{
    APIKeyHash:  "sha256:abc123",
    LastUpdated: time.Now(),
    ModelPreferences: map[string]string{
        "coding":    "claudecli:claude-sonnet-4",
        "reasoning": "geminicli:gemini-2.5-pro",
    },
    ProviderBias: map[string]float64{
        "ollama":    0.5,
        "claudecli": 0.3,
    },
    CustomRules: []memory.PreferenceRule{
        {
            Condition: "intent == 'coding'",
            Model:     "claudecli:claude-sonnet-4",
            Priority:  100,
        },
    },
}
Quirk

Represents a known provider issue and its workaround:

quirk := &memory.Quirk{
    Provider:   "ollama",
    Issue:      "Connection timeout on first request after idle",
    Workaround: "Send warmup request on startup",
    Discovered: time.Now(),
    Frequency:  "3/10 startups",
    Severity:   "medium",
}

Security

The memory system implements several security measures:

  • API Key Hashing: API keys are hashed using SHA-256 and never stored in plaintext
  • File Permissions: All files are created with restrictive permissions (0600 for files, 0700 for directories)
  • PII Sanitization: Personal information is sanitized before storage
  • Encryption: Optional encryption at rest for sensitive data

Performance

The memory system is designed for minimal performance impact:

  • Async Writes: All writes are asynchronous and non-blocking
  • Append-Only: Routing history uses JSONL format for efficient appends
  • Caching: Frequently accessed data is cached in memory
  • Batch Processing: Analytics are computed in batches

Target performance metrics:

  • Memory append: < 5ms
  • Memory read: < 10ms
  • Memory query: < 50ms

Testing

Run the tests:

go test -v ./internal/memory/

Run with coverage:

go test -v -cover ./internal/memory/

Requirements Validation

This implementation validates the following requirements:

  • FR-1.1: Persistent Storage - Creates .switchailocal/memory/ directory structure
  • FR-1.2: Memory Types - Defines all core types (RoutingDecision, UserPreferences, Quirk, etc.)

Next Steps

After implementing the directory structure and types, the next tasks are:

  1. Implement routing history store (JSONL append-only storage)
  2. Implement provider quirks tracker (Markdown format)
  3. Implement user preferences system (JSON per API key)
  4. Create unified memory manager
  5. Integrate with Cortex Router

References

Documentation

Overview

Package memory provides persistent storage for routing decisions, provider quirks, and user preferences. This enables switchAILocal to learn from past decisions and improve routing over time.

Example (DefaultConfig)

Example_defaultConfig demonstrates the default memory configuration.

package main

import (
	"fmt"

	"github.com/traylinx/switchAILocal/internal/memory"
)

func main() {
	config := memory.DefaultMemoryConfig()

	fmt.Printf("Enabled: %v\n", config.Enabled)
	fmt.Printf("Base directory: %s\n", config.BaseDir)
	fmt.Printf("Retention days: %d\n", config.RetentionDays)
	fmt.Printf("Max log size (MB): %d\n", config.MaxLogSizeMB)
	fmt.Printf("Compression: %v\n", config.Compression)

}
Output:
Enabled: false
Base directory: .switchailocal/memory
Retention days: 90
Max log size (MB): 100
Compression: true
Example (GetPaths)

Example_getPaths demonstrates how to get paths to various memory system components.

package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"

	"github.com/traylinx/switchAILocal/internal/memory"
)

func main() {
	// Create a temporary directory for this example
	tmpDir, err := os.MkdirTemp("", "memory-example-*")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(tmpDir)

	// Create and initialize directory structure
	baseDir := filepath.Join(tmpDir, ".switchailocal", "memory")
	ds := memory.NewDirectoryStructure(baseDir)

	if err := ds.Initialize(); err != nil {
		log.Fatal(err)
	}

	// Get paths to various components
	fmt.Println("Routing history:", filepath.Base(ds.GetRoutingHistoryPath()))
	fmt.Println("Provider quirks:", filepath.Base(ds.GetProviderQuirksPath()))
	fmt.Println("User preferences dir:", filepath.Base(ds.GetUserPreferencesDir()))
	fmt.Println("Daily logs dir:", filepath.Base(ds.GetDailyLogsDir()))
	fmt.Println("Analytics dir:", filepath.Base(ds.GetAnalyticsDir()))

}
Output:
Routing history: routing-history.jsonl
Provider quirks: provider-quirks.md
User preferences dir: user-preferences
Daily logs dir: daily
Analytics dir: analytics

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CalculateQualityScore

func CalculateQualityScore(success bool, responseTimeMs int64, hasError bool) float64

CalculateQualityScore computes a quality score for a request outcome. The score is based on success, response time, and error presence. Returns a value between 0.0 (worst) and 1.0 (best).

func CheckDiskSpace

func CheckDiskSpace(path string, requiredBytes int64) error

CheckDiskSpace verifies sufficient disk space is available before writing. It requires at least 100MB free space plus the estimated write size.

func SanitizeString

func SanitizeString(s string, maxLen int) string

SanitizeString removes control characters and limits length.

func ValidateQuirk

func ValidateQuirk(quirk *Quirk) error

ValidateQuirk validates a provider quirk before storage.

func ValidateRoutingDecision

func ValidateRoutingDecision(decision *RoutingDecision) error

ValidateRoutingDecision validates all fields of a routing decision before storage.

func ValidateUserPreferences

func ValidateUserPreferences(prefs *UserPreferences) error

ValidateUserPreferences validates user preferences before storage.

Types

type AnalyticsEngine

type AnalyticsEngine struct {
	// contains filtered or unexported fields
}

AnalyticsEngine computes and stores aggregated metrics from routing history. It provides provider stats, model performance metrics, and trend analysis.

func NewAnalyticsEngine

func NewAnalyticsEngine(analyticsDir string) *AnalyticsEngine

NewAnalyticsEngine creates a new analytics engine.

func (*AnalyticsEngine) ComputeAnalytics

func (ae *AnalyticsEngine) ComputeAnalytics(decisions []*RoutingDecision) (*AnalyticsSummary, error)

ComputeAnalytics computes analytics from routing decisions and stores the results.

func (*AnalyticsEngine) GetLastUpdate

func (ae *AnalyticsEngine) GetLastUpdate() time.Time

GetLastUpdate returns the timestamp of the last analytics update.

func (*AnalyticsEngine) GetModelPerformance

func (ae *AnalyticsEngine) GetModelPerformance() map[string]*ModelPerformance

GetModelPerformance returns cached model performance metrics.

func (*AnalyticsEngine) GetProviderStats

func (ae *AnalyticsEngine) GetProviderStats() map[string]*ProviderStats

GetProviderStats returns cached provider statistics.

func (*AnalyticsEngine) LoadAnalytics

func (ae *AnalyticsEngine) LoadAnalytics() (*AnalyticsSummary, error)

LoadAnalytics loads previously stored analytics from disk.

type AnalyticsSummary

type AnalyticsSummary struct {
	GeneratedAt       time.Time                    `json:"generated_at"`
	TimeRange         TimeRange                    `json:"time_range"`
	ProviderStats     map[string]*ProviderStats    `json:"provider_stats"`
	ModelPerformance  map[string]*ModelPerformance `json:"model_performance"`
	TierEffectiveness *TierEffectiveness           `json:"tier_effectiveness"`
	CostAnalysis      *CostAnalysis                `json:"cost_analysis"`
	TrendAnalysis     *TrendAnalysis               `json:"trend_analysis"`
}

AnalyticsSummary provides a comprehensive view of system analytics.

type CostAnalysis

type CostAnalysis struct {
	TotalCost        float64            `json:"total_cost"`
	CostByProvider   map[string]float64 `json:"cost_by_provider"`
	CostByModel      map[string]float64 `json:"cost_by_model"`
	AvgCostPerReq    float64            `json:"avg_cost_per_req"`
	CostTrend        []DailyCost        `json:"cost_trend"`
	SavingsFromLocal float64            `json:"savings_from_local"`
}

CostAnalysis provides cost-related analytics.

type DailyCost

type DailyCost struct {
	Date string  `json:"date"`
	Cost float64 `json:"cost"`
}

DailyCost represents cost for a specific day.

type DailyLogEntry

type DailyLogEntry struct {
	Timestamp time.Time   `json:"timestamp"`
	Type      string      `json:"type"` // "routing", "quirk", "preference_update"
	Data      interface{} `json:"data"`
}

DailyLogEntry represents a single entry in the daily log.

type DailyLogsManager

type DailyLogsManager struct {
	// contains filtered or unexported fields
}

DailyLogsManager handles daily log rotation and archival. It automatically rotates logs at midnight and manages log retention.

func NewDailyLogsManager

func NewDailyLogsManager(baseDir string, retentionDays int, compression bool) (*DailyLogsManager, error)

NewDailyLogsManager creates a new daily logs manager.

func (*DailyLogsManager) CleanupOldLogs

func (dlm *DailyLogsManager) CleanupOldLogs() error

CleanupOldLogs removes log files older than the retention period.

func (*DailyLogsManager) Close

func (dlm *DailyLogsManager) Close() error

Close gracefully shuts down the daily logs manager.

func (*DailyLogsManager) GetLogFiles

func (dlm *DailyLogsManager) GetLogFiles() ([]string, error)

GetLogFiles returns a list of all daily log files, sorted by date.

func (*DailyLogsManager) GetStats

func (dlm *DailyLogsManager) GetStats() (*DailyLogsStats, error)

GetStats returns statistics about the daily logs.

func (*DailyLogsManager) ReadLogFile

func (dlm *DailyLogsManager) ReadLogFile(fileName string, limit int) ([]*DailyLogEntry, error)

ReadLogFile reads entries from a specific daily log file.

func (*DailyLogsManager) WriteEntry

func (dlm *DailyLogsManager) WriteEntry(entryType string, data interface{}) error

WriteEntry writes an entry to the current daily log. This is thread-safe and non-blocking.

type DailyLogsStats

type DailyLogsStats struct {
	TotalLogFiles      int    `json:"total_log_files"`
	TotalEntries       int    `json:"total_entries"`
	DiskUsageBytes     int64  `json:"disk_usage_bytes"`
	OldestLogDate      string `json:"oldest_log_date,omitempty"`
	NewestLogDate      string `json:"newest_log_date,omitempty"`
	RetentionDays      int    `json:"retention_days"`
	CompressionEnabled bool   `json:"compression_enabled"`
}

DailyLogsStats provides statistics about the daily logs system.

type DailyMetric

type DailyMetric struct {
	Date  string  `json:"date"`
	Value float64 `json:"value"`
}

DailyMetric represents a daily metric value.

type DailyVolume

type DailyVolume struct {
	Date     string `json:"date"`
	Requests int    `json:"requests"`
}

DailyVolume represents request volume for a specific day.

type DirectoryStructure

type DirectoryStructure struct {
	// contains filtered or unexported fields
}

DirectoryStructure manages the memory system directory structure.

func NewDirectoryStructure

func NewDirectoryStructure(baseDir string) *DirectoryStructure

NewDirectoryStructure creates a new directory structure manager.

func (*DirectoryStructure) GetAnalyticsDir

func (ds *DirectoryStructure) GetAnalyticsDir() string

GetAnalyticsDir returns the full path to the analytics directory.

func (*DirectoryStructure) GetDailyLogPath

func (ds *DirectoryStructure) GetDailyLogPath(date string) string

GetDailyLogPath returns the full path to a specific day's log file.

func (*DirectoryStructure) GetDailyLogsDir

func (ds *DirectoryStructure) GetDailyLogsDir() string

GetDailyLogsDir returns the full path to the daily logs directory.

func (*DirectoryStructure) GetProviderQuirksPath

func (ds *DirectoryStructure) GetProviderQuirksPath() string

GetProviderQuirksPath returns the full path to the provider quirks file.

func (*DirectoryStructure) GetRoutingHistoryPath

func (ds *DirectoryStructure) GetRoutingHistoryPath() string

GetRoutingHistoryPath returns the full path to the routing history file.

func (*DirectoryStructure) GetUserPreferencePath

func (ds *DirectoryStructure) GetUserPreferencePath(apiKeyHash string) string

GetUserPreferencePath returns the full path to a specific user's preferences file.

func (*DirectoryStructure) GetUserPreferencesDir

func (ds *DirectoryStructure) GetUserPreferencesDir() string

GetUserPreferencesDir returns the full path to the user preferences directory.

func (*DirectoryStructure) Initialize

func (ds *DirectoryStructure) Initialize() error

Initialize creates the complete directory structure for the memory system. It creates all necessary directories and files with proper permissions. Returns an error if any directory or file creation fails.

Example

ExampleDirectoryStructure_Initialize demonstrates how to initialize the memory system directory structure.

package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"

	"github.com/traylinx/switchAILocal/internal/memory"
)

func main() {
	// Create a temporary directory for this example
	tmpDir, err := os.MkdirTemp("", "memory-example-*")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(tmpDir)

	// Create directory structure manager
	baseDir := filepath.Join(tmpDir, ".switchailocal", "memory")
	ds := memory.NewDirectoryStructure(baseDir)

	// Initialize the directory structure
	if err := ds.Initialize(); err != nil {
		log.Fatalf("Failed to initialize memory structure: %v", err)
	}

	// Validate the structure
	if err := ds.Validate(); err != nil {
		log.Fatalf("Validation failed: %v", err)
	}

	fmt.Println("Memory system directory structure initialized successfully")

}
Output:
Memory system directory structure initialized successfully

func (*DirectoryStructure) Validate

func (ds *DirectoryStructure) Validate() error

Validate checks if the directory structure is valid and complete.

type HourlyStats

type HourlyStats struct {
	Hour       int     `json:"hour"`
	Requests   int     `json:"requests"`
	AvgLatency float64 `json:"avg_latency"`
}

HourlyStats represents statistics for a specific hour of day.

type MemoryConfig

type MemoryConfig struct {
	Enabled       bool   `yaml:"enabled"`
	BaseDir       string `yaml:"base_dir"`
	RetentionDays int    `yaml:"retention_days"`
	MaxLogSizeMB  int    `yaml:"max_log_size_mb"`
	Compression   bool   `yaml:"compression"`
}

MemoryConfig represents configuration for the memory system.

func DefaultMemoryConfig

func DefaultMemoryConfig() *MemoryConfig

DefaultMemoryConfig returns the default memory configuration.

type MemoryManager

type MemoryManager interface {
	// RecordRouting stores a routing decision with its outcome
	RecordRouting(decision *RoutingDecision) error

	// GetUserPreferences retrieves learned preferences for an API key
	GetUserPreferences(apiKeyHash string) (*UserPreferences, error)

	// UpdateUserPreferences updates learned preferences explicitly
	UpdateUserPreferences(prefs *UserPreferences) error

	// DeleteUserPreferences deletes preferences for a user
	DeleteUserPreferences(apiKeyHash string) error

	// AddQuirk records a provider quirk or workaround
	AddQuirk(quirk *Quirk) error

	// GetProviderQuirks retrieves known quirks for a provider
	GetProviderQuirks(provider string) ([]*Quirk, error)

	// GetHistory retrieves routing history for an API key
	GetHistory(apiKeyHash string, limit int) ([]*RoutingDecision, error)

	// GetAllHistory retrieves all routing history
	GetAllHistory(limit int) ([]*RoutingDecision, error)

	// LearnFromOutcome updates preferences based on request outcome
	LearnFromOutcome(decision *RoutingDecision) error

	// GetStats returns aggregated statistics
	GetStats() (*MemoryStats, error)

	// GetAnalytics returns computed analytics summary
	GetAnalytics() (*AnalyticsSummary, error)

	// ComputeAnalytics computes fresh analytics from routing history
	ComputeAnalytics() (*AnalyticsSummary, error)

	// Cleanup performs maintenance tasks (log rotation, old file cleanup)
	Cleanup() error

	// Close gracefully shuts down the memory manager
	Close() error
}

MemoryManager provides a unified interface for all memory operations. It coordinates routing history, provider quirks, and user preferences stores.

func NewMemoryManager

func NewMemoryManager(config *MemoryConfig) (MemoryManager, error)

NewMemoryManager creates a new memory manager with the given configuration. It initializes all stores and starts background maintenance tasks.

type MemoryManagerImpl

type MemoryManagerImpl struct {
	// contains filtered or unexported fields
}

MemoryManagerImpl implements the MemoryManager interface. It coordinates all memory stores and provides unified access.

func (*MemoryManagerImpl) AddQuirk

func (mm *MemoryManagerImpl) AddQuirk(quirk *Quirk) error

AddQuirk records a provider quirk or workaround.

func (*MemoryManagerImpl) Cleanup

func (mm *MemoryManagerImpl) Cleanup() error

Cleanup performs maintenance tasks like log rotation and old file cleanup.

func (*MemoryManagerImpl) Close

func (mm *MemoryManagerImpl) Close() error

Close gracefully shuts down the memory manager.

func (*MemoryManagerImpl) ComputeAnalytics

func (mm *MemoryManagerImpl) ComputeAnalytics() (*AnalyticsSummary, error)

ComputeAnalytics computes fresh analytics from all routing history.

func (*MemoryManagerImpl) DeleteUserPreferences

func (mm *MemoryManagerImpl) DeleteUserPreferences(apiKeyHash string) error

DeleteUserPreferences deletes preferences for a user.

func (*MemoryManagerImpl) GetAllHistory

func (mm *MemoryManagerImpl) GetAllHistory(limit int) ([]*RoutingDecision, error)

GetAllHistory retrieves all routing history.

func (*MemoryManagerImpl) GetAnalytics

func (mm *MemoryManagerImpl) GetAnalytics() (*AnalyticsSummary, error)

GetAnalytics returns the most recent analytics summary.

func (*MemoryManagerImpl) GetHistory

func (mm *MemoryManagerImpl) GetHistory(apiKeyHash string, limit int) ([]*RoutingDecision, error)

GetHistory retrieves routing history for an API key.

func (*MemoryManagerImpl) GetProviderQuirks

func (mm *MemoryManagerImpl) GetProviderQuirks(provider string) ([]*Quirk, error)

GetProviderQuirks retrieves known quirks for a provider.

func (*MemoryManagerImpl) GetStats

func (mm *MemoryManagerImpl) GetStats() (*MemoryStats, error)

GetStats returns aggregated statistics about the memory system.

func (*MemoryManagerImpl) GetUserPreferences

func (mm *MemoryManagerImpl) GetUserPreferences(apiKeyHash string) (*UserPreferences, error)

GetUserPreferences retrieves learned preferences for an API key.

func (*MemoryManagerImpl) LearnFromOutcome

func (mm *MemoryManagerImpl) LearnFromOutcome(decision *RoutingDecision) error

LearnFromOutcome updates preferences based on request outcome.

func (*MemoryManagerImpl) RecordRouting

func (mm *MemoryManagerImpl) RecordRouting(decision *RoutingDecision) error

RecordRouting stores a routing decision with its outcome. This is thread-safe and non-blocking.

func (*MemoryManagerImpl) UpdateUserPreferences

func (mm *MemoryManagerImpl) UpdateUserPreferences(prefs *UserPreferences) error

UpdateUserPreferences updates learned preferences explicitly.

type MemoryStats

type MemoryStats struct {
	TotalDecisions     int       `json:"total_decisions"`
	TotalUsers         int       `json:"total_users"`
	TotalQuirks        int       `json:"total_quirks"`
	DiskUsageBytes     int64     `json:"disk_usage_bytes"`
	OldestDecision     time.Time `json:"oldest_decision,omitempty"`
	NewestDecision     time.Time `json:"newest_decision,omitempty"`
	LastCleanup        time.Time `json:"last_cleanup,omitempty"`
	RetentionDays      int       `json:"retention_days"`
	CompressionEnabled bool      `json:"compression_enabled"`

	// Daily logs statistics
	DailyLogsStats *DailyLogsStats `json:"daily_logs_stats,omitempty"`

	// Analytics information
	LastAnalyticsUpdate time.Time `json:"last_analytics_update,omitempty"`
}

MemoryStats provides statistics about the memory system.

type ModelPerformance

type ModelPerformance struct {
	Model           string  `json:"model"`
	TotalRequests   int     `json:"total_requests"`
	SuccessRate     float64 `json:"success_rate"`
	AvgQualityScore float64 `json:"avg_quality_score"`
	AvgCostPerReq   float64 `json:"avg_cost_per_req"`
}

ModelPerformance represents performance metrics for a specific model.

type ModelPopularity

type ModelPopularity struct {
	Model       string  `json:"model"`
	Requests    int     `json:"requests"`
	Percentage  float64 `json:"percentage"`
	SuccessRate float64 `json:"success_rate"`
}

ModelPopularity represents model usage statistics.

type OutcomeInfo

type OutcomeInfo struct {
	Success        bool    `json:"success"`
	ResponseTimeMs int64   `json:"response_time_ms"`
	Error          string  `json:"error,omitempty"`
	QualityScore   float64 `json:"quality_score"` // 0.0 to 1.0
}

OutcomeInfo contains information about the request outcome.

type PreferenceRule

type PreferenceRule struct {
	Condition string `json:"condition"` // e.g., "intent == 'coding' && hour >= 9"
	Model     string `json:"model"`
	Priority  int    `json:"priority"`
}

PreferenceRule represents a user-defined routing preference rule.

type PreferencesStore

type PreferencesStore struct {
	// contains filtered or unexported fields
}

PreferencesStore manages persistent storage of user preferences in JSON format. Each API key gets its own JSON file for preferences storage.

func NewPreferencesStore

func NewPreferencesStore(baseDir string) (*PreferencesStore, error)

NewPreferencesStore creates a new user preferences store. It uses the provided directory to store per-API-key JSON files.

func (*PreferencesStore) ClearCache

func (ps *PreferencesStore) ClearCache(apiKeyHash string)

ClearCache clears the preferences cache for all users or a specific user.

func (*PreferencesStore) Close

func (ps *PreferencesStore) Close() error

Close gracefully shuts down the preferences store. Currently a no-op but provided for consistency with other stores.

func (*PreferencesStore) Count

func (ps *PreferencesStore) Count() (int, error)

Count returns the total number of users with preferences.

func (*PreferencesStore) DeleteUserPreferences

func (ps *PreferencesStore) DeleteUserPreferences(apiKeyHash string) error

DeleteUserPreferences removes preferences for a specific user.

func (*PreferencesStore) GetPreferencesByIntent

func (ps *PreferencesStore) GetPreferencesByIntent(apiKeyHash, intent string) (string, error)

GetPreferencesByIntent retrieves the preferred model for a specific intent. Returns empty string if no preference exists for the intent.

func (*PreferencesStore) GetProviderBias

func (ps *PreferencesStore) GetProviderBias(apiKeyHash, provider string) (float64, error)

GetProviderBias retrieves the bias for a specific provider. Returns 0.0 if no bias exists for the provider.

func (*PreferencesStore) GetUserPreferences

func (ps *PreferencesStore) GetUserPreferences(apiKeyHash string) (*UserPreferences, error)

GetUserPreferences retrieves learned preferences for a specific API key. Returns default preferences if no preferences file exists for the API key.

func (*PreferencesStore) LearnFromOutcome

func (ps *PreferencesStore) LearnFromOutcome(decision *RoutingDecision) error

LearnFromOutcome updates preferences based on routing outcomes. This is the core learning mechanism that adjusts preferences based on success/failure patterns.

func (*PreferencesStore) ListUsers

func (ps *PreferencesStore) ListUsers() ([]string, error)

ListUsers returns a list of API key hashes that have preferences.

func (*PreferencesStore) MergePreferences

func (ps *PreferencesStore) MergePreferences(base, override *UserPreferences) *UserPreferences

MergePreferences merges two preference sets, with the second taking priority in conflicts. This is useful for combining learned preferences with user-defined preferences.

func (*PreferencesStore) UpdatePreferences

func (ps *PreferencesStore) UpdatePreferences(apiKeyHash string, prefs *UserPreferences) error

UpdatePreferences updates preferences for a specific API key. This method handles both creating new preferences and updating existing ones.

type ProviderStats

type ProviderStats struct {
	Provider      string    `json:"provider"`
	TotalRequests int       `json:"total_requests"`
	SuccessRate   float64   `json:"success_rate"`
	AvgLatencyMs  float64   `json:"avg_latency_ms"`
	ErrorRate     float64   `json:"error_rate"`
	LastUpdated   time.Time `json:"last_updated"`
}

ProviderStats represents aggregated statistics for a provider.

type Quirk

type Quirk struct {
	Provider   string    `json:"provider"`
	Issue      string    `json:"issue"`
	Workaround string    `json:"workaround"`
	Discovered time.Time `json:"discovered"`
	Frequency  string    `json:"frequency"` // e.g., "3/10 startups", "daily during peak"
	Severity   string    `json:"severity"`  // low, medium, high, critical
}

Quirk represents a known provider issue and its workaround.

type QuirksStore

type QuirksStore struct {
	// contains filtered or unexported fields
}

QuirksStore manages persistent storage of provider quirks in Markdown format. It provides thread-safe operations for adding and retrieving quirks.

func NewQuirksStore

func NewQuirksStore(filePath string) (*QuirksStore, error)

NewQuirksStore creates a new provider quirks store. It loads existing quirks from the file on initialization.

func (*QuirksStore) AddQuirk

func (qs *QuirksStore) AddQuirk(quirk *Quirk) error

AddQuirk records a provider quirk to persistent storage. It appends the quirk to the markdown file and updates the in-memory cache. Duplicate quirks (same provider and issue) are not added.

func (*QuirksStore) ApplyWorkaround

func (qs *QuirksStore) ApplyWorkaround(provider, issue string) (string, error)

ApplyWorkaround returns the workaround for a specific provider and issue. Returns an empty string if no matching quirk is found.

func (*QuirksStore) Close

func (qs *QuirksStore) Close() error

Close gracefully shuts down the quirks store. Currently a no-op but provided for consistency with other stores.

func (*QuirksStore) Count

func (qs *QuirksStore) Count() int

Count returns the total number of quirks across all providers.

func (*QuirksStore) CountByProvider

func (qs *QuirksStore) CountByProvider(provider string) int

CountByProvider returns the number of quirks for a specific provider.

func (*QuirksStore) GetAllQuirks

func (qs *QuirksStore) GetAllQuirks() (map[string][]*Quirk, error)

GetAllQuirks retrieves all quirks for all providers.

func (*QuirksStore) GetProviderQuirks

func (qs *QuirksStore) GetProviderQuirks(provider string) ([]*Quirk, error)

GetProviderQuirks retrieves all known quirks for a specific provider. Returns an empty slice if no quirks are found for the provider.

func (*QuirksStore) GetQuirksByFrequency

func (qs *QuirksStore) GetQuirksByFrequency(frequencyPattern string) ([]*Quirk, error)

GetQuirksByFrequency retrieves quirks that match a specific frequency pattern. This is useful for finding quirks that occur frequently.

func (*QuirksStore) GetQuirksBySeverity

func (qs *QuirksStore) GetQuirksBySeverity(severity string) ([]*Quirk, error)

GetQuirksBySeverity retrieves all quirks with a specific severity level.

type RequestInfo

type RequestInfo struct {
	Model         string `json:"model"`
	Intent        string `json:"intent"`
	ContentHash   string `json:"content_hash"`
	ContentLength int    `json:"content_length"`
}

RequestInfo contains information about the incoming request.

type RoutingDecision

type RoutingDecision struct {
	Timestamp  time.Time   `json:"timestamp"`
	APIKeyHash string      `json:"api_key_hash"`
	Request    RequestInfo `json:"request"`
	Routing    RoutingInfo `json:"routing"`
	Outcome    OutcomeInfo `json:"outcome"`
}

RoutingDecision represents a complete routing decision with its outcome. This is the core data structure for learning and analytics.

type RoutingHistoryStore

type RoutingHistoryStore struct {
	// contains filtered or unexported fields
}

RoutingHistoryStore manages persistent storage of routing decisions in JSONL format. It uses an async write queue with buffered channels to avoid blocking requests.

func NewRoutingHistoryStore

func NewRoutingHistoryStore(filePath string) (*RoutingHistoryStore, error)

NewRoutingHistoryStore creates a new routing history store. It initializes the async write queue and starts the background writer.

func (*RoutingHistoryStore) Close

func (rhs *RoutingHistoryStore) Close() error

Close gracefully shuts down the routing history store. It waits for all pending writes to complete before closing the file.

func (*RoutingHistoryStore) Count

func (rhs *RoutingHistoryStore) Count() (int, error)

Count returns the total number of routing decisions in the history.

func (*RoutingHistoryStore) GetAllHistory

func (rhs *RoutingHistoryStore) GetAllHistory(limit int) ([]*RoutingDecision, error)

GetAllHistory retrieves all routing history without filtering. The limit parameter controls the maximum number of results returned (most recent first).

func (*RoutingHistoryStore) GetHistory

func (rhs *RoutingHistoryStore) GetHistory(apiKeyHash string, limit int) ([]*RoutingDecision, error)

GetHistory retrieves routing history for a specific API key. It reads the entire history file and filters by API key hash. The limit parameter controls the maximum number of results returned (most recent first).

func (*RoutingHistoryStore) RecordRouting

func (rhs *RoutingHistoryStore) RecordRouting(decision *RoutingDecision) error

RecordRouting records a routing decision to persistent storage. This method is non-blocking and returns immediately after queuing the write. If the write queue is full, it returns an error without blocking.

type RoutingInfo

type RoutingInfo struct {
	Tier          string  `json:"tier"`           // reflex, semantic, cognitive, learned
	SelectedModel string  `json:"selected_model"` // e.g., "claudecli:claude-sonnet-4"
	Confidence    float64 `json:"confidence"`     // 0.0 to 1.0
	LatencyMs     int64   `json:"latency_ms"`     // routing decision latency
}

RoutingInfo contains information about the routing decision.

type TierEffectiveness

type TierEffectiveness struct {
	ReflexTier    *TierStats `json:"reflex_tier"`
	SemanticTier  *TierStats `json:"semantic_tier"`
	CognitiveTier *TierStats `json:"cognitive_tier"`
	LearnedTier   *TierStats `json:"learned_tier"`
}

TierEffectiveness tracks routing tier performance.

type TierStats

type TierStats struct {
	TotalRequests int     `json:"total_requests"`
	SuccessRate   float64 `json:"success_rate"`
	AvgLatencyMs  float64 `json:"avg_latency_ms"`
	AvgConfidence float64 `json:"avg_confidence"`
}

TierStats provides statistics for a routing tier.

type TimeRange

type TimeRange struct {
	StartTime time.Time `json:"start_time"`
	EndTime   time.Time `json:"end_time"`
	Days      int       `json:"days"`
}

TimeRange represents a time period for analytics.

type TrendAnalysis

type TrendAnalysis struct {
	RequestVolumeTrend []DailyVolume     `json:"request_volume_trend"`
	SuccessRateTrend   []DailyMetric     `json:"success_rate_trend"`
	LatencyTrend       []DailyMetric     `json:"latency_trend"`
	PopularModels      []ModelPopularity `json:"popular_models"`
	PeakHours          []HourlyStats     `json:"peak_hours"`
}

TrendAnalysis provides trend information over time.

type UserPreferences

type UserPreferences struct {
	APIKeyHash       string             `json:"api_key_hash"`
	LastUpdated      time.Time          `json:"last_updated"`
	LastAnalyzed     time.Time          `json:"last_analyzed,omitempty"`
	ModelPreferences map[string]string  `json:"model_preferences"` // intent -> model
	ModelConfidences map[string]float64 `json:"model_confidences"` // intent -> confidence
	ProviderBias     map[string]float64 `json:"provider_bias"`     // provider -> bias (-1.0 to 1.0)
	CustomRules      []PreferenceRule   `json:"custom_rules"`
}

UserPreferences represents learned preferences for a specific API key.

type WriteOperation

type WriteOperation struct {
	// contains filtered or unexported fields
}

WriteOperation represents a pending write operation.

Jump to

Keyboard shortcuts

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