Skip to content

feat: add Neosantara provider - #6165

Open
ErRickow wants to merge 16 commits into
anomalyco:devfrom
neosantara-xyz:feat/neosantara-provider
Open

feat: add Neosantara provider#6165
ErRickow wants to merge 16 commits into
anomalyco:devfrom
neosantara-xyz:feat/neosantara-provider

Conversation

@ErRickow

@ErRickow ErRickow commented Sep 3, 2026

Copy link
Copy Markdown

Neosantara is an OpenAI-compatible LLM gateway (a multi-model relay) from Indonesia. This PR adds the provider, logo, model TOMLs, and a sync module.

Data source

The sync consumes a single public endpoint — GET https://api.neosantara.xyz/v1/catalog — which returns the catalog in the models.dev / LLM Gateway response shape (family, architecture, providers[] with reasoning_efforts, and USD‑per‑token pricing). No API key is required.

The gateway performs the host‑specific work upstream (USD pricing incl. IDR conversion and any promotional discount, capability flags, and the mapped reasoning surface), so the models.dev sync is a thin, override‑only translation of that shape.

Scope / filters

A model is synced when it:

  • is not deprecated,
  • resolves to a canonical models/ entry (by id, or a small alias map for renamed generations), and
  • serves ≥ 100k context and advertises function calling, or is an image‑generation model.

Anything the public filter accepts but we can't map yet (no canonical models/ entry) is reported via skippedNotice instead of dropped silently. 49 models currently sync (48 token‑priced + 1 image).

Reasoning options (per‑model)

Neosantara normalizes reasoning onto a single reasoning_effort field and reports each model's real control surface in the catalog. The sync maps it with the LLM Gateway convention:

catalog reasoning_efforts reasoning_options
[] [] — always‑on, no caller control
["none"] [{ type = "toggle" }] (with the required leading wire comment)
graded levels [{ type = "effort", values = … }]

Levels are intersected with the host ladder none·minimal·low·medium·high·xhigh·max. Examples: glm-4.5-flash = toggle; glm-4.7-flash / *V = always‑on (forced thinking); deepseek-v4-* = none/high/max; glm-5.3-flash = low/high/max (forced); gpt-5.x = none…xhigh; gemini-3.x = none/low/medium/high. Current split: 29 effort, 4 always‑on, 1 toggle. These were derived from the gateway's provider adapters and, for the GLM free models, confirmed with live requests.

Pricing

USD per million tokens, converted from the endpoint's per‑token USD strings. IDR conversion and promotional discounts are handled upstream by the gateway, so no currency logic lives in the sync. Free models keep input = 0 / output = 0.

Notes

  • interleaved.field = "reasoning_content" on reasoning models (the gateway streams reasoning there).
  • max_output is intentionally not published — the gateway's runtime cap is not the model's true output limit.
  • Re‑running the sync is idempotent, and bun validate passes.

Neosantara is an OpenAI-compatible LLM gateway. Both catalog endpoints used
by the sync are public and need no API key:

- https://api.neosantara.xyz/v1/models
- https://api.neosantara.xyz/v1/public/pricing

The sync module registers with the existing provider-sync workflow, so the
catalog is refreshed by the usual periodic automation.

Scope of the generated catalog:

- text models with at least 100k context that advertise function calling
- image generation models that have a canonical models/ entry
- deprecated models are excluded

Pricing is published in USD per million tokens, applying the customer-facing
discount and converting IDR list prices with the exchange rate the pricing
endpoint reports. Per-image pricing is left unpublished because models.dev
has no field for it.

Reasoning options are reviewed per model: each effort list is the lab/peer
set intersected with what the public request schema accepts, and models that
expose no caller control author an empty set.

Provider files stay override-only via base_model, so limits, modalities and
benchmarks are inherited from the canonical lab entries.
Single-colour vector mark with a square viewBox and no fixed dimensions, so
it inherits the surrounding text colour when inlined.
The embedded raster carried ~13% transparent padding on every side and was
inset a further 25 units inside a 500x500 viewBox, so the mark covered only
about 66% of the canvas and rendered smaller than neighbouring logos.

Crop to the opaque bounds, centre the mark on a square canvas that it fills
edge to edge, and drop the root width/height (the site strips them when it
inlines the file). Also reduces the file from 102 KB to 59 KB.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [critical] [violation] providers/neosantara/logo.svg:1 - Check: New-provider logo must be SVG using currentColor, with no fixed size or hardcoded colors. Why: The final logo is a base64 PNG embedded via <image xlink:href="data:image/png;…"> inside a bare SVG shell. That cannot inherit theme color and hardcodes pixel colors, so it fails the compliant-logo blocker (the earlier vector/currentColor mark was replaced). Action: Restore a true vector logo.svg (paths/shapes with currentColor, square viewBox, no width/height, no embedded raster).
  • [high] [violation] packages/core/src/sync/providers/neosantara.ts:362 - Check: budget_tokens only for real reasoning-budget APIs; not Claude 4.7+ adaptive effort. Why: claude-fable-5, claude-sonnet-5, claude-opus-7, and claude-opus-8 are authored as toggle + budget_tokens, but first-party Anthropic entries for those models are effort (and for Sonnet 5, toggle + effort)—not extended-thinking budgets. Wire comments claim /v1/messages thinking.budget_tokens on an OpenAI-compatible /v1 host, which invents a budget surface AGENTS.md explicitly disallows for Claude 4.7+. Action: Replace those four control sets with the lab/peer effort (and toggle only if this host really forwards a separate on/off), drop budget_tokens, and keep leading wire comments accurate for the OpenAI-compatible request path.
  • [high] [violation] packages/core/src/sync/providers/neosantara.ts:367 - Check: On multi-model relays, reasoning_options = [] means no caller control—not uncertainty—and must not ignore lab/peer controls the host can express. Why: The PR states this host accepts reasoning_effort of none|minimal|low|medium|high|xhigh, and the same sync already authors effort for gpt-5.6-* and claude-opus-5. Yet many reasoners whose lab/peer baselines expose controls are written as [], including gpt-5.4, gpt-5.4-nano, gpt-5.5, gpt-5-nano, gemini-3.6-flash, gemini-3.7-flash, deepseek-v4-flash, deepseek-v4-pro, claude-opus-4-6, claude-sonnet-4-6, kimi-k2.5, kimi-k2.6, and kimi-k3. That contradicts the host schema claim and sibling entries on this provider. Action: For each of those IDs, set reasoning_options to the lab/same-surface peer set intersected with what Neosantara actually forwards (typically GPT effort lists; Gemini L/M/H; DeepSeek toggle+effort mapped onto this host’s fields; Claude 4.6 effort±budget only if budget is real here; Kimi toggle±effort). Keep [] only with model-specific proof that this route has no control.
  • [medium] [possible mistake] packages/core/src/sync/providers/neosantara.ts:350 - Check: DeepSeek V4 effort baseline is lab/peer high/max (plus toggle), not invented L/M/H. Why: deepseek-v4-pro-0813 is authored as effort ["low", "high"] while first-party DeepSeek V4 Pro is toggle + ["high", "max"] (low maps to high). Dropping max for the host enum is fine; inventing low and omitting toggle without a host-specific wire path is not the documented baseline. Action: Align with lab/peers on this surface (e.g. toggle + high if both exist here, or effort values actually honored after dropping unsupported max), and document the exact request fields in a leading comment when toggle is used.
  • [medium] [possible mistake] providers/neosantara/models/laguna-s-2.1.toml:3 - Check: Relay effort lists must come from lab/same-surface peers, not a default L/M/H. Why: First-party Poolside laguna-s-2.1 is toggle-only (enable_thinking), but Neosantara authors ["low", "medium", "high"] for both Laguna models. Action: Verify this host really accepts graded reasoning_effort for Laguna; if not, use toggle (with wire comment) or [] only if there is no control—do not keep L/M/H without host evidence.

