{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/glasswarp-com/json-schema/glasswarp-com-observe-result-schema.json",
  "title": "ObserveResult",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/glasswarp-com-openapi.yaml#/components/schemas/ObserveResult",
  "type": "object",
  "properties": {
    "width": {
      "type": "integer"
    },
    "height": {
      "type": "integer"
    },
    "native_width": {
      "type": "integer"
    },
    "native_height": {
      "type": "integer"
    },
    "timestamp": {
      "type": "integer"
    },
    "jpeg_base64": {
      "type": "string",
      "format": "byte",
      "description": "Omitted when `image=0` (text/targets-only observe)"
    },
    "dirty": {
      "type": [
        "object",
        "null"
      ],
      "description": "Accumulated DXGI dirty rects since the last take, or null when dirty metadata is unavailable (GDI capture fallback). Never a synthesized full-frame rect. Null ⇒ agents should assume changed.\n",
      "properties": {
        "width": {
          "type": "integer"
        },
        "height": {
          "type": "integer"
        },
        "available": {
          "type": "boolean",
          "description": "Always true when dirty is present; absent dirty uses null."
        },
        "rects": {
          "type": "array",
          "items": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          }
        }
      }
    },
    "changed": {
      "type": "boolean",
      "description": "False only when DXGI dirty was available and empty. True when dirty is null/unavailable (assume changed) or when rects exist.\n"
    },
    "capture_mode": {
      "type": "string",
      "enum": [
        "dxgi",
        "gdi",
        "gdi_fallback",
        "unknown"
      ],
      "description": "Host API capture path (updates mid-session on DXGI loss → GDI fallback)"
    },
    "targets": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/GroundingTarget"
      }
    },
    "text": {
      "$ref": "#/$defs/ObserveText"
    },
    "marked": {
      "type": "boolean"
    },
    "timing": {
      "type": "object",
      "description": "Server-side timing for this observe (milliseconds). Host fields are\nnull until the paired host daemon reports them.\n",
      "properties": {
        "total_ms": {
          "type": "integer",
          "description": "Wall-clock for the whole observe on the gateway"
        },
        "screenshot_rtt_ms": {
          "type": "integer",
          "description": "Gateway ↔ host RTT for the screenshot leg (0 when image=0)"
        },
        "dirty_rtt_ms": {
          "type": "integer",
          "description": "Gateway ↔ host RTT for the dirty-rects leg"
        },
        "targets_rtt_ms": {
          "type": "integer",
          "description": "Gateway ↔ host RTT for the UIA targets leg"
        },
        "host_jpeg_ms": {
          "type": [
            "integer",
            "null"
          ],
          "description": "Host-side capture + JPEG encode time when reported"
        },
        "host_uia_ms": {
          "type": [
            "integer",
            "null"
          ],
          "description": "Host-side UIA snapshot time when reported"
        },
        "image": {
          "type": "boolean",
          "description": "Whether a JPEG was requested"
        }
      }
    }
  },
  "$defs": {
    "GroundingTarget": {
      "type": "object",
      "required": [
        "id",
        "x",
        "y",
        "w",
        "h"
      ],
      "properties": {
        "id": {
          "type": "string",
          "description": "Stable id for click_target / SoM mark"
        },
        "x": {
          "type": "integer",
          "description": "Native capture origin X"
        },
        "y": {
          "type": "integer",
          "description": "Native capture origin Y"
        },
        "w": {
          "type": "integer"
        },
        "h": {
          "type": "integer"
        },
        "role": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "source": {
          "type": "string",
          "enum": [
            "uia",
            "cv",
            "grid",
            "client"
          ],
          "description": "Where the target came from"
        },
        "focused": {
          "type": "boolean",
          "description": "True when this control has keyboard focus"
        },
        "masked": {
          "type": "boolean",
          "description": "Password / masked field — value is always redacted"
        },
        "value": {
          "type": "string",
          "description": "ValuePattern text when available. Always `[redacted]` when\n`masked` is true — plaintext passwords are never returned.\n"
        }
      }
    },
    "ObserveText": {
      "type": "object",
      "description": "Compact structured text for agent decisions without image tokens",
      "properties": {
        "window_title": {
          "type": "string"
        },
        "window_role": {
          "type": "string"
        },
        "targets": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "summary": {
          "type": "string"
        }
      }
    }
  }
}