diff --git a/examples/custom-provider/main.go b/examples/custom-provider/main.go index 4514765e..ab7fb31c 100644 --- a/examples/custom-provider/main.go +++ b/examples/custom-provider/main.go @@ -1,7 +1,15 @@ +// Package main demonstrates how to create a custom AI provider executor +// and integrate it with the CLI Proxy API server. This example shows how to: +// - Create a custom executor that implements the Executor interface +// - Register custom translators for request/response transformation +// - Integrate the custom provider with the SDK server +// - Register custom models in the model registry +// +// This example uses a simple echo service (httpbin.org) as the upstream API +// for demonstration purposes. In a real implementation, you would replace +// this with your actual AI service provider. package main -// Example: Custom provider executor + translators embedded in the SDK server. - import ( "bytes" "context" @@ -25,12 +33,19 @@ import ( ) const ( + // providerKey is the identifier for our custom provider. providerKey = "myprov" - fOpenAI = sdktr.Format("openai.chat") - fMyProv = sdktr.Format("myprov.chat") + + // fOpenAI represents the OpenAI chat format. + fOpenAI = sdktr.Format("openai.chat") + + // fMyProv represents our custom provider's chat format. + fMyProv = sdktr.Format("myprov.chat") ) -// Register trivial translators (pass-through demo). +// init registers trivial translators for demonstration purposes. +// In a real implementation, you would implement proper request/response +// transformation logic between OpenAI format and your provider's format. func init() { sdktr.Register(fOpenAI, fMyProv, func(model string, raw []byte, stream bool) []byte { return raw }, @@ -45,12 +60,23 @@ func init() { ) } -// MyExecutor is a minimal provider implementation for demo purposes. +// MyExecutor is a minimal provider implementation for demonstration purposes. +// It implements the Executor interface to handle requests to a custom AI provider. type MyExecutor struct{} +// Identifier returns the unique identifier for this executor. func (MyExecutor) Identifier() string { return providerKey } // PrepareRequest optionally injects credentials to raw HTTP requests. +// This method is called before each request to allow the executor to modify +// the HTTP request with authentication headers or other necessary modifications. +// +// Parameters: +// - req: The HTTP request to prepare +// - a: The authentication information +// +// Returns: +// - error: An error if request preparation fails func (MyExecutor) PrepareRequest(req *http.Request, a *coreauth.Auth) error { if req == nil || a == nil { return nil diff --git a/internal/cmd/anthropic_login.go b/internal/cmd/anthropic_login.go index b6ba6e80..d0df11fb 100644 --- a/internal/cmd/anthropic_login.go +++ b/internal/cmd/anthropic_login.go @@ -12,6 +12,12 @@ import ( ) // DoClaudeLogin triggers the Claude OAuth flow through the shared authentication manager. +// It initiates the OAuth authentication process for Anthropic Claude services and saves +// the authentication tokens to the configured auth directory. +// +// Parameters: +// - cfg: The application configuration +// - options: Login options including browser behavior and prompts func DoClaudeLogin(cfg *config.Config, options *LoginOptions) { if options == nil { options = &LoginOptions{} diff --git a/internal/cmd/auth_manager.go b/internal/cmd/auth_manager.go index 391608c0..b4a92a28 100644 --- a/internal/cmd/auth_manager.go +++ b/internal/cmd/auth_manager.go @@ -4,6 +4,12 @@ import ( sdkAuth "github.com/router-for-me/CLIProxyAPI/v6/sdk/auth" ) +// newAuthManager creates a new authentication manager instance with all supported +// authenticators and a file-based token store. It initializes authenticators for +// Gemini, Codex, Claude, and Qwen providers. +// +// Returns: +// - *sdkAuth.Manager: A configured authentication manager instance func newAuthManager() *sdkAuth.Manager { store := sdkAuth.NewFileTokenStore() manager := sdkAuth.NewManager(store, diff --git a/internal/cmd/login.go b/internal/cmd/login.go index 2a559057..e11a62d4 100644 --- a/internal/cmd/login.go +++ b/internal/cmd/login.go @@ -1,3 +1,6 @@ +// Package cmd provides command-line interface functionality for the CLI Proxy API server. +// It includes authentication flows for various AI service providers, service startup, +// and other command-line operations. package cmd import ( @@ -10,6 +13,13 @@ import ( ) // DoLogin handles Google Gemini authentication using the shared authentication manager. +// It initiates the OAuth flow for Google Gemini services and saves the authentication +// tokens to the configured auth directory. +// +// Parameters: +// - cfg: The application configuration +// - projectID: Optional Google Cloud project ID for Gemini services +// - options: Login options including browser behavior and prompts func DoLogin(cfg *config.Config, projectID string, options *LoginOptions) { if options == nil { options = &LoginOptions{} diff --git a/internal/cmd/openai_login.go b/internal/cmd/openai_login.go index de7001ab..4d292ea1 100644 --- a/internal/cmd/openai_login.go +++ b/internal/cmd/openai_login.go @@ -12,14 +12,23 @@ import ( ) // LoginOptions contains options for the login processes. +// It provides configuration for authentication flows including browser behavior +// and interactive prompting capabilities. type LoginOptions struct { // NoBrowser indicates whether to skip opening the browser automatically. NoBrowser bool + // Prompt allows the caller to provide interactive input when needed. Prompt func(prompt string) (string, error) } // DoCodexLogin triggers the Codex OAuth flow through the shared authentication manager. +// It initiates the OAuth authentication process for OpenAI Codex services and saves +// the authentication tokens to the configured auth directory. +// +// Parameters: +// - cfg: The application configuration +// - options: Login options including browser behavior and prompts func DoCodexLogin(cfg *config.Config, options *LoginOptions) { if options == nil { options = &LoginOptions{} diff --git a/internal/cmd/qwen_login.go b/internal/cmd/qwen_login.go index 8c6c73a7..bd375356 100644 --- a/internal/cmd/qwen_login.go +++ b/internal/cmd/qwen_login.go @@ -11,6 +11,12 @@ import ( ) // DoQwenLogin handles the Qwen device flow using the shared authentication manager. +// It initiates the device-based authentication process for Qwen services and saves +// the authentication tokens to the configured auth directory. +// +// Parameters: +// - cfg: The application configuration +// - options: Login options including browser behavior and prompts func DoQwenLogin(cfg *config.Config, options *LoginOptions) { if options == nil { options = &LoginOptions{} diff --git a/internal/cmd/run.go b/internal/cmd/run.go index 99a62102..e063e474 100644 --- a/internal/cmd/run.go +++ b/internal/cmd/run.go @@ -1,3 +1,6 @@ +// Package cmd provides command-line interface functionality for the CLI Proxy API server. +// It includes authentication flows for various AI service providers, service startup, +// and other command-line operations. package cmd import ( @@ -12,6 +15,12 @@ import ( ) // StartService builds and runs the proxy service using the exported SDK. +// It creates a new proxy service instance, sets up signal handling for graceful shutdown, +// and starts the service with the provided configuration. +// +// Parameters: +// - cfg: The application configuration +// - configPath: The path to the configuration file func StartService(cfg *config.Config, configPath string) { service, err := cliproxy.NewBuilder(). WithConfig(cfg). diff --git a/internal/constant/constant.go b/internal/constant/constant.go index 5330af52..88700d65 100644 --- a/internal/constant/constant.go +++ b/internal/constant/constant.go @@ -1,11 +1,27 @@ +// Package constant defines provider name constants used throughout the CLI Proxy API. +// These constants identify different AI service providers and their variants, +// ensuring consistent naming across the application. package constant const ( - Gemini = "gemini" - GeminiCLI = "gemini-cli" - GeminiWeb = "gemini-web" - Codex = "codex" - Claude = "claude" - OpenAI = "openai" + // Gemini represents the Google Gemini provider identifier. + Gemini = "gemini" + + // GeminiCLI represents the Google Gemini CLI provider identifier. + GeminiCLI = "gemini-cli" + + // GeminiWeb represents the Google Gemini Web provider identifier. + GeminiWeb = "gemini-web" + + // Codex represents the OpenAI Codex provider identifier. + Codex = "codex" + + // Claude represents the Anthropic Claude provider identifier. + Claude = "claude" + + // OpenAI represents the OpenAI provider identifier. + OpenAI = "openai" + + // OpenaiResponse represents the OpenAI response format identifier. OpenaiResponse = "openai-response" ) diff --git a/internal/interfaces/types.go b/internal/interfaces/types.go index f7a104de..9fb1e7f3 100644 --- a/internal/interfaces/types.go +++ b/internal/interfaces/types.go @@ -1,3 +1,6 @@ +// Package interfaces provides type aliases for backwards compatibility with translator functions. +// It defines common interface types used throughout the CLI Proxy API for request and response +// transformation operations, maintaining compatibility with the SDK translator package. package interfaces import sdktranslator "github.com/router-for-me/CLIProxyAPI/v6/sdk/translator" diff --git a/internal/logging/gin_logger.go b/internal/logging/gin_logger.go index 14685b6c..904fa797 100644 --- a/internal/logging/gin_logger.go +++ b/internal/logging/gin_logger.go @@ -1,3 +1,6 @@ +// Package logging provides Gin middleware for HTTP request logging and panic recovery. +// It integrates Gin web framework with logrus for structured logging of HTTP requests, +// responses, and error handling with panic recovery capabilities. package logging import ( @@ -10,7 +13,12 @@ import ( log "github.com/sirupsen/logrus" ) -// GinLogrusLogger writes Gin-style access logs through logrus. +// GinLogrusLogger returns a Gin middleware handler that logs HTTP requests and responses +// using logrus. It captures request details including method, path, status code, latency, +// client IP, and any error messages, formatting them in a Gin-style log format. +// +// Returns: +// - gin.HandlerFunc: A middleware handler for request logging func GinLogrusLogger() gin.HandlerFunc { return func(c *gin.Context) { start := time.Now() @@ -51,7 +59,12 @@ func GinLogrusLogger() gin.HandlerFunc { } } -// GinLogrusRecovery returns a Gin middleware that recovers from panics and logs them via logrus. +// GinLogrusRecovery returns a Gin middleware handler that recovers from panics and logs +// them using logrus. When a panic occurs, it captures the panic value, stack trace, +// and request path, then returns a 500 Internal Server Error response to the client. +// +// Returns: +// - gin.HandlerFunc: A middleware handler for panic recovery func GinLogrusRecovery() gin.HandlerFunc { return gin.CustomRecovery(func(c *gin.Context, recovered interface{}) { log.WithFields(log.Fields{ diff --git a/internal/misc/header_utils.go b/internal/misc/header_utils.go index a43f03ba..c6279a4c 100644 --- a/internal/misc/header_utils.go +++ b/internal/misc/header_utils.go @@ -1,3 +1,6 @@ +// Package misc provides miscellaneous utility functions for the CLI Proxy API server. +// It includes helper functions for HTTP header manipulation and other common operations +// that don't fit into more specific packages. package misc import ( @@ -5,6 +8,16 @@ import ( "strings" ) +// EnsureHeader ensures that a header exists in the target header map by checking +// multiple sources in order of priority: source headers, existing target headers, +// and finally the default value. It only sets the header if it's not already present +// and the value is not empty after trimming whitespace. +// +// Parameters: +// - target: The target header map to modify +// - source: The source header map to check first (can be nil) +// - key: The header key to ensure +// - defaultValue: The default value to use if no other source provides a value func EnsureHeader(target http.Header, source http.Header, key, defaultValue string) { if target == nil { return diff --git a/internal/runtime/executor/gemini_executor.go b/internal/runtime/executor/gemini_executor.go index fed30324..17f5c1c0 100644 --- a/internal/runtime/executor/gemini_executor.go +++ b/internal/runtime/executor/gemini_executor.go @@ -1,3 +1,6 @@ +// Package executor provides runtime execution capabilities for various AI service providers. +// It includes stateless executors that handle API requests, streaming responses, +// token counting, and authentication refresh for different AI service providers. package executor import ( @@ -22,22 +25,49 @@ import ( ) const ( - glEndpoint = "https://generativelanguage.googleapis.com" + // glEndpoint is the base URL for the Google Generative Language API. + glEndpoint = "https://generativelanguage.googleapis.com" + + // glAPIVersion is the API version used for Gemini requests. glAPIVersion = "v1beta" ) // GeminiExecutor is a stateless executor for the official Gemini API using API keys. -// If no API key is found on the auth entry, it falls back to the legacy client via ClientAdapter. +// It handles both API key and OAuth bearer token authentication, supporting both +// regular and streaming requests to the Google Generative Language API. type GeminiExecutor struct { + // cfg holds the application configuration. cfg *config.Config } +// NewGeminiExecutor creates a new Gemini executor instance. +// +// Parameters: +// - cfg: The application configuration +// +// Returns: +// - *GeminiExecutor: A new Gemini executor instance func NewGeminiExecutor(cfg *config.Config) *GeminiExecutor { return &GeminiExecutor{cfg: cfg} } +// Identifier returns the executor identifier for Gemini. func (e *GeminiExecutor) Identifier() string { return "gemini" } +// PrepareRequest prepares the HTTP request for execution (no-op for Gemini). func (e *GeminiExecutor) PrepareRequest(_ *http.Request, _ *cliproxyauth.Auth) error { return nil } +// Execute performs a non-streaming request to the Gemini API. +// It translates the request to Gemini format, sends it to the API, and translates +// the response back to the requested format. +// +// Parameters: +// - ctx: The context for the request +// - auth: The authentication information +// - req: The request to execute +// - opts: Additional execution options +// +// Returns: +// - cliproxyexecutor.Response: The response from the API +// - error: An error if the request fails func (e *GeminiExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, req cliproxyexecutor.Request, opts cliproxyexecutor.Options) (cliproxyexecutor.Response, error) { apiKey, bearer := geminiCreds(auth) diff --git a/internal/translator/translator/translator.go b/internal/translator/translator/translator.go index 51dec8d1..11a881ad 100644 --- a/internal/translator/translator/translator.go +++ b/internal/translator/translator/translator.go @@ -1,3 +1,7 @@ +// Package translator provides request and response translation functionality +// between different AI API formats. It acts as a wrapper around the SDK translator +// registry, providing convenient functions for translating requests and responses +// between OpenAI, Claude, Gemini, and other API formats. package translator import ( @@ -7,24 +11,79 @@ import ( sdktranslator "github.com/router-for-me/CLIProxyAPI/v6/sdk/translator" ) +// registry holds the default translator registry instance. var registry = sdktranslator.Default() +// Register registers a new translator for converting between two API formats. +// +// Parameters: +// - from: The source API format identifier +// - to: The target API format identifier +// - request: The request translation function +// - response: The response translation function func Register(from, to string, request interfaces.TranslateRequestFunc, response interfaces.TranslateResponse) { registry.Register(sdktranslator.FromString(from), sdktranslator.FromString(to), request, response) } +// Request translates a request from one API format to another. +// +// Parameters: +// - from: The source API format identifier +// - to: The target API format identifier +// - modelName: The model name for the request +// - rawJSON: The raw JSON request data +// - stream: Whether this is a streaming request +// +// Returns: +// - []byte: The translated request JSON func Request(from, to, modelName string, rawJSON []byte, stream bool) []byte { return registry.TranslateRequest(sdktranslator.FromString(from), sdktranslator.FromString(to), modelName, rawJSON, stream) } +// NeedConvert checks if a response translation is needed between two API formats. +// +// Parameters: +// - from: The source API format identifier +// - to: The target API format identifier +// +// Returns: +// - bool: True if response translation is needed, false otherwise func NeedConvert(from, to string) bool { return registry.HasResponseTransformer(sdktranslator.FromString(from), sdktranslator.FromString(to)) } +// Response translates a streaming response from one API format to another. +// +// Parameters: +// - from: The source API format identifier +// - to: The target API format identifier +// - ctx: The context for the translation +// - modelName: The model name for the response +// - originalRequestRawJSON: The original request JSON +// - requestRawJSON: The translated request JSON +// - rawJSON: The raw response JSON +// - param: Additional parameters for translation +// +// Returns: +// - []string: The translated response lines func Response(from, to string, ctx context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string { return registry.TranslateStream(ctx, sdktranslator.FromString(from), sdktranslator.FromString(to), modelName, originalRequestRawJSON, requestRawJSON, rawJSON, param) } +// ResponseNonStream translates a non-streaming response from one API format to another. +// +// Parameters: +// - from: The source API format identifier +// - to: The target API format identifier +// - ctx: The context for the translation +// - modelName: The model name for the response +// - originalRequestRawJSON: The original request JSON +// - requestRawJSON: The translated request JSON +// - rawJSON: The raw response JSON +// - param: Additional parameters for translation +// +// Returns: +// - string: The translated response JSON func ResponseNonStream(from, to string, ctx context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) string { return registry.TranslateNonStream(ctx, sdktranslator.FromString(from), sdktranslator.FromString(to), modelName, originalRequestRawJSON, requestRawJSON, rawJSON, param) } diff --git a/internal/usage/logger_plugin.go b/internal/usage/logger_plugin.go index 122ef305..69a2dfa5 100644 --- a/internal/usage/logger_plugin.go +++ b/internal/usage/logger_plugin.go @@ -1,3 +1,6 @@ +// Package usage provides usage tracking and logging functionality for the CLI Proxy API server. +// It includes plugins for monitoring API usage, token consumption, and other metrics +// to help with observability and billing purposes. package usage import ( @@ -13,12 +16,23 @@ func init() { } // LoggerPlugin outputs every usage record to the application log. +// It implements the coreusage.Plugin interface to provide usage tracking +// and logging capabilities for monitoring API consumption. type LoggerPlugin struct{} // NewLoggerPlugin constructs a new logger plugin instance. +// +// Returns: +// - *LoggerPlugin: A new logger plugin instance func NewLoggerPlugin() *LoggerPlugin { return &LoggerPlugin{} } // HandleUsage implements coreusage.Plugin. +// It processes usage records by marshaling them to JSON and logging them +// at debug level for observability purposes. +// +// Parameters: +// - ctx: The context for the usage record +// - record: The usage record to process and log func (p *LoggerPlugin) HandleUsage(ctx context.Context, record coreusage.Record) { // Output all relevant fields for observability; keep logging lightweight and non-blocking. data, _ := json.Marshal(record) diff --git a/internal/util/util.go b/internal/util/util.go index 78a3d0b0..bad67aae 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -1,3 +1,6 @@ +// Package util provides utility functions for the CLI Proxy API server. +// It includes helper functions for logging configuration, file system operations, +// and other common utilities used throughout the application. package util import ( diff --git a/sdk/cliproxy/builder.go b/sdk/cliproxy/builder.go index 8273e681..4d3b571c 100644 --- a/sdk/cliproxy/builder.go +++ b/sdk/cliproxy/builder.go @@ -1,3 +1,6 @@ +// Package cliproxy provides the core service implementation for the CLI Proxy API. +// It includes service lifecycle management, authentication handling, file watching, +// and integration with various AI service providers through a unified interface. package cliproxy import ( @@ -11,37 +14,81 @@ import ( ) // Builder constructs a Service instance with customizable providers. +// It provides a fluent interface for configuring all aspects of the service +// including authentication, file watching, HTTP server options, and lifecycle hooks. type Builder struct { - cfg *config.Config - configPath string - tokenProvider TokenClientProvider + // cfg holds the application configuration. + cfg *config.Config + + // configPath is the path to the configuration file. + configPath string + + // tokenProvider handles loading token-based clients. + tokenProvider TokenClientProvider + + // apiKeyProvider handles loading API key-based clients. apiKeyProvider APIKeyClientProvider + + // watcherFactory creates file watcher instances. watcherFactory WatcherFactory - hooks Hooks - authManager *sdkAuth.Manager - accessManager *sdkaccess.Manager - coreManager *coreauth.Manager - serverOptions []api.ServerOption + + // hooks provides lifecycle callbacks. + hooks Hooks + + // authManager handles legacy authentication operations. + authManager *sdkAuth.Manager + + // accessManager handles request authentication providers. + accessManager *sdkaccess.Manager + + // coreManager handles core authentication and execution. + coreManager *coreauth.Manager + + // serverOptions contains additional server configuration options. + serverOptions []api.ServerOption } // Hooks allows callers to plug into service lifecycle stages. +// These callbacks provide opportunities to perform custom initialization +// and cleanup operations during service startup and shutdown. type Hooks struct { + // OnBeforeStart is called before the service starts, allowing configuration + // modifications or additional setup. OnBeforeStart func(*config.Config) - OnAfterStart func(*Service) + + // OnAfterStart is called after the service has started successfully, + // providing access to the service instance for additional operations. + OnAfterStart func(*Service) } // NewBuilder creates a Builder with default dependencies left unset. +// Use the fluent interface methods to configure the service before calling Build(). +// +// Returns: +// - *Builder: A new builder instance ready for configuration func NewBuilder() *Builder { return &Builder{} } // WithConfig sets the configuration instance used by the service. +// +// Parameters: +// - cfg: The application configuration +// +// Returns: +// - *Builder: The builder instance for method chaining func (b *Builder) WithConfig(cfg *config.Config) *Builder { b.cfg = cfg return b } // WithConfigPath sets the absolute configuration file path used for reload watching. +// +// Parameters: +// - path: The absolute path to the configuration file +// +// Returns: +// - *Builder: The builder instance for method chaining func (b *Builder) WithConfigPath(path string) *Builder { b.configPath = path return b diff --git a/sdk/cliproxy/service.go b/sdk/cliproxy/service.go index 98c9f05c..40cc32b8 100644 --- a/sdk/cliproxy/service.go +++ b/sdk/cliproxy/service.go @@ -1,3 +1,6 @@ +// Package cliproxy provides the core service implementation for the CLI Proxy API. +// It includes service lifecycle management, authentication handling, file watching, +// and integration with various AI service providers through a unified interface. package cliproxy import ( @@ -26,38 +29,74 @@ import ( ) // Service wraps the proxy server lifecycle so external programs can embed the CLI proxy. +// It manages the complete lifecycle including authentication, file watching, HTTP server, +// and integration with various AI service providers. type Service struct { - cfg *config.Config - cfgMu sync.RWMutex + // cfg holds the current application configuration. + cfg *config.Config + + // cfgMu protects concurrent access to the configuration. + cfgMu sync.RWMutex + + // configPath is the path to the configuration file. configPath string - tokenProvider TokenClientProvider - apiKeyProvider APIKeyClientProvider - watcherFactory WatcherFactory - hooks Hooks - serverOptions []api.ServerOption + // tokenProvider handles loading token-based clients. + tokenProvider TokenClientProvider - server *api.Server + // apiKeyProvider handles loading API key-based clients. + apiKeyProvider APIKeyClientProvider + + // watcherFactory creates file watcher instances. + watcherFactory WatcherFactory + + // hooks provides lifecycle callbacks. + hooks Hooks + + // serverOptions contains additional server configuration options. + serverOptions []api.ServerOption + + // server is the HTTP API server instance. + server *api.Server + + // serverErr channel for server startup/shutdown errors. serverErr chan error - watcher *WatcherWrapper + // watcher handles file system monitoring. + watcher *WatcherWrapper + + // watcherCancel cancels the watcher context. watcherCancel context.CancelFunc - authUpdates chan watcher.AuthUpdate + + // authUpdates channel for authentication updates. + authUpdates chan watcher.AuthUpdate + + // authQueueStop cancels the auth update queue processing. authQueueStop context.CancelFunc - // legacy client caches removed - authManager *sdkAuth.Manager - accessManager *sdkaccess.Manager - coreManager *coreauth.Manager + // authManager handles legacy authentication operations. + authManager *sdkAuth.Manager + // accessManager handles request authentication providers. + accessManager *sdkaccess.Manager + + // coreManager handles core authentication and execution. + coreManager *coreauth.Manager + + // shutdownOnce ensures shutdown is called only once. shutdownOnce sync.Once } // RegisterUsagePlugin registers a usage plugin on the global usage manager. +// This allows external code to monitor API usage and token consumption. +// +// Parameters: +// - plugin: The usage plugin to register func (s *Service) RegisterUsagePlugin(plugin usage.Plugin) { usage.RegisterPlugin(plugin) } +// newDefaultAuthManager creates a default authentication manager with all supported providers. func newDefaultAuthManager() *sdkAuth.Manager { return sdkAuth.NewManager( sdkAuth.NewFileTokenStore(), @@ -216,6 +255,14 @@ func (s *Service) ensureExecutorsForAuth(a *coreauth.Auth) { } // Run starts the service and blocks until the context is cancelled or the server stops. +// It initializes all components including authentication, file watching, HTTP server, +// and starts processing requests. The method blocks until the context is cancelled. +// +// Parameters: +// - ctx: The context for controlling the service lifecycle +// +// Returns: +// - error: An error if the service fails to start or run func (s *Service) Run(ctx context.Context) error { if s == nil { return fmt.Errorf("cliproxy: service is nil") @@ -356,6 +403,14 @@ func (s *Service) Run(ctx context.Context) error { } // Shutdown gracefully stops background workers and the HTTP server. +// It ensures all resources are properly cleaned up and connections are closed. +// The shutdown is idempotent and can be called multiple times safely. +// +// Parameters: +// - ctx: The context for controlling the shutdown timeout +// +// Returns: +// - error: An error if shutdown fails func (s *Service) Shutdown(ctx context.Context) error { if s == nil { return nil diff --git a/sdk/cliproxy/types.go b/sdk/cliproxy/types.go index 1bc0d3fa..1d577153 100644 --- a/sdk/cliproxy/types.go +++ b/sdk/cliproxy/types.go @@ -1,3 +1,6 @@ +// Package cliproxy provides the core service implementation for the CLI Proxy API. +// It includes service lifecycle management, authentication handling, file watching, +// and integration with various AI service providers through a unified interface. package cliproxy import ( @@ -9,30 +12,70 @@ import ( ) // TokenClientProvider loads clients backed by stored authentication tokens. +// It provides an interface for loading authentication tokens from various sources +// and creating clients for AI service providers. type TokenClientProvider interface { + // Load loads token-based clients from the configured source. + // + // Parameters: + // - ctx: The context for the loading operation + // - cfg: The application configuration + // + // Returns: + // - *TokenClientResult: The result containing loaded clients + // - error: An error if loading fails Load(ctx context.Context, cfg *config.Config) (*TokenClientResult, error) } // TokenClientResult represents clients generated from persisted tokens. +// It contains metadata about the loading operation and the number of successful authentications. type TokenClientResult struct { + // SuccessfulAuthed is the number of successfully authenticated clients. SuccessfulAuthed int } // APIKeyClientProvider loads clients backed directly by configured API keys. +// It provides an interface for loading API key-based clients for various AI service providers. type APIKeyClientProvider interface { + // Load loads API key-based clients from the configuration. + // + // Parameters: + // - ctx: The context for the loading operation + // - cfg: The application configuration + // + // Returns: + // - *APIKeyClientResult: The result containing loaded clients + // - error: An error if loading fails Load(ctx context.Context, cfg *config.Config) (*APIKeyClientResult, error) } // APIKeyClientResult contains API key based clients along with type counts. +// It provides metadata about the number of clients loaded for each provider type. type APIKeyClientResult struct { - GeminiKeyCount int - ClaudeKeyCount int - CodexKeyCount int + // GeminiKeyCount is the number of Gemini API key clients loaded. + GeminiKeyCount int + + // ClaudeKeyCount is the number of Claude API key clients loaded. + ClaudeKeyCount int + + // CodexKeyCount is the number of Codex API key clients loaded. + CodexKeyCount int + + // OpenAICompatCount is the number of OpenAI-compatible API key clients loaded. OpenAICompatCount int } // WatcherFactory creates a watcher for configuration and token changes. -// The reload callback now only receives the updated configuration. +// The reload callback receives the updated configuration when changes are detected. +// +// Parameters: +// - configPath: The path to the configuration file to watch +// - authDir: The directory containing authentication tokens to watch +// - reload: The callback function to call when changes are detected +// +// Returns: +// - *WatcherWrapper: A watcher wrapper instance +// - error: An error if watcher creation fails type WatcherFactory func(configPath, authDir string, reload func(*config.Config)) (*WatcherWrapper, error) // WatcherWrapper exposes the subset of watcher methods required by the SDK.