Task configuration:
{"task_id": "24", "task_name": "change_to_camelCase", "description": "\u5728vscode\u4e2d\u6253\u5f00\u6587\u4ef6, \u5e76\u4e14\u5c06\u6587\u4ef6\u4e2d\u7684\u6240\u6709\u53d8\u91cf\u3001\u51fd\u6570\u7684\u547d\u540d\u65b9\u6cd5\u4ece\u4e0b\u5212\u7ebf\u547d\u540d\u6cd5\u66f4\u6539\u4e3a\u5927\u9a7c\u5cf0\u547d\u540d\u6cd5", "application_info": {"name": "vscode", "executable_path": "/usr/share/code/code", "args": ["--no-sandbox", "--user-data-dir=/root/vscode_user_data_dir/"]}, "task_parameters": {"filename": "change_name.cpp", "expected_file_content": "#include<iostream>#include<vector>voidInsertionSort(std::vector<int>&Array){intArraySize=Array.size();for(intI=1;I<ArraySize;I++){intKey=Array[I];intJ=I-1;while(J>=0&&Array[J]>Key){Array[J+1]=Array[J];J--;}Array[J+1]=Key;}}intmain(){std::vector<int>InputArray={64,34,25,12,22,11,90};InsertionSort(InputArray);for(intNum:InputArray){std::cout<<Num<<\"\";}std::cout<<std::endl;return0;}", "expected_file_path": "/root/C-Plus-Plus/agent_test/change_name.cpp"}, "instruction_template": "\u5728vscode\u4e2d\u6253\u5f00\u5f53\u524d\u5de5\u4f5c\u533a\u4e2d\u540d\u4e3a ${filename} \u7684\u6587\u4ef6, \u5c06\u6587\u4ef6\u4e2d\u6240\u6709\u7684\u53d8\u91cf\u540d(\u5305\u62eci\u3001j\u3001k\u7b49)\u3001\u51fd\u6570\u540d\u90fd\u4fee\u6539\u4e3a\u4f7f\u7528\u5927\u9a7c\u5cf0\u547d\u540d\u6cd5\u547d\u540d", "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:
/**
 * 检查当前打开的文件是否含有错误提示，并返回文件名和文件内容（包括未保存的修改）
 * @returns {Promise<{hasErrors: boolean, fileName: string | null, content: string | null}>} 返回对象包含错误状态、文件名和文件内容
 */
async function hasFileErrors() {
    // 获取当前活动编辑器
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
        vscode.window.showInformationMessage('No active editor found.');
        return { hasErrors: false, fileName: null, content: null };
    }

    // 获取当前文件的 URI、文件名和内容
    const fileUri = editor.document.uri;
    const fileName = editor.document.fileName;
    const content = editor.document.getText(); // 获取当前文档内容，包括未保存的修改

    // 获取文件的诊断信息
    const diagnostics = vscode.languages.getDiagnostics(fileUri);

    // 检查是否有错误
    const hasErrors = diagnostics.some(diagnostic => 
        diagnostic.severity === vscode.DiagnosticSeverity.Error
    );

    return { hasErrors, fileName, content };
}

socket.on('evaluate', async () => {
    const hasErrors = await hasFileErrors();
    // vscode.window.showInformationMessage(message);
    socket.emit("send", {
        'event_type': "evaluate_on_completion",
        'message': "任务结束时检查打开的文件是否含有报错",
        'hasErrors': hasErrors
    });
});

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')
    info = message.get('hasErrors', {})
    fileName = info.get('fileName', None)
    hasErrors = info.get('hasErrors', None)
    content = info.get('content', None)
    expected_file_content = task_parameter.get("expected_file_content", "#include<iostream>#include<vector>voidInsertionSort(std::vector<int>&Array){intArraySize=Array.size();for(intI=1;I<ArraySize;I++){intKey=Array[I];intJ=I-1;while(J>=0&&Array[J]>Key){Array[J+1]=Array[J];J--;}Array[J+1]=Key;}}intmain(){std::vector<int>InputArray={64,34,25,12,22,11,90};InsertionSort(InputArray);for(intNum:InputArray){std::cout<<Num<<\"\";}std::cout<<std::endl;return0;}")
    expected_file_path = task_parameter.get("expected_file_path", "/root/C-Plus-Plus/agent_test/change_name.cpp")
    logger.info(message.get('message'))
    if event_type == 'evaluate_on_completion' and fileName == expected_file_path and hasErrors == False:
        if ''.join(content.split()) == expected_file_content:
            return [
                {"status": "key_step", "index": 1},
                {"status": "success", "reason": f"任务成功完成"}
            ]
        else:
            return [{"status": "error", "type": "evaluate_on_completion", "message": "任务没有完成"}]
    return None