fix: persist worldlabs base settings without keys

This commit is contained in:
Your Name 2026-06-04 14:57:32 +08:00
parent 1598722ad0
commit e358e0241c
6 changed files with 70 additions and 16 deletions

View File

@ -372,9 +372,10 @@ export function LocalAiModel3dSections({
<Input
id="worldlabsKeyPoolImportToken"
onChange={(e) =>
setWorldlabsKeyPoolConfig({
setWorldlabsKeyPoolConfig((prev) => ({
...prev,
importToken: e.target.value,
})
}))
}
placeholder="供 /api/worldlabs/key-pool/import 调用的 Bearer Token"
type="password"

View File

@ -167,6 +167,9 @@ export type AiProviderSettingsConfig = {
export type WorldLabsKeyPoolConfig = {
importToken: string;
providerName: string;
baseUrl: string;
isEnabled: boolean;
};
export type LocalAiModel3dSectionsProps = LocalAiSectionControlProps & {

View File

@ -3120,15 +3120,19 @@ export function AdminSettingsClient() {
}, [providersData?.providers]);
useEffect(() => {
const savedWorldlabsConfig = normalizeWorldLabsKeyPoolConfig(
worldlabsKeyPoolConfigData?.setting?.value
);
const worldlabsProvider = (providersData?.providers || []).find(
(provider) => provider.type === "worldlabs-3d"
);
if (worldlabsProvider) {
setWorldlabs3dConfig({
providerId: worldlabsProvider.id,
name: worldlabsProvider.name || "World Labs",
name: worldlabsProvider.name || savedWorldlabsConfig.providerName,
baseUrl:
worldlabsProvider.baseUrl ||
savedWorldlabsConfig.baseUrl ||
getProviderDefaultBaseUrl("worldlabs-3d"),
apiKey: "",
isEnabled: worldlabsProvider.isEnabled,
@ -3136,14 +3140,15 @@ export function AdminSettingsClient() {
return;
}
setWorldlabs3dConfig({
setWorldlabs3dConfig((prev) => ({
providerId: "",
name: "World Labs",
baseUrl: getProviderDefaultBaseUrl("worldlabs-3d"),
apiKey: "",
isEnabled: true,
});
}, [providersData?.providers]);
name: savedWorldlabsConfig.providerName || "World Labs",
baseUrl:
savedWorldlabsConfig.baseUrl || getProviderDefaultBaseUrl("worldlabs-3d"),
apiKey: prev.providerId ? "" : prev.apiKey,
isEnabled: savedWorldlabsConfig.isEnabled,
}));
}, [providersData?.providers, worldlabsKeyPoolConfigData?.setting?.value]);
useEffect(() => {
setWorldlabsKeyPoolConfig(
@ -6407,9 +6412,37 @@ export function AdminSettingsClient() {
worldlabs3dConfig.baseUrl.trim() ||
getProviderDefaultBaseUrl("worldlabs-3d");
const hasProvider = Boolean(worldlabs3dConfig.providerId);
const normalizedKeyPoolConfig = normalizeWorldLabsKeyPoolConfig({
...worldlabsKeyPoolConfig,
providerName: trimmedName,
baseUrl: trimmedBaseUrl,
isEnabled: worldlabs3dConfig.isEnabled,
});
if (!hasProvider && !worldlabs3dConfig.apiKey.trim()) {
toast.error("请填写 World Labs API Key");
const keyPoolResponse = await fetch("/api/admin/settings", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
key: WORLDLABS_KEY_POOL_CONFIG_KEY,
value: normalizedKeyPoolConfig,
}),
});
if (!keyPoolResponse.ok) {
const payload = await keyPoolResponse.json().catch(() => ({}));
throw new Error(
String(
payload?.message ||
payload?.error ||
"保存 World Labs 基础配置失败"
)
);
}
setWorldlabsKeyPoolConfig(normalizedKeyPoolConfig);
mutateWorldlabsKeyPoolConfig();
toast.success("World Labs 基础配置已保存,添加 API Key 后即可生成");
return;
}
@ -6448,7 +6481,7 @@ export function AdminSettingsClient() {
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
key: WORLDLABS_KEY_POOL_CONFIG_KEY,
value: normalizeWorldLabsKeyPoolConfig(worldlabsKeyPoolConfig),
value: normalizedKeyPoolConfig,
}),
});
@ -6465,6 +6498,7 @@ export function AdminSettingsClient() {
toast.success("World Labs 配置保存成功");
setWorldlabs3dConfig((prev) => ({ ...prev, apiKey: "" }));
setWorldlabsKeyPoolConfig(normalizedKeyPoolConfig);
mutateProviders();
mutateWorldlabsKeyPoolConfig();
} catch (error) {

View File

@ -9,13 +9,14 @@ import {
sanitizeWorldLabsApiKey,
sanitizeWorldLabsBaseUrl,
} from "@/lib/worldlabs/server";
import { getWorldLabsKeyPoolConfig } from "@/lib/worldlabs/key-pool-config";
import {
DEFAULT_WORLDLABS_BASE_URL,
getWorldLabsKeyPoolConfig,
} from "@/lib/worldlabs/key-pool-config";
export const runtime = "nodejs";
export const maxDuration = 60;
const DEFAULT_WORLDLABS_BASE_URL = "https://api.worldlabs.ai";
const importPayloadSchema = z.object({
keys: z
.array(
@ -161,7 +162,7 @@ export async function POST(request: Request) {
);
const defaultBaseUrl =
sanitizeWorldLabsBaseUrl(payload.baseUrl || "") ||
sanitizeWorldLabsBaseUrl(payload.baseUrl || dbConfig.baseUrl || "") ||
DEFAULT_WORLDLABS_BASE_URL;
const defaultIsEnabled = payload.isEnabled !== false;
const namePrefix = String(payload.namePrefix || "WorldLabsKey").trim();

View File

@ -1,11 +1,18 @@
export const WORLDLABS_KEY_POOL_CONFIG_KEY = "worldlabs_key_pool_config";
export const DEFAULT_WORLDLABS_BASE_URL = "https://api.worldlabs.ai";
export type WorldLabsKeyPoolConfig = {
importToken: string;
providerName: string;
baseUrl: string;
isEnabled: boolean;
};
export const defaultWorldLabsKeyPoolConfig: WorldLabsKeyPoolConfig = {
importToken: "",
providerName: "World Labs",
baseUrl: DEFAULT_WORLDLABS_BASE_URL,
isEnabled: true,
};
function normalizeImportToken(value: unknown) {
@ -25,5 +32,11 @@ export function normalizeWorldLabsKeyPoolConfig(
const raw = value as Partial<WorldLabsKeyPoolConfig>;
return {
importToken: normalizeImportToken(raw.importToken),
providerName:
String(raw.providerName || "World Labs").trim() || "World Labs",
baseUrl:
String(raw.baseUrl || DEFAULT_WORLDLABS_BASE_URL).trim() ||
DEFAULT_WORLDLABS_BASE_URL,
isEnabled: raw.isEnabled !== false,
};
}

View File

@ -2,6 +2,7 @@ import "server-only";
import { getSystemSetting } from "@/lib/db/queries";
import {
DEFAULT_WORLDLABS_BASE_URL,
defaultWorldLabsKeyPoolConfig,
normalizeWorldLabsKeyPoolConfig,
WORLDLABS_KEY_POOL_CONFIG_KEY,
@ -9,6 +10,7 @@ import {
} from "@/lib/worldlabs/key-pool-config-shared";
export {
DEFAULT_WORLDLABS_BASE_URL,
defaultWorldLabsKeyPoolConfig,
normalizeWorldLabsKeyPoolConfig,
WORLDLABS_KEY_POOL_CONFIG_KEY,