This host is OpenAI-compatible and normalizes reasoning onto a single
caller-facing field, reasoning_effort, accepting
none|minimal|low|medium|high|xhigh. Upstream-native shapes are handled behind
that field and never appear in a caller's request, so documenting a thinking
budget or a vendor toggle described the wrong surface.

Every reasoning model now authors an effort list taken from its lab entry and
same-surface peers, intersected with the values this host accepts, so `max` is
dropped and `minimal` appears only where the lab or peers list it. Two models
whose lab and peers document no graded level keep a toggle, since on or off is
the caller's only choice there.

Drops all budget_tokens controls and the empty control sets, and removes the
wire comments that pointed at a native surface callers never reach.
The per-model table meant every new reasoning model needed a code change. The
values it held were already in the repository, so read them at sync time
instead: the underlying lab entry wins, otherwise the set its same-surface
peers agree on, intersected with the values this host accepts.

Preferring the lab over a relay also corrects two entries the table had copied
from the wrong source. deepseek-v4-flash now follows DeepSeek's own low|high
rather than a relay's full enum, and laguna-xs-2.1 is a toggle like Poolside's
own entry instead of inheriting its sibling's graded levels.

New models now inherit controls with no change here.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [critical] [violation] providers/neosantara/logo.svg:1 - Check: New-provider logo.svg must use currentColor, with no fixed size or hardcoded colors. Why: The final mark is a base64 PNG inside <image>, so fills cannot follow theme/currentColor and colors are baked into the raster. That fails the new-provider logo blocker. Action: Restore a true vector SVG (paths/shapes) using currentColor only, square viewBox, and no root width/height or embedded bitmaps.
  • [high] [violation] packages/core/src/sync/providers/neosantara.ts:2824 - Check: Relay reasoning_options must copy lab + same-surface peer controls for this host, not invent shapes; empty means always-on / no control. Why: neosantaraReasoningControls (1) ignores lab toggles and [], (2) tallies only peers that already have effort, (3) defaults unknowns to { type: "toggle" }, and (4) resolves first-party files only at providers/<lab>/models/<id>.toml, missing nested lab paths such as providers/poolside/models/poolside/…. That systematically invents or drops controls. Action: Match Eden AI’s approach: honor lab [] as always-on; map lab/peer toggle onto this host’s reasoning_effort surface (typically none in effort, not a bare toggle); include toggle-only peers in the baseline; fix first-party path lookup for nested lab IDs; do not default missing baselines to toggle.
  • [high] [violation] providers/neosantara/models/kimi-k2.5.toml:5 - Check: Effort lists must follow the lab/peer baseline, not a full gateway enum. Why: Moonshot’s first-party entry is toggle-only; OpenRouter and other same-surface peers are also toggle (or empty). This file authors none|minimal|low|medium|high|xhigh, which invents graded levels the lab does not expose. The same pattern is in kimi-k2.6.toml. Action: Author toggle (or effort including none if that is the only host wire for off), not the full enum; regenerate via the fixed sync mapping.
  • [high] [violation] providers/neosantara/models/kimi-k2-thinking.toml:5 - Check: [] means the model reasons with no caller control. Why: Lab and most peers use reasoning_options = [] (always-on thinking). This entry authors effort = ["high"] from a minority peer, which falsely advertises a control. Action: Set reasoning_options = [] (and teach the sync to preserve lab always-on).
  • [high] [violation] providers/neosantara/models/laguna-s-2.1.toml:5 - Check: Baseline = Poolside lab + same-surface peers for that model. Why: Lab and OpenRouter/Vercel are toggle-only. This file authors low|medium|high because first-party nested path lookup fails and peer tally only counts effort peers (Pioneer/OpenCode). Action: Author toggle (or host-equivalent off control), not L/M/H; fix path/tally so sync stops rewriting this.
  • [high] [violation] providers/neosantara/models/glm-4.6v-flash.toml:1 - Check: toggle is only for a separate on/off field; off via effort=none must be effort-only (no toggle). Why: Header says # Toggle: reasoning_effort = none turns reasoning off while the option is { type = "toggle" }. That pairs “off = none” with toggle, which AGENTS.md forbids. Same broken header/shape on ling-3.0-flash-fin.toml and laguna-xs-2.1.toml. Action: If the only wire is reasoning_effort, use effort values that include none (when off is supported) or document a real separate field; do not use type = "toggle" for reasoning_effort = none.
  • [medium] [violation] providers/neosantara/models/deepseek-v4-pro.toml:5 - Check: DeepSeek V4 baseline is toggle + high/max (host drops max). Why: Lab is toggle + high|max. This host accepts none on reasoning_effort, so off should appear as none (Eden AI style), not a lone ["high"] that cannot disable thinking. Same for deepseek-v4-pro-0813.toml. Action: Author ["none", "high"] (or toggle + high only if a separate on/off field exists on this host); drop invented L/M/H.
  • [medium] [possible mistake] providers/neosantara/models/gpt-5.4-mini.toml:4 - Check: Provider reasoning should reflect whether this host actually serves the reasoner. Why: Lab/OpenAI mark GPT-5.4 mini as reasoning = true with effort controls; this file forces reasoning = false with no options. Same pattern on claude-4.5-opus, claude-4.5-sonnet, gpt-oss-20b, gpt-oss-120b, and several Gemini/GLM rows. Action: Confirm against Neosantara capabilities/docs; if the gateway still runs them as reasoners, keep reasoning = true and author host reasoning_options; only keep false with evidence the host disables reasoning.

