nexus-agents 8.29.0 → 8.31.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 (25) hide show
  1. package/dist/{chunk-6RNUX5RK.js → chunk-3ZVZXXRY.js} +126 -42
  2. package/dist/chunk-3ZVZXXRY.js.map +1 -0
  3. package/dist/{chunk-MEN32VJC.js → chunk-42LDWYPF.js} +2 -2
  4. package/dist/{chunk-JW5IATB3.js → chunk-PF452UB3.js} +2 -2
  5. package/dist/{chunk-JIHN5BEO.js → chunk-RRI3M73Y.js} +7 -7
  6. package/dist/{chunk-V337TBA6.js → chunk-YEURRBMU.js} +2 -2
  7. package/dist/{chunk-EZ3OCW6Q.js → chunk-ZYLE33GL.js} +3 -3
  8. package/dist/cli.d.ts +1 -1
  9. package/dist/cli.js +7 -7
  10. package/dist/{consensus-vote-TX62EZF7.js → consensus-vote-AJ6SWE4U.js} +4 -4
  11. package/dist/{consensus-vote-types-BlEp-vlK.d.ts → consensus-vote-types-BKoR41Kx.d.ts} +12 -0
  12. package/dist/{improvement-review-2X4COULE.js → improvement-review-MY2U3VKI.js} +4 -4
  13. package/dist/index.d.ts +25 -8
  14. package/dist/index.js +6 -6
  15. package/dist/{setup-data-dir-QOOINIMJ.js → setup-data-dir-T2ZTIRXS.js} +3 -3
  16. package/package.json +1 -1
  17. package/dist/chunk-6RNUX5RK.js.map +0 -1
  18. /package/dist/{chunk-MEN32VJC.js.map → chunk-42LDWYPF.js.map} +0 -0
  19. /package/dist/{chunk-JW5IATB3.js.map → chunk-PF452UB3.js.map} +0 -0
  20. /package/dist/{chunk-JIHN5BEO.js.map → chunk-RRI3M73Y.js.map} +0 -0
  21. /package/dist/{chunk-V337TBA6.js.map → chunk-YEURRBMU.js.map} +0 -0
  22. /package/dist/{chunk-EZ3OCW6Q.js.map → chunk-ZYLE33GL.js.map} +0 -0
  23. /package/dist/{consensus-vote-TX62EZF7.js.map → consensus-vote-AJ6SWE4U.js.map} +0 -0
  24. /package/dist/{improvement-review-2X4COULE.js.map → improvement-review-MY2U3VKI.js.map} +0 -0
  25. /package/dist/{setup-data-dir-QOOINIMJ.js.map → setup-data-dir-T2ZTIRXS.js.map} +0 -0
