Task configuration:
{"task_id": "19", "task_name": "\u5c06\u6240\u6709\u6807\u7b7e\u4e3asuspend\u7684\u5361\u7247\u5220\u9664", "description": "\u5c06\u6240\u6709\u6807\u7b7e\u4e3asuspend\u7684\u5361\u7247\u5220\u9664", "application_info": {"name": "anki", "executable_path": "/home/agent/anki/out/pyenv/bin/python", "args": ["/home/agent/anki/tools/run.py"], "cwd": "/home/agent/anki"}, "task_parameters": {"tag_name": "suspend"}, "instruction_template": "\u5c06\u6240\u6709\u6807\u7b7e\u4e3a${tag_name}\u7684\u5361\u7247\u5220\u9664", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60, "evaluate_on_completion": true}, "events": {"remove_note": {"description": "\u5220\u9664\u4e00\u4e2a\u5361\u7247", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u5220\u9664\u4e00\u4e2a\u5361\u7247"}, "remove_all_notes": {"description": "\u5220\u9664\u4e86\u6240\u6709\u5361\u7247", "is_key_step": true, "key_step_index": 2, "key_step_name": "\u5220\u9664\u4e86\u6240\u6709\u5361\u7247"}}, "sql_path": "/home/agent/.local/share/Anki2/sam/collection.anki2", "total_key_steps": 2, "mcp_servers": [{"command": "/home/agent/anki-mcp-server/.venv/bin/python", "args": ["/home/agent/anki-mcp-server/run_server.py"]}]}

Hook script:
const TRACE_FUNCTION = [
   "service_remove_notes" 
]
function initHooks() {
    // iterate function name and addr, init it.
    for (const function_name of TRACE_FUNCTION){
        initHook(function_name, TRACE_MAPS[function_name]);
    }
}
initHooks();
sendLog("info", "add hooks done");

Evaluation handler:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import os
sys.path.append(os.path.dirname(__file__))
from common import *

def handle_service_remove_notes(context: Context,message) -> Status:
    context.update_database()
    status = Status()
    notes : set[int] = set(map(lambda note:note.nid,AnkiObjMap().array_by_type("note")))
    to_remove = []
    for nid in context._cards_to_remove:
        if nid not in notes:
            to_remove.append(nid)
            status.emit(EventRemoveNote(nid))
        else:
            print(f"nid {nid}")
    for nid in to_remove:
        context._cards_to_remove.remove(nid)
    if not context._cards_to_remove:
        status.emit(EventRemoveAllNotes())
        
    return status

def scan_remove_items(context: Context):
    context.update_database()
    cards : List[Card] = list(map(lambda c:c.nid,filter(lambda c: tp.tag_name in c.get_note().tags, AnkiObjMap().array_by_type("card"))))
    context._cards_to_remove = cards
    assert len(cards) > 0, "No cards found with the tag"
    

def handle_done(context: Context,message): 
    if not context.monitor.is_event_triggered(EventRemoveNote()) or not context.monitor.is_event_triggered(EventRemoveAllNotes()):
        return handle_service_remove_notes(context,None)

TRACE_HANDLERS = {
    "service_remove_notes": handle_service_remove_notes,
}   

dependency_graph = {
   remove_note_ : [],
    remove_all_notes_ : [remove_note_]    
}
finished_list = [
    remove_all_notes_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list,init=scan_remove_items,done=handle_done)