…g options

The first pass at deriving controls had four flaws. It looked for a lab entry
at one fixed path, so nested layouts such as providers/poolside/models/poolside
were missed; it ignored lab entries that declare no control, so an always-on
reasoner borrowed a minority peer's levels; it tallied only peers that already
had an effort list, letting one relay outvote thirty toggles; and it fell back
to a bare toggle, which claims an on/off field this host does not expose.

Controls are now projected onto this host's single field the way Eden AI does
it: an empty lab set stays empty, a lab toggle becomes reasoning_effort = none
and joins the effort list, and the lab always outranks a relay.

kimi-k2-thinking is always-on again, kimi-k2.5 and k2.6 no longer claim graded
levels their lab does not document, deepseek-v4-pro gains the none it needs to
turn thinking off, and the Laguna pair follows Poolside instead of a sibling.
@ErRickow

ErRickow commented Sep 3, 2026

Copy link
Copy Markdown
Author

Thanks — the reasoning items were right, and fixing them exposed real bugs in how I was deriving controls. Addressed in b361068, dd7b6de and 28e3443.

Root cause. This host is OpenAI-compatible and normalizes reasoning onto a single caller-facing field, reasoning_effort. Upstream-native shapes never appear in a caller's request, so documenting a thinking budget or a bare toggle described a surface nobody can reach. Controls are now read from the canonical tree at sync time — the model's own lab entry wins, otherwise the shape its peers agree on — and projected onto that one field the way edenai.ts does it.

budget_tokens on the four Claude models — dropped. No first-party Anthropic entry uses a budget, and the /v1/messages wire comments are gone.

reasoning_options = [] used as uncertainty — gone. Every reasoning model now carries a derived control, and [] survives only where the lab itself declares no control: kimi-k2-thinking, minimax-m2.7.

The four derivation bugs you named — all real, all fixed. Lab lookup now matches by filename anywhere under providers/<lab>/, so nested layouts like providers/poolside/models/poolside/… resolve; a lab's empty set is honoured as always-on; the peer tally counts toggle and empty shapes instead of only effort ones; and nothing falls back to a bare toggle.

Concretely: kimi-k2-thinking[]; kimi-k2.5 and kimi-k2.6["none"] instead of the full enum; deepseek-v4-pro and -0813["none", "high"]; laguna-s-2.1 and laguna-xs-2.1["none"] following Poolside rather than a sibling; glm-4.6v-flash and ling-3.0-flash-fin["none"] with the contradictory toggle header removed. Across all 49 models there are now zero budget_tokens, zero bare toggles, and no value outside what the request schema accepts.

One item I'd push back on: reasoning = false on gpt-5.4-mini and friends. That override is host-level, not an oversight. The public catalog does not advertise reasoning for them:

gpt-5.4-mini:      ["text_generation","function_calling","json_mode"]
gpt-oss-20b:       ["text_generation","json_mode","function_calling"]
gpt-oss-120b:      ["text_generation","json_mode","function_calling"]
claude-4.5-opus:   ["text_generation","function_calling","json_mode","vision"]
claude-4.5-sonnet: ["text_generation","function_calling","json_mode","vision"]

The lab marks the underlying models as reasoners, but this host does not serve them that way, which is what a provider override is for. Happy to revisit if you'd rather the provider file stay silent and inherit.

The logo is still on me and I'll follow up with a vector mark.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [critical] [violation] providers/neosantara/logo.svg:1 - Check: New provider logo.svg must be vector SVG using currentColor, with no fixed size or hardcoded color. Why: The final logo is an embedded PNG (data:image/png;base64) inside a wrapper SVG, so it cannot inherit theme color and ships hardcoded raster colors. That fails the new-provider logo blocker in AGENTS.md. Action: Replace with a real vector mark (fill/stroke = currentColor, square viewBox, no width/height, no embedded raster). The earlier path-based mark was closer to compliant.
  • [high] [violation] providers/neosantara/models/kimi-k2.5.toml:5 - Check: Reasoning options must match this host’s real control surface and lab/peer baseline (AGENTS.md → Reasoning options; audit skill). Why: Several reasoners are authored as effort with only ["none"] (also kimi-k2.6, laguna-s-2.1, laguna-xs-2.1, glm-4.6v-flash, ling-3.0-flash-fin). Lab entries for these are binary on/off (toggle), not graded effort. ["none"] alone documents only “off,” invents an incomplete effort list, and is not the binary-on/off shape (toggle + wire comment) or a graded list with real on levels. Eden AI’s same projection refuses toggle-only rather than inventing ["none"]. Action: For each model, either (a) author toggle with a leading wire comment for the exact host field if on/off is real, (b) author the full host-supported effort set that actually turns reasoning on/off (e.g. none plus graded levels the host honors), or (c) use [] only with affirmative evidence of no caller control—and update neosantaraReasoningControls so sync cannot emit toggle-only → ["none"].
  • [high] [possible mistake] packages/core/src/sync/providers/neosantara.ts (neosantaraReasoningControls / lab index) - Check: First-party lab controls must outrank peers for the same underlying model. Why: Lab indexing keys by owner/basename only. providers/deepseek/models/deepseek-v4-pro.toml is the first-party control set (toggle + high/max) but is stored as deepseek/deepseek-v4-pro, while Neosantara’s deepseek-v4-pro-0813 looks up deepseek/deepseek-v4-pro-0813, misses the lab file, and falls through to peer consensus—hence the authored ["none", "low", "high"] instead of the lab-projected ["none", "high"] (after dropping max). Action: Resolve lab controls via base_model chain / metadata identity (or alias dated snapshots to the lab provider entry), re-sync, and align deepseek-v4-pro-0813.toml with the lab baseline.
  • [medium] [possible mistake] providers/neosantara/models/gpt-oss-120b.toml:2 - Check: Provider reasoning overrides must be real host deltas. Why: Canonical models/openai/gpt-oss-120b (and gpt-oss-20b) are reasoning = true, but Neosantara forces reasoning = false. If the gateway still runs these as reasoners (or accepts effort), clients will omit required reasoning_options and under-report capability. Action: Verify against the Neosantara catalog/docs whether these IDs reason on this host; if yes, set reasoning = true and author correct reasoning_options; if no, keep the override and cite host evidence in the PR body.
  • [medium] [possible mistake] providers/neosantara/models/claude-4.5-opus.toml:2 - Check: Same reasoning override accuracy. Why: claude-4.5-opus / claude-4.5-sonnet set reasoning = false while Anthropic lab entries reason. Action: Confirm the host truly disables thinking for these aliases; otherwise inherit reasoning and author host-accurate controls.
  • [low] [possible mistake] .pr-review/pull-request.json (PR body) - Check: Material catalog claims should map citations to what they support. Why: Sources list API/docs/pricing URLs, but the body does not map them to concrete cost figures, which models get which effort lists, or the IDR→USD rate/date used after discount. Action: Extend the PR body so each material pricing and reasoning claim points at a first-party source and states what that source supports (rate/date for IDR conversion included).

