(apiModel: z.infer<typeof JiekouModel>)
| 183 | } |
| 184 | |
| 185 | function processModel(apiModel: z.infer<typeof JiekouModel>): ProcessedModel { |
| 186 | const features = apiModel.features ?? []; |
| 187 | const inputModalities = apiModel.input_modalities ?? ["text"]; |
| 188 | const outputModalities = apiModel.output_modalities ?? ["text"]; |
| 189 | |
| 190 | // Convert price: divide by 10000 (from 0.0001 USD to USD) |
| 191 | const inputCost = apiModel.input_token_price_per_m / 10000; |
| 192 | const outputCost = apiModel.output_token_price_per_m / 10000; |
| 193 | |
| 194 | // Features mapping (ignore "serverless") |
| 195 | const hasToolCall = features.includes("function-calling"); |
| 196 | const hasStructuredOutput = features.includes("structured-outputs"); |
| 197 | const hasReasoning = features.includes("reasoning"); |
| 198 | |
| 199 | // Attachment: true if image/video/audio in input modalities |
| 200 | const hasAttachment = |
| 201 | inputModalities.includes("image") || |
| 202 | inputModalities.includes("video") || |
| 203 | inputModalities.includes("audio"); |
| 204 | |
| 205 | const yearMonth = getYearMonth(); |
| 206 | |
| 207 | return { |
| 208 | name: apiModel.id, |
| 209 | family: inferFamily(apiModel.id), |
| 210 | release_date: yearMonth, |
| 211 | last_updated: yearMonth, |
| 212 | attachment: hasAttachment, |
| 213 | reasoning: hasReasoning, |
| 214 | temperature: true, |
| 215 | tool_call: hasToolCall, |
| 216 | structured_output: hasStructuredOutput, |
| 217 | open_weights: isOpenWeights(apiModel.id), |
| 218 | cost: { |
| 219 | input: inputCost, |
| 220 | output: outputCost, |
| 221 | }, |
| 222 | limit: { |
| 223 | context: apiModel.context_size, |
| 224 | output: apiModel.max_output_tokens, |
| 225 | }, |
| 226 | modalities: { |
| 227 | input: inputModalities, |
| 228 | output: outputModalities, |
| 229 | }, |
| 230 | }; |
| 231 | } |
| 232 | |
| 233 | function formatToml(model: ProcessedModel): string { |
| 234 | const lines: string[] = []; |
no test coverage detected