Skip to content

feat: self-discover upstream model name for /v1/models - #4

Merged
dengyie merged 1 commit into
mainfrom
feat/model-autodiscovery
Oct 4, 2026
Merged

dengyie merged 1 commit into
mainfrom
feat/model-autodiscovery

Conversation

@dengyie

@dengyie dengyie commented Oct 4, 2026

Copy link
Copy Markdown
Owner

What

/v1/models currently advertises a hardcoded list. The CNB gateway has no model-list endpoint, so this drifts whenever the upstream model is renamed — which just happened: the gateway now resolves every request to deepseek-v4.1-flash (verified live: sending glm-5.3-flash, kimi-k3, or even a made-up name all echo deepseek-v4.1-flash).

How

  • New src/models.mjs: a passive registry. proxy.mjs calls observe(model) on streamed chunks and on the non-stream aggregate; the registry keeps first-seen order, dedups, ignores junk, and persists atomically (.tmp + renameSync) to PROXY_MODELS_STATE.
  • /v1/models returns the sniffed name(s); PROXY_MODELS is only a fallback until the first response is sniffed.
  • No startup probe — zero extra upstream cost.
  • Default model list updated to deepseek-v4.1-flash; docs (README ×2, DESIGN, SETUP, .env.example) updated.

Verification

  • node --test → 61 pass / 0 fail (6 new models unit tests incl. cross-process reload, 2 new proxy E2E sniffing tests).
  • Live production probe confirms the echo-of-resolved-name assumption and that the registry cannot be client-polluted.

The CNB gateway exposes no model-list endpoint, so the only trustworthy
source of the real model id is the `model` field echoed on every
completion. Add a passive registry (src/models.mjs) that records the
echoed name in first-seen order, atomically persists it to
PROXY_MODELS_STATE (survives a workspace hot restart), and makes
/v1/models advertise the real name. PROXY_MODELS becomes a fallback used
only until the first response has been sniffed.

Update the default model list to deepseek-v4.1-flash (the gateway now
resolves every request to it) and mirror the docs (README x2, DESIGN,
SETUP, .env.example).

Tests: 61/61 (6 new models unit tests + 2 proxy E2E sniffing tests).
Copilot AI lite review requested due to automatic review settings October 4, 2026 14:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@dengyie
dengyie merged commit f397cd8 into main Oct 4, 2026
2 checks passed
@dengyie
dengyie deleted the feat/model-autodiscovery branch October 4, 2026 14:56
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.

2 participants