Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
5dd83d3c
"backend/internal/vscode:/vscode.git/clone" did not exist on "74e05b83eaa175029cc2a25a154bc750045aba99"
Commit
5dd83d3c
authored
Feb 10, 2026
by
shaw
Browse files
fix: 移除特定system以适配新版cc客户端缓存失效的bug
parent
14e1aac9
Changes
6
Show whitespace changes
Inline
Side-by-side
backend/internal/pkg/antigravity/request_transformer.go
View file @
5dd83d3c
...
@@ -271,6 +271,21 @@ func filterOpenCodePrompt(text string) string {
...
@@ -271,6 +271,21 @@ func filterOpenCodePrompt(text string) string {
return
""
return
""
}
}
// systemBlockFilterPrefixes 需要从 system 中过滤的文本前缀列表
var
systemBlockFilterPrefixes
=
[]
string
{
"x-anthropic-billing-header"
,
}
// filterSystemBlockByPrefix 如果文本匹配过滤前缀,返回空字符串
func
filterSystemBlockByPrefix
(
text
string
)
string
{
for
_
,
prefix
:=
range
systemBlockFilterPrefixes
{
if
strings
.
HasPrefix
(
text
,
prefix
)
{
return
""
}
}
return
text
}
// buildSystemInstruction 构建 systemInstruction(与 Antigravity-Manager 保持一致)
// buildSystemInstruction 构建 systemInstruction(与 Antigravity-Manager 保持一致)
func
buildSystemInstruction
(
system
json
.
RawMessage
,
modelName
string
,
opts
TransformOptions
,
tools
[]
ClaudeTool
)
*
GeminiContent
{
func
buildSystemInstruction
(
system
json
.
RawMessage
,
modelName
string
,
opts
TransformOptions
,
tools
[]
ClaudeTool
)
*
GeminiContent
{
var
parts
[]
GeminiPart
var
parts
[]
GeminiPart
...
@@ -287,8 +302,8 @@ func buildSystemInstruction(system json.RawMessage, modelName string, opts Trans
...
@@ -287,8 +302,8 @@ func buildSystemInstruction(system json.RawMessage, modelName string, opts Trans
if
strings
.
Contains
(
sysStr
,
"You are Antigravity"
)
{
if
strings
.
Contains
(
sysStr
,
"You are Antigravity"
)
{
userHasAntigravityIdentity
=
true
userHasAntigravityIdentity
=
true
}
}
// 过滤 OpenCode 默认提示词
// 过滤 OpenCode 默认提示词
和黑名单前缀
filtered
:=
filterOpenCodePrompt
(
sysStr
)
filtered
:=
filterSystemBlockByPrefix
(
filterOpenCodePrompt
(
sysStr
)
)
if
filtered
!=
""
{
if
filtered
!=
""
{
userSystemParts
=
append
(
userSystemParts
,
GeminiPart
{
Text
:
filtered
})
userSystemParts
=
append
(
userSystemParts
,
GeminiPart
{
Text
:
filtered
})
}
}
...
@@ -302,8 +317,8 @@ func buildSystemInstruction(system json.RawMessage, modelName string, opts Trans
...
@@ -302,8 +317,8 @@ func buildSystemInstruction(system json.RawMessage, modelName string, opts Trans
if
strings
.
Contains
(
block
.
Text
,
"You are Antigravity"
)
{
if
strings
.
Contains
(
block
.
Text
,
"You are Antigravity"
)
{
userHasAntigravityIdentity
=
true
userHasAntigravityIdentity
=
true
}
}
// 过滤 OpenCode 默认提示词
// 过滤 OpenCode 默认提示词
和黑名单前缀
filtered
:=
filterOpenCodePrompt
(
block
.
Text
)
filtered
:=
filterSystemBlockByPrefix
(
filterOpenCodePrompt
(
block
.
Text
)
)
if
filtered
!=
""
{
if
filtered
!=
""
{
userSystemParts
=
append
(
userSystemParts
,
GeminiPart
{
Text
:
filtered
})
userSystemParts
=
append
(
userSystemParts
,
GeminiPart
{
Text
:
filtered
})
}
}
...
...
backend/internal/service/antigravity_gateway_service.go
View file @
5dd83d3c
...
@@ -48,10 +48,6 @@ const (
...
@@ -48,10 +48,6 @@ const (
googleRPCReasonModelCapacityExhausted
=
"MODEL_CAPACITY_EXHAUSTED"
googleRPCReasonModelCapacityExhausted
=
"MODEL_CAPACITY_EXHAUSTED"
googleRPCReasonRateLimitExceeded
=
"RATE_LIMIT_EXCEEDED"
googleRPCReasonRateLimitExceeded
=
"RATE_LIMIT_EXCEEDED"
// 单账号 503 退避重试:预检查中等待模型限流过期的最大时间
// 超过此值的限流将直接切换账号(避免请求等待过久)
antigravitySingleAccountMaxWait
=
30
*
time
.
Second
// 单账号 503 退避重试:Service 层原地重试的最大次数
// 单账号 503 退避重试:Service 层原地重试的最大次数
// 在 handleSmartRetry 中,对于 shouldRateLimitModel(长延迟 ≥ 7s)的情况,
// 在 handleSmartRetry 中,对于 shouldRateLimitModel(长延迟 ≥ 7s)的情况,
// 多账号模式下会设限流+切换账号;但单账号模式下改为原地等待+重试。
// 多账号模式下会设限流+切换账号;但单账号模式下改为原地等待+重试。
...
...
backend/internal/service/antigravity_single_account_retry_test.go
View file @
5dd83d3c
...
@@ -57,8 +57,6 @@ func TestSingleAccountRetryConstants(t *testing.T) {
...
@@ -57,8 +57,6 @@ func TestSingleAccountRetryConstants(t *testing.T) {
"单次最大等待 15s"
)
"单次最大等待 15s"
)
require
.
Equal
(
t
,
30
*
time
.
Second
,
antigravitySingleAccountSmartRetryTotalMaxWait
,
require
.
Equal
(
t
,
30
*
time
.
Second
,
antigravitySingleAccountSmartRetryTotalMaxWait
,
"总累计等待不超过 30s"
)
"总累计等待不超过 30s"
)
require
.
Equal
(
t
,
30
*
time
.
Second
,
antigravitySingleAccountMaxWait
,
"预检查最大等待 30s"
)
}
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
...
...
backend/internal/service/gateway_service.go
View file @
5dd83d3c
...
@@ -243,6 +243,12 @@ var (
...
@@ -243,6 +243,12 @@ var (
}
}
)
)
// systemBlockFilterPrefixes 需要从 system 中过滤的文本前缀列表
// OAuth/SetupToken 账号转发时,匹配这些前缀的 system 元素会被移除
var
systemBlockFilterPrefixes
=
[]
string
{
"x-anthropic-billing-header"
,
}
// ErrClaudeCodeOnly 表示分组仅允许 Claude Code 客户端访问
// ErrClaudeCodeOnly 表示分组仅允许 Claude Code 客户端访问
var
ErrClaudeCodeOnly
=
errors
.
New
(
"this group only allows Claude Code clients"
)
var
ErrClaudeCodeOnly
=
errors
.
New
(
"this group only allows Claude Code clients"
)
...
@@ -2684,6 +2690,60 @@ func hasClaudeCodePrefix(text string) bool {
...
@@ -2684,6 +2690,60 @@ func hasClaudeCodePrefix(text string) bool {
return
false
return
false
}
}
// matchesFilterPrefix 检查文本是否匹配任一过滤前缀
func
matchesFilterPrefix
(
text
string
)
bool
{
for
_
,
prefix
:=
range
systemBlockFilterPrefixes
{
if
strings
.
HasPrefix
(
text
,
prefix
)
{
return
true
}
}
return
false
}
// filterSystemBlocksByPrefix 从 body 的 system 中移除文本匹配 systemBlockFilterPrefixes 前缀的元素
// 直接从 body 解析 system,不依赖外部传入的 parsed.System(因为前置步骤可能已修改 body 中的 system)
func
filterSystemBlocksByPrefix
(
body
[]
byte
)
[]
byte
{
sys
:=
gjson
.
GetBytes
(
body
,
"system"
)
if
!
sys
.
Exists
()
{
return
body
}
switch
{
case
sys
.
Type
==
gjson
.
String
:
if
matchesFilterPrefix
(
sys
.
Str
)
{
result
,
err
:=
sjson
.
DeleteBytes
(
body
,
"system"
)
if
err
!=
nil
{
return
body
}
return
result
}
case
sys
.
IsArray
()
:
var
parsed
[]
any
if
err
:=
json
.
Unmarshal
([]
byte
(
sys
.
Raw
),
&
parsed
);
err
!=
nil
{
return
body
}
filtered
:=
make
([]
any
,
0
,
len
(
parsed
))
changed
:=
false
for
_
,
item
:=
range
parsed
{
if
m
,
ok
:=
item
.
(
map
[
string
]
any
);
ok
{
if
text
,
ok
:=
m
[
"text"
]
.
(
string
);
ok
&&
matchesFilterPrefix
(
text
)
{
changed
=
true
continue
}
}
filtered
=
append
(
filtered
,
item
)
}
if
changed
{
result
,
err
:=
sjson
.
SetBytes
(
body
,
"system"
,
filtered
)
if
err
!=
nil
{
return
body
}
return
result
}
}
return
body
}
// injectClaudeCodePrompt 在 system 开头注入 Claude Code 提示词
// injectClaudeCodePrompt 在 system 开头注入 Claude Code 提示词
// 处理 null、字符串、数组三种格式
// 处理 null、字符串、数组三种格式
func
injectClaudeCodePrompt
(
body
[]
byte
,
system
any
)
[]
byte
{
func
injectClaudeCodePrompt
(
body
[]
byte
,
system
any
)
[]
byte
{
...
@@ -2963,6 +3023,12 @@ func (s *GatewayService) Forward(ctx context.Context, c *gin.Context, account *A
...
@@ -2963,6 +3023,12 @@ func (s *GatewayService) Forward(ctx context.Context, c *gin.Context, account *A
body
,
reqModel
=
normalizeClaudeOAuthRequestBody
(
body
,
reqModel
,
normalizeOpts
)
body
,
reqModel
=
normalizeClaudeOAuthRequestBody
(
body
,
reqModel
,
normalizeOpts
)
}
}
// OAuth/SetupToken 账号:移除黑名单前缀匹配的 system 元素(如客户端注入的计费元数据)
// 放在 inject/normalize 之后,确保不会被覆盖
if
account
.
IsOAuth
()
{
body
=
filterSystemBlocksByPrefix
(
body
)
}
// 强制执行 cache_control 块数量限制(最多 4 个)
// 强制执行 cache_control 块数量限制(最多 4 个)
body
=
enforceCacheControlLimit
(
body
)
body
=
enforceCacheControlLimit
(
body
)
...
...
frontend/package.json
View file @
5dd83d3c
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
"dependencies"
:
{
"dependencies"
:
{
"@lobehub/icons"
:
"^4.0.2"
,
"@lobehub/icons"
:
"^4.0.2"
,
"@vueuse/core"
:
"^10.7.0"
,
"@vueuse/core"
:
"^10.7.0"
,
"axios"
:
"^1.
6.2
"
,
"axios"
:
"^1.
13.5
"
,
"chart.js"
:
"^4.4.1"
,
"chart.js"
:
"^4.4.1"
,
"dompurify"
:
"^3.3.1"
,
"dompurify"
:
"^3.3.1"
,
"driver.js"
:
"^1.4.0"
,
"driver.js"
:
"^1.4.0"
,
...
...
frontend/pnpm-lock.yaml
View file @
5dd83d3c
...
@@ -15,8 +15,8 @@ importers:
...
@@ -15,8 +15,8 @@ importers:
specifier
:
^10.7.0
specifier
:
^10.7.0
version
:
10.11.1(vue@3.5.26(typescript@5.6.3))
version
:
10.11.1(vue@3.5.26(typescript@5.6.3))
axios
:
axios
:
specifier
:
^1.
6.2
specifier
:
^1.
13.5
version
:
1.13.
2
version
:
1.13.
5
chart.js
:
chart.js
:
specifier
:
^4.4.1
specifier
:
^4.4.1
version
:
4.5.1
version
:
4.5.1
...
@@ -1257,56 +1257,67 @@ packages:
...
@@ -1257,56 +1257,67 @@ packages:
resolution
:
{
integrity
:
sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==
}
resolution
:
{
integrity
:
sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==
}
cpu
:
[
arm
]
cpu
:
[
arm
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
glibc
]
'
@rollup/rollup-linux-arm-musleabihf@4.54.0'
:
'
@rollup/rollup-linux-arm-musleabihf@4.54.0'
:
resolution
:
{
integrity
:
sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==
}
resolution
:
{
integrity
:
sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==
}
cpu
:
[
arm
]
cpu
:
[
arm
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
musl
]
'
@rollup/rollup-linux-arm64-gnu@4.54.0'
:
'
@rollup/rollup-linux-arm64-gnu@4.54.0'
:
resolution
:
{
integrity
:
sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==
}
resolution
:
{
integrity
:
sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==
}
cpu
:
[
arm64
]
cpu
:
[
arm64
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
glibc
]
'
@rollup/rollup-linux-arm64-musl@4.54.0'
:
'
@rollup/rollup-linux-arm64-musl@4.54.0'
:
resolution
:
{
integrity
:
sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==
}
resolution
:
{
integrity
:
sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==
}
cpu
:
[
arm64
]
cpu
:
[
arm64
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
musl
]
'
@rollup/rollup-linux-loong64-gnu@4.54.0'
:
'
@rollup/rollup-linux-loong64-gnu@4.54.0'
:
resolution
:
{
integrity
:
sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==
}
resolution
:
{
integrity
:
sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==
}
cpu
:
[
loong64
]
cpu
:
[
loong64
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
glibc
]
'
@rollup/rollup-linux-ppc64-gnu@4.54.0'
:
'
@rollup/rollup-linux-ppc64-gnu@4.54.0'
:
resolution
:
{
integrity
:
sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==
}
resolution
:
{
integrity
:
sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==
}
cpu
:
[
ppc64
]
cpu
:
[
ppc64
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
glibc
]
'
@rollup/rollup-linux-riscv64-gnu@4.54.0'
:
'
@rollup/rollup-linux-riscv64-gnu@4.54.0'
:
resolution
:
{
integrity
:
sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==
}
resolution
:
{
integrity
:
sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==
}
cpu
:
[
riscv64
]
cpu
:
[
riscv64
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
glibc
]
'
@rollup/rollup-linux-riscv64-musl@4.54.0'
:
'
@rollup/rollup-linux-riscv64-musl@4.54.0'
:
resolution
:
{
integrity
:
sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==
}
resolution
:
{
integrity
:
sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==
}
cpu
:
[
riscv64
]
cpu
:
[
riscv64
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
musl
]
'
@rollup/rollup-linux-s390x-gnu@4.54.0'
:
'
@rollup/rollup-linux-s390x-gnu@4.54.0'
:
resolution
:
{
integrity
:
sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==
}
resolution
:
{
integrity
:
sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==
}
cpu
:
[
s390x
]
cpu
:
[
s390x
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
glibc
]
'
@rollup/rollup-linux-x64-gnu@4.54.0'
:
'
@rollup/rollup-linux-x64-gnu@4.54.0'
:
resolution
:
{
integrity
:
sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==
}
resolution
:
{
integrity
:
sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==
}
cpu
:
[
x64
]
cpu
:
[
x64
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
glibc
]
'
@rollup/rollup-linux-x64-musl@4.54.0'
:
'
@rollup/rollup-linux-x64-musl@4.54.0'
:
resolution
:
{
integrity
:
sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==
}
resolution
:
{
integrity
:
sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==
}
cpu
:
[
x64
]
cpu
:
[
x64
]
os
:
[
linux
]
os
:
[
linux
]
libc
:
[
musl
]
'
@rollup/rollup-openharmony-arm64@4.54.0'
:
'
@rollup/rollup-openharmony-arm64@4.54.0'
:
resolution
:
{
integrity
:
sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==
}
resolution
:
{
integrity
:
sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==
}
...
@@ -1805,8 +1816,8 @@ packages:
...
@@ -1805,8 +1816,8 @@ packages:
peerDependencies
:
peerDependencies
:
postcss
:
^8.1.0
postcss
:
^8.1.0
axios@1.13.
2
:
axios@1.13.
5
:
resolution
:
{
integrity
:
sha512-
VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA
==
}
resolution
:
{
integrity
:
sha512-
cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q
==
}
babel-plugin-macros@3.1.0
:
babel-plugin-macros@3.1.0
:
resolution
:
{
integrity
:
sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==
}
resolution
:
{
integrity
:
sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==
}
...
@@ -6387,7 +6398,7 @@ snapshots:
...
@@ -6387,7 +6398,7 @@ snapshots:
postcss
:
8.5.6
postcss
:
8.5.6
postcss-value-parser
:
4.2.0
postcss-value-parser
:
4.2.0
axios@1.13.
2
:
axios@1.13.
5
:
dependencies
:
dependencies
:
follow-redirects
:
1.15.11
follow-redirects
:
1.15.11
form-data
:
4.0.5
form-data
:
4.0.5
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment