mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:40:44 +00:00
test: tolerate transient google tts and openrouter tool probes
This commit is contained in:
@@ -277,6 +277,54 @@ describe("Google speech provider", () => {
|
||||
expect(result.audioBuffer.subarray(44)).toEqual(pcm);
|
||||
});
|
||||
|
||||
it("retries once when Gemini TTS fetch aborts", async () => {
|
||||
const pcm = Buffer.from([7, 0, 8, 0]);
|
||||
const abortError = new Error("This operation was aborted");
|
||||
abortError.name = "AbortError";
|
||||
const requestSequence = vi
|
||||
.fn()
|
||||
.mockRejectedValueOnce(abortError)
|
||||
.mockResolvedValueOnce({
|
||||
response: googleTtsResponse(pcm),
|
||||
release: vi.fn(async () => {}),
|
||||
});
|
||||
postJsonRequestMock.mockImplementation(requestSequence);
|
||||
const provider = buildGoogleSpeechProvider();
|
||||
|
||||
const result = await provider.synthesize({
|
||||
text: "Retry aborted fetch.",
|
||||
cfg: {},
|
||||
providerConfig: {
|
||||
apiKey: "google-test-key",
|
||||
},
|
||||
target: "audio-file",
|
||||
timeoutMs: 5_000,
|
||||
});
|
||||
|
||||
expect(requestSequence).toHaveBeenCalledTimes(2);
|
||||
expect(result.audioBuffer.subarray(44)).toEqual(pcm);
|
||||
});
|
||||
|
||||
it("does not retry non-transient Gemini TTS request failures", async () => {
|
||||
const requestSequence = vi.fn().mockRejectedValueOnce(new Error("invalid request"));
|
||||
postJsonRequestMock.mockImplementation(requestSequence);
|
||||
const provider = buildGoogleSpeechProvider();
|
||||
|
||||
await expect(
|
||||
provider.synthesize({
|
||||
text: "Do not retry this.",
|
||||
cfg: {},
|
||||
providerConfig: {
|
||||
apiKey: "google-test-key",
|
||||
},
|
||||
target: "audio-file",
|
||||
timeoutMs: 5_000,
|
||||
}),
|
||||
).rejects.toThrow("invalid request");
|
||||
|
||||
expect(requestSequence).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("falls back to GEMINI_API_KEY and configured Google API base URL", async () => {
|
||||
vi.stubEnv("GEMINI_API_KEY", "env-google-key");
|
||||
const requestMock = installGoogleTtsRequestMock();
|
||||
|
||||
@@ -107,6 +107,25 @@ class GoogleTtsRetryableError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
function isGoogleTtsRetryableError(err: unknown): boolean {
|
||||
if (err instanceof GoogleTtsRetryableError) {
|
||||
return true;
|
||||
}
|
||||
if (!(err instanceof Error)) {
|
||||
return false;
|
||||
}
|
||||
if (err.name === "AbortError") {
|
||||
return true;
|
||||
}
|
||||
const message = err.message.toLowerCase();
|
||||
return (
|
||||
message.includes("aborted") ||
|
||||
message.includes("timeout") ||
|
||||
message.includes("fetch failed") ||
|
||||
message.includes("network")
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeGoogleTtsModel(model: unknown): string {
|
||||
const trimmed = normalizeOptionalString(model);
|
||||
if (!trimmed) {
|
||||
@@ -509,7 +528,7 @@ async function synthesizeGoogleTtsPcm(params: {
|
||||
return await synthesizeGoogleTtsPcmOnce(params);
|
||||
} catch (err) {
|
||||
lastError = err;
|
||||
if (!(err instanceof GoogleTtsRetryableError) || attempt > 0) {
|
||||
if (!isGoogleTtsRetryableError(err) || attempt > 0) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,6 +685,7 @@ function shouldSkipToolNonceProbeMissForLiveModel(modelKey?: string): boolean {
|
||||
provider === "minimax" ||
|
||||
provider === "opencode" ||
|
||||
provider === "opencode-go" ||
|
||||
provider === "openrouter" ||
|
||||
provider === "xai" ||
|
||||
provider === "zai"
|
||||
) {
|
||||
@@ -703,6 +704,7 @@ describe("shouldSkipToolNonceProbeMissForLiveModel", () => {
|
||||
{ modelKey: "minimax/minimax-m1", expected: true },
|
||||
{ modelKey: "opencode/big-pickle", expected: true },
|
||||
{ modelKey: "opencode-go/glm-5", expected: true },
|
||||
{ modelKey: "openrouter/ai21/jamba-large-1.7", expected: true },
|
||||
{ modelKey: "xai/grok-4.1-fast", expected: true },
|
||||
{ modelKey: "zai/glm-5.1", expected: true },
|
||||
{ modelKey: "google/gemini-3-flash-preview", expected: true },
|
||||
|
||||
Reference in New Issue
Block a user