import assert from 'node:assert/strict'; import test from 'node:test'; import { seededRandom, sample, validateSettings } from '../src/sampling.js'; const defaults = { seed: 20261007, temperature: 0.5, topP: 0.9, topK: 0, maxTokens: 512 }; test('greedy sampling handles negative logits and consumes no randomness', () => { assert.equal(sample([-3, -1, -2], { ...defaults, temperature: 0 }, () => { throw new Error('Unexpected random draw'); }), 1); }); test('nucleus keeps the token that crosses the probability threshold', () => { assert.equal(sample([Math.log(0.5), Math.log(0.3), Math.log(0.2)], { ...defaults, temperature: 1, topP: 0.6 }, () => 0.99), 1); }); test('top-k removes low logits but preserves ties at its cutoff', () => { assert.equal(sample([10, 9, 9, -100], { ...defaults, temperature: 1, topP: 1, topK: 2 }, () => 0.999), 2); }); test('seeds repeat sampled experiments, with zero accepted as a real seed', () => { const run = seed => { const random = seededRandom(seed); return Array.from({ length: 64 }, () => sample([0, 0, 0], { ...defaults, temperature: 1, topP: 1 }, random)); }; assert.deepEqual(run(0), run(0)); assert.notDeepEqual(run(0), run(1)); }); test('invalid settings fail before inference, and full context length is accepted', () => { for (const settings of [{ seed: -1 }, { seed: 2 ** 32 }, { temperature: NaN }, { topP: 0 }, { topK: 379 }, { maxTokens: 2048 }]) assert.throws(() => validateSettings({ ...defaults, ...settings })); assert.doesNotThrow(() => validateSettings({ ...defaults, seed: 0, temperature: 0, maxTokens: 2047 })); });