Skip to main content
Glama

Costory: Your Finops MCP

preview_report_widget

Compute a proposed report widget to inspect its output before saving a report. Use when the user wants to check a widget's output before saving it to a report. Does not save a report or send messages. Graph-snapshot previews render and upload a PNG, even though image fields are omitted from the bounded preview response. Pass the same reportContext + widget object you will later hand to create_report. Returns a token-bounded, per-type result. By type: DIGEST → resolvedPeriod, comparison totals, largest changes, root nodes, summary markdown (when display is "summary"), recommendations; TOP_FLOP → bounded top/flop rows; GRAPH_SNAPSHOT → bounded series sample (no image) + explorerUrl; DASHBOARD_PDF/TEXT → validity pointer; DIVIDER → Slack thread cut (no compute). Put shared period / groupBy / metric / currency / conditionsCel in reportContext; widgets omit matching fields to inherit. DIGEST hierarchy: reportContext.groupBy (default root) + additionalGroupBy (deeper levels). Per-widget override: set useDashboardGroupBy: false to ignore reportContext.groupBy for this widget — the first additionalGroupBy item (or queries[0].groupBy) becomes the root; false requires at least one dimension. DIGEST threshold defaults: 100 absolute / 5% relative / 20 changes (topLargestAbsoluteChange integer 1–100, applied at every tree level). DIGEST AI (opt-in, does not save a report or deliver messages): display ("tree" default | "table" | "summary" for LLM executive narrative) and enableAiInvestigation (boolean, default false — per-node deep analysis, independent of display). DIGEST aggBy is Month or Week — never Period (Period is TOP_FLOP). EXAMPLES: • Monthly DIGEST by env → project → service (AI summary) → { reportContext: { datePreset: "LAST_MONTH", groupBy: "cos_environment", metricId: "cost", currency: "USD" }, widget: { type: "DIGEST", queries: [{ type: "cost", name: "a" }], aggBy: "Month", additionalGroupBy: ["cos_sub_account_id", "cos_service_name"], minAbsoluteDiff: 100, minRelativeDiff: 5, topLargestAbsoluteChange: 20, display: "summary", enableAiInvestigation: false } } • Kubernetes-only weekly DIGEST (per-widget filterCel) → { reportContext: { datePreset: "LAST_WEEK", groupBy: "cos_namespace_reallocated", metricId: "cost", currency: "USD" }, widget: { type: "DIGEST", title: "Kubernetes", queries: [{ type: "cost", name: "a", filterCel: "cos_cluster_name != null" }], aggBy: "Week", additionalGroupBy: ["cos_workload_name"] } } • Namespace-rooted DIGEST overriding the report group-by → { reportContext: { datePreset: "LAST_MONTH", groupBy: "cos_environment", metricId: "cost", currency: "USD" }, widget: { type: "DIGEST", title: "Kubernetes", useDashboardGroupBy: false, queries: [{ type: "cost", name: "a" }], aggBy: "Month", additionalGroupBy: ["cos_namespace_reallocated", "cos_workload_name"] } } • Weekly TOP_FLOP → { reportContext: { datePreset: "LAST_WEEK", groupBy: "cos_service_name", metricId: "cost", currency: "USD" }, widget: { type: "TOP_FLOP", queries: [{ type: "cost", name: "a" }], aggBy: "Period", topN: 5, flopN: 5 } }

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "widget": "<widget>",
      "context": "<context>"
    },
    "name": "preview_report_widget"
  }
}

Input Schema

