Skip to content

feat(providers): add canonical free provider directory#405

Closed
HaydernCenterpoint wants to merge 1 commit into
lidge-jun:devfrom
HaydernCenterpoint:feat/provider-directory
Closed

feat(providers): add canonical free provider directory#405
HaydernCenterpoint wants to merge 1 commit into
lidge-jun:devfrom
HaydernCenterpoint:feat/provider-directory

Conversation

@HaydernCenterpoint

@HaydernCenterpoint HaydernCenterpoint commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a canonical directory for free provider presets
  • derive and register directory entries consistently
  • cover registry parity

Tests

  • bun test tests/provider-registry-parity.test.ts

Summary by CodeRabbit

  • New Features

    • Added a directory of free and reference providers with access, verification, documentation, and model availability details.
    • Expanded provider discovery and preset information shown by the application.
    • Added regional endpoint choices for SiliconFlow.
    • Improved support for optional-key providers and free provider configurations.
  • Bug Fixes

    • Excluded reference-only and directory-only providers from connection and initialization lists.
    • Preserved missing provider configuration details when registry information is available.

Copilot AI review requested due to automatic review settings July 24, 2026 11:13

This comment was marked as outdated.

@github-actions github-actions Bot added the enhancement New feature or request label Jul 24, 2026
@coderabbitai

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

chatgpt-codex-connector[bot]

This comment was marked as outdated.

@lidge-jun

Copy link
Copy Markdown
Owner

Reviewed — two blocking findings:

  1. High — directory-only IDs collide with existing custom providers. registry.ts:1045-1049 adds 68 directory-only IDs to the global registry, and derive.ts:210-246 enriches any runtime config whose name matches. A user's custom provider named vertex, baidu, cloudflare-ai, or qoder gets injected models, liveModels:false, and googleMode. Reproduced: qoder loses live discovery; vertex gets unrelated Gemini models + googleMode:"vertex". Directory-only rows must be excluded from runtime enrichment, with a collision regression test.

  2. High — incomplete directory exposed in the credential UI. derive.ts:203-207 includes accessGroups entries as GUI presets, but provider-presets.ts:13-60 doesn't understand accessGroups/supportLevel/verification — 66 of 68 directory-only rows land in the Paid tab, and 21 reference-only rows (with unverified/primary endpoints) are selectable and lead to the API-key input in AddProviderModal.tsx:507-509. The baseUrl/authKind in free-directory.ts:51-125 determine where a user's API key is sent — this is a credential-destination trust boundary that needs human security review.

Also missing: directory invariants test, reference-row exclusion test, GUI free-classification test, custom-name collision test, and docs sync for the user-facing change.

Happy to re-review after the enrichment exclusion + UI gating are in.

@HaydernCenterpoint

Copy link
Copy Markdown
Contributor Author

@lidge-jun got it boss, will fix it when i wake up!

@lidge-jun

Copy link
Copy Markdown
Owner

🔒 Under maintainer review — detailed feedback incoming

@lidge-jun (maintainer) has this PR in an active review pass. Please do not merge or close
it
until the detailed review lands; a full comment with specific file:line findings,
failure modes, and suggested fixes is being prepared.

This PR is not part of the current integration batch. It is held back deliberately —
either because it touches a security boundary that MAINTAINERS.md requires an explicit
security review for, because it needs to be split into reviewable units, or because it needs
a rebase onto changes landing in dev right now.

Heads-up on rebasing: dev is receiving a coordinated integration batch today. If this PR
touches the same files, expect to rebase after that batch lands. The upcoming review comment
will name the exact overlapping paths so you only have to do it once.

No action needed from you until then. Thanks for the contribution and for your patience.

Review tracker: devlog/_plan/260725_pr_issue_rework · marker posted by the maintainer review pass

@lidge-jun

Copy link
Copy Markdown
Owner

Thank you for assembling the canonical free-provider directory. This PR should not merge independently in its current form.

At src/providers/derive.ts:202, entries marked reference / directoryOnly are still emitted into dashboard presets. The UI guard that prevents those informational rows from being connected (isPresetActionable) exists only in #434, not in this PR. Merging #405 alone would therefore present unverified/reference endpoints as connectable providers, which turns directory metadata into a product trust decision without the corresponding safety gate.

Please either add the actionable-state contract and tests in the same narrowly scoped PR, or keep directory-only rows out of dashboard presets. A regression should prove a directoryOnly entry can be displayed as reference information but cannot create provider config.

#434 already contains #405's four changed file blobs unchanged, so maintaining both also creates duplicate/superseded review work. Please close this PR in favor of the appropriately split directory slice from #434, rebased on current dev. Thanks for the research and curation; it needs to land with the non-actionable boundary intact.

Please also rebase the directory slice onto current dev, which now includes #385's BizRouter registry entry and the expanded registry-parity assertions.


Reviewed as part of a maintainer integration pass. dev moved to ebc62d1f today (7 PRs integrated); Cross-platform CI is green on ubuntu, macOS, and Windows.

@Wibias
Wibias marked this pull request as draft July 25, 2026 19:44
lidge-jun added a commit that referenced this pull request Jul 26, 2026
Adds the catalog of free/credit-based provider endpoints as a standalone module
with no runtime consumer. Deliberately does NOT take the PR's registry and
derive hunks.

