Task configuration:
{"task_id": "19", "task_name": "compare_files", "description": "\u5728vscode\u4e2d\u5bf9\u6bd4\u4e24\u4e2a\u6587\u4ef6\u6709\u4ec0\u4e48\u4e0d\u540c", "application_info": {"name": "vscode", "executable_path": "/usr/share/code/code", "args": ["--no-sandbox", "--user-data-dir=/root/vscode_user_data_dir/"]}, "task_parameters": {"file_name1": "quick_sort.cpp", "file_name2": "quick_sort_3.cpp", "file1": "/root/C-Plus-Plus/sorting/quick_sort.cpp", "file2": "/root/C-Plus-Plus/sorting/quick_sort_3.cpp"}, "instruction_template": "\u4f7f\u7528vscode\u4e2d\u7684\u627e\u5230\u6587\u4ef6 ${file_name1} \u548c ${file_name2}, \u5e76\u4e14\u4f7f\u7528\u6bd4\u8f83\u6587\u4ef6\u5185\u5bb9\u7684\u529f\u80fd\u5bf9\u6bd4\u4e24\u4e2a\u6587\u4ef6", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js"}, {"role": "handler", "path": "handler.py"}], "timeout": 120, "evaluator_type": "IpcInjector", "evaluate_on_completion": true}, "total_key_steps": 1, "preconditions": {"vscode_running": true}, "events": {"evaluate_on_completion": {"description": "\u5728\u4efb\u52a1\u7ed3\u675f\u65f6\u68c0\u67e5\u4efb\u52a1\u662f\u5426\u5b8c\u6210", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u4efb\u52a1\u6210\u529f\u5b8c\u6210"}}, "mcp_servers": [{"command": "mcp-proxy", "args": ["http://127.0.0.1:6010/sse"]}], "context_data": [{"from": "tests/context_data/vscode/user_data", "to": "/root/vscode_user_data_dir"}, {"from": "tests/context_data/vscode/extensions", "to": "/root/.vscode/"}, {"from": "tests/context_data/vscode/C-Plus-Plus", "to": "/root/C-Plus-Plus"}]}

Hook script:
/**
 * Checks if the current view is a VS Code file comparison (non-Git) and returns the paths of the compared files.
 * @returns {Promise<{ originalPath: string, modifiedPath: string } | null>} The paths of the compared files or null if not in compare mode.
 * @throws {Error} If an error occurs while checking the compare view.
 */
async function checkCompareFiles() {
    try {
        // Get the active text editor
        const activeEditor = vscode.window.activeTextEditor;
        if (!activeEditor) {
            throw new Error('No active editor found.');
        }

        // socket.emit("send", {
        //     'event_type': "get_info",
        //     'message': "任务结束时检查任务是否完成",
        //     'info': vscode.window.visibleTextEditors.map(e => ({
        //         uri: e.document.uri.toString(),
        //         scheme: e.document.uri.scheme,
        //         viewColumn: e.viewColumn
        //     }))
        // });

        // Check if the active editor is part of a diff editor
        // Diff editors typically have a specific structure and may not have a viewColumn
        if (activeEditor.viewColumn === undefined) {
            // Try to access the diff editor model
            const diffEditor = activeEditor;
            const diffModel = diffEditor._documentData?._diffEditorModel;

            if (diffModel) {
                const originalUri = diffModel.original.uri;
                const modifiedUri = diffModel.modified.uri;

                console.log('Diff model found:', {
                    originalUri: originalUri.toString(),
                    modifiedUri: modifiedUri.toString()
                });

                if (originalUri.scheme === 'file' && modifiedUri.scheme === 'file') {
                    const originalPath = originalUri.fsPath;
                    const modifiedPath = modifiedUri.fsPath;

                    if (originalPath && modifiedPath) {
                        return { originalPath, modifiedPath };
                    }
                }
                throw new Error('Invalid file URIs in diff editor.');
            } else {
                // Alternative approach: Check visible editors for diff-like behavior
                const editors = vscode.window.visibleTextEditors;
                let originalPath = '';
                let modifiedPath = '';

                for (const editor of editors) {
                    if (editor.document.uri.scheme === 'file') {
                        if (!originalPath) {
                            originalPath = editor.document.uri.fsPath;
                        } else if (!modifiedPath && editor.document.uri.fsPath !== originalPath) {
                            modifiedPath = editor.document.uri.fsPath;
                        }
                    }
                }

                if (originalPath && modifiedPath) {
                    console.log('Fallback method found paths:', { originalPath, modifiedPath });
                    return { originalPath, modifiedPath };
                }
            }
        }

        console.log('Not in a diff editor view.');
        return null; // Not in a file comparison view
    } catch (error) {
        console.error('Error in checkCompareFiles:', error);
        throw new Error(`Error checking compare files: ${error.message}`);
    }
}

socket.on('evaluate', async () => {
    const info = await checkCompareFiles();
    // vscode.window.showInformationMessage(message);
    socket.emit("send", {
        'event_type': "evaluate_on_completion",
        'message': "任务结束时检查任务是否完成",
        'info': info
    });
});

Evaluation handler:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from typing import Dict, Any, Optional, List

def message_handler(message: Dict[str, Any], logger, task_parameter: Dict[str, Any]) -> Optional[List[Dict[str, Any]]]:    
    event_type = message.get('event_type')
    logger.info(message)
    expected_file1 = task_parameter.get("file1", "/root/C-Plus-Plus/sorting/quick_sort.cpp")
    expected_file2 = task_parameter.get("file2", "/root/C-Plus-Plus/sorting/quick_sort_3.cpp")
    if event_type == "evaluate_on_completion":
        info = message.get('info', None)
        if not info:
            return [{"status": "error", "type": "evaluate_on_completion", "message": "任务没有完成"}]
        files = [info.get('originalPath', None), info.get('modifiedPath', None)]
        if expected_file1 in files and expected_file2 in files:
            return [
                {"status": "key_step", "index": 1},
                {"status": "success", "reason": f"任务成功完成"}
            ]
        else:
            return [{"status": "error", "type": "evaluate_on_completion", "message": "任务没有完成"}]
    return None