make-mp-data 2.1.11 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +31 -0
  2. package/dungeons/adspend.js +2 -2
  3. package/dungeons/ai-chat-analytics-ed.js +3 -2
  4. package/dungeons/anon.js +2 -2
  5. package/dungeons/array-of-object-loopup.js +181 -0
  6. package/dungeons/benchmark-heavy.js +241 -0
  7. package/dungeons/benchmark-light.js +141 -0
  8. package/dungeons/big.js +9 -8
  9. package/dungeons/business.js +2 -1
  10. package/dungeons/clinch-agi.js +632 -0
  11. package/dungeons/complex.js +3 -2
  12. package/dungeons/copilot.js +383 -0
  13. package/dungeons/ecommerce-store.js +0 -0
  14. package/dungeons/experiments.js +5 -4
  15. package/dungeons/foobar.js +1 -1
  16. package/dungeons/funnels.js +2 -2
  17. package/dungeons/gaming.js +3 -2
  18. package/dungeons/harness/harness-education.js +988 -0
  19. package/dungeons/harness/harness-fintech.js +976 -0
  20. package/dungeons/harness/harness-food.js +985 -0
  21. package/dungeons/harness/harness-gaming.js +1178 -0
  22. package/dungeons/harness/harness-media.js +961 -0
  23. package/dungeons/harness/harness-sass.js +923 -0
  24. package/dungeons/harness/harness-social.js +928 -0
  25. package/dungeons/kurby.js +211 -0
  26. package/dungeons/media.js +5 -4
  27. package/dungeons/mil.js +4 -3
  28. package/dungeons/mirror.js +2 -2
  29. package/dungeons/money2020-ed.js +8 -7
  30. package/dungeons/sanity.js +3 -2
  31. package/dungeons/scd.js +3 -2
  32. package/dungeons/simple.js +30 -15
  33. package/dungeons/strict-event-test.js +30 -0
  34. package/dungeons/student-teacher.js +3 -2
  35. package/dungeons/text-generation.js +84 -85
  36. package/dungeons/too-big-events.js +166 -0
  37. package/dungeons/uday-schema.json +220 -0
  38. package/dungeons/userAgent.js +4 -3
  39. package/index.js +41 -54
  40. package/lib/core/config-validator.js +122 -7
  41. package/lib/core/context.js +7 -14
  42. package/lib/core/storage.js +57 -25
  43. package/lib/generators/adspend.js +12 -12
  44. package/lib/generators/events.js +6 -5
  45. package/lib/generators/funnels.js +32 -10
  46. package/lib/generators/product-lookup.js +262 -0
  47. package/lib/generators/product-names.js +195 -0
  48. package/lib/generators/profiles.js +3 -3
  49. package/lib/generators/scd.js +13 -3
  50. package/lib/generators/text.js +17 -4
  51. package/lib/orchestrators/mixpanel-sender.js +244 -204
  52. package/lib/orchestrators/user-loop.js +54 -16
  53. package/lib/templates/funnels-instructions.txt +272 -0
  54. package/lib/templates/hook-examples.json +187 -0
  55. package/lib/templates/hooks-instructions.txt +295 -8
  56. package/lib/templates/phrases.js +473 -16
  57. package/lib/templates/refine-instructions.txt +485 -0
  58. package/lib/templates/schema-instructions.txt +239 -109
  59. package/lib/templates/schema.d.ts +173 -0
  60. package/lib/templates/verbose-schema.js +140 -206
  61. package/lib/utils/ai.js +853 -77
  62. package/lib/utils/chart.js +210 -0
  63. package/lib/utils/function-registry.js +285 -0
  64. package/lib/utils/json-evaluator.js +172 -0
  65. package/lib/utils/logger.js +38 -0
  66. package/lib/utils/mixpanel.js +101 -0
  67. package/lib/utils/project.js +3 -2
  68. package/lib/utils/utils.js +41 -4
  69. package/package.json +15 -21
  70. package/types.d.ts +15 -5
  71. package/lib/generators/text-bak-old.js +0 -1121
  72. package/lib/orchestrators/worker-manager.js +0 -203
  73. package/lib/templates/phrases-bak.js +0 -925
  74. package/lib/templates/prompt (old).txt +0 -98
  75. package/lib/templates/scratch-dungeon-template.js +0 -116
  76. package/lib/templates/textQuickTest.js +0 -172
@@ -12,6 +12,28 @@ The user has already generated a dungeon schema with these events, properties, a
12
12
 
13
13
  --------------
14
14
 
