Repository navigation
feat(providers): add NaN.Builders API-key provider (chat, embeddings, audio, images, rerank, quota usage) - #16912
Merged
diegosouzapw merged 5 commits intoOct 17, 2026
Conversation
Register NaN.Builders (`nan`, https://api.nan.builders/v1) as an OpenAI-compatible API-key provider: chat with live `/v1/models` discovery, embeddings (qwen3-embedding, 4096 dims), STT (whisper), TTS (kokoro), image generation (flux-2-klein, qwen-image-2.1) and rerank. Add a per-model token quota fetcher (GET https://cloud-api.nan.builders/api/usage/quota) that maps each {model, tokensUsed, cap, periodEnd} row to a token quota and rejects malformed reports instead of guessing. The OpenAI-compatible speech path now honors an optional `defaultVoice` on the audio provider config, so a Kokoro request without `voice` sends `af_heart` instead of the OpenAI stock `alloy`. Co-authored-by: Tasa <93864300+tasarren@users.noreply.github.com> Inspired-by: decolua/9router#4429
| for (const kind of ["llm", "embedding", "stt", "tts", "image"]) { | ||
| assert.ok(entry.serviceKinds.includes(kind), `serviceKinds must include ${kind}`); | ||
| } | ||
| assert.ok(String(entry.apiHint).includes("https://cloud.nan.builders")); |
…vider count to 373 Replace the substring URL check flagged by CodeQL (incomplete URL substring sanitization) with an exact-string assertion, and update the public provider count the docs-counts gate requires now that nan is registered (llm.txt mirrors included).
diegosouzapw
added a commit
that referenced
this pull request
Oct 17, 2026
NaN.Builders (#16912) landed first and took the count to 373; DaoXE makes it 374. Regenerate PROVIDER_REFERENCE.md and update the count wherever the docs-counts gate requires it (llm.txt mirrors included).
diegosouzapw
added a commit
that referenced
this pull request
Oct 17, 2026
Merged via /merge-batch (2026-10-16 wave). Fixes applied on top of the port: the CodeQL incomplete-URL-substring alert in tests/unit/provider-daoxe-registry.test.ts now asserts the apiHint exactly; reconciled with #16912 (NaN.Builders, landed first) so both providers are registered and the count pins move once more; the public provider count goes 373 -> 374 (README, AGENTS.md, llm.txt + mirrors, package.json, generated skills — owner-approved, count-only lines). Focused tests 42/42 (DaoXE + NaN + reserved-prefix + constants-split); check:provider-consistency OK (374 canonical); check:docs-counts no strict drift (2 soft executor-count drifts are inherited from the tip); agent-skills-sync Generated 0; docs-sync PASS; boundary 774/774; eslint clean. Remaining CI reds are the inherited base-red #15306.
Contributor
CI Coverage Report
Coverage artifact was not available for this run. |
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
nan,https://api.nan.builders/v1) as an OpenAI-compatible API-key provider: chat with live/v1/modelsdiscovery, embeddings (qwen3-embedding, 4096 dims), STT (whisper), TTS (kokoro), image generation (flux-2-klein,qwen-image-2.1) and rerank (rerank).GET https://cloud-api.nan.builders/api/usage/quotathat maps each per-model{model, tokensUsed, cap, periodEnd}row to a token quota in the limits panel. A malformed report (duplicate model, negative/non-integer counters,cap <= 0, unparseableperiodEnd) is reported as unavailable; it is never partially guessed.defaultVoicefrom the audio provider config, so a Kokoro request withoutvoicesendsaf_heartinstead of the OpenAI stockalloy(which Kokoro does not have). Providers withoutdefaultVoicestill fall back toalloy.Attribution
Thanks to @tasarren for the original implementation.
Changes
open-sse/config/providers/registry/nan/index.ts(new) +open-sse/config/providers/index.ts: chat registry entry (buildOpenAiCompatibleRegistryEntry,modelsUrlfor live discovery, small seed list kept as the offline fallback).src/shared/constants/providers/apikey/gateways.ts: display entry (name, color#6D5EF3, website, apiHint pointing tohttps://cloud.nan.builders).src/shared/constants/config.ts:PROVIDER_ENDPOINTS.nan.open-sse/config/embeddingRegistry.ts,audioRegistry.ts(STT + TTS, new optionalAudioProvider.defaultVoice),imageRegistryData.ts,rerankRegistry.ts: curatednanentries.open-sse/handlers/audioSpeech.ts:voice: body.voice || providerConfig.defaultVoice || "alloy"(one line).open-sse/services/usage/nan.ts(new) wired intousage.ts,usage/fetcherProviders.ts,usage/supportedProviders.ts,src/lib/usage/providerLimits.tsand the ProviderLimits label map. Errors go throughsanitizeErrorMessage(), there is a 10 s timeout, and the upstream body is never echoed.src/app/api/providers/[id]/models/discovery/providerSets.ts:nanadded to the named OpenAI-style discovery set.docs/reference/PROVIDER_REFERENCE.md: only the total (372 → 373), the API-key section count (249 → 250) and the newnanrow.provider-node-reserved-prefix(431 → 432, id and alias are bothnan) andproviders-constants-split(249 → 250).Not ported (deliberately):
/v1/images/editsfornan/flux-2-klein.classifyImageEditTargetinsrc/app/api/v1/images/edits/route.tsonly accepts codex/fal/adobe/syntx/openrouter and custom nodes as built-in edit targets. Supporting NaN edits would change that public route's dispatch, so this PR leaves it out. Generation works. Edits can come in a follow-up.textIcon("NaN").Provider count docs (expected red)
check:docs-counts(and thereforecheck:docs-all) is red on purpose. The aggregate "372 providers" prose in README/AGENTS.md/llm.txt/docs/SVGs/package.jsondescription/skills now reads 373. Per the maintainer's decision for this campaign, the count prose and the protected agent-instruction surfaces are not touched here. A single count-sync PR lands at the end of the campaign. The real number also depends on merge order with the sibling provider PR #16889 (DaoXE), which bumps the same counters.Test plan
node --import tsx/esm --test tests/unit/nan-provider.test.tsfailed before the port (moduleopen-sse/services/usage/nan.tsmissing, registries returned null) and passes after:ℹ tests 11 ℹ pass 11 ℹ fail 0test:unit:cipreamble and an isolatedDATA_DIR:ℹ tests 3248 ℹ pass 3244 ℹ fail 4. After updating the two pinned counts, only 2 failures are left:check-docs-counts-sync.test.ts: the expected provider-count drift described above.models-catalog-route.test.ts› "v1 models catalog exposes bare Codex-preferred IDs" (codex-auto-review must not be listed): pre-existing on base. It fails the same way on a pristineorigin/release/v3.8.52checkout (ℹ tests 44 ℹ pass 43 ℹ fail 1) and has nothing to do withnan.provider-node-reserved-prefix+providers-constants-splitpass.npx vitest run tests/unit/ui/ProviderIcon-icon-url.test.tsx:Tests 94 passed (94)node --import tsx scripts/check/check-provider-consistency.ts:OK — 290 entradas REGISTRY, 373 providers canônicos, 0 exceção(ões) registry-onlynpm run typecheck:core: exit 0npx eslint --suppressions-location config/quality/eslint-suppressions.json <changed files>: clean.npx prettier --check <changed files>: all formattednode scripts/check/check-file-size.mjs: OK (no ceiling raised)GITHUB_BASE_REF=release/v3.8.52 npm run check:test-masking:OK — 2 modificado(s) … sem enfraquecimentocheck-pr-test-policy.mjs(PR context):Result: PASScheck:env-doc-sync,check:doc-links,check:fabricated-docs: pass.check:docs-counts: expected red (see above)live_check (hold-vps)
The endpoints of this vendor have not been verified live. Before merge, on the VPS with a real NaN.Builders key:
Also confirm that the dashboard Limits panel shows per-model token bars for the NaN connection (quota endpoint
cloud-api.nan.builders/api/usage/quota).