Something went wrong. Try again.
sloproxy
Something went wrong. Try again.
6.8 kB · 192 lines
Go
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193// 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 ( "context"
"github.com/router-for-me/CLIProxyAPI/v7/internal/watcher" coreauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth" "github.com/router-for-me/CLIProxyAPI/v7/sdk/config" "github.com/router-for-me/CLIProxyAPI/v7/sdk/pluginapi")
// 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 is returned by APIKeyClientProvider.Load()type APIKeyClientResult struct { // GeminiKeyCount is the number of Gemini-family API keys loaded. // It includes native Interactions API keys. GeminiKeyCount int
// VertexCompatKeyCount is the number of Vertex-compatible API keys loaded VertexCompatKeyCount int
// ClaudeKeyCount is the number of Claude API keys loaded ClaudeKeyCount int
// CodexKeyCount is the number of Codex API keys loaded CodexKeyCount int
// XAIKeyCount is the number of xAI API keys loaded XAIKeyCount int
// OpenAICompatCount is the number of OpenAI compatibility API keys loaded OpenAICompatCount int}
// WatcherFactory creates a watcher for configuration and token changes.// 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 failstype WatcherFactory func(configPath, authDir string, reload func(*config.Config)) (*WatcherWrapper, error)
// PluginAuthParser parses auth JSON owned by plugin providers.type PluginAuthParser interface { ParseAuth(context.Context, pluginapi.AuthParseRequest) (*coreauth.Auth, bool, error)}
// PluginMultiAuthParser expands one auth JSON payload into multiple plugin auth records.// Returning handled=true with an empty slice means the plugin intentionally suppresses built-in parsing.type PluginMultiAuthParser interface { ParseAuths(context.Context, pluginapi.AuthParseRequest) ([]*coreauth.Auth, bool, error)}
// WatcherWrapper exposes the subset of watcher methods required by the SDK.type WatcherWrapper struct { start func(ctx context.Context) error stop func() error
setConfig func(cfg *config.Config) snapshotAuths func() []*coreauth.Auth setUpdateQueue func(queue chan<- watcher.AuthUpdate) dispatchRuntimeUpdate func(update watcher.AuthUpdate) bool dispatchPersistedAuth func(update watcher.AuthUpdate) bool setPluginAuthParser func(parser PluginAuthParser) reloadConfigIfChanged func()}
// Start proxies to the underlying watcher Start implementation.func (w *WatcherWrapper) Start(ctx context.Context) error { if w == nil || w.start == nil { return nil } return w.start(ctx)}
// Stop proxies to the underlying watcher Stop implementation.func (w *WatcherWrapper) Stop() error { if w == nil || w.stop == nil { return nil } return w.stop()}
// SetConfig updates the watcher configuration cache.func (w *WatcherWrapper) SetConfig(cfg *config.Config) { if w == nil || w.setConfig == nil { return } w.setConfig(cfg)}
// ReloadConfigIfChanged asks the underlying watcher to reload config from disk.func (w *WatcherWrapper) ReloadConfigIfChanged() bool { if w == nil || w.reloadConfigIfChanged == nil { return false } w.reloadConfigIfChanged() return true}
// SetPluginAuthParser updates the plugin auth parser used by the watcher.func (w *WatcherWrapper) SetPluginAuthParser(parser PluginAuthParser) { if w == nil || w.setPluginAuthParser == nil { return } w.setPluginAuthParser(parser)}
// DispatchRuntimeAuthUpdate forwards runtime auth updates (e.g., websocket providers)// into the watcher-managed auth update queue when available.// Returns true if the update was enqueued successfully.func (w *WatcherWrapper) DispatchRuntimeAuthUpdate(update watcher.AuthUpdate) bool { if w == nil || w.dispatchRuntimeUpdate == nil { return false } return w.dispatchRuntimeUpdate(update)}
// DispatchPersistedAuthUpdate forwards already-persisted file auth updates.func (w *WatcherWrapper) DispatchPersistedAuthUpdate(update watcher.AuthUpdate) bool { if w == nil || w.dispatchPersistedAuth == nil { return false } return w.dispatchPersistedAuth(update)}
// SetClients updates the watcher file-backed clients registry.// SetClients and SetAPIKeyClients removed; watcher manages its own caches
// SnapshotClients returns the current combined clients snapshot from the underlying watcher.// SnapshotClients removed; use SnapshotAuths
// SnapshotAuths returns the current auth entries derived from legacy clients.func (w *WatcherWrapper) SnapshotAuths() []*coreauth.Auth { if w == nil || w.snapshotAuths == nil { return nil } return w.snapshotAuths()}
// SetAuthUpdateQueue registers the channel used to propagate auth updates.func (w *WatcherWrapper) SetAuthUpdateQueue(queue chan<- watcher.AuthUpdate) { if w == nil || w.setUpdateQueue == nil { return } w.setUpdateQueue(queue)}