The PR merges directory rows into PROVIDER_REGISTRY behind a `directoryOnly`
marker, but that marker is descriptive only. `routedProviderConfig()` looks up
by id with no such guard, so a user's own provider named `qoder`, `vertex`, or
`baidu` would be canonicalized onto the directory row's adapter and baseUrl. For
`qoder` that baseUrl is the empty string, so the request loses its destination
outright. Review found several other unguarded consumers — CLI provider
list/create, GUI presets, catalog enrichment, subagent prefix classification —
and the GUI DTO carries no actionable/reference distinction, so reference rows
reach a provider-creation surface that implies they are connectable.

Landing the catalog without those hunks keeps the data available for a later UI
slice while leaving routing untouched. That slice needs its own read-only DTO
and a server-side actionable check; teaching every registry consumer about a
flag is the fragile direction.

Two data corrections on the way in:

- `lastVerified` is now optional and only present on rows whose endpoint was
  actually checked. The module previously stamped one shared date on all 81
  rows including the 22 marked `unverified` — a provenance claim nobody made.
  `bytez` keeps its live endpoint but drops the date, since its recurring-credit
  terms could not be confirmed.
- Both iFlytek rows cited the WebSocket protocol page as documentation for an
  OpenAI-compatible HTTP endpoint. Pointed at the HTTP guide instead.

Tests lock the isolation rather than the catalog contents: reference ids stay
out of PROVIDER_REGISTRY, a custom `qoder` provider keeps its own destination
through routeModel, and unverified rows carry no verification date. Verified red
by reproducing the PR's append design.

Co-authored-by: Haydern <oriskinhaydern@gmail.com>
@lidge-jun

Copy link
Copy Markdown
Owner

Integrated the catalog into dev as be16c1d8 with your authorship preserved via Co-authored-by. Closing this PR, though I took the module and left the wiring behind — let me explain why, because your directoryOnly design was a genuine attempt to solve exactly the problem I'm about to describe.

The marker doesn't isolate anything. routedProviderConfig() looks up by id at src/router.ts:121 with no directoryOnly guard, so a directory row in PROVIDER_REGISTRY still canonicalizes a user's same-named provider. Concretely: a user with their own qoder provider pointed at https://custom.example.test/v1 gets routed onto the directory row's baseUrl, which is the empty string — the request loses its destination entirely. vertex and baidu collide differently, replacing the user's adapter and endpoint with Google's and Qianfan's.

Review also found the flag is honored in only two of the projections that need it. Unguarded: runtime routing and known-model merging, CLI provider list and create, deriveProviderPresets(), catalog enrichment and live discovery, subagent provider-prefix classification, and the generic getProviderRegistryEntry() consumers. The GUI DTO carries no supportLevel/verification/directoryOnly at all, so reference rows land in a provider-creation surface that implies they're connectable — they fail only because the URL field starts blank, and a user can just type one in.

So the catalog landed as a standalone module with no runtime consumer. The data is preserved and available; nothing routes through it. When someone builds the UI slice, it should read through its own DTO with a server-side actionable check, rather than teaching every registry consumer about a flag — one missed consumer is the whole hazard, and this head had several.

Two data corrections on the way in. The module stamped a single LAST_VERIFIED = "2026-07-23" on all 81 rows, including the 22 marked verification: "unverified" — a provenance claim nobody actually made. lastVerified is now optional and present only on rows whose endpoint was checked; verified rows must also carry a documentation, models, or dashboard URL. bytez keeps its endpoint but drops the date, since its recurring-credit terms couldn't be confirmed independently.

Both iFlytek rows cited xfyun.cn/doc/spark/Web.html — the WebSocket protocol page — as documentation for https://spark-api-open.xf-yun.com/v1, which is an OpenAI-compatible HTTP endpoint. Repointed at the HTTP guide.

Worth noting the rest of the catalog held up well under spot checks: Baidu Qianfan, Cloudflare Workers AI, OVHcloud, and Nebius all matched their official documentation, and live unauthenticated probes to Bytez, AgentRouter, and LongCat returned provider auth errors rather than dead hosts. One caveat for later — Pollinations' keyless contract wasn't fully verified, so keyOptional: true on that row deserves a focused check before anything acts on it.

Tests lock the isolation rather than the catalog contents: reference ids stay out of PROVIDER_REGISTRY, a custom qoder provider keeps its own destination through routeModel, and unverified rows carry no verification date. I verified these go red by reproducing your append design, so if someone reintroduces it the suite says so immediately.

Thank you for assembling this — 81 endpoints with access-group classification is real research, and it's now in the tree where a UI can pick it up safely.


Integrated as part of a maintainer PABCD pass. Plan unit: devlog/_plan/260726_pr_close_rework/080_wp8_free_provider_directory_405.md.

@lidge-jun lidge-jun closed this Jul 26, 2026
lidge-jun added a commit that referenced this pull request Jul 26, 2026
통합(dev push 완료): #437 803807a, #460 74ddd96, #431 82a47db,
#405 be16c1d, #468 후속 테스트 bcaf029.

close: 통합 4건 + 통합 없이 1건(#459, 설계 충돌). #457은 OPEN 유지.
이슈 close 0건 — dev에서 고쳐졌는데 안 닫힌 이슈가 없었다.

무효화: WP4(#466)와 WP6(#467)은 동료가 직접 머지했고, 우리 분석이
지적한 결함을 동료 커밋이 같은 방향으로 해소했다.

보안 보류 5건에 신규 발견 게시: #429 재분류, #355 OAuth 토큰 목적지,
#424 유료 브리지 기본 ON, #408 설치 락 해제, #403 4분할 요청.

A-gate는 사이클마다 3~5라운드를 돌았다. 반복된 원인은 계획서에
테스트나 코드를 적으면서 실물 소스를 확인하지 않은 것이었다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants