routing

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: May 26, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package routing provides model routing and health checking. Model discovery, pricing, and catalog data are delegated to eyrie. Hawk does NOT carry a hardcoded model catalog.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AllCatalogModelNames

func AllCatalogModelNames() []string

AllCatalogModelNames returns model IDs from the eyrie catalog cache.

func AllProviders

func AllProviders() []string

AllProviders returns all canonical model owner providers from eyrie's catalog.

func CheapestForProvider

func CheapestForProvider(provider, fallback string) string

CheapestForProvider queries eyrie's catalog at runtime and returns the cheapest model for the given provider. No hardcoded model names.

func DefaultModel

func DefaultModel(provider string) string

DefaultModel returns the first catalog model for a provider via eyrie JSON.

func MatchScore

func MatchScore(rule TagRule, tags map[string]string) int

MatchScore returns the number of matching tags between a rule and a tag set. Returns 0 if any tag in the rule does not match (all rule tags must be present).

func MostExpensiveForProvider

func MostExpensiveForProvider(provider, fallback string) string

MostExpensiveForProvider picks the highest input-priced model for a provider.

func PreferredModelForTier

func PreferredModelForTier(provider string, tier eycatalog.ModelTier, fallback string) string

PreferredModelForTier returns the eyrie-preferred model for a provider and tier.

func SuggestTierForTask

func SuggestTierForTask(taskType string) eycatalog.ModelTier

SuggestTierForTask maps a task type to an eyrie cost tier (not a concrete model ID).

func TierModels

func TierModels(provider string) (haiku, sonnet, opus string)

TierModels returns eyrie-preferred model IDs for haiku, sonnet, and opus tiers.

Types

type Capabilities

type Capabilities struct {
	Streaming       bool `json:"streaming"`
	FunctionCalling bool `json:"function_calling"`
	Vision          bool `json:"vision"`
	JSON            bool `json:"json"`
	Thinking        bool `json:"thinking"`
}

Capabilities describes what a model supports.

type CascadeRouter

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

CascadeRouter selects models based on task classification. It uses heuristic keyword matching to avoid LLM calls for routing.

func NewCascadeRouter

func NewCascadeRouter(roles ModelRoles) *CascadeRouter

NewCascadeRouter creates a cascade router with the given role assignments.

func (*CascadeRouter) ModelForTask

func (cr *CascadeRouter) ModelForTask(task TaskType) string

ModelForTask returns the model assigned to the given task type.

func (*CascadeRouter) Route

func (cr *CascadeRouter) Route(message string, hint TaskType) string

Route returns the model name for a given message. If hint is non-empty, it overrides the automatic classification.

type CircuitState

type CircuitState int

CircuitState represents circuit breaker state.

const (
	CircuitClosed   CircuitState = iota // normal
	CircuitOpen                         // rejecting
	CircuitHalfOpen                     // testing
)

type CodeHealth

type CodeHealth struct {
	Complexity   float64 // cyclomatic complexity estimate
	FileSize     int     // lines of code
	Dependencies int     // import count
	TestCoverage float64 // if known (0-1)
	Language     string
}

CodeHealth captures complexity metrics for a source file, used to route tasks to the cheapest model that can handle the file's complexity.

type CostTier

type CostTier int

CostTier is a relative cost band for cascade routing (cheap / mid / expensive).

const (
	CostTierCheap CostTier = iota
	CostTierMid
	CostTierExpensive
)

func CostTierOf

func CostTierOf(modelName string) CostTier

CostTierOf resolves a model's cost tier from eyrie catalog data (family, tier candidates, and within-provider pricing). Unknown models default to mid-tier.

type FallbackChain

type FallbackChain struct {
	Providers      []ProviderConfig
	HealthStatus   map[string]*FallbackProviderHealth
	ActiveProvider string
	// contains filtered or unexported fields
}

FallbackChain manages multi-provider fallback with health tracking.

func NewFallbackChain

func NewFallbackChain(providers []ProviderConfig) *FallbackChain

NewFallbackChain creates a new fallback chain from the given provider configs. Providers are sorted by priority (lower number = higher priority).

func (*FallbackChain) AllDown

func (fc *FallbackChain) AllDown() bool

AllDown returns true if every provider is either down or in cooldown.

func (*FallbackChain) BestLatency

func (fc *FallbackChain) BestLatency() *ProviderConfig

BestLatency returns the provider config with the lowest recent latency among healthy providers. Returns nil if no providers are healthy.

func (*FallbackChain) FormatStatus

func (fc *FallbackChain) FormatStatus() string

FormatStatus returns a human-readable status report of all providers.

func (*FallbackChain) GetFallback

func (fc *FallbackChain) GetFallback(currentProvider string) (*ProviderConfig, error)

GetFallback finds the next healthy provider after the current one in the chain.

func (*FallbackChain) IsHealthy

func (fc *FallbackChain) IsHealthy(provider string) bool

IsHealthy returns true if the named provider is currently healthy and not in cooldown.

func (*FallbackChain) RecordFailure

func (fc *FallbackChain) RecordFailure(provider string, err error)

RecordFailure records a failed call to a provider and applies cooldown if threshold exceeded.

func (*FallbackChain) RecordSuccess

func (fc *FallbackChain) RecordSuccess(provider string, latency time.Duration)

RecordSuccess records a successful call to a provider and resets failure state.

func (*FallbackChain) RecoverProvider

func (fc *FallbackChain) RecoverProvider(provider string)

RecoverProvider manually marks a provider as healthy and clears its cooldown.

func (*FallbackChain) SelectProvider

func (fc *FallbackChain) SelectProvider() (*ProviderConfig, error)

SelectProvider picks the highest-priority healthy provider, skipping those in cooldown.

type FallbackProviderHealth

type FallbackProviderHealth struct {
	Name                string
	Status              string // "healthy", "degraded", "down"
	LastSuccess         time.Time
	LastFailure         time.Time
	ConsecutiveFailures int
	CooldownUntil       *time.Time
	Latency             time.Duration
}

FallbackProviderHealth tracks detailed health state of a provider in the fallback chain.

type FallbackResult

type FallbackResult struct {
	Provider  string
	Model     string
	Attempts  int
	Fallbacks []string
	Duration  time.Duration
}

FallbackResult captures the outcome of a provider selection with fallback.

type HealthRouter

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

HealthRouter selects the cheapest appropriate model tier based on a file's code health metrics.

func NewHealthRouter

func NewHealthRouter() *HealthRouter

NewHealthRouter creates a router with catalog-backed tier configuration.

func NewHealthRouterForProvider

func NewHealthRouterForProvider(provider string) *HealthRouter

NewHealthRouterForProvider creates a router using eyrie tier models for the provider.

func (*HealthRouter) ComputeHealth

func (hr *HealthRouter) ComputeHealth(path string) CodeHealth

ComputeHealth estimates code health metrics for a file at the given path. It reads the file and analyses line count, nesting depth, and import count.

func (*HealthRouter) ModelForTask

func (hr *HealthRouter) ModelForTask(path string, primaryModel string) string

ModelForTask returns the cheapest appropriate model for the file's health level. If the selected tier contains the primaryModel, it is returned. Otherwise, the first model in the selected tier is returned.

func (*HealthRouter) SelectTier

func (hr *HealthRouter) SelectTier(health CodeHealth) string

SelectTier returns the tier name appropriate for the given code health.

  • "light": simple files (<100 lines, low complexity)
  • "standard": moderate files (100-500 lines)
  • "heavy": complex files (>500 lines, high complexity, many deps)

type LatencyClass

type LatencyClass string

LatencyClass categorizes model response speed.

const (
	LatencyFast   LatencyClass = "fast"
	LatencyMedium LatencyClass = "medium"
	LatencySlow   LatencyClass = "slow"
)

type ModelInfo

type ModelInfo struct {
	Name        string  `json:"name"`
	Provider    string  `json:"provider"`
	ContextSize int     `json:"context_size"`
	InputPrice  float64 `json:"input_price_per_million"`
	OutputPrice float64 `json:"output_price_per_million"`
	Description string  `json:"description,omitempty"`
	Recommended bool    `json:"recommended,omitempty"`
}

ModelInfo describes a known LLM model (view over eyrie catalog entries).

func ByProvider

func ByProvider(provider string) []ModelInfo

ByProvider returns all models for a given provider from eyrie's catalog.

func Find

func Find(name string) (ModelInfo, bool)

Find looks up a model by name via eyrie's JSON catalog.

func Recommended(provider string) (ModelInfo, bool)

Recommended returns the first catalog model for a provider.

type ModelRoles

type ModelRoles struct {
	Planner  string `json:"planner,omitempty"`
	Coder    string `json:"coder,omitempty"`
	Reviewer string `json:"reviewer,omitempty"`
	Commit   string `json:"commit,omitempty"`
}

ModelRoles maps each role to a specific model name. Empty fields fall back to the primary (coder) model.

func DefaultRoles

func DefaultRoles(primaryModel string) ModelRoles

DefaultRoles returns a ModelRoles where every role uses primaryModel except Commit, which defaults to the cheapest available model from the catalog.

func RolesForProvider

func RolesForProvider(provider string) ModelRoles

RolesForProvider builds standard planner/coder/reviewer/commit roles from the catalog.

func (ModelRoles) ModelForRole

func (r ModelRoles) ModelForRole(role Role) string

ModelForRole returns the model name assigned to role, falling back to the Coder model (primary) if the role-specific field is empty.

type ModelTier

type ModelTier struct {
	Name          string   // "light", "standard", "heavy"
	Models        []string // model names in this tier
	MaxComplexity float64  // max code health score for this tier
}

ModelTier groups models by the code complexity they can handle.

func DefaultHealthTiers

func DefaultHealthTiers(primaryProvider string) []ModelTier

DefaultHealthTiers builds complexity-based routing tiers from the eyrie catalog.

func DefaultTiers

