Banking Email Support Workflow
Multi-phase banking email support with strict sequential agent progression
Workflow Information
ID: banking_email_support
Namespace: default
Version: 3.3
Created: 2025-07-21
Updated: 2025-08-26
Tasks: 10
Quick Actions
Inputs
| Name | Type | Required | Default |
|---|---|---|---|
customer_quary |
string | Required | None |
Outputs
No outputs defined
Tasks
case_orchestrator
ai_agentNo description
case_number_extractor
scriptNo description
phase_router
conditional_routerNo description
Conditional Router
Router Type: condition
Default Route: continue_analysis
Default Route: continue_analysis
case_context_agent
ai_agentNo description
classification_agent
ai_agentNo description
sentiment_analysis_agent
ai_agentNo description
summary_agent
ai_agentNo description
template_router_agent
ai_agentNo description
email_generator_agent
ai_agentNo description
duplicate_end_handler
scriptNo description
YAML Source
id: banking_email_support_fixed
name: Quinte Customer Support Workflow
tasks:
- id: case_orchestrator
name: Case Orchestrator Agent - Phase 1
type: ai_agent
config:
tools:
- search_cases_by_email
- create_case
- get_case
- manage_duplicate_priority
- check_case_priority_status
- get_priority_escalation_rules
- send_duplicate_acknowledgement
user_message: 'Process this customer email for case management: ${customer_email}'
system_message: "# Case Orchestrator Agent - Phase 1: Case Detection/Creation\n\
\nYou are responsible for the FIRST PHASE of the workflow: case detection and\
\ creation/retrieval.\n\n## CRITICAL: ALWAYS END WITH EXACT CASE NUMBER EXTRACTION\n\
Your response MUST always end with ONE of these EXACT formats:\n- \"DUPLICATE_PROCESSED\
\ - Case linked to #[actual_case_number]\"\n- \"CASE_RETRIEVED_FOR_UPDATE -\
\ Case #[actual_case_number]\" \n- \"NEW_CASE_CREATED - Case #[actual_case_number]\"\
\n\n## YOUR PROCESS\n\n**Step 1: Parse Input and Detect Duplicates**\n- Extract\
\ email address from sender field\n- Check for case references in subject/body\
\ (Case #XXXXX, Re:, ticket number)\n- Use search_cases_by_email to find existing\
\ cases\n- Analyze for duplicate content and core issue similarity\n\n**Step\
\ 2: Handle Based on Detection Results**\n\n**If CASE_REFERENCE_DETECTED:**\n\
- Extract case number from subject/body\n- Use get_case to retrieve case details\n\
- **If case exists**: End with \"CASE_RETRIEVED_FOR_UPDATE - Case #[actual_case_number]\"\
\n- **If case does NOT exist**: Call create_case() to create a NEW case\n- **CRITICAL**:\
\ Extract the NEW CaseNumber from the create_case response\n- End with \"NEW_CASE_CREATED\
\ - Case #[new_case_number_from_create_response]\"\n\n**If DUPLICATE_FOUND:**\n\
- Create duplicate case with create_case (status: \"Rejected\")\n- Extract actual\
\ CaseNumber from create_case response\n- Call manage_duplicate_priority for\
\ priority escalation\n- Call send_duplicate_acknowledgement to notify customer\n\
- End with \"DUPLICATE_PROCESSED - Case linked to #[actual_case_number_from_response]\"\
\n\n**If NO_DUPLICATE and NO_CASE_REFERENCE:**\n- Create new case with create_case\n\
- Extract ACTUAL CaseNumber from the create_case response\n- End with \"NEW_CASE_CREATED\
\ - Case #[actual_case_number_from_response]\"\n\n**If TECHNICAL_ERROR (like\
\ case not found):**\n- Create a new case to ensure workflow continues\n- Extract\
\ ACTUAL CaseNumber from create_case response\n- End with \"NEW_CASE_CREATED\
\ - Case #[actual_case_number_from_response]\"\n\n## CRITICAL RULES FOR CASE\
\ NUMBER EXTRACTION\n1. **ALWAYS extract actual case numbers from tool responses**\n\
2. When you call create_case, look for \"CaseNumber\" or \"case_number\" in\
\ the response\n3. When you call get_case, look for \"CaseNumber\" in the response\n\
4. **NEVER use placeholder numbers** - always use the actual numbers returned\
\ by tools\n5. **NEVER use referenced case numbers if the case doesn't exist**\
\ - create NEW case instead\n6. **ALWAYS end with one of the three exact status\
\ phrases above with REAL case numbers**\n7. If any tool fails, create a new\
\ case to keep workflow moving\n8. Never return technical error messages - always\
\ provide a status with actual case number\n\n## EXAMPLE CORRECT PROCESSING:\n\
```\nInput: Email references \"Case #00001942\" but case doesn't exist\n\n1.\
\ Call get_case(\"00001942\") \u2192 Error: Case not found\n2. Call create_case(...)\
\ \u2192 Response: {\"CaseNumber\": \"00001994\", \"Id\": \"500XYZ\"}\n3. Extract\
\ \"00001994\" from response\n4. Output: \"NEW_CASE_CREATED - Case #00001994\"\
\n```\n\n## NEVER DO THIS:\n\u274C \"NEW_CASE_CREATED - Case #00001942\" (using\
\ non-existent case number)\n\u274C \"NEW_CASE_CREATED - Case #PLACEHOLDER\"\
\ (using placeholder)\n\n## ALWAYS DO THIS:\n\u2705 \"NEW_CASE_CREATED - Case\
\ #00001994\" (using actual number from create_case response)\n\u2705 \"CASE_RETRIEVED_FOR_UPDATE\
\ - Case #00001942\" (using actual number from get_case response)\n"
model_client_id: gpt4.1
timeout_seconds: 120
- id: case_number_extractor
name: Case Number Extraction Script
type: script
script: "import json\nimport re\n\n# Get orchestrator response\norchestrator_result\
\ = \"\"\"${case_orchestrator.ai_response}\"\"\"\n\nprint(f\"DEBUG: Orchestrator\
\ result: {orchestrator_result}\")\n\n# Extract case number using regex patterns\n\
patterns = [\n r\"DUPLICATE_PROCESSED - Case linked to #(\\d+)\",\n r\"\
CASE_RETRIEVED_FOR_UPDATE - Case #(\\d+)\",\n r\"NEW_CASE_CREATED - Case #(\\\
d+)\"\n]\n\nextracted_case_number = None\nprocessing_type = \"unknown\"\n\nfor\
\ pattern in patterns:\n match = re.search(pattern, orchestrator_result)\n\
\ if match:\n extracted_case_number = match.group(1)\n if \"\
DUPLICATE_PROCESSED\" in orchestrator_result:\n processing_type = \"\
duplicate\"\n elif \"CASE_RETRIEVED_FOR_UPDATE\" in orchestrator_result:\n\
\ processing_type = \"update\"\n elif \"NEW_CASE_CREATED\" in\
\ orchestrator_result:\n processing_type = \"new\"\n break\n\
\nif not extracted_case_number:\n # Fallback: Create a placeholder case number\
\ to prevent workflow failure\n extracted_case_number = \"EXTRACTION_FAILED\"\
\n processing_type = \"error\"\n print(f\"ERROR: Could not extract case\
\ number from: {orchestrator_result}\")\n\nprint(f\"DEBUG: Extracted case number:\
\ {extracted_case_number}\")\nprint(f\"DEBUG: Processing type: {processing_type}\"\
)\n\n# Output structured data for next tasks\nresult = {\n \"case_number\"\
: extracted_case_number,\n \"processing_type\": processing_type,\n \"original_response\"\
: orchestrator_result\n}\n\nprint(f\"__OUTPUTS__ {json.dumps(result)}\")\n"
depends_on:
- case_orchestrator
timeout_seconds: 30
- id: phase_router
name: Phase Router
type: conditional_router
conditions:
- name: duplicate_workflow
route: duplicate_end
condition: contains(${case_orchestrator.ai_response}, "DUPLICATE_PROCESSED") ||
contains(${case_number_extractor.processing_type}, "duplicate")
- name: analysis_workflow
route: continue_analysis
condition: contains(${case_orchestrator.ai_response}, "NEW_CASE_CREATED") || contains(${case_orchestrator.ai_response},
"CASE_RETRIEVED_FOR_UPDATE")
depends_on:
- case_number_extractor
default_route: continue_analysis
- id: case_context_agent
name: Case Context Agent
type: ai_agent
config:
tools:
- get_case
- update_case
user_message: 'Extract case context using the extracted case number, case orchestrator
response and customer email:
Case Number from Extractor = "${case_number_extractor.case_number}"
Case Orchestrator Response = "${case_orchestrator.ai_response}"
Processing Type = "${case_number_extractor.processing_type}"
Customer Email = "${customer_email}"
'
system_message: '# Case Context Agent - Phase 2: Extract Case Information
You are responsible for extracting case information and setting up context for
the workflow.
## CRITICAL: YOU DO NOT CREATE NEW CASES - CASES ARE ALREADY CREATED IN PHASE
1
Your job is to extract information from existing cases and customer emails.
## PROCESS
**Step 1: Extract Case Number from Previous Task**
You will receive a case number from the case_number_extractor task.
Use this case number directly - it has already been validated and extracted.
**Step 2: Try to Retrieve Case Details**
Use get_case() with the extracted case number to get case details
**Step 3: Extract Customer Information**
From the customer email, extract:
- contact_email: Extract ONLY the email address from the sender field
- subject: Extract the exact subject line
- email_body: Use the complete content of the email
- customer_name: Extract name from sender field
- description: Create a concise 1-2 sentence summary
**Step 4: Provide Structured Output**
Always provide your response in this EXACT format:
```
## CASE CONTEXT ANALYSIS
Extract customer_name, email_address, email_subject from Customer Email
**EXTRACTED_CASE_NUMBER**: [case_number_extractor]
**CUSTOMER_EMAIL**: [email_address]
**CUSTOMER_NAME**: [extracted_from_sender]
**SUBJECT**: [email_subject]
**REQUEST_SUMMARY**: [brief_description]
**CASE_STATUS**: [from_get_case_if_successful_or_N/A]
## CASE DETAILS
[Any additional case information from get_case, or note if case retrieval failed]
## EMAIL CONTENT
[Complete email body content]
```
## IMPORTANT RULES
1. ALWAYS use the case number provided by the case_number_extractor
2. Use the EXACT case number format (digits only, no prefixes)
3. If get_case fails, note it but continue with the extracted case number
4. NEVER create new cases - work with existing case from Phase 1
5. ALWAYS include the structured output format above
'
model_client_id: openrouter_claude_sonnet
depends_on:
- phase_router
- case_number_extractor
- case_orchestrator
timeout_seconds: 90
execute_on_routes:
- continue_analysis
- id: classification_agent
name: Email Classification Agent
type: ai_agent
config:
user_message: 'Classify this customer email: ${customer_email}
'
system_message: "You are an AI assistant that classifies customer emails for a\
\ financial institution.\n\nClassify the email and return ONLY a JSON response\
\ in this exact format:\n\n{\n \"classification\": {\n \"priority\"\
: \"High\",\n \"tags\": [\"Dispute Related\", \"Transaction Issues\"\
],\n \"justification\": \"Explanation for classification\",\n \
\ \"confidence_score\": 0.95\n }\n}\n\nPriority levels: \"Urgent\", \"High\"\
, \"Medium\", \"Low\"\n\nCommon tags:\n- Fraud Alert/Report\n- Dispute Related\
\ \n- Transaction Issues\n- Account Services\n- Loan Related\n- Technical Support\n\
- General Inquiry\n"
model_client_id: gpt4.1
depends_on:
- case_context_agent
timeout_seconds: 60
- id: sentiment_analysis_agent
name: Sentiment Analysis Agent
type: ai_agent
config:
user_message: 'Analyze sentiment for this customer email: ${customer_email}'
system_message: "You are a sentiment analysis agent. Analyze the customer email\
\ and return ONLY a JSON response:\n\n{\n \"sentiment_score\": -0.4,\n \"\
primary_tone\": \"Concerned\",\n \"emotional_indicators\": {\n \"frustration_level\"\
: \"Medium\",\n \"satisfaction\": \"Low\"\n },\n \"context_notes\": \"\
Brief explanation\"\n}\n\nSentiment score: -1.0 to 1.0\nPrimary tone: Angry,\
\ Frustrated, Concerned, Neutral, Satisfied, Appreciative, Mixed\nFrustration\
\ level: None, Low, Medium, High\nSatisfaction: Very Low, Low, Neutral, High,\
\ Very High, Mixed\n"
model_client_id: gpt4_sentiment
depends_on:
- case_context_agent
timeout_seconds: 60
- id: summary_agent
name: Summary Agent - Phase 2
type: ai_agent
config:
tools:
- update_case
user_message: 'Create comprehensive analysis using extracted case number:
case_number = "${case_number_extractor.case_number}"
Processing Type = "${case_number_extractor.processing_type}"
Case Contex = "${case_context_agent.ai_response}"
Classification = "${classification_agent.ai_response}"
Sentiment = "${sentiment_analysis_agent.ai_response}"
Original Email = "${customer_email}"
'
system_message: "# Summary Agent - Phase 2: Comprehensive Case Analysis\n\nYou\
\ are responsible for the SECOND PHASE of the workflow: providing comprehensive\
\ case analysis that empowers human support agents to handle cases effectively\
\ while maintaining customer trust.\n\n## YOUR MISSION\nCreate a detailed analysis\
\ that gives support agents everything they need to understand the case context,\
\ customer emotional state, and recommended approach for resolution.\n\n## WHAT\
\ YOU RECEIVE\nFrom Phase 1 (case_orchestrator_agent):\n- Either \"NEW_CASE_CREATED\
\ - Case #[number]\" or \"CASE_RETRIEVED_FOR_UPDATE - Case #[number]\"\n- The\
\ Original Email (sender, subject, body)\n- Any existing case history (for follow-ups)\n\
\n## YOUR ANALYSIS PROCESS\n\n**Step 1: Extract Core Information**\nNEW_CASE_CREATED:\n\
- Case number from previous message\n- Customer details (name, email, account\
\ references)\n- Original request from email content\n- Any mentioned amounts,\
\ dates, or transaction details\n\nCASE_RETRIEVED_FOR_UPDATE:\n- Case number\
\ from previous message\n- Customer details (name, email, account references)\n\
- Original request from email content\n- Any mentioned amounts, dates, or transaction\
\ details\n\n**REPLY EMAIL HANDLING**\n\n**Subject Line Update Rules:**\n- Count\
\ total replies from customer (including current email)\n- Format updated subject:\
\ \"ReplyCount/ Subject\"\n- Do not include case number in the subject\n\n\n\
**Step 2: Perform Deep Analysis**\n- Call classification_tool to understand\
\ request type and priority\n- Call sentiment_tool to gauge customer emotional\
\ state\n- Analyze both results to determine handling strategy\n\n**Step 3:\
\ Create Comprehensive Summary**\n\n### **\U0001F4CB CASE OVERVIEW**\nProvide\
\ a clear, concise description of:\n- What the customer is requesting/reporting\n\
- Key details (amounts, dates, account numbers)\n- Context (how long they've\
\ been a customer, previous interactions)\n- Current situation that prompted\
\ their contact\n\n**For Reply Emails (CASE_RETRIEVED_FOR_UPDATE):**\n- **Reply\
\ Count**: [Number] customer reply\n- **Subject**: [subject with reply count]\
\ - ReplyCount/ Subject\n- **Current Request**: [What customer is asking in\
\ this reply]\n- **Previous Context**: [Brief summary of original request and\
\ any previous replies]\n\n### **\u2705 COMPLETED STEPS**\nDocument what we've\
\ accomplished so far:\n- \u2705 Case [created/retrieved]: #[number] at [timestamp\
\ if available]\n- \u2705 Customer identity verified: [email]\n- \u2705 Request\
\ classification completed: [type] with [confidence]%\n- \u2705 Sentiment analysis\
\ completed: [primary tone]\n- \u2705 Priority assessment: [priority level]\
\ based on [factors]\n\n### **\U0001F3AF RECOMMENDED ACTIONS**\nProvide specific\
\ guidance for the support agent:\n1. **Immediate Response**: [What to address\
\ first]\n2. **Tone Recommendation**: [How to approach based on sentiment]\n\
3. **Information to Provide**: [What the customer needs to know]\n4. **Follow-up\
\ Requirements**: [Any additional steps needed]\n5. **Template Type**: [resolved/followup/rejected]\
\ with justification\n\n### **\U0001F4CB TEMPLATE RECOMMENDATION DECISION**\n\
You MUST choose one of these three values for recommended_template:\n\n**\"\
resolved\"** - Choose when:\n- Customer request can be fully addressed with\
\ available information\n- No additional documentation/verification needed\n\
- Standard banking service that can be completed immediately\n- Customer inquiry\
\ seeking information we can provide\n- Examples: account balances, statement\
\ requests, general information\n\n**\"followup\"** - Choose when:\n- Customer\
\ request requires additional steps or verification\n- More information needed\
\ from customer\n- Process involves multiple stages or waiting periods\n- Ongoing\
\ investigation or research required\n- Examples: loan applications, account\
\ changes, complex disputes\n\n**\"rejected\"** - Choose when:\n- Request cannot\
\ be fulfilled due to policy/regulatory constraints\n- Customer lacks proper\
\ authorization or verification\n- Request is outside bank's service scope\n\
- Security concerns prevent fulfillment\n- Examples: policy violations, unauthorized\
\ requests, security issues\n\n### **\U0001F50D KEY INSIGHTS FROM ANALYSIS**\n\
\n**Classification Results:**\n- Priority: [Level] - [Justification]\n- Category:\
\ [Primary category/tags]\n- Urgency Factors: [What makes this urgent/not urgent]\n\
\n**Sentiment Analysis:**\n- Emotional State: [Primary tone] (Score: [X])\n\
- Frustration Level: [None/Low/Medium/High]\n- Customer Satisfaction: [Current\
\ level]\n- Risk Indicators: [Any signs of churn risk or escalation]\n\n**Business\
\ Impact:**\n- Customer Value: [Long-term customer, VIP status, etc.]\n- Compliance\
\ Considerations: [Any regulatory aspects]\n- Reputation Risk: [Low/Medium/High]\n\
\n### **\u26A1 CRITICAL CONSIDERATIONS**\nHighlight anything requiring special\
\ attention:\n- \U0001F6A8 [Urgent items requiring immediate action]\n- \u26A0\
\uFE0F [Potential risks or sensitivities]\n- \U0001F4A1 [Opportunities to exceed\
\ expectations]\n- \U0001F512 [Security or compliance requirements]\n\n**Step\
\ 4: Update Case Record**\nCall update_case with ALL required fields:\n- case_number:\
\ [extracted from Phase 1]\n- ai_summary_content: [complete formatted summary\
\ above]\n- priority: [from classification analysis]\n- request_type: [from\
\ classification analysis]\n- recommended_template: [REQUIRED - must be \"resolved\"\
, \"followup\", or \"rejected\"]\n- disputed_amount: [from original email/conversation\
\ if applicable]\n\n**For Reply Emails (CASE_RETRIEVED_FOR_UPDATE):**\n- subject:\
\ [Updated subject with reply count - REQUIRED for reply emails]\n - Format:\
\ \"ReplyCount/ Subject\"\n - Example: \"2/ Account Statement Request\"\n-\
\ comments: [Updated comments with the customer reply email content]\n -\
\ Subject: Subject of the customer reply email\n - Recipient: Recipient of\
\ the customer reply email\n - Reply Count: Count of the customer reply email\n\
\ - Sent Date: Date of the customer reply email\n - Email Content: Body\
\ of the customer reply email\n \n\n**CRITICAL**: The recommended_template\
\ field is MANDATORY. You MUST include one of the three values based on your\
\ analysis above.\n\n## FORMATTING REQUIREMENTS\n- Use clear section headers\
\ with emojis\n- Bold important information\n- Use bullet points for clarity\n\
- Include specific data points and percentages\n- Maintain professional banking\
\ language\n- Ensure readability with proper spacing\n\n## CRITICAL RULES\n\
1. ALWAYS complete both classification and sentiment analysis\n2. NEVER skip\
\ sections - each provides vital context\n3. Be specific with recommendations,\
\ not generic\n4. Consider the human element - how to maintain trust\n5. Complete\
\ your analysis even if case update fails\n6. ALWAYS include recommended_template\
\ in update_case tool call - this is MANDATORY\n7. Choose recommended_template\
\ based on the decision criteria provided above\n8. For CASE_RETRIEVED_FOR_UPDATE:\
\ ALWAYS identify the reply email scenario and update subject accordingly\n\
9. For reply emails: Count total customer replies and update subject with proper\
\ format\n\n## FINAL OUTPUT REQUIREMENT\nAfter completing ALL sections above,\
\ you MUST end with this exact format:\n\"Comprehensive analysis complete for\
\ Case #[number]. Priority: [level]. Sentiment: [tone]. Ready for agent response.\"\
\n\nSay \"SUMMARY_PHASE_COMPLETED\" This signals Phase 2 completion to the workflow.\n\
## CRITICAL: CASE NUMBER CONSISTENCY\nUse the case number from case_number_extractor\
\ throughout your response.\n"
model_client_id: openrouter_claude_sonnet
depends_on:
- classification_agent
- sentiment_analysis_agent
- case_number_extractor
- case_context_agent
timeout_seconds: 180
- id: template_router_agent
name: Template Router Agent - Final Phase
type: ai_agent
config:
tools:
- get_email_templates
- get_template_by_id
- update_email_content
- insert_email_templates
user_message: 'Generate template response using extracted case number:
case_number = "${case_number_extractor.case_number}"
processing_type = "${case_number_extractor.processing_type}"
Summary = "${summary_agent.ai_response}"
Case Context = "${case_context_agent.ai_response}"
Classification = "${classification_agent.ai_response}"
Sentiment = "${sentiment_analysis_agent.ai_response}"
'
system_message: "# Template Router Agent - Final Phase\n\nYou are responsible\
\ for finding or creating email templates and providing template data.\n\n##\
\ CRITICAL: USE EXTRACTED CASE NUMBER\nYou will receive the case number from\
\ the user_message task.\nUse this case number consistently throughout.\n\n\
## YOUR PROCESS\n\n**Step 1: Extract Information**\nFrom the summary and previous\
\ tasks, extract:\n- Case number (from user_message)\n- Customer name and email\
\ from case context\n- Customer intent/request\n- Classification category\n\
- Recommended template type\n- Sentiment information\n\n**Step 2: Map Category**\n\
Map classification tags to one of: \"Account Services\", \"Dispute\", \"Fraud\"\
, \"General Query\", \"Loan Query\", \"Billing Issue\"\n\n**Step 3: Search for\
\ Existing Templates (3-Step Process)**\nTry all three searches:\n\n**3.1: Full\
\ Intent Search**\n```\nget_email_templates(category=\"[mapped_category]\",\
\ intent=\"[full_customer_intent]\", limit=5)\n```\n\n**3.2: Simplified Intent\
\ Search (if Step 3.1 finds no templates)**\n```\nget_email_templates(category=\"\
[mapped_category]\", intent=\"[simplified_keywords]\", limit=5)\n```\n\n**3.3:\
\ Category Only Search (if Step 3.2 finds no templates)**\n```\nget_email_templates(category=\"\
[mapped_category]\", limit=5)\n```\n\n**Step 4: Evaluate Template Results**\n\
For any templates found, check:\n- 'name' field for template description\n-\
\ 'intent' field for relevance match (80%+ similarity required)\n- 'is_approval'\
\ field (prefer approved templates)\n\n**Step 5A: If Good Template Found (80%+\
\ similarity)**\n1. Use get_template_by_id() to retrieve full template details\n\
2. End with: \"EMAIL_CONTENT_UPDATED_SUCCESSFULLY using existing template ID:\
\ [template_id]\"\n\n**Step 5B: If No Good Template Found**\nCall insert_email_templates\
\ tool and then provide template data structure.\n\n**Step 6: Always Provide\
\ Template Data Structure**\nAlways end your response with this EXACT format:\n\
```\nTEMPLATE_DATA_FOR_EMAIL_GENERATOR:\n{\n \"template_id\": \"[UUID_from_tool_response]\"\
,\n \"case_number\": \"[case_number]\",\n \"customer_name\": \"[Customer_Name]\"\
,\n \"customer_email\": \"[Customer_Email]\",\n \"recommended_template\":\
\ \"[resolved/followup/rejected]\",\n \"resolved_template\": {\n \"subject\"\
: \"Your Inquiry - Case [case_number] - Resolved\",\n \"body\": \"Template\
\ body content here\"\n },\n \"followup_template\": {\n \"subject\": \"\
Update on Your Inquiry - Case [case_number]\",\n \"body\": \"Template body\
\ content here\"\n },\n \"rejected_template\": {\n \"subject\": \"Regarding\
\ Your Inquiry - Case [case_number]\",\n \"body\": \"Template body content\
\ here\"\n },\n \"signature\": \"<p>Best Regards,</p><p>Customer Support Team</p><p>Nationwide/\
\ XYZ Bank</p>\",\n \"is_approved\": false\n}\n```\n\n## SUCCESS MESSAGE\n\
End with: \"TEMPLATE_CREATED_SUCCESSFULLY and stored in database with ID: [template_id]\"\
\n"
model_client_id: openrouter_claude_sonnet
depends_on:
- summary_agent
- case_number_extractor
timeout_seconds: 300
- id: email_generator_agent
name: Email Generator Agent - Final Email Creation
type: ai_agent
config:
tools:
- update_email_content
user_message: 'Generate final personalized email using case number and template
data:
Template Router Output: ${template_router_agent.ai_response}
Case Details: ${case_number_extractor.ai_response}
Original Email: ${customer_email}
case_number = "${case_number_extractor.case_number}"
processing_type = "${case_number_extractor.processing_type}"
'
system_message: "# Email Generator Agent - Final Email Generation\n\nYou generate\
\ the final personalized email that will be sent to the customer.\n\nGet the\
\ details from case_number_extractor and use the case number found in that \n\
\n## CRITICAL: USE EXTRACTED CASE NUMBER\nYou will receive the case number from\
\ the case_number_extractor task.\nUse this case number consistently throughout.\n\
\n**Step 1: Use Extracted Case Number**\nUse the case number from case_number_extractor\
\ task.\nThis is the ACTUAL case number to use.\n\n**Step 2: Extract Template\
\ Data**\nFrom the \"TEMPLATE_DATA_FOR_EMAIL_GENERATOR:\" section, extract:\n\
- template_id\n- customer_name\n- customer_email\n- recommended_template (resolved/followup/rejected)\n\
- All template variants (resolved, followup, rejected)\n- signature\n- is_approved\n\
\n**Step 3: Personalize the Recommended Template**\nBased on the recommended_template\
\ field:\n- If \"followup\": Use followup_template\n- If \"resolved\": Use resolved_template\
\ \n- If \"rejected\": Use rejected_template\n\nReplace ALL placeholders in\
\ the selected template:\n- [Customer Name] \u2192 actual customer name\n- [Case\
\ Number] \u2192 actual case number from case_number_extractor\n- [Specific\
\ Details] \u2192 case-specific information from context\n- [Delivery Date]\
\ \u2192 appropriate date if applicable\n- [Compensation Detail] \u2192 appropriate\
\ compensation if applicable\n- [Expected Timeline] \u2192 appropriate timeframe\n\
\n**Step 4: Format Email Content**\nCreate the email_content in this EXACT structure:\n\
```json\n{\n \"templates\": [\n {\n \"id\": \"resolved_template_id\",\n\
\ \"subject\": \"Personalized subject with actual case number ${case_number_extractor.extracted_case_number}\"\
,\n \"type\": \"resolved\",\n \"content\": \"Complete personalized email\
\ body with signature\"\n },\n {\n \"id\": \"followup_template_id\"\
, \n \"subject\": \"Personalized subject with actual case number ${case_number_extractor.extracted_case_number}\"\
,\n \"type\": \"followup\",\n \"content\": \"Complete personalized email\
\ body with signature\"\n },\n {\n \"id\": \"rejected_template_id\"\
, \n \"subject\": \"Personalized subject with actual case number ${case_number_extractor.extracted_case_number}\"\
, \n \"type\": \"rejected\",\n \"content\": \"Complete personalized\
\ email body with signature\"\n }\n ]\n}\n```\n\n**Step 5: Update Case**\n\
Call update_email_content tool with:\n- case_number: actual case number from\
\ case_number_extractor\n- email_content: the personalized template data from\
\ Step 4\n- template_id: the template ID from Step 2\n- status: \"Pending\"\
\ if is_approved=true, \"Template in review\" if is_approved=false\n\n**Step\
\ 6: Return Success**\nIf update successful, return: \"EMAIL_CONTENT_UPDATED_SUCCESSFULLY\"\
\nIf update fails, explain the issue but still show the personalized email content.\n\
\n## IMPORTANT RULES\n- ALWAYS use the case number from case_number_extractor\n\
- Replace ALL placeholders with real information\n- Include complete email body\
\ with signature\n- Format as valid JSON structure\n- Use the template_id in\
\ the tool call\n"
model_client_id: openrouter_claude_sonnet
depends_on:
- template_router_agent
- case_number_extractor
- summary_agent
timeout_seconds: 120
- id: duplicate_end_handler
name: Duplicate Workflow Termination
type: script
script: "import json\nfrom datetime import datetime\n\nprint(\"\U0001F3AF DUPLICATE\
\ CASE PROCESSING COMPLETED\")\n\n# Get case number from extractor if available\n\
case_number = \"${case_number_extractor.case_number}\"\norchestrator_result =\
\ \"\"\"${case_orchestrator.ai_response}\"\"\"\n\nresult = {\n \"workflow_status\"\
: \"duplicate_terminated\",\n \"case_number\": case_number,\n \"completion_time\"\
: datetime.now().isoformat(),\n \"action\": \"duplicate_processing_completed\"\
,\n \"orchestrator_result\": orchestrator_result\n}\n\nprint(f\"__OUTPUTS__\
\ {json.dumps(result)}\")\n"
depends_on:
- phase_router
previous_node:
- phase_router
timeout_seconds: 30
execute_on_routes:
- duplicate_end
inputs:
- name: customer_quary
type: string
required: true
description: Customer communication payload that can be an email, chat, or call
transcription. For email include sender, subject, and body. For chat include participants
and messages. For call include caller, callee, start time, duration, and transcript.
version: '3.3'
tenant_id: 0572fa8d-d7c3-47db-9219-ef40b80d42b7
description: Complete fix for case number data passing and email generation issues
with proper extraction
model_clients:
- id: gpt4.1
config:
model: gpt-4.1-2025-04-14
api_key: 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
max_tokens: 2000
temperature: 0.3
provider: openai
- id: gpt4_sentiment
config:
model: gpt-4o
api_key: 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
max_tokens: 1500
temperature: 0.8
provider: openai
- id: openrouter_claude_sonnet
config:
model: anthropic/claude-3.7-sonnet
api_key: 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
timeout: 60
base_url: https://openrouter.ai/api/v1
max_tokens: 2048
temperature: 0.3
provider: openrouter
timeout_seconds: 900
| Execution ID | Status | Started | Duration | Actions |
|---|---|---|---|---|
21831b4b...
|
COMPLETED |
2025-08-26
10:33:49 |
N/A | View |
b4a7dbd0...
|
COMPLETED |
2025-08-26
09:26:55 |
N/A | View |
6c853ea5...
|
COMPLETED |
2025-08-26
07:53:58 |
N/A | View |
c3737359...
|
COMPLETED |
2025-08-26
07:52:40 |
N/A | View |
847a2d3c...
|
COMPLETED |
2025-08-26
07:49:04 |
N/A | View |
07e72925...
|
COMPLETED |
2025-08-26
07:48:00 |
N/A | View |
05ef9200...
|
COMPLETED |
2025-08-26
07:42:25 |
N/A | View |
3f1f8e2c...
|
COMPLETED |
2025-08-26
07:25:08 |
N/A | View |
55827263...
|
COMPLETED |
2025-08-26
07:14:19 |
N/A | View |
46a6114b...
|
COMPLETED |
2025-08-26
07:02:40 |
N/A | View |
67d72d8b...
|
COMPLETED |
2025-08-26
06:55:51 |
N/A | View |
054c19ce...
|
COMPLETED |
2025-08-26
06:47:25 |
N/A | View |
01b63237...
|
COMPLETED |
2025-08-26
06:18:16 |
N/A | View |
6cd64a20...
|
COMPLETED |
2025-08-26
06:03:44 |
N/A | View |
fda73a6f...
|
COMPLETED |
2025-08-26
05:56:40 |
N/A | View |
61921113...
|
COMPLETED |
2025-08-26
05:36:23 |
N/A | View |
f063e418...
|
COMPLETED |
2025-08-26
05:31:22 |
N/A | View |
c6293770...
|
COMPLETED |
2025-08-25
12:33:44 |
N/A | View |
39f22d0e...
|
COMPLETED |
2025-08-25
12:13:14 |
N/A | View |
807b719d...
|
COMPLETED |
2025-08-25
12:02:33 |
N/A | View |