@@ -291,6 +291,10 @@ export async function runLLM<TOutput extends ZodTypeAny>(
291291 unavailable_reason : 'LLM call failed before usage could be recorded' ,
292292 } ) ;
293293
294+ // Declare tokenUsage outside try block so it's accessible in catch
295+ // when JSON parsing or schema validation fails after a successful API call
296+ let tokenUsage : TokenUsage = noUsage ;
297+
294298 try {
295299 // Handle temperature based on model capabilities
296300 let temperature = 0.0 ;
@@ -319,7 +323,8 @@ export async function runLLM<TOutput extends ZodTypeAny>(
319323 // @ts -ignore - safety_identifier is not in the OpenAI types yet
320324 const response = await client . chat . completions . create ( params ) ;
321325
322- const tokenUsage = extractTokenUsage ( response ) ;
326+ // Extract token usage immediately after API call so it's available even if parsing fails
327+ tokenUsage = extractTokenUsage ( response ) ;
323328 const result = response . choices [ 0 ] ?. message ?. content ;
324329 if ( ! result ) {
325330 return [
@@ -356,6 +361,7 @@ export async function runLLM<TOutput extends ZodTypeAny>(
356361 }
357362
358363 // Fail-open on JSON parsing errors (malformed or non-JSON responses)
364+ // Use tokenUsage here since API call succeeded but response parsing failed
359365 if ( error instanceof SyntaxError || ( error as Error ) ?. constructor ?. name === 'SyntaxError' ) {
360366 console . warn ( 'LLM returned non-JSON or malformed JSON.' , error ) ;
361367 return [
@@ -366,11 +372,12 @@ export async function runLLM<TOutput extends ZodTypeAny>(
366372 error_message : 'LLM returned non-JSON or malformed JSON.' ,
367373 } ,
368374 } ) ,
369- noUsage ,
375+ tokenUsage ,
370376 ] ;
371377 }
372378
373379 // Fail-open on schema validation errors (e.g., wrong types like confidence as string)
380+ // Use tokenUsage here since API call succeeded but schema validation failed
374381 if ( error instanceof z . ZodError ) {
375382 console . warn ( 'LLM response validation failed.' , error ) ;
376383 return [
@@ -382,7 +389,7 @@ export async function runLLM<TOutput extends ZodTypeAny>(
382389 zod_issues : error . issues ?? [ ] ,
383390 } ,
384391 } ) ,
385- noUsage ,
392+ tokenUsage ,
386393 ] ;
387394 }
388395
0 commit comments