diff --git a/config.example.yaml b/config.example.yaml index fb29477d9b..3718a07a1e 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -212,11 +212,11 @@ nonstream-keepalive-interval: 0 # - name: "kimi-k2.5" # alias: "claude-opus-4.66" -# Vertex API keys (Vertex-compatible endpoints, use API key + base URL) +# Vertex API keys (Vertex-compatible endpoints, base-url is optional) # vertex-api-key: # - api-key: "vk-123..." # x-goog-api-key header # prefix: "test" # optional: require calls like "test/vertex-pro" to target this credential -# base-url: "https://example.com/api" # e.g. https://zenmux.ai/api +# base-url: "https://example.com/api" # optional, e.g. https://zenmux.ai/api; falls back to Google Vertex when omitted # proxy-url: "socks5://proxy.example.com:1080" # optional per-key proxy override # # proxy-url: "direct" # optional: explicit direct connect for this credential # headers: diff --git a/internal/api/handlers/management/config_lists.go b/internal/api/handlers/management/config_lists.go index 503179c11c..083d4e31ef 100644 --- a/internal/api/handlers/management/config_lists.go +++ b/internal/api/handlers/management/config_lists.go @@ -509,8 +509,12 @@ func (h *Handler) PutVertexCompatKeys(c *gin.Context) { } for i := range arr { normalizeVertexCompatKey(&arr[i]) + if arr[i].APIKey == "" { + c.JSON(400, gin.H{"error": fmt.Sprintf("vertex-api-key[%d].api-key is required", i)}) + return + } } - h.cfg.VertexCompatAPIKey = arr + h.cfg.VertexCompatAPIKey = append([]config.VertexCompatKey(nil), arr...) h.cfg.SanitizeVertexCompatKeys() h.persist(c) } diff --git a/internal/config/config.go b/internal/config/config.go index 7bd137e0db..a11c741efc 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -621,7 +621,7 @@ func LoadConfigOptional(configFile string, optional bool) (*Config, error) { // Sanitize Gemini API key configuration and migrate legacy entries. cfg.SanitizeGeminiKeys() - // Sanitize Vertex-compatible API keys: drop entries without base-url + // Sanitize Vertex-compatible API keys. cfg.SanitizeVertexCompatKeys() // Sanitize Codex keys: drop entries without base-url diff --git a/internal/config/vertex_compat.go b/internal/config/vertex_compat.go index 5f6c7c88cd..c13e438df7 100644 --- a/internal/config/vertex_compat.go +++ b/internal/config/vertex_compat.go @@ -20,9 +20,9 @@ type VertexCompatKey struct { // Prefix optionally namespaces model aliases for this credential (e.g., "teamA/vertex-pro"). Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty"` - // BaseURL is the base URL for the Vertex-compatible API endpoint. + // BaseURL optionally overrides the Vertex-compatible API endpoint. // The executor will append "/v1/publishers/google/models/{model}:action" to this. - // Example: "https://zenmux.ai/api" becomes "https://zenmux.ai/api/v1/publishers/google/models/..." + // When empty, requests fall back to the default Vertex API base URL. BaseURL string `yaml:"base-url,omitempty" json:"base-url,omitempty"` // ProxyURL optionally overrides the global proxy for this API key. @@ -71,10 +71,6 @@ func (cfg *Config) SanitizeVertexCompatKeys() { } entry.Prefix = normalizeModelPrefix(entry.Prefix) entry.BaseURL = strings.TrimSpace(entry.BaseURL) - if entry.BaseURL == "" { - // BaseURL is required for Vertex API key entries - continue - } entry.ProxyURL = strings.TrimSpace(entry.ProxyURL) entry.Headers = NormalizeHeaders(entry.Headers) entry.ExcludedModels = NormalizeExcludedModels(entry.ExcludedModels)