Fix cost tracking accuracy and OpenRouter model pricing (#3189)

Co-authored-by: jack <>
Co-authored-by: angiejones <jones.angie@gmail.com>
This commit is contained in:
jack
2025-07-02 04:14:05 +02:00
committed by GitHub
parent 7f0053e6c2
commit 620474b76e
11 changed files with 574 additions and 649 deletions
+18 -5
View File
@@ -619,10 +619,22 @@ function ChatContent({
}));
}
// Reset token counters for the new model
setSessionTokenCount(0);
setSessionInputTokens(0);
setSessionOutputTokens(0);
// Restore token counters from session metadata instead of resetting to 0
// This preserves the accumulated session tokens when switching models
// and ensures cost tracking remains accurate across model changes
if (sessionMetadata) {
// Use Math.max to ensure non-negative values and handle potential data issues
setSessionTokenCount(Math.max(0, sessionMetadata.totalTokens || 0));
setSessionInputTokens(Math.max(0, sessionMetadata.accumulatedInputTokens || 0));
setSessionOutputTokens(Math.max(0, sessionMetadata.accumulatedOutputTokens || 0));
} else {
// Fallback: if no session metadata, preserve current session tokens instead of resetting
// This handles edge cases where metadata might not be available yet
console.warn(
'No session metadata available during model change, preserving current tokens'
);
}
// Only reset local token estimation counters since they're model-specific
setLocalInputTokens(0);
setLocalOutputTokens(0);
@@ -631,7 +643,7 @@ function ChatContent({
`${prevProviderRef.current}/${prevModelRef.current}`,
'to',
`${currentProvider}/${currentModel}`,
'- saved costs and reset token counters'
'- saved costs and restored session token counters'
);
}
@@ -644,6 +656,7 @@ function ChatContent({
sessionOutputTokens,
localInputTokens,
localOutputTokens,
sessionMetadata,
]);
const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
@@ -66,9 +66,7 @@ export function CostTracker({ inputTokens = 0, outputTokens = 0, sessionCosts }:
initializeCostDatabase();
// Update costs for all models in background
updateAllModelCosts().catch((error) => {
console.error('Failed to update model costs:', error);
});
updateAllModelCosts().catch(() => {});
}, [getProviders]);
useEffect(() => {
@@ -78,18 +76,12 @@ export function CostTracker({ inputTokens = 0, outputTokens = 0, sessionCosts }:
return;
}
console.log(`CostTracker: Loading cost info for ${currentProvider}/${currentModel}`);
try {
// First check sync cache
let costData = getCostForModel(currentProvider, currentModel);
if (costData) {
// We have cached data
console.log(
`CostTracker: Found cached data for ${currentProvider}/${currentModel}:`,
costData
);
setCostInfo(costData);
setPricingFailed(false);
setModelNotFound(false);
@@ -97,30 +89,19 @@ export function CostTracker({ inputTokens = 0, outputTokens = 0, sessionCosts }:
setHasAttemptedFetch(true);
} else {
// Need to fetch from backend
console.log(
`CostTracker: No cached data, fetching from backend for ${currentProvider}/${currentModel}`
);
setIsLoading(true);
const result = await fetchAndCachePricing(currentProvider, currentModel);
setHasAttemptedFetch(true);
if (result && result.costInfo) {
console.log(
`CostTracker: Fetched data for ${currentProvider}/${currentModel}:`,
result.costInfo
);
setCostInfo(result.costInfo);
setPricingFailed(false);
setModelNotFound(false);
} else if (result && result.error === 'model_not_found') {
console.log(
`CostTracker: Model not found in pricing data for ${currentProvider}/${currentModel}`
);
// Model not found in pricing database, but API call succeeded
setModelNotFound(true);
setPricingFailed(false);
} else {
console.log(`CostTracker: API failed for ${currentProvider}/${currentModel}`);
// API call failed or other error
const freeProviders = ['ollama', 'local', 'localhost'];
if (!freeProviders.includes(currentProvider.toLowerCase())) {
@@ -131,7 +112,6 @@ export function CostTracker({ inputTokens = 0, outputTokens = 0, sessionCosts }:
setIsLoading(false);
}
} catch (error) {
console.error('Error loading cost info:', error);
setHasAttemptedFetch(true);
// Only set pricing failed if we're not dealing with a known free provider
const freeProviders = ['ollama', 'local', 'localhost'];
@@ -194,8 +174,6 @@ export function CostTracker({ inputTokens = 0, outputTokens = 0, sessionCosts }:
return cost.toFixed(6);
};
// Debug logging removed
// Show loading state or when we don't have model/provider info
if (!currentModel || !currentProvider) {
return null;