@probelabs/probe 0.6.0-rc264 → 0.6.0-rc266

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.
Files changed (41) hide show
  1. package/bin/binaries/probe-v0.6.0-rc266-aarch64-apple-darwin.tar.gz +0 -0
  2. package/bin/binaries/probe-v0.6.0-rc266-aarch64-unknown-linux-musl.tar.gz +0 -0
  3. package/bin/binaries/probe-v0.6.0-rc266-x86_64-apple-darwin.tar.gz +0 -0
  4. package/bin/binaries/probe-v0.6.0-rc266-x86_64-pc-windows-msvc.zip +0 -0
  5. package/bin/binaries/probe-v0.6.0-rc266-x86_64-unknown-linux-musl.tar.gz +0 -0
  6. package/build/agent/ProbeAgent.js +640 -1441
  7. package/build/agent/engines/enhanced-vercel.js +0 -7
  8. package/build/agent/index.js +3972 -5938
  9. package/build/agent/mcp/index.js +6 -15
  10. package/build/agent/mcp/xmlBridge.js +24 -324
  11. package/build/agent/shared/prompts.js +25 -2
  12. package/build/agent/tasks/index.js +0 -1
  13. package/build/agent/tools.js +11 -181
  14. package/build/index.js +13 -35
  15. package/build/tools/common.js +15 -707
  16. package/build/tools/edit.js +7 -0
  17. package/build/tools/executePlan.js +2 -2
  18. package/build/tools/index.js +8 -11
  19. package/cjs/agent/ProbeAgent.cjs +3503 -5461
  20. package/cjs/index.cjs +4429 -6362
  21. package/package.json +2 -2
  22. package/src/agent/ProbeAgent.js +640 -1441
  23. package/src/agent/engines/enhanced-vercel.js +0 -7
  24. package/src/agent/index.js +10 -2
  25. package/src/agent/mcp/index.js +6 -15
  26. package/src/agent/mcp/xmlBridge.js +24 -324
  27. package/src/agent/shared/prompts.js +25 -2
  28. package/src/agent/tasks/index.js +0 -1
  29. package/src/agent/tools.js +11 -181
  30. package/src/index.js +13 -35
  31. package/src/tools/common.js +15 -707
  32. package/src/tools/edit.js +7 -0
  33. package/src/tools/executePlan.js +2 -2
  34. package/src/tools/index.js +8 -11
  35. package/bin/binaries/probe-v0.6.0-rc264-aarch64-apple-darwin.tar.gz +0 -0
  36. package/bin/binaries/probe-v0.6.0-rc264-aarch64-unknown-linux-musl.tar.gz +0 -0
  37. package/bin/binaries/probe-v0.6.0-rc264-x86_64-apple-darwin.tar.gz +0 -0
  38. package/bin/binaries/probe-v0.6.0-rc264-x86_64-pc-windows-msvc.zip +0 -0
  39. package/bin/binaries/probe-v0.6.0-rc264-x86_64-unknown-linux-musl.tar.gz +0 -0
  40. package/build/agent/xmlParsingUtils.js +0 -221
  41. package/src/agent/xmlParsingUtils.js +0 -221
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * This module provides:
5
5
  * - MCP client management for connecting to MCP servers
6
- * - XML/JSON hybrid tool interface
6
+ * - Native Vercel AI SDK tool interface
7
7
  * - Configuration management
8
8
  */
9
9
 
@@ -18,10 +18,7 @@ export {
18
18
  } from './config.js';
19
19
  export {
20
20
  MCPXmlBridge,
21
- mcpToolToXmlDefinition,
22
- parseXmlMcpToolCall,
23
- parseHybridXmlToolCall,
24
- createHybridSystemMessage
21
+ mcpToolToDescription
25
22
  } from './xmlBridge.js';
26
23
 
27
24
  // Import for default export
@@ -35,10 +32,7 @@ import {
35
32
  } from './config.js';
36
33
  import {
37
34
  MCPXmlBridge,
38
- mcpToolToXmlDefinition,
39
- parseXmlMcpToolCall,
40
- parseHybridXmlToolCall,
41
- createHybridSystemMessage
35
+ mcpToolToDescription
42
36
  } from './xmlBridge.js';
43
37
 
44
38
  // Default export for convenience