NameRequiredDescriptionDefault
slugNoOrganization slug. Omit to auto-detect from your account (fails if you belong to multiple orgs).
widgetYesSingle widget to preview (same shape as create/update `widgets[]` items).
contextYesA few words on why you are calling this tool, for the server developer's analytics. Describe people and things by role, such as "a customer". Do not quote the user or include names, emails, or other personal details.
scoutIdNoScout id assigned to the report being previewed (from `get_report` `scoutId`) — feeds its approved prompt into DIGEST summary previews. Omit when the report has no Scout.
llm_modelNoThe model identifier you are running as, for example "claude-opus-4-8" or "gpt-5.2". Pass "unknown" if you are not certain. Recorded for the server developer's analytics.
reportContextNoOptional shared context the widget inherits (same shape as `create_report` `reportContext`).
conversation_idNoThe conversation_id this server returned earlier in this conversation, unchanged, including after later user messages. Omit it if you have none. Recorded for the server developer's analytics.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changed
    • changedInput schema / definitions / ReportMcpContext / properties / datePreset / description
      Previous value: -"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate."New value: +"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Use this when a preset matches the requested range; otherwise use startDate/endDate."
    • changedInput schema / definitions / ReportMcpQueries / description
      Previous value: -"Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Budget groupBy is explicit (budget VD bqName); it does not inherit reportContext.groupBy. Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports."New value: +"Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (use short ids like a/b/c); put human labels in `alias`. Cost inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Budget groupBy is explicit (budget VD bqName); it does not inherit reportContext.groupBy. Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports."
    • changedInput schema / properties / context / description
      Previous value: -"Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""New value: +"A few words on why you are calling this tool, for the server developer's analytics. Describe people and things by role, such as \"a customer\". Do not quote the user or include names, emails, or other personal details."
    • changedInput schema / properties / widget / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "additionalProperties": false,
      -        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -        "properties": {
      -          "chartType": {
      -            "default": "WATERFALL",
      -            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -            "enum": [
      -              "WATERFALL",
      -              "TABLE",
      -              "KPI_BREAKDOWN"
      -            ],
      -            "type": "string"
      -          },
      -          "enabled": {
      -            "default": true,
      -            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -            "type": "boolean"
      -          },
      -          "from": {
      -            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      -        "type": [
      -          "string",
      -          "null"
      -        ]
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "queries",
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      -        "type": [
      -          "string",
      -          "null"
      -        ]
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "queries",
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DIVIDER",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      -        "type": [
      -          "string",
      -          "null"
      -        ]
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      -        "maximum": 100,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      },
      -      "useDashboardGroupBy": {
      -        "default": true,
      -        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "queries",
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "additionalProperties": false,
      +        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +        "properties": {
      +          "chartType": {
      +            "default": "WATERFALL",
      +            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +            "enum": [
      +              "WATERFALL",
      +              "TABLE",
      +              "KPI_BREAKDOWN"
      +            ],
      +            "type": "string"
      +          },
      +          "enabled": {
      +            "default": true,
      +            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +            "type": "boolean"
      +          },
      +          "from": {
      +            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DIVIDER",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` by default, or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Use datePreset or reportContext when available.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Use display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      },
      +      "useDashboardGroupBy": {
      +        "default": true,
      +        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / required
      Previous value: -[
      -  "widget",
      -  "context",
      -  "llm_model"
      -]New value: +[
      +  "widget",
      +  "context"
      +]
  2. Changed6 schema fields changed
    • removedInput schema / properties / context / allOf
      Removed value: -[
      -  {
      -    "$ref": "#/definitions/ReportMcpContext"
      -  }
      -]
    • changedInput schema / properties / context / description
      Previous value: -"Deprecated alias for `reportContext`; supported temporarily for backward compatibility. Do not send both fields."New value: +"Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
    • addedInput schema / properties / context / type
      Added value: +"string"
    • addedInput schema / properties / conversation_id
      Added value: +{
      +  "description": "The conversation_id this server returned earlier in this conversation, unchanged, including after later user messages. Omit it if you have none. Recorded for the server developer's analytics.",
      +  "type": "string"
      +}
    • addedInput schema / properties / llm_model
      Added value: +{
      +  "description": "The model identifier you are running as, for example \"claude-opus-4-8\" or \"gpt-5.2\". Pass \"unknown\" if you are not certain. Recorded for the server developer's analytics.",
      +  "type": "string"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "widget"
      -]New value: +[
      +  "widget",
      +  "context",
      +  "llm_model"
      +]
  3. Changed8 schema fields changed
    • removedInput schema / definitions / ReportMcpContext / properties / groupBy / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / definitions / ReportMcpContext / properties / groupBy / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / definitions / ReportMcpContext / properties / metricId / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / definitions / ReportMcpContext / properties / metricId / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / definitions / ReportMcpContext / properties / scopeId / anyOf
      Removed value: -[
      -  {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ]
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / definitions / ReportMcpContext / properties / scopeId / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • addedInput schema / properties / scoutId
      Added value: +{
      +  "description": "Scout id assigned to the report being previewed (from `get_report` `scoutId`) — feeds its approved prompt into DIGEST summary previews. Omit when the report has no Scout.",
      +  "type": "string"
      +}
    • changedInput schema / properties / widget / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "additionalProperties": false,
      -        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -        "properties": {
      -          "chartType": {
      -            "default": "WATERFALL",
      -            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -            "enum": [
      -              "WATERFALL",
      -              "TABLE",
      -              "KPI_BREAKDOWN"
      -            ],
      -            "type": "string"
      -          },
      -          "enabled": {
      -            "default": true,
      -            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -            "type": "boolean"
      -          },
      -          "from": {
      -            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      -        "maximum": 100,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      },
      -      "useDashboardGroupBy": {
      -        "default": true,
      -        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "additionalProperties": false,
      +        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +        "properties": {
      +          "chartType": {
      +            "default": "WATERFALL",
      +            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +            "enum": [
      +              "WATERFALL",
      +              "TABLE",
      +              "KPI_BREAKDOWN"
      +            ],
      +            "type": "string"
      +          },
      +          "enabled": {
      +            "default": true,
      +            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +            "type": "boolean"
      +          },
      +          "from": {
      +            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DIVIDER",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      },
      +      "useDashboardGroupBy": {
      +        "default": true,
      +        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  4. Changed1 schema field changed
    • changedInput schema / properties / widget / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "additionalProperties": false,
      -        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -        "properties": {
      -          "chartType": {
      -            "default": "WATERFALL",
      -            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -            "enum": [
      -              "WATERFALL",
      -              "TABLE",
      -              "KPI_BREAKDOWN"
      -            ],
      -            "type": "string"
      -          },
      -          "enabled": {
      -            "default": true,
      -            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -            "type": "boolean"
      -          },
      -          "from": {
      -            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      -        "maximum": 100,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "additionalProperties": false,
      +        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +        "properties": {
      +          "chartType": {
      +            "default": "WATERFALL",
      +            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +            "enum": [
      +              "WATERFALL",
      +              "TABLE",
      +              "KPI_BREAKDOWN"
      +            ],
      +            "type": "string"
      +          },
      +          "enabled": {
      +            "default": true,
      +            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +            "type": "boolean"
      +          },
      +          "from": {
      +            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      },
      +      "useDashboardGroupBy": {
      +        "default": true,
      +        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  5. Changed1 schema field changed
    • changedInput schema / definitions / ReportMcpQueries / description
      Previous value: -"Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports."New value: +"Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Budget groupBy is explicit (budget VD bqName); it does not inherit reportContext.groupBy. Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports."
  6. Changed8 schema fields changed
    • addedInput schema / definitions
      Added value: +{
      +  "ReportMcpContext": {
      +    "properties": {
      +      "conditionsCel": {
      +        "description": "Report-wide CEL filter merged into cost and usage widgets. Omit or empty string for no report-level filter.",
      +        "type": "string"
      +      },
      +      "currency": {
      +        "anyOf": [
      +          {
      +            "enum": [
      +              "USD",
      +              "EUR",
      +              "GBP",
      +              "CNY",
      +              "KRW"
      +            ],
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "datePreset": {
      +        "anyOf": [
      +          {
      +            "enum": [
      +              "TRAILING_90_DAYS",
      +              "TRAILING_30_DAYS",
      +              "TRAILING_45_DAYS",
      +              "TRAILING_7_DAYS",
      +              "TRAILING_3_DAYS",
      +              "TRAILING_1_DAYS",
      +              "TRAILING_14_WEEKS",
      +              "MTD",
      +              "QTD",
      +              "YTD",
      +              "CURRENT_MONTH",
      +              "CURRENT_QUARTER",
      +              "CURRENT_YEAR",
      +              "LAST_WEEK",
      +              "LAST_MONTH",
      +              "LAST_6_MONTHS",
      +              "LAST_12_MONTHS",
      +              "LAST_4_YEARS",
      +              "LAST_3_MONTHS",
      +              "LAST_INVOICE_MONTH"
      +            ],
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate."
      +      },
      +      "endDate": {
      +        "anyOf": [
      +          {
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "groupBy": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Default group-by axis inherited by widgets that omit `groupBy`. For DIGEST, this is the root hierarchy axis — put deeper levels in `additionalGroupBy`."
      +      },
      +      "metricId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Default metric inherited by widget cost queries that omit `metricId`."
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Applied report-wide unless a widget overrides."
      +      },
      +      "startDate": {
      +        "anyOf": [
      +          {
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Used only when `datePreset` is null; ISO date (YYYY-MM-DD)."
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "ReportMcpQueries": {
      +    "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports.",
      +    "items": {
      +      "additionalProperties": {},
      +      "propertyNames": {
      +        "type": "string"
      +      },
      +      "type": "object"
      +    },
      +    "type": "array"
      +  }
      +}
    • addedInput schema / properties / context / allOf
      Added value: +[
      +  {
      +    "$ref": "#/definitions/ReportMcpContext"
      +  }
      +]
    • removedInput schema / properties / context / properties
      Removed value: -{
      -  "conditionsCel": {
      -    "description": "Report-wide CEL filter merged into cost widgets. Omit or empty string for no report-level filter.",
      -    "type": "string"
      -  },
      -  "currency": {
      -    "anyOf": [
      -      {
      -        "enum": [
      -          "USD",
      -          "EUR",
      -          "GBP",
      -          "CNY",
      -          "KRW"
      -        ],
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ]
      -  },
      -  "datePreset": {
      -    "anyOf": [
      -      {
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate."
      -  },
      -  "endDate": {
      -    "anyOf": [
      -      {
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ]
      -  },
      -  "groupBy": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default group-by axis inherited by widgets that omit `groupBy`. For DIGEST, this is the root hierarchy axis — put deeper levels in `additionalGroupBy`."
      -  },
      -  "metricId": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default metric inherited by widget cost queries that omit `metricId`."
      -  },
      -  "scopeId": {
      -    "anyOf": [
      -      {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Optional saved team scope id (from list_teams). Applied report-wide unless a widget overrides."
      -  },
      -  "startDate": {
      -    "anyOf": [
      -      {
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Used only when `datePreset` is null; ISO date (YYYY-MM-DD)."
      -  }
      -}
    • removedInput schema / properties / context / type
      Removed value: -"object"
    • addedInput schema / properties / reportContext / allOf
      Added value: +[
      +  {
      +    "$ref": "#/definitions/ReportMcpContext"
      +  }
      +]
    • removedInput schema / properties / reportContext / properties
      Removed value: -{
      -  "conditionsCel": {
      -    "description": "Report-wide CEL filter merged into cost widgets. Omit or empty string for no report-level filter.",
      -    "type": "string"
      -  },
      -  "currency": {
      -    "anyOf": [
      -      {
      -        "enum": [
      -          "USD",
      -          "EUR",
      -          "GBP",
      -          "CNY",
      -          "KRW"
      -        ],
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ]
      -  },
      -  "datePreset": {
      -    "anyOf": [
      -      {
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate."
      -  },
      -  "endDate": {
      -    "anyOf": [
      -      {
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ]
      -  },
      -  "groupBy": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default group-by axis inherited by widgets that omit `groupBy`. For DIGEST, this is the root hierarchy axis — put deeper levels in `additionalGroupBy`."
      -  },
      -  "metricId": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default metric inherited by widget cost queries that omit `metricId`."
      -  },
      -  "scopeId": {
      -    "anyOf": [
      -      {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Optional saved team scope id (from list_teams). Applied report-wide unless a widget overrides."
      -  },
      -  "startDate": {
      -    "anyOf": [
      -      {
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Used only when `datePreset` is null; ISO date (YYYY-MM-DD)."
      -  }
      -}
    • removedInput schema / properties / reportContext / type
      Removed value: -"object"
    • changedInput schema / properties / widget / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "additionalProperties": false,
      -        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -        "properties": {
      -          "chartType": {
      -            "default": "WATERFALL",
      -            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -            "enum": [
      -              "WATERFALL",
      -              "TABLE",
      -              "KPI_BREAKDOWN"
      -            ],
      -            "type": "string"
      -          },
      -          "enabled": {
      -            "default": true,
      -            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -            "type": "boolean"
      -          },
      -          "from": {
      -            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      -        "maximum": 100,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "additionalProperties": false,
      +        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +        "properties": {
      +          "chartType": {
      +            "default": "WATERFALL",
      +            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +            "enum": [
      +              "WATERFALL",
      +              "TABLE",
      +              "KPI_BREAKDOWN"
      +            ],
      +            "type": "string"
      +          },
      +          "enabled": {
      +            "default": true,
      +            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +            "type": "boolean"
      +          },
      +          "from": {
      +            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  7. Changed2 schema fields changed
    • changedInput schema / properties / context / properties / datePreset / description
      Previous value: -"Default date preset inherited when a widget omits date fields. Prefer this over startDate/endDate whenever an available preset matches."New value: +"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate."
    • changedInput schema / properties / reportContext / properties / datePreset / description
      Previous value: -"Default date preset inherited when a widget omits date fields. Prefer this over startDate/endDate whenever an available preset matches."New value: +"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate."
  8. Changed2 schema fields changed
    • changedInput schema / properties / context / properties / currency / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "USD",
      -      "EUR",
      -      "GBP",
      -      "CNY"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "USD",
      +      "EUR",
      +      "GBP",
      +      "CNY",
      +      "KRW"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / reportContext / properties / currency / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "USD",
      -      "EUR",
      -      "GBP",
      -      "CNY"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "USD",
      +      "EUR",
      +      "GBP",
      +      "CNY",
      +      "KRW"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  9. Changed3 schema fields changed
    • changedInput schema / properties / context / properties / datePreset / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "TRAILING_90_DAYS",
      -      "TRAILING_30_DAYS",
      -      "TRAILING_45_DAYS",
      -      "TRAILING_7_DAYS",
      -      "TRAILING_3_DAYS",
      -      "TRAILING_14_WEEKS",
      -      "MTD",
      -      "QTD",
      -      "YTD",
      -      "CURRENT_MONTH",
      -      "CURRENT_QUARTER",
      -      "CURRENT_YEAR",
      -      "LAST_WEEK",
      -      "LAST_MONTH",
      -      "LAST_6_MONTHS",
      -      "LAST_12_MONTHS",
      -      "LAST_4_YEARS",
      -      "LAST_3_MONTHS",
      -      "LAST_INVOICE_MONTH"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "TRAILING_90_DAYS",
      +      "TRAILING_30_DAYS",
      +      "TRAILING_45_DAYS",
      +      "TRAILING_7_DAYS",
      +      "TRAILING_3_DAYS",
      +      "TRAILING_1_DAYS",
      +      "TRAILING_14_WEEKS",
      +      "MTD",
      +      "QTD",
      +      "YTD",
      +      "CURRENT_MONTH",
      +      "CURRENT_QUARTER",
      +      "CURRENT_YEAR",
      +      "LAST_WEEK",
      +      "LAST_MONTH",
      +      "LAST_6_MONTHS",
      +      "LAST_12_MONTHS",
      +      "LAST_4_YEARS",
      +      "LAST_3_MONTHS",
      +      "LAST_INVOICE_MONTH"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / reportContext / properties / datePreset / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "TRAILING_90_DAYS",
      -      "TRAILING_30_DAYS",
      -      "TRAILING_45_DAYS",
      -      "TRAILING_7_DAYS",
      -      "TRAILING_3_DAYS",
      -      "TRAILING_14_WEEKS",
      -      "MTD",
      -      "QTD",
      -      "YTD",
      -      "CURRENT_MONTH",
      -      "CURRENT_QUARTER",
      -      "CURRENT_YEAR",
      -      "LAST_WEEK",
      -      "LAST_MONTH",
      -      "LAST_6_MONTHS",
      -      "LAST_12_MONTHS",
      -      "LAST_4_YEARS",
      -      "LAST_3_MONTHS",
      -      "LAST_INVOICE_MONTH"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "TRAILING_90_DAYS",
      +      "TRAILING_30_DAYS",
      +      "TRAILING_45_DAYS",
      +      "TRAILING_7_DAYS",
      +      "TRAILING_3_DAYS",
      +      "TRAILING_1_DAYS",
      +      "TRAILING_14_WEEKS",
      +      "MTD",
      +      "QTD",
      +      "YTD",
      +      "CURRENT_MONTH",
      +      "CURRENT_QUARTER",
      +      "CURRENT_YEAR",
      +      "LAST_WEEK",
      +      "LAST_MONTH",
      +      "LAST_6_MONTHS",
      +      "LAST_12_MONTHS",
      +      "LAST_4_YEARS",
      +      "LAST_3_MONTHS",
      +      "LAST_INVOICE_MONTH"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / widget / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "additionalProperties": false,
      -        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -        "properties": {
      -          "chartType": {
      -            "default": "WATERFALL",
      -            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -            "enum": [
      -              "WATERFALL",
      -              "TABLE",
      -              "KPI_BREAKDOWN"
      -            ],
      -            "type": "string"
      -          },
      -          "enabled": {
      -            "default": true,
      -            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -            "type": "boolean"
      -          },
      -          "from": {
      -            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      -        "type": "number"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "additionalProperties": false,
      +        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +        "properties": {
      +          "chartType": {
      +            "default": "WATERFALL",
      +            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +            "enum": [
      +              "WATERFALL",
      +              "TABLE",
      +              "KPI_BREAKDOWN"
      +            ],
      +            "type": "string"
      +          },
      +          "enabled": {
      +            "default": true,
      +            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +            "type": "boolean"
      +          },
      +          "from": {
      +            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      +        "items": {
      +          "additionalProperties": {},
      +          "propertyNames": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      +        "items": {
      +          "additionalProperties": {},
      +          "propertyNames": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_1_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      +        "items": {
      +          "additionalProperties": {},
      +          "propertyNames": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  10. Changed3 schema fields changed
    • changedInput schema / properties / context / properties / datePreset / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "TRAILING_90_DAYS",
      -      "TRAILING_30_DAYS",
      -      "TRAILING_45_DAYS",
      -      "TRAILING_7_DAYS",
      -      "TRAILING_3_DAYS",
      -      "TRAILING_14_WEEKS",
      -      "MTD",
      -      "QTD",
      -      "YTD",
      -      "LAST_WEEK",
      -      "LAST_MONTH",
      -      "LAST_6_MONTHS",
      -      "LAST_12_MONTHS",
      -      "LAST_4_YEARS",
      -      "LAST_3_MONTHS",
      -      "LAST_INVOICE_MONTH"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "TRAILING_90_DAYS",
      +      "TRAILING_30_DAYS",
      +      "TRAILING_45_DAYS",
      +      "TRAILING_7_DAYS",
      +      "TRAILING_3_DAYS",
      +      "TRAILING_14_WEEKS",
      +      "MTD",
      +      "QTD",
      +      "YTD",
      +      "CURRENT_MONTH",
      +      "CURRENT_QUARTER",
      +      "CURRENT_YEAR",
      +      "LAST_WEEK",
      +      "LAST_MONTH",
      +      "LAST_6_MONTHS",
      +      "LAST_12_MONTHS",
      +      "LAST_4_YEARS",
      +      "LAST_3_MONTHS",
      +      "LAST_INVOICE_MONTH"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / reportContext / properties / datePreset / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "TRAILING_90_DAYS",
      -      "TRAILING_30_DAYS",
      -      "TRAILING_45_DAYS",
      -      "TRAILING_7_DAYS",
      -      "TRAILING_3_DAYS",
      -      "TRAILING_14_WEEKS",
      -      "MTD",
      -      "QTD",
      -      "YTD",
      -      "LAST_WEEK",
      -      "LAST_MONTH",
      -      "LAST_6_MONTHS",
      -      "LAST_12_MONTHS",
      -      "LAST_4_YEARS",
      -      "LAST_3_MONTHS",
      -      "LAST_INVOICE_MONTH"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "TRAILING_90_DAYS",
      +      "TRAILING_30_DAYS",
      +      "TRAILING_45_DAYS",
      +      "TRAILING_7_DAYS",
      +      "TRAILING_3_DAYS",
      +      "TRAILING_14_WEEKS",
      +      "MTD",
      +      "QTD",
      +      "YTD",
      +      "CURRENT_MONTH",
      +      "CURRENT_QUARTER",
      +      "CURRENT_YEAR",
      +      "LAST_WEEK",
      +      "LAST_MONTH",
      +      "LAST_6_MONTHS",
      +      "LAST_12_MONTHS",
      +      "LAST_4_YEARS",
      +      "LAST_3_MONTHS",
      +      "LAST_INVOICE_MONTH"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / widget / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "additionalProperties": false,
      -        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -        "properties": {
      -          "chartType": {
      -            "default": "WATERFALL",
      -            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -            "enum": [
      -              "WATERFALL",
      -              "TABLE",
      -              "KPI_BREAKDOWN"
      -            ],
      -            "type": "string"
      -          },
      -          "enabled": {
      -            "default": true,
      -            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -            "type": "boolean"
      -          },
      -          "from": {
      -            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      -        "type": "number"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "additionalProperties": false,
      +        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +        "properties": {
      +          "chartType": {
      +            "default": "WATERFALL",
      +            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +            "enum": [
      +              "WATERFALL",
      +              "TABLE",
      +              "KPI_BREAKDOWN"
      +            ],
      +            "type": "string"
      +          },
      +          "enabled": {
      +            "default": true,
      +            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +            "type": "boolean"
      +          },
      +          "from": {
      +            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      +        "items": {
      +          "additionalProperties": {},
      +          "propertyNames": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 50,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      +        "items": {
      +          "additionalProperties": {},
      +          "propertyNames": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 50,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "CURRENT_MONTH",
      +          "CURRENT_QUARTER",
      +          "CURRENT_YEAR",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      +        "items": {
      +          "additionalProperties": {},
      +          "propertyNames": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      +        "type": "number"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  11. Changed1 schema field changed
    • changedInput schema / properties / widget / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "additionalProperties": false,
      -        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -        "properties": {
      -          "chartType": {
      -            "default": "WATERFALL",
      -            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -            "enum": [
      -              "WATERFALL",
      -              "TABLE",
      -              "KPI_BREAKDOWN"
      -            ],
      -            "type": "string"
      -          },
      -          "enabled": {
      -            "default": true,
      -            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -            "type": "boolean"
      -          },
      -          "from": {
      -            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -        "enum": [
      -          "Hour",
      -          "Day",
      -          "Week",
      -          "Month",
      -          "Period"
      -        ],
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "format": "date",
      -            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "limit": {
      -        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      -        "items": {
      -          "additionalProperties": {},
      -          "propertyNames": {
      -            "type": "string"
      -          },
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      -        "type": "number"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "additionalProperties": false,
      +        "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +        "properties": {
      +          "chartType": {
      +            "default": "WATERFALL",
      +            "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +            "enum": [
      +              "WATERFALL",
      +              "TABLE",
      +              "KPI_BREAKDOWN"
      +            ],
      +            "type": "string"
      +          },
      +          "enabled": {
      +            "default": true,
      +            "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +            "type": "boolean"
      +          },
      +          "from": {
      +            "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      +        "items": {
      +          "additionalProperties": {},
      +          "propertyNames": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +        "enum": [
      +          "Hour",
      +          "Day",
      +          "Week",
      +          "Month",
      +          "Period"
      +        ],
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 50,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "queries": {
      +        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      +        "items": {
      +          "additionalProperties": {},
      +          "propertyNames": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 50,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "format": "date",
      +            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "enum": [
      +          "TRAILING_90_DAYS",
      +          "TRAILING_30_DAYS",
      +          "TRAILING_45_DAYS",
      +          "TRAILING_7_DAYS",
      +          "TRAILING_3_DAYS",
      +          "TRAILING_14_WEEKS",
      +          "MTD",
      +          "QTD",
      +          "YTD",
      +          "LAST_WEEK",
      +          "LAST_MONTH",
      +          "LAST_6_MONTHS",
      +          "LAST_12_MONTHS",
      +          "LAST_4_YEARS",
      +          "LAST_3_MONTHS",
      +          "LAST_INVOICE_MONTH"
      +        ],
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "limit": {
      +        "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" for examples.",
      +        "items": {
      +          "additionalProperties": {},
      +          "propertyNames": {
      +            "type": "string"
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "format": "date",
      +        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      +        "type": "string"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      +        "type": "number"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  12. First observed

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds real behavior beyond the annotations: the token-bounded response, the fact that GRAPH_SNAPSHOT renders and uploads a PNG and therefore has no image in the bounded response, the DIVIDER Slack thread cut, and that enableAiInvestigation runs an async analysis that is noticeably slower. This also explains the non-obvious readOnlyHint=false. It does not quantify cost/latency for the remaining types, so not a full 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the negative scope are front-loaded before the type reference, and the examples earn their space. There is some redundancy: "Does not save a report or send messages" is restated later as "does not save a report or deliver messages," and threshold defaults are repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with a large discriminated-union schema and no output schema, the description supplies what the schema cannot: the per-type return shape (resolvedPeriod/totals/root nodes/markdown for DIGEST, bounded rows for TOP_FLOP, bounded series plus explorerUrl for GRAPH_SNAPSHOT) and the fact that responses are token-bounded. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Goes well past 100% schema coverage by explaining the inheritance model: shared period/groupBy/metric/currency/conditionsCel live in reportContext and widgets omit matching fields to inherit. It clarifies that useDashboardGroupBy:false promotes the first additionalGroupBy item (or queries[0].groupBy) to root and requires at least one dimension, and that topLargestAbsoluteChange applies at every tree level — semantics the schema alone does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Compute a proposed report widget to inspect its output") and immediately scopes it negatively: "Does not save a report or send messages." It also distinguishes itself from the eventual write path by telling the agent to pass the same payload "you will later hand to create_report."

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ("Use when the user wants to check a widget's output before saving it to a report") plus an exclusion (no saving, no message delivery) and a concrete handoff to create_report with identical payloads. The per-type breakdown (DIGEST/TOP_FLOP/GRAPH_SNAPSHOT/DASHBOARD_PDF/DIVIDER) further routes the agent by scenario.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources