Keep harness tools within registration limit
Rolling release / release (push) Successful in 12m20s

This commit is contained in:
2026-09-11 18:05:41 -04:00
parent 28150185dc
commit 354e25995a
3 changed files with 39 additions and 3 deletions
+2 -2
View File
@@ -6,12 +6,12 @@ import { createQvacTools } from '../skills/qvac-tools.js';
import { VOICE_SYSTEM_PROMPT, parseHudSidecar } from '../skills/voice-prompt.js';
import { createComputerObserveTools } from '../skills/computer-observe.js';
import { createComputerActTools } from '../skills/computer-act.js';
import { createPhase9Tools } from '../skills/phase9-tools.js';
import { createPhase9GatewayTool } from '../skills/phase9-tools.js';
export class HarnessBridge extends EventEmitter {
constructor({ cwd = process.cwd(), model = 'qwen3.5-4b', tools = [], computer, observer, actuator, permissionMode = 'ask' } = {}) {
super();
this.options = { cwd, model, tools: [...createRuntimeTools({ computer }), ...createPhase2Tools({ cwd, computer }), ...createComputerObserveTools({ computer, observer }), ...createComputerActTools({ actuator }), ...createQvacTools(), ...createPhase9Tools(), ...tools], permissionMode, origin: 'jarvis-qvac', system: VOICE_SYSTEM_PROMPT };
this.options = { cwd, model, tools: [...createRuntimeTools({ computer }), ...createPhase2Tools({ cwd, computer }), ...createComputerObserveTools({ computer, observer }), ...createComputerActTools({ actuator }), ...createQvacTools(), ...createPhase9GatewayTool(), ...tools], permissionMode, origin: 'jarvis-qvac', system: VOICE_SYSTEM_PROMPT };
this.session = null;
}
+30
View File
@@ -53,4 +53,34 @@ export function createPhase9Tools() {
return tools;
}
// The harness reserves 32 custom-tool slots. Keep the complete per-capability
// catalog available to callers, while exposing one gateway to the agent so
// every QVAC capability remains reachable without exceeding that limit.
export function createPhase9GatewayTool() {
const operations = [...specs.map(([name]) => name), 'job_cancel', 'p2p_status'];
return [{
name: 'qvac_capability',
permission: 'write',
description: `Run one local QVAC capability through the single master adapter. Operations: ${operations.join(', ')}.`,
parameters: {
type: 'object',
properties: {
operation: { type: 'string', enum: operations },
input: { type: 'object' },
},
required: ['operation'],
},
execute: async ({ operation, input = {} } = {}) => {
if (operation === 'p2p_status') return p2pStatus();
if (operation === 'job_cancel') return callQvac('cancel', input);
const spec = specs.find(([name]) => name === operation);
if (!spec) throw new Error(`unknown QVAC capability: ${operation}`);
const [, method] = spec;
if (method === 'modelRegistryGetModel') return resultShape(await callQvac(method, [input.registryPath || input.path, input.registrySource || input.source]));
if (method === 'ocr') { const result = await callQvac(method, input); return { blocks: await result.blocks }; }
return resultShape(await callQvac(method, input));
},
}];
}
export { specs as PHASE9_SPECS };
+7 -1
View File
@@ -1,6 +1,6 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { createPhase9Tools, PHASE9_SPECS } from '../skills/phase9-tools.js';
import { createPhase9GatewayTool, createPhase9Tools, PHASE9_SPECS } from '../skills/phase9-tools.js';
import { SKILLS } from '../skills/catalog.js';
test('Phase 9 exposes the complete local QVAC capability surface', () => {
@@ -13,3 +13,9 @@ test('Phase 9 exposes the complete local QVAC capability surface', () => {
assert.ok(SKILLS.some(([id]) => id === 'model-registry'));
for (const tool of tools) assert.ok(tool.parameters?.type === 'object', tool.name);
});
test('Phase 9 gateway keeps the complete capability surface within harness custom-tool limits', () => {
const [gateway] = createPhase9GatewayTool();
assert.ok(gateway.parameters.properties.operation.enum.length >= PHASE9_SPECS.length);
assert.ok(gateway.parameters.properties.operation.enum.includes('p2p_status'));
});