@probelabs/probe 0.6.0-rc292 → 0.6.0-rc294
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-rc292-aarch64-apple-darwin.tar.gz → probe-v0.6.0-rc294-aarch64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc292-aarch64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc294-aarch64-unknown-linux-musl.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc292-x86_64-apple-darwin.tar.gz → probe-v0.6.0-rc294-x86_64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc292-x86_64-pc-windows-msvc.zip → probe-v0.6.0-rc294-x86_64-pc-windows-msvc.zip} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc292-x86_64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc294-x86_64-unknown-linux-musl.tar.gz} +0 -0
- package/build/agent/ProbeAgent.js +156 -48
- package/build/agent/shared/prompts.js +33 -3
- package/build/tools/fileTracker.js +33 -17
- package/build/tools/vercel.js +13 -10
- package/cjs/agent/ProbeAgent.cjs +211 -78
- package/cjs/index.cjs +218 -85
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +156 -48
- package/src/agent/shared/prompts.js +33 -3
- package/src/tools/fileTracker.js +33 -17
- package/src/tools/vercel.js +13 -10
package/cjs/index.cjs
CHANGED
|
@@ -27260,6 +27260,10 @@ var init_symbolEdit = __esm({
|
|
|
27260
27260
|
});
|
|
27261
27261
|
|
|
27262
27262
|
// src/tools/fileTracker.js
|
|
27263
|
+
function normalizePath(filePath) {
|
|
27264
|
+
if (!filePath) return filePath;
|
|
27265
|
+
return (0, import_path6.resolve)(filePath);
|
|
27266
|
+
}
|
|
27263
27267
|
function computeContentHash(content) {
|
|
27264
27268
|
const normalized = (content || "").split("\n").map((l) => l.trimEnd()).join("\n");
|
|
27265
27269
|
return (0, import_crypto2.createHash)("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
@@ -27322,10 +27326,11 @@ var init_fileTracker = __esm({
|
|
|
27322
27326
|
* @param {string} resolvedPath - Absolute path to the file
|
|
27323
27327
|
*/
|
|
27324
27328
|
markFileSeen(resolvedPath) {
|
|
27325
|
-
|
|
27326
|
-
this.
|
|
27329
|
+
const normalized = normalizePath(resolvedPath);
|
|
27330
|
+
this._seenFiles.add(normalized);
|
|
27331
|
+
this._textEditCounts.set(normalized, 0);
|
|
27327
27332
|
if (this.debug) {
|
|
27328
|
-
console.error(`[FileTracker] Marked as seen: ${
|
|
27333
|
+
console.error(`[FileTracker] Marked as seen: ${normalized}`);
|
|
27329
27334
|
}
|
|
27330
27335
|
}
|
|
27331
27336
|
/**
|
|
@@ -27334,7 +27339,7 @@ var init_fileTracker = __esm({
|
|
|
27334
27339
|
* @returns {boolean}
|
|
27335
27340
|
*/
|
|
27336
27341
|
isFileSeen(resolvedPath) {
|
|
27337
|
-
return this._seenFiles.has(resolvedPath);
|
|
27342
|
+
return this._seenFiles.has(normalizePath(resolvedPath));
|
|
27338
27343
|
}
|
|
27339
27344
|
/**
|
|
27340
27345
|
* Store a content hash for a symbol in a file.
|
|
@@ -27346,7 +27351,7 @@ var init_fileTracker = __esm({
|
|
|
27346
27351
|
* @param {string} [source='extract'] - How the content was obtained
|
|
27347
27352
|
*/
|
|
27348
27353
|
trackSymbolContent(resolvedPath, symbolName, code, startLine, endLine, source = "extract") {
|
|
27349
|
-
const key = `${resolvedPath}#${symbolName}`;
|
|
27354
|
+
const key = `${normalizePath(resolvedPath)}#${symbolName}`;
|
|
27350
27355
|
const contentHash = computeContentHash(code);
|
|
27351
27356
|
this._contentRecords.set(key, {
|
|
27352
27357
|
contentHash,
|
|
@@ -27367,7 +27372,7 @@ var init_fileTracker = __esm({
|
|
|
27367
27372
|
* @returns {Object|null} The stored record or null
|
|
27368
27373
|
*/
|
|
27369
27374
|
getSymbolRecord(resolvedPath, symbolName) {
|
|
27370
|
-
return this._contentRecords.get(`${resolvedPath}#${symbolName}`) || null;
|
|
27375
|
+
return this._contentRecords.get(`${normalizePath(resolvedPath)}#${symbolName}`) || null;
|
|
27371
27376
|
}
|
|
27372
27377
|
/**
|
|
27373
27378
|
* Check if a symbol's current content matches what was stored.
|
|
@@ -27377,7 +27382,7 @@ var init_fileTracker = __esm({
|
|
|
27377
27382
|
* @returns {{ok: boolean, reason?: string, message?: string}}
|
|
27378
27383
|
*/
|
|
27379
27384
|
checkSymbolContent(resolvedPath, symbolName, currentCode) {
|
|
27380
|
-
const key = `${resolvedPath}#${symbolName}`;
|
|
27385
|
+
const key = `${normalizePath(resolvedPath)}#${symbolName}`;
|
|
27381
27386
|
const record2 = this._contentRecords.get(key);
|
|
27382
27387
|
if (!record2) {
|
|
27383
27388
|
return { ok: true };
|
|
@@ -27454,7 +27459,7 @@ var init_fileTracker = __esm({
|
|
|
27454
27459
|
* @returns {{ok: boolean, reason?: string, message?: string}}
|
|
27455
27460
|
*/
|
|
27456
27461
|
checkBeforeEdit(resolvedPath) {
|
|
27457
|
-
if (!this._seenFiles.has(resolvedPath)) {
|
|
27462
|
+
if (!this._seenFiles.has(normalizePath(resolvedPath))) {
|
|
27458
27463
|
return {
|
|
27459
27464
|
ok: false,
|
|
27460
27465
|
reason: "untracked",
|
|
@@ -27469,8 +27474,9 @@ var init_fileTracker = __esm({
|
|
|
27469
27474
|
* @param {string} resolvedPath - Absolute path to the file
|
|
27470
27475
|
*/
|
|
27471
27476
|
async trackFileAfterWrite(resolvedPath) {
|
|
27472
|
-
|
|
27473
|
-
this.
|
|
27477
|
+
const normalized = normalizePath(resolvedPath);
|
|
27478
|
+
this._seenFiles.add(normalized);
|
|
27479
|
+
this.invalidateFileRecords(normalized);
|
|
27474
27480
|
}
|
|
27475
27481
|
/**
|
|
27476
27482
|
* Record a text-mode edit (old_string/new_string) to a file.
|
|
@@ -27478,10 +27484,11 @@ var init_fileTracker = __esm({
|
|
|
27478
27484
|
* @param {string} resolvedPath - Absolute path to the file
|
|
27479
27485
|
*/
|
|
27480
27486
|
recordTextEdit(resolvedPath) {
|
|
27481
|
-
const
|
|
27482
|
-
this._textEditCounts.
|
|
27487
|
+
const normalized = normalizePath(resolvedPath);
|
|
27488
|
+
const count = (this._textEditCounts.get(normalized) || 0) + 1;
|
|
27489
|
+
this._textEditCounts.set(normalized, count);
|
|
27483
27490
|
if (this.debug) {
|
|
27484
|
-
console.error(`[FileTracker] Text edit #${count} for ${
|
|
27491
|
+
console.error(`[FileTracker] Text edit #${count} for ${normalized}`);
|
|
27485
27492
|
}
|
|
27486
27493
|
}
|
|
27487
27494
|
/**
|
|
@@ -27490,7 +27497,7 @@ var init_fileTracker = __esm({
|
|
|
27490
27497
|
* @returns {{ok: boolean, editCount?: number, message?: string}}
|
|
27491
27498
|
*/
|
|
27492
27499
|
checkTextEditStaleness(resolvedPath) {
|
|
27493
|
-
const count = this._textEditCounts.get(resolvedPath) || 0;
|
|
27500
|
+
const count = this._textEditCounts.get(normalizePath(resolvedPath)) || 0;
|
|
27494
27501
|
if (count >= this.maxConsecutiveTextEdits) {
|
|
27495
27502
|
return {
|
|
27496
27503
|
ok: false,
|
|
@@ -27519,7 +27526,7 @@ var init_fileTracker = __esm({
|
|
|
27519
27526
|
* @param {string} resolvedPath - Absolute path to the file
|
|
27520
27527
|
*/
|
|
27521
27528
|
invalidateFileRecords(resolvedPath) {
|
|
27522
|
-
const prefix = resolvedPath + "#";
|
|
27529
|
+
const prefix = normalizePath(resolvedPath) + "#";
|
|
27523
27530
|
for (const key of this._contentRecords.keys()) {
|
|
27524
27531
|
if (key.startsWith(prefix)) {
|
|
27525
27532
|
this._contentRecords.delete(key);
|
|
@@ -27535,7 +27542,7 @@ var init_fileTracker = __esm({
|
|
|
27535
27542
|
* @returns {boolean}
|
|
27536
27543
|
*/
|
|
27537
27544
|
isTracked(resolvedPath) {
|
|
27538
|
-
return this.isFileSeen(resolvedPath);
|
|
27545
|
+
return this.isFileSeen(normalizePath(resolvedPath));
|
|
27539
27546
|
}
|
|
27540
27547
|
/**
|
|
27541
27548
|
* Clear all tracking state.
|
|
@@ -31588,7 +31595,7 @@ var init_esm3 = __esm({
|
|
|
31588
31595
|
});
|
|
31589
31596
|
|
|
31590
31597
|
// node_modules/path-scurry/dist/esm/index.js
|
|
31591
|
-
var import_node_path, import_node_url, import_fs4, actualFS, import_promises, realpathSync2, defaultFS, fsFromOption, uncDriveRegexp, uncToDrive, eitherSep, UNKNOWN, IFIFO, IFCHR, IFDIR, IFBLK, IFREG, IFLNK, IFSOCK, IFMT, IFMT_UNKNOWN, READDIR_CALLED, LSTAT_CALLED, ENOTDIR, ENOENT, ENOREADLINK, ENOREALPATH, ENOCHILD, TYPEMASK, entToType, normalizeCache,
|
|
31598
|
+
var import_node_path, import_node_url, import_fs4, actualFS, import_promises, realpathSync2, defaultFS, fsFromOption, uncDriveRegexp, uncToDrive, eitherSep, UNKNOWN, IFIFO, IFCHR, IFDIR, IFBLK, IFREG, IFLNK, IFSOCK, IFMT, IFMT_UNKNOWN, READDIR_CALLED, LSTAT_CALLED, ENOTDIR, ENOENT, ENOREADLINK, ENOREALPATH, ENOCHILD, TYPEMASK, entToType, normalizeCache, normalize2, normalizeNocaseCache, normalizeNocase, ResolveCache, ChildrenCache, setAsCwd, PathBase, PathWin32, PathPosix, PathScurryBase, PathScurryWin32, PathScurryPosix, PathScurryDarwin, Path, PathScurry;
|
|
31592
31599
|
var init_esm4 = __esm({
|
|
31593
31600
|
"node_modules/path-scurry/dist/esm/index.js"() {
|
|
31594
31601
|
init_esm2();
|
|
@@ -31643,7 +31650,7 @@ var init_esm4 = __esm({
|
|
|
31643
31650
|
TYPEMASK = 1023;
|
|
31644
31651
|
entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN;
|
|
31645
31652
|
normalizeCache = /* @__PURE__ */ new Map();
|
|
31646
|
-
|
|
31653
|
+
normalize2 = (s) => {
|
|
31647
31654
|
const c = normalizeCache.get(s);
|
|
31648
31655
|
if (c)
|
|
31649
31656
|
return c;
|
|
@@ -31656,7 +31663,7 @@ var init_esm4 = __esm({
|
|
|
31656
31663
|
const c = normalizeNocaseCache.get(s);
|
|
31657
31664
|
if (c)
|
|
31658
31665
|
return c;
|
|
31659
|
-
const n =
|
|
31666
|
+
const n = normalize2(s.toLowerCase());
|
|
31660
31667
|
normalizeNocaseCache.set(s, n);
|
|
31661
31668
|
return n;
|
|
31662
31669
|
};
|
|
@@ -31823,7 +31830,7 @@ var init_esm4 = __esm({
|
|
|
31823
31830
|
*/
|
|
31824
31831
|
constructor(name15, type = UNKNOWN, root2, roots, nocase, children, opts) {
|
|
31825
31832
|
this.name = name15;
|
|
31826
|
-
this.#matchName = nocase ? normalizeNocase(name15) :
|
|
31833
|
+
this.#matchName = nocase ? normalizeNocase(name15) : normalize2(name15);
|
|
31827
31834
|
this.#type = type & TYPEMASK;
|
|
31828
31835
|
this.nocase = nocase;
|
|
31829
31836
|
this.roots = roots;
|
|
@@ -31916,7 +31923,7 @@ var init_esm4 = __esm({
|
|
|
31916
31923
|
return this.parent || this;
|
|
31917
31924
|
}
|
|
31918
31925
|
const children = this.children();
|
|
31919
|
-
const name15 = this.nocase ? normalizeNocase(pathPart) :
|
|
31926
|
+
const name15 = this.nocase ? normalizeNocase(pathPart) : normalize2(pathPart);
|
|
31920
31927
|
for (const p of children) {
|
|
31921
31928
|
if (p.#matchName === name15) {
|
|
31922
31929
|
return p;
|
|
@@ -32161,7 +32168,7 @@ var init_esm4 = __esm({
|
|
|
32161
32168
|
* directly.
|
|
32162
32169
|
*/
|
|
32163
32170
|
isNamed(n) {
|
|
32164
|
-
return !this.nocase ? this.#matchName ===
|
|
32171
|
+
return !this.nocase ? this.#matchName === normalize2(n) : this.#matchName === normalizeNocase(n);
|
|
32165
32172
|
}
|
|
32166
32173
|
/**
|
|
32167
32174
|
* Return the Path object corresponding to the target of a symbolic link.
|
|
@@ -32300,7 +32307,7 @@ var init_esm4 = __esm({
|
|
|
32300
32307
|
#readdirMaybePromoteChild(e, c) {
|
|
32301
32308
|
for (let p = c.provisional; p < c.length; p++) {
|
|
32302
32309
|
const pchild = c[p];
|
|
32303
|
-
const name15 = this.nocase ? normalizeNocase(e.name) :
|
|
32310
|
+
const name15 = this.nocase ? normalizeNocase(e.name) : normalize2(e.name);
|
|
32304
32311
|
if (name15 !== pchild.#matchName) {
|
|
32305
32312
|
continue;
|
|
32306
32313
|
}
|
|
@@ -53617,7 +53624,7 @@ var init_graph_builder = __esm({
|
|
|
53617
53624
|
applyLinkStyles() {
|
|
53618
53625
|
if (!this.pendingLinkStyles.length || !this.edges.length)
|
|
53619
53626
|
return;
|
|
53620
|
-
const
|
|
53627
|
+
const normalize4 = (s) => {
|
|
53621
53628
|
const out = {};
|
|
53622
53629
|
for (const [kRaw, vRaw] of Object.entries(s)) {
|
|
53623
53630
|
const k = kRaw.trim().toLowerCase();
|
|
@@ -53638,7 +53645,7 @@ var init_graph_builder = __esm({
|
|
|
53638
53645
|
return out;
|
|
53639
53646
|
};
|
|
53640
53647
|
for (const cmd of this.pendingLinkStyles) {
|
|
53641
|
-
const style =
|
|
53648
|
+
const style = normalize4(cmd.props);
|
|
53642
53649
|
for (const idx of cmd.indices) {
|
|
53643
53650
|
if (idx >= 0 && idx < this.edges.length) {
|
|
53644
53651
|
const e = this.edges[idx];
|
|
@@ -60905,7 +60912,7 @@ var require_layout = __commonJS({
|
|
|
60905
60912
|
"use strict";
|
|
60906
60913
|
var _ = require_lodash2();
|
|
60907
60914
|
var acyclic = require_acyclic();
|
|
60908
|
-
var
|
|
60915
|
+
var normalize4 = require_normalize();
|
|
60909
60916
|
var rank = require_rank();
|
|
60910
60917
|
var normalizeRanks = require_util().normalizeRanks;
|
|
60911
60918
|
var parentDummyChains = require_parent_dummy_chains();
|
|
@@ -60967,7 +60974,7 @@ var require_layout = __commonJS({
|
|
|
60967
60974
|
removeEdgeLabelProxies(g);
|
|
60968
60975
|
});
|
|
60969
60976
|
time3(" normalize.run", function() {
|
|
60970
|
-
|
|
60977
|
+
normalize4.run(g);
|
|
60971
60978
|
});
|
|
60972
60979
|
time3(" parentDummyChains", function() {
|
|
60973
60980
|
parentDummyChains(g);
|
|
@@ -60994,7 +61001,7 @@ var require_layout = __commonJS({
|
|
|
60994
61001
|
removeBorderNodes(g);
|
|
60995
61002
|
});
|
|
60996
61003
|
time3(" normalize.undo", function() {
|
|
60997
|
-
|
|
61004
|
+
normalize4.undo(g);
|
|
60998
61005
|
});
|
|
60999
61006
|
time3(" fixupEdgeLabelCoords", function() {
|
|
61000
61007
|
fixupEdgeLabelCoords(g);
|
|
@@ -67365,8 +67372,8 @@ var require_resolve = __commonJS({
|
|
|
67365
67372
|
}
|
|
67366
67373
|
return count;
|
|
67367
67374
|
}
|
|
67368
|
-
function getFullPath(resolver, id = "",
|
|
67369
|
-
if (
|
|
67375
|
+
function getFullPath(resolver, id = "", normalize4) {
|
|
67376
|
+
if (normalize4 !== false)
|
|
67370
67377
|
id = normalizeId(id);
|
|
67371
67378
|
const p = resolver.parse(id);
|
|
67372
67379
|
return _getFullPath(resolver, p);
|
|
@@ -68706,7 +68713,7 @@ var require_fast_uri = __commonJS({
|
|
|
68706
68713
|
"use strict";
|
|
68707
68714
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils();
|
|
68708
68715
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
68709
|
-
function
|
|
68716
|
+
function normalize4(uri, options) {
|
|
68710
68717
|
if (typeof uri === "string") {
|
|
68711
68718
|
uri = /** @type {T} */
|
|
68712
68719
|
serialize(parse11(uri, options), options);
|
|
@@ -68942,7 +68949,7 @@ var require_fast_uri = __commonJS({
|
|
|
68942
68949
|
}
|
|
68943
68950
|
var fastUri = {
|
|
68944
68951
|
SCHEMES,
|
|
68945
|
-
normalize:
|
|
68952
|
+
normalize: normalize4,
|
|
68946
68953
|
resolve: resolve9,
|
|
68947
68954
|
resolveComponent,
|
|
68948
68955
|
equal,
|
|
@@ -73149,9 +73156,9 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
73149
73156
|
- Do not add code comments unless the logic is genuinely complex and non-obvious.
|
|
73150
73157
|
|
|
73151
73158
|
# Before Implementation
|
|
73152
|
-
-
|
|
73153
|
-
-
|
|
73154
|
-
-
|
|
73159
|
+
- Read tests first \u2014 find existing test files for the module you're changing. They reveal expected behavior, edge cases, and the project's testing patterns.
|
|
73160
|
+
- Read neighboring files \u2014 understand naming conventions, error handling patterns, import style, and existing utilities before creating new ones.
|
|
73161
|
+
- Trace the call chain \u2014 follow how the code you're changing is called and what depends on it. Check interfaces, types, and consumers.
|
|
73155
73162
|
- Focus on backward compatibility
|
|
73156
73163
|
- Consider scalability, maintainability, and extensibility in your analysis
|
|
73157
73164
|
|
|
@@ -73176,6 +73183,20 @@ Before building or testing, determine the project's toolchain:
|
|
|
73176
73183
|
- Read README for build/test instructions if the above are unclear
|
|
73177
73184
|
- Common patterns: \`make build\`/\`make test\`, \`npm run build\`/\`npm test\`, \`cargo build\`/\`cargo test\`, \`go build ./...\`/\`go test ./...\`, \`python -m pytest\`
|
|
73178
73185
|
|
|
73186
|
+
# File Editing Rules
|
|
73187
|
+
You have access to the \`edit\`, \`create\`, and \`multi_edit\` tools for modifying files. You MUST use these tools for ALL code changes. They are purpose-built, atomic, and safe.
|
|
73188
|
+
|
|
73189
|
+
DO NOT use sed, awk, echo/cat redirection, or heredocs to modify source code. These commands cause real damage in practice: truncated lines, duplicate code blocks, broken syntax. Every bad edit wastes iterations on fix-up commits.
|
|
73190
|
+
|
|
73191
|
+
Use the right tool:
|
|
73192
|
+
1. To MODIFY existing code \u2192 \`edit\` tool (old_string \u2192 new_string, or start_line/end_line)
|
|
73193
|
+
2. To CREATE a new file \u2192 \`create\` tool
|
|
73194
|
+
3. To CHANGE multiple files at once \u2192 \`multi_edit\` tool
|
|
73195
|
+
4. To READ code \u2192 \`extract\` or \`search\` tools
|
|
73196
|
+
5. If \`edit\` fails with "file has not been read yet" \u2192 use \`extract\` with the EXACT same file path you will pass to \`edit\`. Relative vs absolute path mismatch causes this error. Use the same path format consistently. If it still fails, use bash \`cat\` to read the file, then use \`create\` to write the entire modified file. Do NOT fall back to sed.
|
|
73197
|
+
|
|
73198
|
+
Bash is fine for: formatters (gofmt, prettier, black), build/test/lint commands, git operations, and read-only file inspection (cat, head, tail). sed/awk should ONLY be used for trivial non-code tasks (e.g., config file tweaks) where the replacement is a simple literal string swap.
|
|
73199
|
+
|
|
73179
73200
|
# During Implementation
|
|
73180
73201
|
- Always create a new branch before making changes to the codebase.
|
|
73181
73202
|
- Fix problems at the root cause, not with surface-level patches. Prefer general solutions over special cases.
|
|
@@ -73202,6 +73223,22 @@ Before committing or creating a PR, run through this checklist:
|
|
|
73202
73223
|
|
|
73203
73224
|
Do NOT skip verification. Do NOT proceed to PR creation with a broken build or failing tests.
|
|
73204
73225
|
|
|
73226
|
+
# Output Integrity
|
|
73227
|
+
Your final output MUST accurately reflect what ACTUALLY happened. Do NOT fabricate, hallucinate, or report aspirational results.
|
|
73228
|
+
|
|
73229
|
+
- Only report PR URLs you actually created or updated with \`gh pr create\` or \`git push\`. If you checked out an existing PR but did NOT push changes to it, do NOT claim you updated it.
|
|
73230
|
+
- Describe what you ACTUALLY DID, not what you planned or intended to do. If you ran out of iterations, say so. If tests failed, say so.
|
|
73231
|
+
- Only list files you actually modified AND committed.
|
|
73232
|
+
- If you could not complete the task \u2014 ran out of iterations, tests failed, build broken, push rejected \u2014 report the real reason honestly.
|
|
73233
|
+
|
|
73234
|
+
NEVER claim success when:
|
|
73235
|
+
- You did not run \`git push\` successfully
|
|
73236
|
+
- Tests failed and you did not fix them
|
|
73237
|
+
- You hit the iteration limit before completing the work
|
|
73238
|
+
- You only analyzed/investigated but did not implement changes
|
|
73239
|
+
|
|
73240
|
+
A false success report is WORSE than an honest failure \u2014 it misleads the user into thinking work is done when it is not.
|
|
73241
|
+
|
|
73205
73242
|
# GitHub Integration
|
|
73206
73243
|
- Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
|
|
73207
73244
|
- To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
|
|
@@ -97494,9 +97531,13 @@ var init_ProbeAgent = __esm({
|
|
|
97494
97531
|
}
|
|
97495
97532
|
return await this.fallbackManager.executeWithFallback(
|
|
97496
97533
|
async (provider, model, config2) => {
|
|
97534
|
+
let fallbackModel = provider(model);
|
|
97535
|
+
if (this.concurrencyLimiter) {
|
|
97536
|
+
fallbackModel = _ProbeAgent._wrapModelWithLimiter(fallbackModel, this.concurrencyLimiter, this.debug);
|
|
97537
|
+
}
|
|
97497
97538
|
const fallbackOptions = {
|
|
97498
97539
|
...options,
|
|
97499
|
-
model:
|
|
97540
|
+
model: fallbackModel,
|
|
97500
97541
|
abortSignal: controller.signal
|
|
97501
97542
|
};
|
|
97502
97543
|
if (config2.provider !== "google" && fallbackOptions.tools) {
|
|
@@ -97524,6 +97565,132 @@ var init_ProbeAgent = __esm({
|
|
|
97524
97565
|
}
|
|
97525
97566
|
);
|
|
97526
97567
|
}
|
|
97568
|
+
/**
|
|
97569
|
+
* Wrap a LanguageModelV1 model so each doStream/doGenerate call acquires and
|
|
97570
|
+
* releases a concurrency limiter slot. This gates individual LLM API calls
|
|
97571
|
+
* (seconds each) instead of entire multi-step agent sessions (minutes).
|
|
97572
|
+
*
|
|
97573
|
+
* @param {Object} model - LanguageModelV1 model instance
|
|
97574
|
+
* @param {Object} limiter - Concurrency limiter with acquire/release/getStats
|
|
97575
|
+
* @param {boolean} debug - Enable debug logging
|
|
97576
|
+
* @returns {Object} Wrapped model with per-call concurrency gating
|
|
97577
|
+
* @private
|
|
97578
|
+
*/
|
|
97579
|
+
static _wrapModelWithLimiter(model, limiter, debug) {
|
|
97580
|
+
return new Proxy(model, {
|
|
97581
|
+
get(target, prop) {
|
|
97582
|
+
if (prop === "doStream") {
|
|
97583
|
+
return async function(...args) {
|
|
97584
|
+
await limiter.acquire(null);
|
|
97585
|
+
if (debug) {
|
|
97586
|
+
const stats = limiter.getStats();
|
|
97587
|
+
console.log(`[DEBUG] Acquired AI slot for LLM call (${stats.globalActive}/${stats.maxConcurrent}, queue: ${stats.queueSize})`);
|
|
97588
|
+
}
|
|
97589
|
+
try {
|
|
97590
|
+
const result = await target.doStream(...args);
|
|
97591
|
+
const originalStream = result.stream;
|
|
97592
|
+
const originalReader = originalStream.getReader();
|
|
97593
|
+
let released = false;
|
|
97594
|
+
const releaseOnce = () => {
|
|
97595
|
+
if (released) return;
|
|
97596
|
+
released = true;
|
|
97597
|
+
limiter.release(null);
|
|
97598
|
+
};
|
|
97599
|
+
const wrappedStream = new ReadableStream({
|
|
97600
|
+
async pull(controller) {
|
|
97601
|
+
try {
|
|
97602
|
+
const { done, value: value2 } = await originalReader.read();
|
|
97603
|
+
if (done) {
|
|
97604
|
+
controller.close();
|
|
97605
|
+
releaseOnce();
|
|
97606
|
+
if (debug) {
|
|
97607
|
+
const stats = limiter.getStats();
|
|
97608
|
+
console.log(`[DEBUG] Released AI slot after LLM stream complete (${stats.globalActive}/${stats.maxConcurrent})`);
|
|
97609
|
+
}
|
|
97610
|
+
} else {
|
|
97611
|
+
controller.enqueue(value2);
|
|
97612
|
+
}
|
|
97613
|
+
} catch (err) {
|
|
97614
|
+
releaseOnce();
|
|
97615
|
+
if (debug) {
|
|
97616
|
+
console.log(`[DEBUG] Released AI slot on LLM stream error`);
|
|
97617
|
+
}
|
|
97618
|
+
controller.error(err);
|
|
97619
|
+
}
|
|
97620
|
+
},
|
|
97621
|
+
cancel() {
|
|
97622
|
+
releaseOnce();
|
|
97623
|
+
if (debug) {
|
|
97624
|
+
console.log(`[DEBUG] Released AI slot on LLM stream cancel`);
|
|
97625
|
+
}
|
|
97626
|
+
originalReader.cancel();
|
|
97627
|
+
}
|
|
97628
|
+
});
|
|
97629
|
+
return { ...result, stream: wrappedStream };
|
|
97630
|
+
} catch (err) {
|
|
97631
|
+
limiter.release(null);
|
|
97632
|
+
if (debug) {
|
|
97633
|
+
console.log(`[DEBUG] Released AI slot on doStream error`);
|
|
97634
|
+
}
|
|
97635
|
+
throw err;
|
|
97636
|
+
}
|
|
97637
|
+
};
|
|
97638
|
+
}
|
|
97639
|
+
if (prop === "doGenerate") {
|
|
97640
|
+
return async function(...args) {
|
|
97641
|
+
await limiter.acquire(null);
|
|
97642
|
+
if (debug) {
|
|
97643
|
+
const stats = limiter.getStats();
|
|
97644
|
+
console.log(`[DEBUG] Acquired AI slot for LLM generate (${stats.globalActive}/${stats.maxConcurrent})`);
|
|
97645
|
+
}
|
|
97646
|
+
try {
|
|
97647
|
+
const result = await target.doGenerate(...args);
|
|
97648
|
+
return result;
|
|
97649
|
+
} finally {
|
|
97650
|
+
limiter.release(null);
|
|
97651
|
+
if (debug) {
|
|
97652
|
+
const stats = limiter.getStats();
|
|
97653
|
+
console.log(`[DEBUG] Released AI slot after LLM generate (${stats.globalActive}/${stats.maxConcurrent})`);
|
|
97654
|
+
}
|
|
97655
|
+
}
|
|
97656
|
+
};
|
|
97657
|
+
}
|
|
97658
|
+
const value = target[prop];
|
|
97659
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
97660
|
+
}
|
|
97661
|
+
});
|
|
97662
|
+
}
|
|
97663
|
+
/**
|
|
97664
|
+
* Wrap an engine stream result so its textStream async generator acquires
|
|
97665
|
+
* and releases a concurrency limiter slot. Acquire happens when iteration
|
|
97666
|
+
* begins; release happens in finally (completion, error, or break).
|
|
97667
|
+
*
|
|
97668
|
+
* @param {Object} result - Engine result with { textStream, usage, ... }
|
|
97669
|
+
* @param {Object} limiter - Concurrency limiter with acquire/release/getStats
|
|
97670
|
+
* @param {boolean} debug - Enable debug logging
|
|
97671
|
+
* @returns {Object} Result with wrapped textStream
|
|
97672
|
+
* @private
|
|
97673
|
+
*/
|
|
97674
|
+
static _wrapEngineStreamWithLimiter(result, limiter, debug) {
|
|
97675
|
+
const originalStream = result.textStream;
|
|
97676
|
+
async function* gatedStream() {
|
|
97677
|
+
await limiter.acquire(null);
|
|
97678
|
+
if (debug) {
|
|
97679
|
+
const stats = limiter.getStats();
|
|
97680
|
+
console.log(`[DEBUG] Acquired AI slot for engine stream (${stats.globalActive}/${stats.maxConcurrent}, queue: ${stats.queueSize})`);
|
|
97681
|
+
}
|
|
97682
|
+
try {
|
|
97683
|
+
yield* originalStream;
|
|
97684
|
+
} finally {
|
|
97685
|
+
limiter.release(null);
|
|
97686
|
+
if (debug) {
|
|
97687
|
+
const stats = limiter.getStats();
|
|
97688
|
+
console.log(`[DEBUG] Released AI slot after engine stream (${stats.globalActive}/${stats.maxConcurrent})`);
|
|
97689
|
+
}
|
|
97690
|
+
}
|
|
97691
|
+
}
|
|
97692
|
+
return { ...result, textStream: gatedStream() };
|
|
97693
|
+
}
|
|
97527
97694
|
/**
|
|
97528
97695
|
* Execute streamText with retry and fallback support
|
|
97529
97696
|
* @param {Object} options - streamText options
|
|
@@ -97532,12 +97699,8 @@ var init_ProbeAgent = __esm({
|
|
|
97532
97699
|
*/
|
|
97533
97700
|
async streamTextWithRetryAndFallback(options) {
|
|
97534
97701
|
const limiter = this.concurrencyLimiter;
|
|
97535
|
-
if (limiter) {
|
|
97536
|
-
|
|
97537
|
-
if (this.debug) {
|
|
97538
|
-
const stats = limiter.getStats();
|
|
97539
|
-
console.log(`[DEBUG] Acquired global AI concurrency slot (${stats.globalActive}/${stats.maxConcurrent}, queue: ${stats.queueSize})`);
|
|
97540
|
-
}
|
|
97702
|
+
if (limiter && options.model) {
|
|
97703
|
+
options = { ...options, model: _ProbeAgent._wrapModelWithLimiter(options.model, limiter, this.debug) };
|
|
97541
97704
|
}
|
|
97542
97705
|
const controller = new AbortController();
|
|
97543
97706
|
const timeoutState = { timeoutId: null };
|
|
@@ -97565,6 +97728,9 @@ var init_ProbeAgent = __esm({
|
|
|
97565
97728
|
if (useClaudeCode || useCodex) {
|
|
97566
97729
|
try {
|
|
97567
97730
|
result = await this._tryEngineStreamPath(options, controller, timeoutState);
|
|
97731
|
+
if (result && limiter) {
|
|
97732
|
+
result = _ProbeAgent._wrapEngineStreamWithLimiter(result, limiter, this.debug);
|
|
97733
|
+
}
|
|
97568
97734
|
} catch (error40) {
|
|
97569
97735
|
if (this.debug) {
|
|
97570
97736
|
const engineType = useClaudeCode ? "Claude Code" : "Codex";
|
|
@@ -97575,41 +97741,7 @@ var init_ProbeAgent = __esm({
|
|
|
97575
97741
|
if (!result) {
|
|
97576
97742
|
result = await this._executeWithVercelProvider(options, controller);
|
|
97577
97743
|
}
|
|
97578
|
-
if (limiter && result.textStream) {
|
|
97579
|
-
const originalStream = result.textStream;
|
|
97580
|
-
const debug = this.debug;
|
|
97581
|
-
const wrappedStream = (async function* () {
|
|
97582
|
-
try {
|
|
97583
|
-
for await (const chunk of originalStream) {
|
|
97584
|
-
yield chunk;
|
|
97585
|
-
}
|
|
97586
|
-
} finally {
|
|
97587
|
-
limiter.release(null);
|
|
97588
|
-
if (debug) {
|
|
97589
|
-
const stats = limiter.getStats();
|
|
97590
|
-
console.log(`[DEBUG] Released global AI concurrency slot (${stats.globalActive}/${stats.maxConcurrent}, queue: ${stats.queueSize})`);
|
|
97591
|
-
}
|
|
97592
|
-
}
|
|
97593
|
-
})();
|
|
97594
|
-
return new Proxy(result, {
|
|
97595
|
-
get(target, prop) {
|
|
97596
|
-
if (prop === "textStream") return wrappedStream;
|
|
97597
|
-
const value = target[prop];
|
|
97598
|
-
return typeof value === "function" ? value.bind(target) : value;
|
|
97599
|
-
}
|
|
97600
|
-
});
|
|
97601
|
-
} else if (limiter) {
|
|
97602
|
-
limiter.release(null);
|
|
97603
|
-
}
|
|
97604
97744
|
return result;
|
|
97605
|
-
} catch (error40) {
|
|
97606
|
-
if (limiter) {
|
|
97607
|
-
limiter.release(null);
|
|
97608
|
-
if (this.debug) {
|
|
97609
|
-
console.log(`[DEBUG] Released global AI concurrency slot on error`);
|
|
97610
|
-
}
|
|
97611
|
-
}
|
|
97612
|
-
throw error40;
|
|
97613
97745
|
} finally {
|
|
97614
97746
|
if (timeoutState.timeoutId) {
|
|
97615
97747
|
clearTimeout(timeoutState.timeoutId);
|
|
@@ -101404,7 +101536,7 @@ var init_vercel = __esm({
|
|
|
101404
101536
|
name: "search",
|
|
101405
101537
|
description: searchDelegate ? searchDelegateDescription : searchDescription,
|
|
101406
101538
|
inputSchema: searchSchema,
|
|
101407
|
-
execute: async ({ query: searchQuery, path: path9, allow_tests, exact, maxTokens: paramMaxTokens, language, session, nextPage }) => {
|
|
101539
|
+
execute: async ({ query: searchQuery, path: path9, allow_tests, exact, maxTokens: paramMaxTokens, language, session, nextPage, workingDirectory }) => {
|
|
101408
101540
|
if (!exact && searchQuery) {
|
|
101409
101541
|
const originalQuery = searchQuery;
|
|
101410
101542
|
searchQuery = autoQuoteSearchTerms(searchQuery);
|
|
@@ -101413,18 +101545,19 @@ var init_vercel = __esm({
|
|
|
101413
101545
|
}
|
|
101414
101546
|
}
|
|
101415
101547
|
const effectiveMaxTokens = paramMaxTokens || maxTokens;
|
|
101548
|
+
const effectiveSearchCwd = workingDirectory || options.cwd || ".";
|
|
101416
101549
|
let searchPaths;
|
|
101417
101550
|
if (path9) {
|
|
101418
|
-
searchPaths = parseAndResolvePaths(path9,
|
|
101551
|
+
searchPaths = parseAndResolvePaths(path9, effectiveSearchCwd);
|
|
101419
101552
|
}
|
|
101420
101553
|
if (!searchPaths || searchPaths.length === 0) {
|
|
101421
|
-
searchPaths = [
|
|
101554
|
+
searchPaths = [effectiveSearchCwd];
|
|
101422
101555
|
}
|
|
101423
101556
|
const searchPath = searchPaths.join(" ");
|
|
101424
101557
|
const searchOptions = {
|
|
101425
101558
|
query: searchQuery,
|
|
101426
101559
|
path: searchPath,
|
|
101427
|
-
cwd:
|
|
101560
|
+
cwd: effectiveSearchCwd,
|
|
101428
101561
|
// Working directory for resolving relative paths
|
|
101429
101562
|
allowTests: allow_tests ?? true,
|
|
101430
101563
|
exact,
|
|
@@ -101475,7 +101608,7 @@ var init_vercel = __esm({
|
|
|
101475
101608
|
try {
|
|
101476
101609
|
const result = maybeAnnotate(await runRawSearch());
|
|
101477
101610
|
if (options.fileTracker && typeof result === "string") {
|
|
101478
|
-
options.fileTracker.trackFilesFromOutput(result,
|
|
101611
|
+
options.fileTracker.trackFilesFromOutput(result, effectiveSearchCwd).catch(() => {
|
|
101479
101612
|
});
|
|
101480
101613
|
}
|
|
101481
101614
|
return result;
|
|
@@ -101528,7 +101661,7 @@ var init_vercel = __esm({
|
|
|
101528
101661
|
}
|
|
101529
101662
|
const fallbackResult = maybeAnnotate(await runRawSearch());
|
|
101530
101663
|
if (options.fileTracker && typeof fallbackResult === "string") {
|
|
101531
|
-
options.fileTracker.trackFilesFromOutput(fallbackResult,
|
|
101664
|
+
options.fileTracker.trackFilesFromOutput(fallbackResult, effectiveSearchCwd).catch(() => {
|
|
101532
101665
|
});
|
|
101533
101666
|
}
|
|
101534
101667
|
return fallbackResult;
|
|
@@ -101591,7 +101724,7 @@ var init_vercel = __esm({
|
|
|
101591
101724
|
try {
|
|
101592
101725
|
const fallbackResult2 = maybeAnnotate(await runRawSearch());
|
|
101593
101726
|
if (options.fileTracker && typeof fallbackResult2 === "string") {
|
|
101594
|
-
options.fileTracker.trackFilesFromOutput(fallbackResult2,
|
|
101727
|
+
options.fileTracker.trackFilesFromOutput(fallbackResult2, effectiveSearchCwd).catch(() => {
|
|
101595
101728
|
});
|
|
101596
101729
|
}
|
|
101597
101730
|
return fallbackResult2;
|
|
@@ -101645,9 +101778,9 @@ var init_vercel = __esm({
|
|
|
101645
101778
|
name: "extract",
|
|
101646
101779
|
description: extractDescription,
|
|
101647
101780
|
inputSchema: extractSchema,
|
|
101648
|
-
execute: async ({ targets, input_content, line, end_line, allow_tests, context_lines, format }) => {
|
|
101781
|
+
execute: async ({ targets, input_content, line, end_line, allow_tests, context_lines, format, workingDirectory }) => {
|
|
101649
101782
|
try {
|
|
101650
|
-
const effectiveCwd = options.cwd || ".";
|
|
101783
|
+
const effectiveCwd = workingDirectory || options.cwd || ".";
|
|
101651
101784
|
if (debug) {
|
|
101652
101785
|
if (targets) {
|
|
101653
101786
|
console.error(`Executing extract with targets: "${targets}", cwd: "${effectiveCwd}", context lines: ${context_lines || 10}`);
|