15
+ CRITICAL - EXACT PROPERTY AND VALUE NAMES:
16
+
17
+ You MUST use the EXACT event names, property names, and property values from the schema above. These are CASE-SENSITIVE and must match EXACTLY.
18
+
19
+ DO NOT:
20
+ - Invent new event names
21
+ - Invent new property names
22
+ - Invent new property values
23
+ - Change the case of any names (e.g., "user_id" ≠ "User_ID" ≠ "userId")
24
+ - Use similar but different names (e.g., "status" ≠ "application status")
25
+
26
+ DO:
27
+ - Copy event names exactly as they appear in the schema
28
+ - Copy property names exactly as they appear in the schema
29
+ - Copy property values exactly as they appear in the schema (for arrays)
30
+ - Reference only properties that actually exist in the schema
31
+ - Respect underscores, hyphens, spaces, and capitalization
32
+
33
+ If the user asks you to reference a property that doesn't exist in the schema, ask them to add it to the schema first OR work with the closest matching property that does exist.
34
+
35
+ --------------
36
+
15
37
  YOUR TASK:
16
38
 
17
39
  Based on the user's description of desired trends or patterns, generate a single JavaScript hook function that implements those statistical relationships.
@@ -38,6 +60,36 @@ HOOK TYPES (type parameter):
38
60
  - "ad-spend": Hook into ad spend events.
39
61
  - "everything": Runs once per user after all their events are generated. `record` is the full event stream array, and `meta` contains user profile and metadata. This is the most powerful hook for creating complex correlations.
40
62
 
63
+ COMPOSING MULTIPLE HOOK TYPES:
64
+
65
+ IMPORTANT: Your hook function can handle MULTIPLE hook types in the SAME function. The examples below show individual patterns, but you should COMBINE and COMPOSE multiple hook types together when the user's requirements call for it.
66
+
67
+ For example, a single hook function can:
68
+ - Modify event properties (event type)
69
+ - Alter funnel conversion rates (funnel-pre type)
70
+ - Filter or modify the full event stream (everything type)
71
+ - All in the same function!
72
+
73
+ Pattern for multi-type hooks:
74
+
75
+ if (type === "event") {
76
+ // Handle individual event modifications
77
+ }
78
+
79
+ if (type === "funnel-pre") {
80
+ // Handle funnel configuration changes
81
+ }
82
+
83
+ if (type === "everything") {
84
+ // Handle full user event stream modifications
85
+ }
86
+
87
+ return record;
88
+
89
+ Think of the examples below as BUILDING BLOCKS that you can mix and match. If the user asks for "users who do X are more likely to do Y AND their funnels convert better AND they churn less", you should compose event-level, funnel-level, and everything-level logic into ONE cohesive hook function.
90
+
91
+ The examples are NOT rigid templates - they're patterns to learn from and combine creatively.
92
+
41
93
  AVAILABLE HELPERS:
42
94
 
43
95
  You have access to these utilities within the hook:
@@ -52,13 +104,17 @@ You have access to these utilities within the hook:
52
104
 
53
105
  CRITICAL RULES:
54
106
 
55
- 1. Your ONLY output is the hook function body (the code inside the function, NOT including the "hook: function (record, type, meta) {" wrapper).
107
+ 1. Output Format: You MUST output a COMPLETE JavaScript function with the exact signature: function(record, type, meta) { ... }
108
+ - INCLUDE the function declaration: function(record, type, meta) {
109
+ - INCLUDE all your hook logic in the body
110
+ - INCLUDE the closing brace: }
111
+ - The function MUST always return record at the end
56
112
 
57
113
  2. Generate VALID JavaScript code that will execute without errors.
58
114
 
59
115
  3. The code should implement the statistical trends described by the user.
60
116
 
61
- 4. Use the actual event names and property names from the schema provided above.
117
+ 4. CRITICAL: Use ONLY the EXACT event names, property names, and values from the schema. Case-sensitive. No variations. No invented names. Copy them exactly.
62
118
 
63
119
  5. Always return `record` at the end.
64
120
 
@@ -390,6 +446,203 @@ if (type === "event") {
390
446
  }
391
447
  return record;
392
448
 
