Created
May 27, 2025 15:22
-
-
Save PaulieScanlon/d58e380cc197ebb5af2fc6c809412786 to your computer and use it in GitHub Desktop.
Grabs Vercel Model Capabilities and creates a modelData array for mastra.ai docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as cheerio from "cheerio"; | |
const apiKeyMap = { | |
"xAI Grok": "XAI_API_KEY", | |
OpenAI: "OPENAI_API_KEY", | |
Anthropic: "ANTHROPIC_API_KEY", | |
Mistral: "MISTRAL_API_KEY", | |
"Google Generative AI": "GOOGLE_API_KEY", | |
"Google Vertex": "GOOGLE_VERTEX_API_KEY", | |
DeepSeek: "DEEPSEEK_API_KEY", | |
Cerebras: "CEREBRAS_API_KEY", | |
Groq: "GROQ_API_KEY", | |
Vercel: "VERCEL_API_KEY" | |
}; | |
function parseBool(cell) { | |
const val = cell.toLowerCase(); | |
if (val.includes("<check")) return true; | |
if (val.includes("<cross")) return false; | |
return val === "yes"; | |
} | |
// Helper: Get first word lowercased for provider URL slug | |
function slugifyProviderFirstWord(name) { | |
const firstWord = name.trim().split(/\s+/)[0]; | |
return firstWord.toLowerCase(); | |
} | |
function getApiKey(provider) { | |
// Extract plain text from markdown link [Name](url) | |
const plainProvider = provider.replace(/\[([^\]]+)\]\([^)]+\)/, "$1").trim(); | |
// Find matching key ignoring case | |
const key = Object.keys(apiKeyMap).find((k) => k.toLowerCase() === plainProvider.toLowerCase()); | |
return key ? apiKeyMap[key] : ""; | |
} | |
(async () => { | |
const url = "https://raw.githubusercontent.com/vercel/ai/refs/heads/main/content/docs/02-foundations/02-providers-and-models.mdx"; | |
const res = await fetch(url); | |
const mdx = await res.text(); | |
const sectionRegex = /## Model Capabilities\s+([\s\S]*?)(?=\n## |\n$)/; | |
const match = sectionRegex.exec(mdx); | |
if (!match) { | |
console.error("❌ Could not find the Model Capabilities section"); | |
return; | |
} | |
const tableMarkdown = match[1].trim(); | |
const tableMatch = tableMarkdown.match(/\|(.+\|)+\n\|[-|:\s]+\|\n([\s\S]+?)(?=\n\n|\n$)/); | |
if (!tableMatch) { | |
console.error("❌ Could not find a markdown table in the section"); | |
return; | |
} | |
const headerRow = tableMatch[0].split("\n")[0]; | |
const dataRows = tableMatch[0].split("\n").slice(2); | |
const htmlTable = ` | |
<table> | |
<thead> | |
<tr>${headerRow | |
.split("|") | |
.filter(Boolean) | |
.map((c) => `<th>${c.trim()}</th>`) | |
.join("")}</tr> | |
</thead> | |
<tbody> | |
${dataRows | |
.map((row) => { | |
const cells = row.split("|").filter(Boolean); | |
return `<tr>${cells.map((c) => `<td>${c.trim()}</td>`).join("")}</tr>`; | |
}) | |
.join("")} | |
</tbody> | |
</table> | |
`; | |
const $ = cheerio.load(htmlTable); | |
const modelData = []; | |
$("tbody tr").each(function () { | |
const tds = $(this).find("td"); | |
const rawProvider = tds.eq(0).html() || ""; | |
const provider = rawProvider.replace(/\[([^\]]+)\]\([^)]+\)/, "$1").trim(); | |
let model = tds.eq(1).text().trim(); | |
model = model.replace(/`/g, ""); | |
const imageInput = parseBool(tds.eq(2).html() || ""); | |
const objectGeneration = parseBool(tds.eq(3).html() || ""); | |
const toolUsage = parseBool(tds.eq(4).html() || ""); | |
const toolStreaming = parseBool(tds.eq(5).html() || ""); | |
const apiKey = getApiKey(provider); | |
const providerSlug = slugifyProviderFirstWord(provider); | |
modelData.push({ | |
provider, | |
providerUrl: `https://sdk.vercel.ai/providers/ai-sdk-providers/${providerSlug}`, | |
model, | |
imageInput, | |
objectGeneration, | |
toolUsage, | |
toolStreaming, | |
apiKey | |
}); | |
}); | |
console.log("const modelData =", JSON.stringify(modelData, null, 2)); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment