Fix review issues: lyrics polling, validation, undici fetch, retry, timeout, throttle, payload helper

This commit is contained in:
OpenCode
2026-07-14 16:17:51 +07:00
parent ac22e28128
commit 82087be1b3
14 changed files with 628 additions and 315 deletions
+40 -6
View File
@@ -20,17 +20,43 @@ const CommonGenerateParams = {
callBackUrl: CallbackUrl,
};
// 1. Generate Music (12 credits)
exports.GenerateMusicSchema = zod_1.z.object({
prompt: zod_1.z.string().optional().describe('Music description / lyrics (max 500 chars non-custom, 3000-5000 custom mode; required when customMode=false or customMode=true with instrumental=false)'),
exports.GenerateMusicSchema = zod_1.z
.object({
prompt: zod_1.z
.string()
.optional()
.describe('Music description / lyrics (max 500 chars non-custom, 3000-5000 custom mode; required when customMode=false or customMode=true with instrumental=false)'),
customMode: zod_1.z.boolean().describe('Enable custom mode (requires style and title)'),
instrumental: zod_1.z.boolean().describe('Generate instrumental without vocals'),
style: zod_1.z.string().optional().describe('Music style/genre (required when customMode=true)'),
title: zod_1.z.string().optional().describe('Song title (required when customMode=true)'),
...CommonGenerateParams,
}).strict();
})
.strict()
.superRefine(requirePromptWhenNeeded)
.refine((data) => !data.customMode || (!!data.style && !!data.title), {
message: 'style and title are required when customMode is true',
path: ['style'],
});
function requirePromptWhenNeeded(data, ctx) {
if (!data.customMode && !data.prompt) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: 'prompt is required when customMode is false',
path: ['prompt'],
});
}
if (data.customMode && !data.instrumental && !data.prompt) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: 'prompt is required when customMode is true and instrumental is false',
path: ['prompt'],
});
}
}
// 2. Generate Lyrics (0.4 credits)
exports.GenerateLyricsSchema = zod_1.z.object({
prompt: zod_1.z.string().describe('Topic or theme for lyrics'),
prompt: zod_1.z.string().max(200).describe('Topic or theme for lyrics (max 200 chars)'),
callBackUrl: CallbackUrl,
}).strict();
// 3. Generate Sounds (2.5 credits)
@@ -99,7 +125,8 @@ exports.AddInstrumentalSchema = zod_1.z.object({
callBackUrl: CallbackUrl,
}).strict();
// 8. Upload and Cover (12 credits)
exports.UploadAndCoverSchema = zod_1.z.object({
exports.UploadAndCoverSchema = zod_1.z
.object({
uploadUrl: zod_1.z.string().url().describe('Public URL of audio file to cover (max 8 minutes)'),
prompt: zod_1.z.string().optional(),
customMode: zod_1.z.boolean(),
@@ -115,7 +142,13 @@ exports.UploadAndCoverSchema = zod_1.z.object({
personaId: zod_1.z.string().optional(),
personaModel: PersonaModelEnum,
callBackUrl: CallbackUrl,
}).strict();
})
.strict()
.superRefine(requirePromptWhenNeeded)
.refine((data) => !data.customMode || (!!data.style && !!data.title), {
message: 'style and title are required when customMode is true',
path: ['style'],
});
// 9. Upload and Extend (12 credits)
exports.UploadAndExtendSchema = zod_1.z.object({
uploadUrl: zod_1.z.string().url().describe('Public URL of audio file to extend'),
@@ -169,6 +202,7 @@ exports.GeneratePersonaSchema = zod_1.z.object({
audioId: zod_1.z.string().describe('Track ID to derive persona from'),
}).strict();
// 17. Generate Mashup (12 credits)
// Note: Suno API docs list only V4/V4_5/V4_5PLUS/V4_5ALL/V5 for mashup; V5_5 is not supported.
exports.GenerateMashupSchema = zod_1.z.object({
uploadUrlList: zod_1.z.array(zod_1.z.string().url()).length(2).describe('Exactly 2 audio URLs to mash up'),
customMode: zod_1.z.boolean(),