()
| 109 | } |
| 110 | |
| 111 | async function main() { |
| 112 | const dryRun = process.argv.includes("--dry-run"); |
| 113 | |
| 114 | const outDir = path.join( |
| 115 | import.meta.dirname, |
| 116 | "..", |
| 117 | "..", |
| 118 | "..", |
| 119 | "providers", |
| 120 | "ambient", |
| 121 | "models", |
| 122 | ); |
| 123 | |
| 124 | const res = await fetch(API_ENDPOINT); |
| 125 | if (!res.ok) { |
| 126 | console.error(`Fetch failed: ${res.status} ${res.statusText}`); |
| 127 | process.exit(1); |
| 128 | } |
| 129 | |
| 130 | const parsed = AmbientResponse.safeParse(await res.json()); |
| 131 | if (!parsed.success) { |
| 132 | console.error("Invalid Ambient response:", parsed.error.issues); |
| 133 | process.exit(1); |
| 134 | } |
| 135 | |
| 136 | const selected = parsed.data.data.filter((m) => ALLOWLIST.has(m.id)); |
| 137 | const missing = [...ALLOWLIST].filter( |
| 138 | (id) => !selected.some((m) => m.id === id), |
| 139 | ); |
| 140 | if (missing.length > 0) { |
| 141 | console.error(`Allowlisted models missing from API: ${missing.join(", ")}`); |
| 142 | process.exit(1); |
| 143 | } |
| 144 | |
| 145 | let count = 0; |
| 146 | for (const model of selected) { |
| 147 | const baseModel = BASE_MODEL_MAP[model.id]; |
| 148 | if (!baseModel) { |
| 149 | console.error(`No BASE_MODEL_MAP entry for ${model.id}; skipping`); |
| 150 | continue; |
| 151 | } |
| 152 | const filePath = path.join(outDir, `${model.id}.toml`); |
| 153 | const toml = formatToml(model, baseModel); |
| 154 | if (dryRun) { |
| 155 | console.log(`--- ${path.relative(process.cwd(), filePath)} ---`); |
| 156 | console.log(toml); |
| 157 | } else { |
| 158 | await mkdir(path.dirname(filePath), { recursive: true }); |
| 159 | await Bun.write(filePath, toml); |
| 160 | } |
| 161 | count++; |
| 162 | } |
| 163 | |
| 164 | console.log( |
| 165 | `${dryRun ? "Previewed" : "Wrote"} ${count} model file(s) under providers/ambient/models/`, |
| 166 | ); |
| 167 | } |
| 168 |
no test coverage detected