base

package
v1.0.35 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2025 License: MIT Imports: 17 Imported by: 0

README

Provider Factory with Authentication-Aware Testing

This package provides a comprehensive ProviderFactory with a TestProvider method that performs authentication-aware testing across all provider types using the interfaces and error structures we've already built.

Overview

The ProviderFactory orchestrates the testing logic across all provider types using the OAuthProvider, TestableProvider, and other interfaces. It provides comprehensive testing with detailed phases, error types, and diagnostic information.

Key Features

Authentication-Aware Testing
  • OAuth Providers: Uses OAuthProvider methods for token validation, refresh, and OAuth-specific error handling
  • API Key Providers: Validates configuration and uses TestableProvider.TestConnectivity() for connectivity testing
  • Virtual Providers: Tests through their underlying providers
  • Graceful Fallbacks: Handles providers that don't implement testing interfaces
Comprehensive Test Phases
  1. Configuration Phase: Provider creation and configuration validation
  2. Authentication Phase: Token validation (OAuth) or API key validation
  3. Connectivity Phase: Network connectivity testing
  4. Model Fetch Phase: Model discovery (if supported)
Detailed Error Handling
  • Uses TestResult structures with detailed phases and error types
  • Leverages OAuthProvider and TestableProvider interfaces
  • Handles providers that don't implement testing interfaces gracefully
  • Provides detailed error messages for debugging
  • Distinguishes between auth errors, connectivity errors, configuration errors
  • Includes timing information and retryable flags

Usage

Basic Usage
package main

import (
    "context"
    "log"

    "github.com/cecil-the-coder/ai-provider-kit/pkg/providers/base"
    "github.com/cecil-the-coder/ai-provider-kit/pkg/types"
)

func main() {
    // Create factory
    factory := base.NewProviderFactory()

    // Register providers
    factory.RegisterProvider(types.ProviderTypeOpenAI, func(config types.ProviderConfig) types.Provider {
        return &OpenAIProvider{...} // Your provider implementation
    })

    // Test provider
    config := map[string]interface{}{
        "api_key": "sk-your-api-key",
        "base_url": "https://api.openai.com/v1",
    }

    result, err := factory.TestProvider(context.Background(), "openai", config)
    if err != nil {
        log.Fatal(err)
    }

    if result.IsSuccess() {
        log.Printf("✅ Provider test passed! (%v)", result.Duration)
        log.Printf("Models available: %d", result.ModelsCount)
    } else {
        log.Printf("❌ Provider test failed: %s", result.Error)
        log.Printf("Phase: %s, Retryable: %t", result.Phase, result.IsRetryable())
    }
}
Testing OAuth Providers
// Register OAuth provider
factory.RegisterProvider(types.ProviderTypeGemini, func(config types.ProviderConfig) types.Provider {
    return &GeminiProvider{...} // Implements OAuthProvider interface
})

// Test with OAuth configuration
oauthConfig := map[string]interface{}{
    "client_id":     "your-client-id",
    "client_secret": "your-client-secret",
    "auth_url":      "https://accounts.google.com/o/oauth2/auth",
    "token_url":     "https://oauth2.googleapis.com/token",
}

result, err := factory.TestProvider(context.Background(), "gemini", oauthConfig)
Provider Name Variations

The factory supports various provider name variations:

// All of these work:
factory.TestProvider(ctx, "openai", config)
factory.TestProvider(ctx, "gpt", config)       // Maps to OpenAI
factory.TestProvider(ctx, "anthropic", config)
factory.TestProvider(ctx, "claude", config)    // Maps to Anthropic
factory.TestProvider(ctx, "xai", config)       // Maps to xAI
factory.TestProvider(ctx, "x.ai", config)      // Maps to xAI

Test Result Structure

The TestResult provides comprehensive information:

type TestResult struct {
    Status      TestStatus        `json:"status"`        // success, auth_failed, connectivity_failed, etc.
    Error       string            `json:"error,omitempty"`
    Details     map[string]string `json:"details,omitempty"`
    ModelsCount int               `json:"models_count,omitempty"`
    Phase       TestPhase         `json:"phase"`         // authentication, connectivity, etc.
    Timestamp   time.Time         `json:"timestamp"`
    Duration    time.Duration     `json:"duration"`
    ProviderType ProviderType      `json:"provider_type"`
    TestError   *TestError        `json:"test_error,omitempty"`
}

Error Types and Handling

The factory provides detailed error categorization:

  • Authentication Errors: Invalid tokens, missing credentials
  • Token Errors: Expired tokens, refresh failures
  • OAuth Errors: OAuth-specific failures
  • Connectivity Errors: Network failures, timeouts
  • Configuration Errors: Invalid configuration, missing parameters
  • Server Errors: HTTP 5xx errors from providers
  • Rate Limit Errors: API rate limiting
  • Unknown Errors: Unclassified errors

