|
| 1 | +"""Realtime agent definitions shared by the Twilio SIP example.""" |
| 2 | + |
| 3 | +from __future__ import annotations |
| 4 | + |
| 5 | +import asyncio |
| 6 | + |
| 7 | +from agents import function_tool |
| 8 | +from agents.extensions.handoff_prompt import RECOMMENDED_PROMPT_PREFIX |
| 9 | +from agents.realtime import RealtimeAgent, realtime_handoff |
| 10 | + |
| 11 | +# --- Tools ----------------------------------------------------------------- |
| 12 | + |
| 13 | + |
| 14 | +WELCOME_MESSAGE = "Hello, this is ABC customer service. How can I help you today?" |
| 15 | + |
| 16 | + |
| 17 | +@function_tool( |
| 18 | + name_override="faq_lookup_tool", description_override="Lookup frequently asked questions." |
| 19 | +) |
| 20 | +async def faq_lookup_tool(question: str) -> str: |
| 21 | + """Fetch FAQ answers for the caller.""" |
| 22 | + |
| 23 | + await asyncio.sleep(3) |
| 24 | + |
| 25 | + q = question.lower() |
| 26 | + if "plan" in q or "wifi" in q or "wi-fi" in q: |
| 27 | + return "We provide complimentary Wi-Fi. Join the ABC-Customer network." # demo data |
| 28 | + if "billing" in q or "invoice" in q: |
| 29 | + return "Your latest invoice is available in the ABC portal under Billing > History." |
| 30 | + if "hours" in q or "support" in q: |
| 31 | + return "Human support agents are available 24/7; transfer to the specialist if needed." |
| 32 | + return "I'm not sure about that. Let me transfer you back to the triage agent." |
| 33 | + |
| 34 | + |
| 35 | +@function_tool |
| 36 | +async def update_customer_record(customer_id: str, note: str) -> str: |
| 37 | + """Record a short note about the caller.""" |
| 38 | + |
| 39 | + await asyncio.sleep(1) |
| 40 | + return f"Recorded note for {customer_id}: {note}" |
| 41 | + |
| 42 | + |
| 43 | +# --- Agents ---------------------------------------------------------------- |
| 44 | + |
| 45 | + |
| 46 | +faq_agent = RealtimeAgent( |
| 47 | + name="FAQ Agent", |
| 48 | + handoff_description="Handles frequently asked questions and general account inquiries.", |
| 49 | + instructions=f"""{RECOMMENDED_PROMPT_PREFIX} |
| 50 | + You are an FAQ specialist. Always rely on the faq_lookup_tool for answers and keep replies |
| 51 | + concise. If the caller needs hands-on help, transfer back to the triage agent. |
| 52 | + """, |
| 53 | + tools=[faq_lookup_tool], |
| 54 | +) |
| 55 | + |
| 56 | +records_agent = RealtimeAgent( |
| 57 | + name="Records Agent", |
| 58 | + handoff_description="Updates customer records with brief notes and confirmation numbers.", |
| 59 | + instructions=f"""{RECOMMENDED_PROMPT_PREFIX} |
| 60 | + You handle structured updates. Confirm the customer's ID, capture their request in a short |
| 61 | + note, and use the update_customer_record tool. For anything outside data updates, return to the |
| 62 | + triage agent. |
| 63 | + """, |
| 64 | + tools=[update_customer_record], |
| 65 | +) |
| 66 | + |
| 67 | +triage_agent = RealtimeAgent( |
| 68 | + name="Triage Agent", |
| 69 | + handoff_description="Greets callers and routes them to the most appropriate specialist.", |
| 70 | + instructions=( |
| 71 | + f"{RECOMMENDED_PROMPT_PREFIX} " |
| 72 | + "Always begin the call by saying exactly: '" |
| 73 | + f"{WELCOME_MESSAGE}' " |
| 74 | + "before collecting details. Once the greeting is complete, gather context and hand off to " |
| 75 | + "the FAQ or Records agents when appropriate." |
| 76 | + ), |
| 77 | + handoffs=[faq_agent, realtime_handoff(records_agent)], |
| 78 | +) |
| 79 | + |
| 80 | +faq_agent.handoffs.append(triage_agent) |
| 81 | +records_agent.handoffs.append(triage_agent) |
| 82 | + |
| 83 | + |
| 84 | +def get_starting_agent() -> RealtimeAgent: |
| 85 | + """Return the agent used to start each realtime call.""" |
| 86 | + |
| 87 | + return triage_agent |
0 commit comments