mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-20 13:52:28 +03:00
Restores ChatGPT Web on a clean-room browser transport, merged on the operator's explicit decision. Worth stating precisely, because this touches a provenance decision: the PR does not revert #11754. It narrows RETIRED_COMMON_CHATGPT_WEB_PROVIDER_IDS to the single GPL-derived alias cgpt-web and registers chatgpt-web as a separate clean-room id. The old implementation stays retired and blocked; the retirement machinery, its error code and its 410 contract are untouched. All four retirement suites agree with that distinction and pass unchanged. The 44 protected agent-instruction surfaces this PR touches (AGENTS.md, llm.txt and its 42 mirrors, README) were verified rather than trusted: masking digits and comparing the removed and added line sets gives 264 lines on each side, identical — every change is a provider-count substitution, with no sentence added, removed or reworded. Reconciled on merge: clean against the tip, with the two chat chokepoints this PR grows (src/sse/handlers/chat.ts +40, open-sse/handlers/chatCore.ts +30) recorded in the file-size baseline under an annotation. Verified that exactly those two caps move and nothing else, so the #12411 ratchet holds. The rebaseline is carried on this branch rather than left in a validation worktree — the propagation mistake that put the 2026-09-02 merge waves base-red in #12434. Verified: 504/504 across the PR's 44 test files plus all four chatgpt-web retirement suites, check:provider-consistency OK (272 REGISTRY entries, 355 canonical providers), check-file-size OK, and every changed TypeScript file parses. Thanks @backryun — separating the clean-room id from the retired alias, instead of reopening the old one, is what made this reviewable.
58 lines
2.8 KiB
TypeScript
58 lines
2.8 KiB
TypeScript
// #5420 — Tool-only providers (web search / web fetch) do not expose a model
|
|
// listing; their "Import Models" button hits the `400 "does not support models
|
|
// listing"` route. The old `-search` suffix heuristic caught `brave-search` but
|
|
// missed tool-only providers whose id has no suffix (e.g. `firecrawl`, declared
|
|
// `serviceKinds: ["webFetch"]`). This pure helper decides, from the provider id
|
|
// plus its resolved serviceKinds, whether to hide model listing — without ever
|
|
// hiding an LLM or media provider that genuinely lists models. Leaf module: it
|
|
// imports nothing, so it cannot create an import cycle with the page.
|
|
|
|
/** Service kinds that, on their own, mean the provider lists no models. */
|
|
const TOOL_ONLY_SERVICE_KINDS = new Set<string>(["webSearch", "webFetch"]);
|
|
|
|
/** Providers whose registry catalog is the complete, intentional model list.
|
|
*
|
|
* Volcano Ark plan providers (`volcengine-agent-plan` / `volcengine-coding-plan`)
|
|
* are intentionally NOT curated: their model list is discovered live from the
|
|
* console API (see volcenginePlanModelDiscovery.ts) and merged into the synced
|
|
* catalog, so the static registry only acts as a capability-seed fallback. */
|
|
const CURATED_MODEL_ONLY_PROVIDERS = new Set<string>([
|
|
"kimi-web",
|
|
"zai-web",
|
|
// The clean-room browser integration exposes only model/effort routes
|
|
// observed in the first-party picker. It has no upstream model-list API.
|
|
"chatgpt-web",
|
|
]);
|
|
|
|
export function providerUsesCuratedModelsOnly(providerId: string): boolean {
|
|
return CURATED_MODEL_ONLY_PROVIDERS.has(providerId.trim().toLowerCase());
|
|
}
|
|
|
|
/**
|
|
* Providers whose non-empty synced AvailableModels catalog fully replaces the
|
|
* static registry for dashboard / `/v1/models` / Test All listing. Static rows
|
|
* remain offline fallback only when synced is empty.
|
|
*
|
|
* Cursor-only for now — other authoritative live-catalog providers keep
|
|
* coverage-style static preservation (e.g. command-code uncovered static ids).
|
|
*/
|
|
export function providerUsesExclusiveSyncedListing(providerId: string): boolean {
|
|
const id = providerId.trim().toLowerCase();
|
|
return id === "cursor" || id === "cu";
|
|
}
|
|
|
|
/**
|
|
* True when the provider is tool-only and therefore has no model listing:
|
|
* - its id ends in `-search` (legacy search providers), OR
|
|
* - it declares at least one serviceKind and EVERY declared kind is a tool-only
|
|
* kind (`webSearch` / `webFetch`) — i.e. no `llm` and no media/embedding kind.
|
|
*
|
|
* Returns false for an empty `kinds` (most LLM providers declare nothing) and for
|
|
* any provider that has `llm`/image/video/music/tts/stt/embedding.
|
|
*/
|
|
export function providerLacksModelListing(providerId: string, kinds: readonly string[]): boolean {
|
|
if (providerId.endsWith("-search")) return true;
|
|
if (kinds.length === 0) return false;
|
|
return kinds.every((kind) => TOOL_ONLY_SERVICE_KINDS.has(kind));
|
|
}
|