fix(sse): family auto-combos include any backend that serves the family (no-auth allowlist scoped to tier pools) (#8391)

Context: #8183 introduced AUTO_COMBO_NOAUTH_ALLOWLIST (opencode, felo-web) to
gate no-auth providers out of every auto/* candidate pool, motivated by public
HTTP egress reliability on the reference VPS (.15) — several no-auth backends
(duckduckgo-web, theoldllm, chipotle, aihorde) were flaky there. Its own tests
(noauth-autocombo-allowlist.test.ts, virtual-auto-combo.test.ts) never
exercised the auto/<family> path, so the gate silently applied there too.

auto/<family> combos (#6453, e.g. auto/glm, auto/zai) are a different axis:
an identity selector ("route to whatever genuinely serves GLM"), not a
reliability-curated pool. auggie (local CLI subprocess, zero HTTP egress —
the reliability concern #8183 targets doesn't even apply to it) advertises a
literal glm-5.2 model and had an explicit design-test seat in auto/glm since
#7032, but the #8183 allowlist silently excluded it from that pool.

Operator decision (2026-07-24): the no-auth allowlist gate keeps applying to
category/tier and flat-variant auto/* pools (auto/best-free, auto/coding:fast,
...), but auto/<family> pools bypass it — any no-auth backend that genuinely
serves the family is admitted.

Fix: thread a `bypassAllowlist` flag through isChatAutoComboNoAuthProvider()
and getNoAuthCandidates(), set to `Boolean(spec?.family)` at the single call
site in createVirtualAutoCombo(). Family narrowing (buildFamilyCandidateFilter)
still runs afterward, so a bypassed no-auth candidate only survives if its
model actually belongs to the requested family. Category/tier and flat-variant
pools (spec.family unset) keep the gate fully intact.

Validation:
- tests/unit/autoCombo/provider-family-combos.test.ts:136 was red (expected
  ["auggie","glm","zai"], got ["glm","zai"]) — now green (11/11 passing).
- tests/unit/noauth-autocombo-allowlist.test.ts (3/3) and
  tests/unit/virtual-auto-combo.test.ts (10/10, including "restricts the
  no-auth pool to the allowlist") stay green — the #8183 gate is untouched for
  spec-less/category/tier pools.
- Full tests/unit/autoCombo/ vitest sweep: 5 files, 36/36 passing.
- npm run typecheck:core clean.
- 4 unrelated failures pre-exist on origin/release/v3.8.49 (verified via `git
  show HEAD:<path>` swap, no stash) in
  tests/unit/auto-combo-credentialed-model-pool.test.ts (antigravity/gemini-3.5
  credentialed-pool logic, untouched by this change).

Refs #8183, Refs #6453, Refs #7032
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-24 09:57:08 -03:00
committed by GitHub
parent c5c27b813a
commit bb4cb86be2

View File

@@ -143,11 +143,23 @@ const SYNTHETIC_NOAUTH_CONNECTION_ID = "noauth";
// and the others are unreliable. The excluded providers stay fully usable via
// direct `<alias>/<model>` calls — they are just kept OUT of auto-routing until
// re-verified. Re-add an id here to bring it back into every auto/* pool.
//
// Scope (operator decision 2026-07-24, refs #8183/#6453/#7032): this allowlist
// targets public-HTTP-egress reliability for the category/tier and flat-variant
// `auto/*` pools (auto/best-free, auto/coding:fast, ...). It does NOT apply to
// `auto/<family>` pools (auto/glm, auto/zai, ...) — a family combo is an
// identity selector ("whatever genuinely serves GLM"), not a reliability-curated
// pool, so it admits any no-auth backend that genuinely serves the family (e.g.
// auggie, a local CLI subprocess with zero HTTP egress, belongs in auto/glm
// regardless of this list). See the `bypassAllowlist` param below.
const AUTO_COMBO_NOAUTH_ALLOWLIST = new Set<string>(["opencode", "felo-web"]);
function isChatAutoComboNoAuthProvider(providerDef: NoAuthProviderDefinition): boolean {
function isChatAutoComboNoAuthProvider(
providerDef: NoAuthProviderDefinition,
bypassAllowlist: boolean
): boolean {
if (providerDef.noAuth !== true) return false;
if (!AUTO_COMBO_NOAUTH_ALLOWLIST.has(providerDef.id)) return false;
if (!bypassAllowlist && !AUTO_COMBO_NOAUTH_ALLOWLIST.has(providerDef.id)) return false;
if (!Array.isArray(providerDef.serviceKinds) || providerDef.serviceKinds.length === 0)
return true;
return providerDef.serviceKinds.includes("llm");
@@ -158,13 +170,14 @@ function getNoAuthCandidates(
blockedProviders: Set<string>,
disabledNoAuthProviders: Set<string>,
noAuthProviderSpecificData: Map<string, Record<string, unknown> | null | undefined>,
hiddenModelsMap: Map<string, Set<string>>
hiddenModelsMap: Map<string, Set<string>>,
bypassAllowlist: boolean
): VirtualAutoComboCandidate[] {
const registry = getProviderRegistry();
const candidates: VirtualAutoComboCandidate[] = [];
for (const providerDef of Object.values(NOAUTH_PROVIDERS) as NoAuthProviderDefinition[]) {
if (!isChatAutoComboNoAuthProvider(providerDef)) continue;
if (!isChatAutoComboNoAuthProvider(providerDef, bypassAllowlist)) continue;
const providerId = providerDef.id;
if (!providerId || excludedProviders.has(providerId)) continue;
@@ -386,7 +399,13 @@ export async function createVirtualAutoCombo(
blockedProviders,
disabledNoAuthProviders,
noAuthProviderSpecificData,
hiddenModelsMap
hiddenModelsMap,
// #6453/#8183 (operator decision 2026-07-24): auto/<family> combos are an
// identity selector, not a reliability-curated pool — bypass the no-auth
// allowlist gate so any backend that genuinely serves the family (e.g.
// auggie for auto/glm) is admitted. Category/tier and flat-variant pools
// (spec.family unset) keep the allowlist gate intact.
Boolean(spec?.family)
)
);