Spaces:
Sleeping
Sleeping
File size: 43,233 Bytes
dfd4feb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 | """
data_generators.py β Deterministic procedural data generators for Meta v3.1
Replaces small hand-crafted datasets with richly varied, reproducible data.
Design principles
-----------------
* Every generator takes an `episode_id: str` and seeds Python's stdlib `random`
with `hash(episode_id + salt)` so the same episode always yields the same data.
* No third-party libs needed β stdlib only (random, string, datetime, hashlib).
* Each generator returns (agent_ctx, grader_ctx) tuples matching existing grader
contracts so graders need zero changes.
Drop-in replacement usage in Meta_environment.py::_load_context():
Replace the hardcoded-data blocks with:
from data_generators import gen_<task>(episode_id)
agent_ctx, grader_ctx = gen_<task>(episode_id)
Generators provided
-------------------
Email domain
gen_email_easy(episode_id) β 1 email, 3-way class, 30 sender/subject combos
gen_email_medium(episode_id) β 10 emails, varying priority pool
gen_email_hard(episode_id) β customer complaint, 8 scenario templates
Code domain
gen_code_easy(episode_id) β 6 code snippet variants
gen_code_medium(episode_id) β deterministic (same code, no variant needed)
gen_code_hard(episode_id) β deterministic (same code, no variant needed)
Data-cleaning domain
gen_data_easy(episode_id) β 6-10 rows, random nulls + one dup pair
gen_data_medium(episode_id) β 5 rows, randomised messy formats per field
gen_data_hard(episode_id) β 12-16 rows, IQR-detected outliers
Content moderation domain
gen_mod_easy(episode_id) β 7 posts drawn from larger pool
gen_mod_medium(episode_id) β 8 posts drawn from larger pool
(hard is already adversarial/static β left unchanged)
Ticket domain
gen_ticket_easy(episode_id) β 1 ticket from 8-variant pool
gen_ticket_medium(episode_id) β deterministic (same 8 tickets, no variant)
gen_ticket_hard(episode_id) β deterministic (same 6 incidents, no variant)
"""
from __future__ import annotations
import hashlib
import random
import string
from copy import deepcopy
from datetime import date, timedelta
from typing import Any
# ββ Seeding helper βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def _rng(episode_id: str, salt: str = "") -> random.Random:
seed = int(hashlib.md5((episode_id + salt).encode()).hexdigest(), 16)
return random.Random(seed)
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# EMAIL EASY β 30+ variant pool
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_EMAIL_EASY_POOL = [
# (subject, sender, body, label)
("You won $1,000,000!!!", "promo@totally-legit-lottery.com",
"Click here to claim your prize now! Limited time offer!", "spam"),
("Q3 Budget Review β Urgent Action Required", "cfo@company.com",
"Please review the attached Q3 budget before our board meeting tomorrow at 9 AM.", "important"),
("Your weekly digest from Medium", "noreply@medium.com",
"Top stories this week: AI trends, Python tips, and startup news.", "newsletter"),
("CONGRATULATIONS! iPhone 15 Pro is yours!", "winner@prize-alert.net",
"You have been selected. Click now to claim your free iPhone!", "spam"),
("Action Required: Sign the NDA before Friday", "legal@company.com",
"Please sign the attached NDA before Friday's partnership meeting. Deadline is strict.", "important"),
("TechCrunch Newsletter β March 2026", "newsletter@techcrunch.com",
"This week's top stories in tech, AI, and startups.", "newsletter"),
("Claim your $500 Amazon gift card NOW", "deals@amazingoffers.biz",
"You are today's lucky winner. No purchase necessary. Act fast!", "spam"),
("Production incident P1 β please join bridge", "oncall@company.com",
"We have a P1 production incident. Please join the war room immediately.", "important"),
("Developer digest: April 2026", "digest@devweekly.io",
"This week: Rust 2.0 release, LLM benchmarks, and open-source highlights.", "newsletter"),
("FREE vacation cruise β you've been selected!", "winner@vacation-cruise.net",
"Claim your free cruise for two. Just pay shipping and handling.", "spam"),
("Board approval needed: Series B term sheet", "ceo@company.com",
"Our Series B term sheet requires your signature before the 5 PM deadline today.", "important"),
("Product Hunt daily digest", "digest@producthunt.com",
"Today's top products: AI code review, async stand-ups, no-code CRM.", "newsletter"),
("Congratulations β Survey reward $250!", "rewards@surveypanel.net",
"You qualify for a $250 reward. Complete our 2-minute survey to claim.", "spam"),
("HR: Performance review cycle starts Monday", "hr@company.com",
"The annual performance review cycle begins Monday. Please complete your self-assessment.", "important"),
("Hacker News digest: top 10 links this week", "weekly@hackernews.app",
"Rust, WASM, and the AI bubble: top discussions from the community.", "newsletter"),
("Double billing detected on account #AC-8821", "billing@ourplatform.com",
"We noticed a duplicate charge on your account. Reply to initiate a refund.", "spam"),
("Legal: Partnership agreement signature required EOD", "legal@company.com",
"The partnership agreement with Nexus Corp must be countersigned by 5 PM today.", "important"),
("SaaS Weekly β your industry roundup", "editor@saasweekly.com",
"Churn rates, AI copilots, and the future of vertical SaaS.", "newsletter"),
("You have unclaimed crypto rewards!", "support@cryptorewards.io",
"Wallet 0x4fβ¦a2 has 0.3 ETH waiting. Connect now to claim.", "spam"),
("Security alert: admin password reset requested", "security@company.com",
"An admin-level password reset was requested from IP 198.51.100.42. Verify or block.", "important"),
("The Batch β AI newsletter by deeplearning.ai", "batch@deeplearning.ai",
"Andrew Ng on scaling laws, fine-tuning tips, and this week's papers.", "newsletter"),
("Limited offer: 90% off VPN subscription", "deals@vpndeals.biz",
"Today only: get lifetime VPN access for $1.99. Offer expires midnight.", "spam"),
("Vendor invoice #INV-7721 overdue by 14 days", "ar@vendor.com",
"Invoice #INV-7721 for $12,400 is now 14 days overdue. Please remit payment to avoid service interruption.", "important"),
("The Algorithm Newsletter β weekly edition", "hello@thealgorithm.co",
"ML papers, job listings, and a tutorial on RLHF.", "newsletter"),
("Your package was held β verify address", "delivery@postalnow.net",
"Your package is held due to an address discrepancy. Click to confirm.", "spam"),
("Compliance: GDPR audit documentation due Friday", "compliance@company.com",
"Please upload your GDPR data-processing records to the compliance portal by Friday.", "important"),
("Morning Brew β your daily business digest", "hello@morningbrew.com",
"Markets, tech, and the big stories you need to know today.", "newsletter"),
("Account suspended β click to restore", "support@accountalert.biz",
"Unusual activity detected. Your account has been temporarily suspended.", "spam"),
("CTO sync needed: infrastructure cost overrun", "cto@company.com",
"AWS bill came in 340% over budget. Need your sign-off on emergency cost controls.", "important"),
("The Hustle β daily newsletter", "news@thehustle.co",
"Today's biggest business stories, curated for founders and operators.", "newsletter"),
]
def gen_email_easy(episode_id: str) -> tuple[dict, dict]:
rng = _rng(episode_id, "email_easy")
email = dict(zip(["subject", "sender", "body", "label"],
rng.choice(_EMAIL_EASY_POOL)))
email["id"] = "e1"
agent_ctx = {"email": {k: v for k, v in email.items() if k != "label"}}
grader_ctx = {"email": email}
return agent_ctx, grader_ctx
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# EMAIL MEDIUM β varied priority pools
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_CRITICAL_POOL = [
{"subject": "[ALERT] Production server DOWN", "sender": "ops@company.com",
"body": "All services unresponsive since 2 AM. Revenue impact: $10k/min.", "priority": 1, "category": "critical"},
{"subject": "[P1] Database primary down β all writes failing", "sender": "oncall@company.com",
"body": "The primary DB replica crashed. No write operations possible site-wide.", "priority": 1, "category": "critical"},
{"subject": "[WARNING] Security alert: unusual login attempt", "sender": "security@company.com",
"body": "Unauthorised login attempt from IP 45.33.32.156. Verify immediately.", "priority": 1, "category": "critical"},
{"subject": "[ALERT] DDoS attack in progress", "sender": "security@company.com",
"body": "We are under a DDoS attack. Site response time is 30s+. Join the war room.", "priority": 1, "category": "critical"},
]
_URGENT_POOL = [
{"subject": "Acme Corp contract renewal β URGENT", "sender": "sales@company.com",
"body": "Acme contract expires Friday. They need signature or they walk.", "priority": 2, "category": "business"},
{"subject": "Legal: Partnership agreement needs signature TODAY", "sender": "legal@company.com",
"body": "The partnership agreement must be countersigned by EOD or the deal falls through.", "priority": 2, "category": "legal"},
{"subject": "Series B term sheet β board sign-off required by 5 PM", "sender": "ceo@company.com",
"body": "VCs need the countersigned term sheet by 5 PM today or the round lapses.", "priority": 2, "category": "legal"},
]
_FINANCE_POOL = [
{"subject": "Invoice #INV-4521 overdue", "sender": "billing@vendor.com",
"body": "Invoice of $5,400 was due 3 days ago. Payment needed to avoid suspension.", "priority": 3, "category": "finance"},
{"subject": "AWS bill 340% over budget", "sender": "finance@company.com",
"body": "Last month's cloud bill was $82k vs $24k budget. Need approval to proceed.", "priority": 3, "category": "finance"},
{"subject": "Customer double-charged β refund dispute open", "sender": "billing@company.com",
"body": "Customer #C-1121 was charged twice. Finance blocked. Needs VP sign-off.", "priority": 3, "category": "finance"},
]
_BUSINESS_POOL = [
{"subject": "Q4 product launch deck β review needed", "sender": "marketing@company.com",
"body": "Please review launch slides before Thursday. Launch is next Monday.", "priority": 4, "category": "business"},
{"subject": "Quarterly board deck β slides need your input", "sender": "ea@company.com",
"body": "Board meeting is Tuesday. Your section on growth metrics needs updating.", "priority": 4, "category": "business"},
{"subject": "Key account at risk β needs executive call", "sender": "cs@company.com",
"body": "TechGiant Corp is threatening churn. They want an exec call this week.", "priority": 4, "category": "business"},
]
_SOCIAL_POOL = [
{"subject": "Team lunch this Friday?", "sender": "colleague@company.com",
"body": "Hey, thinking of doing a team lunch Friday. You in?", "priority": 9, "category": "social"},
{"subject": "Happy Work Anniversary!", "sender": "hr@company.com",
"body": "Celebrating your 3 years with us!", "priority": 9, "category": "social"},
{"subject": "Office trivia night β Thursday 7 PM", "sender": "social@company.com",
"body": "Join us for office trivia Thursday evening. Pizza provided!", "priority": 9, "category": "social"},
]
_NEWSLETTER_POOL = [
{"subject": "Weekly SaaS digest", "sender": "news@saasdigest.com",
"body": "Top SaaS stories this week...", "priority": 10, "category": "newsletter"},
{"subject": "Free AI productivity webinar", "sender": "promo@webinar.io",
"body": "Join our free webinar on AI tools this Thursday.", "priority": 10, "category": "newsletter"},
{"subject": "The Batch: AI news weekly", "sender": "batch@deeplearning.ai",
"body": "Andrew Ng on scaling, fine-tuning, and paper highlights.", "priority": 10, "category": "newsletter"},
]
def gen_email_medium(episode_id: str) -> tuple[dict, dict]:
"""
Always picks 2 critical, 1 urgent, 1 finance, 2 business, 2 social, 2 newsletter = 10 emails.
Correct ordering: criticals first, then urgent, finance, business, social, newsletter.
"""
rng = _rng(episode_id, "email_medium")
crits = rng.sample(_CRITICAL_POOL, k=min(2, len(_CRITICAL_POOL)))
urgents = rng.sample(_URGENT_POOL, k=min(1, len(_URGENT_POOL)))
fins = rng.sample(_FINANCE_POOL, k=min(1, len(_FINANCE_POOL)))
bizs = rng.sample(_BUSINESS_POOL, k=min(2, len(_BUSINESS_POOL)))
socials = rng.sample(_SOCIAL_POOL, k=min(2, len(_SOCIAL_POOL)))
news = rng.sample(_NEWSLETTER_POOL,k=min(2, len(_NEWSLETTER_POOL)))
ordered = crits + urgents + fins + bizs + socials + news
emails = []
correct_order = []
for i, e in enumerate(ordered):
eid = f"m{i+1}"
emails.append({"id": eid, **e})
correct_order.append(eid)
# Shuffle for presentation; keep correct_order as ground truth
display = emails[:]
rng.shuffle(display)
agent_ctx = {"emails": [{k: v for k, v in e.items() if k not in ("priority", "category")} for e in display]}
grader_ctx = {"emails": emails, "correct_order": correct_order}
return agent_ctx, grader_ctx
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# EMAIL HARD β 8 complaint scenario templates
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_EMAIL_HARD_TEMPLATES = [
{
"subject": "Completely unacceptable β Order #{order_id}",
"sender": "furious.customer@email.com",
"body": (
"I have been a loyal customer for 5 years and I am absolutely furious. "
"My order #{order_id} arrived broken for the SECOND time this month. "
"Your support team has been dismissive and unhelpful every time I called. "
"I demand a full refund, a replacement sent overnight, AND compensation. "
"If this is not resolved within 24 hours, I will file a consumer court complaint."
),
"expected_elements": {
"acknowledge_frustration": ["understand", "frustrat", "disappoint", "concern", "feel"],
"apologize": ["sorry", "apologize", "apology", "sincerely"],
"offer_refund": ["refund", "money back", "full refund"],
"offer_replacement": ["replacement", "replace", "new order", "send another", "overnight"],
"provide_timeline": ["24 hours", "48 hours", "within", "today", "tomorrow", "business day"],
"professional_tone": None,
"compensation_acknowledged": ["compensat", "inconvenience", "make it right", "goodwill"],
},
},
{
"subject": "Billing error β charged twice for subscription",
"sender": "billing.complaint@customer.com",
"body": (
"I was charged twice for my annual subscription this month β once on March 1st "
"and again on March 15th. I have the bank statements as proof. "
"This is a clear billing error on your end. I need an immediate refund of the "
"duplicate charge and a written confirmation that this won't happen again. "
"I've been waiting 2 weeks for a response from your support team."
),
"expected_elements": {
"acknowledge_frustration": ["understand", "concern", "apologize", "sorry"],
"apologize": ["sorry", "apologize", "apology"],
"offer_refund": ["refund", "reimburse", "credit"],
"confirm_investigation": ["investigat", "look into", "check", "review", "verify"],
"provide_timeline": ["within", "hours", "days", "business day"],
"professional_tone": None,
"written_confirmation": ["confirm", "written", "email confirmation", "receipt"],
},
},
{
"subject": "Data breach β my account was hacked",
"sender": "angry.user@personal.com",
"body": (
"I just discovered that my account was used to make purchases I never authorised. "
"Someone accessed my account and changed my email and password. "
"I was only able to regain access because I remembered my security questions. "
"This is a serious security failure on your part. I demand to know what happened, "
"how my data was exposed, and what you will do to protect me going forward. "
"If I do not hear back within 24 hours, I will contact the data protection authority."
),
"expected_elements": {
"acknowledge_frustration": ["understand", "serious", "concern", "alarming"],
"apologize": ["sorry", "apologize", "apology"],
"confirm_investigation": ["investigat", "security team", "look into", "review"],
"offer_remediation": ["secure", "reset", "protect", "steps", "safeguard"],
"provide_timeline": ["24 hours", "48 hours", "within", "shortly", "immediately"],
"professional_tone": None,
"regulatory_mention": ["authority", "regulat", "notify", "report", "transparent"],
},
},
{
"subject": "Defective product β 3 replacements still broken",
"sender": "frustrated.buyer@email.com",
"body": (
"This is my THIRD replacement unit and it is still defective. "
"The first unit arrived with a cracked screen. The second had a faulty battery. "
"This third unit powers off randomly. "
"I have spent over 6 hours on support calls. I want a full refund immediately β "
"no more replacements. I will also be leaving reviews on every platform I can find."
),
"expected_elements": {
"acknowledge_frustration": ["understand", "frustrat", "disappoint", "three", "3"],
"apologize": ["sorry", "apologize", "sincerely"],
"offer_refund": ["refund", "full refund", "money back"],
"no_more_replacement_push": ["will not", "no further", "respect", "understand", "preference"],
"provide_timeline": ["within", "24 hours", "48 hours", "business day"],
"professional_tone": None,
"de_escalation": ["value", "loyal", "appreciate", "important to us"],
},
},
{
"subject": "Package lost β 3 weeks and still nothing",
"sender": "lost.package@customer.net",
"body": (
"I placed an order 3 weeks ago and my package has still not arrived. "
"The tracking has shown 'In Transit' for 18 days without any movement. "
"I have contacted your support team 4 times. Each time I am told to 'wait a few more days'. "
"I need this item for an event next week. Either find the package, send a replacement now, "
"or give me a full refund so I can purchase elsewhere. This is unacceptable."
),
"expected_elements": {
"acknowledge_frustration": ["understand", "frustrat", "waiting", "3 weeks", "three weeks"],
"apologize": ["sorry", "apologize", "apology"],
"offer_refund": ["refund", "full refund"],
"offer_replacement": ["replacement", "resend", "new shipment", "send another"],
"provide_timeline": ["24 hours", "48 hours", "immediately", "today", "next day"],
"professional_tone": None,
"carrier_investigation": ["carrier", "investigate", "trace", "courier", "tracking"],
},
},
{
"subject": "Cancelled subscription still being charged",
"sender": "cancelled.user@email.com",
"body": (
"I cancelled my subscription on January 15th and have proof of the cancellation email. "
"However, I have been charged $99/month for the past 3 months since then. "
"Total unauthorised charges: $297. I want a full refund of all three charges immediately. "
"If this is not resolved within 48 hours, I will initiate a chargeback with my bank "
"and report this to the consumer protection agency."
),
"expected_elements": {
"acknowledge_frustration": ["understand", "concern", "apologize", "recognised"],
"apologize": ["sorry", "apologize", "apology"],
"offer_refund": ["refund", "full refund", "$297", "three charges", "all charges"],
"confirm_cancellation": ["confirm", "cancellation", "verified", "record"],
"provide_timeline": ["48 hours", "24 hours", "immediately", "within"],
"professional_tone": None,
"prevent_recurrence": ["prevent", "ensure", "will not happen", "steps", "corrective"],
},
},
{
"subject": "Discriminatory treatment by your staff",
"sender": "discrimination.complaint@email.com",
"body": (
"I visited your store on April 2nd and was followed around by a staff member "
"while other customers were not treated this way. When I raised this with the manager, "
"I was told 'it's just store policy'. This felt discriminatory and I am deeply hurt. "
"I expect a formal apology, an explanation of your training policies, "
"and assurance that this will not happen to any customer again."
),
"expected_elements": {
"acknowledge_frustration": ["understand", "serious", "concern", "upset", "hurt"],
"apologize": ["sorry", "apologize", "sincerely", "formal apology"],
"confirm_investigation": ["investigat", "review", "look into", "hr", "management"],
"policy_commitment": ["policy", "training", "standards", "commit", "improve"],
"provide_timeline": ["within", "48 hours", "days", "shortly"],
"professional_tone": None,
"empathy_specific": ["dignity", "respect", "every customer", "valued"],
},
},
{
"subject": "Software destroyed my data β urgent",
"sender": "data.loss@business.com",
"body": (
"Your software update on March 28th corrupted our entire database backup. "
"We lost 6 months of customer records. Our business has been at a standstill for 3 days. "
"We are a paying enterprise customer ($24,000/year). "
"I need immediate escalation to your engineering team, a post-mortem report, "
"and a discussion about compensation for our business losses."
),
"expected_elements": {
"acknowledge_frustration": ["understand", "serious", "impact", "significant", "recognise"],
"apologize": ["sorry", "sincerely", "deeply apologize"],
"escalate": ["engineering", "escalate", "senior", "team", "immediately"],
"post_mortem": ["post-mortem", "root cause", "analysis", "report", "findings"],
"provide_timeline": ["24 hours", "immediately", "today", "within"],
"professional_tone": None,
"compensation_acknowledged": ["compensat", "discuss", "impact", "losses", "make it right"],
},
},
]
def gen_email_hard(episode_id: str) -> tuple[dict, dict]:
rng = _rng(episode_id, "email_hard")
template = rng.choice(_EMAIL_HARD_TEMPLATES)
order_id = rng.randint(10000, 99999)
subject = template["subject"].format(order_id=order_id)
body = template["body"].format(order_id=order_id)
case = {**template, "subject": subject, "body": body, "sender": template["sender"], "id": "h1"}
agent_ctx = {"email": {k: v for k, v in case.items() if k not in ("expected_elements", "id")}}
grader_ctx = {"email": case}
return agent_ctx, grader_ctx
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# CODE EASY β 6 snippet variants
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_CODE_EASY_POOL = [
{"code": "def calculate_average(numbers):\n total = 0\n for num in numbers\n total += num\n return total / len(numbers)\n",
"keywords": ["colon", "for loop", "syntax", "for statement"]},
{"code": "def greet(name)\n print(f'Hello, {name}!')\n\ngreet('World')\n",
"keywords": ["colon", "def", "function", "syntax"]},
{"code": "numbers = [1, 2, 3, 4, 5]\nif len(numbers) > 0\n print('Not empty')\n",
"keywords": ["colon", "if statement", "syntax"]},
{"code": "class Animal:\n def __init__(self, name)\n self.name = name\n\n def speak(self):\n return f'{self.name} speaks'\n",
"keywords": ["colon", "__init__", "constructor", "function", "def"]},
{"code": "def read_file(path):\n with open(path) as f\n return f.read()\n",
"keywords": ["colon", "with statement", "context manager", "syntax"]},
{"code": "def retry(fn, times=3):\n for i in range(times)\n try:\n return fn()\n except Exception:\n pass\n",
"keywords": ["colon", "for loop", "range", "syntax"]},
]
def gen_code_easy(episode_id: str) -> tuple[dict, dict]:
rng = _rng(episode_id, "code_easy")
variant = rng.choice(_CODE_EASY_POOL)
agent_ctx = {"code": variant["code"]}
grader_ctx = {"code": variant["code"], "keywords": variant["keywords"]}
return agent_ctx, grader_ctx
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# DATA EASY β procedurally generated 6-10 rows
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_FIRST_NAMES = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Hiro", "Iris", "Jake"]
_DOMAINS = ["example.com", "company.net", "test.org", "work.io"]
def gen_data_easy(episode_id: str) -> tuple[dict, dict]:
rng = _rng(episode_id, "data_easy")
n = rng.randint(6, 10)
names = rng.sample(_FIRST_NAMES, k=n)
base_salary = 50000
rows = []
for i, name in enumerate(names, 1):
rows.append({
"id": i,
"name": name,
"age": rng.randint(22, 55),
"email": f"{name.lower()}@{rng.choice(_DOMAINS)}",
"salary": base_salary + rng.randint(0, 50) * 1000,
})
# Inject 3-4 nulls in distinct rows and fields
null_fields = rng.sample(["age", "name", "email", "salary"], k=rng.randint(3, 4))
null_rows = rng.sample(list(range(n)), k=len(null_fields))
missing_answers = []
for row_idx, field in zip(null_rows, null_fields):
rows[row_idx][field] = None
missing_answers.append(f"{field} (row {row_idx + 1})")
# Inject one duplicate pair
dup_src = rng.randint(0, n - 2)
dup_dst = dup_src + 1
rows[dup_dst] = {**rows[dup_src], "id": dup_dst + 1}
dup_ids = sorted([rows[dup_src]["id"], rows[dup_dst]["id"]])
agent_ctx = {"data": rows}
grader_ctx = {
"data": rows,
"answers": {"missing": sorted(missing_answers), "duplicates": dup_ids},
}
return agent_ctx, grader_ctx
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# DATA MEDIUM β randomised messy formats per field
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_AGE_STRINGS = ["thirty", "twenty-two", "forty-five", "nineteen", "fifty"]
_DATE_FORMATS = [("%Y/%m/%d", "2020/01/15"), ("%d-%m-%Y", "15-03-2021"),
("%Y-%m-%d", "2019-07-22"), ("%Y/%m/%d", "2022/11/01"),
("%d/%m/%Y", "01/06/2023")]
_ACTIVE_MESSY = ["yes", "no", "TRUE", "FALSE", "1", "0"]
def gen_data_medium(episode_id: str) -> tuple[dict, dict]:
rng = _rng(episode_id, "data_medium")
names = rng.sample(_FIRST_NAMES, k=5)
rows = []
salaries = [50000, 60000, 70000, 80000, 45000]
for i, (name, salary) in enumerate(zip(names, salaries), 1):
# Introduce one of each issue type
if i == 1:
age_val = rng.choice(_AGE_STRINGS) # string age
sal_val = f"${salary:,}" # dollar+comma format
elif i == 2:
age_val = 25 # correct
sal_val = f"${salary:,}" # dollar+comma
elif i == 3:
age_val = str(rng.randint(25, 40)) # string digit
sal_val = str(salary) # clean
elif i == 4:
age_val = rng.randint(30, 45) # int β correct
sal_val = f"{salary:,}" # comma only
else:
age_val = rng.choice(_AGE_STRINGS) # string age
sal_val = str(salary) # clean
_, date_str = rng.choice(_DATE_FORMATS)
name_messy = name.lower() if i == 4 else name.upper() if i == 5 else name
active_val = rng.choice(_ACTIVE_MESSY) if i in (1, 3, 5) else rng.choice([True, False])
rows.append({"id": i, "name": name_messy, "age": age_val, "salary": sal_val,
"join_date": date_str, "active": active_val})
issues = {
"age": "mixed types: some ages are word strings, should be integers",
"salary": "inconsistent formats: dollar signs and commas present in some values",
"join_date": "three different date formats used across rows",
"name": "inconsistent casing: some names lowercase, some all-caps",
"active": "mixed types: booleans and strings ('yes','no','TRUE') mixed",
}
agent_ctx = {"data": rows}
grader_ctx = {"data": rows, "issues": issues}
return agent_ctx, grader_ctx
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# DATA HARD β IQR-detectable outliers, missing values
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def gen_data_hard(episode_id: str) -> tuple[dict, dict]:
rng = _rng(episode_id, "data_hard")
n = rng.randint(12, 16)
base = round(rng.uniform(9.5, 12.5), 1)
spread = round(rng.uniform(0.3, 0.8), 2)
rows = []
for i in range(1, n + 1):
val = round(base + rng.gauss(0, spread), 2)
rows.append({"id": i, "value": val})
# Pick 2 outlier positions (ensure they're not neighbours)
positions = list(range(n))
rng.shuffle(positions)
o1, o2 = sorted(positions[:2])
outlier_mult = rng.choice([8, 10, 12, -5, -8])
rows[o1]["value"] = round(base * abs(outlier_mult) * (1 if outlier_mult > 0 else -1), 1)
outlier_mult2 = rng.choice([-4, -6, 15, 20])
rows[o2]["value"] = round(base * abs(outlier_mult2) * (1 if outlier_mult2 > 0 else -1), 1)
outlier_ids = sorted([o1 + 1, o2 + 1])
# Pick 2 missing positions (not overlapping outliers)
available = [i for i in range(n) if i not in (o1, o2)]
m1, m2 = sorted(rng.sample(available, 2))
rows[m1]["value"] = None
rows[m2]["value"] = None
missing_ids = sorted([m1 + 1, m2 + 1])
normal_vals = [r["value"] for r in rows if r["value"] is not None and r["id"] not in outlier_ids]
lo = round(min(normal_vals) - 1.0, 2)
hi = round(max(normal_vals) + 1.0, 2)
agent_ctx = {"data": rows}
grader_ctx = {
"data": rows,
"answers": {
"outliers": set(outlier_ids),
"missing": set(missing_ids),
"imputed_range": (lo, hi),
},
}
return agent_ctx, grader_ctx
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# CONTENT MODERATION EASY β draw 7 from a pool of 20
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_MOD_EASY_POOL = [
{"text": "I hate you so much, I want to hurt you!", "label": "harmful"},
{"text": "Great weather today! Loving this sunshine", "label": "safe"},
{"text": "All people from that group should be eliminated.", "label": "harmful"},
{"text": "Can someone recommend a good Python beginner book?", "label": "safe"},
{"text": "You're an absolute idiot and nobody likes you.", "label": "harmful"},
{"text": "I just finished a 5k run β feeling amazing!", "label": "safe"},
{"text": "People like you should just disappear forever.", "label": "harmful"},
{"text": "Just dropped off a care package for my neighbor.", "label": "safe"},
{"text": "Kill yourself, nobody would miss you.", "label": "harmful"},
{"text": "Anyone else excited for the new season of that show?", "label": "safe"},
{"text": "I'm going to find you and make you pay for this.", "label": "harmful"},
{"text": "Finally got my herb garden started!", "label": "safe"},
{"text": "These people deserve to suffer for what they've done.", "label": "harmful"},
{"text": "Happy birthday to my best friend!", "label": "safe"},
{"text": "Someone should shoot that politician.", "label": "harmful"},
{"text": "Loving the new coffee shop that opened downtown.", "label": "safe"},
{"text": "I hope your family gets what's coming to them.", "label": "harmful"},
{"text": "Just hit 100 days of learning Spanish β so proud!", "label": "safe"},
{"text": "People from that country are all criminals.", "label": "harmful"},
{"text": "The cherry blossoms are out β spring is finally here!", "label": "safe"},
]
def gen_mod_easy(episode_id: str) -> tuple[dict, dict]:
rng = _rng(episode_id, "mod_easy")
# Ensure at least 3 harmful, 3 safe among 7
harmful = [p for p in _MOD_EASY_POOL if p["label"] == "harmful"]
safe = [p for p in _MOD_EASY_POOL if p["label"] == "safe"]
chosen = rng.sample(harmful, 4) + rng.sample(safe, 3)
rng.shuffle(chosen)
posts = [{"id": f"c{i+1}", **p} for i, p in enumerate(chosen)]
agent_ctx = {"posts": [{"id": p["id"], "text": p["text"]} for p in posts]}
grader_ctx = {"posts": posts}
return agent_ctx, grader_ctx
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# CONTENT MODERATION MEDIUM β draw 8 from a pool of 20
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_MOD_MEDIUM_POOL = [
{"text": "Oh sure, like THAT went well. Classic genius move.", "label": "harmful"},
{"text": "I'm so done with these people. Absolutely insufferable.", "label": "harmful"},
{"text": "That presentation was... very unique.", "label": "safe"},
{"text": "Some people just shouldn't be allowed to have opinions.", "label": "harmful"},
{"text": "Oh wow, another 'brilliant' idea from upper management", "label": "harmful"},
{"text": "Congrats on the promotion! Well deserved!", "label": "safe"},
{"text": "Not everyone is cut out for this kind of work, clearly.", "label": "harmful"},
{"text": "Thanks for the feedback, I'll take it into account.", "label": "safe"},
{"text": "Some of us actually read the requirements before submitting.", "label": "harmful"},
{"text": "Good effort β interesting approach to the problem.", "label": "safe"},
{"text": "If you'd done even a little research, you'd know better.", "label": "harmful"},
{"text": "Really enjoyed the team retrospective today.", "label": "safe"},
{"text": "Must be nice having a job you're actually qualified for.", "label": "harmful"},
{"text": "Great work getting the release out on time!", "label": "safe"},
{"text": "Shocking that anyone thought that plan would work.", "label": "harmful"},
{"text": "Just wanted to say β the onboarding docs are really clear.", "label": "safe"},
{"text": "The bar for hiring has clearly dropped.", "label": "harmful"},
{"text": "Appreciate everyone's patience during the migration.", "label": "safe"},
{"text": "I see we've decided quantity over quality again.", "label": "harmful"},
{"text": "The demo went really smoothly β nice job everyone.", "label": "safe"},
]
def gen_mod_medium(episode_id: str) -> tuple[dict, dict]:
rng = _rng(episode_id, "mod_medium")
harmful = [p for p in _MOD_MEDIUM_POOL if p["label"] == "harmful"]
safe = [p for p in _MOD_MEDIUM_POOL if p["label"] == "safe"]
chosen = rng.sample(harmful, 5) + rng.sample(safe, 3)
rng.shuffle(chosen)
posts = [{"id": f"m{i+1}", **p} for i, p in enumerate(chosen)]
agent_ctx = {"posts": [{"id": p["id"], "text": p["text"]} for p in posts]}
grader_ctx = {"posts": posts}
return agent_ctx, grader_ctx
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# TICKET EASY β 8 variant pool (already existed; keep contract-compatible)
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
_TICKET_EASY_POOL = [
{"id": "t1", "title": "App crashes on login for all users",
"description": "Since the 2.3.1 deploy, 100% of login attempts throw a 500 error.",
"reporter": "ops-monitoring@company.com", "correct_priority": "critical", "correct_category": "bug"},
{"id": "t2", "title": "Add dark mode to the dashboard",
"description": "Multiple users have requested a dark mode option.",
"reporter": "product@company.com", "correct_priority": "low", "correct_category": "feature_request"},
{"id": "t3", "title": "How do I export my data as CSV?",
"description": "I can't find the export button anywhere in the UI.",
"reporter": "user123@customer.com", "correct_priority": "low", "correct_category": "question"},
{"id": "t4", "title": "Charged twice for last month's invoice",
"description": "Account #AC-4421 shows two charges of $299 on March 1st.",
"reporter": "finance@customer.com", "correct_priority": "high", "correct_category": "billing"},
{"id": "t5", "title": "Memory leak in mobile app β crashes after 10 min",
"description": "The iOS app uses 2 GB RAM then crashes. Reproducible on all devices.",
"reporter": "qa@company.com", "correct_priority": "high", "correct_category": "bug"},
{"id": "t6", "title": "Add SSO support for Google Workspace",
"description": "Enterprise customers are requesting Google SSO. High deal-blocker frequency.",
"reporter": "sales@company.com", "correct_priority": "medium", "correct_category": "feature_request"},
{"id": "t7", "title": "Refund policy β how long does it take?",
"description": "A customer is asking about the refund timeline for a cancelled subscription.",
"reporter": "support@company.com", "correct_priority": "low", "correct_category": "question"},
{"id": "t8", "title": "Wrong amount charged β $0 instead of $499",
"description": "New enterprise contract shows $0 on the invoice. Revenue loss.",
"reporter": "billing@company.com", "correct_priority": "critical", "correct_category": "billing"},
]
def gen_ticket_easy(episode_id: str) -> tuple[dict, dict]:
rng = _rng(episode_id, "ticket_easy")
ticket = rng.choice(_TICKET_EASY_POOL)
agent_ctx = {"ticket": {k: v for k, v in ticket.items() if k not in ("correct_priority", "correct_category")}}
grader_ctx = {"ticket": ticket}
return agent_ctx, grader_ctx |