AI Voice Agents for Hyperlocal Services

Build production-ready voice agents for food delivery, grocery, pharmacy, and quick commerce. Low-latency order confirmation, delivery slot booking, and real-time updates with regional language support.

AI Voice Agents for Hyperlocal Services

Hyperlocal services demand instant responses and real-time coordination. Voice agents excel at order confirmation, delivery scheduling, and customer availability checks - tasks that require immediate action and clear communication.

Why Voice Agents for Hyperlocal

Challenge Voice Agent Solution
High call volumes during peak hours Unlimited concurrent calls
Customer unavailable for delivery Proactive availability checks
Order confirmation delays Instant automated confirmation
Language barriers Regional language support (Hindi, Tamil, etc.)
Delivery slot coordination Real-time slot booking
Feedback collection at scale Post-delivery automated surveys

Use Cases

1. Order Confirmation Calls

Confirm orders immediately after placement to reduce cancellations:

Agent: "Namaste! Aapka order confirm ho gaya hai - 2 burgers aur 1
        coke, total 450 rupees. Delivery 30 minutes mein hogi.
        Kya yeh sahi hai?"
Customer: "Haan, theek hai"
Agent: "Perfect! Aapko delivery se pehle call karenge. Dhanyavaad!"

2. Delivery Slot Booking

Schedule deliveries based on customer availability:

Agent: "Aapka grocery order ready hai. Delivery ke liye kaunsa
        time slot prefer karenge - 10 se 12, 2 se 4, ya 6 se 8?"
Customer: "6 se 8 evening mein"
Agent: "Done! 6 se 8 baje ke beech delivery ho jayegi."

3. Customer Availability Check

Reduce failed deliveries by confirming availability:

Agent: "Aapka order 15 minutes mein pahunch raha hai. Kya aap
        delivery lene ke liye available hain?"
Customer: "Haan, main ghar pe hun"
Agent: "Bahut accha! Delivery executive aapko pahunchne se
        pehle call karenge."

4. Real-time Updates

Proactive updates for delays or issues:

Agent: "Aapke order mein thoda delay ho raha hai traffic ki
        wajah se. New ETA 45 minutes hai. Kya aap wait kar
        sakte hain ya cancel karna chahenge?"

5. Feedback Collection

Post-delivery satisfaction surveys:

Agent: "Aapka order deliver ho gaya. 1 se 5 mein rating dein -
        1 poor, 5 excellent."
Customer: "4"
Agent: "Dhanyavaad! Koi feedback ya complaint?"
Customer: "Food thanda tha"
Agent: "Sorry about that. Aapko next order pe 50 rupees off
        milega. Thank you!"

Agent Configuration

Optimized for quick commerce where every second counts:

{
  "agent": {
    "name": "Quick Delivery Agent",
    "language": "hi-IN",

    "llmProvider": "gemini-2.5",
    "llmModel": "gemini-2.5-flash-lite",
    "llmTemperature": 0.3,
    "llmMaxTokens": 150,

    "sttProvider": "deepgram",
    "sttModel": "nova-3",
    "sttConfig": {
      "language": "hi",
      "endpointing": 200,
      "interimResults": true,
      "keywords": ["haan:2", "nahi:2", "cancel:2", "order:2"]
    },

    "ttsProvider": "azure",
    "ttsVoice": "hi-IN-SwaraNeural",
    "ttsConfig": {
      "speakingRate": 1.1
    },

    "vadConfig": {
      "threshold": 0.6,
      "minSilenceDurationMs": 150,
      "volumeThreshold": 0.02
    },

    "allowInterruptions": true,
    "maxCallDuration": 120,

    "greetingMessage": "Namaste! {{businessName}} se bol raha hun. Aapka order {{orderId}} ke baare mein call hai.",

    "prompt": "..."
  }
}

Configuration Breakdown

Setting Value Reason
llmTemperature: 0.3 Low creativity Consistent, predictable responses
llmMaxTokens: 150 Short responses Faster TTS, natural conversation
endpointing: 200 200ms silence Quick turn detection
speakingRate: 1.1 Slightly faster Match hyperlocal urgency
maxCallDuration: 120 2 minutes Keep calls focused

System Prompts

Food Delivery Agent

You are a food delivery confirmation agent for {{businessName}}.

## Your Tasks
1. Confirm order details with the customer
2. Verify delivery address
3. Provide accurate ETA
4. Handle modifications or cancellations
5. Note special delivery instructions

## Response Guidelines
- Keep responses under 2 sentences
- Speak in Hinglish (Hindi-English mix)
- Use informal, friendly tone
- Always confirm understanding with "theek hai?" or "sahi?"

## Order Details Available
- Order ID: {{orderId}}
- Items: {{orderItems}}
- Total: {{orderTotal}}
- Address: {{deliveryAddress}}
- ETA: {{estimatedTime}} minutes

## Conversation Flow

### Confirmation Call
1. Greet and state purpose
2. Read order summary
3. Confirm total amount
4. Verify address landmark
5. Give ETA
6. Ask for special instructions
7. Thank and end

### If Customer Wants to Modify
Use modify_order tool. Say "Ek minute, main update kar raha hun."

### If Customer Wants to Cancel
Use cancel_order tool. Confirm cancellation reason.
Say "Aapka order cancel ho gaya. Refund 24 hours mein ho jayega."

### If Customer Unavailable
Ask for alternate contact or preferred callback time.
Use reschedule_delivery tool.

## Sample Responses
- "Aapka order mein 2 veg biryani aur 1 raita hai, total 380 rupees."
- "Delivery 25 minutes mein ho jayegi. Address sahi hai - Sector 15, C block?"
- "Main delivery executive ko bolunga gate pe call kare."

Grocery Delivery Agent

You are a grocery delivery scheduling agent for {{businessName}}.

## Your Tasks
1. Confirm order and payment
2. Book delivery time slot
3. Verify availability of items
4. Handle substitutions
5. Confirm delivery instructions

## Available Time Slots
{{availableSlots}}

## Order Details
- Order ID: {{orderId}}
- Items: {{itemCount}} items
- Total: {{orderTotal}}
- Payment: {{paymentStatus}}

## Guidelines
- Be concise - grocery calls should be under 90 seconds
- Offer alternatives for out-of-stock items
- Always confirm the final slot

## Slot Booking Flow
1. "Delivery ke liye kaunsa slot chahiye?"
2. Read available slots
3. Confirm selected slot
4. Mention delivery window (2-hour slots)

## If Item Unavailable
1. Inform customer
2. Suggest alternative: "Amul butter nahi hai, should I add Britannia?"
3. Use update_order tool for substitutions
4. Adjust total if price differs

## Sample Responses
- "Aaj ke liye 3 slots available hain - 10-12, 2-4, ya 6-8 baje."
- "6-8 baje ka slot book ho gaya. Exact time delivery boy batayega."
- "Tata Salt nahi hai, Catch salt add kar dun? Same price hai."

Pharmacy Delivery Agent

You are a pharmacy delivery agent for {{businessName}}.

## Critical Guidelines
- NEVER provide medical advice
- Always verify prescription requirements
- Maintain patient confidentiality
- Confirm exact medicine names and dosages

## Order Details
- Order ID: {{orderId}}
- Prescription Required: {{prescriptionRequired}}
- Items: {{medicines}}
- Total: {{orderTotal}}

## Prescription Handling
If prescription required and not uploaded:
"Prescription upload nahi hui hai. Delivery ke time dikha sakte hain,
ya abhi WhatsApp kar dijiye 98XXXXXXXX pe."

## Medicine Name Verification
Always spell out medicine names:
"Aapke order mein D-O-L-O 650 - 2 strips, aur C-R-O-C-I-N Advance
1 strip hai. Yeh sahi hai?"

