@probelabs/probe 0.6.0-rc169 → 0.6.0-rc170
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/build/agent/ProbeAgent.js +41 -14
- package/build/agent/imageConfig.js +57 -0
- package/build/agent/index.js +58 -25
- package/cjs/agent/ProbeAgent.cjs +124 -43
- package/cjs/index.cjs +124 -43
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +41 -14
- package/src/agent/imageConfig.js +57 -0
|
@@ -13,11 +13,11 @@ import { randomUUID } from 'crypto';
|
|
|
13
13
|
import { EventEmitter } from 'events';
|
|
14
14
|
import { existsSync } from 'fs';
|
|
15
15
|
import { readFile, stat } from 'fs/promises';
|
|
16
|
-
import { resolve, isAbsolute, dirname } from 'path';
|
|
16
|
+
import { resolve, isAbsolute, dirname, basename, normalize, sep } from 'path';
|
|
17
17
|
import { TokenCounter } from './tokenCounter.js';
|
|
18
18
|
import { InMemoryStorageAdapter } from './storage/InMemoryStorageAdapter.js';
|
|
19
19
|
import { HookManager, HOOK_TYPES } from './hooks/HookManager.js';
|
|
20
|
-
import { SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES } from './imageConfig.js';
|
|
20
|
+
import { SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES, isFormatSupportedByProvider } from './imageConfig.js';
|
|
21
21
|
import {
|
|
22
22
|
createTools,
|
|
23
23
|
searchToolDefinition,
|
|
@@ -475,6 +475,21 @@ export class ProbeAgent {
|
|
|
475
475
|
throw new Error('Image path is required');
|
|
476
476
|
}
|
|
477
477
|
|
|
478
|
+
// Validate extension before attempting to load
|
|
479
|
+
// Use basename to prevent path traversal attacks (e.g., 'malicious.jpg/../../../etc/passwd')
|
|
480
|
+
const filename = basename(imagePath);
|
|
481
|
+
const extension = filename.toLowerCase().split('.').pop();
|
|
482
|
+
|
|
483
|
+
// Always validate extension is in allowed list (defense-in-depth)
|
|
484
|
+
if (!extension || !SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
|
|
485
|
+
throw new Error(`Invalid or unsupported image extension: ${extension}. Supported formats: ${SUPPORTED_IMAGE_EXTENSIONS.join(', ')}`);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Check provider-specific format restrictions (e.g., SVG not supported by Google Gemini)
|
|
489
|
+
if (this.apiType && !isFormatSupportedByProvider(extension, this.apiType)) {
|
|
490
|
+
throw new Error(`Image format '${extension}' is not supported by the current AI provider (${this.apiType}). Try using a different image format like PNG or JPEG.`);
|
|
491
|
+
}
|
|
492
|
+
|
|
478
493
|
// Load the image using the existing loadImageIfValid method
|
|
479
494
|
const loaded = await this.loadImageIfValid(imagePath);
|
|
480
495
|
|
|
@@ -1262,20 +1277,28 @@ export class ProbeAgent {
|
|
|
1262
1277
|
}
|
|
1263
1278
|
|
|
1264
1279
|
// Security validation: check if path is within any allowed directory
|
|
1280
|
+
// Use normalize() after resolve() to handle path traversal attempts (e.g., '/allowed/../etc/passwd')
|
|
1265
1281
|
const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
|
|
1266
|
-
|
|
1282
|
+
|
|
1267
1283
|
let absolutePath;
|
|
1268
1284
|
let isPathAllowed = false;
|
|
1269
|
-
|
|
1285
|
+
|
|
1270
1286
|
// If absolute path, check if it's within any allowed directory
|
|
1271
1287
|
if (isAbsolute(imagePath)) {
|
|
1272
|
-
|
|
1273
|
-
|
|
1288
|
+
// Normalize to resolve any '..' sequences
|
|
1289
|
+
absolutePath = normalize(resolve(imagePath));
|
|
1290
|
+
isPathAllowed = allowedDirs.some(dir => {
|
|
1291
|
+
const normalizedDir = normalize(resolve(dir));
|
|
1292
|
+
// Ensure the path is within the allowed directory (add separator to prevent prefix attacks)
|
|
1293
|
+
return absolutePath === normalizedDir || absolutePath.startsWith(normalizedDir + sep);
|
|
1294
|
+
});
|
|
1274
1295
|
} else {
|
|
1275
1296
|
// For relative paths, try resolving against each allowed directory
|
|
1276
1297
|
for (const dir of allowedDirs) {
|
|
1277
|
-
const
|
|
1278
|
-
|
|
1298
|
+
const normalizedDir = normalize(resolve(dir));
|
|
1299
|
+
const resolvedPath = normalize(resolve(dir, imagePath));
|
|
1300
|
+
// Ensure the resolved path is within the allowed directory
|
|
1301
|
+
if (resolvedPath === normalizedDir || resolvedPath.startsWith(normalizedDir + sep)) {
|
|
1279
1302
|
absolutePath = resolvedPath;
|
|
1280
1303
|
isPathAllowed = true;
|
|
1281
1304
|
break;
|
|
@@ -1319,6 +1342,10 @@ export class ProbeAgent {
|
|
|
1319
1342
|
return false;
|
|
1320
1343
|
}
|
|
1321
1344
|
|
|
1345
|
+
// Note: Provider-specific format validation (e.g., SVG not supported by Google Gemini)
|
|
1346
|
+
// is handled by the readImage tool which provides explicit error messages.
|
|
1347
|
+
// loadImageIfValid is a lower-level method that only checks general format support.
|
|
1348
|
+
|
|
1322
1349
|
// Determine MIME type (from shared config)
|
|
1323
1350
|
const mimeType = IMAGE_MIME_TYPES[extension];
|
|
1324
1351
|
|
|
@@ -2504,7 +2531,7 @@ When troubleshooting:
|
|
|
2504
2531
|
maxIterations,
|
|
2505
2532
|
parentSessionId: this.sessionId, // Pass parent session ID for tracking
|
|
2506
2533
|
path: this.searchPath, // Inherit search path
|
|
2507
|
-
provider: this.
|
|
2534
|
+
provider: this.apiType, // Inherit AI provider (string identifier)
|
|
2508
2535
|
model: this.model, // Inherit model
|
|
2509
2536
|
debug: this.debug,
|
|
2510
2537
|
tracer: this.tracer
|
|
@@ -2513,7 +2540,7 @@ When troubleshooting:
|
|
|
2513
2540
|
if (this.debug) {
|
|
2514
2541
|
console.log(`[DEBUG] Executing delegate tool at iteration ${currentIteration}/${maxIterations}`);
|
|
2515
2542
|
console.log(`[DEBUG] Parent session: ${this.sessionId}`);
|
|
2516
|
-
console.log(`[DEBUG] Inherited config: path=${this.searchPath}, provider=${this.
|
|
2543
|
+
console.log(`[DEBUG] Inherited config: path=${this.searchPath}, provider=${this.apiType}, model=${this.model}`);
|
|
2517
2544
|
console.log(`[DEBUG] Delegate task: ${toolParams.task?.substring(0, 100)}...`);
|
|
2518
2545
|
}
|
|
2519
2546
|
|
|
@@ -2597,10 +2624,10 @@ When troubleshooting:
|
|
|
2597
2624
|
content: toolResultMessage
|
|
2598
2625
|
});
|
|
2599
2626
|
|
|
2600
|
-
//
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2627
|
+
// NOTE: Automatic image processing removed (GitHub issue #305)
|
|
2628
|
+
// Images are now only loaded when the AI explicitly calls the readImage tool
|
|
2629
|
+
// This prevents: 1) implicit behavior that users don't expect
|
|
2630
|
+
// 2) crashes with unsupported MIME types (e.g., SVG on Gemini)
|
|
2604
2631
|
|
|
2605
2632
|
if (this.debug) {
|
|
2606
2633
|
console.log(`[DEBUG] Tool ${toolName} executed successfully. Result length: ${typeof toolResult === 'string' ? toolResult.length : JSON.stringify(toolResult).length}`);
|
|
@@ -21,6 +21,12 @@ export const IMAGE_MIME_TYPES = {
|
|
|
21
21
|
'svg': 'image/svg+xml'
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
+
// Provider-specific unsupported image formats
|
|
25
|
+
// These providers do not support certain MIME types and will crash if they receive them
|
|
26
|
+
export const PROVIDER_UNSUPPORTED_FORMATS = {
|
|
27
|
+
'google': ['svg'], // Google Gemini doesn't support image/svg+xml
|
|
28
|
+
};
|
|
29
|
+
|
|
24
30
|
/**
|
|
25
31
|
* Generate a regex pattern string for matching image file extensions
|
|
26
32
|
* @param {string[]} extensions - Array of extensions (without dots)
|
|
@@ -38,3 +44,54 @@ export function getExtensionPattern(extensions = SUPPORTED_IMAGE_EXTENSIONS) {
|
|
|
38
44
|
export function getMimeType(extension) {
|
|
39
45
|
return IMAGE_MIME_TYPES[extension.toLowerCase()];
|
|
40
46
|
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Check if an image extension is supported by a specific provider
|
|
50
|
+
* @param {string} extension - File extension (without dot)
|
|
51
|
+
* @param {string} provider - Provider name (e.g., 'google', 'anthropic', 'openai')
|
|
52
|
+
* @returns {boolean} True if the format is supported by the provider
|
|
53
|
+
*/
|
|
54
|
+
export function isFormatSupportedByProvider(extension, provider) {
|
|
55
|
+
// Validate extension parameter - must be a non-empty string without path separators
|
|
56
|
+
if (!extension || typeof extension !== 'string') {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
// Sanitize: reject extensions containing path traversal characters
|
|
60
|
+
if (extension.includes('/') || extension.includes('\\') || extension.includes('..')) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const ext = extension.toLowerCase();
|
|
65
|
+
|
|
66
|
+
// First check if it's a generally supported format
|
|
67
|
+
if (!SUPPORTED_IMAGE_EXTENSIONS.includes(ext)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Handle null/undefined provider gracefully (treat as no restrictions)
|
|
72
|
+
if (!provider || typeof provider !== 'string') {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Check provider-specific restrictions
|
|
77
|
+
const unsupportedFormats = PROVIDER_UNSUPPORTED_FORMATS[provider];
|
|
78
|
+
if (unsupportedFormats && unsupportedFormats.includes(ext)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get supported image extensions for a specific provider
|
|
87
|
+
* @param {string} provider - Provider name (e.g., 'google', 'anthropic', 'openai')
|
|
88
|
+
* @returns {string[]} Array of supported extensions for this provider
|
|
89
|
+
*/
|
|
90
|
+
export function getSupportedExtensionsForProvider(provider) {
|
|
91
|
+
// Handle null/undefined/non-string provider gracefully (return all extensions)
|
|
92
|
+
if (!provider || typeof provider !== 'string') {
|
|
93
|
+
return [...SUPPORTED_IMAGE_EXTENSIONS];
|
|
94
|
+
}
|
|
95
|
+
const unsupportedFormats = PROVIDER_UNSUPPORTED_FORMATS[provider] || [];
|
|
96
|
+
return SUPPORTED_IMAGE_EXTENSIONS.filter(ext => !unsupportedFormats.includes(ext));
|
|
97
|
+
}
|
package/build/agent/index.js
CHANGED
|
@@ -1998,7 +1998,27 @@ var init_HookManager = __esm({
|
|
|
1998
1998
|
});
|
|
1999
1999
|
|
|
2000
2000
|
// src/agent/imageConfig.js
|
|
2001
|
-
|
|
2001
|
+
function isFormatSupportedByProvider(extension, provider) {
|
|
2002
|
+
if (!extension || typeof extension !== "string") {
|
|
2003
|
+
return false;
|
|
2004
|
+
}
|
|
2005
|
+
if (extension.includes("/") || extension.includes("\\") || extension.includes("..")) {
|
|
2006
|
+
return false;
|
|
2007
|
+
}
|
|
2008
|
+
const ext2 = extension.toLowerCase();
|
|
2009
|
+
if (!SUPPORTED_IMAGE_EXTENSIONS.includes(ext2)) {
|
|
2010
|
+
return false;
|
|
2011
|
+
}
|
|
2012
|
+
if (!provider || typeof provider !== "string") {
|
|
2013
|
+
return true;
|
|
2014
|
+
}
|
|
2015
|
+
const unsupportedFormats = PROVIDER_UNSUPPORTED_FORMATS[provider];
|
|
2016
|
+
if (unsupportedFormats && unsupportedFormats.includes(ext2)) {
|
|
2017
|
+
return false;
|
|
2018
|
+
}
|
|
2019
|
+
return true;
|
|
2020
|
+
}
|
|
2021
|
+
var SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES, PROVIDER_UNSUPPORTED_FORMATS;
|
|
2002
2022
|
var init_imageConfig = __esm({
|
|
2003
2023
|
"src/agent/imageConfig.js"() {
|
|
2004
2024
|
"use strict";
|
|
@@ -2011,6 +2031,10 @@ var init_imageConfig = __esm({
|
|
|
2011
2031
|
"bmp": "image/bmp",
|
|
2012
2032
|
"svg": "image/svg+xml"
|
|
2013
2033
|
};
|
|
2034
|
+
PROVIDER_UNSUPPORTED_FORMATS = {
|
|
2035
|
+
"google": ["svg"]
|
|
2036
|
+
// Google Gemini doesn't support image/svg+xml
|
|
2037
|
+
};
|
|
2014
2038
|
}
|
|
2015
2039
|
});
|
|
2016
2040
|
|
|
@@ -15373,7 +15397,7 @@ var init_esm4 = __esm({
|
|
|
15373
15397
|
*
|
|
15374
15398
|
* @internal
|
|
15375
15399
|
*/
|
|
15376
|
-
constructor(cwd = process.cwd(), pathImpl,
|
|
15400
|
+
constructor(cwd = process.cwd(), pathImpl, sep4, { nocase, childrenCacheSize = 16 * 1024, fs: fs8 = defaultFS } = {}) {
|
|
15377
15401
|
this.#fs = fsFromOption(fs8);
|
|
15378
15402
|
if (cwd instanceof URL || cwd.startsWith("file://")) {
|
|
15379
15403
|
cwd = fileURLToPath4(cwd);
|
|
@@ -15384,7 +15408,7 @@ var init_esm4 = __esm({
|
|
|
15384
15408
|
this.#resolveCache = new ResolveCache();
|
|
15385
15409
|
this.#resolvePosixCache = new ResolveCache();
|
|
15386
15410
|
this.#children = new ChildrenCache(childrenCacheSize);
|
|
15387
|
-
const split = cwdPath.substring(this.rootPath.length).split(
|
|
15411
|
+
const split = cwdPath.substring(this.rootPath.length).split(sep4);
|
|
15388
15412
|
if (split.length === 1 && !split[0]) {
|
|
15389
15413
|
split.pop();
|
|
15390
15414
|
}
|
|
@@ -36300,7 +36324,7 @@ var init_graph_builder = __esm({
|
|
|
36300
36324
|
applyLinkStyles() {
|
|
36301
36325
|
if (!this.pendingLinkStyles.length || !this.edges.length)
|
|
36302
36326
|
return;
|
|
36303
|
-
const
|
|
36327
|
+
const normalize3 = (s) => {
|
|
36304
36328
|
const out = {};
|
|
36305
36329
|
for (const [kRaw, vRaw] of Object.entries(s)) {
|
|
36306
36330
|
const k = kRaw.trim().toLowerCase();
|
|
@@ -36321,7 +36345,7 @@ var init_graph_builder = __esm({
|
|
|
36321
36345
|
return out;
|
|
36322
36346
|
};
|
|
36323
36347
|
for (const cmd of this.pendingLinkStyles) {
|
|
36324
|
-
const style =
|
|
36348
|
+
const style = normalize3(cmd.props);
|
|
36325
36349
|
for (const idx of cmd.indices) {
|
|
36326
36350
|
if (idx >= 0 && idx < this.edges.length) {
|
|
36327
36351
|
const e = this.edges[idx];
|
|
@@ -43413,7 +43437,7 @@ var require_bk = __commonJS({
|
|
|
43413
43437
|
return xs;
|
|
43414
43438
|
}
|
|
43415
43439
|
function buildBlockGraph(g, layering, root2, reverseSep) {
|
|
43416
|
-
var blockGraph = new Graph(), graphLabel = g.graph(), sepFn =
|
|
43440
|
+
var blockGraph = new Graph(), graphLabel = g.graph(), sepFn = sep4(graphLabel.nodesep, graphLabel.edgesep, reverseSep);
|
|
43417
43441
|
_.forEach(layering, function(layer) {
|
|
43418
43442
|
var u;
|
|
43419
43443
|
_.forEach(layer, function(v) {
|
|
@@ -43503,7 +43527,7 @@ var require_bk = __commonJS({
|
|
|
43503
43527
|
alignCoordinates(xss, smallestWidth);
|
|
43504
43528
|
return balance(xss, g.graph().align);
|
|
43505
43529
|
}
|
|
43506
|
-
function
|
|
43530
|
+
function sep4(nodeSep, edgeSep, reverseSep) {
|
|
43507
43531
|
return function(g, v, w) {
|
|
43508
43532
|
var vLabel = g.node(v);
|
|
43509
43533
|
var wLabel = g.node(w);
|
|
@@ -43588,7 +43612,7 @@ var require_layout = __commonJS({
|
|
|
43588
43612
|
"use strict";
|
|
43589
43613
|
var _ = require_lodash2();
|
|
43590
43614
|
var acyclic = require_acyclic();
|
|
43591
|
-
var
|
|
43615
|
+
var normalize3 = require_normalize();
|
|
43592
43616
|
var rank = require_rank();
|
|
43593
43617
|
var normalizeRanks = require_util().normalizeRanks;
|
|
43594
43618
|
var parentDummyChains = require_parent_dummy_chains();
|
|
@@ -43650,7 +43674,7 @@ var require_layout = __commonJS({
|
|
|
43650
43674
|
removeEdgeLabelProxies(g);
|
|
43651
43675
|
});
|
|
43652
43676
|
time(" normalize.run", function() {
|
|
43653
|
-
|
|
43677
|
+
normalize3.run(g);
|
|
43654
43678
|
});
|
|
43655
43679
|
time(" parentDummyChains", function() {
|
|
43656
43680
|
parentDummyChains(g);
|
|
@@ -43677,7 +43701,7 @@ var require_layout = __commonJS({
|
|
|
43677
43701
|
removeBorderNodes(g);
|
|
43678
43702
|
});
|
|
43679
43703
|
time(" normalize.undo", function() {
|
|
43680
|
-
|
|
43704
|
+
normalize3.undo(g);
|
|
43681
43705
|
});
|
|
43682
43706
|
time(" fixupEdgeLabelCoords", function() {
|
|
43683
43707
|
fixupEdgeLabelCoords(g);
|
|
@@ -50048,8 +50072,8 @@ var require_resolve = __commonJS({
|
|
|
50048
50072
|
}
|
|
50049
50073
|
return count;
|
|
50050
50074
|
}
|
|
50051
|
-
function getFullPath(resolver, id = "",
|
|
50052
|
-
if (
|
|
50075
|
+
function getFullPath(resolver, id = "", normalize3) {
|
|
50076
|
+
if (normalize3 !== false)
|
|
50053
50077
|
id = normalizeId(id);
|
|
50054
50078
|
const p = resolver.parse(id);
|
|
50055
50079
|
return _getFullPath(resolver, p);
|
|
@@ -51389,7 +51413,7 @@ var require_fast_uri = __commonJS({
|
|
|
51389
51413
|
"use strict";
|
|
51390
51414
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils();
|
|
51391
51415
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
51392
|
-
function
|
|
51416
|
+
function normalize3(uri, options) {
|
|
51393
51417
|
if (typeof uri === "string") {
|
|
51394
51418
|
uri = /** @type {T} */
|
|
51395
51419
|
serialize(parse6(uri, options), options);
|
|
@@ -51625,7 +51649,7 @@ var require_fast_uri = __commonJS({
|
|
|
51625
51649
|
}
|
|
51626
51650
|
var fastUri = {
|
|
51627
51651
|
SCHEMES,
|
|
51628
|
-
normalize:
|
|
51652
|
+
normalize: normalize3,
|
|
51629
51653
|
resolve: resolve6,
|
|
51630
51654
|
resolveComponent,
|
|
51631
51655
|
equal,
|
|
@@ -58993,7 +59017,7 @@ import { randomUUID as randomUUID5 } from "crypto";
|
|
|
58993
59017
|
import { EventEmitter as EventEmitter5 } from "events";
|
|
58994
59018
|
import { existsSync as existsSync5 } from "fs";
|
|
58995
59019
|
import { readFile, stat } from "fs/promises";
|
|
58996
|
-
import { resolve as resolve4, isAbsolute as isAbsolute2, dirname as dirname4 } from "path";
|
|
59020
|
+
import { resolve as resolve4, isAbsolute as isAbsolute2, dirname as dirname4, basename, normalize as normalize2, sep as sep3 } from "path";
|
|
58997
59021
|
var MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
58998
59022
|
var init_ProbeAgent = __esm({
|
|
58999
59023
|
"src/agent/ProbeAgent.js"() {
|
|
@@ -59319,6 +59343,14 @@ var init_ProbeAgent = __esm({
|
|
|
59319
59343
|
if (!imagePath) {
|
|
59320
59344
|
throw new Error("Image path is required");
|
|
59321
59345
|
}
|
|
59346
|
+
const filename = basename(imagePath);
|
|
59347
|
+
const extension = filename.toLowerCase().split(".").pop();
|
|
59348
|
+
if (!extension || !SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
|
|
59349
|
+
throw new Error(`Invalid or unsupported image extension: ${extension}. Supported formats: ${SUPPORTED_IMAGE_EXTENSIONS.join(", ")}`);
|
|
59350
|
+
}
|
|
59351
|
+
if (this.apiType && !isFormatSupportedByProvider(extension, this.apiType)) {
|
|
59352
|
+
throw new Error(`Image format '${extension}' is not supported by the current AI provider (${this.apiType}). Try using a different image format like PNG or JPEG.`);
|
|
59353
|
+
}
|
|
59322
59354
|
const loaded = await this.loadImageIfValid(imagePath);
|
|
59323
59355
|
if (!loaded) {
|
|
59324
59356
|
throw new Error(`Failed to load image: ${imagePath}. The file may not exist, be too large, have an unsupported format, or be outside allowed directories.`);
|
|
@@ -59937,12 +59969,16 @@ var init_ProbeAgent = __esm({
|
|
|
59937
59969
|
let absolutePath;
|
|
59938
59970
|
let isPathAllowed2 = false;
|
|
59939
59971
|
if (isAbsolute2(imagePath)) {
|
|
59940
|
-
absolutePath = imagePath;
|
|
59941
|
-
isPathAllowed2 = allowedDirs.some((dir) =>
|
|
59972
|
+
absolutePath = normalize2(resolve4(imagePath));
|
|
59973
|
+
isPathAllowed2 = allowedDirs.some((dir) => {
|
|
59974
|
+
const normalizedDir = normalize2(resolve4(dir));
|
|
59975
|
+
return absolutePath === normalizedDir || absolutePath.startsWith(normalizedDir + sep3);
|
|
59976
|
+
});
|
|
59942
59977
|
} else {
|
|
59943
59978
|
for (const dir of allowedDirs) {
|
|
59944
|
-
const
|
|
59945
|
-
|
|
59979
|
+
const normalizedDir = normalize2(resolve4(dir));
|
|
59980
|
+
const resolvedPath = normalize2(resolve4(dir, imagePath));
|
|
59981
|
+
if (resolvedPath === normalizedDir || resolvedPath.startsWith(normalizedDir + sep3)) {
|
|
59946
59982
|
absolutePath = resolvedPath;
|
|
59947
59983
|
isPathAllowed2 = true;
|
|
59948
59984
|
break;
|
|
@@ -60950,8 +60986,8 @@ ${toolResultContent}
|
|
|
60950
60986
|
// Pass parent session ID for tracking
|
|
60951
60987
|
path: this.searchPath,
|
|
60952
60988
|
// Inherit search path
|
|
60953
|
-
provider: this.
|
|
60954
|
-
// Inherit AI provider
|
|
60989
|
+
provider: this.apiType,
|
|
60990
|
+
// Inherit AI provider (string identifier)
|
|
60955
60991
|
model: this.model,
|
|
60956
60992
|
// Inherit model
|
|
60957
60993
|
debug: this.debug,
|
|
@@ -60960,7 +60996,7 @@ ${toolResultContent}
|
|
|
60960
60996
|
if (this.debug) {
|
|
60961
60997
|
console.log(`[DEBUG] Executing delegate tool at iteration ${currentIteration}/${maxIterations}`);
|
|
60962
60998
|
console.log(`[DEBUG] Parent session: ${this.sessionId}`);
|
|
60963
|
-
console.log(`[DEBUG] Inherited config: path=${this.searchPath}, provider=${this.
|
|
60999
|
+
console.log(`[DEBUG] Inherited config: path=${this.searchPath}, provider=${this.apiType}, model=${this.model}`);
|
|
60964
61000
|
console.log(`[DEBUG] Delegate task: ${toolParams.task?.substring(0, 100)}...`);
|
|
60965
61001
|
}
|
|
60966
61002
|
if (this.tracer) {
|
|
@@ -61027,9 +61063,6 @@ ${toolResultContent}
|
|
|
61027
61063
|
role: "user",
|
|
61028
61064
|
content: toolResultMessage
|
|
61029
61065
|
});
|
|
61030
|
-
if (toolResultContent) {
|
|
61031
|
-
await this.processImageReferences(toolResultContent);
|
|
61032
|
-
}
|
|
61033
61066
|
if (this.debug) {
|
|
61034
61067
|
console.log(`[DEBUG] Tool ${toolName} executed successfully. Result length: ${typeof toolResult === "string" ? toolResult.length : JSON.stringify(toolResult).length}`);
|
|
61035
61068
|
}
|