@ErRickow
ErRickow marked this pull request as draft September 3, 2026 07:57
Reading the gateway's public schemas end to end corrected one thing and
explained several others.

No model may author a toggle here. `reasoning.enabled` on its own is inert:
reasoning is switched on by `reasoning_effort` being anything other than
`none`, so a toggle would name a control a caller cannot use. Models whose lab
documents only a binary on/off therefore author the one effort value that
changes behaviour.

provider.toml now carries the wire format the way the established relays do:
the accepted effort values, how reasoning is switched off, that a
non-reasoning model rejects the field outright, and that published costs are
the raw price after the catalog discount with IDR converted at the rate the
pricing endpoint reports.
@ErRickow
ErRickow marked this pull request as ready for review September 3, 2026 08:32
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [critical] [violation] providers/neosantara/logo.svg:1 - Check: New-provider logo must use currentColor only (no fixed size or hardcoded color). Why: The final mark still hardcodes fills/strokes (#999, #d8d8d8, #bcbcbc, #a9a9a9, #fdfdfd, #000) and opacity-based greys, so it will not inherit theme color and fails the new-provider logo blocker. Action: Replace with a single-color vector that uses only currentColor (no hex/rgb fills or strokes), keep a square viewBox, and omit fixed width/height.
  • [high] [violation] providers/neosantara/models/kimi-k2.5.toml:4 - Check: Binary on/off reasoning must be authored as a real caller control, not an incomplete effort enum. Why: Several toggle-only lab/peer models are published as effort = ["none"] only (kimi-k2.5, kimi-k2.6, laguna-s-2.1, laguna-xs-2.1, glm-4.6v-flash, ling-3.0-flash-fin). That lists how to turn reasoning off but no value that turns it on, so clients cannot exercise the control the lab documents. Same-surface peers (and AGENTS.md) treat binary control as toggle (with a leading wire comment), or as effort that includes both off and real on levels. Action: For each of these, either author [[reasoning_options]] type = "toggle" with a top-of-file wire comment for the host mapping (e.g. reasoning_effort=none vs a non-none value), or publish the full host-accepted on/off effort set that actually enables reasoning—not ["none"] alone. Update the sync projector the same way so resyncs do not reintroduce the incomplete shape.
  • [medium] [possible mistake] providers/neosantara/models/deepseek-v4-pro.toml:7 - Check: Relay effort lists should preserve the lab/peer top effort when the host has an accepted substitute. Why: Lab DeepSeek V4 is toggle + high/max; OpenRouter peers map the top tier to xhigh. This host accepts xhigh but drops max, leaving only none/high and losing the highest tier. Action: Verify whether Neosantara maps lab max to xhigh (or another accepted value). If yes, include xhigh for DeepSeek V4 flash/pro (and the dated snapshot); if not, cite host docs/tests that max/xhigh is rejected or no-ops.
  • [medium] [possible mistake] providers/neosantara/models/gemini-3.5-flash.toml:2 - Check: Do not force reasoning = false on lab reasoners unless this host truly has no reasoning path. Why: Lab + first-party entries for several models are reasoning = true with controls (gemini-3.1-flash-lite, gemini-3.5-flash, gpt-oss-20b/120b, gpt-5.4-mini, Claude 4.5 opus/sonnet, etc.), but the sync overrides reasoning = false solely from a missing reasoning capability flag. That can hide real reasoning and omit required reasoning_options. Action: Confirm each override against the live Neosantara model object (or docs). If the route still reasons or accepts reasoning_effort, keep reasoning = true and author controls from the lab/peer baseline; only keep false where the host rejects reasoning for that id.

@ErRickow
ErRickow marked this pull request as draft September 3, 2026 08:41
…mment

Six models whose lab documents only an on/off were published as effort
["none"], which told a caller how to switch reasoning off but named no value
that switches it on. They are toggles now, each carrying a leading comment for
the mapping this host uses: reasoning_effort = "none" is off, any other
accepted value leaves it on, and reasoning.enabled alone does nothing.

Follows the same shape and header convention as the LLM Gateway sync, which
fronts many labs behind one reasoning_effort field too.
The vector mark still carried six hex fills and strokes, so it rendered the
same shade on both themes. Every fill and stroke is currentColor now, which is
what the site inlines against, while the existing opacity values keep the
depth of the original artwork.
@ErRickow

ErRickow commented Sep 3, 2026

Copy link
Copy Markdown
Author

All four addressed in c908cfd, 66f733c and ae8062f.

Logo — now a real vector: 9 paths, no raster, square viewBox="0 0 250 250", no root width/height, and every fill/stroke is currentColor. The original artwork's fill-opacity values are kept, so it still has depth while taking its hue from the surrounding text colour.

Binary reasoning published as effort = ["none"] — you're right that listed only the off value. Those six are toggles now, each with a leading wire comment for the mapping this host actually uses:

# Toggle: reasoning_effort = "none" turns reasoning off; any other accepted
# value (or omitting the field) leaves it on. This host has no separate on/off
# field: reasoning.enabled alone does not enable reasoning.

Same shape and header convention as llmgateway.ts:134-138, which also fronts many labs behind one reasoning_effort field. Worth recording why a separate on/off would have been wrong here: the request schema does expose a reasoning.enabled boolean, but reasoning is only switched on when an effort other than none is present, so enabled on its own is inert.

DeepSeek V4 losing the top tiermax is rejected outright, not silently dropped: the field is z.enum(['none','minimal','low','medium','high','xhigh']), so a request carrying max fails validation before dispatch. On whether xhigh substitutes for the lab's max, I have no host evidence either way, and the peers that use xhigh are documenting their own mapping rather than this one. Rather than assert a mapping I cannot show, the entry stays at the values the lab documents and this host accepts. If you'd rather see xhigh included on the strength of the peer convention, say so and I'll add it.

reasoning = false overrides — these are host deltas, verified against the live catalog rather than inferred. All 15 such files correspond to ids whose capabilities array omits reasoning, and the gateway does not merely ignore the field for them: a request carrying reasoning_effort is rejected with HTTP 400 unsupported_capability. The ids you named:

gemini-3.5-flash       ["text_generation","function_calling","json_mode","vision"]
gemini-3.1-flash-lite  ["text_generation","vision","function_calling","json_mode"]
gpt-oss-20b            ["text_generation","json_mode","function_calling"]
gpt-oss-120b           ["text_generation","json_mode","function_calling"]
gpt-5.4-mini           ["text_generation","function_calling","json_mode"]
claude-4.5-opus        ["text_generation","function_calling","json_mode","vision"]
claude-4.5-sonnet      ["text_generation","function_calling","json_mode","vision"]

Keeping reasoning = true for them would advertise a control that returns 400.

Longer term. The recurring theme across your reviews is that this entry infers the host's reasoning surface from lab and peer files. The hosts that avoid that publish it themselves — capabilities.reasoning_efforts on LLM Gateway and DigitalOcean, reasoning.effort_values on Merge Gateway, opencode.variants.*.reasoning on Kilo. I'm proposing the same on the Neosantara side so the sync reads the accepted values per model instead of deriving them. Until that ships, the derivation follows the lab entry first and peer consensus second.

@ErRickow
ErRickow marked this pull request as ready for review September 3, 2026 08:54
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/neosantara.ts:456 - Check: Resolved provider models must not contradict canonical lab reasoning (and must set reasoning_options when reasoning = true). Why: buildNeosantaraModel sets reasoning only from Neosantara capabilities.includes("reasoning"), then writes reasoning = false with no reasoning_options for many lab reasoners (e.g. claude-4.5-opusanthropic/claude-opus-4-5, gpt-5.4-mini, gpt-oss-20b/120b, gemini-3.1-flash-lite/3.5-flash, deepseek-v4-flash-0731, glm-4.5-flash/4.7/4.7-flash, minimax-m3, mistral-small-latest, muse-glimmer-30b, llama-3.3-nemotron-super-49b-v1.5). Eden AI treats reasoning as a lab fact; a missing gateway capability flag must not force false. Action: Derive reasoning from the base_model lab entry (or lab ∪ gateway), author reasoning_options for every resolved reasoner, and stop emitting reasoning = false overrides that contradict the lab.
  • [high] [violation] providers/neosantara/logo.svg:6 - Check: New-provider logo.svg must use currentColor for fills/strokes (no fixed color). Why: Three paths use only fill-opacity / stroke="currentColor" with no fill. SVG default fill is black, so those shapes stay black on both themes and fail the compliant-logo blocker. Established logos (e.g. Helicone) set fill="currentColor" together with opacity. Action: Add fill="currentColor" (and keep opacity) on every path that paints fill.
  • [low] [violation] providers/neosantara/provider.toml:10 - Check: Leading wire-format comments must match authored controls. Why: The header still says no model authors a toggle, but six models (glm-4.6v-flash, kimi-k2.5/k2.6, laguna-s-2.1/xs-2.1, ling-3.0-flash-fin) author type = "toggle" with toggle headers. Action: Update the provider.toml comment so it documents toggle + reasoning_effort mapping consistently with those files.

@ErRickow
ErRickow marked this pull request as draft September 3, 2026 09:09
@ErRickow

ErRickow commented Sep 3, 2026

Copy link
Copy Markdown
Author

@rekram1-node hei, the github action reviewer just making me going through to the loop. He always asking, but I'm unable to answer with the tag (eg. @bot).

The sync and reasoning field is gateway design, so if the reviewer point to the upstream that the existing models.dev provider have, is not valid issues, and he always ask, how tf i will reply to that feedback. Please give me some advice :)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this svg.... Would prefer b64 embed instead of full vector

