@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@probelabs/probe-chat",
3
- "version": "0.6.0-rc114",
3
+ "version": "0.6.0-rc116",
4
4
  "description": "CLI and web interface for Probe code search (formerly @probelabs/probe-web and @probelabs/probe-chat)",
5
5
  "main": "index.js",
6
6
  "type": "module",
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(`[DEBUG] probeTool: Executing ${toolName} for session ${toolSessionId}`);
101
- console.log(`[DEBUG] probeTool: Received params:`, params);
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 the results
366
- const result = files.map(file => {
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
- type: isDirectory ? 'directory' : 'file',
371
- path: path.join(targetDirectory, file.name)
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 ${result.length} files/directories in ${targetDir}`);
433
+ console.log(`[DEBUG] Found ${entries.length} files/directories in ${targetDir}`);
377
434
  }
378
435
 
379
- return {
380
- success: true,
381
- directory: targetDir,
382
- files: result,
383
- timestamp: new Date().toISOString()
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.