Files
gnome-jarvis/vendor/agent-harness/test/test.js
T
snxraven 0e52942b8b
Rolling release / release (push) Successful in 8m58s
Better Search
2026-09-12 12:33:52 -04:00

410 lines
16 KiB
JavaScript

'use strict';
const assert = require('assert');
const path = require('path');
const os = require('os');
const fs = require('fs');
const catalog = require('../lib/catalog.js');
const compaction = require('../agent/compaction.js');
const sr = require('../agent/search-replace.js');
const toolSet = require('../agent/tool-set.js');
const prompts = require('../agent/prompts.js');
const net = require('../lib/net.js');
const customTools = require('../agent/custom-tools.js');
const planMode = require('../agent/plan-mode.js');
const todos = require('../agent/todos.js');
const stationarity = require('../agent/stationarity.js');
const truncate = require('../agent/truncate.js');
const permRules = require('../agent/perm-rules.js');
const policy = require('../agent/policy.js');
const toolBudget = require('../agent/tool-budget.js');
const paths = require('../lib/paths.js');
const device = require('../lib/device.js');
const tools = require('../agent/tools.js');
function testCatalog() {
assert.strictEqual(catalog.resolveModelConstant('qwen3.5-4b'), 'QWEN3_5_4B_MULTIMODAL_Q4_K_M');
assert.strictEqual(catalog.resolveModelConstant('gemma4-4b'), 'GEMMA4_4B_MULTIMODAL_Q4_K_M');
assert.strictEqual(catalog.resolveModelConstant('qwen3-8b'), 'QWEN3_8B_INST_Q4_K_M');
assert.strictEqual(catalog.resolveModelConstant('qwen3vl-2b'), 'QWEN3_VL_2B_INSTRUCT_Q4_K_M');
assert.strictEqual(catalog.findCatalogEntry('gemma4-4b').vision, true);
assert.strictEqual(catalog.findCatalogEntry('qwen3-8b').vision, false);
assert.strictEqual(catalog.toolDialectFor('gemma4-4b'), 'gemma4');
assert.strictEqual(catalog.toolDialectFor('qwen3-8b'), 'hermes');
assert.ok(/~5 GB/.test(catalog.catalogLabel(catalog.findCatalogEntry('qwen3-8b'))));
assert.ok(catalog.FALLBACK_LLM_IDS.indexOf('gemma4-4b') >= 0);
const listed = catalog.listCatalog().find((m) => m.id === 'gemma4-2b');
assert.ok(listed && listed.label.indexOf('~3.5 GB') >= 0);
}
function hugeToolDefs() {
return Array.from({ length: 24 }, (_, i) => ({
name: 'tool_' + i,
description: 'd'.repeat(400),
parameters: { type: 'object', properties: { q: { type: 'string' } } },
}));
}
function testCompaction() {
const sys = { role: 'system', content: 'sys' };
const user = { role: 'user', content: 'hello' };
const hist = [sys, user];
for (let i = 0; i < 40; i++) {
hist.push({ role: 'assistant', content: 'x'.repeat(200) });
hist.push({ role: 'tool', name: 'read_file', content: 'y'.repeat(200) });
}
assert.ok(compaction.shouldCompact(hist, [], 1024));
const out = compaction.compact(hist, { budgetTokens: 400, tools: [] });
assert.ok(out.length < hist.length);
assert.strictEqual(out[0].role, 'system');
assert.ok(compaction.isOverflowError(new Error('prompt too long for context window')));
const tools = hugeToolDefs();
const short = [
{ role: 'system', content: 'You are Jarvis' },
{ role: 'assistant', content: 'Hello! How can I help you today?' },
{ role: 'user', content: 'Hi, please tell me about my computer.' },
];
assert.ok(compaction.toolTokens(tools) > 2000);
assert.equal(compaction.shouldCompact(short, tools, 8192), false);
const kept = compaction.compact(short, {
budgetTokens: compaction.historyBudget(8192, tools, 0),
tools,
});
assert.strictEqual(kept.length, short.length);
assert.strictEqual(kept[2].content, short[2].content);
assert.ok(JSON.stringify(kept).indexOf('Earlier turns were compacted') < 0);
const four = short.concat([
{ role: 'assistant', content: 'Let me look.' },
{ role: 'user', content: 'Go ahead.' },
]);
assert.ok(compaction.nonSystemCount(four) >= compaction.MIN_COMPACT_MESSAGES);
const stillKept = compaction.heuristicCompact(four, {
budgetTokens: compaction.historyBudget(8192, tools, 0),
tools,
});
assert.ok(stillKept.some((m) => String(m.content).indexOf('tell me about my computer') >= 0));
assert.ok(JSON.stringify(stillKept).indexOf('Earlier turns were compacted') < 0);
assert.strictEqual(compaction.autoContinue([{ role: 'assistant', content: 'hi' }], { voice: true }), null);
assert.ok(compaction.autoContinue([{ role: 'assistant', content: 'hi' }]));
assert.ok(compaction.compactReminder({ voice: true }).indexOf('Do not greet') >= 0);
assert.ok(compaction.VOICE_COMPACT_PROMPT.indexOf('Do not greet') >= 0);
}
function testSearchReplace() {
const applied = sr.applySearchReplace('aaa bbb aaa', 'bbb', 'ccc', false);
assert.strictEqual(applied.text, 'aaa ccc aaa');
assert.strictEqual(applied.replacements, 1);
}
function testToolSet() {
assert.ok(toolSet.isHostWorkspaceTool('read_file'));
assert.ok(!toolSet.parseHostWorkspace({ hostWorkspace: false }));
const all = [
{ name: 'read_file' },
{ name: 'todo_write' },
{ name: 'web_fetch' },
];
const page = toolSet.filterBuiltinSchemas(all, { hostWorkspace: false, builtinTools: ['todo_write'] });
assert.ok(!page.find((t) => t.name === 'read_file'));
const withFetch = toolSet.filterBuiltinSchemas(all, {
hostWorkspace: true,
builtinTools: ['web_fetch'],
webFetch: true,
});
assert.ok(withFetch.find((t) => t.name === 'web_fetch'));
const noFetch = toolSet.filterBuiltinSchemas(all, {
hostWorkspace: true,
builtinTools: ['web_fetch'],
});
assert.ok(!noFetch.find((t) => t.name === 'web_fetch'));
}
function testPrompts() {
assert.ok(prompts.DEFAULT_SYSTEM.indexOf('QVAC') >= 0);
assert.ok(prompts.DEFAULT_SYSTEM.indexOf('BridgeSwarm') < 0);
const page = prompts.assemble({ cwd: 'container', hostWorkspace: false });
assert.ok(page.indexOf('host filesystem') >= 0);
const voice = prompts.assemble({
personality: 'voice',
extra: 'You are Jarvis, a local Ubuntu GNOME voice assistant.',
cwd: '/tmp/jarvis',
hostWorkspace: true,
fsRead: () => '# AGENTS.md\nFollow coding-agent rules.',
});
assert.ok(voice.indexOf('You are Jarvis') >= 0);
assert.ok(voice.indexOf(prompts.DEFAULT_SYSTEM) < 0);
assert.ok(voice.indexOf('coding agent') < 0);
assert.ok(voice.indexOf('AGENTS.md') < 0);
assert.ok(voice.indexOf('Current workspace:') >= 0);
}
function testNet() {
assert.throws(() => net.assertPublicHttpUrl('http://127.0.0.1/x'));
assert.throws(() => net.assertPublicHttpUrl('http://192.168.1.1/x'));
const u = net.assertPublicHttpUrl('https://example.com/a');
assert.strictEqual(u.hostname, 'example.com');
assert.strictEqual(net.assertHttpUrl('https://ifconfig.me/ip').hostname, 'ifconfig.me');
assert.strictEqual(net.assertHttpUrl('http://192.168.1.1/status').hostname, '192.168.1.1');
assert.throws(() => net.assertHttpUrl('file:///etc/passwd'));
}
function testCustomTools() {
customTools.clear('s1');
customTools.setSession('s1', { hostWorkspace: false });
customTools.register('s1', {
name: 'ping',
description: 'ping',
parameters: { type: 'object', properties: {} },
execute: () => ({ ok: true }),
});
assert.ok(customTools.has('s1', 'ping'));
assert.strictEqual(typeof customTools.getHandler('s1', 'ping'), 'function');
customTools.clear('s1');
}
function testPlanTodosStationarity() {
const pm = planMode.create();
planMode.activate(pm);
assert.ok(planMode.isActive(pm));
const blocked = planMode.gateWrite(pm, 'write_file', { path: 'foo.txt' });
assert.ok(blocked);
const ok = planMode.gateWrite(pm, 'write_file', { path: 'plan.md' });
assert.ok(!ok);
const list = todos.merge([], [{ id: '1', content: 'a', status: 'pending' }], 'replace');
assert.ok(todos.hasOpen(list));
const st = stationarity.create();
stationarity.observe(st, 'read_file', { path: 'a' });
stationarity.observe(st, 'read_file', { path: 'a' });
stationarity.observe(st, 'read_file', { path: 'a' });
assert.ok(stationarity.shouldNudge(st) || !stationarity.shouldStop(st));
}
function testTruncateAndPerm() {
const t = truncate.truncateWithMarker('x'.repeat(5000), 400);
assert.ok(t.length < 5000);
assert.ok(t.indexOf('truncated') >= 0);
const pat = permRules.patternFromArgs('run_terminal_cmd', { command: 'git status -sb' });
assert.strictEqual(pat, 'git status');
assert.ok(policy.shellSafe('git status'));
assert.ok(!policy.shellSafe('rm -rf /'));
assert.ok(permRules.globish('uname -a', '*'));
assert.strictEqual(permRules.patternFromArgs('run_terminal_cmd', { command: '*' }), '*');
const voice = toolBudget.fromPayload({}, 'jarvis-qvac');
toolBudget.markShell(voice);
assert.strictEqual(voice.answerOnly, true);
assert.ok(toolBudget.shouldSkipShell(voice));
}
function testPaths() {
const dir = paths.ensureDir(path.join(os.tmpdir(), 'agent-harness-test'));
assert.ok(fs.existsSync(dir));
assert.ok(paths.isPathInside(dir, path.join(dir, 'a.txt')));
assert.ok(!paths.isPathInside(dir, path.join(dir, '..', 'escape')));
}
function testQvacWorkerDeps() {
assert.doesNotThrow(() => require('hyperdispatch/runtime'));
assert.doesNotThrow(() => require('@qvac/registry-schema'));
}
function testDevicePrefersGpu() {
const empty = { gpus: [], drivers: {}, vramBytes: 0 };
assert.deepStrictEqual(device.pickDevice('auto', empty), { device: 'gpu', gpu_layers: 99 });
assert.deepStrictEqual(device.pickDevice(undefined, empty), { device: 'gpu', gpu_layers: 99 });
assert.deepStrictEqual(device.pickDevice('gpu', empty), { device: 'gpu', gpu_layers: 99 });
assert.deepStrictEqual(device.pickDevice('cpu', { gpus: [{ name: 'NVIDIA' }], drivers: { vulkan: true } }), {
device: 'cpu',
gpu_layers: 0,
});
assert.strictEqual(device.mmprojOnGpu({}, empty, true), true);
assert.strictEqual(device.mmprojOnGpu({ mmprojUseGpu: false }, empty, true), false);
assert.strictEqual(device.mmprojOnGpu({}, empty, false), false);
assert.strictEqual(device.gpuLayers({}, { device: 'gpu', gpu_layers: 99 }), 99);
const sdkShape = {
capabilities: {
memory: { totalBytes: { status: 'supported', value: 32e9, provenance: { source: 'test' } } },
gpus: {
status: 'supported',
value: [
{
id: '0',
name: { status: 'supported', value: 'GeForce', provenance: { source: 'test' } },
type: { status: 'supported', value: 2, provenance: { source: 'test' } },
memoryTotalBytes: { status: 'supported', value: 24e9, provenance: { source: 'test' } },
drivers: { vulkan: { status: 'supported', value: true, provenance: { source: 'test' } } },
},
],
provenance: { source: 'test' },
},
},
};
const norm = device.normalizeResources(sdkShape);
assert.ok(device.hasGpu(norm));
assert.ok(norm.vramBytes > 1e9);
assert.strictEqual(device.backendLabel(norm).backend, 'vulkan');
}
testCatalog();
testCompaction();
testSearchReplace();
testToolSet();
testPrompts();
testNet();
testCustomTools();
testPlanTodosStationarity();
testTruncateAndPerm();
testPaths();
testQvacWorkerDeps();
testDevicePrefersGpu();
testGoogleSearchParseAndFallback();
testWebFetchTimeout()
.then(() => testGoogleSearchFallsBackToDuckDuckGo())
.then(() => {
console.log('ok');
})
.catch((err) => {
console.error(err);
process.exitCode = 1;
});
async function testWebFetchTimeout() {
const orig = globalThis.fetch;
globalThis.fetch = () => new Promise(() => {});
const started = Date.now();
try {
const hung = await tools.webFetch('https://example.com/ip', 40);
assert.ok(hung.error);
assert.ok(/timed out/i.test(hung.error));
assert.strictEqual(hung.url, 'https://example.com/ip');
assert.ok(Date.now() - started < 2000);
} finally {
globalThis.fetch = orig;
}
globalThis.fetch = async (url) => ({
status: 200,
url: String(url),
text: async () => '203.0.113.8',
});
try {
const ok = await tools.webFetch('https://ifconfig.me/ip', 200);
assert.strictEqual(ok.status, 200);
assert.strictEqual(ok.url, 'https://ifconfig.me/ip');
assert.strictEqual(ok.text, '203.0.113.8');
assert.ok(!ok.error);
} finally {
globalThis.fetch = orig;
}
globalThis.fetch = async () => ({ status: 503, url: 'https://example.com', text: async () => 'down' });
try {
const failed = await tools.webFetch('https://example.com/status', 200);
assert.ok(failed.error);
assert.strictEqual(failed.status, 503);
assert.strictEqual(failed.url, 'https://example.com');
} finally {
globalThis.fetch = orig;
}
}
function testGoogleSearchParseAndFallback() {
const parsed = tools.parseGoogleHits(
'<a href="/url?q=https://example.com/page&amp;sa=U"><div class="BNeawe vvjwJb AP7Wnd">Example Domain</div></a>'
);
assert.strictEqual(parsed.length, 1);
assert.strictEqual(parsed[0].url, 'https://example.com/page');
assert.strictEqual(parsed[0].title, 'Example Domain');
assert.strictEqual(tools.parseGoogleHits('<title>Google Search</title><noscript>Please click here</noscript>').length, 0);
assert.ok(tools.SCHEMAS.find((t) => t.name === 'google_search'));
assert.ok(tools.SCHEMAS.find((t) => t.name === 'fetch_page'));
assert.ok(tools.SCHEMAS.find((t) => t.name === 'wiki_search'));
const rss = require('../agent/web-search.js').parseRssItems(
'<rss><item><title>Example</title><link>https://example.com/rss</link></item></rss>'
);
assert.strictEqual(rss[0].url, 'https://example.com/rss');
}
async function testGoogleSearchFallsBackToDuckDuckGo() {
const orig = globalThis.fetch;
globalThis.fetch = async (url) => {
const href = String(url);
if (href.indexOf('google.com') >= 0) {
return {
status: 200,
url: href,
text: async () => '<title>Google Search</title><noscript>Please click here</noscript>',
};
}
return {
status: 200,
url: href,
text: async () => '<a class="result__a" href="https://duckduckgo.com/l/?uddg=https%3A%2F%2Fexample.com%2Fddg">DDG Example</a>',
};
};
try {
const hits = await tools.webSearch('example domain', 200);
assert.ok(Array.isArray(hits));
assert.strictEqual(hits.length, 1);
assert.strictEqual(hits[0].source, 'duckduckgo');
assert.strictEqual(hits[0].url, 'https://example.com/ddg');
assert.strictEqual(hits[0].title, 'DDG Example');
} finally {
globalThis.fetch = orig;
}
globalThis.fetch = async (url) => {
const href = String(url);
if (href.indexOf('google.com') >= 0) {
return {
status: 200,
url: href,
text: async () =>
'<a href="/url?q=https://example.com/google&amp;sa=U"><div class="BNeawe vvjwJb AP7Wnd">From Google</div></a>',
};
}
throw new Error('duckduckgo should not run when google hits');
};
try {
const hits = await tools.googleSearchWithFallback('example domain', 200);
assert.strictEqual(hits[0].source, 'google');
assert.strictEqual(hits[0].url, 'https://example.com/google');
assert.strictEqual(hits[0].title, 'From Google');
} finally {
globalThis.fetch = orig;
}
const bingHref =
'https://www.bing.com/ck/a?!&&p=ae&u=a1aHR0cDovL3d3dy5leGFtcGxlLmNvbS8&ntb=1';
globalThis.fetch = async (url) => {
const href = String(url);
if (href.indexOf('google.com') >= 0) {
return { status: 200, url: href, text: async () => '<title>Google Search</title>' };
}
if (href.indexOf('duckduckgo.com') >= 0) {
return {
status: 202,
url: href,
text: async () => '<div class="anomaly-modal__title">Unfortunately, bots use DuckDuckGo too.</div>',
};
}
return {
status: 200,
url: href,
text: async () => '<li class="b_algo"><h2><a href="' + bingHref + '"><strong>Example Domain</strong></a></h2></li>',
};
};
try {
const hits = await tools.googleSearchWithFallback('example domain', 200);
assert.strictEqual(hits[0].source, 'bing');
assert.strictEqual(hits[0].url, 'http://www.example.com/');
} finally {
globalThis.fetch = orig;
}
}