@@ -55,10 +49,7 @@ export default {
55
49
  createSampleConfig,
56
50
  saveConfig,
57
51
 
58
- // XML Bridge
52
+ // MCP Bridge
59
53
  MCPXmlBridge,
60
- mcpToolToXmlDefinition,
61
- parseXmlMcpToolCall,
62
- parseHybridXmlToolCall,
63
- createHybridSystemMessage
64
- };
54
+ mcpToolToDescription
55
+ };
@@ -1,129 +1,36 @@
1
1
  /**
2
- * XML-to-MCP Bridge
3
- * Allows using MCP tools with XML-like syntax while maintaining JSON parameters
2
+ * MCP Bridge - manages MCP tool connections and provides Vercel-compatible tools
4
3
  */
5
4
 
6
5
  import { MCPClientManager } from './client.js';
7
6
  import { loadMCPConfiguration } from './config.js';
8
- import { processXmlWithThinkingAndRecovery } from '../xmlParsingUtils.js';
9
- import { unescapeXmlEntities } from '../../tools/common.js';
10
7
 
11
8
  /**
12
- * Convert MCP tool to XML definition format
9
+ * Convert MCP tool to description string (for debug logging)
13
10
  * @param {string} name - Tool name
14
11
  * @param {Object} tool - MCP tool object
15
- * @returns {string} XML-formatted tool definition
12
+ * @returns {string} Description of the tool
16
13
  */
17
- export function mcpToolToXmlDefinition(name, tool) {
14
+ export function mcpToolToDescription(name, tool) {
18
15
  const description = tool.description || 'MCP tool';
19
16
  const inputSchema = tool.inputSchema || tool.parameters || {};
20
17
 
21
- // Build parameter documentation
22
18
  let paramDocs = '';
23
19
  if (inputSchema.properties) {
24
- paramDocs = '\n\nParameters (provide as JSON object):';
20
+ paramDocs = '\nParameters:';
25
21
  for (const [paramName, paramSchema] of Object.entries(inputSchema.properties)) {
26
22
  const required = inputSchema.required?.includes(paramName) ? ' (required)' : ' (optional)';
27
23
  const desc = paramSchema.description || '';
28
24
  const type = paramSchema.type || 'any';
29
25
  paramDocs += `\n- ${paramName}: ${type}${required} - ${desc}`;
30
-
31
- if (paramSchema.enum) {
32
- paramDocs += ` [choices: ${paramSchema.enum.join(', ')}]`;
33
- }
34
26
  }
35
27
  }
36
28
 
37
- return `## ${name}
38
- Description: ${description}${paramDocs}
39
-
40
- Usage:
41
- <${name}>
42
- <params>
43
- {
44
- "param1": "value1",
45
- "param2": "value2"
46
- }
47
- </params>
48
- </${name}>
49
-
50
- Or for simple single parameter:
51
- <${name}>
52
- <params>value</params>
53
- </${name}>`;
54
- }
55
-
56
- /**
57
- * Parse XML tool call with JSON parameters
58
- * Handles both JSON object parameters and simple string parameters
59
- * @param {string} xmlString - XML string containing tool call
60
- * @param {Array<string>} mcpToolNames - List of available MCP tool names
61
- * @returns {Object|null} Parsed tool call with name and params
62
- */
63
- export function parseXmlMcpToolCall(xmlString, mcpToolNames = []) {
64
- // Clean the XML string
65
- const cleanedXml = xmlString.replace(/<thinking>[\s\S]*?<\/thinking>/g, '').trim();
66
-
67
- for (const toolName of mcpToolNames) {
68
- // Look for the tool in XML format
69
- const openTag = `<${toolName}>`;
70
- const closeTag = `</${toolName}>`;
71
-
72
- const openIndex = cleanedXml.indexOf(openTag);
73
- if (openIndex === -1) continue;
74
-
75
- const closeIndex = cleanedXml.indexOf(closeTag, openIndex);
76
- if (closeIndex === -1) continue;
77
-
78
- // Extract content between tags
79
- const contentStart = openIndex + openTag.length;
80
- const content = cleanedXml.substring(contentStart, closeIndex).trim();
81
-
82
- // Look for params tag
83
- const paramsMatch = content.match(/<params>([\s\S]*?)<\/params>/);
84
-
85
- let params = {};
86
- if (paramsMatch) {
87
- let paramsContent = paramsMatch[1].trim();
88
-
89
- // Handle CDATA sections
90
- const cdataMatch = paramsContent.match(/^<!\[CDATA\[([\s\S]*?)\]\]>$/);
91
- if (cdataMatch) {
92
- paramsContent = cdataMatch[1];
93
- }
94
-
95
- // Try to parse as JSON first
96
- try {
97
- // Handle JSON object
98
- if (paramsContent.startsWith('{')) {
99
- params = JSON.parse(paramsContent);
100
- } else {
101
- // Handle simple string parameter
102
- // For backwards compatibility with simple XML params
103
- params = { value: paramsContent };
104
- }
105
- } catch (e) {
106
- // If JSON parsing fails, treat as simple string
107
- params = { value: paramsContent };
108
- }
109
- } else {
110
- // Legacy format: parse individual XML parameters
111
- const paramPattern = /<(\w+)>([\s\S]*?)<\/\1>/g;
112
- let match;
113
- while ((match = paramPattern.exec(content)) !== null) {
114
- const [, paramName, paramValue] = match;
115
- params[paramName] = unescapeXmlEntities(paramValue.trim());
116
- }
117
- }
118
-
119
- return { toolName, params };
120
- }
121
-
122
- return null;
29
+ return `## ${name}\nDescription: ${description}${paramDocs}`;
123
30
  }
124
31
 
125
32
  /**
126
- * MCP Tool Manager that bridges XML and MCP
33
+ * MCP Bridge - manages MCP connections and provides native Vercel AI SDK tools
127
34
  */
128
35
  export class MCPXmlBridge {
129
36
  constructor(options = {}) {
@@ -131,7 +38,7 @@ export class MCPXmlBridge {
131
38
  this.tracer = options.tracer || null;
132
39
  this.mcpTools = {};
133
40
  this.mcpManager = null;
134
- this.xmlDefinitions = {};
41
+ this.toolDescriptions = {};
135
42
  }
136
43
 
137
44
  /**
@@ -142,13 +49,11 @@ export class MCPXmlBridge {
142
49
  let mcpConfigs = null;
143
50
 
144
51
  if (!config) {
145
- // No config provided - fall back to auto-discovery for backward compatibility
146
52
  if (this.debug) {
147
53
  console.error('[MCP DEBUG] No config provided, attempting auto-discovery...');
148
54
  }
149
55
  mcpConfigs = loadMCPConfiguration();
150
56
 
151
- // Check if auto-discovery found anything
152
57
  if (!mcpConfigs || !mcpConfigs.mcpServers || Object.keys(mcpConfigs.mcpServers).length === 0) {
153
58
  console.error('[MCP WARNING] MCP enabled but no configuration found');
154
59
  console.error('[MCP INFO] To use MCP, provide configuration via:');
@@ -158,13 +63,11 @@ export class MCPXmlBridge {
158
63
  console.error('[MCP INFO] - Environment variable MCP_CONFIG_PATH');
159
64
  }
160
65
  } else if (Array.isArray(config)) {
161
- // Deprecated: Array of server configs (backward compatibility)
162
66
  if (this.debug) {
163
67
  console.error('[MCP DEBUG] Using deprecated array config format (consider using mcpConfig object)');
164
68
  }
165
69
  mcpConfigs = { mcpServers: config };
166
70
  } else {
167
- // New: Full config object provided directly
168
71
  if (this.debug) {
169
72
  console.error('[MCP DEBUG] Using provided MCP config object');
170
73
  }
@@ -181,28 +84,23 @@ export class MCPXmlBridge {
181
84
  console.error('[MCP DEBUG] Initializing MCP client manager...');
182
85
  }
183
86
 
184
- // Initialize the MCP client manager with tracer support
185
87
  this.mcpManager = new MCPClientManager({ debug: this.debug, tracer: this.tracer });
186
88
  const result = await this.mcpManager.initialize(mcpConfigs);
187
89
 
188
- // Get tools from the manager
90
+ // Get tools from the manager (already in Vercel format)
189
91
  const vercelTools = this.mcpManager.getVercelTools();
190
92
  this.mcpTools = vercelTools;
191
93
  const toolCount = Object.keys(vercelTools).length;
192
94
 
193
- // Generate XML definitions for all tools
95
+ // Generate descriptions for debug logging
194
96
  for (const [name, tool] of Object.entries(vercelTools)) {
195
- this.xmlDefinitions[name] = mcpToolToXmlDefinition(name, tool);
97
+ this.toolDescriptions[name] = mcpToolToDescription(name, tool);
196
98
  }
197
99
 
198
100
  if (toolCount === 0) {
199
101
  console.error('[MCP INFO] MCP initialization complete: 0 tools loaded');
200
102
  } else {
201
103
  console.error(`[MCP INFO] MCP initialization complete: ${toolCount} tool${toolCount !== 1 ? 's' : ''} loaded from ${result.connected} server${result.connected !== 1 ? 's' : ''}`);
202
-
203
- if (this.debug) {
204
- console.error('[MCP DEBUG] Tool definitions generated for XML bridge');
205
- }
206
104
  }
207
105
  } catch (error) {
208
106
  console.error('[MCP ERROR] Failed to initialize MCP connections:', error.message);
@@ -213,20 +111,21 @@ export class MCPXmlBridge {
213
111
  }
214
112
 
215
113
  /**
216
- * Get XML tool definitions for inclusion in system prompt
217
- * @param {Array<string>|null} filterToolNames - Optional list of tool names to include (if null, include all)
218
- * @returns {string} Combined XML tool definitions
114
+ * Get Vercel AI SDK compatible tools for use with streamText
115
+ * @param {Array<string>|null} filterToolNames - Optional list of tool names to include
116
+ * @returns {Object} Map of tool name to Vercel tool object
219
117
  */
220
- getXmlToolDefinitions(filterToolNames = null) {
118
+ getVercelTools(filterToolNames = null) {
221
119
  if (filterToolNames === null) {
222
- return Object.values(this.xmlDefinitions).join('\n\n');
120
+ return { ...this.mcpTools };
223
121
  }
224
-
225
- // Filter definitions based on provided tool names
226
- return Object.entries(this.xmlDefinitions)
227
- .filter(([name]) => filterToolNames.includes(name))
228
- .map(([, def]) => def)
229
- .join('\n\n');
122
+ const filtered = {};
123
+ for (const name of filterToolNames) {
124
+ if (this.mcpTools[name]) {
125
+ filtered[name] = this.mcpTools[name];
126
+ }
127
+ }
128
+ return filtered;
230
129
  }
231
130
 
232
131
  /**
@@ -237,59 +136,6 @@ export class MCPXmlBridge {
237
136
  return Object.keys(this.mcpTools);
238
137
  }
239
138
 
240
- /**
241
- * Execute an MCP tool from XML call
242
- * @param {string} xmlString - XML tool call string
243
- * @returns {Promise<Object>} Tool execution result
244
- */
245
- async executeFromXml(xmlString) {
246
- const parsed = parseXmlMcpToolCall(xmlString, this.getToolNames());
247
-
248
- if (!parsed) {
249
- console.error('[MCP ERROR] No valid MCP tool call found in XML');
250
- throw new Error('No valid MCP tool call found in XML');
251
- }
252
-
253
- const { toolName, params } = parsed;
254
-
255
- if (this.debug) {
256
- console.error(`[MCP DEBUG] Executing MCP tool: ${toolName}`);
257
- console.error(`[MCP DEBUG] Parameters:`, JSON.stringify(params, null, 2));
258
- }
259
-
260
- const tool = this.mcpTools[toolName];
261
- if (!tool) {
262
- console.error(`[MCP ERROR] Unknown MCP tool: ${toolName}`);
263
- console.error(`[MCP ERROR] Available tools: ${this.getToolNames().join(', ')}`);
264
- throw new Error(`Unknown MCP tool: ${toolName}`);
265
- }
266
-
267
- try {
268
- const result = await tool.execute(params);
269
-
270
- if (this.debug) {
271
- console.error(`[MCP DEBUG] Tool ${toolName} executed successfully`);
272
- }
273
-
274
- return {
275
- success: true,
276
- toolName,
277
- result
278
- };
279
- } catch (error) {
280
- console.error(`[MCP ERROR] Tool ${toolName} execution failed:`, error.message);
281
- if (this.debug) {
282
- console.error(`[MCP DEBUG] Full error details:`, error);
283
- }
284
-
285
- return {
286
- success: false,
287
- toolName,
288
- error: error.message
289
- };
290
- }
291
- }
292
-
293
139
  /**
294
140
  * Check if a tool call is an MCP tool
295
141
  * @param {string} toolName - Tool name to check
@@ -309,150 +155,4 @@ export class MCPXmlBridge {
309
155
  }
310
156
  }
311
157
 
312
- /**
313
- * Enhanced XML parser that handles both native and MCP tools
314
- * Uses the exact same logic as CLI/SDK mode to ensure consistency
315
- * @param {string} xmlString - XML string to parse
316
- * @param {Array<string>} nativeTools - List of native tool names
317
- * @param {MCPXmlBridge} mcpBridge - MCP bridge instance
318
- * @returns {Object|null} Parsed tool call
319
- */
320
- export function parseHybridXmlToolCall(xmlString, nativeTools = [], mcpBridge = null) {
321
- // First try native tools with the same logic as CLI/SDK mode
322
- // This includes thinking tag removal and attempt_complete recovery logic
323
- const nativeResult = parseNativeXmlToolWithThinking(xmlString, nativeTools);
324
- if (nativeResult) {
325
- const { thinkingContent, ...rest } = nativeResult;
326
- return { ...rest, type: 'native', thinkingContent };
327
- }
328
-
329
- // Then try MCP tools if bridge is available
330
- if (mcpBridge) {
331
- const mcpResult = parseXmlMcpToolCall(xmlString, mcpBridge.getToolNames());
332
- if (mcpResult) {
333
- // Extract thinking content for MCP tools as well
334
- const { thinkingContent } = processXmlWithThinkingAndRecovery(xmlString, []);
335
- return { ...mcpResult, type: 'mcp', thinkingContent };
336
- }
337
- }
338
-
339
- return null;
340
- }
341
-
342
- /**
343
- * Parse native XML tools using the same logic as CLI/SDK mode
344
- * Now uses shared utilities instead of duplicating code
345
- * @param {string} xmlString - XML string to parse
346
- * @param {Array<string>} validTools - List of valid tool names
347
- * @returns {Object|null} Parsed tool call
348
- */
349
- function parseNativeXmlToolWithThinking(xmlString, validTools) {
350
- // Use the shared processing logic
351
- const { cleanedXmlString, recoveryResult, thinkingContent } = processXmlWithThinkingAndRecovery(xmlString, validTools);
352
-
353
- // If recovery found an attempt_complete pattern, return it with thinking content
354
- if (recoveryResult) {
355
- return { ...recoveryResult, thinkingContent };
356
- }
357
-
358
- // Use the original parseNativeXmlTool function to parse the cleaned XML string
359
- for (const toolName of validTools) {
360
- const result = parseNativeXmlTool(cleanedXmlString, toolName);
361
- if (result) {
362
- return { ...result, thinkingContent };
363
- }
364
- }
365
-
366
- return null;
367
- }
368
-
369
- /**
370
- * Parse native XML tool (existing format)
371
- * @param {string} xmlString - XML string
372
- * @param {string} toolName - Tool name to look for
373
- * @returns {Object|null} Parsed tool call
374
- */
375
- function parseNativeXmlTool(xmlString, toolName) {
376
- const openTag = `<${toolName}>`;
377
- const closeTag = `</${toolName}>`;
378
-
379
- const openIndex = xmlString.indexOf(openTag);
380
- if (openIndex === -1) return null;
381
-
382
- const closeIndex = xmlString.indexOf(closeTag, openIndex);
383
- if (closeIndex === -1) return null;
384
-
385
- const contentStart = openIndex + openTag.length;
386
- const content = xmlString.substring(contentStart, closeIndex).trim();
387
-
388
- // Parse individual XML parameters (native format)
389
- const params = {};
390
- const paramPattern = /<(\w+)>([\s\S]*?)<\/\1>/g;
391
- let match;
392
-
393
- while ((match = paramPattern.exec(content)) !== null) {
394
- const [, paramName, paramValue] = match;
395
- // Skip if this is the params tag itself (MCP format)
396
- if (paramName !== 'params') {
397
- params[paramName] = unescapeXmlEntities(paramValue.trim());
398
- }
399
- }
400
-
401
- // Only return if we found actual parameters (not MCP format)
402
- if (Object.keys(params).length > 0) {
403
- return { toolName, params };
404
- }
405
-
406
- return null;
407
- }
408
-
409
- /**
410
- * Create a combined system message with both native and MCP tools
411
- * @param {string} baseSystemMessage - Base system message
412
- * @param {string} nativeToolDefinitions - Native tool definitions in XML format
413
- * @param {MCPXmlBridge} mcpBridge - MCP bridge with loaded tools
414
- * @returns {string} Combined system message
415
- */
416
- export function createHybridSystemMessage(baseSystemMessage, nativeToolDefinitions, mcpBridge) {
417
- let message = baseSystemMessage;
418
-
419
- // Add native tools section
420
- if (nativeToolDefinitions) {
421
- message += '\n\n=== NATIVE TOOLS ===\n';
422
- message += 'These tools use standard XML parameter format:\n\n';
423
- message += nativeToolDefinitions;
424
- }
425
-
426
- // Add MCP tools section if available
427
- if (mcpBridge && mcpBridge.getToolNames().length > 0) {
428
- message += '\n\n=== MCP TOOLS ===\n';
429
- message += 'These tools use JSON parameters within the params tag:\n\n';
430
- message += mcpBridge.getXmlToolDefinitions();
431
- }
432
-
433
- // Add usage instructions
434
- message += '\n\n=== TOOL USAGE INSTRUCTIONS ===\n';
435
- message += `
436
- For NATIVE tools, use standard XML format:
437
- <search>
438
- <query>authentication</query>
439
- <path>./src</path>
440
- </search>
441
-
442
- For MCP tools, use JSON within params tag:
443
- <mcp_tool_name>
444
- <params>
445
- {
446
- "param1": "value1",
447
- "param2": 123
448
- }
449
- </params>
450
- </mcp_tool_name>
451
-
452
- IMPORTANT: Always check the tool definition to determine whether it's a native tool (XML params) or MCP tool (JSON params).
453
- `;
454
-
455
- return message;
456
- }
457
-
458
- export default MCPXmlBridge;
158
+ export default MCPXmlBridge;
@@ -87,6 +87,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
87
87
  - Avoid implementing special cases when a general approach works
88
88
  - Never expose secrets, API keys, or credentials in generated code. Never log sensitive information.
89
89
  - Do not surprise the user with unrequested changes. Do what was asked, including reasonable follow-up actions, but do not refactor surrounding code or add features that were not requested.
90
+ - When editing files, keep edits focused and minimal. For changes spanning more than a few lines, prefer line-targeted editing (start_line/end_line) over text replacement (old_string) — it constrains scope and prevents accidental removal of adjacent content. Never include unrelated sections in an edit operation.
90
91
  - After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
91
92
 
92
93
  # After Implementation
@@ -97,11 +98,33 @@ If the solution is clear, you can jump to implementation right away. If not, ask
97
98
 
98
99
  # GitHub Integration
99
100
  - Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
100
- - To create a pull request: commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
101
101
  - To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
102
102
  - If given a GitHub URL, use \`gh\` to fetch the relevant information rather than guessing.
103
103
  - Always return the pull request URL to the user after creating one.
104
- - When checking GitHub Actions, only read logs of failed jobs — do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.`,
104
+ - When checking GitHub Actions, only read logs of failed jobs — do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.
105
+
106
+ # Pull Request Creation
107
+ - Commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
108
+ - **PR title**: Keep it short (under 72 characters). Use imperative mood describing the change (e.g. "Add retry logic for API calls", "Fix race condition in cache invalidation"). Prefix with the type of change when useful: \`fix:\`, \`feat:\`, \`refactor:\`, \`docs:\`, \`test:\`, \`chore:\`.
109
+ - **PR body**: MUST follow this structure:
110
+
111
+ \`\`\`
112
+ ## Problem / Task
113
+ <What problem is being solved or what task was requested. If there is a linked issue, reference it with #number. Be specific about the root cause or motivation.>
114
+
115
+ ## Changes
116
+ <Concise list of what was actually changed. Describe each meaningful change — files modified, logic added/removed, and why. Do NOT just list filenames; explain what each change does.>
117
+
118
+ ## Testing
119
+ <What tests were added, modified, or run. Include:
120
+ - New test names and what they verify
121
+ - Whether existing tests still pass
122
+ - Manual verification steps if applicable
123
+ - Commands used to validate (e.g. \`make test\`, \`npm test\`)>
124
+ \`\`\`
125
+
126
+ - If the task originated from a GitHub issue, always reference it in the PR body (e.g. "Fixes #123" or "Closes #123") so the issue is automatically closed on merge. If it originated from an external ticket system (Jira, Linear, etc.), include the ticket ID and link in the Problem / Task section (e.g. "Resolves PROJ-456").
127
+ - Do not leave the PR body empty or vague. Every PR must clearly communicate what was done and why so reviewers can understand the change without reading every line of diff.`,
105
128
 
106
129
  'support': `You are ProbeChat Support, a specialized AI assistant focused on helping developers troubleshoot issues and solve problems. Your primary function is to help users diagnose errors, understand unexpected behaviors, and find solutions using the provided code analysis tools.
107
130
 
@@ -6,7 +6,6 @@
6
6
  export { TaskManager, default as TaskManagerDefault } from './TaskManager.js';
7
7
  export {
8
8
  taskSchema,
9
- taskToolDefinition,
10
9
  taskSystemPrompt,
11
10
  taskGuidancePrompt,
12
11
  createTaskCompletionBlockedMessage,