-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
fix: missing i18n keys and streaming fetch timeout (#748, #769) #779
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -264,13 +264,12 @@ export class BaseExecutor { | |||||||||||||||||||||||||||||||||||||||||||||||||
| const transformedBody = this.transformRequest(model, body, stream, credentials); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // For non-streaming requests, apply a fetch timeout to prevent stalled connections. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Streaming requests skip the timeout — they use stream idle detection instead. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const timeoutSignal = !stream ? AbortSignal.timeout(FETCH_TIMEOUT_MS) : null; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const combinedSignal = | ||||||||||||||||||||||||||||||||||||||||||||||||||
| signal && timeoutSignal | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ? mergeAbortSignals(signal, timeoutSignal) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| : signal || timeoutSignal; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Apply timeout to all requests. Non-streaming requests need this to prevent | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // stalled connections. Streaming requests also need it for the initial fetch() call | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // to prevent hanging on unresponsive providers (e.g. 300s TCP default timeout — #769). | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Stream idle detection (STREAM_IDLE_TIMEOUT_MS) handles stalls after data starts flowing. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const timeoutSignal = AbortSignal.timeout(FETCH_TIMEOUT_MS); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const combinedSignal = signal ? mergeAbortSignals(signal, timeoutSignal) : timeoutSignal; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+272
to
273
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const combinedSignal = signal ? mergeAbortSignals(signal, timeoutSignal) : timeoutSignal; | |
| let combinedSignal: AbortSignal | undefined; | |
| if (signal) { | |
| const controller = new AbortController(); | |
| const forwardAbort = (src: AbortSignal) => { | |
| if (src.aborted) { | |
| controller.abort(src.reason); | |
| } else { | |
| src.addEventListener( | |
| "abort", | |
| () => controller.abort(src.reason), | |
| { once: true }, | |
| ); | |
| } | |
| }; | |
| forwardAbort(signal); | |
| forwardAbort(timeoutSignal); | |
| combinedSignal = controller.signal; | |
| } else { | |
| combinedSignal = timeoutSignal; | |
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -648,7 +648,9 @@ | |
| "cursor": "Cursor AI Code Editor", | ||
| "continue": "Continue AI Assistant", | ||
| "opencode": "OpenCode AI coding agent (Terminal)", | ||
| "kiro": "Amazon Kiro — AI-powered IDE" | ||
| "kiro": "Amazon Kiro — AI-powered IDE", | ||
| "windsurf": "Windsurf AI Code Editor", | ||
| "copilot": "GitHub Copilot AI Assistant" | ||
|
Comment on lines
+651
to
+653
|
||
| }, | ||
| "guides": { | ||
| "cursor": { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AbortSignal.timeout(FETCH_TIMEOUT_MS)applies to the entire streaming request lifetime, not just the initial connection. Withsignalalways provided in streaming mode (viastreamController.signal), this will abort long-running streams afterFETCH_TIMEOUT_MSeven if data is flowing, which conflicts with the comment/PR intent of only protecting the initialfetch()hang. If the goal is only an initial connect/headers timeout, use a separate AbortController timer that is cleared once the response is established (or once the first chunk arrives), and rely onSTREAM_IDLE_TIMEOUT_MSthereafter.