Skip to content

feat(providers): add xkiro.com as an OpenAI-compatible provider (#947) - #967

Open
tashdroid wants to merge 1 commit into
mainfrom
tashdroid/add-xkiro-provider
Open

feat(providers): add xkiro.com as an OpenAI-compatible provider (#947)#967
tashdroid wants to merge 1 commit into
mainfrom
tashdroid/add-xkiro-provider

Conversation

@tashdroid

Copy link
Copy Markdown
Collaborator

What

Add xkiro.com as a registered OpenAI-compatible provider, like the other
aggregators (OrcaRouter, SEA-LION, NaraRouter, AnyAPI).

xkiro.com is a real OpenAI-compatible gateway. Live-probed 2026-08-22:

  • GET https://xkiro.com/v1/models200 JSON (public model catalog)
  • POST https://xkiro.com/v1/chat/completions (no key) → 401 Missing ClientApiKey. Send "Authorization: Bearer <key>" or the "x-api-key" header.
  • GET https://xkiro.com/v1/usage (no key / bogus key) → 401 Invalid or disabled ClientApiKey.

Change (9 files)

file change
shared/types.ts add 'xkiro' to the Platform union (with a comment)
server/src/providers/index.ts register(new OpenAICompatProvider({ platform:'xkiro', name:'xkiro', baseUrl:'https://xkiro.com/v1', validateUrl:'https://xkiro.com/v1/usage' }))
server/src/lib/key-parser.ts XKIRO_ prefix + xkiro auth.json provider name
server/src/routes/keys.ts add 'xkiro' to PLATFORMS
server/src/services/provider-quota.ts xkiro::free account-level shared pool + isSharedPool
client/src/components/keys/shared.tsx provider picker entry xkiro (free key)https://xkiro.com
client/src/lib/routing.ts platform color #a855f7
server/src/__tests__/providers/openai-compat.test.ts xkiro in the platform-instances list
server/src/__tests__/lib/key-parser.test.ts XKIRO_ prefix detection assertion

The one non-obvious wiring decision: validateUrl

The default key validation is GET {baseUrl}/models. For xkiro that is a
false positive: /v1/models answers 200 with no key at all (it's a
public catalog — I verified it returns 200 even with a bogus Bearer token).
Left at the default, a garbage key would validate as "valid" and only fail on
the first real chat call. So validateUrl points at /v1/usage, which
401s on a missing or invalid ClientApiKey — the same pattern the ModelScope
and Pollinations adapters use for their public /models endpoints. A bad key
is now rejected at validation time with the provider's own reason.

What this PR does NOT do (and why)

The model ids named in #947 (gpt-5.4, gpt-5.4-mini, claude-opus-4.6,
gemini-2.5-flash-lite, etc.) are catalog rows, authored in the hosted
catalog repo, not in this gateway. I did not hard-code them here because
(a) they are unverified against a live xkiro account — I have no key — and
(b) a bad id shipped as a default is worse than one caught by the catalog
health check. The gateway-side registration is complete and correct; the
catalog rows are the follow-up in the catalog repo (where a bad id is caught
by the health check instead of reaching a user).

How I checked it

  • server vitest key-parser.test.ts + openai-compat.test.ts: 77/77 pass (xkiro added to the platform-instances list and the prefix-detection test).
  • client vitest: 177/177 pass.
  • client eslint: clean on my two files — the 7 react-refresh/only-export-components errors in shared.tsx are pre-existing (identical count on clean main; my one-line picker entry at line 59 is not among them).
  • Pre-existing failures, not mine (verified by git stash + re-run on clean main): the one compression.test.ts timing assertion (<250ms, 310ms on this box) and the client jsdom missing-package error both fail identically on clean main.

xkiro.com is a real OpenAI-compatible gateway (https://xkiro.com/v1) that
answers /v1/models and /v1/chat/completions. Registered it like the other
aggregators (OrcaRouter, SEA-LION, NaraRouter): shared Platform type, key
prefix detection (XKIRO_), auth.json provider name (xkiro), the keys-route
PLATFORMS list, an account-level shared quota pool (xkiro::free), the client
provider picker, and a platform color.

One non-obvious wiring decision, live-probed 2026-08-22: GET /v1/models
answers 200 with NO key (public catalog), so the default /v1/models key
validation would be a false positive — it would mark a garbage key valid.
validateUrl therefore points at /v1/usage, which 401s on a missing or invalid
ClientApiKey ("Invalid or disabled ClientApiKey"), so a bad key is rejected
the way the ModelScope and Pollinations adapters handle their public /models
endpoints.

Catalog rows (the model ids named in #947) are authored in the hosted catalog
repo, not here — the ids are unverified against a live account, and a bad id
is caught by the health check there rather than shipped as a default. This PR
is the gateway-side registration only.

Checked: server vitest key-parser + openai-compat 77/77 pass (xkiro added to
the platform-instances list and the prefix-detection test); client vitest
177/177 pass; client eslint clean (the 7 react-refresh/only-export-components
errors in shared.tsx are pre-existing, identical on clean main). The one
server compression.test.ts timing failure and the client jsdom
missing-package error are both pre-existing on clean main (verified by
stashing and re-running).
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