mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
feat(openclaw): register suggested models to allowlist on provider add
When adding an OpenClaw provider with suggestedDefaults, automatically merge its model catalog into the allowlist and set the default model if not already configured.
This commit is contained in:
@@ -17,6 +17,7 @@ import { UniversalProviderPanel } from "@/components/universal";
|
||||
import { providerPresets } from "@/config/claudeProviderPresets";
|
||||
import { codexProviderPresets } from "@/config/codexProviderPresets";
|
||||
import { geminiProviderPresets } from "@/config/geminiProviderPresets";
|
||||
import type { OpenClawSuggestedDefaults } from "@/config/openclawProviderPresets";
|
||||
import type { UniversalProviderPreset } from "@/config/universalProviderPresets";
|
||||
|
||||
interface AddProviderDialogProps {
|
||||
@@ -24,7 +25,10 @@ interface AddProviderDialogProps {
|
||||
onOpenChange: (open: boolean) => void;
|
||||
appId: AppId;
|
||||
onSubmit: (
|
||||
provider: Omit<Provider, "id"> & { providerKey?: string },
|
||||
provider: Omit<Provider, "id"> & {
|
||||
providerKey?: string;
|
||||
suggestedDefaults?: OpenClawSuggestedDefaults;
|
||||
},
|
||||
) => Promise<void> | void;
|
||||
}
|
||||
|
||||
@@ -83,7 +87,11 @@ export function AddProviderDialog({
|
||||
unknown
|
||||
>;
|
||||
|
||||
const providerData: Omit<Provider, "id"> & { providerKey?: string } = {
|
||||
// 构造基础提交数据
|
||||
const providerData: Omit<Provider, "id"> & {
|
||||
providerKey?: string;
|
||||
suggestedDefaults?: OpenClawSuggestedDefaults;
|
||||
} = {
|
||||
name: values.name.trim(),
|
||||
notes: values.notes?.trim() || undefined,
|
||||
websiteUrl: values.websiteUrl?.trim() || undefined,
|
||||
@@ -95,7 +103,10 @@ export function AddProviderDialog({
|
||||
};
|
||||
|
||||
// OpenCode/OpenClaw: pass providerKey for ID generation
|
||||
if ((appId === "opencode" || appId === "openclaw") && values.providerKey) {
|
||||
if (
|
||||
(appId === "opencode" || appId === "openclaw") &&
|
||||
values.providerKey
|
||||
) {
|
||||
providerData.providerKey = values.providerKey;
|
||||
}
|
||||
|
||||
@@ -213,6 +224,11 @@ export function AddProviderDialog({
|
||||
}
|
||||
}
|
||||
|
||||
// OpenClaw: pass suggestedDefaults for model registration
|
||||
if (appId === "openclaw" && values.suggestedDefaults) {
|
||||
providerData.suggestedDefaults = values.suggestedDefaults;
|
||||
}
|
||||
|
||||
await onSubmit(providerData);
|
||||
onOpenChange(false);
|
||||
},
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
import {
|
||||
openclawProviderPresets,
|
||||
type OpenClawProviderPreset,
|
||||
type OpenClawSuggestedDefaults,
|
||||
} from "@/config/openclawProviderPresets";
|
||||
import { OpenCodeFormFields } from "./OpenCodeFormFields";
|
||||
import { OpenClawFormFields } from "./OpenClawFormFields";
|
||||
@@ -277,6 +278,7 @@ export function ProviderForm({
|
||||
category?: ProviderCategory;
|
||||
isPartner?: boolean;
|
||||
partnerPromotionKey?: string;
|
||||
suggestedDefaults?: OpenClawSuggestedDefaults;
|
||||
} | null>(null);
|
||||
const [isEndpointModalOpen, setIsEndpointModalOpen] = useState(false);
|
||||
const [isCodexEndpointModalOpen, setIsCodexEndpointModalOpen] =
|
||||
@@ -1446,6 +1448,10 @@ export function ProviderForm({
|
||||
if (activePreset.isPartner) {
|
||||
payload.isPartner = activePreset.isPartner;
|
||||
}
|
||||
// OpenClaw: 传递预设的 suggestedDefaults 到提交数据
|
||||
if (activePreset.suggestedDefaults) {
|
||||
payload.suggestedDefaults = activePreset.suggestedDefaults;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isEditMode && draftCustomEndpoints.length > 0) {
|
||||
@@ -1726,6 +1732,15 @@ export function ProviderForm({
|
||||
const preset = entry.preset as OpenClawProviderPreset;
|
||||
const config = preset.settingsConfig;
|
||||
|
||||
// Update activePreset with suggestedDefaults for OpenClaw
|
||||
setActivePreset({
|
||||
id: value,
|
||||
category: preset.category,
|
||||
isPartner: preset.isPartner,
|
||||
partnerPromotionKey: preset.partnerPromotionKey,
|
||||
suggestedDefaults: preset.suggestedDefaults,
|
||||
});
|
||||
|
||||
// Clear provider key (user must enter their own unique key)
|
||||
setOpenclawProviderKey("");
|
||||
|
||||
@@ -2206,5 +2221,6 @@ export type ProviderFormValues = ProviderFormData & {
|
||||
presetCategory?: ProviderCategory;
|
||||
isPartner?: boolean;
|
||||
meta?: ProviderMeta;
|
||||
providerKey?: string;
|
||||
providerKey?: string; // OpenCode/OpenClaw: user-defined provider key
|
||||
suggestedDefaults?: OpenClawSuggestedDefaults; // OpenClaw: suggested default model configuration
|
||||
};
|
||||
|
||||
@@ -2,8 +2,9 @@ import { useCallback } from "react";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { providersApi, settingsApi, type AppId } from "@/lib/api";
|
||||
import { providersApi, settingsApi, openclawApi, type AppId } from "@/lib/api";
|
||||
import type { Provider, UsageScript } from "@/types";
|
||||
import type { OpenClawSuggestedDefaults } from "@/config/openclawProviderPresets";
|
||||
import {
|
||||
useAddProviderMutation,
|
||||
useUpdateProviderMutation,
|
||||
@@ -54,10 +55,55 @@ export function useProviderActions(activeApp: AppId) {
|
||||
|
||||
// 添加供应商
|
||||
const addProvider = useCallback(
|
||||
async (provider: Omit<Provider, "id"> & { providerKey?: string }) => {
|
||||
async (
|
||||
provider: Omit<Provider, "id"> & {
|
||||
providerKey?: string;
|
||||
suggestedDefaults?: OpenClawSuggestedDefaults;
|
||||
},
|
||||
) => {
|
||||
await addProviderMutation.mutateAsync(provider);
|
||||
|
||||
// OpenClaw: register models to allowlist after adding provider
|
||||
if (activeApp === "openclaw" && provider.suggestedDefaults) {
|
||||
const { model, modelCatalog } = provider.suggestedDefaults;
|
||||
let modelsRegistered = false;
|
||||
|
||||
try {
|
||||
// 1. Merge model catalog (allowlist)
|
||||
if (modelCatalog && Object.keys(modelCatalog).length > 0) {
|
||||
const existingCatalog = (await openclawApi.getModelCatalog()) || {};
|
||||
const mergedCatalog = { ...existingCatalog, ...modelCatalog };
|
||||
await openclawApi.setModelCatalog(mergedCatalog);
|
||||
modelsRegistered = true;
|
||||
}
|
||||
|
||||
// 2. Set default model (only if not already set)
|
||||
if (model) {
|
||||
const existingDefault = await openclawApi.getDefaultModel();
|
||||
if (!existingDefault?.primary) {
|
||||
await openclawApi.setDefaultModel(model);
|
||||
}
|
||||
}
|
||||
|
||||
// Show success toast if models were registered
|
||||
if (modelsRegistered) {
|
||||
toast.success(
|
||||
t("notifications.openclawModelsRegistered", {
|
||||
defaultValue: "模型已注册到 /model 列表",
|
||||
}),
|
||||
{ closeButton: true },
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
// Log warning but don't block main flow - provider config is already saved
|
||||
console.warn(
|
||||
"[OpenClaw] Failed to register models to allowlist:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
[addProviderMutation],
|
||||
[addProviderMutation, activeApp, t],
|
||||
);
|
||||
|
||||
// 更新供应商
|
||||
|
||||
@@ -162,7 +162,8 @@
|
||||
"settingsSaved": "Settings saved",
|
||||
"settingsSaveFailed": "Failed to save settings: {{error}}",
|
||||
"openAIChatFormatHint": "This provider uses OpenAI Chat format and requires the proxy service to be enabled",
|
||||
"openLinkFailed": "Failed to open link"
|
||||
"openLinkFailed": "Failed to open link",
|
||||
"openclawModelsRegistered": "Models have been registered to /model list"
|
||||
},
|
||||
"confirm": {
|
||||
"deleteProvider": "Delete Provider",
|
||||
|
||||
@@ -162,7 +162,8 @@
|
||||
"settingsSaved": "設定を保存しました",
|
||||
"settingsSaveFailed": "設定の保存に失敗しました: {{error}}",
|
||||
"openAIChatFormatHint": "このプロバイダーは OpenAI Chat フォーマットを使用しており、プロキシサービスの有効化が必要です",
|
||||
"openLinkFailed": "リンクを開けませんでした"
|
||||
"openLinkFailed": "リンクを開けませんでした",
|
||||
"openclawModelsRegistered": "モデルが /model リストに登録されました"
|
||||
},
|
||||
"confirm": {
|
||||
"deleteProvider": "プロバイダーを削除",
|
||||
|
||||
@@ -162,7 +162,8 @@
|
||||
"settingsSaved": "设置已保存",
|
||||
"settingsSaveFailed": "保存设置失败:{{error}}",
|
||||
"openAIChatFormatHint": "此供应商使用 OpenAI Chat 格式,需要开启代理服务才能正常使用",
|
||||
"openLinkFailed": "链接打开失败"
|
||||
"openLinkFailed": "链接打开失败",
|
||||
"openclawModelsRegistered": "模型已注册到 /model 列表"
|
||||
},
|
||||
"confirm": {
|
||||
"deleteProvider": "删除供应商",
|
||||
|
||||
@@ -7,7 +7,7 @@ export { skillsApi } from "./skills";
|
||||
export { usageApi } from "./usage";
|
||||
export { vscodeApi } from "./vscode";
|
||||
export { proxyApi } from "./proxy";
|
||||
export { sessionsApi } from "./sessions";
|
||||
export { openclawApi } from "./openclaw";
|
||||
export * as configApi from "./config";
|
||||
export type { ProviderSwitchEvent } from "./providers";
|
||||
export type { Prompt } from "./prompts";
|
||||
|
||||
Reference in New Issue
Block a user