mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 20:00:47 +00:00
fix(xiaomi-tokenplan): region selector, key validation, multi-connection (#2251)
- Add top-level regions array so Add/Edit modals render region <Select> - EditConnectionModal: load/persist region generically for region-aware providers - validate: accept 403 for xiaomi-tokenplan valid keys, add 8s fetch timeout - Remove single-connection guard for compatible/embedding nodes Co-authored-by: MiQieR <122154116+MiQieR@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
co-authored by
Cursor
parent
ce6120ce7b
commit
9102c4c6d8
@@ -6,7 +6,8 @@ import Modal from "@/shared/components/Modal";
|
||||
import Input from "@/shared/components/Input";
|
||||
import Button from "@/shared/components/Button";
|
||||
import Badge from "@/shared/components/Badge";
|
||||
import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider } from "@/shared/constants/providers";
|
||||
import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider, AI_PROVIDERS } from "@/shared/constants/providers";
|
||||
import Select from "@/shared/components/Select";
|
||||
|
||||
export default function EditConnectionModal({ isOpen, connection, proxyPools, onSave, onClose }) {
|
||||
const [formData, setFormData] = useState({
|
||||
@@ -21,6 +22,7 @@ export default function EditConnectionModal({ isOpen, connection, proxyPools, on
|
||||
organization: "",
|
||||
});
|
||||
const [cloudflareData, setCloudflareData] = useState({ accountId: "" });
|
||||
const [region, setRegion] = useState("");
|
||||
const [testing, setTesting] = useState(false);
|
||||
const [testResult, setTestResult] = useState(null);
|
||||
const [validating, setValidating] = useState(false);
|
||||
@@ -46,6 +48,12 @@ export default function EditConnectionModal({ isOpen, connection, proxyPools, on
|
||||
if (connection.provider === "cloudflare-ai" && connection.providerSpecificData) {
|
||||
setCloudflareData({ accountId: connection.providerSpecificData.accountId || "" });
|
||||
}
|
||||
// Load region for providers that support it (e.g. xiaomi-tokenplan)
|
||||
const providerCfg = AI_PROVIDERS?.[connection.provider];
|
||||
if (providerCfg?.regions) {
|
||||
const savedRegion = connection.providerSpecificData?.region || providerCfg.defaultRegion || providerCfg.regions[0]?.id || "";
|
||||
setRegion(savedRegion);
|
||||
}
|
||||
setTestResult(null);
|
||||
setValidationResult(null);
|
||||
}
|
||||
@@ -57,6 +65,13 @@ export default function EditConnectionModal({ isOpen, connection, proxyPools, on
|
||||
const isCompatible = connection
|
||||
? (isOpenAICompatibleProvider(connection.provider) || isAnthropicCompatibleProvider(connection.provider))
|
||||
: false;
|
||||
const providerRegions = connection ? (AI_PROVIDERS?.[connection.provider]?.regions || null) : null;
|
||||
|
||||
// Build providerSpecificData for region-aware providers
|
||||
const buildRegionSpecificData = () => {
|
||||
if (providerRegions && region) return { ...((connection?.providerSpecificData) || {}), region };
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const handleTest = async () => {
|
||||
if (!connection?.provider) return;
|
||||
@@ -86,6 +101,7 @@ export default function EditConnectionModal({ isOpen, connection, proxyPools, on
|
||||
apiKey: formData.apiKey,
|
||||
...(isAzure ? { providerSpecificData: azureData } : {}),
|
||||
...(isCloudflareAi ? { providerSpecificData: cloudflareData } : {}),
|
||||
...(providerRegions ? { providerSpecificData: buildRegionSpecificData() } : {}),
|
||||
}),
|
||||
});
|
||||
const data = await res.json();
|
||||
@@ -120,6 +136,7 @@ export default function EditConnectionModal({ isOpen, connection, proxyPools, on
|
||||
apiKey: formData.apiKey,
|
||||
...(isAzure ? { providerSpecificData: azureData } : {}),
|
||||
...(isCloudflareAi ? { providerSpecificData: cloudflareData } : {}),
|
||||
...(providerRegions ? { providerSpecificData: buildRegionSpecificData() } : {}),
|
||||
}),
|
||||
});
|
||||
const data = await res.json();
|
||||
@@ -150,6 +167,10 @@ export default function EditConnectionModal({ isOpen, connection, proxyPools, on
|
||||
if (isCloudflareAi) {
|
||||
updates.providerSpecificData = { accountId: cloudflareData.accountId };
|
||||
}
|
||||
// Persist updated region for region-aware providers
|
||||
if (providerRegions && region) {
|
||||
updates.providerSpecificData = buildRegionSpecificData();
|
||||
}
|
||||
|
||||
await onSave(updates);
|
||||
} finally {
|
||||
@@ -243,6 +264,15 @@ export default function EditConnectionModal({ isOpen, connection, proxyPools, on
|
||||
</div>
|
||||
)}
|
||||
|
||||
{providerRegions && (
|
||||
<Select
|
||||
label="Region"
|
||||
value={region}
|
||||
onChange={(e) => setRegion(e.target.value)}
|
||||
options={providerRegions.map((r) => ({ value: r.id, label: r.label }))}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!isCompatible && !isAzure && !isCloudflareAi && (
|
||||
<div className="flex items-center gap-3">
|
||||
<Button onClick={handleTest} variant="secondary" disabled={testing}>
|
||||
|
||||
Reference in New Issue
Block a user