Skip to content

Conversation

@aeroxy
Copy link

@aeroxy aeroxy commented Nov 30, 2025

No description provided.

@chatgpt-codex-connector
Copy link

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@gemini-code-assist
Copy link

Summary of Changes

Hello @aeroxy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly extends the system's capabilities by adding comprehensive support for Vertex AI-compatible services. This allows for seamless integration with external providers that adhere to Vertex AI's API patterns but utilize simpler API key-based authentication. The changes span configuration, client management, and API request execution, ensuring that these new services are fully recognized and functional within the existing framework.

Highlights

  • Vertex AI-compatible Service Support: Introduced new configuration types (VertexCompatKey, VertexCompatModel) and an executor (VertexCompatExecutor) to support third-party services that mimic Vertex AI's API structure but use API key authentication.
  • Configuration Integration: Updated the main configuration (config.Config) to include VertexCompatAPIKey and added sanitization logic for these new keys, ensuring proper validation and normalization.
  • Client Management Updates: Modified server and watcher components to correctly count, load, and manage these new Vertex AI-compatible clients, including synthesizing authentication entries and model hashing for dynamic registration.
  • API Request Handling: Implemented a dedicated executor (VertexCompatExecutor) to handle non-streaming, streaming, and token counting requests, translating between internal formats and the Vertex AI-compatible API, and managing API key authentication and custom headers.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for a new VertexAI-compatible service. This includes new configuration options, a new executor, and updates to the watcher and service logic to integrate the new provider. The changes are mostly correct and follow the existing patterns in the codebase. However, I've identified a few issues:

  1. A significant amount of code in the new vertex_compat_executor.go is duplicated from other executors, which could be refactored to improve maintainability.
  2. There is a redundant and incorrect block of code in internal/watcher/watcher.go that creates duplicate Auth objects.
  3. A new file sdk/auth/vertex_compat.go seems to be unused and contains logic that is inconsistent with other parts of the code.

I've provided specific comments and suggestions to address these points.

