From 475f473dab1964303d7c680d5f1fcf89e8b7b525 Mon Sep 17 00:00:00 2001 From: hkfires <10558748+hkfires@users.noreply.github.com> Date: Wed, 29 Oct 2025 21:10:14 +0800 Subject: [PATCH 1/2] docs: add AI Studio setup --- README.md | 47 ++++++++++++++++++++++++++++++----------------- README_CN.md | 46 +++++++++++++++++++++++++++++++--------------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index c8cd4381..b5e63809 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Chinese providers have now been added: [Qwen Code](https://github.com/QwenLM/qwe - Multiple accounts with round-robin load balancing (Gemini, OpenAI, Claude, Qwen and iFlow) - Simple CLI authentication flows (Gemini, OpenAI, Claude, Qwen and iFlow) - Generative Language API Key support +- AI Studio Build multi-account load balancing - Gemini CLI multi-account load balancing - Claude Code multi-account load balancing - Qwen Code multi-account load balancing @@ -268,12 +269,16 @@ console.log(await claudeResponse.json()); - gemini-2.5-flash-lite - gemini-2.5-flash-image - gemini-2.5-flash-image-preview +- gemini-pro-latest +- gemini-flash-latest +- gemini-flash-lite-latest - gpt-5 - gpt-5-codex - claude-opus-4-1-20250805 - claude-opus-4-20250514 - claude-sonnet-4-20250514 - claude-sonnet-4-5-20250929 +- claude-haiku-4-5-20251001 - claude-3-7-sonnet-20250219 - claude-3-5-haiku-20241022 - qwen3-coder-plus @@ -285,7 +290,6 @@ console.log(await claudeResponse.json()); - deepseek-r1 - deepseek-v3 - kimi-k2 -- glm-4.5 - glm-4.6 - tstars2.0 - And other iFlow-supported models @@ -518,28 +522,37 @@ openai-compatibility: alias: "kimi-k2" ``` -Legacy format (still supported): - -```yaml -openai-compatibility: - - name: "openrouter" - base-url: "https://openrouter.ai/api/v1" - api-keys: - - "sk-or-v1-...b780" - - "sk-or-v1-...b781" - models: - - name: "moonshotai/kimi-k2:free" - alias: "kimi-k2" -``` - Usage: Call OpenAI's endpoint `/v1/chat/completions` with `model` set to the alias (e.g., `kimi-k2`). The proxy routes to the configured provider/model automatically. -Also, you may call Claude's endpoint `/v1/messages`, Gemini's `/v1beta/models/model-name:streamGenerateContent` or `/v1beta/models/model-name:generateContent`. - And you can always use Gemini CLI with `CODE_ASSIST_ENDPOINT` set to `http://127.0.0.1:8317` for these OpenAI-compatible provider's models. +### AI Studio Instructions + +You can use this service (CLIProxyAPI) as a backend for [this AI Studio App](https://aistudio.google.com/apps/drive/1CPW7FpWGsDZzkaYgYOyXQ_6FWgxieLmL). Follow the steps below to configure it: + +1. **Start the CLIProxyAPI Service**: Ensure your CLIProxyAPI instance is running, either locally or remotely. +2. **Access the AI Studio App**: Log in to your Google account in your browser, then open the following link: + - [https://aistudio.google.com/apps/drive/1CPW7FpWGsDZzkaYgYOyXQ_6FWgxieLmL](https://aistudio.google.com/apps/drive/1CPW7FpWGsDZzkaYgYOyXQ_6FWgxieLmL) + +#### Connection Configuration + +By default, the AI Studio App attempts to connect to a local CLIProxyAPI instance at `ws://127.0.0.1:8317`. + +- **Connecting to a Remote Service**: + If you need to connect to a remotely deployed CLIProxyAPI, modify the `config.ts` file in the AI Studio App to update the `WEBSOCKET_PROXY_URL` value. + - Use the `wss://` protocol if your remote service has SSL enabled. + - Use the `ws://` protocol if SSL is not enabled. + +#### Authentication Configuration + +By default, WebSocket connections to CLIProxyAPI do not require authentication. + +- **Enable Authentication on the CLIProxyAPI Server**: + In your `config.yaml` file, set `ws_auth` to `true`. +- **Configure Authentication on the AI Studio Client**: + In the `config.ts` file of the AI Studio App, set the `JWT_TOKEN` value to your authentication token. ### Authentication Directory diff --git a/README_CN.md b/README_CN.md index dd7d71ca..37ccd544 100644 --- a/README_CN.md +++ b/README_CN.md @@ -43,6 +43,7 @@ - 多账户支持与轮询负载均衡(Gemini、OpenAI、Claude、Qwen 与 iFlow) - 简单的 CLI 身份验证流程(Gemini、OpenAI、Claude、Qwen 与 iFlow) - 支持 Gemini AIStudio API 密钥 +- 支持 AI Studio Build 多账户轮询 - 支持 Gemini CLI 多账户轮询 - 支持 Claude Code 多账户轮询 - 支持 Qwen Code 多账户轮询 @@ -281,12 +282,16 @@ console.log(await claudeResponse.json()); - gemini-2.5-flash-lite - gemini-2.5-flash-image - gemini-2.5-flash-image-preview +- gemini-pro-latest +- gemini-flash-latest +- gemini-flash-lite-latest - gpt-5 - gpt-5-codex - claude-opus-4-1-20250805 - claude-opus-4-20250514 - claude-sonnet-4-20250514 - claude-sonnet-4-5-20250929 +- claude-haiku-4-5-20251001 - claude-3-7-sonnet-20250219 - claude-3-5-haiku-20241022 - qwen3-coder-plus @@ -298,7 +303,6 @@ console.log(await claudeResponse.json()); - deepseek-r1 - deepseek-v3 - kimi-k2 -- glm-4.5 - glm-4.6 - tstars2.0 - 以及其他 iFlow 支持的模型 @@ -531,24 +535,36 @@ openai-compatibility: alias: "kimi-k2" ``` -旧格式(仍支持): - -```yaml -openai-compatibility: - - name: "openrouter" - base-url: "https://openrouter.ai/api/v1" - api-keys: - - "sk-or-v1-...b780" - - "sk-or-v1-...b781" - models: - - name: "moonshotai/kimi-k2:free" - alias: "kimi-k2" -``` - 使用方式:在 `/v1/chat/completions` 中将 `model` 设为别名(如 `kimi-k2`),代理将自动路由到对应提供商与模型。 并且,对于这些与OpenAI兼容的提供商模型,您始终可以通过将CODE_ASSIST_ENDPOINT设置为 http://127.0.0.1:8317 来使用Gemini CLI。 +### AI Studio 使用说明 + +您可以将本服务 (CLIProxyAPI) 作为后端,配合 [这个 AI Studio 应用](https://aistudio.google.com/apps/drive/1CPW7FpWGsDZzkaYgYOyXQ_6FWgxieLmL) 使用。请遵循以下步骤进行配置: + +1. **启动 CLIProxyAPI 服务**:确保您的 CLIProxyAPI 实例正在本地或远程运行。 +2. **访问 AI Studio 应用**:在浏览器中登录您的 Google 账户,然后打开以下链接: + - [https://aistudio.google.com/apps/drive/1CPW7FpWGsDZzkaYgYOyXQ_6FWgxieLmL](https://aistudio.google.com/apps/drive/1CPW7FpWGsDZzkaYgYOyXQ_6FWgxieLmL) + +#### 连接配置 + +默认情况下,AI Studio 应用会尝试连接到本地的 CLIProxyAPI (`ws://127.0.0.1:8317`)。 + +- **连接到远程服务**: + 如果您需要连接到远程部署的 CLIProxyAPI,请修改 AI Studio 应用中的 `config.ts` 文件,更新 `WEBSOCKET_PROXY_URL` 的值。 + - 如果您的远程服务启用了 SSL,请使用 `wss://` 协议。 + - 如果未启用 SSL,请使用 `ws://` 协议。 + +#### 认证配置 + +默认情况下,CLIProxyAPI 的 WebSocket 连接不要求认证。 + +- **在 CLIProxyAPI 服务端启用认证**: + 在您的 `config.yaml` 文件中,将 `ws_auth` 设置为 `true`。 +- **在 AI Studio 客户端配置认证**: + 在 AI Studio 应用的 `config.ts` 文件中,设置 `JWT_TOKEN` 的值为您的认证令牌。 + ### 身份验证目录 `auth-dir` 参数指定身份验证令牌的存储位置。当您运行登录命令时,应用程序将在此目录中创建包含 Google 账户身份验证令牌的 JSON 文件。多个账户可用于轮询。 From 24446a4dc42120fe352e9774f7cdf849507a6be2 Mon Sep 17 00:00:00 2001 From: hkfires <10558748+hkfires@users.noreply.github.com> Date: Wed, 29 Oct 2025 21:49:35 +0800 Subject: [PATCH 2/2] feat(cliproxy): skip persisting runtime-only websocket auths --- sdk/cliproxy/auth/manager.go | 5 +++++ sdk/cliproxy/service.go | 15 ++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/sdk/cliproxy/auth/manager.go b/sdk/cliproxy/auth/manager.go index 2cf7c77e..1e3f4197 100644 --- a/sdk/cliproxy/auth/manager.go +++ b/sdk/cliproxy/auth/manager.go @@ -872,6 +872,11 @@ func (m *Manager) persist(ctx context.Context, auth *Auth) error { if m.store == nil || auth == nil { return nil } + if auth.Attributes != nil { + if v := strings.ToLower(strings.TrimSpace(auth.Attributes["runtime_only"])); v == "true" { + return nil + } + } // Skip persistence when metadata is absent (e.g., runtime-only auths). if auth.Metadata == nil { return nil diff --git a/sdk/cliproxy/service.go b/sdk/cliproxy/service.go index eeccccab..27a40cc9 100644 --- a/sdk/cliproxy/service.go +++ b/sdk/cliproxy/service.go @@ -210,13 +210,14 @@ func (s *Service) wsOnConnected(channelID string) { } now := time.Now().UTC() auth := &coreauth.Auth{ - ID: channelID, // keep channel identifier as ID - Provider: "aistudio", // logical provider for switch routing - Label: channelID, // display original channel id - Status: coreauth.StatusActive, - CreatedAt: now, - UpdatedAt: now, - Metadata: map[string]any{"email": channelID}, // inject email inline + ID: channelID, // keep channel identifier as ID + Provider: "aistudio", // logical provider for switch routing + Label: channelID, // display original channel id + Status: coreauth.StatusActive, + CreatedAt: now, + UpdatedAt: now, + Attributes: map[string]string{"runtime_only": "true"}, + Metadata: map[string]any{"email": channelID}, // metadata drives logging and usage tracking } log.Infof("websocket provider connected: %s", channelID) s.applyCoreAuthAddOrUpdate(context.Background(), auth)