@probelabs/probe 0.6.0-rc290 → 0.6.0-rc291
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-rc290-aarch64-apple-darwin.tar.gz → probe-v0.6.0-rc291-aarch64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc290-aarch64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc291-aarch64-unknown-linux-musl.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc290-x86_64-apple-darwin.tar.gz → probe-v0.6.0-rc291-x86_64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc290-x86_64-pc-windows-msvc.zip → probe-v0.6.0-rc291-x86_64-pc-windows-msvc.zip} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc290-x86_64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc291-x86_64-unknown-linux-musl.tar.gz} +0 -0
- package/build/agent/ProbeAgent.js +34 -4
- package/build/tools/vercel.js +5 -1
- package/build/utils/error-types.js +2 -2
- package/build/utils/path-validation.js +1 -1
- package/cjs/agent/ProbeAgent.cjs +62 -7
- package/cjs/index.cjs +62 -7
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +34 -4
- package/src/tools/vercel.js +5 -1
- package/src/utils/error-types.js +2 -2
- package/src/utils/path-validation.js +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1444,11 +1444,13 @@ export class ProbeAgent {
|
|
|
1444
1444
|
result = await this._executeWithVercelProvider(options, controller);
|
|
1445
1445
|
}
|
|
1446
1446
|
|
|
1447
|
-
// Wrap textStream so limiter slot is held until stream completes
|
|
1447
|
+
// Wrap textStream so limiter slot is held until stream completes.
|
|
1448
|
+
// result.textStream is a read-only getter on DefaultStreamTextResult,
|
|
1449
|
+
// so we wrap the result in a Proxy that intercepts the textStream property.
|
|
1448
1450
|
if (limiter && result.textStream) {
|
|
1449
1451
|
const originalStream = result.textStream;
|
|
1450
1452
|
const debug = this.debug;
|
|
1451
|
-
|
|
1453
|
+
const wrappedStream = (async function* () {
|
|
1452
1454
|
try {
|
|
1453
1455
|
for await (const chunk of originalStream) {
|
|
1454
1456
|
yield chunk;
|
|
@@ -1461,6 +1463,13 @@ export class ProbeAgent {
|
|
|
1461
1463
|
}
|
|
1462
1464
|
}
|
|
1463
1465
|
})();
|
|
1466
|
+
return new Proxy(result, {
|
|
1467
|
+
get(target, prop) {
|
|
1468
|
+
if (prop === 'textStream') return wrappedStream;
|
|
1469
|
+
const value = target[prop];
|
|
1470
|
+
return typeof value === 'function' ? value.bind(target) : value;
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1464
1473
|
} else if (limiter) {
|
|
1465
1474
|
// No textStream (shouldn't happen, but release just in case)
|
|
1466
1475
|
limiter.release(null);
|
|
@@ -3499,6 +3508,7 @@ Follow these instructions carefully:
|
|
|
3499
3508
|
return true;
|
|
3500
3509
|
}
|
|
3501
3510
|
}
|
|
3511
|
+
|
|
3502
3512
|
}
|
|
3503
3513
|
|
|
3504
3514
|
return false;
|
|
@@ -3529,6 +3539,24 @@ Follow these instructions carefully:
|
|
|
3529
3539
|
}
|
|
3530
3540
|
}
|
|
3531
3541
|
|
|
3542
|
+
// Force text-only response after 3 consecutive tool errors
|
|
3543
|
+
// (e.g. workspace deleted mid-run — let the model produce its answer)
|
|
3544
|
+
if (steps.length >= 3) {
|
|
3545
|
+
const last3 = steps.slice(-3);
|
|
3546
|
+
const allErrors = last3.every(s =>
|
|
3547
|
+
s.toolResults?.length > 0 && s.toolResults.every(tr => {
|
|
3548
|
+
const r = typeof tr.result === 'string' ? tr.result : '';
|
|
3549
|
+
return r.includes('<error ') || r.includes('does not exist');
|
|
3550
|
+
})
|
|
3551
|
+
);
|
|
3552
|
+
if (allErrors) {
|
|
3553
|
+
if (this.debug) {
|
|
3554
|
+
console.log(`[DEBUG] prepareStep: 3 consecutive tool errors, forcing toolChoice=none`);
|
|
3555
|
+
}
|
|
3556
|
+
return { toolChoice: 'none' };
|
|
3557
|
+
}
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3532
3560
|
const lastStep = steps[steps.length - 1];
|
|
3533
3561
|
const modelJustStopped = lastStep?.finishReason === 'stop'
|
|
3534
3562
|
&& (!lastStep?.toolCalls || lastStep.toolCalls.length === 0);
|
|
@@ -3565,7 +3593,8 @@ Here is the result to review:
|
|
|
3565
3593
|
${resultToReview}
|
|
3566
3594
|
</result>
|
|
3567
3595
|
|
|
3568
|
-
|
|
3596
|
+
IMPORTANT: First review ALL completed work in the conversation above before taking any action.
|
|
3597
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If your text has inaccuracies, fix the text. Only call a tool if you find a genuinely MISSING action — NEVER redo work that was already completed successfully. Respond with the COMPLETE corrected answer.`;
|
|
3569
3598
|
|
|
3570
3599
|
return {
|
|
3571
3600
|
userMessage: completionPromptMessage,
|
|
@@ -3774,7 +3803,8 @@ Here is the result to review:
|
|
|
3774
3803
|
${finalResult}
|
|
3775
3804
|
</result>
|
|
3776
3805
|
|
|
3777
|
-
|
|
3806
|
+
IMPORTANT: First review ALL completed work in the conversation above before taking any action.
|
|
3807
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If your text has inaccuracies, fix the text. Only call a tool if you find a genuinely MISSING action — NEVER redo work that was already completed successfully. Respond with the COMPLETE corrected answer.`;
|
|
3778
3808
|
|
|
3779
3809
|
currentMessages.push({ role: 'user', content: completionPromptMessage });
|
|
3780
3810
|
|
package/build/tools/vercel.js
CHANGED
|
@@ -478,7 +478,11 @@ export const searchTool = (options = {}) => {
|
|
|
478
478
|
return result;
|
|
479
479
|
} catch (error) {
|
|
480
480
|
console.error('Error executing search command:', error);
|
|
481
|
-
|
|
481
|
+
const formatted = formatErrorForAI(error);
|
|
482
|
+
if (error.category === 'path_error' || error.message?.includes('does not exist')) {
|
|
483
|
+
return formatted + '\n\nThe path does not exist. Use the listFiles tool to verify the correct directory structure before retrying. If the workspace itself is gone, output your final answer with whatever information you have.';
|
|
484
|
+
}
|
|
485
|
+
return formatted;
|
|
482
486
|
}
|
|
483
487
|
}
|
|
484
488
|
|
|
@@ -181,14 +181,14 @@ export function categorizeError(error) {
|
|
|
181
181
|
errorCode === 'enoent') {
|
|
182
182
|
return new PathError(message, {
|
|
183
183
|
originalError: error,
|
|
184
|
-
suggestion: 'The specified path does not exist.
|
|
184
|
+
suggestion: 'The specified path does not exist. Use the listFiles tool to check the correct directory structure, then retry with a valid path.'
|
|
185
185
|
});
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
if (lowerMessage.includes('not a directory') || errorCode === 'enotdir') {
|
|
189
189
|
return new PathError(message, {
|
|
190
190
|
originalError: error,
|
|
191
|
-
suggestion: 'The path is not a directory.
|
|
191
|
+
suggestion: 'The path is not a directory. Use the listFiles tool to find the correct directory, then retry.'
|
|
192
192
|
});
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -110,7 +110,7 @@ export async function validateCwdPath(inputPath, defaultPath = process.cwd()) {
|
|
|
110
110
|
}
|
|
111
111
|
if (error.code === 'ENOENT') {
|
|
112
112
|
throw new PathError(`Path does not exist: ${normalizedPath}`, {
|
|
113
|
-
suggestion: 'The specified path does not exist.
|
|
113
|
+
suggestion: 'The specified path does not exist. Use the listFiles tool to check the correct directory structure, then retry with a valid path.',
|
|
114
114
|
details: { path: normalizedPath }
|
|
115
115
|
});
|
|
116
116
|
}
|
package/cjs/agent/ProbeAgent.cjs
CHANGED
|
@@ -25324,13 +25324,13 @@ function categorizeError(error40) {
|
|
|
25324
25324
|
if (lowerMessage.includes("path does not exist") || lowerMessage.includes("no such file or directory") || errorCode === "enoent") {
|
|
25325
25325
|
return new PathError(message, {
|
|
25326
25326
|
originalError: error40,
|
|
25327
|
-
suggestion: "The specified path does not exist.
|
|
25327
|
+
suggestion: "The specified path does not exist. Use the listFiles tool to check the correct directory structure, then retry with a valid path."
|
|
25328
25328
|
});
|
|
25329
25329
|
}
|
|
25330
25330
|
if (lowerMessage.includes("not a directory") || errorCode === "enotdir") {
|
|
25331
25331
|
return new PathError(message, {
|
|
25332
25332
|
originalError: error40,
|
|
25333
|
-
suggestion: "The path is not a directory.
|
|
25333
|
+
suggestion: "The path is not a directory. Use the listFiles tool to find the correct directory, then retry."
|
|
25334
25334
|
});
|
|
25335
25335
|
}
|
|
25336
25336
|
if (lowerMessage.includes("permission denied") || errorCode === "eacces") {
|
|
@@ -25586,7 +25586,7 @@ async function validateCwdPath(inputPath, defaultPath = process.cwd()) {
|
|
|
25586
25586
|
}
|
|
25587
25587
|
if (error40.code === "ENOENT") {
|
|
25588
25588
|
throw new PathError(`Path does not exist: ${normalizedPath}`, {
|
|
25589
|
-
suggestion: "The specified path does not exist.
|
|
25589
|
+
suggestion: "The specified path does not exist. Use the listFiles tool to check the correct directory structure, then retry with a valid path.",
|
|
25590
25590
|
details: { path: normalizedPath }
|
|
25591
25591
|
});
|
|
25592
25592
|
}
|
|
@@ -27643,7 +27643,11 @@ var init_vercel = __esm({
|
|
|
27643
27643
|
return result;
|
|
27644
27644
|
} catch (error40) {
|
|
27645
27645
|
console.error("Error executing search command:", error40);
|
|
27646
|
-
|
|
27646
|
+
const formatted = formatErrorForAI(error40);
|
|
27647
|
+
if (error40.category === "path_error" || error40.message?.includes("does not exist")) {
|
|
27648
|
+
return formatted + "\n\nThe path does not exist. Use the listFiles tool to verify the correct directory structure before retrying. If the workspace itself is gone, output your final answer with whatever information you have.";
|
|
27649
|
+
}
|
|
27650
|
+
return formatted;
|
|
27647
27651
|
}
|
|
27648
27652
|
}
|
|
27649
27653
|
try {
|
|
@@ -31008,6 +31012,9 @@ var require_utils = __commonJS({
|
|
|
31008
31012
|
sandboxGlobal
|
|
31009
31013
|
};
|
|
31010
31014
|
context.prototypeWhitelist.set(Object.getPrototypeOf([][Symbol.iterator]()), /* @__PURE__ */ new Set());
|
|
31015
|
+
context.prototypeWhitelist.set(Object.getPrototypeOf(""[Symbol.iterator]()), /* @__PURE__ */ new Set());
|
|
31016
|
+
context.prototypeWhitelist.set(Object.getPrototypeOf((/* @__PURE__ */ new Set())[Symbol.iterator]()), /* @__PURE__ */ new Set());
|
|
31017
|
+
context.prototypeWhitelist.set(Object.getPrototypeOf((/* @__PURE__ */ new Map())[Symbol.iterator]()), /* @__PURE__ */ new Set());
|
|
31011
31018
|
return context;
|
|
31012
31019
|
}
|
|
31013
31020
|
function createExecContext(sandbox, executionTree, evalContext) {
|
|
@@ -32146,6 +32153,18 @@ var require_executor = __commonJS({
|
|
|
32146
32153
|
a = void 0;
|
|
32147
32154
|
}
|
|
32148
32155
|
}
|
|
32156
|
+
if (op === 29 && !a) {
|
|
32157
|
+
done(void 0, a);
|
|
32158
|
+
return;
|
|
32159
|
+
}
|
|
32160
|
+
if (op === 30 && a) {
|
|
32161
|
+
done(void 0, a);
|
|
32162
|
+
return;
|
|
32163
|
+
}
|
|
32164
|
+
if (op === 85 && a !== null && a !== void 0) {
|
|
32165
|
+
done(void 0, a);
|
|
32166
|
+
return;
|
|
32167
|
+
}
|
|
32149
32168
|
let bobj;
|
|
32150
32169
|
try {
|
|
32151
32170
|
let ad;
|
|
@@ -32208,6 +32227,18 @@ var require_executor = __commonJS({
|
|
|
32208
32227
|
a = void 0;
|
|
32209
32228
|
}
|
|
32210
32229
|
}
|
|
32230
|
+
if (op === 29 && !a) {
|
|
32231
|
+
done(void 0, a);
|
|
32232
|
+
return;
|
|
32233
|
+
}
|
|
32234
|
+
if (op === 30 && a) {
|
|
32235
|
+
done(void 0, a);
|
|
32236
|
+
return;
|
|
32237
|
+
}
|
|
32238
|
+
if (op === 85 && a !== null && a !== void 0) {
|
|
32239
|
+
done(void 0, a);
|
|
32240
|
+
return;
|
|
32241
|
+
}
|
|
32211
32242
|
let bobj;
|
|
32212
32243
|
try {
|
|
32213
32244
|
bobj = syncDone((d) => execSync(ticks, tree[2], scope, context, d, inLoopOrSwitch)).result;
|
|
@@ -100588,7 +100619,7 @@ var init_ProbeAgent = __esm({
|
|
|
100588
100619
|
if (limiter && result.textStream) {
|
|
100589
100620
|
const originalStream = result.textStream;
|
|
100590
100621
|
const debug = this.debug;
|
|
100591
|
-
|
|
100622
|
+
const wrappedStream = (async function* () {
|
|
100592
100623
|
try {
|
|
100593
100624
|
for await (const chunk of originalStream) {
|
|
100594
100625
|
yield chunk;
|
|
@@ -100601,6 +100632,13 @@ var init_ProbeAgent = __esm({
|
|
|
100601
100632
|
}
|
|
100602
100633
|
}
|
|
100603
100634
|
})();
|
|
100635
|
+
return new Proxy(result, {
|
|
100636
|
+
get(target, prop) {
|
|
100637
|
+
if (prop === "textStream") return wrappedStream;
|
|
100638
|
+
const value = target[prop];
|
|
100639
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
100640
|
+
}
|
|
100641
|
+
});
|
|
100604
100642
|
} else if (limiter) {
|
|
100605
100643
|
limiter.release(null);
|
|
100606
100644
|
}
|
|
@@ -102254,6 +102292,21 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
102254
102292
|
}
|
|
102255
102293
|
}
|
|
102256
102294
|
}
|
|
102295
|
+
if (steps.length >= 3) {
|
|
102296
|
+
const last3 = steps.slice(-3);
|
|
102297
|
+
const allErrors = last3.every(
|
|
102298
|
+
(s) => s.toolResults?.length > 0 && s.toolResults.every((tr) => {
|
|
102299
|
+
const r = typeof tr.result === "string" ? tr.result : "";
|
|
102300
|
+
return r.includes("<error ") || r.includes("does not exist");
|
|
102301
|
+
})
|
|
102302
|
+
);
|
|
102303
|
+
if (allErrors) {
|
|
102304
|
+
if (this.debug) {
|
|
102305
|
+
console.log(`[DEBUG] prepareStep: 3 consecutive tool errors, forcing toolChoice=none`);
|
|
102306
|
+
}
|
|
102307
|
+
return { toolChoice: "none" };
|
|
102308
|
+
}
|
|
102309
|
+
}
|
|
102257
102310
|
const lastStep = steps[steps.length - 1];
|
|
102258
102311
|
const modelJustStopped = lastStep?.finishReason === "stop" && (!lastStep?.toolCalls || lastStep.toolCalls.length === 0);
|
|
102259
102312
|
if (modelJustStopped) {
|
|
@@ -102282,7 +102335,8 @@ Here is the result to review:
|
|
|
102282
102335
|
${resultToReview}
|
|
102283
102336
|
</result>
|
|
102284
102337
|
|
|
102285
|
-
|
|
102338
|
+
IMPORTANT: First review ALL completed work in the conversation above before taking any action.
|
|
102339
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If your text has inaccuracies, fix the text. Only call a tool if you find a genuinely MISSING action \u2014 NEVER redo work that was already completed successfully. Respond with the COMPLETE corrected answer.`;
|
|
102286
102340
|
return {
|
|
102287
102341
|
userMessage: completionPromptMessage,
|
|
102288
102342
|
toolChoice: "none"
|
|
@@ -102441,7 +102495,8 @@ Here is the result to review:
|
|
|
102441
102495
|
${finalResult}
|
|
102442
102496
|
</result>
|
|
102443
102497
|
|
|
102444
|
-
|
|
102498
|
+
IMPORTANT: First review ALL completed work in the conversation above before taking any action.
|
|
102499
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If your text has inaccuracies, fix the text. Only call a tool if you find a genuinely MISSING action \u2014 NEVER redo work that was already completed successfully. Respond with the COMPLETE corrected answer.`;
|
|
102445
102500
|
currentMessages.push({ role: "user", content: completionPromptMessage });
|
|
102446
102501
|
const completionStreamOptions = {
|
|
102447
102502
|
model: this.provider ? this.provider(this.model) : this.model,
|
package/cjs/index.cjs
CHANGED
|
@@ -1447,13 +1447,13 @@ function categorizeError(error40) {
|
|
|
1447
1447
|
if (lowerMessage.includes("path does not exist") || lowerMessage.includes("no such file or directory") || errorCode === "enoent") {
|
|
1448
1448
|
return new PathError(message, {
|
|
1449
1449
|
originalError: error40,
|
|
1450
|
-
suggestion: "The specified path does not exist.
|
|
1450
|
+
suggestion: "The specified path does not exist. Use the listFiles tool to check the correct directory structure, then retry with a valid path."
|
|
1451
1451
|
});
|
|
1452
1452
|
}
|
|
1453
1453
|
if (lowerMessage.includes("not a directory") || errorCode === "enotdir") {
|
|
1454
1454
|
return new PathError(message, {
|
|
1455
1455
|
originalError: error40,
|
|
1456
|
-
suggestion: "The path is not a directory.
|
|
1456
|
+
suggestion: "The path is not a directory. Use the listFiles tool to find the correct directory, then retry."
|
|
1457
1457
|
});
|
|
1458
1458
|
}
|
|
1459
1459
|
if (lowerMessage.includes("permission denied") || errorCode === "eacces") {
|
|
@@ -1709,7 +1709,7 @@ async function validateCwdPath(inputPath, defaultPath = process.cwd()) {
|
|
|
1709
1709
|
}
|
|
1710
1710
|
if (error40.code === "ENOENT") {
|
|
1711
1711
|
throw new PathError(`Path does not exist: ${normalizedPath}`, {
|
|
1712
|
-
suggestion: "The specified path does not exist.
|
|
1712
|
+
suggestion: "The specified path does not exist. Use the listFiles tool to check the correct directory structure, then retry with a valid path.",
|
|
1713
1713
|
details: { path: normalizedPath }
|
|
1714
1714
|
});
|
|
1715
1715
|
}
|
|
@@ -82700,6 +82700,9 @@ var require_utils2 = __commonJS({
|
|
|
82700
82700
|
sandboxGlobal
|
|
82701
82701
|
};
|
|
82702
82702
|
context.prototypeWhitelist.set(Object.getPrototypeOf([][Symbol.iterator]()), /* @__PURE__ */ new Set());
|
|
82703
|
+
context.prototypeWhitelist.set(Object.getPrototypeOf(""[Symbol.iterator]()), /* @__PURE__ */ new Set());
|
|
82704
|
+
context.prototypeWhitelist.set(Object.getPrototypeOf((/* @__PURE__ */ new Set())[Symbol.iterator]()), /* @__PURE__ */ new Set());
|
|
82705
|
+
context.prototypeWhitelist.set(Object.getPrototypeOf((/* @__PURE__ */ new Map())[Symbol.iterator]()), /* @__PURE__ */ new Set());
|
|
82703
82706
|
return context;
|
|
82704
82707
|
}
|
|
82705
82708
|
function createExecContext(sandbox, executionTree, evalContext) {
|
|
@@ -83838,6 +83841,18 @@ var require_executor = __commonJS({
|
|
|
83838
83841
|
a = void 0;
|
|
83839
83842
|
}
|
|
83840
83843
|
}
|
|
83844
|
+
if (op === 29 && !a) {
|
|
83845
|
+
done(void 0, a);
|
|
83846
|
+
return;
|
|
83847
|
+
}
|
|
83848
|
+
if (op === 30 && a) {
|
|
83849
|
+
done(void 0, a);
|
|
83850
|
+
return;
|
|
83851
|
+
}
|
|
83852
|
+
if (op === 85 && a !== null && a !== void 0) {
|
|
83853
|
+
done(void 0, a);
|
|
83854
|
+
return;
|
|
83855
|
+
}
|
|
83841
83856
|
let bobj;
|
|
83842
83857
|
try {
|
|
83843
83858
|
let ad;
|
|
@@ -83900,6 +83915,18 @@ var require_executor = __commonJS({
|
|
|
83900
83915
|
a = void 0;
|
|
83901
83916
|
}
|
|
83902
83917
|
}
|
|
83918
|
+
if (op === 29 && !a) {
|
|
83919
|
+
done(void 0, a);
|
|
83920
|
+
return;
|
|
83921
|
+
}
|
|
83922
|
+
if (op === 30 && a) {
|
|
83923
|
+
done(void 0, a);
|
|
83924
|
+
return;
|
|
83925
|
+
}
|
|
83926
|
+
if (op === 85 && a !== null && a !== void 0) {
|
|
83927
|
+
done(void 0, a);
|
|
83928
|
+
return;
|
|
83929
|
+
}
|
|
83903
83930
|
let bobj;
|
|
83904
83931
|
try {
|
|
83905
83932
|
bobj = syncDone((d) => execSync(ticks, tree[2], scope, context, d, inLoopOrSwitch)).result;
|
|
@@ -97538,7 +97565,7 @@ var init_ProbeAgent = __esm({
|
|
|
97538
97565
|
if (limiter && result.textStream) {
|
|
97539
97566
|
const originalStream = result.textStream;
|
|
97540
97567
|
const debug = this.debug;
|
|
97541
|
-
|
|
97568
|
+
const wrappedStream = (async function* () {
|
|
97542
97569
|
try {
|
|
97543
97570
|
for await (const chunk of originalStream) {
|
|
97544
97571
|
yield chunk;
|
|
@@ -97551,6 +97578,13 @@ var init_ProbeAgent = __esm({
|
|
|
97551
97578
|
}
|
|
97552
97579
|
}
|
|
97553
97580
|
})();
|
|
97581
|
+
return new Proxy(result, {
|
|
97582
|
+
get(target, prop) {
|
|
97583
|
+
if (prop === "textStream") return wrappedStream;
|
|
97584
|
+
const value = target[prop];
|
|
97585
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
97586
|
+
}
|
|
97587
|
+
});
|
|
97554
97588
|
} else if (limiter) {
|
|
97555
97589
|
limiter.release(null);
|
|
97556
97590
|
}
|
|
@@ -99204,6 +99238,21 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99204
99238
|
}
|
|
99205
99239
|
}
|
|
99206
99240
|
}
|
|
99241
|
+
if (steps.length >= 3) {
|
|
99242
|
+
const last3 = steps.slice(-3);
|
|
99243
|
+
const allErrors = last3.every(
|
|
99244
|
+
(s) => s.toolResults?.length > 0 && s.toolResults.every((tr) => {
|
|
99245
|
+
const r = typeof tr.result === "string" ? tr.result : "";
|
|
99246
|
+
return r.includes("<error ") || r.includes("does not exist");
|
|
99247
|
+
})
|
|
99248
|
+
);
|
|
99249
|
+
if (allErrors) {
|
|
99250
|
+
if (this.debug) {
|
|
99251
|
+
console.log(`[DEBUG] prepareStep: 3 consecutive tool errors, forcing toolChoice=none`);
|
|
99252
|
+
}
|
|
99253
|
+
return { toolChoice: "none" };
|
|
99254
|
+
}
|
|
99255
|
+
}
|
|
99207
99256
|
const lastStep = steps[steps.length - 1];
|
|
99208
99257
|
const modelJustStopped = lastStep?.finishReason === "stop" && (!lastStep?.toolCalls || lastStep.toolCalls.length === 0);
|
|
99209
99258
|
if (modelJustStopped) {
|
|
@@ -99232,7 +99281,8 @@ Here is the result to review:
|
|
|
99232
99281
|
${resultToReview}
|
|
99233
99282
|
</result>
|
|
99234
99283
|
|
|
99235
|
-
|
|
99284
|
+
IMPORTANT: First review ALL completed work in the conversation above before taking any action.
|
|
99285
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If your text has inaccuracies, fix the text. Only call a tool if you find a genuinely MISSING action \u2014 NEVER redo work that was already completed successfully. Respond with the COMPLETE corrected answer.`;
|
|
99236
99286
|
return {
|
|
99237
99287
|
userMessage: completionPromptMessage,
|
|
99238
99288
|
toolChoice: "none"
|
|
@@ -99391,7 +99441,8 @@ Here is the result to review:
|
|
|
99391
99441
|
${finalResult}
|
|
99392
99442
|
</result>
|
|
99393
99443
|
|
|
99394
|
-
|
|
99444
|
+
IMPORTANT: First review ALL completed work in the conversation above before taking any action.
|
|
99445
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If your text has inaccuracies, fix the text. Only call a tool if you find a genuinely MISSING action \u2014 NEVER redo work that was already completed successfully. Respond with the COMPLETE corrected answer.`;
|
|
99395
99446
|
currentMessages.push({ role: "user", content: completionPromptMessage });
|
|
99396
99447
|
const completionStreamOptions = {
|
|
99397
99448
|
model: this.provider ? this.provider(this.model) : this.model,
|
|
@@ -101417,7 +101468,11 @@ var init_vercel = __esm({
|
|
|
101417
101468
|
return result;
|
|
101418
101469
|
} catch (error40) {
|
|
101419
101470
|
console.error("Error executing search command:", error40);
|
|
101420
|
-
|
|
101471
|
+
const formatted = formatErrorForAI(error40);
|
|
101472
|
+
if (error40.category === "path_error" || error40.message?.includes("does not exist")) {
|
|
101473
|
+
return formatted + "\n\nThe path does not exist. Use the listFiles tool to verify the correct directory structure before retrying. If the workspace itself is gone, output your final answer with whatever information you have.";
|
|
101474
|
+
}
|
|
101475
|
+
return formatted;
|
|
101421
101476
|
}
|
|
101422
101477
|
}
|
|
101423
101478
|
try {
|
package/package.json
CHANGED
package/src/agent/ProbeAgent.js
CHANGED
|
@@ -1444,11 +1444,13 @@ export class ProbeAgent {
|
|
|
1444
1444
|
result = await this._executeWithVercelProvider(options, controller);
|
|
1445
1445
|
}
|
|
1446
1446
|
|
|
1447
|
-
// Wrap textStream so limiter slot is held until stream completes
|
|
1447
|
+
// Wrap textStream so limiter slot is held until stream completes.
|
|
1448
|
+
// result.textStream is a read-only getter on DefaultStreamTextResult,
|
|
1449
|
+
// so we wrap the result in a Proxy that intercepts the textStream property.
|
|
1448
1450
|
if (limiter && result.textStream) {
|
|
1449
1451
|
const originalStream = result.textStream;
|
|
1450
1452
|
const debug = this.debug;
|
|
1451
|
-
|
|
1453
|
+
const wrappedStream = (async function* () {
|
|
1452
1454
|
try {
|
|
1453
1455
|
for await (const chunk of originalStream) {
|
|
1454
1456
|
yield chunk;
|
|
@@ -1461,6 +1463,13 @@ export class ProbeAgent {
|
|
|
1461
1463
|
}
|
|
1462
1464
|
}
|
|
1463
1465
|
})();
|
|
1466
|
+
return new Proxy(result, {
|
|
1467
|
+
get(target, prop) {
|
|
1468
|
+
if (prop === 'textStream') return wrappedStream;
|
|
1469
|
+
const value = target[prop];
|
|
1470
|
+
return typeof value === 'function' ? value.bind(target) : value;
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1464
1473
|
} else if (limiter) {
|
|
1465
1474
|
// No textStream (shouldn't happen, but release just in case)
|
|
1466
1475
|
limiter.release(null);
|
|
@@ -3499,6 +3508,7 @@ Follow these instructions carefully:
|
|
|
3499
3508
|
return true;
|
|
3500
3509
|
}
|
|
3501
3510
|
}
|
|
3511
|
+
|
|
3502
3512
|
}
|
|
3503
3513
|
|
|
3504
3514
|
return false;
|
|
@@ -3529,6 +3539,24 @@ Follow these instructions carefully:
|
|
|
3529
3539
|
}
|
|
3530
3540
|
}
|
|
3531
3541
|
|
|
3542
|
+
// Force text-only response after 3 consecutive tool errors
|
|
3543
|
+
// (e.g. workspace deleted mid-run — let the model produce its answer)
|
|
3544
|
+
if (steps.length >= 3) {
|
|
3545
|
+
const last3 = steps.slice(-3);
|
|
3546
|
+
const allErrors = last3.every(s =>
|
|
3547
|
+
s.toolResults?.length > 0 && s.toolResults.every(tr => {
|
|
3548
|
+
const r = typeof tr.result === 'string' ? tr.result : '';
|
|
3549
|
+
return r.includes('<error ') || r.includes('does not exist');
|
|
3550
|
+
})
|
|
3551
|
+
);
|
|
3552
|
+
if (allErrors) {
|
|
3553
|
+
if (this.debug) {
|
|
3554
|
+
console.log(`[DEBUG] prepareStep: 3 consecutive tool errors, forcing toolChoice=none`);
|
|
3555
|
+
}
|
|
3556
|
+
return { toolChoice: 'none' };
|
|
3557
|
+
}
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3532
3560
|
const lastStep = steps[steps.length - 1];
|
|
3533
3561
|
const modelJustStopped = lastStep?.finishReason === 'stop'
|
|
3534
3562
|
&& (!lastStep?.toolCalls || lastStep.toolCalls.length === 0);
|
|
@@ -3565,7 +3593,8 @@ Here is the result to review:
|
|
|
3565
3593
|
${resultToReview}
|
|
3566
3594
|
</result>
|
|
3567
3595
|
|
|
3568
|
-
|
|
3596
|
+
IMPORTANT: First review ALL completed work in the conversation above before taking any action.
|
|
3597
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If your text has inaccuracies, fix the text. Only call a tool if you find a genuinely MISSING action — NEVER redo work that was already completed successfully. Respond with the COMPLETE corrected answer.`;
|
|
3569
3598
|
|
|
3570
3599
|
return {
|
|
3571
3600
|
userMessage: completionPromptMessage,
|
|
@@ -3774,7 +3803,8 @@ Here is the result to review:
|
|
|
3774
3803
|
${finalResult}
|
|
3775
3804
|
</result>
|
|
3776
3805
|
|
|
3777
|
-
|
|
3806
|
+
IMPORTANT: First review ALL completed work in the conversation above before taking any action.
|
|
3807
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If your text has inaccuracies, fix the text. Only call a tool if you find a genuinely MISSING action — NEVER redo work that was already completed successfully. Respond with the COMPLETE corrected answer.`;
|
|
3778
3808
|
|
|
3779
3809
|
currentMessages.push({ role: 'user', content: completionPromptMessage });
|
|
3780
3810
|
|
package/src/tools/vercel.js
CHANGED
|
@@ -478,7 +478,11 @@ export const searchTool = (options = {}) => {
|
|
|
478
478
|
return result;
|
|
479
479
|
} catch (error) {
|
|
480
480
|
console.error('Error executing search command:', error);
|
|
481
|
-
|
|
481
|
+
const formatted = formatErrorForAI(error);
|
|
482
|
+
if (error.category === 'path_error' || error.message?.includes('does not exist')) {
|
|
483
|
+
return formatted + '\n\nThe path does not exist. Use the listFiles tool to verify the correct directory structure before retrying. If the workspace itself is gone, output your final answer with whatever information you have.';
|
|
484
|
+
}
|
|
485
|
+
return formatted;
|
|
482
486
|
}
|
|
483
487
|
}
|
|
484
488
|
|
package/src/utils/error-types.js
CHANGED
|
@@ -181,14 +181,14 @@ export function categorizeError(error) {
|
|
|
181
181
|
errorCode === 'enoent') {
|
|
182
182
|
return new PathError(message, {
|
|
183
183
|
originalError: error,
|
|
184
|
-
suggestion: 'The specified path does not exist.
|
|
184
|
+
suggestion: 'The specified path does not exist. Use the listFiles tool to check the correct directory structure, then retry with a valid path.'
|
|
185
185
|
});
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
if (lowerMessage.includes('not a directory') || errorCode === 'enotdir') {
|
|
189
189
|
return new PathError(message, {
|
|
190
190
|
originalError: error,
|
|
191
|
-
suggestion: 'The path is not a directory.
|
|
191
|
+
suggestion: 'The path is not a directory. Use the listFiles tool to find the correct directory, then retry.'
|
|
192
192
|
});
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -110,7 +110,7 @@ export async function validateCwdPath(inputPath, defaultPath = process.cwd()) {
|
|
|
110
110
|
}
|
|
111
111
|
if (error.code === 'ENOENT') {
|
|
112
112
|
throw new PathError(`Path does not exist: ${normalizedPath}`, {
|
|
113
|
-
suggestion: 'The specified path does not exist.
|
|
113
|
+
suggestion: 'The specified path does not exist. Use the listFiles tool to check the correct directory structure, then retry with a valid path.',
|
|
114
114
|
details: { path: normalizedPath }
|
|
115
115
|
});
|
|
116
116
|
}
|