@@ -23,10 +23,10 @@ import {
23
23
  toolSuccessStructured,
24
24
  withProgressHeartbeat,
25
25
  wrapToolWithTimeout
26
- } from "./chunk-MEN32VJC.js";
26
+ } from "./chunk-42LDWYPF.js";
27
27
  import {
28
28
  VERSION
29
- } from "./chunk-JW5IATB3.js";
29
+ } from "./chunk-PF452UB3.js";
30
30
  import {
31
31
  assessPanelIndependence,
32
32
  countDistinctModels,
@@ -40,6 +40,7 @@ import {
40
40
  authRemediation,
41
41
  delay,
42
42
  getAvailableClis,
43
+ sleep,
43
44
  withTimeout
44
45
  } from "./chunk-K6PI22W5.js";
45
46
  import {
@@ -196,6 +197,66 @@ function reportPanelModelIndependence(modelIds, roleCount, phase, logger11) {
196
197
  );
197
198
  }
198
199
 
200
+ // src/cli/voter-retry.ts
201
+ var DEFAULT_ERRORED_ROLE_BACKOFF_MS = 3e3;
202
+ async function retryErroredRoles(first, relaunch, logger11, backoffMs) {
203
+ const erroredRoles = first.filter((v) => v.source === "error").map((v) => v.role);
204
+ if (erroredRoles.length === 0) return first;
205
+ logger11.warn("Retrying errored voter roles before aggregating (#5578)", {
206
+ erroredRoles,
207
+ of: first.length
208
+ });
209
+ if (backoffMs > 0) await sleep(backoffMs);
210
+ const retriedResults = await relaunch(erroredRoles);
211
+ const recovered = /* @__PURE__ */ new Map();
212
+ for (const r of retriedResults) {
213
+ if (r.source === "error") continue;
214
+ recovered.set(r.role, { ...r, retried: true });
215
+ }
216
+ if (recovered.size === 0) {
217
+ logger11.warn("Per-role retry recovered no voter \u2014 the panel stays degraded", { erroredRoles });
218
+ return first;
219
+ }
220
+ logger11.info("Per-role retry recovered voters", {
221
+ recoveredRoles: [...recovered.keys()],
222
+ stillErrored: erroredRoles.filter((r) => !recovered.has(r))
223
+ });
224
+ return first.map((v) => recovered.get(v.role) ?? v);
225
+ }
226
+
227
+ // src/cli/voter-adapter-resolve.ts
228
+ var NoAdapterError = class extends Error {
229
+ constructor(message) {
230
+ super(message);
231
+ this.name = "NoAdapterError";
232
+ }
233
+ };
234
+ function resolveAdapter(options, logger11) {
235
+ try {
236
+ if (options.adapter !== void 0) return { adapter: options.adapter };
237
+ const gateway = options.gatewayAdapters;
238
+ if (gateway !== void 0 && gateway.length > 0 && gateway[0] !== void 0) {
239
+ return { adapter: gateway[0] };
240
+ }
241
+ const registry = getGlobalRegistry({ logger: logger11 });
242
+ return { adapter: registry.getDefault() };
243
+ } catch (error) {
244
+ return { error: getErrorMessage(error) };
245
+ }
246
+ }
247
+ function resolveAdapterOrFail(options, logger11, allowSimulation) {
248
+ const resolved = resolveAdapter(options, logger11);
249
+ if (!("error" in resolved)) return resolved;
250
+ logger11.error("No adapter available for voting", void 0, { error: resolved.error });
251
+ if (allowSimulation) {
252
+ logger11.warn("Falling back to simulation (allowSimulation=true)");
253
+ return { simulated: true };
254
+ }
255
+ throw new NoAdapterError(
256
+ `No adapter available for voting: ${resolved.error}. Install a CLI (claude/gemini/codex) or set ANTHROPIC_API_KEY.`
257
+ );
258
+ }
259
+
199
260
  // src/cli/voter-prompts.ts
200
261
  var DEFAULT_PROJECT = "nexus-agents";
201
262
  function prReviewModeAddendum() {
@@ -1193,25 +1254,6 @@ async function executeAgentVote(role, proposal, adapter, logger11, options) {
1193
1254
  ${remediation}`;
1194
1255
  return createErrorVoteResult(role, errorText, processingTimeMs, adapter.providerId);
1195
1256
  }
1196
- var NoAdapterError = class extends Error {
1197
- constructor(message) {
1198
- super(message);
1199
- this.name = "NoAdapterError";
1200
- }
1201
- };
1202
- function resolveAdapter(options, logger11) {
1203
- try {
1204
- if (options.adapter !== void 0) return { adapter: options.adapter };
1205
- const gateway = options.gatewayAdapters;
1206
- if (gateway !== void 0 && gateway.length > 0 && gateway[0] !== void 0) {
1207
- return { adapter: gateway[0] };
1208
- }
1209
- const registry = getGlobalRegistry({ logger: logger11 });
1210
- return { adapter: registry.getDefault() };
1211
- } catch (error) {
1212
- return { error: getErrorMessage(error) };
1213
- }
1214
- }
1215
1257
  function warnIfCodexConcurrencyExceeded(roleAdapters, logger11) {
1216
1258
  const codexBound = [...roleAdapters.values()].filter(
1217
1259
  (a) => a.name === "codex"
@@ -1343,17 +1385,8 @@ async function collectRealVotes(options) {
1343
1385
  logger11.info("Using simulation mode (explicitly requested)");
1344
1386
  return createSimulatedVotes(roles, proposal);
1345
1387
  }
1346
- const adapterResult = resolveAdapter(options, logger11);
1347
- if ("error" in adapterResult) {
1348
- logger11.error("No adapter available for voting", void 0, { error: adapterResult.error });
1349
- if (allowSimulation === true) {
1350
- logger11.warn("Falling back to simulation (allowSimulation=true)");
1351
- return createSimulatedVotes(roles, proposal, "No adapter available");
1352
- }
1353
- throw new NoAdapterError(
1354
- `No adapter available for voting: ${adapterResult.error}. Install a CLI (claude/gemini/codex) or set ANTHROPIC_API_KEY.`
1355
- );
1356
- }
1388
+ const adapterResult = resolveAdapterOrFail(options, logger11, allowSimulation === true);
1389
+ if ("simulated" in adapterResult) return createSimulatedVotes(roles, proposal, "No adapter available");
1357
1390
  const roleAdapters = options.adapter !== void 0 ? assignUniformAdapter(roles, adapterResult.adapter) : await resolveDiverseAdapters(roles, logger11, adapterResult.adapter, options.gatewayAdapters);
1358
1391
  warnIfCodexConcurrencyExceeded(roleAdapters, logger11);
1359
1392
  const voteOptions = {
@@ -1365,7 +1398,7 @@ async function collectRealVotes(options) {
1365
1398
  declaredOptions: options.declaredOptions
1366
1399
  };
1367
1400
  const interDelay = options.interAgentDelayMs ?? DEFAULT_INTER_AGENT_DELAY_MS;
1368
- const results = await launchStaggeredVotes({
1401
+ const launchInput = {
1369
1402
  roles,
1370
1403
  proposal,
1371
1404
  roleAdapters,
@@ -1374,7 +1407,14 @@ async function collectRealVotes(options) {
1374
1407
  voteOptions,
1375
1408
  interDelay,
1376
1409
  signal: options.signal
1377
- });
1410
+ };
1411
+ const firstPass = await launchStaggeredVotes(launchInput);
1412
+ const results = await retryErroredRoles(
1413
+ firstPass,
1414
+ (retryRoles) => launchStaggeredVotes({ ...launchInput, roles: retryRoles }),
1415
+ logger11,
1416
+ options.erroredRoleBackoffMs ?? DEFAULT_ERRORED_ROLE_BACKOFF_MS
1417
+ );
1378
1418
  reportVoteIndependence(results, logger11);
1379
1419
  return results;
1380
1420
  }
@@ -5089,10 +5129,33 @@ var VoteRecordPanelCoverageSchema = z7.object({
5089
5129
  /** The roles behind `errored`, in panel order. */
5090
5130
  erroredRoles: z7.array(z7.string().min(1).max(100))
5091
5131
  }).strict();
5132
+ var MAX_VOTER_REASONING_CHARS = 2e4;
5092
5133
  var VoterSummarySchema = z7.object({
5093
5134
  role: z7.string().min(1).max(100),
5094
5135
  decision: z7.enum(["approve", "reject", "abstain"]),
5095
- confidence: z7.number().min(0).max(1)
5136
+ confidence: z7.number().min(0).max(1),
5137
+ /**
5138
+ * The voter's stated grounds (#5373, schema 1.6).
5139
+ *
5140
+ * `generateVoteHash` already hashed `{role, decision, reasoning}` and then
5141
+ * discarded the text, so the chain attested to a value it did not store and
5142
+ * nobody could re-verify the hash without re-obtaining the reasoning. On
5143
+ * #5228 a contrarian rejection was clipped mid-sentence in the terminal, the
5144
+ * grounds were unrecoverable, and the same defect resurfaced a round later —
5145
+ * one round of a 7-voter panel is 7-13 minutes of model time, and the
5146
+ * objection was right both times.
5147
+ *
5148
+ * Stored whole rather than sampled. Warn-mode near-misses are emitted per
5149
+ * TOOL CALL, thousands a day; votes are emitted per PANEL, dozens a day at
5150
+ * most, so ~17 KB per vote is not the same growth problem.
5151
+ *
5152
+ * Absence is not an empty argument: an errored voter has no entry in
5153
+ * `voters` at all (see `panelCoverage`), so `reasoning: ''` means a live
5154
+ * voter returned nothing, which is itself a signal.
5155
+ */
5156
+ reasoning: z7.string().max(MAX_VOTER_REASONING_CHARS).optional(),
5157
+ /** True when `reasoning` was clipped to {@link MAX_VOTER_REASONING_CHARS}. */
5158
+ reasoningTruncated: z7.literal(true).optional()
5096
5159
  }).strict();
5097
5160
  var VoteRecordCountsSchema = z7.object({
5098
5161
  approve: z7.number().int().nonnegative(),
@@ -5114,7 +5177,7 @@ var VoteRecordSchema = z7.object({
5114
5177
  * `ratifies` is folded into the self-hash ONLY when present (see
5115
5178
  * {@link computeVoteRecordHash}).
5116
5179
  */
5117
- version: z7.enum(["1.1", "1.2", "1.3", "1.4", "1.5"]),
5180
+ version: z7.enum(["1.1", "1.2", "1.3", "1.4", "1.5", "1.6"]),
5118
5181
  /** Unique record id (also usable as a `ratificationVoteRef`). */
5119
5182
  id: z7.string().min(1),
5120
5183
  /**
@@ -5246,10 +5309,17 @@ function computeVoteRecordHash(payload) {
5246
5309
  abstain: payload.voteCounts.abstain,
5247
5310
  total: payload.voteCounts.total
5248
5311
  },
5312
+ // `reasoning` / `reasoningTruncated` (#5373, schema 1.6) are appended per
5313
+ // entry ONLY when present, on the same rule as the record-level optional
5314
+ // fields: a pre-1.6 voter entry re-hashes byte-identical, so every
5315
+ // historical record still verifies, while editing or removing a stored
5316
+ // reasoning flips the hash.
5249
5317
  voters: payload.voters.map((v) => ({
5250
5318
  role: v.role,
5251
5319
  decision: v.decision,
5252
- confidence: v.confidence
5320
+ confidence: v.confidence,
5321
+ ...v.reasoning !== void 0 ? { reasoning: v.reasoning } : {},
5322
+ ...v.reasoningTruncated === true ? { reasoningTruncated: true } : {}
5253
5323
  })),
5254
5324
  correlationId: payload.correlationId ?? null
5255
5325
  };
@@ -5281,10 +5351,22 @@ function toVoterSummaries(votes) {
5281
5351
  for (const v of votes) {
5282
5352
  if (v.source === "error") continue;
5283
5353
  const vote = v.vote;
5284
- summaries.push({ role: v.role, decision: vote.decision, confidence: vote.confidence });
5354
+ summaries.push({
5355
+ role: v.role,
5356
+ decision: vote.decision,
5357
+ confidence: vote.confidence,
5358
+ ...reasoningFields(vote.reasoning)
5359
+ });
5285
5360
  }
5286
5361
  return summaries;
5287
5362
  }
5363
+ function reasoningFields(reasoning) {
5364
+ if (reasoning.length <= MAX_VOTER_REASONING_CHARS) return { reasoning };
5365
+ return {
5366
+ reasoning: reasoning.slice(0, MAX_VOTER_REASONING_CHARS),
5367
+ reasoningTruncated: true
5368
+ };
5369
+ }
5288
5370
  function recordDecisionFor(input) {
5289
5371
  return input.resolvedDecision ?? outcomeToDecision(input.result, input.votes, input.errorVoided ?? false);
5290
5372
  }
@@ -5295,7 +5377,8 @@ function deriveOptionFields(votes) {
5295
5377
  optionCoverage: optionTally === void 0 ? void 0 : coverageOf(votes)
5296
5378
  };
5297
5379
  }
5298
- function recordVersion(optionTally, optionCoverage, panelCoverage) {
5380
+ function recordVersion(optionTally, optionCoverage, panelCoverage, voters) {
5381
+ if (voters.some((v) => v.reasoning !== void 0)) return "1.6";
5299
5382
  if (panelCoverage !== void 0) return "1.5";
5300
5383
  if (optionCoverage !== void 0) return "1.4";
5301
5384
  return optionTally !== void 0 ? "1.3" : "1.2";
@@ -5333,8 +5416,9 @@ function buildVoteRecord(input) {
5333
5416
  const proposalTruncated = input.proposal.length > MAX_PROPOSAL_RECORD_CHARS ? input.proposal.slice(0, MAX_PROPOSAL_RECORD_CHARS) + "..." : input.proposal;
5334
5417
  const { optionTally, optionCoverage } = deriveOptionFields(input.votes);
5335
5418
  const panelCoverage = panelCoverageOf(input.votes);
5419
+ const voters = toVoterSummaries(input.votes);
5336
5420
  const payload = {
5337
- version: recordVersion(optionTally, optionCoverage, panelCoverage),
5421
+ version: recordVersion(optionTally, optionCoverage, panelCoverage, voters),
5338
5422
  id: input.id,
5339
5423
  sequence: input.sequence ?? 0,
5340
5424
  recordedAt: input.recordedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
@@ -5349,7 +5433,7 @@ function buildVoteRecord(input) {
5349
5433
  abstain: input.result.voteCounts.abstain,
5350
5434
  total: input.result.voteCounts.total
5351
5435
  },
5352
- voters: toVoterSummaries(input.votes),
5436
+ voters,
5353
5437
  ...input.correlationId !== void 0 ? { correlationId: input.correlationId } : {},
5354
5438
  ...input.ratifies !== void 0 ? { ratifies: input.ratifies } : {},
5355
5439
  ...optionTally !== void 0 ? { optionTally } : {},
@@ -7722,4 +7806,4 @@ export {
7722
7806
  CONSENSUS_VOTE_TOOL_SCHEMA,
7723
7807
  registerConsensusVoteTool
7724
7808
  };
7725
- //# sourceMappingURL=chunk-6RNUX5RK.js.map
7809
+ //# sourceMappingURL=chunk-3ZVZXXRY.js.map