mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-18 16:02:10 +00:00
fix: keep alias suffixes resolving to their model's price
This commit is contained in:
@@ -116,6 +116,9 @@ function normalizeVersionSeparators(model: string): string {
|
||||
return model.replace(/\./g, '-')
|
||||
}
|
||||
|
||||
/** Suffixes that name a route to a model rather than a different model. */
|
||||
const DECORATIVE_SUFFIXES = ['latest', 'preview', 'beta', 'stable']
|
||||
|
||||
/**
|
||||
* Compile a most-specific-first `[name, value]` table into matchers against the
|
||||
* bare model id. Shared with the pricing table so both resolve the same set of
|
||||
@@ -140,11 +143,13 @@ export function buildModelMatchers<T>(
|
||||
/\d$/.test(pattern) ? '(?!\\d)' : '',
|
||||
// A named sub-model (`gpt-5-pro`, `gpt-5-mini`) is a different model with
|
||||
// its own price, not another route to this one — so under strictVariants an
|
||||
// entry does not match when a further *name* segment follows. Date suffixes
|
||||
// (`-20251101`) and Bedrock's `-v1` are route decorations, not sub-models,
|
||||
// and still match. Off by default: for a context window an inherited value
|
||||
// is a safe approximation, for a price it is a wrong number.
|
||||
strictVariants ? '(?!-(?!v\\d)[a-z])' : ''
|
||||
// entry does not match when a further *name* segment follows. What follows
|
||||
// is only a decoration when it is a date (`-20251101`), Bedrock's `-v1`, or
|
||||
// one of the alias words below (`claude-3-5-haiku-latest` is the same model
|
||||
// as `claude-3-5-haiku`, and is a shipped default). Off by default: for a
|
||||
// context window an inherited value is a safe approximation, for a price it
|
||||
// is a wrong number.
|
||||
strictVariants ? `(?!-(?!v\\d|${DECORATIVE_SUFFIXES.join('|')})[a-z])` : ''
|
||||
].join('')
|
||||
return [new RegExp(pattern + guards), value]
|
||||
})
|
||||
|
||||
@@ -39,12 +39,22 @@ describe('resolveModelPrice', () => {
|
||||
})
|
||||
|
||||
it('still resolves the route decorations that name the same model', () => {
|
||||
// Dates and Bedrock's -v1 are ways of spelling one model, not sub-models.
|
||||
// Dates, Bedrock's -v1 and floating aliases are ways of spelling one model,
|
||||
// not sub-models. `claude-3-5-haiku-latest` is a shipped picker default, so
|
||||
// unpricing it would silently disable cost tracking out of the box.
|
||||
expect(resolveModelPrice('anthropic', 'claude-opus-4-5-20251101', undefined)?.price.input).toBe(5)
|
||||
expect(
|
||||
resolveModelPrice('bedrock', 'anthropic.claude-sonnet-4-6-20250101-v1:0', undefined)?.price
|
||||
.input
|
||||
).toBe(3)
|
||||
expect(resolveModelPrice('anthropic', 'claude-3-5-haiku-latest', undefined)?.price.input).toBe(
|
||||
0.8
|
||||
)
|
||||
expect(
|
||||
resolveModelPrice('openrouter', '~anthropic/claude-sonnet-latest', undefined)?.price.input
|
||||
).toBe(3)
|
||||
// …while a genuine sub-model stays unpriced.
|
||||
expect(resolveModelPrice('openai', 'gpt-5-pro', undefined)).toBeUndefined()
|
||||
})
|
||||
|
||||
it('prefers a workspace override, keeping the model’s own cache ratios', () => {
|
||||
|
||||
Reference in New Issue
Block a user