Skip to content

Commit 11e38b6

Browse files
[inference provider] wavespeed support images field (#1839)
Support i2i and i2v to pass in the public parameters of images test: <img width="1602" height="764" alt="img_v3_02s0_e3d125d3-59e4-47d3-ac3d-8743a458e79g" src="https://github.com/user-attachments/assets/16165f72-8b4a-4f44-8ffb-49edae2797c3" /> --------- Co-authored-by: célina <[email protected]>
1 parent 7291a10 commit 11e38b6

File tree

2 files changed

+65
-15
lines changed

2 files changed

+65
-15
lines changed

packages/inference/src/providers/wavespeed.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@ interface WaveSpeedAISubmitTaskResponse {
6969
data: WaveSpeedAISubmitResponse;
7070
}
7171

72+
async function buildImagesField(
73+
inputs: Blob | ArrayBuffer,
74+
hasImages: unknown
75+
): Promise<{ base: string; images: string[] }> {
76+
const base = base64FromBytes(
77+
new Uint8Array(inputs instanceof ArrayBuffer ? inputs : await (inputs as Blob).arrayBuffer())
78+
);
79+
const images =
80+
Array.isArray(hasImages) && hasImages.every((value): value is string => typeof value === "string")
81+
? hasImages
82+
: [base];
83+
return { base, images };
84+
}
85+
7286
abstract class WavespeedAITask extends TaskProviderHelper {
7387
constructor(url?: string) {
7488
super("wavespeed", url || WAVESPEEDAI_API_BASE_URL);
@@ -83,7 +97,7 @@ abstract class WavespeedAITask extends TaskProviderHelper {
8397
): Record<string, unknown> {
8498
const payload: Record<string, unknown> = {
8599
...omit(params.args, ["inputs", "parameters"]),
86-
...params.args.parameters,
100+
...(params.args.parameters ? omit(params.args.parameters as Record<string, unknown>, ["images"]) : undefined),
87101
prompt: params.args.inputs,
88102
};
89103
// Add LoRA support if adapter is specified in the mapping
@@ -188,13 +202,10 @@ export class WavespeedAIImageToImageTask extends WavespeedAITask implements Imag
188202
}
189203

190204
async preparePayloadAsync(args: ImageToImageArgs): Promise<RequestArgs> {
191-
return {
192-
...args,
193-
inputs: args.parameters?.prompt,
194-
image: base64FromBytes(
195-
new Uint8Array(args.inputs instanceof ArrayBuffer ? args.inputs : await (args.inputs as Blob).arrayBuffer())
196-
),
197-
};
205+
const hasImages =
206+
(args as { images?: unknown }).images ?? (args.parameters as Record<string, unknown> | undefined)?.images;
207+
const { base, images } = await buildImagesField(args.inputs as Blob | ArrayBuffer, hasImages);
208+
return { ...args, inputs: args.parameters?.prompt, image: base, images };
198209
}
199210
}
200211

@@ -204,12 +215,9 @@ export class WavespeedAIImageToVideoTask extends WavespeedAITask implements Imag
204215
}
205216

206217
async preparePayloadAsync(args: ImageToVideoArgs): Promise<RequestArgs> {
207-
return {
208-
...args,
209-
inputs: args.parameters?.prompt,
210-
image: base64FromBytes(
211-
new Uint8Array(args.inputs instanceof ArrayBuffer ? args.inputs : await (args.inputs as Blob).arrayBuffer())
212-
),
213-
};
218+
const hasImages =
219+
(args as { images?: unknown }).images ?? (args.parameters as Record<string, unknown> | undefined)?.images;
220+
const { base, images } = await buildImagesField(args.inputs as Blob | ArrayBuffer, hasImages);
221+
return { ...args, inputs: args.parameters?.prompt, image: base, images };
214222
}
215223
}

packages/inference/test/InferenceClient.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,6 +2297,22 @@ describe.skip("InferenceClient", () => {
22972297
const client = new InferenceClient(env.HF_WAVESPEED_KEY ?? "dummy");
22982298

22992299
HARDCODED_MODEL_INFERENCE_MAPPING["wavespeed"] = {
2300+
"Qwen/Qwen-Image-Edit-2509": {
2301+
provider: "wavespeed",
2302+
hfModelId: "Qwen/Qwen-Image-Edit-2509",
2303+
providerId: "wavespeed-ai/qwen-image/edit-plus-lora",
2304+
status: "live",
2305+
task: "image-to-image",
2306+
},
2307+
"dx8152/Qwen-Edit-2509-Multiple-angles": {
2308+
provider: "wavespeed",
2309+
hfModelId: "dx8152/Qwen-Edit-2509-Multiple-angles",
2310+
providerId: "wavespeed-ai/qwen-image/edit-plus-lora",
2311+
status: "live",
2312+
task: "image-to-image",
2313+
adapter: "lora",
2314+
adapterWeightsPath: "镜头转换.safetensors",
2315+
},
23002316
"black-forest-labs/FLUX.1-schnell": {
23012317
provider: "wavespeed",
23022318
hfModelId: "black-forest-labs/FLUX.1-schnell",
@@ -2421,6 +2437,32 @@ describe.skip("InferenceClient", () => {
24212437
});
24222438
expect(res).toBeInstanceOf(Blob);
24232439
});
2440+
it(`imageToImage - Qwen/Qwen-Image-Edit-2509`, async () => {
2441+
const res = await client.imageToImage({
2442+
model: "Qwen/Qwen-Image-Edit-2509",
2443+
provider: "wavespeed",
2444+
inputs: new Blob([readTestFile("cheetah.png")], { type: "image/png" }),
2445+
parameters: {
2446+
prompt: "Turn the animal's head left",
2447+
},
2448+
});
2449+
expect(res).toBeInstanceOf(Blob);
2450+
});
2451+
it(`imageToImage - dx8152/Qwen-Edit-2509-Multiple-angles`, async () => {
2452+
const res = await client.imageToImage({
2453+
model: "dx8152/Qwen-Edit-2509-Multiple-angles",
2454+
provider: "wavespeed",
2455+
inputs: new Blob([readTestFile("cheetah.png")], { type: "image/png" }),
2456+
parameters: {
2457+
prompt: "Turn the animal's head left",
2458+
images: [
2459+
new Blob([readTestFile("cheetah.png")], { type: "image/png" }),
2460+
new Blob([readTestFile("bird_canny.png")], { type: "image/png" }),
2461+
],
2462+
},
2463+
});
2464+
expect(res).toBeInstanceOf(Blob);
2465+
});
24242466
},
24252467
TIMEOUT
24262468
);

0 commit comments

Comments
 (0)