Skip to content

feat(providers): add Alibaba (China) provider for the dashscope China endpoint - #3329

Merged
Astro-Han merged 2 commits into
apache:mainfrom
me2seeks:feat/alibaba-china-provider
Aug 23, 2026
Merged

feat(providers): add Alibaba (China) provider for the dashscope China endpoint#3329
Astro-Han merged 2 commits into
apache:mainfrom
me2seeks:feat/alibaba-china-provider

Conversation

@me2seeks

Copy link
Copy Markdown
Contributor

Summary

Maka's alibaba provider is pinned to the international Model Studio endpoint (dashscope-intl.aliyuncs.com), leaving no access path for the China platform. This PR registers models.dev alibaba-cn as a first-class provider bound to https://dashscope.aliyuncs.com/compatible-mode/v1, so China-platform users can connect with keys from bailian.console.aliyun.com. The catalog carries 81 tool-calling models and defaults to qwen3.8-max (1M context, 128k output, vision/pdf input, thinking toggle + low/medium/xhigh efforts). Hosted web-search handling mirrors the international alibaba provider, and the desktop picker gains display copy (Alibaba 中国站 / Alibaba (China)) plus the Alibaba brand mark.

The models.dev sync now ingests alibaba-cn. The generated metadata and pricing snapshots gain only the alibaba-cn blocks (spliced from a full live regeneration): a full regen is currently blocked by unrelated upstream drift — e.g. models.dev renamed the opencode free model north-mini-code-free, which would break an existing registry pin — and that drift deserves its own sync pass rather than riding along here.

Fixes #3323

Verification

  • node --test packages/core/dist/__tests__/**/*.test.js — 553/553 pass (includes new catalog + web-search assertions)
  • node --test packages/runtime/dist/__tests__/**/*.test.js — 2843 pass, 0 fail (includes new wire-contract assertion keeping qwen3.8-max on openai-chat)
  • @maka/desktop typecheck — clean (all four tsconfigs)
  • biome format / biome lint on all touched files — clean
  • Registry smoke check: PROVIDER_REGISTRY['alibaba-cn'] → label Alibaba (China), China endpoint, fallbackModels[0] === 'qwen3.8-max'
  • Not run: desktop e2e / real-network call against the China endpoint (no China-platform key available in this environment)

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Maka — investigation, implementation, and tests; commit carries the Generated-by: Maka trailer.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

… endpoint

Register models.dev alibaba-cn as a first-class provider so China-platform
users can connect to https://dashscope.aliyuncs.com/compatible-mode/v1 with
keys from bailian.console.aliyun.com. The catalog carries 81 tool-calling
models and defaults to qwen3.8-max, with hosted web-search parity to the
international alibaba provider.

The models.dev sync ingests alibaba-cn; the generated metadata and pricing
snapshots gain only the alibaba-cn blocks because a full regeneration is
currently blocked by unrelated upstream drift (e.g. opencode free-model
renames) that deserves its own sync pass.

Closes apache#3323

Generated-by: Maka
@Astro-Han
Astro-Han force-pushed the feat/alibaba-china-provider branch from 01b9c2a to 78517cc Compare August 23, 2026 04:28
@Astro-Han

Copy link
Copy Markdown
Contributor

Rebased this branch onto current main for you — it was CONFLICTING and could not be reviewed in that state. New head 78517ccf90d1d2ca761a637b972dcbcb2ed99294, now MERGEABLE. Done under maintainer authorization; nothing about the change itself was touched.

Exactly one conflict, in a generated file, packages/runtime/src/telemetry/model-pricing.generated.ts: main had added two cerebras:* pricing rows into the same sorted block where this branch adds its 177 alibaba-cn:* rows.

Resolved as the sorted union — the alibaba-cn: entries first, then the two cerebras: entries, since alibaba-cn sorts before cerebras and the block is ordered by modelKey. No row was dropped, edited, or reordered relative to its own side.

The rebased commit reports 10 files changed, 1326 insertions(+) — identical to the pre-rebase diffstat, so nothing was lost or picked up along the way.

Two things worth your attention rather than mine:

  1. This is a generated file with scripts/sync-model-metadata.mjs behind it. I resolved the text mechanically rather than regenerating, because regenerating pulls from live pricing sources and would have silently changed rows unrelated to this PR. If the generator is meant to be the source of truth here, re-run it and force-push over my resolution — I would rather be overwritten than have a hand-merged generated file land.
  2. Everything else applied cleanly, including the provider registry, brand marks, display copy, and the web-search and wire-contract tests.

I did not touch the substance of the change and I have not reviewed it yet. An independent review line is being assigned separately.

@Astro-Han

Copy link
Copy Markdown
Contributor

Follow-up on the rebase: CI now runs, and it fails — but not on my conflict resolution. Run 32617948182 on 78517ccf90d1d2ca761a637b972dcbcb2ed99294 fails in Build, packages/core, tsc:

src/provider-registry.ts(1610,41): error TS2322:
  Type '"fallback-models"' is not assignable to type '"language-models" | "tool-capable" | undefined'.
src/provider-registry.ts(1916,14): error TS2322:
  ... is not assignable to type 'Readonly<Record<"MiniMax" | ... | "zenmux", ProviderDefaults>>'.