Each error includes:

  • Retryable flag
  • Phase of failure
  • Detailed error message
  • Status codes (when applicable)

Interface Integration

The factory integrates with existing interfaces:

OAuthProvider
type OAuthProvider interface {
    Provider
    ValidateToken(ctx context.Context) (*TokenInfo, error)
    RefreshToken(ctx context.Context) error
    GetAuthURL(redirectURI, state string) string
}
TestableProvider
type TestableProvider interface {
    Provider
    TestConnectivity(ctx context.Context) error
}

Context Support

The factory respects context cancellation and timeouts:

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

result, err := factory.TestProvider(ctx, "openai", config)

JSON Serialization

Test results can be serialized to/from JSON:

// To JSON
jsonData, err := result.ToJSON()

// From JSON
parsedResult, err := types.TestResultFromJSON(jsonData)

Implementation Details

Test Phases
  1. Configuration: Provider creation and validation
  2. Authentication: OAuth token validation or API key check
  3. Connectivity: Network connectivity testing
  4. Model Fetch: Model discovery (optional)
Error Detection
  • HTTP status code extraction from error messages
  • Error type classification based on patterns
  • Retryable determination based on error type
Fallback Testing
  • Uses HealthCheck() method if TestableProvider not implemented
  • Provides appropriate test results based on available interfaces

Files

  • provider_factory.go - Main implementation
  • provider_factory_test.go - Test cases
  • example_usage.go - Usage examples
  • README.md - This documentation

Dependencies

  • github.com/cecil-the-coder/ai-provider-kit/pkg/types - Type definitions and interfaces

The implementation provides a robust, authentication-aware testing framework that works with all provider types while providing detailed diagnostic information and graceful error handling.

Documentation

Overview

Package base provides common functionality and utilities for AI providers. It includes base implementations, shared components, and standardized patterns that can be used by specific provider implementations.

Package base provides common functionality and utilities for AI providers.

Package base provides common functionality and utilities for AI providers.

Package base provides common functionality and utilities for AI providers.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExampleUsage added in v1.0.14

func ExampleUsage()

ExampleUsage demonstrates how to use the ProviderFactory and TestProvider method

func ExampleUsageWithJSON added in v1.0.14

func ExampleUsageWithJSON()

ExampleUsageWithJSON demonstrates how to work with JSON serialization

func ExampleUsageWithTimeout added in v1.0.14

func ExampleUsageWithTimeout()

ExampleUsageWithTimeout demonstrates how to use context with timeout

Types

type BaseProvider

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

BaseProvider provides common functionality for all providers

func NewBaseProvider

func NewBaseProvider(name string, config types.ProviderConfig, client *http.Client, logger *log.Logger) *BaseProvider

NewBaseProvider creates a new base provider

func (*BaseProvider) Authenticate

func (p *BaseProvider) Authenticate(ctx context.Context, authConfig types.AuthConfig) error

Authenticate handles API key authentication

func (*BaseProvider) Configure

func (p *BaseProvider) Configure(config types.ProviderConfig) error

Configure updates the provider configuration

func (*BaseProvider) Description

func (p *BaseProvider) Description() string

func (*BaseProvider) GenerateChatCompletion

func (p *BaseProvider) GenerateChatCompletion(ctx context.Context, options types.GenerateOptions) (types.ChatCompletionStream, error)

GenerateChatCompletion generates a mock chat completion

func (*BaseProvider) GetConfig

func (p *BaseProvider) GetConfig() types.ProviderConfig

GetConfig returns the current provider configuration

func (*BaseProvider) GetDefaultModel

func (p *BaseProvider) GetDefaultModel() string

func (*BaseProvider) GetMetrics

func (p *BaseProvider) GetMetrics() types.ProviderMetrics

func (*BaseProvider) GetModels

func (p *BaseProvider) GetModels(ctx context.Context) ([]types.Model, error)

func (*BaseProvider) GetToolFormat

func (p *BaseProvider) GetToolFormat() types.ToolFormat

func (*BaseProvider) HealthCheck

func (p *BaseProvider) HealthCheck(ctx context.Context) error

func (*BaseProvider) IncrementRequestCount

func (p *BaseProvider) IncrementRequestCount()

IncrementRequestCount increments the request counter

func (*BaseProvider) InvokeServerTool

func (p *BaseProvider) InvokeServerTool(ctx context.Context, toolName string, params interface{}) (interface{}, error)

