{
  "$defs": {
    "personalityInline": {
      "additionalProperties": false,
      "description": "Inline caller personality, used for this run only \u2014 no personality is created in your workspace. Supply `base` to adjust one of your existing personalities, or omit it to define one from scratch.",
      "if": {
        "not": {
          "required": [
            "base"
          ]
        }
      },
      "properties": {
        "accent": {
          "maxLength": 255,
          "type": "string"
        },
        "background_noise": {
          "description": "'off', 'office', or a URL to a custom background audio clip.",
          "type": "string"
        },
        "base": {
          "description": "ID of an existing personality to layer these overrides onto. Must belong to your organization or be a Cekura-provided one. Omit to define a personality from scratch.",
          "minimum": 1,
          "type": "integer"
        },
        "end_call_enabled": {
          "type": "boolean"
        },
        "language": {
          "enum": [
            "af",
            "ar",
            "bg",
            "bn",
            "cs",
            "da",
            "de",
            "el",
            "en",
            "es",
            "et",
            "fi",
            "fr",
            "gu",
            "he",
            "hi",
            "hu",
            "id",
            "it",
            "ja",
            "kn",
            "ko",
            "ml",
            "mr",
            "ms",
            "multi",
            "nl",
            "no",
            "pa",
            "pl",
            "pt",
            "ro",
            "ru",
            "sk",
            "sv",
            "ta",
            "te",
            "th",
            "tl",
            "tr",
            "uk",
            "vi",
            "zh"
          ]
        },
        "name": {
          "maxLength": 255,
          "type": "string"
        },
        "prompt": {
          "description": "How the simulated caller behaves.",
          "minLength": 1,
          "type": "string"
        },
        "provider": {
          "enum": [
            "11labs",
            "cartesia"
          ]
        },
        "speed": {
          "description": "1.0 is normal pace.",
          "maximum": 1.2,
          "minimum": 0.8,
          "type": "number"
        },
        "voice_id": {
          "minLength": 1,
          "type": "string"
        },
        "voice_model": {
          "enum": [
            "eleven_flash_v2_5",
            "eleven_multilingual_v2",
            "eleven_turbo_v2_5",
            "sonic-3.5"
          ]
        }
      },
      "then": {
        "required": [
          "prompt",
          "language",
          "voice_model",
          "voice_id",
          "background_noise"
        ]
      },
      "type": "object"
    },
    "scenario": {
      "additionalProperties": false,
      "else": {
        "required": [
          "instructions"
        ]
      },
      "if": {
        "properties": {
          "type": {
            "const": "conditional_actions"
          }
        },
        "required": [
          "type"
        ]
      },
      "properties": {
        "conditional_actions": {
          "description": "Scripted turn-by-turn conditions. Required when type is 'conditional_actions'.",
          "type": "object"
        },
        "expected_outcome": {
          "description": "What a successful call looks like, in plain language.",
          "type": "string"
        },
        "first_message": {
          "type": "string"
        },
        "frequency": {
          "description": "How many times to run this test case. Defaults to 1.",
          "minimum": 1,
          "type": "integer"
        },
        "instructions": {
          "description": "What the simulated caller should do. Required unless this is a conditional_actions scenario.",
          "type": "string"
        },
        "key": {
          "description": "Stable identifier for this test case within the spec. Keep it constant across commits so results stay comparable over time.",
          "maxLength": 128,
          "type": "string"
        },
        "language": {
          "enum": [
            "af",
            "ar",
            "bg",
            "bn",
            "cs",
            "da",
            "de",
            "el",
            "en",
            "es",
            "et",
            "fi",
            "fr",
            "gu",
            "he",
            "hi",
            "hu",
            "id",
            "it",
            "ja",
            "kn",
            "ko",
            "ml",
            "mr",
            "ms",
            "multi",
            "nl",
            "no",
            "pa",
            "pl",
            "pt",
            "ro",
            "ru",
            "sk",
            "sv",
            "ta",
            "te",
            "th",
            "tl",
            "tr",
            "uk",
            "vi",
            "zh"
          ]
        },
        "max_duration": {
          "description": "Max call duration in seconds. Defaults to the project setting.",
          "minimum": 1,
          "type": "integer"
        },
        "metrics": {
          "items": {
            "description": "An existing metric in this project, by numeric ID or by slug. Metrics cannot be defined in a spec \u2014 create them in the dashboard first. Slugs keep a spec portable between projects; IDs pin exactly. The metric must be enabled for the target agent, otherwise it would not be evaluated.",
            "oneOf": [
              {
                "minimum": 1,
                "type": "integer"
              },
              {
                "minLength": 1,
                "pattern": "^[a-z0-9_]+$",
                "type": "string"
              }
            ]
          },
          "maxItems": 64,
          "type": "array"
        },
        "name": {
          "maxLength": 80,
          "minLength": 1,
          "type": "string"
        },
        "personality": {
          "oneOf": [
            {
              "description": "ID of an existing personality \u2014 yours or a Cekura-provided one.",
              "minimum": 1,
              "type": "integer"
            },
            {
              "$ref": "#/$defs/personalityInline"
            }
          ]
        },
        "tags": {
          "items": {
            "maxLength": 64,
            "type": "string"
          },
          "maxItems": 32,
          "type": "array"
        },
        "test_profile": {
          "oneOf": [
            {
              "description": "ID of an existing test profile on this agent or its project.",
              "minimum": 1,
              "type": "integer"
            },
            {
              "$ref": "#/$defs/testProfileInline"
            }
          ]
        },
        "tools": {
          "items": {
            "enum": [
              "call_hold",
              "dtmf",
              "end_call",
              "end_call_only_on_transfer",
              "receive_dtmf",
              "send_sms"
            ]
          },
          "maxItems": 16,
          "type": "array"
        },
        "type": {
          "description": "Defaults to 'instruction'.",
          "enum": [
            "conditional_actions",
            "instruction",
            "real_world_fixed",
            "real_world_smart"
          ]
        }
      },
      "required": [
        "name"
      ],
      "then": {
        "required": [
          "conditional_actions",
          "language"
        ]
      },
      "type": "object"
    },
    "testProfileInline": {
      "additionalProperties": false,
      "description": "Inline test data, used for this run only \u2014 no test profile is created in your workspace.",
      "minProperties": 1,
      "properties": {
        "agent_variables": {
          "description": "Dynamic variables delivered to the agent under test at call time.",
          "type": "object"
        },
        "caller_variables": {
          "description": "Context for the simulated caller only. Never sent to the agent under test. Reference these in instructions as {{test_profile.<key>}}.",
          "type": "object"
        },
        "name": {
          "maxLength": 255,
          "type": "string"
        }
      },
      "type": "object"
    }
  },
  "$id": "https://docs.cekura.ai/schemas/test-suite/v1.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "description": "A suite of agent test cases, versioned in your repository and run from CI. The file describes what to test; which agent to run it against and how to reach that agent are supplied by the request, so one file works unchanged across agents and environments. Nothing in this file is saved as an evaluator in your workspace.",
  "properties": {
    "$schema": {
      "type": "string"
    },
    "defaults": {
      "additionalProperties": false,
      "description": "Applied to every test case unless the test case overrides it.",
      "properties": {
        "concurrency_limit": {
          "minimum": 1,
          "type": "integer"
        },
        "frequency": {
          "minimum": 1,
          "type": "integer"
        },
        "language": {
          "enum": [
            "af",
            "ar",
            "bg",
            "bn",
            "cs",
            "da",
            "de",
            "el",
            "en",
            "es",
            "et",
            "fi",
            "fr",
            "gu",
            "he",
            "hi",
            "hu",
            "id",
            "it",
            "ja",
            "kn",
            "ko",
            "ml",
            "mr",
            "ms",
            "multi",
            "nl",
            "no",
            "pa",
            "pl",
            "pt",
            "ro",
            "ru",
            "sk",
            "sv",
            "ta",
            "te",
            "th",
            "tl",
            "tr",
            "uk",
            "vi",
            "zh"
          ]
        },
        "max_duration": {
          "minimum": 1,
          "type": "integer"
        },
        "metrics": {
          "items": {
            "description": "An existing metric in this project, by numeric ID or by slug. Metrics cannot be defined in a spec \u2014 create them in the dashboard first. Slugs keep a spec portable between projects; IDs pin exactly. The metric must be enabled for the target agent, otherwise it would not be evaluated.",
            "oneOf": [
              {
                "minimum": 1,
                "type": "integer"
              },
              {
                "minLength": 1,
                "pattern": "^[a-z0-9_]+$",
                "type": "string"
              }
            ]
          },
          "maxItems": 64,
          "type": "array"
        },
        "personality": {
          "oneOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "$ref": "#/$defs/personalityInline"
            }
          ]
        },
        "tags": {
          "items": {
            "maxLength": 64,
            "type": "string"
          },
          "maxItems": 32,
          "type": "array"
        },
        "test_profile": {
          "oneOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "$ref": "#/$defs/testProfileInline"
            }
          ]
        }
      },
      "type": "object"
    },
    "scenarios": {
      "items": {
        "$ref": "#/$defs/scenario"
      },
      "maxItems": 200,
      "minItems": 1,
      "type": "array"
    },
    "suite": {
      "additionalProperties": false,
      "properties": {
        "description": {
          "type": "string"
        },
        "name": {
          "maxLength": 255,
          "type": "string"
        }
      },
      "type": "object"
    },
    "version": {
      "const": "1",
      "description": "Spec format version. Pin this; new formats ship as new versions."
    }
  },
  "required": [
    "version",
    "scenarios"
  ],
  "title": "Cekura test suite",
  "type": "object"
}
