mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-01 04:02:35 +00:00
* feat(core): resolve model limits and modalities from a models.dev catalog
Bundle a trimmed models.dev snapshot (12 first-party providers, 237
models) and refresh it in the background once a day into
~/.qwen/model-registry.json with ETag revalidation, so a model that
appears on models.dev gets its context window, output limit, and input
modalities without a CLI release. tokenLimit()/knownTokenLimit()/
hasExplicitOutputLimit() consult the catalog before the regex tables;
defaultModalities() merges both so the catalog can only add modalities.
QWEN_CODE_MODELS_DEV=off restores the regex-only behavior (default in the
unit test setups), QWEN_CODE_MODELS_DEV_REFRESH=off disables the network
refresh, QWEN_CODE_MODELS_DEV_URL points at a mirror. `npm run
generate:model-catalog` regenerates the committed snapshot.
Implements PR2 and PR3 of the design in #9851. Refs #8558.
* feat(core): add model.customCatalog for offline model metadata
Offline and proxy-restricted users cannot reach models.dev, so let them
point `model.customCatalog` at a URL or local file whose entries are
merged over the bundled catalog per model and field. Both the trimmed
`{ models: { id: entry } }` shape and models.dev-style payloads are
accepted. A file is re-read synchronously at every start so the first
model resolution already sees it; a URL is cached like models.dev and
is still fetched when QWEN_CODE_MODELS_DEV_REFRESH=off. The cache
records its source, so a changed or removed setting drops the overlay.
Also sort snapshot keys with a plain comparator instead of localeCompare
so regeneration is deterministic across machines.
* docs: add a verification brief for the models.dev catalog
CI covers the mechanism, but every unit test stubs fetch and the test
setups run with the catalog off, so neither the data values nor the real
runtime behavior are verified anywhere. This brief is the handoff for a
machine that can run the CLI against live endpoints: an on/off A/B with
measured reference numbers, the refresh and offline paths, and the two
values that may still be wrong (Anthropic 1M context, qwen3.8-max PDF).
* fix(core): only catalog models the endpoint question has one answer for
Two projection bugs, both found by reviewing the magnitude of the changes
the catalog was making rather than their direction.
The provider whitelist filtered by vendor but never by model type, so the
catalog also carried embedding, text-to-speech, image, video, OCR and
translation models whose limits mean something else entirely:
gemini-embedding-001 reported an output limit of 1 and veo-3.1-generate a
context of 480, and those numbers outranked the family fallbacks that keep
such ids harmless today. Require tool calling and text output, which drops
34 ids and no real chat model.
Conflict resolution picked the vendor's numbers when several providers
served one id, but a context window is a property of the endpoint, not the
weights. DashScope caps GLM-5 output at 16,384 where Z.ai allows 131,072;
both are correct for their own endpoint. Worse, kimi-k2.6 has no matching
output pattern today, so it is treated as unknown and the user's max_tokens
is respected, and the catalog would have clamped it to 262,144. Drop such
ids instead of guessing: 220 of 237 ids have no conflict, and the 11 that
remain keep exactly the answer they get today.
Snapshot goes from 237 models to 192, 29,824 to 24,685 bytes.
* fix(core): validate catalog defaults and reject alias conflicts
* fix(core): narrow catalog defaults to verified behavior
* fix(core): preserve curated output limits over catalog defaults
* fix(core): harden models.dev catalog refresh and keying
- Reject a 200 response that projects to zero models so a gateway error
body or an upstream field rename cannot shadow the bundled snapshot,
and treat an already-empty cache as absent so a 304 cannot re-stamp it.
- Omit catalog candidates whose key is not a normalize() fixed point:
deepseek-v3 was unreachable by its own name while its dated alias
inherited a 163,840 output limit. Snapshot drops that entry (194).
- Exclude QWEN_CODE_MODELS_DEV_URL from project .env files: the refresh
writes the global cache every project reads.
- Reject false-valued modalities when parsing catalog caches.
- Document the fixed-point keying rule and the accurate REFRESH=off
semantics in the settings table.
* fix(core): preserve explicit budgets for catalog-only models
* fix(core): harden catalog cache reads and correct qwen3-coder-plus window
- loadModelCatalog drops cache keys no normalized spelling can reach and
treats a cache that is empty after validation as absent, so a stale or
poisoned cache can no longer displace the bundled snapshot.
- Correct qwen3-coder-plus to its vendor-declared 1,000,000-token window
(models.dev's alibaba buckets approximate it as 1,048,576), applied in
the loader so a refreshed cache cannot reintroduce the approximation.
- Pin the cross-origin refresh guard with a non-empty cache fixture, the
normalized-id catalog lookup for modalities, the env-budget clamp
precondition for glm-4.7, and control keys plus reload/snapshot arms
for the project-scoped catalog URL exclusion.
- Align the QWEN_CODE_MODELS_DEV_REFRESH docs and JSDoc with the
newer-than-bundled selection rule.
* fix(core): project catalog modalities across providers and test against the real catalog
Review round on PR #11959:
- trimModelsDevCatalog: token limits stay gated on the first-party
allowlist with disagreement-drop; input modalities describe the
weights, so they now union across every provider that serves the
model. First-party vendors outside the allowlist (issue #8558's
thinkingmachines/inkling) project image/pdf support again, while
their endpoint limits stay untrusted.
- modalityDefaults.test.ts: drop the file-scoped catalog mock that let
three assertions pin the opposite of shipped behavior; run against
the real bundled snapshot in an isolated QWEN_HOME and correct the
qwen3.8-max / glm-5v-turbo / glm-5.3-flash expectations. The
mock-based merge tests move to modalityDefaults.catalog.test.ts.
- vscode-ide-companion: add the missing QWEN_CODE_MODELS_DEV=off test
default via test-setup.ts so a host's ~/.qwen/model-registry.json
cache cannot flip its contextLimit assertions.
* revert(vscode-ide-companion): drop out-of-footprint catalog test wiring
Deterministic verification rejected the setupFiles addition to
packages/vscode-ide-companion/vitest.config.ts: per-package vitest
configs are test-config verification machinery, and this PR's
footprint does not include that package. Revert the wiring and remove
the now-orphaned test-setup.ts.
The underlying hazard (R4-2: acpModelInfo contextLimit assertions
resolve against the host's ~/.qwen/model-registry.json cache) is real
and reproduced on this head — a poisoned cache flips exactly the two
witness tests red — but every fix lives outside this PR's footprint,
so it is deferred to the follow-up queue with an open question for
maintainers.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix: close model catalog environment gaps
* fix(core): validate refreshed model metadata
* fix(core): reject incomplete model catalogs
* fix(core): keep catalog defaults agent-safe
* fix(core): preserve DeepSeek vision boundary
* fix(core): harden the catalog refresh fetch and pin the catalog fixture clock
Six review findings on the refresh/generator path:
- Bound the download: the refresh now reads the 200 body with a
200KB ceiling (the generator's budget) instead of buffering an
unbounded payload, rejects a present-but-non-JSON Content-Type one
step earlier than JSON.parse, and cancels the body on the HTTP-error
path so the socket is released.
- Clock skew: a cache stamped by a faster clock (negative or unreadable
age) now refetches instead of serving indefinitely; the re-stamp uses
the local clock so the skew self-heals.
- The refresh failure log goes through the canonical getErrorMessage,
so error.cause survives into the debug channel.
- The 'serves it immediately' test pins its clock ahead of the bundled
snapshot's committed fetchedAt, decoupling it from the runner's wall
clock (the snapshot is regenerated by whichever host runs the
generator).
- The generator refuses a non-OK response and an empty projection
instead of overwriting the committed snapshot with either.
Each new test is red under its corresponding revert (byte cap, content
-type check, skew guard); the clock-pin witness mutates the snapshot's
fetchedAt to 9999 and stays green.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(core): drop mirror providers from catalog limits and keep parse fidelity
Seven more review findings on the catalog path:
- MODELS_DEV_PROVIDERS no longer includes modelscope. Measured against
the live payload: its only contributions were four dated -2507 qwen3
snapshots recorded under the bare ids plus vetoing z.ai's first-party
glm-4.6 numbers into a conflict drop. volcengine stays — it is the
first-party endpoint for the doubao/seed family (dropping it costs 16
keys). Snapshot regenerated: 203 entries, glm-4.6 restored to the
first-party figures.
- parseModelCatalog no longer lets one bad modalities member take a
whole entry down: unknown or mistyped modality keys are filtered and
the entry keeps its limits; context/output stay strict. The parser
also skips an own-property __proto__ key instead of invoking the
prototype setter (the refresh path can legitimately write one).
- A declared text-only modalities list now survives projection as {}
on entries that ship limits, instead of being indistinguishable from
"upstream said nothing" — inert under today's union, recorded so a
future narrowing can tell the two apart. A bare {} never creates an
entry on its own, so conflict-dropped and limit-less models still
drop.
- The committed snapshot now has a parse-and-budget gate: every shipped
entry must survive parseModelCatalog and stay within the 200KB budget
(corrupting one entry turns the new test red).
- The gpt-4o resolver expectation's comment now says it pins the
catalog-off regex answer; the catalog-on production value already has
its own twin test.
- The verification README's evidence pointers no longer reference a
gitignored .qwen path; they name the committed suites that pin the
same numbers.
Modality list is now single-sourced as CATALOG_MODALITIES exported from
model-catalog.ts. Each behavior change is red under its revert:
restoring modelscope re-drops glm-4.6, restoring whole-entry modality
rejection or the __proto__ assignment reds the parse test, restoring
the empty-modalities drop reds the projection expectations.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(core): narrow catalog modality keys with a type predicate
Object.entries widens the key to string, and includes() on the widened
readonly string[] does not narrow it back, so the indexed write into
InputModalities was an implicit any under noImplicitAny. That failed the
packages/core build with TS7053 and cascaded into every required check.
Extract the membership test into an isCatalogModality predicate so the
write is type-safe. Type-level only, no behavior change: the existing
"drops malformed entries while parsing" coverage still pins that an
unrecognised modality key degrades that one field instead of discarding
the entry.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmunuawz4h7
* fix(core): keep catalog refresh usable and process-consistent
* fix(core): invalidate incompatible model catalog projections
* fix(core): stamp canonical models.dev URL as bundled catalog provenance
The generator passed its input locator straight through as the provenance
stamp, so generating from a local payload copy recorded a machine-specific
path (e.g. /tmp/11959-models-dev.json) in the committed snapshot. Stamp
MODELS_DEV_URL for local-path inputs (the payload is models.dev data
regardless of where the machine stored it), keep URL inputs stamping
themselves, regenerate the snapshot, and pin the artifact's source field
with a test.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmuofqisz0a
* fix(core): share the provider-coverage guard and key DeepSeek narrowing on the family root
Round-9 review findings on
|
||
|---|---|---|
| .. | ||
| 2025-06-03-stats-dashboard-redesign.md | ||
| 2026-03-22-agent-tool-display-design.md | ||
| 2026-05-14-auto-compaction-threshold-redesign.md | ||
| 2026-05-15-worktree-phase-c.md | ||
| 2026-05-18-qwen-runtime-memory-investigation.md | ||
| 2026-05-26-daemon-logger.md | ||
| 2026-05-27-daemon-workspace-service.md | ||
| 2026-05-28-computer-use-built-in.md | ||
| 2026-06-30-channel-loop.md | ||
| 2026-07-01-channel-lifecycle-status-adapters.md | ||
| 2026-07-01-channel-lifecycle-status-umbrella.md | ||
| 2026-07-01-channel-p0-identity-task-lifecycle.md | ||
| 2026-07-01-extension-runtime-refresh-implementation.md | ||
| 2026-07-10-pr-6635-remaining-comments.md | ||
| 2026-07-10-pr-6635-review-followups.md | ||
| 2026-07-10-workspace-qualified-acp-hardening.md | ||
| 2026-07-11-chrome-extension-alpha-diagnostics.md | ||
| 2026-07-11-managed-memory-microcompaction.md | ||
| 2026-07-14-dingtalk-webhook-direct-message.md | ||
| 2026-07-16-default-background-subagents.md | ||
| 2026-07-16-webshell-git-integration.md | ||
| 2026-07-17-observed-channel-delivery-targets.md | ||
| 2026-07-18-observed-channel-group-names.md | ||
| 2026-07-21-channel-delivery-review-fixes.md | ||
| 2026-07-22-channel-delivery-final-only.md | ||
| 2026-07-23-session-workflow-approval.md | ||
| 2026-07-24-webshell-git-status-fast-path.md | ||
| 2026-07-31-daemon-memory-budget-pr1.md | ||
| 2026-08-05-feishu-ask-user-question-cards.md | ||
| 2026-08-08-selective-session-restore.md | ||
| 2026-08-13-standalone-pr1-runtime-boundary.md | ||
| 2026-08-14-standalone-pr2-core.md | ||
| 2026-08-18-autofix-handoff-bilingual.md | ||
| 2026-08-18-peer-session-collaboration.md | ||
| 2026-08-20-cua-driver-0.20.0-upstream-sync.md | ||
| 2026-08-20-cua-driver-computer-use-sdk.md | ||
| 2026-08-22-serve-open-with-auth.md | ||
| 2026-08-25-standalone-pr3-daemon-api.md | ||
| 2026-08-27-standalone-pr4-typescript-sdk.md | ||
| 2026-08-27-web-shell-composer-add-menu.md | ||
| 2026-08-28-standalone-pr5-webshell-context.md | ||
| 2026-08-29-dingtalk-permission-cards.md | ||
| 2026-08-29-standalone-pr6-webshell-ui.md | ||
| 2026-08-31-dingtalk-lifecycle-delivery-convergence.md | ||
| 2026-08-31-dingtalk-permission-card-language.md | ||
| 2026-09-01-dingtalk-granular-kind-phases.md | ||
| 2026-09-03-test-suite-barrel-cost.md | ||
| 2026-09-04-background-agent-surfaces.md | ||
| 2026-09-04-session-workflow-dag-design.md | ||
| 2026-09-04-web-shell-global-turn-navigation-phase2.md | ||
| 2026-09-06-conversations-ownership-cutover.md | ||
| 2026-09-10-remote-web-shell-daemon.md | ||
| 2026-09-13-pr9040-review-followups.md | ||
| 2026-09-14-remote-computer-use-desktop-relay.md | ||
| 2026-09-16-models-dev-catalog-plan.md | ||
| 2026-09-16-non-conversation-context-token-governance.md | ||
| dingtalk-richtext-multi-image.md | ||
| extension-management-v2.md | ||
| feishu-observed-contact-label-enrichment.md | ||
| final-tool-response-budget-implementation.md | ||
| memory-diagnostics-reference-design.md | ||
| web-shell-session-sources.md | ||