From e00e5d774ee97a7672440dec8ec635dcdeb67ab5 Mon Sep 17 00:00:00 2001 From: "alexey.nazarov@softmg.ru" Date: Thu, 6 Aug 2026 18:02:41 +0300 Subject: [PATCH] fix(combo): restore routing module load --- .../fixes/release-v3850-combo-module-load.md | 1 + open-sse/services/combo/comboStructure.ts | 6 +++++ open-sse/services/combo/quotaStrategies.ts | 8 +------ .../unit/combo-context-window-filter.test.ts | 24 +++++++++++++++++-- tests/unit/combo-module-load-basered.test.ts | 9 +++++++ 5 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 changelog.d/fixes/release-v3850-combo-module-load.md create mode 100644 tests/unit/combo-module-load-basered.test.ts diff --git a/changelog.d/fixes/release-v3850-combo-module-load.md b/changelog.d/fixes/release-v3850-combo-module-load.md new file mode 100644 index 0000000000..f850a9c9f0 --- /dev/null +++ b/changelog.d/fixes/release-v3850-combo-module-load.md @@ -0,0 +1 @@ +- Restore combo routing module loading by removing a duplicate compatibility constant and an unresolved Antigravity helper import. diff --git a/open-sse/services/combo/comboStructure.ts b/open-sse/services/combo/comboStructure.ts index aa6ff9e596..deb72f012f 100644 --- a/open-sse/services/combo/comboStructure.ts +++ b/open-sse/services/combo/comboStructure.ts @@ -615,6 +615,12 @@ export type CompatFilterOptions = { failOpen?: boolean; }; + +function hasHardCapabilityFailure(reasons: string[]): boolean { + return reasons.some((reason) => HARD_COMPAT_REASONS.has(reason)); +} + + /** * Summarize a capability-filter exhaustion for a 400-class combo error (#8488). * Returns null when the empty pool is not attributable to hard requirements. diff --git a/open-sse/services/combo/quotaStrategies.ts b/open-sse/services/combo/quotaStrategies.ts index 4234b29433..b8e3e876c2 100644 --- a/open-sse/services/combo/quotaStrategies.ts +++ b/open-sse/services/combo/quotaStrategies.ts @@ -19,7 +19,6 @@ * (D7a) so reset-aware tie rotation stays consistent with round-robin routing. * * @changes - * - [2026-07-24] [Composer] - Exclude Antigravity accounts without stored projectId from reset-aware pool * - [2026-07-24] [Composer] - Skip quota-exhausted and rate-limited connections in reset-aware expansion * * Pure leaf: this module never imports from the combo barrel. @@ -85,14 +84,9 @@ async function getQuotaAwareConnectionsForTarget( (async () => { try { const connections = await getCachedProviderConnections({ provider, isActive: true }); - let activeConnections = Array.isArray(connections) + const activeConnections = Array.isArray(connections) ? (connections as Array>) : []; - if (provider === "antigravity" || provider === "agy") { - activeConnections = preferAntigravityConnectionsWithStoredProject( - activeConnections - ) as Array>; - } if ( !resetAwareConnectionCache.has(provider) && resetAwareConnectionCache.size >= MAX_RESET_AWARE_CACHE diff --git a/tests/unit/combo-context-window-filter.test.ts b/tests/unit/combo-context-window-filter.test.ts index e8f198c629..c2c900ae6d 100644 --- a/tests/unit/combo-context-window-filter.test.ts +++ b/tests/unit/combo-context-window-filter.test.ts @@ -192,6 +192,26 @@ test("all known-too-small context targets still fall back to strategy order", () ); }); +test("output-token limits remain a hard compatibility requirement", () => { + saveModelsDevCapabilities({ + "unit-output-limit": { + insufficient: capabilityEntryWithLimits(128_000, 128_000, 128), + sufficient: capabilityEntryWithLimits(128_000, 128_000, 4_096), + }, + }); + + const out = filterTargetsByRequestCompatibility( + [target("unit-output-limit/insufficient"), target("unit-output-limit/sufficient")], + { messages: [{ role: "user", content: "hello" }], max_tokens: 512 }, + noopLog + ); + + assert.deepEqual( + out.map((entry) => entry.modelStr), + ["unit-output-limit/sufficient"] + ); +}); + test("known context overflow reports the largest target limit", () => { saveModelsDevCapabilities({ "unit-known-context": { @@ -415,8 +435,8 @@ test("without an override the small-catalog target is ordered last for the large capped: capabilityEntry(8_000), }, }); - // No override: capped (8K) is genuinely too small and must be filtered out, - // guarding the override read-path from masking a real too-small target. + // No override: capped (8K) is catalog-too-small, so it stays behind the + // known-compatible target while remaining available as a runtime fallback. const out = filterTargetsByRequestCompatibility( [target("unit-override/capped"), target("unit-override/big")], largeContextBody(), diff --git a/tests/unit/combo-module-load-basered.test.ts b/tests/unit/combo-module-load-basered.test.ts new file mode 100644 index 0000000000..8bfd2412b5 --- /dev/null +++ b/tests/unit/combo-module-load-basered.test.ts @@ -0,0 +1,9 @@ +import test from "node:test"; +import assert from "node:assert/strict"; + +test("combo routing module loads without unresolved symbols", async () => { + const combo = await import("../../open-sse/services/combo.ts"); + + assert.equal(typeof combo.filterTargetsByRequestCompatibility, "function"); + assert.equal(typeof combo.handleComboChat, "function"); +});