{
 "schema_version": "1.0",
 "nodes": [
  {
   "id": "inbox",
   "type": "input/json_value",
   "label": "Inbox",
   "parameters": { "value": [{"id": "M-101", "text": "The headphones stopped working after two days and now smell of burnt plastic. I don't want another pair, I want my money back."}, {"id": "M-102", "text": "Il mio ordine #48213 doveva arrivare lunedì e il tracciamento è fermo da quattro giorni. Dov'è finito?"}, {"id": "M-103", "text": "One of the four dining chairs has a cracked leg out of the box. Could you send me a new chair? I'd like to keep the set."}, {"id": "M-104", "text": "Prima di ordinare: il passeggino chiuso entra nel bagagliaio di un'utilitaria?"}, {"id": "M-105", "text": "Mi avete addebitato tre volte lo stesso ordine. Sistemate subito o chiamo la banca."}, {"id": "M-106", "text": "Just wanted to say the bookshop staff were lovely yesterday. Keep it up!"}, {"id": "M-107", "text": "The trainers are lovely but maybe half a size small? I might keep them, I might not."}, {"id": "M-108", "text": "I fiori per il funerale di mia madre di domani alle 9 non sono ancora stati spediti. Vi prego, mi servono in tempo."}],
    "required": true
   }
  },
  {
   "id": "each",
   "type": "enumerate/json",
   "label": "One message at a time",
   "parameters": {
    "emptyBehavior": "fail",
    "jsonConfig": {
     "arrayPath": "(root)",
     "properties": [
      {
       "sourcePath": "id",
       "outputPort": "id",
       "outputType": "text",
       "selected": true,
       "label": "Message"
      },
      {
       "sourcePath": "text",
       "outputPort": "text",
       "outputType": "text",
       "selected": true,
       "label": "Text"
      }
     ]
    }
   }
  },
  {
   "id": "triage",
   "type": "ai/decide",
   "label": "Triage the message",
   "parameters": {
    "questions": {
     "schema": "madoo.decision-questions/v1",
     "questions": [
      {
       "name": "team",
       "type": "choice",
       "instructions": "Which team should handle this message?",
       "options": [
        {
         "value": "refunds",
         "description": "The customer asks for money back"
        },
        {
         "value": "replacements",
         "description": "The customer asks for the item to be replaced or exchanged"
        },
        {
         "value": "deliveries",
         "description": "Delivery, tracking, address or courier"
        },
        {
         "value": "product_advice",
         "description": "A question about a product before or after buying"
        },
        {
         "value": "other",
         "description": "Anything else: account, newsletter, praise, partnership, stores"
        }
       ],
       "threshold": 0.7
      },
      {
       "name": "urgency",
       "type": "score",
       "instructions": "How urgent is this message?",
       "levels": [
        {
         "label": "low",
         "description": "No time pressure, informational"
        },
        {
         "label": "medium",
         "description": "Needs an answer this week"
        },
        {
         "label": "high",
         "description": "Angry, repeated, or a deadline within a day"
        }
       ],
       "threshold": 0.6
      },
      {
       "name": "damaged",
       "type": "yes_no",
       "instructions": "The item the customer received is damaged or broken.",
       "threshold": 0.8
      }
     ]
    }
   }
  },
  {
   "id": "is_refund",
   "type": "utility/predicate",
   "label": "A refund request?",
   "parameters": {
    "operation": "equals",
    "compare_text": "refunds"
   }
  },
  {
   "id": "sure_refund",
   "type": "utility/boolean_combine",
   "label": "A refund, and the model is sure",
   "parameters": {
    "mode": "all"
   }
  },
  {
   "id": "only_refunds",
   "type": "utility/filter",
   "label": "Only sure refund requests",
   "parameters": {
    "invert": false
   }
  },
  {
   "id": "draft",
   "type": "ai/text_generation",
   "label": "Draft the refund reply",
   "parameters": {
    "max_tokens": 400,
    "system_prompt": "You write short, warm replies for a shop's customer service. Apologise once, say that the refund request has been passed to the refunds team, never promise a date or an amount. Answer in the language of the customer's message, in at most three sentences."
   }
  },
  {
   "id": "queue",
   "type": "aggregate/json",
   "label": "Work queue",
   "parameters": {
    "jsonAggregateConfig": {
     "prettyPrint": true,
     "outputName": "queue",
     "columns": [
      {
       "name": "id",
       "inputPort": "id",
       "type": "text"
      },
      {
       "name": "team",
       "inputPort": "team",
       "type": "text"
      },
      {
       "name": "team_probability",
       "inputPort": "team_probability",
       "type": "number"
      },
      {
       "name": "urgency",
       "inputPort": "urgency",
       "type": "text"
      },
      {
       "name": "urgency_score",
       "inputPort": "urgency_score",
       "type": "number"
      },
      {
       "name": "damaged",
       "inputPort": "damaged",
       "type": "boolean"
      },
      {
       "name": "model_sure",
       "inputPort": "model_sure",
       "type": "boolean"
      },
      {
       "name": "reply_draft",
       "inputPort": "reply_draft",
       "type": "text",
       "whenAbsent": "null"
      }
     ]
    }
   }
  },
  {
   "id": "o_queue",
   "type": "output/json",
   "label": "Work queue",
   "parameters": {
    "output_name": "queue"
   }
  }
 ],
 "connections": [
  {
   "from_node": "inbox",
   "from_output": "json",
   "to_node": "each",
   "to_input": "json"
  },
  {
   "from_node": "each",
   "from_output": "text",
   "to_node": "triage",
   "to_input": "content"
  },
  {
   "from_node": "triage",
   "from_output": "team",
   "to_node": "is_refund",
   "to_input": "a"
  },
  {
   "from_node": "is_refund",
   "from_output": "result",
   "to_node": "sure_refund",
   "to_input": "conditions_0"
  },
  {
   "from_node": "triage",
   "from_output": "all_accepted",
   "to_node": "sure_refund",
   "to_input": "conditions_1"
  },
  {
   "from_node": "sure_refund",
   "from_output": "result",
   "to_node": "only_refunds",
   "to_input": "condition"
  },
  {
   "from_node": "each",
   "from_output": "text",
   "to_node": "only_refunds",
   "to_input": "value"
  },
  {
   "from_node": "only_refunds",
   "from_output": "value",
   "to_node": "draft",
   "to_input": "prompt"
  },
  {
   "from_node": "each",
   "from_output": "id",
   "to_node": "queue",
   "to_input": "id"
  },
  {
   "from_node": "triage",
   "from_output": "team",
   "to_node": "queue",
   "to_input": "team"
  },
  {
   "from_node": "triage",
   "from_output": "team_probability",
   "to_node": "queue",
   "to_input": "team_probability"
  },
  {
   "from_node": "triage",
   "from_output": "urgency_level",
   "to_node": "queue",
   "to_input": "urgency"
  },
  {
   "from_node": "triage",
   "from_output": "urgency",
   "to_node": "queue",
   "to_input": "urgency_score"
  },
  {
   "from_node": "triage",
   "from_output": "damaged",
   "to_node": "queue",
   "to_input": "damaged"
  },
  {
   "from_node": "triage",
   "from_output": "all_accepted",
   "to_node": "queue",
   "to_input": "model_sure"
  },
  {
   "from_node": "draft",
   "from_output": "result",
   "to_node": "queue",
   "to_input": "reply_draft"
  },
  {
   "from_node": "queue",
   "from_output": "result",
   "to_node": "o_queue",
   "to_input": "json"
  }
 ]
}