## Substitution Policy
- Generic substitution only with explicit consent
- "Original brand nahi hai. Generic version half price mein available hai."
- Use substitute_medicine tool

## Sensitive Information
- Don't mention medicine names loudly if customer seems in public
- Offer to send details on WhatsApp instead

## Sample Responses
- "Aapki medicines delivery ke liye ready hain. Prescription original dikhani hogi."
- "Cash on delivery hai, total 450 rupees exact rakhna."
- "Evening 6-8 baje delivery ho jayegi. Koi aur help chahiye?"

Tools for Hyperlocal Operations

Order Management Tools

{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "confirm_order",
        "description": "Confirm order after customer verification",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": {
              "type": "string",
              "description": "Order ID to confirm"
            },
            "special_instructions": {
              "type": "string",
              "description": "Any delivery instructions from customer"
            }
          },
          "required": ["order_id"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "modify_order",
        "description": "Modify items in the order",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string" },
            "action": {
              "type": "string",
              "enum": ["add_item", "remove_item", "change_quantity"]
            },
            "item_name": { "type": "string" },
            "quantity": { "type": "integer" }
          },
          "required": ["order_id", "action", "item_name"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "cancel_order",
        "description": "Cancel the order with reason",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string" },
            "reason": {
              "type": "string",
              "enum": ["customer_request", "item_unavailable", "wrong_order", "too_late", "other"]
            },
            "refund_method": {
              "type": "string",
              "enum": ["original", "wallet", "coupon"]
            }
          },
          "required": ["order_id", "reason"]
        }
      }
    }
  ]
}

Delivery Management Tools

{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "book_delivery_slot",
        "description": "Book a delivery time slot",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string" },
            "slot_id": { "type": "string" },
            "date": {
              "type": "string",
              "description": "Delivery date (YYYY-MM-DD)"
            }
          },
          "required": ["order_id", "slot_id"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "check_customer_availability",
        "description": "Record customer availability status",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string" },
            "is_available": { "type": "boolean" },
            "alternate_contact": { "type": "string" },
            "leave_at_door": { "type": "boolean" }
          },
          "required": ["order_id", "is_available"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "reschedule_delivery",
        "description": "Reschedule delivery to a new time",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string" },
            "new_slot": { "type": "string" },
            "new_date": { "type": "string" },
            "reason": { "type": "string" }
          },
          "required": ["order_id", "new_slot"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "update_delivery_instructions",
        "description": "Add special delivery instructions",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string" },
            "instructions": { "type": "string" },
            "landmark": { "type": "string" },
            "gate_code": { "type": "string" }
          },
          "required": ["order_id", "instructions"]
        }
      }
    }
  ]
}

Feedback Collection Tools

{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "record_feedback",
        "description": "Record customer feedback after delivery",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string" },
            "overall_rating": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5
            },
            "delivery_rating": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5
            },
            "food_quality_rating": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5
            },
            "comments": { "type": "string" },
            "issues": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["late_delivery", "wrong_items", "cold_food", "missing_items", "rude_delivery", "packaging"]
              }
            }
          },
          "required": ["order_id", "overall_rating"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "issue_compensation",
        "description": "Issue compensation for service issues",
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string" },
            "compensation_type": {
              "type": "string",
              "enum": ["refund", "coupon", "free_delivery", "discount"]
            },
            "amount": { "type": "number" },
            "reason": { "type": "string" }
          },
          "required": ["order_id", "compensation_type", "amount"]
        }
      }
    }
  ]
}

Tool Handler Implementations

package handlers

import (
    "context"
    "fmt"
    "time"
)

type HyperlocalToolHandler struct {
    orderService    OrderService
    deliveryService DeliveryService
    feedbackService FeedbackService
}

func (h *HyperlocalToolHandler) ConfirmOrder(ctx context.Context, args map[string]any) (string, error) {
    orderID := args["order_id"].(string)
    instructions := ""
    if v, ok := args["special_instructions"].(string); ok {
        instructions = v
    }

    order, err := h.orderService.Confirm(ctx, orderID, instructions)
    if err != nil {
        return "Order confirm nahi ho paya. Please try again.", nil
    }

    return fmt.Sprintf(
        "Order %s confirmed. ETA %d minutes. Delivery address: %s",
        order.ID,
        order.ETAMinutes,
        order.Address,
    ), nil
}

func (h *HyperlocalToolHandler) BookDeliverySlot(ctx context.Context, args map[string]any) (string, error) {
    orderID := args["order_id"].(string)
    slotID := args["slot_id"].(string)

    slot, err := h.deliveryService.BookSlot(ctx, orderID, slotID)
    if err != nil {
        if err == ErrSlotUnavailable {
            return "Yeh slot ab available nahi hai. Doosra slot choose karein.", nil
        }
        return "Slot book nahi ho paya. Please try again.", nil
    }

    return fmt.Sprintf(
        "Slot booked: %s to %s on %s. Delivery person call karega pahunchne se pehle.",
        slot.StartTime.Format("3:04 PM"),
        slot.EndTime.Format("3:04 PM"),
        slot.Date.Format("Monday"),
    ), nil
}

func (h *HyperlocalToolHandler) CheckAvailability(ctx context.Context, args map[string]any) (string, error) {
    orderID := args["order_id"].(string)
    isAvailable := args["is_available"].(bool)

    if isAvailable {
        h.deliveryService.MarkAvailable(ctx, orderID)
        return "Customer available. Delivery proceed karein.", nil
    }

    // Customer not available
    if altContact, ok := args["alternate_contact"].(string); ok {
        h.deliveryService.SetAlternateContact(ctx, orderID, altContact)
        return fmt.Sprintf("Alternate contact saved: %s", altContact), nil
    }

    if leaveAtDoor, ok := args["leave_at_door"].(bool); ok && leaveAtDoor {
        h.deliveryService.SetLeaveAtDoor(ctx, orderID)
        return "Door pe rakhne ka instruction save ho gaya.", nil
    }

    return "Customer unavailable. Reschedule needed.", nil
}

func (h *HyperlocalToolHandler) RecordFeedback(ctx context.Context, args map[string]any) (string, error) {
    orderID := args["order_id"].(string)
    rating := int(args["overall_rating"].(float64))

    feedback := Feedback{
        OrderID:       orderID,
        OverallRating: rating,
        Timestamp:     time.Now(),
    }

    if comments, ok := args["comments"].(string); ok {
        feedback.Comments = comments
    }

    if issues, ok := args["issues"].([]any); ok {
        for _, issue := range issues {
            feedback.Issues = append(feedback.Issues, issue.(string))
        }
    }

    err := h.feedbackService.Save(ctx, feedback)
    if err != nil {
        return "Feedback save nahi ho paya.", nil
    }

    if rating <= 2 && len(feedback.Issues) > 0 {
        // Auto-escalate low ratings
        h.feedbackService.Escalate(ctx, feedback)
        return "Feedback recorded. Humari team aapko contact karegi.", nil
    }

    return "Feedback recorded. Thank you!", nil
}

Low-Latency Requirements

Hyperlocal operations demand the fastest possible response times:

Latency Budget for Hyperlocal

Target: 400ms end-to-end

Component Breakdown:
├── VAD (End of Speech)      ─── 40ms   (aggressive threshold)
├── STT (Final Transcript)   ─── 100ms  (Deepgram Nova-3)
├── LLM (First Token)        ─── 120ms  (Gemini 2.5 Flash-Lite)
├── TTS (First Chunk)        ─── 60ms   (Azure Neural)
├── Network Overhead         ─── 30ms   (regional deployment)
└── Buffer                   ─── 50ms
                                ─────────
                                400ms

Optimized Provider Selection

Component Provider Latency Why
STT Deepgram Nova-3 ~100ms Fastest streaming, good Hindi
LLM Gemini 2.5 Flash-Lite ~120ms Lowest latency, excellent Hindi
TTS Azure Neural ~60ms Fast streaming, natural Hindi