449
+ === SCD HOOKS (Slowly Changing Dimensions) ===
450
+
451
+ Example 9: Modifying events based on user's SCD state at that time
452
+
453
+ // SCDs track how user properties change over time (e.g., plan upgrades, role changes)
454
+ // This hook modifies user behavior during different SCD periods
455
+
456
+ if (type === "everything") {
457
+ // Assuming the schema has an SCD for "subscription_plan" with values ["free", "basic", "pro", "enterprise"]
458
+ // We'll modify user behavior based on their plan at the time of each event
459
+
460
+ const UPGRADE_DATE = dayjs().subtract(15, 'days');
461
+ const ENTERPRISE_DATE = dayjs().subtract(5, 'days');
462
+
463
+ record.forEach((event) => {
464
+ const EVENT_TIME = dayjs(event.time);
465
+
466
+ // Determine user's plan at this point in time
467
+ let currentPlan = "free"; // default
468
+ if (EVENT_TIME.isAfter(UPGRADE_DATE)) {
469
+ currentPlan = "basic";
470
+ }
471
+ if (EVENT_TIME.isAfter(ENTERPRISE_DATE)) {
472
+ currentPlan = "enterprise";
473
+ }
474
+
475
+ // Modify event behavior based on plan
476
+ if (currentPlan === "enterprise") {
477
+ // Enterprise users use advanced features more
478
+ if (event.event === "feature_used" && event["feature_name"]) {
479
+ if (chance.bool({ likelihood: 70 })) {
480
+ event["feature_name"] = "advanced_analytics";
481
+ event["usage_duration"] = u.integer(300, 600); // longer sessions
482
+ }
483
+ }
484
+ // They also generate more API calls
485
+ if (event.event === "api_call") {
486
+ event["rate_limit"] = "unlimited";
487
+ event["response_time"] = u.integer(50, 150); // faster response
488
+ }
489
+ } else if (currentPlan === "basic") {
490
+ // Basic users have moderate usage
491
+ if (event.event === "feature_used") {
492
+ event["usage_duration"] = u.integer(60, 300);
493
+ }
494
+ if (event.event === "api_call") {
495
+ event["rate_limit"] = "1000/hour";
496
+ event["response_time"] = u.integer(100, 300);
497
+ }
498
+ } else {
499
+ // Free users have limited behavior
500
+ if (event.event === "feature_used") {
501
+ event["usage_duration"] = u.integer(30, 120); // shorter sessions
502
+ if (chance.bool({ likelihood: 30 })) {
503
+ // Sometimes hit paywalls
504
+ event["hit_paywall"] = true;
505
+ }
506
+ }
507
+ if (event.event === "api_call") {
508
+ event["rate_limit"] = "100/hour";
509
+ event["response_time"] = u.integer(200, 500);
510
+ if (chance.bool({ likelihood: 20 })) {
511
+ event["error"] = "rate_limit_exceeded";
512
+ }
513
+ }
514
+ }
515
+ });
516
+ }
517
+ return record;
518
+
519
+ Example 10: SCD-driven churn patterns
520
+
521
+ // Users who downgrade their plan are more likely to churn
522
+
523
+ if (type === "everything") {
524
+ const DOWNGRADE_DATE = dayjs().subtract(20, 'days');
525
+ const CHURN_DATE = dayjs().subtract(10, 'days');
526
+
527
+ // Check if user downgraded (would be tracked in SCD)
528
+ let userDowngraded = false;
529
+
530
+ record.forEach((event, idx) => {
531
+ const EVENT_TIME = dayjs(event.time);
532
+
533
+ // Simulate checking SCD history
534
+ if (EVENT_TIME.isAfter(DOWNGRADE_DATE) && EVENT_TIME.isBefore(CHURN_DATE)) {
535
+ userDowngraded = true;
536
+ }
537
+
538
+ if (userDowngraded && EVENT_TIME.isAfter(CHURN_DATE)) {
539
+ // Downgraded users have 60% chance to stop using the product
540
+ if (chance.bool({ likelihood: 60 })) {
541
+ // Remove this event (user churned)
542
+ record.splice(idx, 1);
543
+ }
544
+ }
545
+ });
546
+
547
+ // If user downgraded, reduce overall event frequency
548
+ if (userDowngraded) {
549
+ record = record.filter((event, idx) => {
550
+ const EVENT_TIME = dayjs(event.time);
551
+ if (EVENT_TIME.isAfter(DOWNGRADE_DATE)) {
552
+ // Keep only 30% of events after downgrade
553
+ return chance.bool({ likelihood: 30 });
554
+ }
555
+ return true;
556
+ });
557
+ }
558
+ }
559
+ return record;
560
+
561
+ === MULTI-TYPE COMPOSITION EXAMPLE ===
562
+
563
+ Example 11: Complete multi-type hook for product launch impact
564
+
565
+ // This example shows how to compose multiple hook types for a comprehensive trend:
566
+ // A new feature launch that affects individual events, funnel conversion, and overall usage
567
+
568
+ const FEATURE_LAUNCH = dayjs().subtract(21, 'days');
569
+ const FEATURE_IMPROVEMENT = dayjs().subtract(7, 'days');
570
+
571
+ // Handle individual events
572
+ if (type === "event") {
573
+ const EVENT_TIME = dayjs(record.time);
574
+
575
+ // After feature launch, usage patterns change
576
+ if (EVENT_TIME.isAfter(FEATURE_LAUNCH)) {
577
+ // New feature attracts more engagement
578
+ if (record.event === "page_view" && record["page_name"] === "dashboard") {
579
+ if (chance.bool({ likelihood: 40 })) {
580
+ record["page_name"] = "new_feature";
581
+ record["engagement_score"] = u.integer(70, 100);
582
+ }
583
+ }
584
+
585
+ // But initially has bugs
586
+ if (EVENT_TIME.isBefore(FEATURE_IMPROVEMENT)) {
587
+ if (record.event === "error" && record["error_type"]) {
588
+ if (chance.bool({ likelihood: 30 })) {
589
+ record["error_type"] = "feature_bug";
590
+ record["severity"] = "high";
591
+ }
592
+ }
593
+ }
594
+ }
595
+ }
596
+
597
+ // Handle funnel conversion changes
598
+ if (type === "funnel-pre") {
599
+ const funnelTime = dayjs.unix(meta.firstEventTime);
600
+
601
+ // Feature launch improves conversion for certain funnels
602
+ if (funnelTime.isAfter(FEATURE_LAUNCH)) {
603
+ if (record.sequence && record.sequence.includes("signup")) {
604
+ // New feature attracts more signups
605
+ record.conversionRate *= 1.3;
606
+
607
+ // After improvements, conversion gets even better
608
+ if (funnelTime.isAfter(FEATURE_IMPROVEMENT)) {
609
+ record.conversionRate *= 1.2;
610
+ }
611
+ }
612
+ }
613
+ }
614
+
615
+ // Handle overall user stream modifications
616
+ if (type === "everything") {
617
+ const firstEventTime = record[0] ? dayjs(record[0].time) : dayjs();
618
+
619
+ // Users who joined after feature launch are more engaged
620
+ if (firstEventTime.isAfter(FEATURE_LAUNCH)) {
621
+ // These users generate 50% more events
622
+ const additionalEvents = Math.floor(record.length * 0.5);
623
+
624
+ for (let i = 0; i < additionalEvents; i++) {
625
+ if (record.length > 0 && chance.bool({ likelihood: 70 })) {
626
+ // Clone and modify random events
627
+ const sourceEvent = record[u.integer(0, record.length - 1)];
628
+ const newEvent = v.clone(sourceEvent);
629
+
630
+ // Adjust time and properties
631
+ newEvent.time = dayjs(sourceEvent.time).add(u.integer(1, 60), 'minutes').toISOString();
632
+ newEvent["feature_related"] = true;
633
+
634
+ // Add to stream
635
+ record.push(newEvent);
636
+ }
637
+ }
638
+
639
+ // Sort events by time after additions
640
+ record.sort((a, b) => new Date(a.time) - new Date(b.time));
641
+ }
642
+ }
643
+
644
+ return record;
645
+
393
646
  === KEY PATTERNS FOR ENGINEERING TRENDS ===
