Code-Father commited on
Commit
db97c09
·
1 Parent(s): 4026fc5

changed to 3 task

Browse files
Files changed (1) hide show
  1. inference.py +29 -183
inference.py CHANGED
@@ -40,88 +40,28 @@ MODEL_NAME = os.environ["MODEL_NAME"]
40
  HF_TOKEN = os.environ["HF_TOKEN"]
41
 
42
  BENCHMARK = "store"
43
- MAX_STEPS = 10
44
- MAX_TOTAL_REWARD = MAX_STEPS * 1.0
45
- SUCCESS_SCORE_THRESHOLD = 0.5
46
 
47
  TASKS: list[dict[str, Any]] = [
48
  {
49
- "name": "margin_aware_pricing",
50
- "description": (
51
- "Optimize selling prices using the ground-truth selling score formula: "
52
- "selling_score = max(0, demand_score - margin_pct * 3). "
53
- "The agent must identify which thin-margin SKUs (Milk, Bread, Eggs, "
54
- "Bottled Water) are anchor items driving volume through high selling scores, "
55
- "and resist the naive urge to raise every low-margin price. Meanwhile, "
56
- "it should find genuinely over-margined or low-demand products where a "
57
- "price cut boosts volume, or under-margined items where a raise barely "
58
- "hurts score. Sugar is the key trap: thin margin but strong anchor role."
59
- ),
60
- "max_steps": MAX_STEPS,
61
- "success_threshold": 0.5,
62
- },
63
- {
64
- "name": "supplier_risk_arbitrage",
65
- "description": (
66
- "Navigate the seller reliability spectrum to restock fast-movers cheaply "
67
- "without incurring late-delivery stockouts. Seller A offers Rice at 138, "
68
- "Oil at 156, Spices at 345 — far below Seller B — but overcommits and "
69
- "frequently delivers 1-2 days late. Seller C quotes conservatively on "
70
- "Bread (31), Eggs (64), Curd (33), Vegetables (38) and often arrives "
71
- "early. The agent must weigh price savings against delivery risk, use "
72
- "Seller B as a reliable baseline, and avoid staking urgent restocks on "
73
- "Seller A when stock cover is already thin (Biscuits at 40, Water at 48)."
74
- ),
75
- "max_steps": MAX_STEPS,
76
  "success_threshold": 0.5,
77
  },
78
  {
79
- "name": "inventory_and_capital_discipline",
80
- "description": (
81
- "Maintain service levels on high-demand fast-movers while avoiding "
82
- "capital sinks. Starting cash is only ₹100k against ~₹240k inventory. "
83
- "Kitchen Appliances (demand 28, buy 1800, qty 4 = ₹7200 locked) is "
84
- "dead stock the agent should stop restocking. Biscuits (demand 90, qty 40) "
85
- "and Bottled Water (demand 89, qty 48) are replenishment misses that need "
86
- "immediate reorder. The agent must balance reorder urgency against cash "
87
- "preservation — daily expenses are ₹3000, and bank balance going negative "
88
- "ends the episode. Reward = 0.5 + (capital_change - recurring_costs) / "
89
- "starting_capital, so wasted capital directly reduces the score."
90
- ),
91
- "max_steps": MAX_STEPS,
92
- "success_threshold": 0.5,
93
  },
94
  {
95
- "name": "marketing_roi_evaluation",
96
  "description": (
97
- "Select durable marketing actions that maximize order-processing capacity "
98
- "and satisfaction per rupee of recurring cost. Cheap, effective picks: "
99
- "Shelf placement (ID 1: ₹800 one-time, 0 recurring, +20 capacity), "
100
- "WhatsApp ordering (ID 4: ₹1500, ₹100/day, +15 capacity), Staff training "
101
- "(ID 10: ₹2500, 0 recurring, +25 capacity). Mid-game path: Local delivery "
102
- "(ID 7), Website (ID 12), Rider (ID 13), Stockroom (ID 14). The trap is "
103
- "Action 15 (social ads): ₹4000 upfront, ₹1200/day recurring, +0 capacity "
104
- "— a weak-ROI money drain. The aspirational Action 11 (second branch: "
105
- "₹750k) is unreachable on day-1 capital. The agent should evaluate total "
106
- "cost of ownership, not just headline satisfaction boosts."
107
  ),
108
- "max_steps": MAX_STEPS,
109
- "success_threshold": 0.45,
110
- },
111
- {
112
- "name": "full_store_management",
113
- "description": (
114
- "Holistic 30-day store management combining all dimensions: pricing using "
115
- "the selling-score formula, supplier selection balancing cost vs reliability, "
116
- "inventory discipline on fast-movers and dead stock, and phased marketing "
117
- "investments. The agent must sequence decisions across 10 three-day windows, "
118
- "adapt to delivery arrivals and changing stock levels, and avoid both "
119
- "bankruptcy (bank < 0) and stagnation (no growth). This is the integrative "
120
- "test: partial credit for getting any single dimension right, full credit "
121
- "for coherent multi-objective reasoning across the entire episode."
122
- ),
123
- "max_steps": MAX_STEPS,
124
- "success_threshold": 0.5,
125
  },
126
  ]
