AIX: fix Openrouter parsing

This commit is contained in:
Enrico Ros
2025-10-22 03:56:12 -07:00
parent 5f8d5678fa
commit d99668aa40
2 changed files with 31 additions and 10 deletions
@@ -576,9 +576,17 @@ function _fromOpenAIUsage(usage: OpenAIWire_API_Chat_Completions.Response['usage
// Upstream Cost Reporting
// [Perplexity, 2025-10-20]
if (!!usage.cost && typeof usage.cost === 'object' && 'total_cost' in usage.cost && typeof usage.cost.total_cost === 'number')
metricsUpdate.$cReported = Math.round(usage.cost.total_cost * 100 * 10000) / 10000;
// [Perplexity, 2025-10-20] - cost as object with total_cost
// [OpenRouter, 2025-10-22] - cost as direct number
if (usage.cost !== null && usage.cost !== undefined) {
if (typeof usage.cost === 'number') {
// OpenRouter sends cost directly as a number
metricsUpdate.$cReported = Math.round(usage.cost * 100 * 10000) / 10000;
} else if (typeof usage.cost === 'object' && 'total_cost' in usage.cost && typeof usage.cost.total_cost === 'number') {
// Perplexity sends cost as an object with total_cost
metricsUpdate.$cReported = Math.round(usage.cost.total_cost * 100 * 10000) / 10000;
}
}
// Time Metrics
@@ -418,6 +418,7 @@ export namespace OpenAIWire_API_Chat_Completions {
reasoning_tokens: z.number().optional(), // [Discord, 2024-04-10] reported missing
// text_tokens: z.number().optional(), // [Discord, 2024-04-10] revealed as present on custom OpenAI endpoint - not using it here yet
audio_tokens: z.number().optional(), // [OpenAI, 2024-10-01] audio tokens used in the completion (charged at a different rate)
// image_tokens: z.number().optional(), // [OpenRouter, 2025-10-22] first seen.. sounds likely?
accepted_prediction_tokens: z.number().optional(), // [OpenAI, 2024-11-05] Predicted Outputs
rejected_prediction_tokens: z.number().optional(), // [OpenAI, 2024-11-05] Predicted Outputs
}).optional() // not present in other APIs yet
@@ -427,13 +428,25 @@ export namespace OpenAIWire_API_Chat_Completions {
prompt_cache_hit_tokens: z.number().optional(),
prompt_cache_miss_tokens: z.number().optional(),
// [Perplexity, 2025-10-20] cost breakdown
cost: z.looseObject({
input_tokens_cost: z.number().optional(),
output_tokens_cost: z.number().optional(),
request_cost: z.number().optional(),
total_cost: z.number().optional(),
}).nullish(),
// [Perplexity, 2025-10-20] cost breakdown (object format)
// [OpenRouter, 2025-01-22] cost as direct number
cost: z.union([
z.number(), // OpenRouter sends cost as a number directly
z.looseObject({
input_tokens_cost: z.number().optional(),
output_tokens_cost: z.number().optional(),
request_cost: z.number().optional(),
total_cost: z.number().optional(),
}),
]).nullish(),
// [OpenRouter, 2025-10-22] additional usage fields when used with Chutes
// is_byok: z.boolean().optional(), // Bring Your Own Key indicator
// cost_details: z.object({
// upstream_inference_cost: z.number().optional(),
// upstream_inference_prompt_cost: z.number().optional(),
// upstream_inference_completions_cost: z.number().optional(),
// }).optional(),
}).nullable();
/**