feat(provider): 重构模型测试对话框,加固 Vertex AI 传输层

模型测试:
- 将消息输入替换为完整 JSON 请求体编辑器,支持格式化和校验
- 新增端点选择面板,测试前可选择目标端点
- 新增调试检查器,可查看每次尝试的请求/响应头和体
- 结果视图改用 HorizontalRequestTimeline 组件展示请求追踪
- endpoint_checker 返回完整调试数据,通过 candidate extra_data 持久化

Vertex AI:
- 改进上下文检测逻辑,不再仅依赖 provider_type,支持从 base_url 推断
- Service Account 密钥现支持自动拉取模型(使用 auth_config 而非 api_key)
- 移除 Gemini Developer API 回退,API Key 仅走 Express 模式
- 端点表单为 Vertex AI 显示格式特定的默认路径模板
- 密钥格式校验仅在 auth_type/api_formats 变更时执行

其他:
- 禁用 ClaudeCode 提供商类型创建入口
- Dialog 组件新增 closeOnBackdrop 属性
This commit is contained in:
fawney19
2026-03-19 23:52:17 +08:00
parent e4ebd5cca1
commit 6984984c22
31 changed files with 1609 additions and 434 deletions

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
import sys
import types
from contextlib import contextmanager
from datetime import datetime, timezone
from types import SimpleNamespace
from typing import Any, cast
@@ -167,6 +168,42 @@ def test_prepare_update_payload_vertex_to_oauth_clears_auth_config(
assert prepared.update_data["api_key"] == "ENC:__placeholder__"
def test_validate_vertex_api_formats_api_key_allows_gemini_only() -> None:
command_module._validate_vertex_api_formats("vertex_ai", "api_key", ["gemini:chat"])
with pytest.raises(InvalidRequestException, match="claude:chat"):
command_module._validate_vertex_api_formats("vertex_ai", "api_key", ["claude:chat"])
def test_validate_vertex_api_formats_service_account_allows_gemini_and_claude() -> None:
command_module._validate_vertex_api_formats("vertex_ai", "service_account", ["claude:chat"])
command_module._validate_vertex_api_formats("vertex_ai", "service_account", ["gemini:chat"])
command_module._validate_vertex_api_formats(
"vertex_ai", "service_account", ["gemini:chat", "claude:chat"]
)
with pytest.raises(InvalidRequestException, match="openai:chat"):
command_module._validate_vertex_api_formats("vertex_ai", "service_account", ["openai:chat"])
def test_prepare_update_payload_allows_unrelated_update_for_legacy_vertex_combo() -> None:
key = _build_key(
auth_type="service_account",
api_formats=["gemini:chat"],
provider=SimpleNamespace(provider_type="vertex_ai"),
)
key_data = EndpointAPIKeyUpdate.model_validate({"name": "legacy-key"})
prepared = command_module._prepare_update_key_payload(
db=cast(Any, _NoQueryDB()),
key=cast(Any, key),
key_id="key-1",
key_data=key_data,
)
assert prepared.update_data["name"] == "legacy-key"
def test_clear_oauth_invalid_response_invalidates_caches(
monkeypatch: pytest.MonkeyPatch,
) -> None:
@@ -346,6 +383,12 @@ async def test_batch_delete_endpoint_keys_response_cleans_related_references(
]
db = _FakeBatchDeleteDB(keys)
@contextmanager
def _fake_get_db_context() -> Any:
yield db
monkeypatch.setattr(command_module, "get_db_context", _fake_get_db_context)
result = await command_module.batch_delete_endpoint_keys_response(
cast(Any, db),
["key-1", "key-2"],