Task configuration:
{"task_id": "18", "task_name": "configure_transition", "description": "configure transition animation to Fade and change scene", "application_info": {"name": "obs-studio", "executable_path": "apps/obs-studio/bin/64bit/obs64", "args": []}, "task_parameters": {"transition_name": "Fade", "duration_ms": 1000, "dest_scene": "test_scene"}, "instruction_template": "Set OBS transition animation to ${transition_name}, set duration to ${duration_ms} milliseconds, and switch scene to ${dest_scene}", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js"}, {"role": "handler", "path": "handler.py"}], "timeout": 120}, "total_key_steps": 2, "events": {"name_matches": {"description": "name matches", "is_key_step": true, "key_step_index": 1, "key_step_name": "name matches"}, "duration_matches": {"description": "duration matches", "is_key_step": true, "key_step_index": 2, "key_step_name": "duration matches"}, "dest_scene_matches": {"description": "scene matches", "is_key_step": true, "key_step_index": 3, "key_step_name": "scene matches"}}, "mcp_servers": [{"command": "node", "args": ["/home/agent/obs-mcp/build/index.js"]}]}

Hook script:
(function () {
    // Script settings
    const MESSAGE_script_initialized = "Monitoring script has started";
    const MESSAGE_hook_installed = "Monitoring hook installed, waiting for operation...";

    // Send events to the evaluation system
    function sendEvent(eventType, data = {}) {
        console.log("[Event]", eventType, JSON.stringify(data, null, 2));
        const payload = {
            event: eventType,
            ...data,
            timestamp: new Date().getTime()
        };
        send(payload);
    }

    // Get function address
    function getFunctionAddress(functionName, symbolName) {
        console.log(`[Debug] Attempting to get address of function ${functionName} (symbol: ${symbolName})`);

        const funcAddr = DebugSymbol.getFunctionByName(symbolName);
        if (!funcAddr) {
            console.log(`[Error] Unable to find function ${functionName} (symbol: ${symbolName})`);
            return null;
        }

        console.log(`[Debug] Found actual address of function ${functionName} (symbol: ${symbolName}): ${funcAddr.toString()}`);
        return funcAddr;
    }

    // Initialize transition configuration hook
    function hookTransitionConfig() {
        // Monitor transition start function
        let startFunc = "obs_transition_start";
        let startSymbol = "obs_transition_start";

        const startAddr = getFunctionAddress(startFunc, startSymbol);
        if (startAddr) {
            Interceptor.attach(startAddr, {
                onEnter(args) {
                    this.transition = args[0];
                    this.duration = args[2].toInt32();
                    this.dest = args[3];
                    console.log(`[Debug] Transition start function called, duration: ${this.duration}ms`);
                },
                
                onLeave(retval) {
                    // Get transition name
                    const getSourceName = new NativeFunction(
                        DebugSymbol.getFunctionByName("obs_source_get_name"),
                        'pointer',
                        ['pointer']
                    );
                    const namePtr = getSourceName(this.transition);
                    const transitionName = namePtr.readCString();
                    const destName = getSourceName(this.dest).readCString();

                    console.log(`[Debug] Transition started: type=${transitionName}, duration=${this.duration}ms`);
                    
                    // Send transition configuration information
                    sendEvent("transition_executed", {
                        transition_name: transitionName,
                        duration_ms: this.duration,
                        success: retval.toInt32() !== 0,
                        dest: destName
                    });
                }
            });
        }
    }

    // Initialize hooks
    function initHook() {
        console.log("[Init] Starting hook initialization");
        sendEvent("script_initialized", {
            message: MESSAGE_script_initialized
        });

        // Initialize transition configuration hook
        hookTransitionConfig();
        
        console.log("[Init] Hook initialization completed");
        sendEvent("hook_installed", {
            message: MESSAGE_hook_installed
        });
    }

    // Start script
    console.log("[Start] Script execution started");
    initHook();
    console.log("[Start] Script execution completed, waiting for events...");
})();

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

from typing import Dict, Any, Optional, List

step = 0


def check_transition(
    transition_name: str, duration_ms: int, dest: str, logger, task_parameter
) -> Optional[List[Dict[str, Any]]]:
    """Check if the transition configuration meets the requirements"""
    global step
    expected_name = task_parameter["transition_name"]
    expected_duration = task_parameter["duration_ms"]
    expected_dest = task_parameter["dest_scene"]

    name_match = transition_name == expected_name
    duration_match = duration_ms == expected_duration
    dest_match = dest == expected_dest

    key_step = []
    if name_match and step == 0:
        step = 1
        key_step.append({"status": "key_step", "index": 1})

    if duration_match and step == 1:
        step = 2
        key_step.append({"status": "key_step", "index": 2})

    if dest_match and step == 2:
        key_step.append({"status": "key_step", "index": 3})
        key_step.append({"status": "success", "reason": "Name and duration matched"})

    return None if len(key_step) == 0 else key_step


def message_handler(
    message: Dict[str, Any], logger, task_parameter: Dict[str, Any]
) -> Optional[List[Dict[str, Any]]]:
    print(message)
    payload = message["payload"]
    print(payload)
    event_type = payload["event"]
    logger.debug(f"Received event: {event_type}")

    # Handle transition execution event
    if event_type == "transition_executed":
        transition_name = payload.get("transition_name")
        duration_ms = payload.get("duration_ms")
        dest = payload.get("dest")

        return check_transition(
            transition_name, duration_ms, dest, logger, task_parameter
        )

    return None