From 2f08fe2579f1e2cfc3021855640bc980f0c2cfa2 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Thu, 10 Sep 2026 14:13:37 -0400 Subject: [PATCH 01/15] feat(nearai): add catalog sync provider --- package.json | 1 + packages/core/src/sync/index.ts | 5 +- packages/core/src/sync/providers/nearai.ts | 170 ++++++++++++++++++ packages/core/test/nearai.test.ts | 142 +++++++++++++++ .../Qwen/Qwen3-VL-30B-A3B-Instruct.toml | 5 +- .../models/Qwen/Qwen3.6-35B-A3B-FP8.toml | 7 +- .../models/anthropic/claude-haiku-4-5.toml | 9 +- .../models/anthropic/claude-opus-4-6.toml | 10 +- .../models/anthropic/claude-opus-4-7.toml | 8 +- .../models/anthropic/claude-sonnet-4-5.toml | 14 +- .../models/anthropic/claude-sonnet-4-6.toml | 12 +- .../black-forest-labs/FLUX.2-klein-4B.toml | 6 +- .../models/google/gemini-2.5-flash-lite.toml | 3 + .../models/google/gemini-2.5-flash.toml | 4 + .../nearai/models/google/gemini-2.5-pro.toml | 4 + .../models/google/gemini-3.1-flash-lite.toml | 3 + .../models/google/gemini-3.5-flash.toml | 4 + .../nearai/models/openai/gpt-4.1-mini.toml | 4 + .../nearai/models/openai/gpt-4.1-nano.toml | 4 + providers/nearai/models/openai/gpt-4.1.toml | 4 + .../nearai/models/openai/gpt-5-mini.toml | 8 +- .../nearai/models/openai/gpt-5-nano.toml | 8 +- providers/nearai/models/openai/gpt-5.1.toml | 8 +- providers/nearai/models/openai/gpt-5.2.toml | 10 +- .../nearai/models/openai/gpt-5.4-mini.toml | 8 +- .../nearai/models/openai/gpt-5.4-nano.toml | 8 +- providers/nearai/models/openai/gpt-5.4.toml | 8 +- providers/nearai/models/openai/gpt-5.5.toml | 8 +- providers/nearai/models/openai/gpt-5.toml | 8 +- providers/nearai/models/openai/o3-mini.toml | 8 +- providers/nearai/models/openai/o3.toml | 8 +- providers/nearai/models/openai/o4-mini.toml | 8 +- .../models/openai/whisper-large-v3.toml | 2 +- .../nearai/models/zai-org/GLM-5.1-FP8.toml | 7 +- sync.md | 15 ++ 35 files changed, 511 insertions(+), 30 deletions(-) create mode 100644 packages/core/src/sync/providers/nearai.ts create mode 100644 packages/core/test/nearai.test.ts diff --git a/package.json b/package.json index 4a7b90393f7..b3c7ca651ce 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "requesty:sync": "bun ./packages/core/script/sync-models.ts requesty", "merge-gateway:sync": "bun ./packages/core/script/sync-models.ts merge-gateway", "nano-gpt:sync": "bun ./packages/core/script/sync-models.ts nano-gpt", + "nearai:sync": "bun ./packages/core/script/sync-models.ts nearai", "venice:sync": "bun ./packages/core/script/sync-models.ts venice", "tinfoil:sync": "bun ./packages/core/script/sync-models.ts tinfoil", "vercel:generate": "bun ./packages/core/script/sync-models.ts vercel", diff --git a/packages/core/src/sync/index.ts b/packages/core/src/sync/index.ts index 7f88aacb5bb..e144e97a45b 100644 --- a/packages/core/src/sync/index.ts +++ b/packages/core/src/sync/index.ts @@ -28,6 +28,7 @@ import { llmgateway, llmgatewayProviders } from "./providers/llmgateway.js"; import { mergeGateway } from "./providers/merge-gateway.js"; import { meta } from "./providers/meta.js"; import { nanoGpt } from "./providers/nano-gpt.js"; +import { nearai } from "./providers/nearai.js"; import { openai } from "./providers/openai.js"; import { ofox } from "./providers/ofox.js"; import { openrouter } from "./providers/openrouter.js"; @@ -153,6 +154,7 @@ export const providers: { "merge-gateway": SyncProvider; meta: SyncProvider; "nano-gpt": SyncProvider; + nearai: SyncProvider; ofox: SyncProvider; openai: SyncProvider; openrouter: SyncProvider; @@ -188,6 +190,7 @@ export const providers: { "merge-gateway": mergeGateway, meta, "nano-gpt": nanoGpt, + nearai, ofox, openai, openrouter, @@ -219,7 +222,7 @@ export const groups = { "vercel", ], cloudflare: ["cloudflare-ai-gateway", "cloudflare-workers-ai"], - direct: ["ambient", "anthropic", "baseten", "chutes", "cortecs", "deepinfra", "digitalocean", "github-copilot", "google", "hyper", "meta", "openai", "ovhcloud", "pioneer", "tinfoil", "venice", "wandb", "xai"], + direct: ["ambient", "anthropic", "baseten", "chutes", "cortecs", "deepinfra", "digitalocean", "github-copilot", "google", "hyper", "meta", "nearai", "openai", "ovhcloud", "pioneer", "tinfoil", "venice", "wandb", "xai"], } as const; type ProviderID = keyof typeof providers; diff --git a/packages/core/src/sync/providers/nearai.ts b/packages/core/src/sync/providers/nearai.ts new file mode 100644 index 00000000000..920250fd247 --- /dev/null +++ b/packages/core/src/sync/providers/nearai.ts @@ -0,0 +1,170 @@ +import { z } from "zod"; + +import type { ExistingModel, SyncedFullModel, SyncedModel, SyncProvider } from "../index.js"; +import { factorBaseModel } from "./openrouter.js"; + +const API_ENDPOINT = "https://cloud-api.near.ai/v1/models"; + +const TOKENS_PER_PRICING_UNIT = 1_000_000; + +const NearAIPricing = z.object({ + input: z.number().nonnegative(), + output: z.number().nonnegative(), + input_cache_read: z.string().optional(), +}).passthrough(); + +export const NearAIModel = z.object({ + id: z.string().min(1), + object: z.literal("model"), + created: z.number().int().nonnegative(), + owned_by: z.string(), + name: z.string().min(1), + pricing: NearAIPricing, + context_length: z.number().int().positive(), + max_output_length: z.number().int().positive().optional(), + input_modalities: z.array(z.string()), + output_modalities: z.array(z.string()), + supported_features: z.array(z.string()), +}).passthrough(); + +export const NearAIResponse = z.object({ + object: z.literal("list"), + data: z.array(NearAIModel), +}).passthrough(); + +export type NearAIModel = z.infer; + +export const nearai = { + id: "nearai", + name: "NEAR AI Cloud", + modelsDir: "providers/nearai/models", + skipCreates: true, + // Much of the catalog has no local entry. Those are reported in the sync + // notice rather than filed as an issue each. + trackMissingModels: false, + // A truncated or degraded catalog response is indistinguishable from a + // genuine removal, so absence never proposes a delete. + deleteMissing: false, + sourceID(model) { + return model.id; + }, + skippedNotice(ids) { + if (ids.length === 0) return []; + return [ + `${ids.length} NEAR AI models were not created because the catalog exposes no release date, knowledge cutoff, or reasoning controls, and most of them reason.`, + `Skipped remote IDs: ${ids.map((id) => `\`${id}\``).join(", ")}`, + ]; + }, + async fetchModels() { + return fetchNearAIModels(); + }, + parseModels(raw) { + return NearAIResponse.parse(raw).data; + }, + translateModel(model, context) { + const existing = context.existing(model.id); + if (existing === undefined) return undefined; + return { + id: model.id, + model: buildNearAIModel(model, existing), + }; + }, +} satisfies SyncProvider; + +export async function fetchNearAIModels(fetcher: typeof fetch = fetch) { + const response = await fetcher(API_ENDPOINT); + if (!response.ok) { + throw new Error(`NEAR AI models request failed: ${response.status} ${response.statusText}`); + } + return NearAIResponse.parse(await response.json()); +} + +type Modality = SyncedFullModel["modalities"]["input"][number]; + +const MODALITIES = new Set(["text", "audio", "image", "video", "pdf"]); + +// Only ever adds: a modality the gateway leaves out is not proof the lab model +// rejects it. NEAR AI also reports `embedding`, which the schema has no value +// for, so unrepresentable entries are filtered instead of written. +function withModalities( + existing: Modality[] | undefined, + reported: string[], +): Modality[] | undefined { + if (existing === undefined) return undefined; + const additions = reported.filter( + (value): value is Modality => + MODALITIES.has(value as Modality) && !existing.includes(value as Modality), + ); + return additions.length === 0 ? existing : [...existing, ...additions]; +} + +function atMost(current: number | undefined, reported: number | undefined): number | undefined { + if (current === undefined) return reported; + if (reported === undefined) return current; + return Math.min(current, reported); +} + +// The catalog returns artifacts like 1.4000000000000001, and scaling per-token +// strings introduces its own, so every published price is rounded. +function price(value: number): number { + return Number(value.toFixed(6)); +} + +// Per-token strings, unlike the per-million `input` and `output` numbers. +function perMillion(value: string | undefined): number | undefined { + if (value === undefined) return undefined; + const parsed = Number(value); + return Number.isFinite(parsed) ? price(parsed * TOKENS_PER_PRICING_UNIT) : undefined; +} + +export function buildNearAIModel( + model: NearAIModel, + existing: ExistingModel, +): SyncedModel { + if (existing.cost === undefined) { + throw new Error(`NEAR AI model ${model.id} has incomplete local pricing required for sync`); + } + + const { base_model: baseModel, base_model_omit: baseModelOmit, ...current } = existing; + + const cost = { + ...existing.cost, + input: price(model.pricing.input), + output: price(model.pricing.output), + cache_read: perMillion(model.pricing.input_cache_read) ?? existing.cost.cache_read, + }; + + // The gateway may cap below the lab model, never above it. + const limit = { + ...existing.limit, + context: atMost(existing.limit?.context, model.context_length), + output: atMost(existing.limit?.output, model.max_output_length), + }; + + const input = withModalities(existing.modalities?.input, model.input_modalities); + const output = withModalities(existing.modalities?.output, model.output_modalities); + const modalities = input === undefined || output === undefined + ? existing.modalities + : { input, output }; + + const values = { + ...current, + // `supported_features` omits reasoning for relayed models that plainly + // reason, so it is only ever evidence FOR a capability, never against one. + // reasoning and reasoning_options stay hand-authored. + tool_call: model.supported_features.includes("tools") ? true : existing.tool_call, + structured_output: model.supported_features.includes("structured_outputs") + ? true + : existing.structured_output, + attachment: input === undefined + ? existing.attachment + : input.some((modality) => modality !== "text"), + cost, + limit, + modalities, + } as SyncedFullModel; + + return baseModel === undefined + ? values + : factorBaseModel(baseModel, values, limit, baseModelOmit); +} diff --git a/packages/core/test/nearai.test.ts b/packages/core/test/nearai.test.ts new file mode 100644 index 00000000000..27983afeebd --- /dev/null +++ b/packages/core/test/nearai.test.ts @@ -0,0 +1,142 @@ +import { expect, test } from "bun:test"; + +import type { ExistingModel } from "../src/sync/index.js"; +import { + buildNearAIModel, + type NearAIModel, +} from "../src/sync/providers/nearai.js"; + +function nearAIModel(overrides: Partial = {}): NearAIModel { + return { + id: "zai-org/GLM-5.1-FP8", + object: "model", + created: 1_759_104_000, + owned_by: "zai-org", + name: "GLM 5.1 FP8", + pricing: { input: 1.4, output: 4.4, input_cache_read: "0.00000026" }, + context_length: 202_752, + max_output_length: 16_384, + input_modalities: ["text"], + output_modalities: ["text"], + supported_features: ["tools", "structured_outputs", "reasoning"], + ...overrides, + }; +} + +// A full provider definition rather than a base_model overlay, so these assert +// the mapping itself instead of how factorBaseModel diffs against a lab file. +function authored(overrides: Record = {}): ExistingModel { + return { + name: "GLM 5.1 FP8", + reasoning: true, + reasoning_options: [{ type: "toggle" }], + tool_call: true, + structured_output: true, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_write: 0.5 }, + limit: { context: 202_752, output: 64_000 }, + modalities: { input: ["text", "pdf"], output: ["text"] }, + ...overrides, + } as ExistingModel; +} + +test("keeps hand-authored reasoning when the catalog omits the feature", () => { + const built = buildNearAIModel( + nearAIModel({ supported_features: ["tools"] }), + authored(), + ); + + expect(built).toMatchObject({ + reasoning: true, + reasoning_options: [{ type: "toggle" }], + }); +}); + +test("converts the per-token cache price to dollars per million tokens", () => { + const built = buildNearAIModel(nearAIModel(), authored()); + + expect(built).toMatchObject({ cost: { cache_read: 0.26 } }); +}); + +test("rounds away the catalog's floating point artifacts", () => { + const built = buildNearAIModel( + nearAIModel({ pricing: { input: 1.4000000000000001, output: 4.4 } }), + authored(), + ); + + expect(built).toMatchObject({ cost: { input: 1.4, output: 4.4 } }); +}); + +test("preserves a locally authored cost the catalog does not publish", () => { + const built = buildNearAIModel(nearAIModel(), authored()); + + expect(built).toMatchObject({ cost: { cache_write: 0.5 } }); +}); + +test("caps a limit the gateway serves lower and never raises one", () => { + const built = buildNearAIModel( + nearAIModel({ context_length: 1_000_000, max_output_length: 16_384 }), + authored(), + ); + + expect(built).toMatchObject({ limit: { context: 202_752, output: 16_384 } }); +}); + +test("retains a modality the gateway does not advertise", () => { + const built = buildNearAIModel(nearAIModel(), authored()); + + expect(built).toMatchObject({ modalities: { input: ["text", "pdf"] } }); +}); + +test("adds a modality the gateway advertises and the local entry lacks", () => { + const built = buildNearAIModel( + nearAIModel({ input_modalities: ["text", "image"] }), + authored(), + ); + + expect(built).toMatchObject({ modalities: { input: ["text", "pdf", "image"] } }); +}); + +test("ignores an output modality the catalog schema cannot express", () => { + const built = buildNearAIModel( + nearAIModel({ output_modalities: ["embedding"] }), + authored(), + ); + + expect(built).toMatchObject({ modalities: { output: ["text"] } }); +}); + +test("never withdraws a capability the catalog stops advertising", () => { + const built = buildNearAIModel( + nearAIModel({ supported_features: [] }), + authored(), + ); + + expect(built).toMatchObject({ tool_call: true, structured_output: true }); +}); + +test("marks a model with a non-text input as an attachment host", () => { + const built = buildNearAIModel( + nearAIModel({ input_modalities: ["text", "image"] }), + authored({ modalities: { input: ["text"], output: ["text"] } }), + ); + + expect(built).toMatchObject({ attachment: true }); +}); + +test("routes an overlay through the base model rather than inlining it", () => { + const built = buildNearAIModel( + nearAIModel({ id: "anthropic/claude-sonnet-4-5" }), + authored({ base_model: "anthropic/claude-sonnet-4-5" }), + ); + + expect(built).toMatchObject({ + base_model: "anthropic/claude-sonnet-4-5", + cost: { input: 1.4, output: 4.4 }, + }); +}); + +test("refuses to sync a model with no locally authored pricing", () => { + expect(() => buildNearAIModel(nearAIModel(), authored({ cost: undefined }))) + .toThrow(/incomplete local pricing/); +}); diff --git a/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml b/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml index 8503d559601..f738c9d1825 100644 --- a/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml +++ b/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml @@ -13,10 +13,11 @@ open_weights = true [cost] input = 0.15 output = 0.55 +cache_read = 0.03 [limit] -context = 16384 -output = 8192 +context = 16_384 +output = 8_192 [modalities] input = ["text", "image"] diff --git a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml index 6dd21027b99..6c252877780 100644 --- a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml +++ b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml @@ -1,6 +1,9 @@ base_model = "alibaba/qwen3.6-35b-a3b" -reasoning_options = [{ type = "toggle" }] name = "Qwen 3.6 35B A3B FP8" +attachment = false + +[[reasoning_options]] +type = "toggle" [cost] input = 0.17 @@ -8,7 +11,7 @@ output = 1.1 cache_read = 0.056 [limit] -output = 8192 +output = 8_192 [modalities] input = ["text"] diff --git a/providers/nearai/models/anthropic/claude-haiku-4-5.toml b/providers/nearai/models/anthropic/claude-haiku-4-5.toml index 5b433123ea1..31c1144753e 100644 --- a/providers/nearai/models/anthropic/claude-haiku-4-5.toml +++ b/providers/nearai/models/anthropic/claude-haiku-4-5.toml @@ -1,5 +1,12 @@ base_model = "anthropic/claude-haiku-4-5" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 [cost] input = 1 diff --git a/providers/nearai/models/anthropic/claude-opus-4-6.toml b/providers/nearai/models/anthropic/claude-opus-4-6.toml index 7eb9749db48..6cc7c9f82d4 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-6.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-6.toml @@ -1,5 +1,12 @@ base_model = "anthropic/claude-opus-4-6" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 [cost] input = 5 @@ -9,3 +16,4 @@ cache_write = 6.25 [limit] context = 200_000 +output = 32_768 diff --git a/providers/nearai/models/anthropic/claude-opus-4-7.toml b/providers/nearai/models/anthropic/claude-opus-4-7.toml index 13e2d208e24..bfa8e8818ab 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-7.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-7.toml @@ -1,8 +1,14 @@ base_model = "anthropic/claude-opus-4-7" -reasoning_options = [{ type = "toggle" }] +structured_output = true + +[[reasoning_options]] +type = "toggle" [cost] input = 5 output = 25 cache_read = 0.5 cache_write = 6.25 + +[limit] +output = 32_768 diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml index f6b5beba2ca..fe7a1a5d2d1 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml @@ -1,8 +1,18 @@ base_model = "anthropic/claude-sonnet-4-5" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 [cost] input = 3 -output = 15.0 +output = 15 cache_read = 0.3 cache_write = 3.75 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml index 54eeb5119e8..3f5fa1090b9 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml @@ -1,8 +1,18 @@ base_model = "anthropic/claude-sonnet-4-6" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] +structured_output = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +min = 1_024 [cost] input = 3 output = 15 cache_read = 0.3 cache_write = 3.75 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/black-forest-labs/FLUX.2-klein-4B.toml b/providers/nearai/models/black-forest-labs/FLUX.2-klein-4B.toml index 4745dd25339..44cdde74695 100644 --- a/providers/nearai/models/black-forest-labs/FLUX.2-klein-4B.toml +++ b/providers/nearai/models/black-forest-labs/FLUX.2-klein-4B.toml @@ -10,12 +10,12 @@ tool_call = false open_weights = true [cost] -input = 1.00 -output = 1.00 +input = 1 +output = 1 [limit] context = 128_000 -output = 128_000 +output = 1 [modalities] input = ["text"] diff --git a/providers/nearai/models/google/gemini-2.5-flash-lite.toml b/providers/nearai/models/google/gemini-2.5-flash-lite.toml index b503e6c2e5b..a8c24583d20 100644 --- a/providers/nearai/models/google/gemini-2.5-flash-lite.toml +++ b/providers/nearai/models/google/gemini-2.5-flash-lite.toml @@ -6,3 +6,6 @@ input = 0.1 output = 0.4 cache_read = 0.01 input_audio = 0.3 + +[limit] +output = 8_192 diff --git a/providers/nearai/models/google/gemini-2.5-flash.toml b/providers/nearai/models/google/gemini-2.5-flash.toml index 9256c5dcb66..0690475bf6c 100644 --- a/providers/nearai/models/google/gemini-2.5-flash.toml +++ b/providers/nearai/models/google/gemini-2.5-flash.toml @@ -6,3 +6,7 @@ input = 0.3 output = 2.5 cache_read = 0.03 input_audio = 1 + +[limit] +context = 1_000_000 +output = 8_192 diff --git a/providers/nearai/models/google/gemini-2.5-pro.toml b/providers/nearai/models/google/gemini-2.5-pro.toml index 1dd86d6408a..9356f31096c 100644 --- a/providers/nearai/models/google/gemini-2.5-pro.toml +++ b/providers/nearai/models/google/gemini-2.5-pro.toml @@ -11,3 +11,7 @@ tier = { type = "context", size = 200_000 } input = 2.5 output = 15 cache_read = 0.25 + +[limit] +context = 1_000_000 +output = 16_384 diff --git a/providers/nearai/models/google/gemini-3.1-flash-lite.toml b/providers/nearai/models/google/gemini-3.1-flash-lite.toml index b32d73c7f4c..66a7156ff85 100644 --- a/providers/nearai/models/google/gemini-3.1-flash-lite.toml +++ b/providers/nearai/models/google/gemini-3.1-flash-lite.toml @@ -6,3 +6,6 @@ input = 0.25 output = 1.5 cache_read = 0.025 input_audio = 0.5 + +[limit] +output = 8_192 diff --git a/providers/nearai/models/google/gemini-3.5-flash.toml b/providers/nearai/models/google/gemini-3.5-flash.toml index cdb6aa95773..2f40806187b 100644 --- a/providers/nearai/models/google/gemini-3.5-flash.toml +++ b/providers/nearai/models/google/gemini-3.5-flash.toml @@ -6,3 +6,7 @@ input = 1.5 output = 9 cache_read = 0.15 input_audio = 1.5 + +[limit] +context = 1_000_000 +output = 8_192 diff --git a/providers/nearai/models/openai/gpt-4.1-mini.toml b/providers/nearai/models/openai/gpt-4.1-mini.toml index b2d9217542d..fe8cb62c33b 100644 --- a/providers/nearai/models/openai/gpt-4.1-mini.toml +++ b/providers/nearai/models/openai/gpt-4.1-mini.toml @@ -4,3 +4,7 @@ base_model = "openai/gpt-4.1-mini" input = 0.4 output = 1.6 cache_read = 0.1 + +[limit] +context = 1_000_000 +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-4.1-nano.toml b/providers/nearai/models/openai/gpt-4.1-nano.toml index f85c0947701..5a4a6ed8db8 100644 --- a/providers/nearai/models/openai/gpt-4.1-nano.toml +++ b/providers/nearai/models/openai/gpt-4.1-nano.toml @@ -4,3 +4,7 @@ base_model = "openai/gpt-4.1-nano" input = 0.1 output = 0.4 cache_read = 0.025 + +[limit] +context = 1_000_000 +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-4.1.toml b/providers/nearai/models/openai/gpt-4.1.toml index 1fdb518f628..76c1a2a258f 100644 --- a/providers/nearai/models/openai/gpt-4.1.toml +++ b/providers/nearai/models/openai/gpt-4.1.toml @@ -4,3 +4,7 @@ base_model = "openai/gpt-4.1" input = 2 output = 8 cache_read = 0.5 + +[limit] +context = 1_000_000 +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5-mini.toml b/providers/nearai/models/openai/gpt-5-mini.toml index 5754d47df3f..b905c17880a 100644 --- a/providers/nearai/models/openai/gpt-5-mini.toml +++ b/providers/nearai/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 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5-nano.toml b/providers/nearai/models/openai/gpt-5-nano.toml index b96eddfd6f0..8d58a707769 100644 --- a/providers/nearai/models/openai/gpt-5-nano.toml +++ b/providers/nearai/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 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.1.toml b/providers/nearai/models/openai/gpt-5.1.toml index 489f83fffcb..d3caf9c3ab8 100644 --- a/providers/nearai/models/openai/gpt-5.1.toml +++ b/providers/nearai/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 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.2.toml b/providers/nearai/models/openai/gpt-5.2.toml index 839990b6c17..0694ed32085 100644 --- a/providers/nearai/models/openai/gpt-5.2.toml +++ b/providers/nearai/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.0 +output = 14 cache_read = 0.175 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.4-mini.toml b/providers/nearai/models/openai/gpt-5.4-mini.toml index 36bc93ba6e3..e9d92cf0813 100644 --- a/providers/nearai/models/openai/gpt-5.4-mini.toml +++ b/providers/nearai/models/openai/gpt-5.4-mini.toml @@ -1,7 +1,13 @@ base_model = "openai/gpt-5.4-mini" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] + +[[reasoning_options]] +type = "effort" +values = ["none", "low", "medium", "high", "xhigh"] [cost] input = 0.75 output = 4.5 cache_read = 0.075 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.4-nano.toml b/providers/nearai/models/openai/gpt-5.4-nano.toml index 3872b109a25..fdcc18c585c 100644 --- a/providers/nearai/models/openai/gpt-5.4-nano.toml +++ b/providers/nearai/models/openai/gpt-5.4-nano.toml @@ -1,7 +1,13 @@ base_model = "openai/gpt-5.4-nano" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] + +[[reasoning_options]] +type = "effort" +values = ["none", "low", "medium", "high", "xhigh"] [cost] input = 0.2 output = 1.25 cache_read = 0.02 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.4.toml b/providers/nearai/models/openai/gpt-5.4.toml index 230eac09d35..4e47b1f2d2b 100644 --- a/providers/nearai/models/openai/gpt-5.4.toml +++ b/providers/nearai/models/openai/gpt-5.4.toml @@ -1,5 +1,8 @@ base_model = "openai/gpt-5.4" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] + +[[reasoning_options]] +type = "effort" +values = ["none", "low", "medium", "high", "xhigh"] [cost] input = 2.5 @@ -11,3 +14,6 @@ tier = { type = "context", size = 272_000 } input = 5 output = 22.5 cache_read = 0.5 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.5.toml b/providers/nearai/models/openai/gpt-5.5.toml index 07a4af278d0..8e8d8f7b0fa 100644 --- a/providers/nearai/models/openai/gpt-5.5.toml +++ b/providers/nearai/models/openai/gpt-5.5.toml @@ -1,5 +1,8 @@ base_model = "openai/gpt-5.5" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] + +[[reasoning_options]] +type = "effort" +values = ["none", "low", "medium", "high", "xhigh"] [cost] input = 5 @@ -11,3 +14,6 @@ tier = { type = "context", size = 272_000 } input = 10 output = 45 cache_read = 1 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.toml b/providers/nearai/models/openai/gpt-5.toml index 104575502bb..b9be6204a18 100644 --- a/providers/nearai/models/openai/gpt-5.toml +++ b/providers/nearai/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 + +[limit] +output = 16_384 diff --git a/providers/nearai/models/openai/o3-mini.toml b/providers/nearai/models/openai/o3-mini.toml index 716e4b6e1ac..83047b3c003 100644 --- a/providers/nearai/models/openai/o3-mini.toml +++ b/providers/nearai/models/openai/o3-mini.toml @@ -1,7 +1,13 @@ base_model = "openai/o3-mini" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high"] [cost] input = 1.1 output = 4.4 cache_read = 0.55 + +[limit] +output = 32_768 diff --git a/providers/nearai/models/openai/o3.toml b/providers/nearai/models/openai/o3.toml index da90132d618..938a517a8ad 100644 --- a/providers/nearai/models/openai/o3.toml +++ b/providers/nearai/models/openai/o3.toml @@ -1,7 +1,13 @@ base_model = "openai/o3" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high"] [cost] input = 2 output = 8 cache_read = 0.5 + +[limit] +output = 32_768 diff --git a/providers/nearai/models/openai/o4-mini.toml b/providers/nearai/models/openai/o4-mini.toml index b8f94a811e3..779da293d99 100644 --- a/providers/nearai/models/openai/o4-mini.toml +++ b/providers/nearai/models/openai/o4-mini.toml @@ -1,7 +1,13 @@ base_model = "openai/o4-mini" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] + +[[reasoning_options]] +type = "effort" +values = ["low", "medium", "high"] [cost] input = 1.1 output = 4.4 cache_read = 0.275 + +[limit] +output = 32_768 diff --git a/providers/nearai/models/openai/whisper-large-v3.toml b/providers/nearai/models/openai/whisper-large-v3.toml index 4d5dbf409ba..a8b39b903b9 100644 --- a/providers/nearai/models/openai/whisper-large-v3.toml +++ b/providers/nearai/models/openai/whisper-large-v3.toml @@ -3,7 +3,7 @@ description = "Speech transcription model for accurate audio-to-text and caption family = "whisper" release_date = "2023-11-06" last_updated = "2023-11-06" -attachment = false +attachment = true reasoning = false temperature = false tool_call = false diff --git a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml index 8043e4c0cf5..a4359065350 100644 --- a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml +++ b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml @@ -5,7 +5,6 @@ release_date = "2026-03-27" last_updated = "2026-03-27" attachment = false reasoning = true -reasoning_options = [{ type = "toggle" }] temperature = true tool_call = true structured_output = true @@ -14,13 +13,17 @@ open_weights = true [interleaved] field = "reasoning_content" +[[reasoning_options]] +type = "toggle" + [cost] input = 1.4 output = 4.4 +cache_read = 0.26 [limit] context = 202_752 -output = 16384 +output = 16_384 [modalities] input = ["text"] diff --git a/sync.md b/sync.md index 7595a924dc4..b6d859eba6d 100644 --- a/sync.md +++ b/sync.md @@ -22,6 +22,7 @@ The grouped sync targets are available for local convenience, but CI syncs each - `bun models:sync openai` syncs only OpenAI catalog availability. - `bun models:sync github-copilot` syncs only GitHub Copilot pricing. - `bun models:sync tinfoil` syncs only Tinfoil. +- `bun models:sync nearai` syncs only NEAR AI Cloud. - `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. - `bun models:sync --open-issues` opens GitHub issues for missing models (on by default only when `GITHUB_ACTIONS=true`). @@ -259,6 +260,20 @@ xAI is implemented in `packages/core/src/sync/providers/xai.ts`. - New token-priced chat, safety, and embedding models are not created automatically (`skipCreates`); each missing ID opens a deduped GitHub issue for hand-authored metadata. - Per-request tool, TTS, transcription, realtime, and document-processing services are ignored because their pricing cannot be represented by the token-cost schema. +## NEAR AI Cloud Notes + +- NEAR AI Cloud is implemented in `packages/core/src/sync/providers/nearai.ts`. +- Source endpoint: `https://cloud-api.near.ai/v1/models`. +- No authentication is required; the catalog is public, so the sync needs no repository secret. +- Existing models are updated from API-authoritative input, output and cached-input pricing, context windows, and output limits. +- `pricing.input` and `pricing.output` are already dollars per million tokens, while `pricing.input_cache_read` is per token and is scaled. Every published price is rounded because the endpoint returns artifacts such as `1.4000000000000001`. +- Limits are taken as the lower of the local value and the figure the gateway reports, so a smaller verified cap survives and a lower gateway ceiling is followed. +- `supported_features` omits `reasoning` for several relayed models that plainly reason, so it is treated as evidence for a capability and never against one. `reasoning`, `reasoning_options`, `interleaved` and lifecycle `status` stay hand-authored, and `tool_call` and `structured_output` are only ever added. +- Modalities are additive for the same reason. The endpoint also reports `embedding`, which the schema has no value for, so unrepresentable entries are ignored rather than written. +- New models are not created automatically (`skipCreates`) because the endpoint exposes no release date or knowledge cutoff, and most NEAR AI models reason and so need hand-authored controls. +- Remote-only models are listed in the sync notice rather than filed as issues (`trackMissingModels: false`), because a substantial part of the catalog has no local entry. +- Absence never removes a model (`deleteMissing: false`): a truncated response would be indistinguishable from a genuine withdrawal. + ## OpenAI Notes - OpenAI is implemented in `packages/core/src/sync/providers/openai.ts`. From 475ba0f99a2c7cd947cad21a6cb2892ec29e0770 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Thu, 10 Sep 2026 18:37:21 -0400 Subject: [PATCH 02/15] fix(nearai): sync only pricing and hosted-model context --- packages/core/src/sync/providers/nearai.ts | 54 ++++++------------- packages/core/test/nearai.test.ts | 38 +++++++++---- .../models/Qwen/Qwen3.6-35B-A3B-FP8.toml | 7 +-- .../models/anthropic/claude-opus-4-6.toml | 1 - .../models/anthropic/claude-opus-4-7.toml | 3 -- .../models/anthropic/claude-sonnet-4-5.toml | 3 -- .../models/anthropic/claude-sonnet-4-6.toml | 3 -- .../black-forest-labs/FLUX.2-klein-4B.toml | 6 +-- .../models/google/gemini-2.5-flash-lite.toml | 3 -- .../models/google/gemini-2.5-flash.toml | 4 -- .../nearai/models/google/gemini-2.5-pro.toml | 4 -- .../models/google/gemini-3.1-flash-lite.toml | 3 -- .../models/google/gemini-3.5-flash.toml | 4 -- .../nearai/models/openai/gpt-4.1-mini.toml | 4 -- .../nearai/models/openai/gpt-4.1-nano.toml | 4 -- providers/nearai/models/openai/gpt-4.1.toml | 4 -- .../nearai/models/openai/gpt-5-mini.toml | 8 +-- .../nearai/models/openai/gpt-5-nano.toml | 8 +-- providers/nearai/models/openai/gpt-5.1.toml | 8 +-- providers/nearai/models/openai/gpt-5.2.toml | 10 +--- .../nearai/models/openai/gpt-5.4-mini.toml | 8 +-- .../nearai/models/openai/gpt-5.4-nano.toml | 8 +-- providers/nearai/models/openai/gpt-5.4.toml | 8 +-- providers/nearai/models/openai/gpt-5.5.toml | 8 +-- providers/nearai/models/openai/gpt-5.toml | 8 +-- providers/nearai/models/openai/o3-mini.toml | 8 +-- providers/nearai/models/openai/o3.toml | 8 +-- providers/nearai/models/openai/o4-mini.toml | 8 +-- .../models/openai/whisper-large-v3.toml | 2 +- sync.md | 9 ++-- 30 files changed, 68 insertions(+), 186 deletions(-) diff --git a/packages/core/src/sync/providers/nearai.ts b/packages/core/src/sync/providers/nearai.ts index 920250fd247..51e6f07b609 100644 --- a/packages/core/src/sync/providers/nearai.ts +++ b/packages/core/src/sync/providers/nearai.ts @@ -7,6 +7,8 @@ const API_ENDPOINT = "https://cloud-api.near.ai/v1/models"; const TOKENS_PER_PRICING_UNIT = 1_000_000; +const HOSTED_BY_NEAR_AI = "nearai"; + const NearAIPricing = z.object({ input: z.number().nonnegative(), output: z.number().nonnegative(), @@ -79,25 +81,6 @@ export async function fetchNearAIModels(fetcher: typeof fetch = fetch) { return NearAIResponse.parse(await response.json()); } -type Modality = SyncedFullModel["modalities"]["input"][number]; - -const MODALITIES = new Set(["text", "audio", "image", "video", "pdf"]); - -// Only ever adds: a modality the gateway leaves out is not proof the lab model -// rejects it. NEAR AI also reports `embedding`, which the schema has no value -// for, so unrepresentable entries are filtered instead of written. -function withModalities( - existing: Modality[] | undefined, - reported: string[], -): Modality[] | undefined { - if (existing === undefined) return undefined; - const additions = reported.filter( - (value): value is Modality => - MODALITIES.has(value as Modality) && !existing.includes(value as Modality), - ); - return additions.length === 0 ? existing : [...existing, ...additions]; -} - function atMost(current: number | undefined, reported: number | undefined): number | undefined { if (current === undefined) return reported; if (reported === undefined) return current; @@ -134,34 +117,29 @@ export function buildNearAIModel( cache_read: perMillion(model.pricing.input_cache_read) ?? existing.cost.cache_read, }; - // The gateway may cap below the lab model, never above it. - const limit = { - ...existing.limit, - context: atMost(existing.limit?.context, model.context_length), - output: atMost(existing.limit?.output, model.max_output_length), - }; - - const input = withModalities(existing.modalities?.input, model.input_modalities); - const output = withModalities(existing.modalities?.output, model.output_modalities); - const modalities = input === undefined || output === undefined - ? existing.modalities - : { input, output }; + // `context_length` is the serving `max_model_len` only for models NEAR AI hosts + // itself. On relayed routes it is whatever the upstream aggregator reported and + // is often rounded below the lab figure, so it would publish a cap the host does + // not impose. `max_output_length` is advisory even on hosted models: requests + // above it succeed, and only exceeding the context window is rejected. So output + // is never synced, and context only for hosted models, capped downward. + const limit = model.owned_by === HOSTED_BY_NEAR_AI + ? { ...existing.limit, context: atMost(existing.limit?.context, model.context_length) } + : existing.limit; const values = { ...current, - // `supported_features` omits reasoning for relayed models that plainly - // reason, so it is only ever evidence FOR a capability, never against one. - // reasoning and reasoning_options stay hand-authored. + // The catalog misreports capabilities in both directions: `supported_features` + // omits reasoning for relayed models that plainly reason, and + // `input_modalities` claims image for routes that reject it. So these two + // flags are the only ones taken from it, and only to turn something on; + // reasoning, modalities and attachment stay hand-authored. tool_call: model.supported_features.includes("tools") ? true : existing.tool_call, structured_output: model.supported_features.includes("structured_outputs") ? true : existing.structured_output, - attachment: input === undefined - ? existing.attachment - : input.some((modality) => modality !== "text"), cost, limit, - modalities, } as SyncedFullModel; return baseModel === undefined diff --git a/packages/core/test/nearai.test.ts b/packages/core/test/nearai.test.ts index 27983afeebd..e0711ca0986 100644 --- a/packages/core/test/nearai.test.ts +++ b/packages/core/test/nearai.test.ts @@ -73,13 +73,31 @@ test("preserves a locally authored cost the catalog does not publish", () => { expect(built).toMatchObject({ cost: { cache_write: 0.5 } }); }); -test("caps a limit the gateway serves lower and never raises one", () => { +test("caps context at the lower of local and gateway, and never raises it", () => { const built = buildNearAIModel( - nearAIModel({ context_length: 1_000_000, max_output_length: 16_384 }), - authored(), + nearAIModel({ owned_by: "nearai", context_length: 1_000_000 }), + authored({ limit: { context: 202_752, output: 131_072 } }), + ); + + expect(built).toMatchObject({ limit: { context: 202_752 } }); +}); + +test("ignores the context a relayed route reports, which can round below the lab", () => { + const built = buildNearAIModel( + nearAIModel({ owned_by: "openai", context_length: 1_000_000 }), + authored({ limit: { context: 1_047_576, output: 32_768 } }), + ); + + expect(built).toMatchObject({ limit: { context: 1_047_576 } }); +}); + +test("leaves the output limit authored, since max_output_length is not enforced", () => { + const built = buildNearAIModel( + nearAIModel({ max_output_length: 16_384 }), + authored({ limit: { context: 202_752, output: 131_072 } }), ); - expect(built).toMatchObject({ limit: { context: 202_752, output: 16_384 } }); + expect(built).toMatchObject({ limit: { output: 131_072 } }); }); test("retains a modality the gateway does not advertise", () => { @@ -88,13 +106,13 @@ test("retains a modality the gateway does not advertise", () => { expect(built).toMatchObject({ modalities: { input: ["text", "pdf"] } }); }); -test("adds a modality the gateway advertises and the local entry lacks", () => { +test("does not widen a hand-narrowed modality the gateway over-reports", () => { const built = buildNearAIModel( nearAIModel({ input_modalities: ["text", "image"] }), - authored(), + authored({ modalities: { input: ["text"], output: ["text"] } }), ); - expect(built).toMatchObject({ modalities: { input: ["text", "pdf", "image"] } }); + expect(built).toMatchObject({ modalities: { input: ["text"] } }); }); test("ignores an output modality the catalog schema cannot express", () => { @@ -115,13 +133,13 @@ test("never withdraws a capability the catalog stops advertising", () => { expect(built).toMatchObject({ tool_call: true, structured_output: true }); }); -test("marks a model with a non-text input as an attachment host", () => { +test("leaves attachment as authored when the gateway claims an image route", () => { const built = buildNearAIModel( nearAIModel({ input_modalities: ["text", "image"] }), - authored({ modalities: { input: ["text"], output: ["text"] } }), + authored({ attachment: false, modalities: { input: ["text"], output: ["text"] } }), ); - expect(built).toMatchObject({ attachment: true }); + expect(built).toMatchObject({ attachment: false }); }); test("routes an overlay through the base model rather than inlining it", () => { diff --git a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml index 6c252877780..6dd21027b99 100644 --- a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml +++ b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml @@ -1,9 +1,6 @@ base_model = "alibaba/qwen3.6-35b-a3b" +reasoning_options = [{ type = "toggle" }] name = "Qwen 3.6 35B A3B FP8" -attachment = false - -[[reasoning_options]] -type = "toggle" [cost] input = 0.17 @@ -11,7 +8,7 @@ output = 1.1 cache_read = 0.056 [limit] -output = 8_192 +output = 8192 [modalities] input = ["text"] diff --git a/providers/nearai/models/anthropic/claude-opus-4-6.toml b/providers/nearai/models/anthropic/claude-opus-4-6.toml index 6cc7c9f82d4..708cba3dbbc 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-6.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-6.toml @@ -16,4 +16,3 @@ cache_write = 6.25 [limit] context = 200_000 -output = 32_768 diff --git a/providers/nearai/models/anthropic/claude-opus-4-7.toml b/providers/nearai/models/anthropic/claude-opus-4-7.toml index bfa8e8818ab..5bc807681de 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-7.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-7.toml @@ -9,6 +9,3 @@ input = 5 output = 25 cache_read = 0.5 cache_write = 6.25 - -[limit] -output = 32_768 diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml index fe7a1a5d2d1..62c609b1094 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml @@ -13,6 +13,3 @@ input = 3 output = 15 cache_read = 0.3 cache_write = 3.75 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml index 3f5fa1090b9..b92f618bc50 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml @@ -13,6 +13,3 @@ input = 3 output = 15 cache_read = 0.3 cache_write = 3.75 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/black-forest-labs/FLUX.2-klein-4B.toml b/providers/nearai/models/black-forest-labs/FLUX.2-klein-4B.toml index 44cdde74695..4745dd25339 100644 --- a/providers/nearai/models/black-forest-labs/FLUX.2-klein-4B.toml +++ b/providers/nearai/models/black-forest-labs/FLUX.2-klein-4B.toml @@ -10,12 +10,12 @@ tool_call = false open_weights = true [cost] -input = 1 -output = 1 +input = 1.00 +output = 1.00 [limit] context = 128_000 -output = 1 +output = 128_000 [modalities] input = ["text"] diff --git a/providers/nearai/models/google/gemini-2.5-flash-lite.toml b/providers/nearai/models/google/gemini-2.5-flash-lite.toml index a8c24583d20..b503e6c2e5b 100644 --- a/providers/nearai/models/google/gemini-2.5-flash-lite.toml +++ b/providers/nearai/models/google/gemini-2.5-flash-lite.toml @@ -6,6 +6,3 @@ input = 0.1 output = 0.4 cache_read = 0.01 input_audio = 0.3 - -[limit] -output = 8_192 diff --git a/providers/nearai/models/google/gemini-2.5-flash.toml b/providers/nearai/models/google/gemini-2.5-flash.toml index 0690475bf6c..9256c5dcb66 100644 --- a/providers/nearai/models/google/gemini-2.5-flash.toml +++ b/providers/nearai/models/google/gemini-2.5-flash.toml @@ -6,7 +6,3 @@ input = 0.3 output = 2.5 cache_read = 0.03 input_audio = 1 - -[limit] -context = 1_000_000 -output = 8_192 diff --git a/providers/nearai/models/google/gemini-2.5-pro.toml b/providers/nearai/models/google/gemini-2.5-pro.toml index 9356f31096c..1dd86d6408a 100644 --- a/providers/nearai/models/google/gemini-2.5-pro.toml +++ b/providers/nearai/models/google/gemini-2.5-pro.toml @@ -11,7 +11,3 @@ tier = { type = "context", size = 200_000 } input = 2.5 output = 15 cache_read = 0.25 - -[limit] -context = 1_000_000 -output = 16_384 diff --git a/providers/nearai/models/google/gemini-3.1-flash-lite.toml b/providers/nearai/models/google/gemini-3.1-flash-lite.toml index 66a7156ff85..b32d73c7f4c 100644 --- a/providers/nearai/models/google/gemini-3.1-flash-lite.toml +++ b/providers/nearai/models/google/gemini-3.1-flash-lite.toml @@ -6,6 +6,3 @@ input = 0.25 output = 1.5 cache_read = 0.025 input_audio = 0.5 - -[limit] -output = 8_192 diff --git a/providers/nearai/models/google/gemini-3.5-flash.toml b/providers/nearai/models/google/gemini-3.5-flash.toml index 2f40806187b..cdb6aa95773 100644 --- a/providers/nearai/models/google/gemini-3.5-flash.toml +++ b/providers/nearai/models/google/gemini-3.5-flash.toml @@ -6,7 +6,3 @@ input = 1.5 output = 9 cache_read = 0.15 input_audio = 1.5 - -[limit] -context = 1_000_000 -output = 8_192 diff --git a/providers/nearai/models/openai/gpt-4.1-mini.toml b/providers/nearai/models/openai/gpt-4.1-mini.toml index fe8cb62c33b..b2d9217542d 100644 --- a/providers/nearai/models/openai/gpt-4.1-mini.toml +++ b/providers/nearai/models/openai/gpt-4.1-mini.toml @@ -4,7 +4,3 @@ base_model = "openai/gpt-4.1-mini" input = 0.4 output = 1.6 cache_read = 0.1 - -[limit] -context = 1_000_000 -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-4.1-nano.toml b/providers/nearai/models/openai/gpt-4.1-nano.toml index 5a4a6ed8db8..f85c0947701 100644 --- a/providers/nearai/models/openai/gpt-4.1-nano.toml +++ b/providers/nearai/models/openai/gpt-4.1-nano.toml @@ -4,7 +4,3 @@ base_model = "openai/gpt-4.1-nano" input = 0.1 output = 0.4 cache_read = 0.025 - -[limit] -context = 1_000_000 -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-4.1.toml b/providers/nearai/models/openai/gpt-4.1.toml index 76c1a2a258f..1fdb518f628 100644 --- a/providers/nearai/models/openai/gpt-4.1.toml +++ b/providers/nearai/models/openai/gpt-4.1.toml @@ -4,7 +4,3 @@ base_model = "openai/gpt-4.1" input = 2 output = 8 cache_read = 0.5 - -[limit] -context = 1_000_000 -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5-mini.toml b/providers/nearai/models/openai/gpt-5-mini.toml index b905c17880a..5754d47df3f 100644 --- a/providers/nearai/models/openai/gpt-5-mini.toml +++ b/providers/nearai/models/openai/gpt-5-mini.toml @@ -1,13 +1,7 @@ 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 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5-nano.toml b/providers/nearai/models/openai/gpt-5-nano.toml index 8d58a707769..b96eddfd6f0 100644 --- a/providers/nearai/models/openai/gpt-5-nano.toml +++ b/providers/nearai/models/openai/gpt-5-nano.toml @@ -1,13 +1,7 @@ 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 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.1.toml b/providers/nearai/models/openai/gpt-5.1.toml index d3caf9c3ab8..489f83fffcb 100644 --- a/providers/nearai/models/openai/gpt-5.1.toml +++ b/providers/nearai/models/openai/gpt-5.1.toml @@ -1,13 +1,7 @@ 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 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.2.toml b/providers/nearai/models/openai/gpt-5.2.toml index 0694ed32085..839990b6c17 100644 --- a/providers/nearai/models/openai/gpt-5.2.toml +++ b/providers/nearai/models/openai/gpt-5.2.toml @@ -1,13 +1,7 @@ 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 +output = 14.0 cache_read = 0.175 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.4-mini.toml b/providers/nearai/models/openai/gpt-5.4-mini.toml index e9d92cf0813..36bc93ba6e3 100644 --- a/providers/nearai/models/openai/gpt-5.4-mini.toml +++ b/providers/nearai/models/openai/gpt-5.4-mini.toml @@ -1,13 +1,7 @@ base_model = "openai/gpt-5.4-mini" - -[[reasoning_options]] -type = "effort" -values = ["none", "low", "medium", "high", "xhigh"] +reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] input = 0.75 output = 4.5 cache_read = 0.075 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.4-nano.toml b/providers/nearai/models/openai/gpt-5.4-nano.toml index fdcc18c585c..3872b109a25 100644 --- a/providers/nearai/models/openai/gpt-5.4-nano.toml +++ b/providers/nearai/models/openai/gpt-5.4-nano.toml @@ -1,13 +1,7 @@ base_model = "openai/gpt-5.4-nano" - -[[reasoning_options]] -type = "effort" -values = ["none", "low", "medium", "high", "xhigh"] +reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] input = 0.2 output = 1.25 cache_read = 0.02 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.4.toml b/providers/nearai/models/openai/gpt-5.4.toml index 4e47b1f2d2b..230eac09d35 100644 --- a/providers/nearai/models/openai/gpt-5.4.toml +++ b/providers/nearai/models/openai/gpt-5.4.toml @@ -1,8 +1,5 @@ base_model = "openai/gpt-5.4" - -[[reasoning_options]] -type = "effort" -values = ["none", "low", "medium", "high", "xhigh"] +reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] input = 2.5 @@ -14,6 +11,3 @@ tier = { type = "context", size = 272_000 } input = 5 output = 22.5 cache_read = 0.5 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.5.toml b/providers/nearai/models/openai/gpt-5.5.toml index 8e8d8f7b0fa..07a4af278d0 100644 --- a/providers/nearai/models/openai/gpt-5.5.toml +++ b/providers/nearai/models/openai/gpt-5.5.toml @@ -1,8 +1,5 @@ base_model = "openai/gpt-5.5" - -[[reasoning_options]] -type = "effort" -values = ["none", "low", "medium", "high", "xhigh"] +reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] input = 5 @@ -14,6 +11,3 @@ tier = { type = "context", size = 272_000 } input = 10 output = 45 cache_read = 1 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/openai/gpt-5.toml b/providers/nearai/models/openai/gpt-5.toml index b9be6204a18..104575502bb 100644 --- a/providers/nearai/models/openai/gpt-5.toml +++ b/providers/nearai/models/openai/gpt-5.toml @@ -1,13 +1,7 @@ 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 - -[limit] -output = 16_384 diff --git a/providers/nearai/models/openai/o3-mini.toml b/providers/nearai/models/openai/o3-mini.toml index 83047b3c003..716e4b6e1ac 100644 --- a/providers/nearai/models/openai/o3-mini.toml +++ b/providers/nearai/models/openai/o3-mini.toml @@ -1,13 +1,7 @@ base_model = "openai/o3-mini" - -[[reasoning_options]] -type = "effort" -values = ["low", "medium", "high"] +reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] [cost] input = 1.1 output = 4.4 cache_read = 0.55 - -[limit] -output = 32_768 diff --git a/providers/nearai/models/openai/o3.toml b/providers/nearai/models/openai/o3.toml index 938a517a8ad..da90132d618 100644 --- a/providers/nearai/models/openai/o3.toml +++ b/providers/nearai/models/openai/o3.toml @@ -1,13 +1,7 @@ base_model = "openai/o3" - -[[reasoning_options]] -type = "effort" -values = ["low", "medium", "high"] +reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] [cost] input = 2 output = 8 cache_read = 0.5 - -[limit] -output = 32_768 diff --git a/providers/nearai/models/openai/o4-mini.toml b/providers/nearai/models/openai/o4-mini.toml index 779da293d99..b8f94a811e3 100644 --- a/providers/nearai/models/openai/o4-mini.toml +++ b/providers/nearai/models/openai/o4-mini.toml @@ -1,13 +1,7 @@ base_model = "openai/o4-mini" - -[[reasoning_options]] -type = "effort" -values = ["low", "medium", "high"] +reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] [cost] input = 1.1 output = 4.4 cache_read = 0.275 - -[limit] -output = 32_768 diff --git a/providers/nearai/models/openai/whisper-large-v3.toml b/providers/nearai/models/openai/whisper-large-v3.toml index a8b39b903b9..4d5dbf409ba 100644 --- a/providers/nearai/models/openai/whisper-large-v3.toml +++ b/providers/nearai/models/openai/whisper-large-v3.toml @@ -3,7 +3,7 @@ description = "Speech transcription model for accurate audio-to-text and caption family = "whisper" release_date = "2023-11-06" last_updated = "2023-11-06" -attachment = true +attachment = false reasoning = false temperature = false tool_call = false diff --git a/sync.md b/sync.md index b6d859eba6d..55a1bbd0a66 100644 --- a/sync.md +++ b/sync.md @@ -265,11 +265,12 @@ xAI is implemented in `packages/core/src/sync/providers/xai.ts`. - NEAR AI Cloud is implemented in `packages/core/src/sync/providers/nearai.ts`. - Source endpoint: `https://cloud-api.near.ai/v1/models`. - No authentication is required; the catalog is public, so the sync needs no repository secret. -- Existing models are updated from API-authoritative input, output and cached-input pricing, context windows, and output limits. +- Existing models are updated from API-authoritative input, output and cached-input pricing, and context windows. Nothing else is taken from the endpoint. - `pricing.input` and `pricing.output` are already dollars per million tokens, while `pricing.input_cache_read` is per token and is scaled. Every published price is rounded because the endpoint returns artifacts such as `1.4000000000000001`. -- Limits are taken as the lower of the local value and the figure the gateway reports, so a smaller verified cap survives and a lower gateway ceiling is followed. -- `supported_features` omits `reasoning` for several relayed models that plainly reason, so it is treated as evidence for a capability and never against one. `reasoning`, `reasoning_options`, `interleaved` and lifecycle `status` stay hand-authored, and `tool_call` and `structured_output` are only ever added. -- Modalities are additive for the same reason. The endpoint also reports `embedding`, which the schema has no value for, so unrepresentable entries are ignored rather than written. +- `context` is synced only for models NEAR AI hosts itself (`owned_by = "nearai"`), where `context_length` is the serving `max_model_len`. On relayed routes the figure comes from the upstream aggregator and is often rounded below the lab entry, so syncing it would publish a cap the host does not impose. Where it is synced it is taken as the lower of the two values, so a smaller verified cap survives. +- `limit.output` is never synced. `max_output_length` is advisory rather than enforced: a request above it is accepted, and only exceeding the context window is rejected. +- The endpoint misreports capabilities in both directions, so most of them are not synced. `supported_features` omits `reasoning` for several relayed models that plainly reason, and `input_modalities` advertises image input for routes that reject it on a live request. `tool_call` and `structured_output` are the only capability fields taken from it, and only ever to turn one on. +- `reasoning`, `reasoning_options`, `modalities`, `attachment`, `interleaved` and lifecycle `status` stay hand-authored. The endpoint also reports an `embedding` modality the schema has no value for, which is a further reason not to write modalities from it. - New models are not created automatically (`skipCreates`) because the endpoint exposes no release date or knowledge cutoff, and most NEAR AI models reason and so need hand-authored controls. - Remote-only models are listed in the sync notice rather than filed as issues (`trackMissingModels: false`), because a substantial part of the catalog has no local entry. - Absence never removes a model (`deleteMissing: false`): a truncated response would be indistinguishable from a genuine withdrawal. From 58c6a7b96b4f0b0b8d36ce635241f083da537cba Mon Sep 17 00:00:00 2001 From: Lloyd Mak Date: Tue, 8 Sep 2026 22:58:15 +0000 Subject: [PATCH 03/15] nearai: sync catalog with cloud-api.near.ai and rank TEE models first Refresh providers/nearai against the live gateway model list (https://cloud-api.near.ai/v1/models, checked 2026-09-08). - Add 19 models now served by the gateway: GLM 5.2, GLM 5.3 Flash, DeepSeek V4 Flash and Qwen 3.8 27B on NEAR TEE hosts, plus the pass-through routes for Claude Fable 5/5.1, Opus 4.8, Opus 5, Sonnet 5, GPT-5.6 Luna/Sol, GPT-6 Astra, Gemini 3.8 Flash, Kimi K2.6/K3, DeepSeek V3.2, Qwen3 32B, Qwen3.5 397B and Qwen3.7 Max. - Remove 5 models the gateway no longer lists: gemini-3-pro, gemma-4-31B-it, gpt-oss-120b, Qwen3-30B-A3B-Instruct-2507, Qwen3.5-122B-A10B. - Fix prices for GLM-5.1-FP8, gpt-5.2 and claude-sonnet-4-5. - Convert GLM-5.1-FP8 to base_model = "zhipuai/glm-5.1". - Fix Qwen3-VL-30B limits to the served max_model_len (16 384). - NEAR-hosted TEE entries carry a " TEE" name suffix and a release_date/last_updated of the TEE catalog refresh, following the Chutes TEE convention, so they sort first in date-ordered pickers. Reasoning controls were verified live against the gateway: GLM 5.2 / 5.3 Flash / Qwen 3.8 toggle with chat_template_kwargs.enable_thinking; DeepSeek V4 Flash (off by default) and Kimi K3 toggle with chat_template_kwargs.thinking. --- .../Qwen/Qwen3-VL-30B-A3B-Instruct.toml | 6 ++-- .../models/Qwen/Qwen3.6-35B-A3B-FP8.toml | 13 +++++++-- providers/nearai/models/Qwen/Qwen3.8-27B.toml | 21 ++++++++++++++ .../models/anthropic/claude-fable-5-1.toml | 10 +++++++ .../models/anthropic/claude-fable-5.toml | 10 +++++++ .../models/anthropic/claude-opus-4-8.toml | 10 +++++++ .../models/anthropic/claude-opus-5.toml | 10 +++++++ .../models/anthropic/claude-sonnet-5.toml | 10 +++++++ .../models/deepseek-ai/DeepSeek-V4-Flash.toml | 21 ++++++++++++++ .../nearai/models/deepseek/deepseek-v3.2.toml | 7 +++++ .../models/google/gemini-3.8-flash.toml | 10 +++++++ .../nearai/models/moonshotai/kimi-k2.6.toml | 15 ++++++++++ .../nearai/models/moonshotai/kimi-k3.toml | 16 +++++++++++ providers/nearai/models/openai/gpt-5.2.toml | 2 +- .../nearai/models/openai/gpt-5.6-luna.toml | 10 +++++++ .../nearai/models/openai/gpt-5.6-sol.toml | 10 +++++++ .../nearai/models/openai/gpt-6-astra.toml | 10 +++++++ providers/nearai/models/qwen/qwen3-32b.toml | 7 +++++ .../nearai/models/qwen/qwen3.5-397b-a17b.toml | 11 ++++++++ providers/nearai/models/qwen/qwen3.7-max.toml | 6 ++++ providers/nearai/models/z-ai/glm-5.2.toml | 18 ++++++++++++ .../nearai/models/z-ai/glm-5.3-flash.toml | 21 ++++++++++++++ .../nearai/models/zai-org/GLM-5.1-FP8.toml | 28 ++++++------------- 23 files changed, 258 insertions(+), 24 deletions(-) create mode 100644 providers/nearai/models/Qwen/Qwen3.8-27B.toml create mode 100644 providers/nearai/models/anthropic/claude-fable-5-1.toml create mode 100644 providers/nearai/models/anthropic/claude-fable-5.toml create mode 100644 providers/nearai/models/anthropic/claude-opus-4-8.toml create mode 100644 providers/nearai/models/anthropic/claude-opus-5.toml create mode 100644 providers/nearai/models/anthropic/claude-sonnet-5.toml create mode 100644 providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml create mode 100644 providers/nearai/models/deepseek/deepseek-v3.2.toml create mode 100644 providers/nearai/models/google/gemini-3.8-flash.toml create mode 100644 providers/nearai/models/moonshotai/kimi-k2.6.toml create mode 100644 providers/nearai/models/moonshotai/kimi-k3.toml create mode 100644 providers/nearai/models/openai/gpt-5.6-luna.toml create mode 100644 providers/nearai/models/openai/gpt-5.6-sol.toml create mode 100644 providers/nearai/models/openai/gpt-6-astra.toml create mode 100644 providers/nearai/models/qwen/qwen3-32b.toml create mode 100644 providers/nearai/models/qwen/qwen3.5-397b-a17b.toml create mode 100644 providers/nearai/models/qwen/qwen3.7-max.toml create mode 100644 providers/nearai/models/z-ai/glm-5.2.toml create mode 100644 providers/nearai/models/z-ai/glm-5.3-flash.toml diff --git a/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml b/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml index f738c9d1825..882ba04ac36 100644 --- a/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml +++ b/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml @@ -1,8 +1,10 @@ -name = "Qwen3-VL 30B-A3B Instruct" +# NEAR AI Cloud TEE deployment. Served with max_model_len = 16 384 (verified on +# https://qwen3-vl-30b.completions.near.ai/v1/models 2026-09-08). +name = "Qwen3-VL 30B-A3B Instruct TEE" description = "Qwen vision-language model for visual reasoning, documents, and agent tasks" family = "qwen" release_date = "2025-09-23" -last_updated = "2025-09-23" +last_updated = "2026-09-08" attachment = true reasoning = false temperature = true diff --git a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml index 6dd21027b99..73fae40800b 100644 --- a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml +++ b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml @@ -1,6 +1,15 @@ +# NEAR AI Cloud TEE deployment (FP8). release_date/last_updated track the TEE catalog +# refresh, not the lab release (see models/alibaba/qwen3.6-35b-a3b.toml). +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) +# https://docs.near.ai/cloud/reasoning-models base_model = "alibaba/qwen3.6-35b-a3b" +name = "Qwen 3.6 35B A3B FP8 TEE" +release_date = "2026-09-08" +last_updated = "2026-09-08" reasoning_options = [{ type = "toggle" }] -name = "Qwen 3.6 35B A3B FP8" + +[interleaved] +field = "reasoning_content" [cost] input = 0.17 @@ -8,7 +17,7 @@ output = 1.1 cache_read = 0.056 [limit] -output = 8192 +output = 32_768 [modalities] input = ["text"] diff --git a/providers/nearai/models/Qwen/Qwen3.8-27B.toml b/providers/nearai/models/Qwen/Qwen3.8-27B.toml new file mode 100644 index 00000000000..d183917f3d8 --- /dev/null +++ b/providers/nearai/models/Qwen/Qwen3.8-27B.toml @@ -0,0 +1,21 @@ +# NEAR AI Cloud TEE deployment. release_date/last_updated track the TEE catalog +# refresh, not the lab release (see models/alibaba/qwen3.8-27b.toml). +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) +# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# reasoning_content present when on, absent when off +base_model = "alibaba/qwen3.8-27b" +name = "Qwen 3.8 27B TEE" +release_date = "2026-09-08" +last_updated = "2026-09-08" +reasoning_options = [{ type = "toggle" }] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.44 +output = 3.3 +cache_read = 0.044 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-fable-5-1.toml b/providers/nearai/models/anthropic/claude-fable-5-1.toml new file mode 100644 index 00000000000..c0531752328 --- /dev/null +++ b/providers/nearai/models/anthropic/claude-fable-5-1.toml @@ -0,0 +1,10 @@ +base_model = "anthropic/claude-fable-5-1" +reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] + +[cost] +input = 10 +output = 50 +cache_read = 0.25 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-fable-5.toml b/providers/nearai/models/anthropic/claude-fable-5.toml new file mode 100644 index 00000000000..ce034cad2e4 --- /dev/null +++ b/providers/nearai/models/anthropic/claude-fable-5.toml @@ -0,0 +1,10 @@ +base_model = "anthropic/claude-fable-5" +reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] + +[cost] +input = 10 +output = 50 +cache_read = 1 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-opus-4-8.toml b/providers/nearai/models/anthropic/claude-opus-4-8.toml new file mode 100644 index 00000000000..85d29c87360 --- /dev/null +++ b/providers/nearai/models/anthropic/claude-opus-4-8.toml @@ -0,0 +1,10 @@ +base_model = "anthropic/claude-opus-4-8" +reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] + +[cost] +input = 5 +output = 25 +cache_read = 0.5 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-opus-5.toml b/providers/nearai/models/anthropic/claude-opus-5.toml new file mode 100644 index 00000000000..65826817104 --- /dev/null +++ b/providers/nearai/models/anthropic/claude-opus-5.toml @@ -0,0 +1,10 @@ +base_model = "anthropic/claude-opus-5" +reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] + +[cost] +input = 5 +output = 25 +cache_read = 0.5 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-sonnet-5.toml b/providers/nearai/models/anthropic/claude-sonnet-5.toml new file mode 100644 index 00000000000..caa2b39e764 --- /dev/null +++ b/providers/nearai/models/anthropic/claude-sonnet-5.toml @@ -0,0 +1,10 @@ +base_model = "anthropic/claude-sonnet-5" +reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] + +[cost] +input = 2 +output = 10 +cache_read = 0.2 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml b/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml new file mode 100644 index 00000000000..252c2ac1104 --- /dev/null +++ b/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml @@ -0,0 +1,21 @@ +# NEAR AI Cloud TEE deployment of DeepSeek-V4-Flash-0731. release_date/last_updated +# track the TEE catalog refresh, not the lab release (see models/deepseek/deepseek-v4-flash-0731.toml). +# Toggle: chat_template_kwargs.thinking = true|false (OFF by default on this host) +# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# reasoning_content present when on, absent when off +base_model = "deepseek/deepseek-v4-flash-0731" +name = "DeepSeek V4 Flash TEE" +release_date = "2026-09-08" +last_updated = "2026-09-08" +reasoning_options = [{ type = "toggle" }] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.17 +output = 0.35 +cache_read = 0.035 + +[limit] +output = 131_072 diff --git a/providers/nearai/models/deepseek/deepseek-v3.2.toml b/providers/nearai/models/deepseek/deepseek-v3.2.toml new file mode 100644 index 00000000000..ef1cbed46f2 --- /dev/null +++ b/providers/nearai/models/deepseek/deepseek-v3.2.toml @@ -0,0 +1,7 @@ +base_model = "deepseek/deepseek-v3.2" +reasoning_options = [] + +[cost] +input = 1.1 +output = 1.1 +cache_read = 0.55 diff --git a/providers/nearai/models/google/gemini-3.8-flash.toml b/providers/nearai/models/google/gemini-3.8-flash.toml new file mode 100644 index 00000000000..a45a9f46b32 --- /dev/null +++ b/providers/nearai/models/google/gemini-3.8-flash.toml @@ -0,0 +1,10 @@ +base_model = "google/gemini-3.8-flash" +reasoning_options = [] + +[cost] +input = 0.75 +output = 3.75 +cache_read = 0.075 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/moonshotai/kimi-k2.6.toml b/providers/nearai/models/moonshotai/kimi-k2.6.toml new file mode 100644 index 00000000000..0005d97e87e --- /dev/null +++ b/providers/nearai/models/moonshotai/kimi-k2.6.toml @@ -0,0 +1,15 @@ +# Toggle: chat_template_kwargs.thinking = true|false (on by default); reasoning_effort is ignored +# https://docs.near.ai/cloud/reasoning-models +base_model = "moonshotai/kimi-k2.6" +reasoning_options = [{ type = "toggle" }] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.81 +output = 3.85 +cache_read = 0.41 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/moonshotai/kimi-k3.toml b/providers/nearai/models/moonshotai/kimi-k3.toml new file mode 100644 index 00000000000..96a99ab8fa6 --- /dev/null +++ b/providers/nearai/models/moonshotai/kimi-k3.toml @@ -0,0 +1,16 @@ +# Toggle: chat_template_kwargs.thinking = true|false (on by default); reasoning_effort is ignored +# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# reasoning_content present when on, absent when off +base_model = "moonshotai/kimi-k3" +reasoning_options = [{ type = "toggle" }] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 3.3 +output = 16.5 +cache_read = 0.33 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-5.2.toml b/providers/nearai/models/openai/gpt-5.2.toml index 839990b6c17..a2a20d0e325 100644 --- a/providers/nearai/models/openai/gpt-5.2.toml +++ b/providers/nearai/models/openai/gpt-5.2.toml @@ -3,5 +3,5 @@ reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high [cost] input = 1.75 -output = 14.0 +output = 14 cache_read = 0.175 diff --git a/providers/nearai/models/openai/gpt-5.6-luna.toml b/providers/nearai/models/openai/gpt-5.6-luna.toml new file mode 100644 index 00000000000..140c5ad9d41 --- /dev/null +++ b/providers/nearai/models/openai/gpt-5.6-luna.toml @@ -0,0 +1,10 @@ +base_model = "openai/gpt-5.6-luna" +reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh", "max"] }] + +[cost] +input = 0.2 +output = 1.2 +cache_read = 0.02 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-5.6-sol.toml b/providers/nearai/models/openai/gpt-5.6-sol.toml new file mode 100644 index 00000000000..4ff46a5b270 --- /dev/null +++ b/providers/nearai/models/openai/gpt-5.6-sol.toml @@ -0,0 +1,10 @@ +base_model = "openai/gpt-5.6-sol" +reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh", "max"] }] + +[cost] +input = 4 +output = 20 +cache_read = 0.4 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-6-astra.toml b/providers/nearai/models/openai/gpt-6-astra.toml new file mode 100644 index 00000000000..958ac130b7c --- /dev/null +++ b/providers/nearai/models/openai/gpt-6-astra.toml @@ -0,0 +1,10 @@ +base_model = "openai/gpt-6-astra" +reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] + +[cost] +input = 10 +output = 50 +cache_read = 1 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/qwen/qwen3-32b.toml b/providers/nearai/models/qwen/qwen3-32b.toml new file mode 100644 index 00000000000..de84a8e587f --- /dev/null +++ b/providers/nearai/models/qwen/qwen3-32b.toml @@ -0,0 +1,7 @@ +base_model = "alibaba/qwen3-32b" +reasoning_options = [] + +[cost] +input = 0.11 +output = 0.46 +cache_read = 0.06 diff --git a/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml b/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml new file mode 100644 index 00000000000..a743f88836e --- /dev/null +++ b/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml @@ -0,0 +1,11 @@ +base_model = "alibaba/qwen3.5-397b-a17b" +reasoning_options = [] +attachment = false + +[cost] +input = 0.5 +output = 3.3 +cache_read = 0.25 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/qwen/qwen3.7-max.toml b/providers/nearai/models/qwen/qwen3.7-max.toml new file mode 100644 index 00000000000..f94bd4bb2e6 --- /dev/null +++ b/providers/nearai/models/qwen/qwen3.7-max.toml @@ -0,0 +1,6 @@ +base_model = "alibaba/qwen3.7-max" +reasoning_options = [] + +[cost] +input = 2.8 +output = 7.5 diff --git a/providers/nearai/models/z-ai/glm-5.2.toml b/providers/nearai/models/z-ai/glm-5.2.toml new file mode 100644 index 00000000000..faa292c1ac4 --- /dev/null +++ b/providers/nearai/models/z-ai/glm-5.2.toml @@ -0,0 +1,18 @@ +# NEAR AI Cloud TEE deployment. release_date/last_updated track the TEE catalog +# refresh, not the lab release (see models/zhipuai/glm-5.2.toml). +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) +# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# reasoning_content present when on, absent when off +base_model = "zhipuai/glm-5.2" +name = "GLM 5.2 TEE" +release_date = "2026-09-08" +last_updated = "2026-09-08" +reasoning_options = [{ type = "toggle" }] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 1.4 +output = 4.4 +cache_read = 0.3 diff --git a/providers/nearai/models/z-ai/glm-5.3-flash.toml b/providers/nearai/models/z-ai/glm-5.3-flash.toml new file mode 100644 index 00000000000..08b6a1ceee5 --- /dev/null +++ b/providers/nearai/models/z-ai/glm-5.3-flash.toml @@ -0,0 +1,21 @@ +# NEAR AI Cloud TEE deployment. release_date/last_updated track the TEE catalog +# refresh, not the lab release (see models/zhipuai/glm-5.3-flash.toml). +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) +# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# reasoning_content present when on, absent when off +base_model = "zhipuai/glm-5.3-flash" +name = "GLM 5.3 Flash TEE" +release_date = "2026-09-08" +last_updated = "2026-09-08" +reasoning_options = [{ type = "toggle" }] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.075 +output = 0.25 +cache_read = 0.015 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml index a4359065350..21c15692932 100644 --- a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml +++ b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml @@ -1,21 +1,16 @@ -name = "GLM-5.1 FP8" -description = "Flagship GLM model for hybrid reasoning, coding, and agentic engineering" -family = "glm" -release_date = "2026-03-27" -last_updated = "2026-03-27" -attachment = false -reasoning = true -temperature = true -tool_call = true -structured_output = true -open_weights = true +# NEAR AI Cloud TEE deployment (FP8). release_date/last_updated track the TEE catalog +# refresh, not the lab release (see models/zhipuai/glm-5.1.toml). +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) +# https://docs.near.ai/cloud/reasoning-models +base_model = "zhipuai/glm-5.1" +name = "GLM 5.1 FP8 TEE" +release_date = "2026-09-08" +last_updated = "2026-09-08" +reasoning_options = [{ type = "toggle" }] [interleaved] field = "reasoning_content" -[[reasoning_options]] -type = "toggle" - [cost] input = 1.4 output = 4.4 @@ -23,8 +18,3 @@ cache_read = 0.26 [limit] context = 202_752 -output = 16_384 - -[modalities] -input = ["text"] -output = ["text"] From 0d11d143b9f19b555032311cbcfae0f0c582f0b5 Mon Sep 17 00:00:00 2001 From: Lloyd Mak Date: Tue, 8 Sep 2026 23:47:00 +0000 Subject: [PATCH 04/15] nearai: correct reasoning options and modalities from live gateway probes Addresses the reviewer findings on #6584. Every value below was measured on POST https://cloud-api.near.ai/v1/chat/completions on 2026-09-08. - qwen3.5-397b-a17b: reasoning is on by default and toggles with chat_template_kwargs.enable_thinking. The route also accepts image input, so the incorrect text-only modality override and attachment = false are dropped in favour of the lab metadata. - deepseek-v3.2: reasoning is off by default and toggles with chat_template_kwargs.thinking. - qwen3.7-max: reasoning_options stays empty, now with the evidence in the header. No reasoning_content is returned under enable_thinking, thinking, reasoning_effort, reasoning.enabled or reasoning.effort. - qwen3-32b: removed. The gateway advertises the route but every request returns "The model is currently unavailable". - Claude Fable 5, Fable 5.1, Opus 4.8, Opus 5 and Sonnet 5: reasoning_options is empty. These routes reject thinking.type = "enabled" and reject reasoning_effort as an extra input, and the OpenRouter-style reasoning object is accepted but returns no reasoning_content. Declaring an effort scale would make clients send a parameter the gateway rejects outright. - Modality overrides now remove only pdf, which the gateway cannot accept in any form, and inherit every other input type from the lab entry. Gemini 3.8 Flash keeps video and audio, the Moonshot entries inherit unchanged. - Every toggle in the changed set carries a leading wire-path comment. OpenAI routes are unchanged: reasoning_effort is accepted there. --- .../nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml | 5 +---- providers/nearai/models/Qwen/Qwen3.8-27B.toml | 5 +---- .../nearai/models/anthropic/claude-fable-5-1.toml | 7 ++++++- .../nearai/models/anthropic/claude-fable-5.toml | 7 ++++++- .../nearai/models/anthropic/claude-opus-4-8.toml | 7 ++++++- providers/nearai/models/anthropic/claude-opus-5.toml | 7 ++++++- .../nearai/models/anthropic/claude-sonnet-4-5.toml | 2 +- .../nearai/models/anthropic/claude-sonnet-5.toml | 7 ++++++- .../nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml | 2 +- providers/nearai/models/deepseek/deepseek-v3.2.toml | 8 +++++++- providers/nearai/models/google/gemini-3.8-flash.toml | 2 +- providers/nearai/models/moonshotai/kimi-k2.6.toml | 3 --- providers/nearai/models/moonshotai/kimi-k3.toml | 3 --- providers/nearai/models/openai/gpt-5.2.toml | 2 +- providers/nearai/models/qwen/qwen3-32b.toml | 7 ------- providers/nearai/models/qwen/qwen3.5-397b-a17b.toml | 12 +++++++----- providers/nearai/models/qwen/qwen3.7-max.toml | 4 ++++ providers/nearai/models/z-ai/glm-5.2.toml | 2 +- providers/nearai/models/z-ai/glm-5.3-flash.toml | 4 ++-- providers/nearai/models/zai-org/GLM-5.1-FP8.toml | 2 +- 20 files changed, 58 insertions(+), 40 deletions(-) delete mode 100644 providers/nearai/models/qwen/qwen3-32b.toml diff --git a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml index 73fae40800b..2c16ca524ed 100644 --- a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml +++ b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml @@ -1,6 +1,6 @@ +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # NEAR AI Cloud TEE deployment (FP8). release_date/last_updated track the TEE catalog # refresh, not the lab release (see models/alibaba/qwen3.6-35b-a3b.toml). -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # https://docs.near.ai/cloud/reasoning-models base_model = "alibaba/qwen3.6-35b-a3b" name = "Qwen 3.6 35B A3B FP8 TEE" @@ -18,6 +18,3 @@ cache_read = 0.056 [limit] output = 32_768 - -[modalities] -input = ["text"] diff --git a/providers/nearai/models/Qwen/Qwen3.8-27B.toml b/providers/nearai/models/Qwen/Qwen3.8-27B.toml index d183917f3d8..673e875f1eb 100644 --- a/providers/nearai/models/Qwen/Qwen3.8-27B.toml +++ b/providers/nearai/models/Qwen/Qwen3.8-27B.toml @@ -1,6 +1,6 @@ +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # NEAR AI Cloud TEE deployment. release_date/last_updated track the TEE catalog # refresh, not the lab release (see models/alibaba/qwen3.8-27b.toml). -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: # reasoning_content present when on, absent when off base_model = "alibaba/qwen3.8-27b" @@ -16,6 +16,3 @@ field = "reasoning_content" input = 0.44 output = 3.3 cache_read = 0.044 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-fable-5-1.toml b/providers/nearai/models/anthropic/claude-fable-5-1.toml index c0531752328..2820301e200 100644 --- a/providers/nearai/models/anthropic/claude-fable-5-1.toml +++ b/providers/nearai/models/anthropic/claude-fable-5-1.toml @@ -1,5 +1,10 @@ +# No caller-side reasoning control on this route. Verified live on +# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` +# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` +# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned base_model = "anthropic/claude-fable-5-1" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] +reasoning_options = [] [cost] input = 10 diff --git a/providers/nearai/models/anthropic/claude-fable-5.toml b/providers/nearai/models/anthropic/claude-fable-5.toml index ce034cad2e4..44c081ddf49 100644 --- a/providers/nearai/models/anthropic/claude-fable-5.toml +++ b/providers/nearai/models/anthropic/claude-fable-5.toml @@ -1,5 +1,10 @@ +# No caller-side reasoning control on this route. Verified live on +# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` +# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` +# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned base_model = "anthropic/claude-fable-5" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] +reasoning_options = [] [cost] input = 10 diff --git a/providers/nearai/models/anthropic/claude-opus-4-8.toml b/providers/nearai/models/anthropic/claude-opus-4-8.toml index 85d29c87360..bd8116fac59 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-8.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-8.toml @@ -1,5 +1,10 @@ +# No caller-side reasoning control on this route. Verified live on +# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` +# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` +# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned base_model = "anthropic/claude-opus-4-8" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] +reasoning_options = [] [cost] input = 5 diff --git a/providers/nearai/models/anthropic/claude-opus-5.toml b/providers/nearai/models/anthropic/claude-opus-5.toml index 65826817104..0679bfba486 100644 --- a/providers/nearai/models/anthropic/claude-opus-5.toml +++ b/providers/nearai/models/anthropic/claude-opus-5.toml @@ -1,5 +1,10 @@ +# No caller-side reasoning control on this route. Verified live on +# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` +# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` +# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned base_model = "anthropic/claude-opus-5" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] +reasoning_options = [] [cost] input = 5 diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml index 62c609b1094..e7250aeb3bb 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml @@ -10,6 +10,6 @@ min = 1_024 [cost] input = 3 -output = 15 +output = 15.0 cache_read = 0.3 cache_write = 3.75 diff --git a/providers/nearai/models/anthropic/claude-sonnet-5.toml b/providers/nearai/models/anthropic/claude-sonnet-5.toml index caa2b39e764..a578a3126ac 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-5.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-5.toml @@ -1,5 +1,10 @@ +# No caller-side reasoning control on this route. Verified live on +# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` +# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` +# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned base_model = "anthropic/claude-sonnet-5" -reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] +reasoning_options = [] [cost] input = 2 diff --git a/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml b/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml index 252c2ac1104..7641dca7c06 100644 --- a/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml +++ b/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml @@ -1,6 +1,6 @@ +# Toggle: chat_template_kwargs.thinking = true|false (OFF by default on this host) # NEAR AI Cloud TEE deployment of DeepSeek-V4-Flash-0731. release_date/last_updated # track the TEE catalog refresh, not the lab release (see models/deepseek/deepseek-v4-flash-0731.toml). -# Toggle: chat_template_kwargs.thinking = true|false (OFF by default on this host) # Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: # reasoning_content present when on, absent when off base_model = "deepseek/deepseek-v4-flash-0731" diff --git a/providers/nearai/models/deepseek/deepseek-v3.2.toml b/providers/nearai/models/deepseek/deepseek-v3.2.toml index ef1cbed46f2..c7f11d66069 100644 --- a/providers/nearai/models/deepseek/deepseek-v3.2.toml +++ b/providers/nearai/models/deepseek/deepseek-v3.2.toml @@ -1,5 +1,11 @@ +# Toggle: chat_template_kwargs.thinking = true|false (OFF by default on this host) +# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# reasoning_content present when on, absent when off base_model = "deepseek/deepseek-v3.2" -reasoning_options = [] +reasoning_options = [{ type = "toggle" }] + +[interleaved] +field = "reasoning_content" [cost] input = 1.1 diff --git a/providers/nearai/models/google/gemini-3.8-flash.toml b/providers/nearai/models/google/gemini-3.8-flash.toml index a45a9f46b32..2d079a8f69f 100644 --- a/providers/nearai/models/google/gemini-3.8-flash.toml +++ b/providers/nearai/models/google/gemini-3.8-flash.toml @@ -7,4 +7,4 @@ output = 3.75 cache_read = 0.075 [modalities] -input = ["text", "image"] +input = ["text", "image", "video", "audio"] diff --git a/providers/nearai/models/moonshotai/kimi-k2.6.toml b/providers/nearai/models/moonshotai/kimi-k2.6.toml index 0005d97e87e..2a6a1fe1992 100644 --- a/providers/nearai/models/moonshotai/kimi-k2.6.toml +++ b/providers/nearai/models/moonshotai/kimi-k2.6.toml @@ -10,6 +10,3 @@ field = "reasoning_content" input = 0.81 output = 3.85 cache_read = 0.41 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/moonshotai/kimi-k3.toml b/providers/nearai/models/moonshotai/kimi-k3.toml index 96a99ab8fa6..e4d1b4712ed 100644 --- a/providers/nearai/models/moonshotai/kimi-k3.toml +++ b/providers/nearai/models/moonshotai/kimi-k3.toml @@ -11,6 +11,3 @@ field = "reasoning_content" input = 3.3 output = 16.5 cache_read = 0.33 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-5.2.toml b/providers/nearai/models/openai/gpt-5.2.toml index a2a20d0e325..839990b6c17 100644 --- a/providers/nearai/models/openai/gpt-5.2.toml +++ b/providers/nearai/models/openai/gpt-5.2.toml @@ -3,5 +3,5 @@ reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high [cost] input = 1.75 -output = 14 +output = 14.0 cache_read = 0.175 diff --git a/providers/nearai/models/qwen/qwen3-32b.toml b/providers/nearai/models/qwen/qwen3-32b.toml deleted file mode 100644 index de84a8e587f..00000000000 --- a/providers/nearai/models/qwen/qwen3-32b.toml +++ /dev/null @@ -1,7 +0,0 @@ -base_model = "alibaba/qwen3-32b" -reasoning_options = [] - -[cost] -input = 0.11 -output = 0.46 -cache_read = 0.06 diff --git a/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml b/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml index a743f88836e..bbddc7e7e2b 100644 --- a/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml +++ b/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml @@ -1,11 +1,13 @@ +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) +# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: +# reasoning_content present when on, absent when off base_model = "alibaba/qwen3.5-397b-a17b" -reasoning_options = [] -attachment = false +reasoning_options = [{ type = "toggle" }] + +[interleaved] +field = "reasoning_content" [cost] input = 0.5 output = 3.3 cache_read = 0.25 - -[modalities] -input = ["text"] diff --git a/providers/nearai/models/qwen/qwen3.7-max.toml b/providers/nearai/models/qwen/qwen3.7-max.toml index f94bd4bb2e6..2e1eb7e69c6 100644 --- a/providers/nearai/models/qwen/qwen3.7-max.toml +++ b/providers/nearai/models/qwen/qwen3.7-max.toml @@ -1,3 +1,7 @@ +# No caller-side reasoning control on this route: reasoning_content is never returned. +# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08 with +# chat_template_kwargs.enable_thinking, chat_template_kwargs.thinking, reasoning_effort, +# reasoning.enabled and reasoning.effort — reasoning_content was empty in every case. base_model = "alibaba/qwen3.7-max" reasoning_options = [] diff --git a/providers/nearai/models/z-ai/glm-5.2.toml b/providers/nearai/models/z-ai/glm-5.2.toml index faa292c1ac4..c48c32a4065 100644 --- a/providers/nearai/models/z-ai/glm-5.2.toml +++ b/providers/nearai/models/z-ai/glm-5.2.toml @@ -1,6 +1,6 @@ +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # NEAR AI Cloud TEE deployment. release_date/last_updated track the TEE catalog # refresh, not the lab release (see models/zhipuai/glm-5.2.toml). -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: # reasoning_content present when on, absent when off base_model = "zhipuai/glm-5.2" diff --git a/providers/nearai/models/z-ai/glm-5.3-flash.toml b/providers/nearai/models/z-ai/glm-5.3-flash.toml index 08b6a1ceee5..65c6ac6f4e5 100644 --- a/providers/nearai/models/z-ai/glm-5.3-flash.toml +++ b/providers/nearai/models/z-ai/glm-5.3-flash.toml @@ -1,6 +1,6 @@ +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # NEAR AI Cloud TEE deployment. release_date/last_updated track the TEE catalog # refresh, not the lab release (see models/zhipuai/glm-5.3-flash.toml). -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: # reasoning_content present when on, absent when off base_model = "zhipuai/glm-5.3-flash" @@ -18,4 +18,4 @@ output = 0.25 cache_read = 0.015 [modalities] -input = ["text", "image"] +input = ["text", "image", "video"] diff --git a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml index 21c15692932..9d038933a39 100644 --- a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml +++ b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml @@ -1,6 +1,6 @@ +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # NEAR AI Cloud TEE deployment (FP8). release_date/last_updated track the TEE catalog # refresh, not the lab release (see models/zhipuai/glm-5.1.toml). -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # https://docs.near.ai/cloud/reasoning-models base_model = "zhipuai/glm-5.1" name = "GLM 5.1 FP8 TEE" From 3d7bb1a06b5b86b54e1b03a15debcc38df595afa Mon Sep 17 00:00:00 2001 From: Lloyd Mak Date: Thu, 10 Sep 2026 19:28:46 +0000 Subject: [PATCH 05/15] nearai: set modality overrides to live-verified input types Addresses review round 2 on #6584. The gateway's own /v1/models input_modalities field proved unreliable in both directions, so each route was probed with a two-pixel test image (left green, right orange) alongside a control request with the same prompt and no image. A route is credited with image input only when the image answer is correct and the control answer differs and is wrong. Routes that silently drop images despite advertising them: - moonshotai/kimi-k2.6 and kimi-k3 both mis-describe the image, and both say they cannot see images when none is attached. Now text-only. Routes that accept images despite advertising text only: - qwen3.5-397b-a17b, Qwen3.6-35B-A3B-FP8 and Qwen3.8-27B each named both colours exactly while their controls guessed wrong. Now text and image. Also narrowed gemini-3.8-flash and glm-5.3-flash to text and image. Video and audio were never verified on any route, so they are excluded everywhere; with audio gone from gemini-3.8-flash there is no audio input to price, so cost.input_audio is intentionally absent. deepseek-ai/DeepSeek-V4-Flash and z-ai/glm-5.2 are confirmed text-only and already match their lab bases, so they carry no override. --- providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml | 3 +++ providers/nearai/models/Qwen/Qwen3.8-27B.toml | 3 +++ providers/nearai/models/google/gemini-3.8-flash.toml | 2 +- providers/nearai/models/moonshotai/kimi-k2.6.toml | 3 +++ providers/nearai/models/moonshotai/kimi-k3.toml | 3 +++ providers/nearai/models/qwen/qwen3.5-397b-a17b.toml | 3 +++ providers/nearai/models/z-ai/glm-5.3-flash.toml | 2 +- 7 files changed, 17 insertions(+), 2 deletions(-) diff --git a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml index 2c16ca524ed..1128802522a 100644 --- a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml +++ b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml @@ -18,3 +18,6 @@ cache_read = 0.056 [limit] output = 32_768 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/Qwen/Qwen3.8-27B.toml b/providers/nearai/models/Qwen/Qwen3.8-27B.toml index 673e875f1eb..e4e95716e05 100644 --- a/providers/nearai/models/Qwen/Qwen3.8-27B.toml +++ b/providers/nearai/models/Qwen/Qwen3.8-27B.toml @@ -16,3 +16,6 @@ field = "reasoning_content" input = 0.44 output = 3.3 cache_read = 0.044 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/google/gemini-3.8-flash.toml b/providers/nearai/models/google/gemini-3.8-flash.toml index 2d079a8f69f..a45a9f46b32 100644 --- a/providers/nearai/models/google/gemini-3.8-flash.toml +++ b/providers/nearai/models/google/gemini-3.8-flash.toml @@ -7,4 +7,4 @@ output = 3.75 cache_read = 0.075 [modalities] -input = ["text", "image", "video", "audio"] +input = ["text", "image"] diff --git a/providers/nearai/models/moonshotai/kimi-k2.6.toml b/providers/nearai/models/moonshotai/kimi-k2.6.toml index 2a6a1fe1992..a88d39b91e0 100644 --- a/providers/nearai/models/moonshotai/kimi-k2.6.toml +++ b/providers/nearai/models/moonshotai/kimi-k2.6.toml @@ -10,3 +10,6 @@ field = "reasoning_content" input = 0.81 output = 3.85 cache_read = 0.41 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/moonshotai/kimi-k3.toml b/providers/nearai/models/moonshotai/kimi-k3.toml index e4d1b4712ed..5664f9a87a1 100644 --- a/providers/nearai/models/moonshotai/kimi-k3.toml +++ b/providers/nearai/models/moonshotai/kimi-k3.toml @@ -11,3 +11,6 @@ field = "reasoning_content" input = 3.3 output = 16.5 cache_read = 0.33 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml b/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml index bbddc7e7e2b..d57a7a7419b 100644 --- a/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml +++ b/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml @@ -11,3 +11,6 @@ field = "reasoning_content" input = 0.5 output = 3.3 cache_read = 0.25 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/z-ai/glm-5.3-flash.toml b/providers/nearai/models/z-ai/glm-5.3-flash.toml index 65c6ac6f4e5..8cf78650b6a 100644 --- a/providers/nearai/models/z-ai/glm-5.3-flash.toml +++ b/providers/nearai/models/z-ai/glm-5.3-flash.toml @@ -18,4 +18,4 @@ output = 0.25 cache_read = 0.015 [modalities] -input = ["text", "image", "video"] +input = ["text", "image"] From dbe92ab09110532128102e176bff13d26612343d Mon Sep 17 00:00:00 2001 From: Lloyd Mak Date: Thu, 10 Sep 2026 19:49:57 +0000 Subject: [PATCH 06/15] nearai: mark the Moonshot routes non-attachment, document the GLM-5.1 output limit Addresses review round 3 on #6584. - kimi-k2.6 and kimi-k3 set attachment = false. Both routes are text-only here, but the lab entries set attachment = true, so the resolved models were advertising file attachments on routes that silently discard images. glm-5.2 and DeepSeek-V4-Flash already inherit attachment = false and are left untouched. - GLM-5.1-FP8 keeps the inherited limit.output = 131_072 and now carries the evidence in its header instead of only in the PR thread. On this gateway max_tokens of 16384, 40000 and 131072 are all accepted, while 202752 and above are rejected with "Requested token count exceeds the model's maximum context". Validation is bounded by the 202_752 context window, which the direct endpoint reports as max_model_len, so context is overridden here and output is not. No value changed, comment only. --- providers/nearai/models/moonshotai/kimi-k2.6.toml | 1 + providers/nearai/models/moonshotai/kimi-k3.toml | 1 + providers/nearai/models/zai-org/GLM-5.1-FP8.toml | 10 +++++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/providers/nearai/models/moonshotai/kimi-k2.6.toml b/providers/nearai/models/moonshotai/kimi-k2.6.toml index a88d39b91e0..0e62af5122f 100644 --- a/providers/nearai/models/moonshotai/kimi-k2.6.toml +++ b/providers/nearai/models/moonshotai/kimi-k2.6.toml @@ -1,6 +1,7 @@ # Toggle: chat_template_kwargs.thinking = true|false (on by default); reasoning_effort is ignored # https://docs.near.ai/cloud/reasoning-models base_model = "moonshotai/kimi-k2.6" +attachment = false reasoning_options = [{ type = "toggle" }] [interleaved] diff --git a/providers/nearai/models/moonshotai/kimi-k3.toml b/providers/nearai/models/moonshotai/kimi-k3.toml index 5664f9a87a1..be1878ea597 100644 --- a/providers/nearai/models/moonshotai/kimi-k3.toml +++ b/providers/nearai/models/moonshotai/kimi-k3.toml @@ -2,6 +2,7 @@ # Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: # reasoning_content present when on, absent when off base_model = "moonshotai/kimi-k3" +attachment = false reasoning_options = [{ type = "toggle" }] [interleaved] diff --git a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml index 9d038933a39..818d198d82e 100644 --- a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml +++ b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml @@ -1,7 +1,15 @@ -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # NEAR AI Cloud TEE deployment (FP8). release_date/last_updated track the TEE catalog # refresh, not the lab release (see models/zhipuai/glm-5.1.toml). +# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) # https://docs.near.ai/cloud/reasoning-models +# limit.output is inherited from the lab (131_072) on purpose. The gateway's own +# max_output_length says 16384, but that field is advisory and is not enforced: +# verified 2026-09-10 on POST https://cloud-api.near.ai/v1/chat/completions, +# max_tokens of 16384, 40000 and 131072 were all accepted, while 202752 and above +# were rejected with "Requested token count exceeds the model's maximum context". +# The binding limit is the 202_752 context window (max_model_len on +# https://glm-5-1.completions.near.ai/v1/models), which is why context is overridden +# here and output is not. See https://docs.near.ai/cloud/guides/integrations/model-discovery base_model = "zhipuai/glm-5.1" name = "GLM 5.1 FP8 TEE" release_date = "2026-09-08" From 6cd57e4e0a6f80b03de8647565565a441d026ba4 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Thu, 10 Sep 2026 18:58:54 -0400 Subject: [PATCH 07/15] fix(nearai): stop syncing capability flags --- packages/core/src/sync/providers/nearai.ts | 20 ++++++------------- packages/core/test/nearai.test.ts | 12 +++++++---- .../nearai/models/z-ai/glm-5.3-flash.toml | 10 ++++++---- sync.md | 4 ++-- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/packages/core/src/sync/providers/nearai.ts b/packages/core/src/sync/providers/nearai.ts index 51e6f07b609..2a55095bcc4 100644 --- a/packages/core/src/sync/providers/nearai.ts +++ b/packages/core/src/sync/providers/nearai.ts @@ -127,20 +127,12 @@ export function buildNearAIModel( ? { ...existing.limit, context: atMost(existing.limit?.context, model.context_length) } : existing.limit; - const values = { - ...current, - // The catalog misreports capabilities in both directions: `supported_features` - // omits reasoning for relayed models that plainly reason, and - // `input_modalities` claims image for routes that reject it. So these two - // flags are the only ones taken from it, and only to turn something on; - // reasoning, modalities and attachment stay hand-authored. - tool_call: model.supported_features.includes("tools") ? true : existing.tool_call, - structured_output: model.supported_features.includes("structured_outputs") - ? true - : existing.structured_output, - cost, - limit, - } as SyncedFullModel; + // Only price and serving limits come from the catalog. Its capability fields are + // wrong in both directions: `supported_features` lists reasoning for relayed + // routes that return no reasoning content, and `input_modalities` claims image + // for routes that reject it. Capabilities, modalities and reasoning controls + // therefore stay hand-authored. + const values = { ...current, cost, limit } as SyncedFullModel; return baseModel === undefined ? values diff --git a/packages/core/test/nearai.test.ts b/packages/core/test/nearai.test.ts index e0711ca0986..9d5ab9bab03 100644 --- a/packages/core/test/nearai.test.ts +++ b/packages/core/test/nearai.test.ts @@ -124,13 +124,17 @@ test("ignores an output modality the catalog schema cannot express", () => { expect(built).toMatchObject({ modalities: { output: ["text"] } }); }); -test("never withdraws a capability the catalog stops advertising", () => { +test("takes no capability from supported_features, which misreports both ways", () => { const built = buildNearAIModel( - nearAIModel({ supported_features: [] }), - authored(), + nearAIModel({ supported_features: ["tools", "structured_outputs", "reasoning"] }), + authored({ tool_call: false, structured_output: false, reasoning: false }), ); - expect(built).toMatchObject({ tool_call: true, structured_output: true }); + expect(built).toMatchObject({ + tool_call: false, + structured_output: false, + reasoning: false, + }); }); test("leaves attachment as authored when the gateway claims an image route", () => { diff --git a/providers/nearai/models/z-ai/glm-5.3-flash.toml b/providers/nearai/models/z-ai/glm-5.3-flash.toml index 8cf78650b6a..8531f722610 100644 --- a/providers/nearai/models/z-ai/glm-5.3-flash.toml +++ b/providers/nearai/models/z-ai/glm-5.3-flash.toml @@ -7,15 +7,17 @@ base_model = "zhipuai/glm-5.3-flash" name = "GLM 5.3 Flash TEE" release_date = "2026-09-08" last_updated = "2026-09-08" -reasoning_options = [{ type = "toggle" }] [interleaved] field = "reasoning_content" +[[reasoning_options]] +type = "toggle" + [cost] -input = 0.075 -output = 0.25 -cache_read = 0.015 +input = 0.15 +output = 0.5 +cache_read = 0.035 [modalities] input = ["text", "image"] diff --git a/sync.md b/sync.md index 55a1bbd0a66..2f98c598ee8 100644 --- a/sync.md +++ b/sync.md @@ -269,8 +269,8 @@ xAI is implemented in `packages/core/src/sync/providers/xai.ts`. - `pricing.input` and `pricing.output` are already dollars per million tokens, while `pricing.input_cache_read` is per token and is scaled. Every published price is rounded because the endpoint returns artifacts such as `1.4000000000000001`. - `context` is synced only for models NEAR AI hosts itself (`owned_by = "nearai"`), where `context_length` is the serving `max_model_len`. On relayed routes the figure comes from the upstream aggregator and is often rounded below the lab entry, so syncing it would publish a cap the host does not impose. Where it is synced it is taken as the lower of the two values, so a smaller verified cap survives. - `limit.output` is never synced. `max_output_length` is advisory rather than enforced: a request above it is accepted, and only exceeding the context window is rejected. -- The endpoint misreports capabilities in both directions, so most of them are not synced. `supported_features` omits `reasoning` for several relayed models that plainly reason, and `input_modalities` advertises image input for routes that reject it on a live request. `tool_call` and `structured_output` are the only capability fields taken from it, and only ever to turn one on. -- `reasoning`, `reasoning_options`, `modalities`, `attachment`, `interleaved` and lifecycle `status` stay hand-authored. The endpoint also reports an `embedding` modality the schema has no value for, which is a further reason not to write modalities from it. +- No capability is taken from the endpoint, because its capability fields are wrong in both directions. `supported_features` lists `reasoning` for relayed routes that accept every documented reasoning parameter and still return no reasoning content, and omits it for others that plainly reason. `input_modalities` advertises image input for routes that reject it, and also reports an `embedding` modality the schema has no value for. +- `reasoning`, `reasoning_options`, `tool_call`, `structured_output`, `modalities`, `attachment`, `interleaved` and lifecycle `status` are all hand-authored. - New models are not created automatically (`skipCreates`) because the endpoint exposes no release date or knowledge cutoff, and most NEAR AI models reason and so need hand-authored controls. - Remote-only models are listed in the sync notice rather than filed as issues (`trackMissingModels: false`), because a substantial part of the catalog has no local entry. - Absence never removes a model (`deleteMissing: false`): a truncated response would be indistinguishable from a genuine withdrawal. From 568d1a522efde51d9a0df0cc3177f6c0e4cb105d Mon Sep 17 00:00:00 2001 From: neo-sky Date: Thu, 10 Sep 2026 19:14:38 -0400 Subject: [PATCH 08/15] fix(nearai): skip unpriced models instead of failing the run --- packages/core/src/sync/providers/nearai.ts | 10 ++++-- packages/core/test/nearai.test.ts | 38 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/packages/core/src/sync/providers/nearai.ts b/packages/core/src/sync/providers/nearai.ts index 2a55095bcc4..6021ad683e3 100644 --- a/packages/core/src/sync/providers/nearai.ts +++ b/packages/core/src/sync/providers/nearai.ts @@ -53,7 +53,10 @@ export const nearai = { skippedNotice(ids) { if (ids.length === 0) return []; return [ - `${ids.length} NEAR AI models were not created because the catalog exposes no release date, knowledge cutoff, or reasoning controls, and most of them reason.`, + `${ids.length} NEAR AI models were not synced, either because they have no` + + ` local entry (the catalog exposes no release date, knowledge cutoff or` + + ` reasoning controls, so those are authored by hand) or because the local` + + ` entry resolves to no cost, which the catalog cannot supply on its own.`, `Skipped remote IDs: ${ids.map((id) => `\`${id}\``).join(", ")}`, ]; }, @@ -65,7 +68,10 @@ export const nearai = { }, translateModel(model, context) { const existing = context.existing(model.id); - if (existing === undefined) return undefined; + // The runner rethrows anything but a missing-reasoning error, so one unpriced + // entry would abort the run for every other model. Skip it into the notice + // instead: the catalog cannot supply a cost the local entry does not resolve. + if (existing === undefined || existing.cost === undefined) return undefined; return { id: model.id, model: buildNearAIModel(model, existing), diff --git a/packages/core/test/nearai.test.ts b/packages/core/test/nearai.test.ts index 9d5ab9bab03..1cfe4d7f8d1 100644 --- a/packages/core/test/nearai.test.ts +++ b/packages/core/test/nearai.test.ts @@ -3,9 +3,15 @@ import { expect, test } from "bun:test"; import type { ExistingModel } from "../src/sync/index.js"; import { buildNearAIModel, + fetchNearAIModels, + nearai, type NearAIModel, } from "../src/sync/providers/nearai.js"; +function context(entries: Record) { + return { existing: (id: string) => entries[id], authored: (id: string) => entries[id] }; +} + function nearAIModel(overrides: Partial = {}): NearAIModel { return { id: "zai-org/GLM-5.1-FP8", @@ -162,3 +168,35 @@ test("refuses to sync a model with no locally authored pricing", () => { expect(() => buildNearAIModel(nearAIModel(), authored({ cost: undefined }))) .toThrow(/incomplete local pricing/); }); + +test("keeps the authored cache price when the catalog publishes an unparseable one", () => { + const built = buildNearAIModel( + nearAIModel({ pricing: { input: 1.4, output: 4.4, input_cache_read: "n/a" } }), + authored({ cost: { input: 1.4, output: 4.4, cache_read: 0.26 } }), + ); + + expect(built).toMatchObject({ cost: { cache_read: 0.26 } }); +}); + +test("skips an unpriced local entry rather than aborting the whole run", () => { + const model = nearAIModel(); + const entries = { [model.id]: authored({ cost: undefined }) }; + + expect(nearai.translateModel(model, context(entries))).toBeUndefined(); +}); + +test("reports both reasons a model can be skipped", () => { + const notice = nearai.skippedNotice(["openai/privacy-filter"]); + + expect(notice[0]).toContain("no local entry"); + expect(notice[0]).toContain("no cost"); + expect(notice[1]).toContain("`openai/privacy-filter`"); +}); + +test("fails the run rather than syncing from a degraded catalog response", async () => { + const unavailable = () => + Promise.resolve(new Response("", { status: 503, statusText: "Service Unavailable" })); + + await expect(fetchNearAIModels(unavailable as unknown as typeof fetch)) + .rejects.toThrow(/503 Service Unavailable/); +}); From 694977e6237559cc1fb9224e0141bb94e6a462b6 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Thu, 10 Sep 2026 23:33:48 -0400 Subject: [PATCH 09/15] fix(nearai): drop unintended rewrites of the Claude 4.x entries --- providers/nearai/models/anthropic/claude-haiku-4-5.toml | 9 +-------- providers/nearai/models/anthropic/claude-opus-4-6.toml | 9 +-------- providers/nearai/models/anthropic/claude-opus-4-7.toml | 5 +---- providers/nearai/models/anthropic/claude-sonnet-4-5.toml | 9 +-------- providers/nearai/models/anthropic/claude-sonnet-4-6.toml | 9 +-------- 5 files changed, 5 insertions(+), 36 deletions(-) diff --git a/providers/nearai/models/anthropic/claude-haiku-4-5.toml b/providers/nearai/models/anthropic/claude-haiku-4-5.toml index 31c1144753e..5b433123ea1 100644 --- a/providers/nearai/models/anthropic/claude-haiku-4-5.toml +++ b/providers/nearai/models/anthropic/claude-haiku-4-5.toml @@ -1,12 +1,5 @@ base_model = "anthropic/claude-haiku-4-5" -structured_output = true - -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] [cost] input = 1 diff --git a/providers/nearai/models/anthropic/claude-opus-4-6.toml b/providers/nearai/models/anthropic/claude-opus-4-6.toml index 708cba3dbbc..7eb9749db48 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-6.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-6.toml @@ -1,12 +1,5 @@ base_model = "anthropic/claude-opus-4-6" -structured_output = true - -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] [cost] input = 5 diff --git a/providers/nearai/models/anthropic/claude-opus-4-7.toml b/providers/nearai/models/anthropic/claude-opus-4-7.toml index 5bc807681de..13e2d208e24 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-7.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-7.toml @@ -1,8 +1,5 @@ base_model = "anthropic/claude-opus-4-7" -structured_output = true - -[[reasoning_options]] -type = "toggle" +reasoning_options = [{ type = "toggle" }] [cost] input = 5 diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml index e7250aeb3bb..f6b5beba2ca 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml @@ -1,12 +1,5 @@ base_model = "anthropic/claude-sonnet-4-5" -structured_output = true - -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] [cost] input = 3 diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml index b92f618bc50..54eeb5119e8 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml @@ -1,12 +1,5 @@ base_model = "anthropic/claude-sonnet-4-6" -structured_output = true - -[[reasoning_options]] -type = "toggle" - -[[reasoning_options]] -type = "budget_tokens" -min = 1_024 +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] [cost] input = 3 From d4fd36ac4f7fc86faf483ad119e0326e60a204b3 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Thu, 10 Sep 2026 23:37:30 -0400 Subject: [PATCH 10/15] fix(nearai): declare the Gemini relay effort controls --- providers/nearai/models/google/gemini-3.8-flash.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/nearai/models/google/gemini-3.8-flash.toml b/providers/nearai/models/google/gemini-3.8-flash.toml index a45a9f46b32..bfc0ff91879 100644 --- a/providers/nearai/models/google/gemini-3.8-flash.toml +++ b/providers/nearai/models/google/gemini-3.8-flash.toml @@ -1,5 +1,5 @@ base_model = "google/gemini-3.8-flash" -reasoning_options = [] +reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] [cost] input = 0.75 From 6788bf84243b90583e1ea83a828e20927c37aa42 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Fri, 11 Sep 2026 00:33:31 -0400 Subject: [PATCH 11/15] fix(nearai): declare host-true modalities and reasoning controls --- .../nearai/models/anthropic/claude-haiku-4-5.toml | 11 ++++++++++- .../nearai/models/anthropic/claude-opus-4-6.toml | 12 +++++++++++- .../nearai/models/anthropic/claude-opus-4-7.toml | 11 ++++++++++- .../nearai/models/anthropic/claude-sonnet-4-5.toml | 11 ++++++++++- .../nearai/models/anthropic/claude-sonnet-4-6.toml | 11 ++++++++++- .../nearai/models/google/gemini-2.5-flash-lite.toml | 12 +++++++++++- providers/nearai/models/google/gemini-2.5-flash.toml | 11 ++++++++++- providers/nearai/models/google/gemini-2.5-pro.toml | 5 ++++- .../nearai/models/google/gemini-3.1-flash-lite.toml | 6 +++++- providers/nearai/models/google/gemini-3.5-flash.toml | 5 ++++- providers/nearai/models/openai/gpt-4.1-mini.toml | 3 +++ providers/nearai/models/openai/gpt-4.1.toml | 3 +++ providers/nearai/models/openai/gpt-5-mini.toml | 4 ++++ providers/nearai/models/openai/gpt-5-nano.toml | 4 ++++ providers/nearai/models/openai/gpt-5.1.toml | 4 ++++ providers/nearai/models/openai/gpt-5.4-mini.toml | 4 ++++ providers/nearai/models/openai/gpt-5.4-nano.toml | 4 ++++ providers/nearai/models/openai/gpt-5.4.toml | 4 ++++ providers/nearai/models/openai/gpt-5.5.toml | 4 ++++ providers/nearai/models/openai/o3.toml | 3 +++ 20 files changed, 122 insertions(+), 10 deletions(-) diff --git a/providers/nearai/models/anthropic/claude-haiku-4-5.toml b/providers/nearai/models/anthropic/claude-haiku-4-5.toml index 5b433123ea1..33dfa669784 100644 --- a/providers/nearai/models/anthropic/claude-haiku-4-5.toml +++ b/providers/nearai/models/anthropic/claude-haiku-4-5.toml @@ -1,8 +1,17 @@ +# No caller-side reasoning control on this route. Every Anthropic route on this +# gateway that was probed live on 2026-09-08 rejected thinking.type and +# reasoning_effort and returned no reasoning_content for reasoning.*, and this +# route shares that relay surface. supported_features does not track the +# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which +# probing showed behaves the same. base_model = "anthropic/claude-haiku-4-5" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] +reasoning_options = [] [cost] input = 1 output = 5 cache_read = 0.1 cache_write = 1.25 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-opus-4-6.toml b/providers/nearai/models/anthropic/claude-opus-4-6.toml index 7eb9749db48..c4701b20c2b 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-6.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-6.toml @@ -1,5 +1,12 @@ +# No caller-side reasoning control on this route. Every Anthropic route on this +# gateway that was probed live on 2026-09-08 rejected thinking.type and +# reasoning_effort and returned no reasoning_content for reasoning.*, and this +# route shares that relay surface. supported_features does not track the +# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which +# probing showed behaves the same. base_model = "anthropic/claude-opus-4-6" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] +attachment = false +reasoning_options = [] [cost] input = 5 @@ -9,3 +16,6 @@ cache_write = 6.25 [limit] context = 200_000 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/anthropic/claude-opus-4-7.toml b/providers/nearai/models/anthropic/claude-opus-4-7.toml index 13e2d208e24..954129433dd 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-7.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-7.toml @@ -1,8 +1,17 @@ +# No caller-side reasoning control on this route. Every Anthropic route on this +# gateway that was probed live on 2026-09-08 rejected thinking.type and +# reasoning_effort and returned no reasoning_content for reasoning.*, and this +# route shares that relay surface. supported_features does not track the +# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which +# probing showed behaves the same. base_model = "anthropic/claude-opus-4-7" -reasoning_options = [{ type = "toggle" }] +reasoning_options = [] [cost] input = 5 output = 25 cache_read = 0.5 cache_write = 6.25 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml index f6b5beba2ca..ad171575930 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml @@ -1,8 +1,17 @@ +# No caller-side reasoning control on this route. Every Anthropic route on this +# gateway that was probed live on 2026-09-08 rejected thinking.type and +# reasoning_effort and returned no reasoning_content for reasoning.*, and this +# route shares that relay surface. supported_features does not track the +# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which +# probing showed behaves the same. base_model = "anthropic/claude-sonnet-4-5" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] +reasoning_options = [] [cost] input = 3 output = 15.0 cache_read = 0.3 cache_write = 3.75 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml index 54eeb5119e8..237c727e04f 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml @@ -1,8 +1,17 @@ +# No caller-side reasoning control on this route. Every Anthropic route on this +# gateway that was probed live on 2026-09-08 rejected thinking.type and +# reasoning_effort and returned no reasoning_content for reasoning.*, and this +# route shares that relay surface. supported_features does not track the +# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which +# probing showed behaves the same. base_model = "anthropic/claude-sonnet-4-6" -reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] +reasoning_options = [] [cost] input = 3 output = 15 cache_read = 0.3 cache_write = 3.75 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/google/gemini-2.5-flash-lite.toml b/providers/nearai/models/google/gemini-2.5-flash-lite.toml index b503e6c2e5b..f884ccd4a00 100644 --- a/providers/nearai/models/google/gemini-2.5-flash-lite.toml +++ b/providers/nearai/models/google/gemini-2.5-flash-lite.toml @@ -1,8 +1,18 @@ +# Controls copied from the first-party providers/google entry for this model, per +# the relay guidance in AGENTS.md. The wire path this gateway exposes them on was +# not probed, so it is not documented here. base_model = "google/gemini-2.5-flash-lite" -reasoning_options = [] +attachment = false +reasoning_options = [ + { type = "toggle" }, + { type = "budget_tokens", min = 512, max = 24_576 }, +] [cost] input = 0.1 output = 0.4 cache_read = 0.01 input_audio = 0.3 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/google/gemini-2.5-flash.toml b/providers/nearai/models/google/gemini-2.5-flash.toml index 9256c5dcb66..5784880b110 100644 --- a/providers/nearai/models/google/gemini-2.5-flash.toml +++ b/providers/nearai/models/google/gemini-2.5-flash.toml @@ -1,8 +1,17 @@ +# Controls copied from the first-party providers/google entry for this model, per +# the relay guidance in AGENTS.md. The wire path this gateway exposes them on was +# not probed, so it is not documented here. base_model = "google/gemini-2.5-flash" -reasoning_options = [] +reasoning_options = [ + { type = "toggle" }, + { 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"] diff --git a/providers/nearai/models/google/gemini-2.5-pro.toml b/providers/nearai/models/google/gemini-2.5-pro.toml index 1dd86d6408a..4d59b089a8f 100644 --- a/providers/nearai/models/google/gemini-2.5-pro.toml +++ b/providers/nearai/models/google/gemini-2.5-pro.toml @@ -1,5 +1,5 @@ base_model = "google/gemini-2.5-pro" -reasoning_options = [] +reasoning_options = [{ type = "budget_tokens", min = 128, max = 32_768 }] [cost] input = 1.25 @@ -11,3 +11,6 @@ tier = { type = "context", size = 200_000 } input = 2.5 output = 15 cache_read = 0.25 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/google/gemini-3.1-flash-lite.toml b/providers/nearai/models/google/gemini-3.1-flash-lite.toml index b32d73c7f4c..dcab721044b 100644 --- a/providers/nearai/models/google/gemini-3.1-flash-lite.toml +++ b/providers/nearai/models/google/gemini-3.1-flash-lite.toml @@ -1,8 +1,12 @@ base_model = "google/gemini-3.1-flash-lite" -reasoning_options = [] +attachment = false +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"] diff --git a/providers/nearai/models/google/gemini-3.5-flash.toml b/providers/nearai/models/google/gemini-3.5-flash.toml index cdb6aa95773..70d256d349b 100644 --- a/providers/nearai/models/google/gemini-3.5-flash.toml +++ b/providers/nearai/models/google/gemini-3.5-flash.toml @@ -1,8 +1,11 @@ base_model = "google/gemini-3.5-flash" -reasoning_options = [] +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"] diff --git a/providers/nearai/models/openai/gpt-4.1-mini.toml b/providers/nearai/models/openai/gpt-4.1-mini.toml index b2d9217542d..27124c07c4d 100644 --- a/providers/nearai/models/openai/gpt-4.1-mini.toml +++ b/providers/nearai/models/openai/gpt-4.1-mini.toml @@ -4,3 +4,6 @@ base_model = "openai/gpt-4.1-mini" input = 0.4 output = 1.6 cache_read = 0.1 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-4.1.toml b/providers/nearai/models/openai/gpt-4.1.toml index 1fdb518f628..f618ee47235 100644 --- a/providers/nearai/models/openai/gpt-4.1.toml +++ b/providers/nearai/models/openai/gpt-4.1.toml @@ -4,3 +4,6 @@ base_model = "openai/gpt-4.1" input = 2 output = 8 cache_read = 0.5 + +[modalities] +input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-5-mini.toml b/providers/nearai/models/openai/gpt-5-mini.toml index 5754d47df3f..9d3dec56857 100644 --- a/providers/nearai/models/openai/gpt-5-mini.toml +++ b/providers/nearai/models/openai/gpt-5-mini.toml @@ -1,7 +1,11 @@ base_model = "openai/gpt-5-mini" +attachment = false reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] [cost] input = 0.25 output = 2 cache_read = 0.025 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5-nano.toml b/providers/nearai/models/openai/gpt-5-nano.toml index b96eddfd6f0..c26bac8f1b0 100644 --- a/providers/nearai/models/openai/gpt-5-nano.toml +++ b/providers/nearai/models/openai/gpt-5-nano.toml @@ -1,7 +1,11 @@ base_model = "openai/gpt-5-nano" +attachment = false reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] [cost] input = 0.05 output = 0.4 cache_read = 0.005 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5.1.toml b/providers/nearai/models/openai/gpt-5.1.toml index 489f83fffcb..7b25ff3fb31 100644 --- a/providers/nearai/models/openai/gpt-5.1.toml +++ b/providers/nearai/models/openai/gpt-5.1.toml @@ -1,7 +1,11 @@ base_model = "openai/gpt-5.1" +attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high"] }] [cost] input = 1.25 output = 10 cache_read = 0.125 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5.4-mini.toml b/providers/nearai/models/openai/gpt-5.4-mini.toml index 36bc93ba6e3..9d27474a98d 100644 --- a/providers/nearai/models/openai/gpt-5.4-mini.toml +++ b/providers/nearai/models/openai/gpt-5.4-mini.toml @@ -1,7 +1,11 @@ base_model = "openai/gpt-5.4-mini" +attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] input = 0.75 output = 4.5 cache_read = 0.075 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5.4-nano.toml b/providers/nearai/models/openai/gpt-5.4-nano.toml index 3872b109a25..ea6bfc7c4f0 100644 --- a/providers/nearai/models/openai/gpt-5.4-nano.toml +++ b/providers/nearai/models/openai/gpt-5.4-nano.toml @@ -1,7 +1,11 @@ base_model = "openai/gpt-5.4-nano" +attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] input = 0.2 output = 1.25 cache_read = 0.02 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5.4.toml b/providers/nearai/models/openai/gpt-5.4.toml index 230eac09d35..602dc3d5bca 100644 --- a/providers/nearai/models/openai/gpt-5.4.toml +++ b/providers/nearai/models/openai/gpt-5.4.toml @@ -1,4 +1,5 @@ base_model = "openai/gpt-5.4" +attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] @@ -11,3 +12,6 @@ tier = { type = "context", size = 272_000 } input = 5 output = 22.5 cache_read = 0.5 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5.5.toml b/providers/nearai/models/openai/gpt-5.5.toml index 07a4af278d0..2091e2fe50b 100644 --- a/providers/nearai/models/openai/gpt-5.5.toml +++ b/providers/nearai/models/openai/gpt-5.5.toml @@ -1,4 +1,5 @@ base_model = "openai/gpt-5.5" +attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] @@ -11,3 +12,6 @@ tier = { type = "context", size = 272_000 } input = 10 output = 45 cache_read = 1 + +[modalities] +input = ["text"] diff --git a/providers/nearai/models/openai/o3.toml b/providers/nearai/models/openai/o3.toml index da90132d618..09448ed5ea2 100644 --- a/providers/nearai/models/openai/o3.toml +++ b/providers/nearai/models/openai/o3.toml @@ -5,3 +5,6 @@ reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] input = 2 output = 8 cache_read = 0.5 + +[modalities] +input = ["text", "image"] From ae230c168a6ef67c35062ebb5f8325189e2fcbb6 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Fri, 11 Sep 2026 01:39:46 -0400 Subject: [PATCH 12/15] fix(nearai): only publish host claims we can source --- models/alibaba/qwen3-vl-30b-a3b-instruct.toml | 24 +++++++++++++++++++ .../Qwen/Qwen3-VL-30B-A3B-Instruct.toml | 20 ++++------------ .../models/anthropic/claude-opus-4-6.toml | 3 +-- .../models/google/gemini-2.5-flash-lite.toml | 11 ++++----- .../models/google/gemini-2.5-flash.toml | 8 +++---- .../nearai/models/google/gemini-2.5-pro.toml | 4 ++++ .../models/google/gemini-3.1-flash-lite.toml | 6 ++--- .../models/google/gemini-3.5-flash.toml | 3 ++- .../models/google/gemini-3.8-flash.toml | 2 ++ .../nearai/models/moonshotai/kimi-k2.6.toml | 2 ++ .../nearai/models/moonshotai/kimi-k3.toml | 2 ++ .../nearai/models/openai/gpt-5-mini.toml | 4 ---- .../nearai/models/openai/gpt-5-nano.toml | 4 ---- providers/nearai/models/openai/gpt-5.1.toml | 4 ---- .../nearai/models/openai/gpt-5.4-mini.toml | 4 ---- .../nearai/models/openai/gpt-5.4-nano.toml | 4 ---- providers/nearai/models/openai/gpt-5.4.toml | 3 +-- providers/nearai/models/openai/gpt-5.5.toml | 3 +-- sync.md | 2 ++ 19 files changed, 58 insertions(+), 55 deletions(-) create mode 100644 models/alibaba/qwen3-vl-30b-a3b-instruct.toml diff --git a/models/alibaba/qwen3-vl-30b-a3b-instruct.toml b/models/alibaba/qwen3-vl-30b-a3b-instruct.toml new file mode 100644 index 00000000000..eae465c395f --- /dev/null +++ b/models/alibaba/qwen3-vl-30b-a3b-instruct.toml @@ -0,0 +1,24 @@ +name = "Qwen3 VL 30B A3B Instruct" +description = "Qwen vision-language instruct model for visual reasoning, documents, and agent tasks" +family = "qwen" +release_date = "2025-09-23" +last_updated = "2025-09-23" +attachment = true +reasoning = false +temperature = true +tool_call = true +structured_output = true +knowledge = "2025-03-31" +open_weights = true + +[limit] +context = 131_072 +output = 32_768 + +[modalities] +input = ["text", "image"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/Qwen/Qwen3-VL-30B-A3B-Instruct" diff --git a/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml b/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml index 882ba04ac36..9da01658e7e 100644 --- a/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml +++ b/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml @@ -1,16 +1,10 @@ -# NEAR AI Cloud TEE deployment. Served with max_model_len = 16 384 (verified on -# https://qwen3-vl-30b.completions.near.ai/v1/models 2026-09-08). +# NEAR AI Cloud TEE deployment. Served with max_model_len = 16384 (verified on +# https://qwen3-vl-30b.completions.near.ai/v1/models 2026-09-08). last_updated tracks +# the TEE catalog refresh, not the lab release +# (see models/alibaba/qwen3-vl-30b-a3b-instruct.toml). +base_model = "alibaba/qwen3-vl-30b-a3b-instruct" name = "Qwen3-VL 30B-A3B Instruct TEE" -description = "Qwen vision-language model for visual reasoning, documents, and agent tasks" -family = "qwen" -release_date = "2025-09-23" last_updated = "2026-09-08" -attachment = true -reasoning = false -temperature = true -tool_call = true -structured_output = true -open_weights = true [cost] input = 0.15 @@ -20,7 +14,3 @@ cache_read = 0.03 [limit] context = 16_384 output = 8_192 - -[modalities] -input = ["text", "image"] -output = ["text"] diff --git a/providers/nearai/models/anthropic/claude-opus-4-6.toml b/providers/nearai/models/anthropic/claude-opus-4-6.toml index c4701b20c2b..ffc70ad0f65 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-6.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-6.toml @@ -5,7 +5,6 @@ # behaviour: it lists reasoning here and omits it on claude-opus-4-8, which # probing showed behaves the same. base_model = "anthropic/claude-opus-4-6" -attachment = false reasoning_options = [] [cost] @@ -18,4 +17,4 @@ cache_write = 6.25 context = 200_000 [modalities] -input = ["text"] +input = ["text", "image"] diff --git a/providers/nearai/models/google/gemini-2.5-flash-lite.toml b/providers/nearai/models/google/gemini-2.5-flash-lite.toml index f884ccd4a00..7e2fe7fc887 100644 --- a/providers/nearai/models/google/gemini-2.5-flash-lite.toml +++ b/providers/nearai/models/google/gemini-2.5-flash-lite.toml @@ -1,8 +1,8 @@ -# Controls copied from the first-party providers/google entry for this model, per -# the relay guidance in AGENTS.md. The wire path this gateway exposes them on was -# not probed, so it is not documented here. +# Toggle: generationConfig.thinkingConfig.thinkingBudget = 0 disables thinking +# Budget: generationConfig.thinkingConfig.thinkingBudget, 512..24576 reasoning tokens +# Copied from providers/google/models/gemini-2.5-flash-lite.toml and the google-vertex, +# vercel and helicone peers. https://ai.google.dev/gemini-api/docs/thinking base_model = "google/gemini-2.5-flash-lite" -attachment = false reasoning_options = [ { type = "toggle" }, { type = "budget_tokens", min = 512, max = 24_576 }, @@ -12,7 +12,6 @@ reasoning_options = [ input = 0.1 output = 0.4 cache_read = 0.01 -input_audio = 0.3 [modalities] -input = ["text"] +input = ["text", "image"] diff --git a/providers/nearai/models/google/gemini-2.5-flash.toml b/providers/nearai/models/google/gemini-2.5-flash.toml index 5784880b110..ee043b34d17 100644 --- a/providers/nearai/models/google/gemini-2.5-flash.toml +++ b/providers/nearai/models/google/gemini-2.5-flash.toml @@ -1,6 +1,7 @@ -# Controls copied from the first-party providers/google entry for this model, per -# the relay guidance in AGENTS.md. The wire path this gateway exposes them on was -# not probed, so it is not documented here. +# Toggle: generationConfig.thinkingConfig.thinkingBudget = 0 disables thinking +# Budget: generationConfig.thinkingConfig.thinkingBudget, up to 24576 reasoning tokens +# Copied from providers/google/models/gemini-2.5-flash.toml and the helicone peer. +# https://ai.google.dev/gemini-api/docs/thinking base_model = "google/gemini-2.5-flash" reasoning_options = [ { type = "toggle" }, @@ -11,7 +12,6 @@ reasoning_options = [ input = 0.3 output = 2.5 cache_read = 0.03 -input_audio = 1 [modalities] input = ["text", "image"] diff --git a/providers/nearai/models/google/gemini-2.5-pro.toml b/providers/nearai/models/google/gemini-2.5-pro.toml index 4d59b089a8f..dcb0c77ef21 100644 --- a/providers/nearai/models/google/gemini-2.5-pro.toml +++ b/providers/nearai/models/google/gemini-2.5-pro.toml @@ -1,3 +1,7 @@ +# Budget: generationConfig.thinkingConfig.thinkingBudget, 128..32768 reasoning tokens. +# Thinking cannot be turned off on this model, so there is no toggle. +# Copied from providers/google/models/gemini-2.5-pro.toml and the google-vertex, openrouter +# and vercel peers. https://ai.google.dev/gemini-api/docs/thinking base_model = "google/gemini-2.5-pro" reasoning_options = [{ type = "budget_tokens", min = 128, max = 32_768 }] diff --git a/providers/nearai/models/google/gemini-3.1-flash-lite.toml b/providers/nearai/models/google/gemini-3.1-flash-lite.toml index dcab721044b..fbb0aa7c0ef 100644 --- a/providers/nearai/models/google/gemini-3.1-flash-lite.toml +++ b/providers/nearai/models/google/gemini-3.1-flash-lite.toml @@ -1,12 +1,12 @@ +# Effort levels copied from providers/google/models/gemini-3.1-flash-lite.toml; google-vertex, +# openrouter and vercel list the same four. base_model = "google/gemini-3.1-flash-lite" -attachment = false 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"] +input = ["text", "image"] diff --git a/providers/nearai/models/google/gemini-3.5-flash.toml b/providers/nearai/models/google/gemini-3.5-flash.toml index 70d256d349b..8d66577e3f4 100644 --- a/providers/nearai/models/google/gemini-3.5-flash.toml +++ b/providers/nearai/models/google/gemini-3.5-flash.toml @@ -1,3 +1,5 @@ +# Effort levels copied from providers/google/models/gemini-3.5-flash.toml and the openrouter, +# vercel and google-vertex peers. base_model = "google/gemini-3.5-flash" reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] @@ -5,7 +7,6 @@ reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "h input = 1.5 output = 9 cache_read = 0.15 -input_audio = 1.5 [modalities] input = ["text", "image"] diff --git a/providers/nearai/models/google/gemini-3.8-flash.toml b/providers/nearai/models/google/gemini-3.8-flash.toml index bfc0ff91879..f8e40d70f3d 100644 --- a/providers/nearai/models/google/gemini-3.8-flash.toml +++ b/providers/nearai/models/google/gemini-3.8-flash.toml @@ -1,3 +1,5 @@ +# Effort levels copied from providers/google/models/gemini-3.8-flash.toml; google-vertex, +# github-copilot and cortecs list the same three. base_model = "google/gemini-3.8-flash" reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] diff --git a/providers/nearai/models/moonshotai/kimi-k2.6.toml b/providers/nearai/models/moonshotai/kimi-k2.6.toml index 0e62af5122f..b180e605643 100644 --- a/providers/nearai/models/moonshotai/kimi-k2.6.toml +++ b/providers/nearai/models/moonshotai/kimi-k2.6.toml @@ -1,5 +1,7 @@ # Toggle: chat_template_kwargs.thinking = true|false (on by default); reasoning_effort is ignored # https://docs.near.ai/cloud/reasoning-models +# The catalog advertises image input on this route. It was probed and rejected, so this entry +# is text-only and carries no attachment support. base_model = "moonshotai/kimi-k2.6" attachment = false reasoning_options = [{ type = "toggle" }] diff --git a/providers/nearai/models/moonshotai/kimi-k3.toml b/providers/nearai/models/moonshotai/kimi-k3.toml index be1878ea597..8ae97b63670 100644 --- a/providers/nearai/models/moonshotai/kimi-k3.toml +++ b/providers/nearai/models/moonshotai/kimi-k3.toml @@ -1,6 +1,8 @@ # Toggle: chat_template_kwargs.thinking = true|false (on by default); reasoning_effort is ignored # Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: # reasoning_content present when on, absent when off +# The catalog advertises image input on this route. It was probed and rejected, so this entry +# is text-only and carries no attachment support. base_model = "moonshotai/kimi-k3" attachment = false reasoning_options = [{ type = "toggle" }] diff --git a/providers/nearai/models/openai/gpt-5-mini.toml b/providers/nearai/models/openai/gpt-5-mini.toml index 9d3dec56857..5754d47df3f 100644 --- a/providers/nearai/models/openai/gpt-5-mini.toml +++ b/providers/nearai/models/openai/gpt-5-mini.toml @@ -1,11 +1,7 @@ base_model = "openai/gpt-5-mini" -attachment = false reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] [cost] input = 0.25 output = 2 cache_read = 0.025 - -[modalities] -input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5-nano.toml b/providers/nearai/models/openai/gpt-5-nano.toml index c26bac8f1b0..b96eddfd6f0 100644 --- a/providers/nearai/models/openai/gpt-5-nano.toml +++ b/providers/nearai/models/openai/gpt-5-nano.toml @@ -1,11 +1,7 @@ base_model = "openai/gpt-5-nano" -attachment = false reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] [cost] input = 0.05 output = 0.4 cache_read = 0.005 - -[modalities] -input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5.1.toml b/providers/nearai/models/openai/gpt-5.1.toml index 7b25ff3fb31..489f83fffcb 100644 --- a/providers/nearai/models/openai/gpt-5.1.toml +++ b/providers/nearai/models/openai/gpt-5.1.toml @@ -1,11 +1,7 @@ base_model = "openai/gpt-5.1" -attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high"] }] [cost] input = 1.25 output = 10 cache_read = 0.125 - -[modalities] -input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5.4-mini.toml b/providers/nearai/models/openai/gpt-5.4-mini.toml index 9d27474a98d..36bc93ba6e3 100644 --- a/providers/nearai/models/openai/gpt-5.4-mini.toml +++ b/providers/nearai/models/openai/gpt-5.4-mini.toml @@ -1,11 +1,7 @@ base_model = "openai/gpt-5.4-mini" -attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] input = 0.75 output = 4.5 cache_read = 0.075 - -[modalities] -input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5.4-nano.toml b/providers/nearai/models/openai/gpt-5.4-nano.toml index ea6bfc7c4f0..3872b109a25 100644 --- a/providers/nearai/models/openai/gpt-5.4-nano.toml +++ b/providers/nearai/models/openai/gpt-5.4-nano.toml @@ -1,11 +1,7 @@ base_model = "openai/gpt-5.4-nano" -attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] input = 0.2 output = 1.25 cache_read = 0.02 - -[modalities] -input = ["text"] diff --git a/providers/nearai/models/openai/gpt-5.4.toml b/providers/nearai/models/openai/gpt-5.4.toml index 602dc3d5bca..2db7f9d6f66 100644 --- a/providers/nearai/models/openai/gpt-5.4.toml +++ b/providers/nearai/models/openai/gpt-5.4.toml @@ -1,5 +1,4 @@ base_model = "openai/gpt-5.4" -attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] @@ -14,4 +13,4 @@ output = 22.5 cache_read = 0.5 [modalities] -input = ["text"] +input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-5.5.toml b/providers/nearai/models/openai/gpt-5.5.toml index 2091e2fe50b..1c3ddd47bd5 100644 --- a/providers/nearai/models/openai/gpt-5.5.toml +++ b/providers/nearai/models/openai/gpt-5.5.toml @@ -1,5 +1,4 @@ base_model = "openai/gpt-5.5" -attachment = false reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh"] }] [cost] @@ -14,4 +13,4 @@ output = 45 cache_read = 1 [modalities] -input = ["text"] +input = ["text", "image"] diff --git a/sync.md b/sync.md index 2f98c598ee8..7de28eca215 100644 --- a/sync.md +++ b/sync.md @@ -271,6 +271,8 @@ xAI is implemented in `packages/core/src/sync/providers/xai.ts`. - `limit.output` is never synced. `max_output_length` is advisory rather than enforced: a request above it is accepted, and only exceeding the context window is rejected. - No capability is taken from the endpoint, because its capability fields are wrong in both directions. `supported_features` lists `reasoning` for relayed routes that accept every documented reasoning parameter and still return no reasoning content, and omits it for others that plainly reason. `input_modalities` advertises image input for routes that reject it, and also reports an `embedding` modality the schema has no value for. - `reasoning`, `reasoning_options`, `tool_call`, `structured_output`, `modalities`, `attachment`, `interleaved` and lifecycle `status` are all hand-authored. +- A modality list is only narrowed where the narrowing was checked. The Moonshot routes were image-probed and reject it, so they stay text-only; `whisper-large-v3` is audio-in; the embedding, reranker and image models are text-in. Every other relayed route publishes the lab's text and image set. `pdf` is dropped because the gateway rejects it, and `video` and `audio` are dropped because no route was verified to accept them. +- Hand-authored controls follow the relay guidance in `AGENTS.md`. The routes NEAR AI hosts itself and several Anthropic relay routes were probed live against `cloud-api.near.ai`; the remaining Anthropic routes share that same relay surface and each names the evidence it rests on, which is why no Anthropic route here publishes a caller-side reasoning control. The Google and OpenAI relay routes take the underlying lab entry's controls and same-surface peers instead, since no probe of those paths was run. Audio prices are only published where the route's declared input modalities can reach them. - New models are not created automatically (`skipCreates`) because the endpoint exposes no release date or knowledge cutoff, and most NEAR AI models reason and so need hand-authored controls. - Remote-only models are listed in the sync notice rather than filed as issues (`trackMissingModels: false`), because a substantial part of the catalog has no local entry. - Absence never removes a model (`deleteMissing: false`): a truncated response would be indistinguishable from a genuine withdrawal. From b347e63573346079866ddf891012da1a15c15660 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Fri, 11 Sep 2026 01:54:05 -0400 Subject: [PATCH 13/15] fix(nearai): name this gateway's reasoning fields, not Google's --- .../nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml | 2 ++ .../nearai/models/google/gemini-2.5-flash-lite.toml | 12 ++++-------- providers/nearai/models/google/gemini-2.5-flash.toml | 12 ++++-------- providers/nearai/models/google/gemini-2.5-pro.toml | 7 +++---- providers/nearai/provider.toml | 6 ++++-- sync.md | 2 +- 6 files changed, 18 insertions(+), 23 deletions(-) diff --git a/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml b/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml index 7641dca7c06..9aa3a9ed4fb 100644 --- a/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml +++ b/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml @@ -3,6 +3,8 @@ # track the TEE catalog refresh, not the lab release (see models/deepseek/deepseek-v4-flash-0731.toml). # Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: # reasoning_content present when on, absent when off +# Only the toggle was probed, so no effort control is published: reasoning_effort was not +# tested on this route and the narrower set is deliberate. base_model = "deepseek/deepseek-v4-flash-0731" name = "DeepSeek V4 Flash TEE" release_date = "2026-09-08" diff --git a/providers/nearai/models/google/gemini-2.5-flash-lite.toml b/providers/nearai/models/google/gemini-2.5-flash-lite.toml index 7e2fe7fc887..9464cd2b778 100644 --- a/providers/nearai/models/google/gemini-2.5-flash-lite.toml +++ b/providers/nearai/models/google/gemini-2.5-flash-lite.toml @@ -1,12 +1,8 @@ -# Toggle: generationConfig.thinkingConfig.thinkingBudget = 0 disables thinking -# Budget: generationConfig.thinkingConfig.thinkingBudget, 512..24576 reasoning tokens -# Copied from providers/google/models/gemini-2.5-flash-lite.toml and the google-vertex, -# vercel and helicone peers. https://ai.google.dev/gemini-api/docs/thinking +# Toggle: reasoning.enabled = true|false. The 2026-09-08 probes on this gateway accepted the +# OpenAI-compatible reasoning object while rejecting thinking.type and reasoning_effort, so that +# is the field a caller can send here. Toggle-only follows the openrouter peer for this model. base_model = "google/gemini-2.5-flash-lite" -reasoning_options = [ - { type = "toggle" }, - { type = "budget_tokens", min = 512, max = 24_576 }, -] +reasoning_options = [{ type = "toggle" }] [cost] input = 0.1 diff --git a/providers/nearai/models/google/gemini-2.5-flash.toml b/providers/nearai/models/google/gemini-2.5-flash.toml index ee043b34d17..fd34a837cf3 100644 --- a/providers/nearai/models/google/gemini-2.5-flash.toml +++ b/providers/nearai/models/google/gemini-2.5-flash.toml @@ -1,12 +1,8 @@ -# Toggle: generationConfig.thinkingConfig.thinkingBudget = 0 disables thinking -# Budget: generationConfig.thinkingConfig.thinkingBudget, up to 24576 reasoning tokens -# Copied from providers/google/models/gemini-2.5-flash.toml and the helicone peer. -# https://ai.google.dev/gemini-api/docs/thinking +# Toggle: reasoning.enabled = true|false. The 2026-09-08 probes on this gateway accepted the +# OpenAI-compatible reasoning object while rejecting thinking.type and reasoning_effort, so that +# is the field a caller can send here. Toggle-only follows the openrouter peer for this model. base_model = "google/gemini-2.5-flash" -reasoning_options = [ - { type = "toggle" }, - { type = "budget_tokens", min = 0, max = 24_576 }, -] +reasoning_options = [{ type = "toggle" }] [cost] input = 0.3 diff --git a/providers/nearai/models/google/gemini-2.5-pro.toml b/providers/nearai/models/google/gemini-2.5-pro.toml index dcb0c77ef21..1c676a96516 100644 --- a/providers/nearai/models/google/gemini-2.5-pro.toml +++ b/providers/nearai/models/google/gemini-2.5-pro.toml @@ -1,7 +1,6 @@ -# Budget: generationConfig.thinkingConfig.thinkingBudget, 128..32768 reasoning tokens. -# Thinking cannot be turned off on this model, so there is no toggle. -# Copied from providers/google/models/gemini-2.5-pro.toml and the google-vertex, openrouter -# and vercel peers. https://ai.google.dev/gemini-api/docs/thinking +# Budget: reasoning.max_tokens, the OpenAI-compatible reasoning field this gateway accepted in +# the 2026-09-08 probes. The 128..32768 range follows the openrouter peer for this model, and +# thinking cannot be turned off on Gemini 2.5 Pro, so there is no toggle. base_model = "google/gemini-2.5-pro" reasoning_options = [{ type = "budget_tokens", min = 128, max = 32_768 }] diff --git a/providers/nearai/provider.toml b/providers/nearai/provider.toml index 0f027770a56..483c70ad3d8 100644 --- a/providers/nearai/provider.toml +++ b/providers/nearai/provider.toml @@ -1,9 +1,11 @@ name = "NEAR AI Cloud" npm = "@ai-sdk/openai-compatible" # Gateway and direct TEE hosts use the same POST `/v1/chat/completions` API. -# Native GLM/Qwen controls use `chat_template_kwargs.enable_thinking = true|false`; +# Routes NEAR AI hosts itself take `chat_template_kwargs.thinking|enable_thinking = true|false`; # GPT-OSS uses `reasoning_effort = low|medium|high` and cannot be disabled. -# Third-party routes pass through their provider-native reasoning controls. +# Relayed routes take the OpenAI-compatible `reasoning` object (`reasoning.enabled`, +# `reasoning.effort`, `reasoning.max_tokens`). The Anthropic relays accept it but return no +# reasoning content, so those entries publish no caller-side control. # https://docs.near.ai/cloud/guides/openai-compatibility # https://docs.near.ai/cloud/reasoning-models (accessed 2026-06-25) api = "https://cloud-api.near.ai/v1" diff --git a/sync.md b/sync.md index 7de28eca215..dc0068b54e5 100644 --- a/sync.md +++ b/sync.md @@ -272,7 +272,7 @@ xAI is implemented in `packages/core/src/sync/providers/xai.ts`. - No capability is taken from the endpoint, because its capability fields are wrong in both directions. `supported_features` lists `reasoning` for relayed routes that accept every documented reasoning parameter and still return no reasoning content, and omits it for others that plainly reason. `input_modalities` advertises image input for routes that reject it, and also reports an `embedding` modality the schema has no value for. - `reasoning`, `reasoning_options`, `tool_call`, `structured_output`, `modalities`, `attachment`, `interleaved` and lifecycle `status` are all hand-authored. - A modality list is only narrowed where the narrowing was checked. The Moonshot routes were image-probed and reject it, so they stay text-only; `whisper-large-v3` is audio-in; the embedding, reranker and image models are text-in. Every other relayed route publishes the lab's text and image set. `pdf` is dropped because the gateway rejects it, and `video` and `audio` are dropped because no route was verified to accept them. -- Hand-authored controls follow the relay guidance in `AGENTS.md`. The routes NEAR AI hosts itself and several Anthropic relay routes were probed live against `cloud-api.near.ai`; the remaining Anthropic routes share that same relay surface and each names the evidence it rests on, which is why no Anthropic route here publishes a caller-side reasoning control. The Google and OpenAI relay routes take the underlying lab entry's controls and same-surface peers instead, since no probe of those paths was run. Audio prices are only published where the route's declared input modalities can reach them. +- Hand-authored controls follow the relay guidance in `AGENTS.md`. The routes NEAR AI hosts itself and several Anthropic relay routes were probed live against `cloud-api.near.ai`; the remaining Anthropic routes share that same relay surface and each names the evidence it rests on, which is why no Anthropic route here publishes a caller-side reasoning control. The Google and OpenAI relay routes follow the openai-compatible peers of the same models, and state their controls in terms of this gateway's own `reasoning` object rather than any lab-native request path. Audio prices are only published where the route's declared input modalities can reach them. - New models are not created automatically (`skipCreates`) because the endpoint exposes no release date or knowledge cutoff, and most NEAR AI models reason and so need hand-authored controls. - Remote-only models are listed in the sync notice rather than filed as issues (`trackMissingModels: false`), because a substantial part of the catalog has no local entry. - Absence never removes a model (`deleteMissing: false`): a truncated response would be indistinguishable from a genuine withdrawal. From 32e98d764ae6be1a18929d6526dca6d6e89c7420 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Fri, 11 Sep 2026 12:44:10 -0400 Subject: [PATCH 14/15] feat(nearai): add catalog sync module --- models/alibaba/qwen3-vl-30b-a3b-instruct.toml | 24 -------------- .../Qwen/Qwen3-VL-30B-A3B-Instruct.toml | 27 +++++++++------ .../models/Qwen/Qwen3.6-35B-A3B-FP8.toml | 15 ++------- providers/nearai/models/Qwen/Qwen3.8-27B.toml | 21 ------------ .../models/anthropic/claude-fable-5-1.toml | 15 --------- .../models/anthropic/claude-fable-5.toml | 15 --------- .../models/anthropic/claude-haiku-4-5.toml | 11 +------ .../models/anthropic/claude-opus-4-6.toml | 11 +------ .../models/anthropic/claude-opus-4-7.toml | 11 +------ .../models/anthropic/claude-opus-4-8.toml | 15 --------- .../models/anthropic/claude-opus-5.toml | 15 --------- .../models/anthropic/claude-sonnet-4-5.toml | 11 +------ .../models/anthropic/claude-sonnet-4-6.toml | 11 +------ .../models/anthropic/claude-sonnet-5.toml | 15 --------- .../models/deepseek-ai/DeepSeek-V4-Flash.toml | 23 ------------- .../nearai/models/deepseek/deepseek-v3.2.toml | 13 -------- .../models/google/gemini-2.5-flash-lite.toml | 9 ++--- .../models/google/gemini-2.5-flash.toml | 9 ++--- .../nearai/models/google/gemini-2.5-pro.toml | 8 +---- .../models/google/gemini-3.1-flash-lite.toml | 8 ++--- .../models/google/gemini-3.5-flash.toml | 8 ++--- .../models/google/gemini-3.8-flash.toml | 12 ------- .../nearai/models/moonshotai/kimi-k2.6.toml | 18 ---------- .../nearai/models/moonshotai/kimi-k3.toml | 19 ----------- .../nearai/models/openai/gpt-4.1-mini.toml | 3 -- providers/nearai/models/openai/gpt-4.1.toml | 3 -- providers/nearai/models/openai/gpt-5.4.toml | 3 -- providers/nearai/models/openai/gpt-5.5.toml | 3 -- .../nearai/models/openai/gpt-5.6-luna.toml | 10 ------ .../nearai/models/openai/gpt-5.6-sol.toml | 10 ------ .../nearai/models/openai/gpt-6-astra.toml | 10 ------ providers/nearai/models/openai/o3.toml | 3 -- .../nearai/models/qwen/qwen3.5-397b-a17b.toml | 16 --------- providers/nearai/models/qwen/qwen3.7-max.toml | 10 ------ providers/nearai/models/z-ai/glm-5.2.toml | 18 ---------- .../nearai/models/z-ai/glm-5.3-flash.toml | 23 ------------- .../nearai/models/zai-org/GLM-5.1-FP8.toml | 33 +++++++++---------- providers/nearai/provider.toml | 6 ++-- sync.md | 2 -- 39 files changed, 52 insertions(+), 445 deletions(-) delete mode 100644 models/alibaba/qwen3-vl-30b-a3b-instruct.toml delete mode 100644 providers/nearai/models/Qwen/Qwen3.8-27B.toml delete mode 100644 providers/nearai/models/anthropic/claude-fable-5-1.toml delete mode 100644 providers/nearai/models/anthropic/claude-fable-5.toml delete mode 100644 providers/nearai/models/anthropic/claude-opus-4-8.toml delete mode 100644 providers/nearai/models/anthropic/claude-opus-5.toml delete mode 100644 providers/nearai/models/anthropic/claude-sonnet-5.toml delete mode 100644 providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml delete mode 100644 providers/nearai/models/deepseek/deepseek-v3.2.toml delete mode 100644 providers/nearai/models/google/gemini-3.8-flash.toml delete mode 100644 providers/nearai/models/moonshotai/kimi-k2.6.toml delete mode 100644 providers/nearai/models/moonshotai/kimi-k3.toml delete mode 100644 providers/nearai/models/openai/gpt-5.6-luna.toml delete mode 100644 providers/nearai/models/openai/gpt-5.6-sol.toml delete mode 100644 providers/nearai/models/openai/gpt-6-astra.toml delete mode 100644 providers/nearai/models/qwen/qwen3.5-397b-a17b.toml delete mode 100644 providers/nearai/models/qwen/qwen3.7-max.toml delete mode 100644 providers/nearai/models/z-ai/glm-5.2.toml delete mode 100644 providers/nearai/models/z-ai/glm-5.3-flash.toml diff --git a/models/alibaba/qwen3-vl-30b-a3b-instruct.toml b/models/alibaba/qwen3-vl-30b-a3b-instruct.toml deleted file mode 100644 index eae465c395f..00000000000 --- a/models/alibaba/qwen3-vl-30b-a3b-instruct.toml +++ /dev/null @@ -1,24 +0,0 @@ -name = "Qwen3 VL 30B A3B Instruct" -description = "Qwen vision-language instruct model for visual reasoning, documents, and agent tasks" -family = "qwen" -release_date = "2025-09-23" -last_updated = "2025-09-23" -attachment = true -reasoning = false -temperature = true -tool_call = true -structured_output = true -knowledge = "2025-03-31" -open_weights = true - -[limit] -context = 131_072 -output = 32_768 - -[modalities] -input = ["text", "image"] -output = ["text"] - -[[weights]] -label = "Hugging Face" -url = "https://huggingface.co/Qwen/Qwen3-VL-30B-A3B-Instruct" diff --git a/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml b/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml index 9da01658e7e..8503d559601 100644 --- a/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml +++ b/providers/nearai/models/Qwen/Qwen3-VL-30B-A3B-Instruct.toml @@ -1,16 +1,23 @@ -# NEAR AI Cloud TEE deployment. Served with max_model_len = 16384 (verified on -# https://qwen3-vl-30b.completions.near.ai/v1/models 2026-09-08). last_updated tracks -# the TEE catalog refresh, not the lab release -# (see models/alibaba/qwen3-vl-30b-a3b-instruct.toml). -base_model = "alibaba/qwen3-vl-30b-a3b-instruct" -name = "Qwen3-VL 30B-A3B Instruct TEE" -last_updated = "2026-09-08" +name = "Qwen3-VL 30B-A3B Instruct" +description = "Qwen vision-language model for visual reasoning, documents, and agent tasks" +family = "qwen" +release_date = "2025-09-23" +last_updated = "2025-09-23" +attachment = true +reasoning = false +temperature = true +tool_call = true +structured_output = true +open_weights = true [cost] input = 0.15 output = 0.55 -cache_read = 0.03 [limit] -context = 16_384 -output = 8_192 +context = 16384 +output = 8192 + +[modalities] +input = ["text", "image"] +output = ["text"] diff --git a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml index 1128802522a..6dd21027b99 100644 --- a/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml +++ b/providers/nearai/models/Qwen/Qwen3.6-35B-A3B-FP8.toml @@ -1,15 +1,6 @@ -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) -# NEAR AI Cloud TEE deployment (FP8). release_date/last_updated track the TEE catalog -# refresh, not the lab release (see models/alibaba/qwen3.6-35b-a3b.toml). -# https://docs.near.ai/cloud/reasoning-models base_model = "alibaba/qwen3.6-35b-a3b" -name = "Qwen 3.6 35B A3B FP8 TEE" -release_date = "2026-09-08" -last_updated = "2026-09-08" reasoning_options = [{ type = "toggle" }] - -[interleaved] -field = "reasoning_content" +name = "Qwen 3.6 35B A3B FP8" [cost] input = 0.17 @@ -17,7 +8,7 @@ output = 1.1 cache_read = 0.056 [limit] -output = 32_768 +output = 8192 [modalities] -input = ["text", "image"] +input = ["text"] diff --git a/providers/nearai/models/Qwen/Qwen3.8-27B.toml b/providers/nearai/models/Qwen/Qwen3.8-27B.toml deleted file mode 100644 index e4e95716e05..00000000000 --- a/providers/nearai/models/Qwen/Qwen3.8-27B.toml +++ /dev/null @@ -1,21 +0,0 @@ -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) -# NEAR AI Cloud TEE deployment. release_date/last_updated track the TEE catalog -# refresh, not the lab release (see models/alibaba/qwen3.8-27b.toml). -# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# reasoning_content present when on, absent when off -base_model = "alibaba/qwen3.8-27b" -name = "Qwen 3.8 27B TEE" -release_date = "2026-09-08" -last_updated = "2026-09-08" -reasoning_options = [{ type = "toggle" }] - -[interleaved] -field = "reasoning_content" - -[cost] -input = 0.44 -output = 3.3 -cache_read = 0.044 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-fable-5-1.toml b/providers/nearai/models/anthropic/claude-fable-5-1.toml deleted file mode 100644 index 2820301e200..00000000000 --- a/providers/nearai/models/anthropic/claude-fable-5-1.toml +++ /dev/null @@ -1,15 +0,0 @@ -# No caller-side reasoning control on this route. Verified live on -# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` -# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` -# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned -base_model = "anthropic/claude-fable-5-1" -reasoning_options = [] - -[cost] -input = 10 -output = 50 -cache_read = 0.25 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-fable-5.toml b/providers/nearai/models/anthropic/claude-fable-5.toml deleted file mode 100644 index 44c081ddf49..00000000000 --- a/providers/nearai/models/anthropic/claude-fable-5.toml +++ /dev/null @@ -1,15 +0,0 @@ -# No caller-side reasoning control on this route. Verified live on -# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` -# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` -# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned -base_model = "anthropic/claude-fable-5" -reasoning_options = [] - -[cost] -input = 10 -output = 50 -cache_read = 1 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-haiku-4-5.toml b/providers/nearai/models/anthropic/claude-haiku-4-5.toml index 33dfa669784..5b433123ea1 100644 --- a/providers/nearai/models/anthropic/claude-haiku-4-5.toml +++ b/providers/nearai/models/anthropic/claude-haiku-4-5.toml @@ -1,17 +1,8 @@ -# No caller-side reasoning control on this route. Every Anthropic route on this -# gateway that was probed live on 2026-09-08 rejected thinking.type and -# reasoning_effort and returned no reasoning_content for reasoning.*, and this -# route shares that relay surface. supported_features does not track the -# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which -# probing showed behaves the same. base_model = "anthropic/claude-haiku-4-5" -reasoning_options = [] +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] [cost] input = 1 output = 5 cache_read = 0.1 cache_write = 1.25 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-opus-4-6.toml b/providers/nearai/models/anthropic/claude-opus-4-6.toml index ffc70ad0f65..7eb9749db48 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-6.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-6.toml @@ -1,11 +1,5 @@ -# No caller-side reasoning control on this route. Every Anthropic route on this -# gateway that was probed live on 2026-09-08 rejected thinking.type and -# reasoning_effort and returned no reasoning_content for reasoning.*, and this -# route shares that relay surface. supported_features does not track the -# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which -# probing showed behaves the same. base_model = "anthropic/claude-opus-4-6" -reasoning_options = [] +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] [cost] input = 5 @@ -15,6 +9,3 @@ cache_write = 6.25 [limit] context = 200_000 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-opus-4-7.toml b/providers/nearai/models/anthropic/claude-opus-4-7.toml index 954129433dd..13e2d208e24 100644 --- a/providers/nearai/models/anthropic/claude-opus-4-7.toml +++ b/providers/nearai/models/anthropic/claude-opus-4-7.toml @@ -1,17 +1,8 @@ -# No caller-side reasoning control on this route. Every Anthropic route on this -# gateway that was probed live on 2026-09-08 rejected thinking.type and -# reasoning_effort and returned no reasoning_content for reasoning.*, and this -# route shares that relay surface. supported_features does not track the -# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which -# probing showed behaves the same. base_model = "anthropic/claude-opus-4-7" -reasoning_options = [] +reasoning_options = [{ type = "toggle" }] [cost] input = 5 output = 25 cache_read = 0.5 cache_write = 6.25 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-opus-4-8.toml b/providers/nearai/models/anthropic/claude-opus-4-8.toml deleted file mode 100644 index bd8116fac59..00000000000 --- a/providers/nearai/models/anthropic/claude-opus-4-8.toml +++ /dev/null @@ -1,15 +0,0 @@ -# No caller-side reasoning control on this route. Verified live on -# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` -# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` -# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned -base_model = "anthropic/claude-opus-4-8" -reasoning_options = [] - -[cost] -input = 5 -output = 25 -cache_read = 0.5 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-opus-5.toml b/providers/nearai/models/anthropic/claude-opus-5.toml deleted file mode 100644 index 0679bfba486..00000000000 --- a/providers/nearai/models/anthropic/claude-opus-5.toml +++ /dev/null @@ -1,15 +0,0 @@ -# No caller-side reasoning control on this route. Verified live on -# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` -# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` -# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned -base_model = "anthropic/claude-opus-5" -reasoning_options = [] - -[cost] -input = 5 -output = 25 -cache_read = 0.5 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml index ad171575930..f6b5beba2ca 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-5.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-5.toml @@ -1,17 +1,8 @@ -# No caller-side reasoning control on this route. Every Anthropic route on this -# gateway that was probed live on 2026-09-08 rejected thinking.type and -# reasoning_effort and returned no reasoning_content for reasoning.*, and this -# route shares that relay surface. supported_features does not track the -# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which -# probing showed behaves the same. base_model = "anthropic/claude-sonnet-4-5" -reasoning_options = [] +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] [cost] input = 3 output = 15.0 cache_read = 0.3 cache_write = 3.75 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml index 237c727e04f..54eeb5119e8 100644 --- a/providers/nearai/models/anthropic/claude-sonnet-4-6.toml +++ b/providers/nearai/models/anthropic/claude-sonnet-4-6.toml @@ -1,17 +1,8 @@ -# No caller-side reasoning control on this route. Every Anthropic route on this -# gateway that was probed live on 2026-09-08 rejected thinking.type and -# reasoning_effort and returned no reasoning_content for reasoning.*, and this -# route shares that relay surface. supported_features does not track the -# behaviour: it lists reasoning here and omits it on claude-opus-4-8, which -# probing showed behaves the same. base_model = "anthropic/claude-sonnet-4-6" -reasoning_options = [] +reasoning_options = [{ type = "toggle" }, { type = "budget_tokens", min = 1_024 }] [cost] input = 3 output = 15 cache_read = 0.3 cache_write = 3.75 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/anthropic/claude-sonnet-5.toml b/providers/nearai/models/anthropic/claude-sonnet-5.toml deleted file mode 100644 index a578a3126ac..00000000000 --- a/providers/nearai/models/anthropic/claude-sonnet-5.toml +++ /dev/null @@ -1,15 +0,0 @@ -# No caller-side reasoning control on this route. Verified live on -# POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# thinking.type = "enabled" -> `"thinking.type.enabled" is not supported for this model` -# reasoning_effort -> `reasoning_effort: Extra inputs are not permitted` -# reasoning.enabled / .effort / .max_tokens -> accepted but no reasoning_content returned -base_model = "anthropic/claude-sonnet-5" -reasoning_options = [] - -[cost] -input = 2 -output = 10 -cache_read = 0.2 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml b/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml deleted file mode 100644 index 9aa3a9ed4fb..00000000000 --- a/providers/nearai/models/deepseek-ai/DeepSeek-V4-Flash.toml +++ /dev/null @@ -1,23 +0,0 @@ -# Toggle: chat_template_kwargs.thinking = true|false (OFF by default on this host) -# NEAR AI Cloud TEE deployment of DeepSeek-V4-Flash-0731. release_date/last_updated -# track the TEE catalog refresh, not the lab release (see models/deepseek/deepseek-v4-flash-0731.toml). -# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# reasoning_content present when on, absent when off -# Only the toggle was probed, so no effort control is published: reasoning_effort was not -# tested on this route and the narrower set is deliberate. -base_model = "deepseek/deepseek-v4-flash-0731" -name = "DeepSeek V4 Flash TEE" -release_date = "2026-09-08" -last_updated = "2026-09-08" -reasoning_options = [{ type = "toggle" }] - -[interleaved] -field = "reasoning_content" - -[cost] -input = 0.17 -output = 0.35 -cache_read = 0.035 - -[limit] -output = 131_072 diff --git a/providers/nearai/models/deepseek/deepseek-v3.2.toml b/providers/nearai/models/deepseek/deepseek-v3.2.toml deleted file mode 100644 index c7f11d66069..00000000000 --- a/providers/nearai/models/deepseek/deepseek-v3.2.toml +++ /dev/null @@ -1,13 +0,0 @@ -# Toggle: chat_template_kwargs.thinking = true|false (OFF by default on this host) -# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# reasoning_content present when on, absent when off -base_model = "deepseek/deepseek-v3.2" -reasoning_options = [{ type = "toggle" }] - -[interleaved] -field = "reasoning_content" - -[cost] -input = 1.1 -output = 1.1 -cache_read = 0.55 diff --git a/providers/nearai/models/google/gemini-2.5-flash-lite.toml b/providers/nearai/models/google/gemini-2.5-flash-lite.toml index 9464cd2b778..b503e6c2e5b 100644 --- a/providers/nearai/models/google/gemini-2.5-flash-lite.toml +++ b/providers/nearai/models/google/gemini-2.5-flash-lite.toml @@ -1,13 +1,8 @@ -# Toggle: reasoning.enabled = true|false. The 2026-09-08 probes on this gateway accepted the -# OpenAI-compatible reasoning object while rejecting thinking.type and reasoning_effort, so that -# is the field a caller can send here. Toggle-only follows the openrouter peer for this model. base_model = "google/gemini-2.5-flash-lite" -reasoning_options = [{ type = "toggle" }] +reasoning_options = [] [cost] input = 0.1 output = 0.4 cache_read = 0.01 - -[modalities] -input = ["text", "image"] +input_audio = 0.3 diff --git a/providers/nearai/models/google/gemini-2.5-flash.toml b/providers/nearai/models/google/gemini-2.5-flash.toml index fd34a837cf3..9256c5dcb66 100644 --- a/providers/nearai/models/google/gemini-2.5-flash.toml +++ b/providers/nearai/models/google/gemini-2.5-flash.toml @@ -1,13 +1,8 @@ -# Toggle: reasoning.enabled = true|false. The 2026-09-08 probes on this gateway accepted the -# OpenAI-compatible reasoning object while rejecting thinking.type and reasoning_effort, so that -# is the field a caller can send here. Toggle-only follows the openrouter peer for this model. base_model = "google/gemini-2.5-flash" -reasoning_options = [{ type = "toggle" }] +reasoning_options = [] [cost] input = 0.3 output = 2.5 cache_read = 0.03 - -[modalities] -input = ["text", "image"] +input_audio = 1 diff --git a/providers/nearai/models/google/gemini-2.5-pro.toml b/providers/nearai/models/google/gemini-2.5-pro.toml index 1c676a96516..1dd86d6408a 100644 --- a/providers/nearai/models/google/gemini-2.5-pro.toml +++ b/providers/nearai/models/google/gemini-2.5-pro.toml @@ -1,8 +1,5 @@ -# Budget: reasoning.max_tokens, the OpenAI-compatible reasoning field this gateway accepted in -# the 2026-09-08 probes. The 128..32768 range follows the openrouter peer for this model, and -# thinking cannot be turned off on Gemini 2.5 Pro, so there is no toggle. base_model = "google/gemini-2.5-pro" -reasoning_options = [{ type = "budget_tokens", min = 128, max = 32_768 }] +reasoning_options = [] [cost] input = 1.25 @@ -14,6 +11,3 @@ tier = { type = "context", size = 200_000 } input = 2.5 output = 15 cache_read = 0.25 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/google/gemini-3.1-flash-lite.toml b/providers/nearai/models/google/gemini-3.1-flash-lite.toml index fbb0aa7c0ef..b32d73c7f4c 100644 --- a/providers/nearai/models/google/gemini-3.1-flash-lite.toml +++ b/providers/nearai/models/google/gemini-3.1-flash-lite.toml @@ -1,12 +1,8 @@ -# Effort levels copied from providers/google/models/gemini-3.1-flash-lite.toml; google-vertex, -# openrouter and vercel list the same four. base_model = "google/gemini-3.1-flash-lite" -reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] +reasoning_options = [] [cost] input = 0.25 output = 1.5 cache_read = 0.025 - -[modalities] -input = ["text", "image"] +input_audio = 0.5 diff --git a/providers/nearai/models/google/gemini-3.5-flash.toml b/providers/nearai/models/google/gemini-3.5-flash.toml index 8d66577e3f4..cdb6aa95773 100644 --- a/providers/nearai/models/google/gemini-3.5-flash.toml +++ b/providers/nearai/models/google/gemini-3.5-flash.toml @@ -1,12 +1,8 @@ -# Effort levels copied from providers/google/models/gemini-3.5-flash.toml and the openrouter, -# vercel and google-vertex peers. base_model = "google/gemini-3.5-flash" -reasoning_options = [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] +reasoning_options = [] [cost] input = 1.5 output = 9 cache_read = 0.15 - -[modalities] -input = ["text", "image"] +input_audio = 1.5 diff --git a/providers/nearai/models/google/gemini-3.8-flash.toml b/providers/nearai/models/google/gemini-3.8-flash.toml deleted file mode 100644 index f8e40d70f3d..00000000000 --- a/providers/nearai/models/google/gemini-3.8-flash.toml +++ /dev/null @@ -1,12 +0,0 @@ -# Effort levels copied from providers/google/models/gemini-3.8-flash.toml; google-vertex, -# github-copilot and cortecs list the same three. -base_model = "google/gemini-3.8-flash" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] - -[cost] -input = 0.75 -output = 3.75 -cache_read = 0.075 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/moonshotai/kimi-k2.6.toml b/providers/nearai/models/moonshotai/kimi-k2.6.toml deleted file mode 100644 index b180e605643..00000000000 --- a/providers/nearai/models/moonshotai/kimi-k2.6.toml +++ /dev/null @@ -1,18 +0,0 @@ -# Toggle: chat_template_kwargs.thinking = true|false (on by default); reasoning_effort is ignored -# https://docs.near.ai/cloud/reasoning-models -# The catalog advertises image input on this route. It was probed and rejected, so this entry -# is text-only and carries no attachment support. -base_model = "moonshotai/kimi-k2.6" -attachment = false -reasoning_options = [{ type = "toggle" }] - -[interleaved] -field = "reasoning_content" - -[cost] -input = 0.81 -output = 3.85 -cache_read = 0.41 - -[modalities] -input = ["text"] diff --git a/providers/nearai/models/moonshotai/kimi-k3.toml b/providers/nearai/models/moonshotai/kimi-k3.toml deleted file mode 100644 index 8ae97b63670..00000000000 --- a/providers/nearai/models/moonshotai/kimi-k3.toml +++ /dev/null @@ -1,19 +0,0 @@ -# Toggle: chat_template_kwargs.thinking = true|false (on by default); reasoning_effort is ignored -# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# reasoning_content present when on, absent when off -# The catalog advertises image input on this route. It was probed and rejected, so this entry -# is text-only and carries no attachment support. -base_model = "moonshotai/kimi-k3" -attachment = false -reasoning_options = [{ type = "toggle" }] - -[interleaved] -field = "reasoning_content" - -[cost] -input = 3.3 -output = 16.5 -cache_read = 0.33 - -[modalities] -input = ["text"] diff --git a/providers/nearai/models/openai/gpt-4.1-mini.toml b/providers/nearai/models/openai/gpt-4.1-mini.toml index 27124c07c4d..b2d9217542d 100644 --- a/providers/nearai/models/openai/gpt-4.1-mini.toml +++ b/providers/nearai/models/openai/gpt-4.1-mini.toml @@ -4,6 +4,3 @@ base_model = "openai/gpt-4.1-mini" input = 0.4 output = 1.6 cache_read = 0.1 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-4.1.toml b/providers/nearai/models/openai/gpt-4.1.toml index f618ee47235..1fdb518f628 100644 --- a/providers/nearai/models/openai/gpt-4.1.toml +++ b/providers/nearai/models/openai/gpt-4.1.toml @@ -4,6 +4,3 @@ base_model = "openai/gpt-4.1" input = 2 output = 8 cache_read = 0.5 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-5.4.toml b/providers/nearai/models/openai/gpt-5.4.toml index 2db7f9d6f66..230eac09d35 100644 --- a/providers/nearai/models/openai/gpt-5.4.toml +++ b/providers/nearai/models/openai/gpt-5.4.toml @@ -11,6 +11,3 @@ tier = { type = "context", size = 272_000 } input = 5 output = 22.5 cache_read = 0.5 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-5.5.toml b/providers/nearai/models/openai/gpt-5.5.toml index 1c3ddd47bd5..07a4af278d0 100644 --- a/providers/nearai/models/openai/gpt-5.5.toml +++ b/providers/nearai/models/openai/gpt-5.5.toml @@ -11,6 +11,3 @@ tier = { type = "context", size = 272_000 } input = 10 output = 45 cache_read = 1 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-5.6-luna.toml b/providers/nearai/models/openai/gpt-5.6-luna.toml deleted file mode 100644 index 140c5ad9d41..00000000000 --- a/providers/nearai/models/openai/gpt-5.6-luna.toml +++ /dev/null @@ -1,10 +0,0 @@ -base_model = "openai/gpt-5.6-luna" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh", "max"] }] - -[cost] -input = 0.2 -output = 1.2 -cache_read = 0.02 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-5.6-sol.toml b/providers/nearai/models/openai/gpt-5.6-sol.toml deleted file mode 100644 index 4ff46a5b270..00000000000 --- a/providers/nearai/models/openai/gpt-5.6-sol.toml +++ /dev/null @@ -1,10 +0,0 @@ -base_model = "openai/gpt-5.6-sol" -reasoning_options = [{ type = "effort", values = ["none", "low", "medium", "high", "xhigh", "max"] }] - -[cost] -input = 4 -output = 20 -cache_read = 0.4 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/openai/gpt-6-astra.toml b/providers/nearai/models/openai/gpt-6-astra.toml deleted file mode 100644 index 958ac130b7c..00000000000 --- a/providers/nearai/models/openai/gpt-6-astra.toml +++ /dev/null @@ -1,10 +0,0 @@ -base_model = "openai/gpt-6-astra" -reasoning_options = [{ type = "effort", values = ["low", "medium", "high", "xhigh", "max"] }] - -[cost] -input = 10 -output = 50 -cache_read = 1 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/openai/o3.toml b/providers/nearai/models/openai/o3.toml index 09448ed5ea2..da90132d618 100644 --- a/providers/nearai/models/openai/o3.toml +++ b/providers/nearai/models/openai/o3.toml @@ -5,6 +5,3 @@ reasoning_options = [{ type = "effort", values = ["low", "medium", "high"] }] input = 2 output = 8 cache_read = 0.5 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml b/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml deleted file mode 100644 index d57a7a7419b..00000000000 --- a/providers/nearai/models/qwen/qwen3.5-397b-a17b.toml +++ /dev/null @@ -1,16 +0,0 @@ -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) -# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# reasoning_content present when on, absent when off -base_model = "alibaba/qwen3.5-397b-a17b" -reasoning_options = [{ type = "toggle" }] - -[interleaved] -field = "reasoning_content" - -[cost] -input = 0.5 -output = 3.3 -cache_read = 0.25 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/qwen/qwen3.7-max.toml b/providers/nearai/models/qwen/qwen3.7-max.toml deleted file mode 100644 index 2e1eb7e69c6..00000000000 --- a/providers/nearai/models/qwen/qwen3.7-max.toml +++ /dev/null @@ -1,10 +0,0 @@ -# No caller-side reasoning control on this route: reasoning_content is never returned. -# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08 with -# chat_template_kwargs.enable_thinking, chat_template_kwargs.thinking, reasoning_effort, -# reasoning.enabled and reasoning.effort — reasoning_content was empty in every case. -base_model = "alibaba/qwen3.7-max" -reasoning_options = [] - -[cost] -input = 2.8 -output = 7.5 diff --git a/providers/nearai/models/z-ai/glm-5.2.toml b/providers/nearai/models/z-ai/glm-5.2.toml deleted file mode 100644 index c48c32a4065..00000000000 --- a/providers/nearai/models/z-ai/glm-5.2.toml +++ /dev/null @@ -1,18 +0,0 @@ -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) -# NEAR AI Cloud TEE deployment. release_date/last_updated track the TEE catalog -# refresh, not the lab release (see models/zhipuai/glm-5.2.toml). -# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# reasoning_content present when on, absent when off -base_model = "zhipuai/glm-5.2" -name = "GLM 5.2 TEE" -release_date = "2026-09-08" -last_updated = "2026-09-08" -reasoning_options = [{ type = "toggle" }] - -[interleaved] -field = "reasoning_content" - -[cost] -input = 1.4 -output = 4.4 -cache_read = 0.3 diff --git a/providers/nearai/models/z-ai/glm-5.3-flash.toml b/providers/nearai/models/z-ai/glm-5.3-flash.toml deleted file mode 100644 index 8531f722610..00000000000 --- a/providers/nearai/models/z-ai/glm-5.3-flash.toml +++ /dev/null @@ -1,23 +0,0 @@ -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) -# NEAR AI Cloud TEE deployment. release_date/last_updated track the TEE catalog -# refresh, not the lab release (see models/zhipuai/glm-5.3-flash.toml). -# Verified live on POST https://cloud-api.near.ai/v1/chat/completions 2026-09-08: -# reasoning_content present when on, absent when off -base_model = "zhipuai/glm-5.3-flash" -name = "GLM 5.3 Flash TEE" -release_date = "2026-09-08" -last_updated = "2026-09-08" - -[interleaved] -field = "reasoning_content" - -[[reasoning_options]] -type = "toggle" - -[cost] -input = 0.15 -output = 0.5 -cache_read = 0.035 - -[modalities] -input = ["text", "image"] diff --git a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml index 818d198d82e..8043e4c0cf5 100644 --- a/providers/nearai/models/zai-org/GLM-5.1-FP8.toml +++ b/providers/nearai/models/zai-org/GLM-5.1-FP8.toml @@ -1,20 +1,15 @@ -# NEAR AI Cloud TEE deployment (FP8). release_date/last_updated track the TEE catalog -# refresh, not the lab release (see models/zhipuai/glm-5.1.toml). -# Toggle: chat_template_kwargs.enable_thinking = true|false (on by default) -# https://docs.near.ai/cloud/reasoning-models -# limit.output is inherited from the lab (131_072) on purpose. The gateway's own -# max_output_length says 16384, but that field is advisory and is not enforced: -# verified 2026-09-10 on POST https://cloud-api.near.ai/v1/chat/completions, -# max_tokens of 16384, 40000 and 131072 were all accepted, while 202752 and above -# were rejected with "Requested token count exceeds the model's maximum context". -# The binding limit is the 202_752 context window (max_model_len on -# https://glm-5-1.completions.near.ai/v1/models), which is why context is overridden -# here and output is not. See https://docs.near.ai/cloud/guides/integrations/model-discovery -base_model = "zhipuai/glm-5.1" -name = "GLM 5.1 FP8 TEE" -release_date = "2026-09-08" -last_updated = "2026-09-08" +name = "GLM-5.1 FP8" +description = "Flagship GLM model for hybrid reasoning, coding, and agentic engineering" +family = "glm" +release_date = "2026-03-27" +last_updated = "2026-03-27" +attachment = false +reasoning = true reasoning_options = [{ type = "toggle" }] +temperature = true +tool_call = true +structured_output = true +open_weights = true [interleaved] field = "reasoning_content" @@ -22,7 +17,11 @@ field = "reasoning_content" [cost] input = 1.4 output = 4.4 -cache_read = 0.26 [limit] context = 202_752 +output = 16384 + +[modalities] +input = ["text"] +output = ["text"] diff --git a/providers/nearai/provider.toml b/providers/nearai/provider.toml index 483c70ad3d8..0f027770a56 100644 --- a/providers/nearai/provider.toml +++ b/providers/nearai/provider.toml @@ -1,11 +1,9 @@ name = "NEAR AI Cloud" npm = "@ai-sdk/openai-compatible" # Gateway and direct TEE hosts use the same POST `/v1/chat/completions` API. -# Routes NEAR AI hosts itself take `chat_template_kwargs.thinking|enable_thinking = true|false`; +# Native GLM/Qwen controls use `chat_template_kwargs.enable_thinking = true|false`; # GPT-OSS uses `reasoning_effort = low|medium|high` and cannot be disabled. -# Relayed routes take the OpenAI-compatible `reasoning` object (`reasoning.enabled`, -# `reasoning.effort`, `reasoning.max_tokens`). The Anthropic relays accept it but return no -# reasoning content, so those entries publish no caller-side control. +# Third-party routes pass through their provider-native reasoning controls. # https://docs.near.ai/cloud/guides/openai-compatibility # https://docs.near.ai/cloud/reasoning-models (accessed 2026-06-25) api = "https://cloud-api.near.ai/v1" diff --git a/sync.md b/sync.md index dc0068b54e5..2f98c598ee8 100644 --- a/sync.md +++ b/sync.md @@ -271,8 +271,6 @@ xAI is implemented in `packages/core/src/sync/providers/xai.ts`. - `limit.output` is never synced. `max_output_length` is advisory rather than enforced: a request above it is accepted, and only exceeding the context window is rejected. - No capability is taken from the endpoint, because its capability fields are wrong in both directions. `supported_features` lists `reasoning` for relayed routes that accept every documented reasoning parameter and still return no reasoning content, and omits it for others that plainly reason. `input_modalities` advertises image input for routes that reject it, and also reports an `embedding` modality the schema has no value for. - `reasoning`, `reasoning_options`, `tool_call`, `structured_output`, `modalities`, `attachment`, `interleaved` and lifecycle `status` are all hand-authored. -- A modality list is only narrowed where the narrowing was checked. The Moonshot routes were image-probed and reject it, so they stay text-only; `whisper-large-v3` is audio-in; the embedding, reranker and image models are text-in. Every other relayed route publishes the lab's text and image set. `pdf` is dropped because the gateway rejects it, and `video` and `audio` are dropped because no route was verified to accept them. -- Hand-authored controls follow the relay guidance in `AGENTS.md`. The routes NEAR AI hosts itself and several Anthropic relay routes were probed live against `cloud-api.near.ai`; the remaining Anthropic routes share that same relay surface and each names the evidence it rests on, which is why no Anthropic route here publishes a caller-side reasoning control. The Google and OpenAI relay routes follow the openai-compatible peers of the same models, and state their controls in terms of this gateway's own `reasoning` object rather than any lab-native request path. Audio prices are only published where the route's declared input modalities can reach them. - New models are not created automatically (`skipCreates`) because the endpoint exposes no release date or knowledge cutoff, and most NEAR AI models reason and so need hand-authored controls. - Remote-only models are listed in the sync notice rather than filed as issues (`trackMissingModels: false`), because a substantial part of the catalog has no local entry. - Absence never removes a model (`deleteMissing: false`): a truncated response would be indistinguishable from a genuine withdrawal. From 8fe27f47de5dd504797e0b45acdd2cb8288378d5 Mon Sep 17 00:00:00 2001 From: neo-sky Date: Fri, 11 Sep 2026 13:00:27 -0400 Subject: [PATCH 15/15] test(nearai): match the fixture owner to the live catalog --- packages/core/test/nearai.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/test/nearai.test.ts b/packages/core/test/nearai.test.ts index 1cfe4d7f8d1..cd7c0bd45fb 100644 --- a/packages/core/test/nearai.test.ts +++ b/packages/core/test/nearai.test.ts @@ -17,7 +17,7 @@ function nearAIModel(overrides: Partial = {}): NearAIModel { id: "zai-org/GLM-5.1-FP8", object: "model", created: 1_759_104_000, - owned_by: "zai-org", + owned_by: "nearai", name: "GLM 5.1 FP8", pricing: { input: 1.4, output: 4.4, input_cache_read: "0.00000026" }, context_length: 202_752,