@nexus-cortex/core 4.124.59 → 4.124.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -95,6 +95,7 @@ import { resolveEffortRamp, rampEffortFor } from './effortRamp.js';
95
95
  import { firstRequestActionEffort } from './transportEffortFixes.js'; // CORTEX_ACTION_EFFORT_FIRST (dark)
96
96
  import { resolveWallCacheFix, resolvePersistInjected, resolveAppendOnlyTools, resolveKeepMentorMessages, resolveResponsesSliceAll, chainedSliceStart, tailUnitAfterLastAssistant, isPreviousResponseUnavailable } from './appendOnlyHistory.js'; // R221-R228 append-only history (dark)
97
97
  import { resolveWallDrop, resolveOutputCap, dropWalledTurn, resolveWallSummary, extractWalledReasoning, clipReasoning, formatWallSummary } from './wallGuard.js';
98
+ import { resolveWallRetryLadder, ladderCapFor, shouldForceAction } from './wallRetryLadder.js'; // HB-WALL-RETRY-LADDER (dark)
98
99
  import { resolvePid1Guard, detectPid1Note } from './pid1Guard.js'; // R209
99
100
  import { PlateauStopTracker, plateauBootInstruction, plateauStatusSegment } from './plateauStop.js'; // R210
100
101
  import { resolveTaskRules, taskRulesPlanBlock, taskRulesJudgeClause } from '../training/taskRules.js'; // R211–R214
@@ -2580,6 +2581,7 @@ export class CortexOrchestrator {
2580
2581
  const BUDGET_CONTINUE_MAX_NUDGES = resolveBudgetContinueMaxNudges();
2581
2582
  this.reasoningBackoffRemaining = 0;
2582
2583
  this.reasoningBackoffLastLevel = undefined; // R153: backoff is per turn
2584
+ this.wallsThisTurn = 0; // HB-WALL-RETRY-LADDER: wall index is per turn
2583
2585
  const END_TURN_MAX_NUDGES = 2;
2584
2586
  // EndTurn gate / Stages 1-3 are OPT-IN (default OFF). The line-number
2585
2587
  // fabrication they targeted is fully resolved at the root cause:
@@ -2705,6 +2707,18 @@ export class CortexOrchestrator {
2705
2707
  }
2706
2708
  console.warn(`[Orchestrator] Empty response detected (${emptyClass.kind}, hadReasoning=${emptyClass.hadReasoning}, iteration=${toolCallIteration}). ` +
2707
2709
  `Retrying once with explicit completion prompt.`);
2710
+ // HB-WALL-RETRY-LADDER (CORTEX_WALL_RETRY_LADDER, dark): the n-th exhaustion wall of the turn bounds the RETRY's max_tokens and,
2711
+ // from CORTEX_WALL_FORCE_ACTION_AT on, forces an action (tool_choice required → thinking off on DeepSeek). Off = untouched.
2712
+ const ladderCfg = resolveWallRetryLadder();
2713
+ if (ladderCfg.enabled && isReasoningExhaustion(emptyClass))
2714
+ this.wallsThisTurn += 1;
2715
+ const ladderCap = ladderCfg.enabled && isReasoningExhaustion(emptyClass) ? ladderCapFor(ladderCfg, this.wallsThisTurn, options.parameters?.maxTokens) : options.parameters?.maxTokens;
2716
+ const ladderForce = shouldForceAction(ladderCfg, this.wallsThisTurn, emptyClass);
2717
+ if (ladderCfg.enabled && isReasoningExhaustion(emptyClass)) {
2718
+ const st = this.decisionStore;
2719
+ if (st)
2720
+ void st.recordEvent({ sessionId: this.currentSessionId ?? 'unknown', kind: 'wall_retry_ladder', detail: { wallIndex: this.wallsThisTurn, cap: ladderCap ?? null, forceAction: ladderForce, iteration: toolCallIteration } }).catch(() => { });
2721
+ }
2708
2722
  const exhaustionLevel = this.armReasoningBackoffIfExhausted(emptyClass, options.parameters?.reasoningEffort ?? effectiveModel?.reasoning?.effort, toolCallIteration, currentAssistantMessage?.usage?.outputTokens, effectiveModel.provider);
2709
2723
  // HB-WALL-DROP (CORTEX_WALL_DROP, dark): drop the walled turn + carry the nudge on the newest tool_result (cache-preserving retry).
2710
2724
  const wallSummary = await this.summarizeWall(emptyClass, toolCallIteration, false); // HB-WALL-SUMMARY (dark); '' when off/failed
@@ -2776,12 +2790,13 @@ export class CortexOrchestrator {
2776
2790
  const retryCanonicalHistory = this.convertToCanonicalMessages(this.chainedHistoryForApi(effectiveModel)); // R228 (CORTEX_RESPONSES_SLICE_ALL; off = full history)
2777
2791
  const req = this.gatewayTranslation.prepareRequest(retryCanonicalHistory, toolsToUse, effectiveModel, {
2778
2792
  temperature: options.parameters?.temperature,
2779
- maxTokens: options.parameters?.maxTokens,
2793
+ maxTokens: ladderCap, // HB-WALL-RETRY-LADDER (off = options.parameters?.maxTokens)
2780
2794
  topP: options.parameters?.topP,
2781
2795
  reasoningEffort: retryEffort,
2782
2796
  stream: options.streaming,
2783
2797
  staticSystemPrompt: this.currentStaticSystemPrompt, // R28
2784
2798
  conversationId: this.currentConversationId, // R28b
2799
+ ...(ladderForce ? { toolChoice: { type: 'required' } } : {}), // HB-WALL-RETRY-LADDER: forced action (thinking off on DeepSeek)
2785
2800
  });
2786
2801
  if (this.lastResponseId && effectiveModel.api.pattern === 'responses') {
2787
2802
  req.previousResponseId = this.lastResponseId;
@@ -2799,6 +2814,12 @@ export class CortexOrchestrator {
2799
2814
  this.lastResponseId = retryApiResponse.data.id;
2800
2815
  this.lastResponseIdProvider = effectiveModel.provider; // R20a
2801
2816
  }
2817
+ // R240 (2026-10-06): the empty-response retry was never added to the session ledger — the bench's usage.session under-reported
2818
+ // exactly the retries that walls add. Same accounting as the initial request (CO ~2713-2715).
2819
+ if (retryConverted.usage) {
2820
+ this.cacheMetricsAccumulator.addUsage(retryConverted.usage, effectiveModel.provider);
2821
+ this.noteRequestUsage(retryConverted.usage);
2822
+ }
2802
2823
  if (retryConverted.messages && retryConverted.messages.length > 0) {
2803
2824
  const retryAssistantCanonical = retryConverted.messages[0];
2804
2825
  const retryAssistantMessage = {
@@ -9348,6 +9369,7 @@ export class CortexOrchestrator {
9348
9369
  /** R153 HB-REASONING-EXHAUSTION: continuations left at a LOWERED reasoning effort after a truncated
9349
9370
  * reasoning-only turn (output cap hit, nothing delivered). Takes precedence over the effort pulse. */
9350
9371
  reasoningBackoffRemaining = 0;
9372
+ wallsThisTurn = 0; // HB-WALL-RETRY-LADDER (dark): reasoning-exhaustion walls seen in the current turn
9351
9373
  reasoningBackoffLevel;
9352
9374
  /** R153b (4.111.1, tb4-p foodstuff): the level the LAST exhaustion in this turn stepped to — a repeat exhaustion steps down
9353
9375
  * from here even after the counter expired (the empty-retry call consumed one of the lowered turns, so iteration 10 went