Weekend Adventure Planner
L3
NotionToronto Guide
Create a comprehensive weekend adventure planner that analyzes Toronto Guide databases and generates a structured itinerary page.
Created by Xiangyan Liu
2025-08-14
Conditional FilteringData AggregationReport GenerationVisual 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 |
---|---|---|---|---|---|---|---|---|
gpt-5 | 3 /4 | 245.8s | 5.3 | 128,525 | 12,695 | 141,220 | ||
claude-4-sonnet | 2 /4 | 143.0s | 13.5 | 244,474 | 3,690 | 248,164 | ||
qwen-3-coder | 2 /4 | 165.3s | 25.8 | 700,467 | 3,089 | 703,556 | ||
claude-4-1-opus | 1 /1 | - | - | 208.8s | 10.0 | 151,321 | 3,160 | 154,481 |
k2 | 1 /4 | 76.3s | 8.0 | 89,325 | 1,788 | 91,113 | ||
o3 | 1 /4 | 86.1s | 11.5 | 105,766 | 4,796 | 110,561 | ||
deepseek-chat | 0 /4 | 162.4s | 10.0 | 156,851 | 2,038 | 158,889 | ||
gemini-2-5-pro | 0 /4 | 19.8s | 1.0 | 3,393 | 448 | 3,841 | ||
grok-4 | 0 /4 | - | - | - | - | - |
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
Verify
Python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from notion_client import Client
from tasks.utils import notion_utils
def verify(notion: Client, main_id: str = None) -> bool:
"""
Verifies that the Perfect Weekend Adventure page has been created correctly.
"""
# Find the main Toronto Guide page
page_id = 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, "Toronto Guide")
if not page_id:
print("Error: Main 'Toronto Guide' page not found.", file=sys.stderr)
return False
# Find the Perfect Weekend Adventure child page
adventure_page_id = None
try:
response = notion.search(
query="Perfect Weekend Adventure",
filter={"property": "object", "value": "page"}
)
for result in response.get("results", []):
parent = result.get("parent", {})
if parent.get("type") == "page_id" and parent.get("page_id") == page_id:
adventure_page_id = result["id"]
break
if not adventure_page_id:
for result in response.get("results", []):
title_list = result.get("properties", {}).get("title", {}).get("title", [])
for title_obj in title_list:
if "Perfect Weekend Adventure" in title_obj.get("plain_text", ""):
adventure_page_id = result["id"]
break
if adventure_page_id:
break
except Exception as e:
print(f"Error searching for Perfect Weekend Adventure page: {e}", file=sys.stderr)
return False
if not adventure_page_id:
print("Error: 'Perfect Weekend Adventure' page not found as child of main page.", file=sys.stderr)
return False
# Get all blocks from the adventure page
all_blocks = notion_utils.get_all_blocks_recursively(notion, adventure_page_id)
# Get databases from the main Toronto Guide page
activities_db_id = None
food_db_id = None
cafes_db_id = None
main_blocks = notion_utils.get_all_blocks_recursively(notion, page_id)
for block in main_blocks:
if block.get("type") == "child_database":
title = block.get("child_database", {}).get("title", "")
if "Activities" in title:
activities_db_id = block.get("id")
elif "Food" in title:
food_db_id = block.get("id")
elif "Cafes" in title or "Caf�" in title:
cafes_db_id = block.get("id")
# Query databases to get expected data
beach_activities = []
cultural_restaurants = []
cafes_list = []
if activities_db_id:
try:
db_response = notion.databases.query(database_id=activities_db_id)
for page in db_response.get("results", []):
properties = page.get("properties", {})
tags_prop = properties.get("Tags", {})
if tags_prop.get("type") == "multi_select":
tags = [tag.get("name") for tag in tags_prop.get("multi_select", [])]
if "Beaches" in tags:
name_prop = properties.get("Name", {})
if name_prop.get("type") == "title" and name_prop.get("title"):
name = name_prop["title"][0]["plain_text"]
url_prop = properties.get("Google Maps Link", {})
url = url_prop.get("url", "") if url_prop.get("type") == "url" else ""
beach_activities.append({"name": name, "url": url})
except Exception as e:
print(f"Error querying Activities database: {e}", file=sys.stderr)
return False
if food_db_id:
try:
db_response = notion.databases.query(database_id=food_db_id)
for page in db_response.get("results", []):
properties = page.get("properties", {})
tags_prop = properties.get("Tags", {})
if tags_prop.get("type") == "multi_select":
tags = [tag.get("name") for tag in tags_prop.get("multi_select", [])]
for tag in tags:
if tag in ["Turkish", "Hakka"]:
name_prop = properties.get("Name", {})
if name_prop.get("type") == "title" and name_prop.get("title"):
name = name_prop["title"][0]["plain_text"]
cultural_restaurants.append({"name": name, "tag": tag})
break
except Exception as e:
print(f"Error querying Food database: {e}", file=sys.stderr)
return False
if cafes_db_id:
try:
db_response = notion.databases.query(database_id=cafes_db_id)
for page in db_response.get("results", []):
properties = page.get("properties", {})
name_prop = properties.get("Name", {})
if name_prop.get("type") == "title" and name_prop.get("title"):
name = name_prop["title"][0]["plain_text"]
cafes_list.append(name)
except Exception as e:
print(f"Error querying Cafes database: {e}", file=sys.stderr)
return False
# Required headings and their types
required_headings = [
("🎒 Perfect Weekend Adventure", "heading_1"),
("🏖️ Beach Activities", "heading_2"),
("🍽️ Cultural Dining Experience", "heading_2"),
("☕ Coffee Break Spots", "heading_2"),
("📊 Weekend Summary", "heading_2")
]
# Track verification results
found_headings = set()
found_beach_list = False
found_restaurant_list = False
found_toggle_with_cafes = False
found_summary = False
found_divider = False
found_callout = False
# Variables to track counts
beach_count = 0
restaurant_count = 0
cafe_count = 0
current_section = None
is_in_toggle = False
for block in all_blocks:
block_type = block.get("type")
block_text = notion_utils.get_block_plain_text(block)
# Check headings
for heading_text, expected_type in required_headings:
if heading_text in block_text and block_type == expected_type:
found_headings.add(heading_text)
current_section = heading_text
# Check Beach Activities section
if current_section == "🏖️ Beach Activities" and block_type == "bulleted_list_item":
found_beach_list = True
beach_count += 1
# Verify format includes name and potentially URL
for activity in beach_activities:
if activity["name"] in block_text:
if activity["url"] and activity["url"] not in block_text:
print(f"Warning: Beach activity '{activity['name']}' missing URL", file=sys.stderr)
# Check Cultural Dining section
elif current_section == "🍽️ Cultural Dining Experience" and block_type == "numbered_list_item":
found_restaurant_list = True
restaurant_count += 1
# Check format: Restaurant Name (Tag: [tag])
for restaurant in cultural_restaurants:
if restaurant["name"] in block_text and f"Tag: {restaurant['tag']}" in block_text:
pass # Format is correct
# Check Coffee Break Spots section
elif current_section == "☕ Coffee Break Spots":
if block_type == "toggle" and "Top Cafes to Visit" in block_text:
is_in_toggle = True
found_toggle_with_cafes = True
elif is_in_toggle and block_type == "to_do":
cafe_count += 1
# Verify unchecked status
to_do_data = block.get("to_do", {})
if to_do_data.get("checked", False):
print(f"Error: Cafe to-do item should be unchecked: {block_text}", file=sys.stderr)
return False
elif block_type in ["heading_1", "heading_2", "heading_3"]:
is_in_toggle = False
# Check Weekend Summary section
elif current_section == "📊 Weekend Summary" and block_type == "paragraph":
expected_text = f"This weekend includes {len(beach_activities)} beach activities, {len(cultural_restaurants)} cultural dining options, and {len(cafes_list)} coffee spots to explore!"
if expected_text in block_text:
found_summary = True
# Check for divider after summary
if block_type == "divider":
found_divider = True
# Check for callout with pro tip
if block_type == "callout":
callout_data = block.get("callout", {})
icon = callout_data.get("icon", {})
if icon.get("type") == "emoji" and icon.get("emoji") == "💡":
if "Pro tip: Check the Seasons database for the best time to enjoy outdoor activities!" in block_text:
found_callout = True
# Verify all required elements
all_passed = True
# Check all headings are present
for heading_text, _ in required_headings:
if heading_text not in found_headings:
print(f"Error: Missing required heading: {heading_text}", file=sys.stderr)
all_passed = False
# Check beach activities list
if not found_beach_list:
print("Error: Beach activities bulleted list not found", file=sys.stderr)
all_passed = False
elif beach_count != len(beach_activities):
print(f"Error: Expected {len(beach_activities)} beach activities, found {beach_count}", file=sys.stderr)
all_passed = False
# Check restaurant list
if not found_restaurant_list:
print("Error: Cultural dining numbered list not found", file=sys.stderr)
all_passed = False
elif restaurant_count != len(cultural_restaurants):
print(f"Error: Expected {len(cultural_restaurants)} cultural restaurants, found {restaurant_count}", file=sys.stderr)
all_passed = False
# Check cafes toggle
if not found_toggle_with_cafes:
print("Error: Toggle block 'Top Cafes to Visit' not found", file=sys.stderr)
all_passed = False
elif cafe_count != len(cafes_list):
print(f"Error: Expected {len(cafes_list)} cafes, found {cafe_count}", file=sys.stderr)
all_passed = False
# Check summary
if not found_summary:
print("Error: Weekend summary with correct counts not found", file=sys.stderr)
all_passed = False
# Check divider
if not found_divider:
print("Error: Divider block not found after summary", file=sys.stderr)
all_passed = False
# Check callout
if not found_callout:
print("Error: Callout with pro tip not found", file=sys.stderr)
all_passed = False
if all_passed:
print(f"Success: Perfect Weekend Adventure page created with all required elements.")
print(f"- {len(beach_activities)} beach activities")
print(f"- {len(cultural_restaurants)} cultural dining options")
print(f"- {len(cafes_list)} coffee spots")
return True
else:
return False
def main():
"""
Executes the verification process and exits with a status code.
"""
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()