@nexus-cortex/core 4.93.0 → 4.94.0

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.
Files changed (44) hide show
  1. package/{.env.example → .env.defaults} +93 -25
  2. package/dist/config/MentorshipConfigService.d.ts +0 -1
  3. package/dist/config/MentorshipConfigService.d.ts.map +1 -1
  4. package/dist/config/MentorshipConfigService.js +10 -5
  5. package/dist/config/MentorshipConfigService.js.map +1 -1
  6. package/dist/config/SettingsLoader.d.ts +92 -11
  7. package/dist/config/SettingsLoader.d.ts.map +1 -1
  8. package/dist/config/SettingsLoader.js +331 -131
  9. package/dist/config/SettingsLoader.js.map +1 -1
  10. package/dist/config/effectiveConfig.d.ts +1 -1
  11. package/dist/config/effectiveConfig.d.ts.map +1 -1
  12. package/dist/config/effectiveConfig.js +6 -1
  13. package/dist/config/effectiveConfig.js.map +1 -1
  14. package/dist/middleware/HelperModelMiddleware.d.ts +16 -0
  15. package/dist/middleware/HelperModelMiddleware.d.ts.map +1 -1
  16. package/dist/middleware/HelperModelMiddleware.js +32 -5
  17. package/dist/middleware/HelperModelMiddleware.js.map +1 -1
  18. package/dist/models/cards/deepseek/deepseek-v4-flash.d.ts.map +1 -1
  19. package/dist/models/cards/deepseek/deepseek-v4-flash.js +4 -2
  20. package/dist/models/cards/deepseek/deepseek-v4-flash.js.map +1 -1
  21. package/dist/orchestrator/CortexOrchestrator.d.ts +14 -0
  22. package/dist/orchestrator/CortexOrchestrator.d.ts.map +1 -1
  23. package/dist/orchestrator/CortexOrchestrator.js +131 -6
  24. package/dist/orchestrator/CortexOrchestrator.js.map +1 -1
  25. package/dist/orchestrator/OrchestratorFactory.js +1 -1
  26. package/dist/orchestrator/OrchestratorFactory.js.map +1 -1
  27. package/dist/orchestrator/displayHistorySanitizer.d.ts +29 -0
  28. package/dist/orchestrator/displayHistorySanitizer.d.ts.map +1 -0
  29. package/dist/orchestrator/displayHistorySanitizer.js +62 -0
  30. package/dist/orchestrator/displayHistorySanitizer.js.map +1 -0
  31. package/dist/tools/context-management/InitCortexContext.js +1 -1
  32. package/dist/tools/context-management/InitCortexContext.js.map +1 -1
  33. package/dist/training/DecisionStore.d.ts +1 -1
  34. package/dist/training/DecisionStore.d.ts.map +1 -1
  35. package/dist/training/DecisionStore.js.map +1 -1
  36. package/dist/training/deadlineExitMentor.d.ts +67 -0
  37. package/dist/training/deadlineExitMentor.d.ts.map +1 -0
  38. package/dist/training/deadlineExitMentor.js +99 -0
  39. package/dist/training/deadlineExitMentor.js.map +1 -0
  40. package/dist/training/endTurnResolver.d.ts +14 -3
  41. package/dist/training/endTurnResolver.d.ts.map +1 -1
  42. package/dist/training/endTurnResolver.js +27 -10
  43. package/dist/training/endTurnResolver.js.map +1 -1
  44. package/package.json +5 -5
@@ -0,0 +1,99 @@
1
+ /**
2
+ * deadlineExitMentor — the mentor-as-deadline-checkpoint (operator design 2026-09-05, the
3
+ * "smart deadline"). The THIRD mentor invocation (distinct from liftPlanner and
4
+ * endTurnResolver). At the WARN rung (~0.81 of the task budget, where residual still exists),
5
+ * instead of a dumb "wrap up" nudge to the junior, a bounded mentor looks at the work product
6
+ * and the remaining budget and decides ONE thing:
7
+ *
8
+ * CONTINUE — on-track / closing in (like schemelike, which solves in the last fifth) → let it
9
+ * run to the hard-floor break; do NOT truncate a win.
10
+ * FINISH — the work ALREADY meets the task's real criteria → end now with an attestation,
11
+ * bypassing the EndTurn resolver (no double pro@max pay).
12
+ * ACTION — a small, specific gap remains and the ONE minimal action to close it fits the
13
+ * residual → inject that action, then finish.
14
+ * RETIRE — stuck / structurally unclosable in the residual (like filter-js grinding) → end
15
+ * CLEANLY now, do not burn the residual on a lost cause.
16
+ *
17
+ * 🔴 WHY smart, not a slid number (resolver-k5): 24% of PASSING rows finish at ≥0.80 of budget —
18
+ * a flat earlier deadline would truncate a quarter of wins. The mentor's job is to tell
19
+ * "closing in" from "grinding". Value is GATED on that judgment (an early checkpoint that
20
+ * mis-calls a closing-in task HURTS), so this ships DARK and is A/B-validated. Pure + testable;
21
+ * the hard-floor break rung stays as the unconditional failsafe underneath.
22
+ */
23
+ const DEFAULTS = {
24
+ enabled: false,
25
+ effort: 'max',
26
+ outputBudgetTokensCap: 2000,
27
+ timeoutMsCap: 45000,
28
+ residualFrac: 0.4,
29
+ };
30
+ export function resolveDeadlineExitConfig(env = process.env) {
31
+ const e = (env.CORTEX_DEADLINE_EXIT_MENTOR_EFFORT ?? '').trim();
32
+ const b = parseInt((env.CORTEX_DEADLINE_EXIT_MENTOR_BUDGET_TOKENS ?? '').trim(), 10);
33
+ const t = parseInt((env.CORTEX_DEADLINE_EXIT_MENTOR_TIMEOUT_MS ?? '').trim(), 10);
34
+ const f = parseFloat((env.CORTEX_DEADLINE_EXIT_MENTOR_RESIDUAL_FRAC ?? '').trim());
35
+ return {
36
+ enabled: (env.CORTEX_DEADLINE_EXIT_MENTOR ?? '').trim().toLowerCase() === 'true',
37
+ effort: e || DEFAULTS.effort,
38
+ outputBudgetTokensCap: Number.isInteger(b) && b > 0 ? b : DEFAULTS.outputBudgetTokensCap,
39
+ timeoutMsCap: Number.isInteger(t) && t > 0 ? t : DEFAULTS.timeoutMsCap,
40
+ residualFrac: Number.isFinite(f) && f > 0 && f < 1 ? f : DEFAULTS.residualFrac,
41
+ };
42
+ }
43
+ /** Residual-scaled budget/timeout for ONE checkpoint call, never exceeding the caps and never
44
+ * eating more than residualFrac of the remaining wall-clock. */
45
+ export function deadlineExitCallBudget(cfg, remainingMs) {
46
+ const scaledTimeout = Math.max(0, Math.floor(remainingMs * cfg.residualFrac));
47
+ const timeoutMs = Math.max(1, Math.min(cfg.timeoutMsCap, scaledTimeout || cfg.timeoutMsCap));
48
+ // Keep the output budget proportional to the (bounded) time we allow — ~40 tok/s of headroom,
49
+ // capped. A checkpoint verdict + one action line is short by design.
50
+ const byTime = Math.floor((timeoutMs / 1000) * 40);
51
+ const outputBudgetTokens = Math.max(256, Math.min(cfg.outputBudgetTokensCap, byTime || cfg.outputBudgetTokensCap));
52
+ return { timeoutMs, outputBudgetTokens };
53
+ }
54
+ export const DEADLINE_EXIT_SYSTEM = 'You are a senior engineer running a CHECKPOINT on a junior agent that is deep into a task in a ' +
55
+ 'real terminal container and is running low on time. You are given the TASK, an ENVIRONMENT REPORT, ' +
56
+ 'the WORK SO FAR, and the REMAINING BUDGET. Decide, in ONE verdict, what to do with the time left — ' +
57
+ 'the goal is to convert the residual into a PASS, or to stop wasting it on a lost cause.\n' +
58
+ 'FORMAT — your FIRST line MUST be exactly one of:\n' +
59
+ ' VERDICT: CONTINUE (on-track / closing in — let it keep working to the hard deadline; do NOT cut a near-win)\n' +
60
+ ' VERDICT: FINISH (the work ALREADY meets the task\'s real criteria — end now)\n' +
61
+ ' VERDICT: ACTION (a small specific gap remains and ONE action closes it within the residual)\n' +
62
+ ' VERDICT: RETIRE (stuck / structurally unclosable in the residual — end cleanly, stop grinding)\n' +
63
+ 'Judge against the TASK\'s real criteria (what the hidden grader checks), NOT the junior\'s own tests. ' +
64
+ 'Be decisive but fair: CONTINUE when there is genuine convergence (each recent step reduced the gap); ' +
65
+ 'RETIRE only when the same gap persists across attempts or a required capability is missing.\n' +
66
+ 'If ACTION: after the verdict line, give the SINGLE concrete step + the exact check to run.\n' +
67
+ 'If FINISH: optionally one clause confirming the criteria are met.\n' +
68
+ 'If RETIRE: one short line naming why the residual cannot close it.\n' +
69
+ 'If CONTINUE: nothing more.';
70
+ export function buildDeadlineExitPrompt(ctx) {
71
+ const parts = [];
72
+ parts.push(`TASK:\n${(ctx.task || '').trim().slice(0, 2500)}`);
73
+ const env = (ctx.envReport || '').trim();
74
+ if (env)
75
+ parts.push(`ENVIRONMENT REPORT:\n${env.slice(0, 2000)}`);
76
+ parts.push(`REMAINING BUDGET: ${(ctx.remainingBudget || '').trim().slice(0, 200)}`);
77
+ const prog = (ctx.recentProgress || '').trim();
78
+ if (prog)
79
+ parts.push(`RECENT PROGRESS (did each step reduce the gap?):\n${prog.slice(0, 1500)}`);
80
+ parts.push(`WORK SO FAR (latest answer + recent tool outputs):\n${(ctx.workProduct || '').trim().slice(0, 5000)}`);
81
+ parts.push('Checkpoint now. First line: `VERDICT: CONTINUE` | `FINISH` | `ACTION` | `RETIRE`. ' +
82
+ 'If ACTION, the single step + its check; if RETIRE, one line why; if FINISH, one confirming clause.');
83
+ return parts.join('\n\n');
84
+ }
85
+ /** Parse the checkpoint response. Fail-SAFE to CONTINUE (let it keep working) when unparseable —
86
+ * a broken mentor call must never truncate a turn. */
87
+ export function parseDeadlineExitVerdict(text) {
88
+ const t = (text || '').trim();
89
+ if (!t)
90
+ return { decision: 'continue', detail: '', parsed: false };
91
+ const m = t.match(/VERDICT:\s*(CONTINUE|FINISH|ACTION|RETIRE)/i);
92
+ if (!m)
93
+ return { decision: 'continue', detail: '', parsed: false };
94
+ const decision = m[1].toLowerCase();
95
+ const idx = t.indexOf(m[0]);
96
+ const detail = t.slice(idx + m[0].length).trim();
97
+ return { decision, detail, parsed: true };
98
+ }
99
+ //# sourceMappingURL=deadlineExitMentor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deadlineExitMentor.js","sourceRoot":"","sources":["../../src/training/deadlineExitMentor.ts"],"names":[],"mappings":"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"}
@@ -16,10 +16,18 @@ export interface EndTurnResolverConfig {
16
16
  effort: string;
17
17
  /** Max GAP verdicts that reject-and-replan before the gate fallback-accepts (liveness beats loops). */
18
18
  maxRejects: number;
19
+ /** ABSTENTION (CORTEX_ENDTURN_RESOLVER_ABSTAIN): offer the judge a RETIRE verdict for a
20
+ * structurally-hopeless finish and HONOR it (accept + stop) instead of burning the reject
21
+ * cycles on a task the junior can't fix. Dark by default (A/B-able). */
22
+ abstain: boolean;
19
23
  }
