From 1e55fbd20b03995c77975110960f95ffa6850e22 Mon Sep 17 00:00:00 2001 From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com> Date: Thu, 6 Aug 2026 23:38:59 +0930 Subject: [PATCH] [v3.8.50] fix(open-sse): filter non-numeric values in comboTargetLimits before min calculation (#8774) Validated in post-merge-train sweep (boards clean on release/v3.8.50 tip) --- open-sse/handlers/chatCore.ts | 18 ++++++++++-------- tests/unit/resolveComboContextLimit.test.ts | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 tests/unit/resolveComboContextLimit.test.ts diff --git a/open-sse/handlers/chatCore.ts b/open-sse/handlers/chatCore.ts index 373a0e6ea1..26120abce3 100644 --- a/open-sse/handlers/chatCore.ts +++ b/open-sse/handlers/chatCore.ts @@ -1724,14 +1724,16 @@ export async function handleChatCore({ comboConfig as unknown as { name: string; models: unknown[] }, allCombosData as unknown as { name: string; models: unknown[] }[] ); - comboTargetLimits = targets.map((t: { modelStr?: string; provider?: string }) => - // Fall back to ResolvedComboTarget.provider when modelStr lacks a - // provider/ prefix — parseModel alone returns provider:null (#8716). - getComboTargetTokenLimit({ - modelStr: t.modelStr, - provider: t.provider, - }) - ); + // Fall back to ResolvedComboTarget.provider when modelStr lacks a + // provider/ prefix — parseModel alone returns provider:null (#8716). + comboTargetLimits = targets + .map((t: { modelStr?: string; provider?: string }) => + getComboTargetTokenLimit({ modelStr: t.modelStr, provider: t.provider }) + ) + .filter( + (limit): limit is number => + typeof limit === "number" && Number.isFinite(limit) && limit > 0 + ); } // chatCore executes per concrete target (handleSingleModel resolves // provider/effectiveModel before delegating). Compress against THIS diff --git a/tests/unit/resolveComboContextLimit.test.ts b/tests/unit/resolveComboContextLimit.test.ts new file mode 100644 index 0000000000..94673ba55e --- /dev/null +++ b/tests/unit/resolveComboContextLimit.test.ts @@ -0,0 +1,21 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { resolveComboContextLimit } from "../../open-sse/services/contextManager.ts"; + +test("resolveComboContextLimit handles array of combo target objects ({ name, models }) in comboTargetLimits", () => { + const result = resolveComboContextLimit({ + provider: "unknown_provider", + model: "unknown_model", + comboTargetLimits: [ + { name: "subcombo1", models: [{ provider: "openai", model: "gpt-4" }] }, + { name: "subcombo2", models: [{ provider: "anthropic", model: "claude-3-5-sonnet" }] }, + ] as unknown as number[], + }); + + // Default fallback limit for unknown provider should be returned without throwing NaN or crash + assert.equal(typeof result.limit, "number"); + assert.ok(!Number.isNaN(result.limit)); + assert.ok(result.limit > 0); + assert.equal(result.source, "fallback"); +}); +