---
updatedAt: 2026-10-29T14:20:40.000Z
---

# Create a chat completion

Supports text, up to eight images, function tools, and streaming. Video and audio inputs are unsupported. With stream=true, consume data-only SSE events until data: [DONE]; reasoning, content, and tool calls arrive as deltas.

# OpenAPI definition

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Mistral Large 4 Chat Completions API",
    "version": "1.0.0",
    "description": "Generate text from text and image conversations with mistralai/mistral-large-4-1t-a52b. Responses may carry reasoning_content separately from the final content when reasoning is requested. The combined prompt and generated response must fit within the 262,144-token context window."
  },
  "servers": [
    {
      "url": "https://integrate.api.nvidia.com"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/v1/chat/completions": {
      "post": {
        "summary": "Create a chat completion",
        "description": "Supports text, up to eight images, function tools, and streaming. Video and audio inputs are unsupported. With stream=true, consume data-only SSE events until data: [DONE]; reasoning, content, and tool calls arrive as deltas.",
        "operationId": "mistralai-mistral-large-4-1t-a52b-infer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletionRequest"
              },
              "examples": {
                "quick-arithmetic": {
                  "summary": "Quick arithmetic",
                  "value": {
                    "model": "mistralai/mistral-large-4-1t-a52b",
                    "messages": [
                      {
                        "role": "user",
                        "content": "What is 37 + 58? Reply with only the number."
                      }
                    ],
                    "max_tokens": 4096,
                    "stream": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A chat completion, or SSE chunks when streaming is enabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletionResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "JSON chat.completion.chunk events followed by data: [DONE]."
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or unsupported input."
          },
          "401": {
            "description": "Missing or invalid NVIDIA API key."
          },
          "402": {
            "description": "Insufficient API credits."
          },
          "422": {
            "description": "Request validation failed."
          },
          "429": {
            "description": "Request rate limit exceeded."
          }
        },
        "x-nvai-meta": {
          "name": "Create chat completion",
          "path": "create",
          "examples": [
            {
              "input": {
                "images": [
                  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAADwCAIAAAChXqV1AAAFIUlEQVR4nO3a23ISURBAUbH8/1/GB1IUFdCEcJnZfdZ61zCtve1JPByPx18ABb+3/gAA3yVYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVk/Hnflzoc3ve1xjset/4EfLjr77U/twe9MVjQ9+A/u9e/XMLuIljwhZe+G1z+5uL1JcGC297/PYzzV1SufxEs+Gzzb7eePoBsXRMs+LB5pz5xcF0TLNhdqj5xcJ0JFkvbeaouydYv/3GUlYVqdVb8zE/kwmJF6bVf+dRyYbGcdK3OZjzFvVxYLGTYki94armwWMWwWp1Nfa6bBIslzN7q2U93ySshwy2yzIu8HrqwmGyRWp2Nf17BYqzx23vT7KcWLGaavbf/N/jZBYuBBm/sN02dgGAxzdRdvdfIOQgWo4zc0h+bNw3BYo55+/m4YTMRLCBDsBhi2CnxRJMmI1hMMGknX2HMfASLvDHb+FIzpiRYQIZg0TbjcHiPAbMSLMIGbOCb1ScmWECGYFFVPxa2kp6bYJGU3rrNdacnWECGYNHTPRD2IzpDwQIyBIuY6GmwQ8VJChaQIVhAhmBRUnyL2bPcPAULyBAsMnLnQEJrqoIFZAgWkCFYNLTeXFpCsxUsIEOwgAzBAjIEi4DQN1miKhMWLCBDsIAMwQIyBAvIECwgQ7DYu8oPsOoScxYsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBYu+Ox60/wRoScxYsIEOwgAzBAjIEC8gQLCBDsAhI/AArrTJhwQIyBAvIECwgQ7BoqHyTpSg0W8ECMgQLyBAsMkJvLiGtqQoWkCFYlLTOgf3LzVOwgAzBAjIEi5jcW8xuFScpWECGYNFTPA32JjpDwQIyBIuk6IGwE93pCRZV3a3bVnpuggVkCBZh6WNhE/WJCRZt9Q18pwGzEiwgQ7DIG3A4vMGMKQkWE8zYxtcZMx/BYogxO/l0kyYjWECGYDHHpFPiWYbNRLAYZdh+PmjeNASLaeZt6c+MnINgMdDIXb3L1AkIFjNN3djvGPzsgsVYg/f2P2Y/tWAx2eztvTb+ef9s/QHgtU47fDhs/TlebHyqTlxYLGH2Ps9+ukuCxSqmbvXU57rJKyELGfZ6uFSqTlxYLGfGns94inu5sFhR+tRaM1UnLizWVdz84md+IhcWSwudWoun6kSwYO/ZkqozwYIP5y7spFw6dU2w4LPNDy6p+hfBgtvef3Dp1JcEC75w2ZGnx0uk7iJYcIfrvtyVMHl60OFohECE/zgKZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZPwFDKmsA+Djk0cAAAAASUVORK5CYII="
                ],
                "text": "Describe the color and shape on the left and on the right."
              },
              "name": "Compare two shapes",
              "output": {
                "text": "A red square on the left and a blue circle on the right."
              },
              "requestJson": "{\"model\": \"mistralai/mistral-large-4-1t-a52b\", \"messages\": [{\"role\": \"user\", \"content\": [{\"type\": \"text\", \"text\": \"Describe the color and shape on the left and on the right.\"}, {\"type\": \"image_url\", \"image_url\": {\"url\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAADwCAIAAAChXqV1AAAFIUlEQVR4nO3a23ISURBAUbH8/1/GB1IUFdCEcJnZfdZ61zCtve1JPByPx18ABb+3/gAA3yVYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVk/Hnflzoc3ve1xjset/4EfLjr77U/twe9MVjQ9+A/u9e/XMLuIljwhZe+G1z+5uL1JcGC297/PYzzV1SufxEs+Gzzb7eePoBsXRMs+LB5pz5xcF0TLNhdqj5xcJ0JFkvbeaouydYv/3GUlYVqdVb8zE/kwmJF6bVf+dRyYbGcdK3OZjzFvVxYLGTYki94armwWMWwWp1Nfa6bBIslzN7q2U93ySshwy2yzIu8HrqwmGyRWp2Nf17BYqzx23vT7KcWLGaavbf/N/jZBYuBBm/sN02dgGAxzdRdvdfIOQgWo4zc0h+bNw3BYo55+/m4YTMRLCBDsBhi2CnxRJMmI1hMMGknX2HMfASLvDHb+FIzpiRYQIZg0TbjcHiPAbMSLMIGbOCb1ScmWECGYFFVPxa2kp6bYJGU3rrNdacnWECGYNHTPRD2IzpDwQIyBIuY6GmwQ8VJChaQIVhAhmBRUnyL2bPcPAULyBAsMnLnQEJrqoIFZAgWkCFYNLTeXFpCsxUsIEOwgAzBAjIEi4DQN1miKhMWLCBDsIAMwQIyBAvIECwgQ7DYu8oPsOoScxYsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBYu+Ox60/wRoScxYsIEOwgAzBAjIEC8gQLCBDsAhI/AArrTJhwQIyBAvIECwgQ7BoqHyTpSg0W8ECMgQLyBAsMkJvLiGtqQoWkCFYlLTOgf3LzVOwgAzBAjIEi5jcW8xuFScpWECGYNFTPA32JjpDwQIyBIuk6IGwE93pCRZV3a3bVnpuggVkCBZh6WNhE/WJCRZt9Q18pwGzEiwgQ7DIG3A4vMGMKQkWE8zYxtcZMx/BYogxO/l0kyYjWECGYDHHpFPiWYbNRLAYZdh+PmjeNASLaeZt6c+MnINgMdDIXb3L1AkIFjNN3djvGPzsgsVYg/f2P2Y/tWAx2eztvTb+ef9s/QHgtU47fDhs/TlebHyqTlxYLGH2Ps9+ukuCxSqmbvXU57rJKyELGfZ6uFSqTlxYLGfGns94inu5sFhR+tRaM1UnLizWVdz84md+IhcWSwudWoun6kSwYO/ZkqozwYIP5y7spFw6dU2w4LPNDy6p+hfBgtvef3Dp1JcEC75w2ZGnx0uk7iJYcIfrvtyVMHl60OFohECE/zgKZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZPwFDKmsA+Djk0cAAAAASUVORK5CYII=\"}}]}], \"max_tokens\": 4096, \"stream\": true}",
              "responseJson": "{\"model\": \"mistralai/mistral-large-4-1t-a52b\", \"choices\": [{\"index\": 0, \"message\": {\"role\": \"assistant\", \"content\": \"A red square on the left and a blue circle on the right.\"}, \"finish_reason\": \"stop\"}]}"
            },
            {
              "input": {
                "text": "What is 37 + 58? Reply with only the number."
              },
              "name": "Quick arithmetic",
              "output": {
                "text": "95"
              },
              "requestJson": "{\"model\": \"mistralai/mistral-large-4-1t-a52b\", \"messages\": [{\"role\": \"user\", \"content\": \"What is 37 + 58? Reply with only the number.\"}], \"max_tokens\": 4096, \"stream\": true}",
              "responseJson": "{\"model\": \"mistralai/mistral-large-4-1t-a52b\", \"choices\": [{\"index\": 0, \"message\": {\"role\": \"assistant\", \"content\": \"95\"}, \"finish_reason\": \"stop\"}]}"
            }
          ],
          "templates": [
            {
              "title": "Chat completion",
              "requestEjs": {
                "python": "<%\n  // Catalog ejs locals replace JSON with {stringify} only (spread skips non-enumerable parse).\n  const deepClone = (value) => {\n    if (Array.isArray(value)) return value.map(deepClone);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const key of Object.keys(value)) out[key] = deepClone(value[key]);\n      return out;\n    }\n    return value;\n  };\n  const mediaConfig = {\"image\": {\"mimeTypes\": {\".png\": \"image/png\", \".jpg\": \"image/jpeg\", \".jpeg\": \"image/jpeg\", \".webp\": \"image/webp\"}}, \"video\": {\"mimeTypes\": {}}, \"audio\": {\"mimeTypes\": {}, \"defaultFormat\": \"wav\"}};\n  const stripNulls = (value) => {\n    if (Array.isArray(value)) return value.map(stripNulls);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const [key, item] of Object.entries(value)) {\n        if (item === null || item === undefined) continue;\n        out[key] = stripNulls(item);\n      }\n      return out;\n    }\n    return value;\n  };\n  const payloadForSnippet = stripNulls(deepClone(request || {}));\n  const hasStream = payloadForSnippet.stream !== undefined && payloadForSnippet.stream !== null;\n  const pyStream = payloadForSnippet.stream ? \"True\" : \"False\";\n  if (hasStream) payloadForSnippet.stream = \"__STREAM__\";\n\n  const hasMediaKind = (kind) => Object.keys(mediaConfig[kind].mimeTypes || {}).length > 0;\n  const isInlineDataUrl = (url, kind) => (\n    typeof url === \"string\" && new RegExp(`^data:${kind}/[^;]+;base64,`, \"i\").test(url)\n  );\n\n  const mediaUrl = (part, key) => {\n    const slot = part?.[key];\n    return typeof slot === \"string\" ? slot : slot?.url;\n  };\n  const setMediaUrl = (part, key, url) => {\n    if (typeof part[key] === \"string\") part[key] = url;\n    else {\n      if (!part[key] || typeof part[key] !== \"object\") part[key] = {};\n      part[key].url = url;\n    }\n  };\n\n  let imageCount = 0;\n  let videoCount = 0;\n  let audioCount = 0;\n\n  (payloadForSnippet.messages || []).forEach((message) => {\n    if (!Array.isArray(message?.content)) return;\n    message.content.forEach((part) => {\n      const imageUrl = mediaUrl(part, \"image_url\");\n      const videoUrl = mediaUrl(part, \"video_url\");\n      const audioUrl = mediaUrl(part, \"audio_url\");\n      // File helpers only for inline base64; http(s) URLs stay as-is in the payload.\n      if (hasMediaKind(\"image\") && part?.type === \"image_url\" && isInlineDataUrl(imageUrl, \"image\")) {\n        setMediaUrl(part, \"image_url\", `__IMAGE_DATA_URL_${imageCount}__`);\n        imageCount += 1;\n      } else if (hasMediaKind(\"video\") && part?.type === \"video_url\" && isInlineDataUrl(videoUrl, \"video\")) {\n        setMediaUrl(part, \"video_url\", `__VIDEO_DATA_URL_${videoCount}__`);\n        videoCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"audio_url\" && isInlineDataUrl(audioUrl, \"audio\")) {\n        setMediaUrl(part, \"audio_url\", `__AUDIO_DATA_URL_${audioCount}__`);\n        audioCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"input_audio\" && part.input_audio?.data) {\n        part.input_audio.data = `__AUDIO_B64_${audioCount}__`;\n        part.input_audio.format = part.input_audio.format || mediaConfig.audio.defaultFormat;\n        audioCount += 1;\n      }\n    });\n  });\n\n  const pyRepr = (value, level = 0) => {\n    if (value === null) return \"None\";\n    if (typeof value === \"boolean\") return value ? \"True\" : \"False\";\n    if (typeof value === \"number\") return String(value);\n    if (typeof value === \"string\") return JSON.stringify(value);\n    const pad = \" \".repeat(level);\n    const innerPad = \" \".repeat(level + 2);\n    if (Array.isArray(value)) {\n      if (value.length === 0) return \"[]\";\n      return \"[\\n\" + value.map((item) => `${innerPad}${pyRepr(item, level + 2)}`).join(\",\\n\") + \"\\n\" + pad + \"]\";\n    }\n    if (typeof value === \"object\") {\n      const entries = Object.entries(value);\n      if (entries.length === 0) return \"{}\";\n      return \"{\\n\" + entries.map(([key, item]) => `${innerPad}${JSON.stringify(key)}: ${pyRepr(item, level + 2)}`).join(\",\\n\") + \"\\n\" + pad + \"}\";\n    }\n    return \"None\";\n  };\n\n  const replaceAll = (s, a, b) => s.split(a).join(b);\n  let renderedPayload = pyRepr(payloadForSnippet);\n  if (hasStream) renderedPayload = replaceAll(renderedPayload, '\"__STREAM__\"', \"stream\");\n  for (let i = 0; i < imageCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__IMAGE_DATA_URL_${i}__\"`, `image_data_urls[${i}]`);\n  }\n  for (let i = 0; i < videoCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__VIDEO_DATA_URL_${i}__\"`, `video_data_urls[${i}]`);\n  }\n  for (let i = 0; i < audioCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_DATA_URL_${i}__\"`, `audio_data_urls[${i}]`);\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_B64_${i}__\"`, `audio_b64s[${i}]`);\n  }\n\n  // Either file helpers XOR inline base64 - never emit unused helpers.\n  const usesFileHelpers =\n    imageCount + videoCount + audioCount > 0 &&\n    [...Array(imageCount).keys()].every((i) => renderedPayload.includes(`image_data_urls[${i}]`)) &&\n    [...Array(videoCount).keys()].every((i) => renderedPayload.includes(`video_data_urls[${i}]`)) &&\n    [...Array(audioCount).keys()].every(\n      (i) => renderedPayload.includes(`audio_data_urls[${i}]`) || renderedPayload.includes(`audio_b64s[${i}]`)\n    );\n  if (!usesFileHelpers) {\n    imageCount = 0;\n    videoCount = 0;\n    audioCount = 0;\n    const restored = stripNulls(deepClone(request || {}));\n    const restoredStream = restored.stream !== undefined && restored.stream !== null;\n    if (restoredStream) restored.stream = \"__STREAM__\";\n    renderedPayload = pyRepr(restored);\n    if (restoredStream) renderedPayload = replaceAll(renderedPayload, '\"__STREAM__\"', \"stream\");\n  }\n  const hasMedia = usesFileHelpers;\n  const mimePy = (mimes) =>\n    \"{\" + Object.entries(mimes).map(([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`).join(\", \") + \"}\";\n%>\n<% if (hasMedia) { %>import base64\nfrom pathlib import Path\n<% } %>import requests\n\ninvoke_url = \"https://integrate.api.nvidia.com/v1/chat/completions\"\nstream = <%- pyStream %>\n<% if (hasMedia) { %>\ndef media_data_url(kind, index, mime_types):\n    for suffix, mime in mime_types.items():\n        path = Path(f\"{kind}_{index}{suffix}\")\n        if path.exists():\n            return f\"data:{mime};base64,{base64.b64encode(path.read_bytes()).decode()}\"\n    raise FileNotFoundError(f\"Expected {kind}_{index} with suffix in {list(mime_types)}\")\n<% if (imageCount > 0) { %>\nimage_data_urls = [media_data_url(\"image\", i, <%- mimePy(mediaConfig.image.mimeTypes) %>) for i in <%- imageCount === 1 ? \"[1]\" : (\"range(1, \" + (imageCount + 1) + \")\") %>]\n<% } %><% if (videoCount > 0) { %>\nvideo_data_urls = [media_data_url(\"video\", i, <%- mimePy(mediaConfig.video.mimeTypes) %>) for i in <%- videoCount === 1 ? \"[1]\" : (\"range(1, \" + (videoCount + 1) + \")\") %>]\n<% } %><% if (audioCount > 0) { %>\naudio_data_urls = [media_data_url(\"audio\", i, <%- mimePy(mediaConfig.audio.mimeTypes) %>) for i in <%- audioCount === 1 ? \"[1]\" : (\"range(1, \" + (audioCount + 1) + \")\") %>]\naudio_b64s = [url.split(\",\", 1)[1] for url in audio_data_urls]\n<% } %><% } %>\nheaders = {\n    \"Authorization\": \"Bearer $NVIDIA_API_KEY\",\n    \"Accept\": \"text/event-stream\" if stream else \"application/json\",\n}\n\npayload = <%- renderedPayload %>\n\nresponse = requests.post(invoke_url, headers=headers, json=payload, stream=stream)\nif stream:\n    for line in response.iter_lines():\n        if line:\n            print(line.decode(\"utf-8\"))\nelse:\n    print(response.json())\n",
                "langChain": "<%\n  const deepClone = (value) => {\n    if (Array.isArray(value)) return value.map(deepClone);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const key of Object.keys(value)) out[key] = deepClone(value[key]);\n      return out;\n    }\n    return value;\n  };\n  const mediaConfig = {\"image\": {\"mimeTypes\": {\".png\": \"image/png\", \".jpg\": \"image/jpeg\", \".jpeg\": \"image/jpeg\", \".webp\": \"image/webp\"}}, \"video\": {\"mimeTypes\": {}}, \"audio\": {\"mimeTypes\": {}, \"defaultFormat\": \"wav\"}};\n  const payloadForSnippet = deepClone(request || {});\n  const messagesForSnippet = deepClone(payloadForSnippet.messages || []);\n  const hasMediaKind = (kind) => Object.keys(mediaConfig[kind].mimeTypes || {}).length > 0;\n  const isInlineDataUrl = (url, kind) => (\n    typeof url === \"string\" && new RegExp(`^data:${kind}/[^;]+;base64,`, \"i\").test(url)\n  );\n\n  const mediaUrl = (part, key) => {\n    const slot = part?.[key];\n    return typeof slot === \"string\" ? slot : slot?.url;\n  };\n  const setMediaUrl = (part, key, url) => {\n    if (typeof part[key] === \"string\") part[key] = url;\n    else {\n      if (!part[key] || typeof part[key] !== \"object\") part[key] = {};\n      part[key].url = url;\n    }\n  };\n\n  let imageCount = 0;\n  let hasUnsupportedMedia = false;\n  messagesForSnippet.forEach((message) => {\n    if (!Array.isArray(message?.content)) return;\n    message.content.forEach((part) => {\n      const imageUrl = mediaUrl(part, \"image_url\");\n      if (hasMediaKind(\"image\") && part?.type === \"image_url\" && isInlineDataUrl(imageUrl, \"image\")) {\n        setMediaUrl(part, \"image_url\", `__IMAGE_DATA_URL_${imageCount}__`);\n        imageCount += 1;\n      } else if (part?.type === \"video_url\" && isInlineDataUrl(mediaUrl(part, \"video_url\"), \"video\")) {\n        // LangChain cannot ship local file helpers for video; reject inline only.\n        hasUnsupportedMedia = true;\n        setMediaUrl(part, \"video_url\", \"__UNSUPPORTED_MEDIA_DATA__\");\n      } else if (part?.type === \"audio_url\" && isInlineDataUrl(mediaUrl(part, \"audio_url\"), \"audio\")) {\n        hasUnsupportedMedia = true;\n        setMediaUrl(part, \"audio_url\", \"__UNSUPPORTED_MEDIA_DATA__\");\n      } else if (part?.type === \"input_audio\" && part.input_audio?.data) {\n        hasUnsupportedMedia = true;\n        part.input_audio.data = \"__UNSUPPORTED_MEDIA_DATA__\";\n      }\n    });\n  });\n\n  const pyRepr = (value, level = 0) => {\n    if (value === null) return \"None\";\n    if (typeof value === \"boolean\") return value ? \"True\" : \"False\";\n    if (typeof value === \"number\") return String(value);\n    if (typeof value === \"string\") return JSON.stringify(value);\n    const pad = \" \".repeat(level);\n    const innerPad = \" \".repeat(level + 2);\n    if (Array.isArray(value)) {\n      if (value.length === 0) return \"[]\";\n      return \"[\\n\" + value.map((item) => `${innerPad}${pyRepr(item, level + 2)},`).join(\"\\n\") + \"\\n\" + pad + \"]\";\n    }\n    if (typeof value === \"object\") {\n      const entries = Object.entries(value);\n      if (entries.length === 0) return \"{}\";\n      return \"{\\n\" + entries.map(([key, item]) => `${innerPad}${JSON.stringify(key)}: ${pyRepr(item, level + 2)},`).join(\"\\n\") + \"\\n\" + pad + \"}\";\n    }\n    return \"None\";\n  };\n\n  const replaceAll = (s, a, b) => s.split(a).join(b);\n  let renderedMessages = pyRepr(messagesForSnippet);\n  for (let i = 0; i < imageCount; i++) {\n    renderedMessages = replaceAll(renderedMessages, `\"__IMAGE_DATA_URL_${i}__\"`, `image_data_urls[${i}]`);\n  }\n  // Either file helpers XOR inline base64 - never emit unused helpers.\n  const usesFileHelpers =\n    imageCount > 0 &&\n    [...Array(imageCount).keys()].every((i) => renderedMessages.includes(`image_data_urls[${i}]`));\n  if (!usesFileHelpers) {\n    imageCount = 0;\n    renderedMessages = pyRepr(deepClone((request || {}).messages || []));\n  }\n  const invokeOptions = deepClone(request || {});\n  for (const key of [\"model\", \"messages\", \"stream\", \"temperature\", \"top_p\", \"max_tokens\", \"tools\"]) {\n    delete invokeOptions[key];\n  }\n  if (request.tools?.length) delete invokeOptions.tool_choice;\n%>\nfrom langchain_nvidia_ai_endpoints import ChatNVIDIA\n<% if (imageCount > 0) { %>from pathlib import Path\nimport base64\n<% } %>\n\nclient = ChatNVIDIA(\n  model=\"<%- request.model %>\",\n  api_key=\"$NVIDIA_API_KEY\",\n<% if (request.temperature !== undefined && request.temperature !== null) { %>\n  temperature=<%- request.temperature %>,\n<% } %>\n<% if (request.top_p !== undefined && request.top_p !== null) { %>\n  top_p=<%- request.top_p %>,\n<% } %>\n<% if (request.max_tokens !== undefined && request.max_tokens !== null) { %>\n  max_completion_tokens=<%- request.max_tokens %>,\n<% } %>\n)\n<% if (request.tools?.length) { %>\nclient = client.bind_tools(\n  <%- pyRepr(request.tools) %><% if (request.tool_choice !== undefined && request.tool_choice !== null) { %>,\n  tool_choice=<%- pyRepr(request.tool_choice) %><% } %>\n)\n<% } %>\ninvoke_options = <%- pyRepr(invokeOptions) %>\n<% if (imageCount > 0) { %>\ndef find_image_path(index):\n  image_mime_types = <%- pyRepr(mediaConfig.image.mimeTypes) %>\n  for suffix in image_mime_types:\n    path = Path(f\"image_{index}{suffix}\")\n    if path.exists():\n      return path\n  expected = \"/\".join(f\".{suffix.lstrip('.')}\" for suffix in image_mime_types)\n  raise FileNotFoundError(f\"Expected image_{index}{expected}\")\n\ndef read_image_data_url(path):\n  image_mime_types = <%- pyRepr(mediaConfig.image.mimeTypes) %>\n  with open(path, \"rb\") as f:\n    image_b64 = base64.b64encode(f.read()).decode()\n  return f\"data:{image_mime_types[path.suffix.lower()]};base64,{image_b64}\"\n\nimage_data_urls = [read_image_data_url(find_image_path(i)) for i in range(1, <%- imageCount + 1 %>)]\n<% } %><% if (hasUnsupportedMedia) { %>\nraise ValueError(\"LangChain snippet currently supports text and image input. Use Python, Node.js, or Shell for video or audio input.\")\n<% } %>\nlc_messages = <%- renderedMessages %>\n<% if (request.stream) { %>\nfor chunk in client.stream(lc_messages, **invoke_options):\n  if chunk.additional_kwargs and \"reasoning_content\" in chunk.additional_kwargs:\n    print(chunk.additional_kwargs[\"reasoning_content\"], end=\"\")\n  print(chunk.content, end=\"\")\n  if chunk.tool_call_chunks:\n    print(chunk.tool_call_chunks)\n<% } else { %>\nresponse = client.invoke(lc_messages, **invoke_options)\nif response.additional_kwargs and \"reasoning_content\" in response.additional_kwargs:\n  print(response.additional_kwargs[\"reasoning_content\"])\nprint(response.content)\nif response.tool_calls:\n  print(response.tool_calls)\n<% } %>\n",
                "node.js": "<%\n  const deepClone = (value) => {\n    if (Array.isArray(value)) return value.map(deepClone);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const key of Object.keys(value)) out[key] = deepClone(value[key]);\n      return out;\n    }\n    return value;\n  };\n  const mediaConfig = {\"image\": {\"mimeTypes\": {\".png\": \"image/png\", \".jpg\": \"image/jpeg\", \".jpeg\": \"image/jpeg\", \".webp\": \"image/webp\"}}, \"video\": {\"mimeTypes\": {}}, \"audio\": {\"mimeTypes\": {}, \"defaultFormat\": \"wav\"}};\n  const payloadForSnippet = deepClone(request || {});\n  const hasStream = payloadForSnippet.stream !== undefined && payloadForSnippet.stream !== null;\n  if (hasStream) payloadForSnippet.stream = \"__STREAM__\";\n\n  const hasMediaKind = (kind) => Object.keys(mediaConfig[kind].mimeTypes || {}).length > 0;\n  const isInlineDataUrl = (url, kind) => (\n    typeof url === \"string\" && new RegExp(`^data:${kind}/[^;]+;base64,`, \"i\").test(url)\n  );\n\n  let imageCount = 0;\n  let videoCount = 0;\n  let audioCount = 0;\n  (payloadForSnippet.messages || []).forEach((message) => {\n    if (!Array.isArray(message?.content)) return;\n    message.content.forEach((part) => {\n      if (hasMediaKind(\"image\") && part?.type === \"image_url\" && isInlineDataUrl(part.image_url?.url, \"image\")) {\n        part.image_url.url = `__IMAGE_DATA_URL_${imageCount}__`;\n        imageCount += 1;\n      } else if (hasMediaKind(\"video\") && part?.type === \"video_url\" && isInlineDataUrl(part.video_url?.url, \"video\")) {\n        part.video_url.url = `__VIDEO_DATA_URL_${videoCount}__`;\n        videoCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"audio_url\" && isInlineDataUrl(part.audio_url?.url, \"audio\")) {\n        part.audio_url.url = `__AUDIO_DATA_URL_${audioCount}__`;\n        audioCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"input_audio\" && part.input_audio?.data) {\n        part.input_audio.data = `__AUDIO_B64_${audioCount}__`;\n        part.input_audio.format = part.input_audio.format || mediaConfig.audio.defaultFormat;\n        audioCount += 1;\n      }\n    });\n  });\n\n  const replaceAll = (s, a, b) => s.split(a).join(b);\n  let renderedPayload = JSON.stringify(payloadForSnippet, null, 2);\n  if (hasStream) renderedPayload = replaceAll(renderedPayload, '\"__STREAM__\"', \"stream\");\n  for (let i = 0; i < imageCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__IMAGE_DATA_URL_${i}__\"`, `imageDataUrls[${i}]`);\n  }\n  for (let i = 0; i < videoCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__VIDEO_DATA_URL_${i}__\"`, `videoDataUrls[${i}]`);\n  }\n  for (let i = 0; i < audioCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_DATA_URL_${i}__\"`, `audioDataUrls[${i}]`);\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_B64_${i}__\"`, `audioB64s[${i}]`);\n  }\n  // Either file helpers XOR inline base64 - never emit unused helpers.\n  const usesFileHelpers =\n    imageCount + videoCount + audioCount > 0 &&\n    [...Array(imageCount).keys()].every((i) => renderedPayload.includes(`imageDataUrls[${i}]`)) &&\n    [...Array(videoCount).keys()].every((i) => renderedPayload.includes(`videoDataUrls[${i}]`)) &&\n    [...Array(audioCount).keys()].every(\n      (i) => renderedPayload.includes(`audioDataUrls[${i}]`) || renderedPayload.includes(`audioB64s[${i}]`)\n    );\n  if (!usesFileHelpers) {\n    imageCount = 0;\n    videoCount = 0;\n    audioCount = 0;\n    const restored = deepClone(request || {});\n    const restoredStream = restored.stream !== undefined && restored.stream !== null;\n    if (restoredStream) restored.stream = \"__STREAM__\";\n    renderedPayload = JSON.stringify(restored, null, 2);\n    if (restoredStream) renderedPayload = replaceAll(renderedPayload, '\"__STREAM__\"', \"stream\");\n  }\n  const hasMedia = usesFileHelpers;\n%>\nimport axios from 'axios';\n<% if (hasMedia) { %>import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\n<% } %>\n\nconst invokeUrl = \"https://integrate.api.nvidia.com/v1/chat/completions\";\nconst stream = <%- Boolean(request.stream) %>;\n\nconst headers = {\n  \"Authorization\": \"Bearer $NVIDIA_API_KEY\",\n  \"Accept\": stream ? \"text/event-stream\" : \"application/json\"\n};\n<% if (hasMedia) { %>\nfunction findMediaPath(kind, index, mimeTypes) {\n  for (const suffix of Object.keys(mimeTypes)) {\n    const path = `${kind}_${index}${suffix}`;\n    if (existsSync(path)) {\n      return path;\n    }\n  }\n  const expected = Object.keys(mimeTypes).join(\"/\");\n  throw new Error(`Expected ${kind}_${index}${expected}`);\n}\n\nasync function readMediaB64(path) {\n  return Buffer.from(await readFile(path)).toString('base64');\n}\n\nfunction mediaDataUrl(path, mediaB64, mimeTypes) {\n  return `data:${mimeTypes[extname(path).toLowerCase()]};base64,${mediaB64}`;\n}\n<% } %>\nasync function main() {\n<% if (imageCount > 0) { %>  const imageMimeTypes = <%- JSON.stringify(mediaConfig.image.mimeTypes, null, 2) %>;\n  const imagePaths = [<% for (let i = 1; i <= imageCount; i++) { %>findMediaPath(\"image\", <%- i %>, imageMimeTypes)<%- i < imageCount ? \", \" : \"\" %><% } %>];\n  const imageB64s = await Promise.all(imagePaths.map(readMediaB64));\n  const imageDataUrls = imagePaths.map((path, index) => mediaDataUrl(path, imageB64s[index], imageMimeTypes));\n<% } %><% if (videoCount > 0) { %>  const videoMimeTypes = <%- JSON.stringify(mediaConfig.video.mimeTypes, null, 2) %>;\n  const videoPaths = [<% for (let i = 1; i <= videoCount; i++) { %>findMediaPath(\"video\", <%- i %>, videoMimeTypes)<%- i < videoCount ? \", \" : \"\" %><% } %>];\n  const videoB64s = await Promise.all(videoPaths.map(readMediaB64));\n  const videoDataUrls = videoPaths.map((path, index) => mediaDataUrl(path, videoB64s[index], videoMimeTypes));\n<% } %><% if (audioCount > 0) { %>  const audioMimeTypes = <%- JSON.stringify(mediaConfig.audio.mimeTypes, null, 2) %>;\n  const audioPaths = [<% for (let i = 1; i <= audioCount; i++) { %>findMediaPath(\"audio\", <%- i %>, audioMimeTypes)<%- i < audioCount ? \", \" : \"\" %><% } %>];\n  const audioB64s = await Promise.all(audioPaths.map(readMediaB64));\n  const audioDataUrls = audioPaths.map((path, index) => mediaDataUrl(path, audioB64s[index], audioMimeTypes));\n<% } %>  const payload = <%- renderedPayload %>;\n\n  const response = await axios.post(invokeUrl, payload, {\n    headers: headers,\n    responseType: stream ? 'stream' : 'json'\n  });\n\n  if (stream) {\n    response.data.on('data', (chunk) => {\n      console.log(chunk.toString());\n    });\n  } else {\n    console.log(JSON.stringify(response.data));\n  }\n}\n\nmain().catch(error => {\n  if (error.response) {\n    console.error(`HTTP ${error.response.status}`);\n    if (error.response.data?.on) {\n      error.response.data.on('data', (chunk) => console.error(chunk.toString()));\n    } else {\n      console.error(error.response.data);\n    }\n  } else {\n    console.error(error);\n  }\n});\n",
                "curl": "<%\n  const deepClone = (value) => {\n    if (Array.isArray(value)) return value.map(deepClone);\n    if (value && typeof value === \"object\") {\n      const out = {};\n      for (const key of Object.keys(value)) out[key] = deepClone(value[key]);\n      return out;\n    }\n    return value;\n  };\n  const mediaConfig = {\"image\": {\"mimeTypes\": {\".png\": \"image/png\", \".jpg\": \"image/jpeg\", \".jpeg\": \"image/jpeg\", \".webp\": \"image/webp\"}}, \"video\": {\"mimeTypes\": {}}, \"audio\": {\"mimeTypes\": {}, \"defaultFormat\": \"wav\"}};\n  const payloadForSnippet = deepClone(request || {});\n  const hasMediaKind = (kind) => Object.keys(mediaConfig[kind].mimeTypes || {}).length > 0;\n  const isInlineDataUrl = (url, kind) => (\n    typeof url === \"string\" && new RegExp(`^data:${kind}/[^;]+;base64,`, \"i\").test(url)\n  );\n\n  let imageCount = 0;\n  let videoCount = 0;\n  let audioCount = 0;\n  (payloadForSnippet.messages || []).forEach((message) => {\n    if (!Array.isArray(message?.content)) return;\n    message.content.forEach((part) => {\n      if (hasMediaKind(\"image\") && part?.type === \"image_url\" && isInlineDataUrl(part.image_url?.url, \"image\")) {\n        part.image_url.url = `__IMAGE_DATA_URL_${imageCount}__`;\n        imageCount += 1;\n      } else if (hasMediaKind(\"video\") && part?.type === \"video_url\" && isInlineDataUrl(part.video_url?.url, \"video\")) {\n        part.video_url.url = `__VIDEO_DATA_URL_${videoCount}__`;\n        videoCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"audio_url\" && isInlineDataUrl(part.audio_url?.url, \"audio\")) {\n        part.audio_url.url = `__AUDIO_DATA_URL_${audioCount}__`;\n        audioCount += 1;\n      } else if (hasMediaKind(\"audio\") && part?.type === \"input_audio\" && part.input_audio?.data) {\n        part.input_audio.data = `__AUDIO_B64_${audioCount}__`;\n        part.input_audio.format = part.input_audio.format || mediaConfig.audio.defaultFormat;\n        audioCount += 1;\n      }\n    });\n  });\n\n  const replaceAll = (s, a, b) => s.split(a).join(b);\n  const escapeHeredoc = (text) => text.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"$\", \"\\\\$\").replaceAll(\"`\", \"\\\\`\");\n  let renderedPayload = escapeHeredoc(JSON.stringify(payloadForSnippet, null, 2));\n  for (let i = 0; i < imageCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__IMAGE_DATA_URL_${i}__\"`, `\"${\"${\"}image_${i + 1}_data_url}\"`);\n  }\n  for (let i = 0; i < videoCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__VIDEO_DATA_URL_${i}__\"`, `\"${\"${\"}video_${i + 1}_data_url}\"`);\n  }\n  for (let i = 0; i < audioCount; i++) {\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_DATA_URL_${i}__\"`, `\"${\"${\"}audio_${i + 1}_data_url}\"`);\n    renderedPayload = replaceAll(renderedPayload, `\"__AUDIO_B64_${i}__\"`, `\"${\"${\"}audio_${i + 1}_b64}\"`);\n  }\n  // Either file helpers XOR inline base64 - never emit unused helpers.\n  const usesFileHelpers =\n    imageCount + videoCount + audioCount > 0 &&\n    [...Array(imageCount).keys()].every((i) => renderedPayload.includes(`image_${i + 1}_data_url`)) &&\n    [...Array(videoCount).keys()].every((i) => renderedPayload.includes(`video_${i + 1}_data_url`)) &&\n    [...Array(audioCount).keys()].every(\n      (i) => renderedPayload.includes(`audio_${i + 1}_data_url`) || renderedPayload.includes(`audio_${i + 1}_b64`)\n    );\n  if (!usesFileHelpers) {\n    imageCount = 0;\n    videoCount = 0;\n    audioCount = 0;\n    renderedPayload = escapeHeredoc(JSON.stringify(deepClone(request || {}), null, 2));\n  }\n  const hasMedia = usesFileHelpers;\n%>\nstream=<%- request.stream ? \"true\" : \"false\" %>\nif [ \"$stream\" = true ]; then\n    accept_header='Accept: text/event-stream'\nelse\n    accept_header='Accept: application/json'\nfi\n<% if (hasMedia) { %>\nmime_type_for() {\n  case \"$1\" in\n<% for (const [suffix, mimeType] of Object.entries({...mediaConfig.image.mimeTypes, ...mediaConfig.video.mimeTypes, ...mediaConfig.audio.mimeTypes})) { %>    *<%- suffix %>) echo \"<%- mimeType %>\" ;;\n<% } %>    *) echo \"Unsupported media file: $1\" >&2; return 1 ;;\n  esac\n}\n\nfind_media_path() {\n  local kind=\"$1\"\n  local index=\"$2\"\n  shift 2\n  local ext path\n  for ext in \"$@\"; do\n    path=\"${kind}_${index}.${ext}\"\n    if [ -f \"$path\" ]; then\n      echo \"$path\"\n      return 0\n    fi\n  done\n  echo \"Expected ${kind}_${index}.$*\" >&2\n  return 1\n}\n\nmedia_b64() {\n  base64 < \"$1\" | tr -d '\\n'\n}\n\nmedia_data_url() {\n  local path=\"$1\"\n  local mime_type media_base64\n  mime_type=$(mime_type_for \"$path\") || return 1\n  media_base64=$(media_b64 \"$path\") || return 1\n  printf 'data:%s;base64,%s' \"$mime_type\" \"$media_base64\"\n}\n<% for (let i = 1; i <= imageCount; i++) { %>\nimage_<%- i %>_path=$(find_media_path image <%- i %><% for (const suffix of Object.keys(mediaConfig.image.mimeTypes)) { %> <%- suffix.slice(1) %><% } %>)\nimage_<%- i %>_data_url=$(media_data_url \"$image_<%- i %>_path\")\n<% } %><% for (let i = 1; i <= videoCount; i++) { %>\nvideo_<%- i %>_path=$(find_media_path video <%- i %><% for (const suffix of Object.keys(mediaConfig.video.mimeTypes)) { %> <%- suffix.slice(1) %><% } %>)\nvideo_<%- i %>_data_url=$(media_data_url \"$video_<%- i %>_path\")\n<% } %><% for (let i = 1; i <= audioCount; i++) { %>\naudio_<%- i %>_path=$(find_media_path audio <%- i %><% for (const suffix of Object.keys(mediaConfig.audio.mimeTypes)) { %> <%- suffix.slice(1) %><% } %>)\naudio_<%- i %>_b64=$(media_b64 \"$audio_<%- i %>_path\")\naudio_<%- i %>_data_url=$(media_data_url \"$audio_<%- i %>_path\")\n<% } %><% } %>\ncat > payload.json <<JSON\n<%- renderedPayload %>\nJSON\n\ncurl https://integrate.api.nvidia.com/v1/chat/completions \\\n  -H \"Authorization: Bearer $NVIDIA_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"$accept_header\" \\\n  -d @payload.json"
              }
            }
          ]
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "ChatCompletionRequest": {
        "type": "object",
        "required": [
          "model",
          "messages"
        ],
        "properties": {
          "model": {
            "type": "string",
            "default": "mistralai/mistral-large-4-1t-a52b",
            "enum": [
              "mistralai/mistral-large-4-1t-a52b"
            ],
            "title": "Model"
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "description": "Conversation history. Use content-part arrays for images. After an assistant tool call, include a tool message with its tool_call_id. Preserve assistant reasoning_content when continuing a conversation.",
            "items": {
              "$ref": "#/components/schemas/ChatMessage"
            },
            "default": [
              {
                "role": "user",
                "content": "What is 37 + 58? Reply with only the number."
              }
            ],
            "examples": [
              [
                {
                  "role": "user",
                  "content": "What is 37 + 58? Reply with only the number."
                }
              ]
            ],
            "title": "Messages"
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 1,
            "maximum": 262144,
            "default": 4096,
            "description": "Maximum generated tokens, including reasoning and the final answer. Small budgets may end during reasoning with null content and finish_reason=length. Prompt plus output must fit the context window.",
            "title": "Max Tokens"
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "title": "Stream"
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 2,
            "default": 0.5,
            "description": "The sampling temperature to use for text generation. The higher the temperature value is, the less deterministic the output text will be. It is not recommended to modify both temperature and top_p in the same call.",
            "title": "Temperature"
          },
          "top_p": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 1,
            "default": 1,
            "description": "The top-p sampling mass used for text generation. The top-p value determines the probability mass that is sampled at sampling time. For example, if top_p = 0.2, only the most likely tokens (summing to 0.2 cumulative probability) will be sampled. It is not recommended to modify both temperature and top_p in the same call.",
            "title": "Top P"
          },
          "frequency_penalty": {
            "type": "number",
            "minimum": -2,
            "maximum": 2,
            "default": 0,
            "description": "Indicates how much to penalize new tokens based on their existing frequency in the text so far, decreasing model likelihood to repeat the same line verbatim.",
            "title": "Frequency Penalty"
          },
          "presence_penalty": {
            "type": "number",
            "minimum": -2,
            "maximum": 2,
            "default": 0,
            "description": "Positive values penalize new tokens based on whether they appear in the text so far, increasing model likelihood to talk about new topics.",
            "title": "Presence Penalty"
          },
          "seed": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Optional sampling seed, limited to JavaScript-safe integers for the interactive examples. Deterministic output is not guaranteed.",
            "title": "Seed"
          },
          "stop": {
            "description": "Stop string or list of stop strings; omitted from the output.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "null"
              }
            ],
            "title": "Stop"
          },
          "tools": {
            "type": "array",
            "description": "Functions the model may request; the caller executes them.",
            "items": {
              "$ref": "#/components/schemas/FunctionTool"
            },
            "title": "Tools"
          },
          "tool_choice": {
            "description": "Choose auto, none, required, or force a named function.",
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "auto",
                  "none",
                  "required"
                ]
              },
              {
                "type": "object",
                "required": [
                  "type",
                  "function"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "function"
                    ],
                    "const": "function",
                    "title": "Type",
                    "default": "function"
                  },
                  "function": {
                    "type": "object",
                    "required": [
                      "name"
                    ],
                    "properties": {
                      "name": {
                        "type": "string",
                        "title": "Name"
                      }
                    },
                    "title": "Function"
                  }
                }
              }
            ],
            "title": "Tool Choice"
          },
          "reasoning_effort": {
            "type": "string",
            "enum": [
              "none",
              "high"
            ],
            "default": "high",
            "description": "Controls reasoning for this request. Set to high, the model reasons first and the response carries reasoning_content separately from the final content; set to none, it answers directly. The playground sends high by default; a request that omits this field is served as none. chat_template_kwargs.enable_thinking is not honored by this recipe.",
            "title": "Reasoning Effort"
          }
        },
        "title": "ChatCompletionRequest"
      },
      "ChatMessage": {
        "type": "object",
        "required": [
          "role"
        ],
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "system",
              "user",
              "assistant",
              "tool"
            ],
            "title": "Role"
          },
          "content": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              },
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ContentPart"
                }
              }
            ],
            "description": "Message text or content parts. Required except on an assistant message that carries tool_calls, where it may be null.",
            "title": "Content"
          },
          "reasoning_content": {
            "type": [
              "string",
              "null"
            ],
            "description": "Assistant reasoning, separate from the final answer.",
            "title": "Reasoning Content"
          },
          "tool_calls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ToolCall"
            },
            "title": "Tool Calls"
          },
          "tool_call_id": {
            "type": "string",
            "description": "Required on tool-result messages; matches an assistant tool call ID.",
            "title": "Tool Call Id"
          },
          "name": {
            "type": "string",
            "title": "Name"
          }
        },
        "title": "ChatMessage"
      },
      "ContentPart": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "type",
              "text"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "text"
                ],
                "const": "text",
                "title": "Type",
                "default": "text"
              },
              "text": {
                "type": "string",
                "title": "Text"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "image_url"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "image_url"
                ],
                "const": "image_url",
                "title": "Type",
                "default": "image_url"
              },
              "image_url": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "HTTPS image URL or base64 data URL. PNG, JPEG, or WebP; at most eight images per request.",
                    "title": "Url"
                  },
                  "detail": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "low",
                      "high"
                    ],
                    "title": "Detail"
                  }
                },
                "title": "Image Url"
              }
            }
          }
        ],
        "title": "ContentPart"
      },
      "FunctionTool": {
        "type": "object",
        "required": [
          "type",
          "function"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "function"
            ],
            "const": "function",
            "title": "Type",
            "default": "function"
          },
          "function": {
            "type": "object",
            "required": [
              "name"
            ],
            "properties": {
              "name": {
                "type": "string",
                "title": "Name"
              },
              "description": {
                "type": "string",
                "title": "Description"
              },
              "parameters": {
                "type": "object",
                "description": "JSON Schema for the function arguments.",
                "title": "Parameters"
              }
            },
            "title": "Function"
          }
        },
        "title": "FunctionTool"
      },
      "ToolCall": {
        "type": "object",
        "required": [
          "id",
          "type",
          "function"
        ],
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "type": {
            "type": "string",
            "enum": [
              "function"
            ],
            "const": "function",
            "title": "Type",
            "default": "function"
          },
          "function": {
            "type": "object",
            "required": [
              "name",
              "arguments"
            ],
            "properties": {
              "name": {
                "type": "string",
                "title": "Name"
              },
              "arguments": {
                "type": "string",
                "description": "JSON-encoded function arguments; parse and validate before execution.",
                "title": "Arguments"
              }
            },
            "title": "Function"
          }
        },
        "title": "ToolCall"
      },
      "ChatCompletionResponse": {
        "type": "object",
        "required": [
          "model",
          "choices"
        ],
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "object": {
            "type": "string",
            "default": "chat.completion",
            "title": "Object"
          },
          "created": {
            "type": "integer",
            "title": "Created"
          },
          "model": {
            "type": "string",
            "title": "Model"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "index",
                "message",
                "finish_reason"
              ],
              "properties": {
                "index": {
                  "type": "integer",
                  "title": "Index"
                },
                "message": {
                  "$ref": "#/components/schemas/ChatMessage",
                  "title": "Message"
                },
                "finish_reason": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "stop",
                    "length",
                    "tool_calls",
                    "content_filter",
                    null
                  ],
                  "title": "Finish Reason"
                }
              }
            },
            "title": "Choices"
          },
          "usage": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "prompt_tokens": {
                "type": "integer",
                "title": "Prompt Tokens"
              },
              "completion_tokens": {
                "type": "integer",
                "title": "Completion Tokens"
              },
              "total_tokens": {
                "type": "integer",
                "title": "Total Tokens"
              }
            },
            "title": "Usage"
          }
        },
        "title": "ChatCompletionResponse"
      }
    }
  }
}
```