VAD Configuration for Quick Responses

// Aggressive VAD for hyperlocal
vadConfig := VADConfig{
    Threshold:            0.6,   // Lower = more sensitive
    MinSilenceDurationMs: 150,   // Quick end detection
    VolumeThreshold:      0.02,  // Filter ambient noise
    PaddingMs:            50,    // Minimal padding
}

Connection Pooling

// Pre-warm connections for instant responses
type HyperlocalPool struct {
    sttPool *ConnectionPool
    llmPool *ConnectionPool
    ttsPool *ConnectionPool
}

func (p *HyperlocalPool) WarmUp() {
    // Keep 20 warm connections during peak hours
    p.sttPool.PreConnect(20)
    p.llmPool.PreConnect(20)
    p.ttsPool.PreConnect(20)
}

// Scale based on time of day
func (p *HyperlocalPool) ScaleForPeakHours(hour int) {
    // Lunch (12-2 PM) and Dinner (7-10 PM) peaks
    if (hour >= 12 && hour <= 14) || (hour >= 19 && hour <= 22) {
        p.SetPoolSize(50) // 2.5x capacity
    } else {
        p.SetPoolSize(20)
    }
}

Greeting Caching

Pre-generate greetings for common scenarios:

func cacheHyperlocalGreetings(agent *Agent) {
    greetings := map[string]string{
        "order_confirm": "Namaste! Aapka order confirm karne ke liye call hai.",
        "delivery_check": "Namaste! Aapki delivery 10 minutes mein aa rahi hai.",
        "feedback":       "Namaste! Aapka order deliver ho gaya. Quick feedback chahiye.",
    }

    for key, text := range greetings {
        audio := tts.Synthesize(text, agent.TTSConfig)
        cache.Set(fmt.Sprintf("greeting:%s:%s", agent.ID, key), audio, 24*time.Hour)
    }
}

Regional Language Support

Hindi (Primary)

{
  "language": "hi-IN",
  "sttProvider": "deepgram",
  "sttConfig": {
    "language": "hi",
    "model": "nova-3"
  },
  "ttsProvider": "azure",
  "ttsVoice": "hi-IN-SwaraNeural"
}

Hinglish (Most Common)

{
  "language": "hi-IN",
  "prompt": "Respond in Hinglish as spoken in urban India. Mix Hindi and English naturally.\n\nExamples:\n- 'Aapka order confirm ho gaya hai'\n- 'Delivery 30 minutes mein hogi'\n- 'Total amount 450 rupees hai'\n- 'Cash on delivery ya online payment?'"
}

Tamil

{
  "language": "ta-IN",
  "sttProvider": "google",
  "sttConfig": {
    "model": "chirp_2"
  },
  "ttsProvider": "azure",
  "ttsVoice": "ta-IN-PallaviNeural"
}

Telugu

{
  "language": "te-IN",
  "sttProvider": "google",
  "sttConfig": {
    "model": "chirp_2"
  },
  "ttsProvider": "azure",
  "ttsVoice": "te-IN-ShrutiNeural"
}

Multi-language Agent

{
  "agent": {
    "name": "Multi-Language Delivery Agent",
    "primaryLanguage": "hi-IN",
    "supportedLanguages": ["hi-IN", "en-IN", "ta-IN", "te-IN"],

    "prompt": "Detect the customer's language from their first response and continue in that language.\n\nLanguage detection:\n- Hindi/Hinglish: 'haan', 'nahi', 'theek hai'\n- English: 'yes', 'no', 'okay'\n- Tamil: 'aamam', 'illai'\n- Telugu: 'avunu', 'kaadu'\n\nSwitch language mid-call if customer switches.",

    "languageConfig": {
      "hi-IN": {
        "greeting": "Namaste!",
        "confirmation": "Theek hai, confirm ho gaya."
      },
      "en-IN": {
        "greeting": "Hello!",
        "confirmation": "Okay, confirmed."
      },
      "ta-IN": {
        "greeting": "Vanakkam!",
        "confirmation": "Sari, confirm aayiduchu."
      }
    }
  }
}

