Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-10-08 23:59:57 +02:00
padre a694e1085c
commit fd14a0fda6
Se han modificado 5 ficheros con 96 adiciones y 35 borrados

Ver fichero

@@ -40,5 +40,9 @@ MAX_QUBITS=32
MAX_SHOTS=100000
# Python Bridge Configuration
PYTHON_TIMEOUT=60000
# Timeout for Python commands in milliseconds
# Default: 300000 (5 minutes)
# Increase for complex quantum operations or slower hardware
PYTHON_TIMEOUT=300000
PYTHON_MEMORY_LIMIT=2048
```

Ver fichero

@@ -20,6 +20,7 @@ MCP_SERVER_VERSION=1.0.0
CUDAQ_PYTHON_PATH=/usr/local/bin/python3
CUDAQ_DEFAULT_TARGET=qpp-cpu
CUDAQ_LOG_LEVEL=info
PYTHON_TIMEOUT=300000
# GPU Configuration
CUDA_VISIBLE_DEVICES=0
@@ -36,6 +37,11 @@ MAX_CONCURRENT_JOBS=10
QUANTUM_CIRCUIT_TIMEOUT=30000
MAX_QUBITS=32
MAX_SHOTS=100000
# Python Bridge Timeout (in milliseconds)
# Default: 300000 (5 minutes)
# Increase for complex quantum operations or slower hardware
PYTHON_TIMEOUT=300000
```
### Claude Desktop Integration

Ver fichero

@@ -89,6 +89,11 @@ CUDAQ_PYTHON_PATH=/usr/local/bin/python3
CUDAQ_DEFAULT_TARGET=qpp-cpu
CUDAQ_LOG_LEVEL=info
# Python Bridge Timeout (milliseconds)
# Default: 300000 (5 minutes)
# Increase for complex operations or slower hardware
PYTHON_TIMEOUT=300000
# GPU Configuration
CUDA_VISIBLE_DEVICES=0
CUDAQ_ENABLE_GPU=true
@@ -487,13 +492,19 @@ Solution:
#### Python Bridge Timeout
```bash
Error: Python command timeout
Error: Python command timeout after Xms
Solution:
1. Increase timeout in config
2. Check Python path in .env
3. Ensure CUDA Quantum installation
1. Increase timeout with environment variable:
export PYTHON_TIMEOUT=600000 # 10 minutes in milliseconds
2. Check Python path in .env:
CUDAQ_PYTHON_PATH=/usr/local/bin/python3
3. Ensure CUDA Quantum is properly installed:
python3 -c "import cudaq; print(cudaq.__version__)"
4. Check for Python process errors in logs
```
**Note**: The default timeout is 300,000ms (5 minutes). Complex quantum operations or slower hardware may require increasing this value via the `PYTHON_TIMEOUT` environment variable.
### Debug Mode
Enable debug logging:

Ver fichero

@@ -539,6 +539,13 @@ def main():
if command:
result = dispatch_command(command, **data)
# Check if the result already has success/error structure
if isinstance(result, dict) and ("success" in result or "error" in result):
# Result already has proper structure, just add request ID
response = {**result, "requestId": request_id}
else:
# Wrap result in standard response structure
response = {
"success": True,
"data": result,
@@ -552,7 +559,10 @@ def main():
"requestId": request_id
}
print(json.dumps(response), flush=True)
# Ensure response is sent on a single line with explicit flush
output = json.dumps(response)
print(output, flush=True)
sys.stdout.flush() # Extra flush to ensure it's sent
except Exception as e:
print(f"ERROR - Exception in main loop: {str(e)}", file=sys.stderr, flush=True)
@@ -563,7 +573,9 @@ def main():
"traceback": traceback.format_exc(),
"requestId": request.get("requestId", "") if 'request' in locals() else ""
}
print(json.dumps(error_response), flush=True)
output = json.dumps(error_response)
print(output, flush=True)
sys.stdout.flush() # Extra flush to ensure it's sent
if __name__ == "__main__":

Ver fichero