127
 
@@ -308,117 +248,23 @@ No extra text outside JSON. Product names must exactly match the catalog.
308
 
309
 
310
  def _build_task_system_prompt(task: dict[str, Any]) -> str:
311
- task_goal = {
312
- "margin_aware_pricing": (
313
- "## Task: Margin-Aware Pricing\n\n"
314
- "Your PRIMARY goal is to optimize selling prices using the selling-score formula.\n\n"
315
- "The formula selling_score = max(0, demand - margin% × 3) means:\n"
316
- "- A product with demand 96 and margin 6% has score = 96 - 18 = 78 (strong seller)\n"
317
- "- Raising that margin to 20% gives score = 96 - 60 = 36 (volume collapses)\n"
318
- "- A product with demand 28 at any margin has negligible score anyway\n\n"
319
- "KEY INSIGHT: Thin-margin anchor items (Milk, Bread, Eggs, Bottled Water) have "
320
- "HIGH selling scores because margin% × 3 is small. Raising their price destroys "
321
- "volume disproportionately. Sugar (demand 74, margin ~5%) is a deliberate anchor — "
322
- "do NOT raise it aggressively.\n\n"
323
- "WHAT TO DO:\n"
324
- "- Calculate selling_score for every in-stock product before changing prices\n"
325
- "- Only raise prices on items where demand is high enough to absorb the score loss\n"
326
- "- Consider cutting prices on over-margined items (Coffee: ~22% margin, demand 62)\n"
327
- "- Kitchen Appliances (demand 28, margin ~35%) sell almost nothing — pricing won't help\n"
328
- "- Protect total_selling_score: it directly feeds daily order allocation"
329
- ),
330
- "supplier_risk_arbitrage": (
331
- "## Task: Supplier Risk Arbitrage\n\n"
332
- "Your PRIMARY goal is to restock fast-movers at lowest cost without stockouts.\n\n"
333
- "SELLER BEHAVIOR (actual delivery = quoted_ETA + random offset):\n"
334
- "- Seller A: offset from {0,+1,+2} with weights {2,4,5} — most likely +2 days late\n"
335
- "- Seller B: offset = 0 always — perfectly reliable\n"
336
- "- Seller C: offset from {-2,-1,0} with weights {5,4,2} — most likely 2 days early\n"
337
- "- Seller D: offset from {-1,0,+1,+2} with weights {2,4,3,2} — unpredictable\n\n"
338
- "KEY OPPORTUNITIES:\n"
339
- "- Seller A: Rice 138 (vs B: 160), Oil 156 (vs B: 180), Spices 345 (vs B: 400)\n"
340
- " → Big savings but expect delivery 3-4 days instead of quoted 2\n"
341
- "- Seller C: Bread 31, Eggs 64, Curd 33, Vegetables 38 — arrives 3 days early\n"
342
- " → Best for urgent perishable restocks despite higher quoted ETA\n\n"
343
- "URGENT RESTOCKS NEEDED:\n"
344
- "- Biscuits: qty 40, demand 90 — will sell out fast, reorder via Seller B or C\n"
345
- "- Bottled Water: qty 48, demand 89 — thin cover, needs immediate replenishment\n\n"
346
- "STRATEGY: Use Seller A for non-urgent bulk staples (Rice, Oil) where you can "
347
- "absorb delivery slippage. Use Seller C for urgent perishable/fresh restocks. "
348
- "Use Seller B as the safe default when timing matters."
349
- ),
350
- "inventory_and_capital_discipline": (
351
- "## Task: Inventory & Capital Discipline\n\n"
352
- "Your PRIMARY goal is to protect service levels on fast-movers while preserving capital.\n\n"
353
- "STARTING POSITION:\n"
354
- "- Bank: ₹100,000 | Inventory: ~₹240,000 | Daily expense: ₹3,000\n"
355
- "- Only ~33 days of cash runway before expenses alone drain the bank\n"
356
- "- Revenue from sales replenishes cash, but you must keep selling\n\n"
357
- "DEAD STOCK TO AVOID:\n"
358
- "- Kitchen Appliances: demand 28, buy ₹1800, qty 4 = ₹7,200 locked capital\n"
359
- " Selling score ≈ max(0, 28 - 35%×3) ≈ 0 — these barely move. NEVER reorder.\n\n"
360
- "REPLENISHMENT PRIORITIES (by demand × low stock):\n"
361
- "- Biscuits: demand 90, qty 40, buy ₹20 → cheap to restock, huge demand\n"
362
- "- Bottled Water: demand 89, qty 48, buy ₹18 → cheap and high demand\n"
363
- "- Eggs: demand 84, qty 24 → running low\n"
364
- "- Bread: demand 86, qty 36 → perishable, needs frequent restocking\n\n"
365
- "CAPITAL MATH: Each order is paid upfront on ordering (bank -= buy_price × qty). "
366
- "Revenue flows in daily from sales. Over-ordering locks capital in inventory "
367
- "that may not sell fast enough, starving you of cash for expenses.\n\n"
368
- "RULE: Keep bank_balance > ₹20k safety buffer at all times. Order in small "
369
- "batches rather than bulk. Prioritize items with highest demand-to-cost ratio."
370
- ),
371
- "marketing_roi_evaluation": (
372
- "## Task: Marketing ROI Evaluation\n\n"
373
- "Your PRIMARY goal is to select marketing actions that maximize capacity and "
374
- "satisfaction per rupee of TOTAL cost (upfront + recurring over remaining days).\n\n"
375
- "ZERO-RECURRING QUICK WINS (activate early):\n"
376
- "- ID 1: Shelf placement — ₹800, +20 capacity, +1 satisfaction, 0 recurring\n"
377
- "- ID 6: Storage racks — ₹7,000, +30 capacity, 0 satisfaction, 0 recurring\n"
378
- "- ID 10: Staff training — ₹2,500, +25 capacity, +2 satisfaction, 0 recurring\n"
379
- "- ID 9: Clearance shelf — ₹500, +6 capacity, -2 satisfaction, 0 recurring\n\n"
380
- "MODERATE-RECURRING GOOD VALUE:\n"
381
- "- ID 4: WhatsApp ordering — ₹1,500 + ₹100/day, +15 capacity, +4 satisfaction\n"
382
- "- ID 8: Referral rewards — ₹1,800 + ₹150/day, 0 capacity, +3 satisfaction\n\n"
383
- "MID-GAME EXPANSION (expensive but transformative if cash allows):\n"
384
- "- ID 7: Delivery partner — ₹5,000 + ₹600/day, +40 capacity\n"
385
- "- ID 12: Website — ₹60,000 + ₹400/day, +60 capacity\n"
386
- "- ID 13: Delivery rider — ₹45,000 + ₹900/day, +50 capacity\n\n"
387
- "THE TRAP — DO NOT ACTIVATE:\n"
388
- "- ID 15: Social ads — ₹4,000 + ₹1,200/day, +0 capacity, only +3 satisfaction\n"
389
- " → Over 30 days this costs ₹40,000 total with ZERO capacity gain\n\n"
390
- "UNREACHABLE:\n"
391
- "- ID 11: Second branch — ₹750,000 upfront. You only have ₹100k. Skip it.\n\n"
392
- "FORMULA IMPACT: More capacity → more daily_orders_processed → more revenue. "
393
- "Recurring costs are subtracted from reward. Evaluate 6-day total cost of "
394
- "ownership against the capacity gain."
395
- ),
396
- "full_store_management": (
397
- "## Task: Full Store Management (Integrative)\n\n"
398
- "Your PRIMARY goal is to run the store profitably across all 10 decision windows "
399
- "by combining pricing, ordering, inventory management, and marketing.\n\n"
400
- "PHASE 1 (Steps 1-3): Foundation\n"
401
- "- Activate zero-recurring marketing: IDs 1, 10, 6 (total ₹10,300, +75 capacity)\n"
402
- "- Restock urgent items: Biscuits and Bottled Water via Seller B or C\n"
403
- "- Review prices: do NOT raise Milk/Bread/Eggs/Sugar — they're anchor items\n"
404
- "- Consider cutting Coffee price to boost its selling score\n\n"
405
- "PHASE 2 (Steps 4-6): Growth\n"
406
- "- Activate WhatsApp ordering (ID 4) for +15 capacity at ₹100/day\n"
407
- "- Use Seller A for bulk Rice/Oil/Spices — savings are ~15-20% vs Seller B\n"
408
- "- Monitor delivery arrivals and restock perishables via Seller C as needed\n"
409
- "- Evaluate delivery partner (ID 7) — +40 capacity but ₹600/day\n\n"
410
- "PHASE 3 (Steps 7-10): Optimization\n"
411
- "- Fine-tune prices based on observed stock depletion rates\n"
412
- "- If profitable, invest in ID 12 (website) or ID 13 (rider) for big capacity\n"
413
- "- NEVER activate ID 15 (social ads) — ₹1,200/day for +0 capacity is a trap\n"
414
- "- NEVER reorder Kitchen Appliances — dead stock\n"
415
- "- Keep bank > ₹15k at all times to avoid bankruptcy\n\n"
416
- "REWARD OPTIMIZATION: Each step's reward = 0.5 + capital_growth_rate. "
417
- "Capital = bank + inventory. Maximize revenue through high selling scores, "
418
- "minimize costs through smart supplier selection and avoiding wasteful marketing."
419
- ),
420
- }
421
- goal = task_goal.get(task["name"], "Maximize your score.")
422
  return SYSTEM_PROMPT + f"\n\n{goal}"
423
 
424
 
 
40
  HF_TOKEN = os.environ["HF_TOKEN"]
41
 
42
  BENCHMARK = "store"
 
 
 
43
 
44
  TASKS: list[dict[str, Any]] = [
45
  {
46
+ "name": "store_short_run",
47
+ "description": "Run the store profitably over 5 decision windows (15 days).",
48
+ "max_steps": 5,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  "success_threshold": 0.5,
50
  },
51
  {
52
+ "name": "store_medium_run",
53
+ "description": "Run the store profitably over 10 decision windows (30 days).",
54
+ "max_steps": 10,
55
+ "success_threshold": 0.55,
 
 
 
 
 
 
 
 
 
 
56
  },
57
  {
58
+ "name": "store_long_run",
59
  "description": (
60
+ "Run the store profitably over 15 decision windows (45 days). "
61
+ "Requires sustained capital growth and careful long-term planning."
 
 
 
 
 
 
 
 
62
  ),
63
+ "max_steps": 15,
64
+ "success_threshold": 0.6,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  },
66
  ]
67
 
 
248
 
249
 
250
  def _build_task_system_prompt(task: dict[str, Any]) -> str:
251
+ max_steps = task["max_steps"]
252
+ threshold = task["success_threshold"]
253
+ goal = (
254
+ f"## Task: {task['name']}\n\n"
255
+ f"You have {max_steps} decision windows. "
256
+ f"Target average reward per step ≥ {threshold:.1f}.\n\n"
257
+ "STRATEGY PRIORITIES:\n"
258
+ "1. Activate zero-recurring marketing early: IDs 1, 10, 6 (+75 capacity, no daily cost)\n"
259
+ "2. Restock high-demand cheap items: Biscuits (demand 90), Bottled Water (demand 89), "
260
+ "Eggs (demand 84), Bread (demand 86) — use Seller B/C for reliability\n"
261
+ "3. Use Seller A for bulk staples (Rice, Oil, Spices) only when stock cover is safe\n"
262
+ "4. Protect anchor item prices: do NOT raise Milk/Bread/Eggs/Sugar/Bottled Water\n"
263
+ "5. NEVER reorder Kitchen Appliances (dead stock, demand 28, margin ~35%)\n"
264
+ "6. NEVER activate ID 15 (social ads: ₹1,200/day for +0 capacity)\n"
265
+ "7. Keep bank_balance > ₹15k safety buffer at all times\n"
266
+ "8. After foundations, consider WhatsApp ordering (ID 4) and delivery partner (ID 7)"
267
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  return SYSTEM_PROMPT + f"\n\n{goal}"
269
 
270