nexus-agents 2.76.0 → 2.77.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.
@@ -89,6 +89,7 @@ import {
89
89
  getOutcomesFile
90
90
  } from "./chunk-I7ORMAO7.js";
91
91
  import {
92
+ getNexusDataDir,
92
93
  nexusDataPath
93
94
  } from "./chunk-GOT7OAL5.js";
94
95
 
@@ -159,6 +160,11 @@ async function withProgressHeartbeat(toolName, notifier, operation, intervalMs =
159
160
  }
160
161
  }
161
162
 
163
+ // src/mcp/middleware/tool-wrapper.ts
164
+ import { randomUUID } from "crypto";
165
+ import { appendFileSync, existsSync, mkdirSync } from "fs";
166
+ import { dirname, join } from "path";
167
+
162
168
  // src/mcp/middleware/rate-limiter.ts
163
169
  var DEFAULT_REFILL_INTERVAL_MS = CACHE_TIMEOUTS.rateLimitRefillMs;
164
170
  var RateLimiter = class {
@@ -1353,23 +1359,102 @@ function toSdkCallback(handler) {
1353
1359
  };
1354
1360
  }
1355
1361
  var MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS = 6e4;
1362
+ var TIMEOUT_MISMATCH_TELEMETRY_REL_PATH = "mcp-telemetry/timeout-mismatch-events.jsonl";
1363
+ function appendTimeoutMismatchEvent(event) {
1364
+ try {
1365
+ const path3 = join(getNexusDataDir(), TIMEOUT_MISMATCH_TELEMETRY_REL_PATH);
1366
+ const dir = dirname(path3);
1367
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
1368
+ appendFileSync(path3, JSON.stringify(event) + "\n", "utf-8");
1369
+ } catch (err2) {
1370
+ wrapperLogger.debug("Best-effort timeout-mismatch event recording failed", {
1371
+ error: getErrorMessage(err2)
1372
+ });
1373
+ }
1374
+ }
1375
+ function extractErrorCategoryFromResult(result) {
1376
+ const envelope = result._meta?.["nexus-agents/error"];
1377
+ if (envelope !== null && typeof envelope === "object" && "errorCategory" in envelope) {
1378
+ const cat = envelope.errorCategory;
1379
+ if (typeof cat === "string") return cat;
1380
+ }
1381
+ return void 0;
1382
+ }
1383
+ function extractErrorMessageFromResult(result) {
1384
+ const first = result.content[0];
1385
+ if (first?.type === "text" && typeof first.text === "string") {
1386
+ return first.text.slice(0, 500);
1387
+ }
1388
+ return void 0;
1389
+ }
1390
+ function buildMismatchEvent(ctx, eventId, t0, outcome) {
1391
+ const t1 = Date.now();
1392
+ return {
1393
+ eventId,
1394
+ toolName: ctx.toolName,
1395
+ configuredTimeoutMs: ctx.configuredTimeoutMs,
1396
+ mcpSdkDefaultMs: MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS,
1397
+ startedAt: new Date(t0).toISOString(),
1398
+ endedAt: new Date(t1).toISOString(),
1399
+ durationMs: t1 - t0,
1400
+ outcome: outcome.outcome,
1401
+ ...outcome.errorCategory !== void 0 ? { errorCategory: outcome.errorCategory } : {},
1402
+ ...outcome.errorMessage !== void 0 ? { errorMessage: outcome.errorMessage } : {}
1403
+ };
1404
+ }
1405
+ function classifyResult(result) {
1406
+ if (result.isError !== true) return { outcome: "success" };
1407
+ const errorCategory = extractErrorCategoryFromResult(result);
1408
+ const errorMessage = extractErrorMessageFromResult(result);
1409
+ return {
1410
+ outcome: "error",
1411
+ ...errorCategory !== void 0 ? { errorCategory } : {},
1412
+ ...errorMessage !== void 0 ? { errorMessage } : {}
1413
+ };
1414
+ }
1415
+ async function runMismatchedCall(ctx) {
1416
+ const eventId = randomUUID();
1417
+ const t0 = Date.now();
1418
+ ctx.log.warn(
1419
+ "MCP tool budget exceeds client default and no progressToken received \u2014 request likely to be killed by client before server-side deadline",
1420
+ {
1421
+ tool: ctx.toolName,
1422
+ eventId,
1423
+ configuredTimeoutMs: ctx.configuredTimeoutMs,
1424
+ mcpSdkDefaultMs: MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS,
1425
+ remediation: "Client should pass `onprogress` and `resetTimeoutOnProgress: true` when calling, or extend `options.timeout`. See docs/architecture/MCP_PROTOCOL.md."
1426
+ }
1427
+ );
1428
+ try {
1429
+ const result = await runWithContexts(ctx.handler, ctx.args, ctx.progressCtx, ctx.signal);
1430
+ appendTimeoutMismatchEvent(buildMismatchEvent(ctx, eventId, t0, classifyResult(result)));
1431
+ return result;
1432
+ } catch (err2) {
1433
+ appendTimeoutMismatchEvent(
1434
+ buildMismatchEvent(ctx, eventId, t0, {
1435
+ outcome: "error",
1436
+ errorMessage: getErrorMessage(err2).slice(0, 500)
1437
+ })
1438
+ );
1439
+ throw err2;
1440
+ }
1441
+ }
1356
1442
  function toSdkCallbackWithBudgetCheck(handler, toolName, configuredTimeoutMs, logger12) {
1357
1443
  const log = logger12 ?? wrapperLogger;
1358
1444
  return (args, extra) => {
1359
1445
  const progressCtx = extractProgressContext(extra);
1360
1446
  const signal = extra?.signal;
1361
- if (configuredTimeoutMs > MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS && progressCtx === void 0) {
1362
- log.warn(
1363
- "MCP tool budget exceeds client default and no progressToken received \u2014 request likely to be killed by client before server-side deadline",
1364
- {
1365
- tool: toolName,
1366
- configuredTimeoutMs,
1367
- mcpSdkDefaultMs: MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS,
1368
- remediation: "Client should pass `onprogress` and `resetTimeoutOnProgress: true` when calling, or extend `options.timeout`. See docs/architecture/MCP_PROTOCOL.md."
1369
- }
1370
- );
1371
- }
1372
- return runWithContexts(handler, args, progressCtx, signal);
1447
+ const isMismatch = configuredTimeoutMs > MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS && progressCtx === void 0;
1448
+ if (!isMismatch) return runWithContexts(handler, args, progressCtx, signal);
1449
+ return runMismatchedCall({
1450
+ log,
1451
+ handler,
1452
+ args,
1453
+ progressCtx,
1454
+ signal,
1455
+ toolName,
1456
+ configuredTimeoutMs
1457
+ });
1373
1458
  };
1374
1459
  }
