cyberine
UsageRun recipes

4. Switch the OpenRouter loop model (config only)

OPENROUTER_MODEL=deepseek/deepseek-v4-flash-0731 npm run demo  # cheaper, good for credit-limited keys
OPENROUTER_MODEL=openai/gpt-4o-mini npm run demo               # different provider, same adapter

Mind the date suffix — the two DeepSeek routes are inverted. On OpenRouter the DATED ids (deepseek/deepseek-v4-pro-0813, deepseek/deepseek-v4-flash-0731) are the current GAs and the UNDATED deepseek/deepseek-v4-pro is a frozen 2026-04-23 legacy alias — not a moving "latest". DeepSeek's own direct API (DEEPSEEK_MODEL, OPENCODE_MODEL) is the opposite: undated IS the current pointer and a dated id is rejected with HTTP 400. Copying an id from one route to the other on the assumption "no date = latest" silently pins a four-month-old model. Verify with the endpoints listing, not the model page:

curl https://openrouter.ai/api/v1/models/deepseek/deepseek-v4-pro/endpoints        # 17 vendors, no DeepSeek
curl https://openrouter.ai/api/v1/models/deepseek/deepseek-v4-pro-0813/endpoints   # 15 vendors, incl. DeepSeek

Cyberine's defaults are the dated ids, held as two constants in src/core/openrouterModelIds.ts (the single re-pointing site — config.ts, workerProfiles.ts, and selectJudgeModel.ts all read them). Known limitation, deliberate: a dated id goes stale by construction, so these constants need a manual bump when DeepSeek ships the next V4 GA. That bump is owned by recurring chore R02 (docs/providers/CHANGELOG-WATCH.md), and OPENROUTER_MODEL overrides the default without a code change in the meantime. A regression guard locks both directions of the split — dated where dated is required, undated where undated is required, plus the "one edit site" property:

npm run selftest:openrouter-model-default   # offline; no key, no network

Two ids deliberately stay undated: CYBERINE_ROUTER_MODEL (dual-route — router.ts strips the deepseek/ prefix for DeepSeek-direct when no OpenRouter key is set, so only the undated form resolves on both branches) and the DeepSeek-direct / OpenCode model vars. Full reasoning: docs/providers/openrouter.md, "T691 decision".