1. Sub-10-minute promise about to break → proactive save, not a silent late delivery
Today: the store manager keeps the ops dashboard open on one tab and the rider-app in another, and watches the amber timers. When one goes red she pings the store WhatsApp group — 'order 8842 kahan hai?' — someone replies four minutes later, and by then the customer has already seen the timer hit zero. The apology, if it happens, is a CX agent copying a template into the ticket the next morning, and the goodwill amount comes from a per-city rule that lives in a pinned message in that same WhatsApp group.
Trigger: Webhook (order-state / ETA-slip event from the order feed or rider-dispatch platform)
How the workflow runs
- Trigger
ETA slip event fires. An inbound Webhook carries the live order state — promised window, pick-start time, pack status, rider-assignment state. The order feed, POS and rider-dispatch platform have no first-party connector; the event arrives via Webhook and anything extra is read back via a Tool (MCP) node.
- Condition
Is the promise actually at risk?. A Condition node applies your own breach rule (projected delivery beyond the promised window by more than the tolerance in Knowledge) so the workflow only wakes up for orders genuinely heading for a breach — not for every normal order tick.
- Agent
Diagnose where the minutes went. An Agent node reads the timestamps and attributes the slip to a stage — pick queue depth, an item hunt, packing, or no rider assigned — and drafts the honest customer message. The remedy TIER is not the model's opinion: it calls the tenant's own SpEL formula tool.
- Tool (MCP)
Ops' own goodwill band (user-defined SpEL tool). A user-defined tool — a sandboxed SpEL expression over the tool input, not code — returns the goodwill band from the order value and minutes late. The city ops lead edits that one expression when Bengaluru's threshold differs from Indore's; no developer, no deploy, and the model can't drift from the policy because it isn't deciding it.
- Output
Tell the customer before the timer does. An Output node sends the revised ETA and a plain explanation on the customer's channel — WhatsApp or SMS, in their language via Sarvam for Indian-language customers — and offers the option to cancel while it's still cheap for everyone.
- Approval
Store manager approves any goodwill. An Approval node holds every goodwill credit, refund or cancellation-with-compensation. The agent proposes a band with its reason; the manager clicks. Money never moves on the agent's own judgement.
- Sub-workflow
Hand off to the shared credit sub-workflow. On approval a Sub-workflow node calls the one shared 'issue goodwill credit' flow used by every other CX recipe — so the credit ledger write, the Razorpay UPI refund path and the audit trail exist in exactly one place, not copy-pasted into five workflows.
- Output
Nudge the floor + log the cause. A parallel Output node posts the at-risk order to the store's Slack/Telegram floor channel with the diagnosed stage, and the attributed cause is logged so the daily roll-up can show which stage is breaking promises.
Channels & connectors
- Webhook
- SMS
- Slack
- Telegram
- Sarvam (Indian languages)
- Razorpay (UPI)
- Tool (MCP → order feed / rider dispatch)
- Approval / HITL
Outcome
At-risk orders get an honest heads-up and a floor nudge while the order is still recoverable, and every rupee of goodwill is a manager's decision with the cause attached.
Why it helps
Moves the customer conversation from after-the-fact refund to before-the-breach expectation-setting, and turns each slip into an attributed data point (pick / pack / rider) instead of an anonymous late order. The compensation policy moves from a pinned WhatsApp message to a one-line SpEL expression the city ops lead owns and can change per city in seconds — the model drafts, the formula decides the band, the manager approves.
Build spec
1 agent — 1 diagnosis-and-drafting agent; the breach rule, the goodwill band (a user-defined SpEL tool, not a model call), the approval and the shared credit sub-workflow are workflow nodes. · Pattern: Event-triggered single agent behind a Condition gate → tenant-owned SpEL band → human approval → shared Sub-workflow for the money
System prompt (paste-ready)
You are a dark-store fulfilment assistant for {{store}}. Given one live order {order_id, promised_window, placed_at, pick_started_at, pick_completed_at, packed_at, rider_assigned_at, current_stage, items_count, order_value} plus the store's breach-tolerance rules from Knowledge: (1) attribute the delay to exactly ONE stage — PICK_QUEUE | ITEM_HUNT | PACKING | RIDER_UNASSIGNED | IN_TRANSIT — using only the timestamps given; if the timestamps do not support an attribution, return stage=UNKNOWN rather than guessing. (2) Compute a revised ETA only from the observed stage durations — never invent a number to sound reassuring. (3) Draft a short, non-defensive customer message stating the revised ETA and the cancel option. (4) Call the `goodwill_band` tool for the remedy band — do NOT decide the band yourself and do NOT override its answer. You PROPOSE the remedy — you never issue credit, never cancel an order, and never promise a time the stage data does not support.Agent roles & model tiers
Slip diagnostician + drafter (once per at-risk order) — Economy tier — this fires on every at-risk order across every store, so it is the volume step; the work is timestamp arithmetic plus a short message. Configure a fallback model on the same tier: this runs on the live order path, and a provider blip must degrade to a second economy model rather than leave the customer unmessaged.
Attribute the delay to one stage from timestamps only, compute a revised ETA from observed durations, draft the customer message, and call `goodwill_band` for the remedy tier. Return strict JSON {stage, revised_eta, customer_message, remedy_band, reason}. UNKNOWN is a valid stage; a guessed one is not.
MCP connectors
- Order-management / marketplace order feed — inbound via Webhook; read back via Tool (MCP): fetch order header, line items and stage timestamps by order_id
- Rider-dispatch platform — via Tool (MCP): get rider assignment state, current leg and last known ETA for the order
- Wallet / credit ledger — via Tool (MCP): post an approved goodwill credit (called only from inside the approved sub-workflow, never by the agent)
Built-in tools
- knowledge_search (scoped collection: breach tolerances + the per-city compensation matrix)
- http_request (read live order + rider state; post the approved credit)
- user-defined tool `goodwill_band` (SpEL): input.orderValue > 2000 ? 'ESCALATE' : (input.lateMinutes > 20 ? 'CREDIT_FULL' : 'CREDIT_PARTIAL') — a sandboxed expression over the tool input, so ops encodes its own thresholds and edits them per city without a developer or a deployment
- send_email (daily stage-attribution roll-up to the ops lead)
Guardrails
- Every goodwill credit, refund and compensated cancellation passes the Approval node before anything is issued — the agent only proposes a band and a reason
- The compensation band comes from the user-defined SpEL tool, not the model — the LLM cannot argue itself into a bigger credit, and ops can change the thresholds without touching the prompt
- Revised ETAs are computed from observed stage timestamps, never invented to sound better; when the data doesn't support an attribution the agent must return UNKNOWN
- One proactive message per order per stage change, keyed to the order id — a re-fired webhook cannot spam the customer or double-issue a credit
- Customer-language replies go through Sarvam for Indian languages rather than defaulting to English on a bad-news message
Cost strategy
This is the highest-volume workflow in the store, so it sits on the economy tier by design: one short, structured call per AT-RISK order — and the Condition gate is what keeps 'at-risk' from meaning 'every order'. Tighten the breach tolerance first and the model bill follows. The goodwill band costs nothing at all: a SpEL expression is evaluated in-process, so the most policy-sensitive decision in the flow is also the only free one. Reserve standard-tier spend for the end-of-day roll-up that reads the attributed causes in bulk.
Output & delivery
The Condition gate admits only genuinely at-risk orders → the agent attributes the stage and drafts the message → the `goodwill_band` SpEL tool returns the band from ops' own thresholds → an Output node sends the revised ETA on WhatsApp/SMS (Sarvam-localised) and posts the order to the floor channel → the manager approves at the Approval node → a Sub-workflow node runs the shared credit flow, which is the only place that ever touches the ledger or the UPI refund path.