Neither line is in model-pricing.generated.ts, so this is not fallout from the union I resolved — it is a genuine incompatibility between this branch and current main that the merge conflict was hiding.

On today's main, ProviderModelDiscovery is a discriminated union, and filter exists only on the kind: 'protocol' member with exactly two permitted values:

filter?: 'language-models' | 'tool-capable';

There is a separate { kind: 'fallback'; reason: string } member. So 'fallback-models' is not a filter value on current mainand which of those two shapes this provider actually wants is your decision, not something I should guess at. The second error is almost certainly the same problem surfacing again as the whole defaults record failing to typecheck.

Net effect of the rebase: this PR went from CONFLICTING (unreviewable, CI cannot even run) to MERGEABLE with a specific, actionable compile error. That is the intended outcome — the conflict was concealing the real blocker.

I have not attempted to fix it, and I will not: picking between filter and the fallback discovery kind is a behavioral choice about how this provider enumerates models.

Once the build is green, an independent review line will be assigned.

'filter: fallback-models' is not a valid ProviderModelDiscovery filter and
names a mechanism main rejected in apache#1584: intersecting live discovery with
the shipped list drops models the account gains after release. The China
endpoint serves the same compatible-mode /models surface as the
international provider, which discovers via plain protocol; the curated
fallbackModels list already covers the offline path and the default model.

Generated-by: maka
@me2seeks

Copy link
Copy Markdown
Contributor Author

Fixed at 9ca3ebc05. Decision rationale for the shape you left open:

{ kind: 'protocol' } — plain, matching the international alibaba sibling. The China endpoint serves the identical compatible-mode /models surface (dashscope.aliyuncs.com/compatible-mode/v1), so discovery behavior should be symmetric. The invalid filter: 'fallback-models' also named a mechanism main deliberately rejected in #1584 (intersecting live discovery with the shipped list drops post-release models), so it could not be expressed as any current filter value. The curated fallbackModels catalog already owns the offline path and pins qwen3.8-max as default.

Verification on the new head: @maka/core build + full suite 624/624 pass, biome clean.

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approving 9ca3ebc057cb8f3843e854241746f7660f496bda. Required test is completed / success bound to that exact SHA (run 32619203260). No P0–P3.

A note on how this PR got reviewed, because the record could be read the wrong way. The two earlier comments from this account are rebase records, not reviews — the second one says so explicitly. So despite appearances, this change had never actually been reviewed. It was re-triaged as unreviewed and given a full independent line rather than a re-check, which is why this arrives later than the CI green.

The one-line fix is correct, and for a stronger reason than "it compiles now." filter?: 'language-models' | 'tool-capable' is the entire permitted set on ProviderModelDiscovery, so 'fallback-models' was never a value this field could take — the conflict had been hiding a genuine type error, not a stylistic choice. { kind: 'protocol' } also puts alibaba-cn in line with all six sibling alibaba* entries, which was verified entry by entry rather than assumed from the international one.

What was checked on the substance:

  • The endpoint is real and behaves as claimed. An unauthenticated probe of https://dashscope.aliyuncs.com/compatible-mode/v1/models returns HTTP 401 — reachable and auth-gated, which is what protocol discovery needs. The registry pins that URL.
  • The wire contract is pinned, not assumed. alibaba-cn/qwen3.8-max resolves as openai-chat, with exact-model-id, tool-loop and reasoning-replay conformance passing.
  • Web search is correctly declared unsupported. Alibaba CN is added with implemented: false, and routeWebSearchTools only injects the native tool when implemented: true — so a capability the provider advertises but Maka cannot execute does not get silently routed elsewhere. This matches the existing Alibaba entry.
  • The 177 pricing rows come from the same models.dev generated source; alibaba-cn: keys are strictly sorted with no duplicates. The fallback catalogue holds 81 entries with qwen3.8-max first, and toolCallingModelIds admits only models whose metadata says functionCalling: true.

On entropy: of ~1326 lines, roughly 1250 are generated metadata and pricing. The hand-written surface is small and reuses the existing OpenAI-compatible runtime, protocol discovery, web-search capability and brand assets. A separate provider id for the China endpoint is the right call precisely because it did not require a second request, auth or model-resolution authority.

One thing for the maintainers rather than the author: the rebase resolved a conflict in model-pricing.generated.ts by hand — as a sorted union, with no row dropped or reordered — but that file has scripts/sync-model-metadata.mjs behind it. If the generator is the source of truth, re-running it and force-pushing over that resolution is preferable to leaving a hand-merged generated file.

Verified: @maka/core build and 624/624; @maka/runtime build and 349/349 focused; desktop renderer build; Biome on all 10 changed files; git diff --check.

Disclosure, because it changes what this approval is worth: this is an AI review. Under CONTRIBUTING.md §Review it does not count as the required independent human review — merge still needs a committer other than the author to give LGTM and to decide.

@Astro-Han
Astro-Han merged commit e05308b into apache:main Aug 23, 2026
1 check passed
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.

feat(providers): add Alibaba (China) provider for the dashscope China endpoint

2 participants