@probelabs/probe 0.6.0-rc147 → 0.6.0-rc149

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/extract.js CHANGED
@@ -48,7 +48,7 @@ export async function extract(options) {
48
48
  const hasContent = options.content !== undefined && options.content !== null;
49
49
 
50
50
  if (!hasFiles && !hasInputFile && !hasContent) {
51
- throw new Error('Either files array, inputFile, or content must be provided');
51
+ throw new Error('Extract requires one of: "files" (array of file paths), "inputFile" (path to input file), or "content" (string/buffer for stdin)');
52
52
  }
53
53
 
54
54
  // Get the binary path
package/build/index.js CHANGED
@@ -39,8 +39,6 @@ import { searchTool, queryTool, extractTool, delegateTool } from './tools/vercel
39
39
  import { bashTool } from './tools/bash.js';
40
40
  import { ProbeAgent } from './agent/ProbeAgent.js';
41
41
  import { SimpleTelemetry, SimpleAppTracer, initializeSimpleTelemetryFromOptions } from './agent/simpleTelemetry.js';
42
- import { TelemetryConfig, initializeTelemetryFromOptions } from './agent/telemetry.js';
43
- import { AppTracer } from './agent/appTracer.js';
44
42
  import { listFilesToolInstance, searchFilesToolInstance } from './agent/probeTool.js';
45
43
  import { StorageAdapter, InMemoryStorageAdapter } from './agent/storage/index.js';
46
44
  import { HookManager, HOOK_TYPES } from './agent/hooks/index.js';
@@ -64,14 +62,10 @@ export {
64
62
  // Export hooks
65
63
  HookManager,
66
64
  HOOK_TYPES,
67
- // Export simple telemetry classes (no OpenTelemetry dependencies)
65
+ // Export simple telemetry classes (lightweight, no heavy dependencies)
68
66
  SimpleTelemetry,
69
67
  SimpleAppTracer,
70
68
  initializeSimpleTelemetryFromOptions,
71
- // Export full OpenTelemetry telemetry classes
72
- TelemetryConfig,
73
- AppTracer,
74
- initializeTelemetryFromOptions,
75
69
  // Export tool generators directly
76
70
  searchTool,
77
71
  queryTool,
@@ -149,18 +149,18 @@ class ProbeServer {
149
149
  },
150
150
  {
151
151
  name: 'extract_code',
152
- description: "Extract code from files. Formats: file.js (whole file), file.js:42 (from line), file.js#functionName (symbol).",
152
+ description: "Extract code blocks from files using tree-sitter AST parsing. Each file path can include optional line numbers or symbol names to extract specific code blocks.",
153
153
  inputSchema: {
154
154
  type: 'object',
155
155
  properties: {
156
156
  path: {
157
157
  type: 'string',
158
- description: 'Absolute path to the project directory',
158
+ description: 'Absolute path to the project root directory (used as working directory for relative file paths)',
159
159
  },
160
160
  files: {
161
161
  type: 'array',
162
162
  items: { type: 'string' },
163
- description: 'Array of file paths with optional line/symbol: ["file.rs:10", "file.rs#func_name"]',
163
+ description: 'Array of file paths to extract from. Formats: "file.js" (entire file), "file.js:42" (code block at line 42), "file.js:10-20" (lines 10-20), "file.js#funcName" (specific symbol). Line numbers and symbols are part of the path string, not separate parameters. Paths can be absolute or relative to the project directory.',
164
164
  }
165
165
  },
166
166
  required: ['path', 'files'],
@@ -199,18 +199,18 @@ class ProbeServer {
199
199
  },
200
200
  {
201
201
  name: 'extract_code',
202
- description: "Extract code from files. Formats: file.js (whole file), file.js:42 (from line), file.js#functionName (symbol).",
202
+ description: "Extract code blocks from files using tree-sitter AST parsing. Each file path can include optional line numbers or symbol names to extract specific code blocks.",
203
203
  inputSchema: {
204
204
  type: 'object',
205
205
  properties: {
206
206
  path: {
207
207
  type: 'string',
208
- description: 'Absolute path to the project directory',
208
+ description: 'Absolute path to the project root directory (used as working directory for relative file paths)',
209
209
  },
210
210
  files: {
211
211
  type: 'array',
212
212
  items: { type: 'string' },
213
- description: 'Array of file paths with optional line/symbol: ["file.rs:10", "file.rs#func_name"]',
213
+ description: 'Array of file paths to extract from. Formats: "file.js" (entire file), "file.js:42" (code block at line 42), "file.js:10-20" (lines 10-20), "file.js#funcName" (specific symbol). Line numbers and symbols are part of the path string, not separate parameters. Paths can be absolute or relative to the project directory.',
214
214
  }
215
215
  },
216
216
  required: ['path', 'files'],
@@ -7,13 +7,8 @@ import { z } from 'zod';
7
7
 
8
8
  // Common schemas for tool parameters (used for internal execution after XML parsing)
9
9
  export const searchSchema = z.object({
10
- query: z.string().describe('Search query with Elasticsearch syntax. Use + for important terms.'),
11
- path: z.string().optional().default('.').describe('Path to search in. For dependencies use "go:github.com/owner/repo", "js:package_name", or "rust:cargo_name" etc.'),
12
- allow_tests: z.boolean().optional().default(false).describe('Allow test files in search results'),
13
- exact: z.boolean().optional().default(false).describe('Perform exact search without tokenization (case-insensitive)'),
14
- maxResults: z.number().optional().describe('Maximum number of results to return'),
15
- maxTokens: z.number().optional().default(10000).describe('Maximum number of tokens to return'),
16
- language: z.string().optional().describe('Limit search to files of a specific programming language')
10
+ query: z.string().describe('Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation.'),
11
+ path: z.string().optional().default('.').describe('Path to search in. For dependencies use "go:github.com/owner/repo", "js:package_name", or "rust:cargo_name" etc.')
17
12
  });
18
13
 
19
14
  export const querySchema = z.object({
@@ -24,13 +19,8 @@ export const querySchema = z.object({
24
19
  });
25
20
 
26
21
  export const extractSchema = z.object({
27
- targets: z.string().optional().describe('File paths or symbols to extract from. Can include line numbers, symbol names, or multiple space-separated targets'),
28
- input_content: z.string().optional().describe('Text content to extract file paths from'),
29
- line: z.number().optional().describe('Start line number to extract a specific code block'),
30
- end_line: z.number().optional().describe('End line number for extracting a range of lines'),
31
- allow_tests: z.boolean().optional().default(false).describe('Allow test files and test code blocks'),
32
- context_lines: z.number().optional().default(10).describe('Number of context lines to include'),
33
- format: z.string().optional().default('plain').describe('Output format (plain, markdown, json, xml, color, outline-xml, outline-diff)')
22
+ targets: z.string().optional().describe('File paths or symbols to extract from. Formats: "file.js" (whole file), "file.js:42" (line 42), "file.js:10-20" (lines 10-20), "file.js#funcName" (symbol). Multiple targets separated by spaces.'),
23
+ input_content: z.string().optional().describe('Text content to extract file paths from (alternative to targets)')
34
24
  });
35
25
 
36
26
  export const delegateSchema = z.object({
@@ -120,13 +110,8 @@ You need to focus on main keywords when constructing the query, and always use e
120
110
  - Once data is returned, it's cached and won't return on next runs (this is expected behavior)
121
111
 
122
112
  Parameters:
123
- - query: (required) Search query with Elasticsearch syntax. You can use + for important terms, and - for negation.
124
- - path: (required) Path to search in. All dependencies located in /dep folder, under language sub folders, like this: "/dep/go/github.com/owner/repo", "/dep/js/package_name", or "/dep/rust/cargo_name" etc. YOU SHOULD ALWAYS provide FULL PATH when searching dependencies, including depency name.
125
- - allow_tests: (optional, default: false) Allow test files in search results (true/false).
126
- - exact: (optional, default: false) Perform exact pricise search. Use it when you already know function or struct name, or some other code block, and want exact match.
127
- - maxResults: (optional) Maximum number of results to return (number).
128
- - maxTokens: (optional, default: 10000) Maximum number of tokens to return (number).
129
- - language: (optional) Limit search to files of a specific programming language (e.g., 'rust', 'js', 'python', 'go' etc.).
113
+ - query: (required) Search query with Elasticsearch syntax. Use quotes for exact matches ("functionName"), AND/OR for boolean logic, - for negation, + for important terms.
114
+ - path: (optional, default: '.') Path to search in. All dependencies located in /dep folder, under language sub folders, like this: "/dep/go/github.com/owner/repo", "/dep/js/package_name", or "/dep/rust/cargo_name" etc.
130
115
 
131
116
  **Workflow:** Always start with search, then use extract for detailed context when needed.
132
117
 
@@ -148,30 +133,24 @@ User: How to calculate the total amount in the payments module?
148
133
  <search>
149
134
  <query>calculate AND payment</query>
150
135
  <path>src/utils</path>
151
- <allow_tests>false</allow_tests>
152
136
  </search>
153
137
 
154
138
  User: How do the user authentication and authorization work?
155
139
  <search>
156
- <query>+user and (authentification OR authroization OR authz)</query>
140
+ <query>+user AND (authentication OR authorization OR authz)</query>
157
141
  <path>.</path>
158
- <allow_tests>true</allow_tests>
159
- <language>go</language>
160
142
  </search>
161
143
 
162
144
  User: Find all react imports in the project.
163
145
  <search>
164
- <query>import { react }</query>
146
+ <query>"import" AND "react"</query>
165
147
  <path>.</path>
166
- <exact>true</exact>
167
- <language>js</language>
168
148
  </search>
169
149
 
170
- User: Find how decompoud library works?
150
+ User: Find how decompound library works?
171
151
  <search>
172
- <query>import { react }</query>
152
+ <query>decompound</query>
173
153
  <path>/dep/rust/decompound</path>
174
- <language>rust</language>
175
154
  </search>
176
155
 
177
156
  </examples>
@@ -208,11 +187,9 @@ Full file extraction should be the LAST RESORT! Always prefer search.
208
187
  **Session Awareness:** Reuse context from previous tool calls. Don't re-extract the same symbols you already have.
209
188
 
210
189
  Parameters:
211
- - targets: (required) File paths or symbols to extract from. Can include line numbers, symbol names, or multiple space-separated targets (e.g., 'src/main.rs:10-20', 'src/utils.js#myFunction').
212
- For multiple extractions: 'session.rs#AuthService.login auth.rs:2-100 config.rs#DatabaseConfig'
213
- - line: (optional) Start line number to extract a specific code block. Use with end_line for ranges.
214
- - end_line: (optional) End line number for extracting a range of lines.
215
- - allow_tests: (optional, default: false) Allow test files and test code blocks (true/false).
190
+ - targets: (required) File paths or symbols to extract from. Formats: "file.js" (whole file), "file.js:42" (code block at line 42), "file.js:10-20" (lines 10-20), "file.js#funcName" (specific symbol). Multiple targets separated by spaces.
191
+ - input_content: (optional) Text content to extract file paths from (alternative to targets for processing diffs/logs).
192
+
216
193
  Usage Example:
217
194
 
218
195
  <examples>
@@ -239,9 +216,7 @@ User: Lets read the whole file
239
216
 
240
217
  User: Read the first 10 lines of the file
241
218
  <extract>
242
- <targets>src/search/ranking.rs</targets>
243
- <line>1</line>
244
- <end_line>10</end_line>
219
+ <targets>src/search/ranking.rs:1-10</targets>
245
220
  </extract>
246
221
 
247
222
  User: Read file inside the dependency
@@ -349,7 +324,7 @@ export const bashDescription = 'Execute bash commands for system exploration and
349
324
  // Valid tool names that should be parsed as tool calls
350
325
  const DEFAULT_VALID_TOOLS = [
351
326
  'search',
352
- 'query',
327
+ 'query',
353
328
  'extract',
354
329
  'delegate',
355
330
  'listFiles',
@@ -358,6 +333,43 @@ const DEFAULT_VALID_TOOLS = [
358
333
  'attempt_completion'
359
334
  ];
360
335
 
336
+ /**
337
+ * Get valid parameter names for a specific tool from its schema
338
+ * @param {string} toolName - Name of the tool
339
+ * @returns {string[]} - Array of valid parameter names for this tool
340
+ */
341
+ function getValidParamsForTool(toolName) {
342
+ // Map tool names to their schemas
343
+ const schemaMap = {
344
+ search: searchSchema,
345
+ query: querySchema,
346
+ extract: extractSchema,
347
+ delegate: delegateSchema,
348
+ bash: bashSchema,
349
+ attempt_completion: attemptCompletionSchema
350
+ };
351
+
352
+ const schema = schemaMap[toolName];
353
+ if (!schema) {
354
+ // For tools without schema (listFiles, searchFiles, implement), return common params
355
+ // These are the shared params that appear across multiple tools
356
+ return ['path', 'directory', 'pattern', 'recursive', 'includeHidden', 'task', 'files', 'autoCommits', 'result'];
357
+ }
358
+
359
+ // For attempt_completion, it has custom validation, just return 'result'
360
+ if (toolName === 'attempt_completion') {
361
+ return ['result'];
362
+ }
363
+
364
+ // Extract keys from Zod schema
365
+ if (schema && schema._def && schema._def.shape) {
366
+ return Object.keys(schema._def.shape());
367
+ }
368
+
369
+ // Fallback: return empty array if we can't extract schema keys
370
+ return [];
371
+ }
372
+
361
373
  // Simple XML parser helper - safer string-based approach
362
374
  export function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
363
375
  // Look for each valid tool name specifically using string search
@@ -387,15 +399,12 @@ export function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
387
399
 
388
400
  const params = {};
389
401
 
402
+ // Get valid parameters for this specific tool from its schema
403
+ const validParams = getValidParamsForTool(toolName);
404
+
390
405
  // Parse parameters using string-based approach for better safety
391
- // Common parameter names to look for (can be extended as needed)
392
- // Note: includes both camelCase and underscore_case variants to handle inconsistencies
393
- const commonParams = ['query', 'file_path', 'line', 'end_line', 'path', 'recursive', 'includeHidden',
394
- 'max_results', 'maxResults', 'result', 'command', 'description', 'task', 'param', 'pattern',
395
- 'allow_tests', 'exact', 'maxTokens', 'language', 'input_content',
396
- 'context_lines', 'format', 'directory', 'autoCommits', 'files', 'targets'];
397
-
398
- for (const paramName of commonParams) {
406
+ // Only look for parameters that are valid for this specific tool
407
+ for (const paramName of validParams) {
399
408
  const paramOpenTag = `<${paramName}>`;
400
409
  const paramCloseTag = `</${paramName}>`;
401
410
 
@@ -410,7 +419,7 @@ export function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
410
419
  if (paramCloseIndex === -1) {
411
420
  // Find the next opening tag after this parameter
412
421
  let nextTagIndex = innerContent.length;
413
- for (const nextParam of commonParams) {
422
+ for (const nextParam of validParams) {
414
423
  const nextOpenTag = `<${nextParam}>`;
415
424
  const nextIndex = innerContent.indexOf(nextOpenTag, paramOpenIndex + paramOpenTag.length);
416
425
  if (nextIndex !== -1 && nextIndex < nextTagIndex) {