diff --git a/README-JA.md b/README-JA.md index 529829a..227c362 100644 --- a/README-JA.md +++ b/README-JA.md @@ -47,16 +47,6 @@ AICodeMirror の本プロジェクトへのスポンサーシップに感謝します!AICodeMirror は、Claude Code / Codex / Gemini CLI 向けに公式の高安定性リレーサービスを提供しており、企業レベルの同時実行性、迅速な請求書発行、24時間365日の専用技術サポートを備えています。Claude Code / Codex / Gemini の公式チャンネルを、元の価格の 38% / 2% / 9% で利用でき、チャージ時にはさらなる割引もあります!AICodeMirror は AIClient-2-API ユーザーに特別な特典を提供しています:このリンクから登録すると、初回チャージが 20% オフになり、法人のお客様は最大 25% オフになります! -
-
-
diff --git a/README-ZH.md b/README-ZH.md
index 048bf2f..e7e2ddf 100644
--- a/README-ZH.md
+++ b/README-ZH.md
@@ -46,16 +46,6 @@
感谢 AICodeMirror 赞助本项目!AICodeMirror 为 Claude Code / Codex / Gemini CLI 提供官方高稳定性中转服务,具备企业级并发能力、快速开票和 7/24 专属技术支持。Claude Code / Codex / Gemini 官方渠道价格仅为原价的 38% / 2% / 9%,充值还有额外优惠!AICodeMirror 为 AIClient-2-API 用户提供专属福利:通过此链接注册即可享受首充 8折(20% off) 优惠,企业客户最高可享 75折(25% off)!
-
-
diff --git a/README.md b/README.md
index 3aef936..8c0895e 100644
--- a/README.md
+++ b/README.md
@@ -47,16 +47,6 @@
Thanks to AICodeMirror for sponsoring this project! AICodeMirror provides official high-stability relay services for Claude Code / Codex / Gemini CLI, with enterprise-grade concurrency, fast invoicing, and 24/7 dedicated technical support. Claude Code / Codex / Gemini official channels at 38% / 2% / 9% of original price, with extra discounts on top-ups! AICodeMirror offers special benefits for AIClient-2-API users: register via this link to enjoy 20% off your first top-up, and enterprise customers can get up to 25% off!
-
-
diff --git a/VERSION b/VERSION
index ccc99d0..d463c35 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.12.3
+2.12.2.2
diff --git a/install-and-run.ps1 b/install-and-run.ps1
index d72a7f7..11821a0 100644
--- a/install-and-run.ps1
+++ b/install-and-run.ps1
@@ -2,70 +2,70 @@
$OutputEncoding = [System.Text.Encoding]::UTF8
Write-Host "========================================" -ForegroundColor Cyan
-Write-Host " AI Client 2 API Quick Setup Script" -ForegroundColor Cyan
+Write-Host " AI Client 2 API 快速安装启动脚本" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
-# Handle parameters
+# 处理参数
$forcePull = $args -contains "--pull"
-# Check Git and Pull
+# 检查 Git 并拉取
if ($forcePull) {
- Write-Host "[UPDATE] Pulling latest code from remote repository..."
+ Write-Host "[更新] 正在从远程仓库拉取最新代码..."
if (Get-Command git -ErrorAction SilentlyContinue) {
git pull
if ($LASTEXITCODE -ne 0) {
- Write-Warning "Git pull failed. Please check your network or handle conflicts manually."
+ Write-Warning "Git pull 失败,请检查网络或手动处理冲突。"
} else {
- Write-Host "[SUCCESS] Code updated." -ForegroundColor Green
+ Write-Host "[成功] 代码已更新。" -ForegroundColor Green
}
} else {
- Write-Warning "Git not detected. Skipping code pull."
+ Write-Warning "未检测到 Git,跳过代码拉取。"
}
}
-# Check Node.js
-Write-Host "[CHECK] Checking if Node.js is installed..."
+# 检查 Node.js
+Write-Host "[检查] 正在检查Node.js是否已安装..."
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
- Write-Host "[ERROR] Node.js not detected. Please install Node.js (https://nodejs.org/)" -ForegroundColor Red
+ Write-Host "[错误] 未检测到Node.js,请先安装Node.js (https://nodejs.org/)" -ForegroundColor Red
Pause
exit 1
}
$nodeVersion = node --version
-Write-Host "[SUCCESS] Node.js installed, version: $nodeVersion" -ForegroundColor Green
+Write-Host "[成功] Node.js已安装,版本: $nodeVersion" -ForegroundColor Green
-# Check package.json
+# 检查 package.json
if (-not (Test-Path "package.json")) {
- Write-Host "[ERROR] package.json not found. Please ensure you are running this script from the project root." -ForegroundColor Red
+ Write-Host "[错误] 未找到package.json文件,请确保在项目根目录下运行此脚本" -ForegroundColor Red
Pause
exit 1
}
-# Determine package manager
+# 确定包管理器
$pkgManager = if (Get-Command pnpm -ErrorAction SilentlyContinue) { "pnpm" } else { "npm" }
-Write-Host "[INSTALL] Installing/updating dependencies using $pkgManager..." -ForegroundColor Cyan
+Write-Host "[安装] 正在使用 $pkgManager 安装/更新依赖..." -ForegroundColor Cyan
& $pkgManager install
if ($LASTEXITCODE -ne 0) {
- Write-Host "[ERROR] Dependency installation failed. Please check your network connection." -ForegroundColor Red
+ Write-Host "[错误] 依赖安装失败,请检查网络连接。" -ForegroundColor Red
Pause
exit 1
}
-# Check master file
+# 检查主文件
if (-not (Test-Path "src\core\master.js")) {
- Write-Host "[ERROR] src\core\master.js not found." -ForegroundColor Red
+ Write-Host "[错误] 未找到 src\core\master.js 文件" -ForegroundColor Red
Pause
exit 1
}
Write-Host ""
Write-Host "========================================" -ForegroundColor Green
-Write-Host " Starting AIClient2API Server..." -ForegroundColor Green
+Write-Host " 启动 AIClient2API 服务器..." -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green
-Write-Host "Server will start at http://localhost:3000"
-Write-Host "Press Ctrl+C to stop the server"
+Write-Host "服务器将在 http://localhost:3000 启动"
+Write-Host "按 Ctrl+C 停止服务器"
Write-Host ""
node src\core\master.js
diff --git a/src/providers/gemini/antigravity-core.js b/src/providers/gemini/antigravity-core.js
index e1da3dc..c66fd2e 100644
--- a/src/providers/gemini/antigravity-core.js
+++ b/src/providers/gemini/antigravity-core.js
@@ -40,7 +40,6 @@ const ANTIGRAVITY_SYSTEM_PROMPT = `You are Antigravity, a powerful agentic AI co
// Thinking 配置相关常量
const DEFAULT_THINKING_MIN = 1024;
const DEFAULT_THINKING_MAX = 100000;
-const FALLBACK_THINKING_SIGNATURE = "skip_thought_signature_validator_fallback";
// 获取 Antigravity 模型列表
const ANTIGRAVITY_MODELS = getProviderModels(MODEL_PROVIDER.ANTIGRAVITY);
@@ -200,16 +199,16 @@ function normalizeAntigravityThinking(modelName, payload, isClaudeModel) {
let normalizedBudget = normalizeThinkingBudget(modelName, budget);
- // 确保 thinking budget < max_tokens (对所有模型生效,不仅是 Claude)
- const maxTokens = payload?.request?.generationConfig?.maxOutputTokens || payload?.request?.generationConfig?.max_output_tokens;
- if (maxTokens && maxTokens > 0 && normalizedBudget >= maxTokens) {
- normalizedBudget = Math.max(0, maxTokens - 1);
- }
-
- // 如果是 Claude 模型,检查最小 budget
+ // 对于 Claude 模型,确保 thinking budget < max_tokens
if (isClaudeModel) {
+ const maxTokens = payload?.request?.generationConfig?.maxOutputTokens;
+ if (maxTokens && maxTokens > 0 && normalizedBudget >= maxTokens) {
+ normalizedBudget = maxTokens - 1;
+ }
+
+ // 检查最小 budget
const minBudget = DEFAULT_THINKING_MIN;
- if (normalizedBudget >= 0 && normalizedBudget < minBudget && normalizedBudget !== -1) {
+ if (normalizedBudget >= 0 && normalizedBudget < minBudget) {
// Budget 低于最小值,移除 thinking 配置
delete payload.request.generationConfig.thinkingConfig;
return payload;
@@ -600,7 +599,7 @@ function toGeminiApiResponse(antigravityResponse) {
}
/**
- * 确保请求体中的内容部分都有角色属性,并修复历史记录中的思考签名
+ * 确保请求体中的内容部分都有角色属性
* @param {Object} requestBody - 请求体
* @returns {Object} 处理后的请求体
*/
@@ -675,24 +674,6 @@ function ensureRolesInContents(requestBody, modelName) {
if (!content.role) {
content.role = 'user';
}
-
- // [FIX] 修复历史记录中的思考块,确保有签名 (messages.1.content.0.thinking.signature 报错修复)
- if (content.parts && Array.isArray(content.parts)) {
- content.parts.forEach(part => {
- if (part && part.thought === true) {
- if (!part.thoughtSignature && !part.thought_signature) {
- part.thoughtSignature = FALLBACK_THINKING_SIGNATURE;
- }
-
- // [FIX] 额外增加一个 'thinking' 对象以适配某些 Antigravity 内部验证逻辑
- if (!part.thinking) {
- part.thinking = {
- signature: part.thoughtSignature || part.thought_signature || FALLBACK_THINKING_SIGNATURE
- };
- }
- }
- });
- }
});
}
@@ -715,6 +696,25 @@ export class AntigravityApiService {
timeout: 120000,
});
+ // 检查是否需要使用代理
+ const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY);
+
+ // 配置 OAuth2Client 使用自定义的 HTTP agent
+ const oauth2Options = {
+ clientId: OAUTH_CLIENT_ID,
+ clientSecret: OAUTH_CLIENT_SECRET,
+ };
+
+ if (proxyConfig) {
+ oauth2Options.transporterOptions = proxyConfig;
+ logger.info('[Antigravity] Using proxy for OAuth2Client');
+ } else {
+ oauth2Options.transporterOptions = {
+ agent: this.httpsAgent,
+ };
+ }
+
+ this.authClient = new OAuth2Client(oauth2Options);
this.availableModels = [];
this.isInitialized = false;
@@ -730,32 +730,6 @@ export class AntigravityApiService {
// 保存代理配置供后续使用
this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY);
-
- // 检查是否需要使用代理
- const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY);
-
- // 配置 OAuth2Client 使用自定义的 HTTP agent
- const oauth2Options = {
- clientId: OAUTH_CLIENT_ID,
- clientSecret: OAUTH_CLIENT_SECRET,
- };
-
- if (proxyConfig) {
- oauth2Options.transporterOptions = proxyConfig;
- logger.info('[Antigravity] Using proxy for OAuth2Client');
- } else {
- // 根据 base URL 判断使用 http 还是 https agent
- const firstBaseURL = this.baseURLs && this.baseURLs.length > 0 ? this.baseURLs[0] : '';
- const useHttp = firstBaseURL.startsWith('http://');
- oauth2Options.transporterOptions = {
- agent: useHttp ? this.httpAgent : this.httpsAgent,
- };
- if (useHttp) {
- logger.info('[Antigravity] Using HTTP agent for OAuth2Client');
- }
- }
-
- this.authClient = new OAuth2Client(oauth2Options);
}
_applySidecar(requestOptions) {
diff --git a/src/providers/gemini/gemini-core.js b/src/providers/gemini/gemini-core.js
index 57abb77..b4f386c 100644
--- a/src/providers/gemini/gemini-core.js
+++ b/src/providers/gemini/gemini-core.js
@@ -287,6 +287,24 @@ export class GeminiApiService {
maxFreeSockets: 5,
timeout: 120000,
});
+
+ // 检查是否需要使用代理
+ const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI);
+
+ // 配置 OAuth2Client 使用自定义的 HTTP agent
+ const oauth2Options = {
+ clientId: OAUTH_CLIENT_ID,
+ clientSecret: OAUTH_CLIENT_SECRET,
+ };
+
+ if (proxyConfig) {
+ oauth2Options.transporterOptions = proxyConfig;
+ logger.info('[Gemini] Using proxy for OAuth2Client');
+ } else {
+ oauth2Options.transporterOptions = {
+ agent: this.httpsAgent,
+ };
+ }
this.authClient = new OAuth2Client(oauth2Options);
this.availableModels = [];
@@ -304,29 +322,6 @@ export class GeminiApiService {
// 保存代理配置供后续使用
this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI);
-
- // 检查是否需要使用代理
- const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI);
-
- // 配置 OAuth2Client 使用自定义的 HTTP agent
- const oauth2Options = {
- clientId: OAUTH_CLIENT_ID,
- clientSecret: OAUTH_CLIENT_SECRET,
- };
-
- if (proxyConfig) {
- oauth2Options.transporterOptions = proxyConfig;
- logger.info('[Gemini] Using proxy for OAuth2Client');
- } else {
- // 根据 base URL 判断使用 http 还是 https agent
- const useHttp = this.codeAssistEndpoint && this.codeAssistEndpoint.startsWith('http://');
- oauth2Options.transporterOptions = {
- agent: useHttp ? this.httpAgent : this.httpsAgent,
- };
- if (useHttp) {
- logger.info('[Gemini] Using HTTP agent for OAuth2Client');
- }
- }
}
async initialize() {
diff --git a/src/providers/openai/qwen-core.js b/src/providers/openai/qwen-core.js
index f84a679..e2621ca 100644
--- a/src/providers/openai/qwen-core.js
+++ b/src/providers/openai/qwen-core.js
@@ -50,38 +50,6 @@ export const qwenOAuth2Events = new EventEmitter();
// --- Helper Functions ---
-/**
- * Qwen 默认系统提示词
- */
-const QWEN_DEFAULT_SYSTEM_PROMPT = "You are a helpful assistant. You are Qwen, a large language model trained by Alibaba.";
-
-/**
- * 应用 Qwen 默认系统提示词逻辑
- * @param {Object} requestBody - OpenAI 格式的请求体
- * @returns {Object} 处理后的请求体
- */
-function applyQwenDefaultSystemPrompt(requestBody) {
- if (!requestBody || !requestBody.messages || !Array.isArray(requestBody.messages)) {
- return requestBody;
- }
-
- // 检查是否已有系统提示词 (role 为 system 或 developer)
- const hasSystemPrompt = requestBody.messages.some(msg =>
- msg.role === 'system' || msg.role === 'developer'
- );
-
- // 如果没有系统提示词,则在消息列表最前面插入默认提示词
- if (!hasSystemPrompt) {
- requestBody.messages.unshift({
- role: 'system',
- content: QWEN_DEFAULT_SYSTEM_PROMPT
- });
- logger.info('[Qwen Auth] 已应用默认系统提示词');
- }
-
- return requestBody;
-}
-
// 封装公共的 await fetch 方法
async function commonFetch(url, options = {}, useSystemProxy = false) {
const defaultOptions = {
@@ -612,7 +580,7 @@ export class QwenApiService {
this.currentAxiosInstance = axios.create(axiosConfig);
// Process message content before sending the request
- const processedBody = applyQwenDefaultSystemPrompt(body);
+ const processedBody = body;//this.processMessageContent(body);
// Check if model in body is in QWEN_MODEL_LIST, if not, use the first model's id
if (processedBody.model && !QWEN_MODEL_LIST.some(model => model.id === processedBody.model)) {
diff --git a/static/lingtrueapi.png b/static/lingtrueapi.png
deleted file mode 100644
index 0829a7c..0000000
Binary files a/static/lingtrueapi.png and /dev/null differ