136 lines
4.5 KiB
JavaScript
136 lines
4.5 KiB
JavaScript
import test from 'brittle'
|
|
import { readFileSync } from 'node:fs'
|
|
|
|
const STATE = readFileSync(new URL('../lib/agent-state.js', import.meta.url), 'utf8')
|
|
const TOOLS = readFileSync(new URL('../lib/agent-tools.js', import.meta.url), 'utf8')
|
|
const OPENAI = readFileSync(new URL('../lib/agent-openai.js', import.meta.url), 'utf8')
|
|
const TUI = readFileSync(new URL('../lib/agent-tui.js', import.meta.url), 'utf8')
|
|
|
|
test('agent-state exposes QVAC backend config keys', async (t) => {
|
|
for (const key of [
|
|
'backend',
|
|
'qvac_model',
|
|
'qvac_profile',
|
|
'qvac_ctx_size',
|
|
'qvac_device',
|
|
'qvac_main_gpu',
|
|
'qvac_gpu_layers'
|
|
]) {
|
|
t.ok(STATE.includes(key), 'missing QVAC key in agent-state.js: ' + key)
|
|
}
|
|
t.ok(STATE.includes("backend: 'qvac'"), 'default backend should be qvac')
|
|
t.ok(STATE.includes("provider: 'qvac'"), 'default provider should be qvac')
|
|
t.ok(STATE.includes('QWEN3_1_7B_INST_Q4'), 'default qvac model id')
|
|
})
|
|
|
|
test('agent-tui wizard offers QVAC vs REST and auto model selection', async (t) => {
|
|
t.ok(TUI.includes('Backend [1=QVAC, 2=REST]'))
|
|
t.ok(TUI.includes('Only identity + backend'))
|
|
t.ok(TUI.includes('QVAC auto: profile'))
|
|
t.ok(!TUI.includes('Model profile number'))
|
|
t.ok(!TUI.includes('REST base URL'))
|
|
t.ok(!TUI.includes('Enable autonomous coding mode?'))
|
|
t.ok(TUI.includes('bareOsQvacComplete'))
|
|
t.ok(TUI.includes("backendIter === 'qvac'"))
|
|
})
|
|
|
|
test('agent-tools merge patch allows backend / qvac keys', async (t) => {
|
|
t.ok(TOOLS.includes("'backend'"))
|
|
t.ok(TOOLS.includes("'qvac_model'"))
|
|
t.ok(TOOLS.includes("'qvac_profile'"))
|
|
t.ok(TOOLS.includes("'qvac_ctx_size'"))
|
|
t.ok(TOOLS.includes("'qvac_device'"))
|
|
t.ok(TOOLS.includes("'qvac_main_gpu'"))
|
|
t.ok(TUI.includes('bareAgentQvacResolveDeviceOpts'))
|
|
})
|
|
|
|
|
|
test('agent-state exposes bridge policy keys', async (t) => {
|
|
for (const key of [
|
|
'allow_bridge_mutations',
|
|
'allow_host_notifications',
|
|
'allow_host_actions',
|
|
'emergency_stop_mutations'
|
|
]) {
|
|
t.ok(STATE.includes(key), 'missing key in agent-state.js: ' + key)
|
|
}
|
|
})
|
|
|
|
test('agent-state exposes autonomous mode config keys', async (t) => {
|
|
for (const key of [
|
|
'autonomous_mode_enabled',
|
|
'autonomous_max_runtime_ms',
|
|
'autonomous_completion_required_checks',
|
|
'autonomous_allow_paths',
|
|
'autonomous_deny_ops',
|
|
'autonomous_active',
|
|
'autonomous_started_at_ms',
|
|
'autonomous_stop_requested',
|
|
'autonomous_goal',
|
|
'autonomous_status',
|
|
'autonomous_last_error'
|
|
]) {
|
|
t.ok(STATE.includes(key), 'missing autonomous key in agent-state.js: ' + key)
|
|
}
|
|
})
|
|
|
|
test('agent-tools exposes agent ops tools', async (t) => {
|
|
for (const toolName of [
|
|
'list_services',
|
|
'service_status',
|
|
'list_timers',
|
|
'read_cron_log',
|
|
'read_audit_log',
|
|
'read_boot_policy',
|
|
'read_kernel_extension_resolution',
|
|
'get_initd_graph',
|
|
'read_unit_journal',
|
|
'inspect_ipc_backpressure',
|
|
'get_network_summary',
|
|
'tail_telemetry_streams',
|
|
'pkg_index_lookup',
|
|
'list_verification_scripts',
|
|
'run_maintenance_gate',
|
|
'run_contract_checks',
|
|
'summarize_build_drift',
|
|
'get_hrpc_bridge_health',
|
|
'get_hrpc_allowlist_status',
|
|
'emit_host_notification',
|
|
'request_host_action',
|
|
'autonomous_run',
|
|
'autonomous_run_status',
|
|
'autonomous_run_stop',
|
|
'verification_hints',
|
|
'runtime_diagnostic_bundle'
|
|
]) {
|
|
t.ok(TOOLS.includes("name: '" + toolName + "'"), 'missing tool definition: ' + toolName)
|
|
}
|
|
})
|
|
|
|
test('agent-openai parses reasoning deltas when present', async (t) => {
|
|
t.ok(OPENAI.includes('delta_reasoning'))
|
|
t.ok(OPENAI.includes('reasoning_content'))
|
|
t.ok(OPENAI.includes('response.reasoning_summary_text.delta'))
|
|
t.ok(OPENAI.includes('response_shape_keys'))
|
|
})
|
|
|
|
test('agent-tui contains groq provider profile/request shaping', async (t) => {
|
|
t.ok(TUI.includes("provider === 'groq'"))
|
|
t.ok(TUI.includes('https://api.groq.com/openai/v1'))
|
|
t.ok(TUI.includes('body.parallel_tool_calls'))
|
|
t.ok(TUI.includes('body.max_completion_tokens'))
|
|
})
|
|
|
|
test('agent-tui contains autonomous loop controls and completion gates', async (t) => {
|
|
t.ok(TUI.includes('bareAgentAutonomousSettings'))
|
|
t.ok(TUI.includes('autonomous run stopped by request'))
|
|
t.ok(TUI.includes('autonomous run stopped (timebox expired)'))
|
|
t.ok(TUI.includes('Autonomous completion gates failed for checks'))
|
|
t.ok(TUI.includes('autonomous completion gates passed'))
|
|
})
|
|
|
|
test('agent-tui embeds operating contract appendix', async (t) => {
|
|
t.ok(TUI.includes('BARE_AGENT_OPERATING_CONTRACT'))
|
|
t.ok(TUI.includes('verification_hints'))
|
|
})
|