Capability flags are read only from each catalog entry's `capabilities`
array, never inherited from lab metadata: this gateway enforces its own
list and answers HTTP 400 for `reasoning_effort` on a model without
`reasoning`, so a model the lab ships as a reasoner is published here
with reasoning = false until the catalog advertises it. `tool_call`
follows `function_calling` for the same reason. A capability the gateway
adds later is therefore picked up by the next sync with no code change.

Reasoning models gain `interleaved.field = "reasoning_content"`. Verified
against the live API through the AI SDK with streaming: `reasoning_effort
= none` returns zero reasoning tokens, any graded level streams
`reasoning_content` deltas, and `max` is rejected with the enum
`none|minimal|low|medium|high|xhigh`.

Reasoning-control indexing: the provider tree is resolved from the module
rather than the working directory, an unreadable tree throws instead of
silently publishing "no caller control" for every reasoning model, and a
lab entry whose controls this host cannot express is left unrecorded so
peer consensus still applies.

Model TOMLs regenerated with `sync-models.ts neosantara`; re-running it
reports no further changes. Also lets the remaining logo paths inherit
the theme color.
@ErRickow
ErRickow marked this pull request as ready for review September 3, 2026 10:55
@ErRickow

ErRickow commented Sep 3, 2026

Copy link
Copy Markdown
Author

