Updates
Rolling release / release (push) Successful in 11m51s

This commit is contained in:
2026-09-14 12:58:16 -04:00
parent 3001b90df8
commit dd8b00a56b
21 changed files with 178 additions and 38 deletions
+2 -1
View File
@@ -100,7 +100,8 @@ test('harness bridge caps voice shell chaining', () => {
assert.equal(bridge.options.origin, 'jarvis-qvac');
assert.equal(bridge.options.voice, true);
assert.equal(bridge.options.maxShellCalls, 1);
assert.equal(bridge.options.maxTurns, 6);
assert.equal(bridge.options.maxTurns, 24);
assert.equal(bridge.options.maxToolRounds, 16);
assert.deepEqual(bridge.options.roots, []);
assert.deepEqual(harnessRoots('filesystem'), ['/']);
assert.match(bridge.options.cwd, /jarvis\/workspace$/);
+13
View File
@@ -11,6 +11,7 @@ import { PortalInputBackend } from '../computer-use/portal-input.js';
import { createComputerObserveTools } from '../skills/computer-observe.js';
import { createComputerActTools } from '../skills/computer-act.js';
import { createPhase2Tools, filesystemRoots } from '../skills/phase2-tools.js';
import { createObsidianTools } from '../skills/obsidian-tools.js';
import { createBrowserTools } from '../skills/browser-tools.js';
import { createWebcamTools } from '../skills/webcam-tools.js';
import { VoiceStateMachine } from '../daemon/voice-state.js';
@@ -107,6 +108,18 @@ test('browser gateway is a public read and does not wait for confirmation', () =
} finally { custom.clear(id); }
});
test('agent vault and memory notes do not wait for confirmation', () => {
const id = 'vault-memory-permission';
try {
custom.register(id, [
...createObsidianTools({ enabled: true }),
...createPhase2Tools({ cwd: process.cwd() }).filter(tool => tool.name === 'memory_remember'),
]);
assert.equal(custom.needsPermission(id, 'obsidian', 'ask'), false);
assert.equal(custom.needsPermission(id, 'memory_remember', 'ask'), false);
} finally { custom.clear(id); }
});
test('webcam is a read tool gated by the camera grant', async () => {
const id = 'webcam-permission';
const camera = { assertActive() { throw new Error('webcam grant is inactive'); }, device: '', setBackend() {}, backend: 'none' };
+6
View File
@@ -186,6 +186,12 @@ test('voice prompt tells the model not to chain extra terminal commands', () =>
assert.match(VOICE_SYSTEM_PROMPT, /Allow now/);
assert.match(VOICE_SYSTEM_PROMPT, /It is /);
assert.match(VOICE_SYSTEM_PROMPT, /memory date is /);
assert.match(VOICE_SYSTEM_PROMPT, /not sentient/);
assert.match(VOICE_SYSTEM_PROMPT, /unconditional control/);
assert.match(VOICE_SYSTEM_PROMPT, /obsidian write/);
assert.match(VOICE_SYSTEM_PROMPT, /Do not ask permission/);
assert.match(VOICE_SYSTEM_PROMPT, /Finish the request before you speak/);
assert.match(VOICE_SYSTEM_PROMPT, /That is not an answer/);
assert.doesNotMatch(VOICE_SYSTEM_PROMPT, /Never claim cloud access/);
});
+2
View File
@@ -220,6 +220,8 @@ test('Obsidian Apply replaces the tool and memory selection, resets context, and
const tool = daemon.harness.options.tools.find(t => t.name === 'obsidian'); assert.ok(tool);
assert.equal(daemon.harness.options.builtinTools.includes('memory_write'), false);
assert.match(daemon.harness.options.system, /obsidian memory_search/);
assert.match(daemon.harness.options.system, /Do not ask permission/);
assert.equal(tool.permission, 'memory');
assert.equal(JSON.parse(daemon.obsidianAction('{"action":"initialize"}')).ready, true);
assert.equal(JSON.parse(daemon.obsidianAction('{"action":"verify"}')).memoryVerified, true);
tool.execute({ action: 'write', path: 'memory/test.md', content: 'saved memory' });
+11 -1
View File
@@ -38,6 +38,15 @@ test('voice unfinished tool talk nudges another call', () => {
assert.equal(toolBudget.shouldNudgeToolCall('I should search more specifically for Honeypier LLC.', voice), true);
assert.equal(toolBudget.shouldNudgeToolCall('Your public I P is 203 0 113 8.', voice), false);
assert.equal(toolBudget.shouldNudgeToolCall('Let me know if you need more.', voice), false);
assert.equal(toolBudget.isUnfinishedReply('Good sir—let me have an overview now before we move forward:'), true);
assert.equal(toolBudget.isUnfinishedReply('Your public I P is 203 0 113 8.'), false);
assert.equal(toolBudget.isUnfinishedReply('function\n/tool_call'), true);
assert.equal(
toolBudget.usableReply('Good sir—let me have an overview now before we move forward:', [
{ role: 'tool', content: JSON.stringify({ entries: [{ path: 'Welcome.md' }, { path: 'memory' }, { path: 'notes' }] }) },
]),
'I found Welcome.md, memory, notes.'
);
toolBudget.forceAnswer(voice);
assert.equal(toolBudget.shouldNudgeToolCall('Let me fetch it.', voice), false);
});
@@ -90,7 +99,8 @@ test('html pages are stripped to text for web_fetch', () => {
test('Jarvis voice budget runs one shell then forces an answer', () => {
const budget = toolBudget.fromPayload({}, 'jarvis-qvac');
assert.equal(budget.maxShellCalls, 1);
assert.equal(budget.maxTurns, 6);
assert.equal(budget.maxTurns, 24);
assert.equal(budget.maxToolRounds, 16);
assert.equal(budget.completeIdleMs, 10000);
assert.equal(budget.completeTimeoutMs, 45000);
assert.equal(toolBudget.shouldSkipShell(budget), false);