@probelabs/probe 0.6.0-rc161 → 0.6.0-rc162
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/README.md +89 -0
- package/build/agent/ProbeAgent.js +349 -85
- package/build/agent/contextCompactor.js +271 -0
- package/build/agent/index.js +788 -84
- package/build/agent/schemaUtils.js +7 -0
- package/build/agent/xmlParsingUtils.js +24 -4
- package/build/tools/common.js +16 -1
- package/cjs/agent/ProbeAgent.cjs +823 -134
- package/cjs/index.cjs +823 -134
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +349 -85
- package/src/agent/contextCompactor.js +271 -0
- package/src/agent/index.js +30 -1
- package/src/agent/schemaUtils.js +7 -0
- package/src/agent/xmlParsingUtils.js +24 -4
- package/src/tools/common.js +16 -1
|
@@ -100,6 +100,13 @@ export function decodeHtmlEntities(text) {
|
|
|
100
100
|
/**
|
|
101
101
|
* Clean AI response by extracting JSON content when response contains JSON
|
|
102
102
|
* Only processes responses that contain JSON structures { or [
|
|
103
|
+
*
|
|
104
|
+
* NOTE: This function handles both JSON extraction AND content stripping.
|
|
105
|
+
* Future improvement: Consider splitting into separate functions for better separation of concerns:
|
|
106
|
+
* - extractJsonContent() - Find and extract JSON from response
|
|
107
|
+
* - stripNonJsonContent() - Remove explanatory text while preserving validation-relevant content
|
|
108
|
+
* This would allow validation to run on full responses before content is discarded.
|
|
109
|
+
*
|
|
103
110
|
* @param {string} response - Raw AI response
|
|
104
111
|
* @returns {string} - Cleaned response with JSON boundaries extracted if applicable
|
|
105
112
|
*/
|
|
@@ -59,10 +59,30 @@ export function extractThinkingContent(xmlString) {
|
|
|
59
59
|
export function checkAttemptCompleteRecovery(cleanedXmlString, validTools = []) {
|
|
60
60
|
// Check for <attempt_completion> with content (with or without closing tag)
|
|
61
61
|
// This handles: "<attempt_completion>content" or "<attempt_completion>content</attempt_completion>"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
|
|
63
|
+
// IMPORTANT: Use greedy match ([\s\S]*) instead of non-greedy ([\s\S]*?) to handle cases
|
|
64
|
+
// where the content contains the string "</attempt_completion>" (e.g., in regex patterns or code examples).
|
|
65
|
+
// We want to find the LAST occurrence of </attempt_completion>, not the first one.
|
|
66
|
+
const openTagIndex = cleanedXmlString.indexOf('<attempt_completion>');
|
|
67
|
+
if (openTagIndex !== -1) {
|
|
68
|
+
const afterOpenTag = cleanedXmlString.substring(openTagIndex + '<attempt_completion>'.length);
|
|
69
|
+
const closeTagIndex = cleanedXmlString.lastIndexOf('</attempt_completion>');
|
|
70
|
+
|
|
71
|
+
let content;
|
|
72
|
+
let hasClosingTag = false;
|
|
73
|
+
|
|
74
|
+
if (closeTagIndex !== -1 && closeTagIndex >= openTagIndex + '<attempt_completion>'.length) {
|
|
75
|
+
// Found a closing tag at or after the opening tag - extract content between them
|
|
76
|
+
content = cleanedXmlString.substring(
|
|
77
|
+
openTagIndex + '<attempt_completion>'.length,
|
|
78
|
+
closeTagIndex
|
|
79
|
+
).trim();
|
|
80
|
+
hasClosingTag = true;
|
|
81
|
+
} else {
|
|
82
|
+
// No closing tag - use content from opening tag to end of string
|
|
83
|
+
content = afterOpenTag.trim();
|
|
84
|
+
hasClosingTag = false;
|
|
85
|
+
}
|
|
66
86
|
|
|
67
87
|
if (content) {
|
|
68
88
|
// If there's content after the tag, use it as the result
|
package/build/tools/common.js
CHANGED
|
@@ -384,7 +384,22 @@ export function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
|
|
|
384
384
|
continue; // Tool not found, try next tool
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
-
|
|
387
|
+
// For attempt_completion, use lastIndexOf to find the LAST occurrence of closing tag
|
|
388
|
+
// This prevents issues where the content contains the closing tag string (e.g., in regex patterns)
|
|
389
|
+
// For other tools, use indexOf from the opening tag position
|
|
390
|
+
let closeIndex;
|
|
391
|
+
if (toolName === 'attempt_completion') {
|
|
392
|
+
// Find the last occurrence of the closing tag in the entire string
|
|
393
|
+
// This assumes attempt_completion doesn't have nested tags of the same name
|
|
394
|
+
closeIndex = xmlString.lastIndexOf(closeTag);
|
|
395
|
+
// Make sure the closing tag is after the opening tag
|
|
396
|
+
if (closeIndex !== -1 && closeIndex <= openIndex + openTag.length) {
|
|
397
|
+
closeIndex = -1; // Invalid, treat as no closing tag
|
|
398
|
+
}
|
|
399
|
+
} else {
|
|
400
|
+
closeIndex = xmlString.indexOf(closeTag, openIndex + openTag.length);
|
|
401
|
+
}
|
|
402
|
+
|
|
388
403
|
let hasClosingTag = closeIndex !== -1;
|
|
389
404
|
|
|
390
405
|
// If no closing tag found, use content until end of string
|