394
647
 
395
648
  1. **Time-Based Changes**: Define key dates (product launches, feature changes, bugs fixed) and modify behavior before/after
@@ -425,10 +678,44 @@ return record;
425
678
 
426
679
  YOUR OUTPUT:
427
680
 
428
- Generate ONLY the hook function body (the code between the curly braces). Do not include:
429
- - The "hook: function (record, type, meta) {" wrapper
430
- - The closing "}" of the function
431
- - Any explanations or comments outside the code
432
- - Any markdown formatting
681
+ You MUST output a COMPLETE JavaScript function that can be directly stored and executed.
682
+
683
+ REQUIRED FORMAT:
684
+ ```
685
+ function(record, type, meta) {
686
+ // Your hook implementation here
687
+ // Can handle multiple types in one function
688
+ // Must always return record at the end
689
+ return record;
690
+ }
691
+ ```
692
+
693
+ OUTPUT REQUIREMENTS:
694
+ ✅ MUST include the function declaration: function(record, type, meta) {
695
+ ✅ MUST include all hook logic in the function body
696
+ ✅ MUST include the closing brace: }
697
+ ✅ MUST return record at the end (even if modified or filtered)
698
+ ❌ DO NOT include markdown formatting or backticks
699
+ ❌ DO NOT include explanations outside the function
700
+ ❌ DO NOT include anything except the JavaScript function
701
+
702
+ Example of CORRECT output:
703
+ ```
704
+ function(record, type, meta) {
705
+ if (type === "event") {
706
+ // Modify individual events
707
+ if (record.event === "purchase") {
708
+ record.amount *= 1.1;
709
+ }
710
+ }
711
+
712
+ if (type === "everything") {
713
+ // Modify full event stream
714
+ record = record.filter(e => e.event !== "test");
715
+ }
716
+
717
+ return record;
718
+ }
719
+ ```
433
720
 
434
- Your output should be pure JavaScript code that can be directly inserted into a hook function.
721
+ Your entire output should be exactly one JavaScript function that starts with function(record, type, meta) { and ends with }