Repository navigation
feat(combo): add nestedComboMode execute — black-box combo-ref execution for selection strategies - #4537
Conversation
Modeled on the existing per-combo stickyRoundRobinLimit (cheaper-inference#3846). Adds a stickyWeightedLimit config field (0–1000, clamps to 1) that makes weighted combos pin their random selection for N consecutive successes before re-drawing. Fallback successes migrate sticky to the new healthy step. Exhaustion-aware: if the currently-sticky top-level weighted step becomes unavailable (all its expanded leaves are missing), sticky is cleared and the next weighted draw renormalizes over the remaining available steps. A top-level step is still considered available if at least one of its nested leaves reports healthy. Runtime logic: - resolveWeightedStepGroups() — new pure resolver exposing top-level weighted step → leaf expansion before sampling - resolveWeightedTargets() — optional preferredExecutionKey + optional eligibleExecutionKeys set for availability filtering - handleComboChat() — availability pre-filter checks circuit breaker, provider cooldown, model lockout, and isModelAvailable State lives in a new weightedStickyTargets map (same eviction ceiling as rrStickyTargets). getStickyWeightedExecutionKey / recordStickyWeightedSuccess are symmetrical to the round-robin helpers. Schema: comboRuntimeConfigSchema.stickyWeightedLimit (0–1000, coerce). UI: "Sticky Weighted Limit" input in the weighted advanced section, stickyWeightedLimit field description in ADVANCED_FIELD_HELP_FALLBACK, and save wiring in handleSave. Applying recommendations for weighted now opens advanced settings (consistent with round-robin). Tests: schema accept/reject, sticky batch sequencing (controlled Math.random), sticky migration on fallback success, stale sticky clearing when the preselected step is unavailable, nested combo-ref availability when one leaf is down. Co-authored-by: Cursor <cursoragent@cursor.com>
Mirror the weighted sticky availability pre-filter in handleRoundRobinCombo: before computing the start index, check whether the currently sticky round-robin target is still available (circuit breaker, provider cooldown, model lockout, isModelAvailable). If not, clear the stale sticky record so the rotation starts at the counter position instead of probing a dead target. Round-robin already migrated sticky on fallback success (Option B), so this only saves the one wasted probe on the first request after exhaustion. Added for consistency with the weighted sticky behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
…, stale cleanup Fixes four issues from gemini-code-assist review on cheaper-inference#4489: 1. Guard falsy target.provider before getCircuitBreaker call in both the weighted availability pre-filter and the RR sticky pre-filter to prevent a TypeError on unresolved steps. 2. Fix prefix-matching bug in getWeightedStepKeyForTarget: use exact match or startsWith with ">" separator so step-1 no longer matches step-10's expanded targets. 3. Eliminate redundant resolveWeightedStepGroups call: hoist stepGroups outside the if block and pass it to resolveWeightedTargets via a new optional parameter, avoiding a second recursive DAG expansion. 4. Clear stale weightedStickyTargets entries when the strategy is not weighted or stickyWeightedLimit is disabled (<=1), preventing unbounded memory growth from orphaned sticky records. Co-authored-by: Cursor <cursoragent@cursor.com>
…utor
Introduces the scaffolding for nested combo black-box execution:
- New config key nestedComboMode ("flatten" / "execute") defaulting to
"flatten" for backward compatibility.
- NestedComboMode and ComboNestingContext types (depth, visited, budget).
- HandleComboChatOptions.nesting optional field for recursive ctx.
- SingleModelTarget.effectiveComboStrategy for cache-control propagation.
- New runtimeUnits.ts module: helpers for model/combo-ref unit execution,
cycle/depth enforcement, shared attempt budget, and metrics recording.
Co-authored-by: Cursor <cursoragent@cursor.com>
…propagation Add the named ResolvedComboUnit/ResolvedComboRefTarget exports and retype the round-robin sticky helpers to operate on runtime units so combo-ref targets can flow through selection state. Add the nestedComboMode schema field and propagate the effective child strategy into chatCore so an inner deterministic combo preserves client cache_control even under an outer round-robin. Co-authored-by: Cursor <cursoragent@cursor.com>
Add a per-combo "Nested Combo Behavior" select (flatten vs execute) to the combos advanced config, with help text. Add config tests for the nestedComboMode default, schema validation, and cascade, plus strategy tests covering black-box priority execution, parent fallback after child failure, 3-level nesting, cycle detection, and unchanged flatten-mode behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
…mode - combo.ts 2611→2738 (execute dispatch block, effectiveComboStrategy threading) - page.tsx 4385→4414 (nestedComboMode UI control) - chat.ts 1491→1493 (effectiveComboStrategy in handleSingleModel closures) - tests/unit/combo-strategy-fallbacks.test.ts added at 877 (5 new tests) Pre-existing sticky-weighted base drift bumped together: usage.ts 3408→3414, core.ts 1820→1825, providers.ts 3242→3243, providerLimits.ts 949→950 Co-authored-by: Cursor <cursoragent@cursor.com>
|
Update: #4489 (sticky-weighted) is now merged into Could you rebase onto the current |
…erence#4537) Rebases the nestedComboMode feature onto release now that cheaper-inference#4489 (sticky-weighted) is merged. Conflict resolution: - combo.ts / comboStructure.ts / combo-strategy-fallbacks.test.ts: kept release's reconciled sticky-weighted + provider-wildcard (cheaper-inference#4545) versions (the branch carried the pre-cheaper-inference#4489 sticky-weighted code + the old Math.random test mocks); the nestedComboMode dispatch (resolveComboRuntimeUnits / normalizeNestedComboMode / execute-mode branch with depth/cycle/budget caps) is preserved and layered on top. - config.stickyWeightedLimit read via the (config as Record<string, unknown>) cast at the two nested-execute sites (mirrors stickyRoundRobinLimit), since the combo config type tightened on the release base. - page.tsx: kept the new Nested Combo Behavior selector. - baselines reconciled: combo.ts 2818->2955, combos/page.tsx 4406->4434, chat.ts 1513->1515, combo-strategy-fallbacks.test.ts frozen at 880, complexity 1913->1915 (Hard Rule cheaper-inference#9). 59/59 combo tests pass on the merged tip; typecheck:core clean. Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
|
Thanks @adivekar-utexas! Now that #4489 (sticky-weighted) is merged, I rebased this onto |
09d8a4a
into
cheaper-inference:release/v3.8.33
…e drift) Pre-existing drift on origin/release/v3.8.33 surfaced by the release full CI (cognitive-complexity doesn't run on PR->release fast-gates). My release-finalize prod changes add 0 new violations to the count (verified: geminiHelper merge is intra-function; auth.ts only gained args). +4 from this cycle's combo logic (#4537/#4489/#4581). Structural shrink tracked in #3501.
…ion for selection strategies (cheaper-inference#4537) Integrated into release/v3.8.33
…e drift) Pre-existing drift on origin/release/v3.8.33 surfaced by the release full CI (cognitive-complexity doesn't run on PR->release fast-gates). My release-finalize prod changes add 0 new violations to the count (verified: geminiHelper merge is intra-function; auth.ts only gained args). +4 from this cycle's combo logic (cheaper-inference#4537/cheaper-inference#4489/cheaper-inference#4581). Structural shrink tracked in cheaper-inference#3501.
PR: Nested Combo Execution (
nestedComboMode) -- Stage 1Summary
Add
nestedComboMode: "flatten" | "execute"(default"flatten") as a per-combo config toggle. In"execute"mode, combo-ref members stay as opaque black-box runtime targets: the parent strategy selects the child combo as one unit, and the child runs its own strategy, retries, sticky, and validation via a recursivehandleComboChatcall. This fixes the flattening problem where nested combo boundaries were lost and inner strategy/retry/sticky behavior never executed.Fixes: Cache locality loss and cache-control marker stripping in round-robin-over-priority topologies (see the detailed design doc at
docs/routing/NESTED-COMBO-EXECUTION.md).Changes
Core Runtime
comboConfig.ts:nestedComboMode: "flatten"inDEFAULT_COMBO_CONFIG.types.ts:NestedComboMode,ComboNestingContext,ResolvedComboUnit,ResolvedComboRefTarget,ComboRuntimeStepalias,effectiveComboStrategyonSingleModelTarget,nestingonHandleComboChatOptions.comboStructure.ts:resolveComboRuntimeUnits-- mode-aware resolver that delegates to legacy flattening in flatten mode and returns top-level runtime steps (including combo-ref units) in execute mode.validateComboDAGreused for static cycle detection.runtimeUnits.ts:executeRuntimeUnitCombo(per-unit loop with attempt-budget enforcement, retries, metrics),executeRuntimeUnit(dispatch by kind),executeModelUnit,executeComboRefUnit(recursivehandleComboChatcall with depth/cycle guard),buildChildNestingContext.combo.ts(dispatch block ~551-671): Nesting context construction,normalizeNestedComboMode,resolveComboRuntimeUnits,simpleExecuteStrategiesset, strategy-specific unit ordering (sticky rotation, weighted sticky, fisher-yates shuffle, deck draw),executeRuntimeUnitCombocall, post-success sticky recording.effectiveComboStrategythreaded at non-RR leaf call (~1495) and round-robin handler (~2421).rrState.ts:getStickyRoundRobinStartIndexandrecordStickyRoundRobinSuccessretyped fromResolvedComboTargettoResolvedComboUnitso sticky works over combo-ref units.Schema & Integration
schema/combo.ts:nestedComboMode: z.enum(["flatten", "execute"]).optional()incomboRuntimeConfigSchema.chat.ts: BothhandleSingleModelclosures (main combo path ~600-645, auto-combo redirect ~796-829) readtarget?.effectiveComboStrategy ?? combo.strategyand pass it ascomboStrategytohandleSingleModelChat.page.tsx: UI select bound toconfig.nestedComboMode(~3867) with help text (~172).sanitizeComboRuntimeConfigpasses through non-null keys, so no save-path change is needed.Tests
combo-config.test.ts: 3 new tests (default, schema accept/reject, cascade).combo-strategy-fallbacks.test.ts: 5 new tests (black-box priority, parent fallback, 3-level nesting, cycle detection, flatten unchanged default).Test Results
feat/combo-sticky-weighted-cleancommit (fail identically on the base commit and are unrelated to this work).Backward Compatibility
nestedComboModedefaults to"flatten"inDEFAULT_COMBO_CONFIG."flatten"and follow the legacy path unchanged.nestedComboMode === "execute", the strategy is insimpleExecuteStrategies, AND the unit list contains at least one combo-ref.effectiveComboStrategyis optional and falls back tocombo.strategy.Notes
feat/combo-sticky-weighted-clean(requires weighted-sticky helpers from that PR).docs/routing/NESTED-COMBO-EXECUTION.md.Closes #4536
Made with Cursor