Skip to content

Commit 17b5f66

Browse files
authored
Update vial-mcp.js
1 parent 7423e63 commit 17b5f66

File tree

1 file changed

+240
-10
lines changed

1 file changed

+240
-10
lines changed

main/frontend/public/js/vial-mcp.js

Lines changed: 240 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ let wallet = { address: null, balance: 0, hash: null };
7676
let lastLogMessage = null;
7777
let lastLogTime = 0;
7878
let lastLogId = 0;
79+
let toolboxClient = null;
80+
let toolboxTools = null;
7981

8082
// UUID generator
8183
function generateUUID() {
@@ -137,7 +139,7 @@ function parseMarkdownForTraining(mdContent) {
137139
// Simulate blockchain transaction
138140
async function addToBlockchain(type, data) {
139141
if (isOffline && type !== 'train' && type !== 'import' && type !== 'export') {
140-
return null; // Skip blockchain in offline mode for non-training actions
142+
return null;
141143
}
142144
const timestamp = new Date().toISOString();
143145
const prevHash = blockchain.length ? blockchain[blockchain.length - 1].hash : '0'.repeat(64);
@@ -201,8 +203,8 @@ function updateVialStatusBars() {
201203
vial.latency = isOffline ? 0 : Math.floor(Math.random() * (200 - 50 + 1)) + 50;
202204
});
203205
vialStatusBars.innerHTML = vials.map(vial => {
204-
const mode = vial.isTraining ? 'Training' : (isOffline ? 'Offline (Wallet Disabled)' : 'Online');
205-
const statusClass = vial.isTraining ? 'training' : (isOffline ? 'offline-grey' : 'online');
206+
const mode = vial.isTraining ? 'Training' : (isOffline ? 'Offline (Wallet Disabled)' : (toolboxClient ? 'GenAI' : 'Online'));
207+
const statusClass = vial.isTraining ? 'training' : (isOffline ? 'offline-grey' : (toolboxClient ? 'genai' : 'online'));
206208
const fillClass = vial.status === 'running' ? statusClass : '';
207209
return `
208210
<div class="progress-container">
@@ -253,14 +255,13 @@ async function startTokenEarning() {
253255
});
254256
wallet.hash = blockHash;
255257
logEvent('token', `Earned 1 $WEBXOS | Reputation: ${reputation} | Block: ${blockHash.slice(0, 8)}...`, { wallet: wallet.address });
256-
logEvent('token', `Earned 1 $WEBXOS | Reputation: ${reputation} | Block: ${blockHash.slice(0, 8)}...`, { wallet: wallet.address });
257258
updateBalanceDisplay();
258259
}, 10000);
259260
}
260261

261262
// Disable functions on auth loss or offline mode
262263
function disableFunctions() {
263-
const buttons = ['quantumLinkButton', 'exportButton', 'importButton'];
264+
const buttons = ['quantumLinkButton', 'exportButton', 'importButton', 'googleGenAIButton'];
264265
if (isOffline) buttons.push('apiAccessButton');
265266
buttons.forEach(id => {
266267
const btn = document.getElementById(id);
@@ -276,6 +277,57 @@ function disableFunctions() {
276277
}
277278
}
278279

280+
// Initialize Google GenAI Toolbox client
281+
async function initializeToolboxClient() {
282+
if (isOffline) {
283+
logEvent('error', 'Google GenAI Toolbox cannot be initialized in offline mode.', {});
284+
return;
285+
}
286+
if (!isAuthenticated) {
287+
logEvent('error', 'Authentication required to initialize Google GenAI Toolbox.', {});
288+
return;
289+
}
290+
try {
291+
const response = await axios.get('http://127.0.0.1:5000/mcp/toolsets', {
292+
headers: { 'Authorization': `Bearer ${apiCredentials.key}` }
293+
});
294+
toolboxTools = response.data.tools;
295+
toolboxClient = { url: 'http://127.0.0.1:5000', tools: toolboxTools };
296+
const googleGenAIButton = document.getElementById('googleGenAIButton');
297+
if (googleGenAIButton) {
298+
googleGenAIButton.disabled = false;
299+
googleGenAIButton.classList.add('active-genai');
300+
}
301+
document.body.classList.add('genai-glow');
302+
document.getElementById('console').classList.add('active-genai');
303+
logEvent('genai', 'Google GenAI Toolbox initialized. Available tools: ' + toolboxTools.map(t => t.name).join(', '), {});
304+
updateVialStatusBars();
305+
} catch (error) {
306+
logEvent('error', `Failed to initialize Google GenAI Toolbox: ${error.message}`, { error });
307+
showErrorNotification('Failed to connect to Google GenAI Toolbox server.');
308+
}
309+
}
310+
311+
// Execute GenAI tool
312+
async function executeGenAITool(toolName, params) {
313+
if (!toolboxClient) {
314+
logEvent('error', 'Google GenAI Toolbox not initialized.', {});
315+
return null;
316+
}
317+
try {
318+
const response = await axios.post(`${toolboxClient.url}/mcp/tools/${toolName}/execute`, { parameters: params }, {
319+
headers: { 'Authorization': `Bearer ${apiCredentials.key}` }
320+
});
321+
const blockHash = await addToBlockchain('genai_tool', { toolName, params, result: response.data });
322+
logEvent('genai', `Executed tool ${toolName}: ${JSON.stringify(response.data)} | Block: ${blockHash.slice(0, 8)}...`, { toolName, params });
323+
return response.data;
324+
} catch (error) {
325+
logEvent('error', `Failed to execute tool ${toolName}: ${error.message}`, { error });
326+
showErrorNotification(`Tool execution failed: ${error.message}`);
327+
return null;
328+
}
329+
}
330+
279331
// Authenticate
280332
async function authenticate() {
281333
const isOnline = confirm('Authenticate in online mode? Cancel for offline mode.');
@@ -286,7 +338,7 @@ async function authenticate() {
286338
wallet = { address: isOffline ? null : generateUUID(), balance: 0, hash: isOffline ? null : await sha256(agenticNetworkId) };
287339
reputation = 0;
288340
blockchain = [];
289-
apiCredentials = { key: null, secret: null };
341+
apiCredentials = { key: isOffline ? null : generateUUID(), secret: isOffline ? null : generateUUID() };
290342
isAuthenticated = true;
291343
await addToBlockchain('auth', { wallet: wallet.address, networkId: agenticNetworkId });
292344
vials.forEach((vial, i) => {
@@ -295,7 +347,7 @@ async function authenticate() {
295347
});
296348
const authButton = document.getElementById('authButton');
297349
if (authButton) authButton.classList.add('active-monitor');
298-
['quantumLinkButton', 'exportButton', 'importButton'].forEach(id => {
350+
['quantumLinkButton', 'exportButton', 'importButton', 'googleGenAIButton'].forEach(id => {
299351
const btn = document.getElementById(id);
300352
if (btn) btn.disabled = false;
301353
});
@@ -309,6 +361,185 @@ async function authenticate() {
309361
updateBalanceDisplay();
310362
}
311363

364+
// Handle Git and GenAI commands
365+
async function handleGitCommand(input) {
366+
const sanitizedInput = sanitizeInput(input.trim());
367+
if (!sanitizedInput) return;
368+
logEvent('command', sanitizedInput);
369+
const parts = sanitizedInput.split(' ');
370+
const command = parts[0].toLowerCase();
371+
372+
if (command === '/genai' && parts.length > 1) {
373+
if (!toolboxClient) {
374+
logEvent('error', 'Google GenAI Toolbox not initialized. Click "Google GenAI" button to initialize.', {});
375+
return;
376+
}
377+
const toolName = parts[1];
378+
const params = parts.slice(2);
379+
const tool = toolboxTools.find(t => t.name === toolName);
380+
if (!tool) {
381+
logEvent('error', `Tool ${toolName} not found. Available tools: ${toolboxTools.map(t => t.name).join(', ')}`, {});
382+
return;
383+
}
384+
const result = await executeGenAITool(toolName, params);
385+
if (result) {
386+
logEvent('genai', `Tool ${toolName} result: ${JSON.stringify(result)}`, { toolName, params });
387+
}
388+
} else if (command === '/help') {
389+
const helpText = `
390+
Available commands:
391+
/prompt vial[1-4] train <dataset> - Train a vial
392+
/genai <tool_name> <params> - Execute Google GenAI tool (e.g., /genai search-hotels-by-name Marriott)
393+
/status - Check vial statuses
394+
/auth - Re-authenticate
395+
`;
396+
logEvent('info', helpText.replace(/\n/g, '<br>'), {});
397+
} else {
398+
logEvent('error', `Unknown command: ${sanitizedInput}. Use /help for available commands.`, {});
399+
}
400+
}
401+
402+
// Void vials
403+
async function voidVials() {
404+
if (!isAuthenticated) {
405+
logEvent('error', 'Authentication required to void vials.', {});
406+
return;
407+
}
408+
vials.forEach(vial => {
409+
vial.status = 'stopped';
410+
vial.isTraining = false;
411+
vial.tasks = [];
412+
vial.trainingData = [];
413+
});
414+
await addToBlockchain('void', { vials: vials.map(v => v.id) });
415+
logEvent('system', 'All vials voided.', {});
416+
updateVialStatusBars();
417+
}
418+
419+
// Troubleshoot
420+
async function troubleshoot() {
421+
if (!isAuthenticated) {
422+
logEvent('error', 'Authentication required to troubleshoot.', {});
423+
return;
424+
}
425+
const issues = [];
426+
vials.forEach(vial => {
427+
if (vial.status === 'stopped' && vial.tasks.length > 0) {
428+
issues.push(`${vial.id}: Stopped but has pending tasks.`);
429+
}
430+
if (vial.latency > 200) {
431+
issues.push(`${vial.id}: High latency detected (${vial.latency}ms).`);
432+
}
433+
});
434+
if (toolboxClient) {
435+
try {
436+
await axios.get(`${toolboxClient.url}/health`, {
437+
headers: { 'Authorization': `Bearer ${apiCredentials.key}` }
438+
});
439+
logEvent('genai', 'Google GenAI Toolbox server health: OK', {});
440+
} catch (error) {
441+
issues.push(`Google GenAI Toolbox server: Unhealthy (${error.message})`);
442+
}
443+
}
444+
if (issues.length === 0) {
445+
logEvent('system', 'No issues detected.', {});
446+
} else {
447+
issues.forEach(issue => logEvent('error', issue, {}));
448+
}
449+
updateVialStatusBars();
450+
}
451+
452+
// Quantum link
453+
async function quantumLink() {
454+
if (!isAuthenticated) {
455+
logEvent('error', 'Authentication required for quantum link.', {});
456+
return;
457+
}
458+
vials.forEach(vial => {
459+
vial.quantumState = { qubits: [Math.random(), Math.random()], entanglement: 'linked' };
460+
});
461+
const blockHash = await addToBlockchain('quantum_link', { vials: vials.map(v => v.id) });
462+
logEvent('system', `Quantum link established. Block: ${blockHash.slice(0, 8)}...`, {});
463+
}
464+
465+
// Export vials
466+
async function exportVials() {
467+
if (!isAuthenticated) {
468+
logEvent('error', 'Authentication required to export vials.', {});
469+
return;
470+
}
471+
const exportData = {
472+
vials: vials.map(vial => ({
473+
id: vial.id,
474+
code: vial.code,
475+
status: vial.status,
476+
wallet: vial.wallet,
477+
quantumState: vial.quantumState
478+
})),
479+
blockchain: blockchain.slice(-10)
480+
};
481+
const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
482+
const url = URL.createObjectURL(blob);
483+
const a = document.createElement('a');
484+
a.href = url;
485+
a.download = 'vial-mcp-export.json';
486+
a.click();
487+
URL.revokeObjectURL(url);
488+
logEvent('system', 'Vials exported successfully.', {});
489+
}
490+
491+
// Import file
492+
async function importFile(event) {
493+
if (!isAuthenticated) {
494+
logEvent('error', 'Authentication required to import files.', {});
495+
return;
496+
}
497+
const file = event.target.files[0];
498+
if (!file) return;
499+
const reader = new FileReader();
500+
reader.onload = async (e) => {
501+
const content = e.target.result;
502+
if (!validateMarkdown(content)) {
503+
logEvent('error', 'Invalid .md file format.', {});
504+
return;
505+
}
506+
const { tasks, parameters } = parseMarkdownForTraining(content);
507+
vials.forEach(vial => {
508+
vial.tasks = tasks;
509+
vial.config = parameters;
510+
});
511+
const blockHash = await addToBlockchain('import', { tasks, parameters });
512+
logEvent('system', `Imported tasks and parameters. Block: ${blockHash.slice(0, 8)}...`, { tasks, parameters });
513+
updateVialStatusBars();
514+
};
515+
reader.readAsText(file);
516+
}
517+
518+
// Show API popup
519+
function showApiPopup() {
520+
if (!isAuthenticated || isOffline) {
521+
logEvent('error', 'Authentication required and online mode needed for API access.', {});
522+
return;
523+
}
524+
const apiInput = document.getElementById('api-input');
525+
const apiPopup = document.getElementById('api-popup');
526+
apiInput.value = JSON.stringify(apiCredentials, null, 2);
527+
apiPopup.classList.add('visible');
528+
}
529+
530+
// Generate API credentials
531+
async function generateApiCredentials() {
532+
if (!isAuthenticated || isOffline) {
533+
logEvent('error', 'Authentication required and online mode needed for API credentials.', {});
534+
return;
535+
}
536+
apiCredentials = { key: generateUUID(), secret: generateUUID() };
537+
const blockHash = await addToBlockchain('api_credentials', { key: apiCredentials.key });
538+
const apiInput = document.getElementById('api-input');
539+
apiInput.value = JSON.stringify(apiCredentials, null, 2);
540+
logEvent('system', `New API credentials generated. Block: ${blockHash.slice(0, 8)}...`, {});
541+
}
542+
312543
// Initialize
313544
document.addEventListener('DOMContentLoaded', () => {
314545
updateVialStatusBars();
@@ -321,6 +552,7 @@ document.addEventListener('DOMContentLoaded', () => {
321552
exportButton: document.getElementById('exportButton'),
322553
importButton: document.getElementById('importButton'),
323554
apiAccessButton: document.getElementById('apiAccessButton'),
555+
googleGenAIButton: document.getElementById('googleGenAIButton'),
324556
apiSubmit: document.getElementById('api-generate'),
325557
apiClose: document.getElementById('api-close'),
326558
fileInput: document.getElementById('file-input'),
@@ -334,6 +566,7 @@ document.addEventListener('DOMContentLoaded', () => {
334566
elements.exportButton.addEventListener('click', exportVials);
335567
elements.importButton.addEventListener('click', () => elements.fileInput.click());
336568
elements.apiAccessButton.addEventListener('click', showApiPopup);
569+
elements.googleGenAIButton.addEventListener('click', initializeToolboxClient);
337570
elements.apiSubmit.addEventListener('click', generateApiCredentials);
338571
elements.apiClose.addEventListener('click', () => {
339572
const apiPopup = document.getElementById('api-popup');
@@ -352,6 +585,3 @@ document.addEventListener('DOMContentLoaded', () => {
352585

353586
logEvent('system', 'Vial MCP Controller initialized. Use /help for API commands.', {});
354587
}, { once: true });
355-
</script>
356-
</body>
357-
</html>

0 commit comments

Comments
 (0)