Banking Email Support Workflow

Multi-phase banking email support with strict sequential agent progression

Back
Workflow Information

ID: banking_email_support

Namespace: default

Version: 3.3

Created: 2025-07-21

Updated: 2025-08-26

Tasks: 10

Quick Actions
Manage Secrets
Inputs
Name Type Required Default
customer_quary string Required None
Outputs

No outputs defined

Tasks
case_orchestrator
ai_agent

No description

case_number_extractor
script

No description

phase_router
conditional_router

No description

Conditional Router
Router Type: condition
Default Route: continue_analysis
case_context_agent
ai_agent

No description

classification_agent
ai_agent

No description

sentiment_analysis_agent
ai_agent

No description

summary_agent
ai_agent

No description

template_router_agent
ai_agent

No description

email_generator_agent
ai_agent

No description

duplicate_end_handler
script

No 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