Plan and build grocery orders on Rohlik. Orchestrates fridge state checking, preference matching, promotion scanning, and cart building. Use when the user wants to order groceries, plan meals, or asks for a shopping list.
Build smart grocery orders by combining fridge state, preferences, promotions, and user requirements.
Before starting the workflow, determine the order type from the user's message:
Full order — "prepare a weekly order", "need groceries for the week", "make an order for 5 days" → Run the full workflow with all subagents.
Quick top-up — "I need milk", "can you add bread and eggs", "forgot to order butter", "we ran out of ham"
→ Skip subagents. Search for the requested items directly via mcp__rohlik__search_products (use cached Rohlik IDs from staples.md when available). Add to cart. Suggest a delivery slot. Done.
→ Still check planning-feedback.md for the item — if user previously adjusted quantities, use their preferred quantity.
→ Do NOT ask household/fridge questions for top-ups.
Restock check — "what do we need?", "anything running low?" → Run only the Fridge Estimator subagent. Present DEPLETED/LOW items. Ask if the user wants to turn it into an order.
If unclear, default to full order.
When the user asks to prepare a full grocery order:
Send an immediate message via mcp__nanoclaw__send_message:
"Working on your order — analyzing your deliveries, fridge, and current deals..."
Then launch 3 background subagents in parallel using the Task tool with run_in_background: true:
Description: "Analyze recent Rohlik deliveries and update grocery memory"
Prompt: |
You are a delivery analysis agent. Your job:
1. Call mcp__rohlik__get_order_history to get recent completed/delivered orders
2. Read /workspace/group/grocery/delivery-log.md to find which orders are already processed
3. For each NEW completed order, call mcp__rohlik__get_order_detail to get item-level data
4. Update these files with new data merged into existing consolidation:
- grocery/preferences.md (brand loyalty, liked/disliked categories)
- grocery/staples.md (items in 70%+ of orders — include Rohlik product ID for each item)
- grocery/patterns.md (co-purchase patterns, seasonal trends, order frequency)
- grocery/spending.md (order totals, averages)
- grocery/delivery-log.md (append new order summaries)
- grocery/meals.md (infer meals from co-purchase ingredient groups)
5. If grocery/ directory doesn't exist, create it and bootstrap from last 10-20 orders
6. Calculate consumption calibration: for staple items, measure actual reorder intervals
and write calibrated rates to fridge-state.md under "## Calibrated Rates"
7. Check grocery/planning-feedback.md for items with 3+ repeated corrections:
- Removals 3+ times → add to preferences.md as disliked, mark promoted
- Additions 3+ times → add to staples.md, mark promoted
- Quantity adjustments 3+ times → update typical qty in staples.md
IMPORTANT: Only process COMPLETED/DELIVERED orders. Never update from pending orders.
Return a concise summary:
- How many new orders were processed
- Any new patterns or preference changes detected
- Current order frequency and average spend
- Any planning feedback promoted to preferences/staples
- Any consumption rates calibrated (product, old default, new calibrated)
Description: "Estimate current fridge and pantry contents"
Prompt: |
You are a fridge state estimation agent. Your job:
1. Read /workspace/group/grocery/fridge-state.md for the last known state
2. Read /workspace/group/grocery/delivery-log.md for recent deliveries
3. Read /workspace/group/grocery/household.md for household size (default: 2 adults if missing)
4. Apply the consumption rate model with this priority:
a. Check "## Calibrated Rates" in fridge-state.md — if a product has a calibrated
rate based on actual reorder intervals, use it (do NOT apply household scaling)
b. Check "## Custom Rates" in fridge-state.md — user manual overrides
c. Fall back to category defaults:
Fresh meat/fish: 2-3 days, Deli/ham: 4-5 days
Milk/kefir: 5-7 days, Yogurt: 7-10 days
Fresh vegetables: 5-7 days, Root vegetables: 14-21 days
Fresh fruit: 3-5 days, Citrus/apples: 10-14 days
Bread: 3-4 days, Eggs: 14 days
Hard cheese: 14-21 days, Butter: 21-30 days
Pantry staples (rice, pasta, flour): 60-90 days
Spices/condiments: 180+ days, Frozen: 60 days
For category defaults only, scale consumption by (household_size / 2).
5. Calculate estimated remaining % for each item
6. Update /workspace/group/grocery/fridge-state.md with current estimates
(preserve the Calibrated Rates and Custom Rates sections when updating)
Return a concise summary grouped by status:
- DEPLETED (0-10%): items that definitely need restocking
- LOW (10-30%): items that should probably be included
- OK (30-70%): no action needed
- FULL (70-100%): recently delivered, skip these
Also list 2-3 borderline items where you're uncertain and suggest
questions the main agent should ask the user.
Note on subagent ordering: The Delivery Analyzer and Fridge Estimator both touch fridge-state.md. The Analyzer adds newly delivered items and calibrated rates; the Estimator recalculates remaining percentages. When both run in parallel, the Estimator may read stale data. This is acceptable — the Estimator works with whatever state exists at read time, and both preserve each other's sections. The next run will reconcile.
Description: "Find relevant Rohlik promotions matching taste profile"
Prompt: |
You are a promotion scanning agent. Your job:
1. Read /workspace/group/grocery/preferences.md for taste profile and brand preferences
2. Read /workspace/group/grocery/staples.md for always-buy items
3. Read /workspace/group/grocery/patterns.md for seasonal preferences
4. Call mcp__rohlik__get_discounted_items to fetch current promotions
5. Filter promotions to ONLY items matching the household's taste profile:
- Staple items on sale (direct savings)
- Preferred brands on sale
- Items in liked categories
- Seasonal items appropriate for current time
6. EXCLUDE deals on disliked items or categories
Return a concise summary:
- Top 5-10 most relevant deals with product name, Rohlik product ID, discount %, price, and why it matches
- Any staple items currently on promotion (highlight these — guaranteed savings)
- Total potential savings if all suggested deals are taken
While the 3 subagents run in the background, use this time to ask the user questions.
Check /workspace/group/grocery/household.md. If missing or incomplete, ask:
If household.md exists and is recent, only ask about the current order:
Wait for all 3 subagents to complete (use TaskOutput to read results). You now have:
If the Fridge Estimator suggested borderline questions, ask them now (max 2-3 questions).
Read the user's answers from Step 2 and the subagent summaries from Step 3. Also read:
grocery/preferences.md — respect likes, dislikes, brand preferencesgrocery/staples.md — always-buy items form the baselinegrocery/patterns.md — co-purchase patterns (if adding pasta, add canned tomatoes too)Combine all inputs into a structured proposal. For each item, add a short reasoning tag so the user knows WHY it's in the cart. Use Rohlik product IDs from staples.md when available to avoid re-searching.
Reasoning tags (pick the most relevant one per item):
staple — always-buy item from staples.mdlow — fridge tracker shows running low or depleteddeal -N% — currently on promotionpattern — co-purchase pattern (e.g., goes with pasta)meal — ingredient for a favorite meal from meals.mdseasonal — seasonal item matching current timerequested — user explicitly asked for it*Weekly order (N days, M people)*
*Dairy*
• Milk 1.5% Madeta 1L x2 — 35 CZK _staple, low_
• Yogurt natural x4 — 60 CZK _staple_
• Eidam 30% — 45 CZK _deal -25%_
*Meat & Fish*
• Chicken breast 500g — 89 CZK _low, meal: stir-fry_
*Pantry*
• Canned tomatoes x2 — 30 CZK _pattern: goes with pasta_
*Total: ~X CZK (saved ~Y CZK on deals)*
Anything to add, remove, or change?
Keep WhatsApp messages under 4000 characters. If the order is large, split into 2 messages.
Process user feedback:
mcp__rohlik__search_products, suggest optionsTrack corrections in grocery/planning-feedback.md:
Use Rohlik product IDs from staples.md whenever available — call mcp__rohlik__add_to_cart with the cached ID directly. Only fall back to mcp__rohlik__search_products for items without a cached ID.
Delivery timing intelligence: After adding items to cart, suggest optimal delivery timing based on fridge state:
fridge-state.md for the earliest depletion date among DEPLETED/LOW staple itemsmcp__rohlik__get_delivery_slots to get available slotsPresent it as:
"Your milk and eggs are likely running out by Wednesday. The earliest slot is Tuesday 10-12 — want that one, or prefer a different time?"
Show 2-3 options with context about why the recommended slot makes sense.
DO NOT update grocery memory files based on the planned or confirmed cart. A planned order is not a completed delivery — it may be modified, cancelled, or never delivered. Memory must only reflect what was actually bought and delivered.
fridge-state.md, delivery-log.md, spending.md, staples.md, patterns.md, or preferences.md from cart contents.planning-feedback.md IS allowed to be updated during planning (Step 5) — it's a correction tracker, not a preference file. It only promotes to preferences after 3+ consistent signals during the next delivery analysis.Exception — durable user preferences: If the user explicitly states a lasting preference during the planning conversation, you MAY update preferences.md or household.md. Examples:
These are user-stated facts about their identity/household, not predictions from a cart. Only save preferences that clearly apply to all future orders, not one-time requests like "add beer for tonight".
If /workspace/group/grocery/ doesn't exist or is mostly empty:
grocery/household.mdWhen the user asks for meal suggestions:
grocery/meals.md for favorite meals and when they were last cooked"• Pasta bolognese — have pasta & tomatoes, need ground beef low" "• Stir-fry — have chicken low, need vegetables"
meals.md with the current date as Last Cookedmeals.md, add it with its ingredientsWhen the user mentions guests or a special occasion:
When searching for a product and the preferred item is unavailable:
If the agent notices it's been longer than the usual order interval (from patterns.md):
"It's been N days since your last delivery — usually you order every M days. Want me to prepare an order?"
This can be set up as a scheduled task via mcp__nanoclaw__schedule_task.