nexus-agents 8.3.3 → 8.5.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.
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-OQB3XC5O.js";
7
7
  import {
8
8
  VERSION
9
- } from "./chunk-LV3LWVWI.js";
9
+ } from "./chunk-KIQLNY6S.js";
10
10
  import {
11
11
  capitalize
12
12
  } from "./chunk-6T3EPABN.js";
@@ -1201,7 +1201,7 @@ async function runDoctorFix(result) {
1201
1201
  writeLine2("\u2500".repeat(40));
1202
1202
  let fixCount = 0;
1203
1203
  if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
1204
- const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-NXOVPIK7.js");
1204
+ const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-4P6HKDAD.js");
1205
1205
  const outcome = describeDataDirFix2(initDataDirectories2());
1206
1206
  writeLine2(outcome.line);
1207
1207
  if (outcome.counted) fixCount++;
@@ -1303,4 +1303,4 @@ export {
1303
1303
  startStdioServer,
1304
1304
  closeServer
1305
1305
  };
1306
- //# sourceMappingURL=chunk-5HQ64BQJ.js.map
1306
+ //# sourceMappingURL=chunk-2DRZS743.js.map
@@ -23,7 +23,7 @@ import {
23
23
  toolSuccessStructured,
24
24
  withProgressHeartbeat,
25
25
  wrapToolWithTimeout
26
- } from "./chunk-T5SLVJCK.js";
26
+ } from "./chunk-VXKWGJ36.js";
27
27
  import {
28
28
  assessPanelIndependence,
29
29
  countDistinctModels,
@@ -1015,6 +1015,7 @@ async function executeWithRetries(opts) {
1015
1015
 
1016
1016
  // src/cli/voter-agents-deadline.ts
1017
1017
  var DEADLINE_MESSAGE = "overall consensus deadline exceeded";
1018
+ var CANCELLED_MESSAGE = "cancelled before this voter was launched";
1018
1019
  function shouldRetryOnFallback(result, used, fallback) {
1019
1020
  return result.source === "error" && result.error !== DEADLINE_MESSAGE && adapterCliKey(used) !== adapterCliKey(fallback);
1020
1021
  }
@@ -1047,6 +1048,9 @@ function raceWithDeadline(p, role, deadlineMs) {
1047
1048
  if (timer !== void 0) clearTimeout(timer);
1048
1049
  });
1049
1050
  }
1051
+ function cancelled(signal) {
1052
+ return signal?.aborted === true;
1053
+ }
1050
1054
  async function launchVotesWithOverallDeadline(input) {
1051
1055
  const {
1052
1056
  roles,
@@ -1076,9 +1080,11 @@ async function launchVotesWithOverallDeadline(input) {
1076
1080
  );
1077
1081
  const wrapped = roles.map(async (role, i) => {
1078
1082
  if (i > 0 && interDelay > 0) await delay(interDelay);
1083
+ if (cancelled(input.signal)) return createErrorVoteResult(role, CANCELLED_MESSAGE, 0);
1079
1084
  const adapter = roleAdapters.get(role) ?? fallbackAdapter;
1080
1085
  const primary = await voteOnAdapter(role, adapter);
1081
1086
  if (!shouldRetryOnFallback(primary, adapter, fallbackAdapter)) return primary;
1087
+ if (cancelled(input.signal)) return primary;
1082
1088
  logger10.warn("Voter failed on diverse adapter; retrying on fallback (#3587)", {
1083
1089
  role,
1084
1090
  failedCli: adapterCliKey(adapter),
@@ -1303,7 +1309,8 @@ async function launchStaggeredVotes(input) {
1303
1309
  voteOptions,
1304
1310
  interDelay,
1305
1311
  overallDeadlineMs,
1306
- voteFn: executeAgentVote
1312
+ voteFn: executeAgentVote,
1313
+ signal: input.signal
1307
1314
  });
1308
1315
  }
1309
1316
  async function collectRealVotes(options) {
@@ -1344,7 +1351,8 @@ async function collectRealVotes(options) {
1344
1351
  fallbackAdapter: adapterResult.adapter,
1345
1352
  logger: logger10,
1346
1353
  voteOptions,
1347
- interDelay
1354
+ interDelay,
1355
+ signal: options.signal
1348
1356
  });
1349
1357
  reportPanelIndependence([...roleAdapters.values()], roles.length, "post-vote", logger10);
1350
1358
  return results;
@@ -4489,6 +4497,31 @@ function createPersistedProposal(proposalId, votes, outcome) {
4489
4497
 
4490
4498
  // src/mcp/tools/consensus-vote-types.ts
4491
4499
  import { z as z6 } from "zod";
4500
+
4501
+ // src/mcp/tools/consensus-vote-option-detection.ts
4502
+ var MULTI_OPTION_PATTERNS = Object.freeze([
4503
+ // `Option A` and `OPTION A`, but NOT `option a` — the lowercase form appears
4504
+ // in ordinary prose ("there is no option a caller can set"), the capitalised
4505
+ // form is a heading. The motivating proposal used `Option A`; an
4506
+ // uppercase-only pattern would have missed the instance this exists for.
4507
+ /\b(?:Option|OPTION) [A-Z0-9]\b/,
4508
+ /\bchoose between\b/i,
4509
+ /\bwhich of (?:the )?(?:these|those|the following)\b/i,
4510
+ /\bpick exactly one\b/i,
4511
+ /\bvote for exactly one\b/i
4512
+ ]);
4513
+ function checkUndeclaredOptions(proposal, declaredOptions, allEngagedApproved) {
4514
+ if (declaredOptions !== void 0 && declaredOptions.length > 0) return { flagged: false };
4515
+ if (proposal === "") return { flagged: false };
4516
+ if (!MULTI_OPTION_PATTERNS.some((p) => p.test(proposal))) return { flagged: false };
4517
+ const base = "This proposal appears to name alternatives, but `options` was not declared, so the tally records approve/reject only and cannot say WHICH alternative won (#4452, #5360). Re-run with `options` to record the option tally.";
4518
+ return {
4519
+ flagged: true,
4520
+ warning: allEngagedApproved === true ? `${base} Every non-errored voter returned \`approve\`, which is the signature of this defect.` : base
4521
+ };
4522
+ }
4523
+
4524
+ // src/mcp/tools/consensus-vote-types.ts
4492
4525
  var MAX_PROPOSAL_LENGTH = 4e3;
4493
4526
  var VotingStrategySchema = z6.enum([
4494
4527
  "simple_majority",
@@ -4521,7 +4554,7 @@ function getDefaultErrorPolicy(strategy) {
4521
4554
  }
4522
4555
  var ConsensusVoteInputSchema = z6.object({
4523
4556
  proposal: z6.string().min(1).max(MAX_PROPOSAL_LENGTH).describe(
4524
- "Proposal text to vote on. If the proposal asks voters to choose among named alternatives, you MUST declare them in `options` (#4472). Without `options` the tally records approve/reject/abstain only, so every voter who engages returns `approve` and a 6-1 split on WHICH option persists as 7-0, 100% (#4452)."
4557
+ 'Proposal text to vote on. If the proposal asks voters to choose among named alternatives, declare them in `options` (#4472) \u2014 otherwise the tally records approve/reject/abstain only, so every voter who engages returns `approve` and a 6-1 split on WHICH option persists as 7-0, 100% (#4452). This is ENFORCED AS A WARNING, not a refusal: a heuristic over the proposal text flags an apparent multi-option proposal with no `options` and says so on `panelWarning` (#5360). The wording says "declare", not "MUST", because the warning is what the code actually holds \u2014 it is tightened back only in the same change that promotes the warning to a refusal.'
4525
4558
  ),
4526
4559
  options: z6.array(z6.string().min(1).max(200)).min(2).max(10).optional().describe(
4527
4560
  "Named alternatives for a multi-option proposal (#4472). When present, the threshold must ALSO be cleared by the leading option, in addition to the ordinary approve/reject bar: `unanimous` requires every approver to have chosen the SAME option, and `supermajority`/`majority` measure the leading option's share of approvers. An approving voter whose selection is absent or matches no declared option stays in the denominator and credits no option, so a degraded response can only lower the leading share, never raise it. Omit for an ordinary yes/no vote \u2014 behaviour is then unchanged."
@@ -4747,6 +4780,15 @@ function applyOptionalResponseFields(response, input, result, errorCount, costSu
4747
4780
  if (panelWarning !== void 0) {
4748
4781
  response.panelWarning = panelWarning;
4749
4782
  }
4783
+ const engaged = result.votes.length - errorCount;
4784
+ const undeclared = checkUndeclaredOptions(
4785
+ input.proposal,
4786
+ input.options,
4787
+ engaged > 0 && response.voteCounts.reject === 0 && response.voteCounts.abstain === 0
4788
+ );
4789
+ if (undeclared.flagged) {
4790
+ response.panelWarning = response.panelWarning === void 0 ? undeclared.warning : `${response.panelWarning} ${undeclared.warning}`;
4791
+ }
4750
4792
  if (isHigherOrderStrategy(result.strategy) && result.higherOrderResult) {
4751
4793
  response.higherOrderMetadata = toHigherOrderMetadata(result.higherOrderResult);
4752
4794
  }
@@ -6387,7 +6429,7 @@ async function maybeEscalateContrarian(input, outcome, ctx, logger10, opts) {
6387
6429
  return { escalated: await executeVoting({ ...input, quickMode: false }, logger10, opts) };
6388
6430
  }
6389
6431
  async function executeVoting(input, logger10, opts) {
6390
- const result = await executeVotingInner(input, logger10, opts);
6432
+ const result = await executeVotingInner(input, logger10, opts ?? {});
6391
6433
  const errorCount = result.votes.filter((v) => v.source === "error").length;
6392
6434
  applyOptionGate(input, result);
6393
6435
  result.decision = resolveVoteDecision(input, result, errorCount).decision;
@@ -6425,9 +6467,10 @@ async function executeVotingInner(input, logger10, opts) {
6425
6467
  roles,
6426
6468
  proposal: input.proposal,
6427
6469
  simulate: input.simulateVotes,
6428
- ...opts?.voteTimeoutMs !== void 0 && { timeoutMs: opts.voteTimeoutMs },
6429
- ...opts?.gatewayAdapters !== void 0 && { gatewayAdapters: opts.gatewayAdapters },
6430
- declaredOptions: input.options
6470
+ ...opts.voteTimeoutMs !== void 0 && { timeoutMs: opts.voteTimeoutMs },
6471
+ ...opts.gatewayAdapters !== void 0 && { gatewayAdapters: opts.gatewayAdapters },
6472
+ declaredOptions: input.options,
6473
+ signal: opts.signal
6431
6474
  });
6432
6475
  const policyDecision = applyErrorPolicy(votes, errorPolicy);
6433
6476
  if (policyDecision.shortCircuit) {
@@ -6539,11 +6582,12 @@ function recordVoteSideEffects(proposal, strategy, result, logger10, ratifies) {
6539
6582
  }
6540
6583
  return { costSummary, voteRecord };
6541
6584
  }
6542
- async function handleConsensusVote(deps, args) {
6585
+ async function handleConsensusVote(deps, args, signal) {
6543
6586
  const logger10 = deps.logger ?? createLogger({ tool: "consensus_vote" });
6544
6587
  try {
6545
6588
  const result = await executeVoting(args, logger10, {
6546
- ...deps.gatewayAdapters !== void 0 && { gatewayAdapters: deps.gatewayAdapters }
6589
+ ...deps.gatewayAdapters !== void 0 && { gatewayAdapters: deps.gatewayAdapters },
6590
+ signal
6547
6591
  });
6548
6592
  const strategy = args.strategy ?? "simple_majority";
6549
6593
  const errorVotes = result.votes.filter((v) => v.source === "error");
@@ -6599,7 +6643,10 @@ function dispatchAsyncConsensusVote(deps, args) {
6599
6643
  // callback RESOLVES — so a dead voter panel produced a job a caller polling
6600
6644
  // `get_job_result` read as a success. Reject instead, mirroring the sync
6601
6645
  // sibling's `toolStructuredError` on the same condition.
6602
- run: (_jobId, input) => unwrapVoteOrThrow(handleConsensusVote(deps, input)),
6646
+ // #5393: arity 3. `runAsJob` derives `signalAccepted` from `run.length`, so
6647
+ // taking the signal is what makes the job record say cancellation works —
6648
+ // the claim follows the capability instead of being asserted separately.
6649
+ run: (_jobId, input, signal) => unwrapVoteOrThrow(handleConsensusVote(deps, input, signal)),
6603
6650
  ...deps.logger !== void 0 ? { logger: deps.logger } : {}
6604
6651
  });
6605
6652
  }
@@ -6892,4 +6939,4 @@ export {
6892
6939
  CONSENSUS_VOTE_TOOL_SCHEMA,
6893
6940
  registerConsensusVoteTool
6894
6941
  };
6895
- //# sourceMappingURL=chunk-AYVIQAGJ.js.map
6942
+ //# sourceMappingURL=chunk-3SKIHGZV.js.map