@probelabs/probe-chat 0.6.0-rc114 → 0.6.0-rc116
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/package.json +1 -1
- package/probeChat.js +46 -0
- package/probeTool.js +89 -25
package/package.json
CHANGED
package/probeChat.js
CHANGED
|
@@ -275,9 +275,55 @@ export class ProbeChat {
|
|
|
275
275
|
|
|
276
276
|
if (this.debug) {
|
|
277
277
|
console.log(`[DEBUG] ProbeChat initialized with MCP ${agentOptions.enableMcp ? 'enabled' : 'disabled'}`);
|
|
278
|
+
|
|
279
|
+
// Log available tools after a short delay to allow MCP initialization
|
|
280
|
+
setTimeout(() => {
|
|
281
|
+
this.logAvailableTools();
|
|
282
|
+
}, 100);
|
|
278
283
|
}
|
|
279
284
|
}
|
|
280
285
|
|
|
286
|
+
/**
|
|
287
|
+
* Log all available tools (native + MCP) in debug mode
|
|
288
|
+
*/
|
|
289
|
+
logAvailableTools() {
|
|
290
|
+
if (!this.debug) return;
|
|
291
|
+
|
|
292
|
+
console.log('\n[DEBUG] ========================================');
|
|
293
|
+
console.log('[DEBUG] All Available Tools:');
|
|
294
|
+
console.log('[DEBUG] ========================================');
|
|
295
|
+
|
|
296
|
+
// Get native tools from agent
|
|
297
|
+
if (this.agent.toolImplementations) {
|
|
298
|
+
console.log('[DEBUG] Native Tools:');
|
|
299
|
+
const nativeTools = Object.keys(this.agent.toolImplementations);
|
|
300
|
+
nativeTools.forEach(toolName => {
|
|
301
|
+
const tool = this.agent.toolImplementations[toolName];
|
|
302
|
+
const desc = tool.description || 'No description';
|
|
303
|
+
console.log(`[DEBUG] - ${toolName}: ${desc}`);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Get MCP tools if available
|
|
308
|
+
if (this.agent.mcpBridge && this.agent.mcpBridge.mcpTools) {
|
|
309
|
+
const mcpTools = Object.keys(this.agent.mcpBridge.mcpTools);
|
|
310
|
+
if (mcpTools.length > 0) {
|
|
311
|
+
console.log('[DEBUG] MCP Tools:');
|
|
312
|
+
mcpTools.forEach(toolName => {
|
|
313
|
+
const tool = this.agent.mcpBridge.mcpTools[toolName];
|
|
314
|
+
const desc = tool.description || 'No description';
|
|
315
|
+
console.log(`[DEBUG] - ${toolName}: ${desc}`);
|
|
316
|
+
});
|
|
317
|
+
} else {
|
|
318
|
+
console.log('[DEBUG] MCP Tools: None loaded');
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
console.log('[DEBUG] MCP Tools: MCP not enabled or not initialized');
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
console.log('[DEBUG] ========================================\n');
|
|
325
|
+
}
|
|
326
|
+
|
|
281
327
|
/**
|
|
282
328
|
* Answer a question using the agentic flow with optional image support
|
|
283
329
|
* @param {string} message - The user's question
|
package/probeTool.js
CHANGED
|
@@ -81,6 +81,27 @@ const configOptions = {
|
|
|
81
81
|
debug: process.env.DEBUG_CHAT === '1'
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
// Helper function to truncate long argument values for logging
|
|
85
|
+
function truncateArgValue(value, maxLength = 200) {
|
|
86
|
+
if (typeof value !== 'string') {
|
|
87
|
+
value = JSON.stringify(value);
|
|
88
|
+
}
|
|
89
|
+
if (value.length <= maxLength * 2) {
|
|
90
|
+
return value;
|
|
91
|
+
}
|
|
92
|
+
// Show first 200 and last 200 characters
|
|
93
|
+
return `${value.substring(0, maxLength)}...${value.substring(value.length - maxLength)}`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Helper function to format tool arguments for debug logging
|
|
97
|
+
function formatToolArgs(args) {
|
|
98
|
+
const formatted = {};
|
|
99
|
+
for (const [key, value] of Object.entries(args)) {
|
|
100
|
+
formatted[key] = truncateArgValue(value);
|
|
101
|
+
}
|
|
102
|
+
return formatted;
|
|
103
|
+
}
|
|
104
|
+
|
|
84
105
|
// Create the base tools using the imported generators
|
|
85
106
|
const baseSearchTool = searchTool(configOptions);
|
|
86
107
|
const baseQueryTool = queryTool(configOptions);
|
|
@@ -97,8 +118,15 @@ const wrapToolWithEmitter = (tool, toolName, baseExecute) => {
|
|
|
97
118
|
const toolSessionId = params.sessionId || defaultSessionId; // Fallback, but should always have sessionId
|
|
98
119
|
|
|
99
120
|
if (debug) {
|
|
100
|
-
console.log(
|
|
101
|
-
console.log(`[DEBUG]
|
|
121
|
+
console.log(`\n[DEBUG] ========================================`);
|
|
122
|
+
console.log(`[DEBUG] Tool Call: ${toolName}`);
|
|
123
|
+
console.log(`[DEBUG] Session: ${toolSessionId}`);
|
|
124
|
+
console.log(`[DEBUG] Arguments:`);
|
|
125
|
+
const formattedArgs = formatToolArgs(params);
|
|
126
|
+
for (const [key, value] of Object.entries(formattedArgs)) {
|
|
127
|
+
console.log(`[DEBUG] ${key}: ${value}`);
|
|
128
|
+
}
|
|
129
|
+
console.log(`[DEBUG] ========================================\n`);
|
|
102
130
|
}
|
|
103
131
|
|
|
104
132
|
// Register this tool execution (and reset cancel flag if needed)
|
|
@@ -345,12 +373,7 @@ const baseListFilesTool = {
|
|
|
345
373
|
if (debug) {
|
|
346
374
|
console.log(`[DEBUG] ${error}`);
|
|
347
375
|
}
|
|
348
|
-
return {
|
|
349
|
-
success: false,
|
|
350
|
-
directory: targetDir,
|
|
351
|
-
error: error,
|
|
352
|
-
timestamp: new Date().toISOString()
|
|
353
|
-
};
|
|
376
|
+
return `Error: ${error}`;
|
|
354
377
|
}
|
|
355
378
|
}
|
|
356
379
|
|
|
@@ -362,34 +385,62 @@ const baseListFilesTool = {
|
|
|
362
385
|
// Read the directory contents
|
|
363
386
|
const files = await fs.promises.readdir(targetDir, { withFileTypes: true });
|
|
364
387
|
|
|
365
|
-
// Format
|
|
366
|
-
const
|
|
388
|
+
// Format size for human readability
|
|
389
|
+
const formatSize = (size) => {
|
|
390
|
+
if (size < 1024) return `${size}B`;
|
|
391
|
+
if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}K`;
|
|
392
|
+
if (size < 1024 * 1024 * 1024) return `${(size / (1024 * 1024)).toFixed(1)}M`;
|
|
393
|
+
return `${(size / (1024 * 1024 * 1024)).toFixed(1)}G`;
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
// Format the results as ls-style output
|
|
397
|
+
const entries = await Promise.all(files.map(async (file) => {
|
|
367
398
|
const isDirectory = file.isDirectory();
|
|
399
|
+
const fullPath = path.join(targetDir, file.name);
|
|
400
|
+
|
|
401
|
+
let size = 0;
|
|
402
|
+
try {
|
|
403
|
+
const stats = await fs.promises.stat(fullPath);
|
|
404
|
+
size = stats.size;
|
|
405
|
+
} catch (statError) {
|
|
406
|
+
if (debug) {
|
|
407
|
+
console.log(`[DEBUG] Could not stat file ${file.name}:`, statError.message);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
368
411
|
return {
|
|
369
412
|
name: file.name,
|
|
370
|
-
|
|
371
|
-
|
|
413
|
+
isDirectory,
|
|
414
|
+
size
|
|
372
415
|
};
|
|
416
|
+
}));
|
|
417
|
+
|
|
418
|
+
// Sort: directories first, then files, both alphabetically
|
|
419
|
+
entries.sort((a, b) => {
|
|
420
|
+
if (a.isDirectory && !b.isDirectory) return -1;
|
|
421
|
+
if (!a.isDirectory && b.isDirectory) return 1;
|
|
422
|
+
return a.name.localeCompare(b.name);
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// Format entries
|
|
426
|
+
const formatted = entries.map(entry => {
|
|
427
|
+
const type = entry.isDirectory ? 'dir ' : 'file';
|
|
428
|
+
const sizeStr = formatSize(entry.size).padStart(8);
|
|
429
|
+
return `${type} ${sizeStr} ${entry.name}`;
|
|
373
430
|
});
|
|
374
431
|
|
|
375
432
|
if (debug) {
|
|
376
|
-
console.log(`[DEBUG] Found ${
|
|
433
|
+
console.log(`[DEBUG] Found ${entries.length} files/directories in ${targetDir}`);
|
|
377
434
|
}
|
|
378
435
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
};
|
|
436
|
+
// Return as formatted text output
|
|
437
|
+
const header = `${targetDir}:\n`;
|
|
438
|
+
const output = header + formatted.join('\n');
|
|
439
|
+
|
|
440
|
+
return output;
|
|
385
441
|
} catch (error) {
|
|
386
442
|
console.error(`Error listing files in ${targetDir}:`, error);
|
|
387
|
-
return {
|
|
388
|
-
success: false,
|
|
389
|
-
directory: targetDir,
|
|
390
|
-
error: error.message || 'Unknown error listing files',
|
|
391
|
-
timestamp: new Date().toISOString()
|
|
392
|
-
};
|
|
443
|
+
return `Error: ${error.message || 'Unknown error listing files'}`;
|
|
393
444
|
}
|
|
394
445
|
}
|
|
395
446
|
};
|
|
@@ -640,6 +691,19 @@ export const implementToolInstance = wrapToolWithEmitter(baseImplementTool, 'imp
|
|
|
640
691
|
export const listFilesToolInstance = wrapToolWithEmitter(baseListFilesTool, 'listFiles', baseListFilesTool.execute);
|
|
641
692
|
export const searchFilesToolInstance = wrapToolWithEmitter(baseSearchFilesTool, 'searchFiles', baseSearchFilesTool.execute);
|
|
642
693
|
|
|
694
|
+
// Log available tools at startup in debug mode
|
|
695
|
+
if (process.env.DEBUG_CHAT === '1') {
|
|
696
|
+
console.log('\n[DEBUG] ========================================');
|
|
697
|
+
console.log('[DEBUG] Probe Tools Loaded:');
|
|
698
|
+
console.log('[DEBUG] - search: Search for code patterns');
|
|
699
|
+
console.log('[DEBUG] - query: Semantic code search');
|
|
700
|
+
console.log('[DEBUG] - extract: Extract code snippets');
|
|
701
|
+
console.log('[DEBUG] - implement: Generate code implementations');
|
|
702
|
+
console.log('[DEBUG] - listFiles: List directory contents');
|
|
703
|
+
console.log('[DEBUG] - searchFiles: Search files by pattern');
|
|
704
|
+
console.log('[DEBUG] ========================================\n');
|
|
705
|
+
}
|
|
706
|
+
|
|
643
707
|
// --- Backward Compatibility Layer (probeTool mapping to searchToolInstance) ---
|
|
644
708
|
// This might be less relevant if the AI is strictly using the new XML format,
|
|
645
709
|
// but keep it for potential direct API calls or older UI elements.
|