mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 21:17:30 +00:00
feat: 适配 Antigravity 账户余额查询与流式响应优化
1. Antigravity 账户适配: - 新增 GeminiBalanceProvider,支持 Antigravity 账户的额度查询(API 模式) - AccountBalanceService 增加 queryMode 逻辑与安全限制 - 前端 BalanceDisplay 适配 Antigravity 配额显示 2. 流式响应增强: - 优化 thoughtSignature 捕获与回填,支持思维链透传 - 修复工具调用签名校验 3. 其他: - 请求体大小限制提升至 100MB - .gitignore 更新
This commit is contained in:
@@ -941,6 +941,7 @@ function convertAnthropicMessagesToGeminiContents(
|
||||
|
||||
const content = message?.content
|
||||
const parts = []
|
||||
let lastAntigravityThoughtSignature = ''
|
||||
|
||||
if (typeof content === 'string') {
|
||||
const text = extractAnthropicText(content)
|
||||
@@ -985,6 +986,7 @@ function convertAnthropicMessagesToGeminiContents(
|
||||
continue
|
||||
}
|
||||
|
||||
lastAntigravityThoughtSignature = signature
|
||||
const thoughtPart = { thought: true, thoughtSignature: signature }
|
||||
if (hasThinkingText) {
|
||||
thoughtPart.text = thinkingText
|
||||
@@ -1013,13 +1015,19 @@ function convertAnthropicMessagesToGeminiContents(
|
||||
if (part.name) {
|
||||
const toolCallId = typeof part.id === 'string' && part.id ? part.id : undefined
|
||||
const args = normalizeToolUseInput(part.input)
|
||||
parts.push({
|
||||
functionCall: {
|
||||
...(vendor === 'antigravity' && toolCallId ? { id: toolCallId } : {}),
|
||||
name: part.name,
|
||||
args
|
||||
}
|
||||
})
|
||||
const functionCall = {
|
||||
...(vendor === 'antigravity' && toolCallId ? { id: toolCallId } : {}),
|
||||
name: part.name,
|
||||
args
|
||||
}
|
||||
|
||||
// Antigravity 对历史工具调用的 functionCall 会校验 thoughtSignature;
|
||||
// Claude Code 侧的签名存放在 thinking block(part.signature),这里需要回填到 functionCall part 上。
|
||||
if (vendor === 'antigravity' && lastAntigravityThoughtSignature) {
|
||||
parts.push({ thoughtSignature: lastAntigravityThoughtSignature, functionCall })
|
||||
} else {
|
||||
parts.push({ functionCall })
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
@@ -2435,6 +2443,47 @@ async function handleAnthropicMessagesToGemini(req, res, { vendor, baseModel })
|
||||
|
||||
const parts = extractGeminiParts(payload)
|
||||
const thoughtSignature = extractGeminiThoughtSignature(payload)
|
||||
const fullThoughtForToolOrdering = extractGeminiThoughtText(payload)
|
||||
|
||||
if (wantsThinkingBlockFirst) {
|
||||
// 关键:确保 thinking/signature 在 tool_use 之前输出,避免出现 tool_use 后紧跟 thinking(signature)
|
||||
// 导致下一轮请求的 thinking 校验/工具调用校验失败(Antigravity 会返回 400)。
|
||||
if (thoughtSignature && canStartThinkingBlock()) {
|
||||
let delta = ''
|
||||
if (thoughtSignature.startsWith(emittedThoughtSignature)) {
|
||||
delta = thoughtSignature.slice(emittedThoughtSignature.length)
|
||||
} else if (thoughtSignature !== emittedThoughtSignature) {
|
||||
delta = thoughtSignature
|
||||
}
|
||||
if (delta) {
|
||||
switchBlockType('thinking')
|
||||
writeAnthropicSseEvent(res, 'content_block_delta', {
|
||||
type: 'content_block_delta',
|
||||
index: currentIndex,
|
||||
delta: { type: 'signature_delta', signature: delta }
|
||||
})
|
||||
emittedThoughtSignature = thoughtSignature
|
||||
}
|
||||
}
|
||||
|
||||
if (fullThoughtForToolOrdering && canStartThinkingBlock()) {
|
||||
let delta = ''
|
||||
if (fullThoughtForToolOrdering.startsWith(emittedThinking)) {
|
||||
delta = fullThoughtForToolOrdering.slice(emittedThinking.length)
|
||||
} else {
|
||||
delta = fullThoughtForToolOrdering
|
||||
}
|
||||
if (delta) {
|
||||
switchBlockType('thinking')
|
||||
emittedThinking = fullThoughtForToolOrdering
|
||||
writeAnthropicSseEvent(res, 'content_block_delta', {
|
||||
type: 'content_block_delta',
|
||||
index: currentIndex,
|
||||
delta: { type: 'thinking_delta', thinking: delta }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const part of parts) {
|
||||
const functionCall = part?.functionCall
|
||||
if (!functionCall?.name) {
|
||||
|
||||
Reference in New Issue
Block a user