func DefaultTiers() []ModelTier

DefaultTiers returns catalog-backed tiers for the default anthropic provider.

type ProviderConfig

type ProviderConfig struct {
	Name             string
	Model            string
	Priority         int
	Weight           float64
	MaxRetries       int
	CooldownDuration time.Duration
}

ProviderConfig describes a provider entry in the fallback chain.

type ProviderHealth

type ProviderHealth struct {
	Available        bool      `json:"available"`
	LastCheck        time.Time `json:"last_check"`
	LastSuccess      time.Time `json:"last_success"`
	ConsecutiveFails int       `json:"consecutive_fails"`
	AvgLatencyMs     float64   `json:"avg_latency_ms"`
}

ProviderHealth tracks the health state of a provider.

type Role

type Role string

Role identifies the purpose of a model within a multi-model workflow.

const (
	RolePlanner  Role = "planner"
	RoleCoder    Role = "coder"
	RoleReviewer Role = "reviewer"
	RoleCommit   Role = "commit"
)

type Router

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

Router provides health-aware provider routing with fallback.

func NewRouter

func NewRouter(strategy RoutingStrategy) *Router

NewRouter creates a new provider router with a default fallback chain.

func (*Router) HealthStatus

func (r *Router) HealthStatus() map[string]*ProviderHealth

HealthStatus returns health info for all tracked providers.

func (*Router) RecordFailure

func (r *Router) RecordFailure(provider string, err error)

RecordFailure records a failed API call for a provider.

func (*Router) RecordSuccess

func (r *Router) RecordSuccess(provider string, latency time.Duration)

RecordSuccess records a successful API call for a provider.

func (*Router) Score

func (r *Router) Score(provider string) float64

Score returns a routing score for a provider (lower is better).

func (*Router) SelectProvider

func (r *Router) SelectProvider(preferred string) (string, error)

SelectProvider chooses the best available provider, falling back if needed.

func (*Router) SelectProviderForModel

func (r *Router) SelectProviderForModel(modelName string) (string, ModelInfo, error)

SelectProviderForModel chooses the best provider for a specific model.

func (*Router) SetFallbackChain

func (r *Router) SetFallbackChain(chain []string)

SetFallbackChain sets the provider fallback order.

type RoutingDecision

type RoutingDecision struct {
	Model       string   `json:"model"`
	Provider    string   `json:"provider"`
	MatchedRule *TagRule `json:"matched_rule,omitempty"`
	Reason      string   `json:"reason"`
}

RoutingDecision holds the result of tag-based routing.

type RoutingStrategy

type RoutingStrategy string

RoutingStrategy determines how the router selects providers.

const (
	StrategyLatency  RoutingStrategy = "latency"
	StrategyCost     RoutingStrategy = "cost"
	StrategyBalanced RoutingStrategy = "balanced"
)

type TagRouter

type TagRouter struct {
	Rules        []TagRule `json:"rules"`
	DefaultModel string    `json:"default_model"`
	// contains filtered or unexported fields
}

TagRouter routes LLM requests to specific models based on metadata tags.

func NewTagRouter

func NewTagRouter(defaultModel string) *TagRouter

NewTagRouter creates a new TagRouter with a default model and built-in rules.

func (*TagRouter) AddRule

func (tr *TagRouter) AddRule(rule TagRule)

AddRule adds a routing rule to the router.

func (*TagRouter) FormatRules

func (tr *TagRouter) FormatRules() string

FormatRules returns a human-readable summary of all routing rules.

func (*TagRouter) Load

func (tr *TagRouter) Load(path string) error

Load reads the router's rules from a JSON file at the given path.

func (*TagRouter) Route

func (tr *TagRouter) Route(tags map[string]string) *RoutingDecision

Route finds the best model for the given tags by matching against rules. All tags in a rule must match the request tags for the rule to apply. Among matching rules, the highest priority wins. Ties are broken by match score.

func (*TagRouter) RouteByContext

func (tr *TagRouter) RouteByContext(task, language, complexity string) *RoutingDecision

RouteByContext auto-generates tags from context parameters and routes accordingly.

func (*TagRouter) Save

func (tr *TagRouter) Save(path string) error

Save persists the router's rules to a JSON file at the given path.

type TagRule

type TagRule struct {
	Tags        map[string]string `json:"tags"`
	Model       string            `json:"model"`
	Provider    string            `json:"provider"`
	Priority    int               `json:"priority"`
	Description string            `json:"description"`
}

TagRule defines a routing rule that maps metadata tags to a model/provider.

type TaskType

type TaskType string

TaskType classifies a user message for model routing.

const (
	TaskPlanning TaskType = "planning"
	TaskCoding   TaskType = "coding"
	TaskSummary  TaskType = "summary"
	TaskReview   TaskType = "review"
	TaskGeneral  TaskType = "general"
)

func ClassifyTask

func ClassifyTask(message string) TaskType

ClassifyTask uses keyword heuristics to determine the task type from a message.

Jump to

Keyboard shortcuts

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