@nexus-cortex/core 4.124.14 → 4.124.17
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.
- package/.env.defaults +22 -0
- package/dist/middleware/HelperModelMiddleware.d.ts +10 -0
- package/dist/middleware/HelperModelMiddleware.d.ts.map +1 -1
- package/dist/middleware/HelperModelMiddleware.js +23 -6
- package/dist/middleware/HelperModelMiddleware.js.map +1 -1
- package/dist/orchestrator/CortexOrchestrator.d.ts +8 -0
- package/dist/orchestrator/CortexOrchestrator.d.ts.map +1 -1
- package/dist/orchestrator/CortexOrchestrator.js +38 -7
- package/dist/orchestrator/CortexOrchestrator.js.map +1 -1
- package/dist/training/DecisionStore.d.ts +1 -1
- package/dist/training/DecisionStore.d.ts.map +1 -1
- package/dist/training/requirementLedger.d.ts +9 -2
- package/dist/training/requirementLedger.d.ts.map +1 -1
- package/dist/training/requirementLedger.js +28 -9
- package/dist/training/requirementLedger.js.map +1 -1
- package/dist/training/usageAccounting.d.ts +46 -0
- package/dist/training/usageAccounting.d.ts.map +1 -0
- package/dist/training/usageAccounting.js +37 -0
- package/dist/training/usageAccounting.js.map +1 -0
- package/package.json +3 -3
|
@@ -23,7 +23,8 @@ import { resolveEndTurnResolverConfig, parseResolverVerdict, effectiveMaxRejects
|
|
|
23
23
|
import { jevAvailable, jevNoul, buildGapHoldState, GAP_HOLD_QUESTIONS } from '../training/jevGate.js'; // R173b
|
|
24
24
|
import { resolveFrameConfig, FRAME_CONTRACT, FRAME_TOOL_NAME } from '../frames/frameConfig.js'; // R179
|
|
25
25
|
import { FrameRunner } from '../frames/frameRunner.js'; // R179
|
|
26
|
-
import {
|
|
26
|
+
import { emptySessionUsage, addMainUsage } from '../training/usageAccounting.js'; // R190
|
|
27
|
+
import { parseRequirementLedger, initLedger, updateLedger, ledgerCounts, ledgerHoldable, formatLedgerForWriter, formatLedgerForJudge, formatLedgerHoldMessage, buildLedgerJevState, buildLedgerJevQuestions, applyLedgerJevAnswers, looksLikeBrokenCheck } from '../training/requirementLedger.js'; // R187 / R191
|
|
27
28
|
import { isValueShapedTask, parseDerivationReply, methodsDiffer, parseValueLines, extractNumbers, reconcile, buildDerivationHoldMessage, isDerivationCommandAllowed, checkRunPassed, checkRunBody } from '../training/independentDerivation.js'; // R176
|
|
28
29
|
import { resolveDeadlineExitConfig, deadlineExitCallBudget, parseDeadlineExitVerdict } from '../training/deadlineExitMentor.js';
|
|
29
30
|
import { isTaskShaped } from './requirementsVerification.js';
|
|
@@ -252,8 +253,11 @@ export class CortexOrchestrator {
|
|
|
252
253
|
specChecksPromise = null; // R174b: authored at lift in the background (CORTEX_JUDGE_SPEC_TESTS_AT=lift)
|
|
253
254
|
reqLedger = null; // R187: the stated-requirement ledger for this turn (null = not yet authored)
|
|
254
255
|
reqLedgerPromise = null; // R187: authored at lift in the background
|
|
256
|
+
sessionUsage = emptySessionUsage(); // R190: every main-model request this session (exact) + helper calls (estimated)
|
|
255
257
|
reqLedgerHolds = 0; // R187: ledger holds used this turn
|
|
258
|
+
reqLedgerRetried = false; // R187c: one re-author at the first finish after an empty lift-time result
|
|
256
259
|
reqLedgerMeta = { genLatencyMs: 0, raw: 0, refused: 0 }; // R187
|
|
260
|
+
reqLedgerBroken = new Set(); // R191: ids whose check was dropped as malformed
|
|
257
261
|
specFailHistory = new Map(); // R174b: consecutive identical spec failures
|
|
258
262
|
lastHoldMs = 0; // R173c: wall clock of the last hold/veto this turn
|
|
259
263
|
derivationHolds = 0; // R176: independent-derivation holds this turn (max 1)
|
|
@@ -603,6 +607,15 @@ export class CortexOrchestrator {
|
|
|
603
607
|
}
|
|
604
608
|
catch { /* fail-open */ }
|
|
605
609
|
}
|
|
610
|
+
/** R190: the session usage with the helper middleware's estimated calls merged in, plus a decision-store row so trajectories carry it. */
|
|
611
|
+
snapshotSessionUsage() {
|
|
612
|
+
const h = this.helperMiddleware?.getHelperUsageEstimate?.();
|
|
613
|
+
const snap = { ...this.sessionUsage, helper: h ? { ...h } : { ...this.sessionUsage.helper } };
|
|
614
|
+
const store = this.getDecisionStore();
|
|
615
|
+
if (store)
|
|
616
|
+
void store.recordEvent({ sessionId: this.currentSessionId ?? 'unknown', kind: 'session_usage', detail: { ...snap } }).catch(() => { });
|
|
617
|
+
return snap;
|
|
618
|
+
}
|
|
606
619
|
/** Bounded read-only environment recon (ENV_RECON_COMMAND), gathered ONCE and cached — shared by the
|
|
607
620
|
* lift planner and the EndTurn resolver. Fail-open: partial stdout on timeout/non-zero, else empty. */
|
|
608
621
|
gatherEnvReport(opts = {}) {
|
|
@@ -801,7 +814,9 @@ export class CortexOrchestrator {
|
|
|
801
814
|
this.reqLedger = [];
|
|
802
815
|
return [];
|
|
803
816
|
}
|
|
804
|
-
|
|
817
|
+
// R187c: the extractor runs in the background at lift beside the planner (which itself takes 80–190 s on pro), so it gets the planner's
|
|
818
|
+
// timeout, not the judge's 90 s — the 09-23 L7 smoke lost the whole ledger to a 98-s pro call (deliveredBy none).
|
|
819
|
+
const tmo = mentorSurfaceTimeoutMs('lift-plan', parseInt(process.env.CORTEX_JUDGE_REQ_LEDGER_TIMEOUT_MS ?? process.env.CORTEX_LIFT_PLAN_TIMEOUT_MS ?? '180000', 10));
|
|
805
820
|
try {
|
|
806
821
|
const raw = await withTimeout(this.helperMiddleware.deriveRequirementLedger({ task, envReport: this.gatherEnvReport({ fresh: false }), max: cfg.reqLedgerMax, helperModelId: this.config.reactiveMentorship?.helperModelId }), tmo);
|
|
807
822
|
const lines = parseRequirementLedger(raw ?? '', cfg.reqLedgerMax);
|
|
@@ -949,7 +964,17 @@ export class CortexOrchestrator {
|
|
|
949
964
|
if (cfg.reqLedger) {
|
|
950
965
|
if (this.reqLedger === null)
|
|
951
966
|
this.reqLedger = await (this.reqLedgerPromise ?? this.authorRequirementLedger(task));
|
|
952
|
-
|
|
967
|
+
// R187c: an empty ledger from a timed-out lift-time call is retried ONCE here (the judge would otherwise run with no lines all session)
|
|
968
|
+
if (this.reqLedger.length === 0 && !this.reqLedgerRetried) {
|
|
969
|
+
this.reqLedgerRetried = true;
|
|
970
|
+
this.reqLedger = await this.authorRequirementLedger(task);
|
|
971
|
+
}
|
|
972
|
+
// R191: a check whose failure is its own defect (usage error, missing script, syntax error) is BROKEN, not FAILED — L7 09-23: photonic's
|
|
973
|
+
// extractor guessed a checker's CLI, two lines failed at every finish on a passing solution, and the writer spent turns on the "harness quirk".
|
|
974
|
+
const runs = this.reqLedger.filter((e) => e.check).map((e) => { const r = runCheck(judgeCwd, e.check, jcfg); const k = classifyCheckRun(r); const cls = k !== 'passed' && looksLikeBrokenCheck(r) ? 'broken' : k; return { id: e.id, result: r, cls }; });
|
|
975
|
+
for (const x of runs)
|
|
976
|
+
if (x.cls === 'broken')
|
|
977
|
+
this.reqLedgerBroken.add(x.id);
|
|
953
978
|
this.reqLedger = updateLedger(this.reqLedger, runs);
|
|
954
979
|
// R187b: Jev decides the lines the shell could not — typed per-line questions on the writer's attestation + harness evidence.
|
|
955
980
|
if (cfg.reqLedgerJev && jevAvailable() && this.reqLedger.some((e) => e.status === 'open' || e.status === 'unverifiable')) {
|
|
@@ -1202,6 +1227,7 @@ export class CortexOrchestrator {
|
|
|
1202
1227
|
vetoMinRemaining: cfg.vetoMinRemaining, belowFloor, holdProgressed: holdProg, holdGapMs: msSinceLastHold, planSim: Number(planSimilarity(this.judgePriorPlan, verdict.plan).toFixed(3)), msSinceLastHold, // R173c
|
|
1203
1228
|
derivation: cfg.derivation, derivationAgreement: derivationInfo?.agreement ?? null, derivationHeld: !!derivationHold, // R176
|
|
1204
1229
|
reqLedger: cfg.reqLedger, reqLines: reqCounts.lines, reqOpen: reqCounts.open, reqExercised: reqCounts.exercised, reqFailed: reqCounts.failed, reqUnverifiable: reqCounts.unverifiable, reqHeld: !!reqHold, reqHolds: this.reqLedgerHolds, reqGenLatencyMs: this.reqLedgerMeta.genLatencyMs, reqJev: cfg.reqLedgerJev, reqJevAsked: reqJev?.asked ?? 0, reqJevClosed: reqJev?.closed ?? [], reqJevLatencyMs: reqJev?.latencyMs ?? 0, // R187/R187b
|
|
1230
|
+
reqBroken: [...this.reqLedgerBroken], reqLinesDetail: (this.reqLedger ?? []).map((e) => ({ id: e.id, kind: e.kind, status: e.status, check: !!e.check, runs: e.runs, last: (e.lastResult ?? '').split('\n').slice(0, 2).join(' / ').slice(0, 200) })), // R191: per-line outcomes so a false-failure read is possible from the decisions file
|
|
1205
1231
|
latencyMs, rawLen: (text ?? '').length,
|
|
1206
1232
|
deltaChars: workspaceDelta.length, checkRan: !!checkResult, checkPassed: checkResult ? /→ PASSED/.test(checkResult) : null,
|
|
1207
1233
|
liftPlanChars: this.liftPlanText.length,
|
|
@@ -2255,6 +2281,7 @@ export class CortexOrchestrator {
|
|
|
2255
2281
|
this.reqLedgerHolds = 0;
|
|
2256
2282
|
this.reqLedgerMeta = { genLatencyMs: 0, raw: 0, refused: 0 };
|
|
2257
2283
|
this.reqLedgerDelivered = false;
|
|
2284
|
+
this.reqLedgerRetried = false;
|
|
2258
2285
|
this.lastHoldMs = 0;
|
|
2259
2286
|
this.derivationHolds = 0; // R165 per-turn / R174 / R173c / R176
|
|
2260
2287
|
this.recordDsmlRecovery(currentAssistantCanonicalMessage);
|
|
@@ -3949,10 +3976,10 @@ export class CortexOrchestrator {
|
|
|
3949
3976
|
messageId: currentAssistantMessage.uuid,
|
|
3950
3977
|
content: currentAssistantCanonicalMessage.content,
|
|
3951
3978
|
toolUses: allExecutedToolUses,
|
|
3952
|
-
usage:
|
|
3953
|
-
inputTokens: 0,
|
|
3954
|
-
|
|
3955
|
-
|
|
3979
|
+
usage: {
|
|
3980
|
+
...(convertedResponse.usage || { inputTokens: 0, outputTokens: 0, totalTokens: 0 }),
|
|
3981
|
+
// R190: the whole session's tokens — every main request (exact) + helper/mentor calls (estimated) — not the last request's
|
|
3982
|
+
session: this.snapshotSessionUsage(),
|
|
3956
3983
|
},
|
|
3957
3984
|
model: {
|
|
3958
3985
|
id: model.id,
|
|
@@ -3960,6 +3987,7 @@ export class CortexOrchestrator {
|
|
|
3960
3987
|
},
|
|
3961
3988
|
metadata: {
|
|
3962
3989
|
conversationId: this.currentConversationId,
|
|
3990
|
+
sessionUsage: this.snapshotSessionUsage(), // R190
|
|
3963
3991
|
usedHelperModel,
|
|
3964
3992
|
compactionTriggered: usedHelperModel,
|
|
3965
3993
|
serverSideTools: serverSideMetadata || undefined,
|
|
@@ -4475,6 +4503,7 @@ export class CortexOrchestrator {
|
|
|
4475
4503
|
this.reqLedgerHolds = 0;
|
|
4476
4504
|
this.reqLedgerMeta = { genLatencyMs: 0, raw: 0, refused: 0 };
|
|
4477
4505
|
this.reqLedgerDelivered = false;
|
|
4506
|
+
this.reqLedgerRetried = false;
|
|
4478
4507
|
this.lastHoldMs = 0;
|
|
4479
4508
|
this.derivationHolds = 0; // R165 per-turn / R174 / R173c / R176
|
|
4480
4509
|
this.recordDsmlRecovery(currentAssistantCanonicalMessage);
|
|
@@ -5795,6 +5824,7 @@ export class CortexOrchestrator {
|
|
|
5795
5824
|
usage: {
|
|
5796
5825
|
inputTokens: finalUsage.inputTokens || 0,
|
|
5797
5826
|
outputTokens: finalUsage.outputTokens || 0,
|
|
5827
|
+
session: this.snapshotSessionUsage(), // R190
|
|
5798
5828
|
},
|
|
5799
5829
|
durationMs: Date.now() - turnStartMs,
|
|
5800
5830
|
toolCallIterations: toolCallIteration,
|
|
@@ -6637,6 +6667,7 @@ export class CortexOrchestrator {
|
|
|
6637
6667
|
* absorbed by the delta logic in anchoredRequestEstimate.
|
|
6638
6668
|
*/
|
|
6639
6669
|
noteRequestUsage(usage) {
|
|
6670
|
+
this.sessionUsage = addMainUsage(this.sessionUsage, usage); // R190: cumulative first — the anchor logic below skips zero usage
|
|
6640
6671
|
const promptTokens = Number(usage?.inputTokens ?? 0);
|
|
6641
6672
|
if (!(promptTokens > 0))
|
|
6642
6673
|
return;
|