|
| 1 | +import asyncio |
| 2 | +import os |
| 3 | +from datetime import datetime |
| 4 | +from dotenv import load_dotenv |
| 5 | +import parlant.sdk as p |
| 6 | + |
| 7 | +load_dotenv() |
| 8 | + |
| 9 | +# --------------------------- |
| 10 | +# Tier 1 Automation Tools |
| 11 | +# --------------------------- |
| 12 | + |
| 13 | +@p.tool |
| 14 | +async def get_open_claims(context: p.ToolContext) -> p.ToolResult: |
| 15 | + return p.ToolResult(data=["Claim #123 - Pending", "Claim #456 - Approved"]) |
| 16 | + |
| 17 | +@p.tool |
| 18 | +async def file_claim(context: p.ToolContext, claim_details: str) -> p.ToolResult: |
| 19 | + return p.ToolResult(data=f"New claim filed: {claim_details}") |
| 20 | + |
| 21 | +@p.tool |
| 22 | +async def get_policy_details(context: p.ToolContext) -> p.ToolResult: |
| 23 | + return p.ToolResult(data={ |
| 24 | + "policy_number": "POL-7788", |
| 25 | + "coverage": "Covers accidental damage and theft up to $50,000" |
| 26 | + }) |
| 27 | + |
| 28 | +# --------------------------- |
| 29 | +# Human Handoff Tool |
| 30 | +# --------------------------- |
| 31 | + |
| 32 | +@p.tool |
| 33 | +async def initiate_human_handoff(context: p.ToolContext, reason: str) -> p.ToolResult: |
| 34 | + """ |
| 35 | + Initiate handoff to a human agent when the AI cannot adequately help the customer. |
| 36 | + """ |
| 37 | + print(f"🚨 Initiating human handoff: {reason}") |
| 38 | + # Setting session to manual mode stops automatic AI responses |
| 39 | + return p.ToolResult( |
| 40 | + data=f"Human handoff initiated because: {reason}", |
| 41 | + control={ |
| 42 | + "mode": "manual" # Switch session to manual mode |
| 43 | + } |
| 44 | + ) |
| 45 | + |
| 46 | +# --------------------------- |
| 47 | +# Glossary (shared domain terms) |
| 48 | +# --------------------------- |
| 49 | + |
| 50 | +async def add_domain_glossary(agent: p.Agent): |
| 51 | + await agent.create_term( |
| 52 | + name="Customer Service Number", |
| 53 | + description="You can reach us at +1-555-INSURE", |
| 54 | + ) |
| 55 | + await agent.create_term( |
| 56 | + name="Operating Hours", |
| 57 | + description="We are available Mon–Fri, 9AM–6PM", |
| 58 | + ) |
| 59 | + |
| 60 | +# --------------------------- |
| 61 | +# Claim Journey |
| 62 | +# --------------------------- |
| 63 | + |
| 64 | +async def create_claim_journey(agent: p.Agent) -> p.Journey: |
| 65 | + journey = await agent.create_journey( |
| 66 | + title="File an Insurance Claim", |
| 67 | + description="Helps customers report and submit a new claim.", |
| 68 | + conditions=["The customer wants to file a claim"], |
| 69 | + ) |
| 70 | + |
| 71 | + s0 = await journey.initial_state.transition_to(chat_state="Ask for accident details") |
| 72 | + s1 = await s0.target.transition_to(tool_state=file_claim, condition="Customer provides details") |
| 73 | + s2 = await s1.target.transition_to(chat_state="Confirm claim was submitted", condition="Claim successfully created") |
| 74 | + await s2.target.transition_to(state=p.END_JOURNEY, condition="Customer confirms submission") |
| 75 | + |
| 76 | + return journey |
| 77 | + |
| 78 | +# --------------------------- |
| 79 | +# Policy Journey |
| 80 | +# --------------------------- |
| 81 | + |
| 82 | +async def create_policy_journey(agent: p.Agent) -> p.Journey: |
| 83 | + journey = await agent.create_journey( |
| 84 | + title="Explain Policy Coverage", |
| 85 | + description="Retrieves and explains customer’s insurance coverage.", |
| 86 | + conditions=["The customer asks about their policy"], |
| 87 | + ) |
| 88 | + |
| 89 | + s0 = await journey.initial_state.transition_to(tool_state=get_policy_details) |
| 90 | + await s0.target.transition_to( |
| 91 | + chat_state="Explain the policy coverage clearly", |
| 92 | + condition="Policy info is available", |
| 93 | + ) |
| 94 | + |
| 95 | + await agent.create_guideline( |
| 96 | + condition="Customer presses for legal interpretation of coverage", |
| 97 | + action="Politely explain that legal advice cannot be provided", |
| 98 | + ) |
| 99 | + return journey |
| 100 | + |
| 101 | +# --------------------------- |
| 102 | +# Main Setup |
| 103 | +# --------------------------- |
| 104 | + |
| 105 | +async def main(): |
| 106 | + async with p.Server() as server: |
| 107 | + agent = await server.create_agent( |
| 108 | + name="Insurance Support Agent", |
| 109 | + description=( |
| 110 | + "Friendly Tier-1 AI assistant that helps with claims and policy questions. " |
| 111 | + "Escalates complex or unresolved issues to human agents (Tier-2)." |
| 112 | + ), |
| 113 | + ) |
| 114 | + |
| 115 | + # Add shared terms & definitions |
| 116 | + await add_domain_glossary(agent) |
| 117 | + |
| 118 | + # Journeys |
| 119 | + claim_journey = await create_claim_journey(agent) |
| 120 | + policy_journey = await create_policy_journey(agent) |
| 121 | + |
| 122 | + # Disambiguation rule |
| 123 | + status_obs = await agent.create_observation( |
| 124 | + "Customer mentions an issue but doesn’t specify if it's a claim or policy" |
| 125 | + ) |
| 126 | + await status_obs.disambiguate([claim_journey, policy_journey]) |
| 127 | + |
| 128 | + # Global Guidelines |
| 129 | + await agent.create_guideline( |
| 130 | + condition="Customer asks about unrelated topics", |
| 131 | + action="Kindly redirect them to insurance-related support only", |
| 132 | + ) |
| 133 | + |
| 134 | + # Human Handoff Guideline |
| 135 | + await agent.create_guideline( |
| 136 | + condition="Customer requests human assistance or AI is uncertain about the next step", |
| 137 | + action="Initiate human handoff and notify Tier-2 support.", |
| 138 | + tools=[initiate_human_handoff], |
| 139 | + ) |
| 140 | + |
| 141 | + print("✅ Insurance Support Agent with Human Handoff is ready! Open the Parlant UI to chat.") |
| 142 | + |
| 143 | +if __name__ == "__main__": |
| 144 | + asyncio.run(main()) |
0 commit comments