about opus 7, 8... this is neosantara side wrong statement about the model id, sorry... will be fixed and will auto sync if we made changes on the gateway

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [high] [possible mistake] providers/neosantara/models/gpt-oss-20b.toml:2 - Check: Provider reasoning must reflect what this host actually serves, not a silent catalog omission. Why: Several entries force reasoning = false on models whose lab metadata is reasoning = true (including gpt-oss-20b, gpt-oss-120b, gpt-5.4-mini, claude-4.5-opus, claude-4.5-sonnet, deepseek-v4-flash-0731, gemini-3.5-flash, glm-4.7). That strips reasoning_options / interleaved and tells clients the route is non-reasoning. Action: Re-check each of these against GET /v1/models capabilities (and a live reasoning_effort call). If the host does serve reasoning, set reasoning = true and author the matching host controls; if it truly does not, keep false and cite that per-model evidence in the PR body.
  • [high] [violation] packages/core/src/sync/providers/neosantara.ts:288 - Check: On relays, reasoning_options = [] means affirmative no caller control, not uncertainty (AGENTS.md → Reasoning options). Why: neosantaraReasoningControls returns [] for both always-on lab/peer sets and unresolved sets (derived === undefined). Combined with always syncing reasoners, a model with no lab/peer control mapping is published as always-on with no controls. Action: Treat unresolved controls as skip (or preserve hand-authored), and only emit [] when lab/peers explicitly document always-on; restore a skip/notice path for unmapped reasoners.
  • [medium] [violation] providers/neosantara/models/gpt-oss-20b.toml:1 - Check: Non-USD costs must note FX rate and date in a leading top-of-file comment (AGENTS.md → Cost). Why: IDR list prices are converted via meta.exchange_rate.usd_idr, but generated IDR model TOMLs (e.g. gpt-oss-20b) ship bare USD numbers with no rate/date header; provider.toml describes the method only. Action: Have the sync write a leading header on IDR-priced models (rate, timestamp/source from the pricing response) and regenerate those files.
  • [medium] [possible mistake] providers/neosantara/models/deepseek-v4-pro.toml:7 - Check: Relay effort lists must be the lab/peer set this host can actually honor. Why: DeepSeek lab V4 is toggle + high/max (Flash: low/high/max). After dropping max (not in the host enum), Pro is published as ["none", "high"] and Flash as ["none", "low", "high"]. That is plausible only if this host really has no max/xhigh equivalent and maps off via none. Action: Confirm against docs/live traffic whether off is reasoning_effort=none and whether any host value covers lab max; if not, document the loss explicitly or adjust the projected set.

Treat missing lab and peer reasoning controls as unresolved instead of
publishing an affirmative always-on control set. Such models are now
skipped and reported until a reviewed control mapping exists; an empty
list remains reserved for explicitly always-on models.

Neosantara's DeepSeek route only consumes effort as an enable flag and
does not forward graded effort upstream, so publish those routes as a
binary toggle rather than claiming high/max distinctions the gateway
cannot honor. Correct the toggle header to record that omission defaults
to off.

Add authoritative FX provenance headers to every model whose IDR source
pricing is converted to USD, including the rate, source, and pricing
snapshot date. Regenerate provider TOMLs from the public catalog.

The gateway capability list remains authoritative for reasoning support:
models that omit reasoning from GET /v1/models retain reasoning=false,
regardless of provider-agnostic lab metadata.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] providers/neosantara/models/kimi-k2-thinking.toml:3 - Check: Relay reasoning_options must reflect this host’s caller controls, not lab always-on. Why: provider.toml and the PR state that on this gateway reasoning_effort = none turns reasoning off and any other accepted value turns it on, with live checks that none yields zero reasoning tokens. Publishing reasoning_options = [] on kimi-k2-thinking and minimax-m2.7 claims no caller control while the same host surface exposes an off switch. Action: Stop treating lab [] as host always-on when this surface accepts none. Author a real control (typically toggle, or effort including none) for these models, and update the sync so lab always-on does not force [] when the host off path applies.
  • [high] [violation] packages/core/src/sync/providers/neosantara.ts:3055 - Check: Multi-model relay baselines = lab same-surface peers ∩ host wire, not first-party Messages/native shapes. Why: hostControls / lab-first indexing projects Anthropic lab files (effort without off, or budget-only) and drops OpenAI-compat peer toggle/none. Generated Claude reasoners such as claude-opus-4-6 / claude-sonnet-4-6 end as ["low","medium","high"] with no off value, while provider.toml documents host-wide off via reasoning_effort = none and same-surface peers (e.g. OpenRouter Claude 4.6) expose toggle + graded effort. Action: Prefer same-surface OpenAI-compat peer controls for this host (or always include host none when the model reasons and the gateway accepts it). Regenerate Claude (and any other lab-native-surface) reasoners so off is represented; do not leave graded effort without none/toggle when the host off path is real.
  • [medium] [possible mistake] providers/neosantara/models/claude-opus-4-6.toml:9 - Check: Effort lists must not omit a host-verified off level. Why: Final graded Claude entries (claude-opus-4-6, claude-sonnet-4-6, claude-fable-5, claude-opus-7, claude-opus-8, claude-opus-5, etc.) advertise only graded levels while the provider documents none as the global off switch. That under-describes the request surface callers can use. Action: Confirm per model whether reasoning_effort=none is accepted; if yes, add none (or a documented toggle) to each affected file and to the derivation logic so future syncs keep it.

@ErRickow
ErRickow marked this pull request as draft September 3, 2026 12:47
…iformly

Neosantara is a relay that normalizes every model's reasoning onto one
OpenAI-compatible reasoning_effort field and maps each upstream native
shape (Anthropic budgets, DeepSeek/GLM toggles, OpenAI effort) behind it.
Its catalog advertises only whether a model reasons, not per-model effort
levels, so stop deriving per-model control sets from lab/peer files and
advertise the host's accepted enum for every reasoning-capable model.

This removes the lab/peer indexing, the DeepSeek toggle special-case, and
the always-on [] path. No reasoning model publishes [] anymore; DeepSeek
is treated like every other relayed model since the gateway maps effort.
Each generated reasoning TOML now carries a leading note explaining that
the effort list is Neosantara's mapped request surface, not the upstream
provider's API, so reviewers understand the divergence.

Verified live via the AI SDK (streaming): the host accepts
none|minimal|low|medium|high|xhigh and rejects max (HTTP 400).

