From 7ad44b91d08e0dc1c2b358ad0c1e89c19a63e0b8 Mon Sep 17 00:00:00 2001 From: "kiloconnect[bot]" <240665456+kiloconnect[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 14:15:44 +0000 Subject: [PATCH 1/2] fix(fim): set has_error on microdollar_usage for upstream errors FIM parse functions never checked the HTTP status code, so 4xx/5xx responses from Mistral/Inception never set has_error=true in microdollar_usage. Mirror the pattern used by regular chat completions: initialise reportedError from statusCode>=400 in the streaming path, and include statusCode>=400 in the hasError expression for non-streaming. --- apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts b/apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts index 5a84550be1..3fad67cc9c 100644 --- a/apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts +++ b/apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts @@ -494,7 +494,8 @@ function computeFimMicrodollarCost(usage: FimUsage, provider: ProviderId): numbe function parseMistralFimUsageFromString( response: string, - provider: ProviderId + provider: ProviderId, + statusCode: number ): MicrodollarUsageStats { const json: MistralFimCompletion = JSON.parse(response); const cost_mUsd = computeFimMicrodollarCost(json.usage, provider); @@ -503,7 +504,7 @@ function parseMistralFimUsageFromString( messageId: json.id, model: json.model, responseContent: json.choices[0]?.text || '', - hasError: !json.model, + hasError: !json.model || statusCode >= 400, inference_provider: provider, inputTokens: json.usage.prompt_tokens, outputTokens: json.usage.completion_tokens, @@ -524,7 +525,8 @@ function parseMistralFimUsageFromString( async function parseMistralFimUsageFromStream( stream: ReadableStream, requestSpan: Span | undefined, - provider: ProviderId + provider: ProviderId, + statusCode: number ): Promise { requestSpan?.end(); const streamProcessingSpan = startInactiveSpan({ @@ -539,7 +541,7 @@ async function parseMistralFimUsageFromStream( let messageId: string | null = null; let model: string | null = null; let responseContent = ''; - let reportedError = false; + let reportedError = statusCode >= 400; const startedAt = performance.now(); let firstTokenReceived = false; let usage: FimUsage | undefined; @@ -627,13 +629,14 @@ export function countAndStoreFimUsage( const logFileExtension = usageContext.isStreaming ? '.log.resp.sse' : '.log.resp.json'; debugSaveProxyResponseStream(clonedResponse, logFileExtension); + const statusCode = usageContext.status_code ?? 0; const usageStatsPromise = !clonedResponse.body ? Promise.resolve(null) : usageContext.isStreaming - ? parseMistralFimUsageFromStream(clonedResponse.body, requestSpan, usageContext.provider) + ? parseMistralFimUsageFromStream(clonedResponse.body, requestSpan, usageContext.provider, statusCode) : clonedResponse .text() - .then(content => parseMistralFimUsageFromString(content, usageContext.provider)); + .then(content => parseMistralFimUsageFromString(content, usageContext.provider, statusCode)); after( usageStatsPromise.then(usageStats => { From d5ace23648479510ad441f38c496c7efe95fcd1f Mon Sep 17 00:00:00 2001 From: "kiloconnect[bot]" <240665456+kiloconnect[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 14:18:03 +0000 Subject: [PATCH 2/2] style: apply oxfmt formatting --- apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts b/apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts index 3fad67cc9c..527063d99c 100644 --- a/apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts +++ b/apps/web/src/lib/ai-gateway/llm-proxy-helpers.ts @@ -633,10 +633,17 @@ export function countAndStoreFimUsage( const usageStatsPromise = !clonedResponse.body ? Promise.resolve(null) : usageContext.isStreaming - ? parseMistralFimUsageFromStream(clonedResponse.body, requestSpan, usageContext.provider, statusCode) + ? parseMistralFimUsageFromStream( + clonedResponse.body, + requestSpan, + usageContext.provider, + statusCode + ) : clonedResponse .text() - .then(content => parseMistralFimUsageFromString(content, usageContext.provider, statusCode)); + .then(content => + parseMistralFimUsageFromString(content, usageContext.provider, statusCode) + ); after( usageStatsPromise.then(usageStats => {