feat: Antigravity 端点签名迁移至 gemini:chat,流式 usage 提取重构与请求详情自动刷新

- Antigravity 端点签名从 gemini:cli 统一为 gemini:chat,保留向后兼容,含 DB 迁移
- 流式处理中 usage/completion/text 提取抽离为 _update_ctx_from_provider_event,
  支持 envelope 解包后提取,避免格式转换流程中重复计数
- 新增 has_format_conversion 属性,区分真正的格式转换与 envelope rewrite,
  修正 usage 展示层的格式转换标记
- 请求详情抽屉对未完成请求支持自动轮询刷新,关闭时自动停止
- 按次计费样式调整;实际成本仅在倍率非 1.0 时显示;缓存日志降级为 trace
This commit is contained in:
fawney19
2026-02-07 02:59:02 +08:00
parent ea22f07046
commit 62f852b851
24 changed files with 481 additions and 104 deletions

View File

@@ -62,7 +62,7 @@ def test_convert_sse_line_unwraps_before_convert_stream_chunk() -> None:
ctx = StreamContext(model="gemini-2.0-flash", api_format="gemini:cli")
ctx.provider_type = "antigravity"
ctx.provider_api_format = "gemini:cli"
ctx.provider_api_format = "gemini:chat"
ctx.client_api_format = "gemini:cli"
v1_line = (

View File

@@ -32,7 +32,7 @@ def test_antigravity_converts_claude_thinking_block_to_gemini_thought_part_prefe
}
registry = get_format_converter_registry()
out = registry.convert_request(req, "claude:chat", "gemini:cli", target_variant="antigravity")
out = registry.convert_request(req, "claude:chat", "gemini:chat", target_variant="antigravity")
assert isinstance(out.get("contents"), list)
model_turn = out["contents"][1]
@@ -63,7 +63,7 @@ def test_antigravity_uses_dummy_signature_for_gemini_when_missing() -> None:
}
registry = get_format_converter_registry()
out = registry.convert_request(req, "claude:chat", "gemini:cli", target_variant="antigravity")
out = registry.convert_request(req, "claude:chat", "gemini:chat", target_variant="antigravity")
parts = out["contents"][1]["parts"]
assert parts[0]["thought"] is True
@@ -91,7 +91,7 @@ def test_antigravity_drops_unsigned_thinking_for_non_gemini_models() -> None:
}
registry = get_format_converter_registry()
out = registry.convert_request(req, "claude:chat", "gemini:cli", target_variant="antigravity")
out = registry.convert_request(req, "claude:chat", "gemini:chat", target_variant="antigravity")
parts = out["contents"][1]["parts"]
assert all(p.get("thought") is not True for p in parts)
@@ -111,7 +111,7 @@ def test_antigravity_inserts_dummy_thought_for_last_assistant_when_thinking_enab
}
registry = get_format_converter_registry()
out = registry.convert_request(req, "claude:chat", "gemini:cli", target_variant="antigravity")
out = registry.convert_request(req, "claude:chat", "gemini:chat", target_variant="antigravity")
parts = out["contents"][1]["parts"]
assert parts[0]["thought"] is True

View File

@@ -19,7 +19,7 @@ class _DummyEndpoint:
def test_antigravity_uses_v1internal_path_and_sets_contextvar() -> None:
endpoint = _DummyEndpoint(
base_url="https://ignored.example.com",
api_format="gemini:cli",
api_format="gemini:chat",
provider=SimpleNamespace(provider_type="antigravity"),
)

View File

@@ -20,7 +20,7 @@ async def test_get_provider_auth_oauth_returns_decrypted_auth_config() -> None:
"project_id": "project-1",
}
endpoint = SimpleNamespace(api_format="gemini:cli")
endpoint = SimpleNamespace(api_format="gemini:chat")
key = SimpleNamespace(
id="k1",
auth_type="oauth",