Metrics and Analytics

Key Performance Indicators

type HyperlocalMetrics struct {
    // Call Metrics
    TotalCalls           int
    SuccessfulCalls      int
    FailedCalls          int
    AverageCallDuration  time.Duration

    // Order Metrics
    OrderConfirmationRate float64 // Target: >95%
    CancellationRate      float64 // Target: <5%
    ModificationRate      float64

    // Delivery Metrics
    SlotBookingRate       float64 // Target: >90%
    AvailabilityCheckRate float64
    DeliverySuccessRate   float64 // Target: >98%
    RescheduleRate        float64

    // Customer Satisfaction
    AverageFeedbackRating float64 // Target: >4.2
    NPSScore              int
    ComplaintRate         float64 // Target: <2%
}

Tracking Implementation

func trackHyperlocalCall(call *Call, outcome *CallOutcome) {
    // Basic metrics
    metrics.Increment("hyperlocal.calls.total")
    metrics.Histogram("hyperlocal.calls.duration", call.Duration.Seconds())

    // Order confirmation
    if outcome.OrderConfirmed {
        metrics.Increment("hyperlocal.orders.confirmed")
    } else if outcome.OrderCancelled {
        metrics.Increment("hyperlocal.orders.cancelled")
        metrics.IncrementTagged("hyperlocal.cancellation.reason", outcome.CancellationReason)
    }

    // Slot booking
    if outcome.SlotBooked {
        metrics.Increment("hyperlocal.slots.booked")
        metrics.IncrementTagged("hyperlocal.slots.preference", outcome.SlotTime)
    }

    // Availability
    if outcome.AvailabilityChecked {
        if outcome.CustomerAvailable {
            metrics.Increment("hyperlocal.availability.available")
        } else {
            metrics.Increment("hyperlocal.availability.unavailable")
            if outcome.AlternateArranged {
                metrics.Increment("hyperlocal.availability.alternate_arranged")
            }
        }
    }

    // Latency tracking
    metrics.Histogram("hyperlocal.latency.e2e", outcome.AverageE2ELatency.Milliseconds())
    metrics.Histogram("hyperlocal.latency.first_response", outcome.FirstResponseLatency.Milliseconds())
}

Dashboard Queries

-- Order Confirmation Rate by Hour
SELECT
    DATE_TRUNC('hour', created_at) as hour,
    COUNT(*) FILTER (WHERE outcome = 'confirmed') * 100.0 / COUNT(*) as confirmation_rate
FROM hyperlocal_calls
WHERE call_type = 'order_confirmation'
    AND created_at > NOW() - INTERVAL '24 hours'
GROUP BY 1
ORDER BY 1;

-- Delivery Success by Slot
SELECT
    slot_time,
    COUNT(*) FILTER (WHERE delivery_status = 'delivered') * 100.0 / COUNT(*) as success_rate,
    AVG(delivery_attempts) as avg_attempts
FROM deliveries
WHERE created_at > NOW() - INTERVAL '7 days'
GROUP BY 1
ORDER BY success_rate DESC;

-- Customer Availability Patterns
SELECT
    EXTRACT(HOUR FROM call_time) as hour,
    COUNT(*) FILTER (WHERE customer_available) * 100.0 / COUNT(*) as availability_rate
FROM availability_checks
WHERE call_date > NOW() - INTERVAL '30 days'
GROUP BY 1
ORDER BY 1;

Alerting Rules

type HyperlocalAlerts struct{}

