@@ -162,6 +162,38 @@ export async function transformGeminiResponse(
162162 try {
163163 const text = await response . text ( ) ;
164164 const headers = new Headers ( response . headers ) ;
165+
166+ // Extract retry timing from Google's structured error response
167+ // Google returns retry timing in error.details[].retryDelay: "55.846891726s"
168+ if ( ! response . ok && text ) {
169+ try {
170+ const errorBody = JSON . parse ( text ) ;
171+ if ( errorBody ?. error ?. details && Array . isArray ( errorBody . error . details ) ) {
172+ // Look for RetryInfo type
173+ const retryInfo = errorBody . error . details . find (
174+ ( detail : any ) => detail [ '@type' ] === 'type.googleapis.com/google.rpc.RetryInfo'
175+ ) ;
176+
177+ if ( retryInfo ?. retryDelay ) {
178+ // Parse "55.846891726s" format
179+ const match = retryInfo . retryDelay . match ( / ^ ( [ \d . ] + ) s $ / ) ;
180+ if ( match && match [ 1 ] ) {
181+ const retrySeconds = parseFloat ( match [ 1 ] ) ;
182+ if ( ! isNaN ( retrySeconds ) && retrySeconds > 0 ) {
183+ // Add both formats for compatibility
184+ const retryAfterSec = Math . ceil ( retrySeconds ) . toString ( ) ;
185+ const retryAfterMs = Math . ceil ( retrySeconds * 1000 ) . toString ( ) ;
186+ headers . set ( 'Retry-After' , retryAfterSec ) ;
187+ headers . set ( 'retry-after-ms' , retryAfterMs ) ;
188+ }
189+ }
190+ }
191+ }
192+ } catch ( parseError ) {
193+ // If JSON parsing fails, continue without retry headers
194+ }
195+ }
196+
165197 const init = {
166198 status : response . status ,
167199 statusText : response . statusText ,
0 commit comments