This commit is contained in:
@@ -6,12 +6,12 @@ import { createQvacTools } from '../skills/qvac-tools.js';
|
|||||||
import { VOICE_SYSTEM_PROMPT, parseHudSidecar } from '../skills/voice-prompt.js';
|
import { VOICE_SYSTEM_PROMPT, parseHudSidecar } from '../skills/voice-prompt.js';
|
||||||
import { createComputerObserveTools } from '../skills/computer-observe.js';
|
import { createComputerObserveTools } from '../skills/computer-observe.js';
|
||||||
import { createComputerActTools } from '../skills/computer-act.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 {
|
export class HarnessBridge extends EventEmitter {
|
||||||
constructor({ cwd = process.cwd(), model = 'qwen3.5-4b', tools = [], computer, observer, actuator, permissionMode = 'ask' } = {}) {
|
constructor({ cwd = process.cwd(), model = 'qwen3.5-4b', tools = [], computer, observer, actuator, permissionMode = 'ask' } = {}) {
|
||||||
super();
|
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;
|
this.session = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,4 +53,34 @@ export function createPhase9Tools() {
|
|||||||
return tools;
|
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 };
|
export { specs as PHASE9_SPECS };
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import test from 'node:test';
|
import test from 'node:test';
|
||||||
import assert from 'node:assert/strict';
|
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';
|
import { SKILLS } from '../skills/catalog.js';
|
||||||
|
|
||||||
test('Phase 9 exposes the complete local QVAC capability surface', () => {
|
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'));
|
assert.ok(SKILLS.some(([id]) => id === 'model-registry'));
|
||||||
for (const tool of tools) assert.ok(tool.parameters?.type === 'object', tool.name);
|
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'));
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user