SAAgent/MCPWorld huggingface dataset:
Task configuration:
{"task_id": "02", "task_name": "\u6dfb\u52a0\u7b80\u5355\u724c\u7ec4", "description": "\u521b\u5efa\u4e00\u4e2a\u53eb\"hello\"\u7684\u724c\u7ec4", "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": {"deck_name": "ielts"}, "instruction_template": "\u521b\u5efa\u4e00\u4e2a\u53eb${deck_name}\u7684\u724c\u7ec4", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"deck_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"}, "correct_deck": {"description": "\u5361\u7247Deck\u6b63\u786e", "is_key_step": true, "key_step_index": 2, "key_step_name": "\u5361\u7247Deck\u6b63\u786e"}, "wrong_deck": {"description": "\u5361\u7247Deck\u4e0d\u6b63\u786e", "is_key_step": false}}, "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:
//! The script only tested in x86-64!
const TRACE_FUNCTION = [
    "storage_add_deck"
]
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_storage_add_deck(context: Context,message) -> Status:
    context.update_database()
    deck : Deck = sorted(AnkiObjMap().array_by_type("deck"),key=lambda x: x.mtime,reverse=True)[0]
    status = Status(status=StatusType.PROGRESS)
    if deck.name == tp.deck_name:
        status.emit(EventCorrectDeck())
        status.mark_success()
    else:
        status.emit(EventWrongDeck(deck.name, tp.deck_name))
    return status

