Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions scripts/convert-openrouter-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,30 @@ function generateModelMetaString(model: OpenRouterModel): string {
const outputModalities = model.architecture.output_modalities
.map(mapInputModality)
.filter((m): m is InputModality => m !== null)
// OpenRouter uses `~prefix/name` to denote routing aliases (e.g.
// `~anthropic/claude-haiku-latest`). The model ID itself is preserved as a
// string literal so users can pass it to `chat({ model: ... })`. The leading
// `~` is mapped to `_` only for the derived constant name so it's a valid
// JavaScript identifier.
const constName = model.id
.replaceAll('~', '_')
.replaceAll('/', '-')
.replaceAll('-', '_')
.replaceAll('.', '_')
.replaceAll(':', '_')
.toUpperCase()
// Safety net: if a future OpenRouter ID quirk produces a non-identifier
// constant name, fail loudly here instead of letting prettier choke on the
// generated file later in the pipeline.
if (!/^[A-Z_][A-Z0-9_]*$/.test(constName)) {
throw new Error(
`Generated constant name is not a valid JS identifier: ${JSON.stringify(
constName,
)} (from OpenRouter model.id ${JSON.stringify(
model.id,
)}). Extend the constName sanitiser to handle this case.`,
)
}
// Ensure at least 'text' is present
if (!inputModalities.includes('text')) {
inputModalities.unshift('text')
Expand Down
Loading