@probelabs/probe 0.6.0-rc215 → 0.6.0-rc217

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.
@@ -33092,11 +33092,14 @@ async function delegate({
33092
33092
  enableTasks = false,
33093
33093
  enableMcp = false,
33094
33094
  mcpConfig = null,
33095
- mcpConfigPath = null
33095
+ mcpConfigPath = null,
33096
+ delegationManager = null
33097
+ // Optional per-instance manager, falls back to default singleton
33096
33098
  }) {
33097
33099
  if (!task || typeof task !== "string") {
33098
33100
  throw new Error("Task parameter is required and must be a string");
33099
33101
  }
33102
+ const manager = delegationManager || defaultDelegationManager;
33100
33103
  const sessionId = (0, import_crypto2.randomUUID)();
33101
33104
  const startTime = Date.now();
33102
33105
  const remainingIterations = Math.max(1, maxIterations - currentIteration);
@@ -33104,17 +33107,17 @@ async function delegate({
33104
33107
  let timeoutId = null;
33105
33108
  let acquired = false;
33106
33109
  try {
33107
- delegationManager.tryAcquire(parentSessionId);
33110
+ await manager.acquire(parentSessionId, debug);
33108
33111
  acquired = true;
33109
33112
  if (debug) {
33110
- const stats = delegationManager.getStats();
33113
+ const stats = manager.getStats();
33111
33114
  console.error(`[DELEGATE] Starting delegation session ${sessionId}`);
33112
33115
  console.error(`[DELEGATE] Parent session: ${parentSessionId || "none"}`);
33113
33116
  console.error(`[DELEGATE] Task: ${task}`);
33114
33117
  console.error(`[DELEGATE] Current iteration: ${currentIteration}/${maxIterations}`);
33115
33118
  console.error(`[DELEGATE] Remaining iterations for subagent: ${remainingIterations}`);
33116
33119
  console.error(`[DELEGATE] Timeout configured: ${timeout} seconds`);
33117
- console.error(`[DELEGATE] Global active delegations: ${stats.globalActive}/${stats.maxConcurrent}`);
33120
+ console.error(`[DELEGATE] Global active delegations: ${stats.globalActive}/${stats.maxConcurrent}, queue: ${stats.queueSize}`);
33118
33121
  console.error(`[DELEGATE] Using ProbeAgent SDK with ${promptType} prompt`);
33119
33122
  }
33120
33123
  const subagent = new ProbeAgent({
@@ -33208,7 +33211,7 @@ async function delegate({
33208
33211
  }
33209
33212
  }
33210
33213
  if (acquired) {
33211
- delegationManager.release(parentSessionId, debug);
33214
+ manager.release(parentSessionId, debug);
33212
33215
  }
33213
33216
  return response;
33214
33217
  } catch (error2) {
@@ -33218,7 +33221,7 @@ async function delegate({
33218
33221
  }
33219
33222
  const duration = Date.now() - startTime;
33220
33223
  if (acquired) {
33221
- delegationManager.release(parentSessionId, debug);
33224
+ manager.release(parentSessionId, debug);
33222
33225
  }
33223
33226
  if (debug) {
33224
33227
  console.error(`[DELEGATE] Task failed for session ${sessionId} after ${duration}ms`);
@@ -33246,7 +33249,7 @@ async function delegate({
33246
33249
  throw new Error(`Delegation failed: ${error2.message}`);
33247
33250
  }
33248
33251
  }
33249
- var import_crypto2, DelegationManager, delegationManager;
33252
+ var import_crypto2, DelegationManager, defaultDelegationManager;
33250
33253
  var init_delegate = __esm({
33251
33254
  "src/delegate.js"() {
33252
33255
  "use strict";
@@ -33256,8 +33259,10 @@ var init_delegate = __esm({
33256
33259
  constructor() {
33257
33260
  this.maxConcurrent = parseInt(process.env.MAX_CONCURRENT_DELEGATIONS || "3", 10);
33258
33261
  this.maxPerSession = parseInt(process.env.MAX_DELEGATIONS_PER_SESSION || "10", 10);
33262
+ this.defaultQueueTimeout = parseInt(process.env.DELEGATION_QUEUE_TIMEOUT || "60000", 10);
33259
33263
  this.sessionDelegations = /* @__PURE__ */ new Map();
33260
33264
  this.globalActive = 0;
33265
+ this.waitQueue = [];
33261
33266
  this.cleanupInterval = setInterval(() => {
33262
33267
  try {
33263
33268
  this.cleanupStaleSessions();
@@ -33272,13 +33277,14 @@ var init_delegate = __esm({
33272
33277
  /**
33273
33278
  * Check limits and increment counters (synchronous, atomic in Node.js event loop)
33274
33279
  * @param {string|null|undefined} parentSessionId - Parent session ID for tracking
33280
+ * @returns {boolean} true if acquired, false if would need to wait
33275
33281
  */
33276
33282
  tryAcquire(parentSessionId) {
33277
33283
  if (parentSessionId !== null && parentSessionId !== void 0 && typeof parentSessionId !== "string") {
33278
33284
  throw new TypeError("parentSessionId must be a string, null, or undefined");
33279
33285
  }
33280
33286
  if (this.globalActive >= this.maxConcurrent) {
33281
- throw new Error(`Maximum concurrent delegations (${this.maxConcurrent}) reached. Please wait for some delegations to complete.`);
33287
+ return false;
33282
33288
  }
33283
33289
  if (parentSessionId) {
33284
33290
  const sessionData = this.sessionDelegations.get(parentSessionId);
@@ -33287,6 +33293,14 @@ var init_delegate = __esm({
33287
33293
  throw new Error(`Maximum delegations per session (${this.maxPerSession}) reached for session ${parentSessionId}`);
33288
33294
  }
33289
33295
  }
33296
+ this._incrementCounters(parentSessionId);
33297
+ return true;
33298
+ }
33299
+ /**
33300
+ * Internal helper to increment counters
33301
+ * @private
33302
+ */
33303
+ _incrementCounters(parentSessionId) {
33290
33304
  this.globalActive++;
33291
33305
  if (parentSessionId) {
33292
33306
  const sessionData = this.sessionDelegations.get(parentSessionId);
@@ -33300,10 +33314,60 @@ var init_delegate = __esm({
33300
33314
  });
33301
33315
  }
33302
33316
  }
33303
- return true;
33304
33317
  }
33305
33318
  /**
33306
- * Decrement counters (synchronous, atomic in Node.js event loop)
33319
+ * Acquire a delegation slot, waiting in queue if necessary
33320
+ * @param {string|null|undefined} parentSessionId - Parent session ID for tracking
33321
+ * @param {boolean} debug - Enable debug logging
33322
+ * @param {number|null} queueTimeout - Max time to wait in queue (ms). Defaults to this.defaultQueueTimeout. Set to 0 to disable.
33323
+ * @returns {Promise<boolean>} Resolves when slot is acquired, rejects on timeout or session limit error
33324
+ */
33325
+ async acquire(parentSessionId, debug = false, queueTimeout = null) {
33326
+ const effectiveTimeout = queueTimeout !== null ? queueTimeout : this.defaultQueueTimeout;
33327
+ if (this.tryAcquire(parentSessionId)) {
33328
+ return true;
33329
+ }
33330
+ if (debug) {
33331
+ console.error(`[DelegationManager] Slot unavailable (${this.globalActive}/${this.maxConcurrent}), queuing... (queue size: ${this.waitQueue.length}, timeout: ${effectiveTimeout}ms)`);
33332
+ }
33333
+ return new Promise((resolve7, reject2) => {
33334
+ const entry = {
33335
+ resolve: null,
33336
+ // Will be wrapped below
33337
+ reject: null,
33338
+ // Will be wrapped below
33339
+ parentSessionId,
33340
+ debug,
33341
+ queuedAt: Date.now(),
33342
+ timeoutId: null
33343
+ };
33344
+ let settled = false;
33345
+ entry.resolve = (value) => {
33346
+ if (settled) return;
33347
+ settled = true;
33348
+ if (entry.timeoutId) clearTimeout(entry.timeoutId);
33349
+ resolve7(value);
33350
+ };
33351
+ entry.reject = (error2) => {
33352
+ if (settled) return;
33353
+ settled = true;
33354
+ if (entry.timeoutId) clearTimeout(entry.timeoutId);
33355
+ reject2(error2);
33356
+ };
33357
+ if (effectiveTimeout > 0) {
33358
+ entry.timeoutId = setTimeout(() => {
33359
+ const index = this.waitQueue.indexOf(entry);
33360
+ if (index !== -1) {
33361
+ this.waitQueue.splice(index, 1);
33362
+ }
33363
+ entry.reject(new Error(`Delegation queue timeout: waited ${effectiveTimeout}ms for an available slot`));
33364
+ }, effectiveTimeout);
33365
+ }
33366
+ this.waitQueue.push(entry);
33367
+ });
33368
+ }
33369
+ /**
33370
+ * Decrement counters and process queue (synchronous, atomic in Node.js event loop)
33307
33371
  */
33308
33372
  release(parentSessionId, debug = false) {
33309
33373
  this.globalActive = Math.max(0, this.globalActive - 1);
@@ -33317,7 +33381,36 @@ var init_delegate = __esm({
33317
33381
  }
33318
33382
  }
33319
33383
  if (debug) {
33320
- console.error(`[DELEGATE] Released. Global active: ${this.globalActive}`);
33384
+ console.error(`[DELEGATE] Released. Global active: ${this.globalActive}, queue size: ${this.waitQueue.length}`);
33385
+ }
33386
+ this._processQueue(debug);
33387
+ }
33388
+ /**
33389
+ * Process the wait queue - grant slot to next waiting delegation
33390
+ * @private
33391
+ */
33392
+ _processQueue(debug = false) {
33393
+ while (this.waitQueue.length > 0 && this.globalActive < this.maxConcurrent) {
33394
+ const next = this.waitQueue.shift();
33395
+ if (!next) break;
33396
+ const { resolve: resolve7, reject: reject2, parentSessionId, queuedAt } = next;
33397
+ if (parentSessionId) {
33398
+ const sessionData = this.sessionDelegations.get(parentSessionId);
33399
+ const sessionCount = sessionData?.count || 0;
33400
+ if (sessionCount >= this.maxPerSession) {
33401
+ if (debug) {
33402
+ console.error(`[DelegationManager] Session limit (${this.maxPerSession}) reached for queued item, rejecting`);
33403
+ }
33404
+ reject2(new Error(`Maximum delegations per session (${this.maxPerSession}) reached for session ${parentSessionId}`));
33405
+ continue;
33406
+ }
33407
+ }
33408
+ this._incrementCounters(parentSessionId);
33409
+ if (debug) {
33410
+ const waitTime = Date.now() - queuedAt;
33411
+ console.error(`[DelegationManager] Granted slot from queue (waited ${waitTime}ms). Active: ${this.globalActive}/${this.maxConcurrent}`);
33412
+ }
33413
+ resolve7(true);
33321
33414
  }
33322
33415
  }
33323
33416
  /**
@@ -33328,7 +33421,9 @@ var init_delegate = __esm({
33328
33421
  globalActive: this.globalActive,
33329
33422
  maxConcurrent: this.maxConcurrent,
33330
33423
  maxPerSession: this.maxPerSession,
33331
- sessionCount: this.sessionDelegations.size
33424
+ defaultQueueTimeout: this.defaultQueueTimeout,
33425
+ sessionCount: this.sessionDelegations.size,
33426
+ queueSize: this.waitQueue.length
33332
33427
  };
33333
33428
  }
33334
33429
  /**
@@ -33350,11 +33445,20 @@ var init_delegate = __esm({
33350
33445
  clearInterval(this.cleanupInterval);
33351
33446
  this.cleanupInterval = null;
33352
33447
  }
33448
+ for (const entry of this.waitQueue) {
33449
+ if (entry.timeoutId) {
33450
+ clearTimeout(entry.timeoutId);
33451
+ }
33452
+ if (entry.reject) {
33453
+ entry.reject(new Error("DelegationManager was cleaned up"));
33454
+ }
33455
+ }
33456
+ this.waitQueue = [];
33353
33457
  this.sessionDelegations.clear();
33354
33458
  this.globalActive = 0;
33355
33459
  }
33356
33460
  };
33357
- delegationManager = new DelegationManager();
33461
+ defaultDelegationManager = new DelegationManager();
33358
33462
  }
33359
33463
  });
33360
33464
 
@@ -33466,7 +33570,9 @@ Instructions:
33466
33570
  enableBash: false,
33467
33571
  promptType: "code-researcher",
33468
33572
  allowedTools: ["extract"],
33469
- maxIterations: 5
33573
+ maxIterations: 5,
33574
+ delegationManager: options.delegationManager
33575
+ // Per-instance delegation limits
33470
33576
  // timeout removed - inherit default from delegate (300s)
33471
33577
  });
33472
33578
  return { chunk, result };
@@ -33564,7 +33670,9 @@ Organize all findings into clear categories with items listed under each.${compl
33564
33670
  enableBash: false,
33565
33671
  promptType: "code-researcher",
33566
33672
  allowedTools: [],
33567
- maxIterations: 5
33673
+ maxIterations: 5,
33674
+ delegationManager: options.delegationManager
33675
+ // Per-instance delegation limits
33568
33676
  // timeout removed - inherit default from delegate (300s)
33569
33677
  });
33570
33678
  return result;
@@ -33627,7 +33735,9 @@ CRITICAL: Do NOT guess keywords. Actually run searches and see what returns resu
33627
33735
  enableBash: false,
33628
33736
  promptType: "code-researcher",
33629
33737
  // Full tool access for exploration and experimentation
33630
- maxIterations: 15
33738
+ maxIterations: 15,
33739
+ delegationManager: options.delegationManager
33740
+ // Per-instance delegation limits
33631
33741
  // timeout removed - inherit default from delegate (300s)
33632
33742
  });
33633
33743
  const plan = parsePlanningResult(stripResultTags(result));
@@ -33683,7 +33793,9 @@ IMPORTANT: When completing, use the FULL format: <attempt_completion><result>YOU
33683
33793
  enableBash: false,
33684
33794
  promptType: "code-researcher",
33685
33795
  allowedTools: [],
33686
- maxIterations: 5
33796
+ maxIterations: 5,
33797
+ delegationManager: options.delegationManager
33798
+ // Per-instance delegation limits
33687
33799
  // timeout removed - inherit default from delegate (300s)
33688
33800
  });
33689
33801
  return stripResultTags(result);
@@ -33705,7 +33817,9 @@ async function analyzeAll(options) {
33705
33817
  model,
33706
33818
  tracer,
33707
33819
  chunkSizeTokens = DEFAULT_CHUNK_SIZE_TOKENS,
33708
- maxChunks = MAX_CHUNKS
33820
+ maxChunks = MAX_CHUNKS,
33821
+ delegationManager = null
33822
+ // Per-instance delegation limits
33709
33823
  } = options;
33710
33824
  if (!question) {
33711
33825
  throw new Error('The "question" parameter is required.');
@@ -33717,7 +33831,9 @@ async function analyzeAll(options) {
33717
33831
  allowedFolders,
33718
33832
  provider,
33719
33833
  model,
33720
- tracer
33834
+ tracer,
33835
+ delegationManager
33836
+ // Per-instance delegation limits
33721
33837
  };
33722
33838
  if (debug) {
33723
33839
  console.error(`[analyze_all] Starting analysis`);
@@ -39644,7 +39760,7 @@ var init_vercel = __esm({
39644
39760
  });
39645
39761
  };
39646
39762
  delegateTool = (options = {}) => {
39647
- const { debug = false, timeout = 300, cwd, allowedFolders, enableBash = false, bashConfig, architectureFileName, enableMcp = false, mcpConfig = null, mcpConfigPath = null } = options;
39763
+ const { debug = false, timeout = 300, cwd, allowedFolders, enableBash = false, bashConfig, architectureFileName, enableMcp = false, mcpConfig = null, mcpConfigPath = null, delegationManager = null } = options;
39648
39764
  return (0, import_ai2.tool)({
39649
39765
  name: "delegate",
39650
39766
  description: delegateDescription,
@@ -39706,14 +39822,16 @@ var init_vercel = __esm({
39706
39822
  searchDelegate,
39707
39823
  enableMcp,
39708
39824
  mcpConfig,
39709
- mcpConfigPath
39825
+ mcpConfigPath,
39826
+ delegationManager
39827
+ // Per-instance delegation limits
39710
39828
  });
39711
39829
  return result;
39712
39830
  }
39713
39831
  });
39714
39832
  };
39715
39833
  analyzeAllTool = (options = {}) => {
39716
- const { sessionId, debug = false } = options;
39834
+ const { sessionId, debug = false, delegationManager = null } = options;
39717
39835
  return (0, import_ai2.tool)({
39718
39836
  name: "analyze_all",
39719
39837
  description: analyzeAllDescription,
@@ -39741,7 +39859,9 @@ var init_vercel = __esm({
39741
39859
  allowedFolders: options.allowedFolders,
39742
39860
  provider: options.provider,
39743
39861
  model: options.model,
39744
- tracer: options.tracer
39862
+ tracer: options.tracer,
39863
+ delegationManager
39864
+ // Per-instance delegation limits
39745
39865
  });
39746
39866
  return result;
39747
39867
  } catch (error2) {
@@ -98904,6 +99024,7 @@ var init_ProbeAgent = __esm({
98904
99024
  init_contextCompactor();
98905
99025
  init_error_types();
98906
99026
  init_outputTruncator();
99027
+ init_delegate();
98907
99028
  init_tasks();
98908
99029
  import_dotenv2.default.config();
98909
99030
  MAX_TOOL_ITERATIONS = (() => {
@@ -99045,6 +99166,7 @@ var init_ProbeAgent = __esm({
99045
99166
  this._mcpInitialized = false;
99046
99167
  this.enableTasks = !!options.enableTasks;
99047
99168
  this.taskManager = null;
99169
+ this.delegationManager = new DelegationManager();
99048
99170
  this.retryConfig = options.retry || {};
99049
99171
  this.retryManager = null;
99050
99172
  this.fallbackConfig = options.fallback || null;
@@ -99216,6 +99338,8 @@ var init_ProbeAgent = __esm({
99216
99338
  architectureFileName: this.architectureFileName,
99217
99339
  provider: this.clientApiProvider,
99218
99340
  model: this.clientApiModel,
99341
+ delegationManager: this.delegationManager,
99342
+ // Per-instance delegation limits
99219
99343
  isToolAllowed
99220
99344
  };
99221
99345
  const baseTools = createTools(configOptions);
@@ -102234,6 +102358,16 @@ Convert your previous response content into actual JSON data that follows this s
102234
102358
  console.error("Error cleaning up MCP bridge:", error2);
102235
102359
  }
102236
102360
  }
102361
+ if (this.delegationManager) {
102362
+ try {
102363
+ this.delegationManager.cleanup();
102364
+ if (this.debug) {
102365
+ console.log("[DEBUG] Delegation manager cleaned up");
102366
+ }
102367
+ } catch (error2) {
102368
+ console.error("Error cleaning up delegation manager:", error2);
102369
+ }
102370
+ }
102237
102371
  this.clearHistory();
102238
102372
  }
102239
102373
  /**