TRACE_HANDLERS = {
    "storage_add_deck": handle_storage_add_deck,
}   
dependency_graph = {
    "deck_added" : [],
    "correct_deck" : ["deck_added"]
}
finished_list = [
    "correct_deck"
]
bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)
Task configuration:
{"task_id": "03", "task_name": "\u5220\u9664\u67d0\u4e2a\u724c\u7ec4", "description": "\u6dfb\u52a0\uff0c\u7136\u540e\u5220\u9664\"ielts\"\u7684\u724c\u7ec4", "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": {"deck_name": "ielts"}, "instruction_template": "\u521b\u5efa\u4e00\u4e2a\u53eb${deck_name}\u724c\u7ec4\uff0c\u7136\u540e\u5220\u9664", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"deck_added": {"description": "\u6570\u636e\u5e93\u4e2d\u6dfb\u52a0\u6210\u529f", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u6570\u636e\u5e93\u4e2d\u6dfb\u52a0\u6210\u529f"}, "deck_removed": {"description": "\u6570\u636e\u5e93\u4e2d\u5220\u9664\u6210\u529f", "is_key_step": true, "key_step_index": 2, "key_step_name": "\u6570\u636e\u5e93\u4e2d\u5220\u9664\u6210\u529f"}}, "success_conditions": ["deck_removed"], "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:
//! The script only tested in x86-64!
const TRACE_FUNCTION = [
    "storage_add_deck",
    "storage_remove_deck"
]
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_storage_add_deck(context: Context,message) -> Status:
    context.update_database()
    deck : Deck = sorted(AnkiObjMap().array_by_type("deck"),key=lambda x: x.mtime,reverse=True)
    status = Status()
    if deck[0].name == tp.deck_name:
        status.emit(EventDeckAdded())   
        context.is_deck_created = True
        status.mark_progress()
    return status

def handle_storage_remove_deck(context: Context,message) -> Status:
    context.update_database()
    status = Status()
    if all([deck.name != tp.deck_name for deck in AnkiObjMap().array_by_type("deck")]):
        if hasattr(context,"is_deck_created"):
            status.mark_success()
    return status

TRACE_HANDLERS = {
    "storage_remove_deck": handle_storage_remove_deck,
    "storage_add_deck": handle_storage_add_deck,
}   
dependency_graph = {
    "deck_added" : [],
    "deck_removed" : ["deck_added"]
}
finished_list = [
    "deck_removed"
]
bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)
Task configuration:
{"task_id": "08", "task_name": "\u6dfb\u52a0\u4e00\u4e2a\u6807\u7b7e\uff0c\u540d\u5b57\u4e3a\u8ba1\u7b97\u673a\u79d1\u5b66", "description": "\u521b\u5efa\u4e00\u5f20\u5361\u7247\uff0c\u6b63\u9762\u7684\u5185\u5bb9\u662f\"explain quick sort algorithm\",\u6807\u7b7e\u4e3acs", "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": "cs"}, "instruction_template": "\u521b\u5efa\u4e00\u5f20\u5361\u7247\uff0c\u6b63\u9762\u7684\u5185\u5bb9\u662f\"explain quick sort algorithm\",\u6807\u7b7e\u4e3a${tag_name}", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"card_added": {"description": "\u6dfb\u52a0\u4e86\u5361\u7247", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u6dfb\u52a0\u4e86\u5361\u7247"}, "tag_added": {"description": "\u6dfb\u52a0\u4e86\u6807\u7b7e", "is_key_step": true, "key_step_index": 2, "key_step_name": "\u6dfb\u52a0\u4e86\u6807\u7b7e"}}, "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 = [
    "storage_add_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_storage_add_card(context: Context,message) -> Status:
    context.update_database()
    latest_card : Card = sorted(AnkiObjMap().array_by_type("card"),key=lambda x: x.mod,reverse=True)[0]
    note = latest_card.get_note()
    status = Status()
    if len(note.fields) == 2:
        status.mark_progress()
        status.emit(EventCardAdded())
    
    if tp.tag_name in note.tags:
        status.emit(EventTagAdded())
        
    return status
TRACE_HANDLERS = {
    "storage_add_card": handle_storage_add_card,
}   
dependency_graph = {
    card_added_ : [],
    tag_added_ : [card_added_]
}
finished_list = [
   tag_added_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)
Task configuration:
{"task_id": "09", "task_name": "\u5220\u9664\u6240\u6709\u672a\u4f7f\u7528\u7684\u6807\u7b7e", "description": "\u5220\u9664\u6240\u6709\u672a\u4f7f\u7528\u7684\u6807\u7b7e", "application_info": {"name": "anki", "executable_path": "/home/agent/anki/out/pyenv/bin/python", "args": ["/home/agent/anki/tools/run.py"], "cwd": "/home/agent/anki"}, "instruction_template": "\u5220\u9664\u6240\u6709\u672a\u4f7f\u7528\u7684\u6807\u7b7e", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"clear_unused_tags": {"description": "\u5220\u9664\u6240\u6709\u672a\u4f7f\u7528\u7684\u6807\u7b7e", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u5220\u9664\u6240\u6709\u672a\u4f7f\u7528\u7684\u6807\u7b7e"}}, "sql_path": "/home/agent/.local/share/Anki2/sam/collection.anki2", "total_key_steps": 1, "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_clear_unused_tags",
]
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_clear_unused_tags(context: Context,message) -> Status:
    status = Status()
    status.emit(EventClearUnusedTags())
    return status

TRACE_HANDLERS = {
    "service_clear_unused_tags": handle_clear_unused_tags,
}   
dependency_graph = {
    clear_unused_tags_ : [],
}
finished_list = [
    clear_unused_tags_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)
Task configuration:
{"task_id": "10", "task_name": "\u6dfb\u52a0\u586b\u7a7a\u5361\u7247", "description": "\u6dfb\u52a0\u4e00\u4e2a\u586b\u7a7a\u9898\u5361\u7247\u5230\u7cfb\u7edf\u9ed8\u8ba4\uff0c\u5185\u5bb9\u4e3aThe capital of China is Beijing\uff0c\u5bf9Beijing\u8fdb\u884c\u6316\u7a7a", "application_info": {"name": "anki", "executable_path": "/home/agent/anki/out/pyenv/bin/python", "args": ["/home/agent/anki/tools/run.py"], "cwd": "/home/agent/anki"}, "instruction_template": "\u6dfb\u52a0\u4e00\u4e2a\u586b\u7a7a\u9898\u5361\u7247\u5230\u7cfb\u7edf\u9ed8\u8ba4\uff0c\u5185\u5bb9\u4e3aThe capital of China is Beijing\uff0c\u5bf9Beijing\u8fdb\u884c\u6316\u7a7a", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"card_added": {"description": "\u6dfb\u52a0\u4e86\u5361\u7247", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u6dfb\u52a0\u4e86\u5361\u7247"}, "card_format_correct": {"description": "\u5361\u7247\u683c\u5f0f\u5339\u914d", "is_key_step": true, "key_step_index": 2, "key_step_name": "\u5361\u7247\u683c\u5f0f\u5339\u914d"}, "card_format_wrong": {"description": "\u5361\u7247\u683c\u5f0f\u4e0d\u5339\u914d", "is_key_step": false}}, "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 = [
    "storage_add_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
sys.path.append(os.path.dirname(__file__))
from common import *
import re

def handle_storage_add_card(context: Context,message) -> Status:
    context.update_database()
    latest_card : Card = sorted(AnkiObjMap().array_by_type("card"),key=lambda x: x.mod,reverse=True)[0]
    note = latest_card.get_note()
    status = Status()
    status.emit(EventCardAdded())
    s = note.fields[0].replace("&nbsp"," ")
    if len(note.fields) == 2 and re.findall("The\s+capital\s+of\s+China\s+is\s+\{\{c1::Beijing\}\}",s):
        status.emit(EventCardFormatCorrect())
    else:
        status.emit(EventCardFormatWrong(note.fields[0],'The capital of China is&nbsp;{{c1::Beijing}}'))
    return status
TRACE_HANDLERS = {
    "storage_add_card": handle_storage_add_card,
}   
dependency_graph = {
    card_added_ : [],
    card_format_correct_ : [card_added_]
}
finished_list = [
    card_format_correct_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)
Task configuration:
{"task_id": "14", "task_name": "\u6401\u7f6e", "description": "\u8bbe\u7f6e\u6807\u7b7e\u4e3adelay\u7684\u5361\u7247\u4e3a\u6401\u7f6e", "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": "delay"}, "instruction_template": "\u8bbe\u7f6e\u6807\u7b7e\u4e3a${tag_name}\u7684\u5361\u7247\u4e3a\u6401\u7f6e", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"delay": {"description": "\u6401\u7f6e\u6210\u529f", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u6401\u7f6e\u6210\u529f"}}, "sql_path": "/home/agent/.local/share/Anki2/sam/collection.anki2", "total_key_steps": 1, "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_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
sys.path.append(os.path.dirname(__file__))
from common import *

def handle_storage_update_card(context: Context,message) -> Status:
    context.update_database()
    status = Status()
    cards : List[Card] = list(filter(lambda card: tp.tag_name in card.get_note().tags,AnkiObjMap().array_by_type("card")))
    if all([card.queue == -3 for card in cards]):
        status.emit(EventDelay())
    return status 

TRACE_HANDLERS = {
    "storage_update_card": handle_storage_update_card,
}   
dependency_graph = {
    delay_: [],
}
finished_list = [
    delay_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)
Task configuration:
{"task_id": "15", "task_name": "\u8bbe\u7f6e\u81ea\u52a8\u5907\u4efd\u65f6\u95f4", "description": "\u8bbe\u7f6e\u81ea\u52a8\u5907\u4efd\u65f6\u95f4\u4e3a15\u5206\u949f", "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": {"time": "15"}, "instruction_template": "\u8bbe\u7f6e\u81ea\u52a8\u5907\u4efd\u65f6\u95f4\u4e3a${time}\u5206\u949f", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"set_sucess": {"description": "\u8bbe\u7f6e\u6210\u529f", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u8bbe\u7f6e\u6210\u529f"}, "set_wrong": {"description": "\u8bbe\u7f6e\u9519\u8bef", "is_key_step": false}}, "sql_path": "/home/agent/.local/share/Anki2/sam/collection.anki2", "total_key_steps": 1, "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_set_config" 
]
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 json
sys.path.append(os.path.dirname(__file__))
from common import *

def handle_storage_set_config(context: Context,message) -> Status:
    context.update_database()
    status = Status()
    config = context.anki_config["backups"]
    if config["minimum_interval_mins"] == int(tp.time):
        status.emit(EventSetSucess())
    else:
        status.emit(EventSetWrong(str(config["minimum_interval_mins"]),tp.time))
    return status 

TRACE_HANDLERS = {
    "storage_set_config": handle_storage_set_config
}   
dependency_graph = {
    set_sucess_: [],
    set_wrong_ : []
}
finished_list = [
    set_sucess_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)
Task configuration:
{"task_id": "16", "task_name": "\u8bbe\u7f6e\u6b21\u65e5\u8d77\u70b9\uff08\u6bcf\u65e5\u8f6e\u6362\u5361\u7247\u7684\u65f6\u95f4\uff09\u4e3a1\u65f6", "description": "\u8bbe\u7f6e\u6b21\u65e5\u8d77\u70b9\uff08\u6bcf\u65e5\u8f6e\u6362\u5361\u7247\u7684\u65f6\u95f4\uff09\u4e3a1\u65f6", "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": {"time": "1"}, "instruction_template": "\u8bbe\u7f6e\u6b21\u65e5\u8d77\u70b9\uff08\u6bcf\u65e5\u8f6e\u6362\u5361\u7247\u7684\u65f6\u95f4\uff09\u4e3a${time}\u65f6", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"set_sucess": {"description": "\u8bbe\u7f6e\u6210\u529f", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u8bbe\u7f6e\u6210\u529f"}, "set_wrong": {"description": "\u8bbe\u7f6e\u9519\u8bef", "is_key_step": false}}, "sql_path": "/home/agent/.local/share/Anki2/sam/collection.anki2", "total_key_steps": 1, "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_set_config" 
]
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 json
sys.path.append(os.path.dirname(__file__))
from common import *

def handle_storage_set_config(context: Context,message) -> Status:
    context.update_database()
    status = Status()
    config = context.anki_config["rollover"]
    if config == int(tp.time):
        status.emit(EventSetSucess())
    else:
        status.emit(EventSetWrong(str(config),tp.time))
    return status 

TRACE_HANDLERS = {
    "storage_set_config": handle_storage_set_config
}   
dependency_graph = {
    set_sucess_: [],
    set_wrong_ : []
}
finished_list = [
    set_sucess_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)
Task configuration:
{"task_id": "17", "task_name": "\u8bbe\u7f6e\u63d0\u524d\u5b66\u4e60\u7684\u65f6\u95f4\u4e0a\u9650\u4e3a30\u5206\u949f", "description": "\u8bbe\u7f6e\u63d0\u524d\u5b66\u4e60\u7684\u65f6\u95f4\u4e0a\u9650\u4e3a30\u5206\u949f", "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": {"time": "30"}, "instruction_template": "\u5728\u8bbe\u7f6e\u91cc\u9762\uff0c\u8bbe\u7f6e\u63d0\u524d\u5b66\u4e60\u7684\u65f6\u95f4\u4e0a\u9650\u4e3a${time}\u5206\u949f", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"set_sucess": {"description": "\u8bbe\u7f6e\u6210\u529f", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u8bbe\u7f6e\u6210\u529f"}, "set_wrong": {"description": "\u8bbe\u7f6e\u9519\u8bef", "is_key_step": false}}, "sql_path": "/home/agent/.local/share/Anki2/sam/collection.anki2", "total_key_steps": 1, "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_set_config" 
]
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_storage_set_config(context: Context,message) -> Status:
    context.update_database()
    status = Status()
    config = context.anki_config["collapseTime"]
    if config == int(tp.time) * 60:
        status.emit(EventSetSucess())
    else:
        status.emit(EventSetWrong(str(config),tp.time*60))
    return status 

TRACE_HANDLERS = {
    "storage_set_config": handle_storage_set_config
}   
dependency_graph = {
    set_sucess_: [],
    set_wrong_ : []
}
finished_list = [
    set_sucess_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)
Task configuration:
{"task_id": "18", "task_name": "\u8bbe\u7f6e\u641c\u7d22\u6846\u9ed8\u8ba4\u641c\u7d22\u5185\u5bb9\u4e3a\"cs\"", "description": "\u8bbe\u7f6e\u641c\u7d22\u6846\u9ed8\u8ba4\u641c\u7d22\u5185\u5bb9\u4e3a\"cs\"", "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": {"key_word": "cs"}, "instruction_template": "\u8bbe\u7f6e\u641c\u7d22\u6846\u9ed8\u8ba4\u641c\u7d22\u5185\u5bb9\u4e3a\"cs\"", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60}, "events": {"set_sucess": {"description": "\u8bbe\u7f6e\u6210\u529f", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u8bbe\u7f6e\u6210\u529f"}, "set_wrong": {"description": "\u8bbe\u7f6e\u9519\u8bef", "is_key_step": false}}, "sql_path": "/home/agent/.local/share/Anki2/sam/collection.anki2", "total_key_steps": 1, "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_set_config" 
]
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_storage_set_config(context: Context,message) -> Status:
    context.update_database()
    status = Status()
    config = context.anki_config["defaultSearchText"]
    if config == tp.key_word:
        status.emit(EventSetSucess())
    else:
        status.emit(EventSetWrong(str(config),tp.time*60))
    return status 

TRACE_HANDLERS = {
    "storage_set_config": handle_storage_set_config
}   
dependency_graph = {
    set_sucess_: [],
    set_wrong_ : []
}
finished_list = [
    set_sucess_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list)