Merge branch 'main' into feat/proxy-full-url

This commit is contained in:
YoVinchen
2026-03-18 22:54:08 +08:00
50 changed files with 4592 additions and 1088 deletions
@@ -80,6 +80,7 @@ import {
useOpencodeFormState,
useOmoDraftState,
useOpenclawFormState,
useCopilotAuth,
} from "./hooks";
import {
CLAUDE_DEFAULT_CONFIG,
@@ -89,6 +90,7 @@ import {
OPENCLAW_DEFAULT_CONFIG,
normalizePricingSource,
} from "./helpers/opencodeFormUtils";
import { resolveManagedAccountId } from "@/lib/authBinding";
type PresetEntry = {
id: string;
@@ -338,6 +340,14 @@ export function ProviderForm({
[localApiKeyField, form, handleSettingsConfigChange],
);
// Copilot OAuth 认证状态(仅 Claude 应用需要)
const { isAuthenticated: isCopilotAuthenticated } = useCopilotAuth();
// 选中的 GitHub 账号 ID(多账号支持)
const [selectedGitHubAccountId, setSelectedGitHubAccountId] = useState<
string | null
>(() => resolveManagedAccountId(initialData?.meta, "github_copilot"));
const {
codexAuth,
codexConfig,
@@ -667,6 +677,21 @@ export function ProviderForm({
// 非官方供应商必填校验:端点和 API Key
// cloud_provider(如 Bedrock)通过模板变量处理认证,跳过通用校验
// GitHub Copilot 使用 OAuth 认证,不需要 API Key
const isCopilotProvider =
templatePreset?.providerType === "github_copilot" ||
initialData?.meta?.providerType === "github_copilot" ||
baseUrl.includes("githubcopilot.com");
// GitHub Copilot 必须先登录才能添加
if (isCopilotProvider && !isCopilotAuthenticated) {
toast.error(
t("copilot.loginRequired", {
defaultValue: "请先登录 GitHub Copilot",
}),
);
return;
}
if (category !== "official" && category !== "cloud_provider") {
if (appId === "claude") {
if (!baseUrl.trim()) {
@@ -677,7 +702,7 @@ export function ProviderForm({
);
return;
}
if (!apiKey.trim()) {
if (!isCopilotProvider && !apiKey.trim()) {
toast.error(
t("providerForm.apiKeyRequired", {
defaultValue: "非官方供应商请填写 API Key",
@@ -874,6 +899,11 @@ export function ProviderForm({
const baseMeta: ProviderMeta | undefined =
payload.meta ?? (initialData?.meta ? { ...initialData.meta } : undefined);
// 确定 providerType(新建时从预设获取,编辑时从现有数据获取)
const providerType =
templatePreset?.providerType || initialData?.meta?.providerType;
payload.meta = {
...(baseMeta ?? {}),
commonConfigEnabled:
@@ -885,6 +915,20 @@ export function ProviderForm({
? useGeminiCommonConfigFlag
: undefined,
endpointAutoSelect,
// 保存 providerType(用于识别 Copilot 等特殊供应商)
providerType,
authBinding: isCopilotProvider
? {
source: "managed_account",
authProvider: "github_copilot",
accountId: selectedGitHubAccountId ?? undefined,
}
: undefined,
// GitHub Copilot 多账号:保存关联的账号 ID
githubAccountId:
isCopilotProvider && selectedGitHubAccountId
? selectedGitHubAccountId
: undefined,
testConfig: testConfig.enabled ? testConfig : undefined,
proxyConfig: proxyConfig.enabled ? proxyConfig : undefined,
costMultiplier: pricingConfig.enabled
@@ -1330,6 +1374,20 @@ export function ProviderForm({
websiteUrl={claudeWebsiteUrl}
isPartner={isClaudePartner}
partnerPromotionKey={claudePartnerPromotionKey}
isCopilotPreset={
templatePreset?.providerType === "github_copilot" ||
initialData?.meta?.providerType === "github_copilot" ||
baseUrl.includes("githubcopilot.com")
}
usesOAuth={
templatePreset?.requiresOAuth === true ||
templatePreset?.providerType === "github_copilot" ||
initialData?.meta?.providerType === "github_copilot" ||
baseUrl.includes("githubcopilot.com")
}
isCopilotAuthenticated={isCopilotAuthenticated}
selectedGitHubAccountId={selectedGitHubAccountId}
onGitHubAccountSelect={setSelectedGitHubAccountId}
templateValueEntries={templateValueEntries}
templateValues={templateValues}
templatePresetName={templatePreset?.name || ""}