fix(ai,coding-agent): expose provider timeout/retry controls closes #3627

This commit is contained in:
Mario Zechner
2026-04-24 13:32:44 +02:00
parent d06db09a53
commit c06750410a
11 changed files with 94 additions and 14 deletions

View File

@@ -10,6 +10,7 @@
- Fixed DeepSeek V4 session replay 400 errors by adding `thinkingFormat: "deepseek"` (sends `thinking: { type }` + `reasoning_effort`), a `reasoningEffortMap`, and `requiresReasoningContentOnAssistantMessages` compat that injects empty `reasoning_content` on all replayed assistant messages when reasoning is enabled ([#3636](https://github.com/badlogic/pi-mono/issues/3636))
- Fixed GPT-5.5 generated context window metadata to use the observed 272k limit.
- Fixed provider request controls to expose `timeoutMs` and `maxRetries` in stream options and forward them through OpenAI/Azure/Anthropic request options, preventing unconfigurable SDK timeout/retry defaults on long-running local inference requests ([#3627](https://github.com/badlogic/pi-mono/issues/3627))
## [0.70.0] - 2026-04-23

View File

@@ -457,7 +457,14 @@ export const streamAnthropic: StreamFunction<"anthropic-messages", AnthropicOpti
params = nextParams as MessageCreateParamsStreaming;
}
const response = await client.messages
.create({ ...params, stream: true }, { signal: options?.signal })
.create(
{ ...params, stream: true },
{
signal: options?.signal,
timeout: options?.timeoutMs,
maxRetries: options?.maxRetries,
},
)
.asResponse();
await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
stream.push({ type: "start", partial: output });

View File

@@ -92,7 +92,11 @@ export const streamAzureOpenAIResponses: StreamFunction<"azure-openai-responses"
params = nextParams as ResponseCreateParamsStreaming;
}
const { data: openaiStream, response } = await client.responses
.create(params, options?.signal ? { signal: options.signal } : undefined)
.create(params, {
signal: options?.signal,
timeout: options?.timeoutMs,
maxRetries: options?.maxRetries,
})
.withResponse();
await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
stream.push({ type: "start", partial: output });

View File

@@ -145,7 +145,11 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions", OpenA
params = nextParams as OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming;
}
const { data: openaiStream, response } = await client.chat.completions
.create(params, { signal: options?.signal })
.create(params, {
signal: options?.signal,
timeout: options?.timeoutMs,
maxRetries: options?.maxRetries,
})
.withResponse();
await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
stream.push({ type: "start", partial: output });

View File

@@ -99,7 +99,11 @@ export const streamOpenAIResponses: StreamFunction<"openai-responses", OpenAIRes
params = nextParams as ResponseCreateParamsStreaming;
}
const { data: openaiStream, response } = await client.responses
.create(params, options?.signal ? { signal: options.signal } : undefined)
.create(params, {
signal: options?.signal,
timeout: options?.timeoutMs,
maxRetries: options?.maxRetries,
})
.withResponse();
await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
stream.push({ type: "start", partial: output });

View File

@@ -11,6 +11,8 @@ export function buildBaseOptions(model: Model<Api>, options?: SimpleStreamOption
headers: options?.headers,
onPayload: options?.onPayload,
onResponse: options?.onResponse,
timeoutMs: options?.timeoutMs,
maxRetries: options?.maxRetries,
maxRetryDelayMs: options?.maxRetryDelayMs,
metadata: options?.metadata,
};

View File

@@ -101,6 +101,16 @@ export interface StreamOptions {
* Not supported by all providers (e.g., AWS Bedrock uses SDK auth).
*/
headers?: Record<string, string>;
/**
* HTTP request timeout in milliseconds for providers/SDKs that support it.
* For example, OpenAI and Anthropic SDK clients default to 10 minutes.
*/
timeoutMs?: number;
/**
* Maximum retry attempts for providers/SDKs that support client-side retries.
* For example, OpenAI and Anthropic SDK clients default to 2.
*/
maxRetries?: number;
/**
* Maximum delay in milliseconds to wait for a retry when the server requests a long wait.
* If the server's requested delay exceeds this value, the request fails immediately