Add OpenRouter platform: wire-served metadata (provider 8)
The 11th registry row and the first THIRD-PARTY wire_serves_metadata=true provider: id "openrouter", OPENROUTER_API_KEY > auth.json "openrouter" scope, https://openrouter.ai/api/v1 (note /api/v1) with KIGI_OPENROUTER_BASE_URL override, Bearer, OpenAI listing + ChatCompletions + Passthrough. OpenRouter's public /models serves context_length for every model (verified live: 340/340), so it needs NO enrichment: models_dev_id=None, wire_serves_metadata=true, restrict_to_enriched=false. An OpenRouter-only user makes zero models.dev calls; context comes straight from the listing. Slashed ids (anthropic/claude-opus-4.8) round-trip through the managed key via the first-slash split; the native id rides the wire. The e2e pins all of this with the models.dev refresh disabled. Review-confirmed defect fixed (and independently re-verified with live curls): OpenRouter's /models is PUBLIC — GET /models returns 200 for ANY key — so login key-validation would false-accept a bad key, deferring the failure to the first chat 401. New spec field key_validation_path lets a public-listing platform validate against an auth-requiring endpoint; OpenRouter uses /key (401s for bad keys). Reusable for Vercel (also public). Tests pin the /key validation and no regression to the default /models path. Gate caught a fixture regression: the kimi_import test used openrouter.ai to represent a CUSTOM provider, which now correctly dedupes to the builtin OpenRouter — moved the fixture to a reserved llm.example.test host that no future platform can shadow.
This commit is contained in:
@@ -611,7 +611,7 @@ model = "kimi-for-coding"
|
||||
max_context_size = 262144
|
||||
|
||||
[models.my-openai]
|
||||
provider = "openrouter"
|
||||
provider = "customllm"
|
||||
model = "gpt-x"
|
||||
max_context_size = 128000
|
||||
|
||||
@@ -620,9 +620,9 @@ type = "kimi"
|
||||
base_url = "https://api.kimi.com/coding/v1"
|
||||
api_key = "sk-kimi-secret"
|
||||
|
||||
[providers.openrouter]
|
||||
[providers.customllm]
|
||||
type = "openai_legacy"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
base_url = "https://llm.example.test/v1"
|
||||
api_key = "sk-or-secret"
|
||||
"#,
|
||||
)
|
||||
@@ -711,7 +711,7 @@ api_key = "sk-or-secret"
|
||||
let m = &plan.custom_models[0];
|
||||
assert_eq!(m.alias, "my-openai");
|
||||
assert_eq!(m.model, "gpt-x");
|
||||
assert_eq!(m.base_url, "https://openrouter.ai/api/v1");
|
||||
assert_eq!(m.base_url, "https://llm.example.test/v1");
|
||||
assert_eq!(m.api_key.as_deref(), Some("sk-or-secret"));
|
||||
assert_eq!(m.context_window, Some(128_000));
|
||||
|
||||
@@ -850,7 +850,7 @@ api_key = "sk-ms"
|
||||
assert_eq!(model["model"].as_str().unwrap(), "gpt-x");
|
||||
assert_eq!(
|
||||
model["base_url"].as_str().unwrap(),
|
||||
"https://openrouter.ai/api/v1"
|
||||
"https://llm.example.test/v1"
|
||||
);
|
||||
assert_eq!(model["api_key"].as_str().unwrap(), "sk-or-secret");
|
||||
assert_eq!(model["context_window"].as_integer().unwrap(), 128_000);
|
||||
|
||||
Reference in New Issue
Block a user