{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://clawdis.dev/protocol.schema.json",
  "title": "Clawdis Gateway Protocol",
  "description": "Handshake, request/response, and event frames for the Gateway WebSocket.",
  "oneOf": [
    {
      "$ref": "#/definitions/Hello"
    },
    {
      "$ref": "#/definitions/HelloOk"
    },
    {
      "$ref": "#/definitions/HelloError"
    },
    {
      "$ref": "#/definitions/RequestFrame"
    },
    {
      "$ref": "#/definitions/ResponseFrame"
    },
    {
      "$ref": "#/definitions/EventFrame"
    }
  ],
  "discriminator": {
    "propertyName": "type",
    "mapping": {
      "hello": "#/definitions/Hello",
      "hello-ok": "#/definitions/HelloOk",
      "hello-error": "#/definitions/HelloError",
      "req": "#/definitions/RequestFrame",
      "res": "#/definitions/ResponseFrame",
      "event": "#/definitions/EventFrame"
    }
  },
  "definitions": {
    "Hello": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "type": {
          "const": "hello",
          "type": "string"
        },
        "minProtocol": {
          "minimum": 1,
          "type": "integer"
        },
        "maxProtocol": {
          "minimum": 1,
          "type": "integer"
        },
        "client": {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "name": {
              "minLength": 1,
              "type": "string"
            },
            "version": {
              "minLength": 1,
              "type": "string"
            },
            "platform": {
              "minLength": 1,
              "type": "string"
            },
            "mode": {
              "minLength": 1,
              "type": "string"
            },
            "instanceId": {
              "minLength": 1,
              "type": "string"
            }
          },
          "required": [
            "name",
            "version",
            "platform",
            "mode"
          ]
        },
        "caps": {
          "default": [],
          "type": "array",
          "items": {
            "minLength": 1,
            "type": "string"
          }
        },
        "auth": {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "token": {
              "type": "string"
            }
          }
        },
        "locale": {
          "type": "string"
        },
        "userAgent": {
          "type": "string"
        }
      },
      "required": [
        "type",
        "minProtocol",
        "maxProtocol",
        "client"
      ]
    },
    "HelloOk": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "type": {
          "const": "hello-ok",
          "type": "string"
        },
        "protocol": {
          "minimum": 1,
          "type": "integer"
        },
        "server": {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "version": {
              "minLength": 1,
              "type": "string"
            },
            "commit": {
              "minLength": 1,
              "type": "string"
            },
            "host": {
              "minLength": 1,
              "type": "string"
            },
            "connId": {
              "minLength": 1,
              "type": "string"
            }
          },
          "required": [
            "version",
            "connId"
          ]
        },
        "features": {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "methods": {
              "type": "array",
              "items": {
                "minLength": 1,
                "type": "string"
              }
            },
            "events": {
              "type": "array",
              "items": {
                "minLength": 1,
                "type": "string"
              }
            }
          },
          "required": [
            "methods",
            "events"
          ]
        },
        "snapshot": {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "presence": {
              "type": "array",
              "items": {
                "additionalProperties": false,
                "type": "object",
                "properties": {
                  "host": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "ip": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "version": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "mode": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "lastInputSeconds": {
                    "minimum": 0,
                    "type": "integer"
                  },
                  "reason": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "text": {
                    "type": "string"
                  },
                  "ts": {
                    "minimum": 0,
                    "type": "integer"
                  },
                  "instanceId": {
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "required": [
                  "ts"
                ]
              }
            },
            "health": {},
            "stateVersion": {
              "additionalProperties": false,
              "type": "object",
              "properties": {
                "presence": {
                  "minimum": 0,
                  "type": "integer"
                },
                "health": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "required": [
                "presence",
                "health"
              ]
            },
            "uptimeMs": {
              "minimum": 0,
              "type": "integer"
            }
          },
          "required": [
            "presence",
            "health",
            "stateVersion",
            "uptimeMs"
          ]
        },
        "policy": {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "maxPayload": {
              "minimum": 1,
              "type": "integer"
            },
            "maxBufferedBytes": {
              "minimum": 1,
              "type": "integer"
            },
            "tickIntervalMs": {
              "minimum": 1,
              "type": "integer"
            }
          },
          "required": [
            "maxPayload",
            "maxBufferedBytes",
            "tickIntervalMs"
          ]
        }
      },
      "required": [
        "type",
        "protocol",
        "server",
        "features",
        "snapshot",
        "policy"
      ]
    },
    "HelloError": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "type": {
          "const": "hello-error",
          "type": "string"
        },
        "reason": {
          "minLength": 1,
          "type": "string"
        },
        "expectedProtocol": {
          "minimum": 1,
          "type": "integer"
        },
        "minClient": {
          "minLength": 1,
          "type": "string"
        }
      },
      "required": [
        "type",
        "reason"
      ]
    },
    "RequestFrame": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "type": {
          "const": "req",
          "type": "string"
        },
        "id": {
          "minLength": 1,
          "type": "string"
        },
        "method": {
          "minLength": 1,
          "type": "string"
        },
        "params": {}
      },
      "required": [
        "type",
        "id",
        "method"
      ]
    },
    "ResponseFrame": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "type": {
          "const": "res",
          "type": "string"
        },
        "id": {
          "minLength": 1,
          "type": "string"
        },
        "ok": {
          "type": "boolean"
        },
        "payload": {},
        "error": {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "code": {
              "minLength": 1,
              "type": "string"
            },
            "message": {
              "minLength": 1,
              "type": "string"
            },
            "details": {},
            "retryable": {
              "type": "boolean"
            },
            "retryAfterMs": {
              "minimum": 0,
              "type": "integer"
            }
          },
          "required": [
            "code",
            "message"
          ]
        }
      },
      "required": [
        "type",
        "id",
        "ok"
      ]
    },
    "EventFrame": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "type": {
          "const": "event",
          "type": "string"
        },
        "event": {
          "minLength": 1,
          "type": "string"
        },
        "payload": {},
        "seq": {
          "minimum": 0,
          "type": "integer"
        },
        "stateVersion": {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "presence": {
              "minimum": 0,
              "type": "integer"
            },
            "health": {
              "minimum": 0,
              "type": "integer"
            }
          },
          "required": [
            "presence",
            "health"
          ]
        }
      },
      "required": [
        "type",
        "event"
      ]
    },
    "GatewayFrame": {
      "discriminator": "type",
      "anyOf": [
        {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "type": {
              "const": "hello",
              "type": "string"
            },
            "minProtocol": {
              "minimum": 1,
              "type": "integer"
            },
            "maxProtocol": {
              "minimum": 1,
              "type": "integer"
            },
            "client": {
              "additionalProperties": false,
              "type": "object",
              "properties": {
                "name": {
                  "minLength": 1,
                  "type": "string"
                },
                "version": {
                  "minLength": 1,
                  "type": "string"
                },
                "platform": {
                  "minLength": 1,
                  "type": "string"
                },
                "mode": {
                  "minLength": 1,
                  "type": "string"
                },
                "instanceId": {
                  "minLength": 1,
                  "type": "string"
                }
              },
              "required": [
                "name",
                "version",
                "platform",
                "mode"
              ]
            },
            "caps": {
              "default": [],
              "type": "array",
              "items": {
                "minLength": 1,
                "type": "string"
              }
            },
            "auth": {
              "additionalProperties": false,
              "type": "object",
              "properties": {
                "token": {
                  "type": "string"
                }
              }
            },
            "locale": {
              "type": "string"
            },
            "userAgent": {
              "type": "string"
            }
          },
          "required": [
            "type",
            "minProtocol",
            "maxProtocol",
            "client"
          ]
        },
        {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "type": {
              "const": "hello-ok",
              "type": "string"
            },
            "protocol": {
              "minimum": 1,
              "type": "integer"
            },
            "server": {
              "additionalProperties": false,
              "type": "object",
              "properties": {
                "version": {
                  "minLength": 1,
                  "type": "string"
                },
                "commit": {
                  "minLength": 1,
                  "type": "string"
                },
                "host": {
                  "minLength": 1,
                  "type": "string"
                },
                "connId": {
                  "minLength": 1,
                  "type": "string"
                }
              },
              "required": [
                "version",
                "connId"
              ]
            },
            "features": {
              "additionalProperties": false,
              "type": "object",
              "properties": {
                "methods": {
                  "type": "array",
                  "items": {
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "events": {
                  "type": "array",
                  "items": {
                    "minLength": 1,
                    "type": "string"
                  }
                }
              },
              "required": [
                "methods",
                "events"
              ]
            },
            "snapshot": {
              "additionalProperties": false,
              "type": "object",
              "properties": {
                "presence": {
                  "type": "array",
                  "items": {
                    "additionalProperties": false,
                    "type": "object",
                    "properties": {
                      "host": {
                        "minLength": 1,
                        "type": "string"
                      },
                      "ip": {
                        "minLength": 1,
                        "type": "string"
                      },
                      "version": {
                        "minLength": 1,
                        "type": "string"
                      },
                      "mode": {
                        "minLength": 1,
                        "type": "string"
                      },
                      "lastInputSeconds": {
                        "minimum": 0,
                        "type": "integer"
                      },
                      "reason": {
                        "minLength": 1,
                        "type": "string"
                      },
                      "tags": {
                        "type": "array",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "text": {
                        "type": "string"
                      },
                      "ts": {
                        "minimum": 0,
                        "type": "integer"
                      },
                      "instanceId": {
                        "minLength": 1,
                        "type": "string"
                      }
                    },
                    "required": [
                      "ts"
                    ]
                  }
                },
                "health": {},
                "stateVersion": {
                  "additionalProperties": false,
                  "type": "object",
                  "properties": {
                    "presence": {
                      "minimum": 0,
                      "type": "integer"
                    },
                    "health": {
                      "minimum": 0,
                      "type": "integer"
                    }
                  },
                  "required": [
                    "presence",
                    "health"
                  ]
                },
                "uptimeMs": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "required": [
                "presence",
                "health",
                "stateVersion",
                "uptimeMs"
              ]
            },
            "policy": {
              "additionalProperties": false,
              "type": "object",
              "properties": {
                "maxPayload": {
                  "minimum": 1,
                  "type": "integer"
                },
                "maxBufferedBytes": {
                  "minimum": 1,
                  "type": "integer"
                },
                "tickIntervalMs": {
                  "minimum": 1,
                  "type": "integer"
                }
              },
              "required": [
                "maxPayload",
                "maxBufferedBytes",
                "tickIntervalMs"
              ]
            }
          },
          "required": [
            "type",
            "protocol",
            "server",
            "features",
            "snapshot",
            "policy"
          ]
        },
        {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "type": {
              "const": "hello-error",
              "type": "string"
            },
            "reason": {
              "minLength": 1,
              "type": "string"
            },
            "expectedProtocol": {
              "minimum": 1,
              "type": "integer"
            },
            "minClient": {
              "minLength": 1,
              "type": "string"
            }
          },
          "required": [
            "type",
            "reason"
          ]
        },
        {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "type": {
              "const": "req",
              "type": "string"
            },
            "id": {
              "minLength": 1,
              "type": "string"
            },
            "method": {
              "minLength": 1,
              "type": "string"
            },
            "params": {}
          },
          "required": [
            "type",
            "id",
            "method"
          ]
        },
        {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "type": {
              "const": "res",
              "type": "string"
            },
            "id": {
              "minLength": 1,
              "type": "string"
            },
            "ok": {
              "type": "boolean"
            },
            "payload": {},
            "error": {
              "additionalProperties": false,
              "type": "object",
              "properties": {
                "code": {
                  "minLength": 1,
                  "type": "string"
                },
                "message": {
                  "minLength": 1,
                  "type": "string"
                },
                "details": {},
                "retryable": {
                  "type": "boolean"
                },
                "retryAfterMs": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "required": [
                "code",
                "message"
              ]
            }
          },
          "required": [
            "type",
            "id",
            "ok"
          ]
        },
        {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "type": {
              "const": "event",
              "type": "string"
            },
            "event": {
              "minLength": 1,
              "type": "string"
            },
            "payload": {},
            "seq": {
              "minimum": 0,
              "type": "integer"
            },
            "stateVersion": {
              "additionalProperties": false,
              "type": "object",
              "properties": {
                "presence": {
                  "minimum": 0,
                  "type": "integer"
                },
                "health": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "required": [
                "presence",
                "health"
              ]
            }
          },
          "required": [
            "type",
            "event"
          ]
        }
      ]
    },
    "PresenceEntry": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "host": {
          "minLength": 1,
          "type": "string"
        },
        "ip": {
          "minLength": 1,
          "type": "string"
        },
        "version": {
          "minLength": 1,
          "type": "string"
        },
        "mode": {
          "minLength": 1,
          "type": "string"
        },
        "lastInputSeconds": {
          "minimum": 0,
          "type": "integer"
        },
        "reason": {
          "minLength": 1,
          "type": "string"
        },
        "tags": {
          "type": "array",
          "items": {
            "minLength": 1,
            "type": "string"
          }
        },
        "text": {
          "type": "string"
        },
        "ts": {
          "minimum": 0,
          "type": "integer"
        },
        "instanceId": {
          "minLength": 1,
          "type": "string"
        }
      },
      "required": [
        "ts"
      ]
    },
    "StateVersion": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "presence": {
          "minimum": 0,
          "type": "integer"
        },
        "health": {
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "presence",
        "health"
      ]
    },
    "Snapshot": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "presence": {
          "type": "array",
          "items": {
            "additionalProperties": false,
            "type": "object",
            "properties": {
              "host": {
                "minLength": 1,
                "type": "string"
              },
              "ip": {
                "minLength": 1,
                "type": "string"
              },
              "version": {
                "minLength": 1,
                "type": "string"
              },
              "mode": {
                "minLength": 1,
                "type": "string"
              },
              "lastInputSeconds": {
                "minimum": 0,
                "type": "integer"
              },
              "reason": {
                "minLength": 1,
                "type": "string"
              },
              "tags": {
                "type": "array",
                "items": {
                  "minLength": 1,
                  "type": "string"
                }
              },
              "text": {
                "type": "string"
              },
              "ts": {
                "minimum": 0,
                "type": "integer"
              },
              "instanceId": {
                "minLength": 1,
                "type": "string"
              }
            },
            "required": [
              "ts"
            ]
          }
        },
        "health": {},
        "stateVersion": {
          "additionalProperties": false,
          "type": "object",
          "properties": {
            "presence": {
              "minimum": 0,
              "type": "integer"
            },
            "health": {
              "minimum": 0,
              "type": "integer"
            }
          },
          "required": [
            "presence",
            "health"
          ]
        },
        "uptimeMs": {
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "presence",
        "health",
        "stateVersion",
        "uptimeMs"
      ]
    },
    "ErrorShape": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "code": {
          "minLength": 1,
          "type": "string"
        },
        "message": {
          "minLength": 1,
          "type": "string"
        },
        "details": {},
        "retryable": {
          "type": "boolean"
        },
        "retryAfterMs": {
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "code",
        "message"
      ]
    },
    "AgentEvent": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "runId": {
          "minLength": 1,
          "type": "string"
        },
        "seq": {
          "minimum": 0,
          "type": "integer"
        },
        "stream": {
          "minLength": 1,
          "type": "string"
        },
        "ts": {
          "minimum": 0,
          "type": "integer"
        },
        "data": {
          "type": "object",
          "patternProperties": {
            "^(.*)$": {}
          }
        }
      },
      "required": [
        "runId",
        "seq",
        "stream",
        "ts",
        "data"
      ]
    },
    "SendParams": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "to": {
          "minLength": 1,
          "type": "string"
        },
        "message": {
          "minLength": 1,
          "type": "string"
        },
        "mediaUrl": {
          "type": "string"
        },
        "provider": {
          "type": "string"
        },
        "idempotencyKey": {
          "minLength": 1,
          "type": "string"
        }
      },
      "required": [
        "to",
        "message",
        "idempotencyKey"
      ]
    },
    "AgentParams": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "message": {
          "minLength": 1,
          "type": "string"
        },
        "to": {
          "type": "string"
        },
        "sessionId": {
          "type": "string"
        },
        "thinking": {
          "type": "string"
        },
        "deliver": {
          "type": "boolean"
        },
        "timeout": {
          "minimum": 0,
          "type": "integer"
        },
        "idempotencyKey": {
          "minLength": 1,
          "type": "string"
        }
      },
      "required": [
        "message",
        "idempotencyKey"
      ]
    },
    "TickEvent": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "ts": {
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "ts"
      ]
    },
    "ShutdownEvent": {
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "reason": {
          "minLength": 1,
          "type": "string"
        },
        "restartExpectedMs": {
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "reason"
      ]
    }
  }
}