Solution to #4: Add abort support to the core ONNX provider chat function #10

Closed
elffuss-bot wants to merge 1 commits from item/0xefacf4f7864fc9d7fe853b2773f3274179396b5563dc0d992b891e41f6c232bc into main
3 changed files with 49 additions and 3 deletions

View File

@@ -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,

View File

@@ -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"
]
}
]
}

View File

@@ -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.<name>(...)
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)
})