@@ -265,6 +265,8 @@ export const OpenAIChatUsage = Schema.StructWithRest(
265265 prompt_cache_hit_tokens : optionalNull ( Schema . Number ) ,
266266 cache_read_input_tokens : optionalNull ( Schema . Number ) ,
267267 cache_created_input_tokens : optionalNull ( Schema . Number ) ,
268+ // GitHub Copilot reports reasoning at the top level instead of in `completion_tokens_details`.
269+ reasoning_tokens : optionalNull ( Schema . Number ) ,
268270 prompt_tokens_details : optionalNull (
269271 Schema . StructWithRest (
270272 Schema . Struct ( {
@@ -967,15 +969,22 @@ const mapUsage = (
967969) : Usage | undefined => {
968970 if ( ! usage ) return undefined
969971 const input = usage . prompt_tokens ?? undefined
970- const output = usage . completion_tokens ?? undefined
972+ const completion = usage . completion_tokens ?? undefined
971973 const cached =
972974 usage . prompt_tokens_details ?. cached_tokens ??
973975 usage . prompt_cache_hit_tokens ??
974976 usage . cached_tokens ??
975977 usage . cache_read_input_tokens ??
976978 undefined
977979 const cacheWrite = usage . prompt_tokens_details ?. cache_write_tokens ?? usage . cache_created_input_tokens ?? undefined
978- const reasoning = usage . completion_tokens_details ?. reasoning_tokens ?? undefined
980+ const reasoning = usage . completion_tokens_details ?. reasoning_tokens ?? usage . reasoning_tokens ?? undefined
981+ // Copilot's Gemini counts reasoning beside `completion_tokens` rather than inside it; the total tells which.
982+ const output =
983+ completion !== undefined &&
984+ reasoning !== undefined &&
985+ usage . total_tokens === ProviderShared . sumTokens ( input , completion , reasoning )
986+ ? completion + reasoning
987+ : completion
979988 const nonCached = ProviderShared . subtractTokens ( input , ProviderShared . sumTokens ( cached , cacheWrite ) )
980989 return new Usage ( {
981990 inputTokens : input ,
@@ -1128,6 +1137,14 @@ const step = (state: ParserState, event: OpenAIChatEvent) =>
11281137 ? {
11291138 normalized : yield * mapFinishReason ( event , rawFinishReason ) ,
11301139 raw : choice ?. native_finish_reason ?? rawFinishReason ,
1140+ ...( rawFinishReason === "content_filter"
1141+ ? {
1142+ category : ProviderShared . contentFilterCategory (
1143+ choice ?. delta ?. copilot_annotations ,
1144+ choice ?. content_filter_results ,
1145+ ) ,
1146+ }
1147+ : { } ) ,
11311148 }
11321149 : state . finishReason
11331150 const delta = choice ?. delta
0 commit comments