























@@ -106,6 +106,7 @@ describe("google video generation provider", () => {
106106generateVideosMock.mockReset();
107107getVideosOperationMock.mockReset();
108108createGoogleGenAIMock.mockClear();
109+vi.useRealTimers();
109110});
110111111112afterAll(() => {
@@ -357,6 +358,75 @@ describe("google video generation provider", () => {
357358expect(result.videos[0]?.buffer).toEqual(Buffer.from("rest-video"));
358359});
359360361+it("retries transient Google REST poll failures with empty bodies", async () => {
362+vi.useFakeTimers();
363+vi.spyOn(providerAuthRuntime, "resolveApiKeyForProvider").mockResolvedValue({
364+apiKey: "google-key",
365+source: "env",
366+mode: "api-key",
367+});
368+generateVideosMock.mockRejectedValue(Object.assign(new Error("sdk 404"), { status: 404 }));
369+const fetchMock = vi
370+.fn()
371+.mockResolvedValueOnce(
372+new Response(
373+JSON.stringify({
374+done: false,
375+name: "operations/rest-123",
376+}),
377+),
378+)
379+.mockResolvedValueOnce(new Response("", { status: 503, statusText: "Service Unavailable" }))
380+.mockResolvedValueOnce(
381+new Response(
382+JSON.stringify({
383+done: true,
384+name: "operations/rest-123",
385+response: {
386+generateVideoResponse: {
387+generatedSamples: [
388+{
389+video: {
390+uri: "https://generativelanguage.googleapis.com/v1beta/files/rest-video:download?alt=media",
391+mimeType: "video/mp4",
392+},
393+},
394+],
395+},
396+},
397+}),
398+),
399+)
400+.mockResolvedValueOnce(
401+new Response("rest-video", {
402+status: 200,
403+statusText: "OK",
404+headers: { "content-type": "video/mp4" },
405+}),
406+);
407+vi.stubGlobal("fetch", fetchMock);
408+409+const provider = buildGoogleVideoGenerationProvider();
410+const resultPromise = provider.generateVideo({
411+provider: "google",
412+model: "veo-3.1-fast-generate-preview",
413+prompt: "A tiny robot watering a windowsill garden",
414+cfg: {},
415+durationSeconds: 3,
416+});
417+await vi.advanceTimersByTimeAsync(10_250);
418+const result = await resultPromise;
419+420+expect(fetchMock).toHaveBeenCalledTimes(4);
421+expect(fetchInputUrl(fetchMock, 1)).toBe(
422+"https://generativelanguage.googleapis.com/v1beta/operations/rest-123",
423+);
424+expect(fetchInputUrl(fetchMock, 2)).toBe(
425+"https://generativelanguage.googleapis.com/v1beta/operations/rest-123",
426+);
427+expect(result.videos[0]?.buffer).toEqual(Buffer.from("rest-video"));
428+});
429+360430it("does not fall back to REST when SDK video generation with reference inputs returns 404", async () => {
361431vi.spyOn(providerAuthRuntime, "resolveApiKeyForProvider").mockResolvedValue({
362432apiKey: "google-key",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。