@probelabs/probe 0.6.0-rc79 → 0.6.0-rc81

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.
@@ -254,21 +254,38 @@ ${attemptCompletionToolDefinition}
254
254
  let xmlToolGuidelines = `
255
255
  # Tool Use Formatting
256
256
 
257
- Tool use MUST be formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. You MUST use exactly ONE tool call per message until you are ready to complete the task.
257
+ Tool use MUST be formatted using XML-style tags. Each tool call requires BOTH opening and closing tags with the exact tool name. Each parameter is similarly enclosed within its own set of opening and closing tags. You MUST use exactly ONE tool call per message until you are ready to complete the task.
258
258
 
259
- Structure:
259
+ **CRITICAL: Every XML tag MUST have both opening <tag> and closing </tag> parts.**
260
+
261
+ Structure (note the closing tags):
260
262
  <tool_name>
261
263
  <parameter1_name>value1</parameter1_name>
262
264
  <parameter2_name>value2</parameter2_name>
263
265
  ...
264
266
  </tool_name>
265
267
 
266
- Example:
268
+ Examples:
267
269
  <search>
268
270
  <query>error handling</query>
269
271
  <path>src/search</path>
270
272
  </search>
271
273
 
274
+ <extract>
275
+ <path>src/config.js</path>
276
+ <start_line>15</start_line>
277
+ <end_line>25</end_line>
278
+ </extract>
279
+
280
+ <attempt_completion>
281
+ <result>The configuration is loaded from src/config.js lines 15-25 which contains the database settings.</result>
282
+ </attempt_completion>
283
+
284
+ # Special Case: Quick Completion
285
+ If your previous response was already correct and complete, you may respond with just:
286
+ <attempt_complete>
287
+ This signals to use your previous response as the final answer without repeating content.
288
+
272
289
  # Thinking Process
273
290
 
274
291
  Before using a tool, analyze the situation within <thinking></thinking> tags. This helps you organize your thoughts and make better decisions.
@@ -283,12 +300,13 @@ I need to find code related to error handling in the search module. The most app
283
300
  1. Think step-by-step about how to achieve the user's goal.
284
301
  2. Use <thinking></thinking> tags to analyze the situation and determine the appropriate tool.
285
302
  3. Choose **one** tool that helps achieve the current step.
286
- 4. Format the tool call using the specified XML format. Ensure all required parameters are included.
303
+ 4. Format the tool call using the specified XML format with BOTH opening and closing tags. Ensure all required parameters are included.
287
304
  5. **You MUST respond with exactly one tool call in the specified XML format in each turn.**
288
305
  6. Wait for the tool execution result, which will be provided in the next message (within a <tool_result> block).
289
306
  7. Analyze the tool result and decide the next step. If more tool calls are needed, repeat steps 2-6.
290
307
  8. If the task is fully complete and all previous steps were successful, use the \`<attempt_completion>\` tool to provide the final answer. This is the ONLY way to finish the task.
291
308
  9. If you cannot proceed (e.g., missing information, invalid request), explain the issue clearly before using \`<attempt_completion>\` with an appropriate message in the \`<result>\` tag.
309
+ 10. If your previous response was already correct and complete, you may use \`<attempt_complete>\` as a shorthand.
292
310
 
293
311
  Available Tools:
294
312
  - search: Search code using keyword queries.
@@ -298,6 +316,7 @@ Available Tools:
298
316
  - searchFiles: Find files matching a glob pattern with recursive search capability.
299
317
  ${this.allowEdit ? '- implement: Implement a feature or fix a bug using aider.\n' : ''}
300
318
  - attempt_completion: Finalize the task and provide the result to the user.
319
+ - attempt_complete: Quick completion using previous response (shorthand).
301
320
  `;
302
321
 
303
322
  // Common instructions
@@ -618,13 +637,33 @@ When troubleshooting:
618
637
 
