You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We're moving this from a code PR to a tracked issue under CONTRIBUTING.md: feature ideas belong in adrs/ as a short human-written note and bugs as an issue, and we implement the underlying code from our side. Capturing the original proposal here so it isn't lost.
This PR adds Nexforce Router — Latin America's largest AI inference router — so QM
deployments get one API key that reaches Anthropic, OpenAI, Google, DeepSeek, Moonshot,
Zhipu, and Cloudflare Workers AI, with automatic fallback and per-key cost control.
One OpenAI-compatible endpoint (https://router.nexforce.ai/v1), one NEXFORCE_API_KEY,
and your team can swap between the frontier labs and the best open models without touching a
line of infra. Response headers (X-Nexforce-Requested-Model / X-Nexforce-Served-Model)
make it transparent which model answered each request, and per-key spend caps and fallback
chains keep every conversation predictable.
Why it matters for Latin America
Local billing and compliance are the real unlock. Nexforce handles invoicing, taxes, and
payment infrastructure locally for each country in the region, so teams get compliant,
locally-issued invoices without the FX and foreign-procurement friction of paying an
overseas provider. You keep full visibility into which model served each request and what it
cost — per API key, per conversation.
What changed
src/model/pi-models.ts — register nexforce in MODEL_PROVIDERS, availability, and serviceability
src/config.ts — read NEXFORCE_API_KEY into the core config
src/model/model-credential-store.ts — track nexforce availability alongside the other providers
src/wiring.ts — surface an environment-provided nexforce key to the credential store
src/api/routes/admin/model-providers.ts — validate nexforce keys against the router (a 1-token chat probe, since /v1/models is public)
Tests updated/added for the new provider across core and CLI
How to configure
Environment: set NEXFORCE_API_KEY (or store it write-only from the Admin page →
Model provider), and it becomes a recognized, validated provider key.
NEXFORCE_API_KEY=nfc_... # minted at https://marketplace.nexforce.ai/workspace/ai-gateway/ai-gateway-keys
Endpoint:https://router.nexforce.ai/v1 — an OpenAI-compatible Chat Completions API
with streaming, tool calling, and multimodal input. Key validation probes a minimal
chat completion against deepseek/deepseek-v4-flash (the cheapest catalog model).
The nexforce catalog — spanning Anthropic, OpenAI, Google, DeepSeek, Moonshot, Zhipu, and
Cloudflare Workers AI — is discoverable at https://router.nexforce.ai/v1/models (public),
including nexforce/smart-route, which lets the router pick an equivalent model per request.
Verification done
Live model listing: fetched https://router.nexforce.ai/v1/models — 139 models across
Anthropic, OpenAI, Google, DeepSeek, Moonshot, Zhipu, Meta, Mistral, MiniMax, Qwen, xAI,
NVIDIA, and the nexforce/smart-route router model.
Key auth gating: confirmed /v1/chat/completions rejects a bad key with 401 invalid_api_key, while the catalog stays public — which is why key validation uses a
chat probe rather than the models listing.
Test suite: core typecheck + lint clean; 95 affected core tests and 66 affected CLI
tests pass; CLI typecheck clean. (A live chat roundtrip with a real nfc_ key is pending a
test key from the reviewer.)
A note on scope
This is the declarative registration: the provider is recognized end-to-end for key
management, secrets, and validation. The QM runtime streams through the pinned @earendil-works/pi-ai engine, which does not yet know nexforce, so it intentionally has no
servable base model and MODEL_PROVIDER=nexforce fails fast at config load rather than
silently serving broken turns. Wiring nexforce into the streaming layer is the natural
follow-up once the runtime gains the provider.
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.
If we ship a fix or feature from this, credit @fernandovitti as co-author.
Tracking the change proposed in #192 (by @fernandovitti).
We're moving this from a code PR to a tracked issue under
CONTRIBUTING.md: feature ideas belong inadrs/as a short human-written note and bugs as an issue, and we implement the underlying code from our side. Capturing the original proposal here so it isn't lost.Original PR: #192
Reported by: @fernandovitti
If we ship a fix or feature from this, credit @fernandovitti as co-author.