test / expert.test.cjs
const test = require('node:test');
const assert = require('node:assert/strict');
const {mkdtemp, writeFile, readFile, rm} = require('node:fs/promises');
const {tmpdir} = require('node:os');
const {join} = require('node:path');
const {consult} = require('../dist/expert.js');
async function fixture(t, overrides={}) {
const root = await mkdtemp(join(tmpdir(), 'deepseek-test-'));
t.after(() => rm(root, {recursive:true, force:true}));
const keyFile = join(root, 'key');
await writeFile(keyFile, 'sk-testfixture0000000000000000');
return { root, settings: {keyFile, model:'deepseek-v4-pro', maxOutput:2500,
thinking:false, dailyCalls:12, dailyTokens:100000, ...overrides},
args: {question:'Проверь этот технический вывод.', context:'',
reason:'insufficient_knowledge', uncertainty:'Не знаю точного закона.'},
directory:join(root,'usage')};
}
const ok = () => new Response(JSON.stringify({choices:[{message:{content:'Экспертный ответ',
reasoning_content:'SECRET REASONING'}, finish_reason:'stop'}],
usage:{prompt_tokens:100,completion_tokens:200}}), {status:200});
test('bounded request, direct official endpoint, no full history or reasoning returned', async t => {
const f=await fixture(t); let body;
const result=await consult(f.args,f.settings,undefined,{directory:f.directory,fetch:async(url,opts)=>{
assert.equal(url,'https://api.deepseek.com/chat/completions');
assert.equal(opts.redirect,'error'); body=JSON.parse(opts.body); return ok();
}});
assert.equal(body.thinking.type,'disabled'); assert.equal(body.max_tokens,2500);
assert.equal(body.messages.length,2); assert.match(result,/Экспертный ответ/);
assert.doesNotMatch(result,/SECRET REASONING/);
const log=await readFile(join(f.directory,'usage.json'),'utf8');
assert.doesNotMatch(log,/sk-|технический|Экспертный/);
assert.equal(JSON.parse(log).calls,1);
});
test('failed requests consume attempt and token reserve, cannot retry same prompt', async t=>{
const f=await fixture(t); let count=0;
const deps={directory:f.directory,fetch:async()=>{count++;return new Response('',{status:500});}};
await assert.rejects(consult(f.args,f.settings,undefined,deps),/HTTP 500/);
await assert.rejects(consult(f.args,f.settings,undefined,deps),/10 минут/);
assert.equal(count,1); assert.equal(JSON.parse(await readFile(join(f.directory,'usage.json'))).calls,1);
});
test('daily attempt ceiling persists across calls', async t=>{
const f=await fixture(t,{dailyCalls:1}); let count=0;
const deps={directory:f.directory,fetch:async()=>{count++;return ok();}};
await consult(f.args,f.settings,undefined,deps);
await assert.rejects(consult({...f.args,question:'Другой вопрос эксперту.'},f.settings,undefined,deps),/лимит попыток/);
assert.equal(count,1);
});
test('concurrent reservations cannot exceed one daily attempt', async t=>{
const f=await fixture(t,{dailyCalls:1}); let count=0;
const deps={directory:f.directory,fetch:async()=>{count++;return ok();}};
const results=await Promise.allSettled([
consult(f.args,f.settings,undefined,deps),
consult({...f.args,question:'Второй одновременный вопрос.'},f.settings,undefined,deps)]);
assert.equal(results.filter(r=>r.status==='fulfilled').length,1); assert.equal(count,1);
});
test('corrupt ledger and exhausted reservation fail closed before network', async t=>{
const f=await fixture(t,{dailyTokens:5000}); const deps={directory:f.directory,fetch:async()=>{throw Error('MUST NOT FETCH');}};
await assert.rejects(consult({...f.args,context:'а'.repeat(3000)},f.settings,undefined,deps),/резерв токенов/);
await writeFile(join(f.directory,'usage.json'),'broken');
await assert.rejects(consult(f.args,f.settings,undefined,deps),/Повреждён/);
});
test('thinking output truncation is explicit and empty final answer is never accepted', async t=>{
const f=await fixture(t,{thinking:true});
const deps={directory:f.directory,fetch:async(_url,opts)=>{
assert.equal(JSON.parse(opts.body).reasoning_effort,'low');
return new Response(JSON.stringify({choices:[{message:{content:'Частичный ответ'},finish_reason:'length'}]}));
}};
assert.match(await consult(f.args,f.settings,undefined,deps),/обрезан/);
await assert.rejects(consult({...f.args,question:'Иной вопрос эксперту.'},f.settings,undefined,
{...deps,fetch:async()=>new Response(JSON.stringify({choices:[{message:{content:'',reasoning_content:'THINK'}}]}))}),/не вернул/);
});
test / expert.test.cjs
const test = require('node:test');
const assert = require('node:assert/strict');
const {mkdtemp, writeFile, readFile, rm} = require('node:fs/promises');
const {tmpdir} = require('node:os');
const {join} = require('node:path');
const {consult} = require('../dist/expert.js');
async function fixture(t, overrides={}) {
const root = await mkdtemp(join(tmpdir(), 'deepseek-test-'));
t.after(() => rm(root, {recursive:true, force:true}));
const keyFile = join(root, 'key');
await writeFile(keyFile, 'sk-testfixture0000000000000000');
return { root, settings: {keyFile, model:'deepseek-v4-pro', maxOutput:2500,
thinking:false, dailyCalls:12, dailyTokens:100000, ...overrides},
args: {question:'Проверь этот технический вывод.', context:'',
reason:'insufficient_knowledge', uncertainty:'Не знаю точного закона.'},
directory:join(root,'usage')};
}
const ok = () => new Response(JSON.stringify({choices:[{message:{content:'Экспертный ответ',
reasoning_content:'SECRET REASONING'}, finish_reason:'stop'}],
usage:{prompt_tokens:100,completion_tokens:200}}), {status:200});
test('bounded request, direct official endpoint, no full history or reasoning returned', async t => {
const f=await fixture(t); let body;
const result=await consult(f.args,f.settings,undefined,{directory:f.directory,fetch:async(url,opts)=>{
assert.equal(url,'https://api.deepseek.com/chat/completions');
assert.equal(opts.redirect,'error'); body=JSON.parse(opts.body); return ok();
}});
assert.equal(body.thinking.type,'disabled'); assert.equal(body.max_tokens,2500);
assert.equal(body.messages.length,2); assert.match(result,/Экспертный ответ/);
assert.doesNotMatch(result,/SECRET REASONING/);
const log=await readFile(join(f.directory,'usage.json'),'utf8');
assert.doesNotMatch(log,/sk-|технический|Экспертный/);
assert.equal(JSON.parse(log).calls,1);
});
test('failed requests consume attempt and token reserve, cannot retry same prompt', async t=>{
const f=await fixture(t); let count=0;
const deps={directory:f.directory,fetch:async()=>{count++;return new Response('',{status:500});}};
await assert.rejects(consult(f.args,f.settings,undefined,deps),/HTTP 500/);
await assert.rejects(consult(f.args,f.settings,undefined,deps),/10 минут/);
assert.equal(count,1); assert.equal(JSON.parse(await readFile(join(f.directory,'usage.json'))).calls,1);
});
test('daily attempt ceiling persists across calls', async t=>{
const f=await fixture(t,{dailyCalls:1}); let count=0;
const deps={directory:f.directory,fetch:async()=>{count++;return ok();}};
await consult(f.args,f.settings,undefined,deps);
await assert.rejects(consult({...f.args,question:'Другой вопрос эксперту.'},f.settings,undefined,deps),/лимит попыток/);
assert.equal(count,1);
});
test('concurrent reservations cannot exceed one daily attempt', async t=>{
const f=await fixture(t,{dailyCalls:1}); let count=0;
const deps={directory:f.directory,fetch:async()=>{count++;return ok();}};
const results=await Promise.allSettled([
consult(f.args,f.settings,undefined,deps),
consult({...f.args,question:'Второй одновременный вопрос.'},f.settings,undefined,deps)]);
assert.equal(results.filter(r=>r.status==='fulfilled').length,1); assert.equal(count,1);
});
test('corrupt ledger and exhausted reservation fail closed before network', async t=>{
const f=await fixture(t,{dailyTokens:5000}); const deps={directory:f.directory,fetch:async()=>{throw Error('MUST NOT FETCH');}};
await assert.rejects(consult({...f.args,context:'а'.repeat(3000)},f.settings,undefined,deps),/резерв токенов/);
await writeFile(join(f.directory,'usage.json'),'broken');
await assert.rejects(consult(f.args,f.settings,undefined,deps),/Повреждён/);
});
test('thinking output truncation is explicit and empty final answer is never accepted', async t=>{
const f=await fixture(t,{thinking:true});
const deps={directory:f.directory,fetch:async(_url,opts)=>{
assert.equal(JSON.parse(opts.body).reasoning_effort,'low');
return new Response(JSON.stringify({choices:[{message:{content:'Частичный ответ'},finish_reason:'length'}]}));
}};
assert.match(await consult(f.args,f.settings,undefined,deps),/обрезан/);
await assert.rejects(consult({...f.args,question:'Иной вопрос эксперту.'},f.settings,undefined,
{...deps,fetch:async()=>new Response(JSON.stringify({choices:[{message:{content:'',reasoning_content:'THINK'}}]}))}),/не вернул/);
});