InvokeServerTool invokes a server tool (not implemented in base provider)

func (*BaseProvider) IsAuthenticated

func (p *BaseProvider) IsAuthenticated() bool

func (*BaseProvider) LogRequest

func (p *BaseProvider) LogRequest(method, url string, headers map[string]string, body interface{})

LogRequest logs an HTTP request

func (*BaseProvider) LogResponse

func (p *BaseProvider) LogResponse(resp *http.Response, duration time.Duration)

LogResponse logs detailed response information

func (*BaseProvider) Logout

func (p *BaseProvider) Logout(ctx context.Context) error

func (*BaseProvider) Name

func (p *BaseProvider) Name() string

func (*BaseProvider) RecordError

func (p *BaseProvider) RecordError(err error)

RecordError records a failed API call

func (*BaseProvider) RecordErrorWithModel added in v1.0.7

func (p *BaseProvider) RecordErrorWithModel(ctx context.Context, err error, modelID string, errorType string)

RecordErrorWithModel records a failed API call with model and error type information

func (*BaseProvider) RecordRequest added in v1.0.7

func (p *BaseProvider) RecordRequest(ctx context.Context, modelID string)

RecordRequest records the start of a request and emits to MetricsCollector if set

func (*BaseProvider) RecordSuccess

func (p *BaseProvider) RecordSuccess(latency time.Duration, tokensUsed int64)

RecordSuccess records a successful API call

func (*BaseProvider) RecordSuccessWithModel added in v1.0.7

func (p *BaseProvider) RecordSuccessWithModel(ctx context.Context, latency time.Duration, tokensUsed int64, modelID string)

RecordSuccessWithModel records a successful API call with model information

func (*BaseProvider) SetMetricsCollector added in v1.0.7

func (p *BaseProvider) SetMetricsCollector(collector types.MetricsCollector)

SetMetricsCollector sets the metrics collector for this provider

func (*BaseProvider) SetVerboseLogging added in v1.0.26

func (p *BaseProvider) SetVerboseLogging(enabled bool)

SetVerboseLogging enables or disables verbose request/response logging

func (*BaseProvider) SupportsResponsesAPI

func (p *BaseProvider) SupportsResponsesAPI() bool

func (*BaseProvider) SupportsStreaming

func (p *BaseProvider) SupportsStreaming() bool

func (*BaseProvider) SupportsToolCalling

func (p *BaseProvider) SupportsToolCalling() bool

func (*BaseProvider) Type

func (p *BaseProvider) Type() types.ProviderType

func (*BaseProvider) UpdateConfig

func (p *BaseProvider) UpdateConfig(config types.ProviderConfig)

UpdateConfig updates provider configuration

func (*BaseProvider) UpdateHealthStatus

func (p *BaseProvider) UpdateHealthStatus(healthy bool, message string)

UpdateHealthStatus updates the health status

func (*BaseProvider) UpdateHealthStatusResponseTime

func (p *BaseProvider) UpdateHealthStatusResponseTime(responseTime float64)

UpdateHealthStatusResponseTime updates the health status response time

type BaseProviderStub

type BaseProviderStub struct {
	*BaseProvider
}

BaseProviderStub wraps BaseProvider to implement Provider interface

func NewBaseProviderStub

func NewBaseProviderStub(name string, config types.ProviderConfig, client *http.Client, logger *log.Logger) *BaseProviderStub

func (*BaseProviderStub) Authenticate

func (b *BaseProviderStub) Authenticate(ctx context.Context, authConfig types.AuthConfig) error

func (*BaseProviderStub) Configure

func (b *BaseProviderStub) Configure(config types.ProviderConfig) error

func (*BaseProviderStub) Description

func (b *BaseProviderStub) Description() string

func (*BaseProviderStub) GenerateChatCompletion

func (b *BaseProviderStub) GenerateChatCompletion(ctx context.Context, options types.GenerateOptions) (types.ChatCompletionStream, error)

func (*BaseProviderStub) GetConfig

func (b *BaseProviderStub) GetConfig() types.ProviderConfig

func (*BaseProviderStub) GetDefaultModel

func (b *BaseProviderStub) GetDefaultModel() string

func (*BaseProviderStub) GetMetrics

func (b *BaseProviderStub) GetMetrics() types.ProviderMetrics

func (*BaseProviderStub) GetModels

func (b *BaseProviderStub) GetModels(ctx context.Context) ([]types.Model, error)

GetModels returns models from the base provider

func (*BaseProviderStub) GetToolFormat

func (b *BaseProviderStub) GetToolFormat() types.ToolFormat

func (*BaseProviderStub) HealthCheck

