feat(vertex-ai): 重构 Vertex AI 为插件化 adapter,支持 service_account 认证与动态路由

将 Vertex AI 从 transport.py 的硬编码逻辑重构为独立的 plugin adapter,
支持 service_account/oauth 认证类型、模型格式自动识别、区域路由和 URL 构建。
前端新增 Key 认证类型选择和 Service Account 配置表单。

Co-authored-by: NyaDoo <65238336+NyaDoo@users.noreply.github.com>
Closes #194
This commit is contained in:
fawney19
2026-03-01 23:32:48 +08:00
parent a137601728
commit 4bf3a453e7
42 changed files with 1855 additions and 546 deletions

View File

@@ -48,6 +48,7 @@ def _should_enable_format_conversion_by_default(provider_type: str | None) -> bo
ProviderType.CLAUDE_CODE.value,
ProviderType.CODEX.value,
ProviderType.KIRO.value,
ProviderType.VERTEX_AI.value,
}
return pt in envelope_provider_types
@@ -56,6 +57,15 @@ def _normalize_provider_type(provider_type: str | None) -> str:
return (provider_type or "custom").strip().lower()
def _get_fixed_provider_template(provider_type: str | None) -> Any | None:
"""Return fixed-provider template when provider_type is managed by FIXED_PROVIDERS."""
normalized = _normalize_provider_type(provider_type)
try:
return FIXED_PROVIDERS.get(ProviderType(normalized))
except Exception:
return None
def _merge_pool_advanced_config(
*,
provider_config: dict[str, Any] | None,
@@ -458,33 +468,31 @@ class AdminCreateProviderAdapter(AdminApiAdapter):
db.flush() # flush 获取 ID但不提交保持在同一事务中
# 固定类型 Provider自动创建并锁定预置 Endpoints同一事务
provider_type = (provider.provider_type or "custom").strip()
if provider_type != ProviderType.CUSTOM:
try:
template = FIXED_PROVIDERS.get(ProviderType(provider_type))
except Exception:
template = None
if template:
now = datetime.now(timezone.utc)
for sig in template.endpoint_signatures:
endpoint = ProviderEndpoint(
id=str(uuid.uuid4()),
provider_id=provider.id,
api_format=sig,
api_family=sig.split(":", 1)[0],
endpoint_kind=sig.split(":", 1)[1],
base_url=template.api_base_url,
custom_path=None,
header_rules=None,
max_retries=provider.max_retries or 2,
is_active=True,
config=None,
proxy=None,
format_acceptance_config=None,
created_at=now,
updated_at=now,
)
db.add(endpoint)
template = _get_fixed_provider_template(provider.provider_type)
if template:
now = datetime.now(timezone.utc)
for sig in template.endpoint_signatures:
endpoint_config: dict[str, str] | None = None
if provider.provider_type == ProviderType.CODEX.value and sig == "openai:cli":
endpoint_config = {"upstream_stream_policy": "force_stream"}
endpoint = ProviderEndpoint(
id=str(uuid.uuid4()),
provider_id=provider.id,
api_format=sig,
api_family=sig.split(":", 1)[0],
endpoint_kind=sig.split(":", 1)[1],
base_url=template.api_base_url,
custom_path=None,
header_rules=None,
max_retries=provider.max_retries or 2,
is_active=True,
config=endpoint_config,
proxy=None,
format_acceptance_config=None,
created_at=now,
updated_at=now,
)
db.add(endpoint)
db.commit()
db.refresh(provider)