feat: 完善 Antigravity OAuth 功能与权限校验

新增功能:
- 实现 Antigravity OAuth 账户支持与路径分流
- 支持 /antigravity/api 路径自动分流到 Antigravity OAuth 账户
- 支持 gemini-antigravity 平台类型的账户创建和管理

修复问题:
- 修复 OAuthFlow 组件中 gemini-antigravity 平台授权页面空白的问题
- 修复 EditApiKeyModal 中 Redis 返回字符串格式 permissions 导致的 400 错误
- 统一使用 hasPermission 函数进行权限校验,支持数组格式

优化改进:
- 添加 Antigravity 调试环境变量说明
This commit is contained in:
52227
2025-12-29 14:23:43 +08:00
parent 3f98267738
commit c67d2bce9d
6 changed files with 58 additions and 61 deletions

View File

@@ -21,7 +21,10 @@ const SYSTEM_REMINDER_PREFIX = '<system-reminder>'
const TOOLS_DUMP_ENV = 'ANTHROPIC_DEBUG_TOOLS_DUMP'
const TOOLS_DUMP_FILENAME = 'anthropic-tools-dump.jsonl'
const TEXT_TOOL_FALLBACK_ENV = 'ANTHROPIC_TEXT_TOOL_FALLBACK'
const TOOL_ERROR_CONTINUE_ENV = 'ANTHROPIC_TOOL_ERROR_CONTINUE'
const THOUGHT_SIGNATURE_FALLBACK = 'skip_thought_signature_validator'
const TOOL_ERROR_CONTINUE_PROMPT =
'Tool calls may fail (e.g., missing prerequisites). When a tool result indicates an error, do not stop: briefly explain the cause and continue with an alternative approach or the remaining steps.'
function ensureAntigravityProjectId(account) {
if (account.projectId) {
@@ -710,12 +713,13 @@ function convertAnthropicMessagesToGeminiContents(
if (vendor === 'antigravity') {
const toolCallId = typeof toolUseId === 'string' && toolUseId ? toolUseId : undefined
const result = parsedResponse !== null ? parsedResponse : raw || ''
const response = part.is_error === true ? { result, is_error: true } : { result }
parts.push({
functionResponse: {
...(toolCallId ? { id: toolCallId } : {}),
name: toolName,
response: { result }
response
}
})
} else {
@@ -761,6 +765,10 @@ function buildGeminiRequestFromAnthropic(body, baseModel, { vendor = null } = {}
)
const systemParts = buildSystemParts(body.system)
if (vendor === 'antigravity' && isEnvEnabled(process.env[TOOL_ERROR_CONTINUE_ENV])) {
systemParts.push({ text: TOOL_ERROR_CONTINUE_PROMPT })
}
const temperature = typeof body.temperature === 'number' ? body.temperature : 1
const maxTokens = Number.isFinite(body.max_tokens) ? body.max_tokens : 4096