{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "#/components/schemas/CreateApiRequestToolDTO",
  "title": "CreateApiRequestToolDTO",
  "type": "object",
  "properties": {
    "messages": {
      "type": "array",
      "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.",
      "items": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/ToolMessageStart",
            "title": "ToolMessageStart"
          },
          {
            "$ref": "#/components/schemas/ToolMessageComplete",
            "title": "ToolMessageComplete"
          },
          {
            "$ref": "#/components/schemas/ToolMessageFailed",
            "title": "ToolMessageFailed"
          },
          {
            "$ref": "#/components/schemas/ToolMessageDelayed",
            "title": "ToolMessageDelayed"
          }
        ]
      }
    },
    "type": {
      "type": "string",
      "enum": [
        "apiRequest"
      ],
      "description": "The type of tool. \"apiRequest\" for API request tool."
    },
    "method": {
      "type": "string",
      "enum": [
        "POST",
        "GET",
        "PUT",
        "PATCH",
        "DELETE"
      ]
    },
    "timeoutSeconds": {
      "type": "number",
      "description": "This is the timeout in seconds for the request. Defaults to 20 seconds.\n\n@default 20",
      "minimum": 1,
      "maximum": 300,
      "example": 20
    },
    "credentialId": {
      "type": "string",
      "description": "The credential ID for API request authentication",
      "example": "550e8400-e29b-41d4-a716-446655440000"
    },
    "encryptedPaths": {
      "type": "array",
      "description": "This is the paths to encrypt in the request body if credentialId and encryptionPlan are defined.",
      "items": {
        "type": "string"
      }
    },
    "parameters": {
      "description": "Static key-value pairs merged into the request body. Values support Liquid templates.",
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ToolParameter"
      }
    },
    "name": {
      "type": "string",
      "description": "This is the name of the tool. This will be passed to the model.\n\nMust be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 40.",
      "maxLength": 40,
      "pattern": "/^[a-zA-Z0-9_-]{1,40}$/"
    },
    "description": {
      "type": "string",
      "description": "This is the description of the tool. This will be passed to the model."
    },
    "url": {
      "type": "string",
      "description": "This is where the request will be sent."
    },
    "body": {
      "description": "This is the body of the request.",
      "allOf": [
        {
          "$ref": "#/components/schemas/JsonSchema"
        }
      ]
    },
    "headers": {
      "description": "These are the headers to send with the request.",
      "allOf": [
        {
          "$ref": "#/components/schemas/JsonSchema"
        }
      ]
    },
    "backoffPlan": {
      "description": "This is the backoff plan if the request fails. Defaults to undefined (the request will not be retried).\n\n@default undefined (the request will not be retried)",
      "allOf": [
        {
          "$ref": "#/components/schemas/BackoffPlan"
        }
      ]
    },
    "variableExtractionPlan": {
      "description": "This is the plan to extract variables from the tool's response. These will be accessible during the call and stored in `call.artifact.variableValues` after the call.\n\nUsage:\n1. Use `aliases` to extract variables from the tool's response body. (Most common case)\n\n```json\n{\n  \"aliases\": [\n    {\n      \"key\": \"customerName\",\n      \"value\": \"{{customer.name}}\"\n    },\n    {\n      \"key\": \"customerAge\",\n      \"value\": \"{{customer.age}}\"\n    }\n  ]\n}\n```\n\nThe tool response body is made available to the liquid template.\n\n2. Use `aliases` to extract variables from the tool's response body if the response is an array.\n\n```json\n{\n  \"aliases\": [\n    {\n      \"key\": \"customerName\",\n      \"value\": \"{{$[0].name}}\"\n    },\n    {\n      \"key\": \"customerAge\",\n      \"value\": \"{{$[0].age}}\"\n    }\n  ]\n}\n```\n\n$ is a shorthand for the tool's response body. `$[0]` is the first item in the array. `$[n]` is the nth item in the array. Note, $ is available regardless of the response body type (both object and array).\n\n3. Use `aliases` to extract variables from the tool's response headers.\n\n```json\n{\n  \"aliases\": [\n    {\n      \"key\": \"customerName\",\n      \"value\": \"{{tool.response.headers.customer-name}}\"\n    },\n    {\n      \"key\": \"customerAge\",\n      \"value\": \"{{tool.response.headers.customer-age}}\"\n    }\n  ]\n}\n```\n\n`tool.response` is made available to the liquid template. Particularly, both `tool.response.headers` and `tool.response.body` are available. Note, `tool.response` is available regardless of the response body type (both object and array).\n\n4. Use `schema` to extract a large portion of the tool's response body.\n\n4.1. If you hit example.com and it returns `{\"name\": \"John\", \"age\": 30}`, then you can specify the schema as:\n\n```json\n{\n  \"schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"name\": {\n        \"type\": \"string\"\n      },\n      \"age\": {\n        \"type\": \"number\"\n      }\n    }\n  }\n}\n```\nThese will be extracted as `{{ name }}` and `{{ age }}` respectively. To emphasize, object properties are extracted as direct global variables.\n\n4.2. If you hit example.com and it returns `{\"name\": {\"first\": \"John\", \"last\": \"Doe\"}}`, then you can specify the schema as:\n\n```json\n{\n  \"schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"name\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"first\": {\n            \"type\": \"string\"\n          },\n          \"last\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nThese will be extracted as `{{ name }}`. And, `{{ name.first }}` and `{{ name.last }}` will be accessible.\n\n4.3. If you hit example.com and it returns `[\"94123\", \"94124\"]`, then you can specify the schema as:\n\n```json\n{\n  \"schema\": {\n    \"type\": \"array\",\n    \"title\": \"zipCodes\",\n    \"items\": {\n      \"type\": \"string\"\n    }\n  }\n}\n```\n\nThis will be extracted as `{{ zipCodes }}`. To access the array items, you can use `{{ zipCodes[0] }}` and `{{ zipCodes[1] }}`.\n\n4.4. If you hit example.com and it returns `[{\"name\": \"John\", \"age\": 30, \"zipCodes\": [\"94123\", \"94124\"]}, {\"name\": \"Jane\", \"age\": 25, \"zipCodes\": [\"94125\", \"94126\"]}]`, then you can specify the schema as:\n\n```json\n{\n  \"schema\": {\n    \"type\": \"array\",\n    \"title\": \"people\",\n    \"items\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"age\": {\n          \"type\": \"number\"\n        },\n        \"zipCodes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nThis will be extracted as `{{ people }}`. To access the array items, you can use `{{ people[n].name }}`, `{{ people[n].age }}`, `{{ people[n].zipCodes }}`, `{{ people[n].zipCodes[0] }}` and `{{ people[n].zipCodes[1] }}`.\n\nNote: Both `aliases` and `schema` can be used together.",
      "allOf": [
        {
          "$ref": "#/components/schemas/VariableExtractionPlan"
        }
      ]
    },
    "rejectionPlan": {
      "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n  conditions: [{\n    type: 'regex',\n    regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n    target: { position: -1, role: 'user' },\n    negate: true  // Reject if pattern does NOT match\n  }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n  conditions: [{\n    type: 'regex',\n    regex: '\\\\?',\n    target: { position: -1, role: 'user' }\n  }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n  conditions: [{\n    type: 'liquid',\n    liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n  {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n    {% assign mentioned = true %}\n    {% break %}\n  {% endif %}\n{% endfor %}\n{% if mentioned %}\n  false\n{% else %}\n  true\n{% endif %}`\n  }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n  conditions: [{\n    type: 'liquid',\n    liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n  false\n{% else %}\n  {% assign msg1 = userMessages[0].content | downcase %}\n  {% assign msg2 = userMessages[1].content | downcase %}\n  {% assign msg3 = userMessages[2].content | downcase %}\n  {% comment %} Check for repetitive messages {% endcomment %}\n  {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n    true\n  {% comment %} Check for common loop phrases {% endcomment %}\n  {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n    true\n  {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n    true\n  {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n    true\n  {% else %}\n    false\n  {% endif %}\n{% endif %}`\n  }]\n}\n```",
      "allOf": [
        {
          "$ref": "#/components/schemas/ToolRejectionPlan"
        }
      ]
    }
  },
  "required": [
    "type",
    "method",
    "url"
  ]
}