|
| 1 | +import { describe, expect, it } from 'vitest'; |
| 2 | + |
| 3 | +import { |
| 4 | + resolveCompactionTokenBudget, |
| 5 | + resolveDynamicMaxTokens, |
| 6 | +} from '../src/provider-budget.js'; |
| 7 | + |
| 8 | +describe('resolveDynamicMaxTokens', () => { |
| 9 | + it('shrinks a Spark output budget from the complete Provider input footprint', () => { |
| 10 | + expect( |
| 11 | + resolveDynamicMaxTokens({ |
| 12 | + contextWindow: 128_000, |
| 13 | + configuredMaxTokens: 128_000, |
| 14 | + estimatedContextTokens: 100_000, |
| 15 | + }), |
| 16 | + ).toBe(25_952); |
| 17 | + }); |
| 18 | +}); |
| 19 | + |
| 20 | +describe('resolveCompactionTokenBudget', () => { |
| 21 | + it.each([ |
| 22 | + [200_000, 181_568], |
| 23 | + [400_000, 380_000], |
| 24 | + [512_000, 486_400], |
| 25 | + [1_000_000, 950_000], |
| 26 | + ] as const)('caps a %i-token context at the conservative Provider limit', (contextWindow, expected) => { |
| 27 | + expect( |
| 28 | + resolveCompactionTokenBudget({ |
| 29 | + contextWindow, |
| 30 | + configuredMaxOutputTokens: 16_384, |
| 31 | + }).providerInputLimit, |
| 32 | + ).toBe(expected); |
| 33 | + }); |
| 34 | + |
| 35 | + it.each([ |
| 36 | + ['1M context', 1_000_000, 128_000, 950_000, 828_400], |
| 37 | + ['512K context', 512_000, 128_000, 486_400, 364_800], |
| 38 | + ['roomy 400K context', 400_000, 128_000, 380_000, 285_000], |
| 39 | + ['gpt-5.4 output floor', 272_000, 128_000, 253_568, 193_800], |
| 40 | + ['MiniMax-M2.7 window', 200_000, 128_000, 181_568, 142_500], |
| 41 | + ['256K relay window', 256_000, 128_000, 237_568, 182_400], |
| 42 | + ['Spark dynamic fallback', 128_000, 128_000, 109_568, 91_200], |
| 43 | + ['1M context with a small output limit', 1_000_000, 32_000, 950_000, 919_600], |
| 44 | + ['64K context capped by the hard limit', 64_000, 128_000, 45_568, 45_568], |
| 45 | + ['caller-limited output', 65_536, 8_192, 49_152, 49_152], |
| 46 | + ] as const)( |
| 47 | + 'resolves the shared input limit and automatic trigger for %s', |
| 48 | + (_case, contextWindow, configuredMaxOutputTokens, providerInputLimit, automaticTriggerAt) => { |
| 49 | + expect( |
| 50 | + resolveCompactionTokenBudget({ contextWindow, configuredMaxOutputTokens }), |
| 51 | + ).toEqual({ providerInputLimit, automaticTriggerAt }); |
| 52 | + }, |
| 53 | + ); |
| 54 | + |
| 55 | + it.each([ |
| 56 | + ['65K context', 65_536, 46_694], |
| 57 | + ['Spark', 128_000, 106_035], |
| 58 | + ['large context', 272_000, 242_835], |
| 59 | + ] as const)( |
| 60 | + 'reserves a small configured output below the window-quarter cap for %s', |
| 61 | + (_case, contextWindow, automaticTriggerAt) => { |
| 62 | + expect( |
| 63 | + resolveCompactionTokenBudget({ |
| 64 | + contextWindow, |
| 65 | + configuredMaxOutputTokens: 16_384, |
| 66 | + }).automaticTriggerAt, |
| 67 | + ).toBe(automaticTriggerAt); |
| 68 | + }, |
| 69 | + ); |
| 70 | + |
| 71 | + it('leaves the configured output room when a large window reaches the trigger', () => { |
| 72 | + const contextWindow = 1_000_000; |
| 73 | + const configuredMaxTokens = 128_000; |
| 74 | + const { automaticTriggerAt } = resolveCompactionTokenBudget({ |
| 75 | + contextWindow, |
| 76 | + configuredMaxOutputTokens: configuredMaxTokens, |
| 77 | + }); |
| 78 | + |
| 79 | + expect( |
| 80 | + resolveDynamicMaxTokens({ |
| 81 | + contextWindow, |
| 82 | + configuredMaxTokens, |
| 83 | + estimatedContextTokens: automaticTriggerAt, |
| 84 | + }), |
| 85 | + ).toBe(configuredMaxTokens); |
| 86 | + }); |
| 87 | + |
| 88 | + it.each([Number.NaN, 0])('ignores an invalid configured output limit: %s', (configuredMaxOutputTokens) => { |
| 89 | + expect( |
| 90 | + resolveCompactionTokenBudget({ |
| 91 | + contextWindow: 65_536, |
| 92 | + configuredMaxOutputTokens, |
| 93 | + }).providerInputLimit, |
| 94 | + ).toBe(49_152); |
| 95 | + }); |
| 96 | + |
| 97 | + it('clamps an invalidly small context to one token', () => { |
| 98 | + expect( |
| 99 | + resolveCompactionTokenBudget({ |
| 100 | + contextWindow: 1, |
| 101 | + configuredMaxOutputTokens: 128_000, |
| 102 | + }), |
| 103 | + ).toEqual({ providerInputLimit: 1, automaticTriggerAt: 1 }); |
| 104 | + }); |
| 105 | +}); |
0 commit comments