{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://ayagmar.github.io/llm-usage-metrics/report-summary.v1.schema.json",
  "title": "llm-usage-metrics summary report output (v1)",
  "description": "Envelope and payload for summary report --json output. Diagnostics are excluded by contract.",
  "type": "object",
  "allOf": [
    {
      "$ref": "https://ayagmar.github.io/llm-usage-metrics/report-common.v1.schema.json#/$defs/envelope"
    }
  ],
  "properties": {
    "report": {
      "const": "summary"
    },
    "data": {
      "description": "Summary payload: today, the last 7 days, month to date, and daily activity over the past year.",
      "type": "object",
      "properties": {
        "timezone": {
          "description": "IANA timezone or offset the periods are computed in.",
          "type": "string"
        },
        "periods": {
          "description": "Periods in fixed order: today, last7Days, monthToDate.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/period"
          }
        },
        "monthEnd": {
          "description": "Month-to-date run rate and the configured budget. Optional so v1 reports from earlier releases stay valid.",
          "$ref": "#/$defs/monthEnd"
        },
        "monthToDateCacheSavingsUsd": {
          "description": "Estimated month-to-date savings from cache reads: cache-read tokens priced at the input rate minus the cache-read rate. Absent when no cache reads could be priced.",
          "type": "number",
          "minimum": 0
        },
        "activity": {
          "description": "Daily activity and streaks. Always emitted by current releases; optional so v1 reports from earlier releases stay valid.",
          "$ref": "#/$defs/activity"
        },
        "spike": {
          "description": "The costliest spend spike of the last 7 days: a day costing at least $1 and at least 3 times the median cost of the active days (cost above 0) among the 28 days before it; with fewer than 3 active days in those 28, no day is one. Absent when no day of the last 7 is one.",
          "$ref": "#/$defs/spike"
        }
      },
      "required": ["timezone", "periods"],
      "additionalProperties": false
    }
  },
  "$defs": {
    "spike": {
      "type": "object",
      "properties": {
        "date": {
          "description": "Local date (YYYY-MM-DD).",
          "type": "string"
        },
        "costUsd": {
          "description": "Cost of the day.",
          "type": "number",
          "minimum": 0
        },
        "costIncomplete": {
          "description": "True when some events of the day had no known price.",
          "type": "boolean"
        },
        "medianActiveDayUsd": {
          "description": "Median cost of the active days among the 28 days before the spike.",
          "type": "number",
          "minimum": 0
        },
        "project": {
          "description": "Label of the project with the largest share of the day's cost.",
          "type": "string"
        },
        "model": {
          "description": "The model with the largest share of the day's cost; absent when those events name no model.",
          "type": "string"
        }
      },
      "required": ["date", "costUsd", "medianActiveDayUsd"],
      "additionalProperties": false
    },
    "windowTotals": {
      "type": "object",
      "description": "Usage totals for one period (non-negative).",
      "allOf": [
        {
          "$ref": "https://ayagmar.github.io/llm-usage-metrics/report-common.v1.schema.json#/$defs/usageTotals"
        }
      ],
      "properties": {
        "events": {
          "description": "Events in the period.",
          "type": "integer",
          "minimum": 0
        },
        "activeDays": {
          "description": "Days with at least one event in the period.",
          "type": "integer",
          "minimum": 0
        }
      },
      "required": ["events", "activeDays"],
      "unevaluatedProperties": false
    },
    "sourceTotals": {
      "type": "object",
      "description": "Usage totals for one source within a period (non-negative).",
      "allOf": [
        {
          "$ref": "https://ayagmar.github.io/llm-usage-metrics/report-common.v1.schema.json#/$defs/usageTotals"
        }
      ],
      "properties": {
        "source": {
          "description": "Source id.",
          "type": "string"
        },
        "events": {
          "description": "Events in the period.",
          "type": "integer",
          "minimum": 0
        },
        "activeDays": {
          "description": "Days with at least one event in the period.",
          "type": "integer",
          "minimum": 0
        }
      },
      "required": ["source", "events", "activeDays"],
      "unevaluatedProperties": false
    },
    "machineTotals": {
      "type": "object",
      "description": "Usage totals for one machine within a period (non-negative).",
      "allOf": [
        {
          "$ref": "https://ayagmar.github.io/llm-usage-metrics/report-common.v1.schema.json#/$defs/usageTotals"
        }
      ],
      "properties": {
        "machine": {
          "description": "`local` for the machine that ran the report, otherwise the name the machine was added under.",
          "type": "string"
        },
        "events": {
          "description": "Events in the period.",
          "type": "integer",
          "minimum": 0
        },
        "activeDays": {
          "description": "Days with at least one event in the period.",
          "type": "integer",
          "minimum": 0
        }
      },
      "required": ["machine", "events", "activeDays"],
      "unevaluatedProperties": false
    },
    "period": {
      "description": "One summarized period.",
      "type": "object",
      "properties": {
        "key": {
          "description": "Stable period identifier.",
          "enum": ["today", "last7Days", "monthToDate"]
        },
        "label": {
          "description": "Human-readable period label.",
          "type": "string"
        },
        "since": {
          "description": "Period start (YYYY-MM-DD, inclusive).",
          "type": "string"
        },
        "until": {
          "description": "Period end (YYYY-MM-DD, inclusive).",
          "type": "string"
        },
        "totals": {
          "$ref": "#/$defs/windowTotals"
        },
        "sources": {
          "description": "Sources with usage in the period, by cost then tokens then id.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/sourceTotals"
          }
        },
        "machines": {
          "description": "Machines with usage in the period, by cost then tokens then name. Present only when the report counts other machines' usage in the past year, after its source, provider and model filters (since 0.11).",
          "type": "array",
          "items": {
            "$ref": "#/$defs/machineTotals"
          }
        },
        "previous": {
          "description": "The window the period is set against, as `compare` picks it: yesterday for today, the 7 days before the last 7 days, and for month to date the same days of the previous month (to its last day when it is shorter). Always emitted by current releases; optional so v1 reports from earlier releases stay valid.",
          "type": "object",
          "properties": {
            "since": {
              "description": "Previous period start (YYYY-MM-DD, inclusive).",
              "type": "string"
            },
            "until": {
              "description": "Previous period end (YYYY-MM-DD, inclusive).",
              "type": "string"
            },
            "totals": {
              "$ref": "#/$defs/windowTotals"
            }
          },
          "required": ["since", "until", "totals"],
          "additionalProperties": false
        }
      },
      "required": ["key", "label", "since", "until", "totals", "sources"],
      "additionalProperties": false
    },
    "activity": {
      "description": "Daily activity over the past 53 ISO weeks: from the Monday 52 weeks before the current week, to today.",
      "type": "object",
      "properties": {
        "from": {
          "description": "First day of the activity window, always a Monday (YYYY-MM-DD).",
          "type": "string"
        },
        "to": {
          "description": "Last day of the activity window: today (YYYY-MM-DD).",
          "type": "string"
        },
        "activeDays": {
          "description": "Days with at least one event in the window.",
          "type": "integer",
          "minimum": 0
        },
        "currentStreak": {
          "description": "Consecutive active days ending today, or ending yesterday while today has no usage yet.",
          "type": "integer",
          "minimum": 0
        },
        "longestStreak": {
          "description": "Longest run of consecutive active days in the window.",
          "type": "integer",
          "minimum": 0
        },
        "bestDay": {
          "description": "Day with the most tokens; ties go to the earliest date. Absent without usage.",
          "type": "object",
          "properties": {
            "date": {
              "description": "Local date (YYYY-MM-DD).",
              "type": "string"
            },
            "totalTokens": {
              "type": "integer",
              "minimum": 0
            },
            "costUsd": {
              "description": "Cost of the day; absent when no event had a known price.",
              "type": "number",
              "minimum": 0
            },
            "costIncomplete": {
              "description": "True when some events of the day had no known price.",
              "type": "boolean"
            }
          },
          "required": ["date", "totalTokens"],
          "additionalProperties": false
        },
        "days": {
          "description": "Every day of the window in date order, with its intensity level: 0 without usage, 1-4 by quartile of active-day tokens.",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "date": {
                "description": "Local date (YYYY-MM-DD).",
                "type": "string"
              },
              "totalTokens": {
                "type": "integer",
                "minimum": 0
              },
              "level": {
                "enum": [0, 1, 2, 3, 4]
              }
            },
            "required": ["date", "totalTokens", "level"],
            "additionalProperties": false
          }
        }
      },
      "required": ["from", "to", "activeDays", "currentStreak", "longestStreak", "days"],
      "additionalProperties": false
    },
    "monthEnd": {
      "type": "object",
      "properties": {
        "daysElapsed": {
          "description": "Days of the month so far, today included.",
          "type": "integer",
          "minimum": 1
        },
        "daysInMonth": {
          "description": "Days in the current month.",
          "type": "integer",
          "minimum": 28,
          "maximum": 31
        },
        "projectedCostUsd": {
          "description": "Month-to-date cost scaled to the whole month. Absent before the third day of the month or without a known cost.",
          "type": "number",
          "minimum": 0
        },
        "costIncomplete": {
          "description": "True when the month-to-date cost leaves out events without a known price.",
          "type": "boolean"
        },
        "budgetUsd": {
          "description": "monthlyBudgetUsd from the config file.",
          "type": "number",
          "exclusiveMinimum": 0
        }
      },
      "required": ["daysElapsed", "daysInMonth"],
      "additionalProperties": false
    }
  }
}
