{
  "$schema": "https://json-schema.org/draft/2019-09/schema",
  "$id": "https://www.krakend.io/schema/v3.0/ai/classifiers.json",
  "title": "AI Router Gates and Classifiers",
  "description": "Declares once, at the service level, the reusable gates and classifiers of the AI router. The `ai/router` of each backend references them by `name`, so you define every condition and engine once and reuse it across routes.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
  "type": "object",
  "properties": {
    "classifiers": {
      "title": "Classifiers",
      "description": "The list of classifiers available to the routes. A classifier delegates the provider choice to an external engine that scores the request against the candidate `providers` of a route and returns the best fit.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
      "type": "array",
      "items": {
        "type": "object",
        "if": {
          "required": [ "engine" ],
          "properties": {
            "engine": {
              "const": "notdiamond"
            }
          }
        },
        "then": {
          "required": [ "notdiamond" ]
        },
        "required": [ "name", "engine" ],
        "properties": {
          "engine": {
            "title": "Classification Engine",
            "description": "The external engine that chooses the provider. The `notdiamond` engine calls the Not Diamond model selection endpoint, and requires you to add its configuration under the `notdiamond` key.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
            "const": "notdiamond"
          },
          "name": {
            "title": "Classifier Name",
            "description": "A unique name for this classifier. Routes reference the classifier through this value in their `classifier` field.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
            "examples": [ "smart" ],
            "type": "string",
            "minLength": 1
          },
          "notdiamond": {
            "title": "Not Diamond Engine",
            "description": "The configuration of the `notdiamond` engine, which calls the Not Diamond model selection endpoint to pick the best provider from the candidates of the route. Set either `tradeoff` or `cost_quality_tradeoff`, but not both.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
            "type": "object",
            "not": {
              "required": [ "tradeoff", "cost_quality_tradeoff" ]
            },
            "required": [ "credentials" ],
            "properties": {
              "base_url": {
                "title": "Base URL",
                "description": "The base URL of the Not Diamond API. Override it only when you target a custom or proxied deployment of the service.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "examples": [ "https://api.example.com" ],
                "type": "string"
              },
              "cost_quality_tradeoff": {
                "title": "Cost and Quality Tradeoff",
                "description": "An integer that balances cost against quality in the model selection. You cannot use it together with `tradeoff`.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "default": 0,
                "type": "integer"
              },
              "credentials": {
                "title": "Credentials",
                "description": "The API key that authenticates KrakenD against the Not Diamond service. Set it through an environment variable instead of writing it in the configuration file.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "type": "string",
                "minLength": 1
              },
              "disable_hash_content": {
                "title": "Disable Content Hashing",
                "description": "KrakenD asks the Not Diamond API to hash the request content it receives, for extra security. Set this flag to `true` to turn that option off, and Not Diamond uses its own default of not hashing the content.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "default": false,
                "type": "boolean"
              },
              "metric": {
                "title": "Metric",
                "description": "The metric the engine optimizes for when it chooses the provider.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "default": "accuracy",
                "const": "accuracy"
              },
              "req_content": {
                "title": "Request Content",
                "description": "The part of the request that KrakenD sends to the classifier. It works like the same field in the semantic cache: use `req_body` with dot-notation to reach nested fields, or `req_params`, `req_query_string`, and `req_headers`. Path parameters are capitalized, so `{id}` becomes `req_params.Id`. When you don't set it, KrakenD sends the entire request body.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "examples": [
                  "req_body.messages",
                  "req_params.Id",
                  "req_headers.x-user",
                  "req_query_string.user"
                ],
                "type": "string"
              },
              "tradeoff": {
                "title": "Tradeoff",
                "description": "The optimization preference of the model selection. Use `cost` to favor cheaper providers or `latency` to favor faster ones. You cannot use it together with `cost_quality_tradeoff`.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "default": "cost",
                "enum": [ "cost", "latency" ]
              }
            },
            "patternProperties": {
              "^[@$_#]": true
            },
            "additionalProperties": false
          }
        },
        "patternProperties": {
          "^[@$_#]": true
        },
        "additionalProperties": false
      }
    },
    "gates": {
      "title": "Gates",
      "description": "The list of gates available to the routes. A gate is a named matching condition, and a route matches only when all the gates it lists pass. Header gates match on values the client controls, so route on headers your gateway sets after validating an API key or a JWT.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
      "type": "array",
      "items": {
        "type": "object",
        "allOf": [
          {
            "if": {
              "required": [ "rule" ],
              "properties": {
                "rule": {
                  "const": "header"
                }
              }
            },
            "then": {
              "required": [ "header" ],
              "properties": {
                "header": true
              }
            }
          }
        ],
        "if": {
          "required": [ "rule" ],
          "properties": {
            "rule": {
              "const": "policy"
            }
          }
        },
        "then": {
          "required": [ "policy" ]
        },
        "required": [ "name", "rule" ],
        "properties": {
          "header": {
            "title": "Header Rule",
            "description": "The configuration of a `header` rule. The gate passes when the request header `name` equals `value`. Add the header to the `input_headers` of the endpoint so the router can see it.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
            "type": "object",
            "required": [ "name", "value" ],
            "properties": {
              "name": {
                "title": "Header Name",
                "description": "The name of the request header you want to inspect.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "examples": [ "X-Plan" ],
                "type": "string",
                "minLength": 1
              },
              "value": {
                "title": "Header Value",
                "description": "The value the header must have for the gate to pass.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "examples": [ "enterprise" ],
                "type": "string"
              }
            },
            "patternProperties": {
              "^[@$_#]": true
            },
            "additionalProperties": false
          },
          "name": {
            "title": "Gate Name",
            "description": "A unique name for this gate. Routes reference the gate through this value in their `gates` list.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
            "examples": [ "plan_enterprise" ],
            "type": "string",
            "minLength": 1
          },
          "policy": {
            "title": "Policy Rule",
            "description": "The configuration of a `policy` rule. The gate passes when the CEL expression in `value` evaluates to `true`.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
            "type": "object",
            "required": [ "value" ],
            "properties": {
              "value": {
                "title": "Policy Expression",
                "description": "The CEL expression to evaluate. You can use the built-in functions of the security policies, such as `hasHeader` and `getHeader`, to compare values or combine several checks that a header rule cannot express.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
                "examples": [ "getHeader('X-Plan') == 'enterprise'" ],
                "type": "string",
                "minLength": 1
              }
            },
            "patternProperties": {
              "^[@$_#]": true
            },
            "additionalProperties": false
          },
          "rule": {
            "title": "Matching Rule",
            "description": "The mechanism the gate uses to match the request. Use `header` to compare a request header with a value, or `policy` to evaluate a CEL expression. Each rule requires its configuration under the key with the same name.\n\nSee: https://www.krakend.io/docs/enterprise/ai-gateway/ai-router/",
            "enum": [ "header", "policy" ]
          }
        },
        "patternProperties": {
          "^[@$_#]": true
        },
        "additionalProperties": false
      }
    }
  },
  "patternProperties": {
    "^[@$_#]": true
  },
  "additionalProperties": false
}