1375
1460
 
@@ -2739,7 +2824,7 @@ async function createAutoAdapter(config = {}) {
2739
2824
  }
2740
2825
 
2741
2826
  // src/agents/collaboration/event-bus-helpers.ts
2742
- import { randomUUID } from "crypto";
2827
+ import { randomUUID as randomUUID2 } from "crypto";
2743
2828
  var DEFAULT_MAX_HISTORY_SIZE = 1e3;
2744
2829
  var MAX_SUBSCRIPTIONS = 500;
2745
2830
  var MAX_TOPIC_PATTERN_LENGTH = 200;
@@ -2760,10 +2845,10 @@ function topicMatchesPattern(topic, regex) {
2760
2845
  return regex.test(topic);
2761
2846
  }
2762
2847
  function generateEventId() {
2763
- return `evt-${String(getTimeProvider().now())}-${randomUUID().slice(0, 8)}`;
2848
+ return `evt-${String(getTimeProvider().now())}-${randomUUID2().slice(0, 8)}`;
2764
2849
  }
2765
2850
  function generateSubscriptionId() {
2766
- return `sub-${String(getTimeProvider().now())}-${randomUUID().slice(0, 8)}`;
2851
+ return `sub-${String(getTimeProvider().now())}-${randomUUID2().slice(0, 8)}`;
2767
2852
  }
2768
2853
  function applyHistoryFilters(history, filter) {
2769
2854
  let result = history;
@@ -8017,7 +8102,7 @@ var DEFAULT_BELIEF_CONFIG = {
8017
8102
  };
8018
8103
 
8019
8104
  // src/utils/id-utils.ts
8020
- import { randomUUID as randomUUID2 } from "crypto";
8105
+ import { randomUUID as randomUUID3 } from "crypto";
8021
8106
  function generateId(prefix, randomLength = 8) {
8022
8107
  const timestamp = getTimeProvider().now().toString(36);
8023
8108
  const random = getRandomProvider().random().toString(36).substring(2, 2 + randomLength);
@@ -8029,7 +8114,7 @@ function generateHyphenId(prefix, randomLength = 6) {
8029
8114
  return `${prefix}-${timestamp}-${random}`;
8030
8115
  }
8031
8116
  function generateUUID() {
8032
- return randomUUID2();
8117
+ return randomUUID3();
8033
8118
  }
8034
8119
 
8035
8120
  // src/context/belief-memory-helpers.ts
@@ -12195,7 +12280,7 @@ var ToolMemoryManager = class {
12195
12280
  };
12196
12281
 
12197
12282
  // src/orchestration/outcomes/outcome-store-persistence.ts
12198
- import { appendFileSync, readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync3 } from "fs";
12283
+ import { appendFileSync as appendFileSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync4 } from "fs";
12199
12284
  var PersistentOutcomeStore = class extends OutcomeStore {
12200
12285
  filePath;
12201
12286
  logger;
@@ -12246,7 +12331,7 @@ var PersistentOutcomeStore = class extends OutcomeStore {
12246
12331
  }
12247
12332
  }
12248
12333
  hydrate() {
12249
- if (!existsSync3(this.filePath)) {
12334
+ if (!existsSync4(this.filePath)) {
12250
12335
  this.logger.debug("No outcomes file found, starting fresh", {
12251
12336
  path: this.filePath
12252
12337
  });
@@ -12305,7 +12390,7 @@ var PersistentOutcomeStore = class extends OutcomeStore {
12305
12390
  }
12306
12391
  persistLine(outcome) {
12307
12392
  try {
12308
- appendFileSync(this.filePath, JSON.stringify(outcome) + "\n", "utf-8");
12393
+ appendFileSync2(this.filePath, JSON.stringify(outcome) + "\n", "utf-8");
12309
12394
  } catch (error) {
12310
12395
  const msg = getErrorMessage(error);
12311
12396
  this.logger.warn("Failed to persist outcome to disk", {
@@ -13330,4 +13415,4 @@ export {
13330
13415
  CONSENSUS_VOTE_OUTPUT_SCHEMA,
13331
13416
  registerConsensusVoteTool
13332
13417
  };
13333
- //# sourceMappingURL=chunk-TMOGKDC2.js.map
13418
+ //# sourceMappingURL=chunk-CPPZCNAS.js.map