File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -61,14 +61,15 @@ const MAX_TIMEOUT_RETRIES = 3
6161
6262// Gateways report their own provider timeouts as ordinary failures: OpenCode Zen answers a dead
6363// upstream in-band with `Streaming response failed: [504] Provider timed out after Nms`, and the
64- // status never reaches the reason. The status and message checks keep those attempts on the same
65- // cap as local transport timeouts instead of the full general allowance.
64+ // status never reaches the reason. Restricting the status and message checks to the gateway
65+ // failure shapes keeps WebSocket idle/connect timeouts and unrelated messages on the general
66+ // allowance.
6667const isTimeout = ( error : AIError ) =>
67- error . reason . _tag === "Timeout" ||
6868 ( error . reason . _tag === "Transport" && error . reason . code === "Timeout" ) ||
69- error . reason . http ?. status === 408 ||
70- error . reason . http ?. status === 504 ||
71- / \b t i m e d ? [ - ] ? o u t \b / i. test ( error . reason . message )
69+ ( ( error . reason . _tag === "ProviderInternal" || error . reason . _tag === "UnknownProvider" ) &&
70+ ( error . reason . http ?. status === 408 ||
71+ error . reason . http ?. status === 504 ||
72+ / \b t i m e d ? [ - ] ? o u t \b / i. test ( error . reason . message ) ) )
7273
7374export const policy = ( sessionID : SessionSchema . ID ) =>
7475 Effect . gen ( function * ( ) {
Original file line number Diff line number Diff line change @@ -19,6 +19,14 @@ const gatewayTimeout = new AIError({
1919const badGateway = new AIError ( {
2020 reason : new ProviderInternalError ( { message : "Streaming response failed: [502] Upstream error" } ) ,
2121} )
22+ const socketTimeout = new AIError ( {
23+ reason : new TransportError ( {
24+ message : "Timed out waiting for WebSocket data" ,
25+ transport : "websocket" ,
26+ operation : "read" ,
27+ code : "idle-timeout" ,
28+ } ) ,
29+ } )
2230
2331const input = ( cause : AIError ) => ( {
2432 cause,
@@ -74,4 +82,10 @@ describe("SessionRunnerRetry.policy", () => {
7482 expect ( yield * decisions ( badGateway , 10 ) ) . toEqual ( Array ( 10 ) . fill ( true ) )
7583 } ) ,
7684 )
85+
86+ it . effect ( "keeps websocket idle timeouts on the general allowance" , ( ) =>
87+ Effect . gen ( function * ( ) {
88+ expect ( yield * decisions ( socketTimeout , 10 ) ) . toEqual ( Array ( 10 ) . fill ( true ) )
89+ } ) ,
90+ )
7791} )
You can’t perform that action at this time.
0 commit comments