{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://example.com/ner-comparison-tool-schema.json",
  "title": "NER Comparison Tool Data Schema",
  "description": "Schema for NER model comparison and annotation data",
  "type": "object",
  "required": ["examples", "modelNames"],
  "properties": {
    "schemaVersion": {
      "type": "integer",
      "const": 2,
      "description": "Schema version. v2 introduces the examples/confidence vocabulary."
    },
    "examples": {
      "type": "array",
      "description": "Array of example texts with their entity annotations",
      "items": {
        "$ref": "#/definitions/example"
      }
    },
    "modelNames": {
      "type": "array",
      "description": "List of model names included in this dataset",
      "items": {
        "type": "string"
      }
    },
    "customLabelColors": {
      "type": "object",
      "description": "Custom color definitions for entity labels",
      "additionalProperties": {
        "type": "string",
        "description": "CSS color class or custom color format (e.g., 'entity-disease' or 'bg:#fee2e2|text:#991b1b|border:#dc2626')"
      }
    },
    "savedThemes": {
      "type": "array",
      "description": "Saved custom color themes for reuse",
      "items": {
        "$ref": "#/definitions/customTheme"
      }
    },
    "labelDefinitions": {
      "type": "object",
      "description": "Per-label annotation guidelines. Map of label name to a definition (description, positive examples, counter-examples) used to keep annotators consistent.",
      "additionalProperties": {
        "$ref": "#/definitions/labelDefinition"
      }
    }
  },
  "definitions": {
    "labelDefinition": {
      "type": "object",
      "description": "Annotation guidance for one label.",
      "properties": {
        "description": {
          "type": "string",
          "description": "Markdown body for the label. Sanitized at render time."
        },
        "examples": {
          "type": "array",
          "description": "Plain-string positive examples. Shown with a green check.",
          "items": { "type": "string" }
        },
        "counterExamples": {
          "type": "array",
          "description": "Plain-string counter-examples. Shown with a red cross.",
          "items": { "type": "string" }
        }
      }
    },
    "example": {
      "type": "object",
      "required": ["id", "text", "modelResponses"],
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique identifier for the example"
        },
        "text": {
          "type": "string",
          "description": "The example text to be analyzed"
        },
        "modelResponses": {
          "type": "array",
          "description": "Entity recognition results from each model",
          "items": {
            "$ref": "#/definitions/modelResponse"
          }
        },
        "humanAnnotations": {
          "type": "array",
          "description": "Optional human-created annotations for this text",
          "items": {
            "$ref": "#/definitions/entity"
          }
        },
        "rejectedPredictions": {
          "type": "array",
          "description": "Predictions the user has rejected (each entry pairs a model with the rejected entity). Excluded from false-positive counts and from the errors-vs-gold filter.",
          "items": {
            "$ref": "#/definitions/rejectedPrediction"
          }
        }
      }
    },
    "rejectedPrediction": {
      "type": "object",
      "required": ["modelName", "entity"],
      "properties": {
        "modelName": {
          "type": "string",
          "description": "Name of the model whose prediction was rejected"
        },
        "entity": {
          "$ref": "#/definitions/entity",
          "description": "The rejected predicted entity"
        }
      }
    },
    "modelResponse": {
      "type": "object",
      "required": ["modelName", "entities"],
      "properties": {
        "modelName": {
          "type": "string",
          "description": "Name of the model that produced these entities"
        },
        "entities": {
          "type": "array",
          "description": "Entities extracted by this model",
          "items": {
            "$ref": "#/definitions/entity"
          }
        },
        "inferenceTime": {
          "type": "number",
          "description": "Optional inference time in seconds",
          "minimum": 0
        }
      }
    },
    "entity": {
      "type": "object",
      "required": ["text", "label"],
      "properties": {
        "text": {
          "type": "string",
          "description": "The entity text as it appears in the example"
        },
        "label": {
          "type": "string",
          "description": "The entity type/category label"
        },
        "start": {
          "type": "integer",
          "description": "Optional start character position in the text",
          "minimum": 0
        },
        "end": {
          "type": "integer",
          "description": "Optional end character position in the text",
          "minimum": 0
        },
        "confidence": {
          "type": "number",
          "description": "Optional confidence score (0.0 to 1.0)",
          "minimum": 0,
          "maximum": 1
        }
      }
    },
    "customTheme": {
      "type": "object",
      "required": ["id", "name", "bgColor", "textColor", "borderColor"],
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique identifier for the theme"
        },
        "name": {
          "type": "string",
          "description": "Display name for the theme"
        },
        "bgColor": {
          "type": "string",
          "description": "Background color in hex format (e.g., '#fee2e2')",
          "pattern": "^#[0-9A-Fa-f]{6}$"
        },
        "textColor": {
          "type": "string",
          "description": "Text color in hex format (e.g., '#991b1b')",
          "pattern": "^#[0-9A-Fa-f]{6}$"
        },
        "borderColor": {
          "type": "string",
          "description": "Border color in hex format (e.g., '#dc2626')",
          "pattern": "^#[0-9A-Fa-f]{6}$"
        }
      }
    }
  },
  "examples": [
    {
      "schemaVersion": 2,
      "examples": [
        {
          "id": "q1",
          "text": "Patient has diabetes and hypertension",
          "modelResponses": [
            {
              "modelName": "GLiNER BioMed",
              "inferenceTime": 0.123,
              "entities": [
                {
                  "text": "diabetes",
                  "label": "Current disease",
                  "start": 12,
                  "end": 20,
                  "confidence": 0.95
                },
                {
                  "text": "hypertension",
                  "label": "Current disease",
                  "start": 25,
                  "end": 37,
                  "confidence": 0.89
                }
              ]
            },
            {
              "modelName": "Medical NER",
              "inferenceTime": 0.087,
              "entities": [
                {
                  "text": "diabetes",
                  "label": "DISEASE_DISORDER",
                  "start": 12,
                  "end": 20
                },
                {
                  "text": "hypertension",
                  "label": "DISEASE_DISORDER",
                  "start": 25,
                  "end": 37
                }
              ]
            }
          ],
          "humanAnnotations": [
            {
              "text": "diabetes",
              "label": "Disease",
              "start": 12,
              "end": 20
            }
          ]
        }
      ],
      "modelNames": ["GLiNER BioMed", "Medical NER"],
      "customLabelColors": {
        "Disease": "entity-disease",
        "Custom Label": "bg:#dbeafe|text:#1e40af|border:#3b82f6"
      },
      "savedThemes": [
        {
          "id": "theme-123",
          "name": "Custom",
          "bgColor": "#dbeafe",
          "textColor": "#1e40af",
          "borderColor": "#3b82f6"
        }
      ]
    }
  ]
}
