Study Session Tracker

L3
ModelContextProtocolNotionComputer Science Student Dashboard

Create a new study-session entry in the Habit tracker section with four unchecked to-do items.

Created by Zijian Wu
2025-07-27
Content OrganizationVisual FormattingStatus Tracking

Model Ranking

Click on the dots to view the trajectory of each task run
Model
Run Results
Pass@4
Pass^4
Avg Time
Avg Turns
Input Tokens
Output Tokens
Total Tokens
Claude
claude-opus-4-1
0
/1
--
275.6s
16.0
330,908
3,221
334,129
Claude
claude-sonnet-4
0
/4
134.2s
14.5
320,890
3,127
324,017
Claude
claude-sonnet-4-high
0
/4
79.2s
11.0
182,631
2,357
184,988
Claude
claude-sonnet-4-low
0
/4
98.5s
13.3
246,169
2,664
248,833
DeepSeek
deepseek-chat
0
/4
115.9s
11.0
142,734
994
143,728
Gemini
gemini-2-5-flash
0
/4
54.5s
3.8
64,144
4,936
69,080
Gemini
gemini-2-5-pro
0
/4
102.7s
5.3
59,078
5,704
64,782
Z.ai
glm-4-5
0
/4
119.8s
10.8
159,751
3,179
162,930
OpenAI
gpt-4-1
0
/4
33.8s
8.3
75,138
640
75,778
OpenAI
gpt-4-1-mini
0
/4
28.8s
8.0
66,289
553
66,842
OpenAI
gpt-4-1-nano
0
/4
22.9s
8.3
35,734
517
36,251
OpenAI
gpt-5-high
0
/4
332.8s
7.0
74,774
13,823
88,597
OpenAI
gpt-5-low
0
/4
221.5s
6.8
81,413
9,910
91,322
OpenAI
gpt-5-medium
0
/4
212.5s
7.0
71,860
8,683
80,544
OpenAI
gpt-5-mini-high
0
/4
149.4s
12.5
180,640
11,794
192,434
OpenAI
gpt-5-mini-low
0
/4
31.9s
6.3
88,807
1,560
90,367
OpenAI
gpt-5-mini-medium
0
/4
79.3s
11.3
126,066
5,514
131,580
OpenAI
gpt-5-nano-high
0
/4
397.1s
15.0
268,899
87,078
355,978
OpenAI
gpt-5-nano-low
0
/4
32.0s
3.0
13,408
4,959
18,367
OpenAI
gpt-5-nano-medium
0
/4
127.3s
7.8
59,173
25,576
84,748
OpenAI
gpt-oss-120b
0
/4
17.5s
3.8
23,295
918
24,213
Grok
grok-4
0
/4
738.4s
14.0
263,669
10,484
274,153
Grok
grok-code-fast-1
0
/4
271.5s
22.0
508,662
8,440
522,212
MoonshotAI
kimi-k2-0711
0
/4
163.0s
18.0
363,345
2,088
365,433
MoonshotAI
kimi-k2-0905
0
/4
334.7s
32.8
733,043
3,562
736,605
OpenAI
o3
0
/4
55.2s
9.3
78,283
2,588
80,871
OpenAI
o4-mini
0
/4
134.7s
10.0
90,710
12,011
102,721
Qwen
qwen-3-coder-plus
0
/4
28.5s
7.8
97,122
753
97,875
Qwen
qwen-3-max
0
/4
123.2s
31.0
859,388
2,007
861,395

Task State

Notion Workspace
This task is executed based on this Notion workspace
This workspace is cloned from notion official template marketplace.View Original Template

Instruction

Your goal is to create a new study-session entry in the Computer Science Student Dashboard page.

  1. Locate the ☑️ Habit tracker section of the page.
  2. Insert a new date section immediately after the existing 2022-09-02 to-do items but before the divider block that follows them. Make sure the new date has proper formatting with a date mention and bold styling like the existing dates, and all to-do items should be unchecked initially. The new section should be inserted right after the 2022-09-02 to-do items but before the divider.
  3. Directly beneath this new date mention, add exactly four unchecked to-do blocks with the following plain text (including the leading emoji on each line): • 🧠 Review algorithms for technical interview • 📚 Study database systems chapter 7 • ⚡ Practice system design problems • 🎯 Complete data structures assignment


Verify

*.py
Python
import sys
from notion_client import Client
from tasks.utils import notion_utils
from typing import Dict


def _normalize_string(s: str) -> str:
    """Replace non-breaking space with regular space for safe comparison."""
    return s.replace("\xa0", " ")


