mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-02 16:19:27 +00:00
fix(pricing): handle date-stamped 4.6 thinking model IDs
This commit is contained in:
@@ -734,7 +734,7 @@ const UNKNOWN_MODEL_PRICING: ModelPricing = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize model name for matching
|
* Normalize model name for matching
|
||||||
* Handles variations like provider prefixes, case differences, and date suffixes
|
* Handles variations like provider prefixes and case differences
|
||||||
*/
|
*/
|
||||||
function normalizeModelName(model: string): string {
|
function normalizeModelName(model: string): string {
|
||||||
// Remove provider prefixes (e.g., "anthropic/claude-..." -> "claude-...")
|
// Remove provider prefixes (e.g., "anthropic/claude-..." -> "claude-...")
|
||||||
@@ -747,10 +747,14 @@ function normalizeModelName(model: string): string {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Strip trailing date suffix from model name (e.g., "-20260101")
|
* Strip trailing date suffix from model name (e.g., "-20260101")
|
||||||
* Only strips 8-digit YYYYMMDD suffixes at the end of the string.
|
* Claude session IDs can place dates either at the end or before "-thinking".
|
||||||
*/
|
*/
|
||||||
function stripDateSuffix(model: string): string {
|
function stripDateSuffix(model: string): string {
|
||||||
return model.replace(/-\d{8}$/, '');
|
if (!model.startsWith('claude-')) {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
return model.replace(/-\d{8}(?=-thinking(?:$|:))/g, '').replace(/-\d{8}(?=$|:)/g, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
const NORMALIZED_PRICING_REGISTRY: Record<string, ModelPricing> = Object.entries(
|
const NORMALIZED_PRICING_REGISTRY: Record<string, ModelPricing> = Object.entries(
|
||||||
|
|||||||
@@ -120,6 +120,18 @@ describe('model-pricing', () => {
|
|||||||
expect(opus46.inputPerMillion).toBe(5.0);
|
expect(opus46.inputPerMillion).toBe(5.0);
|
||||||
expect(opus46.outputPerMillion).toBe(25.0);
|
expect(opus46.outputPerMillion).toBe(25.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should match date-stamped thinking Claude Opus 4.6 to correct pricing', () => {
|
||||||
|
const opus46 = getModelPricing('claude-opus-4-6-20260101-thinking');
|
||||||
|
expect(opus46.inputPerMillion).toBe(5.0);
|
||||||
|
expect(opus46.outputPerMillion).toBe(25.0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should match provider-prefixed date-stamped thinking model to correct pricing', () => {
|
||||||
|
const opus46 = getModelPricing('anthropic/claude-opus-4-6-20260101-thinking');
|
||||||
|
expect(opus46.inputPerMillion).toBe(5.0);
|
||||||
|
expect(opus46.outputPerMillion).toBe(25.0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('calculateCost', () => {
|
describe('calculateCost', () => {
|
||||||
@@ -209,6 +221,10 @@ describe('model-pricing', () => {
|
|||||||
expect(hasCustomPricing('qwen3-coder')).toBe(true);
|
expect(hasCustomPricing('qwen3-coder')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not treat date-stamped non-Claude IDs as deterministic aliases', () => {
|
||||||
|
expect(hasCustomPricing('qwen3-32b-20260101')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it('should return false for unknown models', () => {
|
it('should return false for unknown models', () => {
|
||||||
expect(hasCustomPricing('unknown-model-xyz')).toBe(false);
|
expect(hasCustomPricing('unknown-model-xyz')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user