func (b *BaseProviderStub) HealthCheck(ctx context.Context) error

func (*BaseProviderStub) InvokeServerTool

func (b *BaseProviderStub) InvokeServerTool(ctx context.Context, toolName string, params interface{}) (interface{}, error)

func (*BaseProviderStub) IsAuthenticated

func (b *BaseProviderStub) IsAuthenticated() bool

func (*BaseProviderStub) Logout

func (b *BaseProviderStub) Logout(ctx context.Context) error

func (*BaseProviderStub) Name

func (b *BaseProviderStub) Name() string

Name returns the stub provider name

func (*BaseProviderStub) SupportsResponsesAPI

func (b *BaseProviderStub) SupportsResponsesAPI() bool

func (*BaseProviderStub) SupportsStreaming

func (b *BaseProviderStub) SupportsStreaming() bool

func (*BaseProviderStub) SupportsToolCalling

func (b *BaseProviderStub) SupportsToolCalling() bool

func (*BaseProviderStub) Type

type DefaultRequestHandler added in v1.0.8

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

DefaultRequestHandler provides a default implementation of RequestHandler

func NewDefaultRequestHandler added in v1.0.8

func NewDefaultRequestHandler(client *http.Client, authHelper *auth.AuthHelper, baseURL string) *DefaultRequestHandler

NewDefaultRequestHandler creates a new DefaultRequestHandler

func (*DefaultRequestHandler) ExecuteAuthenticatedRequest added in v1.0.8

func (h *DefaultRequestHandler) ExecuteAuthenticatedRequest(ctx context.Context, method, url string, body interface{}, useOAuth bool) (*http.Response, error)

ExecuteAuthenticatedRequest makes an HTTP request with automatic authentication

func (*DefaultRequestHandler) ExecuteRequest added in v1.0.8

func (h *DefaultRequestHandler) ExecuteRequest(ctx context.Context, method, url string, body interface{}, headers map[string]string) (*http.Response, error)

ExecuteRequest makes an HTTP request with custom headers

func (*DefaultRequestHandler) GetBaseURL added in v1.0.8

func (h *DefaultRequestHandler) GetBaseURL() string

GetBaseURL returns the base URL for API requests

func (*DefaultRequestHandler) PrepareJSONBody added in v1.0.8

func (h *DefaultRequestHandler) PrepareJSONBody(body interface{}) (*bytes.Buffer, error)

PrepareJSONBody marshals the body into JSON and returns a buffer

func (*DefaultRequestHandler) SetBaseURL added in v1.0.8

func (h *DefaultRequestHandler) SetBaseURL(baseURL string)

SetBaseURL updates the base URL for API requests

type DefaultResponseParser added in v1.0.8

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

DefaultResponseParser provides a default implementation of ResponseParser

func NewDefaultResponseParser added in v1.0.8

func NewDefaultResponseParser(rateLimitHelper *common.RateLimitHelper) *DefaultResponseParser

NewDefaultResponseParser creates a new DefaultResponseParser

func (*DefaultResponseParser) CheckStatusCode added in v1.0.8

func (p *DefaultResponseParser) CheckStatusCode(resp *http.Response) error

CheckStatusCode validates HTTP status code and returns error if not OK

func (*DefaultResponseParser) ExtractRateLimits added in v1.0.8

func (p *DefaultResponseParser) ExtractRateLimits(resp *http.Response, model string) *RateLimitInfo

ExtractRateLimits extracts rate limit information from response headers This is a helper method that uses the RateLimitHelper if available

func (*DefaultResponseParser) ParseError added in v1.0.8

func (p *DefaultResponseParser) ParseError(resp *http.Response) error

ParseError extracts error information from HTTP response

func (*DefaultResponseParser) ParseJSON added in v1.0.8

func (p *DefaultResponseParser) ParseJSON(resp *http.Response, target interface{}) error

ParseJSON reads and unmarshals JSON response body into target

func (*DefaultResponseParser) ReadBody added in v1.0.8

func (p *DefaultResponseParser) ReadBody(resp *http.Response) (string, error)

ReadBody reads the entire response body and returns it as a string

type MockStream

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

MockStream implementation

func (*MockStream) Close

func (ms *MockStream) Close() error

func (*MockStream) Next

func (ms *MockStream) Next() (types.ChatCompletionChunk, error)

type ProviderComponents added in v1.0.8

