fix(world): harden world task create external-marble fallback

This commit is contained in:
134 2026-08-19 13:45:10 +08:00
parent fd49843c5a
commit e601f8079f

View File

@ -200,6 +200,22 @@ function buildExternalWorldTaskPayload(
return payload;
}
function buildOfficialWorldTaskPayload(
displayName: string,
worldPrompt: Record<string, unknown>,
officialMarbleModel: string,
body: CreateWorldTaskRequest
) {
return {
display_name: displayName,
model: officialMarbleModel,
permission: {
public: body.makePublic === true,
},
world_prompt: worldPrompt,
};
}
function buildWorldPrompt(body: CreateWorldTaskRequest, mode: WorldTaskMode) {
const textPrompt = readOptionalTrimmedText(body.prompt);
@ -404,6 +420,7 @@ export async function POST(request: Request) {
try {
const useExternalTaskApi = shouldUseExternalTaskCreateApi(candidate, mode);
assertWorldModeSupportedByCandidate(candidate, mode);
let requestUsedExternalTaskApi = false;
if (useExternalTaskApi) {
const payload = buildExternalWorldTaskPayload(
mode,
@ -411,32 +428,64 @@ export async function POST(request: Request) {
readOptionalTrimmedText(body.prompt),
displayName,
);
const externalResult = await worldLabsRequest<
WorldLabsExternalTaskResponse<WorldLabsExternalTaskCreateData>
>(candidate, {
method: "POST",
path: "/api/external/task/generate",
timeoutMs: resolveWorldLabsCreateTimeoutMs(),
json: payload,
});
result = normalizeExternalTaskCreateOperation(externalResult);
try {
const externalResult = await worldLabsRequest<
WorldLabsExternalTaskResponse<WorldLabsExternalTaskCreateData>
>(candidate, {
method: "POST",
path: "/api/external/task/generate",
timeoutMs: resolveWorldLabsCreateTimeoutMs(),
json: payload,
});
result = normalizeExternalTaskCreateOperation(externalResult);
requestUsedExternalTaskApi = true;
} catch (error) {
const externalError = error instanceof Error ? error.message : String(error);
logger.warn("external world create failed, fallback to marble endpoint", {
providerId: candidate.providerId || null,
error: externalError,
});
if (isCredentialOrBillingProviderError(error)) {
await reportWorldLabsProviderRuntimeFailure(
candidate.providerId,
externalError
);
}
result = await worldLabsRequest<WorldLabsOperation>(candidate, {
method: "POST",
path: "/marble/v1/worlds:generate",
timeoutMs: resolveWorldLabsCreateTimeoutMs(),
json: buildOfficialWorldTaskPayload(
displayName,
worldPrompt,
officialMarbleModel,
body
),
});
requestUsedExternalTaskApi = false;
}
} else {
requestUsedExternalTaskApi = false;
result = await worldLabsRequest<WorldLabsOperation>(candidate, {
method: "POST",
path: "/marble/v1/worlds:generate",
timeoutMs: resolveWorldLabsCreateTimeoutMs(),
json: {
display_name: displayName,
model: officialMarbleModel,
permission: {
public: body.makePublic === true,
},
world_prompt: worldPrompt,
},
json: buildOfficialWorldTaskPayload(
displayName,
worldPrompt,
officialMarbleModel,
body
),
});
}
if (!result?.operation_id) {
throw new Error("创建 World Labs 世界任务返回缺少 operation_id");
}
usedProvider = candidate;
usedExternalTaskApi = useExternalTaskApi;
usedExternalTaskApi = requestUsedExternalTaskApi;
providerForLog = candidate.providerId || null;
break;
} catch (error) {