mirror of
https://github.com/NikkeTryHard/zerogravity.git
synced 2026-04-25 15:15:59 +03:00
[GH-ISSUE #39] fix: 已修复gemini-3.1系列不可用问题:"Gemini 3.1 Pro is not available on this version. Please upgrade to the latest version." #36
Labels
No labels
bug
enhancement
enhancement
notice
pull-request
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/zerogravity#36
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @JinchengGao-Infty on GitHub (Feb 20, 2026).
Original GitHub issue: https://github.com/NikkeTryHard/zerogravity/issues/39
What happened?
问题
Headless 模式下,LS 生成的 User-Agent 为
antigravity/ darwin/arm64(版本号为空)。Google 通过 User-Agent 中的版本号来控制新模型(如 Gemini 3.1 Pro)的访问权限。
版本号为空时,Google 在 SSE 响应中直接返回:
"Gemini 3.1 Pro is not available on this version. Please upgrade to the latest version."
(HTTP 200,非错误码,是模型的回复文本)
我认为该问题影响所有平台,因为 LS 在 headless 模式下无法从父进程获取版本号。
定位过程
User-Agent: antigravity/ darwin/arm64版本号为空修复
在 MITM 代理转发请求前,对 User-Agent header 做字节级替换:
antigravity/→antigravity/<检测到的版本号>版本号从已安装的 Antigravity 应用自动检测。替换在 body 处理之前执行,避免破坏 chunked encoding。
验证
这个修改是根据作者大大初期开源的代码进行的修改,我没有将代码泄漏给任何人,我请求成为contributor,我的主要平台是macOS,主要使用的vibe coding为:openclaw,opencode,方便在Mac做适配,
How to reproduce
curl -s --max-time 60 -X POST http://127.0.0.1:8741/v1/chat/completions
-H "Content-Type: application/json"
-d '{"model":"gemini-3.1-pro-low","messages":[{"role":"user","content":"请介绍一下MLP(多层感知机)"}],"stream":false}'
正常返回:Gemini 3.1 Pro is not available on this version. Please upgrade to the latest version.
修复后:{"choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"多层感知机(Multi-Layer Perceptron,简称 MLP)是深度学习和人工神经网络中最基础、最经典的架构之一。它属于前馈人工神经网络(Feedforward Neural Network),意味着信息在其中只能单向流动,从输入直接指向输出,没有循环或反馈。\n\n以下是关于 MLP 的详细介绍:\n\n### 1. 基本结构\n一个标准的 MLP 由多个由节点(神经元)组成的层(Layer)构成,至少包含三层:\n* 输入层(Input Layer):接收原始外部数据。这里的节点数通常与输入数据的特征数量相同。\n* 隐藏层(Hidden Layer):位于输入层和输出层之间,可以是一层或多层。这些层之所以被称为“隐藏层”,是因为它们不对外部直接可见。MLP 强大的拟合能力主要来源于隐藏层。\n* 输出层(Output Layer):网络的最后一层,负责输出最终的预测结果(例如分类的类别概率、回归的数值)。\n\n全连接(Fully Connected)特性:在 MLP 中,任意一层中的每个神经元都与上一层的所有神经元相连,并且也与下一层的所有神经元相连,这就构成了全连接网络(Dense Network)。\n\n### 2. 核心数学概念\n每个神经元的计算都可以分为两步:线性变换和非线性激活。\n\n1. 线性变换(加权求和):\n 每个神经元接收来自上一层的输入信号 $x_i$,每个输入连接都有一个对应的权重(Weight,$w_i$)。神经元会将所有输入信号与其权重相乘后求和,再加上一个偏置项(Bias,$b$):\n $$z = \sum (w_i \cdot x_i) + b$$\n * 权重决定了某个输入特征对当前神经元的影响程度。\n * 偏置相当于一个阈值,决定了神经元在没有输入时是否会被激活。\n\n2. 非线性激活函数(Activation Function):\n 如果仅仅进行加权求和,无论叠接度少层,MLP 的数学本质仍是一个简单的线性回归模型,无法处理复杂的现实问题。因此,我们需要将加权求和的结果
z输入到一个非线性的激活函数f(z)中,从而为网络引入非线性特征。\n * 常见的激活函数有:ReLU(最常用)、Sigmoid、Tanh 等。\n\n### 3. 工作与训练原理\nMLP 的训练过程本质上是一个让网络自己“学习”最合适的权重和偏置的过程,主要分为两个阶段:\n\n* 前向传播(Forward Propagation):\n 输入数据从输入层进入,经过每一层隐藏层的计算(加权求和 + 激活函数),一层层向后传递,最终在输出层生成一个预测结果。\n* 计算损失(Loss):\n 将网络的预测结果与真实的标签(Ground Truth)进行对比,使用损失函数(Loss Function)(如均方误差 MSE、交叉熵等)计算出误差有多大。\n* 反向传播(Backpropagation):\n 这是 MLP 训练的核心算法。系统通过微积分中的链式法则,从输出层算起,逆推计算出误差相对于每一个权重和偏置的梯度(即改变这个参数会让误差变大还是变小)。\n* 参数更新(优化,Optimization):\n 使用梯度下降法(Gradient Descent)或其优化形式(如 Adam、SGD),根据反向传播求出的梯度,稍微调整网络中所有的权重和偏置,以期望在下一次前向传播时,误差能够减小。\n\n经过成千上万次的循环迭代,网络的预测结果会越来越接近真实值,此时我们就可以说模型“收敛”或训练完成了。\n\n### 4. MLP 的优缺点\n\n优点:\n* 通用逼近定理:理论上,只要隐藏层的神经元足够多,一个包含哪怕只有一个隐藏层的 MLP 就可以拟合任何复杂的连续函数。\n* 应用广泛:可以直观地处理分类和回归问题。\n* 基础性:理解 MLP 是学习更复杂的网络(如 CNN卷积神经网络, RNN循环神经网络, Transformer大模型架构)必不可少的前置基石。\n\n缺点:\n* 参数量庞大:由于是“全连接”,如果输入图像等高维数据,参数量会呈指数级爆炸,非常容易导致内存耗尽并且发生过拟合(Overfitting)。\n* 忽略空间与时序信息:MLP 会将输入展平为一维向量,这破坏了图像的 2D 空间结构,也忽略了文本或时间序列前后的因果关系。(CNN 解决了图像空间问题,RNN/Transformer 解决了序列问题)。\n\n### 5. 常见应用场景\n现在的先进系统中,纯粹由多层 MLP 组成的独立模型已经较为少见,但它常常作为复杂网络结构的末端/局部组件出现:\n* 表格数据处理:在结构化数据(如 Excel 表格、CSV)的预测中,MLP 表现依然很好。\n* 深度学习网络的“分类头”:在 CNN(用于图像)或 Transformer(用于自然语言处理)提取出数据的深层特征后,通常会在网络的最末端接上几层 MLP(通常被称为全连接层 FC Layer),用来将特征映射到最终的分类概率上。","reasoning_content":"Analyzing Current Information\n\nI've been examining the available data to identify the most relevant pieces. My focus is on synthesizing this information to form a coherent understanding of the situation. I am currently working to evaluate the applicability of each of the data to the current circumstances.\n\n\nDefining MLP Fundamentals\n\nI'm now formulating a comprehensive introduction to Multi-Layer Perceptrons. I intend to detail its architecture, explain the operational mechanisms, and then cover activation functions used in training. I will conclude with a breakdown of its training, including both forward and backward propagation. I'm focusing on clarity and completeness for this fundamental concept.\n\n\n","role":"assistant"}}],"created":1771598804,"id":"chatcmpl-4944db97dfb54076b30b7feb1b3e1f89","model":"gemini-3.1-pro-low","object":"chat.completion","service_tier":"default","system_fingerprint":"fp_101","usage":{"completion_tokens":1226,"completion_tokens_details":{"reasoning_tokens":487},"prompt_tokens":5083,"prompt_tokens_details":{"cached_tokens":0},"total_tokens":6309}}%Diagnostic Report
Additional Context
No response
@JinchengGao-Infty commented on GitHub (Feb 20, 2026):
这个问题不是更新版本的问题,我测试过docker和anti都更新到最新版也是一样的报错
@JinchengGao-Infty commented on GitHub (Feb 20, 2026):
如果代码结构还是这样的话,修改如下:(opencode里的Claude说的)
核心修改在 src/mitm/proxy.rs,在请求转发前加入 User-Agent 修补:
// Fix empty User-Agent version on macOS BEFORE any body processing.
// LS generates "antigravity/ darwin/arm64" (empty version) in headless mode
// because it can't read the version from the parent process.
// Google checks this to gate new models like Gemini 3.1 Pro.
{
let old_ua = b"User-Agent: antigravity/ ";
if let Some(pos) = request_buf[..headers_end]
.windows(old_ua.len())
.position(|w| w == old_ua)
{
let version = crate::constants::antigravity_version();
let new_ua = format!("User-Agent: antigravity/{version} ");
let mut new_buf = Vec::with_capacity(request_buf.len() + version.len());
new_buf.extend_from_slice(&request_buf[..pos]);
new_buf.extend_from_slice(new_ua.as_bytes());
new_buf.extend_from_slice(&request_buf[pos + old_ua.len()..]);
let len_diff = new_ua.len() as isize - old_ua.len() as isize;
headers_end = (headers_end as isize + len_diff) as usize;
request_buf = new_buf;
}
}
另外 headers_end 的声明需要改成 mut:
// 原来:
let (headers_end, content_length, _is_streaming_request) =
parse_http_request_meta(&request_buf);
// 改为:
let (mut headers_end, content_length, _is_streaming_request) =
parse_http_request_meta(&request_buf);
这段代码插入的位置是在 handle_http_over_tls 函数里,event_tx 声明之后、if req_path.contains("streamGenerateContent") 之前。
@NikkeTryHard commented on GitHub (Feb 20, 2026):
Fixed in main — the MITM proxy now patches the empty User-Agent version that the LS emits in headless mode. Thanks @JinchengGao-Infty for the excellent root cause analysis!