@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.
- package/build/agent/ProbeAgent.js +86 -11
- package/build/agent/index.js +144 -52
- package/build/agent/tools.js +12 -2
- package/build/tools/common.js +47 -40
- package/build/tools/langchain.js +2 -2
- package/build/tools/vercel.js +7 -7
- package/cjs/agent/ProbeAgent.cjs +144 -52
- package/cjs/index.cjs +146 -54
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +86 -11
- package/src/agent/tools.js +12 -2
- package/src/tools/common.js +47 -40
- package/src/tools/langchain.js +2 -2
- package/src/tools/vercel.js +7 -7
|
@@ -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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
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
|
-
|
|
627
|
-
|
|
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:
|
|
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.`);
|
package/build/agent/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
|
1716
|
-
Usage
|
|
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 ({
|
|
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 (
|
|
2034
|
-
console.error(`Executing extract with
|
|
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 (
|
|
2062
|
-
const files = [
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
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
|
-
|
|
4268
|
-
|
|
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:
|
|
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.`);
|
package/build/agent/tools.js
CHANGED
|
@@ -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
|
-
|
|
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);
|