Repository navigation
feat(check): make serviceKinds required + reverse-walk provider consistency gate - #11392
Conversation
…stency gate Fixes #10513 · Refs Discussion #10267 Base-red inherited: #9985 (release/v3.8.50 not green) What: - Schema: providerSchema.ts — serviceKinds changed from optional to required - Backfill: 312 catalog entries get serviceKinds computed from section + registry (341 total, 17 already declared) - Gate: check-provider-consistency.ts — reverse walk flags llm-kind canonical providers with no REGISTRY entry, unless in KNOWN_CATALOG_ONLY (32 connection-routed providers with justification) - Tests: 5 new reverse-walk test cases (11/11 gate tests pass) - Script: scripts/ad-hoc/backfill-servicekinds.mjs — idempotent codemod Validation: - npm run typecheck:core — clean - bun scripts/check/check-provider-consistency.ts — OK (261 REGISTRY, 341 canonical, 32 catalog-only) - 11/11 gate tests, 24/24 provider schema tests, 34/34 route schema tests pass - ESLint on all catalog files — clean
|
Re-homed to |
|
Obrigado pela contribuição — o design do gate (allowlist com justificativas, reverse-walk, backfill idempotente) está muito bem pensado. Mas encontramos um problema estrutural antes de mergear: os 18 arquivos do diff estão sendo criados na raiz do repositório ( Isso viola a regra de higiene da raiz do repositório (AGENTS.md → "File placement & repo-root hygiene") e também sugere que os arquivos não estão substituindo/editando as versões reais existentes nos caminhos aninhados — precisamos confirmar isso antes de aceitar. Poderia reenviar o PR com os arquivos nos caminhos corretos (provavelmente um problema na hora de gerar o diff/commit a partir do seu ambiente local)? Fico à disposição para revisar assim que corrigido. |
|
Hi @Tushar49 — the feature design for #10513 is sound (requiring serviceKinds, backfilling the catalog, and the KNOWN_CATALOG_ONLY reverse-walk to catch incomplete provider removals are all worth shipping), but the PR as pushed doesn't apply any of it: all 18 changed files sit at the repository ROOT as copies (gateways.ts, providerSchema.ts, check-provider-consistency.ts, …) instead of their real locations under src/shared/constants/providers/, src/shared/validation/, scripts/check/ and tests/. On your branch the real providerSchema.ts still has serviceKinds optional and the real consistency script has no reverse walk — so CI would run none of your work, and merging would just dump duplicate modules at the root (which our root-hygiene gate blocks). Could you re-commit the same changes at the correct paths (likely your working directory got flattened when staging), drop the root copies, and rebase on the current release/v3.8.51? Please also re-run the provider-consistency gate and the provider/route schema suites afterwards, and switch the gate's failure messages to English — then this is very mergeable. |
…rent catalog The branch's 18 files landed at the repository root (`git diff --name-status` showed `A gateways.ts`, `A providerSchema.ts`, `A check-provider-consistency.test.ts`, `A backfill-servicekinds.mjs` with no directory), so the real provider files, schema, gate and test were never touched — the diff was +5093/-0 of root files that AGENTS.md forbids, and a no-op for the feature. The content was also 227 commits stale: the root `gateways.ts` was missing `oneminai`, among 267 divergent lines. Reapplied as the delta each file actually carries, onto the current tip: - `src/shared/validation/providerSchema.ts`: `serviceKinds` loses `.optional()`. - `scripts/check/check-provider-consistency.ts`: the reverse walk — `KNOWN_CATALOG_ONLY`, `findCatalogOnlyLlmProviders()`, the check in `main()` and the summary line. The branch's copy also repeated the file header and imports at the end (12 lines of copy/paste residue from the same accident); those were dropped. - `tests/unit/check-provider-consistency.test.ts`: the import block and the five reverse-walk cases. A cosmetic re-wrap that came from the stale base was not carried. - `scripts/ad-hoc/backfill-servicekinds.mjs`: placed at the path its own docstring names, then run against the current catalog — 315 insertions, 352/352 entries now declaring `serviceKinds`, idempotent on a second run. Two entries the mechanical pass could not get right on its own: - `github` in `oauth.ts` is a single-line object, so the script's `id:`-per-line regex skipped it (the one reported failure). Declared `["llm"]` by hand, which is what the script's own rule computes for it. - `magnific` came out as `["llm"]` but is an image provider (`icon: "image"`, registered in `imageRegistry.ts`). It is `freepik` renamed by migration 160, and `freepik` is in the script's `NO_LLM` set — the rename left the set no longer matching. The reverse walk caught it on its first run. Corrected to `[]`, and `magnific` added to `NO_LLM` with a note so a re-run cannot reintroduce it. Verified: `check:provider-consistency` OK (268 REGISTRY entries, 352 canonical providers, 32 catalog-only), `typecheck:core` clean, 137/137 across the provider/schema/serviceKinds suites, `check-file-size` and `check:cycles` green.
a298dc6
into
cheaper-inference:release/v3.8.51
… tools, vision, image-gen, doc-RAG) (#11461) MaxAI joins as a first-class signed provider: 13 chat models discovered live from /models/get_config plus 6 image models, routed through the standard /v1 endpoints with per-request X-Authorization signing, browserless onboarding, prompted tool-calling, vision input, image generation and document RAG. Reconciled on merge — worth reading, because the branch forked 227 commits back and 77 files conflicted. Only five carried MaxAI content; the rest was drift from the older release line and took the tip's side, taking the diff from 113 files to 37 (then 93 as counted against the current base). - executors/index.ts: the tip has since refactored the executor map to lazy dynamic imports, so MaxAI is registered in that shape rather than the branch's static import. - imageRegistry.ts: kept only the maxai block. The branch still carried microsoft-designer-web, which #11754 retired. - models/route.ts: the conflicting hunk was an unrelated Vertex/Anthropic URL change, not MaxAI — tip's side. - volcengine agent-plan/coding-plan registries: git auto-merged both sides and produced a duplicated supportsVision key, which TypeScript rejects (TS1117). Removed. One real integration break that only the combined state shows: the MaxAI entry declared no serviceKinds, which #11392 made required a few hours ago. Provider validation threw at load time and check:provider-consistency crashed outright. Declared ["llm"] — the image kinds derive from imageRegistry, per the convention in that PR's backfill. Every count was measured rather than taken from the branch, and each would have been wrong: reserved prefixes are 402, not the 397 the branch computed from its stale 395 base; providers are 353, not 354. PROVIDER_REFERENCE.md regenerated, the count updated across README/AGENTS.md/llm.txt and its 42 mirrors, package.json and 6 SVGs — every changed line in those files is a digit substitution and nothing else, verified by masking digits and comparing the removed and added sets (90 lines, identical). The executor-map golden snapshot was regenerated: keyCount 133 -> 134. The branch's file-size-baseline.json predates #12411's ratchet re-tightening, so it was discarded rather than merged — taking it would have silently undone that. The three files this PR grows (proxyFetch.ts +20 for the Windows/firefox_150 TLS profile, imageGeneration.ts +12, models/route.ts +48) were entered against the current baseline under one _rebaseline annotation; no other cap moves. Verified: typecheck:core clean, check:provider-consistency OK (269 REGISTRY entries, 353 canonical providers), check:docs-counts exit 0, check-file-size OK, check:cycles OK, and 79/79 across the MaxAI suites plus 21/21 reserved-prefix and 2/2 executor-map-golden. Thanks @arminanton — the provider work itself is thorough; it was the 227 commits of base that needed the attention.
…-provider The branch forked 227 commits back, so 77 files conflicted. Only five carried MaxAI content; the rest was drift from the older release line and took the tip's side. Diff goes from 113 files to 37. Reconciled: - executors/index.ts: the tip refactored the map to lazy dynamic imports, so MaxAI is registered in that shape rather than the branch's static import. - imageRegistry.ts: kept only the maxai block — microsoft-designer-web was retired on the tip (cheaper-inference#11754) and the branch still carried it. - models/route.ts: the Vertex/Anthropic URL hunk is unrelated drift; tip's side. - web-cookie.ts: MaxAI declared no serviceKinds, which cheaper-inference#11392 made required hours ago — provider validation threw on load and check:provider-consistency crashed. Declared ["llm"]; the image kinds come from imageRegistry. - volcengine agent-plan/coding-plan registries: git auto-merged both sides' additions and produced a duplicated supportsVision key (TS1117). Removed. Counts measured rather than taken from the branch: - reserved prefixes 400 -> 402 (branch said 397, from its stale 395 base) - providers 352 -> 353 (branch said 354, from its stale 353 base); PROVIDER_REFERENCE.md regenerated, and the count updated in README/AGENTS.md/llm.txt + 42 mirrors, package.json and 6 SVGs. - executor-map golden snapshot regenerated: keyCount 133 -> 134. file-size-baseline.json: the branch's copy predates cheaper-inference#12411's ratchet re-tightening, so it was discarded and the three files this PR grows were entered against the current baseline with a _rebaseline annotation. No other cap moves.
…tive-standalone 57 files conflicted; only seven carried UC content, the rest was drift from the older release line and took the tip's side. Reconciled: - executors/index.ts: the tip refactored the map to lazy dynamic imports, so `uc` is registered in that shape (uc-direct uses the default OpenAI-compatible executor). - imageGeneration.ts: the branch carried the retired designerWeb import alongside ucImage; kept only the UC one. - config/providers/index.ts, webSessionCredentials.ts, web-cookie.ts: additive against the maxai entries cheaper-inference#11461 added on the tip. - web-cookie.ts: `uc` declared no serviceKinds, required since cheaper-inference#11392. Declared ["llm"]. uc-direct already declared it at the end of its entry — an earlier pass added a second one after `id` and TypeScript rejected the duplicate (TS1117); the author's is kept. Counts measured rather than taken from the branch: - reserved prefixes 402 -> 406 (branch said 399, from its stale base) - APIKEY_PROVIDERS 236 -> 237 (branch said 234) - providers 353 -> 355; PROVIDER_REFERENCE.md regenerated and the count updated across README/AGENTS.md/llm.txt + 42 mirrors, package.json and 6 SVGs — digit changes only. - executor-map golden snapshot regenerated: keyCount 134 -> 135. file-size-baseline.json: the branch's copy predates cheaper-inference#12411's ratchet re-tightening, so it was discarded; imageGeneration.ts (+12 for the uc-image branch) entered against the current baseline with a _rebaseline annotation. No other cap moves.
…ect (metered) (#11513) Adds uncensored.com as two OpenAI-compatible providers mirroring UC's own surfaces: uc, the persona/subscription side over WebSocket with a durable Clerk credential minting a short-lived per-connect token (no API key, un-metered), as a full multimodal port — chat, tools, vision, doc-RAG, image, video, TTS; and uc-direct, the metered Developer API over REST with X-api-key. Same underlying models, two billing surfaces. Reconciled on merge. 57 files conflicted; only seven carried UC content, the rest was drift from the older release line and took the tip's side. - executors/index.ts: the tip has since refactored the executor map to lazy dynamic imports, so uc is registered in that shape. uc-direct needs no entry — it routes through the default OpenAI-compatible executor. - imageGeneration.ts: the branch still carried the retired designerWeb import alongside ucImage; kept only the UC one. - config/providers/index.ts, webSessionCredentials.ts and web-cookie.ts resolved additively against the MaxAI entries #11461 put on the tip an hour earlier. - web-cookie.ts: the uc entry declared no serviceKinds, required since #11392, so provider validation would have thrown at load. Declared ["llm"]. uc-direct already declared it at the end of its own entry — an earlier pass of mine added a second one after id and TypeScript caught the duplicate (TS1117); the author's placement is what shipped. Every count was measured against the merged tree rather than taken from the branch, and all three would have been wrong: reserved prefixes are 406, not 399; APIKEY_PROVIDERS is 237, not 234; providers are 355. PROVIDER_REFERENCE.md regenerated, the count updated across README/AGENTS.md/llm.txt and its 42 mirrors, package.json and 6 SVGs — every changed line in the protected surfaces is a digit substitution and nothing else, verified by masking digits and comparing the removed and added sets (90 lines each, identical). The executor-map golden snapshot went 134 -> 135. The branch's file-size-baseline.json predates #12411's ratchet re-tightening and was discarded rather than merged; imageGeneration.ts (+12 for the uc-image format branch) was entered against the current baseline under a _rebaseline annotation, and no other cap moves. Verified: typecheck:core clean, check:provider-consistency OK (271 REGISTRY entries, 355 canonical providers), check:docs-counts exit 0, check-file-size OK, check:cycles OK, 119/119 across the PR's test files, and 2/2 executor-map-golden. Thanks @arminanton — two providers for two real billing surfaces, rather than one entry pretending to be both, is the right modelling.
…ider consistency gate (cheaper-inference#11392) serviceKinds now drops .optional() in providerSchema.ts, and check-provider-consistency gains the reverse walk: a canonical provider whose serviceKinds include "llm" must have a REGISTRY entry unless it is in the new KNOWN_CATALOG_ONLY allowlist (providers routed through a connection baseUrl or a specialised executor). That turns "catalog entry outlived its registry entry" — the half-finished provider:remove — into a checkable invariant instead of something a reviewer has to notice. Reconciled on merge, and worth reading before comparing diffs. The branch's 18 files had landed at the repository ROOT: git diff --name-status showed A gateways.ts, A providerSchema.ts, A check-provider-consistency.test.ts, A backfill-servicekinds.mjs with no directory component. The real provider files, schema, gate and test were never touched, so the +5093/-0 diff was root files AGENTS.md forbids (a test outside tests/, a script outside scripts/) and a no-op for the feature. The content was also 227 commits stale — the root gateways.ts was missing oneminai, among 267 divergent lines. So each file's actual delta was reapplied onto the current tip rather than copied: the schema one-liner; the gate's KNOWN_CATALOG_ONLY, findCatalogOnlyLlmProviders(), the main() check and the summary line (the branch's copy also repeated the file header and imports at the end — 12 lines of residue from the same accident, dropped); the test's import block and five reverse-walk cases; and backfill-servicekinds.mjs placed at scripts/ad-hoc/, the path its own docstring names, then run against the current catalog: 315 insertions, 352/352 entries declaring serviceKinds, idempotent on a second run. Two entries the mechanical pass could not get right, both surfaced by doing it against the live tree: - github in oauth.ts is a single-line object, so the script's id:-per-line regex skipped it — the one failure it reported. Declared ["llm"] by hand, which is what the script's own rule computes. - magnific came out as ["llm"] but is an image provider (icon: "image", registered in imageRegistry.ts). It is freepik renamed by migration 160, and freepik is in the script's NO_LLM set, so the rename left that set no longer matching. Your reverse walk caught it on its first run — a fair demonstration of why the gate is worth having. Corrected to [], with magnific added to NO_LLM and a note so a re-run cannot reintroduce it. Verified: check:provider-consistency OK (268 REGISTRY entries, 352 canonical providers, 0 registry-only exceptions, 32 catalog-only), typecheck:core clean, 137/137 across the provider/schema/serviceKinds suites, check-file-size and check:cycles green. Thanks @Tushar49 — the design is sound and the backfill script did the heavy lifting; only its placement and freshness needed fixing.
… tools, vision, image-gen, doc-RAG) (cheaper-inference#11461) MaxAI joins as a first-class signed provider: 13 chat models discovered live from /models/get_config plus 6 image models, routed through the standard /v1 endpoints with per-request X-Authorization signing, browserless onboarding, prompted tool-calling, vision input, image generation and document RAG. Reconciled on merge — worth reading, because the branch forked 227 commits back and 77 files conflicted. Only five carried MaxAI content; the rest was drift from the older release line and took the tip's side, taking the diff from 113 files to 37 (then 93 as counted against the current base). - executors/index.ts: the tip has since refactored the executor map to lazy dynamic imports, so MaxAI is registered in that shape rather than the branch's static import. - imageRegistry.ts: kept only the maxai block. The branch still carried microsoft-designer-web, which cheaper-inference#11754 retired. - models/route.ts: the conflicting hunk was an unrelated Vertex/Anthropic URL change, not MaxAI — tip's side. - volcengine agent-plan/coding-plan registries: git auto-merged both sides and produced a duplicated supportsVision key, which TypeScript rejects (TS1117). Removed. One real integration break that only the combined state shows: the MaxAI entry declared no serviceKinds, which cheaper-inference#11392 made required a few hours ago. Provider validation threw at load time and check:provider-consistency crashed outright. Declared ["llm"] — the image kinds derive from imageRegistry, per the convention in that PR's backfill. Every count was measured rather than taken from the branch, and each would have been wrong: reserved prefixes are 402, not the 397 the branch computed from its stale 395 base; providers are 353, not 354. PROVIDER_REFERENCE.md regenerated, the count updated across README/AGENTS.md/llm.txt and its 42 mirrors, package.json and 6 SVGs — every changed line in those files is a digit substitution and nothing else, verified by masking digits and comparing the removed and added sets (90 lines, identical). The executor-map golden snapshot was regenerated: keyCount 133 -> 134. The branch's file-size-baseline.json predates cheaper-inference#12411's ratchet re-tightening, so it was discarded rather than merged — taking it would have silently undone that. The three files this PR grows (proxyFetch.ts +20 for the Windows/firefox_150 TLS profile, imageGeneration.ts +12, models/route.ts +48) were entered against the current baseline under one _rebaseline annotation; no other cap moves. Verified: typecheck:core clean, check:provider-consistency OK (269 REGISTRY entries, 353 canonical providers), check:docs-counts exit 0, check-file-size OK, check:cycles OK, and 79/79 across the MaxAI suites plus 21/21 reserved-prefix and 2/2 executor-map-golden. Thanks @arminanton — the provider work itself is thorough; it was the 227 commits of base that needed the attention.
…ect (metered) (cheaper-inference#11513) Adds uncensored.com as two OpenAI-compatible providers mirroring UC's own surfaces: uc, the persona/subscription side over WebSocket with a durable Clerk credential minting a short-lived per-connect token (no API key, un-metered), as a full multimodal port — chat, tools, vision, doc-RAG, image, video, TTS; and uc-direct, the metered Developer API over REST with X-api-key. Same underlying models, two billing surfaces. Reconciled on merge. 57 files conflicted; only seven carried UC content, the rest was drift from the older release line and took the tip's side. - executors/index.ts: the tip has since refactored the executor map to lazy dynamic imports, so uc is registered in that shape. uc-direct needs no entry — it routes through the default OpenAI-compatible executor. - imageGeneration.ts: the branch still carried the retired designerWeb import alongside ucImage; kept only the UC one. - config/providers/index.ts, webSessionCredentials.ts and web-cookie.ts resolved additively against the MaxAI entries cheaper-inference#11461 put on the tip an hour earlier. - web-cookie.ts: the uc entry declared no serviceKinds, required since cheaper-inference#11392, so provider validation would have thrown at load. Declared ["llm"]. uc-direct already declared it at the end of its own entry — an earlier pass of mine added a second one after id and TypeScript caught the duplicate (TS1117); the author's placement is what shipped. Every count was measured against the merged tree rather than taken from the branch, and all three would have been wrong: reserved prefixes are 406, not 399; APIKEY_PROVIDERS is 237, not 234; providers are 355. PROVIDER_REFERENCE.md regenerated, the count updated across README/AGENTS.md/llm.txt and its 42 mirrors, package.json and 6 SVGs — every changed line in the protected surfaces is a digit substitution and nothing else, verified by masking digits and comparing the removed and added sets (90 lines each, identical). The executor-map golden snapshot went 134 -> 135. The branch's file-size-baseline.json predates cheaper-inference#12411's ratchet re-tightening and was discarded rather than merged; imageGeneration.ts (+12 for the uc-image format branch) was entered against the current baseline under a _rebaseline annotation, and no other cap moves. Verified: typecheck:core clean, check:provider-consistency OK (271 REGISTRY entries, 355 canonical providers), check:docs-counts exit 0, check-file-size OK, check:cycles OK, 119/119 across the PR's test files, and 2/2 executor-map-golden. Thanks @arminanton — two providers for two real billing surfaces, rather than one entry pretending to be both, is the right modelling.
…stency gate
Fixes #10513 · Refs Discussion #10267
Base-red inherited: #9985 (release/v3.8.50 not green)
What:
Validation:
Summary
Related Issues
Validation
Choose the change type and focused loop from the
Contribution Golden Path. The full unit suite,
Vitest, the 60% coverage gate, and the production build all run in CI on this PR (#8329):
npm run lintTests Added Or Updated
Coverage Notes
src/,open-sse/,electron/, orbin/, explain which tests cover the change.Reviewer Notes