{
  "provider_id": "openai",
  "vendor": "openai",
  "display_name": "OpenAI GPT",
  "_verified": "2026-09-13: tier ids confirmed present in models.list and both pinged clean. max_output_tokens read from the provider's own over-limit 400 ('This model supports at most 128000 completion tokens'). reasoning_effort 'minimal' is REJECTED by both tiers ('does not support minimal with this model'); 'low' works. temperature is rejected — only the default is accepted. max_context_tokens is NOT verified: this provider exposes no context window through models.retrieve, which returns id/created/owned_by only.",
  "tiers": {
    "light": {
      "model_id": "gpt-5.6-terra",
      "display_name": "GPT-5.6 Terra",
      "fallback_model_id": "",
      "api_key_env": "OPENAI_API_KEY",
      "max_output_tokens": 128000,
      "max_context_tokens": 400000,
      "cost_tier": "low",
      "thinking_levels": [
        "low",
        "medium",
        "high"
      ],
      "capabilities": [
        "text",
        "multimodal_image",
        "native_pdf",
        "structured_output",
        "function_calling"
      ],
      "_note": "One API key serves both tiers — OpenAI does not split keys by tier. max_context_tokens is a documented figure the provider does not report; it is used only by the PDF guard's context check. thinking_levels omits 'minimal' because this model rejects it outright — the same shape as gemini-3.8-flash rejecting thinking_level 'minimal'."
    },
    "heavy": {
      "model_id": "gpt-5.6-sol",
      "display_name": "GPT-5.6 Sol",
      "fallback_model_id": "gpt-5.6-terra",
      "_fallback_note": "Unversioned aliases; the response reports a dated build (gpt-5.6-sol -> gpt-5.6-sol), so a provider-side version change is only visible through model_version on the response.",
      "api_key_env": "OPENAI_API_KEY",
      "max_output_tokens": 128000,
      "max_context_tokens": 400000,
      "cost_tier": "high",
      "thinking_levels": [
        "low",
        "medium",
        "high"
      ],
      "capabilities": [
        "text",
        "multimodal_image",
        "native_pdf",
        "structured_output",
        "function_calling",
        "deep_reasoning"
      ]
    }
  },
  "request_constraints": {
    "_note": "Rejected parameters, each verified with a live 400 rather than assumed.",
    "sampling_params": false,
    "reasoning_effort_minimal": false,
    "store": false,
    "_store_note": "store=false is sent on every request. This platform handles incident data, so a no-retention posture is a declared property of the client, not an incidental default."
  },
  "file_handling": {
    "application/pdf": {
      "max_pages": 600,
      "max_size_mb": 50,
      "tokens_per_page": 605,
      "tokens_per_page_by_resolution": {
        "low": 603,
        "medium": 605,
        "high": 605
      },
      "default_media_resolution": "medium",
      "ingestion_paths": [
        "inline_bytes"
      ],
      "preferred_ingestion": "inline_bytes",
      "_verified": "2026-09-24, both tiers (gpt-5.6-terra, gpt-5.6-sol), inline base64 input_file. tokens_per_page MEASURED: (document-call input_tokens - same prompt as text) / pages on the 3-page probe PDF; identical on both tiers. media_resolution maps to input_file detail (low->low, medium->auto, high->high); on the text-only probe the three cost the same within 2 tokens, so a page with images may cost more at high than recorded here. max_pages is the LARGEST COUNT VERIFIED, not a refusal: 101 and 600 pages were accepted and counted correctly; no page cap was found below the 400,000-token context window, which binds first at ~660 pages. max_size_mb is DOCUMENTED (50 MB per file and per request) and applies to the decoded file: a 40 MB PDF (53 MB as base64) was accepted, though it took 126 s to upload from a home connection.",
      "_note": "Inline only, never the Files API: an upload is retained provider-side until deleted, which would undo store=false. No gs_uri path: this provider cannot read a GCS URI, so the dispatcher reads the bytes first (no remote_uri_gs capability)."
    }
  },
  "output_budget": {
    "_note": "Reasoning tokens are completion tokens and come out of max_completion_tokens — measured: at a 64-token cap gpt-5-mini spent all 64 on reasoning and returned empty content with finish_reason 'length'. Sizing a reply against the full cap truncates it. max_completion_tokens is a ceiling, not a charge, so reserving generously costs nothing unless spent.",
    "default_thinking_level": "medium",
    "thinking_reserve_tokens": {
      "low": 4096,
      "medium": 16384,
      "high": 32768
    }
  },
  "document_strategies": {
    "application/pdf": "native",
    "application/json": "extract_text",
    "text/csv": "extract_text",
    "text/plain": "extract_text",
    "text/html": "extract_text",
    "default": "extract_and_chunk"
  }
}