20
24
  export declare function resolveEndTurnResolverConfig(env?: NodeJS.ProcessEnv): EndTurnResolverConfig;
21
25
  /** The judge persona. First line is a machine-parseable verdict; a GAP is followed by a fix plan. */
22
26
  export declare const RESOLVER_SYSTEM: string;
27
+ /** Appended to the persona when abstention is enabled — offers the conservative RETIRE verdict. */
28
+ export declare const RESOLVER_ABSTAIN_CLAUSE: string;
29
+ /** The persona for the judge. With `abstain`, the RETIRE option is offered. */
30
+ export declare function resolverSystemPrompt(abstain?: boolean): string;
23
31
  export interface EndTurnResolverContext {
24
32
  /** The task statement the junior received. */
25
33
  task: string;
@@ -31,12 +39,15 @@ export interface EndTurnResolverContext {
31
39
  attestation?: string;
32
40
  }
33
41
  /** Build the user prompt for the judge. Bounded slices keep the call cheap and cache-stable. */
34
- export declare function buildResolverUserPrompt(ctx: EndTurnResolverContext): string;
42
+ export declare function buildResolverUserPrompt(ctx: EndTurnResolverContext, abstain?: boolean): string;
35
43
  export interface ResolverVerdict {
36
- /** true = MEETS (finish); false = GAP (reject + fix plan). Defaults to MEETS on an unparseable/empty
44
+ /** true = MEETS (finish); false = GAP or RETIRE. Defaults to MEETS on an unparseable/empty
37
45
  * response (fail-open: never trap the junior on a broken judge call — liveness beats purity). */
38
46
  meets: boolean;
39
- /** The fix plan (GAP only). */
47
+ /** RETIRE = the finish does not meet requirements AND is structurally unclosable → abstain (accept
48
+ * + stop the reject loop) when CORTEX_ENDTURN_RESOLVER_ABSTAIN is on. Never true for MEETS/GAP. */
49
+ retire: boolean;
50
+ /** GAP: the fix plan. RETIRE: the one-line reason it is unclosable. */
40
51
  plan: string;
41
52
  /** Whether the verdict line was actually found (else it fell back to fail-open MEETS). */
42
53
  parsed: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"endTurnResolver.d.ts","sourceRoot":"","sources":["../../src/training/endTurnResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,uGAAuG;IACvG,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,4BAA4B,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,qBAAqB,CASxG;AAED,qGAAqG;AACrG,eAAO,MAAM,eAAe,QAgB8B,CAAC;AAE3D,MAAM,WAAW,sBAAsB;IACrC,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uGAAuG;IACvG,WAAW,EAAE,MAAM,CAAC;IACpB,wGAAwG;IACxG,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,gGAAgG;AAChG,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,sBAAsB,GAAG,MAAM,CAa3E;AAED,MAAM,WAAW,eAAe;IAC9B;sGACkG;IAClG,KAAK,EAAE,OAAO,CAAC;IACf,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAUlE"}
1
+ {"version":3,"file":"endTurnResolver.d.ts","sourceRoot":"","sources":["../../src/training/endTurnResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,uGAAuG;IACvG,UAAU,EAAE,MAAM,CAAC;IACnB;;6EAEyE;IACzE,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,wBAAgB,4BAA4B,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,qBAAqB,CAUxG;AAED,qGAAqG;AACrG,eAAO,MAAM,eAAe,QAgB8B,CAAC;AAE3D,mGAAmG;AACnG,eAAO,MAAM,uBAAuB,QAMyE,CAAC;AAE9G,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,OAAO,UAAQ,GAAG,MAAM,CAE5D;AAED,MAAM,WAAW,sBAAsB;IACrC,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uGAAuG;IACvG,WAAW,EAAE,MAAM,CAAC;IACpB,wGAAwG;IACxG,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,gGAAgG;AAChG,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,sBAAsB,EAAE,OAAO,UAAQ,GAAG,MAAM,CAgB5F;AAED,MAAM,WAAW,eAAe;IAC9B;sGACkG;IAClG,KAAK,EAAE,OAAO,CAAC;IACf;wGACoG;IACpG,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAYlE"}
@@ -11,7 +11,7 @@
11
11
  * the mentor quarantines that reasoning where it belongs and hands the action model a plan, not a
12
12
  * puzzle. Same delivery as the lift planner: orchestrator-invoke → system-reminder. Pure + testable.
13
13
  */
14
- const DEFAULTS = { outputBudgetTokens: 4000, effort: 'max', maxRejects: 2 };
14
+ const DEFAULTS = { outputBudgetTokens: 4000, effort: 'max', maxRejects: 2, abstain: false };
15
15
  export function resolveEndTurnResolverConfig(env = process.env) {
16
16
  const n = parseInt((env.CORTEX_ENDTURN_RESOLVER_BUDGET_TOKENS ?? '').trim(), 10);
17
17
  const e = (env.CORTEX_ENDTURN_RESOLVER_EFFORT ?? '').trim();
@@ -20,6 +20,7 @@ export function resolveEndTurnResolverConfig(env = process.env) {
20
20
  outputBudgetTokens: Number.isInteger(n) && n > 0 ? n : DEFAULTS.outputBudgetTokens,
21
21
  effort: e || DEFAULTS.effort,
22
22
  maxRejects: Number.isInteger(m) && m >= 0 ? m : DEFAULTS.maxRejects,
23
+ abstain: (env.CORTEX_ENDTURN_RESOLVER_ABSTAIN ?? '').trim().toLowerCase() === 'true',
23
24
  };
24
25
  }
25
26
  /** The judge persona. First line is a machine-parseable verdict; a GAP is followed by a fix plan. */
@@ -39,8 +40,19 @@ export const RESOLVER_SYSTEM = 'You are a senior engineer performing the FINAL a
39
40
  'concrete step(s) to close it and the exact check to verify it against the TASK\'s criteria. If a gap ' +
40
41
  'cannot be verified in this box, say so and tell the junior to note it in open_items and finish. Be ' +
41
42
  'terse and concrete; do not rewrite the whole solution.';
43
+ /** Appended to the persona when abstention is enabled — offers the conservative RETIRE verdict. */
44
+ export const RESOLVER_ABSTAIN_CLAUSE = '\n\nA THIRD verdict is available: `VERDICT: RETIRE`. Use it ONLY when the work does not meet requirements ' +
45
+ 'AND the gap is structurally UNCLOSABLE by this junior in the remaining budget — a fundamentally wrong ' +
46
+ 'approach it keeps repeating, a missing capability/dependency that cannot be obtained in this box, or an ' +
47
+ 'impossible / self-contradictory requirement. RETIRE ends the task as-is instead of dispatching another ' +
48
+ 'doomed fix cycle. 🔴 When in doubt between GAP and RETIRE, choose GAP — only RETIRE when you are CONFIDENT ' +
49
+ 'that more attempts cannot help. After `VERDICT: RETIRE`, give ONE short line naming why it is unclosable.';
50
+ /** The persona for the judge. With `abstain`, the RETIRE option is offered. */
51
+ export function resolverSystemPrompt(abstain = false) {
52
+ return abstain ? RESOLVER_SYSTEM + RESOLVER_ABSTAIN_CLAUSE : RESOLVER_SYSTEM;
53
+ }
42
54
  /** Build the user prompt for the judge. Bounded slices keep the call cheap and cache-stable. */
43
- export function buildResolverUserPrompt(ctx) {
55
+ export function buildResolverUserPrompt(ctx, abstain = false) {
44
56
  const parts = [];
45
57
  parts.push(`TASK:\n${(ctx.task || '').trim().slice(0, 2500)}`);
46
58
  const env = (ctx.envReport || '').trim();
@@ -50,22 +62,27 @@ export function buildResolverUserPrompt(ctx) {
50
62
  const att = (ctx.attestation || '').trim();
51
63
  if (att)
52
64
  parts.push(`THE JUNIOR'S OWN ATTESTATION (treat as a claim to VERIFY, not as truth):\n${att.slice(0, 2000)}`);
53
- parts.push('Adjudicate now. First line: `VERDICT: MEETS` or `VERDICT: GAP`. If GAP, add the numbered fix plan ' +
54
- 'anchored to the TASK\'s real criteria.');
65
+ parts.push(abstain
66
+ ? 'Adjudicate now. First line: `VERDICT: MEETS`, `VERDICT: GAP`, or `VERDICT: RETIRE`. If GAP, add the ' +
67
+ 'numbered fix plan anchored to the TASK\'s real criteria; if RETIRE, one line on why it is unclosable.'
68
+ : 'Adjudicate now. First line: `VERDICT: MEETS` or `VERDICT: GAP`. If GAP, add the numbered fix plan ' +
69
+ 'anchored to the TASK\'s real criteria.');
55
70
  return parts.join('\n\n');
56
71
  }
57
72
  /** Parse the judge's response. Fail-open to MEETS when the verdict line is absent/empty. */
58
73
  export function parseResolverVerdict(text) {
59
74
  const t = (text || '').trim();
60
75
  if (!t)
61
- return { meets: true, plan: '', parsed: false };
62
- const m = t.match(/VERDICT:\s*(MEETS|GAP)/i);
76
+ return { meets: true, retire: false, plan: '', parsed: false };
77
+ const m = t.match(/VERDICT:\s*(MEETS|GAP|RETIRE)/i);
63
78
  if (!m)
64
- return { meets: true, plan: '', parsed: false }; // no clear verdict → do not block the finish
65
- const meets = m[1].toUpperCase() === 'MEETS';
66
- // The plan is everything after the verdict line.
79
+ return { meets: true, retire: false, plan: '', parsed: false }; // no clear verdict → do not block the finish
80
+ const verdict = m[1].toUpperCase();
81
+ const meets = verdict === 'MEETS';
82
+ const retire = verdict === 'RETIRE';
83
+ // The plan (GAP) / reason (RETIRE) is everything after the verdict line.
67
84
  const idx = t.indexOf(m[0]);
68
85
  const plan = t.slice(idx + m[0].length).trim();
69
- return { meets, plan, parsed: true };
86
+ return { meets, retire, plan, parsed: true };
70
87
  }
71
88
  //# sourceMappingURL=endTurnResolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"endTurnResolver.js","sourceRoot":"","sources":["../../src/training/endTurnResolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"endTurnResolver.js","sourceRoot":"","sources":["../../src/training/endTurnResolver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexus-cortex/core",
3
- "version": "4.93.0",
3
+ "version": "4.94.0",
4
4
  "description": "Core orchestration library implementing Claude CLI architecture patterns",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "scripts": {
35
35
  "build": "npm run clean && tsc && npm run copy-assets",
36
- "copy-assets": "mkdir -p dist/system-messages/messages && cp src/system-messages/*.json dist/system-messages/ && cp -r src/system-messages/messages/*.md dist/system-messages/messages/ && cp ../../.env.example ./.env.example",
36
+ "copy-assets": "mkdir -p dist/system-messages/messages && cp src/system-messages/*.json dist/system-messages/ && cp -r src/system-messages/messages/*.md dist/system-messages/messages/ && cp ../../.env.defaults ./.env.defaults",
37
37
  "clean": "rm -rf dist",
38
38
  "test": "vitest",
39
39
  "test:ci": "vitest run --coverage",
@@ -47,8 +47,8 @@
47
47
  "@google/generative-ai": "^0.2.1",
48
48
  "@gradio/client": "^2.3.1",
49
49
  "@modelcontextprotocol/sdk": "^1.20.2",
50
- "@nexus-cortex/executors": "4.93.0",
51
- "@nexus-cortex/types": "4.93.0",
50
+ "@nexus-cortex/executors": "4.94.0",
51
+ "@nexus-cortex/types": "4.94.0",
52
52
  "@types/uuid": "^10.0.0",
53
53
  "ajv": "^8.12.0",
54
54
  "chokidar": "^3.6.0",
@@ -76,7 +76,7 @@
76
76
  "README.md",
77
77
  "LICENSE",
78
78
  "NOTICE",
79
- ".env.example"
79
+ ".env.defaults"
80
80
  ],
81
81
  "repository": {
82
82
  "type": "git",