87 lines
5.4 KiB
JavaScript
87 lines
5.4 KiB
JavaScript
import { callQvac } from '../daemon/qvac-master.js';
|
|
import { p2pStatus } from './optional-sync.js';
|
|
|
|
const READ = 'read';
|
|
const WRITE = 'write';
|
|
const DANGEROUS = 'dangerous';
|
|
const specs = [
|
|
['embed', 'embed', 'Create local text embeddings.', READ],
|
|
['rag_ingest', 'ragIngest', 'Ingest local documents into a QVAC RAG workspace.', WRITE],
|
|
['rag_chunk', 'ragChunk', 'Chunk local documents for RAG.', READ],
|
|
['rag_save_embeddings', 'ragSaveEmbeddings', 'Save local RAG embeddings.', WRITE],
|
|
['rag_search', 'ragSearch', 'Search a local QVAC RAG workspace.', READ],
|
|
['rag_reindex', 'ragReindex', 'Reindex a local QVAC RAG workspace.', WRITE],
|
|
['rag_delete_embeddings', 'ragDeleteEmbeddings', 'Delete embeddings from a local workspace.', DANGEROUS],
|
|
['rag_list_workspaces', 'ragListWorkspaces', 'List local QVAC RAG workspaces.', READ],
|
|
['rag_close_workspace', 'ragCloseWorkspace', 'Close a local RAG workspace.', WRITE],
|
|
['rag_delete_workspace', 'ragDeleteWorkspace', 'Delete a local RAG workspace.', DANGEROUS],
|
|
['batch_prompt', 'batchCompletion', 'Run a local batch completion.', WRITE],
|
|
['translate', 'translate', 'Translate text locally.', READ],
|
|
['ocr', 'ocr', 'Run local QVAC OCR on an image.', READ],
|
|
['classify_image', 'classify', 'Classify a local image.', READ],
|
|
['imagine', 'diffusion', 'Generate or edit a local image.', WRITE],
|
|
['make_video', 'video', 'Generate a local video job.', WRITE],
|
|
['compose_music', 'audioGen', 'Generate a local music job.', WRITE],
|
|
['transcribe_file', 'transcribe', 'Transcribe a local audio file.', READ],
|
|
['tts_speak', 'textToSpeech', 'Synthesize local speech.', READ],
|
|
['finetune_lora', 'finetune', 'Run a confirmed local LoRA training job.', DANGEROUS],
|
|
['bci_transcribe', 'bciTranscribe', 'Use the local BCI transcription slot.', READ],
|
|
['vla_act', 'vla', 'Run the local VLA Lab slot.', DANGEROUS],
|
|
['world_create', 'worldCreateScene', 'Create a local ABot-World scene.', WRITE],
|
|
['world_step', 'worldStep', 'Advance a local ABot-World scene.', WRITE],
|
|
['model_registry_list', 'modelRegistryList', 'List models in the local QVAC registry.', READ],
|
|
['model_registry_search', 'modelRegistrySearch', 'Search the local QVAC registry.', READ],
|
|
['model_registry_get', 'modelRegistryGetModel', 'Read one local registry model entry.', READ],
|
|
['qvac_profile', 'getSystemResources', 'Read local QVAC resource/profile data.', READ],
|
|
];
|
|
|
|
function resultShape(value) {
|
|
if (!value || typeof value !== 'object') return value;
|
|
if (value.requestId) return { requestId: value.requestId, job: true };
|
|
if (value.bufferStream || value.blockStream || value.tokenStream) return { job: true, stream: true, requestId: value.requestId || null };
|
|
return value;
|
|
}
|
|
|
|
export function createPhase9Tools() {
|
|
const tools = specs.map(([name, method, description, permission]) => ({ name, permission, description: `${description} All execution remains local and is routed through the single QVAC master.`, parameters: { type: 'object', properties: { input: { type: 'object' } } }, execute: async ({ input = {} } = {}) => {
|
|
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));
|
|
}}));
|
|
tools.push({ name: 'job_cancel', permission: 'dangerous', description: 'Cancel a local QVAC request or model job through the master.', parameters: { type: 'object', properties: { requestId: { type: 'string' }, modelId: { type: 'string' }, kind: { type: 'string' } } }, execute: async (input) => callQvac('cancel', input) });
|
|
tools.push({ name: 'p2p_status', permission: 'read', description: 'Report optional P2P model/memory transport status; it is disabled by default.', parameters: { type: 'object', properties: {} }, execute: () => p2pStatus() });
|
|
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 };
|