func (a *HyperlocalAlerts) Configure() []Alert {
    return []Alert{
        {
            Name:      "Low Order Confirmation Rate",
            Metric:    "hyperlocal.confirmation_rate",
            Threshold: 90.0,
            Operator:  "lt",
            Window:    15 * time.Minute,
            Severity:  "high",
        },
        {
            Name:      "High Cancellation Rate",
            Metric:    "hyperlocal.cancellation_rate",
            Threshold: 10.0,
            Operator:  "gt",
            Window:    30 * time.Minute,
            Severity:  "medium",
        },
        {
            Name:      "E2E Latency Spike",
            Metric:    "hyperlocal.latency.e2e.p95",
            Threshold: 800.0, // ms
            Operator:  "gt",
            Window:    5 * time.Minute,
            Severity:  "high",
        },
        {
            Name:      "Low Customer Availability",
            Metric:    "hyperlocal.availability.rate",
            Threshold: 60.0,
            Operator:  "lt",
            Window:    60 * time.Minute,
            Severity:  "medium",
        },
    }
}

Outbound Call Automation

Triggering Calls from Order Events

// Order confirmation call
func onOrderPlaced(order *Order) {
    if order.RequiresConfirmation {
        callService.TriggerCall(CallRequest{
            AgentID:   "order_confirmation_agent",
            To:        order.CustomerPhone,
            Variables: map[string]string{
                "orderId":         order.ID,
                "orderItems":      formatItems(order.Items),
                "orderTotal":      fmt.Sprintf("%.0f rupees", order.Total),
                "deliveryAddress": order.Address,
                "estimatedTime":   fmt.Sprintf("%d", order.ETAMinutes),
                "businessName":    order.MerchantName,
            },
            MaxRetries: 3,
            RetryDelay: 5 * time.Minute,
        })
    }
}

// Pre-delivery availability check
func onOutForDelivery(delivery *Delivery) {
    callService.TriggerCall(CallRequest{
        AgentID:   "availability_check_agent",
        To:        delivery.CustomerPhone,
        Variables: map[string]string{
            "orderId":      delivery.OrderID,
            "etaMinutes":   fmt.Sprintf("%d", delivery.ETAMinutes),
            "driverName":   delivery.DriverName,
            "driverPhone":  delivery.DriverPhone,
        },
        Priority: "high",
        Timeout:  2 * time.Minute,
    })
}

// Post-delivery feedback
func onDeliveryCompleted(delivery *Delivery) {
    // Wait 30 minutes after delivery
    scheduler.Schedule(30*time.Minute, func() {
        callService.TriggerCall(CallRequest{
            AgentID:   "feedback_collection_agent",
            To:        delivery.CustomerPhone,
            Variables: map[string]string{
                "orderId":      delivery.OrderID,
                "merchantName": delivery.MerchantName,
            },
            MaxRetries: 2,
            RetryDelay: 2 * time.Hour,
        })
    })
}

API Integration

# Trigger order confirmation call
curl -X POST https://voice-agent.edesy.in/api/v1/calls \
  -H "Authorization: Bearer $API_KEY" \
  -d '{
    "agent_id": "hyperlocal_order_agent",
    "to": "+919876543210",
    "variables": {
      "orderId": "ORD-2024-001234",
      "orderItems": "2x Veg Biryani, 1x Raita",
      "orderTotal": "380 rupees",
      "estimatedTime": "30",
      "businessName": "Paradise Biryani"
    },
    "priority": "high",
    "callback_url": "https://your-server.com/webhook/call-result"
  }'

Cost Optimization

Provider Costs (Per Minute, INR)

Component Budget Option Premium Option
STT Deepgram: ₹0.35 Google Chirp: ₹1.34
LLM Gemini 2.5 FL: ₹0.04 GPT-4o-mini: ₹0.08
TTS Google: ₹0.42 Azure Neural: ₹1.01
Telephony Exotel: ₹0.50 Twilio: ₹1.00
Total ₹1.31/min ₹3.43/min
{
  "production": {
    "sttProvider": "deepgram",
    "llmProvider": "gemini-2.5",
    "ttsProvider": "azure",
    "telephony": "exotel",
    "costPerMinute": "₹1.90"
  }
}

Next Steps