From 7818494a4b8e400a13c7909b5c80842d0c0f23a6 Mon Sep 17 00:00:00 2001
From: Dizzle <112548150+maxmad64bis@users.noreply.github.com>
Date: Sun, 11 Oct 2026 13:35:53 +0200
Subject: [PATCH] fix(health): omit idle models from health matrix by default
Idle rows stay counted per account; includeIdleModels=true restores the full list.
---
.../16333-health-matrix-omit-idle-models.md | 1 +
.../health/ProviderHealthMatrixCard.tsx | 6 +-
src/app/api/providers/health-matrix/route.ts | 6 +
src/lib/monitoring/providerHealthMatrix.ts | 15 +-
tests/unit/provider-health-matrix.test.ts | 227 ++++++++++++++++++
5 files changed, 251 insertions(+), 4 deletions(-)
create mode 100644 changelog.d/fixes/16333-health-matrix-omit-idle-models.md
diff --git a/changelog.d/fixes/16333-health-matrix-omit-idle-models.md b/changelog.d/fixes/16333-health-matrix-omit-idle-models.md
new file mode 100644
index 000000000000..8dbce692c069
--- /dev/null
+++ b/changelog.d/fixes/16333-health-matrix-omit-idle-models.md
@@ -0,0 +1 @@
+- **fix(health):** Shrink the provider health matrix payload by omitting idle models by default, with `includeIdleModels=true` to restore the full list ([#16333](https://github.com/diegosouzapw/OmniRoute/pull/16333)) — thanks @maxmad64bis
diff --git a/src/app/(dashboard)/dashboard/health/ProviderHealthMatrixCard.tsx b/src/app/(dashboard)/dashboard/health/ProviderHealthMatrixCard.tsx
index 58363e23fdce..d36c9b55ef8b 100644
--- a/src/app/(dashboard)/dashboard/health/ProviderHealthMatrixCard.tsx
+++ b/src/app/(dashboard)/dashboard/health/ProviderHealthMatrixCard.tsx
@@ -40,6 +40,7 @@ type HealthMatrixAccount = {
errorCode: string | null;
backoffLevel: number;
modelCount: number;
+ omittedIdleModelCount: number;
issueCount: number;
models: HealthMatrixModel[];
};
@@ -200,7 +201,8 @@ function ModelPill({ model }: { model: HealthMatrixModel }) {
function AccountRow({ account }: { account: HealthMatrixAccount }) {
const t = useTranslations("health");
const visibleModels = account.models.slice(0, 8);
- const hiddenCount = Math.max(0, account.models.length - visibleModels.length);
+ const omittedIdleModels = account.omittedIdleModelCount ?? 0;
+ const hiddenCount = omittedIdleModels + Math.max(0, account.models.length - visibleModels.length);
const additionalModelsLabel = t.has("additionalModels")
? t("additionalModels", { count: hiddenCount })
: `+${hiddenCount} more models`;
@@ -246,7 +248,7 @@ function AccountRow({ account }: { account: HealthMatrixAccount }) {
{account.state}
- {visibleModels.length > 0 ? (
+ {visibleModels.length > 0 || omittedIdleModels > 0 ? (
{visibleModels.map((model) => (
diff --git a/src/app/api/providers/health-matrix/route.ts b/src/app/api/providers/health-matrix/route.ts
index 46ac4617af0e..71e5fd9fbc1d 100644
--- a/src/app/api/providers/health-matrix/route.ts
+++ b/src/app/api/providers/health-matrix/route.ts
@@ -16,6 +16,10 @@ const healthMatrixQuerySchema = z.object({
.enum(["true", "false", "1", "0"])
.nullable()
.transform((value) => (value === null ? true : value === "true" || value === "1")),
+ includeIdleModels: z
+ .enum(["true", "false", "1", "0"])
+ .nullable()
+ .transform((value) => (value === null ? false : value === "true" || value === "1")),
});
export async function GET(request: Request) {
@@ -28,6 +32,7 @@ export async function GET(request: Request) {
provider: url.searchParams.get("provider"),
range: url.searchParams.get("range"),
includeHealthy: url.searchParams.get("includeHealthy"),
+ includeIdleModels: url.searchParams.get("includeIdleModels"),
});
if (!parsedQuery.success) {
@@ -40,6 +45,7 @@ export async function GET(request: Request) {
provider: parsedQuery.data.provider,
range: parsedQuery.data.range,
includeHealthy: parsedQuery.data.includeHealthy,
+ includeIdleModels: parsedQuery.data.includeIdleModels,
});
return NextResponse.json(report);
} catch (error) {
diff --git a/src/lib/monitoring/providerHealthMatrix.ts b/src/lib/monitoring/providerHealthMatrix.ts
index f9af936417aa..6b29d62707b0 100644
--- a/src/lib/monitoring/providerHealthMatrix.ts
+++ b/src/lib/monitoring/providerHealthMatrix.ts
@@ -16,6 +16,7 @@ export interface ProviderHealthMatrixOptions {
provider?: string | null;
range?: ProviderHealthMatrixRange | string | null;
includeHealthy?: boolean;
+ includeIdleModels?: boolean;
}
export interface ProviderHealthMatrixModel {
@@ -47,6 +48,7 @@ export interface ProviderHealthMatrixAccount {
errorCode: string | null;
backoffLevel: number;
modelCount: number;
+ omittedIdleModelCount: number;
issueCount: number;
models: ProviderHealthMatrixModel[];
}
@@ -487,7 +489,11 @@ export async function buildProviderHealthMatrix(
if (model) modelIds.add(model);
}
- const models = [...modelIds].sort().map((model): ProviderHealthMatrixModel => {
+ // Idle lines (no traffic in the window and no live lockout) stay out of the
+ // default payload but remain counted, so large catalogs transfer only
+ // the models with activity.
+ const includeIdleModels = options.includeIdleModels === true;
+ const builtModels = [...modelIds].sort().map((model): ProviderHealthMatrixModel => {
const stat = statsByTarget.get(statsKey(provider, connectionId, model)) ?? null;
const lockout = lockoutsByTarget.get(modelLockKey(provider, connectionId, model)) ?? null;
const isLockedOut = Boolean(lockout);
@@ -508,6 +514,10 @@ export async function buildProviderHealthMatrix(
lastErrorAt: stat?.lastErrorAt ?? null,
};
});
+ const models = includeIdleModels
+ ? builtModels
+ : builtModels.filter((model) => model.status !== "idle");
+ const omittedIdleModelCount = includeIdleModels ? 0 : modelIds.size - models.length;
const cooldownUntil = connection ? parseTimeMs(connection.rateLimitedUntil) : null;
const cooldownRemainingMs = cooldownUntil ? Math.max(0, cooldownUntil - now) : 0;
@@ -529,7 +539,8 @@ export async function buildProviderHealthMatrix(
lastErrorType: connection ? toString(connection.lastErrorType) : null,
errorCode: connection ? toString(connection.errorCode) : null,
backoffLevel: connection ? toNumber(connection.backoffLevel) : 0,
- modelCount: models.length,
+ modelCount: modelIds.size,
+ omittedIdleModelCount,
issueCount,
models,
});
diff --git a/tests/unit/provider-health-matrix.test.ts b/tests/unit/provider-health-matrix.test.ts
index 28dc9dfcfe2c..5f5656465b68 100644
--- a/tests/unit/provider-health-matrix.test.ts
+++ b/tests/unit/provider-health-matrix.test.ts
@@ -276,6 +276,233 @@ test("provider health matrix route requires management auth", async () => {
assert.equal(body.summary.connectionCount, 1);
});
+test("provider health matrix omits idle models by default and counts them", async () => {
+ const connection = (await providersDb.createProviderConnection({
+ id: "matrix-idle-connection",
+ provider: PROVIDER,
+ authType: "apikey",
+ name: "matrix-key",
+ apiKey: "test-key",
+ isActive: true,
+ })) as Record;
+ const connectionId = String(connection.id);
+
+ const syncedInputs = Array.from({ length: 600 }, (_, index) => ({
+ id: `matrix-idle-model-${index}`,
+ name: `Matrix Idle Model ${index}`,
+ }));
+ await modelsDb.replaceSyncedAvailableModelsForConnection(PROVIDER, connectionId, syncedInputs);
+ const startedAt = Date.now();
+ for (let index = 0; index < 3; index += 1) {
+ await callLogs.saveCallLog({
+ id: `matrix-idle-log-${index}`,
+ timestamp: new Date(startedAt + index).toISOString(),
+ status: 200,
+ provider: PROVIDER,
+ connectionId,
+ model: `matrix-idle-model-${index}`,
+ duration: 100,
+ });
+ }
+
+ const report = await matrix.buildProviderHealthMatrix({
+ provider: PROVIDER,
+ range: "24h",
+ includeHealthy: true,
+ });
+
+ const account = report.providers[0]?.accounts[0];
+ assert.ok(account);
+ assert.equal(account.models.length, 3);
+ assert.equal(account.omittedIdleModelCount, 597);
+ assert.equal(account.modelCount, 600);
+ assert.ok(account.models.every((candidate) => candidate.status !== "idle"));
+ assert.equal(report.summary.modelCount, 600);
+});
+
+test("provider health matrix renders a locked model without traffic", async () => {
+ const connection = (await providersDb.createProviderConnection({
+ id: "matrix-idle-locked-connection",
+ provider: PROVIDER,
+ authType: "apikey",
+ name: "matrix-key",
+ apiKey: "test-key",
+ isActive: true,
+ })) as Record;
+ const connectionId = String(connection.id);
+
+ await modelsDb.replaceSyncedAvailableModelsForConnection(PROVIDER, connectionId, [
+ { id: "matrix-idle-locked-model", name: "Matrix Idle Locked Model" },
+ ]);
+ accountFallback.lockModel(
+ PROVIDER,
+ connectionId,
+ "matrix-idle-locked-model",
+ "quota_exhausted",
+ 60_000,
+ {}
+ );
+
+ const report = await matrix.buildProviderHealthMatrix({
+ provider: PROVIDER,
+ range: "24h",
+ includeHealthy: true,
+ });
+
+ const account = report.providers[0]?.accounts[0];
+ assert.ok(account);
+ assert.equal(account.models.length, 1);
+ assert.equal(account.models[0]?.status, "locked");
+ assert.equal(account.omittedIdleModelCount, 0);
+ assert.equal(account.modelCount, 1);
+});
+
+test("provider health matrix renders every synced model when idle models are included", async () => {
+ const connection = (await providersDb.createProviderConnection({
+ id: "matrix-idle-full-connection",
+ provider: PROVIDER,
+ authType: "apikey",
+ name: "matrix-key",
+ apiKey: "test-key",
+ isActive: true,
+ })) as Record;
+ const connectionId = String(connection.id);
+
+ const syncedInputs = Array.from({ length: 600 }, (_, index) => ({
+ id: `matrix-idle-full-model-${index}`,
+ name: `Matrix Idle Full Model ${index}`,
+ }));
+ await modelsDb.replaceSyncedAvailableModelsForConnection(PROVIDER, connectionId, syncedInputs);
+ const startedAt = Date.now();
+ for (let index = 0; index < 3; index += 1) {
+ await callLogs.saveCallLog({
+ id: `matrix-idle-full-log-${index}`,
+ timestamp: new Date(startedAt + index).toISOString(),
+ status: 200,
+ provider: PROVIDER,
+ connectionId,
+ model: `matrix-idle-full-model-${index}`,
+ duration: 100,
+ });
+ }
+
+ const report = await matrix.buildProviderHealthMatrix({
+ provider: PROVIDER,
+ range: "24h",
+ includeHealthy: true,
+ includeIdleModels: true,
+ });
+
+ const account = report.providers[0]?.accounts[0];
+ assert.ok(account);
+ assert.equal(account.models.length, 600);
+ assert.equal(account.omittedIdleModelCount, 0);
+ assert.equal(account.modelCount, 600);
+});
+
+test("provider health matrix route renders every synced model when idle models are included", async () => {
+ await enableManagementAuth();
+ const connection = (await providersDb.createProviderConnection({
+ id: "matrix-idle-route-connection",
+ provider: PROVIDER,
+ authType: "apikey",
+ name: "matrix-key",
+ apiKey: "test-key",
+ isActive: true,
+ })) as Record;
+ const connectionId = String(connection.id);
+
+ await modelsDb.replaceSyncedAvailableModelsForConnection(PROVIDER, connectionId, [
+ { id: "matrix-idle-route-model", name: "Matrix Idle Route Model" },
+ ]);
+
+ const compact = await route.GET(
+ await makeManagementSessionRequest("http://localhost/api/providers/health-matrix")
+ );
+ assert.equal(compact.status, 200);
+ const compactBody = await compact.json();
+ const compactAccount = compactBody.providers[0]?.accounts[0];
+ assert.equal(compactAccount.models.length, 0);
+ assert.equal(compactAccount.omittedIdleModelCount, 1);
+ assert.equal(compactAccount.modelCount, 1);
+
+ const full = await route.GET(
+ await makeManagementSessionRequest(
+ "http://localhost/api/providers/health-matrix?includeIdleModels=true"
+ )
+ );
+ assert.equal(full.status, 200);
+ const fullBody = await full.json();
+ const fullAccount = fullBody.providers[0]?.accounts[0];
+ assert.equal(fullAccount.models.length, 1);
+ assert.equal(fullAccount.omittedIdleModelCount, 0);
+ assert.equal(fullAccount.modelCount, 1);
+});
+
+test("provider health matrix route rejects an invalid idle-models flag", async () => {
+ await enableManagementAuth();
+
+ const invalid = await route.GET(
+ await makeManagementSessionRequest(
+ "http://localhost/api/providers/health-matrix?includeIdleModels=yes"
+ )
+ );
+ assert.equal(invalid.status, 400);
+});
+
+test("provider health matrix leaves an account without synced models unchanged", async () => {
+ await providersDb.createProviderConnection({
+ id: "matrix-idle-empty-connection",
+ provider: PROVIDER,
+ authType: "apikey",
+ name: "matrix-key",
+ apiKey: "test-key",
+ isActive: true,
+ });
+
+ const report = await matrix.buildProviderHealthMatrix({
+ provider: PROVIDER,
+ range: "24h",
+ includeHealthy: true,
+ });
+
+ const account = report.providers[0]?.accounts[0];
+ assert.ok(account);
+ assert.equal(account.models.length, 0);
+ assert.equal(account.modelCount, 0);
+ assert.equal(account.omittedIdleModelCount, 0);
+});
+
+test("provider health matrix counts an account with only idle models as omitted", async () => {
+ const connection = (await providersDb.createProviderConnection({
+ id: "matrix-idle-only-connection",
+ provider: PROVIDER,
+ authType: "apikey",
+ name: "matrix-key",
+ apiKey: "test-key",
+ isActive: true,
+ })) as Record;
+ const connectionId = String(connection.id);
+
+ const syncedInputs = Array.from({ length: 600 }, (_, index) => ({
+ id: `matrix-idle-only-model-${index}`,
+ name: `Matrix Idle Only Model ${index}`,
+ }));
+ await modelsDb.replaceSyncedAvailableModelsForConnection(PROVIDER, connectionId, syncedInputs);
+
+ const report = await matrix.buildProviderHealthMatrix({
+ provider: PROVIDER,
+ range: "24h",
+ includeHealthy: true,
+ });
+
+ const account = report.providers[0]?.accounts[0];
+ assert.ok(account);
+ assert.equal(account.models.length, 0);
+ assert.equal(account.modelCount, 600);
+ assert.equal(account.omittedIdleModelCount, 600);
+});
+
test("provider health matrix route rejects invalid query parameters", async () => {
await enableManagementAuth();