619
638
  if (toolName === 'attempt_completion') {
620
639
  completionAttempted = true;
621
- const validation = attemptCompletionSchema.safeParse(params);
622
- if (validation.success) {
623
- finalResult = validation.data.result;
624
- if (this.debug) console.log(`[DEBUG] Task completed successfully with result: ${finalResult.substring(0, 100)}...`);
640
+
641
+ // Handle attempt_complete shorthand - use previous response
642
+ if (params.result === '__PREVIOUS_RESPONSE__') {
643
+ // Find the last assistant message with actual content (not tool calls)
644
+ const lastAssistantMessage = [...currentMessages].reverse().find(msg =>
645
+ msg.role === 'assistant' &&
646
+ msg.content &&
647
+ !parseXmlToolCallWithThinking(msg.content, validTools)
648
+ );
649
+
650
+ if (lastAssistantMessage) {
651
+ finalResult = lastAssistantMessage.content;
652
+ if (this.debug) console.log(`[DEBUG] Using previous response as completion: ${finalResult.substring(0, 100)}...`);
653
+ } else {
654
+ finalResult = 'Error: No previous response found to use as completion.';
655
+ if (this.debug) console.log(`[DEBUG] No suitable previous response found for attempt_complete shorthand`);
656
+ }
625
657
  } else {
626
- console.error(`[ERROR] Invalid attempt_completion parameters:`, validation.error);
627
- finalResult = 'Error: Invalid completion attempt. The task could not be completed properly.';
658
+ // Standard attempt_completion handling
659
+ const validation = attemptCompletionSchema.safeParse(params);
660
+ if (validation.success) {
661
+ finalResult = validation.data.result;
662
+ if (this.debug) console.log(`[DEBUG] Task completed successfully with result: ${finalResult.substring(0, 100)}...`);
663
+ } else {
664
+ console.error(`[ERROR] Invalid attempt_completion parameters:`, validation.error);
665
+ finalResult = 'Error: Invalid completion attempt. The task could not be completed properly.';
666
+ }
628
667
  }
629
668
  break;
630
669
  } else {
@@ -738,9 +777,45 @@ When troubleshooting:
738
777
  } else {
739
778
  // No tool call found, add assistant response and ask for tool usage
740
779
  currentMessages.push({ role: 'assistant', content: assistantResponseContent });
780
+
781
+ // Build appropriate reminder message based on whether schema is provided
782
+ let reminderContent;
783
+ if (options.schema) { // Apply for ANY schema, not just JSON schemas
784
+ // When schema is provided, give specific instructions
785
+ reminderContent = `Please use one of the available tools to help answer the question, or use attempt_completion if you have enough information to provide a final answer.
786
+
787
+ Remember: Use proper XML format with BOTH opening and closing tags:
788
+
789
+ <tool_name>
790
+ <parameter>value</parameter>
791
+ </tool_name>
792
+
793
+ IMPORTANT: A schema was provided. You MUST respond with data that matches this schema.
794
+ Use attempt_completion with your response directly inside the tags:
795
+
796
+ <attempt_completion>
797
+ {"key": "value", "field": "your actual data here matching the schema"}
798
+ </attempt_completion>
799
+
800
+ Your response must conform to this schema:
801
+ ${options.schema}`;
802
+ } else {
803
+ // Standard reminder without schema
804
+ reminderContent = `Please use one of the available tools to help answer the question, or use attempt_completion if you have enough information to provide a final answer.
805
+
806
+ Remember: Use proper XML format with BOTH opening and closing tags:
807
+
808
+ <tool_name>
809
+ <parameter>value</parameter>
810
+ </tool_name>
811
+
812
+ Or for quick completion if your previous response was already correct:
813
+ <attempt_complete>`;
814
+ }
815
+
741
816
  currentMessages.push({
742
817
  role: 'user',
743
- content: 'Please use one of the available tools to help answer the question, or use attempt_completion if you have enough information to provide a final answer.'
818
+ content: reminderContent
744
819
  });
745
820
  if (this.debug) {
746
821
  console.log(`[DEBUG] No tool call detected in assistant response. Prompting for tool use.`);
@@ -1440,11 +1440,24 @@ function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
1440
1440
  "recursive",
1441
1441
  "includeHidden",
1442
1442
  "max_results",
1443
+ "maxResults",
1443
1444
  "result",
1444
1445
  "command",
1445
1446
  "description",
1446
1447
  "task",
1447
- "param"
1448
+ "param",
1449
+ "pattern",
1450
+ "allow_tests",
1451
+ "exact",
1452
+ "maxTokens",
1453
+ "language",
1454
+ "input_content",
1455
+ "context_lines",
1456
+ "format",
1457
+ "directory",
1458
+ "autoCommits",
1459
+ "files",
1460
+ "targets"
1448
1461
  ];
1449
1462
  for (const paramName of commonParams) {
1450
1463
  const paramOpenTag = `<${paramName}>`;
@@ -1474,23 +1487,7 @@ function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
1474
1487
  params[paramName] = paramValue;
1475
1488
  }
1476
1489
  if (toolName === "attempt_completion") {
1477
- const resultOpenTag = "<result>";
1478
- const resultCloseTag = "</result>";
1479
- const resultOpenIndex = innerContent.indexOf(resultOpenTag);
1480
- if (resultOpenIndex !== -1) {
1481
- const resultCloseIndex = innerContent.indexOf(resultCloseTag, resultOpenIndex + resultOpenTag.length);
1482
- if (resultCloseIndex !== -1) {
1483
- params["result"] = innerContent.substring(
1484
- resultOpenIndex + resultOpenTag.length,
1485
- resultCloseIndex
1486
- ).trim();
1487
- }
1488
- } else {
1489
- const paramsCount = Object.keys(params).filter((key) => key !== "command").length;
1490
- if (paramsCount === 0) {
1491
- params["result"] = innerContent.trim();
1492
- }
1493
- }
1490
+ params["result"] = innerContent.trim();
1494
1491
  if (params.command) {
1495
1492
  delete params.command;
1496
1493
  }
@@ -1534,7 +1531,7 @@ var init_common = __esm({
1534
1531
  allow_tests: z.boolean().optional().default(false).describe("Allow test files in search results")
1535
1532
  });
1536
1533
  extractSchema = z.object({
1537
- file_path: z.string().optional().describe("Path to the file to extract from. Can include line numbers or symbol names"),
1534
+ targets: z.string().optional().describe("File paths or symbols to extract from. Can include line numbers, symbol names, or multiple space-separated targets"),
1538
1535
  input_content: z.string().optional().describe("Text content to extract file paths from"),
1539
1536
  line: z.number().optional().describe("Start line number to extract a specific code block"),
1540
1537
  end_line: z.number().optional().describe("End line number for extracting a range of lines"),
@@ -1602,6 +1599,12 @@ var init_common = __esm({
1602
1599
  Description: Search code in the repository using Elasticsearch query syntax (except field based queries, e.g. "filename:..." NOT supported).
1603
1600
 
1604
1601
  You need to focus on main keywords when constructing the query, and always use elastic search syntax like OR AND and brackets to group keywords.
1602
+
1603
+ **Session Management & Caching:**
1604
+ - Ensure not to re-read the same symbols twice - reuse context from previous tool calls
1605
+ - Probe returns a session ID on first run - reuse it for subsequent calls to avoid redundant searches
1606
+ - Once data is returned, it's cached and won't return on next runs (this is expected behavior)
1607
+
1605
1608
  Parameters:
1606
1609
  - query: (required) Search query with Elasticsearch syntax. You can use + for important terms, and - for negation.
1607
1610
  - 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.
@@ -1611,11 +1614,22 @@ Parameters:
1611
1614
  - maxTokens: (optional, default: 10000) Maximum number of tokens to return (number).
1612
1615
  - language: (optional) Limit search to files of a specific programming language (e.g., 'rust', 'js', 'python', 'go' etc.).
1613
1616
 
1617
+ **Workflow:** Always start with search, then use extract for detailed context when needed.
1614
1618
 
1615
1619
  Usage Example:
1616
1620
 
1617
1621
  <examples>
1618
1622
 
1623
+ User: Where is the login logic?
1624
+ Assistant workflow:
1625
+ 1. <search>
1626
+ <query>login AND auth AND token</query>
1627
+ <path>.</path>
1628
+ </search>
1629
+ 2. Now lets look closer: <extract>
1630
+ <targets>session.rs#AuthService.login auth.rs:2-100</targets>
1631
+ </extract>
1632
+
1619
1633
  User: How to calculate the total amount in the payments module?
1620
1634
  <search>
1621
1635
  <query>calculate AND payment</query>
@@ -1639,7 +1653,6 @@ User: Find all react imports in the project.
1639
1653
  <language>js</language>
1640
1654
  </search>
1641
1655
 
1642
-
1643
1656
  User: Find how decompoud library works?
1644
1657
  <search>
1645
1658
  <query>import { react }</query>
@@ -1671,11 +1684,16 @@ Usage Example:
1671
1684
  `;
1672
1685
  extractToolDefinition = `
1673
1686
  ## extract
1674
- Description: Extract code blocks from files based on file paths and optional line numbers. Use this tool to see complete context after finding relevant files. It can be used to read full files as well.
1687
+ Description: Extract code blocks from files based on file paths and optional line numbers. Use this tool to see complete context after finding relevant files. It can be used to read full files as well.
1675
1688
  Full file extraction should be the LAST RESORT! Always prefer search.
1676
1689
 
1690
+ **Multiple Extraction:** You can extract multiple symbols/files in one call by providing multiple file paths separated by spaces.
1691
+
1692
+ **Session Awareness:** Reuse context from previous tool calls. Don't re-extract the same symbols you already have.
1693
+
1677
1694
  Parameters:
1678
- - file_path: (required) Path to the file to extract from. Can include line numbers or symbol names (e.g., 'src/main.rs:10-20', 'src/utils.js#myFunction').
1695
+ - 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').
1696
+ For multiple extractions: 'session.rs#AuthService.login auth.rs:2-100 config.rs#DatabaseConfig'
1679
1697
  - line: (optional) Start line number to extract a specific code block. Use with end_line for ranges.
1680
1698
  - end_line: (optional) End line number for extracting a range of lines.
1681
1699
  - allow_tests: (optional, default: false) Allow test files and test code blocks (true/false).
@@ -1683,42 +1701,46 @@ Usage Example:
1683
1701
 
1684
1702
  <examples>
1685
1703
 
1704
+ User: Where is the login logic? (After search found relevant files)
1705
+ <extract>
1706
+ <targets>session.rs#AuthService.login auth.rs:2-100 config.rs#DatabaseConfig</targets>
1707
+ </extract>
1708
+
1709
+ User: How does error handling work? (After search identified files)
1710
+ <extract>
1711
+ <targets>error.rs#ErrorType utils.rs#handle_error src/main.rs:50-80</targets>
1712
+ </extract>
1713
+
1686
1714
  User: How RankManager works
1687
1715
  <extract>
1688
- <file_path>src/search/ranking.rs#RankManager</file_path>
1716
+ <targets>src/search/ranking.rs#RankManager</targets>
1689
1717
  </extract>
1690
1718
 
1691
1719
  User: Lets read the whole file
1692
1720
  <extract>
1693
- <file_path>src/search/ranking.rs</file_path>
1721
+ <targets>src/search/ranking.rs</targets>
1694
1722
  </extract>
1695
1723
 
1696
1724
  User: Read the first 10 lines of the file
1697
1725
  <extract>
1698
- <file_path>src/search/ranking.rs</file_path>
1726
+ <targets>src/search/ranking.rs</targets>
1699
1727
  <line>1</line>
1700
1728
  <end_line>10</end_line>
1701
1729
  </extract>
1702
1730
 
1703
1731
  User: Read file inside the dependency
1704
1732
  <extract>
1705
- <file_path>/dep/go/github.com/gorilla/mux/router.go</file_path>
1733
+ <targets>/dep/go/github.com/gorilla/mux/router.go</targets>
1706
1734
  </extract>
1707
1735
 
1708
-
1709
1736
  </examples>
1710
1737
  `;
1711
1738
  attemptCompletionToolDefinition = `
1712
1739
  ## attempt_completion
1713
1740
  Description: Use this tool ONLY when the task is fully complete and you have received confirmation of success for all previous tool uses. Presents the final result to the user. You can provide your response directly inside the XML tags without any parameter wrapper.
1714
1741
  Parameters:
1715
- - No validation required - provide your complete answer directly inside the XML tags or use the <result> parameter (both formats supported).
1716
- Usage Examples:
1717
- <attempt_completion>
1718
- <result>I have refactored the search module according to the requirements and verified the tests pass. The module now uses the new BM25 ranking algorithm and has improved error handling.</result>
1719
- </attempt_completion>
1720
-
1721
- Or direct response:
1742
+ - No validation required - provide your complete answer directly inside the XML tags.
1743
+ Usage Example:
1722
1744
  <attempt_completion>
1723
1745
  I have refactored the search module according to the requirements and verified the tests pass. The module now uses the new BM25 ranking algorithm and has improved error handling.
1724
1746
  </attempt_completion>
@@ -2020,7 +2042,7 @@ var init_vercel = __esm({
2020
2042
  name: "extract",
2021
2043
  description: extractDescription,
2022
2044
  parameters: extractSchema,
2023
- execute: async ({ file_path, input_content, line, end_line, allow_tests, context_lines, format }) => {
2045
+ execute: async ({ targets, input_content, line, end_line, allow_tests, context_lines, format }) => {
2024
2046
  try {
2025
2047
  let extractPath = options.defaultPath || ".";
2026
2048
  if ((extractPath === "." || extractPath === "./") && options.defaultPath) {
@@ -2030,8 +2052,8 @@ var init_vercel = __esm({
2030
2052
  extractPath = options.defaultPath;
2031
2053
  }
2032
2054
  if (debug) {
2033
- if (file_path) {
2034
- console.error(`Executing extract with file: "${file_path}", path: "${extractPath}", context lines: ${context_lines || 10}`);
2055
+ if (targets) {
2056
+ console.error(`Executing extract with targets: "${targets}", path: "${extractPath}", context lines: ${context_lines || 10}`);
2035
2057
  } else if (input_content) {
2036
2058
  console.error(`Executing extract with input content, path: "${extractPath}", context lines: ${context_lines || 10}`);
2037
2059
  }
@@ -2058,8 +2080,8 @@ var init_vercel = __esm({
2058
2080
  contextLines: context_lines,
2059
2081
  format: effectiveFormat
2060
2082
  };
2061
- } else if (file_path) {
2062
- const files = [file_path];
2083
+ } else if (targets) {
2084
+ const files = [targets];
2063
2085
  let effectiveFormat = format;
2064
2086
  if (outline && format === "outline-xml") {
2065
2087
  effectiveFormat = "xml";
@@ -2071,7 +2093,7 @@ var init_vercel = __esm({
2071
2093
  format: effectiveFormat
2072
2094
  };
2073
2095
  } else {
2074
- throw new Error("Either file_path or input_content must be provided");
2096
+ throw new Error("Either targets or input_content must be provided");
2075
2097
  }
2076
2098
  const results = await extract(extractOptions);
2077
2099
  if (tempFilePath) {
@@ -2595,7 +2617,14 @@ function createTools(configOptions) {
2595
2617
  function parseXmlToolCallWithThinking(xmlString, validTools) {
2596
2618
  const thinkingMatch = xmlString.match(/<thinking>([\s\S]*?)<\/thinking>/);
2597
2619
  const thinkingContent = thinkingMatch ? thinkingMatch[1].trim() : null;
2598
- const cleanedXmlString = xmlString.replace(/<thinking>[\s\S]*?<\/thinking>/g, "").trim();
2620
+ let cleanedXmlString = xmlString.replace(/<thinking>[\s\S]*?<\/thinking>/g, "").trim();
2621
+ const attemptCompleteMatch = cleanedXmlString.match(/^<attempt_complete>\s*$/);
2622
+ if (attemptCompleteMatch) {
2623
+ return {
2624
+ toolName: "attempt_completion",
2625
+ params: { result: "__PREVIOUS_RESPONSE__" }
2626
+ };
2627
+ }
2599
2628
  const parsedTool = parseXmlToolCall(cleanedXmlString, validTools);
2600
2629
  if (process.env.DEBUG === "1" && thinkingContent) {
2601
2630
  console.log(`[DEBUG] AI Thinking Process:
@@ -3939,21 +3968,38 @@ ${attemptCompletionToolDefinition}
3939
3968
  let xmlToolGuidelines = `
3940
3969
  # Tool Use Formatting
3941
3970
 
3942
- Tool use MUST be formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. You MUST use exactly ONE tool call per message until you are ready to complete the task.
3971
+ Tool use MUST be formatted using XML-style tags. Each tool call requires BOTH opening and closing tags with the exact tool name. Each parameter is similarly enclosed within its own set of opening and closing tags. You MUST use exactly ONE tool call per message until you are ready to complete the task.
3972
+
3973
+ **CRITICAL: Every XML tag MUST have both opening <tag> and closing </tag> parts.**
3943
3974
 
3944
- Structure:
3975
+ Structure (note the closing tags):
3945
3976
  <tool_name>
3946
3977
  <parameter1_name>value1</parameter1_name>
3947
3978
  <parameter2_name>value2</parameter2_name>
3948
3979
  ...
3949
3980
  </tool_name>
3950
3981
 
3951
- Example:
3982
+ Examples:
3952
3983
  <search>
3953
3984
  <query>error handling</query>
3954
3985
  <path>src/search</path>
3955
3986
  </search>
3956
3987
 
3988
+ <extract>
3989
+ <path>src/config.js</path>
3990
+ <start_line>15</start_line>
3991
+ <end_line>25</end_line>
3992
+ </extract>
3993
+
3994
+ <attempt_completion>
3995
+ <result>The configuration is loaded from src/config.js lines 15-25 which contains the database settings.</result>
3996
+ </attempt_completion>
3997
+
3998
+ # Special Case: Quick Completion
3999
+ If your previous response was already correct and complete, you may respond with just:
4000
+ <attempt_complete>
4001
+ This signals to use your previous response as the final answer without repeating content.
4002
+
3957
4003
  # Thinking Process
3958
4004
 
3959
4005
  Before using a tool, analyze the situation within <thinking></thinking> tags. This helps you organize your thoughts and make better decisions.
@@ -3968,12 +4014,13 @@ I need to find code related to error handling in the search module. The most app
3968
4014
  1. Think step-by-step about how to achieve the user's goal.
3969
4015
  2. Use <thinking></thinking> tags to analyze the situation and determine the appropriate tool.
3970
4016
  3. Choose **one** tool that helps achieve the current step.
3971
- 4. Format the tool call using the specified XML format. Ensure all required parameters are included.
4017
+ 4. Format the tool call using the specified XML format with BOTH opening and closing tags. Ensure all required parameters are included.
3972
4018
  5. **You MUST respond with exactly one tool call in the specified XML format in each turn.**
3973
4019
  6. Wait for the tool execution result, which will be provided in the next message (within a <tool_result> block).
3974
4020
  7. Analyze the tool result and decide the next step. If more tool calls are needed, repeat steps 2-6.
3975
4021
  8. If the task is fully complete and all previous steps were successful, use the \`<attempt_completion>\` tool to provide the final answer. This is the ONLY way to finish the task.
3976
4022
  9. If you cannot proceed (e.g., missing information, invalid request), explain the issue clearly before using \`<attempt_completion>\` with an appropriate message in the \`<result>\` tag.
4023
+ 10. If your previous response was already correct and complete, you may use \`<attempt_complete>\` as a shorthand.
3977
4024
 
3978
4025
  Available Tools:
3979
4026
  - search: Search code using keyword queries.
@@ -3983,6 +4030,7 @@ Available Tools:
3983
4030
  - searchFiles: Find files matching a glob pattern with recursive search capability.
3984
4031
  ${this.allowEdit ? "- implement: Implement a feature or fix a bug using aider.\n" : ""}
3985
4032
  - attempt_completion: Finalize the task and provide the result to the user.
4033
+ - attempt_complete: Quick completion using previous response (shorthand).
3986
4034
  `;
3987
4035
  const commonInstructions = `<instructions>
3988
4036
  Follow these instructions carefully:
@@ -4259,13 +4307,26 @@ You are working with a repository located at: ${searchDirectory}
4259
4307
  if (this.debug) console.log(`[DEBUG] Parsed tool call: ${toolName} with params:`, params);
4260
4308
  if (toolName === "attempt_completion") {
4261
4309
  completionAttempted = true;
4262
- const validation = attemptCompletionSchema.safeParse(params);
4263
- if (validation.success) {
4264
- finalResult = validation.data.result;
4265
- if (this.debug) console.log(`[DEBUG] Task completed successfully with result: ${finalResult.substring(0, 100)}...`);
4310
+ if (params.result === "__PREVIOUS_RESPONSE__") {
4311
+ const lastAssistantMessage = [...currentMessages].reverse().find(
4312
+ (msg) => msg.role === "assistant" && msg.content && !parseXmlToolCallWithThinking(msg.content, validTools)
4313
+ );
4314
+ if (lastAssistantMessage) {
4315
+ finalResult = lastAssistantMessage.content;
4316
+ if (this.debug) console.log(`[DEBUG] Using previous response as completion: ${finalResult.substring(0, 100)}...`);
4317
+ } else {
4318
+ finalResult = "Error: No previous response found to use as completion.";
4319
+ if (this.debug) console.log(`[DEBUG] No suitable previous response found for attempt_complete shorthand`);
4320
+ }
4266
4321
  } else {
4267
- console.error(`[ERROR] Invalid attempt_completion parameters:`, validation.error);
4268
- finalResult = "Error: Invalid completion attempt. The task could not be completed properly.";
4322
+ const validation = attemptCompletionSchema.safeParse(params);
4323
+ if (validation.success) {
4324
+ finalResult = validation.data.result;
4325
+ if (this.debug) console.log(`[DEBUG] Task completed successfully with result: ${finalResult.substring(0, 100)}...`);
4326
+ } else {
4327
+ console.error(`[ERROR] Invalid attempt_completion parameters:`, validation.error);
4328
+ finalResult = "Error: Invalid completion attempt. The task could not be completed properly.";
4329
+ }
4269
4330
  }
4270
4331
  break;
4271
4332
  } else {
@@ -4363,9 +4424,40 @@ Error: Unknown tool '${toolName}'. Available tools: ${Object.keys(this.toolImple
4363
4424
  }
4364
4425
  } else {
4365
4426
  currentMessages.push({ role: "assistant", content: assistantResponseContent });
4427
+ let reminderContent;
4428
+ if (options.schema) {
4429
+ reminderContent = `Please use one of the available tools to help answer the question, or use attempt_completion if you have enough information to provide a final answer.
4430
+
4431
+ Remember: Use proper XML format with BOTH opening and closing tags:
4432
+
4433
+ <tool_name>
4434
+ <parameter>value</parameter>
4435
+ </tool_name>
4436
+
4437
+ IMPORTANT: A schema was provided. You MUST respond with data that matches this schema.
4438
+ Use attempt_completion with your response directly inside the tags:
4439
+
4440
+ <attempt_completion>
4441
+ {"key": "value", "field": "your actual data here matching the schema"}
4442
+ </attempt_completion>
4443
+
4444
+ Your response must conform to this schema:
4445
+ ${options.schema}`;
4446
+ } else {
4447
+ reminderContent = `Please use one of the available tools to help answer the question, or use attempt_completion if you have enough information to provide a final answer.
4448
+
4449
+ Remember: Use proper XML format with BOTH opening and closing tags:
4450
+
4451
+ <tool_name>
4452
+ <parameter>value</parameter>
4453
+ </tool_name>
4454
+
4455
+ Or for quick completion if your previous response was already correct:
4456
+ <attempt_complete>`;
4457
+ }
4366
4458
  currentMessages.push({
4367
4459
  role: "user",
4368
- content: "Please use one of the available tools to help answer the question, or use attempt_completion if you have enough information to provide a final answer."
4460
+ content: reminderContent
4369
4461
  });
4370
4462
  if (this.debug) {
4371
4463
  console.log(`[DEBUG] No tool call detected in assistant response. Prompting for tool use.`);
@@ -126,7 +126,7 @@ User: Find all markdown files in the docs directory, but only at the top level.
126
126
  `;
127
127
 
128
128
  /**
129
- * Enhanced XML parser that handles thinking tags
129
+ * Enhanced XML parser that handles thinking tags and attempt_complete shorthand
130
130
  * This function removes any <thinking></thinking> tags from the input string
131
131
  * before passing it to the original parseXmlToolCall function
132
132
  * @param {string} xmlString - The XML string to parse
@@ -139,7 +139,17 @@ export function parseXmlToolCallWithThinking(xmlString, validTools) {
139
139
  const thinkingContent = thinkingMatch ? thinkingMatch[1].trim() : null;
140
140
 
141
141
  // Remove thinking tags and their content from the XML string
142
- const cleanedXmlString = xmlString.replace(/<thinking>[\s\S]*?<\/thinking>/g, '').trim();
142
+ let cleanedXmlString = xmlString.replace(/<thinking>[\s\S]*?<\/thinking>/g, '').trim();
143
+
144
+ // Check for attempt_complete shorthand (single tag with no closing tag and no parameters)
145
+ const attemptCompleteMatch = cleanedXmlString.match(/^<attempt_complete>\s*$/);
146
+ if (attemptCompleteMatch) {
147
+ // Convert shorthand to full attempt_completion format with special marker
148
+ return {
149
+ toolName: 'attempt_completion',
150
+ params: { result: '__PREVIOUS_RESPONSE__' }
151
+ };
152
+ }
143
153
 
144
154
  // Use the original parseXmlToolCall function to parse the cleaned XML string
145
155
  const parsedTool = parseXmlToolCall(cleanedXmlString, validTools);