Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-10-08 03:12:29 +02:00
padre b4c6a7d52e
commit 2959aea9b1
Se han modificado 7 ficheros con 285 adiciones y 70 borrados

175
.gitignore vendido Archivo normal
Ver fichero

@@ -0,0 +1,175 @@
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
yarn.lock
# Build outputs
dist/
build/
*.tsbuildinfo
# Environment files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# Logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Runtime data
pids/
*.pid
*.seed
*.pid.lock
# Coverage directory used by tools like istanbul
coverage/
*.lcov
.nyc_output
# ESLint cache
.eslintcache
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
.env.production
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
public
# Vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# IDE files
.vscode/
.idea/
*.swp
*.swo
*~
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
ENV/
env.bak/
venv.bak/
# Jupyter Notebook
.ipynb_checkpoints
# pytest
.pytest_cache/
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Docker
docker-compose.override.yml
# Temporary files
tmp/
temp/
*.tmp
*.temp
# Security
*.pem
*.key
!*.key.example
# Database
*.db
*.sqlite
*.sqlite3
# Quantum simulation data
quantum_data/
simulation_results/
*.qasm
*.qobj
# MCP specific
mcp_logs/
quantum_kernels/
circuit_cache/
# Development
.env.development
.env.staging
# Production
.env.production
# Test coverage
coverage/
*.coverage
# Backup files
*.backup
*.bak

Ver fichero

@@ -35,38 +35,30 @@
"node": ">=18.0.0" "node": ">=18.0.0"
}, },
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0", "@modelcontextprotocol/sdk": "^0.5.0",
"python-bridge": "^2.0.2", "chalk": "^5.6.2",
"node-ffi-napi": "^2.5.0", "commander": "^11.1.0",
"ref-napi": "^3.0.3", "dotenv": "^16.6.1",
"ref-array-napi": "^1.2.2",
"ref-struct-napi": "^1.1.1",
"zod": "^3.22.0",
"winston": "^3.11.0",
"express": "^4.18.2",
"cors": "^2.8.5",
"helmet": "^7.1.0",
"dotenv": "^16.3.1",
"uuid": "^9.0.1", "uuid": "^9.0.1",
"chalk": "^5.3.0", "winston": "^3.18.3",
"commander": "^11.1.0" "zod": "^3.25.76"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.10.0",
"@types/uuid": "^9.0.7",
"@types/express": "^4.17.21",
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.8", "@types/jest": "^29.5.8",
"typescript": "^5.3.0", "@types/node": "^20.19.19",
"ts-node": "^10.9.0", "@types/uuid": "^9.0.7",
"jest": "^29.7.0",
"ts-jest": "^29.1.0",
"eslint": "^8.55.0",
"@typescript-eslint/eslint-plugin": "^6.13.0", "@typescript-eslint/eslint-plugin": "^6.13.0",
"@typescript-eslint/parser": "^6.13.0", "@typescript-eslint/parser": "^6.13.0",
"eslint": "^8.55.0",
"jest": "^29.7.0",
"nodemon": "^3.0.2",
"prettier": "^3.1.0", "prettier": "^3.1.0",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.0",
"typedoc": "^0.25.0", "typedoc": "^0.25.0",
"nodemon": "^3.0.2" "typescript": "^5.3.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

Ver fichero

