@probelabs/probe 0.6.0-rc284 → 0.6.0-rc286
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/bin/binaries/probe-v0.6.0-rc286-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/{probe-v0.6.0-rc284-aarch64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc286-aarch64-unknown-linux-musl.tar.gz} +0 -0
- package/bin/binaries/probe-v0.6.0-rc286-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc286-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc286-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.d.ts +1 -1
- package/build/agent/ProbeAgent.js +353 -489
- package/build/agent/contextCompactor.js +17 -10
- package/build/agent/index.js +325 -719
- package/build/agent/schemaUtils.js +10 -11
- package/build/agent/shared/prompts.js +2 -2
- package/build/agent/tasks/taskTool.js +3 -3
- package/build/agent/tools.js +0 -2
- package/build/downloader.js +5 -1
- package/build/index.js +0 -2
- package/build/tools/analyzeAll.js +4 -4
- package/build/tools/common.js +55 -55
- package/build/tools/index.js +0 -1
- package/build/tools/vercel.js +10 -8
- package/cjs/agent/ProbeAgent.cjs +316 -775
- package/cjs/index.cjs +317 -831
- package/package.json +1 -1
- package/src/agent/ProbeAgent.d.ts +1 -1
- package/src/agent/ProbeAgent.js +353 -489
- package/src/agent/contextCompactor.js +17 -10
- package/src/agent/index.js +8 -2
- package/src/agent/schemaUtils.js +10 -11
- package/src/agent/shared/prompts.js +2 -2
- package/src/agent/tasks/taskTool.js +3 -3
- package/src/agent/tools.js +0 -2
- package/src/downloader.js +5 -1
- package/src/index.js +0 -2
- package/src/tools/analyzeAll.js +4 -4
- package/src/tools/common.js +55 -55
- package/src/tools/index.js +0 -1
- package/src/tools/vercel.js +10 -8
- package/bin/binaries/probe-v0.6.0-rc284-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc284-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc284-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc284-x86_64-unknown-linux-musl.tar.gz +0 -0
package/cjs/index.cjs
CHANGED
|
@@ -1098,7 +1098,11 @@ async function extractBinary(assetPath, outputDir) {
|
|
|
1098
1098
|
if (process.env.DEBUG === "1" || process.env.VERBOSE === "1") {
|
|
1099
1099
|
console.log(`Extracting zip to ${extractDir}...`);
|
|
1100
1100
|
}
|
|
1101
|
-
|
|
1101
|
+
if (isWindows) {
|
|
1102
|
+
await exec(`powershell -NoProfile -Command "Expand-Archive -Path '${assetPath}' -DestinationPath '${extractDir}' -Force"`);
|
|
1103
|
+
} else {
|
|
1104
|
+
await exec(`unzip -q "${assetPath}" -d "${extractDir}"`);
|
|
1105
|
+
}
|
|
1102
1106
|
} else {
|
|
1103
1107
|
if (process.env.DEBUG === "1" || process.env.VERBOSE === "1") {
|
|
1104
1108
|
console.log(`Copying binary directly to ${binaryPath}`);
|
|
@@ -26682,7 +26686,7 @@ For each pending/in_progress task, either:
|
|
|
26682
26686
|
- Complete it: call task tool with action="complete", id="task-X"
|
|
26683
26687
|
- Cancel it: call task tool with action="update", id="task-X", status="cancelled"
|
|
26684
26688
|
|
|
26685
|
-
After all tasks are resolved,
|
|
26689
|
+
After all tasks are resolved, provide your final answer.`;
|
|
26686
26690
|
}
|
|
26687
26691
|
function createTaskTool(options = {}) {
|
|
26688
26692
|
const { taskManager, tracer, debug = false } = options;
|
|
@@ -26932,13 +26936,13 @@ Tasks = logical units of work, not files or steps.
|
|
|
26932
26936
|
|
|
26933
26937
|
1. **Plan**: Call task tool with action="create" and a tasks array up front
|
|
26934
26938
|
2. **Execute**: Update status to "in_progress" / "completed" as you work. Add, split, or cancel tasks as you learn more.
|
|
26935
|
-
3. **Finish**: All tasks must be "completed" or "cancelled" before
|
|
26939
|
+
3. **Finish**: All tasks must be "completed" or "cancelled" before providing your final answer.
|
|
26936
26940
|
|
|
26937
26941
|
## Rules
|
|
26938
26942
|
|
|
26939
26943
|
- Dependencies are enforced: a task cannot start until its dependencies are completed
|
|
26940
26944
|
- Circular dependencies are rejected
|
|
26941
|
-
-
|
|
26945
|
+
- Completion is blocked while tasks remain unresolved
|
|
26942
26946
|
`;
|
|
26943
26947
|
}
|
|
26944
26948
|
});
|
|
@@ -27017,6 +27021,34 @@ function createMessagePreview(message, charsPerSide = 200) {
|
|
|
27017
27021
|
const end = message.substring(message.length - charsPerSide);
|
|
27018
27022
|
return `${start}...${end}`;
|
|
27019
27023
|
}
|
|
27024
|
+
function detectStuckResponse(response) {
|
|
27025
|
+
if (!response || typeof response !== "string") {
|
|
27026
|
+
return false;
|
|
27027
|
+
}
|
|
27028
|
+
const stuckPatterns = [
|
|
27029
|
+
/\bi\s+cannot\s+proceed\b/i,
|
|
27030
|
+
/\bi\s+can['']t\s+(?:proceed|continue|move\s+forward)\b/i,
|
|
27031
|
+
/\bunable\s+to\s+(?:proceed|continue|complete)\b/i,
|
|
27032
|
+
/\bblocked\b.*\b(?:proceed|continue)\b/i,
|
|
27033
|
+
/\bneed\s+(?:the|an?)\s+\w+(?:\s+\w+)?\s+to\s+(?:proceed|continue)\b/i,
|
|
27034
|
+
/\brequire[sd]?\s+(?:the|an?)\s+\w+\b.*\bto\s+(?:proceed|continue)\b/i,
|
|
27035
|
+
/\bmissing\s+(?:required|necessary|essential)\b/i,
|
|
27036
|
+
/\bdeadlock\b/i,
|
|
27037
|
+
/\bwe\s+are\s+in\s+a\s+loop\b/i,
|
|
27038
|
+
/\bstuck\s+in\s+a\s+loop\b/i,
|
|
27039
|
+
/\bi\s+(?:have|['']ve)\s+(?:explained|stated|mentioned)\s+(?:this|the\s+situation|it)\s+(?:multiple|several)\s+times\b/i,
|
|
27040
|
+
/\bi\s+(?:cannot|can['']t|could\s+not|couldn['']t)\s+(?:find|locate|get|retrieve|obtain)\s+(?:the|this|that|an?)\b/i,
|
|
27041
|
+
/\bno\s+way\s+to\s+(?:find|get|obtain|retrieve)\b/i,
|
|
27042
|
+
/\bi\s+(?:have|['']ve)\s+exhausted\s+(?:all|my)\s+(?:available\s+)?(?:options|methods|approaches)\b/i,
|
|
27043
|
+
/\bneither\s+of\s+these\s+methods\b/i
|
|
27044
|
+
];
|
|
27045
|
+
for (const pattern of stuckPatterns) {
|
|
27046
|
+
if (pattern.test(response)) {
|
|
27047
|
+
return true;
|
|
27048
|
+
}
|
|
27049
|
+
}
|
|
27050
|
+
return false;
|
|
27051
|
+
}
|
|
27020
27052
|
function parseTargets(targets) {
|
|
27021
27053
|
if (!targets || typeof targets !== "string") {
|
|
27022
27054
|
return [];
|
|
@@ -27053,7 +27085,7 @@ function resolveTargetPath(target, cwd) {
|
|
|
27053
27085
|
}
|
|
27054
27086
|
return filePart + suffix;
|
|
27055
27087
|
}
|
|
27056
|
-
var import_path5, searchSchema, searchAllSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, listFilesSchema, searchFilesSchema, readImageSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema,
|
|
27088
|
+
var import_path5, searchSchema, searchAllSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, listFilesSchema, searchFilesSchema, readImageSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema, searchDescription, searchDelegateDescription, queryDescription, extractDescription, delegateDescription, bashDescription, analyzeAllDescription;
|
|
27057
27089
|
var init_common = __esm({
|
|
27058
27090
|
"src/tools/common.js"() {
|
|
27059
27091
|
"use strict";
|
|
@@ -27123,58 +27155,6 @@ var init_common = __esm({
|
|
|
27123
27155
|
clearOutputBuffer: external_exports2.boolean().optional().default(true).describe("Clear the output buffer from previous execute_plan calls"),
|
|
27124
27156
|
clearSessionStore: external_exports2.boolean().optional().default(false).describe("Clear the session store (persisted data across execute_plan calls)")
|
|
27125
27157
|
});
|
|
27126
|
-
attemptCompletionSchema = {
|
|
27127
|
-
// Custom validation that requires result parameter but allows direct XML response
|
|
27128
|
-
safeParse: (params) => {
|
|
27129
|
-
if (!params || typeof params !== "object") {
|
|
27130
|
-
return {
|
|
27131
|
-
success: false,
|
|
27132
|
-
error: {
|
|
27133
|
-
issues: [{
|
|
27134
|
-
code: "invalid_type",
|
|
27135
|
-
expected: "object",
|
|
27136
|
-
received: typeof params,
|
|
27137
|
-
path: [],
|
|
27138
|
-
message: "Expected object"
|
|
27139
|
-
}]
|
|
27140
|
-
}
|
|
27141
|
-
};
|
|
27142
|
-
}
|
|
27143
|
-
if (!("result" in params)) {
|
|
27144
|
-
return {
|
|
27145
|
-
success: false,
|
|
27146
|
-
error: {
|
|
27147
|
-
issues: [{
|
|
27148
|
-
code: "invalid_type",
|
|
27149
|
-
expected: "string",
|
|
27150
|
-
received: "undefined",
|
|
27151
|
-
path: ["result"],
|
|
27152
|
-
message: "Required"
|
|
27153
|
-
}]
|
|
27154
|
-
}
|
|
27155
|
-
};
|
|
27156
|
-
}
|
|
27157
|
-
if (typeof params.result !== "string") {
|
|
27158
|
-
return {
|
|
27159
|
-
success: false,
|
|
27160
|
-
error: {
|
|
27161
|
-
issues: [{
|
|
27162
|
-
code: "invalid_type",
|
|
27163
|
-
expected: "string",
|
|
27164
|
-
received: typeof params.result,
|
|
27165
|
-
path: ["result"],
|
|
27166
|
-
message: "Expected string"
|
|
27167
|
-
}]
|
|
27168
|
-
}
|
|
27169
|
-
};
|
|
27170
|
-
}
|
|
27171
|
-
const filteredData = { result: params.result };
|
|
27172
|
-
return {
|
|
27173
|
-
success: true,
|
|
27174
|
-
data: filteredData
|
|
27175
|
-
};
|
|
27176
|
-
}
|
|
27177
|
-
};
|
|
27178
27158
|
searchDescription = 'Search code in the repository. Free-form questions are accepted, but Elasticsearch-style keyword queries work best. Use this tool first for any code-related questions. NOTE: By default, search handles stemming, case-insensitive matching, and camelCase/snake_case splitting automatically \u2014 do NOT manually try keyword variations like "getAllUsers" then "get_all_users" then "GetAllUsers". One search covers all variations.';
|
|
27179
27159
|
searchDelegateDescription = 'Search code in the repository by asking a question. Accepts natural language questions (e.g., "How does authentication work?", "Where is the user validation logic?"). A specialized subagent breaks down your question into targeted keyword searches and returns extracted code blocks. Do NOT formulate keyword queries yourself \u2014 just ask the question naturally.';
|
|
27180
27160
|
queryDescription = "Search code using ast-grep structural pattern matching. Use this tool to find specific code structures like functions, classes, or methods.";
|
|
@@ -71535,68 +71515,9 @@ var require_ajv = __commonJS({
|
|
|
71535
71515
|
});
|
|
71536
71516
|
|
|
71537
71517
|
// src/agent/schemaUtils.js
|
|
71538
|
-
var schemaUtils_exports = {};
|
|
71539
|
-
__export(schemaUtils_exports, {
|
|
71540
|
-
JsonFixingAgent: () => JsonFixingAgent,
|
|
71541
|
-
MermaidFixingAgent: () => MermaidFixingAgent,
|
|
71542
|
-
cleanSchemaResponse: () => cleanSchemaResponse,
|
|
71543
|
-
createJsonCorrectionPrompt: () => createJsonCorrectionPrompt,
|
|
71544
|
-
createMermaidCorrectionPrompt: () => createMermaidCorrectionPrompt,
|
|
71545
|
-
createSchemaDefinitionCorrectionPrompt: () => createSchemaDefinitionCorrectionPrompt,
|
|
71546
|
-
decodeHtmlEntities: () => decodeHtmlEntities,
|
|
71547
|
-
extractMermaidFromJson: () => extractMermaidFromJson,
|
|
71548
|
-
extractMermaidFromMarkdown: () => extractMermaidFromMarkdown,
|
|
71549
|
-
generateExampleFromSchema: () => generateExampleFromSchema,
|
|
71550
|
-
generateSchemaInstructions: () => generateSchemaInstructions,
|
|
71551
|
-
isJsonSchema: () => isJsonSchema,
|
|
71552
|
-
isJsonSchemaDefinition: () => isJsonSchemaDefinition,
|
|
71553
|
-
isMermaidSchema: () => isMermaidSchema,
|
|
71554
|
-
isSimpleTextWrapperSchema: () => isSimpleTextWrapperSchema,
|
|
71555
|
-
processSchemaResponse: () => processSchemaResponse,
|
|
71556
|
-
replaceMermaidDiagramsInJson: () => replaceMermaidDiagramsInJson,
|
|
71557
|
-
replaceMermaidDiagramsInMarkdown: () => replaceMermaidDiagramsInMarkdown,
|
|
71558
|
-
sanitizeMarkdownEscapesInJson: () => sanitizeMarkdownEscapesInJson,
|
|
71559
|
-
tryAutoWrapForSimpleSchema: () => tryAutoWrapForSimpleSchema,
|
|
71560
|
-
tryExtractValidJsonPrefix: () => tryExtractValidJsonPrefix,
|
|
71561
|
-
tryMaidAutoFix: () => tryMaidAutoFix,
|
|
71562
|
-
validateAndFixMermaidResponse: () => validateAndFixMermaidResponse,
|
|
71563
|
-
validateJsonResponse: () => validateJsonResponse,
|
|
71564
|
-
validateMermaidDiagram: () => validateMermaidDiagram,
|
|
71565
|
-
validateMermaidResponse: () => validateMermaidResponse,
|
|
71566
|
-
validateXmlResponse: () => validateXmlResponse
|
|
71567
|
-
});
|
|
71568
|
-
function generateExampleFromSchema(schema, options = {}) {
|
|
71569
|
-
const { debug = false } = options;
|
|
71570
|
-
try {
|
|
71571
|
-
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
71572
|
-
if (parsedSchema.type !== "object" || !parsedSchema.properties) {
|
|
71573
|
-
return null;
|
|
71574
|
-
}
|
|
71575
|
-
const exampleObj = {};
|
|
71576
|
-
for (const [key, value] of Object.entries(parsedSchema.properties)) {
|
|
71577
|
-
if (value.type === "boolean") {
|
|
71578
|
-
exampleObj[key] = false;
|
|
71579
|
-
} else if (value.type === "number") {
|
|
71580
|
-
exampleObj[key] = 0;
|
|
71581
|
-
} else if (value.type === "string") {
|
|
71582
|
-
exampleObj[key] = value.description || "your answer here";
|
|
71583
|
-
} else if (value.type === "array") {
|
|
71584
|
-
exampleObj[key] = [];
|
|
71585
|
-
} else {
|
|
71586
|
-
exampleObj[key] = {};
|
|
71587
|
-
}
|
|
71588
|
-
}
|
|
71589
|
-
return exampleObj;
|
|
71590
|
-
} catch (e) {
|
|
71591
|
-
if (debug) {
|
|
71592
|
-
console.error("[DEBUG] generateExampleFromSchema: Failed to parse schema:", e.message);
|
|
71593
|
-
}
|
|
71594
|
-
return null;
|
|
71595
|
-
}
|
|
71596
|
-
}
|
|
71597
71518
|
function generateSchemaInstructions(schema, options = {}) {
|
|
71598
71519
|
const { debug = false } = options;
|
|
71599
|
-
let instructions = "\n\nIMPORTANT: When you provide your final answer
|
|
71520
|
+
let instructions = "\n\nIMPORTANT: When you provide your final answer, you MUST format it as valid JSON matching this schema:\n\n";
|
|
71600
71521
|
try {
|
|
71601
71522
|
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
71602
71523
|
instructions += `${JSON.stringify(parsedSchema, null, 2)}
|
|
@@ -71610,7 +71531,7 @@ function generateSchemaInstructions(schema, options = {}) {
|
|
|
71610
71531
|
|
|
71611
71532
|
`;
|
|
71612
71533
|
}
|
|
71613
|
-
instructions += "Your response
|
|
71534
|
+
instructions += "Your final response must be ONLY valid JSON - no plain text, no explanations, no markdown.\n\nIMPORTANT: First complete the requested analysis/task thoroughly, then provide your final answer in the JSON format above.";
|
|
71614
71535
|
return instructions;
|
|
71615
71536
|
}
|
|
71616
71537
|
function enforceNoAdditionalProperties(schema) {
|
|
@@ -72107,65 +72028,6 @@ function tryExtractValidJsonPrefix(response, options = {}) {
|
|
|
72107
72028
|
return null;
|
|
72108
72029
|
}
|
|
72109
72030
|
}
|
|
72110
|
-
function validateXmlResponse(response) {
|
|
72111
|
-
const xmlPattern = /<\/?[\w\s="'.-]+>/g;
|
|
72112
|
-
const tags = response.match(xmlPattern);
|
|
72113
|
-
if (!tags) {
|
|
72114
|
-
return { isValid: false, error: "No XML tags found" };
|
|
72115
|
-
}
|
|
72116
|
-
if (response.includes("<") && response.includes(">")) {
|
|
72117
|
-
return { isValid: true };
|
|
72118
|
-
}
|
|
72119
|
-
return { isValid: false, error: "Invalid XML structure" };
|
|
72120
|
-
}
|
|
72121
|
-
function processSchemaResponse(response, schema, options = {}) {
|
|
72122
|
-
const { validateJson = false, validateXml = false, debug = false } = options;
|
|
72123
|
-
if (debug) {
|
|
72124
|
-
console.log(`[DEBUG] Schema processing: Starting with response length ${response.length}`);
|
|
72125
|
-
console.log(`[DEBUG] Schema processing: Schema type detection...`);
|
|
72126
|
-
if (isJsonSchema(schema)) {
|
|
72127
|
-
console.log(`[DEBUG] Schema processing: Detected JSON schema`);
|
|
72128
|
-
} else {
|
|
72129
|
-
console.log(`[DEBUG] Schema processing: Non-JSON schema detected`);
|
|
72130
|
-
}
|
|
72131
|
-
}
|
|
72132
|
-
const cleanStart = Date.now();
|
|
72133
|
-
const cleaned = cleanSchemaResponse(response);
|
|
72134
|
-
const cleanTime = Date.now() - cleanStart;
|
|
72135
|
-
const result = { cleaned };
|
|
72136
|
-
if (debug) {
|
|
72137
|
-
console.log(`[DEBUG] Schema processing: Cleaning completed in ${cleanTime}ms`);
|
|
72138
|
-
result.debug = {
|
|
72139
|
-
originalLength: response.length,
|
|
72140
|
-
cleanedLength: cleaned.length,
|
|
72141
|
-
wasModified: response !== cleaned,
|
|
72142
|
-
cleaningTimeMs: cleanTime,
|
|
72143
|
-
removedContent: response !== cleaned ? {
|
|
72144
|
-
before: response.substring(0, 100) + (response.length > 100 ? "..." : ""),
|
|
72145
|
-
after: cleaned.substring(0, 100) + (cleaned.length > 100 ? "..." : "")
|
|
72146
|
-
} : null
|
|
72147
|
-
};
|
|
72148
|
-
if (response !== cleaned) {
|
|
72149
|
-
console.log(`[DEBUG] Schema processing: Response was modified during cleaning`);
|
|
72150
|
-
console.log(`[DEBUG] Schema processing: Original length: ${response.length}, cleaned length: ${cleaned.length}`);
|
|
72151
|
-
} else {
|
|
72152
|
-
console.log(`[DEBUG] Schema processing: Response unchanged during cleaning`);
|
|
72153
|
-
}
|
|
72154
|
-
}
|
|
72155
|
-
if (validateJson) {
|
|
72156
|
-
if (debug) {
|
|
72157
|
-
console.log(`[DEBUG] Schema processing: Running JSON validation...`);
|
|
72158
|
-
}
|
|
72159
|
-
result.jsonValidation = validateJsonResponse(cleaned, { debug });
|
|
72160
|
-
}
|
|
72161
|
-
if (validateXml) {
|
|
72162
|
-
if (debug) {
|
|
72163
|
-
console.log(`[DEBUG] Schema processing: Running XML validation...`);
|
|
72164
|
-
}
|
|
72165
|
-
result.xmlValidation = validateXmlResponse(cleaned);
|
|
72166
|
-
}
|
|
72167
|
-
return result;
|
|
72168
|
-
}
|
|
72169
72031
|
function isJsonSchema(schema) {
|
|
72170
72032
|
if (!schema || typeof schema !== "string") {
|
|
72171
72033
|
return false;
|
|
@@ -72307,18 +72169,18 @@ function createJsonCorrectionPrompt(invalidResponse, schema, errorOrValidation,
|
|
|
72307
72169
|
const strengthLevels = [
|
|
72308
72170
|
{
|
|
72309
72171
|
prefix: "CRITICAL JSON ERROR:",
|
|
72310
|
-
instruction: "You MUST fix this and respond
|
|
72311
|
-
emphasis: "
|
|
72172
|
+
instruction: "You MUST fix this and respond with ONLY valid JSON.",
|
|
72173
|
+
emphasis: "Respond with ONLY the corrected JSON. No explanatory text, no markdown, no code blocks."
|
|
72312
72174
|
},
|
|
72313
72175
|
{
|
|
72314
72176
|
prefix: "URGENT - JSON PARSING FAILED:",
|
|
72315
|
-
instruction: "This is your second chance.
|
|
72316
|
-
emphasis: "ABSOLUTELY NO explanatory text or formatting.
|
|
72177
|
+
instruction: "This is your second chance. Respond with valid JSON that can be parsed by JSON.parse().",
|
|
72178
|
+
emphasis: "ABSOLUTELY NO explanatory text or formatting. Respond with ONLY raw JSON."
|
|
72317
72179
|
},
|
|
72318
72180
|
{
|
|
72319
72181
|
prefix: "FINAL ATTEMPT - CRITICAL JSON ERROR:",
|
|
72320
|
-
instruction: "This is the final retry. You MUST
|
|
72321
|
-
emphasis: 'CORRECT:
|
|
72182
|
+
instruction: "This is the final retry. You MUST respond with ONLY raw JSON.",
|
|
72183
|
+
emphasis: 'CORRECT: {"key": "value"}\nWRONG: Here is the JSON: {"key": "value"}\nWRONG: ```json{"key": "value"}```'
|
|
72322
72184
|
}
|
|
72323
72185
|
];
|
|
72324
72186
|
const level = Math.min(retryCount, strengthLevels.length - 1);
|
|
@@ -72372,28 +72234,6 @@ ${currentLevel.example}
|
|
|
72372
72234
|
Return ONLY the JSON data object/array that follows the schema structure. NO schema definitions, NO explanations, NO markdown formatting.`;
|
|
72373
72235
|
return prompt;
|
|
72374
72236
|
}
|
|
72375
|
-
function isMermaidSchema(schema) {
|
|
72376
|
-
if (!schema || typeof schema !== "string") {
|
|
72377
|
-
return false;
|
|
72378
|
-
}
|
|
72379
|
-
const trimmedSchema = schema.trim().toLowerCase();
|
|
72380
|
-
const mermaidIndicators = [
|
|
72381
|
-
trimmedSchema.includes("mermaid"),
|
|
72382
|
-
trimmedSchema.includes("diagram"),
|
|
72383
|
-
trimmedSchema.includes("flowchart"),
|
|
72384
|
-
trimmedSchema.includes("sequence"),
|
|
72385
|
-
trimmedSchema.includes("gantt"),
|
|
72386
|
-
trimmedSchema.includes("pie chart"),
|
|
72387
|
-
trimmedSchema.includes("state diagram"),
|
|
72388
|
-
trimmedSchema.includes("class diagram"),
|
|
72389
|
-
trimmedSchema.includes("entity relationship"),
|
|
72390
|
-
trimmedSchema.includes("user journey"),
|
|
72391
|
-
trimmedSchema.includes("git graph"),
|
|
72392
|
-
trimmedSchema.includes("requirement diagram"),
|
|
72393
|
-
trimmedSchema.includes("c4 context")
|
|
72394
|
-
];
|
|
72395
|
-
return mermaidIndicators.some((indicator) => indicator);
|
|
72396
|
-
}
|
|
72397
72237
|
function extractMermaidFromJson(response) {
|
|
72398
72238
|
if (!response || typeof response !== "string") {
|
|
72399
72239
|
return { diagrams: [], jsonPaths: [], parsedJson: null };
|
|
@@ -72525,28 +72365,6 @@ ${modifiedJsonString}
|
|
|
72525
72365
|
}
|
|
72526
72366
|
return modifiedJsonString;
|
|
72527
72367
|
}
|
|
72528
|
-
function replaceMermaidDiagramsInMarkdown(originalResponse, correctedDiagrams) {
|
|
72529
|
-
if (!originalResponse || typeof originalResponse !== "string") {
|
|
72530
|
-
return originalResponse;
|
|
72531
|
-
}
|
|
72532
|
-
if (!correctedDiagrams || correctedDiagrams.length === 0) {
|
|
72533
|
-
return originalResponse;
|
|
72534
|
-
}
|
|
72535
|
-
const hasJsonDiagrams = correctedDiagrams.some((d) => d.isInJson);
|
|
72536
|
-
if (hasJsonDiagrams) {
|
|
72537
|
-
return replaceMermaidDiagramsInJson(originalResponse, correctedDiagrams);
|
|
72538
|
-
}
|
|
72539
|
-
let modifiedResponse = originalResponse;
|
|
72540
|
-
const sortedDiagrams = [...correctedDiagrams].sort((a, b) => b.startIndex - a.startIndex);
|
|
72541
|
-
for (const diagram of sortedDiagrams) {
|
|
72542
|
-
const attributesStr = diagram.attributes ? ` ${diagram.attributes}` : "";
|
|
72543
|
-
const newCodeBlock = `\`\`\`mermaid${attributesStr}
|
|
72544
|
-
${diagram.content}
|
|
72545
|
-
\`\`\``;
|
|
72546
|
-
modifiedResponse = modifiedResponse.slice(0, diagram.startIndex) + newCodeBlock + modifiedResponse.slice(diagram.endIndex);
|
|
72547
|
-
}
|
|
72548
|
-
return modifiedResponse;
|
|
72549
|
-
}
|
|
72550
72368
|
function replaceSingleMermaidDiagramInResponse(response, originalDiagram, newContent) {
|
|
72551
72369
|
if (!originalDiagram) {
|
|
72552
72370
|
return response;
|
|
@@ -72631,45 +72449,6 @@ async function validateMermaidResponse(response) {
|
|
|
72631
72449
|
errors: errors.length > 0 ? errors : void 0
|
|
72632
72450
|
};
|
|
72633
72451
|
}
|
|
72634
|
-
function createMermaidCorrectionPrompt(invalidResponse, schema, errors, diagrams) {
|
|
72635
|
-
let prompt = `Your previous response contains invalid Mermaid diagrams that cannot be parsed. Here's what you returned:
|
|
72636
|
-
|
|
72637
|
-
${invalidResponse}
|
|
72638
|
-
|
|
72639
|
-
Validation Errors:`;
|
|
72640
|
-
errors.forEach((error40, index) => {
|
|
72641
|
-
prompt += `
|
|
72642
|
-
${index + 1}. ${error40}`;
|
|
72643
|
-
});
|
|
72644
|
-
if (diagrams && diagrams.length > 0) {
|
|
72645
|
-
prompt += `
|
|
72646
|
-
|
|
72647
|
-
Diagram Details:`;
|
|
72648
|
-
diagrams.forEach((diagramResult, index) => {
|
|
72649
|
-
if (!diagramResult.isValid) {
|
|
72650
|
-
prompt += `
|
|
72651
|
-
|
|
72652
|
-
Diagram ${index + 1}:`;
|
|
72653
|
-
const diagramContent = diagramResult.content || diagramResult.diagram || "";
|
|
72654
|
-
prompt += `
|
|
72655
|
-
- Content: ${diagramContent.substring(0, 100)}${diagramContent.length > 100 ? "..." : ""}`;
|
|
72656
|
-
prompt += `
|
|
72657
|
-
- Error: ${diagramResult.error}`;
|
|
72658
|
-
if (diagramResult.detailedError && diagramResult.detailedError !== diagramResult.error) {
|
|
72659
|
-
prompt += `
|
|
72660
|
-
- Details: ${diagramResult.detailedError}`;
|
|
72661
|
-
}
|
|
72662
|
-
}
|
|
72663
|
-
});
|
|
72664
|
-
}
|
|
72665
|
-
prompt += `
|
|
72666
|
-
|
|
72667
|
-
Please correct your response to include valid Mermaid diagrams that match this schema:
|
|
72668
|
-
${schema}
|
|
72669
|
-
|
|
72670
|
-
Ensure all Mermaid diagrams are properly formatted within \`\`\`mermaid code blocks and follow correct Mermaid syntax.`;
|
|
72671
|
-
return prompt;
|
|
72672
|
-
}
|
|
72673
72452
|
async function tryMaidAutoFix(diagramContent, options = {}) {
|
|
72674
72453
|
const { debug = false } = options;
|
|
72675
72454
|
try {
|
|
@@ -72979,7 +72758,7 @@ async function validateAndFixMermaidResponse(response, options = {}) {
|
|
|
72979
72758
|
};
|
|
72980
72759
|
}
|
|
72981
72760
|
}
|
|
72982
|
-
var import_ajv, HTML_ENTITY_MAP, sessionIdCounter,
|
|
72761
|
+
var import_ajv, HTML_ENTITY_MAP, sessionIdCounter, MermaidFixingAgent;
|
|
72983
72762
|
var init_schemaUtils = __esm({
|
|
72984
72763
|
"src/agent/schemaUtils.js"() {
|
|
72985
72764
|
"use strict";
|
|
@@ -72997,172 +72776,6 @@ var init_schemaUtils = __esm({
|
|
|
72997
72776
|
" ": " "
|
|
72998
72777
|
};
|
|
72999
72778
|
sessionIdCounter = 0;
|
|
73000
|
-
JsonFixingAgent = class {
|
|
73001
|
-
constructor(options = {}) {
|
|
73002
|
-
this.ProbeAgent = null;
|
|
73003
|
-
this.options = {
|
|
73004
|
-
sessionId: options.sessionId || `json-fixer-${Date.now()}-${sessionIdCounter++}`,
|
|
73005
|
-
path: options.path || process.cwd(),
|
|
73006
|
-
provider: options.provider,
|
|
73007
|
-
model: options.model,
|
|
73008
|
-
debug: options.debug,
|
|
73009
|
-
tracer: options.tracer,
|
|
73010
|
-
// Set to false since we're only fixing JSON syntax, not implementing code
|
|
73011
|
-
allowEdit: false
|
|
73012
|
-
};
|
|
73013
|
-
}
|
|
73014
|
-
/**
|
|
73015
|
-
* Get the specialized prompt for JSON fixing
|
|
73016
|
-
*/
|
|
73017
|
-
getJsonFixingPrompt() {
|
|
73018
|
-
return `You are a world-class JSON syntax correction specialist. Your expertise lies in analyzing and fixing JSON syntax errors while preserving the original data structure and intent.
|
|
73019
|
-
|
|
73020
|
-
CORE RESPONSIBILITIES:
|
|
73021
|
-
- Analyze JSON for syntax errors and structural issues
|
|
73022
|
-
- Fix syntax errors while maintaining the original data's semantic meaning
|
|
73023
|
-
- Ensure JSON follows proper RFC 8259 specification
|
|
73024
|
-
- Handle all JSON structures: objects, arrays, primitives, nested structures
|
|
73025
|
-
|
|
73026
|
-
JSON SYNTAX RULES:
|
|
73027
|
-
1. **Property names**: Must be enclosed in double quotes
|
|
73028
|
-
2. **String values**: Must use double quotes (not single quotes)
|
|
73029
|
-
3. **Numbers**: Can be integers or decimals, no quotes needed
|
|
73030
|
-
4. **Booleans**: true or false (lowercase, no quotes)
|
|
73031
|
-
5. **Null**: null (lowercase, no quotes)
|
|
73032
|
-
6. **Arrays**: Comma-separated values in square brackets [...]
|
|
73033
|
-
7. **Objects**: Comma-separated key-value pairs in curly braces {...}
|
|
73034
|
-
8. **No trailing commas**: Last item in array/object must not have a trailing comma
|
|
73035
|
-
9. **Escape sequences**: Special characters must be escaped (\\n, \\t, \\", \\\\, etc.)
|
|
73036
|
-
|
|
73037
|
-
COMMON ERRORS TO FIX:
|
|
73038
|
-
1. **Unquoted property names**: {name: "value"} \u2192 {"name": "value"}
|
|
73039
|
-
2. **Single quotes**: {'key': 'value'} \u2192 {"key": "value"}
|
|
73040
|
-
3. **Trailing commas**: {"a": 1,} \u2192 {"a": 1}
|
|
73041
|
-
4. **Unquoted strings**: {key: value} \u2192 {"key": "value"}
|
|
73042
|
-
5. **Missing commas**: {"a": 1 "b": 2} \u2192 {"a": 1, "b": 2}
|
|
73043
|
-
6. **Extra commas**: {"a": 1,, "b": 2} \u2192 {"a": 1, "b": 2}
|
|
73044
|
-
7. **Unclosed brackets/braces**: {"key": "value" \u2192 {"key": "value"}
|
|
73045
|
-
8. **Invalid escape sequences**: Fix or remove
|
|
73046
|
-
9. **Comments**: Remove // or /* */ comments (not allowed in JSON)
|
|
73047
|
-
10. **Undefined values**: Replace undefined with null
|
|
73048
|
-
|
|
73049
|
-
FIXING METHODOLOGY:
|
|
73050
|
-
1. **Identify the error location** from the error message
|
|
73051
|
-
2. **Analyze the context** around the error
|
|
73052
|
-
3. **Apply the appropriate fix** based on JSON syntax rules
|
|
73053
|
-
4. **Preserve data intent** - never change the meaning of the data
|
|
73054
|
-
5. **Validate the result** - ensure it's parseable JSON
|
|
73055
|
-
|
|
73056
|
-
CRITICAL RULES:
|
|
73057
|
-
- ALWAYS output only the corrected JSON
|
|
73058
|
-
- NEVER add explanations, comments, or additional text
|
|
73059
|
-
- NEVER wrap in markdown code blocks (no \`\`\`json)
|
|
73060
|
-
- PRESERVE the original data structure and values
|
|
73061
|
-
- FIX only syntax errors, don't modify the data itself
|
|
73062
|
-
- ENSURE the output is valid, parseable JSON
|
|
73063
|
-
|
|
73064
|
-
When presented with broken JSON, analyze it thoroughly and provide the corrected version that maintains the original intent while fixing all syntax issues.`;
|
|
73065
|
-
}
|
|
73066
|
-
/**
|
|
73067
|
-
* Initialize the ProbeAgent if not already done
|
|
73068
|
-
*/
|
|
73069
|
-
async initializeAgent() {
|
|
73070
|
-
if (!this.ProbeAgent) {
|
|
73071
|
-
const { ProbeAgent: ProbeAgent2 } = await Promise.resolve().then(() => (init_ProbeAgent(), ProbeAgent_exports));
|
|
73072
|
-
this.ProbeAgent = ProbeAgent2;
|
|
73073
|
-
}
|
|
73074
|
-
if (!this.agent) {
|
|
73075
|
-
this.agent = new this.ProbeAgent({
|
|
73076
|
-
sessionId: this.options.sessionId,
|
|
73077
|
-
customPrompt: this.getJsonFixingPrompt(),
|
|
73078
|
-
path: this.options.path,
|
|
73079
|
-
provider: this.options.provider,
|
|
73080
|
-
model: this.options.model,
|
|
73081
|
-
debug: this.options.debug,
|
|
73082
|
-
tracer: this.options.tracer,
|
|
73083
|
-
allowEdit: this.options.allowEdit,
|
|
73084
|
-
maxIterations: 5,
|
|
73085
|
-
// Allow multiple iterations for JSON fixing
|
|
73086
|
-
disableJsonValidation: true
|
|
73087
|
-
// CRITICAL: Disable JSON validation in nested agent to prevent infinite recursion
|
|
73088
|
-
});
|
|
73089
|
-
}
|
|
73090
|
-
return this.agent;
|
|
73091
|
-
}
|
|
73092
|
-
/**
|
|
73093
|
-
* Fix invalid JSON using the specialized agent
|
|
73094
|
-
* @param {string} invalidJson - The broken JSON string
|
|
73095
|
-
* @param {string} schema - The original schema for context
|
|
73096
|
-
* @param {Object} validationResult - Validation result with error details
|
|
73097
|
-
* @param {number} attemptNumber - Current attempt number (for logging)
|
|
73098
|
-
* @returns {Promise<string>} - The corrected JSON
|
|
73099
|
-
*/
|
|
73100
|
-
async fixJson(invalidJson, schema, validationResult, attemptNumber = 1) {
|
|
73101
|
-
await this.initializeAgent();
|
|
73102
|
-
let errorContext = validationResult.error;
|
|
73103
|
-
if (validationResult.enhancedError) {
|
|
73104
|
-
errorContext = validationResult.enhancedError;
|
|
73105
|
-
}
|
|
73106
|
-
let schemaErrorDetails = "";
|
|
73107
|
-
if (validationResult.errorSummary) {
|
|
73108
|
-
schemaErrorDetails = `
|
|
73109
|
-
|
|
73110
|
-
Schema Validation Errors:
|
|
73111
|
-
${validationResult.errorSummary}`;
|
|
73112
|
-
} else if (validationResult.schemaErrors && validationResult.schemaErrors.length > 0) {
|
|
73113
|
-
const errors = validationResult.schemaErrors.map((err) => {
|
|
73114
|
-
const path9 = err.instancePath || "(root)";
|
|
73115
|
-
return ` ${path9}: ${err.message}`;
|
|
73116
|
-
}).join("\n");
|
|
73117
|
-
schemaErrorDetails = `
|
|
73118
|
-
|
|
73119
|
-
Schema Validation Errors:
|
|
73120
|
-
${errors}`;
|
|
73121
|
-
}
|
|
73122
|
-
const prompt = `Fix the following invalid JSON.
|
|
73123
|
-
|
|
73124
|
-
Error: ${errorContext}${schemaErrorDetails}
|
|
73125
|
-
|
|
73126
|
-
Invalid JSON:
|
|
73127
|
-
${invalidJson}
|
|
73128
|
-
|
|
73129
|
-
Expected schema structure:
|
|
73130
|
-
${schema}
|
|
73131
|
-
|
|
73132
|
-
${schemaErrorDetails ? "CRITICAL: Pay special attention to the schema validation errors above. The JSON may be syntactically valid but does not conform to the required schema. Make sure to:\n- Include all required fields\n- Use correct data types\n- Remove any additional properties not defined in the schema (if additionalProperties is false)\n- Ensure all values match their schema constraints\n\n" : ""}Provide only the corrected JSON without any markdown formatting or explanations.`;
|
|
73133
|
-
try {
|
|
73134
|
-
if (this.options.debug) {
|
|
73135
|
-
console.log(`[DEBUG] JSON fixing: Attempt ${attemptNumber} to fix JSON with separate agent`);
|
|
73136
|
-
}
|
|
73137
|
-
const result = await this.agent.answer(prompt, []);
|
|
73138
|
-
const cleaned = cleanSchemaResponse(result);
|
|
73139
|
-
if (this.options.debug) {
|
|
73140
|
-
console.log(`[DEBUG] JSON fixing: Agent returned ${cleaned.length} chars`);
|
|
73141
|
-
}
|
|
73142
|
-
return cleaned;
|
|
73143
|
-
} catch (error40) {
|
|
73144
|
-
if (this.options.debug) {
|
|
73145
|
-
console.error(`[DEBUG] JSON fixing failed: ${error40.message}`);
|
|
73146
|
-
}
|
|
73147
|
-
throw new Error(`Failed to fix JSON: ${error40.message}`);
|
|
73148
|
-
}
|
|
73149
|
-
}
|
|
73150
|
-
/**
|
|
73151
|
-
* Get token usage information from the specialized agent
|
|
73152
|
-
* @returns {Object} - Token usage statistics
|
|
73153
|
-
*/
|
|
73154
|
-
getTokenUsage() {
|
|
73155
|
-
return this.agent ? this.agent.getTokenUsage() : null;
|
|
73156
|
-
}
|
|
73157
|
-
/**
|
|
73158
|
-
* Cancel any ongoing operations
|
|
73159
|
-
*/
|
|
73160
|
-
cancel() {
|
|
73161
|
-
if (this.agent) {
|
|
73162
|
-
this.agent.cancel();
|
|
73163
|
-
}
|
|
73164
|
-
}
|
|
73165
|
-
};
|
|
73166
72779
|
MermaidFixingAgent = class {
|
|
73167
72780
|
constructor(options = {}) {
|
|
73168
72781
|
this.ProbeAgent = null;
|
|
@@ -73406,7 +73019,7 @@ When reviewing code:
|
|
|
73406
73019
|
"code-review-template": `You are going to perform code review according to provided user rules. Ensure to review only code provided in diff and latest commit, if provided. However you still need to fully understand how modified code works, and read dependencies if something is not clear.`,
|
|
73407
73020
|
"engineer": `You are a senior engineer focused on software architecture and design.
|
|
73408
73021
|
Before jumping on the task you first analyse the user request in detail, and try to provide an elegant and concise solution.
|
|
73409
|
-
If the solution is clear, you can jump to implementation right away. If not, ask the user a clarification question
|
|
73022
|
+
If the solution is clear, you can jump to implementation right away. If not, ask the user a clarification question with the required details.
|
|
73410
73023
|
|
|
73411
73024
|
# Tone and Style
|
|
73412
73025
|
- Be concise and direct. Explain your approach briefly before implementing, then let the code speak for itself.
|
|
@@ -73429,7 +73042,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
73429
73042
|
When the request has **multiple distinct goals** (e.g. "Fix bug A AND add feature B"), use the task tool to track them:
|
|
73430
73043
|
- Call the task tool with action="create" and a tasks array. Each task must have an "id" field.
|
|
73431
73044
|
- Update task status to "in_progress" when starting and "completed" when done.
|
|
73432
|
-
- All tasks must be completed or cancelled before
|
|
73045
|
+
- All tasks must be completed or cancelled before providing your final answer.
|
|
73433
73046
|
- Stay flexible \u2014 add, remove, or reorganize tasks as your understanding changes.
|
|
73434
73047
|
|
|
73435
73048
|
Do NOT create tasks for single-goal requests, even complex ones. Multiple internal steps for one goal (search, read, analyze, implement) do not need tasks.
|
|
@@ -82657,14 +82270,6 @@ var init_FallbackManager = __esm({
|
|
|
82657
82270
|
});
|
|
82658
82271
|
|
|
82659
82272
|
// src/agent/contextCompactor.js
|
|
82660
|
-
var contextCompactor_exports = {};
|
|
82661
|
-
__export(contextCompactor_exports, {
|
|
82662
|
-
calculateCompactionStats: () => calculateCompactionStats,
|
|
82663
|
-
compactMessages: () => compactMessages,
|
|
82664
|
-
handleContextLimitError: () => handleContextLimitError,
|
|
82665
|
-
identifyMessageSegments: () => identifyMessageSegments,
|
|
82666
|
-
isContextLimitError: () => isContextLimitError
|
|
82667
|
-
});
|
|
82668
82273
|
function isContextLimitError(error40) {
|
|
82669
82274
|
if (!error40) return false;
|
|
82670
82275
|
const errorMessage = (typeof error40 === "string" ? error40 : error40?.message || "").toLowerCase();
|
|
@@ -82686,9 +82291,15 @@ function messageContainsCompletion(msg) {
|
|
|
82686
82291
|
}
|
|
82687
82292
|
if (Array.isArray(msg.content)) {
|
|
82688
82293
|
if (msg.content.some((p) => p.type === "tool-call" && p.toolName === "attempt_completion")) return true;
|
|
82294
|
+
const hasToolCalls = msg.content.some((p) => p.type === "tool-call");
|
|
82295
|
+
const hasText = msg.content.some((p) => p.type === "text" && p.text?.trim());
|
|
82296
|
+
if (!hasToolCalls && hasText) return true;
|
|
82689
82297
|
}
|
|
82690
82298
|
const text = typeof msg.content === "string" ? msg.content : "";
|
|
82691
|
-
|
|
82299
|
+
if (text.includes("attempt_completion")) return true;
|
|
82300
|
+
const hasNoToolCalls = !Array.isArray(msg.toolInvocations) && !Array.isArray(msg.tool_calls);
|
|
82301
|
+
if (hasNoToolCalls && text.trim().length > 0) return true;
|
|
82302
|
+
return false;
|
|
82692
82303
|
}
|
|
82693
82304
|
function identifyMessageSegments(messages) {
|
|
82694
82305
|
const segments = [];
|
|
@@ -96738,8 +96349,8 @@ function debugTruncate(s, limit = 200) {
|
|
|
96738
96349
|
function debugLogToolResults(toolResults) {
|
|
96739
96350
|
if (!toolResults || toolResults.length === 0) return;
|
|
96740
96351
|
for (const tr of toolResults) {
|
|
96741
|
-
const argsStr = JSON.stringify(tr.args
|
|
96742
|
-
const resultStr = typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result
|
|
96352
|
+
const argsStr = tr.args != null ? JSON.stringify(tr.args) : "<no args>";
|
|
96353
|
+
const resultStr = tr.result != null ? typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result) : "<no result>";
|
|
96743
96354
|
console.log(`[DEBUG] tool: ${tr.toolName} | args: ${debugTruncate(argsStr)} | result: ${debugTruncate(resultStr)}`);
|
|
96744
96355
|
}
|
|
96745
96356
|
}
|
|
@@ -96846,7 +96457,7 @@ var init_ProbeAgent = __esm({
|
|
|
96846
96457
|
* @param {Array<Object>} [options.fallback.providers] - List of provider configurations for custom fallback
|
|
96847
96458
|
* @param {boolean} [options.fallback.stopOnSuccess=true] - Stop on first success
|
|
96848
96459
|
* @param {number} [options.fallback.maxTotalAttempts=10] - Maximum total attempts across all providers
|
|
96849
|
-
* @param {string} [options.completionPrompt] - Custom prompt to run after
|
|
96460
|
+
* @param {string} [options.completionPrompt] - Custom prompt to run after completion for validation/review (runs before mermaid/JSON validation)
|
|
96850
96461
|
* @param {number} [options.maxOutputTokens] - Maximum tokens for tool output before truncation (default: 20000, can also be set via PROBE_MAX_OUTPUT_TOKENS env var)
|
|
96851
96462
|
* @param {number} [options.requestTimeout] - Timeout in ms for AI requests (default: 120000 or REQUEST_TIMEOUT env var). Used to abort hung requests.
|
|
96852
96463
|
* @param {number} [options.maxOperationTimeout] - Maximum timeout in ms for the entire operation including all retries and fallbacks (default: 300000 or MAX_OPERATION_TIMEOUT env var). This is the absolute maximum time for streamTextWithRetryAndFallback.
|
|
@@ -97998,12 +97609,11 @@ var init_ProbeAgent = __esm({
|
|
|
97998
97609
|
* - Delegate tool param injection
|
|
97999
97610
|
*
|
|
98000
97611
|
* @param {Object} options - Options from the answer() call
|
|
98001
|
-
* @param {Function} onComplete - Callback when attempt_completion is called (receives result string)
|
|
98002
97612
|
* @param {Object} context - Execution context { maxIterations, currentMessages }
|
|
98003
97613
|
* @returns {Object} Tools object for streamText()
|
|
98004
97614
|
* @private
|
|
98005
97615
|
*/
|
|
98006
|
-
_buildNativeTools(options,
|
|
97616
|
+
_buildNativeTools(options, context = {}) {
|
|
98007
97617
|
const { maxIterations = 30 } = context;
|
|
98008
97618
|
const nativeTools = {};
|
|
98009
97619
|
const isToolAllowed = (toolName) => this.allowedTools.isEnabled(toolName);
|
|
@@ -98153,16 +97763,6 @@ var init_ProbeAgent = __esm({
|
|
|
98153
97763
|
});
|
|
98154
97764
|
};
|
|
98155
97765
|
if (options._disableTools) {
|
|
98156
|
-
nativeTools.attempt_completion = (0, import_ai4.tool)({
|
|
98157
|
-
description: "Signal task completion and provide the final result to the user",
|
|
98158
|
-
inputSchema: external_exports2.object({
|
|
98159
|
-
result: external_exports2.string().describe("The final result to present to the user")
|
|
98160
|
-
}),
|
|
98161
|
-
execute: async ({ result }) => {
|
|
98162
|
-
onComplete(result);
|
|
98163
|
-
return result;
|
|
98164
|
-
}
|
|
98165
|
-
});
|
|
98166
97766
|
return nativeTools;
|
|
98167
97767
|
}
|
|
98168
97768
|
for (const [toolName, toolImpl] of Object.entries(this.toolImplementations)) {
|
|
@@ -98173,28 +97773,6 @@ var init_ProbeAgent = __esm({
|
|
|
98173
97773
|
nativeTools[toolName] = wrapTool(toolName, schema, description, toolImpl.execute);
|
|
98174
97774
|
}
|
|
98175
97775
|
}
|
|
98176
|
-
nativeTools.attempt_completion = (0, import_ai4.tool)({
|
|
98177
|
-
description: "Signal task completion and provide the final result to the user",
|
|
98178
|
-
inputSchema: external_exports2.object({
|
|
98179
|
-
result: external_exports2.string().describe("The final result to present to the user")
|
|
98180
|
-
}),
|
|
98181
|
-
execute: async ({ result }) => {
|
|
98182
|
-
if (this.enableTasks && this.taskManager && this.taskManager.hasIncompleteTasks()) {
|
|
98183
|
-
const incompleteTasks = this.taskManager.getIncompleteTasks();
|
|
98184
|
-
const highIterationCount = (context.currentIteration || 0) > maxIterations * 0.7;
|
|
98185
|
-
if (!highIterationCount) {
|
|
98186
|
-
const taskSummary = this.taskManager.getTaskSummary();
|
|
98187
|
-
const blockedMessage = createTaskCompletionBlockedMessage(taskSummary);
|
|
98188
|
-
if (this.debug) {
|
|
98189
|
-
console.log("[DEBUG] Task checkpoint: Blocking completion due to incomplete tasks");
|
|
98190
|
-
}
|
|
98191
|
-
return blockedMessage;
|
|
98192
|
-
}
|
|
98193
|
-
}
|
|
98194
|
-
onComplete(result);
|
|
98195
|
-
return result;
|
|
98196
|
-
}
|
|
98197
|
-
});
|
|
98198
97776
|
if (this.mcpBridge && !options._disableTools) {
|
|
98199
97777
|
const mcpTools = this.mcpBridge.getVercelTools(this._filterMcpTools(this.mcpBridge.getToolNames()));
|
|
98200
97778
|
for (const [name15, mcpTool] of Object.entries(mcpTools)) {
|
|
@@ -99078,7 +98656,7 @@ Follow these instructions carefully:
|
|
|
99078
98656
|
2. Use the available tools step-by-step to fulfill the request.
|
|
99079
98657
|
3. You should always prefer the search tool for code-related questions.${this.searchDelegate ? " Ask natural language questions \u2014 the search subagent handles keyword formulation and returns extracted code blocks. Use extract only to expand context or read full files." : " Search handles stemming and case variations automatically \u2014 do NOT try keyword variations manually. Read full files only if really necessary."}
|
|
99080
98658
|
4. Ensure to get really deep and understand the full picture before answering.
|
|
99081
|
-
5. Once the task is fully completed,
|
|
98659
|
+
5. Once the task is fully completed, provide your final answer directly as text.
|
|
99082
98660
|
6. ${this.searchDelegate ? "Ask clear, specific questions when searching. Each search should target a distinct concept or question." : "Prefer concise and focused search queries. Use specific keywords and phrases to narrow down results."}
|
|
99083
98661
|
7. NEVER use bash for code exploration (no grep, cat, find, head, tail, awk, sed) \u2014 always use search and extract tools instead. Bash is only for system operations like building, running tests, or git commands.${this.allowEdit ? `
|
|
99084
98662
|
7. When modifying files, choose the appropriate tool:
|
|
@@ -99256,7 +98834,7 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99256
98834
|
});
|
|
99257
98835
|
const systemMessage = await this.getSystemMessage();
|
|
99258
98836
|
let userMessage = { role: "user", content: message.trim() };
|
|
99259
|
-
if (options.schema && !options._schemaFormatted) {
|
|
98837
|
+
if (options.schema && !options._schemaFormatted && !options._disableTools) {
|
|
99260
98838
|
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
99261
98839
|
userMessage.content = message.trim() + schemaInstructions;
|
|
99262
98840
|
}
|
|
@@ -99288,8 +98866,17 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99288
98866
|
userMessage
|
|
99289
98867
|
];
|
|
99290
98868
|
}
|
|
98869
|
+
if (this.history.length > 0) {
|
|
98870
|
+
const compacted = compactMessages(currentMessages, { keepLastSegment: true, minSegmentsToKeep: 1 });
|
|
98871
|
+
if (compacted.length < currentMessages.length) {
|
|
98872
|
+
const stats = calculateCompactionStats(currentMessages, compacted);
|
|
98873
|
+
if (this.debug) {
|
|
98874
|
+
console.log(`[DEBUG] Proactive history compaction: ${currentMessages.length} \u2192 ${compacted.length} messages (${stats.reductionPercent}% reduction, ~${stats.tokensSaved} tokens saved)`);
|
|
98875
|
+
}
|
|
98876
|
+
currentMessages = compacted;
|
|
98877
|
+
}
|
|
98878
|
+
}
|
|
99291
98879
|
let currentIteration = 0;
|
|
99292
|
-
let completionAttempted = false;
|
|
99293
98880
|
let finalResult = "I was unable to complete your request due to reaching the maximum number of tool iterations.";
|
|
99294
98881
|
const baseMaxIterations = options._maxIterationsOverride || this.maxIterations || MAX_TOOL_ITERATIONS;
|
|
99295
98882
|
const maxIterations = options._maxIterationsOverride ? baseMaxIterations : options.schema ? baseMaxIterations + 4 : baseMaxIterations;
|
|
@@ -99405,12 +98992,8 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99405
98992
|
console.log(`[DEBUG] Schema provided, using extended iteration limit: ${maxIterations} (base: ${baseMaxIterations})`);
|
|
99406
98993
|
}
|
|
99407
98994
|
}
|
|
99408
|
-
let completionResult = null;
|
|
99409
98995
|
const toolContext = { maxIterations, currentIteration: 0, currentMessages };
|
|
99410
|
-
const tools2 = this._buildNativeTools(options,
|
|
99411
|
-
completionResult = result;
|
|
99412
|
-
completionAttempted = true;
|
|
99413
|
-
}, toolContext);
|
|
98996
|
+
const tools2 = this._buildNativeTools(options, toolContext);
|
|
99414
98997
|
if (this.debug) {
|
|
99415
98998
|
const toolNames = Object.keys(tools2);
|
|
99416
98999
|
console.log(`[DEBUG] Agent tools registered (${toolNames.length}): ${toolNames.join(", ")}`);
|
|
@@ -99424,6 +99007,8 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99424
99007
|
maxResponseTokens = 32e3;
|
|
99425
99008
|
}
|
|
99426
99009
|
}
|
|
99010
|
+
let completionPromptInjected = false;
|
|
99011
|
+
let preCompletionResult = null;
|
|
99427
99012
|
let compactionAttempted = false;
|
|
99428
99013
|
while (true) {
|
|
99429
99014
|
try {
|
|
@@ -99432,19 +99017,103 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99432
99017
|
model: this.provider ? this.provider(this.model) : this.model,
|
|
99433
99018
|
messages: messagesForAI,
|
|
99434
99019
|
tools: tools2,
|
|
99435
|
-
stopWhen: (
|
|
99020
|
+
stopWhen: ({ steps }) => {
|
|
99021
|
+
if (steps.length >= maxIterations) return true;
|
|
99022
|
+
const lastStep = steps[steps.length - 1];
|
|
99023
|
+
const modelWantsToStop = lastStep?.finishReason === "stop" && (!lastStep?.toolCalls || lastStep.toolCalls.length === 0);
|
|
99024
|
+
if (modelWantsToStop) {
|
|
99025
|
+
if (this.enableTasks && this.taskManager?.hasIncompleteTasks()) {
|
|
99026
|
+
const highIterationCount = steps.length > maxIterations * 0.7;
|
|
99027
|
+
if (!highIterationCount) return false;
|
|
99028
|
+
}
|
|
99029
|
+
if (this.completionPrompt && !options._completionPromptProcessed && !completionPromptInjected) {
|
|
99030
|
+
preCompletionResult = lastStep.text || null;
|
|
99031
|
+
return false;
|
|
99032
|
+
}
|
|
99033
|
+
}
|
|
99034
|
+
let trailingNoTool = 0;
|
|
99035
|
+
for (let i = steps.length - 1; i >= 0; i--) {
|
|
99036
|
+
if (!steps[i].toolCalls?.length) trailingNoTool++;
|
|
99037
|
+
else break;
|
|
99038
|
+
}
|
|
99039
|
+
if (trailingNoTool >= 5) return true;
|
|
99040
|
+
if (trailingNoTool >= 3) {
|
|
99041
|
+
const recentTexts = steps.slice(-3).map((s) => s.text);
|
|
99042
|
+
if (recentTexts.every((t) => t && t === recentTexts[0])) return true;
|
|
99043
|
+
if (recentTexts.every((t) => detectStuckResponse(t))) return true;
|
|
99044
|
+
}
|
|
99045
|
+
return false;
|
|
99046
|
+
},
|
|
99047
|
+
prepareStep: ({ steps, stepNumber }) => {
|
|
99048
|
+
if (stepNumber === maxIterations - 1) {
|
|
99049
|
+
return {
|
|
99050
|
+
toolChoice: "none"
|
|
99051
|
+
};
|
|
99052
|
+
}
|
|
99053
|
+
const lastStep = steps[steps.length - 1];
|
|
99054
|
+
const modelJustStopped = lastStep?.finishReason === "stop" && (!lastStep?.toolCalls || lastStep.toolCalls.length === 0);
|
|
99055
|
+
if (modelJustStopped) {
|
|
99056
|
+
if (this.enableTasks && this.taskManager?.hasIncompleteTasks()) {
|
|
99057
|
+
const taskSummary = this.taskManager.getTaskSummary();
|
|
99058
|
+
const blockedMessage = createTaskCompletionBlockedMessage(taskSummary);
|
|
99059
|
+
return {
|
|
99060
|
+
userMessage: blockedMessage
|
|
99061
|
+
};
|
|
99062
|
+
}
|
|
99063
|
+
if (this.completionPrompt && !options._completionPromptProcessed && !completionPromptInjected) {
|
|
99064
|
+
completionPromptInjected = true;
|
|
99065
|
+
const resultToReview = lastStep.text || preCompletionResult || "";
|
|
99066
|
+
if (this.debug) {
|
|
99067
|
+
console.log("[DEBUG] Injecting completion prompt into main loop via prepareStep...");
|
|
99068
|
+
}
|
|
99069
|
+
if (this.tracer) {
|
|
99070
|
+
this.tracer.recordEvent("completion_prompt.started", {
|
|
99071
|
+
"completion_prompt.original_result_length": resultToReview.length
|
|
99072
|
+
});
|
|
99073
|
+
}
|
|
99074
|
+
const completionPromptMessage = `${this.completionPrompt}
|
|
99075
|
+
|
|
99076
|
+
Here is the result to review:
|
|
99077
|
+
<result>
|
|
99078
|
+
${resultToReview}
|
|
99079
|
+
</result>
|
|
99080
|
+
|
|
99081
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If something needs to be fixed or is missing, do it now, then respond with the COMPLETE updated answer (everything you did in total, not just the fix).`;
|
|
99082
|
+
return {
|
|
99083
|
+
userMessage: completionPromptMessage
|
|
99084
|
+
};
|
|
99085
|
+
}
|
|
99086
|
+
}
|
|
99087
|
+
return void 0;
|
|
99088
|
+
},
|
|
99436
99089
|
maxTokens: maxResponseTokens,
|
|
99437
99090
|
temperature: 0.3,
|
|
99438
|
-
onStepFinish: (
|
|
99091
|
+
onStepFinish: (stepResult) => {
|
|
99092
|
+
const { toolResults, toolCalls, text, reasoningText, finishReason, usage } = stepResult;
|
|
99439
99093
|
currentIteration++;
|
|
99440
99094
|
toolContext.currentIteration = currentIteration;
|
|
99441
99095
|
if (this.tracer) {
|
|
99442
|
-
|
|
99096
|
+
const stepEvent = {
|
|
99443
99097
|
"iteration": currentIteration,
|
|
99444
99098
|
"max_iterations": maxIterations,
|
|
99445
99099
|
"finish_reason": finishReason,
|
|
99446
99100
|
"has_tool_calls": !!(toolResults && toolResults.length > 0)
|
|
99447
|
-
}
|
|
99101
|
+
};
|
|
99102
|
+
if (text) {
|
|
99103
|
+
stepEvent["ai.text"] = text.substring(0, 1e4);
|
|
99104
|
+
stepEvent["ai.text.length"] = text.length;
|
|
99105
|
+
}
|
|
99106
|
+
if (reasoningText) {
|
|
99107
|
+
stepEvent["ai.reasoning"] = reasoningText.substring(0, 1e4);
|
|
99108
|
+
stepEvent["ai.reasoning.length"] = reasoningText.length;
|
|
99109
|
+
}
|
|
99110
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
99111
|
+
stepEvent["ai.tool_calls"] = toolCalls.map((tc) => ({
|
|
99112
|
+
name: tc.toolName,
|
|
99113
|
+
args: JSON.stringify(tc.args || {}).substring(0, 2e3)
|
|
99114
|
+
}));
|
|
99115
|
+
}
|
|
99116
|
+
this.tracer.addEvent("iteration.step", stepEvent);
|
|
99448
99117
|
}
|
|
99449
99118
|
if (usage) {
|
|
99450
99119
|
this.tokenCounter.recordUsage(usage);
|
|
@@ -99454,10 +99123,32 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99454
99123
|
}
|
|
99455
99124
|
if (this.debug) {
|
|
99456
99125
|
console.log(`[DEBUG] Step ${currentIteration}/${maxIterations} finished (reason: ${finishReason}, tools: ${toolResults?.length || 0})`);
|
|
99126
|
+
if (text) {
|
|
99127
|
+
console.log(`[DEBUG] model text: ${debugTruncate(text)}`);
|
|
99128
|
+
}
|
|
99129
|
+
if (reasoningText) {
|
|
99130
|
+
console.log(`[DEBUG] reasoning: ${debugTruncate(reasoningText)}`);
|
|
99131
|
+
}
|
|
99457
99132
|
debugLogToolResults(toolResults);
|
|
99458
99133
|
}
|
|
99459
99134
|
}
|
|
99460
99135
|
};
|
|
99136
|
+
const hasActiveTools = Object.keys(tools2).length > 0;
|
|
99137
|
+
if (options.schema && !hasActiveTools) {
|
|
99138
|
+
try {
|
|
99139
|
+
const parsedSchema = typeof options.schema === "string" ? JSON.parse(options.schema) : options.schema;
|
|
99140
|
+
if (isJsonSchema(options.schema)) {
|
|
99141
|
+
streamOptions.output = import_ai4.Output.object({ schema: (0, import_ai4.jsonSchema)(parsedSchema) });
|
|
99142
|
+
if (this.debug) {
|
|
99143
|
+
console.log(`[DEBUG] Native JSON schema output enabled (no active tools)`);
|
|
99144
|
+
}
|
|
99145
|
+
}
|
|
99146
|
+
} catch (e) {
|
|
99147
|
+
if (this.debug) {
|
|
99148
|
+
console.log(`[DEBUG] Failed to set native JSON schema output: ${e.message}`);
|
|
99149
|
+
}
|
|
99150
|
+
}
|
|
99151
|
+
}
|
|
99461
99152
|
const providerOpts = this._buildThinkingProviderOptions(maxResponseTokens);
|
|
99462
99153
|
if (providerOpts) {
|
|
99463
99154
|
streamOptions.providerOptions = providerOpts;
|
|
@@ -99467,7 +99158,7 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99467
99158
|
const finalText = await result.text;
|
|
99468
99159
|
if (this.debug) {
|
|
99469
99160
|
const steps = await result.steps;
|
|
99470
|
-
console.log(`[DEBUG] streamText completed: ${steps?.length || 0} steps, finalText=${finalText?.length || 0} chars
|
|
99161
|
+
console.log(`[DEBUG] streamText completed: ${steps?.length || 0} steps, finalText=${finalText?.length || 0} chars`);
|
|
99471
99162
|
}
|
|
99472
99163
|
const usage = await result.usage;
|
|
99473
99164
|
if (usage) {
|
|
@@ -99491,18 +99182,24 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99491
99182
|
} else {
|
|
99492
99183
|
aiResult = await executeAIRequest();
|
|
99493
99184
|
}
|
|
99494
|
-
if (
|
|
99495
|
-
|
|
99496
|
-
|
|
99497
|
-
|
|
99498
|
-
|
|
99499
|
-
|
|
99500
|
-
|
|
99185
|
+
if (options.schema && streamOptions.output) {
|
|
99186
|
+
try {
|
|
99187
|
+
const outputObject = await aiResult.result.output;
|
|
99188
|
+
if (outputObject) {
|
|
99189
|
+
finalResult = JSON.stringify(outputObject);
|
|
99190
|
+
} else if (aiResult.finalText) {
|
|
99191
|
+
finalResult = aiResult.finalText;
|
|
99192
|
+
}
|
|
99193
|
+
} catch (e) {
|
|
99194
|
+
if (this.debug) {
|
|
99195
|
+
console.log(`[DEBUG] Native JSON output failed, falling back to text: ${e.message}`);
|
|
99196
|
+
}
|
|
99197
|
+
if (aiResult.finalText) {
|
|
99198
|
+
finalResult = aiResult.finalText;
|
|
99501
99199
|
}
|
|
99502
99200
|
}
|
|
99503
99201
|
} else if (aiResult.finalText) {
|
|
99504
99202
|
finalResult = aiResult.finalText;
|
|
99505
|
-
completionAttempted = true;
|
|
99506
99203
|
}
|
|
99507
99204
|
const resultMessages = await aiResult.result.response?.messages;
|
|
99508
99205
|
if (resultMessages) {
|
|
@@ -99510,6 +99207,75 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99510
99207
|
currentMessages.push(msg);
|
|
99511
99208
|
}
|
|
99512
99209
|
}
|
|
99210
|
+
if (this.completionPrompt && !options._completionPromptProcessed && !completionPromptInjected && finalResult) {
|
|
99211
|
+
completionPromptInjected = true;
|
|
99212
|
+
preCompletionResult = finalResult;
|
|
99213
|
+
if (this.debug) {
|
|
99214
|
+
console.log("[DEBUG] Injecting completion prompt as post-streamText follow-up pass...");
|
|
99215
|
+
}
|
|
99216
|
+
if (this.tracer) {
|
|
99217
|
+
this.tracer.recordEvent("completion_prompt.started", {
|
|
99218
|
+
"completion_prompt.original_result_length": finalResult.length
|
|
99219
|
+
});
|
|
99220
|
+
}
|
|
99221
|
+
const completionPromptMessage = `${this.completionPrompt}
|
|
99222
|
+
|
|
99223
|
+
Here is the result to review:
|
|
99224
|
+
<result>
|
|
99225
|
+
${finalResult}
|
|
99226
|
+
</result>
|
|
99227
|
+
|
|
99228
|
+
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is. If something needs to be fixed or is missing, do it now, then respond with the COMPLETE updated answer (everything you did in total, not just the fix).`;
|
|
99229
|
+
currentMessages.push({ role: "user", content: completionPromptMessage });
|
|
99230
|
+
const completionMaxIterations = 5;
|
|
99231
|
+
const completionStreamOptions = {
|
|
99232
|
+
model: this.provider ? this.provider(this.model) : this.model,
|
|
99233
|
+
messages: this.prepareMessagesWithImages(currentMessages),
|
|
99234
|
+
tools: tools2,
|
|
99235
|
+
stopWhen: (0, import_ai4.stepCountIs)(completionMaxIterations),
|
|
99236
|
+
maxTokens: maxResponseTokens,
|
|
99237
|
+
temperature: 0.3,
|
|
99238
|
+
onStepFinish: ({ toolResults, text, finishReason, usage }) => {
|
|
99239
|
+
if (usage) {
|
|
99240
|
+
this.tokenCounter.recordUsage(usage);
|
|
99241
|
+
}
|
|
99242
|
+
if (options.onStream && text) {
|
|
99243
|
+
options.onStream(text);
|
|
99244
|
+
}
|
|
99245
|
+
if (this.debug) {
|
|
99246
|
+
console.log(`[DEBUG] Completion prompt step finished (reason: ${finishReason}, tools: ${toolResults?.length || 0})`);
|
|
99247
|
+
}
|
|
99248
|
+
}
|
|
99249
|
+
};
|
|
99250
|
+
const providerOpts2 = this._buildThinkingProviderOptions(maxResponseTokens);
|
|
99251
|
+
if (providerOpts2) {
|
|
99252
|
+
completionStreamOptions.providerOptions = providerOpts2;
|
|
99253
|
+
}
|
|
99254
|
+
try {
|
|
99255
|
+
const cpResult = await this.streamTextWithRetryAndFallback(completionStreamOptions);
|
|
99256
|
+
const cpFinalText = await cpResult.text;
|
|
99257
|
+
const cpUsage = await cpResult.usage;
|
|
99258
|
+
if (cpUsage) {
|
|
99259
|
+
this.tokenCounter.recordUsage(cpUsage, cpResult.experimental_providerMetadata);
|
|
99260
|
+
}
|
|
99261
|
+
const cpMessages = await cpResult.response?.messages;
|
|
99262
|
+
if (cpMessages) {
|
|
99263
|
+
for (const msg of cpMessages) {
|
|
99264
|
+
currentMessages.push(msg);
|
|
99265
|
+
}
|
|
99266
|
+
}
|
|
99267
|
+
if (cpFinalText && cpFinalText.trim().length > 0) {
|
|
99268
|
+
finalResult = cpFinalText;
|
|
99269
|
+
}
|
|
99270
|
+
if (this.debug) {
|
|
99271
|
+
console.log(`[DEBUG] Completion prompt follow-up produced ${cpFinalText?.length || 0} chars (using ${cpFinalText && cpFinalText.trim().length > 0 ? "updated" : "original"} result)`);
|
|
99272
|
+
}
|
|
99273
|
+
} catch (cpError) {
|
|
99274
|
+
if (this.debug) {
|
|
99275
|
+
console.log(`[DEBUG] Completion prompt follow-up failed: ${cpError.message}, keeping original result`);
|
|
99276
|
+
}
|
|
99277
|
+
}
|
|
99278
|
+
}
|
|
99513
99279
|
break;
|
|
99514
99280
|
} catch (error40) {
|
|
99515
99281
|
if (!compactionAttempted && handleContextLimitError) {
|
|
@@ -99539,17 +99305,13 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99539
99305
|
continue;
|
|
99540
99306
|
}
|
|
99541
99307
|
}
|
|
99542
|
-
if (completionResult) {
|
|
99543
|
-
finalResult = completionResult;
|
|
99544
|
-
break;
|
|
99545
|
-
}
|
|
99546
99308
|
console.error(`Error during streamText:`, error40);
|
|
99547
99309
|
finalResult = `Error: Failed to get response from AI model. ${error40.message}`;
|
|
99548
99310
|
throw new Error(finalResult);
|
|
99549
99311
|
}
|
|
99550
99312
|
}
|
|
99551
|
-
if (currentIteration >= maxIterations
|
|
99552
|
-
console.warn(`[WARN] Max tool iterations (${maxIterations}) reached for session ${this.sessionId}
|
|
99313
|
+
if (currentIteration >= maxIterations) {
|
|
99314
|
+
console.warn(`[WARN] Max tool iterations (${maxIterations}) reached for session ${this.sessionId}.`);
|
|
99553
99315
|
}
|
|
99554
99316
|
this.history = currentMessages.map((msg) => ({ ...msg }));
|
|
99555
99317
|
if (this.history.length > MAX_HISTORY_MESSAGES) {
|
|
@@ -99572,279 +99334,17 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
99572
99334
|
} catch (error40) {
|
|
99573
99335
|
console.error(`[ERROR] Failed to save messages to storage:`, error40);
|
|
99574
99336
|
}
|
|
99575
|
-
if (
|
|
99576
|
-
|
|
99577
|
-
|
|
99578
|
-
|
|
99579
|
-
|
|
99580
|
-
const originalResult = finalResult;
|
|
99581
|
-
if (this.tracer) {
|
|
99582
|
-
this.tracer.recordEvent("completion_prompt.started", {
|
|
99583
|
-
"completion_prompt.original_result_length": finalResult?.length || 0
|
|
99584
|
-
});
|
|
99585
|
-
}
|
|
99586
|
-
const completionPromptMessage = `${this.completionPrompt}
|
|
99587
|
-
|
|
99588
|
-
Here is the result to review:
|
|
99589
|
-
<result>
|
|
99590
|
-
${finalResult}
|
|
99591
|
-
</result>
|
|
99592
|
-
|
|
99593
|
-
Double-check your response based on the criteria above. If everything looks good, respond with your previous answer exactly as-is using attempt_completion. If something needs to be fixed or is missing, do it now, then respond with the COMPLETE updated answer (everything you did in total, not just the fix) using attempt_completion.`;
|
|
99594
|
-
currentMessages.push({ role: "user", content: completionPromptMessage });
|
|
99595
|
-
completionResult = null;
|
|
99596
|
-
completionAttempted = false;
|
|
99597
|
-
const completionMaxIterations = 5;
|
|
99598
|
-
const completionStreamOptions = {
|
|
99599
|
-
model: this.provider ? this.provider(this.model) : this.model,
|
|
99600
|
-
messages: this.prepareMessagesWithImages(currentMessages),
|
|
99601
|
-
tools: tools2,
|
|
99602
|
-
stopWhen: (0, import_ai4.stepCountIs)(completionMaxIterations),
|
|
99603
|
-
maxTokens: maxResponseTokens,
|
|
99604
|
-
temperature: 0.3,
|
|
99605
|
-
onStepFinish: ({ toolResults, text, finishReason, usage }) => {
|
|
99606
|
-
if (usage) {
|
|
99607
|
-
this.tokenCounter.recordUsage(usage);
|
|
99608
|
-
}
|
|
99609
|
-
if (options.onStream && text) {
|
|
99610
|
-
options.onStream(text);
|
|
99611
|
-
}
|
|
99612
|
-
if (this.debug) {
|
|
99613
|
-
console.log(`[DEBUG] Completion prompt step finished (reason: ${finishReason}, tools: ${toolResults?.length || 0})`);
|
|
99614
|
-
debugLogToolResults(toolResults);
|
|
99615
|
-
}
|
|
99616
|
-
}
|
|
99617
|
-
};
|
|
99618
|
-
const providerOpts = this._buildThinkingProviderOptions(maxResponseTokens);
|
|
99619
|
-
if (providerOpts) {
|
|
99620
|
-
completionStreamOptions.providerOptions = providerOpts;
|
|
99621
|
-
}
|
|
99622
|
-
const cpResult = await this.streamTextWithRetryAndFallback(completionStreamOptions);
|
|
99623
|
-
const cpFinalText = await cpResult.text;
|
|
99624
|
-
const cpUsage = await cpResult.usage;
|
|
99625
|
-
if (cpUsage) {
|
|
99626
|
-
this.tokenCounter.recordUsage(cpUsage, cpResult.experimental_providerMetadata);
|
|
99627
|
-
}
|
|
99628
|
-
const cpMessages = await cpResult.response?.messages;
|
|
99629
|
-
if (cpMessages) {
|
|
99630
|
-
for (const msg of cpMessages) {
|
|
99631
|
-
currentMessages.push(msg);
|
|
99632
|
-
}
|
|
99633
|
-
}
|
|
99634
|
-
if (completionResult) {
|
|
99635
|
-
finalResult = completionResult;
|
|
99636
|
-
completionAttempted = true;
|
|
99637
|
-
} else if (cpFinalText && cpFinalText.trim().length > 0) {
|
|
99638
|
-
finalResult = cpFinalText;
|
|
99639
|
-
completionAttempted = true;
|
|
99640
|
-
} else {
|
|
99641
|
-
finalResult = originalResult;
|
|
99642
|
-
completionAttempted = true;
|
|
99643
|
-
if (this.debug) {
|
|
99644
|
-
console.log("[DEBUG] Completion prompt returned empty result, keeping original.");
|
|
99645
|
-
}
|
|
99646
|
-
}
|
|
99647
|
-
if (this.debug) {
|
|
99648
|
-
console.log(`[DEBUG] Completion prompt finished. Final result length: ${finalResult?.length || 0}`);
|
|
99649
|
-
}
|
|
99650
|
-
if (this.tracer) {
|
|
99651
|
-
this.tracer.recordEvent("completion_prompt.completed", {
|
|
99652
|
-
"completion_prompt.final_result_length": finalResult?.length || 0,
|
|
99653
|
-
"completion_prompt.used_original": finalResult === originalResult
|
|
99654
|
-
});
|
|
99655
|
-
}
|
|
99656
|
-
} catch (error40) {
|
|
99657
|
-
console.error("[ERROR] Completion prompt failed:", error40);
|
|
99658
|
-
if (this.tracer) {
|
|
99659
|
-
this.tracer.recordEvent("completion_prompt.error", {
|
|
99660
|
-
"completion_prompt.error": error40.message
|
|
99661
|
-
});
|
|
99662
|
-
}
|
|
99663
|
-
}
|
|
99337
|
+
if (completionPromptInjected && this.tracer) {
|
|
99338
|
+
this.tracer.recordEvent("completion_prompt.completed", {
|
|
99339
|
+
"completion_prompt.final_result_length": finalResult?.length || 0,
|
|
99340
|
+
"completion_prompt.used_original": preCompletionResult && finalResult === preCompletionResult
|
|
99341
|
+
});
|
|
99664
99342
|
}
|
|
99665
|
-
|
|
99666
|
-
if (options.schema && !options._schemaFormatted && !completionAttempted && !reachedMaxIterations) {
|
|
99667
|
-
if (this.debug) {
|
|
99668
|
-
console.log("[DEBUG] Schema provided, applying automatic formatting...");
|
|
99669
|
-
}
|
|
99670
|
-
try {
|
|
99671
|
-
const schemaPrompt = `CRITICAL: You MUST respond with ONLY valid JSON DATA that conforms to this schema structure. DO NOT return the schema definition itself.
|
|
99672
|
-
|
|
99673
|
-
Schema to follow (this is just the structure - provide ACTUAL DATA):
|
|
99674
|
-
${options.schema}
|
|
99675
|
-
|
|
99676
|
-
REQUIREMENTS:
|
|
99677
|
-
- Return ONLY the JSON object/array with REAL DATA that matches the schema structure
|
|
99678
|
-
- DO NOT return the schema definition itself (no "$schema", "$id", "type", "properties", etc.)
|
|
99679
|
-
- NO additional text, explanations, or markdown formatting
|
|
99680
|
-
- NO code blocks or backticks
|
|
99681
|
-
- The JSON must be parseable by JSON.parse()
|
|
99682
|
-
- Fill in actual values that make sense based on your previous response content
|
|
99683
|
-
|
|
99684
|
-
EXAMPLE:
|
|
99685
|
-
If schema defines {type: "object", properties: {name: {type: "string"}, age: {type: "number"}}}
|
|
99686
|
-
Return: {"name": "John Doe", "age": 25}
|
|
99687
|
-
NOT: {"type": "object", "properties": {"name": {"type": "string"}}}
|
|
99688
|
-
|
|
99689
|
-
Convert your previous response content into actual JSON data that follows this schema structure.`;
|
|
99690
|
-
finalResult = await this.answer(schemaPrompt, [], {
|
|
99691
|
-
...options,
|
|
99692
|
-
_schemaFormatted: true,
|
|
99693
|
-
_completionPromptProcessed: true
|
|
99694
|
-
// Prevent cascading completion prompts in retry calls
|
|
99695
|
-
});
|
|
99696
|
-
if (!this.disableMermaidValidation) {
|
|
99697
|
-
try {
|
|
99698
|
-
if (this.debug) {
|
|
99699
|
-
console.log(`[DEBUG] Mermaid validation: Starting enhanced mermaid validation...`);
|
|
99700
|
-
}
|
|
99701
|
-
if (this.tracer) {
|
|
99702
|
-
this.tracer.recordMermaidValidationEvent("schema_processing_started", {
|
|
99703
|
-
"mermaid_validation.context": "schema_processing",
|
|
99704
|
-
"mermaid_validation.response_length": finalResult.length
|
|
99705
|
-
});
|
|
99706
|
-
}
|
|
99707
|
-
const mermaidValidation = await validateAndFixMermaidResponse(finalResult, {
|
|
99708
|
-
debug: this.debug,
|
|
99709
|
-
path: this.workspaceRoot || this.allowedFolders[0],
|
|
99710
|
-
provider: this.clientApiProvider,
|
|
99711
|
-
model: this.model,
|
|
99712
|
-
tracer: this.tracer
|
|
99713
|
-
});
|
|
99714
|
-
if (mermaidValidation.wasFixed) {
|
|
99715
|
-
finalResult = mermaidValidation.fixedResponse;
|
|
99716
|
-
if (this.debug) {
|
|
99717
|
-
console.log(`[DEBUG] Mermaid validation: Diagrams successfully fixed`);
|
|
99718
|
-
if (mermaidValidation.performanceMetrics) {
|
|
99719
|
-
const metrics = mermaidValidation.performanceMetrics;
|
|
99720
|
-
console.log(`[DEBUG] Mermaid validation: Performance - total: ${metrics.totalTimeMs}ms, AI fixing: ${metrics.aiFixingTimeMs}ms`);
|
|
99721
|
-
console.log(`[DEBUG] Mermaid validation: Results - ${metrics.diagramsFixed}/${metrics.diagramsProcessed} diagrams fixed`);
|
|
99722
|
-
}
|
|
99723
|
-
if (mermaidValidation.fixingResults) {
|
|
99724
|
-
mermaidValidation.fixingResults.forEach((fixResult, index) => {
|
|
99725
|
-
if (fixResult.wasFixed) {
|
|
99726
|
-
const method = fixResult.fixedWithHtmlDecoding ? "HTML entity decoding" : "AI correction";
|
|
99727
|
-
const time3 = fixResult.aiFixingTimeMs ? ` in ${fixResult.aiFixingTimeMs}ms` : "";
|
|
99728
|
-
console.log(`[DEBUG] Mermaid validation: Fixed diagram ${fixResult.diagramIndex + 1} with ${method}${time3}`);
|
|
99729
|
-
console.log(`[DEBUG] Mermaid validation: Original error: ${fixResult.originalError}`);
|
|
99730
|
-
} else {
|
|
99731
|
-
console.log(`[DEBUG] Mermaid validation: Failed to fix diagram ${fixResult.diagramIndex + 1}: ${fixResult.fixingError}`);
|
|
99732
|
-
}
|
|
99733
|
-
});
|
|
99734
|
-
}
|
|
99735
|
-
}
|
|
99736
|
-
} else if (this.debug) {
|
|
99737
|
-
console.log(`[DEBUG] Mermaid validation: No fixes needed or fixes unsuccessful`);
|
|
99738
|
-
if (mermaidValidation.diagrams?.length > 0) {
|
|
99739
|
-
console.log(`[DEBUG] Mermaid validation: Found ${mermaidValidation.diagrams.length} diagrams, all valid: ${mermaidValidation.isValid}`);
|
|
99740
|
-
}
|
|
99741
|
-
}
|
|
99742
|
-
} catch (error40) {
|
|
99743
|
-
if (this.debug) {
|
|
99744
|
-
console.log(`[DEBUG] Mermaid validation: Process failed with error: ${error40.message}`);
|
|
99745
|
-
console.log(`[DEBUG] Mermaid validation: Stack trace: ${error40.stack}`);
|
|
99746
|
-
}
|
|
99747
|
-
}
|
|
99748
|
-
} else if (this.debug) {
|
|
99749
|
-
console.log(`[DEBUG] Mermaid validation: Skipped due to disableMermaidValidation option`);
|
|
99750
|
-
}
|
|
99751
|
-
finalResult = cleanSchemaResponse(finalResult);
|
|
99752
|
-
if (isJsonSchema(options.schema)) {
|
|
99753
|
-
if (this.debug) {
|
|
99754
|
-
console.log(`[DEBUG] JSON validation: Starting validation process for schema response`);
|
|
99755
|
-
console.log(`[DEBUG] JSON validation: Cleaned response length: ${finalResult.length} chars`);
|
|
99756
|
-
}
|
|
99757
|
-
if (this.tracer) {
|
|
99758
|
-
this.tracer.recordJsonValidationEvent("started", {
|
|
99759
|
-
"json_validation.response_length": finalResult.length,
|
|
99760
|
-
"json_validation.schema_type": "JSON"
|
|
99761
|
-
});
|
|
99762
|
-
}
|
|
99763
|
-
let validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
99764
|
-
let retryCount = 0;
|
|
99765
|
-
const maxRetries = 3;
|
|
99766
|
-
if (validation.isValid && isJsonSchemaDefinition(finalResult, { debug: this.debug })) {
|
|
99767
|
-
if (this.debug) {
|
|
99768
|
-
console.log(`[DEBUG] JSON validation: Response is a JSON schema definition instead of data, needs correction...`);
|
|
99769
|
-
}
|
|
99770
|
-
validation = {
|
|
99771
|
-
isValid: false,
|
|
99772
|
-
error: "Response is a JSON schema definition instead of actual data",
|
|
99773
|
-
enhancedError: "Response is a JSON schema definition instead of actual data. Please return data that conforms to the schema, not the schema itself."
|
|
99774
|
-
};
|
|
99775
|
-
}
|
|
99776
|
-
if (!validation.isValid) {
|
|
99777
|
-
if (this.debug) {
|
|
99778
|
-
console.log(`[DEBUG] JSON validation: Starting separate JsonFixingAgent session...`);
|
|
99779
|
-
}
|
|
99780
|
-
const { JsonFixingAgent: JsonFixingAgent2 } = await Promise.resolve().then(() => (init_schemaUtils(), schemaUtils_exports));
|
|
99781
|
-
const jsonFixer = new JsonFixingAgent2({
|
|
99782
|
-
path: this.workspaceRoot || this.allowedFolders[0],
|
|
99783
|
-
provider: this.clientApiProvider,
|
|
99784
|
-
model: this.model,
|
|
99785
|
-
debug: this.debug,
|
|
99786
|
-
tracer: this.tracer
|
|
99787
|
-
});
|
|
99788
|
-
let currentResult = finalResult;
|
|
99789
|
-
let currentValidation = validation;
|
|
99790
|
-
while (!currentValidation.isValid && retryCount < maxRetries) {
|
|
99791
|
-
if (this.debug) {
|
|
99792
|
-
console.log(`[DEBUG] JSON validation: Validation failed (attempt ${retryCount + 1}/${maxRetries}):`, currentValidation.error);
|
|
99793
|
-
console.log(`[DEBUG] JSON validation: Invalid response sample: ${currentResult.substring(0, 300)}${currentResult.length > 300 ? "..." : ""}`);
|
|
99794
|
-
}
|
|
99795
|
-
try {
|
|
99796
|
-
currentResult = await jsonFixer.fixJson(
|
|
99797
|
-
currentResult,
|
|
99798
|
-
options.schema,
|
|
99799
|
-
currentValidation,
|
|
99800
|
-
retryCount + 1
|
|
99801
|
-
);
|
|
99802
|
-
currentValidation = validateJsonResponse(currentResult, { debug: this.debug, schema: options.schema });
|
|
99803
|
-
retryCount++;
|
|
99804
|
-
if (this.debug) {
|
|
99805
|
-
if (!currentValidation.isValid && retryCount < maxRetries) {
|
|
99806
|
-
console.log(`[DEBUG] JSON validation: Still invalid after correction ${retryCount}, retrying...`);
|
|
99807
|
-
console.log(`[DEBUG] JSON validation: Corrected response sample: ${currentResult.substring(0, 300)}${currentResult.length > 300 ? "..." : ""}`);
|
|
99808
|
-
} else if (currentValidation.isValid) {
|
|
99809
|
-
console.log(`[DEBUG] JSON validation: Successfully corrected after ${retryCount} attempts with JsonFixingAgent`);
|
|
99810
|
-
}
|
|
99811
|
-
}
|
|
99812
|
-
} catch (error40) {
|
|
99813
|
-
if (this.debug) {
|
|
99814
|
-
console.error(`[DEBUG] JSON validation: JsonFixingAgent error on attempt ${retryCount + 1}:`, error40.message);
|
|
99815
|
-
}
|
|
99816
|
-
break;
|
|
99817
|
-
}
|
|
99818
|
-
}
|
|
99819
|
-
finalResult = currentResult;
|
|
99820
|
-
validation = currentValidation;
|
|
99821
|
-
if (!validation.isValid && this.debug) {
|
|
99822
|
-
console.log(`[DEBUG] JSON validation: Still invalid after ${maxRetries} correction attempts with JsonFixingAgent:`, validation.error);
|
|
99823
|
-
console.log(`[DEBUG] JSON validation: Final invalid response: ${finalResult.substring(0, 500)}${finalResult.length > 500 ? "..." : ""}`);
|
|
99824
|
-
} else if (validation.isValid && this.debug) {
|
|
99825
|
-
console.log(`[DEBUG] JSON validation: Final validation successful`);
|
|
99826
|
-
}
|
|
99827
|
-
}
|
|
99828
|
-
if (this.tracer) {
|
|
99829
|
-
this.tracer.recordJsonValidationEvent("completed", {
|
|
99830
|
-
"json_validation.success": validation.isValid,
|
|
99831
|
-
"json_validation.retry_count": retryCount,
|
|
99832
|
-
"json_validation.max_retries": maxRetries,
|
|
99833
|
-
"json_validation.final_response_length": finalResult.length,
|
|
99834
|
-
"json_validation.error": validation.isValid ? null : validation.error
|
|
99835
|
-
});
|
|
99836
|
-
}
|
|
99837
|
-
}
|
|
99838
|
-
} catch (error40) {
|
|
99839
|
-
console.error("[ERROR] Schema formatting failed:", error40);
|
|
99840
|
-
}
|
|
99841
|
-
} else if (reachedMaxIterations && options.schema && this.debug) {
|
|
99842
|
-
console.log("[DEBUG] Skipping schema formatting due to max iterations reached without completion");
|
|
99843
|
-
} else if (completionAttempted && options.schema && !options._schemaFormatted && !options._skipValidation) {
|
|
99343
|
+
if (options.schema && !options._schemaFormatted && !options._skipValidation) {
|
|
99844
99344
|
try {
|
|
99845
99345
|
if (!this.disableMermaidValidation) {
|
|
99846
99346
|
if (this.debug) {
|
|
99847
|
-
console.log(`[DEBUG] Mermaid validation: Validating
|
|
99347
|
+
console.log(`[DEBUG] Mermaid validation: Validating result BEFORE schema cleaning...`);
|
|
99848
99348
|
}
|
|
99849
99349
|
const mermaidValidation = await validateAndFixMermaidResponse(finalResult, {
|
|
99850
99350
|
debug: this.debug,
|
|
@@ -99856,55 +99356,51 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
99856
99356
|
if (mermaidValidation.wasFixed) {
|
|
99857
99357
|
finalResult = mermaidValidation.fixedResponse;
|
|
99858
99358
|
if (this.debug) {
|
|
99859
|
-
console.log(`[DEBUG] Mermaid validation:
|
|
99359
|
+
console.log(`[DEBUG] Mermaid validation: Diagrams fixed`);
|
|
99860
99360
|
if (mermaidValidation.performanceMetrics) {
|
|
99861
99361
|
console.log(`[DEBUG] Mermaid validation: Fixed in ${mermaidValidation.performanceMetrics.totalTimeMs}ms`);
|
|
99862
99362
|
}
|
|
99863
99363
|
}
|
|
99864
99364
|
} else if (this.debug) {
|
|
99865
|
-
console.log(`[DEBUG] Mermaid validation:
|
|
99365
|
+
console.log(`[DEBUG] Mermaid validation: Completed (no fixes needed)`);
|
|
99866
99366
|
}
|
|
99867
99367
|
} else if (this.debug) {
|
|
99868
|
-
console.log(`[DEBUG] Mermaid validation: Skipped
|
|
99368
|
+
console.log(`[DEBUG] Mermaid validation: Skipped due to disableMermaidValidation option`);
|
|
99869
99369
|
}
|
|
99870
99370
|
finalResult = cleanSchemaResponse(finalResult);
|
|
99871
99371
|
if (isJsonSchema(options.schema)) {
|
|
99872
99372
|
if (this.debug) {
|
|
99873
|
-
console.log(`[DEBUG] JSON validation: Starting validation process
|
|
99373
|
+
console.log(`[DEBUG] JSON validation: Starting validation process`);
|
|
99874
99374
|
console.log(`[DEBUG] JSON validation: Response length: ${finalResult.length} chars`);
|
|
99875
99375
|
}
|
|
99876
99376
|
if (this.tracer) {
|
|
99877
|
-
this.tracer.recordJsonValidationEvent("
|
|
99377
|
+
this.tracer.recordJsonValidationEvent("started", {
|
|
99878
99378
|
"json_validation.response_length": finalResult.length,
|
|
99879
|
-
"json_validation.schema_type": "JSON"
|
|
99880
|
-
"json_validation.context": "attempt_completion"
|
|
99379
|
+
"json_validation.schema_type": "JSON"
|
|
99881
99380
|
});
|
|
99882
99381
|
}
|
|
99883
|
-
let validation = validateJsonResponse(finalResult, { debug: this.debug });
|
|
99382
|
+
let validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
99884
99383
|
let retryCount = 0;
|
|
99885
99384
|
const maxRetries = 3;
|
|
99886
99385
|
if (validation.isValid && isJsonSchemaDefinition(finalResult, { debug: this.debug })) {
|
|
99887
99386
|
if (this.debug) {
|
|
99888
|
-
console.log(`[DEBUG] JSON validation:
|
|
99387
|
+
console.log(`[DEBUG] JSON validation: Response is a JSON schema definition instead of data, correcting...`);
|
|
99889
99388
|
}
|
|
99890
99389
|
const schemaDefinitionPrompt = createSchemaDefinitionCorrectionPrompt(
|
|
99891
99390
|
finalResult,
|
|
99892
99391
|
options.schema,
|
|
99893
99392
|
0
|
|
99894
99393
|
);
|
|
99895
|
-
const { schema: _unusedSchema1, ...schemaDefCorrectionOptions } = options;
|
|
99896
99394
|
finalResult = await this.answer(schemaDefinitionPrompt, [], {
|
|
99897
|
-
...
|
|
99395
|
+
...options,
|
|
99898
99396
|
_schemaFormatted: true,
|
|
99899
99397
|
_skipValidation: true,
|
|
99900
|
-
|
|
99398
|
+
_disableTools: true,
|
|
99901
99399
|
_completionPromptProcessed: true,
|
|
99902
|
-
// Prevent cascading completion prompts in retry calls
|
|
99903
99400
|
_maxIterationsOverride: 3
|
|
99904
|
-
// Correction should complete in 1-2 iterations (issue #447)
|
|
99905
99401
|
});
|
|
99906
99402
|
finalResult = cleanSchemaResponse(finalResult);
|
|
99907
|
-
validation = validateJsonResponse(finalResult);
|
|
99403
|
+
validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
99908
99404
|
retryCount = 1;
|
|
99909
99405
|
}
|
|
99910
99406
|
if (!validation.isValid) {
|
|
@@ -99914,20 +99410,16 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
99914
99410
|
console.log(`[DEBUG] JSON validation: Auto-wrapped plain text for simple schema`);
|
|
99915
99411
|
}
|
|
99916
99412
|
finalResult = autoWrapped;
|
|
99917
|
-
validation = validateJsonResponse(finalResult, { debug: this.debug });
|
|
99413
|
+
validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
99918
99414
|
}
|
|
99919
99415
|
}
|
|
99920
99416
|
while (!validation.isValid && retryCount < maxRetries) {
|
|
99921
99417
|
if (this.debug) {
|
|
99922
|
-
console.log(`[DEBUG] JSON validation:
|
|
99923
|
-
console.log(`[DEBUG] JSON validation: Invalid response sample: ${finalResult.substring(0, 300)}${finalResult.length > 300 ? "..." : ""}`);
|
|
99418
|
+
console.log(`[DEBUG] JSON validation: Validation failed (attempt ${retryCount + 1}/${maxRetries}):`, validation.error);
|
|
99924
99419
|
}
|
|
99925
99420
|
let correctionPrompt;
|
|
99926
99421
|
try {
|
|
99927
99422
|
if (isJsonSchemaDefinition(finalResult, { debug: this.debug })) {
|
|
99928
|
-
if (this.debug) {
|
|
99929
|
-
console.log(`[DEBUG] JSON validation: attempt_completion response is still a schema definition, using specialized correction`);
|
|
99930
|
-
}
|
|
99931
99423
|
correctionPrompt = createSchemaDefinitionCorrectionPrompt(
|
|
99932
99424
|
finalResult,
|
|
99933
99425
|
options.schema,
|
|
@@ -99949,47 +99441,43 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
99949
99441
|
retryCount
|
|
99950
99442
|
);
|
|
99951
99443
|
}
|
|
99952
|
-
const { schema: _unusedSchema2, ...correctionOptions } = options;
|
|
99953
99444
|
finalResult = await this.answer(correctionPrompt, [], {
|
|
99954
|
-
...
|
|
99445
|
+
...options,
|
|
99955
99446
|
_schemaFormatted: true,
|
|
99956
99447
|
_skipValidation: true,
|
|
99957
|
-
// Skip validation in recursive correction calls to prevent loops
|
|
99958
99448
|
_disableTools: true,
|
|
99959
|
-
// Only allow attempt_completion - prevent AI from using search/query tools
|
|
99960
99449
|
_completionPromptProcessed: true,
|
|
99961
|
-
// Prevent cascading completion prompts in retry calls
|
|
99962
99450
|
_maxIterationsOverride: 3
|
|
99963
|
-
// Correction should complete in 1-2 iterations (issue #447)
|
|
99964
99451
|
});
|
|
99965
99452
|
finalResult = cleanSchemaResponse(finalResult);
|
|
99966
|
-
validation = validateJsonResponse(finalResult, { debug: this.debug });
|
|
99453
|
+
validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
99967
99454
|
retryCount++;
|
|
99968
99455
|
if (this.debug) {
|
|
99969
99456
|
if (validation.isValid) {
|
|
99970
|
-
console.log(`[DEBUG] JSON validation:
|
|
99457
|
+
console.log(`[DEBUG] JSON validation: Correction successful on attempt ${retryCount}`);
|
|
99971
99458
|
} else {
|
|
99972
|
-
console.log(`[DEBUG] JSON validation:
|
|
99459
|
+
console.log(`[DEBUG] JSON validation: Correction failed on attempt ${retryCount}: ${validation.error}`);
|
|
99973
99460
|
}
|
|
99974
99461
|
}
|
|
99975
99462
|
}
|
|
99976
99463
|
if (this.tracer) {
|
|
99977
|
-
this.tracer.recordJsonValidationEvent("
|
|
99464
|
+
this.tracer.recordJsonValidationEvent("completed", {
|
|
99978
99465
|
"json_validation.success": validation.isValid,
|
|
99979
99466
|
"json_validation.retry_count": retryCount,
|
|
99980
|
-
"json_validation.
|
|
99467
|
+
"json_validation.max_retries": maxRetries,
|
|
99468
|
+
"json_validation.final_response_length": finalResult.length,
|
|
99469
|
+
"json_validation.error": validation.isValid ? null : validation.error
|
|
99981
99470
|
});
|
|
99982
99471
|
}
|
|
99983
99472
|
if (!validation.isValid && this.debug) {
|
|
99984
|
-
console.log(`[DEBUG] JSON validation:
|
|
99985
|
-
console.log(`[DEBUG] JSON validation: Final attempt_completion response: ${finalResult.substring(0, 500)}${finalResult.length > 500 ? "..." : ""}`);
|
|
99473
|
+
console.log(`[DEBUG] JSON validation: Failed after ${maxRetries} attempts: ${validation.error}`);
|
|
99986
99474
|
} else if (validation.isValid && this.debug) {
|
|
99987
|
-
console.log(`[DEBUG] JSON validation:
|
|
99475
|
+
console.log(`[DEBUG] JSON validation: Final validation successful`);
|
|
99988
99476
|
}
|
|
99989
99477
|
}
|
|
99990
99478
|
} catch (error40) {
|
|
99991
99479
|
if (this.debug) {
|
|
99992
|
-
console.log(`[DEBUG]
|
|
99480
|
+
console.log(`[DEBUG] Schema validation/cleanup failed: ${error40.message}`);
|
|
99993
99481
|
}
|
|
99994
99482
|
}
|
|
99995
99483
|
}
|
|
@@ -100088,7 +99576,6 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
100088
99576
|
* @returns {Object} Compaction statistics
|
|
100089
99577
|
*/
|
|
100090
99578
|
async compactHistory(options = {}) {
|
|
100091
|
-
const { compactMessages: compactMessages2, calculateCompactionStats: calculateCompactionStats2 } = await Promise.resolve().then(() => (init_contextCompactor(), contextCompactor_exports));
|
|
100092
99579
|
if (this.history.length === 0) {
|
|
100093
99580
|
if (this.debug) {
|
|
100094
99581
|
console.log(`[DEBUG] No history to compact for session ${this.sessionId}`);
|
|
@@ -100103,8 +99590,8 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
100103
99590
|
tokensSaved: 0
|
|
100104
99591
|
};
|
|
100105
99592
|
}
|
|
100106
|
-
const compactedMessages =
|
|
100107
|
-
const stats =
|
|
99593
|
+
const compactedMessages = compactMessages(this.history, options);
|
|
99594
|
+
const stats = calculateCompactionStats(this.history, compactedMessages);
|
|
100108
99595
|
this.history = compactedMessages;
|
|
100109
99596
|
try {
|
|
100110
99597
|
await this.storageAdapter.clearHistory(this.sessionId);
|
|
@@ -100930,7 +100417,7 @@ Instructions:
|
|
|
100930
100417
|
- Format as a structured list if multiple items found
|
|
100931
100418
|
- If nothing relevant is found in this chunk, respond with "No relevant items found in this chunk."
|
|
100932
100419
|
- Do NOT summarize the code - extract the specific information requested
|
|
100933
|
-
- When done,
|
|
100420
|
+
- When done, provide your final answer directly.`;
|
|
100934
100421
|
try {
|
|
100935
100422
|
const result = await delegate({
|
|
100936
100423
|
task,
|
|
@@ -100992,7 +100479,7 @@ async function aggregateResults(chunkResults2, aggregation, extractionPrompt, op
|
|
|
100992
100479
|
${stripResultTags(r.result)}`).join("\n\n");
|
|
100993
100480
|
const completionNote = `
|
|
100994
100481
|
|
|
100995
|
-
When done,
|
|
100482
|
+
When done, provide your final answer directly.`;
|
|
100996
100483
|
const aggregationPrompts = {
|
|
100997
100484
|
summarize: `Synthesize these analyses into a comprehensive summary. Combine related findings, remove redundancy, and present a coherent overview.
|
|
100998
100485
|
|
|
@@ -101086,7 +100573,7 @@ For example, if looking for customer data:
|
|
|
101086
100573
|
STEP 3: CREATE THE FINAL PLAN
|
|
101087
100574
|
Based on your experiments, output the BEST search strategy.
|
|
101088
100575
|
|
|
101089
|
-
|
|
100576
|
+
Provide your answer in this EXACT format:
|
|
101090
100577
|
|
|
101091
100578
|
SEARCH_QUERY: <the query that WORKED in your experiments - use OR for multiple terms>
|
|
101092
100579
|
AGGREGATION: <summarize | list_unique | count | group_by>
|
|
@@ -101152,7 +100639,7 @@ Your answer should:
|
|
|
101152
100639
|
|
|
101153
100640
|
Format your response as a well-structured document that fully answers: "${question}"
|
|
101154
100641
|
|
|
101155
|
-
When done,
|
|
100642
|
+
When done, provide your final answer directly.`;
|
|
101156
100643
|
try {
|
|
101157
100644
|
const result = await delegate({
|
|
101158
100645
|
task: synthesisTask,
|
|
@@ -101702,7 +101189,7 @@ var init_vercel = __esm({
|
|
|
101702
101189
|
if (debug) {
|
|
101703
101190
|
console.error(`[DEDUP] Blocked duplicate search: "${searchQuery}" (path: "${searchPath}")`);
|
|
101704
101191
|
}
|
|
101705
|
-
return "DUPLICATE SEARCH BLOCKED: You already searched for this exact query. Changing the path does NOT give different results \u2014 probe searches recursively. Do NOT repeat the same search. Try a genuinely different keyword, use extract to examine results you already found, or
|
|
101192
|
+
return "DUPLICATE SEARCH BLOCKED: You already searched for this exact query. Changing the path does NOT give different results \u2014 probe searches recursively. Do NOT repeat the same search. Try a genuinely different keyword, use extract to examine results you already found, or provide your final answer if you have enough information.";
|
|
101706
101193
|
}
|
|
101707
101194
|
previousSearches.add(searchKey);
|
|
101708
101195
|
paginationCounts.set(searchKey, 0);
|
|
@@ -101713,7 +101200,7 @@ var init_vercel = __esm({
|
|
|
101713
101200
|
if (debug) {
|
|
101714
101201
|
console.error(`[DEDUP] Blocked excessive pagination (page ${pageCount}/${MAX_PAGES_PER_QUERY}): "${searchQuery}" in "${searchPath}"`);
|
|
101715
101202
|
}
|
|
101716
|
-
return `PAGINATION LIMIT REACHED: You have already retrieved ${MAX_PAGES_PER_QUERY} pages of results for this query. You have enough results \u2014 use extract to examine specific files, or
|
|
101203
|
+
return `PAGINATION LIMIT REACHED: You have already retrieved ${MAX_PAGES_PER_QUERY} pages of results for this query. You have enough results \u2014 use extract to examine specific files, or provide your final answer with your findings.`;
|
|
101717
101204
|
}
|
|
101718
101205
|
}
|
|
101719
101206
|
try {
|
|
@@ -101752,7 +101239,7 @@ var init_vercel = __esm({
|
|
|
101752
101239
|
bashConfig: null,
|
|
101753
101240
|
architectureFileName: options.architectureFileName || null,
|
|
101754
101241
|
promptType: "code-searcher",
|
|
101755
|
-
allowedTools: ["search", "extract", "listFiles"
|
|
101242
|
+
allowedTools: ["search", "extract", "listFiles"],
|
|
101756
101243
|
searchDelegate: false,
|
|
101757
101244
|
schema: CODE_SEARCH_SCHEMA,
|
|
101758
101245
|
parentAbortSignal: options.parentAbortSignal || null
|
|
@@ -101923,14 +101410,15 @@ var init_vercel = __esm({
|
|
|
101923
101410
|
const parsedTargets = parseTargets(targets);
|
|
101924
101411
|
extractFiles = parsedTargets.map((target) => resolveTargetPath(target, effectiveCwd));
|
|
101925
101412
|
if (options.allowedFolders && options.allowedFolders.length > 0) {
|
|
101413
|
+
const { join: pathJoin, sep: pathSep } = await import("path");
|
|
101926
101414
|
extractFiles = extractFiles.map((target) => {
|
|
101927
101415
|
const { filePart, suffix } = splitTargetSuffix(target);
|
|
101928
101416
|
if ((0, import_fs11.existsSync)(filePart)) return target;
|
|
101929
|
-
const cwdPrefix = effectiveCwd.endsWith(
|
|
101417
|
+
const cwdPrefix = effectiveCwd.endsWith(pathSep) ? effectiveCwd : effectiveCwd + pathSep;
|
|
101930
101418
|
const relativePart = filePart.startsWith(cwdPrefix) ? filePart.slice(cwdPrefix.length) : null;
|
|
101931
101419
|
if (relativePart) {
|
|
101932
101420
|
for (const folder of options.allowedFolders) {
|
|
101933
|
-
const candidate = folder
|
|
101421
|
+
const candidate = pathJoin(folder, relativePart);
|
|
101934
101422
|
if ((0, import_fs11.existsSync)(candidate)) {
|
|
101935
101423
|
if (debug) console.error(`[extract] Auto-fixed path: ${filePart} \u2192 ${candidate}`);
|
|
101936
101424
|
return candidate + suffix;
|
|
@@ -101938,11 +101426,12 @@ var init_vercel = __esm({
|
|
|
101938
101426
|
}
|
|
101939
101427
|
}
|
|
101940
101428
|
for (const folder of options.allowedFolders) {
|
|
101941
|
-
const folderPrefix = folder.endsWith(
|
|
101942
|
-
const
|
|
101429
|
+
const folderPrefix = folder.endsWith(pathSep) ? folder : folder + pathSep;
|
|
101430
|
+
const sepEscaped = pathSep === "\\" ? "\\\\" : pathSep;
|
|
101431
|
+
const wsParent = folderPrefix.replace(new RegExp("[^" + sepEscaped + "]+" + sepEscaped + "$"), "");
|
|
101943
101432
|
if (filePart.startsWith(wsParent)) {
|
|
101944
101433
|
const tail = filePart.slice(wsParent.length);
|
|
101945
|
-
const candidate = folderPrefix
|
|
101434
|
+
const candidate = pathJoin(folderPrefix, tail);
|
|
101946
101435
|
if (candidate !== filePart && (0, import_fs11.existsSync)(candidate)) {
|
|
101947
101436
|
if (debug) console.error(`[extract] Auto-fixed path via workspace: ${filePart} \u2192 ${candidate}`);
|
|
101948
101437
|
return candidate + suffix;
|
|
@@ -103334,7 +102823,6 @@ For GitHub-compatible mermaid diagrams, avoid single quotes and parentheses in n
|
|
|
103334
102823
|
var tools_exports = {};
|
|
103335
102824
|
__export(tools_exports, {
|
|
103336
102825
|
DEFAULT_SYSTEM_MESSAGE: () => DEFAULT_SYSTEM_MESSAGE,
|
|
103337
|
-
attemptCompletionSchema: () => attemptCompletionSchema,
|
|
103338
102826
|
bashDescription: () => bashDescription,
|
|
103339
102827
|
bashSchema: () => bashSchema,
|
|
103340
102828
|
bashTool: () => bashTool,
|
|
@@ -103982,7 +103470,6 @@ __export(index_exports, {
|
|
|
103982
103470
|
TaskManager: () => TaskManager,
|
|
103983
103471
|
analyzeAllSchema: () => analyzeAllSchema,
|
|
103984
103472
|
analyzeAllTool: () => analyzeAllTool,
|
|
103985
|
-
attemptCompletionSchema: () => attemptCompletionSchema,
|
|
103986
103473
|
bashSchema: () => bashSchema,
|
|
103987
103474
|
bashTool: () => bashTool,
|
|
103988
103475
|
cleanupExecutePlanSchema: () => cleanupExecutePlanSchema,
|
|
@@ -104069,7 +103556,6 @@ init_index();
|
|
|
104069
103556
|
TaskManager,
|
|
104070
103557
|
analyzeAllSchema,
|
|
104071
103558
|
analyzeAllTool,
|
|
104072
|
-
attemptCompletionSchema,
|
|
104073
103559
|
bashSchema,
|
|
104074
103560
|
bashTool,
|
|
104075
103561
|
cleanupExecutePlanSchema,
|