@probelabs/probe 0.6.0-rc154 → 0.6.0-rc159
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.
- package/bin/binaries/probe-v0.6.0-rc159-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc159-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc159-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc159-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc159-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.d.ts +2 -0
- package/build/agent/ProbeAgent.js +20 -4
- package/build/agent/acp/server.js +1 -0
- package/build/agent/index.js +464 -216
- package/build/delegate.js +326 -201
- package/build/downloader.js +46 -17
- package/build/extractor.js +12 -12
- package/build/tools/vercel.js +55 -14
- package/build/utils.js +18 -9
- package/cjs/agent/ProbeAgent.cjs +478 -234
- package/cjs/index.cjs +41496 -41272
- package/package.json +2 -2
- package/src/agent/ProbeAgent.d.ts +2 -0
- package/src/agent/ProbeAgent.js +20 -4
- package/src/agent/acp/server.js +1 -0
- package/src/agent/index.js +8 -0
- package/src/delegate.js +326 -201
- package/src/downloader.js +46 -17
- package/src/extractor.js +12 -12
- package/src/tools/vercel.js +55 -14
- package/src/utils.js +18 -9
- package/bin/binaries/probe-v0.6.0-rc154-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc154-aarch64-unknown-linux-gnu.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc154-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc154-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc154-x86_64-unknown-linux-gnu.tar.gz +0 -0
package/cjs/agent/ProbeAgent.cjs
CHANGED
|
@@ -2440,7 +2440,7 @@ var require_dist_cjs15 = __commonJS({
|
|
|
2440
2440
|
var MIN_WAIT_TIME = 6e3;
|
|
2441
2441
|
async function writeRequestBody(httpRequest, request, maxContinueTimeoutMs = MIN_WAIT_TIME) {
|
|
2442
2442
|
const headers = request.headers ?? {};
|
|
2443
|
-
const expect = headers
|
|
2443
|
+
const expect = headers.Expect || headers.expect;
|
|
2444
2444
|
let timeoutId = -1;
|
|
2445
2445
|
let sendBody = true;
|
|
2446
2446
|
if (expect === "100-continue") {
|
|
@@ -2568,6 +2568,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2568
2568
|
this.config = await this.configProvider;
|
|
2569
2569
|
}
|
|
2570
2570
|
return new Promise((_resolve, _reject) => {
|
|
2571
|
+
const config = this.config;
|
|
2571
2572
|
let writeRequestBodyPromise = void 0;
|
|
2572
2573
|
const timeouts = [];
|
|
2573
2574
|
const resolve4 = async (arg) => {
|
|
@@ -2580,9 +2581,6 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2580
2581
|
timeouts.forEach(timing.clearTimeout);
|
|
2581
2582
|
_reject(arg);
|
|
2582
2583
|
};
|
|
2583
|
-
if (!this.config) {
|
|
2584
|
-
throw new Error("Node HTTP request handler config is not resolved");
|
|
2585
|
-
}
|
|
2586
2584
|
if (abortSignal?.aborted) {
|
|
2587
2585
|
const abortError = new Error("Request aborted");
|
|
2588
2586
|
abortError.name = "AbortError";
|
|
@@ -2590,10 +2588,18 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2590
2588
|
return;
|
|
2591
2589
|
}
|
|
2592
2590
|
const isSSL = request.protocol === "https:";
|
|
2593
|
-
const
|
|
2591
|
+
const headers = request.headers ?? {};
|
|
2592
|
+
const expectContinue = (headers.Expect ?? headers.expect) === "100-continue";
|
|
2593
|
+
let agent = isSSL ? config.httpsAgent : config.httpAgent;
|
|
2594
|
+
if (expectContinue) {
|
|
2595
|
+
agent = new (isSSL ? https.Agent : http.Agent)({
|
|
2596
|
+
keepAlive: false,
|
|
2597
|
+
maxSockets: Infinity
|
|
2598
|
+
});
|
|
2599
|
+
}
|
|
2594
2600
|
timeouts.push(timing.setTimeout(() => {
|
|
2595
|
-
this.socketWarningTimestamp = _NodeHttpHandler.checkSocketUsage(agent, this.socketWarningTimestamp,
|
|
2596
|
-
},
|
|
2601
|
+
this.socketWarningTimestamp = _NodeHttpHandler.checkSocketUsage(agent, this.socketWarningTimestamp, config.logger);
|
|
2602
|
+
}, config.socketAcquisitionWarningTimeout ?? (config.requestTimeout ?? 2e3) + (config.connectionTimeout ?? 1e3)));
|
|
2597
2603
|
const queryString = querystringBuilder.buildQueryString(request.query || {});
|
|
2598
2604
|
let auth = void 0;
|
|
2599
2605
|
if (request.username != null || request.password != null) {
|
|
@@ -2655,10 +2661,10 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
2655
2661
|
abortSignal.onabort = onAbort;
|
|
2656
2662
|
}
|
|
2657
2663
|
}
|
|
2658
|
-
const effectiveRequestTimeout = requestTimeout ??
|
|
2659
|
-
timeouts.push(setConnectionTimeout(req, reject2,
|
|
2660
|
-
timeouts.push(setRequestTimeout(req, reject2, effectiveRequestTimeout,
|
|
2661
|
-
timeouts.push(setSocketTimeout(req, reject2,
|
|
2664
|
+
const effectiveRequestTimeout = requestTimeout ?? config.requestTimeout;
|
|
2665
|
+
timeouts.push(setConnectionTimeout(req, reject2, config.connectionTimeout));
|
|
2666
|
+
timeouts.push(setRequestTimeout(req, reject2, effectiveRequestTimeout, config.throwOnRequestTimeout, config.logger ?? console));
|
|
2667
|
+
timeouts.push(setSocketTimeout(req, reject2, config.socketTimeout));
|
|
2662
2668
|
const httpAgent = nodeHttpsOptions.agent;
|
|
2663
2669
|
if (typeof httpAgent === "object" && "keepAlive" in httpAgent) {
|
|
2664
2670
|
timeouts.push(setSocketKeepAlive(req, {
|
|
@@ -27643,6 +27649,28 @@ var init_directory_resolver = __esm({
|
|
|
27643
27649
|
});
|
|
27644
27650
|
|
|
27645
27651
|
// src/downloader.js
|
|
27652
|
+
function sanitizeError(err) {
|
|
27653
|
+
try {
|
|
27654
|
+
const status = err?.response?.status;
|
|
27655
|
+
const statusText = err?.response?.statusText;
|
|
27656
|
+
const url = err?.config?.url || err?.response?.config?.url;
|
|
27657
|
+
const code = err?.code;
|
|
27658
|
+
const serverMsg = typeof err?.response?.data === "string" ? err.response.data.slice(0, 500) : typeof err?.response?.data?.message === "string" ? err.response.data.message : void 0;
|
|
27659
|
+
const base = err?.message || String(err);
|
|
27660
|
+
const parts = [base];
|
|
27661
|
+
if (status || statusText) parts.push(`[${status ?? ""} ${statusText ?? ""}]`.trim());
|
|
27662
|
+
if (code) parts.push(`code=${code}`);
|
|
27663
|
+
if (url) parts.push(`url=${url}`);
|
|
27664
|
+
if (serverMsg) parts.push(`server="${String(serverMsg).replace(/\s+/g, " ").trim()}"`);
|
|
27665
|
+
const e3 = new Error(parts.filter(Boolean).join(" "));
|
|
27666
|
+
if (status) e3.status = status;
|
|
27667
|
+
if (code) e3.code = code;
|
|
27668
|
+
if (url) e3.url = url;
|
|
27669
|
+
return e3;
|
|
27670
|
+
} catch (_2) {
|
|
27671
|
+
return new Error(err?.message || String(err));
|
|
27672
|
+
}
|
|
27673
|
+
}
|
|
27646
27674
|
async function acquireFileLock(lockPath, version) {
|
|
27647
27675
|
const lockData = {
|
|
27648
27676
|
version,
|
|
@@ -27791,7 +27819,7 @@ function detectOsArch() {
|
|
|
27791
27819
|
case "linux":
|
|
27792
27820
|
osInfo = {
|
|
27793
27821
|
type: "linux",
|
|
27794
|
-
keywords: ["linux", "Linux", "gnu"]
|
|
27822
|
+
keywords: ["linux", "Linux", "musl", "gnu"]
|
|
27795
27823
|
};
|
|
27796
27824
|
break;
|
|
27797
27825
|
case "darwin":
|
|
@@ -27835,7 +27863,7 @@ function constructAssetInfo(version, osInfo, archInfo) {
|
|
|
27835
27863
|
let extension;
|
|
27836
27864
|
switch (osInfo.type) {
|
|
27837
27865
|
case "linux":
|
|
27838
|
-
platform = `${archInfo.type}-unknown-linux-
|
|
27866
|
+
platform = `${archInfo.type}-unknown-linux-musl`;
|
|
27839
27867
|
extension = "tar.gz";
|
|
27840
27868
|
break;
|
|
27841
27869
|
case "darwin":
|
|
@@ -27952,7 +27980,7 @@ async function getLatestRelease(version) {
|
|
|
27952
27980
|
}
|
|
27953
27981
|
return { tag: tag2, assets };
|
|
27954
27982
|
}
|
|
27955
|
-
throw error2;
|
|
27983
|
+
throw sanitizeError(error2);
|
|
27956
27984
|
}
|
|
27957
27985
|
}
|
|
27958
27986
|
function findBestAsset(assets, osInfo, archInfo) {
|
|
@@ -28166,7 +28194,7 @@ async function extractBinary(assetPath, outputDir) {
|
|
|
28166
28194
|
return binaryPath;
|
|
28167
28195
|
} catch (error2) {
|
|
28168
28196
|
console.error(`Error extracting binary: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
28169
|
-
throw error2;
|
|
28197
|
+
throw sanitizeError(error2);
|
|
28170
28198
|
}
|
|
28171
28199
|
}
|
|
28172
28200
|
async function getVersionInfo(binDir) {
|
|
@@ -28331,8 +28359,8 @@ async function downloadProbeBinary(version) {
|
|
|
28331
28359
|
}
|
|
28332
28360
|
return await withDownloadLock(version, () => doDownload(version));
|
|
28333
28361
|
} catch (error2) {
|
|
28334
|
-
console.error("Error downloading probe binary:", error2);
|
|
28335
|
-
throw error2;
|
|
28362
|
+
console.error("Error downloading probe binary:", error2?.message || String(error2));
|
|
28363
|
+
throw sanitizeError(error2);
|
|
28336
28364
|
}
|
|
28337
28365
|
}
|
|
28338
28366
|
var import_axios, import_fs_extra2, import_path2, import_crypto, import_util3, import_child_process, import_tar, import_os2, import_url2, exec, REPO_OWNER, REPO_NAME, BINARY_NAME, __filename2, __dirname2, downloadLocks, LOCK_TIMEOUT_MS, LOCK_POLL_INTERVAL_MS, MAX_LOCK_WAIT_MS;
|
|
@@ -28375,9 +28403,15 @@ async function getBinaryPath(options = {}) {
|
|
|
28375
28403
|
probeBinaryPath = await downloadProbeBinary(version);
|
|
28376
28404
|
return probeBinaryPath;
|
|
28377
28405
|
}
|
|
28378
|
-
const binDir = await getPackageBinDir();
|
|
28379
28406
|
const isWindows = process.platform === "win32";
|
|
28380
28407
|
const binaryName = isWindows ? "probe.exe" : "probe-binary";
|
|
28408
|
+
const localPackageBin = import_path3.default.resolve(__dirname3, "..", "bin");
|
|
28409
|
+
const localBinaryPath = import_path3.default.join(localPackageBin, binaryName);
|
|
28410
|
+
if (import_fs_extra3.default.existsSync(localBinaryPath) && !forceDownload) {
|
|
28411
|
+
probeBinaryPath = localBinaryPath;
|
|
28412
|
+
return probeBinaryPath;
|
|
28413
|
+
}
|
|
28414
|
+
const binDir = await getPackageBinDir();
|
|
28381
28415
|
const binaryPath = import_path3.default.join(binDir, binaryName);
|
|
28382
28416
|
if (import_fs_extra3.default.existsSync(binaryPath) && !forceDownload) {
|
|
28383
28417
|
probeBinaryPath = binaryPath;
|
|
@@ -28822,6 +28856,262 @@ var init_grep = __esm({
|
|
|
28822
28856
|
}
|
|
28823
28857
|
});
|
|
28824
28858
|
|
|
28859
|
+
// src/delegate.js
|
|
28860
|
+
async function delegate({
|
|
28861
|
+
task,
|
|
28862
|
+
timeout = 300,
|
|
28863
|
+
debug = false,
|
|
28864
|
+
currentIteration = 0,
|
|
28865
|
+
maxIterations = 30,
|
|
28866
|
+
tracer = null,
|
|
28867
|
+
parentSessionId = null,
|
|
28868
|
+
path: path7 = null,
|
|
28869
|
+
provider = null,
|
|
28870
|
+
model = null
|
|
28871
|
+
}) {
|
|
28872
|
+
if (!task || typeof task !== "string") {
|
|
28873
|
+
throw new Error("Task parameter is required and must be a string");
|
|
28874
|
+
}
|
|
28875
|
+
const sessionId = (0, import_crypto2.randomUUID)();
|
|
28876
|
+
const startTime = Date.now();
|
|
28877
|
+
const remainingIterations = Math.max(1, maxIterations - currentIteration);
|
|
28878
|
+
const delegationSpan = tracer ? tracer.createDelegationSpan(sessionId, task) : null;
|
|
28879
|
+
let timeoutId = null;
|
|
28880
|
+
let acquired = false;
|
|
28881
|
+
try {
|
|
28882
|
+
delegationManager.tryAcquire(parentSessionId);
|
|
28883
|
+
acquired = true;
|
|
28884
|
+
if (debug) {
|
|
28885
|
+
const stats = delegationManager.getStats();
|
|
28886
|
+
console.error(`[DELEGATE] Starting delegation session ${sessionId}`);
|
|
28887
|
+
console.error(`[DELEGATE] Parent session: ${parentSessionId || "none"}`);
|
|
28888
|
+
console.error(`[DELEGATE] Task: ${task}`);
|
|
28889
|
+
console.error(`[DELEGATE] Current iteration: ${currentIteration}/${maxIterations}`);
|
|
28890
|
+
console.error(`[DELEGATE] Remaining iterations for subagent: ${remainingIterations}`);
|
|
28891
|
+
console.error(`[DELEGATE] Timeout configured: ${timeout} seconds`);
|
|
28892
|
+
console.error(`[DELEGATE] Global active delegations: ${stats.globalActive}/${stats.maxConcurrent}`);
|
|
28893
|
+
console.error(`[DELEGATE] Using ProbeAgent SDK with code-researcher prompt`);
|
|
28894
|
+
}
|
|
28895
|
+
const subagent = new ProbeAgent({
|
|
28896
|
+
sessionId,
|
|
28897
|
+
promptType: "code-researcher",
|
|
28898
|
+
// Clean prompt, not inherited from parent
|
|
28899
|
+
enableDelegate: false,
|
|
28900
|
+
// Explicitly disable delegation to prevent recursion
|
|
28901
|
+
disableMermaidValidation: true,
|
|
28902
|
+
// Faster processing
|
|
28903
|
+
disableJsonValidation: true,
|
|
28904
|
+
// Simpler responses
|
|
28905
|
+
maxIterations: remainingIterations,
|
|
28906
|
+
debug,
|
|
28907
|
+
tracer,
|
|
28908
|
+
path: path7,
|
|
28909
|
+
// Inherit from parent
|
|
28910
|
+
provider,
|
|
28911
|
+
// Inherit from parent
|
|
28912
|
+
model
|
|
28913
|
+
// Inherit from parent
|
|
28914
|
+
});
|
|
28915
|
+
if (debug) {
|
|
28916
|
+
console.error(`[DELEGATE] Created subagent with session ${sessionId}`);
|
|
28917
|
+
console.error(`[DELEGATE] Subagent config: promptType=code-researcher, enableDelegate=false, maxIterations=${remainingIterations}`);
|
|
28918
|
+
}
|
|
28919
|
+
const timeoutPromise = new Promise((_2, reject2) => {
|
|
28920
|
+
timeoutId = setTimeout(() => {
|
|
28921
|
+
reject2(new Error(`Delegation timed out after ${timeout} seconds`));
|
|
28922
|
+
}, timeout * 1e3);
|
|
28923
|
+
});
|
|
28924
|
+
const answerPromise = subagent.answer(task);
|
|
28925
|
+
const response = await Promise.race([answerPromise, timeoutPromise]);
|
|
28926
|
+
if (timeoutId !== null) {
|
|
28927
|
+
clearTimeout(timeoutId);
|
|
28928
|
+
timeoutId = null;
|
|
28929
|
+
}
|
|
28930
|
+
const duration = Date.now() - startTime;
|
|
28931
|
+
if (typeof response !== "string") {
|
|
28932
|
+
throw new Error("Delegate agent returned invalid response (not a string)");
|
|
28933
|
+
}
|
|
28934
|
+
const trimmedResponse = response.trim();
|
|
28935
|
+
if (trimmedResponse.length === 0) {
|
|
28936
|
+
throw new Error("Delegate agent returned empty or whitespace-only response");
|
|
28937
|
+
}
|
|
28938
|
+
if (trimmedResponse.includes("\0")) {
|
|
28939
|
+
throw new Error("Delegate agent returned response containing null bytes");
|
|
28940
|
+
}
|
|
28941
|
+
if (debug) {
|
|
28942
|
+
console.error(`[DELEGATE] Task completed successfully for session ${sessionId}`);
|
|
28943
|
+
console.error(`[DELEGATE] Duration: ${(duration / 1e3).toFixed(2)}s`);
|
|
28944
|
+
console.error(`[DELEGATE] Response length: ${response.length} chars`);
|
|
28945
|
+
}
|
|
28946
|
+
if (tracer) {
|
|
28947
|
+
tracer.recordDelegationEvent("completed", {
|
|
28948
|
+
"delegation.session_id": sessionId,
|
|
28949
|
+
"delegation.parent_session_id": parentSessionId,
|
|
28950
|
+
"delegation.duration_ms": duration,
|
|
28951
|
+
"delegation.response_length": response.length,
|
|
28952
|
+
"delegation.success": true
|
|
28953
|
+
});
|
|
28954
|
+
if (delegationSpan) {
|
|
28955
|
+
delegationSpan.setAttributes({
|
|
28956
|
+
"delegation.result.success": true,
|
|
28957
|
+
"delegation.result.response_length": response.length,
|
|
28958
|
+
"delegation.result.duration_ms": duration
|
|
28959
|
+
});
|
|
28960
|
+
delegationSpan.setStatus({ code: 1 });
|
|
28961
|
+
delegationSpan.end();
|
|
28962
|
+
}
|
|
28963
|
+
}
|
|
28964
|
+
if (acquired) {
|
|
28965
|
+
delegationManager.release(parentSessionId, debug);
|
|
28966
|
+
}
|
|
28967
|
+
return response;
|
|
28968
|
+
} catch (error2) {
|
|
28969
|
+
if (timeoutId !== null) {
|
|
28970
|
+
clearTimeout(timeoutId);
|
|
28971
|
+
timeoutId = null;
|
|
28972
|
+
}
|
|
28973
|
+
const duration = Date.now() - startTime;
|
|
28974
|
+
if (acquired) {
|
|
28975
|
+
delegationManager.release(parentSessionId, debug);
|
|
28976
|
+
}
|
|
28977
|
+
if (debug) {
|
|
28978
|
+
console.error(`[DELEGATE] Task failed for session ${sessionId} after ${duration}ms`);
|
|
28979
|
+
console.error(`[DELEGATE] Error: ${error2.message}`);
|
|
28980
|
+
console.error(`[DELEGATE] Stack: ${error2.stack}`);
|
|
28981
|
+
}
|
|
28982
|
+
if (tracer) {
|
|
28983
|
+
tracer.recordDelegationEvent("failed", {
|
|
28984
|
+
"delegation.session_id": sessionId,
|
|
28985
|
+
"delegation.parent_session_id": parentSessionId,
|
|
28986
|
+
"delegation.duration_ms": duration,
|
|
28987
|
+
"delegation.error_message": error2.message,
|
|
28988
|
+
"delegation.success": false
|
|
28989
|
+
});
|
|
28990
|
+
if (delegationSpan) {
|
|
28991
|
+
delegationSpan.setAttributes({
|
|
28992
|
+
"delegation.result.success": false,
|
|
28993
|
+
"delegation.result.error": error2.message,
|
|
28994
|
+
"delegation.result.duration_ms": duration
|
|
28995
|
+
});
|
|
28996
|
+
delegationSpan.setStatus({ code: 2, message: error2.message });
|
|
28997
|
+
delegationSpan.end();
|
|
28998
|
+
}
|
|
28999
|
+
}
|
|
29000
|
+
throw new Error(`Delegation failed: ${error2.message}`);
|
|
29001
|
+
}
|
|
29002
|
+
}
|
|
29003
|
+
var import_crypto2, DelegationManager, delegationManager;
|
|
29004
|
+
var init_delegate = __esm({
|
|
29005
|
+
"src/delegate.js"() {
|
|
29006
|
+
"use strict";
|
|
29007
|
+
import_crypto2 = require("crypto");
|
|
29008
|
+
init_ProbeAgent();
|
|
29009
|
+
DelegationManager = class {
|
|
29010
|
+
constructor() {
|
|
29011
|
+
this.maxConcurrent = parseInt(process.env.MAX_CONCURRENT_DELEGATIONS || "3", 10);
|
|
29012
|
+
this.maxPerSession = parseInt(process.env.MAX_DELEGATIONS_PER_SESSION || "10", 10);
|
|
29013
|
+
this.sessionDelegations = /* @__PURE__ */ new Map();
|
|
29014
|
+
this.globalActive = 0;
|
|
29015
|
+
this.cleanupInterval = setInterval(() => {
|
|
29016
|
+
try {
|
|
29017
|
+
this.cleanupStaleSessions();
|
|
29018
|
+
} catch (error2) {
|
|
29019
|
+
console.error("[DelegationManager] Error during cleanup:", error2);
|
|
29020
|
+
}
|
|
29021
|
+
}, 5 * 60 * 1e3);
|
|
29022
|
+
if (this.cleanupInterval.unref) {
|
|
29023
|
+
this.cleanupInterval.unref();
|
|
29024
|
+
}
|
|
29025
|
+
}
|
|
29026
|
+
/**
|
|
29027
|
+
* Check limits and increment counters (synchronous, atomic in Node.js event loop)
|
|
29028
|
+
* @param {string|null|undefined} parentSessionId - Parent session ID for tracking
|
|
29029
|
+
*/
|
|
29030
|
+
tryAcquire(parentSessionId) {
|
|
29031
|
+
if (parentSessionId !== null && parentSessionId !== void 0 && typeof parentSessionId !== "string") {
|
|
29032
|
+
throw new TypeError("parentSessionId must be a string, null, or undefined");
|
|
29033
|
+
}
|
|
29034
|
+
if (this.globalActive >= this.maxConcurrent) {
|
|
29035
|
+
throw new Error(`Maximum concurrent delegations (${this.maxConcurrent}) reached. Please wait for some delegations to complete.`);
|
|
29036
|
+
}
|
|
29037
|
+
if (parentSessionId) {
|
|
29038
|
+
const sessionData = this.sessionDelegations.get(parentSessionId);
|
|
29039
|
+
const sessionCount = sessionData?.count || 0;
|
|
29040
|
+
if (sessionCount >= this.maxPerSession) {
|
|
29041
|
+
throw new Error(`Maximum delegations per session (${this.maxPerSession}) reached for session ${parentSessionId}`);
|
|
29042
|
+
}
|
|
29043
|
+
}
|
|
29044
|
+
this.globalActive++;
|
|
29045
|
+
if (parentSessionId) {
|
|
29046
|
+
const sessionData = this.sessionDelegations.get(parentSessionId);
|
|
29047
|
+
if (sessionData) {
|
|
29048
|
+
sessionData.count++;
|
|
29049
|
+
sessionData.lastUpdated = Date.now();
|
|
29050
|
+
} else {
|
|
29051
|
+
this.sessionDelegations.set(parentSessionId, {
|
|
29052
|
+
count: 1,
|
|
29053
|
+
lastUpdated: Date.now()
|
|
29054
|
+
});
|
|
29055
|
+
}
|
|
29056
|
+
}
|
|
29057
|
+
return true;
|
|
29058
|
+
}
|
|
29059
|
+
/**
|
|
29060
|
+
* Decrement counters (synchronous, atomic in Node.js event loop)
|
|
29061
|
+
*/
|
|
29062
|
+
release(parentSessionId, debug = false) {
|
|
29063
|
+
this.globalActive = Math.max(0, this.globalActive - 1);
|
|
29064
|
+
if (parentSessionId) {
|
|
29065
|
+
const sessionData = this.sessionDelegations.get(parentSessionId);
|
|
29066
|
+
if (sessionData) {
|
|
29067
|
+
sessionData.count = Math.max(0, sessionData.count - 1);
|
|
29068
|
+
if (sessionData.count === 0) {
|
|
29069
|
+
this.sessionDelegations.delete(parentSessionId);
|
|
29070
|
+
}
|
|
29071
|
+
}
|
|
29072
|
+
}
|
|
29073
|
+
if (debug) {
|
|
29074
|
+
console.error(`[DELEGATE] Released. Global active: ${this.globalActive}`);
|
|
29075
|
+
}
|
|
29076
|
+
}
|
|
29077
|
+
/**
|
|
29078
|
+
* Get current stats for monitoring
|
|
29079
|
+
*/
|
|
29080
|
+
getStats() {
|
|
29081
|
+
return {
|
|
29082
|
+
globalActive: this.globalActive,
|
|
29083
|
+
maxConcurrent: this.maxConcurrent,
|
|
29084
|
+
maxPerSession: this.maxPerSession,
|
|
29085
|
+
sessionCount: this.sessionDelegations.size
|
|
29086
|
+
};
|
|
29087
|
+
}
|
|
29088
|
+
/**
|
|
29089
|
+
* Clean up stale sessions (sessions with count=0 that haven't been updated in 1 hour)
|
|
29090
|
+
*/
|
|
29091
|
+
cleanupStaleSessions() {
|
|
29092
|
+
const oneHourAgo = Date.now() - 60 * 60 * 1e3;
|
|
29093
|
+
for (const [sessionId, data2] of this.sessionDelegations.entries()) {
|
|
29094
|
+
if (data2.count === 0 && data2.lastUpdated < oneHourAgo) {
|
|
29095
|
+
this.sessionDelegations.delete(sessionId);
|
|
29096
|
+
}
|
|
29097
|
+
}
|
|
29098
|
+
}
|
|
29099
|
+
/**
|
|
29100
|
+
* Cleanup all resources (for testing or shutdown)
|
|
29101
|
+
*/
|
|
29102
|
+
cleanup() {
|
|
29103
|
+
if (this.cleanupInterval) {
|
|
29104
|
+
clearInterval(this.cleanupInterval);
|
|
29105
|
+
this.cleanupInterval = null;
|
|
29106
|
+
}
|
|
29107
|
+
this.sessionDelegations.clear();
|
|
29108
|
+
this.globalActive = 0;
|
|
29109
|
+
}
|
|
29110
|
+
};
|
|
29111
|
+
delegationManager = new DelegationManager();
|
|
29112
|
+
}
|
|
29113
|
+
});
|
|
29114
|
+
|
|
28825
29115
|
// node_modules/zod/v3/helpers/util.js
|
|
28826
29116
|
var util, objectUtil, ZodParsedType, getParsedType;
|
|
28827
29117
|
var init_util2 = __esm({
|
|
@@ -33035,7 +33325,7 @@ function parseTargets(targets) {
|
|
|
33035
33325
|
}
|
|
33036
33326
|
return targets.split(/\s+/).filter((f3) => f3.length > 0);
|
|
33037
33327
|
}
|
|
33038
|
-
var searchSchema, querySchema, extractSchema, delegateSchema, bashSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, attemptCompletionToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, DEFAULT_VALID_TOOLS;
|
|
33328
|
+
var searchSchema, querySchema, extractSchema, delegateSchema, bashSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, DEFAULT_VALID_TOOLS;
|
|
33039
33329
|
var init_common2 = __esm({
|
|
33040
33330
|
"src/tools/common.js"() {
|
|
33041
33331
|
"use strict";
|
|
@@ -33240,6 +33530,26 @@ User: Read file inside the dependency
|
|
|
33240
33530
|
</extract>
|
|
33241
33531
|
|
|
33242
33532
|
</examples>
|
|
33533
|
+
`;
|
|
33534
|
+
delegateToolDefinition = `
|
|
33535
|
+
## delegate
|
|
33536
|
+
Description: Automatically delegate big distinct tasks to specialized probe subagents within the agentic loop. Use this when you recognize that a user's request involves multiple large, distinct components that would benefit from parallel processing or specialized focus. The AI agent should automatically identify opportunities for task separation and use delegation without explicit user instruction.
|
|
33537
|
+
|
|
33538
|
+
Parameters:
|
|
33539
|
+
- task: (required) A complete, self-contained task that can be executed independently by a subagent. Should be specific and focused on one area of expertise.
|
|
33540
|
+
|
|
33541
|
+
Usage Pattern:
|
|
33542
|
+
When the AI agent encounters complex multi-part requests, it should automatically break them down and delegate:
|
|
33543
|
+
|
|
33544
|
+
<delegate>
|
|
33545
|
+
<task>Analyze all authentication and authorization code in the codebase for security vulnerabilities and provide specific remediation recommendations</task>
|
|
33546
|
+
</delegate>
|
|
33547
|
+
|
|
33548
|
+
<delegate>
|
|
33549
|
+
<task>Review database queries and API endpoints for performance bottlenecks and suggest optimization strategies</task>
|
|
33550
|
+
</delegate>
|
|
33551
|
+
|
|
33552
|
+
The agent uses this tool automatically when it identifies that work can be separated into distinct, parallel tasks for more efficient processing.
|
|
33243
33553
|
`;
|
|
33244
33554
|
attemptCompletionToolDefinition = `
|
|
33245
33555
|
## attempt_completion
|
|
@@ -33268,194 +33578,6 @@ I have refactored the search module according to the requirements and verified t
|
|
|
33268
33578
|
}
|
|
33269
33579
|
});
|
|
33270
33580
|
|
|
33271
|
-
// src/delegate.js
|
|
33272
|
-
async function delegate({ task, timeout = 300, debug = false, currentIteration = 0, maxIterations = 30, tracer = null }) {
|
|
33273
|
-
if (!task || typeof task !== "string") {
|
|
33274
|
-
throw new Error("Task parameter is required and must be a string");
|
|
33275
|
-
}
|
|
33276
|
-
const sessionId = (0, import_crypto2.randomUUID)();
|
|
33277
|
-
const startTime = Date.now();
|
|
33278
|
-
const remainingIterations = Math.max(1, maxIterations - currentIteration);
|
|
33279
|
-
if (debug) {
|
|
33280
|
-
console.error(`[DELEGATE] Starting delegation session ${sessionId}`);
|
|
33281
|
-
console.error(`[DELEGATE] Task: ${task}`);
|
|
33282
|
-
console.error(`[DELEGATE] Current iteration: ${currentIteration}/${maxIterations}`);
|
|
33283
|
-
console.error(`[DELEGATE] Remaining iterations for subagent: ${remainingIterations}`);
|
|
33284
|
-
console.error(`[DELEGATE] Timeout configured: ${timeout} seconds`);
|
|
33285
|
-
console.error(`[DELEGATE] Using clean agent environment with code-researcher prompt`);
|
|
33286
|
-
}
|
|
33287
|
-
try {
|
|
33288
|
-
const binaryPath = await getBinaryPath();
|
|
33289
|
-
const args = [
|
|
33290
|
-
"agent",
|
|
33291
|
-
"--task",
|
|
33292
|
-
task,
|
|
33293
|
-
"--session-id",
|
|
33294
|
-
sessionId,
|
|
33295
|
-
"--prompt-type",
|
|
33296
|
-
"code-researcher",
|
|
33297
|
-
// Automatically use default code researcher prompt
|
|
33298
|
-
"--no-schema-validation",
|
|
33299
|
-
// Automatically disable schema validation
|
|
33300
|
-
"--no-mermaid-validation",
|
|
33301
|
-
// Automatically disable mermaid validation
|
|
33302
|
-
"--max-iterations",
|
|
33303
|
-
remainingIterations.toString()
|
|
33304
|
-
// Automatically limit to remaining iterations
|
|
33305
|
-
];
|
|
33306
|
-
if (debug) {
|
|
33307
|
-
args.push("--debug");
|
|
33308
|
-
console.error(`[DELEGATE] Using binary at: ${binaryPath}`);
|
|
33309
|
-
console.error(`[DELEGATE] Command args: ${args.join(" ")}`);
|
|
33310
|
-
}
|
|
33311
|
-
return new Promise((resolve4, reject2) => {
|
|
33312
|
-
const delegationSpan = tracer ? tracer.createDelegationSpan(sessionId, task) : null;
|
|
33313
|
-
const process2 = (0, import_child_process6.spawn)(binaryPath, args, {
|
|
33314
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
33315
|
-
timeout: timeout * 1e3
|
|
33316
|
-
});
|
|
33317
|
-
let stdout = "";
|
|
33318
|
-
let stderr = "";
|
|
33319
|
-
let isResolved = false;
|
|
33320
|
-
process2.stdout.on("data", (data2) => {
|
|
33321
|
-
const chunk = data2.toString();
|
|
33322
|
-
stdout += chunk;
|
|
33323
|
-
if (debug) {
|
|
33324
|
-
const preview = createMessagePreview(chunk);
|
|
33325
|
-
console.error(`[DELEGATE] stdout chunk received (${chunk.length} chars): ${preview}`);
|
|
33326
|
-
}
|
|
33327
|
-
});
|
|
33328
|
-
process2.stderr.on("data", (data2) => {
|
|
33329
|
-
const chunk = data2.toString();
|
|
33330
|
-
stderr += chunk;
|
|
33331
|
-
if (debug) {
|
|
33332
|
-
const preview = createMessagePreview(chunk);
|
|
33333
|
-
console.error(`[DELEGATE] stderr chunk received (${chunk.length} chars): ${preview}`);
|
|
33334
|
-
}
|
|
33335
|
-
});
|
|
33336
|
-
process2.on("close", (code) => {
|
|
33337
|
-
if (isResolved) return;
|
|
33338
|
-
isResolved = true;
|
|
33339
|
-
const duration = Date.now() - startTime;
|
|
33340
|
-
if (debug) {
|
|
33341
|
-
console.error(`[DELEGATE] Process completed with code ${code} in ${duration}ms`);
|
|
33342
|
-
console.error(`[DELEGATE] Duration: ${(duration / 1e3).toFixed(2)}s`);
|
|
33343
|
-
console.error(`[DELEGATE] Total stdout: ${stdout.length} chars`);
|
|
33344
|
-
console.error(`[DELEGATE] Total stderr: ${stderr.length} chars`);
|
|
33345
|
-
}
|
|
33346
|
-
if (code === 0) {
|
|
33347
|
-
const response = stdout.trim();
|
|
33348
|
-
if (!response) {
|
|
33349
|
-
if (debug) {
|
|
33350
|
-
console.error(`[DELEGATE] Task completed but returned empty response for session ${sessionId}`);
|
|
33351
|
-
}
|
|
33352
|
-
reject2(new Error("Delegate agent returned empty response"));
|
|
33353
|
-
return;
|
|
33354
|
-
}
|
|
33355
|
-
if (debug) {
|
|
33356
|
-
console.error(`[DELEGATE] Task completed successfully for session ${sessionId}`);
|
|
33357
|
-
console.error(`[DELEGATE] Response length: ${response.length} chars`);
|
|
33358
|
-
}
|
|
33359
|
-
if (tracer) {
|
|
33360
|
-
tracer.recordDelegationEvent("completed", {
|
|
33361
|
-
"delegation.session_id": sessionId,
|
|
33362
|
-
"delegation.duration_ms": duration,
|
|
33363
|
-
"delegation.response_length": response.length,
|
|
33364
|
-
"delegation.success": true
|
|
33365
|
-
});
|
|
33366
|
-
if (delegationSpan) {
|
|
33367
|
-
delegationSpan.setAttributes({
|
|
33368
|
-
"delegation.result.success": true,
|
|
33369
|
-
"delegation.result.response_length": response.length,
|
|
33370
|
-
"delegation.result.duration_ms": duration
|
|
33371
|
-
});
|
|
33372
|
-
delegationSpan.setStatus({ code: 1 });
|
|
33373
|
-
delegationSpan.end();
|
|
33374
|
-
}
|
|
33375
|
-
}
|
|
33376
|
-
resolve4(response);
|
|
33377
|
-
} else {
|
|
33378
|
-
const errorMessage = stderr.trim() || `Delegate process failed with exit code ${code}`;
|
|
33379
|
-
if (debug) {
|
|
33380
|
-
console.error(`[DELEGATE] Task failed for session ${sessionId} with code ${code}`);
|
|
33381
|
-
console.error(`[DELEGATE] Error message: ${errorMessage}`);
|
|
33382
|
-
}
|
|
33383
|
-
if (tracer) {
|
|
33384
|
-
tracer.recordDelegationEvent("failed", {
|
|
33385
|
-
"delegation.session_id": sessionId,
|
|
33386
|
-
"delegation.duration_ms": duration,
|
|
33387
|
-
"delegation.exit_code": code,
|
|
33388
|
-
"delegation.error_message": errorMessage,
|
|
33389
|
-
"delegation.success": false
|
|
33390
|
-
});
|
|
33391
|
-
if (delegationSpan) {
|
|
33392
|
-
delegationSpan.setAttributes({
|
|
33393
|
-
"delegation.result.success": false,
|
|
33394
|
-
"delegation.result.exit_code": code,
|
|
33395
|
-
"delegation.result.error": errorMessage,
|
|
33396
|
-
"delegation.result.duration_ms": duration
|
|
33397
|
-
});
|
|
33398
|
-
delegationSpan.setStatus({ code: 2, message: errorMessage });
|
|
33399
|
-
delegationSpan.end();
|
|
33400
|
-
}
|
|
33401
|
-
}
|
|
33402
|
-
reject2(new Error(`Delegation failed: ${errorMessage}`));
|
|
33403
|
-
}
|
|
33404
|
-
});
|
|
33405
|
-
process2.on("error", (error2) => {
|
|
33406
|
-
if (isResolved) return;
|
|
33407
|
-
isResolved = true;
|
|
33408
|
-
const duration = Date.now() - startTime;
|
|
33409
|
-
if (debug) {
|
|
33410
|
-
console.error(`[DELEGATE] Process spawn error after ${duration}ms:`, error2);
|
|
33411
|
-
console.error(`[DELEGATE] Session ${sessionId} failed during process creation`);
|
|
33412
|
-
console.error(`[DELEGATE] Error type: ${error2.code || "unknown"}`);
|
|
33413
|
-
}
|
|
33414
|
-
reject2(new Error(`Failed to start delegate process: ${error2.message}`));
|
|
33415
|
-
});
|
|
33416
|
-
setTimeout(() => {
|
|
33417
|
-
if (isResolved) return;
|
|
33418
|
-
isResolved = true;
|
|
33419
|
-
const duration = Date.now() - startTime;
|
|
33420
|
-
if (debug) {
|
|
33421
|
-
console.error(`[DELEGATE] Process timeout after ${(duration / 1e3).toFixed(2)}s (limit: ${timeout}s)`);
|
|
33422
|
-
console.error(`[DELEGATE] Terminating session ${sessionId} due to timeout`);
|
|
33423
|
-
console.error(`[DELEGATE] Partial stdout: ${stdout.substring(0, 500)}${stdout.length > 500 ? "..." : ""}`);
|
|
33424
|
-
console.error(`[DELEGATE] Partial stderr: ${stderr.substring(0, 500)}${stderr.length > 500 ? "..." : ""}`);
|
|
33425
|
-
}
|
|
33426
|
-
process2.kill("SIGTERM");
|
|
33427
|
-
setTimeout(() => {
|
|
33428
|
-
if (!process2.killed) {
|
|
33429
|
-
if (debug) {
|
|
33430
|
-
console.error(`[DELEGATE] Force killing process ${sessionId} after graceful timeout`);
|
|
33431
|
-
}
|
|
33432
|
-
process2.kill("SIGKILL");
|
|
33433
|
-
}
|
|
33434
|
-
}, 5e3);
|
|
33435
|
-
reject2(new Error(`Delegation timed out after ${timeout} seconds`));
|
|
33436
|
-
}, timeout * 1e3);
|
|
33437
|
-
});
|
|
33438
|
-
} catch (error2) {
|
|
33439
|
-
const duration = Date.now() - startTime;
|
|
33440
|
-
if (debug) {
|
|
33441
|
-
console.error(`[DELEGATE] Error in delegate function after ${duration}ms:`, error2);
|
|
33442
|
-
console.error(`[DELEGATE] Session ${sessionId} failed during setup`);
|
|
33443
|
-
console.error(`[DELEGATE] Error stack: ${error2.stack}`);
|
|
33444
|
-
}
|
|
33445
|
-
throw new Error(`Delegation setup failed: ${error2.message}`);
|
|
33446
|
-
}
|
|
33447
|
-
}
|
|
33448
|
-
var import_child_process6, import_crypto2;
|
|
33449
|
-
var init_delegate = __esm({
|
|
33450
|
-
"src/delegate.js"() {
|
|
33451
|
-
"use strict";
|
|
33452
|
-
import_child_process6 = require("child_process");
|
|
33453
|
-
import_crypto2 = require("crypto");
|
|
33454
|
-
init_utils2();
|
|
33455
|
-
init_common2();
|
|
33456
|
-
}
|
|
33457
|
-
});
|
|
33458
|
-
|
|
33459
33581
|
// src/tools/vercel.js
|
|
33460
33582
|
var import_ai, searchTool, queryTool, extractTool, delegateTool;
|
|
33461
33583
|
var init_vercel = __esm({
|
|
@@ -33628,21 +33750,50 @@ var init_vercel = __esm({
|
|
|
33628
33750
|
name: "delegate",
|
|
33629
33751
|
description: delegateDescription,
|
|
33630
33752
|
inputSchema: delegateSchema,
|
|
33631
|
-
execute: async ({ task }) => {
|
|
33632
|
-
|
|
33633
|
-
|
|
33634
|
-
console.error(`Executing delegate with task: "${task}"`);
|
|
33635
|
-
}
|
|
33636
|
-
const result = await delegate({
|
|
33637
|
-
task,
|
|
33638
|
-
timeout,
|
|
33639
|
-
debug
|
|
33640
|
-
});
|
|
33641
|
-
return result;
|
|
33642
|
-
} catch (error2) {
|
|
33643
|
-
console.error("Error executing delegate command:", error2);
|
|
33644
|
-
return `Error executing delegate command: ${error2.message}`;
|
|
33753
|
+
execute: async ({ task, currentIteration, maxIterations, parentSessionId, path: path7, provider, model, tracer }) => {
|
|
33754
|
+
if (!task || typeof task !== "string") {
|
|
33755
|
+
throw new Error("Task parameter is required and must be a non-empty string");
|
|
33645
33756
|
}
|
|
33757
|
+
if (task.trim().length === 0) {
|
|
33758
|
+
throw new Error("Task parameter cannot be empty or whitespace only");
|
|
33759
|
+
}
|
|
33760
|
+
if (currentIteration !== void 0 && (typeof currentIteration !== "number" || currentIteration < 0)) {
|
|
33761
|
+
throw new Error("currentIteration must be a non-negative number");
|
|
33762
|
+
}
|
|
33763
|
+
if (maxIterations !== void 0 && (typeof maxIterations !== "number" || maxIterations < 1)) {
|
|
33764
|
+
throw new Error("maxIterations must be a positive number");
|
|
33765
|
+
}
|
|
33766
|
+
if (parentSessionId !== void 0 && parentSessionId !== null && typeof parentSessionId !== "string") {
|
|
33767
|
+
throw new TypeError("parentSessionId must be a string, null, or undefined");
|
|
33768
|
+
}
|
|
33769
|
+
if (path7 !== void 0 && path7 !== null && typeof path7 !== "string") {
|
|
33770
|
+
throw new TypeError("path must be a string, null, or undefined");
|
|
33771
|
+
}
|
|
33772
|
+
if (provider !== void 0 && provider !== null && typeof provider !== "string") {
|
|
33773
|
+
throw new TypeError("provider must be a string, null, or undefined");
|
|
33774
|
+
}
|
|
33775
|
+
if (model !== void 0 && model !== null && typeof model !== "string") {
|
|
33776
|
+
throw new TypeError("model must be a string, null, or undefined");
|
|
33777
|
+
}
|
|
33778
|
+
if (debug) {
|
|
33779
|
+
console.error(`Executing delegate with task: "${task.substring(0, 100)}${task.length > 100 ? "..." : ""}"`);
|
|
33780
|
+
if (parentSessionId) {
|
|
33781
|
+
console.error(`Parent session: ${parentSessionId}`);
|
|
33782
|
+
}
|
|
33783
|
+
}
|
|
33784
|
+
const result = await delegate({
|
|
33785
|
+
task,
|
|
33786
|
+
timeout,
|
|
33787
|
+
debug,
|
|
33788
|
+
currentIteration: currentIteration || 0,
|
|
33789
|
+
maxIterations: maxIterations || 30,
|
|
33790
|
+
parentSessionId,
|
|
33791
|
+
path: path7,
|
|
33792
|
+
provider,
|
|
33793
|
+
model,
|
|
33794
|
+
tracer
|
|
33795
|
+
});
|
|
33796
|
+
return result;
|
|
33646
33797
|
}
|
|
33647
33798
|
});
|
|
33648
33799
|
};
|
|
@@ -34525,7 +34676,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
34525
34676
|
return;
|
|
34526
34677
|
}
|
|
34527
34678
|
const [cmd, ...cmdArgs] = args;
|
|
34528
|
-
const child = (0,
|
|
34679
|
+
const child = (0, import_child_process6.spawn)(cmd, cmdArgs, {
|
|
34529
34680
|
cwd,
|
|
34530
34681
|
env: processEnv,
|
|
34531
34682
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -34709,11 +34860,11 @@ function validateExecutionOptions(options = {}) {
|
|
|
34709
34860
|
warnings
|
|
34710
34861
|
};
|
|
34711
34862
|
}
|
|
34712
|
-
var
|
|
34863
|
+
var import_child_process6, import_path4, import_fs;
|
|
34713
34864
|
var init_bashExecutor = __esm({
|
|
34714
34865
|
"src/agent/bashExecutor.js"() {
|
|
34715
34866
|
"use strict";
|
|
34716
|
-
|
|
34867
|
+
import_child_process6 = require("child_process");
|
|
34717
34868
|
import_path4 = require("path");
|
|
34718
34869
|
import_fs = require("fs");
|
|
34719
34870
|
init_bashCommandUtils();
|
|
@@ -35145,15 +35296,15 @@ function shouldIgnore(filePath, ignorePatterns) {
|
|
|
35145
35296
|
}
|
|
35146
35297
|
return false;
|
|
35147
35298
|
}
|
|
35148
|
-
var import_fs2, import_path6, import_util11,
|
|
35299
|
+
var import_fs2, import_path6, import_util11, import_child_process7, execAsync3;
|
|
35149
35300
|
var init_file_lister = __esm({
|
|
35150
35301
|
"src/utils/file-lister.js"() {
|
|
35151
35302
|
"use strict";
|
|
35152
35303
|
import_fs2 = __toESM(require("fs"), 1);
|
|
35153
35304
|
import_path6 = __toESM(require("path"), 1);
|
|
35154
35305
|
import_util11 = require("util");
|
|
35155
|
-
|
|
35156
|
-
execAsync3 = (0, import_util11.promisify)(
|
|
35306
|
+
import_child_process7 = require("child_process");
|
|
35307
|
+
execAsync3 = (0, import_util11.promisify)(import_child_process7.exec);
|
|
35157
35308
|
}
|
|
35158
35309
|
});
|
|
35159
35310
|
|
|
@@ -41910,12 +42061,12 @@ function createWrappedTools(baseTools) {
|
|
|
41910
42061
|
}
|
|
41911
42062
|
return wrappedTools;
|
|
41912
42063
|
}
|
|
41913
|
-
var
|
|
42064
|
+
var import_child_process8, import_util12, import_crypto3, import_events, import_fs5, import_fs6, import_path8, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
41914
42065
|
var init_probeTool = __esm({
|
|
41915
42066
|
"src/agent/probeTool.js"() {
|
|
41916
42067
|
"use strict";
|
|
41917
42068
|
init_index();
|
|
41918
|
-
|
|
42069
|
+
import_child_process8 = require("child_process");
|
|
41919
42070
|
import_util12 = require("util");
|
|
41920
42071
|
import_crypto3 = require("crypto");
|
|
41921
42072
|
import_events = require("events");
|
|
@@ -55476,13 +55627,24 @@ function mapFlowchartParserError(err, text) {
|
|
|
55476
55627
|
length: len
|
|
55477
55628
|
};
|
|
55478
55629
|
}
|
|
55479
|
-
if (tokType === "QuotedString") {
|
|
55630
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
55480
55631
|
const context = err?.context;
|
|
55481
55632
|
const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
|
|
55482
55633
|
const lineContent = allLines[Math.max(0, line - 1)] || "";
|
|
55483
55634
|
const beforeQuote = lineContent.slice(0, Math.max(0, column - 1));
|
|
55484
55635
|
const hasLinkBefore = beforeQuote.match(/--\s*$|==\s*$|-\.\s*$|-\.-\s*$|\[\s*$/);
|
|
55485
55636
|
if (inLinkRule || hasLinkBefore) {
|
|
55637
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
55638
|
+
return {
|
|
55639
|
+
line,
|
|
55640
|
+
column,
|
|
55641
|
+
severity: "error",
|
|
55642
|
+
code: "FL-EDGE-LABEL-BRACKET",
|
|
55643
|
+
message: "Square brackets [ ] are not supported inside inline edge labels.",
|
|
55644
|
+
hint: "Use HTML entities [ and ] inside |...|, e.g., --|run: [aggregate]|-->",
|
|
55645
|
+
length: len
|
|
55646
|
+
};
|
|
55647
|
+
}
|
|
55486
55648
|
const quotedText = found.startsWith('"') ? found.slice(1, -1) : found;
|
|
55487
55649
|
return {
|
|
55488
55650
|
line,
|
|
@@ -55576,7 +55738,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
55576
55738
|
}
|
|
55577
55739
|
}
|
|
55578
55740
|
}
|
|
55579
|
-
if (tokType === "QuotedString") {
|
|
55741
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
55580
55742
|
return {
|
|
55581
55743
|
line,
|
|
55582
55744
|
column,
|
|
@@ -55597,7 +55759,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
55597
55759
|
return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '['. Add a matching ']' before the arrow or newline.", hint: "Example: A[Label] --> B", length: 1 };
|
|
55598
55760
|
}
|
|
55599
55761
|
if (expecting(err, "RoundClose")) {
|
|
55600
|
-
if (tokType === "QuotedString") {
|
|
55762
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
55601
55763
|
return {
|
|
55602
55764
|
line,
|
|
55603
55765
|
column,
|
|
@@ -55636,7 +55798,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
55636
55798
|
return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '('. Add a matching ')'.", hint: "Example: B(Label)", length: 1 };
|
|
55637
55799
|
}
|
|
55638
55800
|
if (expecting(err, "DiamondClose")) {
|
|
55639
|
-
if (tokType === "QuotedString") {
|
|
55801
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
55640
55802
|
return {
|
|
55641
55803
|
line,
|
|
55642
55804
|
column,
|
|
@@ -56482,6 +56644,53 @@ function validateFlowchart(text, options = {}) {
|
|
|
56482
56644
|
}
|
|
56483
56645
|
}
|
|
56484
56646
|
}
|
|
56647
|
+
{
|
|
56648
|
+
const byLine = /* @__PURE__ */ new Map();
|
|
56649
|
+
const collect = (arr) => {
|
|
56650
|
+
for (const e3 of arr || []) {
|
|
56651
|
+
if (e3 && e3.code === "FL-LABEL-PARENS-UNQUOTED") {
|
|
56652
|
+
const ln = e3.line ?? 0;
|
|
56653
|
+
const col = e3.column ?? 1;
|
|
56654
|
+
const list2 = byLine.get(ln) || [];
|
|
56655
|
+
list2.push(col);
|
|
56656
|
+
byLine.set(ln, list2);
|
|
56657
|
+
}
|
|
56658
|
+
}
|
|
56659
|
+
};
|
|
56660
|
+
collect(prevErrors);
|
|
56661
|
+
collect(errs);
|
|
56662
|
+
const lines2 = text2.split(/\r?\n/);
|
|
56663
|
+
for (let ii = 0; ii < lines2.length; ii++) {
|
|
56664
|
+
const raw2 = lines2[ii] || "";
|
|
56665
|
+
if (!raw2.includes("[") || !raw2.includes("]"))
|
|
56666
|
+
continue;
|
|
56667
|
+
let search2 = 0;
|
|
56668
|
+
while (true) {
|
|
56669
|
+
const open2 = raw2.indexOf("[", search2);
|
|
56670
|
+
if (open2 === -1)
|
|
56671
|
+
break;
|
|
56672
|
+
const close2 = raw2.indexOf("]", open2 + 1);
|
|
56673
|
+
if (close2 === -1)
|
|
56674
|
+
break;
|
|
56675
|
+
const seg2 = raw2.slice(open2 + 1, close2);
|
|
56676
|
+
const trimmed2 = seg2.trim();
|
|
56677
|
+
const ln2 = ii + 1;
|
|
56678
|
+
const lsp = trimmed2.slice(0, 1);
|
|
56679
|
+
const rsp = trimmed2.slice(-1);
|
|
56680
|
+
const isSlashPair = (lsp === "/" || lsp === "\\") && (rsp === "/" || rsp === "\\");
|
|
56681
|
+
const isParenWrapped = lsp === "(" && rsp === ")";
|
|
56682
|
+
const segStartCol = open2 + 2;
|
|
56683
|
+
const segEndCol = close2 + 1;
|
|
56684
|
+
const existing = byLine.get(ln2) || [];
|
|
56685
|
+
const covered = existing.some((c3) => c3 >= segStartCol && c3 <= segEndCol);
|
|
56686
|
+
if (!covered && !/^".*"$/.test(trimmed2) && (seg2.includes("(") || seg2.includes(")")) && !isSlashPair && !isParenWrapped) {
|
|
56687
|
+
errs.push({ line: ln2, column: segStartCol, severity: "error", code: "FL-LABEL-PARENS-UNQUOTED", message: "Parentheses inside an unquoted label are not supported by Mermaid.", hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and ).' });
|
|
56688
|
+
byLine.set(ln2, existing.concat([segStartCol]));
|
|
56689
|
+
}
|
|
56690
|
+
search2 = close2 + 1;
|
|
56691
|
+
}
|
|
56692
|
+
}
|
|
56693
|
+
}
|
|
56485
56694
|
const dblEsc = (text2.match(/\\\"/g) || []).length;
|
|
56486
56695
|
const dq = (text2.match(/\"/g) || []).length - dblEsc;
|
|
56487
56696
|
const sq = (text2.match(/'/g) || []).length;
|
|
@@ -58826,6 +59035,21 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
58826
59035
|
}
|
|
58827
59036
|
continue;
|
|
58828
59037
|
}
|
|
59038
|
+
if (is("FL-EDGE-LABEL-BRACKET", e3)) {
|
|
59039
|
+
const lineText = lineTextAt(text, e3.line);
|
|
59040
|
+
const firstBar = lineText.indexOf("|");
|
|
59041
|
+
const secondBar = firstBar >= 0 ? lineText.indexOf("|", firstBar + 1) : -1;
|
|
59042
|
+
if (firstBar >= 0 && secondBar > firstBar) {
|
|
59043
|
+
const before = lineText.slice(0, firstBar + 1);
|
|
59044
|
+
const label = lineText.slice(firstBar + 1, secondBar);
|
|
59045
|
+
const after = lineText.slice(secondBar);
|
|
59046
|
+
const fixedLabel = label.replace(/\[/g, "[").replace(/\]/g, "]");
|
|
59047
|
+
const fixedLine = before + fixedLabel + after;
|
|
59048
|
+
const finalLine = fixedLine.replace(/\[([^\]]*)\]/g, (m3, seg) => "[" + String(seg).replace(/`/g, "") + "]");
|
|
59049
|
+
edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line, column: lineText.length + 1 }, newText: finalLine });
|
|
59050
|
+
}
|
|
59051
|
+
continue;
|
|
59052
|
+
}
|
|
58829
59053
|
if (is("FL-EDGE-LABEL-BACKTICK", e3)) {
|
|
58830
59054
|
const lineText = lineTextAt(text, e3.line);
|
|
58831
59055
|
const re = /^(.*?--)\s*([^|>]+?)\s*(-->|==>|\.->|->)(.*)$/;
|
|
@@ -80981,6 +81205,7 @@ var init_ProbeAgent = __esm({
|
|
|
80981
81205
|
* @param {string} [options.customPrompt] - Custom prompt to replace the default system message
|
|
80982
81206
|
* @param {string} [options.promptType] - Predefined prompt type (architect, code-review, support)
|
|
80983
81207
|
* @param {boolean} [options.allowEdit=false] - Allow the use of the 'implement' tool
|
|
81208
|
+
* @param {boolean} [options.enableDelegate=false] - Enable the delegate tool for task distribution to subagents
|
|
80984
81209
|
* @param {string} [options.path] - Search directory path
|
|
80985
81210
|
* @param {string} [options.provider] - Force specific AI provider
|
|
80986
81211
|
* @param {string} [options.model] - Override model name
|
|
@@ -81002,6 +81227,7 @@ var init_ProbeAgent = __esm({
|
|
|
81002
81227
|
this.customPrompt = options.customPrompt || null;
|
|
81003
81228
|
this.promptType = options.promptType || "code-explorer";
|
|
81004
81229
|
this.allowEdit = !!options.allowEdit;
|
|
81230
|
+
this.enableDelegate = !!options.enableDelegate;
|
|
81005
81231
|
this.debug = options.debug || process.env.DEBUG === "1";
|
|
81006
81232
|
this.cancelled = false;
|
|
81007
81233
|
this.tracer = options.tracer || null;
|
|
@@ -81596,6 +81822,10 @@ ${attemptCompletionToolDefinition}
|
|
|
81596
81822
|
`;
|
|
81597
81823
|
if (this.allowEdit) {
|
|
81598
81824
|
toolDefinitions += `${implementToolDefinition}
|
|
81825
|
+
`;
|
|
81826
|
+
}
|
|
81827
|
+
if (this.enableDelegate) {
|
|
81828
|
+
toolDefinitions += `${delegateToolDefinition}
|
|
81599
81829
|
`;
|
|
81600
81830
|
}
|
|
81601
81831
|
let xmlToolGuidelines = `
|
|
@@ -81659,7 +81889,7 @@ Available Tools:
|
|
|
81659
81889
|
- extract: Extract specific code blocks or lines from files.
|
|
81660
81890
|
- listFiles: List files and directories in a specified location.
|
|
81661
81891
|
- searchFiles: Find files matching a glob pattern with recursive search capability.
|
|
81662
|
-
${this.allowEdit ? "- implement: Implement a feature or fix a bug using aider.\n" : ""}
|
|
81892
|
+
${this.allowEdit ? "- implement: Implement a feature or fix a bug using aider.\n" : ""}${this.enableDelegate ? "- delegate: Delegate big distinct tasks to specialized probe subagents.\n" : ""}
|
|
81663
81893
|
- attempt_completion: Finalize the task and provide the result to the user.
|
|
81664
81894
|
- attempt_complete: Quick completion using previous response (shorthand).
|
|
81665
81895
|
`;
|
|
@@ -81979,6 +82209,9 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
81979
82209
|
if (this.allowEdit) {
|
|
81980
82210
|
validTools.push("implement");
|
|
81981
82211
|
}
|
|
82212
|
+
if (this.enableDelegate) {
|
|
82213
|
+
validTools.push("delegate");
|
|
82214
|
+
}
|
|
81982
82215
|
const nativeTools = validTools;
|
|
81983
82216
|
const parsedTool = this.mcpBridge ? parseHybridXmlToolCall(assistantResponseContent, nativeTools, this.mcpBridge) : parseXmlToolCallWithThinking(assistantResponseContent, validTools);
|
|
81984
82217
|
if (parsedTool) {
|
|
@@ -82092,11 +82325,21 @@ ${toolResultContent}
|
|
|
82092
82325
|
...toolParams,
|
|
82093
82326
|
currentIteration,
|
|
82094
82327
|
maxIterations,
|
|
82328
|
+
parentSessionId: this.sessionId,
|
|
82329
|
+
// Pass parent session ID for tracking
|
|
82330
|
+
path: this.searchPath,
|
|
82331
|
+
// Inherit search path
|
|
82332
|
+
provider: this.provider,
|
|
82333
|
+
// Inherit AI provider
|
|
82334
|
+
model: this.model,
|
|
82335
|
+
// Inherit model
|
|
82095
82336
|
debug: this.debug,
|
|
82096
82337
|
tracer: this.tracer
|
|
82097
82338
|
};
|
|
82098
82339
|
if (this.debug) {
|
|
82099
82340
|
console.log(`[DEBUG] Executing delegate tool at iteration ${currentIteration}/${maxIterations}`);
|
|
82341
|
+
console.log(`[DEBUG] Parent session: ${this.sessionId}`);
|
|
82342
|
+
console.log(`[DEBUG] Inherited config: path=${this.searchPath}, provider=${this.provider}, model=${this.model}`);
|
|
82100
82343
|
console.log(`[DEBUG] Delegate task: ${toolParams.task?.substring(0, 100)}...`);
|
|
82101
82344
|
}
|
|
82102
82345
|
if (this.tracer) {
|
|
@@ -82687,6 +82930,7 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
82687
82930
|
customPrompt: this.customPrompt,
|
|
82688
82931
|
promptType: this.promptType,
|
|
82689
82932
|
allowEdit: this.allowEdit,
|
|
82933
|
+
enableDelegate: this.enableDelegate,
|
|
82690
82934
|
path: this.allowedFolders[0],
|
|
82691
82935
|
// Use first allowed folder as primary path
|
|
82692
82936
|
allowedFolders: [...this.allowedFolders],
|