Future-proof: an optional catalog reasoning_efforts array is consumed
automatically (filtered to the host enum) when Neosantara starts
publishing per-model levels; until then the full enum is used. Capability
flags remain catalog-driven, so a model the lab ships as a reasoner stays
reasoning=false until the neosantara catalog advertises it.
@ErRickow
ErRickow marked this pull request as ready for review September 3, 2026 13:10
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/neosantara.ts:142 - Check: Relay reasoning_options must be the lab + same-surface peer baseline intersected with this host’s real controls, not a fixed full schema enum (AGENTS.md → Reasoning options; audit skill anti-pattern “full schema effort enum dumps”). Why: Final sync authors ["none","minimal","low","medium","high","xhigh"] for every reasoning model and regenerates all reasoning TOMLs that way, explicitly abandoning lab/peer sets. That invents levels (e.g. minimal/xhigh on Claude/DeepSeek/always-on routes) and tells clients graded control exists where the origin surface is narrower or none. Wire acceptance of the enum is not the same as per-model meaningful control. Action: Restore per-model options from first-party lab entries + established same-surface peers, filtered to values this host actually maps with effect; stop defaulting to the full host enum. Re-sync the provider TOMLs afterward.
  • [high] [violation] providers/neosantara/models/deepseek-v4-pro.toml:12 - Check: DeepSeek V4 baseline is toggle + high/max (lab/OpenRouter peers), not GPT-style L/M/H (AGENTS.md; DeepSeek lab + OpenRouter peers). Why: These files now publish the full six-value effort list. Earlier in this same PR the author documented that Neosantara’s DeepSeek path only treats non-none as enable and forwards no graded effort—so advertising minimal/low/medium/xhigh is a false control surface. Action: Publish only the real DeepSeek control this host honors (binary toggle with a correct wire comment, or none + the grades that actually change behavior if graded mapping is proven). Apply the same fix to deepseek-v4-flash, deepseek-v4-flash-0731, and deepseek-v4-pro-0813.
  • [high] [violation] providers/neosantara/models/kimi-k2-thinking.toml:11 - Check: Always-on / no-caller-control reasoners must use reasoning_options = [], not invented effort tiers. Why: Lab Moonshot entry is []. This PR replaces that with the full host enum (same pattern on minimax-m2.7). Empty means no caller control; a full enum claims graded control without lab/peer or host evidence of effect. Action: Keep [] unless there is affirmative evidence this host exposes a real control for these IDs; regenerate via sync once the control logic is fixed.
  • [medium] [violation] providers/neosantara/models/gpt-5.4.toml:13 - Check: Extra effort values beyond lab/peers need host docs or live meaningful effect; do not add levels the baseline omits. Why: OpenAI’s gpt-5.4 (and several GPT-5.x peers) use none|low|medium|high|xhigh without minimal. Neosantara adds minimal (and the same full enum on nano/luna/sol/terra/etc.) solely because the gateway schema accepts it. Action: For GPT-family routes, author the OpenAI/lab peer effort set (plus only values this host is shown to change behavior for), not the entire request enum.

@ErRickow
ErRickow marked this pull request as draft September 3, 2026 13:14
…easoning

Rework the sync to consume Neosantara's single models.dev / LLM Gateway
shaped catalog (/v1/catalog) instead of merging /v1/models + /v1/public/
pricing. The gateway now performs the host-specific work (USD-per-token
pricing, capability flags, and the mapped reasoning surface), so the sync
is a thin, override-only translation.

Reasoning options are per-model, derived from each model's real control
surface reported by the catalog and mapped with the LLM Gateway
convention: [] = always-on (no caller control), ["none"] = on/off toggle,
otherwise graded effort. No more uniform full-enum dump. Efforts are
intersected with the host ladder, which now runs up to `max` (GLM-5.x and
DeepSeek V4 use it). Toggle entries carry the required leading wire
comment.

Kept: the 100k+ context / function-calling / image-model filters and the
base-model aliasing. Dropped: the two-endpoint merge, IDR conversion,
discount handling, and FX header (all now upstream).

Regenerated the provider TOMLs; re-running the sync is idempotent and
`bun validate` passes.
@ErRickow
ErRickow marked this pull request as ready for review September 3, 2026 17:55
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/neosantara.ts:6881 - Check: Relay reasoning_options must not treat uncertainty as affirmative always-on ([]). Why: neosantaraReasoningControls collapses both an explicit empty reasoning_efforts list and a missing/undefined list to []. On a multi-model relay, [] means “reasons with no caller control,” not “catalog omitted controls.” That can stamp always-on for models that actually expose effort/toggle. Action: Distinguish explicit [] (always-on) from missing reasoning_efforts; for the latter, skip the model (and report it) until the catalog publishes a real control set.
  • [high] [possible mistake] providers/neosantara/models/laguna-s-2.1.toml:8586 - Check: Relay effort lists must follow lab + same-surface peers for that model, not a full host ladder. Why: Final options are none/minimal/low/medium/high/xhigh/max, but Poolside’s own entry and OpenRouter peers are toggle-only (enable_thinking / reasoning.enabled). Advertising graded levels invents controls the lab/peers do not expose unless this host truly differentiates them. Same issue on laguna-xs-2.1. Action: Verify live/catalog behavior; if only on/off is real, author toggle (with the leading wire comment) or effort that only reflects the actual levels.
  • [high] [possible mistake] providers/neosantara/models/step-3.5-flash.toml:8723 - Check: Do not dump the host effort enum when lab/peers are narrower. Why: Final options are the full ladder including none/minimal/xhigh/max, while first-party StepFun documents only low/high and OpenRouter authors []. That is the full-enum anti-pattern unless Neosantara’s catalog/API meaningfully honors every listed value. Action: Intersect to the host-verified subset (likely low/high, or always-on [] if no control is forwarded); cite the catalog/API evidence for any extra levels.
  • [high] [possible mistake] providers/neosantara/models/ling-3.0-flash-fin.toml:8632 - Check: Baseline for toggle-only models on relays. Why: Final options are the full graded ladder, while established peers (OpenRouter/Vercel/opencode free) author toggle-only for this model. Graded L–max claims caller control the baseline does not support. Action: Match the host’s real surface: toggle with wire comment, or a verified narrower effort list—not the full enum.
  • [medium] [possible mistake] providers/neosantara/models/kimi-k2.5.toml:8511 - Check: Kimi reasoning controls vs lab/peer baseline. Why: Moonshot’s first-party entry is toggle-only; this PR publishes none…max. LLM Gateway peers also dump a wide enum, so this may be a shared gateway shape, but it still needs host evidence that graded efforts (including minimal/max) actually change behavior rather than collapsing to on/off. Same pattern on kimi-k2.6 / kimi-k3. Action: Confirm per-level effect on Neosantara; if only on/off works, author toggle (or effort with only the real levels).
  • [medium] [possible mistake] providers/neosantara/models/muse-spark-1.1.toml:8699 - Check: Extra effort values beyond lab/same-surface peers. Why: Meta/LLM Gateway baseline is minimal/low/medium/high/xhigh; this entry adds none and max. Extra levels need host proof. Action: Drop unproven values or provide catalog/live evidence that none and max are accepted and meaningful here.
  • [medium] [possible mistake] providers/neosantara/models/gpt-5.4.toml:6156 - Check: GPT effort lists should match OpenAI + GPT-style relay peers. Why: After the uniform-enum pass, GPT-5.4/5.5 still carry minimal in addition to OpenAI’s none/low/medium/high/xhigh (and GPT-5.6 variants may omit lab max). Unless the Neosantara catalog advertises those exact sets, this is inventing/dropping levels. Action: Align each GPT id to the catalog-advertised subset (and OpenAI peer baseline); do not keep a residual full-ladder stamp from the earlier uniform-enum approach.
  • [low] [violation] providers/neosantara/provider.toml:6515 - Check: Provider header must match the shipping sync source and reasoning policy. Why: Final code/tests use GET /v1/catalog and per-model reasoning_efforts, but provider.toml still documents the old /v1/models + /v1/public/pricing merge and the commit-14 “full enum for every reasoner” story. That misleads future sync/review. Action: Rewrite the leading comment for /v1/catalog, USD pricing already in-catalog, and the [] / ["none"]→toggle / graded-effort mapping actually implemented.

