From 31a361200636c0559096fd3ee451116450c0df4f Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Mon, 13 Jul 2026 16:45:48 -0400 Subject: [PATCH 01/11] feat(sync): add Merge Gateway model sync --- .github/workflows/sync-models.yml | 1 + package.json | 1 + packages/core/src/sync/index.ts | 5 +- .../core/src/sync/providers/merge-gateway.ts | 287 ++++++++++++++++++ packages/core/test/sync.test.ts | 193 ++++++++++++ .../anthropic/claude-3-7-sonnet-20250219.toml | 13 + .../models/anthropic/claude-fable-5.toml | 9 + .../anthropic/claude-haiku-4-5-20251001.toml | 11 +- .../anthropic/claude-opus-4-1-20250805.toml | 11 +- .../anthropic/claude-opus-4-20250514.toml | 11 +- .../anthropic/claude-opus-4-5-20251101.toml | 15 +- .../models/anthropic/claude-opus-4-6.toml | 14 +- .../models/anthropic/claude-opus-4-7.toml | 9 +- .../models/anthropic/claude-opus-4-8.toml | 3 + .../anthropic/claude-sonnet-4-5-20250929.toml | 11 +- .../models/anthropic/claude-sonnet-4-6.toml | 14 +- .../models/anthropic/claude-sonnet-5.toml | 9 + .../models/cohere/command-a-03-2025.toml | 2 + .../models/cohere/command-r-08-2024.toml | 2 + .../models/cohere/command-r-plus-08-2024.toml | 2 + .../models/cohere/command-r7b-12-2024.toml | 2 + .../models/deepseek/deepseek-r1.toml | 13 + .../models/deepseek/deepseek-v4-flash.toml | 1 + .../models/deepseek/deepseek-v4-pro.toml | 1 + .../models/google/gemini-2.5-flash-lite.toml | 15 +- .../models/google/gemini-2.5-flash.toml | 12 +- .../models/google/gemini-2.5-pro.toml | 9 +- .../models/google/gemini-3-flash-preview.toml | 8 +- .../models/google/gemini-3.1-flash-lite.toml | 9 +- .../gemini-3.1-pro-preview-customtools.toml | 8 +- .../models/google/gemini-3.1-pro-preview.toml | 8 +- .../models/google/gemini-3.5-flash.toml | 8 +- .../models/google/gemma-4-26b-a4b-it.toml | 17 +- .../models/google/gemma-4-31b-it.toml | 17 +- .../models/meta/llama-3.3-70b-instruct.toml | 7 + .../models/meta/muse-spark-1.1.toml | 14 + .../models/minimax/minimax-m2.1.toml | 7 + .../minimax/minimax-m2.5-highspeed.toml | 5 + .../models/minimax/minimax-m2.5.toml | 5 + .../minimax/minimax-m2.7-highspeed.toml | 5 + .../models/minimax/minimax-m2.7.toml | 5 + .../models/minimax/minimax-m2.toml | 7 + .../models/minimax/minimax-m3.toml | 13 +- .../models/mistral/devstral-2512.toml | 6 +- .../models/mistral/mistral-large-2512.toml | 5 + .../models/mistral/mistral-medium-2505.toml | 5 + .../models/nvidia/nemotron-nano-9b-v2.toml | 13 + .../models/openai/gpt-3.5-turbo.toml | 6 + .../models/openai/gpt-4-turbo.toml | 8 + .../models/openai/gpt-4.1-mini.toml | 1 + .../models/openai/gpt-4.1-nano.toml | 4 + .../merge-gateway/models/openai/gpt-4.toml | 7 + .../models/openai/gpt-4o-2024-05-13.toml | 4 + .../models/openai/gpt-4o-2024-08-06.toml | 3 + .../models/openai/gpt-4o-2024-11-20.toml | 3 + .../models/openai/gpt-4o-mini.toml | 1 + .../models/openai/gpt-5-chat-latest.toml | 9 + .../models/openai/gpt-5-mini.toml | 8 +- .../models/openai/gpt-5-nano.toml | 8 +- .../models/openai/gpt-5.1-chat-latest.toml | 4 + .../merge-gateway/models/openai/gpt-5.1.toml | 8 +- .../models/openai/gpt-5.2-chat-latest.toml | 4 + .../merge-gateway/models/openai/gpt-5.2.toml | 8 +- .../models/openai/gpt-5.3-chat-latest.toml | 4 + .../models/openai/gpt-5.4-mini.toml | 9 +- .../models/openai/gpt-5.4-nano.toml | 9 +- .../models/openai/gpt-5.6-luna.toml | 7 + .../models/openai/gpt-5.6-sol.toml | 12 + .../models/openai/gpt-5.6-terra.toml | 7 + .../merge-gateway/models/openai/gpt-5.toml | 8 +- .../models/openai/gpt-oss-120b.toml | 12 + .../models/openai/gpt-oss-20b.toml | 10 + .../merge-gateway/models/openai/o3-mini.toml | 6 +- .../merge-gateway/models/openai/o4-mini.toml | 4 + .../merge-gateway/models/qwen/qwen-flash.toml | 11 + .../merge-gateway/models/qwen/qwen-plus.toml | 11 + .../models/qwen/qwen3-235b-a22b.toml | 12 + .../merge-gateway/models/qwen/qwen3-32b.toml | 11 + .../qwen/qwen3-coder-480b-a35b-instruct.toml | 11 + .../models/qwen/qwen3-coder-flash.toml | 10 + .../models/qwen/qwen3-coder-plus.toml | 11 + .../merge-gateway/models/qwen/qwen3-max.toml | 7 + .../qwen/qwen3-next-80b-a3b-instruct.toml | 7 + .../qwen/qwen3-next-80b-a3b-thinking.toml | 8 + .../models/qwen/qwen3-vl-plus.toml | 12 + .../models/qwen/qwen3.5-122b-a10b.toml | 16 + .../models/qwen/qwen3.5-27b.toml | 16 + .../models/qwen/qwen3.5-35b-a3b.toml | 17 ++ .../models/qwen/qwen3.5-397b-a17b.toml | 17 ++ .../merge-gateway/models/qwen/qwen3.5-9b.toml | 14 + .../models/qwen/qwen3.5-plus.toml | 14 + .../models/qwen/qwen3.6-27b.toml | 15 + .../models/qwen/qwen3.6-35b-a3b.toml | 13 + .../models/qwen/qwen3.6-flash.toml | 15 + .../models/qwen/qwen3.6-max-preview.toml | 11 + .../models/qwen/qwen3.6-plus.toml | 14 + .../models/qwen/qwen3.7-max.toml | 11 + .../models/qwen/qwen3.7-plus.toml | 12 + .../xai/grok-4.20-0309-non-reasoning.toml | 13 + .../models/xai/grok-4.20-0309-reasoning.toml | 7 + .../merge-gateway/models/xai/grok-4.3.toml | 6 + .../merge-gateway/models/xai/grok-4.5.toml | 7 + .../models/xai/grok-build-0.1.toml | 10 + .../merge-gateway/models/zai/glm-4.5-air.toml | 9 +- .../merge-gateway/models/zai/glm-4.5.toml | 8 +- .../merge-gateway/models/zai/glm-4.5v.toml | 17 ++ .../merge-gateway/models/zai/glm-4.6.toml | 8 +- .../models/zai/glm-4.7-flash.toml | 11 + .../models/zai/glm-4.7-flashx.toml | 6 +- .../merge-gateway/models/zai/glm-4.7.toml | 8 +- .../merge-gateway/models/zai/glm-5-turbo.toml | 6 +- .../merge-gateway/models/zai/glm-5.1.toml | 5 +- .../merge-gateway/models/zai/glm-5.2.toml | 11 +- providers/merge-gateway/models/zai/glm-5.toml | 8 +- sync.md | 14 + 115 files changed, 1429 insertions(+), 43 deletions(-) create mode 100644 packages/core/src/sync/providers/merge-gateway.ts create mode 100644 providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml create mode 100644 providers/merge-gateway/models/anthropic/claude-fable-5.toml create mode 100644 providers/merge-gateway/models/anthropic/claude-sonnet-5.toml create mode 100644 providers/merge-gateway/models/deepseek/deepseek-r1.toml create mode 100644 providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml create mode 100644 providers/merge-gateway/models/meta/muse-spark-1.1.toml create mode 100644 providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml create mode 100644 providers/merge-gateway/models/openai/gpt-3.5-turbo.toml create mode 100644 providers/merge-gateway/models/openai/gpt-4-turbo.toml create mode 100644 providers/merge-gateway/models/openai/gpt-4.toml create mode 100644 providers/merge-gateway/models/openai/gpt-5.6-luna.toml create mode 100644 providers/merge-gateway/models/openai/gpt-5.6-sol.toml create mode 100644 providers/merge-gateway/models/openai/gpt-5.6-terra.toml create mode 100644 providers/merge-gateway/models/openai/gpt-oss-120b.toml create mode 100644 providers/merge-gateway/models/openai/gpt-oss-20b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen-flash.toml create mode 100644 providers/merge-gateway/models/qwen/qwen-plus.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3-32b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3-coder-480b-a35b-instruct.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3-coder-flash.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3-coder-plus.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3-max.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3-vl-plus.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.5-27b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.5-9b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.5-plus.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.6-27b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.6-flash.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.6-plus.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.7-max.toml create mode 100644 providers/merge-gateway/models/qwen/qwen3.7-plus.toml create mode 100644 providers/merge-gateway/models/xai/grok-4.20-0309-non-reasoning.toml create mode 100644 providers/merge-gateway/models/xai/grok-4.5.toml create mode 100644 providers/merge-gateway/models/xai/grok-build-0.1.toml create mode 100644 providers/merge-gateway/models/zai/glm-4.5v.toml create mode 100644 providers/merge-gateway/models/zai/glm-4.7-flash.toml diff --git a/.github/workflows/sync-models.yml b/.github/workflows/sync-models.yml index 5edb83859a..0a1bc91169 100644 --- a/.github/workflows/sync-models.yml +++ b/.github/workflows/sync-models.yml @@ -73,6 +73,7 @@ jobs: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} VENICE_API_KEY: ${{ secrets.VENICE_API_KEY }} LLMGATEWAY_API_KEY: ${{ secrets.LLMGATEWAY_API_KEY }} + MERGE_GATEWAY_API_KEY: ${{ secrets.MERGE_GATEWAY_API_KEY }} KILO_API_KEY: ${{ secrets.KILO_API_KEY }} GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} diff --git a/package.json b/package.json index d4cab62ded..3a2159aaac 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "huggingface:sync": "bun ./packages/core/script/sync-models.ts huggingface", "kilo:sync": "bun ./packages/core/script/sync-models.ts kilo", "llmgateway:sync": "bun ./packages/core/script/sync-models.ts llmgateway", + "merge-gateway:sync": "bun ./packages/core/script/sync-models.ts merge-gateway", "venice:sync": "bun ./packages/core/script/sync-models.ts venice", "vercel:generate": "bun ./packages/core/script/sync-models.ts vercel", "wandb:generate": "bun ./packages/core/script/sync-models.ts wandb", diff --git a/packages/core/src/sync/index.ts b/packages/core/src/sync/index.ts index 3b8c8fce97..afc0fc57cc 100644 --- a/packages/core/src/sync/index.ts +++ b/packages/core/src/sync/index.ts @@ -17,6 +17,7 @@ import { google } from "./providers/google.js"; import { huggingface } from "./providers/huggingface.js"; import { kilo } from "./providers/kilo.js"; import { llmgateway } from "./providers/llmgateway.js"; +import { mergeGateway } from "./providers/merge-gateway.js"; import { openai } from "./providers/openai.js"; import { openrouter } from "./providers/openrouter.js"; import { ovhcloud } from "./providers/ovhcloud.js"; @@ -106,6 +107,7 @@ export const providers: { kilo: SyncProvider; huggingface: SyncProvider; llmgateway: SyncProvider; + "merge-gateway": SyncProvider; openai: SyncProvider; openrouter: SyncProvider; ovhcloud: SyncProvider; @@ -128,6 +130,7 @@ export const providers: { kilo, huggingface, llmgateway, + "merge-gateway": mergeGateway, openai, openrouter, ovhcloud, @@ -139,7 +142,7 @@ export const providers: { }; export const groups = { - aggregators: ["crossmodel", "empiriolabs", "huggingface", "kilo", "llmgateway", "openrouter", "vercel"], + aggregators: ["crossmodel", "empiriolabs", "huggingface", "kilo", "llmgateway", "merge-gateway", "openrouter", "vercel"], cloudflare: ["cloudflare-workers-ai"], direct: ["ambient", "anthropic", "baseten", "chutes", "deepinfra", "digitalocean", "google", "openai", "ovhcloud", "pioneer", "venice", "wandb", "xai"], } as const; diff --git a/packages/core/src/sync/providers/merge-gateway.ts b/packages/core/src/sync/providers/merge-gateway.ts new file mode 100644 index 0000000000..87829ede0e --- /dev/null +++ b/packages/core/src/sync/providers/merge-gateway.ts @@ -0,0 +1,287 @@ +import { z } from "zod"; + +import { describeModel } from "../../describe.js"; +import type { ExistingModel, SyncProvider, SyncedFullModel, SyncedModel } from "../index.js"; +import { factorBaseModel, resolveCanonicalBaseModel } from "./openrouter.js"; + +const API_ENDPOINT = "https://api-gateway.merge.dev/v1/models"; + +const AvailabilityStatus = z.enum(["available", "deprecated"]); + +const VendorCapabilities = z.object({ + input: z.array(z.enum(["text", "audio", "image", "document", "embedding"])), + output: z.array(z.enum(["text", "audio", "tool_use", "embedding"])), + supports_tool_calling: z.boolean(), + supports_tool_choice: z.boolean().default(false), + supports_structured_outputs: z.boolean(), + streaming: z.boolean(), +}).passthrough(); + +const PromptCaching = z.object({ + mode: z.enum(["automatic", "explicit", "none"]).optional(), + cache_read_cost_per_million: z.number().nonnegative().nullable().optional(), + cache_write_cost_per_million: z.number().nonnegative().nullable().optional(), +}).passthrough(); + +const VendorInfo = z.object({ + launch_date: z.string().nullable().optional(), + context_window: z.number().int().nonnegative(), + max_output_tokens: z.number().int().nonnegative(), + availability_status: AvailabilityStatus, + capabilities: VendorCapabilities, + pricing: z.object({ + currency: z.literal("USD").default("USD"), + input_per_million: z.number().nonnegative(), + output_per_million: z.number().nonnegative(), + cache_read_per_million: z.number().nonnegative().nullable().optional(), + cache_write_per_million: z.number().nonnegative().nullable().optional(), + }).passthrough(), + prompt_caching: PromptCaching.nullable().optional(), +}).passthrough(); + +export const MergeGatewayModel = z.object({ + model: z.string().min(1), + provider: z.string().min(1), + display_name: z.string().min(1), + vendors: z.record(VendorInfo), + availability_status: AvailabilityStatus, + created_at: z.string().nullable().optional(), + updated_at: z.string().nullable().optional(), +}).passthrough(); + +export const MergeGatewayResponse = z.object({ + object: z.literal("list").default("list"), + data: z.array(MergeGatewayModel), + has_more: z.boolean().default(false), + next_cursor: z.string().nullable().optional(), +}).passthrough(); + +export type MergeGatewayModel = z.infer; +export type MergeGatewayVendor = z.infer; + +export async function fetchMergeGatewayModels( + fetcher: typeof fetch = fetch, + apiKey = process.env.MERGE_GATEWAY_API_KEY, +) { + if (!apiKey) throw new Error("MERGE_GATEWAY_API_KEY is required to sync Merge Gateway models"); + + const models = new Map(); + const cursors = new Set(); + let cursor: string | undefined; + + do { + const url = new URL(API_ENDPOINT); + url.searchParams.set("limit", "500"); + if (cursor !== undefined) url.searchParams.set("cursor", cursor); + + const response = await fetcher(url, { + headers: { Authorization: `Bearer ${apiKey}` }, + }); + if (!response.ok) { + throw new Error(`Merge Gateway request failed: ${response.status} ${response.statusText}`); + } + + const page = MergeGatewayResponse.parse(await response.json()); + for (const model of page.data) models.set(model.model, model); + if (!page.has_more) break; + if (!page.next_cursor) throw new Error("Merge Gateway returned has_more=true without next_cursor"); + if (cursors.has(page.next_cursor)) throw new Error(`Merge Gateway repeated cursor: ${page.next_cursor}`); + cursors.add(page.next_cursor); + cursor = page.next_cursor; + } while (true); + + return { + object: "list" as const, + data: [...models.values()], + has_more: false, + next_cursor: null, + }; +} + +export const mergeGateway = { + id: "merge-gateway", + name: "Merge Gateway", + modelsDir: "providers/merge-gateway/models", + // API-key policy can affect catalog visibility. Retain missing local models + // until Merge exposes an account-independent catalog response. + deleteMissing: false, + sourceID(model) { + return model.model; + }, + skippedNotice(ids) { + if (ids.length === 0) return []; + return [ + `${ids.length} Merge Gateway models were skipped because they are not text models or lack canonical metadata.`, + `Skipped remote IDs: ${ids.map((id) => `\`${id}\``).join(", ")}`, + ]; + }, + missingNotice(paths) { + if (paths.length === 0) return []; + return [ + `${paths.length} local Merge Gateway models were absent from the API response and retained for manual lifecycle review.`, + `Retained local paths: ${paths.map((item) => `\`${item}\``).join(", ")}`, + ]; + }, + fetchModels() { + return fetchMergeGatewayModels(); + }, + parseModels(raw) { + return MergeGatewayResponse.parse(raw).data; + }, + translateModel(model, context) { + const existing = context.existing(model.model); + const translated = buildMergeGatewayModel(model, existing, context.authored(model.model)); + return translated === undefined ? undefined : { id: model.model, model: translated }; + }, +} satisfies SyncProvider; + +export function selectMergeGatewayVendor(model: MergeGatewayModel) { + const canonical = model.vendors[model.provider]; + if (canonical?.availability_status === "available") { + return { id: model.provider, info: canonical }; + } + + const available = Object.entries(model.vendors) + .filter(([, info]) => info.availability_status === "available") + .sort(([a], [b]) => a.localeCompare(b))[0]; + if (available !== undefined) return { id: available[0], info: available[1] }; + if (canonical !== undefined) return { id: model.provider, info: canonical }; + + const fallback = Object.entries(model.vendors).sort(([a], [b]) => a.localeCompare(b))[0]; + return fallback === undefined ? undefined : { id: fallback[0], info: fallback[1] }; +} + +export function buildMergeGatewayModel( + model: MergeGatewayModel, + existing: ExistingModel | undefined, + authored: ExistingModel | undefined = existing, +): SyncedModel | undefined { + const selected = selectMergeGatewayVendor(model); + if (selected === undefined || !selected.info.capabilities.output.includes("text")) return undefined; + + const input = modalities(selected.info.capabilities.input); + const output = modalities(selected.info.capabilities.output); + const limit = { + context: selected.info.context_window || existing?.limit?.context || 0, + // Preserve only a provider-authored input cap. `existing` is resolved + // against base-model metadata, so using its inherited input value here + // can keep an impossible cap when the gateway reports a smaller context. + input: authored?.limit?.input, + output: selected.info.max_output_tokens || existing?.limit?.output || selected.info.context_window, + }; + const cachePricing = mergeGatewayCachePricing(selected.info, existing); + const cost = { + input: selected.info.pricing.input_per_million, + output: selected.info.pricing.output_per_million, + reasoning: existing?.cost?.reasoning, + cache_read: cachePricing.read, + cache_write: cachePricing.write, + input_audio: existing?.cost?.input_audio, + output_audio: existing?.cost?.output_audio, + tiers: existing?.cost?.tiers, + }; + const status = model.availability_status === "deprecated" || selected.info.availability_status === "deprecated" + ? "deprecated" as const + : undefined; + const baseModel = existing?.base_model ?? resolveCanonicalBaseModel(model.model); + const authoritative = { + // Some catalog rows use an upstream org/model ID as display_name. Let + // canonical metadata provide the human-readable name for factored models. + name: baseModel !== undefined && model.display_name.includes("/") ? undefined : model.display_name, + attachment: input.some((value) => value !== "text"), + tool_call: selected.info.capabilities.supports_tool_calling, + structured_output: selected.info.capabilities.supports_structured_outputs, + status, + cost, + limit, + modalities: { input, output }, + }; + + if (baseModel !== undefined) { + return factorBaseModel( + baseModel, + { + ...authoritative, + description: existing?.description, + reasoning: existing?.reasoning, + reasoning_options: existing?.reasoning_options, + temperature: existing?.temperature, + interleaved: existing?.interleaved, + provider: existing?.provider, + experimental: existing?.experimental, + }, + limit, + existing?.base_model_omit, + ); + } + + if (existing === undefined) return undefined; + + const releaseDate = selected.info.launch_date + ?? model.created_at?.slice(0, 10) + ?? existing.release_date; + if (releaseDate === undefined) return undefined; + const lastUpdated = model.updated_at?.slice(0, 10) + ?? existing.last_updated + ?? releaseDate; + return { + ...authoritative, + description: existing.description ?? describeModel({ + id: model.model, + name: model.display_name, + family: existing.family, + reasoning: existing.reasoning, + tool_call: selected.info.capabilities.supports_tool_calling, + structured_output: selected.info.capabilities.supports_structured_outputs, + open_weights: existing.open_weights, + limit, + modalities: { input, output }, + }), + family: existing.family, + release_date: releaseDate, + last_updated: lastUpdated, + reasoning: existing.reasoning ?? false, + reasoning_options: existing.reasoning_options, + temperature: existing.temperature, + knowledge: existing.knowledge, + open_weights: existing.open_weights ?? false, + interleaved: existing.interleaved, + provider: existing.provider, + experimental: existing.experimental, + } satisfies SyncedFullModel; +} + +function mergeGatewayCachePricing( + vendor: MergeGatewayVendor, + existing: ExistingModel | undefined, +) { + const promptCaching = vendor.prompt_caching; + const pricing = vendor.pricing; + const authoritative = promptCaching !== undefined + || pricing.cache_read_per_million !== undefined + || pricing.cache_write_per_million !== undefined; + if (!authoritative) { + return { + read: existing?.cost?.cache_read, + write: existing?.cost?.cache_write, + }; + } + return { + read: promptCaching?.cache_read_cost_per_million + ?? pricing.cache_read_per_million + ?? undefined, + write: promptCaching?.cache_write_cost_per_million + ?? pricing.cache_write_per_million + ?? undefined, + }; +} + +type Modality = "text" | "audio" | "image" | "video" | "pdf"; + +function modalities(values: string[]): Modality[] { + const allowed = new Set(["text", "audio", "image", "video", "pdf"]); + return [...new Set(values + .map((value) => value === "document" ? "pdf" : value) + .filter((value): value is Modality => allowed.has(value as Modality)) + )]; +} diff --git a/packages/core/test/sync.test.ts b/packages/core/test/sync.test.ts index d9287ebca8..4fbd29f3e6 100644 --- a/packages/core/test/sync.test.ts +++ b/packages/core/test/sync.test.ts @@ -32,6 +32,14 @@ import { type OpenRouterModel, } from "../src/sync/providers/openrouter.js"; import { buildLLMGatewayModel, type LLMGatewayModel } from "../src/sync/providers/llmgateway.js"; +import { + buildMergeGatewayModel, + fetchMergeGatewayModels, + mergeGateway, + MergeGatewayResponse, + selectMergeGatewayVendor, + type MergeGatewayModel, +} from "../src/sync/providers/merge-gateway.js"; import { openai, parseOpenAIModels } from "../src/sync/providers/openai.js"; import { resolveVeniceBaseModel } from "../src/sync/providers/venice.js"; import { buildVercelModel, vercel } from "../src/sync/providers/vercel.js"; @@ -1062,6 +1070,153 @@ test("factors aliased LLM Gateway routes against canonical metadata", () => { }); }); +test("fetches every page of the Merge Gateway catalog", async () => { + const requests: string[] = []; + const authorizations: string[] = []; + const fetcher = ((input: string | URL | Request, init?: RequestInit) => { + const url = String(input); + requests.push(url); + authorizations.push(new Headers(init?.headers).get("Authorization") ?? ""); + const next = url.includes("cursor=next-page"); + return Promise.resolve(new Response(JSON.stringify({ + object: "list", + data: [mergeGatewayModel({ + model: next ? "openai/gpt-5.6-terra" : "openai/gpt-5.6-sol", + display_name: next ? "GPT-5.6 Terra" : "GPT-5.6 Sol", + })], + has_more: !next, + next_cursor: next ? null : "next-page", + }))); + }) as typeof fetch; + + const result = await fetchMergeGatewayModels(fetcher, "test-key"); + + expect(result.data.map((model) => model.model)).toEqual([ + "openai/gpt-5.6-sol", + "openai/gpt-5.6-terra", + ]); + expect(requests).toHaveLength(2); + expect(requests[0]).toContain("limit=500"); + expect(requests[1]).toContain("cursor=next-page"); + expect(authorizations).toEqual(["Bearer test-key", "Bearer test-key"]); +}); + +test("accepts audio modalities from the Merge Gateway catalog", () => { + const model = mergeGatewayModel(); + model.vendors.openai.capabilities.input.push("audio"); + + expect(MergeGatewayResponse.parse({ + object: "list", + data: [model], + has_more: false, + next_cursor: null, + }).data[0]?.vendors.openai.capabilities.input).toContain("audio"); +}); + +test("factors Merge Gateway GPT-5.6 Sol against canonical metadata", () => { + const model = buildMergeGatewayModel(mergeGatewayModel(), undefined); + + expect(model).toEqual({ + base_model: "openai/gpt-5.6-sol", + cost: { + input: 5, + output: 30, + }, + }); +}); + +test("syncs authoritative Merge Gateway cache pricing", () => { + const model = buildMergeGatewayModel(mergeGatewayModel({ + vendors: { + openai: mergeGatewayVendor({ + pricing: { + currency: "USD", + input_per_million: 3.75, + output_per_million: 22.5, + }, + prompt_caching: { + mode: "automatic", + cache_read_cost_per_million: 0.375, + }, + }), + }, + }), { + base_model: "openai/gpt-5.6-sol", + cost: { + input: 5, + output: 30, + cache_read: 0.5, + cache_write: 6.25, + }, + }); + + expect(model).toEqual({ + base_model: "openai/gpt-5.6-sol", + cost: { + input: 3.75, + output: 22.5, + cache_read: 0.375, + }, + }); +}); + +test("inherits canonical names for ID-shaped Merge Gateway display names", () => { + const model = buildMergeGatewayModel(mergeGatewayModel({ + model: "minimax/minimax-m2", + provider: "minimax", + display_name: "MiniMaxAI/MiniMax-M2", + vendors: { minimax: mergeGatewayVendor() }, + }), undefined); + + expect(model).not.toHaveProperty("name"); +}); + +test("omits inherited input limits above the Merge Gateway context", () => { + const model = buildMergeGatewayModel(mergeGatewayModel({ + model: "openai/gpt-5-chat-latest", + display_name: "GPT-5 Chat Latest", + vendors: { + openai: mergeGatewayVendor({ + context_window: 128_000, + max_output_tokens: 16_384, + }), + }, + }), { + base_model: "openai/gpt-5-chat-latest", + limit: { + context: 128_000, + input: 272_000, + output: 16_384, + }, + }, { + base_model: "openai/gpt-5-chat-latest", + limit: { + context: 128_000, + output: 16_384, + }, + }); + + expect(model).toHaveProperty("base_model_omit", ["limit.input"]); +}); + +test("uses the canonical Merge Gateway vendor as the catalog baseline", () => { + const model = mergeGatewayModel({ + vendors: { + azure: mergeGatewayVendor({ context_window: 200_000 }), + openai: mergeGatewayVendor({ context_window: 1_050_000 }), + }, + }); + + expect(selectMergeGatewayVendor(model)).toMatchObject({ + id: "openai", + info: { context_window: 1_050_000 }, + }); +}); + +test("retains Merge Gateway models missing from an API-key-scoped response", () => { + expect(mergeGateway.deleteMissing).toBe(false); +}); + test("parses Vercel pricing tiers with an implicit zero minimum", () => { const [model] = vercel.parseModels({ data: [{ @@ -1296,6 +1451,44 @@ function llmGatewayModel(overrides: Partial = {}): LLMGatewayMo }; } +function mergeGatewayVendor( + overrides: Partial = {}, +): MergeGatewayModel["vendors"][string] { + return { + launch_date: "2026-07-09", + context_window: 1_050_000, + max_output_tokens: 128_000, + availability_status: "available", + capabilities: { + input: ["text", "image", "document"], + output: ["text", "tool_use"], + supports_tool_calling: true, + supports_tool_choice: true, + supports_structured_outputs: true, + streaming: true, + }, + pricing: { + currency: "USD", + input_per_million: 5, + output_per_million: 30, + }, + ...overrides, + }; +} + +function mergeGatewayModel(overrides: Partial = {}): MergeGatewayModel { + return { + model: "openai/gpt-5.6-sol", + provider: "openai", + display_name: "GPT-5.6 Sol", + vendors: { openai: mergeGatewayVendor() }, + availability_status: "available", + created_at: "2026-07-09T00:00:00Z", + updated_at: "2026-07-09T00:00:00Z", + ...overrides, + }; +} + function openRouterModel(overrides: Partial = {}): OpenRouterModel { return { id: "anthropic/claude-sonnet-5", diff --git a/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml b/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml new file mode 100644 index 0000000000..8c0263b486 --- /dev/null +++ b/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml @@ -0,0 +1,13 @@ +base_model = "anthropic/claude-3-7-sonnet-20250219" +name = "Claude 3.7 Sonnet" +structured_output = true +reasoning_options = [] + +[cost] +input = 3 +output = 15 +cache_read = 0.3 +cache_write = 3.75 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/anthropic/claude-fable-5.toml b/providers/merge-gateway/models/anthropic/claude-fable-5.toml new file mode 100644 index 0000000000..747fc86411 --- /dev/null +++ b/providers/merge-gateway/models/anthropic/claude-fable-5.toml @@ -0,0 +1,9 @@ +base_model = "anthropic/claude-fable-5" +structured_output = true +reasoning_options = [] + +[cost] +input = 10 +output = 50 +cache_read = 1 +cache_write = 12.5 diff --git a/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml b/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml index 251d373dcd..12beefa8b4 100644 --- a/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml +++ b/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml @@ -1,5 +1,14 @@ base_model = "anthropic/claude-haiku-4-5-20251001" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 63_999 }] +name = "Claude Haiku 4.5 (20251001)" +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 +max = 63_999 [cost] input = 1 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml index a83a37b18f..80cef05967 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml @@ -1,5 +1,14 @@ base_model = "anthropic/claude-opus-4-1-20250805" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 31_999 }] +name = "Claude Opus 4.1 (20250805)" +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 +max = 31_999 [cost] input = 15 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml index 78dc345257..0b0174e5b0 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml @@ -1,5 +1,14 @@ base_model = "anthropic/claude-opus-4-20250514" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 31_999 }] +name = "Claude Opus 4 (20250514)" +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 +max = 31_999 [cost] input = 15 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml index 32e8e536b3..e51f165765 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml @@ -1,5 +1,18 @@ base_model = "anthropic/claude-opus-4-5-20251101" -reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high"] }, { type = "budget_tokens", min = 1_024, max = 63_999 }] +name = "Claude Opus 4.5 (20251101)" +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high"] + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 +max = 63_999 [cost] input = 5 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml index ab7ffef972..63d173c380 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml @@ -1,5 +1,17 @@ base_model = "anthropic/claude-opus-4-6" -reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "max"] }, { type = "budget_tokens", min = 1_024, max = 127_999 }] +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high", "max"] + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 +max = 127_999 [cost] input = 5 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml index fd5f3197ae..0fe0cead33 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml @@ -1,5 +1,12 @@ base_model = "anthropic/claude-opus-4-7" -reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high", "xhigh", "max"] [cost] input = 5 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml index dc3ed91fa4..7606299bdd 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml @@ -1,4 +1,5 @@ base_model = "anthropic/claude-opus-4-8" +structured_output = true [[reasoning_options]] type = "toggle" @@ -11,3 +12,5 @@ max = 128_000 [cost] input = 5 output = 25 +cache_read = 0.5 +cache_write = 6.25 diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml index 638620a26f..e9bf085d46 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml @@ -1,5 +1,14 @@ base_model = "anthropic/claude-sonnet-4-5-20250929" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 63_999 }] +name = "Claude Sonnet 4.5 (20250929)" +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 +max = 63_999 [cost] input = 3 diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml index b341540673..89818d9638 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml @@ -1,5 +1,17 @@ base_model = "anthropic/claude-sonnet-4-6" -reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "max"] }, { type = "budget_tokens", min = 1_024, max = 63_999 }] +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high", "max"] + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 +max = 63_999 [cost] input = 3 diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml new file mode 100644 index 0000000000..fc8b6671ee --- /dev/null +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml @@ -0,0 +1,9 @@ +base_model = "anthropic/claude-sonnet-5" +structured_output = true +reasoning_options = [] + +[cost] +input = 2 +output = 10 +cache_read = 0.2 +cache_write = 2.5 diff --git a/providers/merge-gateway/models/cohere/command-a-03-2025.toml b/providers/merge-gateway/models/cohere/command-a-03-2025.toml index 35796b0798..663193e136 100644 --- a/providers/merge-gateway/models/cohere/command-a-03-2025.toml +++ b/providers/merge-gateway/models/cohere/command-a-03-2025.toml @@ -1,4 +1,6 @@ base_model = "cohere/command-a-03-2025" +name = "Command A 03-2025" +structured_output = true [cost] input = 2.5 diff --git a/providers/merge-gateway/models/cohere/command-r-08-2024.toml b/providers/merge-gateway/models/cohere/command-r-08-2024.toml index 5b6e7da099..481c8c3467 100644 --- a/providers/merge-gateway/models/cohere/command-r-08-2024.toml +++ b/providers/merge-gateway/models/cohere/command-r-08-2024.toml @@ -1,4 +1,6 @@ base_model = "cohere/command-r-08-2024" +name = "Command R 08-2024" +structured_output = true [cost] input = 0.15 diff --git a/providers/merge-gateway/models/cohere/command-r-plus-08-2024.toml b/providers/merge-gateway/models/cohere/command-r-plus-08-2024.toml index 419d99d79c..edb51176f7 100644 --- a/providers/merge-gateway/models/cohere/command-r-plus-08-2024.toml +++ b/providers/merge-gateway/models/cohere/command-r-plus-08-2024.toml @@ -1,4 +1,6 @@ base_model = "cohere/command-r-plus-08-2024" +name = "Command R+ 08-2024" +structured_output = true [cost] input = 2.5 diff --git a/providers/merge-gateway/models/cohere/command-r7b-12-2024.toml b/providers/merge-gateway/models/cohere/command-r7b-12-2024.toml index 815678c3b3..7a77f4353c 100644 --- a/providers/merge-gateway/models/cohere/command-r7b-12-2024.toml +++ b/providers/merge-gateway/models/cohere/command-r7b-12-2024.toml @@ -1,4 +1,6 @@ base_model = "cohere/command-r7b-12-2024" +name = "Command R7B 12-2024" +structured_output = true [cost] input = 0.0375 diff --git a/providers/merge-gateway/models/deepseek/deepseek-r1.toml b/providers/merge-gateway/models/deepseek/deepseek-r1.toml new file mode 100644 index 0000000000..283094ea09 --- /dev/null +++ b/providers/merge-gateway/models/deepseek/deepseek-r1.toml @@ -0,0 +1,13 @@ +base_model = "deepseek/deepseek-r1" +name = "DeepSeek R1" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 1.35 +output = 5.4 + +[limit] +context = 163_840 +output = 40_960 diff --git a/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml b/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml index 83ab2e7bde..12be6ee001 100644 --- a/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml +++ b/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml @@ -1,4 +1,5 @@ base_model = "deepseek/deepseek-v4-flash" +structured_output = false reasoning_options = [] [interleaved] diff --git a/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml b/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml index a90bf4b82e..cd7f2ca5bd 100644 --- a/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml +++ b/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml @@ -1,4 +1,5 @@ base_model = "deepseek/deepseek-v4-pro" +structured_output = false reasoning_options = [] [interleaved] diff --git a/providers/merge-gateway/models/google/gemini-2.5-flash-lite.toml b/providers/merge-gateway/models/google/gemini-2.5-flash-lite.toml index 99ae99972c..3905bebf13 100644 --- a/providers/merge-gateway/models/google/gemini-2.5-flash-lite.toml +++ b/providers/merge-gateway/models/google/gemini-2.5-flash-lite.toml @@ -1,8 +1,21 @@ base_model = "google/gemini-2.5-flash-lite" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 512, max = 24_576 }] + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 512 +max = 24_576 [cost] input = 0.1 output = 0.4 cache_read = 0.01 input_audio = 0.3 + +[limit] +context = 1_000_000 + +[modalities] +input = ["text", "image", "audio", "pdf"] diff --git a/providers/merge-gateway/models/google/gemini-2.5-flash.toml b/providers/merge-gateway/models/google/gemini-2.5-flash.toml index 49ba05adc1..7248eeda32 100644 --- a/providers/merge-gateway/models/google/gemini-2.5-flash.toml +++ b/providers/merge-gateway/models/google/gemini-2.5-flash.toml @@ -1,8 +1,18 @@ base_model = "google/gemini-2.5-flash" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 0, max = 24_576 }] + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 0 +max = 24_576 [cost] input = 0.3 output = 2.5 cache_read = 0.03 input_audio = 1 + +[modalities] +input = ["text", "image", "audio", "pdf"] diff --git a/providers/merge-gateway/models/google/gemini-2.5-pro.toml b/providers/merge-gateway/models/google/gemini-2.5-pro.toml index d5848f8ab3..273ccacf39 100644 --- a/providers/merge-gateway/models/google/gemini-2.5-pro.toml +++ b/providers/merge-gateway/models/google/gemini-2.5-pro.toml @@ -1,5 +1,9 @@ base_model = "google/gemini-2.5-pro" -reasoning_options = [{ type = "budget_tokens", min = 128, max = 32_768 }] + +[[reasoning_options]] +type = "budget_tokens" +min = 128 +max = 32_768 [cost] input = 1.25 @@ -11,3 +15,6 @@ tier = { type = "context", size = 200_000 } input = 2.5 output = 15 cache_read = 0.25 + +[modalities] +input = ["text", "image", "audio", "pdf"] diff --git a/providers/merge-gateway/models/google/gemini-3-flash-preview.toml b/providers/merge-gateway/models/google/gemini-3-flash-preview.toml index 56a17f3920..b8de1e8967 100644 --- a/providers/merge-gateway/models/google/gemini-3-flash-preview.toml +++ b/providers/merge-gateway/models/google/gemini-3-flash-preview.toml @@ -1,8 +1,14 @@ base_model = "google/gemini-3-flash-preview" -reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["minimal", "low", "medium", "high"] [cost] input = 0.5 output = 3 cache_read = 0.05 input_audio = 1 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/google/gemini-3.1-flash-lite.toml b/providers/merge-gateway/models/google/gemini-3.1-flash-lite.toml index d9d9b5d7dd..5c8f0f8a15 100644 --- a/providers/merge-gateway/models/google/gemini-3.1-flash-lite.toml +++ b/providers/merge-gateway/models/google/gemini-3.1-flash-lite.toml @@ -1,8 +1,15 @@ base_model = "google/gemini-3.1-flash-lite" -reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] +name = "Gemini 3.1 Flash-Lite" + +[[reasoning_options]] +type = "effort" +values = ["minimal", "low", "medium", "high"] [cost] input = 0.25 output = 1.5 cache_read = 0.025 input_audio = 0.5 + +[modalities] +input = ["text", "image", "audio", "pdf"] diff --git a/providers/merge-gateway/models/google/gemini-3.1-pro-preview-customtools.toml b/providers/merge-gateway/models/google/gemini-3.1-pro-preview-customtools.toml index 6669e542fc..a4183e8302 100644 --- a/providers/merge-gateway/models/google/gemini-3.1-pro-preview-customtools.toml +++ b/providers/merge-gateway/models/google/gemini-3.1-pro-preview-customtools.toml @@ -1,5 +1,8 @@ base_model = "google/gemini-3.1-pro-preview-customtools" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high"] [cost] input = 2 @@ -11,3 +14,6 @@ tier = { type = "context", size = 200_000 } input = 4 output = 18 cache_read = 0.4 + +[modalities] +input = ["text", "image", "audio", "pdf"] diff --git a/providers/merge-gateway/models/google/gemini-3.1-pro-preview.toml b/providers/merge-gateway/models/google/gemini-3.1-pro-preview.toml index e2b3bf54f8..7c4de40066 100644 --- a/providers/merge-gateway/models/google/gemini-3.1-pro-preview.toml +++ b/providers/merge-gateway/models/google/gemini-3.1-pro-preview.toml @@ -1,5 +1,8 @@ base_model = "google/gemini-3.1-pro-preview" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high"] [cost] input = 2 @@ -11,3 +14,6 @@ tier = { type = "context", size = 200_000 } input = 4 output = 18 cache_read = 0.4 + +[modalities] +input = ["text", "image", "audio", "pdf"] diff --git a/providers/merge-gateway/models/google/gemini-3.5-flash.toml b/providers/merge-gateway/models/google/gemini-3.5-flash.toml index 0d75d4a0d3..ef2d78e676 100644 --- a/providers/merge-gateway/models/google/gemini-3.5-flash.toml +++ b/providers/merge-gateway/models/google/gemini-3.5-flash.toml @@ -1,8 +1,14 @@ base_model = "google/gemini-3.5-flash" -reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["minimal", "low", "medium", "high"] [cost] input = 1.5 output = 9 cache_read = 0.15 input_audio = 1.5 + +[modalities] +input = ["text", "image", "audio", "pdf"] diff --git a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml index a2c94934dc..a776b41646 100644 --- a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml @@ -1,2 +1,17 @@ base_model = "google/gemma-4-26b-a4b-it" -reasoning_options = [{ type = "toggle" }] +attachment = false +tool_call = false +structured_output = false + +[[reasoning_options]] +type = "toggle" + +[cost] +input = 0.13 +output = 0.4 + +[limit] +output = 65_536 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/google/gemma-4-31b-it.toml b/providers/merge-gateway/models/google/gemma-4-31b-it.toml index 396158e520..fda08e4f1e 100644 --- a/providers/merge-gateway/models/google/gemma-4-31b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-31b-it.toml @@ -1,2 +1,17 @@ base_model = "google/gemma-4-31b-it" -reasoning_options = [{ type = "toggle" }] +attachment = false +tool_call = false +structured_output = false + +[[reasoning_options]] +type = "toggle" + +[cost] +input = 0.14 +output = 0.4 + +[limit] +output = 65_536 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml new file mode 100644 index 0000000000..152e720938 --- /dev/null +++ b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml @@ -0,0 +1,7 @@ +base_model = "meta/llama-3.3-70b-instruct" +attachment = false +structured_output = false + +[cost] +input = 0.72 +output = 0.72 diff --git a/providers/merge-gateway/models/meta/muse-spark-1.1.toml b/providers/merge-gateway/models/meta/muse-spark-1.1.toml new file mode 100644 index 0000000000..d49ae48665 --- /dev/null +++ b/providers/merge-gateway/models/meta/muse-spark-1.1.toml @@ -0,0 +1,14 @@ +base_model = "meta/muse-spark-1.1" +structured_output = false +reasoning_options = [] + +[cost] +input = 1.25 +output = 4.25 + +[limit] +context = 1_048_576 +output = 262_144 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/minimax/minimax-m2.1.toml b/providers/merge-gateway/models/minimax/minimax-m2.1.toml index 124cf20365..0a6d4752dc 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.1.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.1.toml @@ -1,6 +1,13 @@ base_model = "minimax/MiniMax-M2.1" +name = "MiniMax M2.1" +structured_output = false reasoning_options = [] [cost] input = 0.3 output = 1.2 +cache_read = 0.03 +cache_write = 0.375 + +[limit] +output = 8_192 diff --git a/providers/merge-gateway/models/minimax/minimax-m2.5-highspeed.toml b/providers/merge-gateway/models/minimax/minimax-m2.5-highspeed.toml index d3be98c0fa..f37846f4fd 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.5-highspeed.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.5-highspeed.toml @@ -1,4 +1,6 @@ base_model = "minimax/MiniMax-M2.5-highspeed" +name = "MiniMax M2.5 Highspeed" +structured_output = false reasoning_options = [] [cost] @@ -6,3 +8,6 @@ input = 0.6 output = 2.4 cache_read = 0.06 cache_write = 0.375 + +[limit] +output = 8_192 diff --git a/providers/merge-gateway/models/minimax/minimax-m2.5.toml b/providers/merge-gateway/models/minimax/minimax-m2.5.toml index b884c3c158..f8b037d4b2 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.5.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.5.toml @@ -1,4 +1,6 @@ base_model = "minimax/MiniMax-M2.5" +name = "MiniMax M2.5" +structured_output = false reasoning_options = [] [cost] @@ -6,3 +8,6 @@ input = 0.3 output = 1.2 cache_read = 0.03 cache_write = 0.375 + +[limit] +output = 8_192 diff --git a/providers/merge-gateway/models/minimax/minimax-m2.7-highspeed.toml b/providers/merge-gateway/models/minimax/minimax-m2.7-highspeed.toml index 1539589db9..4212380399 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.7-highspeed.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.7-highspeed.toml @@ -1,4 +1,6 @@ base_model = "minimax/MiniMax-M2.7-highspeed" +name = "MiniMax M2.7 Highspeed" +structured_output = false reasoning_options = [] [cost] @@ -6,3 +8,6 @@ input = 0.6 output = 2.4 cache_read = 0.06 cache_write = 0.375 + +[limit] +output = 8_192 diff --git a/providers/merge-gateway/models/minimax/minimax-m2.7.toml b/providers/merge-gateway/models/minimax/minimax-m2.7.toml index d02224d535..287dd2e59c 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.7.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.7.toml @@ -1,4 +1,6 @@ base_model = "minimax/MiniMax-M2.7" +name = "MiniMax M2.7" +structured_output = false reasoning_options = [] [cost] @@ -6,3 +8,6 @@ input = 0.3 output = 1.2 cache_read = 0.06 cache_write = 0.375 + +[limit] +output = 8_192 diff --git a/providers/merge-gateway/models/minimax/minimax-m2.toml b/providers/merge-gateway/models/minimax/minimax-m2.toml index dd2a899f2a..b4aba3d972 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.toml @@ -1,6 +1,13 @@ base_model = "minimax/MiniMax-M2" +structured_output = false reasoning_options = [] [cost] input = 0.3 output = 1.2 +cache_read = 0.03 +cache_write = 0.375 + +[limit] +context = 204_800 +output = 8_192 diff --git a/providers/merge-gateway/models/minimax/minimax-m3.toml b/providers/merge-gateway/models/minimax/minimax-m3.toml index bb651110ea..db8f8f5f02 100644 --- a/providers/merge-gateway/models/minimax/minimax-m3.toml +++ b/providers/merge-gateway/models/minimax/minimax-m3.toml @@ -1,4 +1,6 @@ base_model = "minimax/MiniMax-M3" +name = "MiniMax M3" +structured_output = false [[reasoning_options]] type = "toggle" @@ -9,5 +11,12 @@ min = 1 max = 128_000 [cost] -input = 0.6 -output = 2.4 +input = 0.3 +output = 1.2 +cache_read = 0.06 + +[limit] +context = 1_000_000 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/mistral/devstral-2512.toml b/providers/merge-gateway/models/mistral/devstral-2512.toml index a42bb7446c..5be5751c96 100644 --- a/providers/merge-gateway/models/mistral/devstral-2512.toml +++ b/providers/merge-gateway/models/mistral/devstral-2512.toml @@ -1,6 +1,10 @@ base_model = "mistral/devstral-2512" -status = "deprecated" +structured_output = true [cost] input = 0.4 output = 2 + +[limit] +context = 256_000 +output = 256_000 diff --git a/providers/merge-gateway/models/mistral/mistral-large-2512.toml b/providers/merge-gateway/models/mistral/mistral-large-2512.toml index 49df75a634..98e5a5fac0 100644 --- a/providers/merge-gateway/models/mistral/mistral-large-2512.toml +++ b/providers/merge-gateway/models/mistral/mistral-large-2512.toml @@ -1,5 +1,10 @@ base_model = "mistral/mistral-large-2512" +structured_output = true [cost] input = 0.5 output = 1.5 + +[limit] +context = 256_000 +output = 256_000 diff --git a/providers/merge-gateway/models/mistral/mistral-medium-2505.toml b/providers/merge-gateway/models/mistral/mistral-medium-2505.toml index 24ec3b4fa5..6816500cc2 100644 --- a/providers/merge-gateway/models/mistral/mistral-medium-2505.toml +++ b/providers/merge-gateway/models/mistral/mistral-medium-2505.toml @@ -1,5 +1,10 @@ base_model = "mistral/mistral-medium-2505" +structured_output = true [cost] input = 0.4 output = 2 + +[limit] +context = 128_000 +output = 128_000 diff --git a/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml b/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml new file mode 100644 index 0000000000..a24d7e0cfb --- /dev/null +++ b/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml @@ -0,0 +1,13 @@ +base_model = "nvidia/nemotron-nano-9b-v2" +name = "Nemotron Nano 9B" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.06 +output = 0.23 + +[limit] +context = 128_000 +output = 8_192 diff --git a/providers/merge-gateway/models/openai/gpt-3.5-turbo.toml b/providers/merge-gateway/models/openai/gpt-3.5-turbo.toml new file mode 100644 index 0000000000..de8ddba9d0 --- /dev/null +++ b/providers/merge-gateway/models/openai/gpt-3.5-turbo.toml @@ -0,0 +1,6 @@ +base_model = "openai/gpt-3.5-turbo" +name = "GPT-3.5 Turbo" + +[cost] +input = 0.5 +output = 1.5 diff --git a/providers/merge-gateway/models/openai/gpt-4-turbo.toml b/providers/merge-gateway/models/openai/gpt-4-turbo.toml new file mode 100644 index 0000000000..ac792634f8 --- /dev/null +++ b/providers/merge-gateway/models/openai/gpt-4-turbo.toml @@ -0,0 +1,8 @@ +base_model = "openai/gpt-4-turbo" + +[cost] +input = 10 +output = 30 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-4.1-mini.toml b/providers/merge-gateway/models/openai/gpt-4.1-mini.toml index b2d9217542..a6b4371ba1 100644 --- a/providers/merge-gateway/models/openai/gpt-4.1-mini.toml +++ b/providers/merge-gateway/models/openai/gpt-4.1-mini.toml @@ -1,4 +1,5 @@ base_model = "openai/gpt-4.1-mini" +name = "GPT-4.1 Mini" [cost] input = 0.4 diff --git a/providers/merge-gateway/models/openai/gpt-4.1-nano.toml b/providers/merge-gateway/models/openai/gpt-4.1-nano.toml index f85c094770..5deee39d9b 100644 --- a/providers/merge-gateway/models/openai/gpt-4.1-nano.toml +++ b/providers/merge-gateway/models/openai/gpt-4.1-nano.toml @@ -1,6 +1,10 @@ base_model = "openai/gpt-4.1-nano" +name = "GPT-4.1 Nano" [cost] input = 0.1 output = 0.4 cache_read = 0.025 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-4.toml b/providers/merge-gateway/models/openai/gpt-4.toml new file mode 100644 index 0000000000..a4363542ed --- /dev/null +++ b/providers/merge-gateway/models/openai/gpt-4.toml @@ -0,0 +1,7 @@ +base_model = "openai/gpt-4" +attachment = false +tool_call = false + +[cost] +input = 30 +output = 60 diff --git a/providers/merge-gateway/models/openai/gpt-4o-2024-05-13.toml b/providers/merge-gateway/models/openai/gpt-4o-2024-05-13.toml index c4a17bbcf7..6f72744fc8 100644 --- a/providers/merge-gateway/models/openai/gpt-4o-2024-05-13.toml +++ b/providers/merge-gateway/models/openai/gpt-4o-2024-05-13.toml @@ -1,5 +1,9 @@ base_model = "openai/gpt-4o-2024-05-13" +structured_output = false [cost] input = 5 output = 15 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-4o-2024-08-06.toml b/providers/merge-gateway/models/openai/gpt-4o-2024-08-06.toml index 344cd161a7..a02cb635cd 100644 --- a/providers/merge-gateway/models/openai/gpt-4o-2024-08-06.toml +++ b/providers/merge-gateway/models/openai/gpt-4o-2024-08-06.toml @@ -4,3 +4,6 @@ base_model = "openai/gpt-4o-2024-08-06" input = 2.5 output = 10 cache_read = 1.25 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-4o-2024-11-20.toml b/providers/merge-gateway/models/openai/gpt-4o-2024-11-20.toml index c807afdbe1..2df04ffa70 100644 --- a/providers/merge-gateway/models/openai/gpt-4o-2024-11-20.toml +++ b/providers/merge-gateway/models/openai/gpt-4o-2024-11-20.toml @@ -4,3 +4,6 @@ base_model = "openai/gpt-4o-2024-11-20" input = 2.5 output = 10 cache_read = 1.25 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-4o-mini.toml b/providers/merge-gateway/models/openai/gpt-4o-mini.toml index da284d5f15..5662c2ceca 100644 --- a/providers/merge-gateway/models/openai/gpt-4o-mini.toml +++ b/providers/merge-gateway/models/openai/gpt-4o-mini.toml @@ -1,4 +1,5 @@ base_model = "openai/gpt-4o-mini" +name = "GPT-4o Mini" [cost] input = 0.15 diff --git a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml index 4dd858d1af..4af6a73a45 100644 --- a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml @@ -1,7 +1,16 @@ base_model = "openai/gpt-5-chat-latest" +base_model_omit = ["limit.input"] +name = "GPT-5 Chat Latest" reasoning_options = [] [cost] input = 1.25 output = 10 cache_read = 0.125 + +[limit] +context = 128_000 +output = 16_384 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-5-mini.toml b/providers/merge-gateway/models/openai/gpt-5-mini.toml index 5754d47df3..9ab4f24cca 100644 --- a/providers/merge-gateway/models/openai/gpt-5-mini.toml +++ b/providers/merge-gateway/models/openai/gpt-5-mini.toml @@ -1,7 +1,13 @@ base_model = "openai/gpt-5-mini" -reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["minimal", "low", "medium", "high"] [cost] input = 0.25 output = 2 cache_read = 0.025 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-5-nano.toml b/providers/merge-gateway/models/openai/gpt-5-nano.toml index b96eddfd6f..24bc4a0e65 100644 --- a/providers/merge-gateway/models/openai/gpt-5-nano.toml +++ b/providers/merge-gateway/models/openai/gpt-5-nano.toml @@ -1,7 +1,13 @@ base_model = "openai/gpt-5-nano" -reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["minimal", "low", "medium", "high"] [cost] input = 0.05 output = 0.4 cache_read = 0.005 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml index 55e1ad4331..d1916353a0 100644 --- a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml @@ -1,7 +1,11 @@ base_model = "openai/gpt-5.1-chat-latest" +name = "GPT-5.1 Chat Latest" reasoning_options = [] [cost] input = 1.25 output = 10 cache_read = 0.125 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-5.1.toml b/providers/merge-gateway/models/openai/gpt-5.1.toml index 489f83fffc..b1e6e83622 100644 --- a/providers/merge-gateway/models/openai/gpt-5.1.toml +++ b/providers/merge-gateway/models/openai/gpt-5.1.toml @@ -1,7 +1,13 @@ base_model = "openai/gpt-5.1" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["none", "low", "medium", "high"] [cost] input = 1.25 output = 10 cache_read = 0.125 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml index bbad0e8faf..c12b1689b0 100644 --- a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml @@ -1,7 +1,11 @@ base_model = "openai/gpt-5.2-chat-latest" +name = "GPT-5.2 Chat Latest" reasoning_options = [] [cost] input = 1.75 output = 14 cache_read = 0.175 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-5.2.toml b/providers/merge-gateway/models/openai/gpt-5.2.toml index a2a20d0e32..4cbeec6e34 100644 --- a/providers/merge-gateway/models/openai/gpt-5.2.toml +++ b/providers/merge-gateway/models/openai/gpt-5.2.toml @@ -1,7 +1,13 @@ base_model = "openai/gpt-5.2" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] + +[[reasoning_options]] +type = "effort" +values = ["none", "low", "medium", "high", "xhigh"] [cost] input = 1.75 output = 14 cache_read = 0.175 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-5.3-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.3-chat-latest.toml index 197284ef5f..5d69491b2e 100644 --- a/providers/merge-gateway/models/openai/gpt-5.3-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.3-chat-latest.toml @@ -1,6 +1,10 @@ base_model = "openai/gpt-5.3-chat-latest" +name = "GPT-5.3 Chat Latest" [cost] input = 1.75 output = 14 cache_read = 0.175 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-5.4-mini.toml b/providers/merge-gateway/models/openai/gpt-5.4-mini.toml index 56a278d15d..913a608765 100644 --- a/providers/merge-gateway/models/openai/gpt-5.4-mini.toml +++ b/providers/merge-gateway/models/openai/gpt-5.4-mini.toml @@ -1,11 +1,18 @@ base_model = "openai/gpt-5.4-mini" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] +name = "GPT-5.4 Mini" + +[[reasoning_options]] +type = "effort" +values = ["none", "low", "medium", "high", "xhigh"] [cost] input = 0.75 output = 4.5 cache_read = 0.075 +[modalities] +input = ["text", "image", "pdf"] + [experimental.modes.fast] cost = { input = 1.5, output = 9, cache_read = 0.15 } provider = { body = { service_tier = "priority" } } diff --git a/providers/merge-gateway/models/openai/gpt-5.4-nano.toml b/providers/merge-gateway/models/openai/gpt-5.4-nano.toml index 3872b109a2..cd1ef0c661 100644 --- a/providers/merge-gateway/models/openai/gpt-5.4-nano.toml +++ b/providers/merge-gateway/models/openai/gpt-5.4-nano.toml @@ -1,7 +1,14 @@ base_model = "openai/gpt-5.4-nano" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] +name = "GPT-5.4 Nano" + +[[reasoning_options]] +type = "effort" +values = ["none", "low", "medium", "high", "xhigh"] [cost] input = 0.2 output = 1.25 cache_read = 0.02 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-5.6-luna.toml b/providers/merge-gateway/models/openai/gpt-5.6-luna.toml new file mode 100644 index 0000000000..409d016fa2 --- /dev/null +++ b/providers/merge-gateway/models/openai/gpt-5.6-luna.toml @@ -0,0 +1,7 @@ +base_model = "openai/gpt-5.6-luna" +reasoning_options = [] + +[cost] +input = 0.75 +output = 4.5 +cache_read = 0.075 diff --git a/providers/merge-gateway/models/openai/gpt-5.6-sol.toml b/providers/merge-gateway/models/openai/gpt-5.6-sol.toml new file mode 100644 index 0000000000..de3ff8acd3 --- /dev/null +++ b/providers/merge-gateway/models/openai/gpt-5.6-sol.toml @@ -0,0 +1,12 @@ +# Merge Gateway catalog: GET https://api-gateway.merge.dev/v1/models +# Reasoning controls: https://openai.com/index/gpt-5-6/ (accessed 2026-07-13) +base_model = "openai/gpt-5.6-sol" + +[[reasoning_options]] +type = "effort" +values = ["none", "low", "medium", "high", "xhigh", "max"] + +[cost] +input = 3.75 +output = 22.5 +cache_read = 0.375 diff --git a/providers/merge-gateway/models/openai/gpt-5.6-terra.toml b/providers/merge-gateway/models/openai/gpt-5.6-terra.toml new file mode 100644 index 0000000000..ca94a4583c --- /dev/null +++ b/providers/merge-gateway/models/openai/gpt-5.6-terra.toml @@ -0,0 +1,7 @@ +base_model = "openai/gpt-5.6-terra" +reasoning_options = [] + +[cost] +input = 1.875 +output = 11.25 +cache_read = 0.1875 diff --git a/providers/merge-gateway/models/openai/gpt-5.toml b/providers/merge-gateway/models/openai/gpt-5.toml index 104575502b..562d91dcdb 100644 --- a/providers/merge-gateway/models/openai/gpt-5.toml +++ b/providers/merge-gateway/models/openai/gpt-5.toml @@ -1,7 +1,13 @@ base_model = "openai/gpt-5" -reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["minimal", "low", "medium", "high"] [cost] input = 1.25 output = 10 cache_read = 0.125 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/openai/gpt-oss-120b.toml b/providers/merge-gateway/models/openai/gpt-oss-120b.toml new file mode 100644 index 0000000000..f6ea8e4325 --- /dev/null +++ b/providers/merge-gateway/models/openai/gpt-oss-120b.toml @@ -0,0 +1,12 @@ +base_model = "openai/gpt-oss-120b" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.1 +output = 0.5 + +[limit] +context = 128_000 +output = 32_000 diff --git a/providers/merge-gateway/models/openai/gpt-oss-20b.toml b/providers/merge-gateway/models/openai/gpt-oss-20b.toml new file mode 100644 index 0000000000..6619d5300c --- /dev/null +++ b/providers/merge-gateway/models/openai/gpt-oss-20b.toml @@ -0,0 +1,10 @@ +base_model = "openai/gpt-oss-20b" +reasoning_options = [] + +[cost] +input = 0.07 +output = 0.3 + +[limit] +context = 128_000 +output = 128_000 diff --git a/providers/merge-gateway/models/openai/o3-mini.toml b/providers/merge-gateway/models/openai/o3-mini.toml index 716e4b6e1a..8e81e03022 100644 --- a/providers/merge-gateway/models/openai/o3-mini.toml +++ b/providers/merge-gateway/models/openai/o3-mini.toml @@ -1,5 +1,9 @@ base_model = "openai/o3-mini" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] +name = "o3 Mini" + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high"] [cost] input = 1.1 diff --git a/providers/merge-gateway/models/openai/o4-mini.toml b/providers/merge-gateway/models/openai/o4-mini.toml index 0ff60822de..e234a45f67 100644 --- a/providers/merge-gateway/models/openai/o4-mini.toml +++ b/providers/merge-gateway/models/openai/o4-mini.toml @@ -1,7 +1,11 @@ base_model = "openai/o4-mini" +name = "o4 Mini" reasoning_options = [] [cost] input = 1.1 output = 4.4 cache_read = 0.275 + +[modalities] +input = ["text", "image", "pdf"] diff --git a/providers/merge-gateway/models/qwen/qwen-flash.toml b/providers/merge-gateway/models/qwen/qwen-flash.toml new file mode 100644 index 0000000000..9d31fbbca2 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen-flash.toml @@ -0,0 +1,11 @@ +base_model = "alibaba/qwen-flash" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.022 +output = 0.216 + +[limit] +output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen-plus.toml b/providers/merge-gateway/models/qwen/qwen-plus.toml new file mode 100644 index 0000000000..eb288e33a6 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen-plus.toml @@ -0,0 +1,11 @@ +base_model = "alibaba/qwen-plus" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.115 +output = 0.287 + +[limit] +output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml b/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml new file mode 100644 index 0000000000..0b3cf01e0d --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml @@ -0,0 +1,12 @@ +base_model = "alibaba/qwen3-235b-a22b" +name = "Qwen3 235B A22B" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.287 +output = 1.147 + +[limit] +output = 32_768 diff --git a/providers/merge-gateway/models/qwen/qwen3-32b.toml b/providers/merge-gateway/models/qwen/qwen3-32b.toml new file mode 100644 index 0000000000..6799a8b98c --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3-32b.toml @@ -0,0 +1,11 @@ +base_model = "alibaba/qwen3-32b" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.287 +output = 0.64 + +[limit] +output = 32_768 diff --git a/providers/merge-gateway/models/qwen/qwen3-coder-480b-a35b-instruct.toml b/providers/merge-gateway/models/qwen/qwen3-coder-480b-a35b-instruct.toml new file mode 100644 index 0000000000..2d2b7fe1ae --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3-coder-480b-a35b-instruct.toml @@ -0,0 +1,11 @@ +base_model = "alibaba/qwen3-coder-480b-a35b-instruct" +tool_call = false +structured_output = false + +[cost] +input = 0.22 +output = 1.8 + +[limit] +context = 131_072 +output = 32_768 diff --git a/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml b/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml new file mode 100644 index 0000000000..171d33583d --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml @@ -0,0 +1,10 @@ +base_model = "alibaba/qwen3-coder-flash" +tool_call = false +structured_output = false + +[cost] +input = 0.144 +output = 0.574 + +[limit] +output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml b/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml new file mode 100644 index 0000000000..1a22f4698c --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml @@ -0,0 +1,11 @@ +base_model = "alibaba/qwen3-coder-plus" +tool_call = false +structured_output = false + +[cost] +input = 0.574 +output = 2.294 + +[limit] +context = 1_000_000 +output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3-max.toml b/providers/merge-gateway/models/qwen/qwen3-max.toml new file mode 100644 index 0000000000..a91ec8afd2 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3-max.toml @@ -0,0 +1,7 @@ +base_model = "alibaba/qwen3-max" +tool_call = false +structured_output = false + +[cost] +input = 0.359 +output = 1.434 diff --git a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml new file mode 100644 index 0000000000..f936e5fb71 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml @@ -0,0 +1,7 @@ +base_model = "alibaba/qwen3-next-80b-a3b-instruct" +tool_call = false +structured_output = false + +[cost] +input = 0.144 +output = 0.574 diff --git a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml new file mode 100644 index 0000000000..c5805b1218 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml @@ -0,0 +1,8 @@ +base_model = "alibaba/qwen3-next-80b-a3b-thinking" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.144 +output = 1.434 diff --git a/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml b/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml new file mode 100644 index 0000000000..62b7809fdb --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml @@ -0,0 +1,12 @@ +base_model = "alibaba/qwen3-vl-plus" +attachment = true +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.143 +output = 1.434 + +[limit] +output = 65_536 diff --git a/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml new file mode 100644 index 0000000000..f6f7beb213 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml @@ -0,0 +1,16 @@ +base_model = "alibaba/qwen3.5-122b-a10b" +attachment = false +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.115 +output = 0.917 + +[limit] +context = 131_072 +output = 32_768 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-27b.toml b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml new file mode 100644 index 0000000000..61838ba5d2 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml @@ -0,0 +1,16 @@ +base_model = "alibaba/qwen3.5-27b" +attachment = false +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.086 +output = 0.688 + +[limit] +context = 131_072 +output = 32_768 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml new file mode 100644 index 0000000000..8a502a1b86 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml @@ -0,0 +1,17 @@ +base_model = "alibaba/qwen3.5-35b-a3b" +name = "Qwen3.5 35B A3B" +attachment = false +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.057 +output = 0.459 + +[limit] +context = 131_072 +output = 32_768 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml new file mode 100644 index 0000000000..9805d19df5 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml @@ -0,0 +1,17 @@ +base_model = "alibaba/qwen3.5-397b-a17b" +name = "Qwen3.5 397B A17B" +attachment = false +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.172 +output = 1.032 + +[limit] +context = 131_072 +output = 32_768 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-9b.toml b/providers/merge-gateway/models/qwen/qwen3.5-9b.toml new file mode 100644 index 0000000000..2b4e2a3935 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.5-9b.toml @@ -0,0 +1,14 @@ +base_model = "alibaba/qwen3.5-9b" +attachment = true +structured_output = false +reasoning_options = [] + +[cost] +input = 0.09 +output = 0.13 + +[limit] +output = 32_768 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-plus.toml b/providers/merge-gateway/models/qwen/qwen3.5-plus.toml new file mode 100644 index 0000000000..8379f126f0 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.5-plus.toml @@ -0,0 +1,14 @@ +base_model = "alibaba/qwen3.5-plus" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.115 +output = 0.688 + +[limit] +output = 250_000 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.6-27b.toml b/providers/merge-gateway/models/qwen/qwen3.6-27b.toml new file mode 100644 index 0000000000..9815022446 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.6-27b.toml @@ -0,0 +1,15 @@ +base_model = "alibaba/qwen3.6-27b" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.4126 +output = 2.4754 + +[limit] +context = 256_000 +output = 64_000 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml b/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml new file mode 100644 index 0000000000..57394e6fad --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml @@ -0,0 +1,13 @@ +base_model = "alibaba/qwen3.6-35b-a3b" +name = "Qwen3.6 35B A3B" +attachment = false +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.248 +output = 1.485 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.6-flash.toml b/providers/merge-gateway/models/qwen/qwen3.6-flash.toml new file mode 100644 index 0000000000..b10df25cf3 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.6-flash.toml @@ -0,0 +1,15 @@ +base_model = "alibaba/qwen3.6-flash" +attachment = false +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.165 +output = 0.99 + +[limit] +output = 250_000 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml b/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml new file mode 100644 index 0000000000..f2f9c11d1b --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml @@ -0,0 +1,11 @@ +base_model = "alibaba/qwen3.6-max-preview" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 1.31 +output = 7.88 + +[limit] +context = 256_000 diff --git a/providers/merge-gateway/models/qwen/qwen3.6-plus.toml b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml new file mode 100644 index 0000000000..a45e5743cf --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml @@ -0,0 +1,14 @@ +base_model = "alibaba/qwen3.6-plus" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.276 +output = 1.651 + +[limit] +output = 250_000 + +[modalities] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.7-max.toml b/providers/merge-gateway/models/qwen/qwen3.7-max.toml new file mode 100644 index 0000000000..b4ef76d4d8 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.7-max.toml @@ -0,0 +1,11 @@ +base_model = "alibaba/qwen3.7-max" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.825 +output = 2.4755 + +[limit] +output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3.7-plus.toml b/providers/merge-gateway/models/qwen/qwen3.7-plus.toml new file mode 100644 index 0000000000..df3d175dc8 --- /dev/null +++ b/providers/merge-gateway/models/qwen/qwen3.7-plus.toml @@ -0,0 +1,12 @@ +base_model = "alibaba/qwen3.7-plus" +attachment = true +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.4 +output = 1.6 + +[limit] +output = 65_536 diff --git a/providers/merge-gateway/models/xai/grok-4.20-0309-non-reasoning.toml b/providers/merge-gateway/models/xai/grok-4.20-0309-non-reasoning.toml new file mode 100644 index 0000000000..e803774686 --- /dev/null +++ b/providers/merge-gateway/models/xai/grok-4.20-0309-non-reasoning.toml @@ -0,0 +1,13 @@ +base_model = "xai/grok-4.20-0309-non-reasoning" +name = "Grok 4.20 Non-Reasoning" + +[cost] +input = 1.25 +output = 2.5 +cache_read = 0.2 + +[limit] +output = 1_000_000 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/xai/grok-4.20-0309-reasoning.toml b/providers/merge-gateway/models/xai/grok-4.20-0309-reasoning.toml index cfff36e939..eef910f466 100644 --- a/providers/merge-gateway/models/xai/grok-4.20-0309-reasoning.toml +++ b/providers/merge-gateway/models/xai/grok-4.20-0309-reasoning.toml @@ -1,4 +1,5 @@ base_model = "xai/grok-4.20-0309-reasoning" +name = "Grok 4.20" reasoning_options = [] [cost] @@ -11,3 +12,9 @@ tier = { type = "context", size = 200_000 } input = 2.5 output = 5 cache_read = 0.4 + +[limit] +output = 1_000_000 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/xai/grok-4.3.toml b/providers/merge-gateway/models/xai/grok-4.3.toml index faeaba94b5..cc89c88330 100644 --- a/providers/merge-gateway/models/xai/grok-4.3.toml +++ b/providers/merge-gateway/models/xai/grok-4.3.toml @@ -11,3 +11,9 @@ tier = { type = "context", size = 200_000 } input = 2.5 output = 5 cache_read = 0.4 + +[limit] +output = 1_000_000 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/xai/grok-4.5.toml b/providers/merge-gateway/models/xai/grok-4.5.toml new file mode 100644 index 0000000000..9179571704 --- /dev/null +++ b/providers/merge-gateway/models/xai/grok-4.5.toml @@ -0,0 +1,7 @@ +base_model = "xai/grok-4.5" +reasoning_options = [] + +[cost] +input = 2 +output = 6 +cache_read = 0.5 diff --git a/providers/merge-gateway/models/xai/grok-build-0.1.toml b/providers/merge-gateway/models/xai/grok-build-0.1.toml new file mode 100644 index 0000000000..2cd89e9a80 --- /dev/null +++ b/providers/merge-gateway/models/xai/grok-build-0.1.toml @@ -0,0 +1,10 @@ +base_model = "xai/grok-build-0.1" +reasoning_options = [] + +[cost] +input = 1 +output = 2 +cache_read = 0.2 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/zai/glm-4.5-air.toml b/providers/merge-gateway/models/zai/glm-4.5-air.toml index 2c9bfb4c1e..fb0ad87b7f 100644 --- a/providers/merge-gateway/models/zai/glm-4.5-air.toml +++ b/providers/merge-gateway/models/zai/glm-4.5-air.toml @@ -1,8 +1,15 @@ base_model = "zhipuai/glm-4.5-air" -reasoning_options = [{ type = "toggle" }] +name = "GLM-4.5 Air" +structured_output = false + +[[reasoning_options]] +type = "toggle" [cost] input = 0.2 output = 1.1 cache_read = 0.03 cache_write = 0 + +[limit] +context = 128_000 diff --git a/providers/merge-gateway/models/zai/glm-4.5.toml b/providers/merge-gateway/models/zai/glm-4.5.toml index d859695015..4286567606 100644 --- a/providers/merge-gateway/models/zai/glm-4.5.toml +++ b/providers/merge-gateway/models/zai/glm-4.5.toml @@ -1,8 +1,14 @@ base_model = "zhipuai/glm-4.5" -reasoning_options = [{ type = "toggle" }] +structured_output = false + +[[reasoning_options]] +type = "toggle" [cost] input = 0.6 output = 2.2 cache_read = 0.11 cache_write = 0 + +[limit] +context = 128_000 diff --git a/providers/merge-gateway/models/zai/glm-4.5v.toml b/providers/merge-gateway/models/zai/glm-4.5v.toml new file mode 100644 index 0000000000..167cbe1dac --- /dev/null +++ b/providers/merge-gateway/models/zai/glm-4.5v.toml @@ -0,0 +1,17 @@ +base_model = "zhipuai/glm-4.5v" +name = "Glm 4.5V" +structured_output = false +reasoning_options = [] + +[cost] +input = 0.6 +output = 1.8 +cache_read = 0.11 +cache_write = 0 + +[limit] +context = 128_000 +output = 32_000 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/zai/glm-4.6.toml b/providers/merge-gateway/models/zai/glm-4.6.toml index 1e32db1892..9b43877924 100644 --- a/providers/merge-gateway/models/zai/glm-4.6.toml +++ b/providers/merge-gateway/models/zai/glm-4.6.toml @@ -1,8 +1,14 @@ base_model = "zhipuai/glm-4.6" -reasoning_options = [{ type = "toggle" }] +structured_output = false + +[[reasoning_options]] +type = "toggle" [cost] input = 0.6 output = 2.2 cache_read = 0.11 cache_write = 0 + +[limit] +context = 200_000 diff --git a/providers/merge-gateway/models/zai/glm-4.7-flash.toml b/providers/merge-gateway/models/zai/glm-4.7-flash.toml new file mode 100644 index 0000000000..85c174b267 --- /dev/null +++ b/providers/merge-gateway/models/zai/glm-4.7-flash.toml @@ -0,0 +1,11 @@ +base_model = "zhipuai/glm-4.7-flash" +name = "GLM 4.7 Flash" +structured_output = false +reasoning_options = [] + +[cost] +input = 0.07 +output = 0.4 + +[limit] +output = 128_000 diff --git a/providers/merge-gateway/models/zai/glm-4.7-flashx.toml b/providers/merge-gateway/models/zai/glm-4.7-flashx.toml index 2ff24442cd..66e530d1d4 100644 --- a/providers/merge-gateway/models/zai/glm-4.7-flashx.toml +++ b/providers/merge-gateway/models/zai/glm-4.7-flashx.toml @@ -1,5 +1,9 @@ base_model = "zhipuai/glm-4.7-flashx" -reasoning_options = [{ type = "toggle" }] +name = "GLM-4.7 FlashX" +structured_output = false + +[[reasoning_options]] +type = "toggle" [cost] input = 0.07 diff --git a/providers/merge-gateway/models/zai/glm-4.7.toml b/providers/merge-gateway/models/zai/glm-4.7.toml index aaa77ab373..2645ef55ee 100644 --- a/providers/merge-gateway/models/zai/glm-4.7.toml +++ b/providers/merge-gateway/models/zai/glm-4.7.toml @@ -1,11 +1,17 @@ base_model = "zhipuai/glm-4.7" -reasoning_options = [{ type = "toggle" }] +structured_output = false [interleaved] field = "reasoning_content" +[[reasoning_options]] +type = "toggle" + [cost] input = 0.6 output = 2.2 cache_read = 0.11 cache_write = 0 + +[limit] +context = 200_000 diff --git a/providers/merge-gateway/models/zai/glm-5-turbo.toml b/providers/merge-gateway/models/zai/glm-5-turbo.toml index 685d533ed3..e0f648c6bb 100644 --- a/providers/merge-gateway/models/zai/glm-5-turbo.toml +++ b/providers/merge-gateway/models/zai/glm-5-turbo.toml @@ -1,9 +1,13 @@ base_model = "zhipuai/glm-5-turbo" -reasoning_options = [{ type = "toggle" }] +name = "GLM-5 Turbo" +structured_output = false [interleaved] field = "reasoning_content" +[[reasoning_options]] +type = "toggle" + [cost] input = 1.2 output = 4 diff --git a/providers/merge-gateway/models/zai/glm-5.1.toml b/providers/merge-gateway/models/zai/glm-5.1.toml index f359f73972..324ad86f62 100644 --- a/providers/merge-gateway/models/zai/glm-5.1.toml +++ b/providers/merge-gateway/models/zai/glm-5.1.toml @@ -1,9 +1,12 @@ base_model = "zhipuai/glm-5.1" -reasoning_options = [{ type = "toggle" }] +structured_output = false [interleaved] field = "reasoning_content" +[[reasoning_options]] +type = "toggle" + [cost] input = 1.4 output = 4.4 diff --git a/providers/merge-gateway/models/zai/glm-5.2.toml b/providers/merge-gateway/models/zai/glm-5.2.toml index 97a7dd870f..32140e8772 100644 --- a/providers/merge-gateway/models/zai/glm-5.2.toml +++ b/providers/merge-gateway/models/zai/glm-5.2.toml @@ -1,4 +1,8 @@ base_model = "zhipuai/glm-5.2" +structured_output = false + +[interleaved] +field = "reasoning_content" [[reasoning_options]] type = "toggle" @@ -8,9 +12,6 @@ type = "budget_tokens" min = 1 max = 50_000 -[interleaved] -field = "reasoning_content" - [cost] -input = 1.4 -output = 4.4 +input = 1.05 +output = 3.3 diff --git a/providers/merge-gateway/models/zai/glm-5.toml b/providers/merge-gateway/models/zai/glm-5.toml index f56566e0a6..0daa2719a0 100644 --- a/providers/merge-gateway/models/zai/glm-5.toml +++ b/providers/merge-gateway/models/zai/glm-5.toml @@ -1,11 +1,17 @@ base_model = "zhipuai/glm-5" -reasoning_options = [{ type = "toggle" }] +structured_output = false [interleaved] field = "reasoning_content" +[[reasoning_options]] +type = "toggle" + [cost] input = 1 output = 3.2 cache_read = 0.2 cache_write = 0 + +[limit] +context = 200_000 diff --git a/sync.md b/sync.md index 1f538b3640..0819c732ca 100644 --- a/sync.md +++ b/sync.md @@ -17,6 +17,7 @@ The grouped sync targets are available for local convenience, but CI syncs each - `bun models:sync digitalocean` syncs only DigitalOcean. - `bun models:sync xai` syncs only xAI. - `bun models:sync kilo` syncs only Kilo. +- `bun models:sync merge-gateway` syncs only Merge Gateway. - `bun models:sync openai` syncs only OpenAI catalog availability. - `bun models:sync aggregators --dry-run` prints changes without writing model files. - `bun models:sync aggregators --new-only` creates new model files but skips updates and removals. @@ -139,6 +140,19 @@ Kilo Gateway is implemented in `packages/core/src/sync/providers/kilo.ts`. - Canonical Kilo model IDs should emit `base_model` references to model metadata when a matching `models/` entry exists. - `reasoning_options` is derived from `opencode.variants` when present. +## Merge Gateway Notes + +Merge Gateway is implemented in `packages/core/src/sync/providers/merge-gateway.ts`. + +- Source endpoint: `https://api-gateway.merge.dev/v1/models`. +- Required auth: `MERGE_GATEWAY_API_KEY`. +- The sync follows `next_cursor` until every page has been fetched. +- The canonical provider's available vendor route supplies pricing, limits, and capabilities; another available vendor is used only when the canonical route is unavailable. +- Canonical model IDs emit `base_model` references to model metadata when a matching `models/` entry exists. +- Existing cache pricing, tiered pricing, reasoning controls, and experimental modes are preserved because the API does not expose them. +- When the API exposes route-level `prompt_caching` or cache pricing fields, those values authoritatively replace preserved cache prices. Cache prices curated before that API support remain in provider TOMLs and survive syncs. +- Local models missing from the response are retained because API-key policy can affect catalog visibility. + ## Cloudflare Workers AI Notes Cloudflare Workers AI is implemented in `packages/core/src/sync/providers/cloudflare-workers-ai.ts`. From 2d91d4583b6aae8c85d52591a5669d69daad887e Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Tue, 14 Jul 2026 09:10:09 -0400 Subject: [PATCH 02/11] fix(merge-gateway): document reasoning controls --- .../anthropic/claude-3-7-sonnet-20250219.toml | 5 ++++- .../models/anthropic/claude-fable-5.toml | 3 +++ .../models/anthropic/claude-sonnet-5.toml | 4 +++- .../models/openai/gpt-5.6-luna.toml | 5 ++++- .../models/openai/gpt-5.6-terra.toml | 5 ++++- .../models/openai/gpt-oss-120b.toml | 3 +++ .../models/openai/gpt-oss-20b.toml | 3 +++ providers/merge-gateway/provider.toml | 20 +++++++++---------- 8 files changed, 33 insertions(+), 15 deletions(-) diff --git a/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml b/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml index 8c0263b486..10113cd6f7 100644 --- a/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml +++ b/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml @@ -1,7 +1,10 @@ +# Merge Gateway GET /v1/models?model=anthropic/claude-3-7-sonnet-20250219 +# (accessed 2026-07-14): the Bedrock route advertises configurable +# `thinking.budget_tokens` and disable support. base_model = "anthropic/claude-3-7-sonnet-20250219" name = "Claude 3.7 Sonnet" structured_output = true -reasoning_options = [] +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 63_999 }] [cost] input = 3 diff --git a/providers/merge-gateway/models/anthropic/claude-fable-5.toml b/providers/merge-gateway/models/anthropic/claude-fable-5.toml index 747fc86411..f8c3b236b2 100644 --- a/providers/merge-gateway/models/anthropic/claude-fable-5.toml +++ b/providers/merge-gateway/models/anthropic/claude-fable-5.toml @@ -1,3 +1,6 @@ +# Merge Gateway GET /v1/models?model=anthropic/claude-fable-5 (accessed 2026-07-14): +# the only available Anthropic route reports `supports_reasoning = false`, so +# callers have no reasoning control despite the base model being reasoning-capable. base_model = "anthropic/claude-fable-5" structured_output = true reasoning_options = [] diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml index fc8b6671ee..0ef763168d 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml @@ -1,6 +1,8 @@ +# Merge Gateway GET /v1/models?model=anthropic/claude-sonnet-5 (accessed 2026-07-14): +# the Anthropic route advertises configurable `reasoning.effort` and disable support. base_model = "anthropic/claude-sonnet-5" structured_output = true -reasoning_options = [] +reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] [cost] input = 2 diff --git a/providers/merge-gateway/models/openai/gpt-5.6-luna.toml b/providers/merge-gateway/models/openai/gpt-5.6-luna.toml index 409d016fa2..37a38e5a9b 100644 --- a/providers/merge-gateway/models/openai/gpt-5.6-luna.toml +++ b/providers/merge-gateway/models/openai/gpt-5.6-luna.toml @@ -1,5 +1,8 @@ +# Merge Gateway GET /v1/models?model=openai/gpt-5.6-luna (accessed 2026-07-14): +# the OpenAI vendor route advertises configurable `reasoning.effort` and disable support. +# Effort values: https://openai.com/index/gpt-5-6/ base_model = "openai/gpt-5.6-luna" -reasoning_options = [] +reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh", "max"] }] [cost] input = 0.75 diff --git a/providers/merge-gateway/models/openai/gpt-5.6-terra.toml b/providers/merge-gateway/models/openai/gpt-5.6-terra.toml index ca94a4583c..592888015f 100644 --- a/providers/merge-gateway/models/openai/gpt-5.6-terra.toml +++ b/providers/merge-gateway/models/openai/gpt-5.6-terra.toml @@ -1,5 +1,8 @@ +# Merge Gateway GET /v1/models?model=openai/gpt-5.6-terra (accessed 2026-07-14): +# the OpenAI vendor route advertises configurable `reasoning.effort` and disable support. +# Effort values: https://openai.com/index/gpt-5-6/ base_model = "openai/gpt-5.6-terra" -reasoning_options = [] +reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh", "max"] }] [cost] input = 1.875 diff --git a/providers/merge-gateway/models/openai/gpt-oss-120b.toml b/providers/merge-gateway/models/openai/gpt-oss-120b.toml index f6ea8e4325..3eb069e5a6 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-120b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-120b.toml @@ -1,3 +1,6 @@ +# Merge Gateway GET /v1/models?model=openai/gpt-oss-120b (accessed 2026-07-14): +# available routes either report `supports_reasoning = false` or reasoning with +# `configurable = false` and no controls, so callers have no reasoning control. base_model = "openai/gpt-oss-120b" tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/openai/gpt-oss-20b.toml b/providers/merge-gateway/models/openai/gpt-oss-20b.toml index 6619d5300c..758d8dc047 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-20b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-20b.toml @@ -1,3 +1,6 @@ +# Merge Gateway GET /v1/models?model=openai/gpt-oss-20b (accessed 2026-07-14): +# available routes either report `supports_reasoning = false` or reasoning with +# `configurable = false` and no controls, so callers have no reasoning control. base_model = "openai/gpt-oss-20b" reasoning_options = [] diff --git a/providers/merge-gateway/provider.toml b/providers/merge-gateway/provider.toml index 93c78884b5..293c689f4f 100644 --- a/providers/merge-gateway/provider.toml +++ b/providers/merge-gateway/provider.toml @@ -1,20 +1,18 @@ name = "Merge Gateway" env = ["MERGE_GATEWAY_API_KEY"] npm = "merge-gateway-ai-sdk-provider" -# Reasoning request surfaces (sources accessed 2026-06-25): -# - OpenAI compatibility: POST /v1/openai/chat/completions uses the native -# top-level `reasoning_effort`; the documented base accepts OpenAI SDK calls. -# - Anthropic compatibility: POST /v1/anthropic/v1/messages uses native -# `thinking = { type = "enabled"|"disabled", budget_tokens = N }` and -# `output_config.effort`. +# Reasoning request surfaces (sources accessed 2026-07-14): +# - Reasoning support and controls are vendor-route capabilities. Use the exact +# model response from GET /v1/models and inspect +# vendors..capabilities.reasoning; do not infer support solely from a +# compatibility endpoint's request shape. +# https://docs.merge.dev/merge-gateway/features/reasoning +# https://docs.merge.dev/merge-gateway/api-overview/models/list +# - OpenAI and Anthropic compatibility endpoints accept their native request +# shapes when the selected vendor route advertises the corresponding control. # https://docs.merge.dev/merge-gateway/get-started -# https://docs.anthropic.com/en/api/messages # - This npm package calls POST /v1/ai-sdk/chat/completions and maps # `providerOptions.mergeGateway.thinking` to # `thinking = { type = "enabled"|"disabled", budget_tokens = N }`. # https://github.com/merge-api/merge-gateway-ai-sdk-provider/blob/main/src/chat/index.ts -# - Native POST /v1/responses has no reasoning field in its strict request -# schema. Other normalized or dynamically routed routes do not document -# transparent native-field passthrough; do not infer support from them. -# https://docs.merge.dev/merge-gateway/api-overview/responses/create doc = "https://docs.merge.dev/merge-gateway" From 46c9418e600067dfdb01ce722108eb089299cf72 Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Tue, 14 Jul 2026 09:23:39 -0400 Subject: [PATCH 03/11] fix(sync): preserve partial Merge Gateway metadata --- .../core/src/sync/providers/merge-gateway.ts | 13 ++------- packages/core/test/sync.test.ts | 28 ++++++++++++++++++- .../models/anthropic/claude-fable-5.toml | 6 ++-- sync.md | 2 +- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/packages/core/src/sync/providers/merge-gateway.ts b/packages/core/src/sync/providers/merge-gateway.ts index 87829ede0e..575f7a5c2c 100644 --- a/packages/core/src/sync/providers/merge-gateway.ts +++ b/packages/core/src/sync/providers/merge-gateway.ts @@ -257,22 +257,13 @@ function mergeGatewayCachePricing( ) { const promptCaching = vendor.prompt_caching; const pricing = vendor.pricing; - const authoritative = promptCaching !== undefined - || pricing.cache_read_per_million !== undefined - || pricing.cache_write_per_million !== undefined; - if (!authoritative) { - return { - read: existing?.cost?.cache_read, - write: existing?.cost?.cache_write, - }; - } return { read: promptCaching?.cache_read_cost_per_million ?? pricing.cache_read_per_million - ?? undefined, + ?? existing?.cost?.cache_read, write: promptCaching?.cache_write_cost_per_million ?? pricing.cache_write_per_million - ?? undefined, + ?? existing?.cost?.cache_write, }; } diff --git a/packages/core/test/sync.test.ts b/packages/core/test/sync.test.ts index 4fbd29f3e6..407a694e26 100644 --- a/packages/core/test/sync.test.ts +++ b/packages/core/test/sync.test.ts @@ -1125,7 +1125,7 @@ test("factors Merge Gateway GPT-5.6 Sol against canonical metadata", () => { }); }); -test("syncs authoritative Merge Gateway cache pricing", () => { +test("merges authoritative Merge Gateway cache pricing field by field", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ vendors: { openai: mergeGatewayVendor({ @@ -1156,6 +1156,32 @@ test("syncs authoritative Merge Gateway cache pricing", () => { input: 3.75, output: 22.5, cache_read: 0.375, + cache_write: 6.25, + }, + }); +}); + +test("preserves Merge Gateway cache pricing when prompt caching exposes only its mode", () => { + const model = buildMergeGatewayModel(mergeGatewayModel({ + vendors: { + openai: mergeGatewayVendor({ + prompt_caching: { mode: "automatic" }, + }), + }, + }), { + base_model: "openai/gpt-5.6-sol", + cost: { + input: 5, + output: 30, + cache_read: 0.5, + cache_write: 6.25, + }, + }); + + expect(model).toMatchObject({ + cost: { + cache_read: 0.5, + cache_write: 6.25, }, }); }); diff --git a/providers/merge-gateway/models/anthropic/claude-fable-5.toml b/providers/merge-gateway/models/anthropic/claude-fable-5.toml index f8c3b236b2..eaa41a5da3 100644 --- a/providers/merge-gateway/models/anthropic/claude-fable-5.toml +++ b/providers/merge-gateway/models/anthropic/claude-fable-5.toml @@ -1,9 +1,9 @@ # Merge Gateway GET /v1/models?model=anthropic/claude-fable-5 (accessed 2026-07-14): -# the only available Anthropic route reports `supports_reasoning = false`, so -# callers have no reasoning control despite the base model being reasoning-capable. +# the only available Anthropic route reports `supports_reasoning = false`, so this +# provider route does not expose the base model's reasoning capability. base_model = "anthropic/claude-fable-5" +reasoning = false structured_output = true -reasoning_options = [] [cost] input = 10 diff --git a/sync.md b/sync.md index 0819c732ca..ce8c22f5f5 100644 --- a/sync.md +++ b/sync.md @@ -150,7 +150,7 @@ Merge Gateway is implemented in `packages/core/src/sync/providers/merge-gateway. - The canonical provider's available vendor route supplies pricing, limits, and capabilities; another available vendor is used only when the canonical route is unavailable. - Canonical model IDs emit `base_model` references to model metadata when a matching `models/` entry exists. - Existing cache pricing, tiered pricing, reasoning controls, and experimental modes are preserved because the API does not expose them. -- When the API exposes route-level `prompt_caching` or cache pricing fields, those values authoritatively replace preserved cache prices. Cache prices curated before that API support remain in provider TOMLs and survive syncs. +- Route-level cache prices replace curated values field by field. A cache read or write price that the API does not expose remains preserved in the provider TOML, including when `prompt_caching` exposes only its mode. - Local models missing from the response are retained because API-key policy can affect catalog visibility. ## Cloudflare Workers AI Notes From 182176ea43ec0a9de36838507dbd9ebdf3d558a2 Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Tue, 14 Jul 2026 23:15:53 -0400 Subject: [PATCH 04/11] fix(merge-gateway): align route metadata sync --- .../core/src/sync/providers/merge-gateway.ts | 34 +++++-- .../core/src/sync/providers/openrouter.ts | 2 + packages/core/test/sync.test.ts | 94 +++++++++++++++++++ .../anthropic/claude-haiku-4-5-20251001.toml | 9 +- .../anthropic/claude-opus-4-1-20250805.toml | 9 +- .../anthropic/claude-opus-4-20250514.toml | 9 +- .../anthropic/claude-opus-4-5-20251101.toml | 13 +-- .../models/anthropic/claude-opus-4-6.toml | 13 +-- .../models/anthropic/claude-opus-4-7.toml | 8 +- .../models/anthropic/claude-opus-4-8.toml | 9 +- .../anthropic/claude-sonnet-4-5-20250929.toml | 9 +- .../models/anthropic/claude-sonnet-4-6.toml | 13 +-- .../bytedance/dola-seed-2.0-code-preview.toml | 25 +++++ .../models/bytedance/dola-seed-2.0-code.toml | 25 +++++ .../models/bytedance/dola-seed-2.0-lite.toml | 25 +++++ .../models/bytedance/dola-seed-2.0-mini.toml | 25 +++++ .../models/bytedance/dola-seed-2.0-pro.toml | 25 +++++ .../models/deepseek/deepseek-r1.toml | 2 +- .../models/google/gemma-4-26b-a4b-it.toml | 4 +- .../models/google/gemma-4-31b-it.toml | 4 +- .../models/meta/llama-3.3-70b-instruct.toml | 8 +- .../models/meta/muse-spark-1.1.toml | 1 + .../{moonshotai => moonshot}/kimi-k2.5.toml | 11 ++- .../{moonshotai => moonshot}/kimi-k2.6.toml | 10 +- .../kimi-k2.7-code-highspeed.toml | 13 ++- .../kimi-k2.7-code.toml | 13 ++- .../models/moonshotai/kimi-k2-thinking.toml | 1 + .../models/nvidia/nemotron-nano-9b-v2.toml | 2 +- .../models/openai/gpt-5-chat-latest.toml | 2 +- .../models/openai/gpt-5.1-chat-latest.toml | 2 +- .../models/openai/gpt-5.2-chat-latest.toml | 2 +- .../models/openai/gpt-oss-120b.toml | 10 +- .../models/openai/gpt-oss-20b.toml | 13 ++- .../merge-gateway/models/qwen/qwen-flash.toml | 3 +- .../merge-gateway/models/qwen/qwen-plus.toml | 3 +- .../models/qwen/qwen3-235b-a22b.toml | 3 +- .../merge-gateway/models/qwen/qwen3-32b.toml | 7 +- .../models/qwen/qwen3-coder-flash.toml | 1 + .../models/qwen/qwen3-coder-plus.toml | 1 + .../merge-gateway/models/qwen/qwen3-max.toml | 1 + .../qwen/qwen3-next-80b-a3b-instruct.toml | 1 + .../qwen/qwen3-next-80b-a3b-thinking.toml | 6 +- .../models/qwen/qwen3-vl-plus.toml | 3 +- .../models/qwen/qwen3.5-122b-a10b.toml | 3 +- .../models/qwen/qwen3.5-27b.toml | 3 +- .../models/qwen/qwen3.5-35b-a3b.toml | 3 +- .../models/qwen/qwen3.5-397b-a17b.toml | 3 +- .../merge-gateway/models/qwen/qwen3.5-9b.toml | 2 +- .../models/qwen/qwen3.5-plus.toml | 3 +- .../models/qwen/qwen3.6-27b.toml | 2 +- .../models/qwen/qwen3.6-35b-a3b.toml | 3 +- .../models/qwen/qwen3.6-flash.toml | 3 +- .../models/qwen/qwen3.6-max-preview.toml | 2 +- .../models/qwen/qwen3.6-plus.toml | 3 +- .../models/qwen/qwen3.7-max.toml | 3 +- .../models/qwen/qwen3.7-plus.toml | 2 +- .../models/sakana/fugu-ultra.toml | 10 ++ .../models/writer/palmyra-x4.toml | 25 +++++ .../models/writer/palmyra-x5.toml | 25 +++++ .../merge-gateway/models/zai/glm-4.5v.toml | 2 +- .../models/zai/glm-4.7-flash.toml | 2 +- .../merge-gateway/models/zai/glm-5.2.toml | 10 +- sync.md | 6 +- 63 files changed, 422 insertions(+), 167 deletions(-) create mode 100644 providers/merge-gateway/models/bytedance/dola-seed-2.0-code-preview.toml create mode 100644 providers/merge-gateway/models/bytedance/dola-seed-2.0-code.toml create mode 100644 providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml create mode 100644 providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml create mode 100644 providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml rename providers/merge-gateway/models/{moonshotai => moonshot}/kimi-k2.5.toml (74%) rename providers/merge-gateway/models/{moonshotai => moonshot}/kimi-k2.6.toml (78%) rename providers/merge-gateway/models/{moonshotai => moonshot}/kimi-k2.7-code-highspeed.toml (73%) rename providers/merge-gateway/models/{moonshotai => moonshot}/kimi-k2.7-code.toml (72%) create mode 100644 providers/merge-gateway/models/sakana/fugu-ultra.toml create mode 100644 providers/merge-gateway/models/writer/palmyra-x4.toml create mode 100644 providers/merge-gateway/models/writer/palmyra-x5.toml diff --git a/packages/core/src/sync/providers/merge-gateway.ts b/packages/core/src/sync/providers/merge-gateway.ts index 575f7a5c2c..4df225a75c 100644 --- a/packages/core/src/sync/providers/merge-gateway.ts +++ b/packages/core/src/sync/providers/merge-gateway.ts @@ -14,6 +14,7 @@ const VendorCapabilities = z.object({ supports_tool_calling: z.boolean(), supports_tool_choice: z.boolean().default(false), supports_structured_outputs: z.boolean(), + supports_reasoning: z.boolean().optional(), streaming: z.boolean(), }).passthrough(); @@ -141,13 +142,22 @@ export function selectMergeGatewayVendor(model: MergeGatewayModel) { return { id: model.provider, info: canonical }; } + // Match Gateway's default resolver: when the model author's native route is + // unavailable, use the cheapest active route by combined input + output + // price. Object order is preserved for equal prices; the public API emits + // vendors in CMS-priority order, which is Gateway's own tiebreaker. const available = Object.entries(model.vendors) - .filter(([, info]) => info.availability_status === "available") - .sort(([a], [b]) => a.localeCompare(b))[0]; - if (available !== undefined) return { id: available[0], info: available[1] }; + .filter(([, info]) => info.availability_status === "available"); + const selected = available.reduce((best, candidate) => { + if (best === undefined) return candidate; + const bestCost = best[1].pricing.input_per_million + best[1].pricing.output_per_million; + const candidateCost = candidate[1].pricing.input_per_million + candidate[1].pricing.output_per_million; + return candidateCost < bestCost ? candidate : best; + }, undefined); + if (selected !== undefined) return { id: selected[0], info: selected[1] }; if (canonical !== undefined) return { id: model.provider, info: canonical }; - const fallback = Object.entries(model.vendors).sort(([a], [b]) => a.localeCompare(b))[0]; + const fallback = Object.entries(model.vendors)[0]; return fallback === undefined ? undefined : { id: fallback[0], info: fallback[1] }; } @@ -184,6 +194,9 @@ export function buildMergeGatewayModel( ? "deprecated" as const : undefined; const baseModel = existing?.base_model ?? resolveCanonicalBaseModel(model.model); + const routeDisablesReasoning = selected.info.capabilities.supports_reasoning === false; + const reasoning = routeDisablesReasoning ? false : existing?.reasoning; + const reasoningOptions = routeDisablesReasoning ? undefined : existing?.reasoning_options; const authoritative = { // Some catalog rows use an upstream org/model ID as display_name. Let // canonical metadata provide the human-readable name for factored models. @@ -203,8 +216,8 @@ export function buildMergeGatewayModel( { ...authoritative, description: existing?.description, - reasoning: existing?.reasoning, - reasoning_options: existing?.reasoning_options, + reasoning, + reasoning_options: reasoningOptions, temperature: existing?.temperature, interleaved: existing?.interleaved, provider: existing?.provider, @@ -230,7 +243,7 @@ export function buildMergeGatewayModel( id: model.model, name: model.display_name, family: existing.family, - reasoning: existing.reasoning, + reasoning, tool_call: selected.info.capabilities.supports_tool_calling, structured_output: selected.info.capabilities.supports_structured_outputs, open_weights: existing.open_weights, @@ -240,8 +253,8 @@ export function buildMergeGatewayModel( family: existing.family, release_date: releaseDate, last_updated: lastUpdated, - reasoning: existing.reasoning ?? false, - reasoning_options: existing.reasoning_options, + reasoning: reasoning ?? false, + reasoning_options: reasoningOptions, temperature: existing.temperature, knowledge: existing.knowledge, open_weights: existing.open_weights ?? false, @@ -257,6 +270,9 @@ function mergeGatewayCachePricing( ) { const promptCaching = vendor.prompt_caching; const pricing = vendor.pricing; + if (promptCaching?.mode === "none") { + return { read: undefined, write: undefined }; + } return { read: promptCaching?.cache_read_cost_per_million ?? pricing.cache_read_per_million diff --git a/packages/core/src/sync/providers/openrouter.ts b/packages/core/src/sync/providers/openrouter.ts index d35cc3f978..7fe7bac2ad 100644 --- a/packages/core/src/sync/providers/openrouter.ts +++ b/packages/core/src/sync/providers/openrouter.ts @@ -27,10 +27,12 @@ const CANONICAL_PROVIDER_PREFIXES = { "meta-llama": { provider: "llama", metadata: "meta" }, minimax: { provider: "minimax", metadata: "minimax" }, mistralai: { provider: "mistral", metadata: "mistral" }, + moonshot: { provider: "moonshotai", metadata: "moonshotai" }, moonshotai: { provider: "moonshotai", metadata: "moonshotai" }, openai: { provider: "openai", metadata: "openai" }, nvidia: { provider: "nvidia", metadata: "nvidia" }, qwen: { provider: "alibaba", metadata: "alibaba" }, + sakana: { provider: "sakana", metadata: "sakana" }, stepfun: { provider: "stepfun", metadata: "stepfun" }, tencent: { provider: "tencent", metadata: "tencent" }, "x-ai": { provider: "xai", metadata: "xai" }, diff --git a/packages/core/test/sync.test.ts b/packages/core/test/sync.test.ts index 407a694e26..a7f10ddfd5 100644 --- a/packages/core/test/sync.test.ts +++ b/packages/core/test/sync.test.ts @@ -962,6 +962,22 @@ test("factors OpenRouter Pro routes against canonical OpenAI metadata", () => { expect("release_date" in model).toBe(false); }); +test("resolves Merge Gateway provider aliases to canonical metadata", () => { + expect([ + resolveCanonicalBaseModel("moonshot/kimi-k2.5"), + resolveCanonicalBaseModel("moonshot/kimi-k2.6"), + resolveCanonicalBaseModel("moonshot/kimi-k2.7-code"), + resolveCanonicalBaseModel("moonshot/kimi-k2.7-code-highspeed"), + resolveCanonicalBaseModel("sakana/fugu-ultra"), + ]).toEqual([ + "moonshotai/kimi-k2.5", + "moonshotai/kimi-k2.6", + "moonshotai/kimi-k2.7-code", + "moonshotai/kimi-k2.7-code-highspeed", + "sakana/fugu-ultra", + ]); +}); + test("resolves Venice Pro routes to canonical OpenAI metadata", () => { expect([ resolveVeniceBaseModel("openai-gpt-56-luna-pro", "GPT-5.6 Luna Pro"), @@ -1125,6 +1141,25 @@ test("factors Merge Gateway GPT-5.6 Sol against canonical metadata", () => { }); }); +test("disables reasoning when the selected Merge Gateway route explicitly does not support it", () => { + const vendor = mergeGatewayVendor(); + vendor.capabilities.supports_reasoning = false; + const model = buildMergeGatewayModel(mergeGatewayModel({ + vendors: { openai: vendor }, + }), { + base_model: "openai/gpt-5.6-sol", + reasoning: true, + reasoning_options: [{ type: "effort", values: ["low", "medium", "high"] }], + cost: { input: 5, output: 30 }, + }); + + expect(model).toMatchObject({ + base_model: "openai/gpt-5.6-sol", + reasoning: false, + }); + expect(model).not.toHaveProperty("reasoning_options"); +}); + test("merges authoritative Merge Gateway cache pricing field by field", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ vendors: { @@ -1186,6 +1221,30 @@ test("preserves Merge Gateway cache pricing when prompt caching exposes only its }); }); +test("removes Merge Gateway cache pricing when prompt caching mode is none", () => { + const model = buildMergeGatewayModel(mergeGatewayModel({ + vendors: { + openai: mergeGatewayVendor({ + prompt_caching: { mode: "none" }, + }), + }, + }), { + base_model: "openai/gpt-5.6-sol", + cost: { + input: 5, + output: 30, + cache_read: 0.5, + cache_write: 6.25, + }, + }); + + expect(model).toMatchObject({ + cost: { input: 5, output: 30 }, + }); + expect(model.cost).not.toHaveProperty("cache_read"); + expect(model.cost).not.toHaveProperty("cache_write"); +}); + test("inherits canonical names for ID-shaped Merge Gateway display names", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ model: "minimax/minimax-m2", @@ -1239,6 +1298,41 @@ test("uses the canonical Merge Gateway vendor as the catalog baseline", () => { }); }); +test("uses Merge Gateway's cheapest fallback route when no canonical route exists", () => { + const model = mergeGatewayModel({ + provider: "qwen", + vendors: { + bedrock: mergeGatewayVendor({ + pricing: { currency: "USD", input_per_million: 0.15, output_per_million: 0.6 }, + }), + alibaba: mergeGatewayVendor({ + pricing: { currency: "USD", input_per_million: 0.287, output_per_million: 0.64 }, + }), + }, + }); + + expect(selectMergeGatewayVendor(model)).toMatchObject({ + id: "bedrock", + info: { pricing: { input_per_million: 0.15, output_per_million: 0.6 } }, + }); +}); + +test("uses Merge Gateway's CMS order to break equal-cost fallback ties", () => { + const model = mergeGatewayModel({ + provider: "qwen", + vendors: { + empiriolabs: mergeGatewayVendor({ + pricing: { currency: "USD", input_per_million: 0.4, output_per_million: 1.6 }, + }), + fireworks: mergeGatewayVendor({ + pricing: { currency: "USD", input_per_million: 0.4, output_per_million: 1.6 }, + }), + }, + }); + + expect(selectMergeGatewayVendor(model)).toMatchObject({ id: "empiriolabs" }); +}); + test("retains Merge Gateway models missing from an API-key-scoped response", () => { expect(mergeGateway.deleteMissing).toBe(false); }); diff --git a/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml b/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml index 12beefa8b4..4b543cb668 100644 --- a/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml +++ b/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml @@ -1,15 +1,8 @@ base_model = "anthropic/claude-haiku-4-5-20251001" name = "Claude Haiku 4.5 (20251001)" +reasoning = false structured_output = true -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 -max = 63_999 - [cost] input = 1 output = 5 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml index 80cef05967..dd3ffc4088 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml @@ -1,15 +1,8 @@ base_model = "anthropic/claude-opus-4-1-20250805" name = "Claude Opus 4.1 (20250805)" +reasoning = false structured_output = true -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 -max = 31_999 - [cost] input = 15 output = 75 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml index 0b0174e5b0..91211fe012 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml @@ -1,15 +1,8 @@ base_model = "anthropic/claude-opus-4-20250514" name = "Claude Opus 4 (20250514)" +reasoning = false structured_output = true -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 -max = 31_999 - [cost] input = 15 output = 75 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml index e51f165765..a68a8f006c 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml @@ -1,19 +1,8 @@ base_model = "anthropic/claude-opus-4-5-20251101" name = "Claude Opus 4.5 (20251101)" +reasoning = false structured_output = true -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "effort" -values = ["low", "medium", "high"] - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 -max = 63_999 - [cost] input = 5 output = 25 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml index 63d173c380..81b36cbff0 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml @@ -1,18 +1,7 @@ base_model = "anthropic/claude-opus-4-6" +reasoning = false structured_output = true -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "effort" -values = ["low", "medium", "high", "max"] - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 -max = 127_999 - [cost] input = 5 output = 25 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml index 0fe0cead33..2a438839af 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml @@ -1,13 +1,7 @@ base_model = "anthropic/claude-opus-4-7" +reasoning = false structured_output = true -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "effort" -values = ["low", "medium", "high", "xhigh", "max"] - [cost] input = 5 output = 25 diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml index 7606299bdd..4ef7dcb879 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml @@ -1,14 +1,7 @@ base_model = "anthropic/claude-opus-4-8" +reasoning = false structured_output = true -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1 -max = 128_000 - [cost] input = 5 output = 25 diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml index e9bf085d46..0790c8ef4c 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml @@ -1,15 +1,8 @@ base_model = "anthropic/claude-sonnet-4-5-20250929" name = "Claude Sonnet 4.5 (20250929)" +reasoning = false structured_output = true -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 -max = 63_999 - [cost] input = 3 output = 15 diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml index 89818d9638..0e668b3f41 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml @@ -1,18 +1,7 @@ base_model = "anthropic/claude-sonnet-4-6" +reasoning = false structured_output = true -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "effort" -values = ["low", "medium", "high", "max"] - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 -max = 63_999 - [cost] input = 3 output = 15 diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-code-preview.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-code-preview.toml new file mode 100644 index 0000000000..abbba27194 --- /dev/null +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-code-preview.toml @@ -0,0 +1,25 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-code-preview + +name = "Dola Seed 2.0 Code (preview)" +description = "Preview coding model for repository understanding, refactors, and engineering tasks" +family = "seed" +release_date = "2026-03-28" +last_updated = "2026-03-28" +attachment = false +reasoning = false +temperature = true +tool_call = false +structured_output = false +open_weights = false + +[cost] +input = 0.5 +output = 3 + +[limit] +context = 131_072 +output = 32_768 + +[modalities] +input = ["text"] +output = ["text"] diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-code.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-code.toml new file mode 100644 index 0000000000..24901bca8a --- /dev/null +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-code.toml @@ -0,0 +1,25 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-code + +name = "Seed 2.0 Code" +description = "Coding model for repository understanding, refactors, and agentic engineering tasks" +family = "seed" +release_date = "2026-02-14" +last_updated = "2026-02-14" +attachment = true +reasoning = false +temperature = true +tool_call = false +structured_output = false +open_weights = false + +[cost] +input = 0.4 +output = 2.4 + +[limit] +context = 256_000 +output = 128_000 + +[modalities] +input = ["text", "image"] +output = ["text"] diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml new file mode 100644 index 0000000000..9c2e1aa96b --- /dev/null +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml @@ -0,0 +1,25 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-lite + +name = "Seed 2.0 Lite" +description = "Efficient Seed model for general chat, analysis, and lightweight production tasks" +family = "seed" +release_date = "2026-02-28" +last_updated = "2026-02-28" +attachment = false +reasoning = false +temperature = true +tool_call = false +structured_output = false +open_weights = false + +[cost] +input = 0.25 +output = 2 + +[limit] +context = 131_072 +output = 32_768 + +[modalities] +input = ["text"] +output = ["text"] diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml new file mode 100644 index 0000000000..b5cea45ca4 --- /dev/null +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml @@ -0,0 +1,25 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-mini + +name = "Seed 2.0 Mini" +description = "Low-cost Seed model for general chat, extraction, and lightweight production tasks" +family = "seed" +release_date = "2026-02-15" +last_updated = "2026-02-15" +attachment = false +reasoning = false +temperature = true +tool_call = false +structured_output = false +open_weights = false + +[cost] +input = 0.1 +output = 0.4 + +[limit] +context = 131_072 +output = 32_768 + +[modalities] +input = ["text"] +output = ["text"] diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml new file mode 100644 index 0000000000..b990a9d442 --- /dev/null +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml @@ -0,0 +1,25 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-pro + +name = "Seed 2.0 Pro" +description = "Higher-capability Seed model for complex chat, analysis, and production tasks" +family = "seed" +release_date = "2026-03-28" +last_updated = "2026-03-28" +attachment = false +reasoning = false +temperature = true +tool_call = false +structured_output = false +open_weights = false + +[cost] +input = 0.5 +output = 3 + +[limit] +context = 131_072 +output = 32_768 + +[modalities] +input = ["text"] +output = ["text"] diff --git a/providers/merge-gateway/models/deepseek/deepseek-r1.toml b/providers/merge-gateway/models/deepseek/deepseek-r1.toml index 283094ea09..669e074a17 100644 --- a/providers/merge-gateway/models/deepseek/deepseek-r1.toml +++ b/providers/merge-gateway/models/deepseek/deepseek-r1.toml @@ -1,8 +1,8 @@ base_model = "deepseek/deepseek-r1" name = "DeepSeek R1" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 1.35 diff --git a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml index a776b41646..0814497dc9 100644 --- a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml @@ -1,11 +1,9 @@ base_model = "google/gemma-4-26b-a4b-it" attachment = false +reasoning = false tool_call = false structured_output = false -[[reasoning_options]] -type = "toggle" - [cost] input = 0.13 output = 0.4 diff --git a/providers/merge-gateway/models/google/gemma-4-31b-it.toml b/providers/merge-gateway/models/google/gemma-4-31b-it.toml index fda08e4f1e..1595362736 100644 --- a/providers/merge-gateway/models/google/gemma-4-31b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-31b-it.toml @@ -1,11 +1,9 @@ base_model = "google/gemma-4-31b-it" attachment = false +reasoning = false tool_call = false structured_output = false -[[reasoning_options]] -type = "toggle" - [cost] input = 0.14 output = 0.4 diff --git a/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml index 152e720938..c4416d75b9 100644 --- a/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml +++ b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml @@ -3,5 +3,9 @@ attachment = false structured_output = false [cost] -input = 0.72 -output = 0.72 +input = 0.22 +output = 0.5 + +[limit] +context = 131_072 +output = 32_768 diff --git a/providers/merge-gateway/models/meta/muse-spark-1.1.toml b/providers/merge-gateway/models/meta/muse-spark-1.1.toml index d49ae48665..d1ed3666ff 100644 --- a/providers/merge-gateway/models/meta/muse-spark-1.1.toml +++ b/providers/merge-gateway/models/meta/muse-spark-1.1.toml @@ -5,6 +5,7 @@ reasoning_options = [] [cost] input = 1.25 output = 4.25 +cache_read = 0.15 [limit] context = 1_048_576 diff --git a/providers/merge-gateway/models/moonshotai/kimi-k2.5.toml b/providers/merge-gateway/models/moonshot/kimi-k2.5.toml similarity index 74% rename from providers/merge-gateway/models/moonshotai/kimi-k2.5.toml rename to providers/merge-gateway/models/moonshot/kimi-k2.5.toml index cf77522a3f..41fabf109c 100644 --- a/providers/merge-gateway/models/moonshotai/kimi-k2.5.toml +++ b/providers/merge-gateway/models/moonshot/kimi-k2.5.toml @@ -1,4 +1,8 @@ base_model = "moonshotai/kimi-k2.5" +attachment = true + +[interleaved] +field = "reasoning_content" [[reasoning_options]] type = "toggle" @@ -8,9 +12,10 @@ type = "budget_tokens" min = 1 max = 262_144 -[interleaved] -field = "reasoning_content" - [cost] input = 0.6 output = 3 +cache_read = 0.1 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/moonshotai/kimi-k2.6.toml b/providers/merge-gateway/models/moonshot/kimi-k2.6.toml similarity index 78% rename from providers/merge-gateway/models/moonshotai/kimi-k2.6.toml rename to providers/merge-gateway/models/moonshot/kimi-k2.6.toml index 59d14b6a7f..2ce0ba3019 100644 --- a/providers/merge-gateway/models/moonshotai/kimi-k2.6.toml +++ b/providers/merge-gateway/models/moonshot/kimi-k2.6.toml @@ -1,5 +1,8 @@ base_model = "moonshotai/kimi-k2.6" +[interleaved] +field = "reasoning_content" + [[reasoning_options]] type = "toggle" @@ -8,9 +11,10 @@ type = "budget_tokens" min = 1 max = 262_144 -[interleaved] -field = "reasoning_content" - [cost] input = 0.95 output = 4 +cache_read = 0.16 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/moonshotai/kimi-k2.7-code-highspeed.toml b/providers/merge-gateway/models/moonshot/kimi-k2.7-code-highspeed.toml similarity index 73% rename from providers/merge-gateway/models/moonshotai/kimi-k2.7-code-highspeed.toml rename to providers/merge-gateway/models/moonshot/kimi-k2.7-code-highspeed.toml index fbc261f9eb..97b6f81d47 100644 --- a/providers/merge-gateway/models/moonshotai/kimi-k2.7-code-highspeed.toml +++ b/providers/merge-gateway/models/moonshot/kimi-k2.7-code-highspeed.toml @@ -1,5 +1,8 @@ base_model = "moonshotai/kimi-k2.7-code-highspeed" +[interleaved] +field = "reasoning_content" + [[reasoning_options]] type = "toggle" @@ -8,9 +11,13 @@ type = "budget_tokens" min = 1 max = 32_768 -[interleaved] -field = "reasoning_content" - [cost] input = 1.9 output = 8 +cache_read = 0.38 + +[limit] +output = 32_768 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/moonshotai/kimi-k2.7-code.toml b/providers/merge-gateway/models/moonshot/kimi-k2.7-code.toml similarity index 72% rename from providers/merge-gateway/models/moonshotai/kimi-k2.7-code.toml rename to providers/merge-gateway/models/moonshot/kimi-k2.7-code.toml index 9286e04bc6..d2d7dd319a 100644 --- a/providers/merge-gateway/models/moonshotai/kimi-k2.7-code.toml +++ b/providers/merge-gateway/models/moonshot/kimi-k2.7-code.toml @@ -1,5 +1,8 @@ base_model = "moonshotai/kimi-k2.7-code" +[interleaved] +field = "reasoning_content" + [[reasoning_options]] type = "toggle" @@ -8,9 +11,13 @@ type = "budget_tokens" min = 1 max = 32_768 -[interleaved] -field = "reasoning_content" - [cost] input = 0.95 output = 4 +cache_read = 0.19 + +[limit] +output = 32_768 + +[modalities] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/moonshotai/kimi-k2-thinking.toml b/providers/merge-gateway/models/moonshotai/kimi-k2-thinking.toml index dfc8f5290b..117e4fd856 100644 --- a/providers/merge-gateway/models/moonshotai/kimi-k2-thinking.toml +++ b/providers/merge-gateway/models/moonshotai/kimi-k2-thinking.toml @@ -1,4 +1,5 @@ base_model = "moonshotai/kimi-k2-thinking" +status = "deprecated" [[reasoning_options]] type = "toggle" diff --git a/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml b/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml index a24d7e0cfb..479e511a4b 100644 --- a/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml +++ b/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml @@ -1,8 +1,8 @@ base_model = "nvidia/nemotron-nano-9b-v2" name = "Nemotron Nano 9B" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.06 diff --git a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml index 4af6a73a45..eb539d9998 100644 --- a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml @@ -1,7 +1,7 @@ base_model = "openai/gpt-5-chat-latest" base_model_omit = ["limit.input"] name = "GPT-5 Chat Latest" -reasoning_options = [] +reasoning = false [cost] input = 1.25 diff --git a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml index d1916353a0..efc818ff44 100644 --- a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml @@ -1,6 +1,6 @@ base_model = "openai/gpt-5.1-chat-latest" name = "GPT-5.1 Chat Latest" -reasoning_options = [] +reasoning = false [cost] input = 1.25 diff --git a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml index c12b1689b0..818ab9e704 100644 --- a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml @@ -1,6 +1,6 @@ base_model = "openai/gpt-5.2-chat-latest" name = "GPT-5.2 Chat Latest" -reasoning_options = [] +reasoning = false [cost] input = 1.75 diff --git a/providers/merge-gateway/models/openai/gpt-oss-120b.toml b/providers/merge-gateway/models/openai/gpt-oss-120b.toml index 3eb069e5a6..5fd494cee9 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-120b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-120b.toml @@ -2,14 +2,10 @@ # available routes either report `supports_reasoning = false` or reasoning with # `configurable = false` and no controls, so callers have no reasoning control. base_model = "openai/gpt-oss-120b" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] -input = 0.1 -output = 0.5 - -[limit] -context = 128_000 -output = 32_000 +input = 0.09 +output = 0.36 diff --git a/providers/merge-gateway/models/openai/gpt-oss-20b.toml b/providers/merge-gateway/models/openai/gpt-oss-20b.toml index 758d8dc047..cd7d74a531 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-20b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-20b.toml @@ -2,12 +2,11 @@ # available routes either report `supports_reasoning = false` or reasoning with # `configurable = false` and no controls, so callers have no reasoning control. base_model = "openai/gpt-oss-20b" -reasoning_options = [] +reasoning = false +tool_call = false +structured_output = false [cost] -input = 0.07 -output = 0.3 - -[limit] -context = 128_000 -output = 128_000 +input = 0.04 +output = 0.2 +cache_read = 0.02 diff --git a/providers/merge-gateway/models/qwen/qwen-flash.toml b/providers/merge-gateway/models/qwen/qwen-flash.toml index 9d31fbbca2..299e89c391 100644 --- a/providers/merge-gateway/models/qwen/qwen-flash.toml +++ b/providers/merge-gateway/models/qwen/qwen-flash.toml @@ -1,11 +1,12 @@ base_model = "alibaba/qwen-flash" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.022 output = 0.216 +cache_read = 0.0044 [limit] output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen-plus.toml b/providers/merge-gateway/models/qwen/qwen-plus.toml index eb288e33a6..a3fb0776eb 100644 --- a/providers/merge-gateway/models/qwen/qwen-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen-plus.toml @@ -1,11 +1,12 @@ base_model = "alibaba/qwen-plus" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.115 output = 0.287 +cache_read = 0.023 [limit] output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml b/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml index 0b3cf01e0d..926127614d 100644 --- a/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml +++ b/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml @@ -1,12 +1,13 @@ base_model = "alibaba/qwen3-235b-a22b" name = "Qwen3 235B A22B" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.287 output = 1.147 +cache_read = 0.0574 [limit] output = 32_768 diff --git a/providers/merge-gateway/models/qwen/qwen3-32b.toml b/providers/merge-gateway/models/qwen/qwen3-32b.toml index 6799a8b98c..2033594162 100644 --- a/providers/merge-gateway/models/qwen/qwen3-32b.toml +++ b/providers/merge-gateway/models/qwen/qwen3-32b.toml @@ -1,11 +1,10 @@ base_model = "alibaba/qwen3-32b" -tool_call = false +reasoning = false structured_output = false -reasoning_options = [] [cost] -input = 0.287 -output = 0.64 +input = 0.15 +output = 0.6 [limit] output = 32_768 diff --git a/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml b/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml index 171d33583d..ba9dbb0ead 100644 --- a/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml +++ b/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml @@ -5,6 +5,7 @@ structured_output = false [cost] input = 0.144 output = 0.574 +cache_read = 0.0288 [limit] output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml b/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml index 1a22f4698c..8d12a803e8 100644 --- a/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml @@ -5,6 +5,7 @@ structured_output = false [cost] input = 0.574 output = 2.294 +cache_read = 0.1148 [limit] context = 1_000_000 diff --git a/providers/merge-gateway/models/qwen/qwen3-max.toml b/providers/merge-gateway/models/qwen/qwen3-max.toml index a91ec8afd2..22f3b42dc8 100644 --- a/providers/merge-gateway/models/qwen/qwen3-max.toml +++ b/providers/merge-gateway/models/qwen/qwen3-max.toml @@ -5,3 +5,4 @@ structured_output = false [cost] input = 0.359 output = 1.434 +cache_read = 0.0718 diff --git a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml index f936e5fb71..b2ad8e78bc 100644 --- a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml +++ b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml @@ -5,3 +5,4 @@ structured_output = false [cost] input = 0.144 output = 0.574 +cache_read = 0.0288 diff --git a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml index c5805b1218..fe00a88b44 100644 --- a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml +++ b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml @@ -1,8 +1,8 @@ base_model = "alibaba/qwen3-next-80b-a3b-thinking" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] -input = 0.144 -output = 1.434 +input = 0.15 +output = 1.2 diff --git a/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml b/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml index 62b7809fdb..0b7afd7e0f 100644 --- a/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml @@ -1,12 +1,13 @@ base_model = "alibaba/qwen3-vl-plus" attachment = true +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.143 output = 1.434 +cache_read = 0.0286 [limit] output = 65_536 diff --git a/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml index f6f7beb213..2a33d7879b 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml @@ -1,12 +1,13 @@ base_model = "alibaba/qwen3.5-122b-a10b" attachment = false +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.115 output = 0.917 +cache_read = 0.023 [limit] context = 131_072 diff --git a/providers/merge-gateway/models/qwen/qwen3.5-27b.toml b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml index 61838ba5d2..d6a2738a45 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-27b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml @@ -1,12 +1,13 @@ base_model = "alibaba/qwen3.5-27b" attachment = false +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.086 output = 0.688 +cache_read = 0.0172 [limit] context = 131_072 diff --git a/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml index 8a502a1b86..2095aa4c17 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml @@ -1,13 +1,14 @@ base_model = "alibaba/qwen3.5-35b-a3b" name = "Qwen3.5 35B A3B" attachment = false +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.057 output = 0.459 +cache_read = 0.020357 [limit] context = 131_072 diff --git a/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml index 9805d19df5..d7e0ddb495 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml @@ -1,13 +1,14 @@ base_model = "alibaba/qwen3.5-397b-a17b" name = "Qwen3.5 397B A17B" attachment = false +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.172 output = 1.032 +cache_read = 0.0344 [limit] context = 131_072 diff --git a/providers/merge-gateway/models/qwen/qwen3.5-9b.toml b/providers/merge-gateway/models/qwen/qwen3.5-9b.toml index 2b4e2a3935..a72691682d 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-9b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-9b.toml @@ -1,7 +1,7 @@ base_model = "alibaba/qwen3.5-9b" attachment = true +reasoning = false structured_output = false -reasoning_options = [] [cost] input = 0.09 diff --git a/providers/merge-gateway/models/qwen/qwen3.5-plus.toml b/providers/merge-gateway/models/qwen/qwen3.5-plus.toml index 8379f126f0..1bb324949b 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-plus.toml @@ -1,11 +1,12 @@ base_model = "alibaba/qwen3.5-plus" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.115 output = 0.688 +cache_read = 0.023 [limit] output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3.6-27b.toml b/providers/merge-gateway/models/qwen/qwen3.6-27b.toml index 9815022446..b8e90ba940 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-27b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-27b.toml @@ -1,7 +1,7 @@ base_model = "alibaba/qwen3.6-27b" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.4126 diff --git a/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml b/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml index 57394e6fad..c695e7ce73 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml @@ -1,13 +1,14 @@ base_model = "alibaba/qwen3.6-35b-a3b" name = "Qwen3.6 35B A3B" attachment = false +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.248 output = 1.485 +cache_read = 0.0496 [modalities] input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.6-flash.toml b/providers/merge-gateway/models/qwen/qwen3.6-flash.toml index b10df25cf3..e7edc55b2b 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-flash.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-flash.toml @@ -1,12 +1,13 @@ base_model = "alibaba/qwen3.6-flash" attachment = false +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.165 output = 0.99 +cache_read = 0.033 [limit] output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml b/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml index f2f9c11d1b..1a31538776 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml @@ -1,7 +1,7 @@ base_model = "alibaba/qwen3.6-max-preview" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 1.31 diff --git a/providers/merge-gateway/models/qwen/qwen3.6-plus.toml b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml index a45e5743cf..245c5d99d4 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml @@ -1,11 +1,12 @@ base_model = "alibaba/qwen3.6-plus" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.276 output = 1.651 +cache_read = 0.0552 [limit] output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3.7-max.toml b/providers/merge-gateway/models/qwen/qwen3.7-max.toml index b4ef76d4d8..3f3d85bc8a 100644 --- a/providers/merge-gateway/models/qwen/qwen3.7-max.toml +++ b/providers/merge-gateway/models/qwen/qwen3.7-max.toml @@ -1,11 +1,12 @@ base_model = "alibaba/qwen3.7-max" +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.825 output = 2.4755 +cache_read = 0.165 [limit] output = 250_000 diff --git a/providers/merge-gateway/models/qwen/qwen3.7-plus.toml b/providers/merge-gateway/models/qwen/qwen3.7-plus.toml index df3d175dc8..5ae04e9d74 100644 --- a/providers/merge-gateway/models/qwen/qwen3.7-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.7-plus.toml @@ -1,8 +1,8 @@ base_model = "alibaba/qwen3.7-plus" attachment = true +reasoning = false tool_call = false structured_output = false -reasoning_options = [] [cost] input = 0.4 diff --git a/providers/merge-gateway/models/sakana/fugu-ultra.toml b/providers/merge-gateway/models/sakana/fugu-ultra.toml new file mode 100644 index 0000000000..6738a5dfc1 --- /dev/null +++ b/providers/merge-gateway/models/sakana/fugu-ultra.toml @@ -0,0 +1,10 @@ +base_model = "sakana/fugu-ultra" +reasoning = false +structured_output = false + +[cost] +input = 5 +output = 30 + +[limit] +output = 250_000 diff --git a/providers/merge-gateway/models/writer/palmyra-x4.toml b/providers/merge-gateway/models/writer/palmyra-x4.toml new file mode 100644 index 0000000000..dba9900285 --- /dev/null +++ b/providers/merge-gateway/models/writer/palmyra-x4.toml @@ -0,0 +1,25 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=writer%2Fpalmyra-x4 + +name = "Palmyra X4" +description = "Enterprise language model for writing, analysis, and tool-assisted workflows" +family = "palmyra" +release_date = "2024-10-09" +last_updated = "2024-10-09" +attachment = false +reasoning = false +temperature = true +tool_call = true +structured_output = false +open_weights = false + +[cost] +input = 2.5 +output = 10 + +[limit] +context = 128_000 +output = 32_000 + +[modalities] +input = ["text"] +output = ["text"] diff --git a/providers/merge-gateway/models/writer/palmyra-x5.toml b/providers/merge-gateway/models/writer/palmyra-x5.toml new file mode 100644 index 0000000000..c7bdfefa40 --- /dev/null +++ b/providers/merge-gateway/models/writer/palmyra-x5.toml @@ -0,0 +1,25 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=writer%2Fpalmyra-x5 + +name = "Palmyra X5" +description = "Enterprise multimodal model for writing, analysis, and tool-assisted workflows" +family = "palmyra" +release_date = "2025-04-28" +last_updated = "2025-04-28" +attachment = true +reasoning = false +temperature = true +tool_call = true +structured_output = true +open_weights = false + +[cost] +input = 0.6 +output = 6 + +[limit] +context = 1_000_000 +output = 250_000 + +[modalities] +input = ["text", "image"] +output = ["text"] diff --git a/providers/merge-gateway/models/zai/glm-4.5v.toml b/providers/merge-gateway/models/zai/glm-4.5v.toml index 167cbe1dac..1d54a9953b 100644 --- a/providers/merge-gateway/models/zai/glm-4.5v.toml +++ b/providers/merge-gateway/models/zai/glm-4.5v.toml @@ -1,7 +1,7 @@ base_model = "zhipuai/glm-4.5v" name = "Glm 4.5V" +reasoning = false structured_output = false -reasoning_options = [] [cost] input = 0.6 diff --git a/providers/merge-gateway/models/zai/glm-4.7-flash.toml b/providers/merge-gateway/models/zai/glm-4.7-flash.toml index 85c174b267..cc8fb9703e 100644 --- a/providers/merge-gateway/models/zai/glm-4.7-flash.toml +++ b/providers/merge-gateway/models/zai/glm-4.7-flash.toml @@ -1,7 +1,7 @@ base_model = "zhipuai/glm-4.7-flash" name = "GLM 4.7 Flash" +reasoning = false structured_output = false -reasoning_options = [] [cost] input = 0.07 diff --git a/providers/merge-gateway/models/zai/glm-5.2.toml b/providers/merge-gateway/models/zai/glm-5.2.toml index 32140e8772..91542acaf2 100644 --- a/providers/merge-gateway/models/zai/glm-5.2.toml +++ b/providers/merge-gateway/models/zai/glm-5.2.toml @@ -1,17 +1,11 @@ base_model = "zhipuai/glm-5.2" +reasoning = false structured_output = false [interleaved] field = "reasoning_content" -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1 -max = 50_000 - [cost] input = 1.05 output = 3.3 +cache_read = 0.195 diff --git a/sync.md b/sync.md index ce8c22f5f5..1774f6892e 100644 --- a/sync.md +++ b/sync.md @@ -147,10 +147,12 @@ Merge Gateway is implemented in `packages/core/src/sync/providers/merge-gateway. - Source endpoint: `https://api-gateway.merge.dev/v1/models`. - Required auth: `MERGE_GATEWAY_API_KEY`. - The sync follows `next_cursor` until every page has been fetched. -- The canonical provider's available vendor route supplies pricing, limits, and capabilities; another available vendor is used only when the canonical route is unavailable. +- The canonical provider's available vendor route supplies pricing, limits, and capabilities. When it is unavailable, the sync matches Gateway's default resolver by selecting the active route with the lowest combined input and output price; the API's CMS-priority order breaks ties. - Canonical model IDs emit `base_model` references to model metadata when a matching `models/` entry exists. -- Existing cache pricing, tiered pricing, reasoning controls, and experimental modes are preserved because the API does not expose them. +- Existing cache pricing, tiered pricing, reasoning controls, and experimental modes are preserved because the public API does not currently expose the full CMS metadata. Cache prices curated from Gateway's route-level CMS remain stable across syncs until the public contract exposes them. - Route-level cache prices replace curated values field by field. A cache read or write price that the API does not expose remains preserved in the provider TOML, including when `prompt_caching` exposes only its mode. +- `prompt_caching.mode = "none"` explicitly removes preserved cache read and write prices because that route does not cache prompts. +- An explicit `supports_reasoning = false` on the selected vendor route overrides inherited reasoning metadata and removes preserved reasoning controls; supported routes retain curated controls when the API does not enumerate exact values. - Local models missing from the response are retained because API-key policy can affect catalog visibility. ## Cloudflare Workers AI Notes From 8ba08330ef5a1132cb9563f1d7272706f3498522 Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Thu, 16 Jul 2026 12:29:28 -0400 Subject: [PATCH 05/11] fix(merge-gateway): treat supports_reasoning as a positive-only signal The public /v1/models schema does not document supports_reasoning, and the live catalog populates it inconsistently across vendor routes: the same model reports true on one route and false on another (claude-opus-4-6 is false via anthropic, true via bedrock), and reasoning-only models such as deepseek-r1 report false on their sole route. Flipping reasoning = false from that field erased curated reasoning metadata on 42 models. - only confirm reasoning when an available route reports supports_reasoning = true (always accompanied by route reasoning metadata), defaulting reasoning_options to [] when none are curated - preserve curated reasoning metadata when routes report false or omit the field - restore the 42 erased reasoning entries (claude, deepseek-r1, gpt-oss, gemma, qwen, glm, nemotron, fugu) from curated values - re-sync against the live catalog: gemini-embedding-001 added, route cache_read prices and display names ingested, qwen3.5-27b limits and modalities updated Co-Authored-By: Claude Fable 5 --- .../core/src/sync/providers/merge-gateway.ts | 28 +++++++++-- packages/core/test/sync.test.ts | 48 ++++++++++++++++++- .../models/anthropic/claude-fable-5.toml | 9 ++-- .../anthropic/claude-haiku-4-5-20251001.toml | 2 +- .../anthropic/claude-opus-4-1-20250805.toml | 2 +- .../anthropic/claude-opus-4-20250514.toml | 2 +- .../anthropic/claude-opus-4-5-20251101.toml | 2 +- .../models/anthropic/claude-opus-4-6.toml | 2 +- .../models/anthropic/claude-opus-4-7.toml | 2 +- .../models/anthropic/claude-opus-4-8.toml | 9 +++- .../anthropic/claude-sonnet-4-5-20250929.toml | 2 +- .../models/anthropic/claude-sonnet-4-6.toml | 2 +- .../models/deepseek/deepseek-r1.toml | 2 +- .../models/google/gemini-embedding-001.toml | 9 ++++ .../models/google/gemma-4-26b-a4b-it.toml | 2 +- .../models/google/gemma-4-31b-it.toml | 5 +- .../models/meta/llama-3.3-70b-instruct.toml | 1 + .../models/mistral/devstral-2512.toml | 1 + .../models/mistral/mistral-large-2512.toml | 1 + .../models/mistral/mistral-medium-2505.toml | 1 + .../models/nvidia/nemotron-nano-9b-v2.toml | 2 +- .../models/openai/gpt-5-chat-latest.toml | 2 +- .../models/openai/gpt-5.1-chat-latest.toml | 2 +- .../models/openai/gpt-5.2-chat-latest.toml | 2 +- .../models/openai/gpt-oss-120b.toml | 10 ++-- .../models/openai/gpt-oss-20b.toml | 9 ++-- .../merge-gateway/models/qwen/qwen-flash.toml | 2 +- .../merge-gateway/models/qwen/qwen-plus.toml | 2 +- .../models/qwen/qwen3-235b-a22b.toml | 2 +- .../merge-gateway/models/qwen/qwen3-32b.toml | 2 +- .../qwen/qwen3-next-80b-a3b-thinking.toml | 2 +- .../models/qwen/qwen3-vl-plus.toml | 2 +- .../models/qwen/qwen3.5-122b-a10b.toml | 2 +- .../models/qwen/qwen3.5-27b.toml | 9 ++-- .../models/qwen/qwen3.5-35b-a3b.toml | 2 +- .../models/qwen/qwen3.5-397b-a17b.toml | 2 +- .../merge-gateway/models/qwen/qwen3.5-9b.toml | 2 +- .../models/qwen/qwen3.5-plus.toml | 2 +- .../models/qwen/qwen3.6-27b.toml | 2 +- .../models/qwen/qwen3.6-35b-a3b.toml | 2 +- .../models/qwen/qwen3.6-flash.toml | 2 +- .../models/qwen/qwen3.6-max-preview.toml | 2 +- .../models/qwen/qwen3.6-plus.toml | 2 +- .../models/qwen/qwen3.7-max.toml | 2 +- .../models/qwen/qwen3.7-plus.toml | 2 +- .../models/sakana/fugu-ultra.toml | 2 +- .../merge-gateway/models/zai/glm-4.5v.toml | 2 +- .../models/zai/glm-4.7-flash.toml | 2 +- .../merge-gateway/models/zai/glm-5.1.toml | 1 + .../merge-gateway/models/zai/glm-5.2.toml | 9 +++- sync.md | 2 +- 51 files changed, 161 insertions(+), 61 deletions(-) create mode 100644 providers/merge-gateway/models/google/gemini-embedding-001.toml diff --git a/packages/core/src/sync/providers/merge-gateway.ts b/packages/core/src/sync/providers/merge-gateway.ts index 4df225a75c..351da620ab 100644 --- a/packages/core/src/sync/providers/merge-gateway.ts +++ b/packages/core/src/sync/providers/merge-gateway.ts @@ -8,6 +8,14 @@ const API_ENDPOINT = "https://api-gateway.merge.dev/v1/models"; const AvailabilityStatus = z.enum(["available", "deprecated"]); +const VendorReasoning = z.object({ + configurable: z.boolean().optional(), + disable_supported: z.boolean().optional(), + default_enabled: z.boolean().optional(), + controls: z.array(z.string()).optional(), + output_style: z.string().nullable().optional(), +}).passthrough(); + const VendorCapabilities = z.object({ input: z.array(z.enum(["text", "audio", "image", "document", "embedding"])), output: z.array(z.enum(["text", "audio", "tool_use", "embedding"])), @@ -15,6 +23,7 @@ const VendorCapabilities = z.object({ supports_tool_choice: z.boolean().default(false), supports_structured_outputs: z.boolean(), supports_reasoning: z.boolean().optional(), + reasoning: VendorReasoning.nullable().optional(), streaming: z.boolean(), }).passthrough(); @@ -194,9 +203,22 @@ export function buildMergeGatewayModel( ? "deprecated" as const : undefined; const baseModel = existing?.base_model ?? resolveCanonicalBaseModel(model.model); - const routeDisablesReasoning = selected.info.capabilities.supports_reasoning === false; - const reasoning = routeDisablesReasoning ? false : existing?.reasoning; - const reasoningOptions = routeDisablesReasoning ? undefined : existing?.reasoning_options; + // `supports_reasoning` is not part of the documented public schema + // (PublicVendorModelCapabilities) and is inconsistently populated across + // vendor routes: the same model can report `true` on one route and `false` + // on another (e.g. anthropic/claude-opus-4-6 reports `false` via `anthropic` + // and `true` via `bedrock`), and reasoning-only models such as + // deepseek/deepseek-r1 report `false` on their sole route. Treat it as a + // positive-only signal: `true` (always accompanied by route `reasoning` + // metadata) confirms the model reasons on the gateway, while `false`/absent + // means unknown and preserves curated reasoning metadata. + const routeConfirmsReasoning = Object.values(model.vendors).some( + (vendor) => vendor.availability_status === "available" && vendor.capabilities.supports_reasoning === true, + ); + const reasoning = routeConfirmsReasoning ? true : existing?.reasoning; + const reasoningOptions = reasoning === true + ? existing?.reasoning_options ?? [] + : existing?.reasoning_options; const authoritative = { // Some catalog rows use an upstream org/model ID as display_name. Let // canonical metadata provide the human-readable name for factored models. diff --git a/packages/core/test/sync.test.ts b/packages/core/test/sync.test.ts index a7f10ddfd5..983b7033a1 100644 --- a/packages/core/test/sync.test.ts +++ b/packages/core/test/sync.test.ts @@ -1141,7 +1141,10 @@ test("factors Merge Gateway GPT-5.6 Sol against canonical metadata", () => { }); }); -test("disables reasoning when the selected Merge Gateway route explicitly does not support it", () => { +test("preserves curated reasoning when Merge Gateway routes report supports_reasoning = false", () => { + // `supports_reasoning = false` is a positive-only signal: the field is + // undocumented in the public schema and inconsistently populated across + // vendor routes, so it must not erase curated reasoning metadata. const vendor = mergeGatewayVendor(); vendor.capabilities.supports_reasoning = false; const model = buildMergeGatewayModel(mergeGatewayModel({ @@ -1155,8 +1158,49 @@ test("disables reasoning when the selected Merge Gateway route explicitly does n expect(model).toMatchObject({ base_model: "openai/gpt-5.6-sol", - reasoning: false, + reasoning_options: [{ type: "effort", values: ["low", "medium", "high"] }], + }); + expect(model).not.toMatchObject({ reasoning: false }); +}); + +test("confirms reasoning when any available Merge Gateway route reports supports_reasoning = true", () => { + const selected = mergeGatewayVendor(); + selected.capabilities.supports_reasoning = false; + const confirming = mergeGatewayVendor({ + pricing: { currency: "USD", input_per_million: 9, output_per_million: 45 }, + }); + confirming.capabilities.supports_reasoning = true; + confirming.capabilities.reasoning = { + configurable: false, + disable_supported: false, + default_enabled: true, + controls: [], + output_style: "reasoning_content", + }; + const model = buildMergeGatewayModel(mergeGatewayModel({ + vendors: { openai: selected, fireworks: confirming }, + }), { + base_model: "openai/gpt-5.6-sol", + cost: { input: 5, output: 30 }, + }); + + // The model reasons on the gateway with no verified caller control. + expect(model).toMatchObject({ reasoning_options: [] }); + expect(model).not.toMatchObject({ reasoning: false }); +}); + +test("ignores supports_reasoning = true on unavailable Merge Gateway routes", () => { + const selected = mergeGatewayVendor(); + selected.capabilities.supports_reasoning = false; + const deprecated = mergeGatewayVendor({ availability_status: "deprecated" }); + deprecated.capabilities.supports_reasoning = true; + const model = buildMergeGatewayModel(mergeGatewayModel({ + vendors: { openai: selected, legacy: deprecated }, + }), { + base_model: "openai/gpt-5.6-sol", + cost: { input: 5, output: 30 }, }); + expect(model).not.toHaveProperty("reasoning_options"); }); diff --git a/providers/merge-gateway/models/anthropic/claude-fable-5.toml b/providers/merge-gateway/models/anthropic/claude-fable-5.toml index eaa41a5da3..3f151ccd4f 100644 --- a/providers/merge-gateway/models/anthropic/claude-fable-5.toml +++ b/providers/merge-gateway/models/anthropic/claude-fable-5.toml @@ -1,8 +1,9 @@ -# Merge Gateway GET /v1/models?model=anthropic/claude-fable-5 (accessed 2026-07-14): -# the only available Anthropic route reports `supports_reasoning = false`, so this -# provider route does not expose the base model's reasoning capability. +# Merge Gateway GET /v1/models?model=anthropic/claude-fable-5 (accessed 2026-07-16): +# the route reports `supports_reasoning = false`, but that field is unreliable as a +# negative signal (the same Anthropic models report `true` via bedrock routes), so +# reasoning is inherited from base metadata with no verified gateway control. base_model = "anthropic/claude-fable-5" -reasoning = false +reasoning_options = [] structured_output = true [cost] diff --git a/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml b/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml index 4b543cb668..0ad5883668 100644 --- a/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml +++ b/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml @@ -1,6 +1,6 @@ base_model = "anthropic/claude-haiku-4-5-20251001" name = "Claude Haiku 4.5 (20251001)" -reasoning = false +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 63_999 }] structured_output = true [cost] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml index dd3ffc4088..5ca50777fa 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml @@ -1,6 +1,6 @@ base_model = "anthropic/claude-opus-4-1-20250805" name = "Claude Opus 4.1 (20250805)" -reasoning = false +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 31_999 }] structured_output = true [cost] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml index 91211fe012..75499ddbb7 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml @@ -1,6 +1,6 @@ base_model = "anthropic/claude-opus-4-20250514" name = "Claude Opus 4 (20250514)" -reasoning = false +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 31_999 }] structured_output = true [cost] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml index a68a8f006c..405625967c 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml @@ -1,6 +1,6 @@ base_model = "anthropic/claude-opus-4-5-20251101" name = "Claude Opus 4.5 (20251101)" -reasoning = false +reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high"] }, { type = "budget_tokens", min = 1_024, max = 63_999 }] structured_output = true [cost] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml index 81b36cbff0..0c7241d701 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml @@ -1,5 +1,5 @@ base_model = "anthropic/claude-opus-4-6" -reasoning = false +reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "max"] }, { type = "budget_tokens", min = 1_024, max = 127_999 }] structured_output = true [cost] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml index 2a438839af..ca384fbebc 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml @@ -1,5 +1,5 @@ base_model = "anthropic/claude-opus-4-7" -reasoning = false +reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] structured_output = true [cost] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml index 4ef7dcb879..7606299bdd 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml @@ -1,7 +1,14 @@ base_model = "anthropic/claude-opus-4-8" -reasoning = false structured_output = true +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1 +max = 128_000 + [cost] input = 5 output = 25 diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml index 0790c8ef4c..b42706b8cc 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml @@ -1,6 +1,6 @@ base_model = "anthropic/claude-sonnet-4-5-20250929" name = "Claude Sonnet 4.5 (20250929)" -reasoning = false +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 63_999 }] structured_output = true [cost] diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml index 0e668b3f41..1cda8a1fb2 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml @@ -1,5 +1,5 @@ base_model = "anthropic/claude-sonnet-4-6" -reasoning = false +reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "max"] }, { type = "budget_tokens", min = 1_024, max = 63_999 }] structured_output = true [cost] diff --git a/providers/merge-gateway/models/deepseek/deepseek-r1.toml b/providers/merge-gateway/models/deepseek/deepseek-r1.toml index 669e074a17..fcc7a06e64 100644 --- a/providers/merge-gateway/models/deepseek/deepseek-r1.toml +++ b/providers/merge-gateway/models/deepseek/deepseek-r1.toml @@ -1,6 +1,6 @@ base_model = "deepseek/deepseek-r1" name = "DeepSeek R1" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/google/gemini-embedding-001.toml b/providers/merge-gateway/models/google/gemini-embedding-001.toml new file mode 100644 index 0000000000..9143c6026a --- /dev/null +++ b/providers/merge-gateway/models/google/gemini-embedding-001.toml @@ -0,0 +1,9 @@ +base_model = "google/gemini-embedding-001" +structured_output = false + +[cost] +input = 0.15 +output = 0 + +[limit] +output = 4_096 diff --git a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml index 0814497dc9..98984ddf7f 100644 --- a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml @@ -1,6 +1,6 @@ base_model = "google/gemma-4-26b-a4b-it" attachment = false -reasoning = false +reasoning_options = [{ type = "toggle" }] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/google/gemma-4-31b-it.toml b/providers/merge-gateway/models/google/gemma-4-31b-it.toml index 1595362736..fdb22686fc 100644 --- a/providers/merge-gateway/models/google/gemma-4-31b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-31b-it.toml @@ -1,9 +1,12 @@ base_model = "google/gemma-4-31b-it" +name = "Gemma 4 31B It" attachment = false -reasoning = false tool_call = false structured_output = false +[[reasoning_options]] +type = "toggle" + [cost] input = 0.14 output = 0.4 diff --git a/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml index c4416d75b9..e1dd035b20 100644 --- a/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml +++ b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml @@ -5,6 +5,7 @@ structured_output = false [cost] input = 0.22 output = 0.5 +cache_read = 0.11 [limit] context = 131_072 diff --git a/providers/merge-gateway/models/mistral/devstral-2512.toml b/providers/merge-gateway/models/mistral/devstral-2512.toml index 5be5751c96..c12dcc53a4 100644 --- a/providers/merge-gateway/models/mistral/devstral-2512.toml +++ b/providers/merge-gateway/models/mistral/devstral-2512.toml @@ -4,6 +4,7 @@ structured_output = true [cost] input = 0.4 output = 2 +cache_read = 0.04 [limit] context = 256_000 diff --git a/providers/merge-gateway/models/mistral/mistral-large-2512.toml b/providers/merge-gateway/models/mistral/mistral-large-2512.toml index 98e5a5fac0..fc6478c1b3 100644 --- a/providers/merge-gateway/models/mistral/mistral-large-2512.toml +++ b/providers/merge-gateway/models/mistral/mistral-large-2512.toml @@ -4,6 +4,7 @@ structured_output = true [cost] input = 0.5 output = 1.5 +cache_read = 0.05 [limit] context = 256_000 diff --git a/providers/merge-gateway/models/mistral/mistral-medium-2505.toml b/providers/merge-gateway/models/mistral/mistral-medium-2505.toml index 6816500cc2..6eba6a508a 100644 --- a/providers/merge-gateway/models/mistral/mistral-medium-2505.toml +++ b/providers/merge-gateway/models/mistral/mistral-medium-2505.toml @@ -4,6 +4,7 @@ structured_output = true [cost] input = 0.4 output = 2 +cache_read = 0.04 [limit] context = 128_000 diff --git a/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml b/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml index 479e511a4b..ce542f1925 100644 --- a/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml +++ b/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml @@ -1,6 +1,6 @@ base_model = "nvidia/nemotron-nano-9b-v2" name = "Nemotron Nano 9B" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml index eb539d9998..4af6a73a45 100644 --- a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml @@ -1,7 +1,7 @@ base_model = "openai/gpt-5-chat-latest" base_model_omit = ["limit.input"] name = "GPT-5 Chat Latest" -reasoning = false +reasoning_options = [] [cost] input = 1.25 diff --git a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml index efc818ff44..d1916353a0 100644 --- a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml @@ -1,6 +1,6 @@ base_model = "openai/gpt-5.1-chat-latest" name = "GPT-5.1 Chat Latest" -reasoning = false +reasoning_options = [] [cost] input = 1.25 diff --git a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml index 818ab9e704..c12b1689b0 100644 --- a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml @@ -1,6 +1,6 @@ base_model = "openai/gpt-5.2-chat-latest" name = "GPT-5.2 Chat Latest" -reasoning = false +reasoning_options = [] [cost] input = 1.75 diff --git a/providers/merge-gateway/models/openai/gpt-oss-120b.toml b/providers/merge-gateway/models/openai/gpt-oss-120b.toml index 5fd494cee9..a72e2e54c7 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-120b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-120b.toml @@ -1,10 +1,12 @@ -# Merge Gateway GET /v1/models?model=openai/gpt-oss-120b (accessed 2026-07-14): -# available routes either report `supports_reasoning = false` or reasoning with -# `configurable = false` and no controls, so callers have no reasoning control. +# Merge Gateway GET /v1/models?model=openai/gpt-oss-120b (accessed 2026-07-16): +# parasail and fireworks routes report `supports_reasoning = true` with +# `configurable = false` and no controls, so the model reasons on the gateway +# but callers have no reasoning control. base_model = "openai/gpt-oss-120b" -reasoning = false +name = "GPT-OSS 120B" tool_call = false structured_output = false +reasoning_options = [] [cost] input = 0.09 diff --git a/providers/merge-gateway/models/openai/gpt-oss-20b.toml b/providers/merge-gateway/models/openai/gpt-oss-20b.toml index cd7d74a531..f686a8950d 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-20b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-20b.toml @@ -1,8 +1,9 @@ -# Merge Gateway GET /v1/models?model=openai/gpt-oss-20b (accessed 2026-07-14): -# available routes either report `supports_reasoning = false` or reasoning with -# `configurable = false` and no controls, so callers have no reasoning control. +# Merge Gateway GET /v1/models?model=openai/gpt-oss-20b (accessed 2026-07-16): +# routes reporting `supports_reasoning = true` carry `configurable = false` and +# no controls, so the model reasons on the gateway but callers have no +# reasoning control. base_model = "openai/gpt-oss-20b" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen-flash.toml b/providers/merge-gateway/models/qwen/qwen-flash.toml index 299e89c391..542a748108 100644 --- a/providers/merge-gateway/models/qwen/qwen-flash.toml +++ b/providers/merge-gateway/models/qwen/qwen-flash.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen-flash" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen-plus.toml b/providers/merge-gateway/models/qwen/qwen-plus.toml index a3fb0776eb..117afdb8d5 100644 --- a/providers/merge-gateway/models/qwen/qwen-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen-plus.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen-plus" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml b/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml index 926127614d..3e749483e5 100644 --- a/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml +++ b/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml @@ -1,6 +1,6 @@ base_model = "alibaba/qwen3-235b-a22b" name = "Qwen3 235B A22B" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3-32b.toml b/providers/merge-gateway/models/qwen/qwen3-32b.toml index 2033594162..b62d81894a 100644 --- a/providers/merge-gateway/models/qwen/qwen3-32b.toml +++ b/providers/merge-gateway/models/qwen/qwen3-32b.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen3-32b" -reasoning = false +reasoning_options = [] structured_output = false [cost] diff --git a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml index fe00a88b44..339058e004 100644 --- a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml +++ b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen3-next-80b-a3b-thinking" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml b/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml index 0b7afd7e0f..51cbeafc6b 100644 --- a/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml @@ -1,6 +1,6 @@ base_model = "alibaba/qwen3-vl-plus" attachment = true -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml index 2a33d7879b..9336618f96 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml @@ -1,6 +1,6 @@ base_model = "alibaba/qwen3.5-122b-a10b" attachment = false -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.5-27b.toml b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml index d6a2738a45..4d9727883b 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-27b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml @@ -1,8 +1,7 @@ base_model = "alibaba/qwen3.5-27b" -attachment = false -reasoning = false tool_call = false structured_output = false +reasoning_options = [] [cost] input = 0.086 @@ -10,8 +9,8 @@ output = 0.688 cache_read = 0.0172 [limit] -context = 131_072 -output = 32_768 +context = 256_000 +output = 64_000 [modalities] -input = ["text"] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml index 2095aa4c17..70fc5a9ce3 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml @@ -1,7 +1,7 @@ base_model = "alibaba/qwen3.5-35b-a3b" name = "Qwen3.5 35B A3B" attachment = false -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml index d7e0ddb495..8ba2057ef1 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml @@ -1,7 +1,7 @@ base_model = "alibaba/qwen3.5-397b-a17b" name = "Qwen3.5 397B A17B" attachment = false -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.5-9b.toml b/providers/merge-gateway/models/qwen/qwen3.5-9b.toml index a72691682d..5d99815e5e 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-9b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-9b.toml @@ -1,6 +1,6 @@ base_model = "alibaba/qwen3.5-9b" attachment = true -reasoning = false +reasoning_options = [] structured_output = false [cost] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-plus.toml b/providers/merge-gateway/models/qwen/qwen3.5-plus.toml index 1bb324949b..b3bb41fbb0 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-plus.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen3.5-plus" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.6-27b.toml b/providers/merge-gateway/models/qwen/qwen3.6-27b.toml index b8e90ba940..485bf8b972 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-27b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-27b.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen3.6-27b" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml b/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml index c695e7ce73..dd83266392 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml @@ -1,7 +1,7 @@ base_model = "alibaba/qwen3.6-35b-a3b" name = "Qwen3.6 35B A3B" attachment = false -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.6-flash.toml b/providers/merge-gateway/models/qwen/qwen3.6-flash.toml index e7edc55b2b..1a762bb2a0 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-flash.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-flash.toml @@ -1,6 +1,6 @@ base_model = "alibaba/qwen3.6-flash" attachment = false -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml b/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml index 1a31538776..4b6d61e0b2 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen3.6-max-preview" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.6-plus.toml b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml index 245c5d99d4..8e9b5b9686 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen3.6-plus" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.7-max.toml b/providers/merge-gateway/models/qwen/qwen3.7-max.toml index 3f3d85bc8a..7b615bb049 100644 --- a/providers/merge-gateway/models/qwen/qwen3.7-max.toml +++ b/providers/merge-gateway/models/qwen/qwen3.7-max.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen3.7-max" -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.7-plus.toml b/providers/merge-gateway/models/qwen/qwen3.7-plus.toml index 5ae04e9d74..c8aa4db85e 100644 --- a/providers/merge-gateway/models/qwen/qwen3.7-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.7-plus.toml @@ -1,6 +1,6 @@ base_model = "alibaba/qwen3.7-plus" attachment = true -reasoning = false +reasoning_options = [] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/sakana/fugu-ultra.toml b/providers/merge-gateway/models/sakana/fugu-ultra.toml index 6738a5dfc1..73a57b717a 100644 --- a/providers/merge-gateway/models/sakana/fugu-ultra.toml +++ b/providers/merge-gateway/models/sakana/fugu-ultra.toml @@ -1,5 +1,5 @@ base_model = "sakana/fugu-ultra" -reasoning = false +reasoning_options = [] structured_output = false [cost] diff --git a/providers/merge-gateway/models/zai/glm-4.5v.toml b/providers/merge-gateway/models/zai/glm-4.5v.toml index 1d54a9953b..20e2597200 100644 --- a/providers/merge-gateway/models/zai/glm-4.5v.toml +++ b/providers/merge-gateway/models/zai/glm-4.5v.toml @@ -1,6 +1,6 @@ base_model = "zhipuai/glm-4.5v" name = "Glm 4.5V" -reasoning = false +reasoning_options = [] structured_output = false [cost] diff --git a/providers/merge-gateway/models/zai/glm-4.7-flash.toml b/providers/merge-gateway/models/zai/glm-4.7-flash.toml index cc8fb9703e..288f833d80 100644 --- a/providers/merge-gateway/models/zai/glm-4.7-flash.toml +++ b/providers/merge-gateway/models/zai/glm-4.7-flash.toml @@ -1,6 +1,6 @@ base_model = "zhipuai/glm-4.7-flash" name = "GLM 4.7 Flash" -reasoning = false +reasoning_options = [] structured_output = false [cost] diff --git a/providers/merge-gateway/models/zai/glm-5.1.toml b/providers/merge-gateway/models/zai/glm-5.1.toml index 324ad86f62..faa77406f6 100644 --- a/providers/merge-gateway/models/zai/glm-5.1.toml +++ b/providers/merge-gateway/models/zai/glm-5.1.toml @@ -1,4 +1,5 @@ base_model = "zhipuai/glm-5.1" +name = "GLM 5.1" structured_output = false [interleaved] diff --git a/providers/merge-gateway/models/zai/glm-5.2.toml b/providers/merge-gateway/models/zai/glm-5.2.toml index 91542acaf2..09b021b757 100644 --- a/providers/merge-gateway/models/zai/glm-5.2.toml +++ b/providers/merge-gateway/models/zai/glm-5.2.toml @@ -1,7 +1,14 @@ base_model = "zhipuai/glm-5.2" -reasoning = false structured_output = false +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1 +max = 50_000 + [interleaved] field = "reasoning_content" diff --git a/sync.md b/sync.md index 1774f6892e..136a57333e 100644 --- a/sync.md +++ b/sync.md @@ -152,7 +152,7 @@ Merge Gateway is implemented in `packages/core/src/sync/providers/merge-gateway. - Existing cache pricing, tiered pricing, reasoning controls, and experimental modes are preserved because the public API does not currently expose the full CMS metadata. Cache prices curated from Gateway's route-level CMS remain stable across syncs until the public contract exposes them. - Route-level cache prices replace curated values field by field. A cache read or write price that the API does not expose remains preserved in the provider TOML, including when `prompt_caching` exposes only its mode. - `prompt_caching.mode = "none"` explicitly removes preserved cache read and write prices because that route does not cache prompts. -- An explicit `supports_reasoning = false` on the selected vendor route overrides inherited reasoning metadata and removes preserved reasoning controls; supported routes retain curated controls when the API does not enumerate exact values. +- `supports_reasoning` is a positive-only signal. It is absent from the documented public schema and inconsistently populated across vendor routes (the same model can report `true` on one route and `false` on another, and reasoning-only models can report `false` on their sole route). Any available route reporting `true` confirms `reasoning = true`, defaulting `reasoning_options` to `[]` when none are curated; `false` or absent is treated as unknown and preserves curated reasoning metadata. - Local models missing from the response are retained because API-key policy can affect catalog visibility. ## Cloudflare Workers AI Notes From d995b6d2e347565241efae4887a91f0bb36aac10 Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Tue, 21 Jul 2026 11:35:27 -0400 Subject: [PATCH 06/11] chore(merge-gateway): refresh model catalog --- .../models/bytedance/dola-seed-2.0-lite.toml | 1 - .../models/bytedance/dola-seed-2.0-mini.toml | 1 - .../models/bytedance/dola-seed-2.0-pro.toml | 4 ++-- .../models/deepseek/deepseek-v4-flash.toml | 2 +- .../models/deepseek/deepseek-v4-pro.toml | 2 +- .../models/google/gemma-4-26b-a4b-it.toml | 5 ++++- .../merge-gateway/models/google/gemma-4-31b-it.toml | 1 - .../models/meta/llama-3.3-70b-instruct.toml | 1 + .../merge-gateway/models/openai/gpt-oss-20b.toml | 3 ++- .../models/openai/gpt-oss-safeguard-120b.toml | 13 +++++++++++++ .../models/qwen/qwen3-next-80b-a3b-instruct.toml | 1 + .../models/qwen/qwen3.5-122b-a10b.toml | 9 ++++----- .../merge-gateway/models/qwen/qwen3.5-27b.toml | 7 ++++--- .../merge-gateway/models/qwen/qwen3.5-35b-a3b.toml | 2 +- .../models/qwen/qwen3.5-397b-a17b.toml | 2 +- .../merge-gateway/models/qwen/qwen3.6-plus.toml | 2 +- providers/merge-gateway/models/xai/grok-4.3.toml | 2 +- providers/merge-gateway/models/zai/glm-5.2.toml | 7 ++++--- 18 files changed, 41 insertions(+), 24 deletions(-) create mode 100644 providers/merge-gateway/models/openai/gpt-oss-safeguard-120b.toml diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml index 9c2e1aa96b..a285e329cc 100644 --- a/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml @@ -1,5 +1,4 @@ # Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-lite - name = "Seed 2.0 Lite" description = "Efficient Seed model for general chat, analysis, and lightweight production tasks" family = "seed" diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml index b5cea45ca4..cffc435ec6 100644 --- a/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml @@ -1,5 +1,4 @@ # Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-mini - name = "Seed 2.0 Mini" description = "Low-cost Seed model for general chat, extraction, and lightweight production tasks" family = "seed" diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml index b990a9d442..6a6079d726 100644 --- a/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml @@ -1,16 +1,16 @@ # Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-pro - name = "Seed 2.0 Pro" description = "Higher-capability Seed model for complex chat, analysis, and production tasks" family = "seed" release_date = "2026-03-28" last_updated = "2026-03-28" attachment = false -reasoning = false +reasoning = true temperature = true tool_call = false structured_output = false open_weights = false +reasoning_options = [] [cost] input = 0.5 diff --git a/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml b/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml index 12be6ee001..b631e4117f 100644 --- a/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml +++ b/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml @@ -1,6 +1,6 @@ base_model = "deepseek/deepseek-v4-flash" structured_output = false -reasoning_options = [] +reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true [interleaved] field = "reasoning_content" diff --git a/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml b/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml index cd7f2ca5bd..3b8e592233 100644 --- a/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml +++ b/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml @@ -1,6 +1,6 @@ base_model = "deepseek/deepseek-v4-pro" structured_output = false -reasoning_options = [] +reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true [interleaved] field = "reasoning_content" diff --git a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml index 98984ddf7f..190e815d68 100644 --- a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml @@ -1,9 +1,12 @@ base_model = "google/gemma-4-26b-a4b-it" +name = "Gemma 4 26B-A4B" attachment = false -reasoning_options = [{ type = "toggle" }] tool_call = false structured_output = false +[[reasoning_options]] +type = "toggle" + [cost] input = 0.13 output = 0.4 diff --git a/providers/merge-gateway/models/google/gemma-4-31b-it.toml b/providers/merge-gateway/models/google/gemma-4-31b-it.toml index fdb22686fc..fda08e4f1e 100644 --- a/providers/merge-gateway/models/google/gemma-4-31b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-31b-it.toml @@ -1,5 +1,4 @@ base_model = "google/gemma-4-31b-it" -name = "Gemma 4 31B It" attachment = false tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml index e1dd035b20..22ff109cd3 100644 --- a/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml +++ b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml @@ -1,4 +1,5 @@ base_model = "meta/llama-3.3-70b-instruct" +name = "Llama 3.3 70B Instruct" attachment = false structured_output = false diff --git a/providers/merge-gateway/models/openai/gpt-oss-20b.toml b/providers/merge-gateway/models/openai/gpt-oss-20b.toml index f686a8950d..714e07034b 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-20b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-20b.toml @@ -3,9 +3,10 @@ # no controls, so the model reasons on the gateway but callers have no # reasoning control. base_model = "openai/gpt-oss-20b" -reasoning_options = [] +name = "GPT-OSS 20B" tool_call = false structured_output = false +reasoning_options = [] [cost] input = 0.04 diff --git a/providers/merge-gateway/models/openai/gpt-oss-safeguard-120b.toml b/providers/merge-gateway/models/openai/gpt-oss-safeguard-120b.toml new file mode 100644 index 0000000000..052bb87785 --- /dev/null +++ b/providers/merge-gateway/models/openai/gpt-oss-safeguard-120b.toml @@ -0,0 +1,13 @@ +base_model = "openai/gpt-oss-safeguard-120b" +name = "gpt-oss-safeguard-120b" +tool_call = false +structured_output = false +reasoning_options = [] + +[cost] +input = 0.15 +output = 0.6 + +[limit] +context = 4_096 +output = 4_096 diff --git a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml index b2ad8e78bc..082dbd8195 100644 --- a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml +++ b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml @@ -1,4 +1,5 @@ base_model = "alibaba/qwen3-next-80b-a3b-instruct" +name = "Qwen3 Next 80B A3B Instruct" tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml index 9336618f96..90e3316750 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml @@ -1,8 +1,7 @@ base_model = "alibaba/qwen3.5-122b-a10b" -attachment = false -reasoning_options = [] tool_call = false structured_output = false +reasoning_options = [] [cost] input = 0.115 @@ -10,8 +9,8 @@ output = 0.917 cache_read = 0.023 [limit] -context = 131_072 -output = 32_768 +context = 256_000 +output = 64_000 [modalities] -input = ["text"] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-27b.toml b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml index 4d9727883b..579c66dd59 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-27b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml @@ -1,4 +1,5 @@ base_model = "alibaba/qwen3.5-27b" +attachment = false tool_call = false structured_output = false reasoning_options = [] @@ -9,8 +10,8 @@ output = 0.688 cache_read = 0.0172 [limit] -context = 256_000 -output = 64_000 +context = 131_072 +output = 32_768 [modalities] -input = ["text", "image"] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml index 70fc5a9ce3..e30ccc863e 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml @@ -1,7 +1,7 @@ base_model = "alibaba/qwen3.5-35b-a3b" name = "Qwen3.5 35B A3B" attachment = false -reasoning_options = [] +reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml index 8ba2057ef1..9fb2498fb8 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml @@ -1,7 +1,7 @@ base_model = "alibaba/qwen3.5-397b-a17b" name = "Qwen3.5 397B A17B" attachment = false -reasoning_options = [] +reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.6-plus.toml b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml index 8e9b5b9686..0657797d0f 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml @@ -1,5 +1,5 @@ base_model = "alibaba/qwen3.6-plus" -reasoning_options = [] +reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/xai/grok-4.3.toml b/providers/merge-gateway/models/xai/grok-4.3.toml index cc89c88330..3dc91bbe77 100644 --- a/providers/merge-gateway/models/xai/grok-4.3.toml +++ b/providers/merge-gateway/models/xai/grok-4.3.toml @@ -1,5 +1,5 @@ base_model = "xai/grok-4.3" -reasoning_options = [] +reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["reasoning.effort"], disable_supported = true; effort values not exposed [cost] input = 1.25 diff --git a/providers/merge-gateway/models/zai/glm-5.2.toml b/providers/merge-gateway/models/zai/glm-5.2.toml index 09b021b757..ec9a3ad07b 100644 --- a/providers/merge-gateway/models/zai/glm-5.2.toml +++ b/providers/merge-gateway/models/zai/glm-5.2.toml @@ -1,6 +1,10 @@ base_model = "zhipuai/glm-5.2" +name = "GLM 5.2" structured_output = false +[interleaved] +field = "reasoning_content" + [[reasoning_options]] type = "toggle" @@ -9,9 +13,6 @@ type = "budget_tokens" min = 1 max = 50_000 -[interleaved] -field = "reasoning_content" - [cost] input = 1.05 output = 3.3 From f69af8639b4356a4f14a859f1fd2d52b53b20876 Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Tue, 21 Jul 2026 12:54:00 -0400 Subject: [PATCH 07/11] fix(merge-gateway): align synced model metadata --- .../core/src/sync/providers/merge-gateway.ts | 33 +++++++++-- packages/core/test/sync.test.ts | 56 +++++++++++++++++++ .../anthropic/claude-3-7-sonnet-20250219.toml | 2 + .../models/anthropic/claude-fable-5.toml | 12 ++-- .../anthropic/claude-haiku-4-5-20251001.toml | 2 + .../anthropic/claude-opus-4-1-20250805.toml | 2 + .../anthropic/claude-opus-4-20250514.toml | 2 + .../anthropic/claude-opus-4-5-20251101.toml | 2 + .../models/anthropic/claude-opus-4-6.toml | 2 + .../models/anthropic/claude-opus-4-7.toml | 2 + .../models/anthropic/claude-opus-4-8.toml | 2 + .../anthropic/claude-sonnet-4-5-20250929.toml | 2 + .../models/anthropic/claude-sonnet-4-6.toml | 2 + .../models/anthropic/claude-sonnet-5.toml | 2 + .../bytedance/dola-seed-2.0-code-preview.toml | 2 +- .../models/bytedance/dola-seed-2.0-code.toml | 2 +- .../models/bytedance/dola-seed-2.0-lite.toml | 3 +- .../models/bytedance/dola-seed-2.0-mini.toml | 3 +- .../models/bytedance/dola-seed-2.0-pro.toml | 3 +- .../models/cohere/command-a-03-2025.toml | 2 + .../models/cohere/command-r-08-2024.toml | 2 + .../models/cohere/command-r-plus-08-2024.toml | 2 + .../models/cohere/command-r7b-12-2024.toml | 2 + .../models/deepseek/deepseek-r1.toml | 2 + .../models/deepseek/deepseek-v4-flash.toml | 5 +- .../models/deepseek/deepseek-v4-pro.toml | 5 +- .../models/google/gemini-2.5-flash-lite.toml | 2 + .../models/google/gemini-2.5-flash.toml | 2 + .../models/google/gemini-2.5-pro.toml | 2 + .../models/google/gemini-3-flash-preview.toml | 2 + .../models/google/gemini-3.1-flash-lite.toml | 2 + .../gemini-3.1-pro-preview-customtools.toml | 2 + .../models/google/gemini-3.1-pro-preview.toml | 2 + .../models/google/gemini-3.5-flash.toml | 2 + .../models/google/gemini-embedding-001.toml | 2 + .../models/google/gemma-4-26b-a4b-it.toml | 2 + .../models/google/gemma-4-31b-it.toml | 2 + .../models/meta/llama-3.3-70b-instruct.toml | 2 + .../models/meta/muse-spark-1.1.toml | 2 + .../models/minimax/minimax-m2.1.toml | 2 + .../minimax/minimax-m2.5-highspeed.toml | 2 + .../models/minimax/minimax-m2.5.toml | 2 + .../minimax/minimax-m2.7-highspeed.toml | 2 + .../models/minimax/minimax-m2.7.toml | 2 + .../models/minimax/minimax-m2.toml | 2 + .../models/minimax/minimax-m3.toml | 2 + .../models/mistral/devstral-2512.toml | 2 + .../models/mistral/mistral-large-2512.toml | 2 + .../models/mistral/mistral-medium-2505.toml | 2 + .../models/moonshot/kimi-k2.5.toml | 2 + .../models/moonshot/kimi-k2.6.toml | 2 + .../moonshot/kimi-k2.7-code-highspeed.toml | 2 + .../models/moonshot/kimi-k2.7-code.toml | 2 + .../models/nvidia/nemotron-nano-9b-v2.toml | 2 + .../models/openai/gpt-3.5-turbo.toml | 2 + .../models/openai/gpt-4-turbo.toml | 2 + .../models/openai/gpt-4.1-mini.toml | 2 + .../models/openai/gpt-4.1-nano.toml | 2 + .../merge-gateway/models/openai/gpt-4.1.toml | 2 + .../merge-gateway/models/openai/gpt-4.toml | 2 + .../models/openai/gpt-4o-2024-05-13.toml | 2 + .../models/openai/gpt-4o-2024-08-06.toml | 2 + .../models/openai/gpt-4o-2024-11-20.toml | 2 + .../models/openai/gpt-4o-mini.toml | 2 + .../merge-gateway/models/openai/gpt-4o.toml | 2 + .../models/openai/gpt-5-chat-latest.toml | 2 + .../models/openai/gpt-5-mini.toml | 2 + .../models/openai/gpt-5-nano.toml | 2 + .../models/openai/gpt-5.1-chat-latest.toml | 2 + .../merge-gateway/models/openai/gpt-5.1.toml | 2 + .../models/openai/gpt-5.2-chat-latest.toml | 2 + .../merge-gateway/models/openai/gpt-5.2.toml | 2 + .../models/openai/gpt-5.3-chat-latest.toml | 2 + .../models/openai/gpt-5.4-mini.toml | 2 + .../models/openai/gpt-5.4-nano.toml | 2 + .../merge-gateway/models/openai/gpt-5.4.toml | 2 + .../merge-gateway/models/openai/gpt-5.5.toml | 2 + .../models/openai/gpt-5.6-luna.toml | 2 + .../models/openai/gpt-5.6-sol.toml | 2 + .../models/openai/gpt-5.6-terra.toml | 2 + .../merge-gateway/models/openai/gpt-5.toml | 2 + .../models/openai/gpt-oss-120b.toml | 2 + .../models/openai/gpt-oss-20b.toml | 2 + .../models/openai/gpt-oss-safeguard-120b.toml | 3 +- providers/merge-gateway/models/openai/o1.toml | 2 + .../merge-gateway/models/openai/o3-mini.toml | 2 + providers/merge-gateway/models/openai/o3.toml | 2 + .../merge-gateway/models/openai/o4-mini.toml | 2 + .../merge-gateway/models/qwen/qwen-flash.toml | 6 +- .../merge-gateway/models/qwen/qwen-plus.toml | 6 +- .../models/qwen/qwen3-235b-a22b.toml | 6 +- .../merge-gateway/models/qwen/qwen3-32b.toml | 2 + .../qwen/qwen3-coder-480b-a35b-instruct.toml | 2 + .../models/qwen/qwen3-coder-flash.toml | 2 + .../models/qwen/qwen3-coder-plus.toml | 2 + .../merge-gateway/models/qwen/qwen3-max.toml | 2 + .../qwen/qwen3-next-80b-a3b-instruct.toml | 2 + .../qwen/qwen3-next-80b-a3b-thinking.toml | 2 + .../models/qwen/qwen3-vl-plus.toml | 2 + .../models/qwen/qwen3.5-122b-a10b.toml | 13 +++-- .../models/qwen/qwen3.5-27b.toml | 9 +-- .../models/qwen/qwen3.5-35b-a3b.toml | 5 +- .../models/qwen/qwen3.5-397b-a17b.toml | 5 +- .../merge-gateway/models/qwen/qwen3.5-9b.toml | 2 + .../models/qwen/qwen3.5-plus.toml | 6 +- .../models/qwen/qwen3.6-27b.toml | 2 + .../models/qwen/qwen3.6-35b-a3b.toml | 6 +- .../models/qwen/qwen3.6-flash.toml | 6 +- .../models/qwen/qwen3.6-max-preview.toml | 2 + .../models/qwen/qwen3.6-plus.toml | 5 +- .../models/qwen/qwen3.7-max.toml | 6 +- .../models/qwen/qwen3.7-plus.toml | 2 + .../models/sakana/fugu-ultra.toml | 2 + .../models/writer/palmyra-x4.toml | 2 +- .../models/writer/palmyra-x5.toml | 2 +- .../xai/grok-4.20-0309-non-reasoning.toml | 2 + .../models/xai/grok-4.20-0309-reasoning.toml | 2 + .../merge-gateway/models/xai/grok-4.3.toml | 5 +- .../merge-gateway/models/xai/grok-4.5.toml | 2 + .../models/xai/grok-build-0.1.toml | 2 + .../merge-gateway/models/zai/glm-4.5-air.toml | 2 + .../merge-gateway/models/zai/glm-4.5.toml | 2 + .../merge-gateway/models/zai/glm-4.5v.toml | 2 + .../merge-gateway/models/zai/glm-4.6.toml | 2 + .../models/zai/glm-4.7-flash.toml | 2 + .../models/zai/glm-4.7-flashx.toml | 2 + .../merge-gateway/models/zai/glm-4.7.toml | 2 + .../merge-gateway/models/zai/glm-5-turbo.toml | 2 + .../merge-gateway/models/zai/glm-5.1.toml | 2 + .../merge-gateway/models/zai/glm-5.2.toml | 2 + providers/merge-gateway/models/zai/glm-5.toml | 2 + providers/merge-gateway/provider.toml | 8 +-- sync.md | 4 +- 133 files changed, 391 insertions(+), 46 deletions(-) diff --git a/packages/core/src/sync/providers/merge-gateway.ts b/packages/core/src/sync/providers/merge-gateway.ts index 351da620ab..53d5693591 100644 --- a/packages/core/src/sync/providers/merge-gateway.ts +++ b/packages/core/src/sync/providers/merge-gateway.ts @@ -57,7 +57,16 @@ export const MergeGatewayModel = z.object({ availability_status: AvailabilityStatus, created_at: z.string().nullable().optional(), updated_at: z.string().nullable().optional(), -}).passthrough(); +}).passthrough().superRefine((model, context) => { + const namespace = model.model.split("/")[0]; + if (namespace !== model.provider) { + context.addIssue({ + code: z.ZodIssueCode.custom, + path: ["provider"], + message: `Model namespace ${namespace} does not match provider ${model.provider}`, + }); + } +}); export const MergeGatewayResponse = z.object({ object: z.literal("list").default("list"), @@ -92,7 +101,12 @@ export async function fetchMergeGatewayModels( } const page = MergeGatewayResponse.parse(await response.json()); - for (const model of page.data) models.set(model.model, model); + for (const model of page.data) { + if (models.has(model.model)) { + throw new Error(`Merge Gateway returned duplicate model ID: ${model.model}`); + } + models.set(model.model, model); + } if (!page.has_more) break; if (!page.next_cursor) throw new Error("Merge Gateway returned has_more=true without next_cursor"); if (cursors.has(page.next_cursor)) throw new Error(`Merge Gateway repeated cursor: ${page.next_cursor}`); @@ -216,13 +230,20 @@ export function buildMergeGatewayModel( (vendor) => vendor.availability_status === "available" && vendor.capabilities.supports_reasoning === true, ); const reasoning = routeConfirmsReasoning ? true : existing?.reasoning; - const reasoningOptions = reasoning === true - ? existing?.reasoning_options ?? [] - : existing?.reasoning_options; + const existingReasoningOptions = existing?.reasoning_options ?? []; + const reasoningOptions = reasoning === true && existingReasoningOptions.length === 0 + && selected.info.capabilities.reasoning?.disable_supported === true + ? [{ type: "toggle" as const }] + : reasoning === true + ? existingReasoningOptions + : existing?.reasoning_options; + const modelSlug = model.model.split("/").at(-1)?.toLowerCase(); + const displayNameIsID = model.display_name.includes("/") + || model.display_name.toLowerCase() === modelSlug; const authoritative = { // Some catalog rows use an upstream org/model ID as display_name. Let // canonical metadata provide the human-readable name for factored models. - name: baseModel !== undefined && model.display_name.includes("/") ? undefined : model.display_name, + name: baseModel !== undefined && displayNameIsID ? undefined : model.display_name, attachment: input.some((value) => value !== "text"), tool_call: selected.info.capabilities.supports_tool_calling, structured_output: selected.info.capabilities.supports_structured_outputs, diff --git a/packages/core/test/sync.test.ts b/packages/core/test/sync.test.ts index 983b7033a1..3ba250889e 100644 --- a/packages/core/test/sync.test.ts +++ b/packages/core/test/sync.test.ts @@ -1117,6 +1117,31 @@ test("fetches every page of the Merge Gateway catalog", async () => { expect(authorizations).toEqual(["Bearer test-key", "Bearer test-key"]); }); +test("rejects duplicate Merge Gateway model IDs across pages", async () => { + const fetcher = ((input: string | URL | Request) => { + const next = String(input).includes("cursor=next-page"); + return Promise.resolve(new Response(JSON.stringify({ + object: "list", + data: [mergeGatewayModel()], + has_more: !next, + next_cursor: next ? null : "next-page", + }))); + }) as typeof fetch; + + expect(fetchMergeGatewayModels(fetcher, "test-key")).rejects.toThrow( + "Merge Gateway returned duplicate model ID: openai/gpt-5.6-sol", + ); +}); + +test("rejects Merge Gateway provider and model namespace mismatches", () => { + expect(() => MergeGatewayResponse.parse({ + object: "list", + data: [mergeGatewayModel({ provider: "anthropic" })], + has_more: false, + next_cursor: null, + })).toThrow("Model namespace openai does not match provider anthropic"); +}); + test("accepts audio modalities from the Merge Gateway catalog", () => { const model = mergeGatewayModel(); model.vendors.openai.capabilities.input.push("audio"); @@ -1189,6 +1214,27 @@ test("confirms reasoning when any available Merge Gateway route reports supports expect(model).not.toMatchObject({ reasoning: false }); }); +test("derives a Merge Gateway reasoning toggle when the selected route supports disabling", () => { + const selected = mergeGatewayVendor(); + selected.capabilities.reasoning = { + configurable: true, + disable_supported: true, + default_enabled: true, + controls: ["thinking"], + output_style: "reasoning_content", + }; + const model = buildMergeGatewayModel(mergeGatewayModel({ + vendors: { openai: selected }, + }), { + base_model: "openai/gpt-5.6-sol", + reasoning: true, + reasoning_options: [], + cost: { input: 5, output: 30 }, + }); + + expect(model).toMatchObject({ reasoning_options: [{ type: "toggle" }] }); +}); + test("ignores supports_reasoning = true on unavailable Merge Gateway routes", () => { const selected = mergeGatewayVendor(); selected.capabilities.supports_reasoning = false; @@ -1300,6 +1346,16 @@ test("inherits canonical names for ID-shaped Merge Gateway display names", () => expect(model).not.toHaveProperty("name"); }); +test("inherits canonical names for slug-shaped Merge Gateway display names", () => { + const model = buildMergeGatewayModel(mergeGatewayModel({ + model: "openai/gpt-oss-safeguard-120b", + display_name: "gpt-oss-safeguard-120b", + vendors: { openai: mergeGatewayVendor() }, + }), undefined); + + expect(model).not.toHaveProperty("name"); +}); + test("omits inherited input limits above the Merge Gateway context", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ model: "openai/gpt-5-chat-latest", diff --git a/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml b/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml index 10113cd6f7..d269e4b778 100644 --- a/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml +++ b/providers/merge-gateway/models/anthropic/claude-3-7-sonnet-20250219.toml @@ -1,6 +1,8 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-3-7-sonnet-20250219 (accessed 2026-07-21) # Merge Gateway GET /v1/models?model=anthropic/claude-3-7-sonnet-20250219 # (accessed 2026-07-14): the Bedrock route advertises configurable # `thinking.budget_tokens` and disable support. + base_model = "anthropic/claude-3-7-sonnet-20250219" name = "Claude 3.7 Sonnet" structured_output = true diff --git a/providers/merge-gateway/models/anthropic/claude-fable-5.toml b/providers/merge-gateway/models/anthropic/claude-fable-5.toml index 3f151ccd4f..cd3581469f 100644 --- a/providers/merge-gateway/models/anthropic/claude-fable-5.toml +++ b/providers/merge-gateway/models/anthropic/claude-fable-5.toml @@ -1,11 +1,13 @@ -# Merge Gateway GET /v1/models?model=anthropic/claude-fable-5 (accessed 2026-07-16): -# the route reports `supports_reasoning = false`, but that field is unreliable as a -# negative signal (the same Anthropic models report `true` via bedrock routes), so -# reasoning is inherited from base metadata with no verified gateway control. +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-fable-5 (accessed 2026-07-21) +# The selected route advertises reasoning.effort and supports disabling reasoning; +# exact effort values are not exposed, so only the verified toggle is listed. + base_model = "anthropic/claude-fable-5" -reasoning_options = [] structured_output = true +[[reasoning_options]] +type = "toggle" + [cost] input = 10 output = 50 diff --git a/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml b/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml index 0ad5883668..b32556bbac 100644 --- a/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml +++ b/providers/merge-gateway/models/anthropic/claude-haiku-4-5-20251001.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-haiku-4-5-20251001 (accessed 2026-07-21) + base_model = "anthropic/claude-haiku-4-5-20251001" name = "Claude Haiku 4.5 (20251001)" reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 63_999 }] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml index 5ca50777fa..f39052626c 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-1-20250805.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-opus-4-1-20250805 (accessed 2026-07-21) + base_model = "anthropic/claude-opus-4-1-20250805" name = "Claude Opus 4.1 (20250805)" reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 31_999 }] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml index 75499ddbb7..88602aae50 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-20250514.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-opus-4-20250514 (accessed 2026-07-21) + base_model = "anthropic/claude-opus-4-20250514" name = "Claude Opus 4 (20250514)" reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 31_999 }] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml index 405625967c..c472a52abf 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-5-20251101.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-opus-4-5-20251101 (accessed 2026-07-21) + base_model = "anthropic/claude-opus-4-5-20251101" name = "Claude Opus 4.5 (20251101)" reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high"] }, { type = "budget_tokens", min = 1_024, max = 63_999 }] diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml index 0c7241d701..dad3022bc0 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-6.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-opus-4-6 (accessed 2026-07-21) + base_model = "anthropic/claude-opus-4-6" reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "max"] }, { type = "budget_tokens", min = 1_024, max = 127_999 }] structured_output = true diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml index ca384fbebc..ba582a88f0 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-7.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-opus-4-7 (accessed 2026-07-21) + base_model = "anthropic/claude-opus-4-7" reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] structured_output = true diff --git a/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml b/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml index 7606299bdd..d1fe70278e 100644 --- a/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml +++ b/providers/merge-gateway/models/anthropic/claude-opus-4-8.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-opus-4-8 (accessed 2026-07-21) + base_model = "anthropic/claude-opus-4-8" structured_output = true diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml index b42706b8cc..e53a7cc7e3 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-4-5-20250929.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-sonnet-4-5-20250929 (accessed 2026-07-21) + base_model = "anthropic/claude-sonnet-4-5-20250929" name = "Claude Sonnet 4.5 (20250929)" reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024, max = 63_999 }] diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml index 1cda8a1fb2..0275ca71de 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-4-6.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-sonnet-4-6 (accessed 2026-07-21) + base_model = "anthropic/claude-sonnet-4-6" reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "max"] }, { type = "budget_tokens", min = 1_024, max = 63_999 }] structured_output = true diff --git a/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml b/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml index 0ef763168d..4ba9d259a9 100644 --- a/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml +++ b/providers/merge-gateway/models/anthropic/claude-sonnet-5.toml @@ -1,5 +1,7 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=anthropic%2Fclaude-sonnet-5 (accessed 2026-07-21) # Merge Gateway GET /v1/models?model=anthropic/claude-sonnet-5 (accessed 2026-07-14): # the Anthropic route advertises configurable `reasoning.effort` and disable support. + base_model = "anthropic/claude-sonnet-5" structured_output = true reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-code-preview.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-code-preview.toml index abbba27194..bb197c39c4 100644 --- a/providers/merge-gateway/models/bytedance/dola-seed-2.0-code-preview.toml +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-code-preview.toml @@ -1,4 +1,4 @@ -# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-code-preview +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-code-preview (accessed 2026-07-21) name = "Dola Seed 2.0 Code (preview)" description = "Preview coding model for repository understanding, refactors, and engineering tasks" diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-code.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-code.toml index 24901bca8a..588e728cdf 100644 --- a/providers/merge-gateway/models/bytedance/dola-seed-2.0-code.toml +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-code.toml @@ -1,4 +1,4 @@ -# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-code +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-code (accessed 2026-07-21) name = "Seed 2.0 Code" description = "Coding model for repository understanding, refactors, and agentic engineering tasks" diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml index a285e329cc..0b944fd765 100644 --- a/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-lite.toml @@ -1,4 +1,5 @@ -# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-lite +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-lite (accessed 2026-07-21) + name = "Seed 2.0 Lite" description = "Efficient Seed model for general chat, analysis, and lightweight production tasks" family = "seed" diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml index cffc435ec6..618e139fb5 100644 --- a/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-mini.toml @@ -1,4 +1,5 @@ -# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-mini +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-mini (accessed 2026-07-21) + name = "Seed 2.0 Mini" description = "Low-cost Seed model for general chat, extraction, and lightweight production tasks" family = "seed" diff --git a/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml b/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml index 6a6079d726..3b0c45668b 100644 --- a/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml +++ b/providers/merge-gateway/models/bytedance/dola-seed-2.0-pro.toml @@ -1,4 +1,5 @@ -# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-pro +# Source: https://api-gateway.merge.dev/v1/models?model=bytedance%2Fdola-seed-2.0-pro (accessed 2026-07-21) + name = "Seed 2.0 Pro" description = "Higher-capability Seed model for complex chat, analysis, and production tasks" family = "seed" diff --git a/providers/merge-gateway/models/cohere/command-a-03-2025.toml b/providers/merge-gateway/models/cohere/command-a-03-2025.toml index 663193e136..2c08c9b924 100644 --- a/providers/merge-gateway/models/cohere/command-a-03-2025.toml +++ b/providers/merge-gateway/models/cohere/command-a-03-2025.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=cohere%2Fcommand-a-03-2025 (accessed 2026-07-21) + base_model = "cohere/command-a-03-2025" name = "Command A 03-2025" structured_output = true diff --git a/providers/merge-gateway/models/cohere/command-r-08-2024.toml b/providers/merge-gateway/models/cohere/command-r-08-2024.toml index 481c8c3467..e31619e4d2 100644 --- a/providers/merge-gateway/models/cohere/command-r-08-2024.toml +++ b/providers/merge-gateway/models/cohere/command-r-08-2024.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=cohere%2Fcommand-r-08-2024 (accessed 2026-07-21) + base_model = "cohere/command-r-08-2024" name = "Command R 08-2024" structured_output = true diff --git a/providers/merge-gateway/models/cohere/command-r-plus-08-2024.toml b/providers/merge-gateway/models/cohere/command-r-plus-08-2024.toml index edb51176f7..93b6fece2e 100644 --- a/providers/merge-gateway/models/cohere/command-r-plus-08-2024.toml +++ b/providers/merge-gateway/models/cohere/command-r-plus-08-2024.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=cohere%2Fcommand-r-plus-08-2024 (accessed 2026-07-21) + base_model = "cohere/command-r-plus-08-2024" name = "Command R+ 08-2024" structured_output = true diff --git a/providers/merge-gateway/models/cohere/command-r7b-12-2024.toml b/providers/merge-gateway/models/cohere/command-r7b-12-2024.toml index 7a77f4353c..9da61741b9 100644 --- a/providers/merge-gateway/models/cohere/command-r7b-12-2024.toml +++ b/providers/merge-gateway/models/cohere/command-r7b-12-2024.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=cohere%2Fcommand-r7b-12-2024 (accessed 2026-07-21) + base_model = "cohere/command-r7b-12-2024" name = "Command R7B 12-2024" structured_output = true diff --git a/providers/merge-gateway/models/deepseek/deepseek-r1.toml b/providers/merge-gateway/models/deepseek/deepseek-r1.toml index fcc7a06e64..14374d319e 100644 --- a/providers/merge-gateway/models/deepseek/deepseek-r1.toml +++ b/providers/merge-gateway/models/deepseek/deepseek-r1.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=deepseek%2Fdeepseek-r1 (accessed 2026-07-21) + base_model = "deepseek/deepseek-r1" name = "DeepSeek R1" reasoning_options = [] diff --git a/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml b/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml index b631e4117f..eb9a76c627 100644 --- a/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml +++ b/providers/merge-gateway/models/deepseek/deepseek-v4-flash.toml @@ -1,6 +1,9 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=deepseek%2Fdeepseek-v4-flash (accessed 2026-07-21) +# Selected route reasoning.controls = ["thinking"], disable_supported = true. + base_model = "deepseek/deepseek-v4-flash" structured_output = false -reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true +reasoning_options = [{ type = "toggle" }] [interleaved] field = "reasoning_content" diff --git a/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml b/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml index 3b8e592233..2761fd13bc 100644 --- a/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml +++ b/providers/merge-gateway/models/deepseek/deepseek-v4-pro.toml @@ -1,6 +1,9 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=deepseek%2Fdeepseek-v4-pro (accessed 2026-07-21) +# Selected route reasoning.controls = ["thinking"], disable_supported = true. + base_model = "deepseek/deepseek-v4-pro" structured_output = false -reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true +reasoning_options = [{ type = "toggle" }] [interleaved] field = "reasoning_content" diff --git a/providers/merge-gateway/models/google/gemini-2.5-flash-lite.toml b/providers/merge-gateway/models/google/gemini-2.5-flash-lite.toml index 3905bebf13..1479efe777 100644 --- a/providers/merge-gateway/models/google/gemini-2.5-flash-lite.toml +++ b/providers/merge-gateway/models/google/gemini-2.5-flash-lite.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemini-2.5-flash-lite (accessed 2026-07-21) + base_model = "google/gemini-2.5-flash-lite" [[reasoning_options]] diff --git a/providers/merge-gateway/models/google/gemini-2.5-flash.toml b/providers/merge-gateway/models/google/gemini-2.5-flash.toml index 7248eeda32..33cf0f6f73 100644 --- a/providers/merge-gateway/models/google/gemini-2.5-flash.toml +++ b/providers/merge-gateway/models/google/gemini-2.5-flash.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemini-2.5-flash (accessed 2026-07-21) + base_model = "google/gemini-2.5-flash" [[reasoning_options]] diff --git a/providers/merge-gateway/models/google/gemini-2.5-pro.toml b/providers/merge-gateway/models/google/gemini-2.5-pro.toml index 273ccacf39..4470063cd3 100644 --- a/providers/merge-gateway/models/google/gemini-2.5-pro.toml +++ b/providers/merge-gateway/models/google/gemini-2.5-pro.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemini-2.5-pro (accessed 2026-07-21) + base_model = "google/gemini-2.5-pro" [[reasoning_options]] diff --git a/providers/merge-gateway/models/google/gemini-3-flash-preview.toml b/providers/merge-gateway/models/google/gemini-3-flash-preview.toml index b8de1e8967..8ae1fb197c 100644 --- a/providers/merge-gateway/models/google/gemini-3-flash-preview.toml +++ b/providers/merge-gateway/models/google/gemini-3-flash-preview.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemini-3-flash-preview (accessed 2026-07-21) + base_model = "google/gemini-3-flash-preview" [[reasoning_options]] diff --git a/providers/merge-gateway/models/google/gemini-3.1-flash-lite.toml b/providers/merge-gateway/models/google/gemini-3.1-flash-lite.toml index 5c8f0f8a15..998ca69aab 100644 --- a/providers/merge-gateway/models/google/gemini-3.1-flash-lite.toml +++ b/providers/merge-gateway/models/google/gemini-3.1-flash-lite.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemini-3.1-flash-lite (accessed 2026-07-21) + base_model = "google/gemini-3.1-flash-lite" name = "Gemini 3.1 Flash-Lite" diff --git a/providers/merge-gateway/models/google/gemini-3.1-pro-preview-customtools.toml b/providers/merge-gateway/models/google/gemini-3.1-pro-preview-customtools.toml index a4183e8302..6ede2cae64 100644 --- a/providers/merge-gateway/models/google/gemini-3.1-pro-preview-customtools.toml +++ b/providers/merge-gateway/models/google/gemini-3.1-pro-preview-customtools.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemini-3.1-pro-preview-customtools (accessed 2026-07-21) + base_model = "google/gemini-3.1-pro-preview-customtools" [[reasoning_options]] diff --git a/providers/merge-gateway/models/google/gemini-3.1-pro-preview.toml b/providers/merge-gateway/models/google/gemini-3.1-pro-preview.toml index 7c4de40066..e0978e4542 100644 --- a/providers/merge-gateway/models/google/gemini-3.1-pro-preview.toml +++ b/providers/merge-gateway/models/google/gemini-3.1-pro-preview.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemini-3.1-pro-preview (accessed 2026-07-21) + base_model = "google/gemini-3.1-pro-preview" [[reasoning_options]] diff --git a/providers/merge-gateway/models/google/gemini-3.5-flash.toml b/providers/merge-gateway/models/google/gemini-3.5-flash.toml index ef2d78e676..1c16b6328b 100644 --- a/providers/merge-gateway/models/google/gemini-3.5-flash.toml +++ b/providers/merge-gateway/models/google/gemini-3.5-flash.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemini-3.5-flash (accessed 2026-07-21) + base_model = "google/gemini-3.5-flash" [[reasoning_options]] diff --git a/providers/merge-gateway/models/google/gemini-embedding-001.toml b/providers/merge-gateway/models/google/gemini-embedding-001.toml index 9143c6026a..01e3b2dce5 100644 --- a/providers/merge-gateway/models/google/gemini-embedding-001.toml +++ b/providers/merge-gateway/models/google/gemini-embedding-001.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemini-embedding-001 (accessed 2026-07-21) + base_model = "google/gemini-embedding-001" structured_output = false diff --git a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml index 190e815d68..1228ad522f 100644 --- a/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-26b-a4b-it.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemma-4-26b-a4b-it (accessed 2026-07-21) + base_model = "google/gemma-4-26b-a4b-it" name = "Gemma 4 26B-A4B" attachment = false diff --git a/providers/merge-gateway/models/google/gemma-4-31b-it.toml b/providers/merge-gateway/models/google/gemma-4-31b-it.toml index fda08e4f1e..68a09e360b 100644 --- a/providers/merge-gateway/models/google/gemma-4-31b-it.toml +++ b/providers/merge-gateway/models/google/gemma-4-31b-it.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=google%2Fgemma-4-31b-it (accessed 2026-07-21) + base_model = "google/gemma-4-31b-it" attachment = false tool_call = false diff --git a/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml index 22ff109cd3..424d70a90d 100644 --- a/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml +++ b/providers/merge-gateway/models/meta/llama-3.3-70b-instruct.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=meta%2Fllama-3.3-70b-instruct (accessed 2026-07-21) + base_model = "meta/llama-3.3-70b-instruct" name = "Llama 3.3 70B Instruct" attachment = false diff --git a/providers/merge-gateway/models/meta/muse-spark-1.1.toml b/providers/merge-gateway/models/meta/muse-spark-1.1.toml index d1ed3666ff..c47d211165 100644 --- a/providers/merge-gateway/models/meta/muse-spark-1.1.toml +++ b/providers/merge-gateway/models/meta/muse-spark-1.1.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=meta%2Fmuse-spark-1.1 (accessed 2026-07-21) + base_model = "meta/muse-spark-1.1" structured_output = false reasoning_options = [] diff --git a/providers/merge-gateway/models/minimax/minimax-m2.1.toml b/providers/merge-gateway/models/minimax/minimax-m2.1.toml index 0a6d4752dc..87d1dde34e 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.1.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.1.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=minimax%2Fminimax-m2.1 (accessed 2026-07-21) + base_model = "minimax/MiniMax-M2.1" name = "MiniMax M2.1" structured_output = false diff --git a/providers/merge-gateway/models/minimax/minimax-m2.5-highspeed.toml b/providers/merge-gateway/models/minimax/minimax-m2.5-highspeed.toml index f37846f4fd..7e4dc4ece1 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.5-highspeed.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.5-highspeed.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=minimax%2Fminimax-m2.5-highspeed (accessed 2026-07-21) + base_model = "minimax/MiniMax-M2.5-highspeed" name = "MiniMax M2.5 Highspeed" structured_output = false diff --git a/providers/merge-gateway/models/minimax/minimax-m2.5.toml b/providers/merge-gateway/models/minimax/minimax-m2.5.toml index f8b037d4b2..c2c6eccd75 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.5.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.5.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=minimax%2Fminimax-m2.5 (accessed 2026-07-21) + base_model = "minimax/MiniMax-M2.5" name = "MiniMax M2.5" structured_output = false diff --git a/providers/merge-gateway/models/minimax/minimax-m2.7-highspeed.toml b/providers/merge-gateway/models/minimax/minimax-m2.7-highspeed.toml index 4212380399..a8783c47c5 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.7-highspeed.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.7-highspeed.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=minimax%2Fminimax-m2.7-highspeed (accessed 2026-07-21) + base_model = "minimax/MiniMax-M2.7-highspeed" name = "MiniMax M2.7 Highspeed" structured_output = false diff --git a/providers/merge-gateway/models/minimax/minimax-m2.7.toml b/providers/merge-gateway/models/minimax/minimax-m2.7.toml index 287dd2e59c..296c2ddf4b 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.7.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.7.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=minimax%2Fminimax-m2.7 (accessed 2026-07-21) + base_model = "minimax/MiniMax-M2.7" name = "MiniMax M2.7" structured_output = false diff --git a/providers/merge-gateway/models/minimax/minimax-m2.toml b/providers/merge-gateway/models/minimax/minimax-m2.toml index b4aba3d972..e6f43e7c87 100644 --- a/providers/merge-gateway/models/minimax/minimax-m2.toml +++ b/providers/merge-gateway/models/minimax/minimax-m2.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=minimax%2Fminimax-m2 (accessed 2026-07-21) + base_model = "minimax/MiniMax-M2" structured_output = false reasoning_options = [] diff --git a/providers/merge-gateway/models/minimax/minimax-m3.toml b/providers/merge-gateway/models/minimax/minimax-m3.toml index db8f8f5f02..ba921d7245 100644 --- a/providers/merge-gateway/models/minimax/minimax-m3.toml +++ b/providers/merge-gateway/models/minimax/minimax-m3.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=minimax%2Fminimax-m3 (accessed 2026-07-21) + base_model = "minimax/MiniMax-M3" name = "MiniMax M3" structured_output = false diff --git a/providers/merge-gateway/models/mistral/devstral-2512.toml b/providers/merge-gateway/models/mistral/devstral-2512.toml index c12dcc53a4..faae35802b 100644 --- a/providers/merge-gateway/models/mistral/devstral-2512.toml +++ b/providers/merge-gateway/models/mistral/devstral-2512.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=mistral%2Fdevstral-2512 (accessed 2026-07-21) + base_model = "mistral/devstral-2512" structured_output = true diff --git a/providers/merge-gateway/models/mistral/mistral-large-2512.toml b/providers/merge-gateway/models/mistral/mistral-large-2512.toml index fc6478c1b3..d5f71ce5bc 100644 --- a/providers/merge-gateway/models/mistral/mistral-large-2512.toml +++ b/providers/merge-gateway/models/mistral/mistral-large-2512.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=mistral%2Fmistral-large-2512 (accessed 2026-07-21) + base_model = "mistral/mistral-large-2512" structured_output = true diff --git a/providers/merge-gateway/models/mistral/mistral-medium-2505.toml b/providers/merge-gateway/models/mistral/mistral-medium-2505.toml index 6eba6a508a..dfea4e4361 100644 --- a/providers/merge-gateway/models/mistral/mistral-medium-2505.toml +++ b/providers/merge-gateway/models/mistral/mistral-medium-2505.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=mistral%2Fmistral-medium-2505 (accessed 2026-07-21) + base_model = "mistral/mistral-medium-2505" structured_output = true diff --git a/providers/merge-gateway/models/moonshot/kimi-k2.5.toml b/providers/merge-gateway/models/moonshot/kimi-k2.5.toml index 41fabf109c..6a59ee6f7e 100644 --- a/providers/merge-gateway/models/moonshot/kimi-k2.5.toml +++ b/providers/merge-gateway/models/moonshot/kimi-k2.5.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=moonshot%2Fkimi-k2.5 (accessed 2026-07-21) + base_model = "moonshotai/kimi-k2.5" attachment = true diff --git a/providers/merge-gateway/models/moonshot/kimi-k2.6.toml b/providers/merge-gateway/models/moonshot/kimi-k2.6.toml index 2ce0ba3019..452440b668 100644 --- a/providers/merge-gateway/models/moonshot/kimi-k2.6.toml +++ b/providers/merge-gateway/models/moonshot/kimi-k2.6.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=moonshot%2Fkimi-k2.6 (accessed 2026-07-21) + base_model = "moonshotai/kimi-k2.6" [interleaved] diff --git a/providers/merge-gateway/models/moonshot/kimi-k2.7-code-highspeed.toml b/providers/merge-gateway/models/moonshot/kimi-k2.7-code-highspeed.toml index 97b6f81d47..f0129aa8dd 100644 --- a/providers/merge-gateway/models/moonshot/kimi-k2.7-code-highspeed.toml +++ b/providers/merge-gateway/models/moonshot/kimi-k2.7-code-highspeed.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=moonshot%2Fkimi-k2.7-code-highspeed (accessed 2026-07-21) + base_model = "moonshotai/kimi-k2.7-code-highspeed" [interleaved] diff --git a/providers/merge-gateway/models/moonshot/kimi-k2.7-code.toml b/providers/merge-gateway/models/moonshot/kimi-k2.7-code.toml index d2d7dd319a..7909c75370 100644 --- a/providers/merge-gateway/models/moonshot/kimi-k2.7-code.toml +++ b/providers/merge-gateway/models/moonshot/kimi-k2.7-code.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=moonshot%2Fkimi-k2.7-code (accessed 2026-07-21) + base_model = "moonshotai/kimi-k2.7-code" [interleaved] diff --git a/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml b/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml index ce542f1925..97a8008a68 100644 --- a/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml +++ b/providers/merge-gateway/models/nvidia/nemotron-nano-9b-v2.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=nvidia%2Fnemotron-nano-9b-v2 (accessed 2026-07-21) + base_model = "nvidia/nemotron-nano-9b-v2" name = "Nemotron Nano 9B" reasoning_options = [] diff --git a/providers/merge-gateway/models/openai/gpt-3.5-turbo.toml b/providers/merge-gateway/models/openai/gpt-3.5-turbo.toml index de8ddba9d0..cedb0d4038 100644 --- a/providers/merge-gateway/models/openai/gpt-3.5-turbo.toml +++ b/providers/merge-gateway/models/openai/gpt-3.5-turbo.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-3.5-turbo (accessed 2026-07-21) + base_model = "openai/gpt-3.5-turbo" name = "GPT-3.5 Turbo" diff --git a/providers/merge-gateway/models/openai/gpt-4-turbo.toml b/providers/merge-gateway/models/openai/gpt-4-turbo.toml index ac792634f8..73a5a02904 100644 --- a/providers/merge-gateway/models/openai/gpt-4-turbo.toml +++ b/providers/merge-gateway/models/openai/gpt-4-turbo.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4-turbo (accessed 2026-07-21) + base_model = "openai/gpt-4-turbo" [cost] diff --git a/providers/merge-gateway/models/openai/gpt-4.1-mini.toml b/providers/merge-gateway/models/openai/gpt-4.1-mini.toml index a6b4371ba1..8d95c3b13e 100644 --- a/providers/merge-gateway/models/openai/gpt-4.1-mini.toml +++ b/providers/merge-gateway/models/openai/gpt-4.1-mini.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4.1-mini (accessed 2026-07-21) + base_model = "openai/gpt-4.1-mini" name = "GPT-4.1 Mini" diff --git a/providers/merge-gateway/models/openai/gpt-4.1-nano.toml b/providers/merge-gateway/models/openai/gpt-4.1-nano.toml index 5deee39d9b..b761c99296 100644 --- a/providers/merge-gateway/models/openai/gpt-4.1-nano.toml +++ b/providers/merge-gateway/models/openai/gpt-4.1-nano.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4.1-nano (accessed 2026-07-21) + base_model = "openai/gpt-4.1-nano" name = "GPT-4.1 Nano" diff --git a/providers/merge-gateway/models/openai/gpt-4.1.toml b/providers/merge-gateway/models/openai/gpt-4.1.toml index 1fdb518f62..f7dc9e2b89 100644 --- a/providers/merge-gateway/models/openai/gpt-4.1.toml +++ b/providers/merge-gateway/models/openai/gpt-4.1.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4.1 (accessed 2026-07-21) + base_model = "openai/gpt-4.1" [cost] diff --git a/providers/merge-gateway/models/openai/gpt-4.toml b/providers/merge-gateway/models/openai/gpt-4.toml index a4363542ed..13e2d563e3 100644 --- a/providers/merge-gateway/models/openai/gpt-4.toml +++ b/providers/merge-gateway/models/openai/gpt-4.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4 (accessed 2026-07-21) + base_model = "openai/gpt-4" attachment = false tool_call = false diff --git a/providers/merge-gateway/models/openai/gpt-4o-2024-05-13.toml b/providers/merge-gateway/models/openai/gpt-4o-2024-05-13.toml index 6f72744fc8..06df984cfd 100644 --- a/providers/merge-gateway/models/openai/gpt-4o-2024-05-13.toml +++ b/providers/merge-gateway/models/openai/gpt-4o-2024-05-13.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4o-2024-05-13 (accessed 2026-07-21) + base_model = "openai/gpt-4o-2024-05-13" structured_output = false diff --git a/providers/merge-gateway/models/openai/gpt-4o-2024-08-06.toml b/providers/merge-gateway/models/openai/gpt-4o-2024-08-06.toml index a02cb635cd..a6ebb109cb 100644 --- a/providers/merge-gateway/models/openai/gpt-4o-2024-08-06.toml +++ b/providers/merge-gateway/models/openai/gpt-4o-2024-08-06.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4o-2024-08-06 (accessed 2026-07-21) + base_model = "openai/gpt-4o-2024-08-06" [cost] diff --git a/providers/merge-gateway/models/openai/gpt-4o-2024-11-20.toml b/providers/merge-gateway/models/openai/gpt-4o-2024-11-20.toml index 2df04ffa70..00f8adb377 100644 --- a/providers/merge-gateway/models/openai/gpt-4o-2024-11-20.toml +++ b/providers/merge-gateway/models/openai/gpt-4o-2024-11-20.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4o-2024-11-20 (accessed 2026-07-21) + base_model = "openai/gpt-4o-2024-11-20" [cost] diff --git a/providers/merge-gateway/models/openai/gpt-4o-mini.toml b/providers/merge-gateway/models/openai/gpt-4o-mini.toml index 5662c2ceca..418dbf5921 100644 --- a/providers/merge-gateway/models/openai/gpt-4o-mini.toml +++ b/providers/merge-gateway/models/openai/gpt-4o-mini.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4o-mini (accessed 2026-07-21) + base_model = "openai/gpt-4o-mini" name = "GPT-4o Mini" diff --git a/providers/merge-gateway/models/openai/gpt-4o.toml b/providers/merge-gateway/models/openai/gpt-4o.toml index 1b57e52012..0c687fa6cc 100644 --- a/providers/merge-gateway/models/openai/gpt-4o.toml +++ b/providers/merge-gateway/models/openai/gpt-4o.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-4o (accessed 2026-07-21) + base_model = "openai/gpt-4o" [cost] diff --git a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml index 4af6a73a45..f2fc62c7e1 100644 --- a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5-chat-latest (accessed 2026-07-21) + base_model = "openai/gpt-5-chat-latest" base_model_omit = ["limit.input"] name = "GPT-5 Chat Latest" diff --git a/providers/merge-gateway/models/openai/gpt-5-mini.toml b/providers/merge-gateway/models/openai/gpt-5-mini.toml index 9ab4f24cca..b581eb9952 100644 --- a/providers/merge-gateway/models/openai/gpt-5-mini.toml +++ b/providers/merge-gateway/models/openai/gpt-5-mini.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5-mini (accessed 2026-07-21) + base_model = "openai/gpt-5-mini" [[reasoning_options]] diff --git a/providers/merge-gateway/models/openai/gpt-5-nano.toml b/providers/merge-gateway/models/openai/gpt-5-nano.toml index 24bc4a0e65..1696ed22a9 100644 --- a/providers/merge-gateway/models/openai/gpt-5-nano.toml +++ b/providers/merge-gateway/models/openai/gpt-5-nano.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5-nano (accessed 2026-07-21) + base_model = "openai/gpt-5-nano" [[reasoning_options]] diff --git a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml index d1916353a0..401c51d7f0 100644 --- a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.1-chat-latest (accessed 2026-07-21) + base_model = "openai/gpt-5.1-chat-latest" name = "GPT-5.1 Chat Latest" reasoning_options = [] diff --git a/providers/merge-gateway/models/openai/gpt-5.1.toml b/providers/merge-gateway/models/openai/gpt-5.1.toml index b1e6e83622..b69d656028 100644 --- a/providers/merge-gateway/models/openai/gpt-5.1.toml +++ b/providers/merge-gateway/models/openai/gpt-5.1.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.1 (accessed 2026-07-21) + base_model = "openai/gpt-5.1" [[reasoning_options]] diff --git a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml index c12b1689b0..5693ae08ab 100644 --- a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.2-chat-latest (accessed 2026-07-21) + base_model = "openai/gpt-5.2-chat-latest" name = "GPT-5.2 Chat Latest" reasoning_options = [] diff --git a/providers/merge-gateway/models/openai/gpt-5.2.toml b/providers/merge-gateway/models/openai/gpt-5.2.toml index 4cbeec6e34..10a945fbe1 100644 --- a/providers/merge-gateway/models/openai/gpt-5.2.toml +++ b/providers/merge-gateway/models/openai/gpt-5.2.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.2 (accessed 2026-07-21) + base_model = "openai/gpt-5.2" [[reasoning_options]] diff --git a/providers/merge-gateway/models/openai/gpt-5.3-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.3-chat-latest.toml index 5d69491b2e..f35e898329 100644 --- a/providers/merge-gateway/models/openai/gpt-5.3-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.3-chat-latest.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.3-chat-latest (accessed 2026-07-21) + base_model = "openai/gpt-5.3-chat-latest" name = "GPT-5.3 Chat Latest" diff --git a/providers/merge-gateway/models/openai/gpt-5.4-mini.toml b/providers/merge-gateway/models/openai/gpt-5.4-mini.toml index 913a608765..6a19d6e63d 100644 --- a/providers/merge-gateway/models/openai/gpt-5.4-mini.toml +++ b/providers/merge-gateway/models/openai/gpt-5.4-mini.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.4-mini (accessed 2026-07-21) + base_model = "openai/gpt-5.4-mini" name = "GPT-5.4 Mini" diff --git a/providers/merge-gateway/models/openai/gpt-5.4-nano.toml b/providers/merge-gateway/models/openai/gpt-5.4-nano.toml index cd1ef0c661..9ee0ed96cf 100644 --- a/providers/merge-gateway/models/openai/gpt-5.4-nano.toml +++ b/providers/merge-gateway/models/openai/gpt-5.4-nano.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.4-nano (accessed 2026-07-21) + base_model = "openai/gpt-5.4-nano" name = "GPT-5.4 Nano" diff --git a/providers/merge-gateway/models/openai/gpt-5.4.toml b/providers/merge-gateway/models/openai/gpt-5.4.toml index 76ccd302ea..c6591d4b7c 100644 --- a/providers/merge-gateway/models/openai/gpt-5.4.toml +++ b/providers/merge-gateway/models/openai/gpt-5.4.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.4 (accessed 2026-07-21) + base_model = "openai/gpt-5.4" reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] diff --git a/providers/merge-gateway/models/openai/gpt-5.5.toml b/providers/merge-gateway/models/openai/gpt-5.5.toml index 9b565dd3a2..5c040bc0fd 100644 --- a/providers/merge-gateway/models/openai/gpt-5.5.toml +++ b/providers/merge-gateway/models/openai/gpt-5.5.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.5 (accessed 2026-07-21) + base_model = "openai/gpt-5.5" reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] diff --git a/providers/merge-gateway/models/openai/gpt-5.6-luna.toml b/providers/merge-gateway/models/openai/gpt-5.6-luna.toml index 37a38e5a9b..fd57002965 100644 --- a/providers/merge-gateway/models/openai/gpt-5.6-luna.toml +++ b/providers/merge-gateway/models/openai/gpt-5.6-luna.toml @@ -1,6 +1,8 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.6-luna (accessed 2026-07-21) # Merge Gateway GET /v1/models?model=openai/gpt-5.6-luna (accessed 2026-07-14): # the OpenAI vendor route advertises configurable `reasoning.effort` and disable support. # Effort values: https://openai.com/index/gpt-5-6/ + base_model = "openai/gpt-5.6-luna" reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh", "max"] }] diff --git a/providers/merge-gateway/models/openai/gpt-5.6-sol.toml b/providers/merge-gateway/models/openai/gpt-5.6-sol.toml index de3ff8acd3..d26085d5b8 100644 --- a/providers/merge-gateway/models/openai/gpt-5.6-sol.toml +++ b/providers/merge-gateway/models/openai/gpt-5.6-sol.toml @@ -1,5 +1,7 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.6-sol (accessed 2026-07-21) # Merge Gateway catalog: GET https://api-gateway.merge.dev/v1/models # Reasoning controls: https://openai.com/index/gpt-5-6/ (accessed 2026-07-13) + base_model = "openai/gpt-5.6-sol" [[reasoning_options]] diff --git a/providers/merge-gateway/models/openai/gpt-5.6-terra.toml b/providers/merge-gateway/models/openai/gpt-5.6-terra.toml index 592888015f..1ee6a1d902 100644 --- a/providers/merge-gateway/models/openai/gpt-5.6-terra.toml +++ b/providers/merge-gateway/models/openai/gpt-5.6-terra.toml @@ -1,6 +1,8 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5.6-terra (accessed 2026-07-21) # Merge Gateway GET /v1/models?model=openai/gpt-5.6-terra (accessed 2026-07-14): # the OpenAI vendor route advertises configurable `reasoning.effort` and disable support. # Effort values: https://openai.com/index/gpt-5-6/ + base_model = "openai/gpt-5.6-terra" reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh", "max"] }] diff --git a/providers/merge-gateway/models/openai/gpt-5.toml b/providers/merge-gateway/models/openai/gpt-5.toml index 562d91dcdb..4c4758eae1 100644 --- a/providers/merge-gateway/models/openai/gpt-5.toml +++ b/providers/merge-gateway/models/openai/gpt-5.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-5 (accessed 2026-07-21) + base_model = "openai/gpt-5" [[reasoning_options]] diff --git a/providers/merge-gateway/models/openai/gpt-oss-120b.toml b/providers/merge-gateway/models/openai/gpt-oss-120b.toml index a72e2e54c7..c2d674463d 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-120b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-120b.toml @@ -1,7 +1,9 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-oss-120b (accessed 2026-07-21) # Merge Gateway GET /v1/models?model=openai/gpt-oss-120b (accessed 2026-07-16): # parasail and fireworks routes report `supports_reasoning = true` with # `configurable = false` and no controls, so the model reasons on the gateway # but callers have no reasoning control. + base_model = "openai/gpt-oss-120b" name = "GPT-OSS 120B" tool_call = false diff --git a/providers/merge-gateway/models/openai/gpt-oss-20b.toml b/providers/merge-gateway/models/openai/gpt-oss-20b.toml index 714e07034b..cd05ecea55 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-20b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-20b.toml @@ -1,7 +1,9 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-oss-20b (accessed 2026-07-21) # Merge Gateway GET /v1/models?model=openai/gpt-oss-20b (accessed 2026-07-16): # routes reporting `supports_reasoning = true` carry `configurable = false` and # no controls, so the model reasons on the gateway but callers have no # reasoning control. + base_model = "openai/gpt-oss-20b" name = "GPT-OSS 20B" tool_call = false diff --git a/providers/merge-gateway/models/openai/gpt-oss-safeguard-120b.toml b/providers/merge-gateway/models/openai/gpt-oss-safeguard-120b.toml index 052bb87785..b01b9bd349 100644 --- a/providers/merge-gateway/models/openai/gpt-oss-safeguard-120b.toml +++ b/providers/merge-gateway/models/openai/gpt-oss-safeguard-120b.toml @@ -1,5 +1,6 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fgpt-oss-safeguard-120b (accessed 2026-07-21) + base_model = "openai/gpt-oss-safeguard-120b" -name = "gpt-oss-safeguard-120b" tool_call = false structured_output = false reasoning_options = [] diff --git a/providers/merge-gateway/models/openai/o1.toml b/providers/merge-gateway/models/openai/o1.toml index f1d328f31a..ca36309e40 100644 --- a/providers/merge-gateway/models/openai/o1.toml +++ b/providers/merge-gateway/models/openai/o1.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fo1 (accessed 2026-07-21) + base_model = "openai/o1" reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] diff --git a/providers/merge-gateway/models/openai/o3-mini.toml b/providers/merge-gateway/models/openai/o3-mini.toml index 8e81e03022..31dd58fec7 100644 --- a/providers/merge-gateway/models/openai/o3-mini.toml +++ b/providers/merge-gateway/models/openai/o3-mini.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fo3-mini (accessed 2026-07-21) + base_model = "openai/o3-mini" name = "o3 Mini" diff --git a/providers/merge-gateway/models/openai/o3.toml b/providers/merge-gateway/models/openai/o3.toml index da90132d61..a9d1e851c3 100644 --- a/providers/merge-gateway/models/openai/o3.toml +++ b/providers/merge-gateway/models/openai/o3.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fo3 (accessed 2026-07-21) + base_model = "openai/o3" reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] diff --git a/providers/merge-gateway/models/openai/o4-mini.toml b/providers/merge-gateway/models/openai/o4-mini.toml index e234a45f67..b2112ce298 100644 --- a/providers/merge-gateway/models/openai/o4-mini.toml +++ b/providers/merge-gateway/models/openai/o4-mini.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=openai%2Fo4-mini (accessed 2026-07-21) + base_model = "openai/o4-mini" name = "o4 Mini" reasoning_options = [] diff --git a/providers/merge-gateway/models/qwen/qwen-flash.toml b/providers/merge-gateway/models/qwen/qwen-flash.toml index 542a748108..c267bb48d7 100644 --- a/providers/merge-gateway/models/qwen/qwen-flash.toml +++ b/providers/merge-gateway/models/qwen/qwen-flash.toml @@ -1,8 +1,12 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen-flash (accessed 2026-07-21) + base_model = "alibaba/qwen-flash" -reasoning_options = [] tool_call = false structured_output = false +[[reasoning_options]] +type = "toggle" + [cost] input = 0.022 output = 0.216 diff --git a/providers/merge-gateway/models/qwen/qwen-plus.toml b/providers/merge-gateway/models/qwen/qwen-plus.toml index 117afdb8d5..aaca52cfa3 100644 --- a/providers/merge-gateway/models/qwen/qwen-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen-plus.toml @@ -1,8 +1,12 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen-plus (accessed 2026-07-21) + base_model = "alibaba/qwen-plus" -reasoning_options = [] tool_call = false structured_output = false +[[reasoning_options]] +type = "toggle" + [cost] input = 0.115 output = 0.287 diff --git a/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml b/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml index 3e749483e5..8aea9d7833 100644 --- a/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml +++ b/providers/merge-gateway/models/qwen/qwen3-235b-a22b.toml @@ -1,9 +1,13 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3-235b-a22b (accessed 2026-07-21) + base_model = "alibaba/qwen3-235b-a22b" name = "Qwen3 235B A22B" -reasoning_options = [] tool_call = false structured_output = false +[[reasoning_options]] +type = "toggle" + [cost] input = 0.287 output = 1.147 diff --git a/providers/merge-gateway/models/qwen/qwen3-32b.toml b/providers/merge-gateway/models/qwen/qwen3-32b.toml index b62d81894a..86b61eb656 100644 --- a/providers/merge-gateway/models/qwen/qwen3-32b.toml +++ b/providers/merge-gateway/models/qwen/qwen3-32b.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3-32b (accessed 2026-07-21) + base_model = "alibaba/qwen3-32b" reasoning_options = [] structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3-coder-480b-a35b-instruct.toml b/providers/merge-gateway/models/qwen/qwen3-coder-480b-a35b-instruct.toml index 2d2b7fe1ae..804e404a49 100644 --- a/providers/merge-gateway/models/qwen/qwen3-coder-480b-a35b-instruct.toml +++ b/providers/merge-gateway/models/qwen/qwen3-coder-480b-a35b-instruct.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3-coder-480b-a35b-instruct (accessed 2026-07-21) + base_model = "alibaba/qwen3-coder-480b-a35b-instruct" tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml b/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml index ba9dbb0ead..00cb0a4cff 100644 --- a/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml +++ b/providers/merge-gateway/models/qwen/qwen3-coder-flash.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3-coder-flash (accessed 2026-07-21) + base_model = "alibaba/qwen3-coder-flash" tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml b/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml index 8d12a803e8..fc5728818b 100644 --- a/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3-coder-plus.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3-coder-plus (accessed 2026-07-21) + base_model = "alibaba/qwen3-coder-plus" tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3-max.toml b/providers/merge-gateway/models/qwen/qwen3-max.toml index 22f3b42dc8..5856bb59f1 100644 --- a/providers/merge-gateway/models/qwen/qwen3-max.toml +++ b/providers/merge-gateway/models/qwen/qwen3-max.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3-max (accessed 2026-07-21) + base_model = "alibaba/qwen3-max" tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml index 082dbd8195..d00ed2daba 100644 --- a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml +++ b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-instruct.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3-next-80b-a3b-instruct (accessed 2026-07-21) + base_model = "alibaba/qwen3-next-80b-a3b-instruct" name = "Qwen3 Next 80B A3B Instruct" tool_call = false diff --git a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml index 339058e004..af96fc5f6c 100644 --- a/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml +++ b/providers/merge-gateway/models/qwen/qwen3-next-80b-a3b-thinking.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3-next-80b-a3b-thinking (accessed 2026-07-21) + base_model = "alibaba/qwen3-next-80b-a3b-thinking" reasoning_options = [] tool_call = false diff --git a/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml b/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml index 51cbeafc6b..a00764633f 100644 --- a/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3-vl-plus.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3-vl-plus (accessed 2026-07-21) + base_model = "alibaba/qwen3-vl-plus" attachment = true reasoning_options = [] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml index 90e3316750..ad3a3b8e18 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-122b-a10b.toml @@ -1,7 +1,12 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.5-122b-a10b (accessed 2026-07-21) + base_model = "alibaba/qwen3.5-122b-a10b" +attachment = false tool_call = false structured_output = false -reasoning_options = [] + +[[reasoning_options]] +type = "toggle" [cost] input = 0.115 @@ -9,8 +14,8 @@ output = 0.917 cache_read = 0.023 [limit] -context = 256_000 -output = 64_000 +context = 131_072 +output = 32_768 [modalities] -input = ["text", "image"] +input = ["text"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-27b.toml b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml index 579c66dd59..dc8a65f1ac 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-27b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-27b.toml @@ -1,5 +1,6 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.5-27b (accessed 2026-07-21) + base_model = "alibaba/qwen3.5-27b" -attachment = false tool_call = false structured_output = false reasoning_options = [] @@ -10,8 +11,8 @@ output = 0.688 cache_read = 0.0172 [limit] -context = 131_072 -output = 32_768 +context = 256_000 +output = 64_000 [modalities] -input = ["text"] +input = ["text", "image"] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml index e30ccc863e..fdf33dbf99 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-35b-a3b.toml @@ -1,7 +1,10 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.5-35b-a3b (accessed 2026-07-21) +# Selected route reasoning.controls = ["thinking"], disable_supported = true. + base_model = "alibaba/qwen3.5-35b-a3b" name = "Qwen3.5 35B A3B" attachment = false -reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true +reasoning_options = [{ type = "toggle" }] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml index 9fb2498fb8..5958cb16c4 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-397b-a17b.toml @@ -1,7 +1,10 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.5-397b-a17b (accessed 2026-07-21) +# Selected route reasoning.controls = ["thinking"], disable_supported = true. + base_model = "alibaba/qwen3.5-397b-a17b" name = "Qwen3.5 397B A17B" attachment = false -reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true +reasoning_options = [{ type = "toggle" }] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.5-9b.toml b/providers/merge-gateway/models/qwen/qwen3.5-9b.toml index 5d99815e5e..e499c01fa2 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-9b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-9b.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.5-9b (accessed 2026-07-21) + base_model = "alibaba/qwen3.5-9b" attachment = true reasoning_options = [] diff --git a/providers/merge-gateway/models/qwen/qwen3.5-plus.toml b/providers/merge-gateway/models/qwen/qwen3.5-plus.toml index b3bb41fbb0..d0f54b9942 100644 --- a/providers/merge-gateway/models/qwen/qwen3.5-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.5-plus.toml @@ -1,8 +1,12 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.5-plus (accessed 2026-07-21) + base_model = "alibaba/qwen3.5-plus" -reasoning_options = [] tool_call = false structured_output = false +[[reasoning_options]] +type = "toggle" + [cost] input = 0.115 output = 0.688 diff --git a/providers/merge-gateway/models/qwen/qwen3.6-27b.toml b/providers/merge-gateway/models/qwen/qwen3.6-27b.toml index 485bf8b972..589894f2e0 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-27b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-27b.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.6-27b (accessed 2026-07-21) + base_model = "alibaba/qwen3.6-27b" reasoning_options = [] tool_call = false diff --git a/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml b/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml index dd83266392..d548955fc6 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-35b-a3b.toml @@ -1,10 +1,14 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.6-35b-a3b (accessed 2026-07-21) + base_model = "alibaba/qwen3.6-35b-a3b" name = "Qwen3.6 35B A3B" attachment = false -reasoning_options = [] tool_call = false structured_output = false +[[reasoning_options]] +type = "toggle" + [cost] input = 0.248 output = 1.485 diff --git a/providers/merge-gateway/models/qwen/qwen3.6-flash.toml b/providers/merge-gateway/models/qwen/qwen3.6-flash.toml index 1a762bb2a0..bbf6ca5ec7 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-flash.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-flash.toml @@ -1,9 +1,13 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.6-flash (accessed 2026-07-21) + base_model = "alibaba/qwen3.6-flash" attachment = false -reasoning_options = [] tool_call = false structured_output = false +[[reasoning_options]] +type = "toggle" + [cost] input = 0.165 output = 0.99 diff --git a/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml b/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml index 4b6d61e0b2..d1b1b36129 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-max-preview.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.6-max-preview (accessed 2026-07-21) + base_model = "alibaba/qwen3.6-max-preview" reasoning_options = [] tool_call = false diff --git a/providers/merge-gateway/models/qwen/qwen3.6-plus.toml b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml index 0657797d0f..fe832a7541 100644 --- a/providers/merge-gateway/models/qwen/qwen3.6-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.6-plus.toml @@ -1,5 +1,8 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.6-plus (accessed 2026-07-21) +# Selected route reasoning.controls = ["thinking"], disable_supported = true. + base_model = "alibaba/qwen3.6-plus" -reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["thinking"], disable_supported = true +reasoning_options = [{ type = "toggle" }] tool_call = false structured_output = false diff --git a/providers/merge-gateway/models/qwen/qwen3.7-max.toml b/providers/merge-gateway/models/qwen/qwen3.7-max.toml index 7b615bb049..b26cf83b54 100644 --- a/providers/merge-gateway/models/qwen/qwen3.7-max.toml +++ b/providers/merge-gateway/models/qwen/qwen3.7-max.toml @@ -1,8 +1,12 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.7-max (accessed 2026-07-21) + base_model = "alibaba/qwen3.7-max" -reasoning_options = [] tool_call = false structured_output = false +[[reasoning_options]] +type = "toggle" + [cost] input = 0.825 output = 2.4755 diff --git a/providers/merge-gateway/models/qwen/qwen3.7-plus.toml b/providers/merge-gateway/models/qwen/qwen3.7-plus.toml index c8aa4db85e..84c900303d 100644 --- a/providers/merge-gateway/models/qwen/qwen3.7-plus.toml +++ b/providers/merge-gateway/models/qwen/qwen3.7-plus.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=qwen%2Fqwen3.7-plus (accessed 2026-07-21) + base_model = "alibaba/qwen3.7-plus" attachment = true reasoning_options = [] diff --git a/providers/merge-gateway/models/sakana/fugu-ultra.toml b/providers/merge-gateway/models/sakana/fugu-ultra.toml index 73a57b717a..6811bc61e5 100644 --- a/providers/merge-gateway/models/sakana/fugu-ultra.toml +++ b/providers/merge-gateway/models/sakana/fugu-ultra.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=sakana%2Ffugu-ultra (accessed 2026-07-21) + base_model = "sakana/fugu-ultra" reasoning_options = [] structured_output = false diff --git a/providers/merge-gateway/models/writer/palmyra-x4.toml b/providers/merge-gateway/models/writer/palmyra-x4.toml index dba9900285..5b8c94a26b 100644 --- a/providers/merge-gateway/models/writer/palmyra-x4.toml +++ b/providers/merge-gateway/models/writer/palmyra-x4.toml @@ -1,4 +1,4 @@ -# Source: https://api-gateway.merge.dev/v1/models?model=writer%2Fpalmyra-x4 +# Source: https://api-gateway.merge.dev/v1/models?model=writer%2Fpalmyra-x4 (accessed 2026-07-21) name = "Palmyra X4" description = "Enterprise language model for writing, analysis, and tool-assisted workflows" diff --git a/providers/merge-gateway/models/writer/palmyra-x5.toml b/providers/merge-gateway/models/writer/palmyra-x5.toml index c7bdfefa40..5ded741a14 100644 --- a/providers/merge-gateway/models/writer/palmyra-x5.toml +++ b/providers/merge-gateway/models/writer/palmyra-x5.toml @@ -1,4 +1,4 @@ -# Source: https://api-gateway.merge.dev/v1/models?model=writer%2Fpalmyra-x5 +# Source: https://api-gateway.merge.dev/v1/models?model=writer%2Fpalmyra-x5 (accessed 2026-07-21) name = "Palmyra X5" description = "Enterprise multimodal model for writing, analysis, and tool-assisted workflows" diff --git a/providers/merge-gateway/models/xai/grok-4.20-0309-non-reasoning.toml b/providers/merge-gateway/models/xai/grok-4.20-0309-non-reasoning.toml index e803774686..f7ca1018d7 100644 --- a/providers/merge-gateway/models/xai/grok-4.20-0309-non-reasoning.toml +++ b/providers/merge-gateway/models/xai/grok-4.20-0309-non-reasoning.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=xai%2Fgrok-4.20-0309-non-reasoning (accessed 2026-07-21) + base_model = "xai/grok-4.20-0309-non-reasoning" name = "Grok 4.20 Non-Reasoning" diff --git a/providers/merge-gateway/models/xai/grok-4.20-0309-reasoning.toml b/providers/merge-gateway/models/xai/grok-4.20-0309-reasoning.toml index eef910f466..dacd64d727 100644 --- a/providers/merge-gateway/models/xai/grok-4.20-0309-reasoning.toml +++ b/providers/merge-gateway/models/xai/grok-4.20-0309-reasoning.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=xai%2Fgrok-4.20-0309-reasoning (accessed 2026-07-21) + base_model = "xai/grok-4.20-0309-reasoning" name = "Grok 4.20" reasoning_options = [] diff --git a/providers/merge-gateway/models/xai/grok-4.3.toml b/providers/merge-gateway/models/xai/grok-4.3.toml index 3dc91bbe77..9ebf40c8f7 100644 --- a/providers/merge-gateway/models/xai/grok-4.3.toml +++ b/providers/merge-gateway/models/xai/grok-4.3.toml @@ -1,5 +1,8 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=xai%2Fgrok-4.3 (accessed 2026-07-21) +# Selected route reasoning.controls = ["reasoning.effort"], disable_supported = true; effort values not exposed. + base_model = "xai/grok-4.3" -reasoning_options = [{ type = "toggle" }] # route reasoning.controls = ["reasoning.effort"], disable_supported = true; effort values not exposed +reasoning_options = [{ type = "toggle" }] [cost] input = 1.25 diff --git a/providers/merge-gateway/models/xai/grok-4.5.toml b/providers/merge-gateway/models/xai/grok-4.5.toml index 9179571704..d1834d708a 100644 --- a/providers/merge-gateway/models/xai/grok-4.5.toml +++ b/providers/merge-gateway/models/xai/grok-4.5.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=xai%2Fgrok-4.5 (accessed 2026-07-21) + base_model = "xai/grok-4.5" reasoning_options = [] diff --git a/providers/merge-gateway/models/xai/grok-build-0.1.toml b/providers/merge-gateway/models/xai/grok-build-0.1.toml index 2cd89e9a80..ca8d567052 100644 --- a/providers/merge-gateway/models/xai/grok-build-0.1.toml +++ b/providers/merge-gateway/models/xai/grok-build-0.1.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=xai%2Fgrok-build-0.1 (accessed 2026-07-21) + base_model = "xai/grok-build-0.1" reasoning_options = [] diff --git a/providers/merge-gateway/models/zai/glm-4.5-air.toml b/providers/merge-gateway/models/zai/glm-4.5-air.toml index fb0ad87b7f..cf057be39e 100644 --- a/providers/merge-gateway/models/zai/glm-4.5-air.toml +++ b/providers/merge-gateway/models/zai/glm-4.5-air.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-4.5-air (accessed 2026-07-21) + base_model = "zhipuai/glm-4.5-air" name = "GLM-4.5 Air" structured_output = false diff --git a/providers/merge-gateway/models/zai/glm-4.5.toml b/providers/merge-gateway/models/zai/glm-4.5.toml index 4286567606..5a9e2beb7e 100644 --- a/providers/merge-gateway/models/zai/glm-4.5.toml +++ b/providers/merge-gateway/models/zai/glm-4.5.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-4.5 (accessed 2026-07-21) + base_model = "zhipuai/glm-4.5" structured_output = false diff --git a/providers/merge-gateway/models/zai/glm-4.5v.toml b/providers/merge-gateway/models/zai/glm-4.5v.toml index 20e2597200..822f172a0a 100644 --- a/providers/merge-gateway/models/zai/glm-4.5v.toml +++ b/providers/merge-gateway/models/zai/glm-4.5v.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-4.5v (accessed 2026-07-21) + base_model = "zhipuai/glm-4.5v" name = "Glm 4.5V" reasoning_options = [] diff --git a/providers/merge-gateway/models/zai/glm-4.6.toml b/providers/merge-gateway/models/zai/glm-4.6.toml index 9b43877924..68e6573180 100644 --- a/providers/merge-gateway/models/zai/glm-4.6.toml +++ b/providers/merge-gateway/models/zai/glm-4.6.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-4.6 (accessed 2026-07-21) + base_model = "zhipuai/glm-4.6" structured_output = false diff --git a/providers/merge-gateway/models/zai/glm-4.7-flash.toml b/providers/merge-gateway/models/zai/glm-4.7-flash.toml index 288f833d80..1974407734 100644 --- a/providers/merge-gateway/models/zai/glm-4.7-flash.toml +++ b/providers/merge-gateway/models/zai/glm-4.7-flash.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-4.7-flash (accessed 2026-07-21) + base_model = "zhipuai/glm-4.7-flash" name = "GLM 4.7 Flash" reasoning_options = [] diff --git a/providers/merge-gateway/models/zai/glm-4.7-flashx.toml b/providers/merge-gateway/models/zai/glm-4.7-flashx.toml index 66e530d1d4..28d46a80dc 100644 --- a/providers/merge-gateway/models/zai/glm-4.7-flashx.toml +++ b/providers/merge-gateway/models/zai/glm-4.7-flashx.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-4.7-flashx (accessed 2026-07-21) + base_model = "zhipuai/glm-4.7-flashx" name = "GLM-4.7 FlashX" structured_output = false diff --git a/providers/merge-gateway/models/zai/glm-4.7.toml b/providers/merge-gateway/models/zai/glm-4.7.toml index 2645ef55ee..0067c6f4b6 100644 --- a/providers/merge-gateway/models/zai/glm-4.7.toml +++ b/providers/merge-gateway/models/zai/glm-4.7.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-4.7 (accessed 2026-07-21) + base_model = "zhipuai/glm-4.7" structured_output = false diff --git a/providers/merge-gateway/models/zai/glm-5-turbo.toml b/providers/merge-gateway/models/zai/glm-5-turbo.toml index e0f648c6bb..7551ca6a3c 100644 --- a/providers/merge-gateway/models/zai/glm-5-turbo.toml +++ b/providers/merge-gateway/models/zai/glm-5-turbo.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-5-turbo (accessed 2026-07-21) + base_model = "zhipuai/glm-5-turbo" name = "GLM-5 Turbo" structured_output = false diff --git a/providers/merge-gateway/models/zai/glm-5.1.toml b/providers/merge-gateway/models/zai/glm-5.1.toml index faa77406f6..7b1830b39a 100644 --- a/providers/merge-gateway/models/zai/glm-5.1.toml +++ b/providers/merge-gateway/models/zai/glm-5.1.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-5.1 (accessed 2026-07-21) + base_model = "zhipuai/glm-5.1" name = "GLM 5.1" structured_output = false diff --git a/providers/merge-gateway/models/zai/glm-5.2.toml b/providers/merge-gateway/models/zai/glm-5.2.toml index ec9a3ad07b..f24278b7f9 100644 --- a/providers/merge-gateway/models/zai/glm-5.2.toml +++ b/providers/merge-gateway/models/zai/glm-5.2.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-5.2 (accessed 2026-07-21) + base_model = "zhipuai/glm-5.2" name = "GLM 5.2" structured_output = false diff --git a/providers/merge-gateway/models/zai/glm-5.toml b/providers/merge-gateway/models/zai/glm-5.toml index 0daa2719a0..c048fb0af3 100644 --- a/providers/merge-gateway/models/zai/glm-5.toml +++ b/providers/merge-gateway/models/zai/glm-5.toml @@ -1,3 +1,5 @@ +# Source: https://api-gateway.merge.dev/v1/models?model=zai%2Fglm-5 (accessed 2026-07-21) + base_model = "zhipuai/glm-5" structured_output = false diff --git a/providers/merge-gateway/provider.toml b/providers/merge-gateway/provider.toml index 293c689f4f..7c4c7079e7 100644 --- a/providers/merge-gateway/provider.toml +++ b/providers/merge-gateway/provider.toml @@ -1,7 +1,4 @@ -name = "Merge Gateway" -env = ["MERGE_GATEWAY_API_KEY"] -npm = "merge-gateway-ai-sdk-provider" -# Reasoning request surfaces (sources accessed 2026-07-14): +# Reasoning request surfaces (sources accessed 2026-07-21): # - Reasoning support and controls are vendor-route capabilities. Use the exact # model response from GET /v1/models and inspect # vendors..capabilities.reasoning; do not infer support solely from a @@ -15,4 +12,7 @@ npm = "merge-gateway-ai-sdk-provider" # `providerOptions.mergeGateway.thinking` to # `thinking = { type = "enabled"|"disabled", budget_tokens = N }`. # https://github.com/merge-api/merge-gateway-ai-sdk-provider/blob/main/src/chat/index.ts +name = "Merge Gateway" +env = ["MERGE_GATEWAY_API_KEY"] +npm = "merge-gateway-ai-sdk-provider" doc = "https://docs.merge.dev/merge-gateway" diff --git a/sync.md b/sync.md index 136a57333e..a47eaa96ef 100644 --- a/sync.md +++ b/sync.md @@ -149,10 +149,10 @@ Merge Gateway is implemented in `packages/core/src/sync/providers/merge-gateway. - The sync follows `next_cursor` until every page has been fetched. - The canonical provider's available vendor route supplies pricing, limits, and capabilities. When it is unavailable, the sync matches Gateway's default resolver by selecting the active route with the lowest combined input and output price; the API's CMS-priority order breaks ties. - Canonical model IDs emit `base_model` references to model metadata when a matching `models/` entry exists. -- Existing cache pricing, tiered pricing, reasoning controls, and experimental modes are preserved because the public API does not currently expose the full CMS metadata. Cache prices curated from Gateway's route-level CMS remain stable across syncs until the public contract exposes them. +- Existing cache pricing, tiered pricing, exact reasoning effort/budget controls, and experimental modes are preserved because the public API does not currently expose the full CMS metadata. When the selected route reports `reasoning.disable_supported = true`, the sync derives a toggle; exact effort values and budget ranges remain curated. Cache prices curated from Gateway's route-level CMS remain stable across syncs until the public contract exposes them. - Route-level cache prices replace curated values field by field. A cache read or write price that the API does not expose remains preserved in the provider TOML, including when `prompt_caching` exposes only its mode. - `prompt_caching.mode = "none"` explicitly removes preserved cache read and write prices because that route does not cache prompts. -- `supports_reasoning` is a positive-only signal. It is absent from the documented public schema and inconsistently populated across vendor routes (the same model can report `true` on one route and `false` on another, and reasoning-only models can report `false` on their sole route). Any available route reporting `true` confirms `reasoning = true`, defaulting `reasoning_options` to `[]` when none are curated; `false` or absent is treated as unknown and preserves curated reasoning metadata. +- `supports_reasoning` is a positive-only signal. It is absent from the documented public schema and inconsistently populated across vendor routes (the same model can report `true` on one route and `false` on another, and reasoning-only models can report `false` on their sole route). Any available route reporting `true` confirms `reasoning = true`; when no controls are curated, `reasoning_options` defaults to a toggle if the selected route reports `reasoning.disable_supported = true`, otherwise `[]`. `supports_reasoning = false` or an absent field is treated as unknown and preserves curated reasoning metadata. - Local models missing from the response are retained because API-key policy can affect catalog visibility. ## Cloudflare Workers AI Notes From 2ba290d1773c125efa3aa0f782dd9ec61e4af686 Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Tue, 21 Jul 2026 13:23:24 -0400 Subject: [PATCH 08/11] docs(sync): trim Merge Gateway notes --- sync.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sync.md b/sync.md index a47eaa96ef..07d9a36838 100644 --- a/sync.md +++ b/sync.md @@ -149,10 +149,6 @@ Merge Gateway is implemented in `packages/core/src/sync/providers/merge-gateway. - The sync follows `next_cursor` until every page has been fetched. - The canonical provider's available vendor route supplies pricing, limits, and capabilities. When it is unavailable, the sync matches Gateway's default resolver by selecting the active route with the lowest combined input and output price; the API's CMS-priority order breaks ties. - Canonical model IDs emit `base_model` references to model metadata when a matching `models/` entry exists. -- Existing cache pricing, tiered pricing, exact reasoning effort/budget controls, and experimental modes are preserved because the public API does not currently expose the full CMS metadata. When the selected route reports `reasoning.disable_supported = true`, the sync derives a toggle; exact effort values and budget ranges remain curated. Cache prices curated from Gateway's route-level CMS remain stable across syncs until the public contract exposes them. -- Route-level cache prices replace curated values field by field. A cache read or write price that the API does not expose remains preserved in the provider TOML, including when `prompt_caching` exposes only its mode. -- `prompt_caching.mode = "none"` explicitly removes preserved cache read and write prices because that route does not cache prompts. -- `supports_reasoning` is a positive-only signal. It is absent from the documented public schema and inconsistently populated across vendor routes (the same model can report `true` on one route and `false` on another, and reasoning-only models can report `false` on their sole route). Any available route reporting `true` confirms `reasoning = true`; when no controls are curated, `reasoning_options` defaults to a toggle if the selected route reports `reasoning.disable_supported = true`, otherwise `[]`. `supports_reasoning = false` or an absent field is treated as unknown and preserves curated reasoning metadata. - Local models missing from the response are retained because API-key policy can affect catalog visibility. ## Cloudflare Workers AI Notes From 4e9a94a276f39f1b4cffa97318c56e977bc144ef Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Tue, 21 Jul 2026 13:47:51 -0400 Subject: [PATCH 09/11] fix(merge-gateway): remove stale Qwen aliases --- .../merge-gateway/models/alibaba/qwen3.6-plus.toml | 13 ------------- .../merge-gateway/models/alibaba/qwen3.7-max.toml | 13 ------------- 2 files changed, 26 deletions(-) delete mode 100644 providers/merge-gateway/models/alibaba/qwen3.6-plus.toml delete mode 100644 providers/merge-gateway/models/alibaba/qwen3.7-max.toml diff --git a/providers/merge-gateway/models/alibaba/qwen3.6-plus.toml b/providers/merge-gateway/models/alibaba/qwen3.6-plus.toml deleted file mode 100644 index 35d0b6af6d..0000000000 --- a/providers/merge-gateway/models/alibaba/qwen3.6-plus.toml +++ /dev/null @@ -1,13 +0,0 @@ -base_model = "alibaba/qwen3.6-plus" - -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1 -max = 250_000 - -[cost] -input = 0.5 -output = 3 diff --git a/providers/merge-gateway/models/alibaba/qwen3.7-max.toml b/providers/merge-gateway/models/alibaba/qwen3.7-max.toml deleted file mode 100644 index f7790f827f..0000000000 --- a/providers/merge-gateway/models/alibaba/qwen3.7-max.toml +++ /dev/null @@ -1,13 +0,0 @@ -base_model = "alibaba/qwen3.7-max" - -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1 -max = 250_000 - -[cost] -input = 1.65 -output = 4.95 From 8944685f6b0f3db971729192812f0bac4fd3c6b9 Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Tue, 21 Jul 2026 14:03:05 -0400 Subject: [PATCH 10/11] test(merge-gateway): document sync coverage --- packages/core/test/sync.test.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/core/test/sync.test.ts b/packages/core/test/sync.test.ts index 3ba250889e..40ccdeaf8a 100644 --- a/packages/core/test/sync.test.ts +++ b/packages/core/test/sync.test.ts @@ -962,6 +962,7 @@ test("factors OpenRouter Pro routes against canonical OpenAI metadata", () => { expect("release_date" in model).toBe(false); }); +// Ensures Merge Gateway namespaces reuse the matching canonical model metadata. test("resolves Merge Gateway provider aliases to canonical metadata", () => { expect([ resolveCanonicalBaseModel("moonshot/kimi-k2.5"), @@ -1086,6 +1087,7 @@ test("factors aliased LLM Gateway routes against canonical metadata", () => { }); }); +// Ensures catalog pagination preserves authentication and returns every page. test("fetches every page of the Merge Gateway catalog", async () => { const requests: string[] = []; const authorizations: string[] = []; @@ -1117,6 +1119,7 @@ test("fetches every page of the Merge Gateway catalog", async () => { expect(authorizations).toEqual(["Bearer test-key", "Bearer test-key"]); }); +// Prevents pagination overlap from publishing the same model ID twice. test("rejects duplicate Merge Gateway model IDs across pages", async () => { const fetcher = ((input: string | URL | Request) => { const next = String(input).includes("cursor=next-page"); @@ -1133,6 +1136,7 @@ test("rejects duplicate Merge Gateway model IDs across pages", async () => { ); }); +// Rejects API records whose provider disagrees with the model ID namespace. test("rejects Merge Gateway provider and model namespace mismatches", () => { expect(() => MergeGatewayResponse.parse({ object: "list", @@ -1142,6 +1146,7 @@ test("rejects Merge Gateway provider and model namespace mismatches", () => { })).toThrow("Model namespace openai does not match provider anthropic"); }); +// Keeps audio-capable records valid when the API advertises audio input. test("accepts audio modalities from the Merge Gateway catalog", () => { const model = mergeGatewayModel(); model.vendors.openai.capabilities.input.push("audio"); @@ -1154,6 +1159,7 @@ test("accepts audio modalities from the Merge Gateway catalog", () => { }).data[0]?.vendors.openai.capabilities.input).toContain("audio"); }); +// Emits only route-specific overrides when canonical metadata already matches. test("factors Merge Gateway GPT-5.6 Sol against canonical metadata", () => { const model = buildMergeGatewayModel(mergeGatewayModel(), undefined); @@ -1166,6 +1172,7 @@ test("factors Merge Gateway GPT-5.6 Sol against canonical metadata", () => { }); }); +// Protects curated reasoning metadata from an unreliable negative API signal. test("preserves curated reasoning when Merge Gateway routes report supports_reasoning = false", () => { // `supports_reasoning = false` is a positive-only signal: the field is // undocumented in the public schema and inconsistently populated across @@ -1188,6 +1195,7 @@ test("preserves curated reasoning when Merge Gateway routes report supports_reas expect(model).not.toMatchObject({ reasoning: false }); }); +// Treats a positive signal from any available route as model-level confirmation. test("confirms reasoning when any available Merge Gateway route reports supports_reasoning = true", () => { const selected = mergeGatewayVendor(); selected.capabilities.supports_reasoning = false; @@ -1214,6 +1222,7 @@ test("confirms reasoning when any available Merge Gateway route reports supports expect(model).not.toMatchObject({ reasoning: false }); }); +// Publishes a toggle only when the selected route explicitly supports disabling reasoning. test("derives a Merge Gateway reasoning toggle when the selected route supports disabling", () => { const selected = mergeGatewayVendor(); selected.capabilities.reasoning = { @@ -1235,6 +1244,7 @@ test("derives a Merge Gateway reasoning toggle when the selected route supports expect(model).toMatchObject({ reasoning_options: [{ type: "toggle" }] }); }); +// Prevents deprecated routes from contributing capabilities to an available model. test("ignores supports_reasoning = true on unavailable Merge Gateway routes", () => { const selected = mergeGatewayVendor(); selected.capabilities.supports_reasoning = false; @@ -1250,6 +1260,7 @@ test("ignores supports_reasoning = true on unavailable Merge Gateway routes", () expect(model).not.toHaveProperty("reasoning_options"); }); +// Updates API-provided cache prices without discarding curated cache fields. test("merges authoritative Merge Gateway cache pricing field by field", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ vendors: { @@ -1286,6 +1297,7 @@ test("merges authoritative Merge Gateway cache pricing field by field", () => { }); }); +// Retains curated cache prices when the API confirms caching but omits prices. test("preserves Merge Gateway cache pricing when prompt caching exposes only its mode", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ vendors: { @@ -1311,6 +1323,7 @@ test("preserves Merge Gateway cache pricing when prompt caching exposes only its }); }); +// Removes inherited cache prices when the selected route explicitly disables caching. test("removes Merge Gateway cache pricing when prompt caching mode is none", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ vendors: { @@ -1335,6 +1348,7 @@ test("removes Merge Gateway cache pricing when prompt caching mode is none", () expect(model.cost).not.toHaveProperty("cache_write"); }); +// Avoids overriding a curated name with a display value that is effectively an ID. test("inherits canonical names for ID-shaped Merge Gateway display names", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ model: "minimax/minimax-m2", @@ -1346,6 +1360,7 @@ test("inherits canonical names for ID-shaped Merge Gateway display names", () => expect(model).not.toHaveProperty("name"); }); +// Avoids overriding a curated name with an unformatted model slug. test("inherits canonical names for slug-shaped Merge Gateway display names", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ model: "openai/gpt-oss-safeguard-120b", @@ -1356,6 +1371,7 @@ test("inherits canonical names for slug-shaped Merge Gateway display names", () expect(model).not.toHaveProperty("name"); }); +// Removes a canonical input limit that exceeds the selected route's context window. test("omits inherited input limits above the Merge Gateway context", () => { const model = buildMergeGatewayModel(mergeGatewayModel({ model: "openai/gpt-5-chat-latest", @@ -1384,6 +1400,7 @@ test("omits inherited input limits above the Merge Gateway context", () => { expect(model).toHaveProperty("base_model_omit", ["limit.input"]); }); +// Prefers the model provider's own route over alternate vendors. test("uses the canonical Merge Gateway vendor as the catalog baseline", () => { const model = mergeGatewayModel({ vendors: { @@ -1398,6 +1415,7 @@ test("uses the canonical Merge Gateway vendor as the catalog baseline", () => { }); }); +// Falls back to the lowest-cost available route when the canonical vendor is absent. test("uses Merge Gateway's cheapest fallback route when no canonical route exists", () => { const model = mergeGatewayModel({ provider: "qwen", @@ -1417,6 +1435,7 @@ test("uses Merge Gateway's cheapest fallback route when no canonical route exist }); }); +// Keeps API insertion order deterministic when fallback routes have equal prices. test("uses Merge Gateway's CMS order to break equal-cost fallback ties", () => { const model = mergeGatewayModel({ provider: "qwen", @@ -1433,6 +1452,7 @@ test("uses Merge Gateway's CMS order to break equal-cost fallback ties", () => { expect(selectMergeGatewayVendor(model)).toMatchObject({ id: "empiriolabs" }); }); +// Prevents a scoped API response from deleting catalog entries it cannot see. test("retains Merge Gateway models missing from an API-key-scoped response", () => { expect(mergeGateway.deleteMissing).toBe(false); }); From 861ad7d9b2befc8bd14313330d445031b5b870d1 Mon Sep 17 00:00:00 2001 From: Matthew Feroz Date: Tue, 21 Jul 2026 17:26:07 -0400 Subject: [PATCH 11/11] fix(merge-gateway): mark chat models as non-reasoning --- providers/merge-gateway/models/openai/gpt-5-chat-latest.toml | 2 +- providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml | 2 +- providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml index f2fc62c7e1..b3163c8c70 100644 --- a/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5-chat-latest.toml @@ -3,7 +3,7 @@ base_model = "openai/gpt-5-chat-latest" base_model_omit = ["limit.input"] name = "GPT-5 Chat Latest" -reasoning_options = [] +reasoning = false [cost] input = 1.25 diff --git a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml index 401c51d7f0..76e46da03a 100644 --- a/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.1-chat-latest.toml @@ -2,7 +2,7 @@ base_model = "openai/gpt-5.1-chat-latest" name = "GPT-5.1 Chat Latest" -reasoning_options = [] +reasoning = false [cost] input = 1.25 diff --git a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml index 5693ae08ab..dc6efbc6d0 100644 --- a/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml +++ b/providers/merge-gateway/models/openai/gpt-5.2-chat-latest.toml @@ -2,7 +2,7 @@ base_model = "openai/gpt-5.2-chat-latest" name = "GPT-5.2 Chat Latest" -reasoning_options = [] +reasoning = false [cost] input = 1.75