Task configuration:
{"task_id": "07", "task_name": "\u521b\u5efa\u4e00\u5f20\u5361\u7247\uff0c\u6b63\u9762\u7684\u5185\u5bb9\u662f\"What is a computer\",\u67e5\u627e\u6240\u6709\u5e26\u6709Computer\u7684\u5361\u7247\uff0c\u8bbe\u7f6e\u8fd9\u4e9b\u5361\u7247\u5230\u671f\u65e5\u4e3a4\u5929", "description": "\u521b\u5efa\u4e00\u5f20\u5361\u7247\uff0c\u6b63\u9762\u7684\u5185\u5bb9\u662f\"What is a computer\",\u67e5\u627e\u6240\u6709\u5e26\u6709Computer\u7684\u5361\u7247\uff0c\u8bbe\u7f6e\u8fd9\u4e9b\u5361\u7247\u5230\u671f\u65e5\u4e3a4\u5929", "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": {"search_keyword": "computer", "due_days": "4"}, "instruction_template": "\u521b\u5efa\u4e00\u5f20\u5361\u7247\uff0c\u6b63\u9762\u7684\u5185\u5bb9\u662f\"What is a ${search_keyword}\",\u67e5\u627e\u6240\u6709\u5e26\u6709${search_keyword}\u7684\u5361\u7247\uff0c\u8bbe\u7f6e\u8fd9\u4e9b\u5361\u7247\u5230\u671f\u65e5\u4e3a${due_days}\u5929", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"card_added": {"description": "\u6570\u636e\u5e93\u4e2d\u51fa\u73b0\u5361\u7247", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u6570\u636e\u5e93\u4e2d\u51fa\u73b0\u5361\u7247"}, "search_card_called": {"description": "\u8c03\u7528\u4e86\u67e5\u627e\u51fd\u6570", "is_key_step": true, "key_step_index": 2, "key_step_name": "\u8c03\u7528\u4e86\u67e5\u627e\u51fd\u6570"}, "update_card_expiration_date": {"description": "\u66f4\u65b0\u4e86\u5361\u7247\u8fc7\u671f\u65e5\u671f", "is_key_step": true, "key_step_index": 3, "key_step_name": "\u66f4\u65b0\u4e86\u5361\u7247\u8fc7\u671f\u65e5\u671f"}}, "sql_path": "/home/agent/.local/share/Anki2/sam/collection.anki2", "total_key_steps": 3, "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 = [
    "storage_add_card",
    "service_serach_cards",
    "storage_update_card",
]
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
import datetime
sys.path.append(os.path.dirname(__file__))
from common import *

def handle_service_search_cards(context: Context,message) -> Status:
    status = Status()
    status.emit(EventSearchCardCalled())
    return status

def handle_storage_update_card(context: Context,message) -> Status:    
    if not context.should_event_trigger(EventUpdateCardExpirationDate()):
        return None
    context.update_database()
    status = Status()
    cards : List[Card] = list(filter(lambda x: any([tp.search_keyword in field for field in x.get_note().fields]),AnkiObjMap().array_by_type("card")))
    due_days = ((datetime.datetime.now() + datetime.timedelta(days=int(tp.due_days))-context.col.crt)).days
    if all([card.type == CardType.REVIEW and card.due == due_days for card in cards]):
        status.emit(EventUpdateCardExpirationDate())
    return status

def handle_storage_add_card(context: Context,message) -> Status:
    context.update_database()
    latest : Card = sorted(AnkiObjMap().array_by_type("card"),key=lambda x: x.mod,reverse=True)[0]
    note = latest.get_note()
    status = Status(status=StatusType.PROGRESS)
    if len(note.fields) == 2 and tp.search_keyword in note.fields[0]  or tp.search_keyword in  note.fields[1]:
        status.emit(EventCardAdded())

    return status
TRACE_HANDLERS = {
    "storage_add_card": handle_storage_add_card,
    "service_serach_cards" : handle_service_search_cards,
    "storage_update_card" : handle_storage_update_card,
}   
dependency_graph = {
    card_added_ : [],
    search_card_called_ : [card_added_],
    update_card_expiration_date_ : [search_card_called_]
}
finished_list = [
    update_card_expiration_date_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)