@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/build/agent/index.js
CHANGED
|
@@ -1893,6 +1893,28 @@ import { exec as execCallback } from "child_process";
|
|
|
1893
1893
|
import tar from "tar";
|
|
1894
1894
|
import os2 from "os";
|
|
1895
1895
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1896
|
+
function sanitizeError(err) {
|
|
1897
|
+
try {
|
|
1898
|
+
const status = err?.response?.status;
|
|
1899
|
+
const statusText = err?.response?.statusText;
|
|
1900
|
+
const url = err?.config?.url || err?.response?.config?.url;
|
|
1901
|
+
const code = err?.code;
|
|
1902
|
+
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;
|
|
1903
|
+
const base = err?.message || String(err);
|
|
1904
|
+
const parts = [base];
|
|
1905
|
+
if (status || statusText) parts.push(`[${status ?? ""} ${statusText ?? ""}]`.trim());
|
|
1906
|
+
if (code) parts.push(`code=${code}`);
|
|
1907
|
+
if (url) parts.push(`url=${url}`);
|
|
1908
|
+
if (serverMsg) parts.push(`server="${String(serverMsg).replace(/\s+/g, " ").trim()}"`);
|
|
1909
|
+
const e = new Error(parts.filter(Boolean).join(" "));
|
|
1910
|
+
if (status) e.status = status;
|
|
1911
|
+
if (code) e.code = code;
|
|
1912
|
+
if (url) e.url = url;
|
|
1913
|
+
return e;
|
|
1914
|
+
} catch (_) {
|
|
1915
|
+
return new Error(err?.message || String(err));
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1896
1918
|
async function acquireFileLock(lockPath, version) {
|
|
1897
1919
|
const lockData = {
|
|
1898
1920
|
version,
|
|
@@ -2041,7 +2063,7 @@ function detectOsArch() {
|
|
|
2041
2063
|
case "linux":
|
|
2042
2064
|
osInfo = {
|
|
2043
2065
|
type: "linux",
|
|
2044
|
-
keywords: ["linux", "Linux", "gnu"]
|
|
2066
|
+
keywords: ["linux", "Linux", "musl", "gnu"]
|
|
2045
2067
|
};
|
|
2046
2068
|
break;
|
|
2047
2069
|
case "darwin":
|
|
@@ -2085,7 +2107,7 @@ function constructAssetInfo(version, osInfo, archInfo) {
|
|
|
2085
2107
|
let extension;
|
|
2086
2108
|
switch (osInfo.type) {
|
|
2087
2109
|
case "linux":
|
|
2088
|
-
platform = `${archInfo.type}-unknown-linux-
|
|
2110
|
+
platform = `${archInfo.type}-unknown-linux-musl`;
|
|
2089
2111
|
extension = "tar.gz";
|
|
2090
2112
|
break;
|
|
2091
2113
|
case "darwin":
|
|
@@ -2202,7 +2224,7 @@ async function getLatestRelease(version) {
|
|
|
2202
2224
|
}
|
|
2203
2225
|
return { tag, assets };
|
|
2204
2226
|
}
|
|
2205
|
-
throw error;
|
|
2227
|
+
throw sanitizeError(error);
|
|
2206
2228
|
}
|
|
2207
2229
|
}
|
|
2208
2230
|
function findBestAsset(assets, osInfo, archInfo) {
|
|
@@ -2416,7 +2438,7 @@ async function extractBinary(assetPath, outputDir) {
|
|
|
2416
2438
|
return binaryPath;
|
|
2417
2439
|
} catch (error) {
|
|
2418
2440
|
console.error(`Error extracting binary: ${error instanceof Error ? error.message : String(error)}`);
|
|
2419
|
-
throw error;
|
|
2441
|
+
throw sanitizeError(error);
|
|
2420
2442
|
}
|
|
2421
2443
|
}
|
|
2422
2444
|
async function getVersionInfo(binDir) {
|
|
@@ -2581,8 +2603,8 @@ async function downloadProbeBinary(version) {
|
|
|
2581
2603
|
}
|
|
2582
2604
|
return await withDownloadLock(version, () => doDownload(version));
|
|
2583
2605
|
} catch (error) {
|
|
2584
|
-
console.error("Error downloading probe binary:", error);
|
|
2585
|
-
throw error;
|
|
2606
|
+
console.error("Error downloading probe binary:", error?.message || String(error));
|
|
2607
|
+
throw sanitizeError(error);
|
|
2586
2608
|
}
|
|
2587
2609
|
}
|
|
2588
2610
|
var exec, REPO_OWNER, REPO_NAME, BINARY_NAME, __filename2, __dirname2, downloadLocks, LOCK_TIMEOUT_MS, LOCK_POLL_INTERVAL_MS, MAX_LOCK_WAIT_MS;
|
|
@@ -2619,9 +2641,15 @@ async function getBinaryPath(options = {}) {
|
|
|
2619
2641
|
probeBinaryPath = await downloadProbeBinary(version);
|
|
2620
2642
|
return probeBinaryPath;
|
|
2621
2643
|
}
|
|
2622
|
-
const binDir = await getPackageBinDir();
|
|
2623
2644
|
const isWindows = process.platform === "win32";
|
|
2624
2645
|
const binaryName = isWindows ? "probe.exe" : "probe-binary";
|
|
2646
|
+
const localPackageBin = path3.resolve(__dirname3, "..", "bin");
|
|
2647
|
+
const localBinaryPath = path3.join(localPackageBin, binaryName);
|
|
2648
|
+
if (fs3.existsSync(localBinaryPath) && !forceDownload) {
|
|
2649
|
+
probeBinaryPath = localBinaryPath;
|
|
2650
|
+
return probeBinaryPath;
|
|
2651
|
+
}
|
|
2652
|
+
const binDir = await getPackageBinDir();
|
|
2625
2653
|
const binaryPath = path3.join(binDir, binaryName);
|
|
2626
2654
|
if (fs3.existsSync(binaryPath) && !forceDownload) {
|
|
2627
2655
|
probeBinaryPath = binaryPath;
|
|
@@ -3063,6 +3091,262 @@ var init_grep = __esm({
|
|
|
3063
3091
|
}
|
|
3064
3092
|
});
|
|
3065
3093
|
|
|
3094
|
+
// src/delegate.js
|
|
3095
|
+
import { randomUUID } from "crypto";
|
|
3096
|
+
async function delegate({
|
|
3097
|
+
task,
|
|
3098
|
+
timeout = 300,
|
|
3099
|
+
debug = false,
|
|
3100
|
+
currentIteration = 0,
|
|
3101
|
+
maxIterations = 30,
|
|
3102
|
+
tracer = null,
|
|
3103
|
+
parentSessionId = null,
|
|
3104
|
+
path: path7 = null,
|
|
3105
|
+
provider = null,
|
|
3106
|
+
model = null
|
|
3107
|
+
}) {
|
|
3108
|
+
if (!task || typeof task !== "string") {
|
|
3109
|
+
throw new Error("Task parameter is required and must be a string");
|
|
3110
|
+
}
|
|
3111
|
+
const sessionId = randomUUID();
|
|
3112
|
+
const startTime = Date.now();
|
|
3113
|
+
const remainingIterations = Math.max(1, maxIterations - currentIteration);
|
|
3114
|
+
const delegationSpan = tracer ? tracer.createDelegationSpan(sessionId, task) : null;
|
|
3115
|
+
let timeoutId = null;
|
|
3116
|
+
let acquired = false;
|
|
3117
|
+
try {
|
|
3118
|
+
delegationManager.tryAcquire(parentSessionId);
|
|
3119
|
+
acquired = true;
|
|
3120
|
+
if (debug) {
|
|
3121
|
+
const stats = delegationManager.getStats();
|
|
3122
|
+
console.error(`[DELEGATE] Starting delegation session ${sessionId}`);
|
|
3123
|
+
console.error(`[DELEGATE] Parent session: ${parentSessionId || "none"}`);
|
|
3124
|
+
console.error(`[DELEGATE] Task: ${task}`);
|
|
3125
|
+
console.error(`[DELEGATE] Current iteration: ${currentIteration}/${maxIterations}`);
|
|
3126
|
+
console.error(`[DELEGATE] Remaining iterations for subagent: ${remainingIterations}`);
|
|
3127
|
+
console.error(`[DELEGATE] Timeout configured: ${timeout} seconds`);
|
|
3128
|
+
console.error(`[DELEGATE] Global active delegations: ${stats.globalActive}/${stats.maxConcurrent}`);
|
|
3129
|
+
console.error(`[DELEGATE] Using ProbeAgent SDK with code-researcher prompt`);
|
|
3130
|
+
}
|
|
3131
|
+
const subagent = new ProbeAgent({
|
|
3132
|
+
sessionId,
|
|
3133
|
+
promptType: "code-researcher",
|
|
3134
|
+
// Clean prompt, not inherited from parent
|
|
3135
|
+
enableDelegate: false,
|
|
3136
|
+
// Explicitly disable delegation to prevent recursion
|
|
3137
|
+
disableMermaidValidation: true,
|
|
3138
|
+
// Faster processing
|
|
3139
|
+
disableJsonValidation: true,
|
|
3140
|
+
// Simpler responses
|
|
3141
|
+
maxIterations: remainingIterations,
|
|
3142
|
+
debug,
|
|
3143
|
+
tracer,
|
|
3144
|
+
path: path7,
|
|
3145
|
+
// Inherit from parent
|
|
3146
|
+
provider,
|
|
3147
|
+
// Inherit from parent
|
|
3148
|
+
model
|
|
3149
|
+
// Inherit from parent
|
|
3150
|
+
});
|
|
3151
|
+
if (debug) {
|
|
3152
|
+
console.error(`[DELEGATE] Created subagent with session ${sessionId}`);
|
|
3153
|
+
console.error(`[DELEGATE] Subagent config: promptType=code-researcher, enableDelegate=false, maxIterations=${remainingIterations}`);
|
|
3154
|
+
}
|
|
3155
|
+
const timeoutPromise = new Promise((_, reject2) => {
|
|
3156
|
+
timeoutId = setTimeout(() => {
|
|
3157
|
+
reject2(new Error(`Delegation timed out after ${timeout} seconds`));
|
|
3158
|
+
}, timeout * 1e3);
|
|
3159
|
+
});
|
|
3160
|
+
const answerPromise = subagent.answer(task);
|
|
3161
|
+
const response = await Promise.race([answerPromise, timeoutPromise]);
|
|
3162
|
+
if (timeoutId !== null) {
|
|
3163
|
+
clearTimeout(timeoutId);
|
|
3164
|
+
timeoutId = null;
|
|
3165
|
+
}
|
|
3166
|
+
const duration = Date.now() - startTime;
|
|
3167
|
+
if (typeof response !== "string") {
|
|
3168
|
+
throw new Error("Delegate agent returned invalid response (not a string)");
|
|
3169
|
+
}
|
|
3170
|
+
const trimmedResponse = response.trim();
|
|
3171
|
+
if (trimmedResponse.length === 0) {
|
|
3172
|
+
throw new Error("Delegate agent returned empty or whitespace-only response");
|
|
3173
|
+
}
|
|
3174
|
+
if (trimmedResponse.includes("\0")) {
|
|
3175
|
+
throw new Error("Delegate agent returned response containing null bytes");
|
|
3176
|
+
}
|
|
3177
|
+
if (debug) {
|
|
3178
|
+
console.error(`[DELEGATE] Task completed successfully for session ${sessionId}`);
|
|
3179
|
+
console.error(`[DELEGATE] Duration: ${(duration / 1e3).toFixed(2)}s`);
|
|
3180
|
+
console.error(`[DELEGATE] Response length: ${response.length} chars`);
|
|
3181
|
+
}
|
|
3182
|
+
if (tracer) {
|
|
3183
|
+
tracer.recordDelegationEvent("completed", {
|
|
3184
|
+
"delegation.session_id": sessionId,
|
|
3185
|
+
"delegation.parent_session_id": parentSessionId,
|
|
3186
|
+
"delegation.duration_ms": duration,
|
|
3187
|
+
"delegation.response_length": response.length,
|
|
3188
|
+
"delegation.success": true
|
|
3189
|
+
});
|
|
3190
|
+
if (delegationSpan) {
|
|
3191
|
+
delegationSpan.setAttributes({
|
|
3192
|
+
"delegation.result.success": true,
|
|
3193
|
+
"delegation.result.response_length": response.length,
|
|
3194
|
+
"delegation.result.duration_ms": duration
|
|
3195
|
+
});
|
|
3196
|
+
delegationSpan.setStatus({ code: 1 });
|
|
3197
|
+
delegationSpan.end();
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
if (acquired) {
|
|
3201
|
+
delegationManager.release(parentSessionId, debug);
|
|
3202
|
+
}
|
|
3203
|
+
return response;
|
|
3204
|
+
} catch (error) {
|
|
3205
|
+
if (timeoutId !== null) {
|
|
3206
|
+
clearTimeout(timeoutId);
|
|
3207
|
+
timeoutId = null;
|
|
3208
|
+
}
|
|
3209
|
+
const duration = Date.now() - startTime;
|
|
3210
|
+
if (acquired) {
|
|
3211
|
+
delegationManager.release(parentSessionId, debug);
|
|
3212
|
+
}
|
|
3213
|
+
if (debug) {
|
|
3214
|
+
console.error(`[DELEGATE] Task failed for session ${sessionId} after ${duration}ms`);
|
|
3215
|
+
console.error(`[DELEGATE] Error: ${error.message}`);
|
|
3216
|
+
console.error(`[DELEGATE] Stack: ${error.stack}`);
|
|
3217
|
+
}
|
|
3218
|
+
if (tracer) {
|
|
3219
|
+
tracer.recordDelegationEvent("failed", {
|
|
3220
|
+
"delegation.session_id": sessionId,
|
|
3221
|
+
"delegation.parent_session_id": parentSessionId,
|
|
3222
|
+
"delegation.duration_ms": duration,
|
|
3223
|
+
"delegation.error_message": error.message,
|
|
3224
|
+
"delegation.success": false
|
|
3225
|
+
});
|
|
3226
|
+
if (delegationSpan) {
|
|
3227
|
+
delegationSpan.setAttributes({
|
|
3228
|
+
"delegation.result.success": false,
|
|
3229
|
+
"delegation.result.error": error.message,
|
|
3230
|
+
"delegation.result.duration_ms": duration
|
|
3231
|
+
});
|
|
3232
|
+
delegationSpan.setStatus({ code: 2, message: error.message });
|
|
3233
|
+
delegationSpan.end();
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
throw new Error(`Delegation failed: ${error.message}`);
|
|
3237
|
+
}
|
|
3238
|
+
}
|
|
3239
|
+
var DelegationManager, delegationManager;
|
|
3240
|
+
var init_delegate = __esm({
|
|
3241
|
+
"src/delegate.js"() {
|
|
3242
|
+
"use strict";
|
|
3243
|
+
init_ProbeAgent();
|
|
3244
|
+
DelegationManager = class {
|
|
3245
|
+
constructor() {
|
|
3246
|
+
this.maxConcurrent = parseInt(process.env.MAX_CONCURRENT_DELEGATIONS || "3", 10);
|
|
3247
|
+
this.maxPerSession = parseInt(process.env.MAX_DELEGATIONS_PER_SESSION || "10", 10);
|
|
3248
|
+
this.sessionDelegations = /* @__PURE__ */ new Map();
|
|
3249
|
+
this.globalActive = 0;
|
|
3250
|
+
this.cleanupInterval = setInterval(() => {
|
|
3251
|
+
try {
|
|
3252
|
+
this.cleanupStaleSessions();
|
|
3253
|
+
} catch (error) {
|
|
3254
|
+
console.error("[DelegationManager] Error during cleanup:", error);
|
|
3255
|
+
}
|
|
3256
|
+
}, 5 * 60 * 1e3);
|
|
3257
|
+
if (this.cleanupInterval.unref) {
|
|
3258
|
+
this.cleanupInterval.unref();
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
/**
|
|
3262
|
+
* Check limits and increment counters (synchronous, atomic in Node.js event loop)
|
|
3263
|
+
* @param {string|null|undefined} parentSessionId - Parent session ID for tracking
|
|
3264
|
+
*/
|
|
3265
|
+
tryAcquire(parentSessionId) {
|
|
3266
|
+
if (parentSessionId !== null && parentSessionId !== void 0 && typeof parentSessionId !== "string") {
|
|
3267
|
+
throw new TypeError("parentSessionId must be a string, null, or undefined");
|
|
3268
|
+
}
|
|
3269
|
+
if (this.globalActive >= this.maxConcurrent) {
|
|
3270
|
+
throw new Error(`Maximum concurrent delegations (${this.maxConcurrent}) reached. Please wait for some delegations to complete.`);
|
|
3271
|
+
}
|
|
3272
|
+
if (parentSessionId) {
|
|
3273
|
+
const sessionData = this.sessionDelegations.get(parentSessionId);
|
|
3274
|
+
const sessionCount = sessionData?.count || 0;
|
|
3275
|
+
if (sessionCount >= this.maxPerSession) {
|
|
3276
|
+
throw new Error(`Maximum delegations per session (${this.maxPerSession}) reached for session ${parentSessionId}`);
|
|
3277
|
+
}
|
|
3278
|
+
}
|
|
3279
|
+
this.globalActive++;
|
|
3280
|
+
if (parentSessionId) {
|
|
3281
|
+
const sessionData = this.sessionDelegations.get(parentSessionId);
|
|
3282
|
+
if (sessionData) {
|
|
3283
|
+
sessionData.count++;
|
|
3284
|
+
sessionData.lastUpdated = Date.now();
|
|
3285
|
+
} else {
|
|
3286
|
+
this.sessionDelegations.set(parentSessionId, {
|
|
3287
|
+
count: 1,
|
|
3288
|
+
lastUpdated: Date.now()
|
|
3289
|
+
});
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3292
|
+
return true;
|
|
3293
|
+
}
|
|
3294
|
+
/**
|
|
3295
|
+
* Decrement counters (synchronous, atomic in Node.js event loop)
|
|
3296
|
+
*/
|
|
3297
|
+
release(parentSessionId, debug = false) {
|
|
3298
|
+
this.globalActive = Math.max(0, this.globalActive - 1);
|
|
3299
|
+
if (parentSessionId) {
|
|
3300
|
+
const sessionData = this.sessionDelegations.get(parentSessionId);
|
|
3301
|
+
if (sessionData) {
|
|
3302
|
+
sessionData.count = Math.max(0, sessionData.count - 1);
|
|
3303
|
+
if (sessionData.count === 0) {
|
|
3304
|
+
this.sessionDelegations.delete(parentSessionId);
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
if (debug) {
|
|
3309
|
+
console.error(`[DELEGATE] Released. Global active: ${this.globalActive}`);
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
/**
|
|
3313
|
+
* Get current stats for monitoring
|
|
3314
|
+
*/
|
|
3315
|
+
getStats() {
|
|
3316
|
+
return {
|
|
3317
|
+
globalActive: this.globalActive,
|
|
3318
|
+
maxConcurrent: this.maxConcurrent,
|
|
3319
|
+
maxPerSession: this.maxPerSession,
|
|
3320
|
+
sessionCount: this.sessionDelegations.size
|
|
3321
|
+
};
|
|
3322
|
+
}
|
|
3323
|
+
/**
|
|
3324
|
+
* Clean up stale sessions (sessions with count=0 that haven't been updated in 1 hour)
|
|
3325
|
+
*/
|
|
3326
|
+
cleanupStaleSessions() {
|
|
3327
|
+
const oneHourAgo = Date.now() - 60 * 60 * 1e3;
|
|
3328
|
+
for (const [sessionId, data] of this.sessionDelegations.entries()) {
|
|
3329
|
+
if (data.count === 0 && data.lastUpdated < oneHourAgo) {
|
|
3330
|
+
this.sessionDelegations.delete(sessionId);
|
|
3331
|
+
}
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
/**
|
|
3335
|
+
* Cleanup all resources (for testing or shutdown)
|
|
3336
|
+
*/
|
|
3337
|
+
cleanup() {
|
|
3338
|
+
if (this.cleanupInterval) {
|
|
3339
|
+
clearInterval(this.cleanupInterval);
|
|
3340
|
+
this.cleanupInterval = null;
|
|
3341
|
+
}
|
|
3342
|
+
this.sessionDelegations.clear();
|
|
3343
|
+
this.globalActive = 0;
|
|
3344
|
+
}
|
|
3345
|
+
};
|
|
3346
|
+
delegationManager = new DelegationManager();
|
|
3347
|
+
}
|
|
3348
|
+
});
|
|
3349
|
+
|
|
3066
3350
|
// node_modules/zod/v3/helpers/util.js
|
|
3067
3351
|
var util, objectUtil, ZodParsedType, getParsedType;
|
|
3068
3352
|
var init_util2 = __esm({
|
|
@@ -7276,7 +7560,7 @@ function parseTargets(targets) {
|
|
|
7276
7560
|
}
|
|
7277
7561
|
return targets.split(/\s+/).filter((f) => f.length > 0);
|
|
7278
7562
|
}
|
|
7279
|
-
var searchSchema, querySchema, extractSchema, delegateSchema, bashSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, attemptCompletionToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, DEFAULT_VALID_TOOLS;
|
|
7563
|
+
var searchSchema, querySchema, extractSchema, delegateSchema, bashSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, DEFAULT_VALID_TOOLS;
|
|
7280
7564
|
var init_common = __esm({
|
|
7281
7565
|
"src/tools/common.js"() {
|
|
7282
7566
|
"use strict";
|
|
@@ -7481,6 +7765,26 @@ User: Read file inside the dependency
|
|
|
7481
7765
|
</extract>
|
|
7482
7766
|
|
|
7483
7767
|
</examples>
|
|
7768
|
+
`;
|
|
7769
|
+
delegateToolDefinition = `
|
|
7770
|
+
## delegate
|
|
7771
|
+
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.
|
|
7772
|
+
|
|
7773
|
+
Parameters:
|
|
7774
|
+
- 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.
|
|
7775
|
+
|
|
7776
|
+
Usage Pattern:
|
|
7777
|
+
When the AI agent encounters complex multi-part requests, it should automatically break them down and delegate:
|
|
7778
|
+
|
|
7779
|
+
<delegate>
|
|
7780
|
+
<task>Analyze all authentication and authorization code in the codebase for security vulnerabilities and provide specific remediation recommendations</task>
|
|
7781
|
+
</delegate>
|
|
7782
|
+
|
|
7783
|
+
<delegate>
|
|
7784
|
+
<task>Review database queries and API endpoints for performance bottlenecks and suggest optimization strategies</task>
|
|
7785
|
+
</delegate>
|
|
7786
|
+
|
|
7787
|
+
The agent uses this tool automatically when it identifies that work can be separated into distinct, parallel tasks for more efficient processing.
|
|
7484
7788
|
`;
|
|
7485
7789
|
attemptCompletionToolDefinition = `
|
|
7486
7790
|
## attempt_completion
|
|
@@ -7509,193 +7813,6 @@ I have refactored the search module according to the requirements and verified t
|
|
|
7509
7813
|
}
|
|
7510
7814
|
});
|
|
7511
7815
|
|
|
7512
|
-
// src/delegate.js
|
|
7513
|
-
import { spawn as spawn2 } from "child_process";
|
|
7514
|
-
import { randomUUID } from "crypto";
|
|
7515
|
-
async function delegate({ task, timeout = 300, debug = false, currentIteration = 0, maxIterations = 30, tracer = null }) {
|
|
7516
|
-
if (!task || typeof task !== "string") {
|
|
7517
|
-
throw new Error("Task parameter is required and must be a string");
|
|
7518
|
-
}
|
|
7519
|
-
const sessionId = randomUUID();
|
|
7520
|
-
const startTime = Date.now();
|
|
7521
|
-
const remainingIterations = Math.max(1, maxIterations - currentIteration);
|
|
7522
|
-
if (debug) {
|
|
7523
|
-
console.error(`[DELEGATE] Starting delegation session ${sessionId}`);
|
|
7524
|
-
console.error(`[DELEGATE] Task: ${task}`);
|
|
7525
|
-
console.error(`[DELEGATE] Current iteration: ${currentIteration}/${maxIterations}`);
|
|
7526
|
-
console.error(`[DELEGATE] Remaining iterations for subagent: ${remainingIterations}`);
|
|
7527
|
-
console.error(`[DELEGATE] Timeout configured: ${timeout} seconds`);
|
|
7528
|
-
console.error(`[DELEGATE] Using clean agent environment with code-researcher prompt`);
|
|
7529
|
-
}
|
|
7530
|
-
try {
|
|
7531
|
-
const binaryPath = await getBinaryPath();
|
|
7532
|
-
const args = [
|
|
7533
|
-
"agent",
|
|
7534
|
-
"--task",
|
|
7535
|
-
task,
|
|
7536
|
-
"--session-id",
|
|
7537
|
-
sessionId,
|
|
7538
|
-
"--prompt-type",
|
|
7539
|
-
"code-researcher",
|
|
7540
|
-
// Automatically use default code researcher prompt
|
|
7541
|
-
"--no-schema-validation",
|
|
7542
|
-
// Automatically disable schema validation
|
|
7543
|
-
"--no-mermaid-validation",
|
|
7544
|
-
// Automatically disable mermaid validation
|
|
7545
|
-
"--max-iterations",
|
|
7546
|
-
remainingIterations.toString()
|
|
7547
|
-
// Automatically limit to remaining iterations
|
|
7548
|
-
];
|
|
7549
|
-
if (debug) {
|
|
7550
|
-
args.push("--debug");
|
|
7551
|
-
console.error(`[DELEGATE] Using binary at: ${binaryPath}`);
|
|
7552
|
-
console.error(`[DELEGATE] Command args: ${args.join(" ")}`);
|
|
7553
|
-
}
|
|
7554
|
-
return new Promise((resolve5, reject2) => {
|
|
7555
|
-
const delegationSpan = tracer ? tracer.createDelegationSpan(sessionId, task) : null;
|
|
7556
|
-
const process2 = spawn2(binaryPath, args, {
|
|
7557
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
7558
|
-
timeout: timeout * 1e3
|
|
7559
|
-
});
|
|
7560
|
-
let stdout = "";
|
|
7561
|
-
let stderr = "";
|
|
7562
|
-
let isResolved = false;
|
|
7563
|
-
process2.stdout.on("data", (data) => {
|
|
7564
|
-
const chunk = data.toString();
|
|
7565
|
-
stdout += chunk;
|
|
7566
|
-
if (debug) {
|
|
7567
|
-
const preview = createMessagePreview(chunk);
|
|
7568
|
-
console.error(`[DELEGATE] stdout chunk received (${chunk.length} chars): ${preview}`);
|
|
7569
|
-
}
|
|
7570
|
-
});
|
|
7571
|
-
process2.stderr.on("data", (data) => {
|
|
7572
|
-
const chunk = data.toString();
|
|
7573
|
-
stderr += chunk;
|
|
7574
|
-
if (debug) {
|
|
7575
|
-
const preview = createMessagePreview(chunk);
|
|
7576
|
-
console.error(`[DELEGATE] stderr chunk received (${chunk.length} chars): ${preview}`);
|
|
7577
|
-
}
|
|
7578
|
-
});
|
|
7579
|
-
process2.on("close", (code) => {
|
|
7580
|
-
if (isResolved) return;
|
|
7581
|
-
isResolved = true;
|
|
7582
|
-
const duration = Date.now() - startTime;
|
|
7583
|
-
if (debug) {
|
|
7584
|
-
console.error(`[DELEGATE] Process completed with code ${code} in ${duration}ms`);
|
|
7585
|
-
console.error(`[DELEGATE] Duration: ${(duration / 1e3).toFixed(2)}s`);
|
|
7586
|
-
console.error(`[DELEGATE] Total stdout: ${stdout.length} chars`);
|
|
7587
|
-
console.error(`[DELEGATE] Total stderr: ${stderr.length} chars`);
|
|
7588
|
-
}
|
|
7589
|
-
if (code === 0) {
|
|
7590
|
-
const response = stdout.trim();
|
|
7591
|
-
if (!response) {
|
|
7592
|
-
if (debug) {
|
|
7593
|
-
console.error(`[DELEGATE] Task completed but returned empty response for session ${sessionId}`);
|
|
7594
|
-
}
|
|
7595
|
-
reject2(new Error("Delegate agent returned empty response"));
|
|
7596
|
-
return;
|
|
7597
|
-
}
|
|
7598
|
-
if (debug) {
|
|
7599
|
-
console.error(`[DELEGATE] Task completed successfully for session ${sessionId}`);
|
|
7600
|
-
console.error(`[DELEGATE] Response length: ${response.length} chars`);
|
|
7601
|
-
}
|
|
7602
|
-
if (tracer) {
|
|
7603
|
-
tracer.recordDelegationEvent("completed", {
|
|
7604
|
-
"delegation.session_id": sessionId,
|
|
7605
|
-
"delegation.duration_ms": duration,
|
|
7606
|
-
"delegation.response_length": response.length,
|
|
7607
|
-
"delegation.success": true
|
|
7608
|
-
});
|
|
7609
|
-
if (delegationSpan) {
|
|
7610
|
-
delegationSpan.setAttributes({
|
|
7611
|
-
"delegation.result.success": true,
|
|
7612
|
-
"delegation.result.response_length": response.length,
|
|
7613
|
-
"delegation.result.duration_ms": duration
|
|
7614
|
-
});
|
|
7615
|
-
delegationSpan.setStatus({ code: 1 });
|
|
7616
|
-
delegationSpan.end();
|
|
7617
|
-
}
|
|
7618
|
-
}
|
|
7619
|
-
resolve5(response);
|
|
7620
|
-
} else {
|
|
7621
|
-
const errorMessage = stderr.trim() || `Delegate process failed with exit code ${code}`;
|
|
7622
|
-
if (debug) {
|
|
7623
|
-
console.error(`[DELEGATE] Task failed for session ${sessionId} with code ${code}`);
|
|
7624
|
-
console.error(`[DELEGATE] Error message: ${errorMessage}`);
|
|
7625
|
-
}
|
|
7626
|
-
if (tracer) {
|
|
7627
|
-
tracer.recordDelegationEvent("failed", {
|
|
7628
|
-
"delegation.session_id": sessionId,
|
|
7629
|
-
"delegation.duration_ms": duration,
|
|
7630
|
-
"delegation.exit_code": code,
|
|
7631
|
-
"delegation.error_message": errorMessage,
|
|
7632
|
-
"delegation.success": false
|
|
7633
|
-
});
|
|
7634
|
-
if (delegationSpan) {
|
|
7635
|
-
delegationSpan.setAttributes({
|
|
7636
|
-
"delegation.result.success": false,
|
|
7637
|
-
"delegation.result.exit_code": code,
|
|
7638
|
-
"delegation.result.error": errorMessage,
|
|
7639
|
-
"delegation.result.duration_ms": duration
|
|
7640
|
-
});
|
|
7641
|
-
delegationSpan.setStatus({ code: 2, message: errorMessage });
|
|
7642
|
-
delegationSpan.end();
|
|
7643
|
-
}
|
|
7644
|
-
}
|
|
7645
|
-
reject2(new Error(`Delegation failed: ${errorMessage}`));
|
|
7646
|
-
}
|
|
7647
|
-
});
|
|
7648
|
-
process2.on("error", (error) => {
|
|
7649
|
-
if (isResolved) return;
|
|
7650
|
-
isResolved = true;
|
|
7651
|
-
const duration = Date.now() - startTime;
|
|
7652
|
-
if (debug) {
|
|
7653
|
-
console.error(`[DELEGATE] Process spawn error after ${duration}ms:`, error);
|
|
7654
|
-
console.error(`[DELEGATE] Session ${sessionId} failed during process creation`);
|
|
7655
|
-
console.error(`[DELEGATE] Error type: ${error.code || "unknown"}`);
|
|
7656
|
-
}
|
|
7657
|
-
reject2(new Error(`Failed to start delegate process: ${error.message}`));
|
|
7658
|
-
});
|
|
7659
|
-
setTimeout(() => {
|
|
7660
|
-
if (isResolved) return;
|
|
7661
|
-
isResolved = true;
|
|
7662
|
-
const duration = Date.now() - startTime;
|
|
7663
|
-
if (debug) {
|
|
7664
|
-
console.error(`[DELEGATE] Process timeout after ${(duration / 1e3).toFixed(2)}s (limit: ${timeout}s)`);
|
|
7665
|
-
console.error(`[DELEGATE] Terminating session ${sessionId} due to timeout`);
|
|
7666
|
-
console.error(`[DELEGATE] Partial stdout: ${stdout.substring(0, 500)}${stdout.length > 500 ? "..." : ""}`);
|
|
7667
|
-
console.error(`[DELEGATE] Partial stderr: ${stderr.substring(0, 500)}${stderr.length > 500 ? "..." : ""}`);
|
|
7668
|
-
}
|
|
7669
|
-
process2.kill("SIGTERM");
|
|
7670
|
-
setTimeout(() => {
|
|
7671
|
-
if (!process2.killed) {
|
|
7672
|
-
if (debug) {
|
|
7673
|
-
console.error(`[DELEGATE] Force killing process ${sessionId} after graceful timeout`);
|
|
7674
|
-
}
|
|
7675
|
-
process2.kill("SIGKILL");
|
|
7676
|
-
}
|
|
7677
|
-
}, 5e3);
|
|
7678
|
-
reject2(new Error(`Delegation timed out after ${timeout} seconds`));
|
|
7679
|
-
}, timeout * 1e3);
|
|
7680
|
-
});
|
|
7681
|
-
} catch (error) {
|
|
7682
|
-
const duration = Date.now() - startTime;
|
|
7683
|
-
if (debug) {
|
|
7684
|
-
console.error(`[DELEGATE] Error in delegate function after ${duration}ms:`, error);
|
|
7685
|
-
console.error(`[DELEGATE] Session ${sessionId} failed during setup`);
|
|
7686
|
-
console.error(`[DELEGATE] Error stack: ${error.stack}`);
|
|
7687
|
-
}
|
|
7688
|
-
throw new Error(`Delegation setup failed: ${error.message}`);
|
|
7689
|
-
}
|
|
7690
|
-
}
|
|
7691
|
-
var init_delegate = __esm({
|
|
7692
|
-
"src/delegate.js"() {
|
|
7693
|
-
"use strict";
|
|
7694
|
-
init_utils();
|
|
7695
|
-
init_common();
|
|
7696
|
-
}
|
|
7697
|
-
});
|
|
7698
|
-
|
|
7699
7816
|
// src/tools/vercel.js
|
|
7700
7817
|
import { tool } from "ai";
|
|
7701
7818
|
var searchTool, queryTool, extractTool, delegateTool;
|
|
@@ -7868,21 +7985,50 @@ var init_vercel = __esm({
|
|
|
7868
7985
|
name: "delegate",
|
|
7869
7986
|
description: delegateDescription,
|
|
7870
7987
|
inputSchema: delegateSchema,
|
|
7871
|
-
execute: async ({ task }) => {
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
});
|
|
7881
|
-
return result;
|
|
7882
|
-
} catch (error) {
|
|
7883
|
-
console.error("Error executing delegate command:", error);
|
|
7884
|
-
return `Error executing delegate command: ${error.message}`;
|
|
7988
|
+
execute: async ({ task, currentIteration, maxIterations, parentSessionId, path: path7, provider, model, tracer }) => {
|
|
7989
|
+
if (!task || typeof task !== "string") {
|
|
7990
|
+
throw new Error("Task parameter is required and must be a non-empty string");
|
|
7991
|
+
}
|
|
7992
|
+
if (task.trim().length === 0) {
|
|
7993
|
+
throw new Error("Task parameter cannot be empty or whitespace only");
|
|
7994
|
+
}
|
|
7995
|
+
if (currentIteration !== void 0 && (typeof currentIteration !== "number" || currentIteration < 0)) {
|
|
7996
|
+
throw new Error("currentIteration must be a non-negative number");
|
|
7885
7997
|
}
|
|
7998
|
+
if (maxIterations !== void 0 && (typeof maxIterations !== "number" || maxIterations < 1)) {
|
|
7999
|
+
throw new Error("maxIterations must be a positive number");
|
|
8000
|
+
}
|
|
8001
|
+
if (parentSessionId !== void 0 && parentSessionId !== null && typeof parentSessionId !== "string") {
|
|
8002
|
+
throw new TypeError("parentSessionId must be a string, null, or undefined");
|
|
8003
|
+
}
|
|
8004
|
+
if (path7 !== void 0 && path7 !== null && typeof path7 !== "string") {
|
|
8005
|
+
throw new TypeError("path must be a string, null, or undefined");
|
|
8006
|
+
}
|
|
8007
|
+
if (provider !== void 0 && provider !== null && typeof provider !== "string") {
|
|
8008
|
+
throw new TypeError("provider must be a string, null, or undefined");
|
|
8009
|
+
}
|
|
8010
|
+
if (model !== void 0 && model !== null && typeof model !== "string") {
|
|
8011
|
+
throw new TypeError("model must be a string, null, or undefined");
|
|
8012
|
+
}
|
|
8013
|
+
if (debug) {
|
|
8014
|
+
console.error(`Executing delegate with task: "${task.substring(0, 100)}${task.length > 100 ? "..." : ""}"`);
|
|
8015
|
+
if (parentSessionId) {
|
|
8016
|
+
console.error(`Parent session: ${parentSessionId}`);
|
|
8017
|
+
}
|
|
8018
|
+
}
|
|
8019
|
+
const result = await delegate({
|
|
8020
|
+
task,
|
|
8021
|
+
timeout,
|
|
8022
|
+
debug,
|
|
8023
|
+
currentIteration: currentIteration || 0,
|
|
8024
|
+
maxIterations: maxIterations || 30,
|
|
8025
|
+
parentSessionId,
|
|
8026
|
+
path: path7,
|
|
8027
|
+
provider,
|
|
8028
|
+
model,
|
|
8029
|
+
tracer
|
|
8030
|
+
});
|
|
8031
|
+
return result;
|
|
7886
8032
|
}
|
|
7887
8033
|
});
|
|
7888
8034
|
};
|
|
@@ -8711,7 +8857,7 @@ var init_bashPermissions = __esm({
|
|
|
8711
8857
|
});
|
|
8712
8858
|
|
|
8713
8859
|
// src/agent/bashExecutor.js
|
|
8714
|
-
import { spawn as
|
|
8860
|
+
import { spawn as spawn2 } from "child_process";
|
|
8715
8861
|
import { resolve, join } from "path";
|
|
8716
8862
|
import { existsSync } from "fs";
|
|
8717
8863
|
async function executeBashCommand(command, options = {}) {
|
|
@@ -8768,7 +8914,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
8768
8914
|
return;
|
|
8769
8915
|
}
|
|
8770
8916
|
const [cmd, ...cmdArgs] = args;
|
|
8771
|
-
const child =
|
|
8917
|
+
const child = spawn2(cmd, cmdArgs, {
|
|
8772
8918
|
cwd,
|
|
8773
8919
|
env: processEnv,
|
|
8774
8920
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -29929,13 +30075,24 @@ function mapFlowchartParserError(err, text) {
|
|
|
29929
30075
|
length: len
|
|
29930
30076
|
};
|
|
29931
30077
|
}
|
|
29932
|
-
if (tokType === "QuotedString") {
|
|
30078
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
29933
30079
|
const context = err?.context;
|
|
29934
30080
|
const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
|
|
29935
30081
|
const lineContent = allLines[Math.max(0, line - 1)] || "";
|
|
29936
30082
|
const beforeQuote = lineContent.slice(0, Math.max(0, column - 1));
|
|
29937
30083
|
const hasLinkBefore = beforeQuote.match(/--\s*$|==\s*$|-\.\s*$|-\.-\s*$|\[\s*$/);
|
|
29938
30084
|
if (inLinkRule || hasLinkBefore) {
|
|
30085
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
30086
|
+
return {
|
|
30087
|
+
line,
|
|
30088
|
+
column,
|
|
30089
|
+
severity: "error",
|
|
30090
|
+
code: "FL-EDGE-LABEL-BRACKET",
|
|
30091
|
+
message: "Square brackets [ ] are not supported inside inline edge labels.",
|
|
30092
|
+
hint: "Use HTML entities [ and ] inside |...|, e.g., --|run: [aggregate]|-->",
|
|
30093
|
+
length: len
|
|
30094
|
+
};
|
|
30095
|
+
}
|
|
29939
30096
|
const quotedText = found.startsWith('"') ? found.slice(1, -1) : found;
|
|
29940
30097
|
return {
|
|
29941
30098
|
line,
|
|
@@ -30029,7 +30186,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
30029
30186
|
}
|
|
30030
30187
|
}
|
|
30031
30188
|
}
|
|
30032
|
-
if (tokType === "QuotedString") {
|
|
30189
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
30033
30190
|
return {
|
|
30034
30191
|
line,
|
|
30035
30192
|
column,
|
|
@@ -30050,7 +30207,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
30050
30207
|
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 };
|
|
30051
30208
|
}
|
|
30052
30209
|
if (expecting(err, "RoundClose")) {
|
|
30053
|
-
if (tokType === "QuotedString") {
|
|
30210
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
30054
30211
|
return {
|
|
30055
30212
|
line,
|
|
30056
30213
|
column,
|
|
@@ -30089,7 +30246,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
30089
30246
|
return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '('. Add a matching ')'.", hint: "Example: B(Label)", length: 1 };
|
|
30090
30247
|
}
|
|
30091
30248
|
if (expecting(err, "DiamondClose")) {
|
|
30092
|
-
if (tokType === "QuotedString") {
|
|
30249
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
30093
30250
|
return {
|
|
30094
30251
|
line,
|
|
30095
30252
|
column,
|
|
@@ -30935,6 +31092,53 @@ function validateFlowchart(text, options = {}) {
|
|
|
30935
31092
|
}
|
|
30936
31093
|
}
|
|
30937
31094
|
}
|
|
31095
|
+
{
|
|
31096
|
+
const byLine = /* @__PURE__ */ new Map();
|
|
31097
|
+
const collect = (arr) => {
|
|
31098
|
+
for (const e of arr || []) {
|
|
31099
|
+
if (e && e.code === "FL-LABEL-PARENS-UNQUOTED") {
|
|
31100
|
+
const ln = e.line ?? 0;
|
|
31101
|
+
const col = e.column ?? 1;
|
|
31102
|
+
const list = byLine.get(ln) || [];
|
|
31103
|
+
list.push(col);
|
|
31104
|
+
byLine.set(ln, list);
|
|
31105
|
+
}
|
|
31106
|
+
}
|
|
31107
|
+
};
|
|
31108
|
+
collect(prevErrors);
|
|
31109
|
+
collect(errs);
|
|
31110
|
+
const lines2 = text2.split(/\r?\n/);
|
|
31111
|
+
for (let ii = 0; ii < lines2.length; ii++) {
|
|
31112
|
+
const raw2 = lines2[ii] || "";
|
|
31113
|
+
if (!raw2.includes("[") || !raw2.includes("]"))
|
|
31114
|
+
continue;
|
|
31115
|
+
let search2 = 0;
|
|
31116
|
+
while (true) {
|
|
31117
|
+
const open2 = raw2.indexOf("[", search2);
|
|
31118
|
+
if (open2 === -1)
|
|
31119
|
+
break;
|
|
31120
|
+
const close2 = raw2.indexOf("]", open2 + 1);
|
|
31121
|
+
if (close2 === -1)
|
|
31122
|
+
break;
|
|
31123
|
+
const seg2 = raw2.slice(open2 + 1, close2);
|
|
31124
|
+
const trimmed2 = seg2.trim();
|
|
31125
|
+
const ln2 = ii + 1;
|
|
31126
|
+
const lsp = trimmed2.slice(0, 1);
|
|
31127
|
+
const rsp = trimmed2.slice(-1);
|
|
31128
|
+
const isSlashPair = (lsp === "/" || lsp === "\\") && (rsp === "/" || rsp === "\\");
|
|
31129
|
+
const isParenWrapped = lsp === "(" && rsp === ")";
|
|
31130
|
+
const segStartCol = open2 + 2;
|
|
31131
|
+
const segEndCol = close2 + 1;
|
|
31132
|
+
const existing = byLine.get(ln2) || [];
|
|
31133
|
+
const covered = existing.some((c) => c >= segStartCol && c <= segEndCol);
|
|
31134
|
+
if (!covered && !/^".*"$/.test(trimmed2) && (seg2.includes("(") || seg2.includes(")")) && !isSlashPair && !isParenWrapped) {
|
|
31135
|
+
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 ).' });
|
|
31136
|
+
byLine.set(ln2, existing.concat([segStartCol]));
|
|
31137
|
+
}
|
|
31138
|
+
search2 = close2 + 1;
|
|
31139
|
+
}
|
|
31140
|
+
}
|
|
31141
|
+
}
|
|
30938
31142
|
const dblEsc = (text2.match(/\\\"/g) || []).length;
|
|
30939
31143
|
const dq = (text2.match(/\"/g) || []).length - dblEsc;
|
|
30940
31144
|
const sq = (text2.match(/'/g) || []).length;
|
|
@@ -33279,6 +33483,21 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
33279
33483
|
}
|
|
33280
33484
|
continue;
|
|
33281
33485
|
}
|
|
33486
|
+
if (is("FL-EDGE-LABEL-BRACKET", e)) {
|
|
33487
|
+
const lineText = lineTextAt(text, e.line);
|
|
33488
|
+
const firstBar = lineText.indexOf("|");
|
|
33489
|
+
const secondBar = firstBar >= 0 ? lineText.indexOf("|", firstBar + 1) : -1;
|
|
33490
|
+
if (firstBar >= 0 && secondBar > firstBar) {
|
|
33491
|
+
const before = lineText.slice(0, firstBar + 1);
|
|
33492
|
+
const label = lineText.slice(firstBar + 1, secondBar);
|
|
33493
|
+
const after = lineText.slice(secondBar);
|
|
33494
|
+
const fixedLabel = label.replace(/\[/g, "[").replace(/\]/g, "]");
|
|
33495
|
+
const fixedLine = before + fixedLabel + after;
|
|
33496
|
+
const finalLine = fixedLine.replace(/\[([^\]]*)\]/g, (m, seg) => "[" + String(seg).replace(/`/g, "") + "]");
|
|
33497
|
+
edits.push({ start: { line: e.line, column: 1 }, end: { line: e.line, column: lineText.length + 1 }, newText: finalLine });
|
|
33498
|
+
}
|
|
33499
|
+
continue;
|
|
33500
|
+
}
|
|
33282
33501
|
if (is("FL-EDGE-LABEL-BACKTICK", e)) {
|
|
33283
33502
|
const lineText = lineTextAt(text, e.line);
|
|
33284
33503
|
const re = /^(.*?--)\s*([^|>]+?)\s*(-->|==>|\.->|->)(.*)$/;
|
|
@@ -55434,6 +55653,7 @@ var init_ProbeAgent = __esm({
|
|
|
55434
55653
|
* @param {string} [options.customPrompt] - Custom prompt to replace the default system message
|
|
55435
55654
|
* @param {string} [options.promptType] - Predefined prompt type (architect, code-review, support)
|
|
55436
55655
|
* @param {boolean} [options.allowEdit=false] - Allow the use of the 'implement' tool
|
|
55656
|
+
* @param {boolean} [options.enableDelegate=false] - Enable the delegate tool for task distribution to subagents
|
|
55437
55657
|
* @param {string} [options.path] - Search directory path
|
|
55438
55658
|
* @param {string} [options.provider] - Force specific AI provider
|
|
55439
55659
|
* @param {string} [options.model] - Override model name
|
|
@@ -55455,6 +55675,7 @@ var init_ProbeAgent = __esm({
|
|
|
55455
55675
|
this.customPrompt = options.customPrompt || null;
|
|
55456
55676
|
this.promptType = options.promptType || "code-explorer";
|
|
55457
55677
|
this.allowEdit = !!options.allowEdit;
|
|
55678
|
+
this.enableDelegate = !!options.enableDelegate;
|
|
55458
55679
|
this.debug = options.debug || process.env.DEBUG === "1";
|
|
55459
55680
|
this.cancelled = false;
|
|
55460
55681
|
this.tracer = options.tracer || null;
|
|
@@ -56049,6 +56270,10 @@ ${attemptCompletionToolDefinition}
|
|
|
56049
56270
|
`;
|
|
56050
56271
|
if (this.allowEdit) {
|
|
56051
56272
|
toolDefinitions += `${implementToolDefinition}
|
|
56273
|
+
`;
|
|
56274
|
+
}
|
|
56275
|
+
if (this.enableDelegate) {
|
|
56276
|
+
toolDefinitions += `${delegateToolDefinition}
|
|
56052
56277
|
`;
|
|
56053
56278
|
}
|
|
56054
56279
|
let xmlToolGuidelines = `
|
|
@@ -56112,7 +56337,7 @@ Available Tools:
|
|
|
56112
56337
|
- extract: Extract specific code blocks or lines from files.
|
|
56113
56338
|
- listFiles: List files and directories in a specified location.
|
|
56114
56339
|
- searchFiles: Find files matching a glob pattern with recursive search capability.
|
|
56115
|
-
${this.allowEdit ? "- implement: Implement a feature or fix a bug using aider.\n" : ""}
|
|
56340
|
+
${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" : ""}
|
|
56116
56341
|
- attempt_completion: Finalize the task and provide the result to the user.
|
|
56117
56342
|
- attempt_complete: Quick completion using previous response (shorthand).
|
|
56118
56343
|
`;
|
|
@@ -56432,6 +56657,9 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
56432
56657
|
if (this.allowEdit) {
|
|
56433
56658
|
validTools.push("implement");
|
|
56434
56659
|
}
|
|
56660
|
+
if (this.enableDelegate) {
|
|
56661
|
+
validTools.push("delegate");
|
|
56662
|
+
}
|
|
56435
56663
|
const nativeTools = validTools;
|
|
56436
56664
|
const parsedTool = this.mcpBridge ? parseHybridXmlToolCall(assistantResponseContent, nativeTools, this.mcpBridge) : parseXmlToolCallWithThinking(assistantResponseContent, validTools);
|
|
56437
56665
|
if (parsedTool) {
|
|
@@ -56545,11 +56773,21 @@ ${toolResultContent}
|
|
|
56545
56773
|
...toolParams,
|
|
56546
56774
|
currentIteration,
|
|
56547
56775
|
maxIterations,
|
|
56776
|
+
parentSessionId: this.sessionId,
|
|
56777
|
+
// Pass parent session ID for tracking
|
|
56778
|
+
path: this.searchPath,
|
|
56779
|
+
// Inherit search path
|
|
56780
|
+
provider: this.provider,
|
|
56781
|
+
// Inherit AI provider
|
|
56782
|
+
model: this.model,
|
|
56783
|
+
// Inherit model
|
|
56548
56784
|
debug: this.debug,
|
|
56549
56785
|
tracer: this.tracer
|
|
56550
56786
|
};
|
|
56551
56787
|
if (this.debug) {
|
|
56552
56788
|
console.log(`[DEBUG] Executing delegate tool at iteration ${currentIteration}/${maxIterations}`);
|
|
56789
|
+
console.log(`[DEBUG] Parent session: ${this.sessionId}`);
|
|
56790
|
+
console.log(`[DEBUG] Inherited config: path=${this.searchPath}, provider=${this.provider}, model=${this.model}`);
|
|
56553
56791
|
console.log(`[DEBUG] Delegate task: ${toolParams.task?.substring(0, 100)}...`);
|
|
56554
56792
|
}
|
|
56555
56793
|
if (this.tracer) {
|
|
@@ -57140,6 +57378,7 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
57140
57378
|
customPrompt: this.customPrompt,
|
|
57141
57379
|
promptType: this.promptType,
|
|
57142
57380
|
allowEdit: this.allowEdit,
|
|
57381
|
+
enableDelegate: this.enableDelegate,
|
|
57143
57382
|
path: this.allowedFolders[0],
|
|
57144
57383
|
// Use first allowed folder as primary path
|
|
57145
57384
|
allowedFolders: [...this.allowedFolders],
|
|
@@ -57896,6 +58135,7 @@ var ACPServer = class {
|
|
|
57896
58135
|
provider: this.options.provider,
|
|
57897
58136
|
model: this.options.model,
|
|
57898
58137
|
allowEdit: this.options.allowEdit,
|
|
58138
|
+
enableDelegate: this.options.enableDelegate,
|
|
57899
58139
|
debug: this.options.debug,
|
|
57900
58140
|
enableMcp: this.options.enableMcp,
|
|
57901
58141
|
mcpConfig: this.options.mcpConfig,
|
|
@@ -58070,6 +58310,7 @@ function parseArgs() {
|
|
|
58070
58310
|
provider: null,
|
|
58071
58311
|
model: null,
|
|
58072
58312
|
allowEdit: false,
|
|
58313
|
+
enableDelegate: false,
|
|
58073
58314
|
verbose: false,
|
|
58074
58315
|
help: false,
|
|
58075
58316
|
maxIterations: null,
|
|
@@ -58104,6 +58345,10 @@ function parseArgs() {
|
|
|
58104
58345
|
config.verbose = true;
|
|
58105
58346
|
} else if (arg === "--allow-edit") {
|
|
58106
58347
|
config.allowEdit = true;
|
|
58348
|
+
} else if (arg === "--enable-delegate") {
|
|
58349
|
+
config.enableDelegate = true;
|
|
58350
|
+
} else if (arg === "--no-delegate") {
|
|
58351
|
+
config.enableDelegate = false;
|
|
58107
58352
|
} else if (arg === "--path" && i + 1 < args.length) {
|
|
58108
58353
|
config.path = args[++i];
|
|
58109
58354
|
} else if (arg === "--allowed-folders" && i + 1 < args.length) {
|
|
@@ -58175,6 +58420,7 @@ Options:
|
|
|
58175
58420
|
--provider <name> Force AI provider: anthropic, openai, google
|
|
58176
58421
|
--model <name> Override model name
|
|
58177
58422
|
--allow-edit Enable code modification capabilities
|
|
58423
|
+
--enable-delegate Enable delegate tool for task distribution to subagents
|
|
58178
58424
|
--verbose Enable verbose output
|
|
58179
58425
|
--outline Use outline-xml format for code search results
|
|
58180
58426
|
--mcp Run as MCP server
|
|
@@ -58455,6 +58701,7 @@ async function main() {
|
|
|
58455
58701
|
model: config.model,
|
|
58456
58702
|
path: config.path,
|
|
58457
58703
|
allowEdit: config.allowEdit,
|
|
58704
|
+
enableDelegate: config.enableDelegate,
|
|
58458
58705
|
debug: config.verbose
|
|
58459
58706
|
});
|
|
58460
58707
|
await server.start();
|
|
@@ -58573,6 +58820,7 @@ async function main() {
|
|
|
58573
58820
|
promptType: config.prompt,
|
|
58574
58821
|
customPrompt: systemPrompt,
|
|
58575
58822
|
allowEdit: config.allowEdit,
|
|
58823
|
+
enableDelegate: config.enableDelegate,
|
|
58576
58824
|
debug: config.verbose,
|
|
58577
58825
|
tracer: appTracer,
|
|
58578
58826
|
outline: config.outline,
|