type ProviderComponents struct {
	// HTTP client for API requests
	HTTPClient *http.Client

	// Authentication helper
	AuthHelper *auth.AuthHelper

	// Configuration helper
	ConfigHelper *config.ConfigHelper

	// Rate limit helper
	RateLimitHelper *common.RateLimitHelper

	// Base provider with metrics, logging, etc.
	BaseProvider *BaseProvider

	// Client-side rate limiter (only set if EnableClientRateLimiting was true)
	ClientSideLimiter *rate.Limiter

	// Extracted configuration values
	BaseURL      string
	DefaultModel string
	Timeout      time.Duration
	MaxTokens    int
	MergedConfig types.ProviderConfig
}

ProviderComponents holds initialized components ready for use by providers. This struct packages all common provider infrastructure into a single container, eliminating the need for each provider to initialize these components individually.

type ProviderFactory added in v1.0.14

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

ProviderFactory manages provider creation, registration, and testing

func NewProviderFactory added in v1.0.14

func NewProviderFactory() *ProviderFactory

NewProviderFactory creates a new provider factory

func (*ProviderFactory) CreateProvider added in v1.0.14

func (f *ProviderFactory) CreateProvider(providerType types.ProviderType, config types.ProviderConfig) (types.Provider, error)

CreateProvider creates a provider instance

func (*ProviderFactory) GetSupportedProviders added in v1.0.14

func (f *ProviderFactory) GetSupportedProviders() []types.ProviderType

GetSupportedProviders returns a list of supported provider types

func (*ProviderFactory) RegisterProvider added in v1.0.14

func (f *ProviderFactory) RegisterProvider(providerType types.ProviderType, factoryFunc func(types.ProviderConfig) types.Provider)

RegisterProvider registers a provider factory function

func (*ProviderFactory) TestProvider added in v1.0.14

func (f *ProviderFactory) TestProvider(ctx context.Context, providerName string, config interface{}) (*types.TestResult, error)

TestProvider performs comprehensive testing of a provider with authentication-aware logic

type ProviderInitConfig added in v1.0.8

type ProviderInitConfig struct {
	// Provider identification
	ProviderType types.ProviderType
	ProviderName string

	// Provider configuration
	Config types.ProviderConfig

	// HTTP client configuration
	HTTPTimeout time.Duration // 0 means use default (10 seconds)

	// Logging
	Logger *log.Logger // nil means use default logger

	// Client-side rate limiting (for providers without rate limit headers)
	EnableClientRateLimiting bool
	ClientRateLimitRPM       int           // Requests per minute (0 means no limit)
	ClientRateLimitBurst     int           // Token bucket burst size
	ClientRateLimitInterval  time.Duration // Rate limit window (default: 1 minute)
}

ProviderInitConfig holds common initialization parameters for providers. This struct centralizes all the configuration data needed to initialize a provider, eliminating duplicate parameter passing across providers.

type RateLimitInfo added in v1.0.8

type RateLimitInfo struct {
	RequestsRemaining int
	RequestsLimit     int
	RequestsReset     time.Time
	TokensRemaining   int
	TokensLimit       int
	TokensReset       time.Time
	RetryAfter        time.Duration
}

RateLimitInfo contains rate limit information extracted from HTTP headers

func ParseRateLimitHeaders added in v1.0.8

func ParseRateLimitHeaders(headers http.Header) *RateLimitInfo

ParseRateLimitHeaders extracts rate limit info directly from headers (static helper) This is a fallback for cases where RateLimitHelper is not available

type RequestHandler added in v1.0.8

type RequestHandler interface {
	// ExecuteRequest makes an HTTP request with custom headers
	ExecuteRequest(ctx context.Context, method, url string, body interface{}, headers map[string]string) (*http.Response, error)

	// ExecuteAuthenticatedRequest makes an HTTP request with automatic authentication
	// useOAuth determines whether to use OAuth or API key authentication
	ExecuteAuthenticatedRequest(ctx context.Context, method, url string, body interface{}, useOAuth bool) (*http.Response, error)

	// PrepareJSONBody marshals the body into JSON and returns a buffer
	PrepareJSONBody(body interface{}) (*bytes.Buffer, error)
}

RequestHandler interface for executing HTTP requests with authentication Provides a unified way to make API calls across different providers

type ResponseParser added in v1.0.8

type ResponseParser interface {
	// ParseJSON reads and unmarshals JSON response body into target
	ParseJSON(resp *http.Response, target interface{}) error

	// ParseError extracts error information from HTTP response
	ParseError(resp *http.Response) error

	// ReadBody reads the entire response body and returns it as a string
	ReadBody(resp *http.Response) (string, error)

	// CheckStatusCode validates HTTP status code and returns error if not OK
	CheckStatusCode(resp *http.Response) error
}

ResponseParser interface for parsing HTTP responses Provides a unified way to handle API responses across different providers

Jump to

Keyboard shortcuts

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