{
  "tello_export": "1.2",
  "kind": "scenario_bundle",
  "exported_at": "2026-09-15T00:00:00.000Z",
  "scenario": {
    "name": "병원 진료 예약 변경",
    "keywords": [
      "예약 변경",
      "예약 취소",
      "진료 예약",
      "예약 확인",
      "날짜 변경"
    ],
    "flow_config": {
      "$schema": "tello-scenario-v1",
      "meta": {
        "name": "병원 진료 예약 변경",
        "trigger_description": "이미 잡힌 진료 예약을 확인하고 날짜를 바꾸거나 취소하고 싶을 때"
      },
      "nodes": [
        {
          "id": "start",
          "type": "initial",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "시작 노드입니다. 안내 문장(\"진료 예약 확인을 도와드리겠습니다\")은 이미 자동으로 재생됐으니 다시 말하지 마세요. 고객이 이 용건을 원하면 아무 말 없이 곧바로 start_appointment을 호출하세요. 다음 단계 안내는 자동으로 나옵니다. 다른 용건이면 짧게 답한 뒤 이 용건을 도와드릴지 물어보세요."
              }
            ],
            "functions": [
              {
                "name": "start_appointment",
                "description": "고객이 진료 예약을 확인·변경·취소하려는 경우",
                "properties": {},
                "required": [],
                "next_node_id": "collect_name"
              }
            ],
            "respond_immediately": true,
            "pre_actions": [
              {
                "type": "tts_say",
                "text": "진료 예약 확인을 도와드리겠습니다."
              }
            ]
          }
        },
        {
          "id": "collect_name",
          "type": "node",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "고객에게 \"예약하신 분 성함을 말씀해 주세요.\"라고 물어보세요. 고객이 정보를 일부만 말하거나 나눠 말하면 이미 받은 부분은 그대로 두고 빠진 부분만 이어서 물어보세요. 고객이 값을 말하기 전에는 수집 함수를 부르지 마세요."
              }
            ],
            "functions": [
              {
                "name": "collect_patient_name",
                "description": "고객이 환자 이름을 말하면 수집",
                "properties": {
                  "patient_name": {
                    "type": "string",
                    "description": "환자 이름"
                  }
                },
                "required": [
                  "patient_name"
                ],
                "next_node_id": "collect_phone"
              }
            ]
          }
        },
        {
          "id": "collect_phone",
          "type": "node",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "키패드 입력 안내 멘트는 자동으로 재생되니 같은 안내를 다시 말하지 마세요. 고객이 키패드로 누르면 자동으로 수집됩니다. 고객이 번호를 말로 불러주면 숫자만 모아 수집 함수를 호출하세요. 고객이 정보를 일부만 말하거나 나눠 말하면 이미 받은 부분은 그대로 두고 빠진 부분만 이어서 물어보세요. 고객이 값을 말하기 전에는 수집 함수를 부르지 마세요."
              }
            ],
            "functions": [
              {
                "name": "collect_phone",
                "description": "고객이 휴대폰 번호를 입력하거나 말하면 수집",
                "properties": {
                  "phone": {
                    "type": "string",
                    "description": "환자 휴대폰 번호. 숫자만"
                  }
                },
                "required": [
                  "phone"
                ],
                "next_node_id": "lookup"
              }
            ],
            "dtmf": {
              "function": "collect_phone",
              "param": "phone",
              "prompt": "예약하신 휴대폰 번호를 누르신 후 우물 정 자를 눌러 주세요. 다시 입력하시려면 별표를 눌러 주세요.",
              "min_digits": 10,
              "max_digits": 11,
              "terminator": "#",
              "timeout_sec": 6,
              "max_retries": 2,
              "readback": "입력하신 번호 {value} 맞으신가요?"
            }
          }
        },
        {
          "id": "lookup",
          "type": "node",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "수집된 정보로 연결된 API를 호출하세요."
              }
            ],
            "functions": [
              {
                "name": "lookup_appointment",
                "description": "수집 완료된 파라미터로 연결 Tool 실행",
                "properties": {},
                "required": [],
                "call_tool": true,
                "tool_id": 1,
                "error_text": "죄송합니다, 예약 조회 중 문제가 발생했습니다. 성함과 번호를 다시 한번 확인해 주시겠어요?",
                "next_node_id": "decide"
              }
            ],
            "pre_actions": [
              {
                "type": "tts_say",
                "text": "예약 내역을 확인하고 있습니다."
              }
            ]
          }
        },
        {
          "id": "decide",
          "type": "node",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "조회 결과([도구 실행 결과])의 예정 예약 일정을 먼저 안내하세요. 결과에 없는 값은 지어내지 마세요. 예정된 예약이 있으면 날짜를 변경하실지 취소하실지 물어보세요. 예정된 예약이 없으면 그 사실을 안내하고 no_appointment 를 호출하세요."
              }
            ],
            "functions": [
              {
                "name": "route_reschedule",
                "description": "고객이 예약 날짜나 시간을 바꾸거나 미루고 싶다고 한 경우",
                "properties": {},
                "required": [],
                "next_node_id": "collect_new_datetime"
              },
              {
                "name": "route_cancel",
                "description": "고객이 예약을 취소하겠다고 한 경우",
                "properties": {},
                "required": [],
                "next_node_id": "cancel_confirm"
              },
              {
                "name": "no_appointment",
                "description": "예정된 예약이 없거나 고객이 그대로 두겠다고 한 경우",
                "properties": {},
                "required": [],
                "next_node_id": "end"
              }
            ]
          }
        },
        {
          "id": "collect_new_datetime",
          "type": "node",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "희망하시는 날짜와 시간을 물어보세요. 날짜는 YYYY-MM-DD, 시간은 HH:MM 형식으로 정리해 수집하세요. 고객이 정보를 일부만 말하거나 나눠 말하면 이미 받은 부분은 그대로 두고 빠진 부분만 이어서 물어보세요. 고객이 값을 말하기 전에는 수집 함수를 부르지 마세요."
              }
            ],
            "functions": [
              {
                "name": "collect_new_datetime",
                "description": "고객이 바꿀 진료 날짜와 시간을 모두 말하면 수집",
                "properties": {
                  "new_visit_date": {
                    "type": "string",
                    "description": "바꿀 진료일 YYYY-MM-DD"
                  },
                  "new_visit_time": {
                    "type": "string",
                    "description": "바꿀 진료 시간 HH:MM"
                  }
                },
                "required": [
                  "new_visit_date",
                  "new_visit_time"
                ],
                "next_node_id": "change_submit"
              }
            ]
          }
        },
        {
          "id": "change_submit",
          "type": "node",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "수집된 정보로 연결된 API를 호출하세요."
              }
            ],
            "functions": [
              {
                "name": "submit_change",
                "description": "수집 완료된 파라미터로 연결 Tool 실행",
                "properties": {},
                "required": [],
                "call_tool": true,
                "tool_id": 2,
                "error_text": "죄송합니다, 예약 변경 중 문제가 발생했습니다. 다른 날짜나 시간으로 다시 말씀해 주시겠어요?",
                "next_node_id": "end"
              }
            ],
            "pre_actions": [
              {
                "type": "tts_say",
                "text": "예약을 변경하겠습니다."
              }
            ]
          }
        },
        {
          "id": "cancel_confirm",
          "type": "node",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "정말 취소하실지 한 번 더 확인하세요. 취소하면 같은 시간대 재예약이 어려울 수 있다고 안내하세요. 고객이 취소를 확정하면 취소 사유를 들은 뒤 confirm_cancel 을, 그대로 두겠다고 하면 keep_appointment 를 호출하세요."
              }
            ],
            "functions": [
              {
                "name": "confirm_cancel",
                "description": "고객이 취소를 확정한 경우",
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "취소 사유"
                  }
                },
                "required": [],
                "next_node_id": "cancel_submit"
              },
              {
                "name": "keep_appointment",
                "description": "고객이 예약을 그대로 두겠다고 한 경우",
                "properties": {},
                "required": [],
                "next_node_id": "end"
              }
            ],
            "barge_in": false
          }
        },
        {
          "id": "cancel_submit",
          "type": "node",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "수집된 정보로 연결된 API를 호출하세요."
              }
            ],
            "functions": [
              {
                "name": "submit_cancel",
                "description": "수집 완료된 파라미터로 연결 Tool 실행",
                "properties": {},
                "required": [],
                "call_tool": true,
                "tool_id": 3,
                "error_text": "죄송합니다, 예약 취소 중 문제가 발생했습니다. 잠시 후 다시 시도해 주시겠어요?",
                "next_node_id": "end"
              }
            ],
            "pre_actions": [
              {
                "type": "tts_say",
                "text": "예약을 취소하겠습니다."
              }
            ]
          }
        },
        {
          "id": "end",
          "type": "end",
          "data": {
            "task_messages": [
              {
                "role": "system",
                "content": "방금 실행한 도구의 결과([도구 실행 결과])에 고객이 요청한 값이 있으면 그 값을 먼저 정확히 안내하세요. 결과에 없는 값은 지어내지 말고, 숫자·날짜·금액은 이름이 _ko 로 끝나는 값을 그대로 읽으세요. 고객이 묻지 않은 내부 식별자(고객번호·계량기번호·청구번호 등)는 읽지 마세요. 그 다음 \"진료 예약 안내를 마쳤습니다.\"라고 마무리하고 다른 문의가 있는지 물어보세요."
              }
            ]
          }
        }
      ]
    },
    "default_ref": "tool_1",
    "completion_message": "진료 예약 안내를 마쳤습니다.",
    "fallback_message": "예약 변경을 취소했습니다."
  },
  "tools": [
    {
      "ref": "tool_1",
      "function_name": "mock_get_patient_appointments",
      "name": "[병원] 환자 예약 조회",
      "tool_type": "api_request",
      "endpoint_url": "https://api-mock.telloai.io/hospital/appointments/summary",
      "http_method": "GET",
      "auth_type": "none",
      "request_schema": {
        "type": "object",
        "required": [
          "patient_name",
          "phone"
        ],
        "properties": {
          "patient_name": {
            "type": "string",
            "description": "환자 이름"
          },
          "phone": {
            "type": "string",
            "description": "환자 휴대폰 번호. 숫자만"
          }
        }
      },
      "description": "환자 이름과 휴대폰 번호로 예정된 진료 예약과 지난 진료 내역을 조회한다.",
      "timeout_sec": 15,
      "config": {
        "url": "https://api-mock.telloai.io/hospital/appointments/summary",
        "body": {
          "type": "object",
          "required": [
            "patient_name",
            "phone"
          ],
          "properties": {
            "patient_name": {
              "type": "string",
              "description": "환자 이름"
            },
            "phone": {
              "type": "string",
              "description": "환자 휴대폰 번호. 숫자만"
            }
          }
        },
        "method": "GET",
        "messages": [
          {
            "type": "request-start",
            "content": "진료 내역을 확인해 볼게요."
          },
          {
            "type": "request-failed",
            "content": "죄송해요, 진료 내역을 불러오지 못했어요."
          },
          {
            "type": "request-response-delayed",
            "content": "조회 중이에요. 잠시만요.",
            "timingMilliseconds": 3000
          }
        ],
        "timeoutSec": 15,
        "variableExtraction": {
          "schema": {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "found": {
                    "type": "boolean"
                  },
                  "stats": {
                    "type": "object",
                    "properties": {
                      "no_show_count": {
                        "type": "integer"
                      },
                      "canceled_count": {
                        "type": "integer"
                      },
                      "completed_count": {
                        "type": "integer"
                      },
                      "total_consult_fee": {
                        "type": "integer"
                      }
                    }
                  },
                  "history": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "room": {
                          "type": "string"
                        },
                        "phone": {
                          "type": "string"
                        },
                        "doctor": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "summary": {
                          "type": "string"
                        },
                        "symptom": {
                          "type": "string"
                        },
                        "queue_no": {
                          "type": "integer"
                        },
                        "birth_date": {
                          "type": "string"
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "updated_at": {
                          "type": "string"
                        },
                        "visit_date": {
                          "type": "string"
                        },
                        "visit_time": {
                          "type": "string"
                        },
                        "visit_type": {
                          "type": "string"
                        },
                        "consult_fee": {
                          "type": "integer"
                        },
                        "patient_name": {
                          "type": "string"
                        },
                        "reception_no": {
                          "type": "string"
                        },
                        "cancel_reason": {
                          "type": "string"
                        },
                        "department_code": {
                          "type": "string"
                        },
                        "department_name": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "patient": {
                    "type": "object",
                    "properties": {
                      "phone": {
                        "type": "string"
                      },
                      "birth_date": {
                        "type": "string"
                      },
                      "last_visit": {
                        "type": "string"
                      },
                      "departments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "count": {
                              "type": "integer"
                            },
                            "department_name": {
                              "type": "string"
                            },
                            "last_visit_date": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "visit_count": {
                        "type": "integer"
                      },
                      "patient_name": {
                        "type": "string"
                      }
                    }
                  },
                  "canceled": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "upcoming": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "room": {
                          "type": "string"
                        },
                        "phone": {
                          "type": "string"
                        },
                        "doctor": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "summary": {
                          "type": "string"
                        },
                        "symptom": {
                          "type": "string"
                        },
                        "queue_no": {
                          "type": "integer"
                        },
                        "birth_date": {
                          "type": "string"
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "updated_at": {
                          "type": "string"
                        },
                        "visit_date": {
                          "type": "string"
                        },
                        "visit_time": {
                          "type": "string"
                        },
                        "visit_type": {
                          "type": "string"
                        },
                        "consult_fee": {
                          "type": "integer"
                        },
                        "patient_name": {
                          "type": "string"
                        },
                        "reception_no": {
                          "type": "string"
                        },
                        "cancel_reason": {
                          "type": "string"
                        },
                        "department_code": {
                          "type": "string"
                        },
                        "department_name": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "next_action": {
                    "type": "string"
                  },
                  "has_upcoming": {
                    "type": "boolean"
                  },
                  "history_count": {
                    "type": "integer"
                  },
                  "canceled_count": {
                    "type": "integer"
                  },
                  "is_new_patient": {
                    "type": "boolean"
                  },
                  "upcoming_count": {
                    "type": "integer"
                  },
                  "next_appointment": {
                    "type": "object",
                    "properties": {
                      "room": {
                        "type": "string"
                      },
                      "phone": {
                        "type": "string"
                      },
                      "doctor": {
                        "type": "string"
                      },
                      "status": {
                        "type": "string"
                      },
                      "summary": {
                        "type": "string"
                      },
                      "symptom": {
                        "type": "string"
                      },
                      "queue_no": {
                        "type": "integer"
                      },
                      "birth_date": {
                        "type": "string"
                      },
                      "created_at": {
                        "type": "string"
                      },
                      "updated_at": {
                        "type": "string"
                      },
                      "visit_date": {
                        "type": "string"
                      },
                      "visit_time": {
                        "type": "string"
                      },
                      "visit_type": {
                        "type": "string"
                      },
                      "consult_fee": {
                        "type": "integer"
                      },
                      "patient_name": {
                        "type": "string"
                      },
                      "reception_no": {
                        "type": "string"
                      },
                      "cancel_reason": {
                        "type": "string"
                      },
                      "department_code": {
                        "type": "string"
                      },
                      "department_name": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "message": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                ],
                "description": "한국어 한 줄 요약(또는 검증 오류 다건). 음성 에이전트가 그대로 읽어줄 수 있다."
              },
              "status_code": {
                "type": "integer",
                "description": "HTTP 상태 코드와 동일"
              }
            }
          },
          "aliases": [
            {
              "key": "예정있음",
              "value": "{{ $.data.has_upcoming }}"
            },
            {
              "key": "다음단계",
              "value": "{{ $.data.next_action }}"
            },
            {
              "key": "신규환자",
              "value": "{{ $.data.is_new_patient }}"
            },
            {
              "key": "예정건수",
              "value": "{{ $.data.upcoming_count }}"
            },
            {
              "key": "접수번호",
              "value": "{{ $.data.next_appointment.reception_no }}"
            }
          ]
        }
      }
    },
    {
      "ref": "tool_2",
      "function_name": "mock_change_appointment",
      "name": "[병원] 예약 일정 변경",
      "tool_type": "api_request",
      "endpoint_url": "https://api-mock.telloai.io/hospital/appointments/change",
      "http_method": "POST",
      "auth_type": "none",
      "request_schema": {
        "type": "object",
        "required": [
          "patient_name",
          "phone",
          "new_visit_date",
          "new_visit_time"
        ],
        "properties": {
          "patient_name": {
            "type": "string",
            "description": "환자 이름"
          },
          "phone": {
            "type": "string",
            "description": "환자 휴대폰 번호. 숫자만"
          },
          "new_visit_date": {
            "type": "string",
            "description": "바꿀 진료일 YYYY-MM-DD"
          },
          "new_visit_time": {
            "type": "string",
            "description": "바꿀 진료 시간 HH:MM"
          }
        }
      },
      "description": "환자 이름과 휴대폰 번호로 찾은 예정 예약의 진료 날짜·시간을 바꾼다.",
      "timeout_sec": 15,
      "config": {
        "url": "https://api-mock.telloai.io/hospital/appointments/change",
        "body": {
          "type": "object",
          "required": [
            "patient_name",
            "phone",
            "new_visit_date",
            "new_visit_time"
          ],
          "properties": {
            "patient_name": {
              "type": "string",
              "description": "환자 이름"
            },
            "phone": {
              "type": "string",
              "description": "환자 휴대폰 번호. 숫자만"
            },
            "new_visit_date": {
              "type": "string",
              "description": "바꿀 진료일 YYYY-MM-DD"
            },
            "new_visit_time": {
              "type": "string",
              "description": "바꿀 진료 시간 HH:MM"
            }
          }
        },
        "method": "POST",
        "messages": [
          {
            "type": "request-start",
            "content": "예약을 변경해 드릴게요."
          },
          {
            "type": "request-failed",
            "content": "죄송해요, 예약 변경이 처리되지 않았어요."
          },
          {
            "type": "request-response-delayed",
            "content": "변경 처리 중이에요. 조금만 기다려 주세요.",
            "timingMilliseconds": 4000
          }
        ],
        "timeoutSec": 15,
        "variableExtraction": {
          "schema": {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "result": {
                    "type": "object",
                    "properties": {
                      "room": {
                        "type": "string",
                        "description": "진료실"
                      },
                      "phone": {
                        "type": "string",
                        "description": "연락처"
                      },
                      "doctor": {
                        "type": "string",
                        "description": "담당 의사"
                      },
                      "status": {
                        "enum": [
                          "접수완료",
                          "진료중",
                          "진료완료",
                          "접수취소",
                          "노쇼"
                        ],
                        "type": "string",
                        "description": "접수상태"
                      },
                      "summary": {
                        "type": "string",
                        "description": "한 줄 요약"
                      },
                      "symptom": {
                        "type": "string",
                        "description": "증상"
                      },
                      "queue_no": {
                        "type": "integer",
                        "description": "대기순번"
                      },
                      "birth_date": {
                        "type": "string",
                        "description": "생년월일"
                      },
                      "created_at": {
                        "type": "string"
                      },
                      "updated_at": {
                        "type": "string"
                      },
                      "visit_date": {
                        "type": "string",
                        "description": "진료일 YYYY-MM-DD"
                      },
                      "visit_time": {
                        "type": "string",
                        "description": "진료시간 HH:MM"
                      },
                      "visit_type": {
                        "enum": [
                          "초진",
                          "재진"
                        ],
                        "type": "string",
                        "description": "초진/재진"
                      },
                      "consult_fee": {
                        "type": "integer",
                        "description": "진료비(원)"
                      },
                      "patient_name": {
                        "type": "string",
                        "description": "환자 이름"
                      },
                      "reception_no": {
                        "type": "string",
                        "description": "접수번호"
                      },
                      "cancel_reason": {
                        "type": "string",
                        "description": "취소 사유"
                      },
                      "department_code": {
                        "type": "string",
                        "description": "진료과 코드"
                      },
                      "department_name": {
                        "type": "string",
                        "description": "진료과 이름"
                      }
                    }
                  }
                },
                "description": "API 업무 응답 데이터"
              },
              "message": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                ],
                "description": "한국어 한 줄 요약(또는 검증 오류 다건). 음성 에이전트가 그대로 읽어줄 수 있다."
              },
              "status_code": {
                "type": "integer",
                "description": "HTTP 상태 코드와 동일"
              }
            }
          },
          "aliases": [
            {
              "key": "접수번호",
              "value": "{{ $.data.result.reception_no }}"
            },
            {
              "key": "환자명",
              "value": "{{ $.data.result.patient_name }}"
            },
            {
              "key": "연락처",
              "value": "{{ $.data.result.phone }}"
            },
            {
              "key": "생년월일",
              "value": "{{ $.data.result.birth_date }}"
            },
            {
              "key": "진료과코드",
              "value": "{{ $.data.result.department_code }}"
            },
            {
              "key": "진료과명",
              "value": "{{ $.data.result.department_name }}"
            },
            {
              "key": "담당의",
              "value": "{{ $.data.result.doctor }}"
            },
            {
              "key": "진료실",
              "value": "{{ $.data.result.room }}"
            },
            {
              "key": "방문일",
              "value": "{{ $.data.result.visit_date }}"
            },
            {
              "key": "방문시간",
              "value": "{{ $.data.result.visit_time }}"
            },
            {
              "key": "방문유형",
              "value": "{{ $.data.result.visit_type }}"
            },
            {
              "key": "증상",
              "value": "{{ $.data.result.symptom }}"
            },
            {
              "key": "상태",
              "value": "{{ $.data.result.status }}"
            },
            {
              "key": "대기번호",
              "value": "{{ $.data.result.queue_no }}"
            },
            {
              "key": "진료비",
              "value": "{{ $.data.result.consult_fee }}"
            },
            {
              "key": "취소사유",
              "value": "{{ $.data.result.cancel_reason }}"
            },
            {
              "key": "요약",
              "value": "{{ $.data.result.summary }}"
            },
            {
              "key": "생성일시",
              "value": "{{ $.data.result.created_at }}"
            },
            {
              "key": "수정일시",
              "value": "{{ $.data.result.updated_at }}"
            }
          ]
        }
      }
    },
    {
      "ref": "tool_3",
      "function_name": "mock_cancel_appointment",
      "name": "[병원] 예약 취소",
      "tool_type": "api_request",
      "endpoint_url": "https://api-mock.telloai.io/hospital/appointments/cancel",
      "http_method": "POST",
      "auth_type": "none",
      "request_schema": {
        "type": "object",
        "required": [
          "patient_name",
          "phone"
        ],
        "properties": {
          "patient_name": {
            "type": "string",
            "description": "환자 이름"
          },
          "phone": {
            "type": "string",
            "description": "환자 휴대폰 번호. 숫자만"
          },
          "reason": {
            "type": "string",
            "description": "취소 사유"
          }
        }
      },
      "description": "환자 이름과 휴대폰 번호로 찾은 예정 예약을 취소한다.",
      "timeout_sec": 15,
      "config": {
        "url": "https://api-mock.telloai.io/hospital/appointments/cancel",
        "body": {
          "type": "object",
          "required": [
            "patient_name",
            "phone"
          ],
          "properties": {
            "patient_name": {
              "type": "string",
              "description": "환자 이름"
            },
            "phone": {
              "type": "string",
              "description": "환자 휴대폰 번호. 숫자만"
            },
            "reason": {
              "type": "string",
              "description": "취소 사유"
            }
          }
        },
        "method": "POST",
        "messages": [
          {
            "type": "request-start",
            "content": "예약을 취소해 드릴게요."
          },
          {
            "type": "request-failed",
            "content": "죄송해요, 취소가 처리되지 않았어요."
          },
          {
            "type": "request-response-delayed",
            "content": "취소 처리 중이에요. 조금만 기다려 주세요.",
            "timingMilliseconds": 4000
          }
        ],
        "timeoutSec": 15,
        "variableExtraction": {
          "schema": {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "canceled": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "room": {
                          "type": "string"
                        },
                        "phone": {
                          "type": "string"
                        },
                        "doctor": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "summary": {
                          "type": "string"
                        },
                        "symptom": {
                          "type": "string"
                        },
                        "queue_no": {
                          "type": "integer"
                        },
                        "birth_date": {
                          "type": "string"
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "updated_at": {
                          "type": "string"
                        },
                        "visit_date": {
                          "type": "string"
                        },
                        "visit_time": {
                          "type": "string"
                        },
                        "visit_type": {
                          "type": "string"
                        },
                        "consult_fee": {
                          "type": "integer"
                        },
                        "patient_name": {
                          "type": "string"
                        },
                        "reception_no": {
                          "type": "string"
                        },
                        "cancel_reason": {
                          "type": "string"
                        },
                        "department_code": {
                          "type": "string"
                        },
                        "department_name": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "next_action": {
                    "type": "string"
                  },
                  "canceled_count": {
                    "type": "integer"
                  },
                  "remaining_count": {
                    "type": "integer"
                  },
                  "remaining_upcoming": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  }
                }
              },
              "message": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                ],
                "description": "한국어 한 줄 요약(또는 검증 오류 다건). 음성 에이전트가 그대로 읽어줄 수 있다."
              },
              "status_code": {
                "type": "integer",
                "description": "HTTP 상태 코드와 동일"
              }
            }
          },
          "aliases": [
            {
              "key": "취소건수",
              "value": "{{ $.data.canceled_count }}"
            },
            {
              "key": "남은건수",
              "value": "{{ $.data.remaining_count }}"
            },
            {
              "key": "다음단계",
              "value": "{{ $.data.next_action }}"
            }
          ]
        }
      }
    }
  ],
  "tool_refs": {
    "1": "tool_1",
    "2": "tool_2",
    "3": "tool_3"
  }
}
