fix(dashboard): include never-tested connections in combo builder active-provider list (port from 9router#2057) (#7118)

Newly-added provider connections default testStatus to null until an operator explicitly runs a connection test. The combo builder's active-providers filter only kept testStatus === active/success, so a freshly-added custom provider was excluded from activeProviders — ModelSelectModal's loadCustomProviderModels() effect never fired for it, and its models never populated the combo model picker.

Extracted the eligibility check into isEligibleActiveConnection (src/lib/combos/builderDraft.ts), treating a never-tested connection the same as a known-good one (consistent with deriveConnectionStatus in builderOptions.ts, which only flags error on an explicit error/fail testStatus).

Reported-by: fajarbossit (https://github.com/decolua/9router/issues/2057)
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-17 10:50:25 -03:00
committed by GitHub
parent 21d5acbb40
commit 32dd3a8249
4 changed files with 93 additions and 2 deletions

View File

@@ -0,0 +1 @@
- **fix(dashboard):** include never-tested custom provider connections in the combo builder's active-provider list so their models load without requiring a manual connection test first. (thanks @fajarbossit)

View File

@@ -14,7 +14,6 @@ import Toggle from "@/shared/components/Toggle";
import Tooltip from "@/shared/components/Tooltip";
import { ComboCompressionModeSelect } from "@/shared/components/compression/ComboCompressionModeSelect";
import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard";
import { filterUsableConnections } from "@/shared/utils/connectionStatus";
import { FieldLabelWithHelp, WeightTotalBar } from "./parts";
import { useComboProxyAssignments } from "./useComboProxyAssignments";
import { ResponseValidationEditor, type ResponseValidationValue } from "./ResponseValidationEditor";
@@ -35,6 +34,7 @@ import {
getNextComboBuilderStage,
getPreviousComboBuilderStage,
hasExactModelStepDuplicate,
isEligibleActiveConnection,
isIntelligentBuilderStrategy,
parseQualifiedModel,
resolveComboBuilderProviderId,
@@ -772,7 +772,8 @@ export default function CombosPage() {
if (combosRes.ok) setCombos((combosData.combos || []).filter((c) => !c.isHidden));
if (providersRes.ok) {
setActiveProviders(filterUsableConnections(providersData.connections || []));
const active = (providersData.connections || []).filter(isEligibleActiveConnection);
setActiveProviders(active);
}
if (metricsRes.ok) setMetrics(metricsData.metrics || {});
setProviderNodes(nodesData.nodes || []);

View File

@@ -20,6 +20,33 @@ export function isIntelligentBuilderStrategy(strategy: unknown): boolean {
return strategy === "auto" || strategy === "lkgp";
}
export type ComboEligibleConnectionLike = {
isActive?: boolean | null;
testStatus?: string | null;
};
/**
* Whether a provider connection should be treated as eligible for the combo
* builder's "active providers" list (used to decide which providers get their
* models fetched/shown when creating or editing a combo).
*
* Newly-created connections default `testStatus` to `null` until someone
* explicitly runs a connection test (`src/lib/db/providers.ts`). Excluding
* those from the combo builder meant a freshly-added custom provider's models
* never populated the combo model picker until an operator manually tested
* the connection — matching the reported symptom (#2057). "Never tested" is
* therefore treated the same as "known good", consistent with
* `deriveConnectionStatus` in `src/lib/combos/builderOptions.ts`, which only
* flags a connection as an error when `testStatus` explicitly matches
* `/error|fail/i`.
*/
export function isEligibleActiveConnection(connection: ComboEligibleConnectionLike): boolean {
if (connection.isActive === false) return false;
const testStatus = connection.testStatus;
if (!testStatus) return true;
return testStatus === "active" || testStatus === "success" || testStatus === "unknown";
}
export function getComboBuilderStages(options: ComboBuilderStageOptions = {}): ComboBuilderStage[] {
if (isIntelligentBuilderStrategy(options.strategy)) {
return [...COMBO_BUILDER_STAGES];

View File

@@ -0,0 +1,62 @@
/**
* tests/unit/combo-builder-eligible-connection-2057.test.ts
*
* Regression for upstream issue #2057: the combo builder's "active providers"
* filter (src/app/(dashboard)/dashboard/combos/page.tsx::fetchData) only kept
* connections whose `testStatus` was exactly "active" or "success". New
* connections default `testStatus` to `null` until someone explicitly runs a
* connection test (src/lib/db/providers.ts), so a freshly-added custom
* provider was excluded from `activeProviders` — which meant
* ModelSelectModal's loadCustomProviderModels() effect never fetched its
* models, and the combo builder's model list stayed empty for that provider.
*
* Fix: `isEligibleActiveConnection` (src/lib/combos/builderDraft.ts) treats a
* never-tested connection (`testStatus` null/undefined) as eligible too,
* matching the "error only on explicit failure" semantics already used by
* `deriveConnectionStatus` in src/lib/combos/builderOptions.ts.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { isEligibleActiveConnection } from "../../src/lib/combos/builderDraft.ts";
test("isEligibleActiveConnection includes a never-tested (testStatus null) connection", () => {
assert.equal(isEligibleActiveConnection({ testStatus: null }), true);
});
test("isEligibleActiveConnection includes a never-tested (testStatus undefined) connection", () => {
assert.equal(isEligibleActiveConnection({}), true);
});
test("isEligibleActiveConnection includes explicit active/success/unknown statuses", () => {
assert.equal(isEligibleActiveConnection({ testStatus: "active" }), true);
assert.equal(isEligibleActiveConnection({ testStatus: "success" }), true);
assert.equal(isEligibleActiveConnection({ testStatus: "unknown" }), true);
});
test("isEligibleActiveConnection excludes connections that were explicitly deactivated", () => {
assert.equal(isEligibleActiveConnection({ isActive: false, testStatus: null }), false);
assert.equal(isEligibleActiveConnection({ isActive: false, testStatus: "active" }), false);
});
test("isEligibleActiveConnection excludes connections with a known error/failed test status", () => {
assert.equal(isEligibleActiveConnection({ testStatus: "error" }), false);
assert.equal(isEligibleActiveConnection({ testStatus: "failed" }), false);
assert.equal(isEligibleActiveConnection({ testStatus: "expired" }), false);
assert.equal(isEligibleActiveConnection({ testStatus: "unavailable" }), false);
});
test("simulated fetchData filter: a fresh custom provider connection with testStatus=null survives to activeProviders", () => {
const connections = [
{ id: "conn-1", provider: "openai", testStatus: "active", isActive: true },
// Freshly-added custom provider, never tested yet.
{ id: "conn-2", provider: "my-custom-provider", testStatus: null, isActive: true },
{ id: "conn-3", provider: "broken-provider", testStatus: "error", isActive: true },
];
const activeProviders = connections.filter(isEligibleActiveConnection);
assert.deepEqual(
activeProviders.map((c) => c.id),
["conn-1", "conn-2"]
);
});