@@ -21,8 +21,8 @@ try:
logger.info("CUDA Quantum successfully imported") logger.info("CUDA Quantum successfully imported")
except ImportError as e: except ImportError as e:
CUDAQ_AVAILABLE = False CUDAQ_AVAILABLE = False
logger.error(f"CUDA Quantum not available: {e}") logger.warning(f"CUDA Quantum not available: {e}")
logger.error("Please install CUDA Quantum: pip install cudaq") logger.warning("Running in mock mode - install CUDA Quantum for full functionality: pip install cudaq")
class QuantumKernelManager: class QuantumKernelManager:
@@ -35,7 +35,13 @@ class QuantumKernelManager:
def create_kernel(self, name: str, num_qubits: int, parameters: Optional[List[Dict]] = None) -> Dict: def create_kernel(self, name: str, num_qubits: int, parameters: Optional[List[Dict]] = None) -> Dict:
"""Create a new quantum kernel""" """Create a new quantum kernel"""
if not CUDAQ_AVAILABLE: if not CUDAQ_AVAILABLE:
return {"error": "CUDA Quantum not available"} # Mock mode - store kernel metadata without actual CUDA Quantum
self.kernel_metadata[name] = {
"num_qubits": num_qubits,
"parameters": parameters or [],
"operations": []
}
return {"success": True, "kernel_name": name, "mode": "mock"}
try: try:
# Create kernel dynamically # Create kernel dynamically
@@ -216,7 +222,31 @@ class QuantumExecutor:
parameters: Optional[Dict] = None) -> Dict: parameters: Optional[Dict] = None) -> Dict:
"""Sample measurement results from quantum kernel""" """Sample measurement results from quantum kernel"""
if not CUDAQ_AVAILABLE: if not CUDAQ_AVAILABLE:
return {"error": "CUDA Quantum not available"} # Mock mode - return simulated results
if kernel_name not in self.kernel_manager.kernel_metadata:
return {"error": f"Kernel {kernel_name} not found"}
import random
num_qubits = self.kernel_manager.kernel_metadata[kernel_name]["num_qubits"]
# Generate mock results for demonstration
mock_counts = {}
if num_qubits == 2: # Bell pair example
mock_counts = {"00": shots//2 + random.randint(-50, 50),
"11": shots//2 + random.randint(-50, 50)}
else:
# Random distribution
for i in range(min(4, 2**num_qubits)):
binary = format(i, f'0{num_qubits}b')
mock_counts[binary] = random.randint(shots//10, shots//3)
return {
"success": True,
"counts": mock_counts,
"shots": shots,
"total_counts": sum(mock_counts.values()),
"mode": "mock"
}
if kernel_name not in self.kernel_manager.kernels: if kernel_name not in self.kernel_manager.kernels:
return {"error": f"Kernel {kernel_name} not found"} return {"error": f"Kernel {kernel_name} not found"}
@@ -459,24 +489,30 @@ def main():
except Exception as e: except Exception as e:
print(json.dumps({"error": str(e), "traceback": traceback.format_exc()})) print(json.dumps({"error": str(e), "traceback": traceback.format_exc()}))
else: else:
# Interactive mode # Server mode - read from stdin for MCP communication
print("CUDA Quantum Python Bridge - Interactive Mode") print("CUDA Quantum Python Bridge - Ready")
print("Available commands: create_kernel, apply_gate, set_target, sample, observe, get_state") sys.stdout.flush()
while True:
try: try:
command_line = input("> ") while True:
if command_line.lower() in ["quit", "exit"]: line = sys.stdin.readline()
if not line:
break break
command_data = json.loads(command_line) try:
command_data = json.loads(line.strip())
result = dispatch_command(**command_data) result = dispatch_command(**command_data)
print(json.dumps(result, indent=2)) print(json.dumps(result))
sys.stdout.flush()
except KeyboardInterrupt: except json.JSONDecodeError:
break print(json.dumps({"error": "Invalid JSON"}))
sys.stdout.flush()
except Exception as e: except Exception as e:
print(json.dumps({"error": str(e)})) print(json.dumps({"error": str(e)}))
sys.stdout.flush()
except KeyboardInterrupt:
pass
if __name__ == "__main__": if __name__ == "__main__":

Ver fichero

@@ -4,7 +4,7 @@
*/ */
import { spawn, ChildProcess } from 'child_process'; import { spawn, ChildProcess } from 'child_process';
import path from 'path'; import * as path from 'path';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { import {
PythonCall, PythonCall,
@@ -40,7 +40,7 @@ export class PythonBridge extends EventEmitter {
this.config = { this.config = {
pythonPath: config.pythonPath || process.env.CUDAQ_PYTHON_PATH || 'python3', pythonPath: config.pythonPath || process.env.CUDAQ_PYTHON_PATH || 'python3',
scriptPath: config.scriptPath || path.join(__dirname, '../../python/cudaq_bridge.py'), scriptPath: config.scriptPath || path.join(process.cwd(), 'python/cudaq_bridge.py'),
timeout: config.timeout || 60000, timeout: config.timeout || 60000,
maxMemory: config.maxMemory || 2048 maxMemory: config.maxMemory || 2048
}; };
@@ -81,7 +81,7 @@ export class PythonBridge extends EventEmitter {
const output = data.toString(); const output = data.toString();
this.logger.debug('Python stdout:', output); this.logger.debug('Python stdout:', output);
if (!initialized && output.includes('CUDA Quantum Python Bridge')) { if (!initialized && (output.includes('CUDA Quantum Python Bridge') || output.includes('Ready'))) {
initialized = true; initialized = true;
resolve(); resolve();
} }
@@ -92,11 +92,21 @@ export class PythonBridge extends EventEmitter {
this.pythonProcess.stderr?.on('data', (data: Buffer) => { this.pythonProcess.stderr?.on('data', (data: Buffer) => {
const error = data.toString(); const error = data.toString();
this.logger.error('Python stderr:', error);
// Check if it's just a warning about CUDA Quantum not being available
if (error.includes('WARNING') && error.includes('CUDA Quantum not available')) {
this.logger.warn('Python warning:', error);
// Don't treat this as a fatal error - continue with initialization
if (!initialized) {
initialized = true;
resolve();
}
} else {
this.logger.error('Python stderr:', error);
if (!initialized) { if (!initialized) {
reject(new Error(`Python process error: ${error}`)); reject(new Error(`Python process error: ${error}`));
} }
}
}); });
this.pythonProcess.on('error', (error) => { this.pythonProcess.on('error', (error) => {

Ver fichero

@@ -63,9 +63,9 @@ export class CudaQuantumMCPServer {
constructor(config: ServerConfig) { constructor(config: ServerConfig) {
this.config = { this.config = {
name: 'cuda-quantum-mcp', ...config,
version: '1.0.0', name: config.name || 'cuda-quantum-mcp',
...config version: config.version || '1.0.0'
}; };
this.logger = new Logger('MCPServer', { this.logger = new Logger('MCPServer', {
@@ -117,41 +117,41 @@ export class CudaQuantumMCPServer {
switch (name) { switch (name) {
// Quantum Circuit Tools // Quantum Circuit Tools
case 'create_quantum_kernel': case 'create_quantum_kernel':
return await handleCreateQuantumKernel(args); return await handleCreateQuantumKernel(args as any);
case 'apply_quantum_gate': case 'apply_quantum_gate':
return await handleApplyQuantumGate(args); return await handleApplyQuantumGate(args as any);
case 'add_measurement': case 'add_measurement':
return await handleAddMeasurement(args); return await handleAddMeasurement(args as any);
case 'create_common_circuit': case 'create_common_circuit':
return await handleCreateCommonCircuit(args); return await handleCreateCommonCircuit(args as any);
case 'list_quantum_kernels': case 'list_quantum_kernels':
return await handleListQuantumKernels(args); return await handleListQuantumKernels(args as any);
case 'visualize_circuit': case 'visualize_circuit':
return await handleVisualizeCircuit(args); return await handleVisualizeCircuit(args as any);
// Quantum Execution Tools // Quantum Execution Tools
case 'sample_quantum_circuit': case 'sample_quantum_circuit':
return await handleSampleQuantumCircuit(args); return await handleSampleQuantumCircuit(args as any);
case 'observe_hamiltonian': case 'observe_hamiltonian':
return await handleObserveHamiltonian(args); return await handleObserveHamiltonian(args as any);
case 'get_quantum_state': case 'get_quantum_state':
return await handleGetQuantumState(args); return await handleGetQuantumState(args as any);
case 'run_quantum_algorithm': case 'run_quantum_algorithm':
return await handleRunQuantumAlgorithm(args); return await handleRunQuantumAlgorithm(args as any);
case 'variational_optimization': case 'variational_optimization':
return await handleVariationalOptimization(args); return await handleVariationalOptimization(args as any);
// Hardware Backend Tools // Hardware Backend Tools
case 'set_quantum_target': case 'set_quantum_target':
return await handleSetQuantumTarget(args); return await handleSetQuantumTarget(args as any);
case 'list_quantum_backends': case 'list_quantum_backends':
return await handleListQuantumBackends(args); return await handleListQuantumBackends(args as any);
case 'get_platform_info': case 'get_platform_info':
return await handleGetPlatformInfo(args); return await handleGetPlatformInfo(args as any);
case 'test_backend_connectivity': case 'test_backend_connectivity':
return await handleTestBackendConnectivity(args); return await handleTestBackendConnectivity(args as any);
case 'configure_gpu_acceleration': case 'configure_gpu_acceleration':
return await handleConfigureGpuAcceleration(args); return await handleConfigureGpuAcceleration(args as any);
default: default:
throw new Error(`Unknown tool: ${name}`); throw new Error(`Unknown tool: ${name}`);

Ver fichero

@@ -260,7 +260,7 @@ export async function handleSampleQuantumCircuit(input: any) {
let entropy = 0; let entropy = 0;
for (const count of Object.values(counts)) { for (const count of Object.values(counts)) {
if ((count as number) > 0) { if ((count as number) > 0) {
const p = (count as number) / totalCounts; const p = (count as number) / (totalCounts as number);
entropy -= p * Math.log2(p); entropy -= p * Math.log2(p);
} }
} }

Ver fichero

@@ -311,6 +311,8 @@ export interface PythonResponse {
result?: any; result?: any;
error?: string; error?: string;
traceback?: string; traceback?: string;
kernels?: string[];
metadata?: Record<string, any>;
} }
// ============================ // ============================