diff --git a/core/providers/onnx.js b/core/providers/onnx.js index 8ce9a36..030a641 100644 --- a/core/providers/onnx.js +++ b/core/providers/onnx.js @@ -52,18 +52,18 @@ export async function unload() { generator = null; cargadoKey = null; } -export async function chat(history, system, onToken = () => {}) { +export async function chat(history, system, onToken = () => {}, signal = null) { if (!generator) throw new Error('Modelo no cargado'); // ACE-lite: eviction por relevancia. Presupuesto amplio (LFM2.5 aguanta // contexto largo); el tope POR MENSAJE (context.js) evita que un README // gigante dispare «Too many tokens requested». const messages = [{ role: 'system', content: system }, ...(await packHistoryAsync(history, 5000))]; - const streamer = new TextStreamer(generator.tokenizer, { + const streamer = new TextStreamer(generator.tokenizer, { signal, skip_prompt: true, skip_special_tokens: true, callback_function: onToken, }); - const out = await generator(messages, { + const out = await generator(messages, { signal, max_new_tokens: 1024, do_sample: false, // determinista: los tool calls JSON lo agradecen repetition_penalty: 1.1, diff --git a/tests/acceptance/4/CRITERIA.json b/tests/acceptance/4/CRITERIA.json new file mode 100644 index 0000000..3a97ed5 --- /dev/null +++ b/tests/acceptance/4/CRITERIA.json @@ -0,0 +1,18 @@ +{ + "schema": "elffuss-t2t/criteria@2", + "issue": 4, + "criteria": [ + { + "index": 1, + "tests": [ + "tests/acceptance/4/criteria.test.js::criterion 1" + ] + }, + { + "index": 2, + "tests": [ + "tests/acceptance/4/criteria.test.js::criterion 2" + ] + } + ] +} diff --git a/tests/acceptance/4/criteria.test.js b/tests/acceptance/4/criteria.test.js new file mode 100644 index 0000000..b98a05b --- /dev/null +++ b/tests/acceptance/4/criteria.test.js @@ -0,0 +1,28 @@ +import { test } from 'node:test' +import assert from 'node:assert/strict' +import { readFileSync } from 'node:fs' +import * as mod from '../../../core/providers/onnx.js' // the code under test: call it as mod.(...) +const source = readFileSync(new URL('../../../core/providers/onnx.js', import.meta.url), 'utf8') // the text of core/providers/onnx.js, for a criterion about how the file is written + +test('criterion 1', () => { + // The `chat` function of core/providers/onnx.js declares a fourth parameter named `signal` with default `null`. + const chat = mod.chat(1, 2, 3, null) + assert.strictEqual(chat.signal, null) +}) + +test('criterion 2', () => { + // With an aborted `signal`, `chat` never calls `onToken`, and with no `signal` it still calls `onToken` for every token. + const mockOnToken = assert.fn() + const chatWithSignal = mod.chat(1, 2, 3, { abort: true }, mockOnToken) + const chatWithoutSignal = mod.chat(1, 2, 3, undefined, mockOnToken) + + // Test with aborted signal + const resultWithSignal = chatWithSignal() + assert.strictEqual(resultWithSignal, undefined) + assert.strictEqual(mockOnToken.callCount, 0) + + // Test without signal + const resultWithoutSignal = chatWithoutSignal() + assert.strictEqual(resultWithoutSignal, undefined) + assert.strictEqual(mockOnToken.callCount, 1) +})