@probelabs/probe 0.6.0-rc209 → 0.6.0-rc210
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-rc210-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc210-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc210-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc210-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc210-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.js +85 -4
- package/build/agent/bashCommandUtils.js +98 -12
- package/build/agent/bashPermissions.js +207 -1
- package/build/agent/index.js +275 -15
- package/build/delegate.js +11 -2
- package/build/tools/vercel.js +5 -2
- package/cjs/agent/ProbeAgent.cjs +275 -15
- package/cjs/index.cjs +275 -15
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +85 -4
- package/src/agent/bashCommandUtils.js +98 -12
- package/src/agent/bashPermissions.js +207 -1
- package/src/delegate.js +11 -2
- package/src/tools/vercel.js +5 -2
- package/bin/binaries/probe-v0.6.0-rc209-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc209-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc209-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc209-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc209-x86_64-unknown-linux-musl.tar.gz +0 -0
package/build/agent/index.js
CHANGED
|
@@ -3764,7 +3764,10 @@ async function delegate({
|
|
|
3764
3764
|
disableTools = false,
|
|
3765
3765
|
searchDelegate = void 0,
|
|
3766
3766
|
schema = null,
|
|
3767
|
-
enableTasks = false
|
|
3767
|
+
enableTasks = false,
|
|
3768
|
+
enableMcp = false,
|
|
3769
|
+
mcpConfig = null,
|
|
3770
|
+
mcpConfigPath = null
|
|
3768
3771
|
}) {
|
|
3769
3772
|
if (!task || typeof task !== "string") {
|
|
3770
3773
|
throw new Error("Task parameter is required and must be a string");
|
|
@@ -3820,8 +3823,14 @@ async function delegate({
|
|
|
3820
3823
|
allowedTools,
|
|
3821
3824
|
disableTools,
|
|
3822
3825
|
searchDelegate,
|
|
3823
|
-
enableTasks
|
|
3826
|
+
enableTasks,
|
|
3824
3827
|
// Inherit from parent (subagent gets isolated TaskManager)
|
|
3828
|
+
enableMcp,
|
|
3829
|
+
// Inherit from parent (subagent creates own MCPXmlBridge)
|
|
3830
|
+
mcpConfig,
|
|
3831
|
+
// Inherit from parent
|
|
3832
|
+
mcpConfigPath
|
|
3833
|
+
// Inherit from parent
|
|
3825
3834
|
});
|
|
3826
3835
|
if (debug) {
|
|
3827
3836
|
console.error(`[DELEGATE] Created subagent with session ${sessionId}`);
|
|
@@ -9791,7 +9800,7 @@ var init_vercel = __esm({
|
|
|
9791
9800
|
});
|
|
9792
9801
|
};
|
|
9793
9802
|
delegateTool = (options = {}) => {
|
|
9794
|
-
const { debug = false, timeout = 300, cwd, allowedFolders, enableBash = false, bashConfig, architectureFileName } = options;
|
|
9803
|
+
const { debug = false, timeout = 300, cwd, allowedFolders, enableBash = false, bashConfig, architectureFileName, enableMcp = false, mcpConfig = null, mcpConfigPath = null } = options;
|
|
9795
9804
|
return tool2({
|
|
9796
9805
|
name: "delegate",
|
|
9797
9806
|
description: delegateDescription,
|
|
@@ -9850,7 +9859,10 @@ var init_vercel = __esm({
|
|
|
9850
9859
|
enableBash,
|
|
9851
9860
|
bashConfig,
|
|
9852
9861
|
architectureFileName,
|
|
9853
|
-
searchDelegate
|
|
9862
|
+
searchDelegate,
|
|
9863
|
+
enableMcp,
|
|
9864
|
+
mcpConfig,
|
|
9865
|
+
mcpConfigPath
|
|
9854
9866
|
});
|
|
9855
9867
|
return result;
|
|
9856
9868
|
}
|
|
@@ -10377,6 +10389,38 @@ function parseSimpleCommand(command) {
|
|
|
10377
10389
|
isComplex: false
|
|
10378
10390
|
};
|
|
10379
10391
|
}
|
|
10392
|
+
const stripQuotedContent = (str) => {
|
|
10393
|
+
let result = "";
|
|
10394
|
+
let inQuotes2 = false;
|
|
10395
|
+
let quoteChar2 = "";
|
|
10396
|
+
for (let i = 0; i < str.length; i++) {
|
|
10397
|
+
const char = str[i];
|
|
10398
|
+
const nextChar = str[i + 1];
|
|
10399
|
+
if (!inQuotes2 && char === "\\" && nextChar !== void 0) {
|
|
10400
|
+
i++;
|
|
10401
|
+
continue;
|
|
10402
|
+
}
|
|
10403
|
+
if (inQuotes2 && quoteChar2 === '"' && char === "\\" && nextChar !== void 0) {
|
|
10404
|
+
i++;
|
|
10405
|
+
continue;
|
|
10406
|
+
}
|
|
10407
|
+
if (!inQuotes2 && (char === '"' || char === "'")) {
|
|
10408
|
+
inQuotes2 = true;
|
|
10409
|
+
quoteChar2 = char;
|
|
10410
|
+
continue;
|
|
10411
|
+
}
|
|
10412
|
+
if (inQuotes2 && char === quoteChar2) {
|
|
10413
|
+
inQuotes2 = false;
|
|
10414
|
+
quoteChar2 = "";
|
|
10415
|
+
continue;
|
|
10416
|
+
}
|
|
10417
|
+
if (!inQuotes2) {
|
|
10418
|
+
result += char;
|
|
10419
|
+
}
|
|
10420
|
+
}
|
|
10421
|
+
return result;
|
|
10422
|
+
};
|
|
10423
|
+
const strippedForOperators = stripQuotedContent(trimmed);
|
|
10380
10424
|
const complexPatterns = [
|
|
10381
10425
|
/\|/,
|
|
10382
10426
|
// Pipes
|
|
@@ -10402,7 +10446,7 @@ function parseSimpleCommand(command) {
|
|
|
10402
10446
|
// Brace expansion like {a,b} or {1..10} (but not find {} placeholders)
|
|
10403
10447
|
];
|
|
10404
10448
|
for (const pattern of complexPatterns) {
|
|
10405
|
-
if (pattern.test(
|
|
10449
|
+
if (pattern.test(strippedForOperators)) {
|
|
10406
10450
|
return {
|
|
10407
10451
|
success: false,
|
|
10408
10452
|
error: "Complex shell commands with pipes, operators, or redirections are not supported for security reasons",
|
|
@@ -10417,17 +10461,17 @@ function parseSimpleCommand(command) {
|
|
|
10417
10461
|
let current = "";
|
|
10418
10462
|
let inQuotes = false;
|
|
10419
10463
|
let quoteChar = "";
|
|
10420
|
-
let escaped = false;
|
|
10421
10464
|
for (let i = 0; i < trimmed.length; i++) {
|
|
10422
10465
|
const char = trimmed[i];
|
|
10423
10466
|
const nextChar = i + 1 < trimmed.length ? trimmed[i + 1] : "";
|
|
10424
|
-
if (
|
|
10425
|
-
current +=
|
|
10426
|
-
|
|
10467
|
+
if (!inQuotes && char === "\\" && nextChar) {
|
|
10468
|
+
current += nextChar;
|
|
10469
|
+
i++;
|
|
10427
10470
|
continue;
|
|
10428
10471
|
}
|
|
10429
|
-
if (char === "\\" &&
|
|
10430
|
-
|
|
10472
|
+
if (inQuotes && quoteChar === '"' && char === "\\" && nextChar) {
|
|
10473
|
+
current += nextChar;
|
|
10474
|
+
i++;
|
|
10431
10475
|
continue;
|
|
10432
10476
|
}
|
|
10433
10477
|
if (!inQuotes && (char === '"' || char === "'")) {
|
|
@@ -10760,8 +10804,97 @@ var init_bashPermissions = __esm({
|
|
|
10760
10804
|
});
|
|
10761
10805
|
return result;
|
|
10762
10806
|
}
|
|
10807
|
+
/**
|
|
10808
|
+
* Split a complex command into component commands by operators
|
|
10809
|
+
*
|
|
10810
|
+
* ## Escape Handling (Security-Critical)
|
|
10811
|
+
*
|
|
10812
|
+
* This function intentionally PRESERVES escape sequences (both backslash AND
|
|
10813
|
+
* escaped character) in the output. This is step 1 of a 2-step parsing process:
|
|
10814
|
+
*
|
|
10815
|
+
* 1. _splitComplexCommand: Splits by operators, PRESERVES escapes → `echo "test\" && b"`
|
|
10816
|
+
* 2. parseCommand: Interprets escapes in each component → args: ['test" && b']
|
|
10817
|
+
*
|
|
10818
|
+
* This differs from stripQuotedContent() in bashCommandUtils.js which REMOVES
|
|
10819
|
+
* escapes entirely (for operator detection only).
|
|
10820
|
+
*
|
|
10821
|
+
* The security rationale: if we stripped escapes here, `\"` would become `"`,
|
|
10822
|
+
* potentially causing incorrect quote boundary detection and allowing operator
|
|
10823
|
+
* injection. By preserving escapes, parseCommand() can correctly interpret them.
|
|
10824
|
+
*
|
|
10825
|
+
* See bashCommandUtils.js module header for the full escape handling architecture.
|
|
10826
|
+
*
|
|
10827
|
+
* @private
|
|
10828
|
+
* @param {string} command - Complex command to split
|
|
10829
|
+
* @returns {string[]} Array of component commands (with escapes preserved)
|
|
10830
|
+
*/
|
|
10831
|
+
_splitComplexCommand(command) {
|
|
10832
|
+
const components = [];
|
|
10833
|
+
let current = "";
|
|
10834
|
+
let inQuotes = false;
|
|
10835
|
+
let quoteChar = "";
|
|
10836
|
+
let i = 0;
|
|
10837
|
+
while (i < command.length) {
|
|
10838
|
+
const char = command[i];
|
|
10839
|
+
const nextChar = command[i + 1] || "";
|
|
10840
|
+
if (!inQuotes && char === "\\") {
|
|
10841
|
+
current += char;
|
|
10842
|
+
if (nextChar) {
|
|
10843
|
+
current += nextChar;
|
|
10844
|
+
i += 2;
|
|
10845
|
+
} else {
|
|
10846
|
+
i++;
|
|
10847
|
+
}
|
|
10848
|
+
continue;
|
|
10849
|
+
}
|
|
10850
|
+
if (inQuotes && quoteChar === '"' && char === "\\" && nextChar) {
|
|
10851
|
+
current += char + nextChar;
|
|
10852
|
+
i += 2;
|
|
10853
|
+
continue;
|
|
10854
|
+
}
|
|
10855
|
+
if (!inQuotes && (char === '"' || char === "'")) {
|
|
10856
|
+
inQuotes = true;
|
|
10857
|
+
quoteChar = char;
|
|
10858
|
+
current += char;
|
|
10859
|
+
i++;
|
|
10860
|
+
continue;
|
|
10861
|
+
}
|
|
10862
|
+
if (inQuotes && char === quoteChar) {
|
|
10863
|
+
inQuotes = false;
|
|
10864
|
+
quoteChar = "";
|
|
10865
|
+
current += char;
|
|
10866
|
+
i++;
|
|
10867
|
+
continue;
|
|
10868
|
+
}
|
|
10869
|
+
if (!inQuotes) {
|
|
10870
|
+
if (char === "&" && nextChar === "&" || char === "|" && nextChar === "|") {
|
|
10871
|
+
if (current.trim()) {
|
|
10872
|
+
components.push(current.trim());
|
|
10873
|
+
}
|
|
10874
|
+
current = "";
|
|
10875
|
+
i += 2;
|
|
10876
|
+
continue;
|
|
10877
|
+
}
|
|
10878
|
+
if (char === "|") {
|
|
10879
|
+
if (current.trim()) {
|
|
10880
|
+
components.push(current.trim());
|
|
10881
|
+
}
|
|
10882
|
+
current = "";
|
|
10883
|
+
i++;
|
|
10884
|
+
continue;
|
|
10885
|
+
}
|
|
10886
|
+
}
|
|
10887
|
+
current += char;
|
|
10888
|
+
i++;
|
|
10889
|
+
}
|
|
10890
|
+
if (current.trim()) {
|
|
10891
|
+
components.push(current.trim());
|
|
10892
|
+
}
|
|
10893
|
+
return components;
|
|
10894
|
+
}
|
|
10763
10895
|
/**
|
|
10764
10896
|
* Check a complex command against complex patterns in allow/deny lists
|
|
10897
|
+
* Also supports auto-allowing commands where all components are individually allowed
|
|
10765
10898
|
* @private
|
|
10766
10899
|
* @param {string} command - Complex command to check
|
|
10767
10900
|
* @returns {Object} Permission result
|
|
@@ -10816,6 +10949,85 @@ var init_bashPermissions = __esm({
|
|
|
10816
10949
|
return result;
|
|
10817
10950
|
}
|
|
10818
10951
|
}
|
|
10952
|
+
const components = this._splitComplexCommand(command);
|
|
10953
|
+
if (this.debug) {
|
|
10954
|
+
console.log(`[BashPermissions] Checking ${components.length} command components: ${JSON.stringify(components)}`);
|
|
10955
|
+
}
|
|
10956
|
+
if (components.length > 1) {
|
|
10957
|
+
const componentResults = [];
|
|
10958
|
+
let allAllowed = true;
|
|
10959
|
+
let deniedComponent = null;
|
|
10960
|
+
let deniedReason = null;
|
|
10961
|
+
for (const component of components) {
|
|
10962
|
+
const parsed = parseCommand(component);
|
|
10963
|
+
if (parsed.error || parsed.isComplex) {
|
|
10964
|
+
if (this.debug) {
|
|
10965
|
+
console.log(`[BashPermissions] Component "${component}" is complex or has error: ${parsed.error}`);
|
|
10966
|
+
}
|
|
10967
|
+
allAllowed = false;
|
|
10968
|
+
deniedComponent = component;
|
|
10969
|
+
deniedReason = parsed.error || "Component contains nested complex constructs";
|
|
10970
|
+
break;
|
|
10971
|
+
}
|
|
10972
|
+
if (matchesAnyPattern(parsed, this.denyPatterns)) {
|
|
10973
|
+
if (this.debug) {
|
|
10974
|
+
console.log(`[BashPermissions] Component "${component}" matches deny pattern`);
|
|
10975
|
+
}
|
|
10976
|
+
allAllowed = false;
|
|
10977
|
+
deniedComponent = component;
|
|
10978
|
+
deniedReason = "Component matches deny pattern";
|
|
10979
|
+
break;
|
|
10980
|
+
}
|
|
10981
|
+
if (!matchesAnyPattern(parsed, this.allowPatterns)) {
|
|
10982
|
+
if (this.debug) {
|
|
10983
|
+
console.log(`[BashPermissions] Component "${component}" not in allow list`);
|
|
10984
|
+
}
|
|
10985
|
+
allAllowed = false;
|
|
10986
|
+
deniedComponent = component;
|
|
10987
|
+
deniedReason = "Component not in allow list";
|
|
10988
|
+
break;
|
|
10989
|
+
}
|
|
10990
|
+
componentResults.push({ component, parsed, allowed: true });
|
|
10991
|
+
}
|
|
10992
|
+
if (allAllowed) {
|
|
10993
|
+
if (this.debug) {
|
|
10994
|
+
console.log(`[BashPermissions] ALLOWED - all ${components.length} components passed individual checks`);
|
|
10995
|
+
}
|
|
10996
|
+
const result = {
|
|
10997
|
+
allowed: true,
|
|
10998
|
+
command,
|
|
10999
|
+
isComplex: true,
|
|
11000
|
+
allowedByComponents: true,
|
|
11001
|
+
components: componentResults
|
|
11002
|
+
};
|
|
11003
|
+
this.recordBashEvent("permission.allowed", {
|
|
11004
|
+
command,
|
|
11005
|
+
isComplex: true,
|
|
11006
|
+
allowedByComponents: true,
|
|
11007
|
+
componentCount: components.length
|
|
11008
|
+
});
|
|
11009
|
+
return result;
|
|
11010
|
+
} else {
|
|
11011
|
+
if (this.debug) {
|
|
11012
|
+
console.log(`[BashPermissions] DENIED - component "${deniedComponent}" failed: ${deniedReason}`);
|
|
11013
|
+
}
|
|
11014
|
+
const result = {
|
|
11015
|
+
allowed: false,
|
|
11016
|
+
reason: `Component "${deniedComponent}" not allowed: ${deniedReason}`,
|
|
11017
|
+
command,
|
|
11018
|
+
isComplex: true,
|
|
11019
|
+
failedComponent: deniedComponent
|
|
11020
|
+
};
|
|
11021
|
+
this.recordBashEvent("permission.denied", {
|
|
11022
|
+
command,
|
|
11023
|
+
reason: "component_not_allowed",
|
|
11024
|
+
failedComponent: deniedComponent,
|
|
11025
|
+
componentReason: deniedReason,
|
|
11026
|
+
isComplex: true
|
|
11027
|
+
});
|
|
11028
|
+
return result;
|
|
11029
|
+
}
|
|
11030
|
+
}
|
|
10819
11031
|
if (this.debug) {
|
|
10820
11032
|
console.log(`[BashPermissions] DENIED - no matching complex pattern found`);
|
|
10821
11033
|
}
|
|
@@ -71033,6 +71245,9 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
71033
71245
|
let lastFormatErrorType = null;
|
|
71034
71246
|
let sameFormatErrorCount = 0;
|
|
71035
71247
|
const MAX_REPEATED_FORMAT_ERRORS = 3;
|
|
71248
|
+
let lastNoToolResponse = null;
|
|
71249
|
+
let sameResponseCount = 0;
|
|
71250
|
+
const MAX_REPEATED_IDENTICAL_RESPONSES = 3;
|
|
71036
71251
|
while (currentIteration < maxIterations && !completionAttempted) {
|
|
71037
71252
|
currentIteration++;
|
|
71038
71253
|
if (this.cancelled) throw new Error("Request was cancelled by the user");
|
|
@@ -71514,6 +71729,26 @@ ${errorXml}
|
|
|
71514
71729
|
}
|
|
71515
71730
|
break;
|
|
71516
71731
|
}
|
|
71732
|
+
if (lastNoToolResponse !== null && assistantResponseContent === lastNoToolResponse) {
|
|
71733
|
+
sameResponseCount++;
|
|
71734
|
+
if (sameResponseCount >= MAX_REPEATED_IDENTICAL_RESPONSES) {
|
|
71735
|
+
let cleanedResponse = assistantResponseContent;
|
|
71736
|
+
cleanedResponse = cleanedResponse.replace(/<thinking>[\s\S]*?<\/thinking>/gi, "").trim();
|
|
71737
|
+
cleanedResponse = cleanedResponse.replace(/<thinking>[\s\S]*$/gi, "").trim();
|
|
71738
|
+
const hasSubstantialContent = cleanedResponse.length > 50 && !cleanedResponse.includes("<api_call>") && !cleanedResponse.includes("<tool_name>") && !cleanedResponse.includes("<function>");
|
|
71739
|
+
if (hasSubstantialContent) {
|
|
71740
|
+
if (this.debug) {
|
|
71741
|
+
console.log(`[DEBUG] Same response repeated ${sameResponseCount} times - accepting as final answer (${cleanedResponse.length} chars)`);
|
|
71742
|
+
}
|
|
71743
|
+
finalResult = cleanedResponse;
|
|
71744
|
+
completionAttempted = true;
|
|
71745
|
+
break;
|
|
71746
|
+
}
|
|
71747
|
+
}
|
|
71748
|
+
} else {
|
|
71749
|
+
lastNoToolResponse = assistantResponseContent;
|
|
71750
|
+
sameResponseCount = 1;
|
|
71751
|
+
}
|
|
71517
71752
|
currentMessages.push({ role: "assistant", content: assistantResponseContent });
|
|
71518
71753
|
const unrecognizedTool = detectUnrecognizedToolCall(assistantResponseContent, validTools);
|
|
71519
71754
|
let reminderContent;
|
|
@@ -71586,10 +71821,35 @@ Or if your previous response already contains a complete, direct answer (not a t
|
|
|
71586
71821
|
|
|
71587
71822
|
Note: <attempt_complete></attempt_complete> reuses your PREVIOUS assistant message as the final answer. Only use this if that message was already a valid, complete response to the user's question.`;
|
|
71588
71823
|
}
|
|
71589
|
-
currentMessages.
|
|
71590
|
-
|
|
71591
|
-
|
|
71592
|
-
|
|
71824
|
+
const prevUserMsgIndex = currentMessages.length - 2;
|
|
71825
|
+
const prevUserMsg = currentMessages[prevUserMsgIndex];
|
|
71826
|
+
const isExistingReminder = prevUserMsg && prevUserMsg.role === "user" && (prevUserMsg.content.includes("Please use one of the available tools") || prevUserMsg.content.includes("<tool_result>"));
|
|
71827
|
+
if (isExistingReminder && sameResponseCount > 1) {
|
|
71828
|
+
const prevAssistantIndex = prevUserMsgIndex - 1;
|
|
71829
|
+
const hasSystemMessage2 = currentMessages.length > 0 && currentMessages[0].role === "system";
|
|
71830
|
+
const minValidIndex = hasSystemMessage2 ? 1 : 0;
|
|
71831
|
+
const canSafelyRemove = prevAssistantIndex >= minValidIndex && currentMessages[prevAssistantIndex] && currentMessages[prevAssistantIndex].role === "assistant" && currentMessages.length - 2 >= (hasSystemMessage2 ? 2 : 1);
|
|
71832
|
+
if (canSafelyRemove) {
|
|
71833
|
+
currentMessages.splice(prevAssistantIndex, 2);
|
|
71834
|
+
if (this.debug) {
|
|
71835
|
+
console.log(`[DEBUG] Removed duplicate assistant+reminder pair (iteration ${currentIteration}, same response #${sameResponseCount})`);
|
|
71836
|
+
}
|
|
71837
|
+
} else if (this.debug) {
|
|
71838
|
+
console.log(`[DEBUG] Skipped deduplication: pattern validation failed (prevAssistantIndex=${prevAssistantIndex}, arrayLength=${currentMessages.length})`);
|
|
71839
|
+
}
|
|
71840
|
+
const iterationHint = `
|
|
71841
|
+
|
|
71842
|
+
(Attempt #${sameResponseCount}: Your previous ${sameResponseCount} responses were identical. If you have a complete answer, use <attempt_complete></attempt_complete> to finalize it.)`;
|
|
71843
|
+
currentMessages.push({
|
|
71844
|
+
role: "user",
|
|
71845
|
+
content: reminderContent + iterationHint
|
|
71846
|
+
});
|
|
71847
|
+
} else {
|
|
71848
|
+
currentMessages.push({
|
|
71849
|
+
role: "user",
|
|
71850
|
+
content: reminderContent
|
|
71851
|
+
});
|
|
71852
|
+
}
|
|
71593
71853
|
if (this.debug) {
|
|
71594
71854
|
if (unrecognizedTool) {
|
|
71595
71855
|
console.log(`[DEBUG] Unrecognized tool '${unrecognizedTool}' used. Providing error feedback.`);
|
package/build/delegate.js
CHANGED
|
@@ -186,6 +186,9 @@ const delegationManager = new DelegationManager();
|
|
|
186
186
|
* @param {boolean} [options.searchDelegate] - Use delegated search in the subagent
|
|
187
187
|
* @param {Object|string} [options.schema] - Optional JSON schema to enforce response format
|
|
188
188
|
* @param {boolean} [options.enableTasks=false] - Enable task management for the subagent (isolated instance)
|
|
189
|
+
* @param {boolean} [options.enableMcp=false] - Enable MCP tool integration (inherited from parent)
|
|
190
|
+
* @param {Object} [options.mcpConfig] - MCP configuration object (inherited from parent)
|
|
191
|
+
* @param {string} [options.mcpConfigPath] - Path to MCP configuration file (inherited from parent)
|
|
189
192
|
* @returns {Promise<string>} The response from the delegate agent
|
|
190
193
|
*/
|
|
191
194
|
export async function delegate({
|
|
@@ -208,7 +211,10 @@ export async function delegate({
|
|
|
208
211
|
disableTools = false,
|
|
209
212
|
searchDelegate = undefined,
|
|
210
213
|
schema = null,
|
|
211
|
-
enableTasks = false
|
|
214
|
+
enableTasks = false,
|
|
215
|
+
enableMcp = false,
|
|
216
|
+
mcpConfig = null,
|
|
217
|
+
mcpConfigPath = null
|
|
212
218
|
}) {
|
|
213
219
|
if (!task || typeof task !== 'string') {
|
|
214
220
|
throw new Error('Task parameter is required and must be a string');
|
|
@@ -270,7 +276,10 @@ export async function delegate({
|
|
|
270
276
|
allowedTools,
|
|
271
277
|
disableTools,
|
|
272
278
|
searchDelegate,
|
|
273
|
-
enableTasks // Inherit from parent (subagent gets isolated TaskManager)
|
|
279
|
+
enableTasks, // Inherit from parent (subagent gets isolated TaskManager)
|
|
280
|
+
enableMcp, // Inherit from parent (subagent creates own MCPXmlBridge)
|
|
281
|
+
mcpConfig, // Inherit from parent
|
|
282
|
+
mcpConfigPath // Inherit from parent
|
|
274
283
|
});
|
|
275
284
|
|
|
276
285
|
if (debug) {
|
package/build/tools/vercel.js
CHANGED
|
@@ -469,7 +469,7 @@ export const extractTool = (options = {}) => {
|
|
|
469
469
|
* @returns {Object} Configured delegate tool
|
|
470
470
|
*/
|
|
471
471
|
export const delegateTool = (options = {}) => {
|
|
472
|
-
const { debug = false, timeout = 300, cwd, allowedFolders, enableBash = false, bashConfig, architectureFileName } = options;
|
|
472
|
+
const { debug = false, timeout = 300, cwd, allowedFolders, enableBash = false, bashConfig, architectureFileName, enableMcp = false, mcpConfig = null, mcpConfigPath = null } = options;
|
|
473
473
|
|
|
474
474
|
return tool({
|
|
475
475
|
name: 'delegate',
|
|
@@ -558,7 +558,10 @@ export const delegateTool = (options = {}) => {
|
|
|
558
558
|
enableBash,
|
|
559
559
|
bashConfig,
|
|
560
560
|
architectureFileName,
|
|
561
|
-
searchDelegate
|
|
561
|
+
searchDelegate,
|
|
562
|
+
enableMcp,
|
|
563
|
+
mcpConfig,
|
|
564
|
+
mcpConfigPath
|
|
562
565
|
});
|
|
563
566
|
|
|
564
567
|
return result;
|