package providers import ( "context" "fmt" ) type ToolCall struct { ID string `json:"id"` Type string `json:"type,omitempty"` Function *FunctionCall `json:"function,omitempty"` Name string `json:"name,omitempty"` Arguments map[string]interface{} `json:"arguments,omitempty"` } type FunctionCall struct { Name string `json:"name"` Arguments string `json:"arguments"` } type LLMResponse struct { Content string `json:"content"` ToolCalls []ToolCall `json:"tool_calls,omitempty"` FinishReason string `json:"finish_reason"` Usage *UsageInfo `json:"usage,omitempty"` } type UsageInfo struct { PromptTokens int `json:"prompt_tokens"` CompletionTokens int `json:"completion_tokens"` TotalTokens int `json:"total_tokens"` } type Message struct { Role string `json:"role"` Content string `json:"content"` ToolCalls []ToolCall `json:"tool_calls,omitempty"` ToolCallID string `json:"tool_call_id,omitempty"` } type LLMProvider interface { Chat(ctx context.Context, messages []Message, tools []ToolDefinition, model string, options map[string]interface{}) (*LLMResponse, error) GetDefaultModel() string } // FailoverReason classifies why an LLM request failed for fallback decisions. type FailoverReason string const ( FailoverAuth FailoverReason = "auth" FailoverRateLimit FailoverReason = "rate_limit" FailoverBilling FailoverReason = "billing" FailoverTimeout FailoverReason = "timeout" FailoverFormat FailoverReason = "format" FailoverOverloaded FailoverReason = "overloaded" FailoverUnknown FailoverReason = "unknown" ) // FailoverError wraps an LLM provider error with classification metadata. type FailoverError struct { Reason FailoverReason Provider string Model string Status int Wrapped error } func (e *FailoverError) Error() string { return fmt.Sprintf("failover(%s): provider=%s model=%s status=%d: %v", e.Reason, e.Provider, e.Model, e.Status, e.Wrapped) } func (e *FailoverError) Unwrap() error { return e.Wrapped } // IsRetriable returns true if this error should trigger fallback to next candidate. // Non-retriable: Format errors (bad request structure, image dimension/size). func (e *FailoverError) IsRetriable() bool { return e.Reason != FailoverFormat } // ModelConfig holds primary model and fallback list. type ModelConfig struct { Primary string Fallbacks []string } type ToolDefinition struct { Type string `json:"type"` Function ToolFunctionDefinition `json:"function"` } type ToolFunctionDefinition struct { Name string `json:"name"` Description string `json:"description"` Parameters map[string]interface{} `json:"parameters"` }