def verify(notion: Client, main_id: str | None = None) -> bool:
    """Verify that the new study-session entry for 2025-01-29 was added correctly.

    The script checks that:
    1. A bold date-mention with start=2025-01-29 exists.
    2. The mention sits after the 2022-09-02 section but before the divider that originally
       followed that section.
    3. Exactly four specified to-do items follow the new date mention and they are all unchecked.
    """

    # ---------------------------------------------------------------------
    # Locate the main page -------------------------------------------------
    # ---------------------------------------------------------------------
    page_id: str | None = None

    if main_id:
        found_id, object_type = notion_utils.find_page_or_database_by_id(
            notion, main_id
        )
        if found_id and object_type == "page":
            page_id = found_id

    if not page_id:
        page_id = notion_utils.find_page(notion, "Computer Science Student Dashboard")

    if not page_id:
        print(
            "Error: Page 'Computer Science Student Dashboard' not found.",
            file=sys.stderr,
        )
        return False

    # ---------------------------------------------------------------------
    # Fetch all blocks under the page (flattened order) --------------------
    # ---------------------------------------------------------------------
    all_blocks = notion_utils.get_all_blocks_recursively(notion, page_id)

    # ---------------------------------------------------------------------
    # Locate reference blocks ---------------------------------------------
    # ---------------------------------------------------------------------
    TARGET_DATE = "2025-01-29"
    PREVIOUS_DATE = "2022-09-02"

    index_previous_date: int | None = None
    index_new_date: int | None = None
    index_divider_after_previous: int | None = None

    for idx, block in enumerate(all_blocks):
        # Divider detection (we care only about the first divider that appears after
        # the 2022-09-02 block)
        if block.get("type") == "divider":
            if index_previous_date is not None and index_divider_after_previous is None:
                index_divider_after_previous = idx

        # We only need to inspect paragraph blocks that contain a date mention
        if block.get("type") != "paragraph":
            continue

        rich_text_list = block["paragraph"].get("rich_text", [])
        for rt in rich_text_list:
            if (
                rt.get("type") != "mention"
                or rt.get("mention", {}).get("type") != "date"
            ):
                continue

            date_start = rt["mention"]["date"].get("start")

            if date_start == PREVIOUS_DATE and index_previous_date is None:
                index_previous_date = idx

            if date_start == TARGET_DATE and index_new_date is None:
                index_new_date = idx
                # (1) Verify bold annotation
                if not rt.get("annotations", {}).get("bold", False):
                    print(
                        "Error: The 2025-01-29 date mention is not bold.",
                        file=sys.stderr,
                    )
                    return False

    # Ensure all reference indices were found
    if index_previous_date is None:
        print("Error: Could not locate the 2022-09-02 date section.", file=sys.stderr)
        return False
    if index_divider_after_previous is None:
        print(
            "Error: Could not locate the divider that follows the 2022-09-02 section.",
            file=sys.stderr,
        )
        return False
    if index_new_date is None:
        print(
            "Error: Could not locate the new 2025-01-29 date mention.", file=sys.stderr
        )
        return False

    # (2) Verify ordering
    if not (index_previous_date < index_new_date < index_divider_after_previous):
        print(
            "Error: The 2025-01-29 section is positioned incorrectly.", file=sys.stderr
        )
        return False

    # ---------------------------------------------------------------------
    # Verify to-do items under the new date section ------------------------
    # ---------------------------------------------------------------------
    expected_texts = [
        "🧠 Review algorithms for technical interview",
        "📚 Study database systems chapter 7",
        "⚡ Practice system design problems",
        "🎯 Complete data structures assignment",
    ]
    expected_todos: Dict[str, bool] = {
        _normalize_string(t): False for t in expected_texts
    }

    # Look through the blocks that lie between the new date mention and the divider
    for block in all_blocks[index_new_date + 1 : index_divider_after_previous]:
        if block.get("type") != "to_do":
            # Any non to-do block inside this range indicates mis-placement.
            # We simply ignore it – correctness is determined by presence of required to-dos.
            continue

        plain_text = notion_utils.get_block_plain_text(block).strip()
        plain_text_norm = _normalize_string(plain_text)
        if plain_text_norm in expected_todos:
            # (3a) Verify the to-do is unchecked
            if block["to_do"].get("checked", False):
                print(f"Error: To-do '{plain_text}' is checked.", file=sys.stderr)
                return False
            expected_todos[plain_text_norm] = True

    missing_items = [text for text, found in expected_todos.items() if not found]
    if missing_items:
        print(f"Error: Missing to-do items: {missing_items}", file=sys.stderr)
        return False

    # ---------------------------------------------------------------------
    # Success --------------------------------------------------------------
    # ---------------------------------------------------------------------
    print("Success: Study session for 2025-01-29 added correctly.")
    return True


# -------------------------------------------------------------------------
# Command-line entry-point -------------------------------------------------
# -------------------------------------------------------------------------


def main() -> None:
    notion = notion_utils.get_notion_client()
    main_id = sys.argv[1] if len(sys.argv) > 1 else None

    if verify(notion, main_id):
        sys.exit(0)
    else:
        sys.exit(1)


if __name__ == "__main__":
    main()