mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-02 04:20:50 +08:00
chore(docs): add and refine package-level comments across modules
- Added detailed package-level comments to improve documentation coverage. - Clarified parameter descriptions, return types, and functionality of exported methods across packages. - Enhanced overall code readability and API documentation consistency.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user