Replace the uniform host-enum reasoning surface with per-model effort
lists that follow each model's real controls (first-party lab entry +
same-surface OpenRouter/Vercel peers), never a full-enum dump:

- Poolside Laguna, InclusionAI Ling, Moonshot Kimi K2.5/K2.6 -> toggle
- StepFun Step-3.5 -> low/high; Meta Muse -> minimal..xhigh
- GPT-5.4/5.5 -> none/low/medium/high/xhigh (no minimal); GPT-5.6 adds max
- Claude -> none/low/medium/high; Kimi K3 -> none/low/high/max
- GLM-4.7 / *V and other forced/always-on models -> [] (no caller control)

Distinguish an explicit empty reasoning_efforts (always-on, []) from a
missing one: a reasoning model whose surface the catalog does not report
is now skipped and reported, not stamped always-on. Toggle entries carry
the leading wire comment.

Rewrite provider.toml for the /v1/catalog source and the []/toggle/effort
mapping. Regenerated TOMLs (6 toggle, 4 always-on, 24 effort); re-sync is
idempotent and bun validate passes.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] providers/neosantara/models/gpt-5-nano.toml:8983 - Check: Relay reasoning_options must follow the lab + same-surface peer baseline for that model (AGENTS.md → Reasoning options). Why: Final efforts are none / low / medium / high / xhigh, but OpenAI first-party and OpenRouter both use minimal / low / medium / high (no none, no xhigh). This invents levels and drops minimal. Action: Set reasoning_options to [{ type = "effort", values = ["minimal", "low", "medium", "high"] }] (or the exact host intersection of that set), and align the catalog/sync mapping so it cannot reintroduce the wrong ladder.
  • [high] [violation] providers/neosantara/models/deepseek-v4-flash.toml:8130 - Check: DeepSeek V4 baseline is lab/peer toggle + graded effort, not a GPT-style ladder. Why: Lab Flash is toggle + low / high / max; OpenRouter peers keep toggle + graded effort. The PR publishes only effort = ["none", "high", "max"], dropping Flash’s low and collapsing the lab toggle+effort surface. The same none / high / max shape is also applied to Pro/dated snapshots. Action: For each DeepSeek V4 route, publish this host’s real control: either toggle + lab efforts (low/high/max for Flash; high/max for Pro) with a leading wire comment, or if off is only reasoning_effort=none, use effort with none plus the lab graded set (include low on Flash). Do not stamp every DeepSeek id with the same incomplete list.
  • [high] [violation] providers/neosantara/models/claude-opus-4-6.toml:8888 - Check: Claude effort lists must track lab + same-surface peers, intersected with host-accepted values (host ladder includes max). Why: Final Claude entries use none / low / medium / high. Lab Opus 4.6 is low / medium / high / max (plus budget); Opus 4.7/4.8/Fable/Opus 5/Sonnet 5 include xhigh and/or max; OpenRouter peers keep those grades (often with toggle). Dropping max/xhigh while the host accepts max understates controls; inventing a uniform Claude ladder is not baseline-faithful. Action: Per Claude id, author lab/peer grades the host actually honors (restore max and, where lab/peers have it, xhigh). If off is host-only via reasoning_effort=none, keep none in effort or a documented toggle—do not strip lab grades.
  • [medium] [violation] providers/neosantara/models/gemini-3.6-flash.toml:8216 - Check: Gemini relay efforts must match Google lab (and peers), not a rewritten ladder. Why: Lab gemini-3.6-flash is minimal / low / medium / high; the PR uses none / low / medium / high (drops minimal, adds none). gemini-3.5-flash has the same pattern vs lab minimal / low / medium / high. Action: Restore minimal and only add none if this host truly exposes off for those models; otherwise match the lab set exactly.
  • [medium] [possible mistake] providers/neosantara/models/kimi-k3.toml:9115 - Check: Moonshot K3 lab is toggle + low / high / max. Why: Final file is effort = ["none", "low", "high", "max"] (folding toggle into none is plausible on an OpenAI-compat host), but confirm the live Neosantara surface actually accepts graded low/high/max rather than toggle-only. Action: Verify against the host API/docs and keep either toggle + ["low","high","max"] with a wire comment, or effort including none plus those grades—do not leave an unverified hybrid if graded effort is not forwarded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant