{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://omni.local/contracts/media-job.schema.json",
  "title": "OMNI Media Job Contract v1",
  "description": "Request, acknowledgement and observable state of an on-demand image or video job.",
  "oneOf": [
    {
      "$ref": "#/$defs/MediaJobRequest"
    },
    {
      "$ref": "#/$defs/MediaJobAccepted"
    },
    {
      "$ref": "#/$defs/MediaJobView"
    }
  ],
  "$defs": {
    "id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 160,
      "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]*$"
    },
    "kind": {
      "enum": [
        "video",
        "image"
      ]
    },
    "status": {
      "enum": [
        "created",
        "queued",
        "loading",
        "ready",
        "running",
        "cancelling",
        "completed",
        "failed",
        "cancelled",
        "unloading"
      ]
    },
    "MediaJobRequest": {
      "title": "MediaJobRequest",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "kind",
        "prompt",
        "session_id",
        "turn_id",
        "trace_id"
      ],
      "properties": {
        "kind": {
          "$ref": "#/$defs/kind"
        },
        "prompt": {
          "type": "string",
          "minLength": 1,
          "maxLength": 32000
        },
        "session_id": {
          "$ref": "#/$defs/id"
        },
        "turn_id": {
          "$ref": "#/$defs/id"
        },
        "trace_id": {
          "$ref": "#/$defs/id"
        },
        "options": {
          "type": "object",
          "default": {}
        }
      }
    },
    "MediaJobAccepted": {
      "title": "MediaJobAccepted",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "job_id"
      ],
      "properties": {
        "job_id": {
          "$ref": "#/$defs/id"
        }
      }
    },
    "MediaArtifact": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "artifact_id",
        "url",
        "mime_type"
      ],
      "properties": {
        "artifact_id": {
          "$ref": "#/$defs/id"
        },
        "url": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "not": {
            "pattern": "^data:"
          }
        },
        "mime_type": {
          "type": "string",
          "minLength": 3,
          "maxLength": 160,
          "pattern": "^[a-z0-9.+-]+/[a-z0-9.+-]+$"
        }
      }
    },
    "MediaJobView": {
      "title": "MediaJobView",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "job_id",
        "kind",
        "status",
        "created_at",
        "updated_at",
        "artifacts"
      ],
      "properties": {
        "job_id": {
          "$ref": "#/$defs/id"
        },
        "kind": {
          "$ref": "#/$defs/kind"
        },
        "status": {
          "$ref": "#/$defs/status"
        },
        "progress": {
          "oneOf": [
            {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "created_at": {
          "type": "string",
          "format": "date-time"
        },
        "updated_at": {
          "type": "string",
          "format": "date-time"
        },
        "artifacts": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/MediaArtifact"
          },
          "default": []
        },
        "error": {
          "oneOf": [
            {
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        }
      }
    }
  },
  "examples": [
    {
      "kind": "image",
      "prompt": "Eine ruhige minimalistische Landschaft",
      "session_id": "session_demo",
      "turn_id": "turn_8",
      "trace_id": "trace_8",
      "options": {
        "aspect_ratio": "1:1"
      }
    }
  ]
}
