fix(openai): extend Azure image timeout

Closes #71705
This commit is contained in:
Peter Steinberger
2026-04-25 23:34:18 +01:00
committed by GitHub
parent e640c0a95f
commit e4bfc8066e
4 changed files with 44 additions and 3 deletions

View File

@@ -66,6 +66,9 @@ Docs: https://docs.openclaw.ai
internal calls no longer hit `scope-upgrade` pairing prompts while remote,
browser, node, device-token, and explicit-device paths still require normal
pairing approval. Fixes #63548.
- Providers/Azure OpenAI: give deployment-scoped image generation requests a
longer 600s default timeout so slow `gpt-image-2` generations can complete
without a per-call `timeoutMs`. Fixes #71705. Thanks @voytas75.
- CLI/gateway: keep diagnostic probes from creating first-time read-only device
pairings, while still reusing cached device tokens for detailed read probes.
Fixes #71766. Thanks @SunboZ.

View File

@@ -543,6 +543,8 @@ For image-generation requests on a recognized Azure host, OpenClaw:
- Sends the `api-key` header instead of `Authorization: Bearer`
- Uses deployment-scoped paths (`/openai/deployments/{deployment}/...`)
- Appends `?api-version=...` to each request
- Uses a 600s default request timeout for Azure image-generation calls.
Per-call `timeoutMs` values still override this default.
Other base URLs (public OpenAI, OpenAI-compatible proxies) keep the standard
OpenAI image request shape.

View File

@@ -1316,6 +1316,35 @@ describe("openai image generation provider", () => {
n: 1,
size: "1024x1024",
},
timeoutMs: 600_000,
}),
);
});
it("lets explicit timeoutMs override the Azure image default", async () => {
mockGeneratedPngResponse();
const provider = buildOpenAIImageGenerationProvider();
await provider.generateImage({
provider: "openai",
model: "gpt-image-2-1",
prompt: "Azure cat",
cfg: {
models: {
providers: {
openai: {
baseUrl: "https://myresource.openai.azure.com/openai/v1",
models: [],
},
},
},
},
timeoutMs: 123_456,
});
expect(postJsonRequestMock).toHaveBeenCalledWith(
expect.objectContaining({
timeoutMs: 123_456,
}),
);
});

View File

@@ -32,6 +32,7 @@ const DEFAULT_OPENAI_CODEX_IMAGE_RESPONSES_MODEL = "gpt-5.5";
const OPENAI_CODEX_IMAGE_INSTRUCTIONS = "You are an image generation assistant.";
const OPENAI_TRANSPARENT_BACKGROUND_IMAGE_MODEL = "gpt-image-1.5";
const DEFAULT_OPENAI_IMAGE_TIMEOUT_MS = 180_000;
const DEFAULT_AZURE_OPENAI_IMAGE_TIMEOUT_MS = 600_000;
const DEFAULT_OUTPUT_MIME = "image/png";
const DEFAULT_OUTPUT_EXTENSION = "png";
const DEFAULT_SIZE = "1024x1024";
@@ -91,8 +92,14 @@ function sanitizeLogValue(value: unknown): string {
: cleaned;
}
function resolveOpenAIImageTimeoutMs(timeoutMs: number | undefined): number {
return timeoutMs ?? DEFAULT_OPENAI_IMAGE_TIMEOUT_MS;
function resolveOpenAIImageTimeoutMs(
timeoutMs: number | undefined,
options?: { isAzure?: boolean },
): number {
return (
timeoutMs ??
(options?.isAzure ? DEFAULT_AZURE_OPENAI_IMAGE_TIMEOUT_MS : DEFAULT_OPENAI_IMAGE_TIMEOUT_MS)
);
}
function resolveOpenAIImageCount(count: number | undefined): number {
@@ -746,7 +753,7 @@ export function buildOpenAIImageGenerationProvider(): ImageGenerationProvider {
});
const count = resolveOpenAIImageCount(req.count);
const size = req.size ?? DEFAULT_SIZE;
const timeoutMs = resolveOpenAIImageTimeoutMs(req.timeoutMs);
const timeoutMs = resolveOpenAIImageTimeoutMs(req.timeoutMs, { isAzure });
const url = isAzure
? buildAzureImageUrl(rawBaseUrl, model, isEdit ? "edits" : "generations")
: `${baseUrl}/images/${isEdit ? "edits" : "generations"}`;