mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
- 删除全部 Python 源码 (src/) 及 Alembic 迁移脚本,归档至 _deprecated_py_src/ - 重构 Rust gateway ai_pipeline: 拆分 planner/finalize 模块,新增 contracts/adaptation 层 - 重组 handlers 模块为 admin/public/proxy/internal/shared 子模块结构 - 新增 executor 模块,引入 Rust 原生数据库迁移 (aether-data/migrations) - 简化 CI/Docker 构建流程,移除 base image 二级构建,统一为单一 app image - 移除 Python 相关基础设施文件 (entrypoint.sh, gunicorn_conf.py, Dockerfile.base)
280 lines
8.4 KiB
Python
280 lines
8.4 KiB
Python
"""Antigravity 全局常量定义。
|
||
|
||
注意:这里的 PROVIDER_TYPE 指的是 Provider.provider_type(用于路由与特判),
|
||
不是 endpoint signature(family:kind)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import platform
|
||
import re
|
||
import threading
|
||
import uuid
|
||
|
||
# ============== API 端点 ==============
|
||
# 唯一定义在 core 层,此处 re-export 保持向后兼容
|
||
from src.core.provider_templates.fixed_providers import ANTIGRAVITY_PROD_URL as PROD_BASE_URL
|
||
|
||
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"
|
||
_FALLBACK_VERSION = "1.18.4"
|
||
_FALLBACK_CHROME = "132.0.6834.160"
|
||
_FALLBACK_ELECTRON = "39.2.3"
|
||
_VERSION_RE = re.compile(r"\d+\.\d+\.\d+")
|
||
|
||
|
||
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"
|
||
|
||
|
||
_PLATFORM_INFO = _detect_platform_info()
|
||
|
||
|
||
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"
|
||
)
|
||
|
||
|
||
# HTTP Header User-Agent(对齐 AM constants.rs: 完整 Electron 浏览器格式)
|
||
HTTP_USER_AGENT = _build_antigravity_http_user_agent(
|
||
platform_token=_PLATFORM_INFO,
|
||
version=_FALLBACK_VERSION,
|
||
chrome_version=_FALLBACK_CHROME,
|
||
electron_version=_FALLBACK_ELECTRON,
|
||
)
|
||
|
||
# V1InternalRequest.userAgent 字段(固定值)
|
||
REQUEST_USER_AGENT = "antigravity"
|
||
|
||
# --- 动态 User-Agent 支持 ---
|
||
_ua_lock = threading.Lock()
|
||
_ua_version: str = _FALLBACK_VERSION
|
||
|
||
|
||
def get_http_user_agent() -> str:
|
||
"""返回当前 HTTP User-Agent 字符串(对齐 AM Electron UA 格式)。"""
|
||
with _ua_lock:
|
||
return _build_antigravity_http_user_agent(
|
||
platform_token=_PLATFORM_INFO,
|
||
version=_ua_version,
|
||
chrome_version=_FALLBACK_CHROME,
|
||
electron_version=_FALLBACK_ELECTRON,
|
||
)
|
||
|
||
|
||
def update_user_agent_version(version: str) -> None:
|
||
"""更新 User-Agent 中的版本号(由 refresh_user_agent 调用)。"""
|
||
global HTTP_USER_AGENT, _ua_version # noqa: PLW0603
|
||
version = str(version or "").strip()
|
||
if not version:
|
||
return
|
||
with _ua_lock:
|
||
_ua_version = version
|
||
HTTP_USER_AGENT = _build_antigravity_http_user_agent(
|
||
platform_token=_PLATFORM_INFO,
|
||
version=_ua_version,
|
||
chrome_version=_FALLBACK_CHROME,
|
||
electron_version=_FALLBACK_ELECTRON,
|
||
)
|
||
|
||
|
||
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 分钟
|
||
|
||
# ============== 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
|
||
|
||
return {
|
||
"User-Agent": get_http_user_agent(),
|
||
"x-client-name": "antigravity",
|
||
"x-client-version": version,
|
||
"x-vscode-sessionid": _SESSION_ID,
|
||
"x-goog-api-client": "gl-node/18.18.2 fire/0.8.6 grpc/1.10.x",
|
||
}
|
||
|
||
|
||
# ============== Thinking Signature ==============
|
||
# 统一从 core 层导入,避免多处定义
|
||
from src.core.api_format.conversion.constants import DUMMY_THOUGHT_SIGNATURE # noqa: E402
|
||
from src.core.api_format.conversion.thinking_cache import MIN_SIGNATURE_LENGTH # noqa: E402, F401
|
||
|
||
# ============== Thinking Budget ==============
|
||
THINKING_BUDGET_AUTO_CAP = 24576
|
||
THINKING_BUDGET_DEFAULT_INJECT = 24576 # 对齐 AM wrapper.rs (was 16000)
|
||
# 给输出留的空间(对齐 Antigravity-Manager:普通模型 8192,图像模型 2048)
|
||
OUTPUT_OVERHEAD = 8192
|
||
OUTPUT_OVERHEAD_IMAGE = 2048
|
||
# 模型最大输出限制(防止超限)
|
||
MODEL_MAX_OUTPUT_LIMIT = 65536
|
||
# 包含这些关键字的模型会自动注入 thinkingConfig(如果缺失)
|
||
THINKING_MODELS_AUTO_INJECT_KEYWORDS = (
|
||
"thinking",
|
||
"gemini-2.0-pro",
|
||
"gemini-3-pro",
|
||
"gemini-3.1-pro",
|
||
)
|
||
|
||
# ============== 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"),
|
||
)
|
||
|
||
# ============== 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",
|
||
"ASPECT_RATIO_TABLE",
|
||
"DAILY_BASE_URL",
|
||
"DUMMY_THOUGHT_SIGNATURE",
|
||
"HTTP_USER_AGENT",
|
||
"IMAGE_ASPECT_RATIO_SUFFIXES",
|
||
"IMAGE_GEN_UPSTREAM_MODEL",
|
||
"MIN_SIGNATURE_LENGTH",
|
||
"MODEL_MAX_OUTPUT_LIMIT",
|
||
"NETWORKING_TOOL_KEYWORDS",
|
||
"OUTPUT_OVERHEAD",
|
||
"OUTPUT_OVERHEAD_IMAGE",
|
||
"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",
|
||
"STANDARD_ASPECT_RATIOS",
|
||
"THINKING_BUDGET_AUTO_CAP",
|
||
"THINKING_BUDGET_DEFAULT_INJECT",
|
||
"THINKING_MODELS_AUTO_INJECT_KEYWORDS",
|
||
"URL_UNAVAILABLE_TTL_SECONDS",
|
||
"V1INTERNAL_PATH_TEMPLATE",
|
||
"VERSION_FETCH_URL",
|
||
"WEB_SEARCH_MODEL",
|
||
"get_http_user_agent",
|
||
"get_v1internal_extra_headers",
|
||
"parse_version_string",
|
||
"update_user_agent_version",
|
||
]
|