2026-02-06 16:37:06 +08:00
|
|
|
|
"""Antigravity 全局常量定义。
|
|
|
|
|
|
|
|
|
|
|
|
注意:这里的 PROVIDER_TYPE 指的是 Provider.provider_type(用于路由与特判),
|
|
|
|
|
|
不是 endpoint signature(family:kind)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
import platform
|
|
|
|
|
|
import re
|
|
|
|
|
|
import threading
|
2026-02-24 01:52:53 +08:00
|
|
|
|
import uuid
|
2026-02-06 16:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
# ============== API 端点 ==============
|
2026-02-16 11:00:48 +08:00
|
|
|
|
# 唯一定义在 core 层,此处 re-export 保持向后兼容
|
|
|
|
|
|
from src.core.provider_templates.fixed_providers import ANTIGRAVITY_PROD_URL as PROD_BASE_URL
|
|
|
|
|
|
|
2026-02-06 16:37:06 +08:00
|
|
|
|
DAILY_BASE_URL = "https://daily-cloudcode-pa.googleapis.com"
|
|
|
|
|
|
SANDBOX_BASE_URL = "https://daily-cloudcode-pa.sandbox.googleapis.com"
|
|
|
|
|
|
|
|
|
|
|
|
# ============== User-Agent ==============
|
|
|
|
|
|
VERSION_FETCH_URL = "https://antigravity-auto-updater-974169037036.us-central1.run.app"
|
2026-02-24 01:52:53 +08:00
|
|
|
|
_FALLBACK_VERSION = "1.18.4"
|
|
|
|
|
|
_FALLBACK_CHROME = "132.0.6834.160"
|
|
|
|
|
|
_FALLBACK_ELECTRON = "39.2.3"
|
2026-02-06 16:37:06 +08:00
|
|
|
|
_VERSION_RE = re.compile(r"\d+\.\d+\.\d+")
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-24 01:52:53 +08:00
|
|
|
|
def _detect_platform_info() -> str:
|
|
|
|
|
|
"""检测当前运行平台,格式对齐 AM constants.rs 的 Electron UA。"""
|
|
|
|
|
|
os_name = platform.system().lower()
|
|
|
|
|
|
if os_name == "darwin":
|
|
|
|
|
|
return "Macintosh; Intel Mac OS X 10_15_7"
|
|
|
|
|
|
elif os_name == "windows":
|
|
|
|
|
|
return "Windows NT 10.0; Win64; x64"
|
|
|
|
|
|
else:
|
|
|
|
|
|
return "X11; Linux x86_64"
|
2026-02-06 16:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
2026-02-24 01:52:53 +08:00
|
|
|
|
_PLATFORM_INFO = _detect_platform_info()
|
2026-02-06 16:37:06 +08:00
|
|
|
|
|
2026-03-05 02:07:34 +08:00
|
|
|
|
|
|
|
|
|
|
def _build_antigravity_http_user_agent(
|
|
|
|
|
|
*,
|
|
|
|
|
|
platform_token: str,
|
|
|
|
|
|
version: str,
|
|
|
|
|
|
chrome_version: str,
|
|
|
|
|
|
electron_version: str,
|
|
|
|
|
|
) -> str:
|
|
|
|
|
|
return (
|
|
|
|
|
|
f"Mozilla/5.0 ({platform_token}) AppleWebKit/537.36 (KHTML, like Gecko) "
|
|
|
|
|
|
f"Antigravity/{version} Chrome/{chrome_version} "
|
|
|
|
|
|
f"Electron/{electron_version} Safari/537.36"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-24 01:52:53 +08:00
|
|
|
|
# HTTP Header User-Agent(对齐 AM constants.rs: 完整 Electron 浏览器格式)
|
2026-03-05 02:07:34 +08:00
|
|
|
|
HTTP_USER_AGENT = _build_antigravity_http_user_agent(
|
|
|
|
|
|
platform_token=_PLATFORM_INFO,
|
|
|
|
|
|
version=_FALLBACK_VERSION,
|
|
|
|
|
|
chrome_version=_FALLBACK_CHROME,
|
|
|
|
|
|
electron_version=_FALLBACK_ELECTRON,
|
2026-02-24 01:52:53 +08:00
|
|
|
|
)
|
2026-02-06 16:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
# V1InternalRequest.userAgent 字段(固定值)
|
|
|
|
|
|
REQUEST_USER_AGENT = "antigravity"
|
|
|
|
|
|
|
|
|
|
|
|
# --- 动态 User-Agent 支持 ---
|
|
|
|
|
|
_ua_lock = threading.Lock()
|
|
|
|
|
|
_ua_version: str = _FALLBACK_VERSION
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_http_user_agent() -> str:
|
2026-02-24 01:52:53 +08:00
|
|
|
|
"""返回当前 HTTP User-Agent 字符串(对齐 AM Electron UA 格式)。"""
|
2026-02-06 16:37:06 +08:00
|
|
|
|
with _ua_lock:
|
2026-03-05 02:07:34 +08:00
|
|
|
|
return _build_antigravity_http_user_agent(
|
|
|
|
|
|
platform_token=_PLATFORM_INFO,
|
|
|
|
|
|
version=_ua_version,
|
|
|
|
|
|
chrome_version=_FALLBACK_CHROME,
|
|
|
|
|
|
electron_version=_FALLBACK_ELECTRON,
|
2026-02-24 01:52:53 +08:00
|
|
|
|
)
|
2026-02-06 16:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_user_agent_version(version: str) -> None:
|
|
|
|
|
|
"""更新 User-Agent 中的版本号(由 refresh_user_agent 调用)。"""
|
2026-02-10 17:53:04 +08:00
|
|
|
|
global HTTP_USER_AGENT, _ua_version # noqa: PLW0603
|
|
|
|
|
|
version = str(version or "").strip()
|
|
|
|
|
|
if not version:
|
|
|
|
|
|
return
|
2026-02-06 16:37:06 +08:00
|
|
|
|
with _ua_lock:
|
|
|
|
|
|
_ua_version = version
|
2026-03-05 02:07:34 +08:00
|
|
|
|
HTTP_USER_AGENT = _build_antigravity_http_user_agent(
|
|
|
|
|
|
platform_token=_PLATFORM_INFO,
|
|
|
|
|
|
version=_ua_version,
|
|
|
|
|
|
chrome_version=_FALLBACK_CHROME,
|
|
|
|
|
|
electron_version=_FALLBACK_ELECTRON,
|
2026-02-24 01:52:53 +08:00
|
|
|
|
)
|
2026-02-06 16:37:06 +08:00
|
|
|
|
|
2026-02-14 12:55:58 +08:00
|
|
|
|
|
2026-02-06 16:37:06 +08:00
|
|
|
|
def parse_version_string(text: str) -> str | None:
|
|
|
|
|
|
"""从任意文本中提取 X.Y.Z 格式的版本号。"""
|
|
|
|
|
|
m = _VERSION_RE.search(text)
|
|
|
|
|
|
return m.group(0) if m else None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ============== URL 可用性 ==============
|
|
|
|
|
|
URL_UNAVAILABLE_TTL_SECONDS = 300 # 5 分钟
|
|
|
|
|
|
|
2026-02-24 01:52:53 +08:00
|
|
|
|
# ============== AM Client Identity Headers ==============
|
|
|
|
|
|
# 对齐 AM upstream/client.rs: 伪装为官方 Antigravity 客户端
|
|
|
|
|
|
# 缺少这些 header 会导致新模型(如 gemini-3.1-pro-preview)返回 404
|
|
|
|
|
|
_SESSION_ID = uuid.uuid4().hex # 每次进程启动生成一个固定 session ID
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_v1internal_extra_headers() -> dict[str, str]:
|
|
|
|
|
|
"""构建 v1internal 请求需要的额外 header(对齐 AM upstream/client.rs)。"""
|
|
|
|
|
|
with _ua_lock:
|
|
|
|
|
|
version = _ua_version
|
2026-03-05 02:07:34 +08:00
|
|
|
|
|
2026-02-24 01:52:53 +08:00
|
|
|
|
return {
|
2026-03-05 10:24:52 +08:00
|
|
|
|
"User-Agent": get_http_user_agent(),
|
2026-02-24 01:52:53 +08:00
|
|
|
|
"x-client-name": "antigravity",
|
|
|
|
|
|
"x-client-version": version,
|
2026-03-05 10:24:52 +08:00
|
|
|
|
"x-vscode-sessionid": _SESSION_ID,
|
|
|
|
|
|
"x-goog-api-client": "gl-node/18.18.2 fire/0.8.6 grpc/1.10.x",
|
2026-02-24 01:52:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-06 16:37:06 +08:00
|
|
|
|
# ============== Thinking Signature ==============
|
2026-02-14 12:55:58 +08:00
|
|
|
|
# 统一从 core 层导入,避免多处定义
|
|
|
|
|
|
from src.core.api_format.conversion.constants import DUMMY_THOUGHT_SIGNATURE # noqa: E402
|
2026-02-16 11:00:48 +08:00
|
|
|
|
from src.core.api_format.conversion.thinking_cache import MIN_SIGNATURE_LENGTH # noqa: E402, F401
|
2026-02-06 16:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
# ============== Thinking Budget ==============
|
|
|
|
|
|
THINKING_BUDGET_AUTO_CAP = 24576
|
2026-02-10 02:05:35 +08:00
|
|
|
|
THINKING_BUDGET_DEFAULT_INJECT = 24576 # 对齐 AM wrapper.rs (was 16000)
|
2026-02-10 05:12:21 +08:00
|
|
|
|
# 给输出留的空间(对齐 Antigravity-Manager:普通模型 8192,图像模型 2048)
|
|
|
|
|
|
OUTPUT_OVERHEAD = 8192
|
|
|
|
|
|
OUTPUT_OVERHEAD_IMAGE = 2048
|
|
|
|
|
|
# 模型最大输出限制(防止超限)
|
|
|
|
|
|
MODEL_MAX_OUTPUT_LIMIT = 65536
|
2026-02-06 16:37:06 +08:00
|
|
|
|
# 包含这些关键字的模型会自动注入 thinkingConfig(如果缺失)
|
2026-02-24 01:52:53 +08:00
|
|
|
|
THINKING_MODELS_AUTO_INJECT_KEYWORDS = (
|
|
|
|
|
|
"thinking",
|
|
|
|
|
|
"gemini-2.0-pro",
|
|
|
|
|
|
"gemini-3-pro",
|
|
|
|
|
|
"gemini-3.1-pro",
|
|
|
|
|
|
)
|
2026-02-10 02:05:35 +08:00
|
|
|
|
|
|
|
|
|
|
# ============== Google Search (Grounding) ==============
|
|
|
|
|
|
# 对齐 AM common_utils.rs: 仅 gemini-2.5-flash 支持 googleSearch tool
|
|
|
|
|
|
WEB_SEARCH_MODEL = "gemini-2.5-flash"
|
|
|
|
|
|
# 联网工具检测关键字(对齐 AM detects_networking_tool)
|
|
|
|
|
|
NETWORKING_TOOL_KEYWORDS = frozenset(
|
|
|
|
|
|
{
|
|
|
|
|
|
"web_search",
|
|
|
|
|
|
"google_search",
|
|
|
|
|
|
"web_search_20250305",
|
|
|
|
|
|
"google_search_retrieval",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# ============== Image Generation ==============
|
|
|
|
|
|
# 上游图像生成模型的固定名称
|
|
|
|
|
|
IMAGE_GEN_UPSTREAM_MODEL = "gemini-3-pro-image"
|
|
|
|
|
|
# 模型后缀 → 宽高比映射
|
|
|
|
|
|
IMAGE_ASPECT_RATIO_SUFFIXES: dict[str, str] = {
|
|
|
|
|
|
"-21x9": "21:9",
|
|
|
|
|
|
"-21-9": "21:9",
|
|
|
|
|
|
"-16x9": "16:9",
|
|
|
|
|
|
"-16-9": "16:9",
|
|
|
|
|
|
"-9x16": "9:16",
|
|
|
|
|
|
"-9-16": "9:16",
|
|
|
|
|
|
"-4x3": "4:3",
|
|
|
|
|
|
"-4-3": "4:3",
|
|
|
|
|
|
"-3x4": "3:4",
|
|
|
|
|
|
"-3-4": "3:4",
|
|
|
|
|
|
"-3x2": "3:2",
|
|
|
|
|
|
"-3-2": "3:2",
|
|
|
|
|
|
"-2x3": "2:3",
|
|
|
|
|
|
"-2-3": "2:3",
|
|
|
|
|
|
"-5x4": "5:4",
|
|
|
|
|
|
"-5-4": "5:4",
|
|
|
|
|
|
"-4x5": "4:5",
|
|
|
|
|
|
"-4-5": "4:5",
|
|
|
|
|
|
"-1x1": "1:1",
|
|
|
|
|
|
"-1-1": "1:1",
|
|
|
|
|
|
}
|
|
|
|
|
|
# 标准宽高比字符串(用于直接匹配 size 参数)
|
|
|
|
|
|
STANDARD_ASPECT_RATIOS = frozenset(
|
|
|
|
|
|
{
|
|
|
|
|
|
"21:9",
|
|
|
|
|
|
"16:9",
|
|
|
|
|
|
"9:16",
|
|
|
|
|
|
"4:3",
|
|
|
|
|
|
"3:4",
|
|
|
|
|
|
"3:2",
|
|
|
|
|
|
"2:3",
|
|
|
|
|
|
"5:4",
|
|
|
|
|
|
"4:5",
|
|
|
|
|
|
"1:1",
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
# 宽高比容差匹配表:(ratio, label)
|
|
|
|
|
|
ASPECT_RATIO_TABLE: tuple[tuple[float, str], ...] = (
|
|
|
|
|
|
(21.0 / 9.0, "21:9"),
|
|
|
|
|
|
(16.0 / 9.0, "16:9"),
|
|
|
|
|
|
(4.0 / 3.0, "4:3"),
|
|
|
|
|
|
(3.0 / 4.0, "3:4"),
|
|
|
|
|
|
(9.0 / 16.0, "9:16"),
|
|
|
|
|
|
(3.0 / 2.0, "3:2"),
|
|
|
|
|
|
(2.0 / 3.0, "2:3"),
|
|
|
|
|
|
(5.0 / 4.0, "5:4"),
|
|
|
|
|
|
(4.0 / 5.0, "4:5"),
|
|
|
|
|
|
(1.0, "1:1"),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-02-06 16:37:06 +08:00
|
|
|
|
# ============== Retry ==============
|
|
|
|
|
|
RETRY_429_BASE_SECONDS = 5.0
|
|
|
|
|
|
RETRY_503_BASE_SECONDS = 10.0
|
|
|
|
|
|
RETRY_503_MAX_SECONDS = 60.0
|
|
|
|
|
|
RETRY_500_BASE_SECONDS = 3.0
|
|
|
|
|
|
|
|
|
|
|
|
# ============== v1internal 路径 ==============
|
|
|
|
|
|
V1INTERNAL_PATH_TEMPLATE = "/v1internal:{action}"
|
|
|
|
|
|
|
|
|
|
|
|
# ============== Signature 错误关键字(用于 400 错误检测) ==============
|
|
|
|
|
|
SIGNATURE_ERROR_KEYWORDS = (
|
|
|
|
|
|
"Invalid `signature`",
|
|
|
|
|
|
"thinking.signature",
|
|
|
|
|
|
"thinking.thinking",
|
|
|
|
|
|
"Corrupted thought signature",
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# ============== Antigravity System Instruction ==============
|
|
|
|
|
|
ANTIGRAVITY_SYSTEM_INSTRUCTION = (
|
|
|
|
|
|
"You are Antigravity, a powerful agentic AI coding assistant designed by the "
|
|
|
|
|
|
"Google Deepmind team working on Advanced Agentic Coding.\n"
|
|
|
|
|
|
"You are pair programming with a USER to solve their coding task. The task may "
|
|
|
|
|
|
"require creating a new codebase, modifying or debugging an existing codebase, "
|
|
|
|
|
|
"or simply answering a question.\n"
|
|
|
|
|
|
"**Absolute paths only**\n"
|
|
|
|
|
|
"**Proactiveness**"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
__all__ = [
|
|
|
|
|
|
"ANTIGRAVITY_SYSTEM_INSTRUCTION",
|
2026-02-10 02:05:35 +08:00
|
|
|
|
"ASPECT_RATIO_TABLE",
|
2026-02-06 16:37:06 +08:00
|
|
|
|
"DAILY_BASE_URL",
|
|
|
|
|
|
"DUMMY_THOUGHT_SIGNATURE",
|
|
|
|
|
|
"HTTP_USER_AGENT",
|
2026-02-10 02:05:35 +08:00
|
|
|
|
"IMAGE_ASPECT_RATIO_SUFFIXES",
|
|
|
|
|
|
"IMAGE_GEN_UPSTREAM_MODEL",
|
2026-02-06 16:37:06 +08:00
|
|
|
|
"MIN_SIGNATURE_LENGTH",
|
2026-02-10 05:12:21 +08:00
|
|
|
|
"MODEL_MAX_OUTPUT_LIMIT",
|
2026-02-10 02:05:35 +08:00
|
|
|
|
"NETWORKING_TOOL_KEYWORDS",
|
2026-02-10 05:12:21 +08:00
|
|
|
|
"OUTPUT_OVERHEAD",
|
|
|
|
|
|
"OUTPUT_OVERHEAD_IMAGE",
|
2026-02-06 16:37:06 +08:00
|
|
|
|
"PROD_BASE_URL",
|
|
|
|
|
|
"REQUEST_USER_AGENT",
|
|
|
|
|
|
"RETRY_429_BASE_SECONDS",
|
|
|
|
|
|
"RETRY_500_BASE_SECONDS",
|
|
|
|
|
|
"RETRY_503_BASE_SECONDS",
|
|
|
|
|
|
"RETRY_503_MAX_SECONDS",
|
|
|
|
|
|
"SANDBOX_BASE_URL",
|
|
|
|
|
|
"SIGNATURE_ERROR_KEYWORDS",
|
2026-02-10 02:05:35 +08:00
|
|
|
|
"STANDARD_ASPECT_RATIOS",
|
2026-02-06 16:37:06 +08:00
|
|
|
|
"THINKING_BUDGET_AUTO_CAP",
|
|
|
|
|
|
"THINKING_BUDGET_DEFAULT_INJECT",
|
|
|
|
|
|
"THINKING_MODELS_AUTO_INJECT_KEYWORDS",
|
|
|
|
|
|
"URL_UNAVAILABLE_TTL_SECONDS",
|
|
|
|
|
|
"V1INTERNAL_PATH_TEMPLATE",
|
|
|
|
|
|
"VERSION_FETCH_URL",
|
2026-02-10 02:05:35 +08:00
|
|
|
|
"WEB_SEARCH_MODEL",
|
2026-02-06 16:37:06 +08:00
|
|
|
|
"get_http_user_agent",
|
2026-02-24 01:52:53 +08:00
|
|
|
|
"get_v1internal_extra_headers",
|
2026-02-06 16:37:06 +08:00
|
|
|
|
"parse_version_string",
|
|
|
|
|
|
"update_user_agent_version",
|
|
|
|
|
|
]
|