Add support for API key indexing in OpenAI compatibility clients

- Updated `NewOpenAICompatibilityClient` to accept `apiKeyIndex` for managing multiple API keys.
- Modified client instantiation loops to initialize one client per API key.
- Adjusted client ID format to include `apiKeyIndex` for unique identification.
- Removed API key rotation logic within `GetCurrentAPIKey`.
- Updated `.gitignore` to include `AGENTS.md`.
This commit is contained in:
Luis Pater
2025-09-08 22:36:44 +08:00
parent f9f2333997
commit 99c9f3069c
4 changed files with 25 additions and 18 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ docs/*
logs/* logs/*
auths/* auths/*
!auths/.gitkeep !auths/.gitkeep
AGENTS.md

View File

@@ -44,7 +44,7 @@ type OpenAICompatibilityClient struct {
// Returns: // Returns:
// - *OpenAICompatibilityClient: A new OpenAI compatibility client instance. // - *OpenAICompatibilityClient: A new OpenAI compatibility client instance.
// - error: An error if the client creation fails. // - error: An error if the client creation fails.
func NewOpenAICompatibilityClient(cfg *config.Config, compatConfig *config.OpenAICompatibility) (*OpenAICompatibilityClient, error) { func NewOpenAICompatibilityClient(cfg *config.Config, compatConfig *config.OpenAICompatibility, apiKeyIndex int) (*OpenAICompatibilityClient, error) {
if compatConfig == nil { if compatConfig == nil {
return nil, fmt.Errorf("compatibility configuration is required") return nil, fmt.Errorf("compatibility configuration is required")
} }
@@ -53,10 +53,14 @@ func NewOpenAICompatibilityClient(cfg *config.Config, compatConfig *config.OpenA
return nil, fmt.Errorf("at least one API key is required for OpenAI compatibility provider: %s", compatConfig.Name) return nil, fmt.Errorf("at least one API key is required for OpenAI compatibility provider: %s", compatConfig.Name)
} }
if len(compatConfig.APIKeys) <= apiKeyIndex {
return nil, fmt.Errorf("invalid API key index for OpenAI compatibility provider: %s", compatConfig.Name)
}
httpClient := util.SetProxy(cfg, &http.Client{}) httpClient := util.SetProxy(cfg, &http.Client{})
// Generate unique client ID // Generate unique client ID
clientID := fmt.Sprintf("openai-compatibility-%s-%d", compatConfig.Name, time.Now().UnixNano()) clientID := fmt.Sprintf("openai-compatibility-%s-%d-%d", compatConfig.Name, apiKeyIndex, time.Now().UnixNano())
client := &OpenAICompatibilityClient{ client := &OpenAICompatibilityClient{
ClientBase: ClientBase{ ClientBase: ClientBase{
@@ -66,7 +70,7 @@ func NewOpenAICompatibilityClient(cfg *config.Config, compatConfig *config.OpenA
modelQuotaExceeded: make(map[string]*time.Time), modelQuotaExceeded: make(map[string]*time.Time),
}, },
compatConfig: compatConfig, compatConfig: compatConfig,
currentAPIKeyIndex: 0, currentAPIKeyIndex: apiKeyIndex,
} }
// Initialize model registry // Initialize model registry
@@ -134,8 +138,6 @@ func (c *OpenAICompatibilityClient) GetCurrentAPIKey() string {
} }
key := c.compatConfig.APIKeys[c.currentAPIKeyIndex] key := c.compatConfig.APIKeys[c.currentAPIKeyIndex]
// Rotate to next key for load balancing
c.currentAPIKeyIndex = (c.currentAPIKeyIndex + 1) % len(c.compatConfig.APIKeys)
return key return key
} }

View File

@@ -335,14 +335,16 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int,
if len(cfg.OpenAICompatibility) > 0 { if len(cfg.OpenAICompatibility) > 0 {
for _, compatConfig := range cfg.OpenAICompatibility { for _, compatConfig := range cfg.OpenAICompatibility {
log.Debugf("Initializing OpenAI compatibility client for provider: %s", compatConfig.Name) for i := 0; i < len(compatConfig.APIKeys); i++ {
compatClient, errClient := client.NewOpenAICompatibilityClient(cfg, &compatConfig) log.Debugf("Initializing OpenAI compatibility client for provider: %s", compatConfig.Name)
if errClient != nil { compatClient, errClient := client.NewOpenAICompatibilityClient(cfg, &compatConfig, i)
log.Errorf("failed to create OpenAI compatibility client for %s: %v", compatConfig.Name, errClient) if errClient != nil {
continue log.Errorf("failed to create OpenAI compatibility client for %s: %v", compatConfig.Name, errClient)
continue
}
apiKeyClients[compatClient.GetClientID()] = compatClient
openAICompatCount++
} }
apiKeyClients[compatClient.GetClientID()] = compatClient
openAICompatCount++
} }
} }

View File

@@ -549,13 +549,15 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int,
} }
if len(cfg.OpenAICompatibility) > 0 { if len(cfg.OpenAICompatibility) > 0 {
for _, compatConfig := range cfg.OpenAICompatibility { for _, compatConfig := range cfg.OpenAICompatibility {
compatClient, errClient := client.NewOpenAICompatibilityClient(cfg, &compatConfig) for i := 0; i < len(compatConfig.APIKeys); i++ {
if errClient != nil { compatClient, errClient := client.NewOpenAICompatibilityClient(cfg, &compatConfig, i)
log.Errorf("failed to create OpenAI-compatibility client for %s: %v", compatConfig.Name, errClient) if errClient != nil {
continue log.Errorf("failed to create OpenAI-compatibility client for %s: %v", compatConfig.Name, errClient)
continue
}
apiKeyClients[compatClient.GetClientID()] = compatClient
openAICompatCount++
} }
apiKeyClients[compatClient.GetClientID()] = compatClient
openAICompatCount++
} }
} }
return apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount return apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount