mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
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:
committed by
GitHub
parent
21d5acbb40
commit
32dd3a8249
1
changelog.d/fixes/2057-combo-custom-provider-models.md
Normal file
1
changelog.d/fixes/2057-combo-custom-provider-models.md
Normal 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)
|
||||
@@ -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 || []);
|
||||
|
||||
@@ -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];
|
||||
|
||||
62
tests/unit/combo-builder-eligible-connection-2057.test.ts
Normal file
62
tests/unit/combo-builder-eligible-connection-2057.test.ts
Normal 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"]
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user