initial commit

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-10-08 02:57:03 +02:00
commit b4c6a7d52e
Se han modificado 25 ficheros con 6465 adiciones y 0 borrados

503
src/tools/circuit-tools.ts Archivo normal
Ver fichero

@@ -0,0 +1,503 @@
/**
* Quantum Circuit Building Tools for MCP Server
* Provides tools for creating and manipulating quantum circuits
*/
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import {
CreateKernelSchema,
ApplyGateSchema,
CreateKernelInput,
ApplyGateInput
} from '../types/index.js';
import { getPythonBridge } from '../bridge/python-bridge.js';
import { Logger } from '../utils/logger.js';
const logger = new Logger('QuantumCircuitTools');
/**
* Tool for creating a new quantum kernel/circuit
*/
export const createQuantumKernelTool: Tool = {
name: 'create_quantum_kernel',
description: 'Create a new quantum kernel (circuit) with specified number of qubits and optional parameters',
inputSchema: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the quantum kernel'
},
num_qubits: {
type: 'integer',
minimum: 1,
maximum: 32,
description: 'Number of qubits in the quantum register'
},
parameters: {
type: 'array',
description: 'Optional parameters for the kernel',
items: {
type: 'object',
properties: {
name: { type: 'string' },
type: {
type: 'string',
enum: ['int', 'float', 'complex', 'list[int]', 'list[float]', 'list[complex]']
},
default: { description: 'Default value for the parameter' }
},
required: ['name', 'type']
}
},
description: {
type: 'string',
description: 'Optional description of the kernel'
}
},
required: ['name', 'num_qubits']
}
};
/**
* Tool for applying quantum gates to a kernel
*/
export const applyQuantumGateTool: Tool = {
name: 'apply_quantum_gate',
description: 'Apply a quantum gate to specified qubits in a quantum kernel',
inputSchema: {
type: 'object',
properties: {
kernel_name: {
type: 'string',
description: 'Name of the quantum kernel to modify'
},
gate_name: {
type: 'string',
description: 'Name of the quantum gate to apply',
enum: ['h', 'x', 'y', 'z', 's', 't', 'rx', 'ry', 'rz', 'cx', 'cy', 'cz', 'ccx', 'swap', 'cswap']
},
qubits: {
type: 'array',
description: 'Indices of qubits to apply the gate to',
items: { type: 'integer', minimum: 0 }
},
parameters: {
type: 'array',
description: 'Parameters for parameterized gates (e.g., rotation angles)',
items: { type: 'number' }
},
controls: {
type: 'array',
description: 'Control qubits for controlled operations',
items: { type: 'integer', minimum: 0 }
},
adjoint: {
type: 'boolean',
description: 'Apply adjoint (inverse) of the gate',
default: false
}
},
required: ['kernel_name', 'gate_name', 'qubits']
}
};
/**
* Tool for adding measurements to a quantum kernel
*/
export const addMeasurementTool: Tool = {
name: 'add_measurement',
description: 'Add quantum measurements to a kernel',
inputSchema: {
type: 'object',
properties: {
kernel_name: {
type: 'string',
description: 'Name of the quantum kernel'
},
qubits: {
type: 'array',
description: 'Qubits to measure (empty array means measure all)',
items: { type: 'integer', minimum: 0 }
},
basis: {
type: 'string',
description: 'Measurement basis',
enum: ['Z', 'X', 'Y'],
default: 'Z'
}
},
required: ['kernel_name']
}
};
/**
* Tool for creating common quantum circuits
*/
export const createCommonCircuitTool: Tool = {
name: 'create_common_circuit',
description: 'Create commonly used quantum circuits (GHZ, Bell states, QFT, etc.)',
inputSchema: {
type: 'object',
properties: {
circuit_type: {
type: 'string',
description: 'Type of quantum circuit to create',
enum: ['bell_pair', 'ghz_state', 'quantum_fourier_transform', 'grover_oracle', 'hadamard_test']
},
name: {
type: 'string',
description: 'Name for the created kernel'
},
num_qubits: {
type: 'integer',
minimum: 2,
maximum: 32,
description: 'Number of qubits (where applicable)'
},
parameters: {
type: 'object',
description: 'Circuit-specific parameters'
}
},
required: ['circuit_type', 'name']
}
};
/**
* Tool for listing available quantum kernels
*/
export const listQuantumKernelsTool: Tool = {
name: 'list_quantum_kernels',
description: 'List all available quantum kernels and their metadata',
inputSchema: {
type: 'object',
properties: {
detailed: {
type: 'boolean',
description: 'Include detailed metadata about each kernel',
default: false
}
}
}
};
/**
* Tool for visualizing quantum circuits
*/
export const visualizeCircuitTool: Tool = {
name: 'visualize_circuit',
description: 'Generate a text-based visualization of a quantum circuit',
inputSchema: {
type: 'object',
properties: {
kernel_name: {
type: 'string',
description: 'Name of the quantum kernel to visualize'
},
format: {
type: 'string',
description: 'Output format for the visualization',
enum: ['text', 'qasm', 'json'],
default: 'text'
}
},
required: ['kernel_name']
}
};
/**
* Implementation functions for the tools
*/
export async function handleCreateQuantumKernel(input: CreateKernelInput) {
try {
// Validate input
const validatedInput = CreateKernelSchema.parse(input);
const bridge = getPythonBridge();
const response = await bridge.createKernel(
validatedInput.name,
validatedInput.num_qubits,
validatedInput.parameters
);
if (response.success) {
logger.info(`Created quantum kernel: ${validatedInput.name} with ${validatedInput.num_qubits} qubits`);
return {
content: [
{
type: 'text' as const,
text: `Successfully created quantum kernel '${validatedInput.name}' with ${validatedInput.num_qubits} qubits.`
}
]
};
} else {
throw new Error(response.error || 'Failed to create quantum kernel');
}
} catch (error) {
logger.error('Error creating quantum kernel:', error);
return {
content: [
{
type: 'text' as const,
text: `Error creating quantum kernel: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleApplyQuantumGate(input: ApplyGateInput) {
try {
const validatedInput = ApplyGateSchema.parse(input);
const bridge = getPythonBridge();
const response = await bridge.applyGate(
validatedInput.kernel_name,
validatedInput.gate_name,
validatedInput.qubits,
validatedInput.parameters,
validatedInput.controls,
validatedInput.adjoint
);
if (response.success) {
const gateDesc = validatedInput.controls
? `controlled ${validatedInput.gate_name}`
: validatedInput.gate_name;
logger.info(`Applied ${gateDesc} gate to kernel ${validatedInput.kernel_name}`);
return {
content: [
{
type: 'text' as const,
text: `Successfully applied ${gateDesc} gate to qubits [${validatedInput.qubits.join(', ')}] in kernel '${validatedInput.kernel_name}'.`
}
]
};
} else {
throw new Error(response.error || 'Failed to apply quantum gate');
}
} catch (error) {
logger.error('Error applying quantum gate:', error);
return {
content: [
{
type: 'text' as const,
text: `Error applying quantum gate: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleAddMeasurement(input: any) {
try {
const bridge = getPythonBridge();
// For now, measurements are added automatically by CUDA Quantum
// This tool documents the measurement intention
return {
content: [
{
type: 'text' as const,
text: `Measurements will be applied to kernel '${input.kernel_name}' in ${input.basis || 'Z'} basis. CUDA Quantum automatically measures all qubits if no explicit measurements are specified.`
}
]
};
} catch (error) {
logger.error('Error adding measurement:', error);
return {
content: [
{
type: 'text' as const,
text: `Error adding measurement: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleCreateCommonCircuit(input: any) {
try {
const bridge = getPythonBridge();
// Create the kernel first
const numQubits = input.num_qubits || (input.circuit_type === 'bell_pair' ? 2 : 3);
let kernelResponse = await bridge.createKernel(input.name, numQubits);
if (!kernelResponse.success) {
throw new Error(kernelResponse.error || 'Failed to create kernel');
}
// Apply gates based on circuit type
switch (input.circuit_type) {
case 'bell_pair':
await bridge.applyGate(input.name, 'h', [0]);
await bridge.applyGate(input.name, 'x', [1], undefined, [0]);
break;
case 'ghz_state':
await bridge.applyGate(input.name, 'h', [0]);
for (let i = 1; i < numQubits; i++) {
await bridge.applyGate(input.name, 'x', [i], undefined, [0]);
}
break;
case 'hadamard_test':
await bridge.applyGate(input.name, 'h', [0]);
// Additional gates would depend on the operator being tested
break;
default:
throw new Error(`Unsupported circuit type: ${input.circuit_type}`);
}
return {
content: [
{
type: 'text' as const,
text: `Successfully created ${input.circuit_type} circuit named '${input.name}' with ${numQubits} qubits.`
}
]
};
} catch (error) {
logger.error('Error creating common circuit:', error);
return {
content: [
{
type: 'text' as const,
text: `Error creating common circuit: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleListQuantumKernels(input: any) {
try {
const bridge = getPythonBridge();
const response = await bridge.listKernels();
if (response.success) {
const kernels = response.kernels || [];
const metadata = response.metadata || {};
if (kernels.length === 0) {
return {
content: [
{
type: 'text' as const,
text: 'No quantum kernels available. Create a kernel first using create_quantum_kernel.'
}
]
};
}
let output = `Available quantum kernels (${kernels.length}):\n\n`;
for (const kernelName of kernels) {
const meta = metadata[kernelName] || {};
output += `${kernelName}\n`;
if (input.detailed && meta) {
output += ` - Qubits: ${meta.num_qubits || 'Unknown'}\n`;
output += ` - Parameters: ${meta.parameters?.length || 0}\n`;
output += ` - Operations: ${meta.operations?.length || 0}\n`;
}
output += '\n';
}
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} else {
throw new Error(response.error || 'Failed to list kernels');
}
} catch (error) {
logger.error('Error listing quantum kernels:', error);
return {
content: [
{
type: 'text' as const,
text: `Error listing quantum kernels: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleVisualizeCircuit(input: any) {
try {
const bridge = getPythonBridge();
const response = await bridge.listKernels();
if (!response.success || !response.kernels?.includes(input.kernel_name)) {
throw new Error(`Kernel '${input.kernel_name}' not found`);
}
const metadata = response.metadata?.[input.kernel_name];
if (!metadata) {
throw new Error(`No metadata available for kernel '${input.kernel_name}'`);
}
// Generate simple text visualization
let circuit = `Quantum Circuit: ${input.kernel_name}\n`;
circuit += `Qubits: ${metadata.num_qubits}\n\n`;
const operations = metadata.operations || [];
if (operations.length === 0) {
circuit += 'No operations applied yet.\n';
} else {
circuit += 'Operations:\n';
operations.forEach((op: any, index: number) => {
const controls = op.controls ? ` (ctrl: ${op.controls.join(',')})` : '';
const params = op.parameters ? ` (${op.parameters.join(',')})` : '';
circuit += `${index + 1}. ${op.gate.toUpperCase()}${params} → qubits[${op.qubits.join(',')}]${controls}\n`;
});
}
return {
content: [
{
type: 'text' as const,
text: circuit
}
]
};
} catch (error) {
logger.error('Error visualizing circuit:', error);
return {
content: [
{
type: 'text' as const,
text: `Error visualizing circuit: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
// Export all tools
export const quantumCircuitTools: Tool[] = [
createQuantumKernelTool,
applyQuantumGateTool,
addMeasurementTool,
createCommonCircuitTool,
listQuantumKernelsTool,
visualizeCircuitTool
];

532
src/tools/execution-tools.ts Archivo normal
Ver fichero

@@ -0,0 +1,532 @@
/**
* Quantum Execution Tools for MCP Server
* Provides tools for executing quantum circuits and obtaining results
*/
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { ExecuteKernelSchema, ExecuteKernelInput } from '../types/index.js';
import { getPythonBridge } from '../bridge/python-bridge.js';
import { Logger } from '../utils/logger.js';
const logger = new Logger('QuantumExecutionTools');
/**
* Tool for sampling quantum circuits
*/
export const sampleQuantumCircuitTool: Tool = {
name: 'sample_quantum_circuit',
description: 'Sample measurement results from a quantum circuit execution',
inputSchema: {
type: 'object',
properties: {
kernel_name: {
type: 'string',
description: 'Name of the quantum kernel to execute'
},
shots: {
type: 'integer',
minimum: 1,
maximum: 100000,
default: 1000,
description: 'Number of measurement shots'
},
parameters: {
type: 'object',
description: 'Parameters to pass to the quantum kernel'
},
target: {
type: 'string',
description: 'Quantum execution target',
default: 'qpp-cpu'
}
},
required: ['kernel_name']
}
};
/**
* Tool for computing expectation values
*/
export const observeHamiltonianTool: Tool = {
name: 'observe_hamiltonian',
description: 'Compute the expectation value of a Hamiltonian using a quantum circuit',
inputSchema: {
type: 'object',
properties: {
kernel_name: {
type: 'string',
description: 'Name of the quantum kernel to use'
},
hamiltonian_terms: {
type: 'array',
description: 'Pauli terms defining the Hamiltonian',
items: {
type: 'object',
properties: {
paulis: {
type: 'array',
items: {
type: 'string',
enum: ['I', 'X', 'Y', 'Z']
}
},
qubits: {
type: 'array',
items: { type: 'integer', minimum: 0 }
},
coefficient: {
type: 'object',
properties: {
real: { type: 'number' },
imag: { type: 'number' }
},
required: ['real', 'imag']
}
},
required: ['paulis', 'qubits', 'coefficient']
}
},
shots: {
type: 'integer',
minimum: 1,
maximum: 100000,
default: 1000,
description: 'Number of measurement shots'
},
parameters: {
type: 'object',
description: 'Parameters to pass to the quantum kernel'
}
},
required: ['kernel_name', 'hamiltonian_terms']
}
};
/**
* Tool for getting quantum state vectors
*/
export const getQuantumStateTool: Tool = {
name: 'get_quantum_state',
description: 'Get the quantum state vector from a quantum circuit',
inputSchema: {
type: 'object',
properties: {
kernel_name: {
type: 'string',
description: 'Name of the quantum kernel'
},
parameters: {
type: 'object',
description: 'Parameters to pass to the quantum kernel'
},
format: {
type: 'string',
enum: ['amplitudes', 'probabilities', 'both'],
default: 'amplitudes',
description: 'Output format for the state'
}
},
required: ['kernel_name']
}
};
/**
* Tool for running quantum algorithms
*/
export const runQuantumAlgorithmTool: Tool = {
name: 'run_quantum_algorithm',
description: 'Execute quantum algorithms with custom return values',
inputSchema: {
type: 'object',
properties: {
kernel_name: {
type: 'string',
description: 'Name of the quantum kernel'
},
shots: {
type: 'integer',
minimum: 1,
maximum: 100000,
default: 1000,
description: 'Number of executions'
},
parameters: {
type: 'object',
description: 'Parameters to pass to the quantum kernel'
}
},
required: ['kernel_name']
}
};
/**
* Tool for quantum variational optimization
*/
export const variationalOptimizationTool: Tool = {
name: 'variational_optimization',
description: 'Perform variational quantum optimization using gradient-based methods',
inputSchema: {
type: 'object',
properties: {
kernel_name: {
type: 'string',
description: 'Name of the parameterized quantum kernel'
},
hamiltonian_terms: {
type: 'array',
description: 'Hamiltonian terms for the cost function',
items: {
type: 'object',
properties: {
paulis: {
type: 'array',
items: { type: 'string', enum: ['I', 'X', 'Y', 'Z'] }
},
qubits: {
type: 'array',
items: { type: 'integer', minimum: 0 }
},
coefficient: {
type: 'object',
properties: {
real: { type: 'number' },
imag: { type: 'number' }
}
}
}
}
},
initial_parameters: {
type: 'array',
description: 'Initial parameter values',
items: { type: 'number' }
},
optimizer: {
type: 'string',
enum: ['cobyla', 'l-bfgs-b', 'gradient-descent'],
default: 'cobyla',
description: 'Optimization algorithm'
},
max_iterations: {
type: 'integer',
minimum: 1,
maximum: 1000,
default: 100,
description: 'Maximum optimization iterations'
}
},
required: ['kernel_name', 'hamiltonian_terms', 'initial_parameters']
}
};
/**
* Implementation functions
*/
export async function handleSampleQuantumCircuit(input: any) {
try {
const bridge = getPythonBridge();
// Set target if specified
if (input.target) {
await bridge.setTarget(input.target);
}
const response = await bridge.sample(
input.kernel_name,
input.shots || 1000,
input.parameters
);
if (response.success) {
const result = response.result || {};
const counts = result.counts || {};
const shots = result.shots || input.shots || 1000;
// Format results
let output = `Sampling Results for '${input.kernel_name}':\n\n`;
output += `Shots: ${shots}\n`;
output += `Results:\n`;
const sortedStates = Object.entries(counts).sort((a, b) => (b[1] as number) - (a[1] as number));
for (const [state, count] of sortedStates) {
const probability = ((count as number) / shots * 100).toFixed(2);
output += ` |${state}⟩: ${count} (${probability}%)\n`;
}
// Calculate entropy
const totalCounts = Object.values(counts).reduce((a, b) => (a as number) + (b as number), 0);
let entropy = 0;
for (const count of Object.values(counts)) {
if ((count as number) > 0) {
const p = (count as number) / totalCounts;
entropy -= p * Math.log2(p);
}
}
output += `\nEntropy: ${entropy.toFixed(3)} bits\n`;
logger.info(`Sampled quantum circuit ${input.kernel_name} with ${shots} shots`);
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} else {
throw new Error(response.error || 'Failed to sample quantum circuit');
}
} catch (error) {
logger.error('Error sampling quantum circuit:', error);
return {
content: [
{
type: 'text' as const,
text: `Error sampling quantum circuit: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleObserveHamiltonian(input: any) {
try {
const bridge = getPythonBridge();
const response = await bridge.observe(
input.kernel_name,
input.hamiltonian_terms,
input.shots || 1000,
input.parameters
);
if (response.success) {
const result = response.result || {};
const expectation = result.expectation;
const variance = result.variance;
const shots = result.shots || input.shots || 1000;
let output = `Hamiltonian Expectation Value for '${input.kernel_name}':\n\n`;
output += `Expectation Value: ${expectation}\n`;
if (variance !== undefined) {
output += `Variance: ${variance}\n`;
output += `Standard Deviation: ${Math.sqrt(variance).toFixed(6)}\n`;
}
output += `Shots: ${shots}\n`;
// Display Hamiltonian terms
output += `\nHamiltonian Terms:\n`;
input.hamiltonian_terms.forEach((term: any, index: number) => {
const coeff = term.coefficient.imag !== 0
? `${term.coefficient.real} + ${term.coefficient.imag}i`
: `${term.coefficient.real}`;
const pauli_str = term.paulis.map((p: string, i: number) => `${p}_${term.qubits[i]}`).join(' ⊗ ');
output += ` Term ${index + 1}: ${coeff} × (${pauli_str})\n`;
});
logger.info(`Computed expectation value for ${input.kernel_name}: ${expectation}`);
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} else {
throw new Error(response.error || 'Failed to observe Hamiltonian');
}
} catch (error) {
logger.error('Error observing Hamiltonian:', error);
return {
content: [
{
type: 'text' as const,
text: `Error observing Hamiltonian: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleGetQuantumState(input: any) {
try {
const bridge = getPythonBridge();
const response = await bridge.getState(
input.kernel_name,
input.parameters
);
if (response.success) {
const result = response.result || {};
const state = result.state || [];
const dimension = result.dimension || state.length;
let output = `Quantum State for '${input.kernel_name}':\n\n`;
output += `State Vector Dimension: ${dimension}\n`;
if (input.format === 'probabilities' || input.format === 'both') {
output += `\nProbability Amplitudes:\n`;
state.forEach((amplitude: any, index: number) => {
const prob = amplitude.real * amplitude.real + amplitude.imag * amplitude.imag;
if (prob > 1e-10) { // Only show non-negligible amplitudes
const binary = index.toString(2).padStart(Math.log2(dimension), '0');
output += ` |${binary}⟩: ${(prob * 100).toFixed(4)}%\n`;
}
});
}
if (input.format === 'amplitudes' || input.format === 'both') {
output += `\nComplex Amplitudes:\n`;
state.forEach((amplitude: any, index: number) => {
const magnitude = Math.sqrt(amplitude.real * amplitude.real + amplitude.imag * amplitude.imag);
if (magnitude > 1e-10) {
const binary = index.toString(2).padStart(Math.log2(dimension), '0');
const complex_str = amplitude.imag >= 0
? `${amplitude.real.toFixed(6)} + ${amplitude.imag.toFixed(6)}i`
: `${amplitude.real.toFixed(6)} - ${Math.abs(amplitude.imag).toFixed(6)}i`;
output += ` |${binary}⟩: ${complex_str}\n`;
}
});
}
// Calculate purity and other properties
let purity = 0;
for (const amplitude of state) {
const prob = amplitude.real * amplitude.real + amplitude.imag * amplitude.imag;
purity += prob * prob;
}
output += `\nState Properties:\n`;
output += ` Purity: ${purity.toFixed(6)}\n`;
output += ` Entanglement: ${purity < 0.99 ? 'Entangled' : 'Separable'}\n`;
logger.info(`Retrieved quantum state for ${input.kernel_name} (dimension: ${dimension})`);
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} else {
throw new Error(response.error || 'Failed to get quantum state');
}
} catch (error) {
logger.error('Error getting quantum state:', error);
return {
content: [
{
type: 'text' as const,
text: `Error getting quantum state: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleRunQuantumAlgorithm(input: any) {
try {
const bridge = getPythonBridge();
// This would use CUDA Quantum's run() function for kernels that return values
// For now, we'll use sample as a placeholder
const response = await bridge.sample(
input.kernel_name,
input.shots || 1000,
input.parameters
);
if (response.success) {
let output = `Quantum Algorithm Execution Results for '${input.kernel_name}':\n\n`;
output += `Executions: ${input.shots || 1000}\n`;
output += `Status: Completed Successfully\n`;
// For actual algorithms, this would show algorithm-specific results
output += `\nNote: This is a sample-based execution. For algorithms with custom return values, `;
output += `implement the kernel with appropriate return statements in CUDA Quantum.\n`;
logger.info(`Executed quantum algorithm ${input.kernel_name}`);
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} else {
throw new Error(response.error || 'Failed to run quantum algorithm');
}
} catch (error) {
logger.error('Error running quantum algorithm:', error);
return {
content: [
{
type: 'text' as const,
text: `Error running quantum algorithm: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleVariationalOptimization(input: any) {
try {
// This is a placeholder for variational optimization
// In a full implementation, this would use optimization libraries
let output = `Variational Optimization for '${input.kernel_name}':\n\n`;
output += `Initial Parameters: [${input.initial_parameters.join(', ')}]\n`;
output += `Optimizer: ${input.optimizer}\n`;
output += `Max Iterations: ${input.max_iterations}\n`;
output += `\nNote: Variational optimization requires integration with optimization libraries.\n`;
output += `This is a placeholder implementation. In production, this would:\n`;
output += `1. Create cost function from Hamiltonian expectation value\n`;
output += `2. Use gradient-based or gradient-free optimization\n`;
output += `3. Return optimized parameters and minimum energy\n`;
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} catch (error) {
logger.error('Error in variational optimization:', error);
return {
content: [
{
type: 'text' as const,
text: `Error in variational optimization: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
// Export all tools
export const quantumExecutionTools: Tool[] = [
sampleQuantumCircuitTool,
observeHamiltonianTool,
getQuantumStateTool,
runQuantumAlgorithmTool,
variationalOptimizationTool
];

446
src/tools/hardware-tools.ts Archivo normal
Ver fichero

@@ -0,0 +1,446 @@
/**
* Hardware Backend Tools for MCP Server
* Provides tools for managing quantum execution targets and hardware backends
*/
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { SetTargetSchema, QuantumBackends } from '../types/index.js';
import { getPythonBridge } from '../bridge/python-bridge.js';
import { Logger } from '../utils/logger.js';
const logger = new Logger('HardwareBackendTools');
/**
* Tool for setting quantum execution target
*/
export const setQuantumTargetTool: Tool = {
name: 'set_quantum_target',
description: 'Set the quantum execution target (simulator or hardware backend)',
inputSchema: {
type: 'object',
properties: {
target: {
type: 'string',
description: 'Quantum target name',
enum: Object.keys(QuantumBackends)
},
configuration: {
type: 'object',
description: 'Target-specific configuration options',
properties: {
shots: { type: 'integer', minimum: 1, maximum: 100000 },
optimization_level: { type: 'integer', minimum: 0, maximum: 3 },
api_key: { type: 'string', description: 'API key for hardware providers' },
url: { type: 'string', description: 'Custom endpoint URL' },
device: { type: 'string', description: 'Specific device name' },
noise_model: { type: 'string', description: 'Noise model for simulation' },
error_mitigation: { type: 'boolean', description: 'Enable error mitigation' }
}
}
},
required: ['target']
}
};
/**
* Tool for listing available quantum backends
*/
export const listQuantumBackendsTool: Tool = {
name: 'list_quantum_backends',
description: 'List all available quantum backends and their capabilities',
inputSchema: {
type: 'object',
properties: {
category: {
type: 'string',
enum: ['all', 'simulators', 'hardware'],
default: 'all',
description: 'Filter backends by category'
},
detailed: {
type: 'boolean',
default: false,
description: 'Include detailed information about each backend'
}
}
}
};
/**
* Tool for getting platform information
*/
export const getPlatformInfoTool: Tool = {
name: 'get_platform_info',
description: 'Get information about the current quantum platform and available resources',
inputSchema: {
type: 'object',
properties: {}
}
};
/**
* Tool for testing backend connectivity
*/
export const testBackendConnectivityTool: Tool = {
name: 'test_backend_connectivity',
description: 'Test connectivity to quantum hardware providers',
inputSchema: {
type: 'object',
properties: {
backend: {
type: 'string',
description: 'Backend to test',
enum: Object.keys(QuantumBackends)
},
credentials: {
type: 'object',
description: 'Credentials for the backend',
properties: {
api_key: { type: 'string' },
url: { type: 'string' },
username: { type: 'string' },
password: { type: 'string' }
}
}
},
required: ['backend']
}
};
/**
* Tool for GPU acceleration configuration
*/
export const configureGpuAccelerationTool: Tool = {
name: 'configure_gpu_acceleration',
description: 'Configure GPU acceleration for quantum simulations',
inputSchema: {
type: 'object',
properties: {
enable: {
type: 'boolean',
description: 'Enable or disable GPU acceleration'
},
device_id: {
type: 'integer',
minimum: 0,
description: 'GPU device ID to use'
},
memory_limit: {
type: 'number',
description: 'GPU memory limit in GB'
},
target: {
type: 'string',
enum: ['qpp-gpu', 'density-matrix-gpu'],
default: 'qpp-gpu',
description: 'GPU-accelerated target'
}
},
required: ['enable']
}
};
/**
* Implementation functions
*/
export async function handleSetQuantumTarget(input: any) {
try {
const bridge = getPythonBridge();
const response = await bridge.setTarget(input.target, input.configuration);
if (response.success) {
logger.info(`Set quantum target to: ${input.target}`);
let output = `Successfully set quantum target to: ${input.target}\n\n`;
output += `Description: ${QuantumBackends[input.target as keyof typeof QuantumBackends]}\n`;
if (input.configuration) {
output += `\nConfiguration:\n`;
for (const [key, value] of Object.entries(input.configuration)) {
if (key !== 'api_key') { // Don't log sensitive information
output += ` ${key}: ${value}\n`;
} else {
output += ` ${key}: [REDACTED]\n`;
}
}
}
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} else {
throw new Error(response.error || 'Failed to set quantum target');
}
} catch (error) {
logger.error('Error setting quantum target:', error);
return {
content: [
{
type: 'text' as const,
text: `Error setting quantum target: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleListQuantumBackends(input: any) {
try {
let output = `Available Quantum Backends:\n\n`;
const simulators = ['qpp-cpu', 'qpp-gpu', 'density-matrix-cpu', 'tensor-network'];
const hardware = ['ionq', 'quantinuum', 'quantum_machines', 'infleqtion', 'iqm', 'oqc', 'pasqal'];
if (input.category === 'all' || input.category === 'simulators') {
output += `🖥️ Simulators:\n`;
for (const backend of simulators) {
if (backend in QuantumBackends) {
output += `${backend}: ${QuantumBackends[backend as keyof typeof QuantumBackends]}\n`;
if (input.detailed) {
output += ` - Local execution\n`;
output += ` - GPU support: ${backend.includes('gpu') ? 'Yes' : 'No'}\n`;
output += ` - Max qubits: ${backend.includes('tensor') ? '40+' : '32'}\n`;
output += `\n`;
}
}
}
output += `\n`;
}
if (input.category === 'all' || input.category === 'hardware') {
output += `🔬 Hardware Providers:\n`;
for (const backend of hardware) {
if (backend in QuantumBackends) {
output += `${backend}: ${QuantumBackends[backend as keyof typeof QuantumBackends]}\n`;
if (input.detailed) {
output += ` - Remote execution\n`;
output += ` - Authentication required\n`;
output += ` - Variable queue times\n`;
output += `\n`;
}
}
}
}
output += `\nTo set a target, use: set_quantum_target\n`;
output += `For GPU acceleration, ensure CUDA is installed and use GPU-enabled targets.\n`;
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} catch (error) {
logger.error('Error listing quantum backends:', error);
return {
content: [
{
type: 'text' as const,
text: `Error listing quantum backends: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleGetPlatformInfo(input: any) {
try {
const bridge = getPythonBridge();
const response = await bridge.getPlatformInfo();
if (response.success) {
const result = response.result || {};
let output = `Quantum Platform Information:\n\n`;
output += `Platform Name: ${result.platform_name || 'Unknown'}\n`;
output += `Number of QPUs: ${result.num_qpus || 'Unknown'}\n`;
output += `Is Simulator: ${result.is_simulator !== undefined ? result.is_simulator : 'Unknown'}\n`;
output += `Is Remote: ${result.is_remote !== undefined ? result.is_remote : 'Unknown'}\n`;
// Add system information
output += `\nSystem Information:\n`;
output += `Node.js Version: ${process.version}\n`;
output += `Platform: ${process.platform}\n`;
output += `Architecture: ${process.arch}\n`;
// GPU information (if available)
const cudaDevice = process.env.CUDA_VISIBLE_DEVICES;
if (cudaDevice) {
output += `CUDA Visible Devices: ${cudaDevice}\n`;
}
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} else {
throw new Error(response.error || 'Failed to get platform information');
}
} catch (error) {
logger.error('Error getting platform information:', error);
return {
content: [
{
type: 'text' as const,
text: `Error getting platform information: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleTestBackendConnectivity(input: any) {
try {
const backend = input.backend;
let output = `Testing connectivity to ${backend}...\n\n`;
// Check if it's a simulator (always available)
const simulators = ['qpp-cpu', 'qpp-gpu', 'density-matrix-cpu', 'tensor-network'];
if (simulators.includes(backend)) {
output += `${backend} is available (local simulator)\n`;
if (backend.includes('gpu')) {
const cudaDevice = process.env.CUDA_VISIBLE_DEVICES;
if (cudaDevice) {
output += `✅ CUDA device available: ${cudaDevice}\n`;
} else {
output += `⚠️ CUDA_VISIBLE_DEVICES not set, using default GPU\n`;
}
}
} else {
// Hardware backend - check credentials
output += `🔗 ${backend} is a hardware provider\n`;
if (input.credentials?.api_key) {
output += `✅ API key provided\n`;
} else {
output += `❌ API key required for ${backend}\n`;
}
if (input.credentials?.url) {
output += `✅ Custom URL provided: ${input.credentials.url}\n`;
}
output += `\nNote: Actual connectivity testing requires valid credentials and active connection.\n`;
}
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} catch (error) {
logger.error('Error testing backend connectivity:', error);
return {
content: [
{
type: 'text' as const,
text: `Error testing backend connectivity: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
export async function handleConfigureGpuAcceleration(input: any) {
try {
let output = `GPU Acceleration Configuration:\n\n`;
if (input.enable) {
output += `✅ Enabling GPU acceleration\n`;
output += `Target: ${input.target || 'qpp-gpu'}\n`;
if (input.device_id !== undefined) {
output += `GPU Device ID: ${input.device_id}\n`;
// Update environment variable
process.env.CUDA_VISIBLE_DEVICES = input.device_id.toString();
}
if (input.memory_limit) {
output += `Memory Limit: ${input.memory_limit} GB\n`;
}
// Attempt to set GPU target
try {
const bridge = getPythonBridge();
const response = await bridge.setTarget(input.target || 'qpp-gpu');
if (response.success) {
output += `✅ Successfully configured GPU target\n`;
} else {
output += `❌ Failed to set GPU target: ${response.error}\n`;
}
} catch (error) {
output += `❌ Error setting GPU target: ${error}\n`;
}
output += `\nNote: Ensure NVIDIA drivers and CUDA toolkit are installed for GPU acceleration.\n`;
} else {
output += `❌ Disabling GPU acceleration\n`;
output += `Falling back to CPU simulation\n`;
try {
const bridge = getPythonBridge();
await bridge.setTarget('qpp-cpu');
output += `✅ Set target to CPU simulator\n`;
} catch (error) {
output += `❌ Error setting CPU target: ${error}\n`;
}
}
return {
content: [
{
type: 'text' as const,
text: output
}
]
};
} catch (error) {
logger.error('Error configuring GPU acceleration:', error);
return {
content: [
{
type: 'text' as const,
text: `Error configuring GPU acceleration: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
}
// Export all tools
export const hardwareBackendTools: Tool[] = [
setQuantumTargetTool,
listQuantumBackendsTool,
getPlatformInfoTool,
testBackendConnectivityTool,
configureGpuAccelerationTool
];