Comment on lines 867 to 894
// Vertex-compatible API keys -> synthesize auths
for i := range cfg.VertexCompatAPIKey {
entry := cfg.VertexCompatAPIKey[i]
key := strings.TrimSpace(entry.APIKey)
base := strings.TrimSpace(entry.BaseURL)
if key == "" || base == "" {
continue
}
proxyURL := strings.TrimSpace(entry.ProxyURL)
id, token := idGen.next("vertex-compat:apikey", key, base)
attrs := map[string]string{
"source": fmt.Sprintf("config:vertex-compat[%s]", token),
"api_key": key,
"base_url": base,
}
addConfigHeadersToAttrs(entry.Headers, attrs)
a := &coreauth.Auth{
ID: id,
Provider: "vertex-compat",
Label: fmt.Sprintf("vertex-compat-%s", token),
Status: coreauth.StatusActive,
ProxyURL: proxyURL,
Attributes: attrs,
CreatedAt: now,
UpdatedAt: now,
}
out = append(out, a)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This block of code, which synthesizes auth objects for Vertex-compatible API keys, appears to be redundant and incorrect. There is another loop further down in the same function (lines 1060-1093) that also handles VertexCompatAPIKey. The second loop correctly handles model aliases by computing a models_hash, which this block does not. This duplication will lead to incorrect behavior and duplicate auth entries.

This block should be removed.

Comment on lines 28 to 36
// VertexCompatExecutor is a stateless executor for Vertex AI-compatible APIs
// that use Vertex-style paths (/publishers/google/models/{model}:action)
// but authenticate with simple API keys instead of Google Cloud service accounts.
//
// This executor supports third-party providers like zenmux.ai that mimic
// Vertex AI's URL structure while using simpler authentication mechanisms.
type VertexCompatExecutor struct {
cfg *config.Config
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This new executor contains a significant amount of code that is duplicated from gemini_executor.go and gemini_vertex_executor.go. The Execute, ExecuteStream, and CountTokens methods are nearly identical across these files, with minor differences in URL construction and authentication.

To improve maintainability and reduce redundancy, consider refactoring the common logic into a base executor struct or a set of shared helper functions. This would make the codebase easier to manage and reduce the chance of bugs when updating the execution logic for Gemini-like providers.

Comment on lines 1 to 94
package auth

import (
"context"
"fmt"
"strings"

"github.com/router-for-me/CLIProxyAPI/v6/internal/config"
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
)

// LoadVertexCompatCredentials loads Vertex AI-compatible API key credentials from config
// into the auth manager. Each entry becomes an in-memory auth entry with API key and
// custom headers stored in attributes.
func LoadVertexCompatCredentials(ctx context.Context, cfg *config.Config, mgr *coreauth.Manager) error {
if cfg == nil || mgr == nil {
return nil
}
if len(cfg.VertexCompatAPIKey) == 0 {
return nil
}

for i, entry := range cfg.VertexCompatAPIKey {
apiKey := strings.TrimSpace(entry.APIKey)
baseURL := strings.TrimSpace(entry.BaseURL)

if apiKey == "" || baseURL == "" {
continue
}

// Create unique ID from index and base URL
id := fmt.Sprintf("vertex-compat-%d-%s", i, sanitizeForID(baseURL))
label := fmt.Sprintf("Vertex-Compat (%s)", extractDomain(baseURL))

// Build attributes map
attrs := make(map[string]string)
attrs["api_key"] = apiKey
attrs["base_url"] = baseURL

// Add proxy URL if specified
if entry.ProxyURL != "" {
attrs["proxy_url"] = strings.TrimSpace(entry.ProxyURL)
}

// Copy custom headers to attributes with "header_" prefix
for k, v := range entry.Headers {
headerKey := "header_" + strings.ToLower(strings.TrimSpace(k))
attrs[headerKey] = strings.TrimSpace(v)
}

auth := &coreauth.Auth{
ID: id,
Provider: "vertex-compat",
Label: label,
Attributes: attrs,
Metadata: make(map[string]any),
}

if _, err := mgr.Register(ctx, auth); err != nil {
return fmt.Errorf("failed to register vertex-compat credential %d: %w", i, err)
}
}

return nil
}

// sanitizeForID creates a safe ID component from a URL.
func sanitizeForID(url string) string {
// Remove https:// and http://
clean := strings.TrimPrefix(url, "https://")
clean = strings.TrimPrefix(clean, "http://")
// Replace non-alphanumeric with dash
clean = strings.Map(func(r rune) rune {
if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') {
return r
}
return '-'
}, clean)
// Limit length
if len(clean) > 30 {
clean = clean[:30]
}
return strings.Trim(clean, "-")
}

// extractDomain extracts the domain from a URL for display purposes.
func extractDomain(url string) string {
clean := strings.TrimPrefix(url, "https://")
clean = strings.TrimPrefix(clean, "http://")
if idx := strings.Index(clean, "/"); idx > 0 {
clean = clean[:idx]
}
return clean
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This new file appears to be unused in the current pull request. The function LoadVertexCompatCredentials duplicates logic for creating Auth objects from the configuration, which is also handled in internal/watcher/watcher.go. The logic here is also inconsistent with the watcher's implementation (e.g., ID generation, handling of model aliases).

If this file is not intended to be used, it should be removed to avoid confusion and dead code. If it is intended for future use, it should be reconciled with the logic in watcher.go to ensure consistency.

@luispater luispater changed the base branch from main to dev November 30, 2025 13:02
Copy link
Collaborator

@luispater luispater left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refer to internal/runtime/executor/claude_executor.go to add apikey support within internal/runtime/executor/gemini_vertex_executor.go, instead of using a separate executor to add this support.

Thank you.

@aeroxy
Copy link
Author

aeroxy commented Nov 30, 2025

Please refer to internal/runtime/executor/claude_executor.go to add apikey support within internal/runtime/executor/gemini_vertex_executor.go, instead of using a separate executor to add this support.

Thank you.

Got it. :) Will do.

@aeroxy aeroxy force-pushed the feat/vertex-compat branch from d313452 to 0fdce3e Compare November 30, 2025 15:18
@aeroxy aeroxy requested a review from luispater November 30, 2025 15:19
@luispater luispater merged commit 0ebb654 into router-for-me:dev Dec 2, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants