88 lines
4.0 KiB
JavaScript
88 lines
4.0 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import path from 'node:path';
|
|
import { extensionLaunch, installedExtensionDirs } from '../browser-use/extensions.js';
|
|
import { formatBrowserReading, pageSliceOffsets } from '../browser-use/reading.js';
|
|
import { createRequire } from 'node:module';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const truncate = require('../vendor/agent-harness/agent/truncate.js');
|
|
const compaction = require('../vendor/agent-harness/agent/compaction.js');
|
|
|
|
test('a browser reading keeps the page text ahead of refs and survives voice compaction', () => {
|
|
const article = 'The launch date is 14 September 2026. The price is 42 dollars. '.repeat(40);
|
|
const reading = formatBrowserReading({
|
|
url: 'https://example.com/story',
|
|
title: 'Story',
|
|
text: article,
|
|
headings: ['Launch'],
|
|
tables: ['Item | Price\nWidget | 42'],
|
|
seen: ['A chart of the price'],
|
|
refs: [{ ref: '1', role: 'a', name: 'Accept cookies' }],
|
|
});
|
|
const textAt = reading.indexOf('page_text:');
|
|
assert.ok(textAt >= 0);
|
|
assert.ok(textAt < reading.indexOf('refs:'));
|
|
assert.match(reading, /14 September 2026/);
|
|
assert.match(reading, /A chart of the price/);
|
|
const rendered = truncate.renderToolResult({ reading, images: [{ path: '/tmp/page.jpg' }] }, 8000);
|
|
assert.match(rendered, /page_text:/);
|
|
assert.doesNotMatch(rendered, /\/tmp\/page\.jpg/);
|
|
const history = [
|
|
{ role: 'system', content: 'You are Jarvis.' },
|
|
{ role: 'user', content: 'What is the launch date and price?' },
|
|
{ role: 'assistant', content: '', tool_calls: [{ id: 'call_1', name: 'browser', arguments: { action: 'snapshot' } }] },
|
|
{ role: 'tool', name: 'browser', tool_call_id: 'call_1', content: reading },
|
|
];
|
|
const compacted = compaction.heuristicCompact(history, {
|
|
budgetTokens: 400,
|
|
voice: true,
|
|
aggressive: true,
|
|
browserFloor: 4000,
|
|
});
|
|
const page = compacted.find((msg) => msg.role === 'tool' && msg.name === 'browser');
|
|
assert.ok(page, 'browser page was discarded');
|
|
assert.match(page.content, /14 September 2026/);
|
|
assert.ok(page.content.length > 500, 'page text was crushed: ' + page.content.length);
|
|
});
|
|
|
|
test('page slices cover a tall page from top to bottom', () => {
|
|
assert.deepEqual(pageSliceOffsets(700, 800, 4), [0]);
|
|
const slices = pageSliceOffsets(8000, 800, 4);
|
|
assert.equal(slices[0], 0);
|
|
assert.equal(slices[slices.length - 1], 7200);
|
|
assert.ok(slices.length >= 2 && slices.length <= 4);
|
|
const reading = formatBrowserReading({
|
|
url: 'https://example.com/long',
|
|
title: 'Long',
|
|
coverage: 'full page, 10 screens',
|
|
text: 'Section near the bottom: the code is 4412.',
|
|
});
|
|
assert.match(reading, /coverage: full page, 10 screens/);
|
|
assert.match(reading, /full readable page after scrolling/);
|
|
assert.match(reading, /4412/);
|
|
});
|
|
|
|
test('browser loads only unpacked extensions that have a manifest', () => {
|
|
const root = mkdtempSync(path.join(tmpdir(), 'jarvis-ext-'));
|
|
try {
|
|
mkdirSync(path.join(root, 'ublock-origin-lite'));
|
|
writeFileSync(path.join(root, 'ublock-origin-lite', 'manifest.json'), '{"name":"uBOL","version":"1"}');
|
|
mkdirSync(path.join(root, 'dark-reader'));
|
|
const missing = extensionLaunch(installedExtensionDirs(root));
|
|
assert.deepEqual(missing.extensions, ['ublock-origin-lite']);
|
|
assert.match(missing.args[1], /--load-extension=/);
|
|
assert.deepEqual(missing.ignoreDefaultArgs, ['--disable-extensions']);
|
|
writeFileSync(path.join(root, 'dark-reader', 'manifest.json'), '{"name":"Dark Reader","version":"1"}');
|
|
const both = extensionLaunch(installedExtensionDirs(root));
|
|
assert.deepEqual(both.extensions, ['ublock-origin-lite', 'dark-reader']);
|
|
assert.match(both.args[0], /disable-extensions-except=/);
|
|
assert.match(both.args[1], /ublock-origin-lite,.*dark-reader/);
|
|
assert.deepEqual(extensionLaunch([]).args, []);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|