@@ -38,10 +38,15 @@ export class PythonBridge extends EventEmitter {
constructor(config: PythonBridgeConfig = {}) {
super();
// Get timeout from environment variable or use default
const defaultTimeout = process.env.PYTHON_TIMEOUT
? parseInt(process.env.PYTHON_TIMEOUT, 10)
: 300000; // Default 5 minutes
this.config = {
pythonPath: config.pythonPath || process.env.CUDAQ_PYTHON_PATH || 'python3',
scriptPath: config.scriptPath || path.join(process.cwd(), 'python/cudaq_bridge.py'),
timeout: config.timeout || 60000,
timeout: config.timeout || defaultTimeout,
maxMemory: config.maxMemory || 2048
};
@@ -102,14 +107,21 @@ export class PythonBridge extends EventEmitter {
// Log stderr messages but don't treat them as fatal errors during initialization
// Most Python logging goes to stderr even for non-errors
if (error.includes('WARNING') || error.includes('INFO') || error.includes('DEBUG')) {
this.logger.debug('Python log message:', error);
} else if (error.trim()) {
this.logger.error('Python stderr:', error);
// Only reject during initialization if it's a real error (not a log message)
if (!initialized && !error.includes('INFO') && !error.includes('WARNING') && !error.includes('DEBUG')) {
if (error.includes('DEBUG')) {
this.logger.debug('Python debug:', error.trim());
} else if (error.includes('WARNING')) {
this.logger.warn('Python warning:', error.trim());
} else if (error.includes('INFO')) {
this.logger.info('Python info:', error.trim());
} else if (error.includes('ERROR')) {
this.logger.error('Python error:', error.trim());
// Only reject during initialization if it's a real error
if (!initialized) {
reject(new Error(`Python process error: ${error}`));
}
} else if (error.trim()) {
// Unknown stderr output - log as debug
this.logger.debug('Python stderr:', error.trim());
}
});
@@ -147,16 +159,25 @@ export class PythonBridge extends EventEmitter {
try {
const response = JSON.parse(line);
if (response.request_id) {
const pending = this.requestQueue.get(response.request_id);
// Handle both requestId and request_id for compatibility
const reqId = response.requestId || response.request_id;
if (reqId) {
const pending = this.requestQueue.get(reqId);
if (pending) {
this.logger.debug(`Received response for request ${reqId}`);
clearTimeout(pending.timeout);
this.requestQueue.delete(response.request_id);
this.requestQueue.delete(reqId);
pending.resolve(response);
} else {
this.logger.warn(`Received response for unknown request ${reqId}`);
}
}
} catch (e) {
// Ignore non-JSON lines
// Ignore non-JSON lines (debug logs, etc.)
if (!line.includes('DEBUG') && !line.includes('INFO') && !line.includes('WARNING')) {
this.logger.debug('Non-JSON output from Python:', line);
}
}
}
} catch (error) {
@@ -172,30 +193,37 @@ export class PythonBridge extends EventEmitter {
const requestId = Math.random().toString(36).substring(2, 15);
const request = { command, data, requestId };
// Set timeout based on command complexity
let timeoutDuration = 5000; // Default 5s
// Use environment variable timeout for all commands
// This allows users to adjust based on hardware capabilities
const timeoutDuration = this.config.timeout;
this.logger.debug(`Sending command '${command}' with request ID ${requestId} (timeout: ${timeoutDuration}ms)`);
if (command === 'set_target') {
timeoutDuration = 100000; // 100s for target operations
} else if (['sample', 'observe', 'get_state'].includes(command)) {
timeoutDuration = 150000; // 150s for quantum operations
} else if (['get_platform_info', 'get_available_targets', 'list_kernels'].includes(command)) {
timeoutDuration = 30000; // 30s for simple info operations
}
const timeout = setTimeout(() => {
this.requestQueue.delete(requestId);
reject(new Error(`Python command timeout: ${command}`));
this.logger.error(`Command '${command}' timed out after ${timeoutDuration}ms (request ID: ${requestId})`);
reject(new Error(`Python command timeout after ${timeoutDuration}ms: ${command}`));
}, timeoutDuration);
// Store request with timeout for cleanup
this.requestQueue.set(requestId, { resolve, reject, timeout });
if (!this.pythonProcess) {
clearTimeout(timeout);
this.requestQueue.delete(requestId);
reject(new Error('Python process not initialized'));
return;
}
try {
this.pythonProcess.stdin?.write(JSON.stringify(request) + '\n');
this.logger.debug(`Command '${command}' sent successfully`);
} catch (error) {
clearTimeout(timeout);
this.requestQueue.delete(requestId);
this.logger.error(`Failed to send command '${command}':`, error);
reject(error);
}
});
}