fix: resolve v3.7.0 stabilization issues (#1566, #1560, #1559)

This commit is contained in:
diegosouzapw
2026-04-24 15:23:43 -03:00
parent 7ed15c742f
commit 5b5e21a99e
3 changed files with 54 additions and 29 deletions

View File

@@ -1051,7 +1051,7 @@ export default function ProviderDetailPage() {
name: cm.name || cm.id,
source: cm.source === "api-sync" ? "api-sync" : "custom",
}));
return [...builtInModels, ...syncedExtras, ...customExtras];
return [...builtInModels, ...syncedExtras];
}, [providerId, registryModels, syncedAvailableModels, modelMeta.customModels]);
const providerAlias = getProviderAlias(providerId);
const isManagedAvailableModelsProvider = isCompatible || providerId === "openrouter";
@@ -2680,11 +2680,7 @@ export default function ProviderDetailPage() {
</p>
</div>
<div className="flex items-center gap-2">
<Button
size="sm"
icon="add"
onClick={() => setShowAddApiKeyModal(true)}
>
<Button size="sm" icon="add" onClick={() => setShowAddApiKeyModal(true)}>
{t("add")}
</Button>
<Button
@@ -3076,15 +3072,13 @@ export default function ProviderDetailPage() {
{renderModelsSection()}
{/* Custom Models — available for all providers */}
{!isManagedAvailableModelsProvider && (
<CustomModelsSection
providerId={providerId}
providerAlias={providerDisplayAlias}
copied={copied}
onCopy={copy}
onModelsChanged={fetchProviderModelMeta}
/>
)}
<CustomModelsSection
providerId={providerId}
providerAlias={providerDisplayAlias}
copied={copied}
onCopy={copy}
onModelsChanged={fetchProviderModelMeta}
/>
</Card>
)}
@@ -3875,6 +3869,7 @@ function CustomModelsSection({
const [editingApiFormat, setEditingApiFormat] = useState("chat-completions");
const [editingEndpoints, setEditingEndpoints] = useState<string[]>(["chat"]);
const [savingModelId, setSavingModelId] = useState<string | null>(null);
const [togglingModelId, setTogglingModelId] = useState<string | null>(null);
const customMap = useMemo(() => buildCompatMap(customModels), [customModels]);
const overrideMap = useMemo(() => buildCompatMap(modelCompatOverrides), [modelCompatOverrides]);
@@ -3943,6 +3938,28 @@ function CustomModelsSection({
}
};
const handleToggleHidden = async (modelId: string, hidden: boolean) => {
setTogglingModelId(modelId);
try {
const res = await fetch(
`/api/provider-models?provider=${encodeURIComponent(providerId)}&modelId=${encodeURIComponent(modelId)}`,
{
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ isHidden: hidden }),
}
);
if (res.ok) {
await fetchCustomModels();
onModelsChanged?.();
}
} catch (e) {
console.error("Failed to toggle model visibility:", e);
} finally {
setTogglingModelId(null);
}
};
const beginEdit = (model) => {
setEditingModelId(model.id);
setEditingApiFormat(model.apiFormat || "chat-completions");
@@ -4311,6 +4328,16 @@ function CustomModelsSection({
showDeveloperToggle
disabled={savingModelId === model.id}
/>
<button
onClick={() => handleToggleHidden(model.id, !model.isHidden)}
disabled={togglingModelId === model.id}
className="rounded p-1 text-text-muted hover:bg-sidebar hover:text-primary disabled:opacity-50"
title={model.isHidden ? t("unhideModel") : t("hideModel")}
>
<span className="material-symbols-outlined text-sm">
{model.isHidden ? "visibility_off" : "visibility"}
</span>
</button>
<button
onClick={() => handleRemove(model.id)}
className="rounded p-1 text-red-500 hover:bg-red-50"

View File

@@ -545,7 +545,15 @@ export default function ProxyRegistryManager() {
title={editingId ? t("modalEditTitle") : t("modalCreateTitle")}
maxWidth="lg"
>
<div className="flex flex-col gap-3">
<form
className="flex flex-col gap-3"
onSubmit={(e) => {
e.preventDefault();
handleSave();
}}
autoComplete="off"
data-1p-ignore="true"
>
<div className="grid grid-cols-2 gap-3">
<div>
<label className="text-xs text-text-muted mb-1 block">{t("labelName")}</label>
@@ -643,7 +651,7 @@ export default function ProxyRegistryManager() {
Save
</Button>
</div>
</div>
</form>
</Modal>
<Modal

View File

@@ -105,12 +105,7 @@ export async function POST(request: Request) {
}
const existingConnections = await getProviderConnections({ provider });
if (!allowMultipleCompatibleConnections && existingConnections.length > 0) {
return NextResponse.json(
{ error: "Only one connection is allowed for this OpenAI Compatible node" },
{ status: 400 }
);
}
// Allow multiple connections for compatible nodes exactly like first-party providers
providerSpecificData = {
...(providerSpecificData || {}),
@@ -135,12 +130,7 @@ export async function POST(request: Request) {
}
const existingConnections = await getProviderConnections({ provider });
if (!allowMultipleCompatibleConnections && existingConnections.length > 0) {
return NextResponse.json(
{ error: "Only one connection is allowed for this Anthropic Compatible node" },
{ status: 400 }
);
}
// Allow multiple connections for compatible nodes exactly like first-party providers
providerSpecificData = {
...(providerSpecificData || {}),