Skip to content

Conversation

@badri-singhal
Copy link
Contributor

@badri-singhal badri-singhal commented Dec 26, 2025

Screenshot 2025-12-27 at 12 26 21 AM

Summary by CodeRabbit

  • New Features

    • Added webhook notifications for unanswered calls during retry attempts, including call details and attempt tracking.
  • Improvements

    • Enhanced webhook reporting to send success notifications, excluding busy call scenarios.
  • Chores

    • Removed unused type imports from codebase.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 26, 2025

Walkthrough

The changes introduce webhook notifications for no-answer call scenarios during retries, update the retry dispatcher to accept outcome parameters for external reporting, adjust webhook behavior for different call outcomes in the websocket bot, and remove unused type imports from the TTS module.

Changes

Cohort / File(s) Summary
Call retry and webhook reporting
app/ai/voice/agents/breeze_buddy/managers/calls.py
Added optional outcome parameter to _retry_call() method. Extended no-answer handling to compute call duration and send webhook notification with call metadata (callSid, outcome, attemptCount, callDuration, orderId) when reporting_webhook_url is present, with max 3 retries.
Websocket outcome handling
app/ai/voice/agents/breeze_buddy/websocket_bot.py
Simplified webhook condition logic: changed from excluding both BUSY and NO_ANSWER outcomes to excluding only BUSY, retaining last-attempt logic for webhook dispatch.
Import cleanup
app/ai/voice/tts/sarvam.py
Removed unused type imports Any and Mapping from typing module; retained Optional.

Sequence Diagram

sequenceDiagram
    participant Call as Call Handler
    participant Retry as Retry Dispatcher
    participant Lead as Lead Tracker
    participant Webhook as Webhook Service
    participant Log as Logger
    
    Call->>Retry: _retry_call(lead, config, "NO_ANSWER")
    Note over Retry: outcome = "NO_ANSWER"
    Retry->>Lead: Check reporting_webhook_url
    
    alt webhook_url present
        Retry->>Retry: Compute call duration
        Retry->>Retry: Assemble summary_data<br/>(callSid, outcome, attemptCount, etc.)
        Retry->>Webhook: Send webhook (max_retries=3)
        
        alt success
            Webhook-->>Retry: 2xx response
            Retry->>Log: Log webhook success
        else failure
            Webhook-->>Retry: error
            Retry->>Log: Log webhook failure
        end
    else no webhook_url
        Note over Retry: Skip webhook notification
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • swaroopvarma1

Poem

🐰 A retry with a note so sweet,
When calls go silent, no one speaks,
We ping the webhook, try once more—
With outcomes tracked to keep the score,
Busy calls we gently ignore! 📞✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add web-hook call when phone is not picked' directly aligns with the main objective to fix webhook calls on no-answer scenarios. It clearly summarizes the primary change across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@badri-singhal badri-singhal changed the title Fix webhook call when call is not picked Add web-hook call when phone is not picked Dec 26, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/ai/voice/agents/breeze_buddy/managers/calls.py (1)

213-248: Consider narrowing the exception handler and evaluating session reuse.

The webhook logic for NO_ANSWER on the last retry is well-implemented and aligns with the PR objective. However, there are two areas to consider:

  1. Catching blind exception: Line 247 catches Exception without specifying the exception type, which is flagged by static analysis. While this ensures the retry logic doesn't break, consider catching more specific exceptions (e.g., aiohttp.ClientError, asyncio.TimeoutError) or at minimum logging the exception type.

  2. Session reuse opportunity: This function creates a new aiohttp session at line 235. When called from process_backlog_leads, an aiohttp session already exists (line 315). Consider whether the session could be passed as a parameter to avoid creating multiple sessions, though this would require refactoring other call sites as well.

🔎 Proposed fix for the exception handler
                 except Exception as e:
-                    logger.error(f"Error sending webhook on no_answer: {e}")
+                    logger.error(f"Error sending webhook on no_answer: {e}", exc_info=True)

This at least adds the stack trace to help debug issues while maintaining the same error-handling behavior.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2ea5b06 and b9ee41a.

📒 Files selected for processing (3)
  • app/ai/voice/agents/breeze_buddy/managers/calls.py
  • app/ai/voice/agents/breeze_buddy/websocket_bot.py
  • app/ai/voice/tts/sarvam.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-10T11:55:16.753Z
Learnt from: narsimhaReddyJuspay
Repo: juspay/clairvoyance PR: 414
File: app/services/langfuse/tasks/score_monitor/score.py:469-489
Timestamp: 2025-12-10T11:55:16.753Z
Learning: In the Breeze Buddy call tracking system, a lead can only have one outcome type among CONFIRM, CANCEL, or ADDRESS_UPDATED—these outcomes are mutually exclusive per lead.

Applied to files:

  • app/ai/voice/agents/breeze_buddy/managers/calls.py
🧬 Code graph analysis (1)
app/ai/voice/agents/breeze_buddy/managers/calls.py (3)
app/schemas/breeze_buddy/core.py (2)
  • LeadCallTracker (34-57)
  • CallExecutionConfig (118-134)
app/core/transport/http_client.py (1)
  • create_aiohttp_session (58-77)
app/ai/voice/agents/breeze_buddy/utils/common.py (1)
  • send_webhook_with_retry (57-99)
🪛 Ruff (0.14.10)
app/ai/voice/agents/breeze_buddy/managers/calls.py

247-247: Do not catch blind exception: Exception

(BLE001)

🔇 Additional comments (2)
app/ai/voice/tts/sarvam.py (1)

7-7: LGTM!

Good cleanup removing unused imports while retaining the necessary Optional type.

app/ai/voice/agents/breeze_buddy/managers/calls.py (1)

186-188: LGTM!

The optional outcome parameter is a clean addition that maintains backward compatibility with existing call sites at lines 293, 629 while enabling the new NO_ANSWER webhook behavior at line 664.

Comment on lines 628 to 631
# Send webhook - skip BUSY/NO_ANSWER unless it's the last attempt
should_send_webhook = self.reporting_webhook_url and (
self.outcome not in ["BUSY", "NO_ANSWER"] or is_last_attempt
self.outcome != "BUSY" or is_last_attempt
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update the outdated comment.

The comment states "skip BUSY/NO_ANSWER" but the code only skips BUSY. NO_ANSWER now triggers webhook sending.

🔎 Proposed fix
-            # Send webhook - skip BUSY/NO_ANSWER unless it's the last attempt
+            # Send webhook - skip BUSY unless it's the last attempt
             should_send_webhook = self.reporting_webhook_url and (
                 self.outcome != "BUSY" or is_last_attempt
             )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Send webhook - skip BUSY/NO_ANSWER unless it's the last attempt
should_send_webhook = self.reporting_webhook_url and (
self.outcome not in ["BUSY", "NO_ANSWER"] or is_last_attempt
self.outcome != "BUSY" or is_last_attempt
)
# Send webhook - skip BUSY unless it's the last attempt
should_send_webhook = self.reporting_webhook_url and (
self.outcome != "BUSY" or is_last_attempt
)
🤖 Prompt for AI Agents
In app/ai/voice/agents/breeze_buddy/websocket_bot.py around lines 628 to 631,
the inline comment is inaccurate ("skip BUSY/NO_ANSWER") while the code only
skips BUSY; update the comment to reflect the actual behavior (e.g., "skip BUSY
unless it's the last attempt") so it no longer mentions NO_ANSWER, keeping the
logic unchanged.

@swaroopvarma1 swaroopvarma1 merged commit ef71043 into juspay:release Dec 27, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants