@probelabs/probe 0.6.0-rc283 → 0.6.0-rc285
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-rc285-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc285-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc285-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc285-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc285-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.d.ts +1 -1
- package/build/agent/ProbeAgent.js +333 -486
- package/build/agent/contextCompactor.js +17 -10
- package/build/agent/index.js +301 -702
- 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/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 +3 -3
- package/cjs/agent/ProbeAgent.cjs +33158 -42860
- package/cjs/index.cjs +31325 -41082
- package/package.json +8 -8
- package/src/agent/ProbeAgent.d.ts +1 -1
- package/src/agent/ProbeAgent.js +333 -486
- 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/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 +3 -3
- package/bin/binaries/probe-v0.6.0-rc283-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc283-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc283-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc283-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc283-x86_64-unknown-linux-musl.tar.gz +0 -0
package/build/agent/index.js
CHANGED
|
@@ -4393,7 +4393,7 @@ Instructions:
|
|
|
4393
4393
|
- Format as a structured list if multiple items found
|
|
4394
4394
|
- If nothing relevant is found in this chunk, respond with "No relevant items found in this chunk."
|
|
4395
4395
|
- Do NOT summarize the code - extract the specific information requested
|
|
4396
|
-
- When done,
|
|
4396
|
+
- When done, provide your final answer directly.`;
|
|
4397
4397
|
try {
|
|
4398
4398
|
const result = await delegate({
|
|
4399
4399
|
task,
|
|
@@ -4455,7 +4455,7 @@ async function aggregateResults(chunkResults2, aggregation, extractionPrompt, op
|
|
|
4455
4455
|
${stripResultTags(r.result)}`).join("\n\n");
|
|
4456
4456
|
const completionNote = `
|
|
4457
4457
|
|
|
4458
|
-
When done,
|
|
4458
|
+
When done, provide your final answer directly.`;
|
|
4459
4459
|
const aggregationPrompts = {
|
|
4460
4460
|
summarize: `Synthesize these analyses into a comprehensive summary. Combine related findings, remove redundancy, and present a coherent overview.
|
|
4461
4461
|
|
|
@@ -4549,7 +4549,7 @@ For example, if looking for customer data:
|
|
|
4549
4549
|
STEP 3: CREATE THE FINAL PLAN
|
|
4550
4550
|
Based on your experiments, output the BEST search strategy.
|
|
4551
4551
|
|
|
4552
|
-
|
|
4552
|
+
Provide your answer in this EXACT format:
|
|
4553
4553
|
|
|
4554
4554
|
SEARCH_QUERY: <the query that WORKED in your experiments - use OR for multiple terms>
|
|
4555
4555
|
AGGREGATION: <summarize | list_unique | count | group_by>
|
|
@@ -4615,7 +4615,7 @@ Your answer should:
|
|
|
4615
4615
|
|
|
4616
4616
|
Format your response as a well-structured document that fully answers: "${question}"
|
|
4617
4617
|
|
|
4618
|
-
When done,
|
|
4618
|
+
When done, provide your final answer directly.`;
|
|
4619
4619
|
try {
|
|
4620
4620
|
const result = await delegate({
|
|
4621
4621
|
task: synthesisTask,
|
|
@@ -8893,6 +8893,34 @@ function createMessagePreview(message, charsPerSide = 200) {
|
|
|
8893
8893
|
const end = message.substring(message.length - charsPerSide);
|
|
8894
8894
|
return `${start}...${end}`;
|
|
8895
8895
|
}
|
|
8896
|
+
function detectStuckResponse(response) {
|
|
8897
|
+
if (!response || typeof response !== "string") {
|
|
8898
|
+
return false;
|
|
8899
|
+
}
|
|
8900
|
+
const stuckPatterns = [
|
|
8901
|
+
/\bi\s+cannot\s+proceed\b/i,
|
|
8902
|
+
/\bi\s+can['']t\s+(?:proceed|continue|move\s+forward)\b/i,
|
|
8903
|
+
/\bunable\s+to\s+(?:proceed|continue|complete)\b/i,
|
|
8904
|
+
/\bblocked\b.*\b(?:proceed|continue)\b/i,
|
|
8905
|
+
/\bneed\s+(?:the|an?)\s+\w+(?:\s+\w+)?\s+to\s+(?:proceed|continue)\b/i,
|
|
8906
|
+
/\brequire[sd]?\s+(?:the|an?)\s+\w+\b.*\bto\s+(?:proceed|continue)\b/i,
|
|
8907
|
+
/\bmissing\s+(?:required|necessary|essential)\b/i,
|
|
8908
|
+
/\bdeadlock\b/i,
|
|
8909
|
+
/\bwe\s+are\s+in\s+a\s+loop\b/i,
|
|
8910
|
+
/\bstuck\s+in\s+a\s+loop\b/i,
|
|
8911
|
+
/\bi\s+(?:have|['']ve)\s+(?:explained|stated|mentioned)\s+(?:this|the\s+situation|it)\s+(?:multiple|several)\s+times\b/i,
|
|
8912
|
+
/\bi\s+(?:cannot|can['']t|could\s+not|couldn['']t)\s+(?:find|locate|get|retrieve|obtain)\s+(?:the|this|that|an?)\b/i,
|
|
8913
|
+
/\bno\s+way\s+to\s+(?:find|get|obtain|retrieve)\b/i,
|
|
8914
|
+
/\bi\s+(?:have|['']ve)\s+exhausted\s+(?:all|my)\s+(?:available\s+)?(?:options|methods|approaches)\b/i,
|
|
8915
|
+
/\bneither\s+of\s+these\s+methods\b/i
|
|
8916
|
+
];
|
|
8917
|
+
for (const pattern of stuckPatterns) {
|
|
8918
|
+
if (pattern.test(response)) {
|
|
8919
|
+
return true;
|
|
8920
|
+
}
|
|
8921
|
+
}
|
|
8922
|
+
return false;
|
|
8923
|
+
}
|
|
8896
8924
|
function parseTargets(targets) {
|
|
8897
8925
|
if (!targets || typeof targets !== "string") {
|
|
8898
8926
|
return [];
|
|
@@ -9402,7 +9430,7 @@ var init_vercel = __esm({
|
|
|
9402
9430
|
if (debug) {
|
|
9403
9431
|
console.error(`[DEDUP] Blocked duplicate search: "${searchQuery}" (path: "${searchPath}")`);
|
|
9404
9432
|
}
|
|
9405
|
-
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
|
|
9433
|
+
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.";
|
|
9406
9434
|
}
|
|
9407
9435
|
previousSearches.add(searchKey);
|
|
9408
9436
|
paginationCounts.set(searchKey, 0);
|
|
@@ -9413,7 +9441,7 @@ var init_vercel = __esm({
|
|
|
9413
9441
|
if (debug) {
|
|
9414
9442
|
console.error(`[DEDUP] Blocked excessive pagination (page ${pageCount}/${MAX_PAGES_PER_QUERY}): "${searchQuery}" in "${searchPath}"`);
|
|
9415
9443
|
}
|
|
9416
|
-
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
|
|
9444
|
+
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.`;
|
|
9417
9445
|
}
|
|
9418
9446
|
}
|
|
9419
9447
|
try {
|
|
@@ -9452,7 +9480,7 @@ var init_vercel = __esm({
|
|
|
9452
9480
|
bashConfig: null,
|
|
9453
9481
|
architectureFileName: options.architectureFileName || null,
|
|
9454
9482
|
promptType: "code-searcher",
|
|
9455
|
-
allowedTools: ["search", "extract", "listFiles"
|
|
9483
|
+
allowedTools: ["search", "extract", "listFiles"],
|
|
9456
9484
|
searchDelegate: false,
|
|
9457
9485
|
schema: CODE_SEARCH_SCHEMA,
|
|
9458
9486
|
parentAbortSignal: options.parentAbortSignal || null
|
|
@@ -31946,7 +31974,7 @@ For each pending/in_progress task, either:
|
|
|
31946
31974
|
- Complete it: call task tool with action="complete", id="task-X"
|
|
31947
31975
|
- Cancel it: call task tool with action="update", id="task-X", status="cancelled"
|
|
31948
31976
|
|
|
31949
|
-
After all tasks are resolved,
|
|
31977
|
+
After all tasks are resolved, provide your final answer.`;
|
|
31950
31978
|
}
|
|
31951
31979
|
function createTaskTool(options = {}) {
|
|
31952
31980
|
const { taskManager, tracer, debug = false } = options;
|
|
@@ -32196,13 +32224,13 @@ Tasks = logical units of work, not files or steps.
|
|
|
32196
32224
|
|
|
32197
32225
|
1. **Plan**: Call task tool with action="create" and a tasks array up front
|
|
32198
32226
|
2. **Execute**: Update status to "in_progress" / "completed" as you work. Add, split, or cancel tasks as you learn more.
|
|
32199
|
-
3. **Finish**: All tasks must be "completed" or "cancelled" before
|
|
32227
|
+
3. **Finish**: All tasks must be "completed" or "cancelled" before providing your final answer.
|
|
32200
32228
|
|
|
32201
32229
|
## Rules
|
|
32202
32230
|
|
|
32203
32231
|
- Dependencies are enforced: a task cannot start until its dependencies are completed
|
|
32204
32232
|
- Circular dependencies are rejected
|
|
32205
|
-
-
|
|
32233
|
+
- Completion is blocked while tasks remain unresolved
|
|
32206
32234
|
`;
|
|
32207
32235
|
}
|
|
32208
32236
|
});
|
|
@@ -69068,68 +69096,9 @@ var require_ajv = __commonJS({
|
|
|
69068
69096
|
});
|
|
69069
69097
|
|
|
69070
69098
|
// src/agent/schemaUtils.js
|
|
69071
|
-
var schemaUtils_exports = {};
|
|
69072
|
-
__export(schemaUtils_exports, {
|
|
69073
|
-
JsonFixingAgent: () => JsonFixingAgent,
|
|
69074
|
-
MermaidFixingAgent: () => MermaidFixingAgent,
|
|
69075
|
-
cleanSchemaResponse: () => cleanSchemaResponse,
|
|
69076
|
-
createJsonCorrectionPrompt: () => createJsonCorrectionPrompt,
|
|
69077
|
-
createMermaidCorrectionPrompt: () => createMermaidCorrectionPrompt,
|
|
69078
|
-
createSchemaDefinitionCorrectionPrompt: () => createSchemaDefinitionCorrectionPrompt,
|
|
69079
|
-
decodeHtmlEntities: () => decodeHtmlEntities2,
|
|
69080
|
-
extractMermaidFromJson: () => extractMermaidFromJson,
|
|
69081
|
-
extractMermaidFromMarkdown: () => extractMermaidFromMarkdown,
|
|
69082
|
-
generateExampleFromSchema: () => generateExampleFromSchema,
|
|
69083
|
-
generateSchemaInstructions: () => generateSchemaInstructions,
|
|
69084
|
-
isJsonSchema: () => isJsonSchema,
|
|
69085
|
-
isJsonSchemaDefinition: () => isJsonSchemaDefinition,
|
|
69086
|
-
isMermaidSchema: () => isMermaidSchema,
|
|
69087
|
-
isSimpleTextWrapperSchema: () => isSimpleTextWrapperSchema,
|
|
69088
|
-
processSchemaResponse: () => processSchemaResponse,
|
|
69089
|
-
replaceMermaidDiagramsInJson: () => replaceMermaidDiagramsInJson,
|
|
69090
|
-
replaceMermaidDiagramsInMarkdown: () => replaceMermaidDiagramsInMarkdown,
|
|
69091
|
-
sanitizeMarkdownEscapesInJson: () => sanitizeMarkdownEscapesInJson,
|
|
69092
|
-
tryAutoWrapForSimpleSchema: () => tryAutoWrapForSimpleSchema,
|
|
69093
|
-
tryExtractValidJsonPrefix: () => tryExtractValidJsonPrefix,
|
|
69094
|
-
tryMaidAutoFix: () => tryMaidAutoFix,
|
|
69095
|
-
validateAndFixMermaidResponse: () => validateAndFixMermaidResponse,
|
|
69096
|
-
validateJsonResponse: () => validateJsonResponse,
|
|
69097
|
-
validateMermaidDiagram: () => validateMermaidDiagram,
|
|
69098
|
-
validateMermaidResponse: () => validateMermaidResponse,
|
|
69099
|
-
validateXmlResponse: () => validateXmlResponse
|
|
69100
|
-
});
|
|
69101
|
-
function generateExampleFromSchema(schema, options = {}) {
|
|
69102
|
-
const { debug = false } = options;
|
|
69103
|
-
try {
|
|
69104
|
-
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
69105
|
-
if (parsedSchema.type !== "object" || !parsedSchema.properties) {
|
|
69106
|
-
return null;
|
|
69107
|
-
}
|
|
69108
|
-
const exampleObj = {};
|
|
69109
|
-
for (const [key, value] of Object.entries(parsedSchema.properties)) {
|
|
69110
|
-
if (value.type === "boolean") {
|
|
69111
|
-
exampleObj[key] = false;
|
|
69112
|
-
} else if (value.type === "number") {
|
|
69113
|
-
exampleObj[key] = 0;
|
|
69114
|
-
} else if (value.type === "string") {
|
|
69115
|
-
exampleObj[key] = value.description || "your answer here";
|
|
69116
|
-
} else if (value.type === "array") {
|
|
69117
|
-
exampleObj[key] = [];
|
|
69118
|
-
} else {
|
|
69119
|
-
exampleObj[key] = {};
|
|
69120
|
-
}
|
|
69121
|
-
}
|
|
69122
|
-
return exampleObj;
|
|
69123
|
-
} catch (e) {
|
|
69124
|
-
if (debug) {
|
|
69125
|
-
console.error("[DEBUG] generateExampleFromSchema: Failed to parse schema:", e.message);
|
|
69126
|
-
}
|
|
69127
|
-
return null;
|
|
69128
|
-
}
|
|
69129
|
-
}
|
|
69130
69099
|
function generateSchemaInstructions(schema, options = {}) {
|
|
69131
69100
|
const { debug = false } = options;
|
|
69132
|
-
let instructions = "\n\nIMPORTANT: When you provide your final answer
|
|
69101
|
+
let instructions = "\n\nIMPORTANT: When you provide your final answer, you MUST format it as valid JSON matching this schema:\n\n";
|
|
69133
69102
|
try {
|
|
69134
69103
|
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
69135
69104
|
instructions += `${JSON.stringify(parsedSchema, null, 2)}
|
|
@@ -69143,7 +69112,7 @@ function generateSchemaInstructions(schema, options = {}) {
|
|
|
69143
69112
|
|
|
69144
69113
|
`;
|
|
69145
69114
|
}
|
|
69146
|
-
instructions += "Your response
|
|
69115
|
+
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.";
|
|
69147
69116
|
return instructions;
|
|
69148
69117
|
}
|
|
69149
69118
|
function enforceNoAdditionalProperties(schema) {
|
|
@@ -69840,18 +69809,18 @@ function createJsonCorrectionPrompt(invalidResponse, schema, errorOrValidation,
|
|
|
69840
69809
|
const strengthLevels = [
|
|
69841
69810
|
{
|
|
69842
69811
|
prefix: "CRITICAL JSON ERROR:",
|
|
69843
|
-
instruction: "You MUST fix this and respond
|
|
69844
|
-
emphasis: "
|
|
69812
|
+
instruction: "You MUST fix this and respond with ONLY valid JSON.",
|
|
69813
|
+
emphasis: "Respond with ONLY the corrected JSON. No explanatory text, no markdown, no code blocks."
|
|
69845
69814
|
},
|
|
69846
69815
|
{
|
|
69847
69816
|
prefix: "URGENT - JSON PARSING FAILED:",
|
|
69848
|
-
instruction: "This is your second chance.
|
|
69849
|
-
emphasis: "ABSOLUTELY NO explanatory text or formatting.
|
|
69817
|
+
instruction: "This is your second chance. Respond with valid JSON that can be parsed by JSON.parse().",
|
|
69818
|
+
emphasis: "ABSOLUTELY NO explanatory text or formatting. Respond with ONLY raw JSON."
|
|
69850
69819
|
},
|
|
69851
69820
|
{
|
|
69852
69821
|
prefix: "FINAL ATTEMPT - CRITICAL JSON ERROR:",
|
|
69853
|
-
instruction: "This is the final retry. You MUST
|
|
69854
|
-
emphasis: 'CORRECT:
|
|
69822
|
+
instruction: "This is the final retry. You MUST respond with ONLY raw JSON.",
|
|
69823
|
+
emphasis: 'CORRECT: {"key": "value"}\nWRONG: Here is the JSON: {"key": "value"}\nWRONG: ```json{"key": "value"}```'
|
|
69855
69824
|
}
|
|
69856
69825
|
];
|
|
69857
69826
|
const level = Math.min(retryCount, strengthLevels.length - 1);
|
|
@@ -69905,28 +69874,6 @@ ${currentLevel.example}
|
|
|
69905
69874
|
Return ONLY the JSON data object/array that follows the schema structure. NO schema definitions, NO explanations, NO markdown formatting.`;
|
|
69906
69875
|
return prompt;
|
|
69907
69876
|
}
|
|
69908
|
-
function isMermaidSchema(schema) {
|
|
69909
|
-
if (!schema || typeof schema !== "string") {
|
|
69910
|
-
return false;
|
|
69911
|
-
}
|
|
69912
|
-
const trimmedSchema = schema.trim().toLowerCase();
|
|
69913
|
-
const mermaidIndicators = [
|
|
69914
|
-
trimmedSchema.includes("mermaid"),
|
|
69915
|
-
trimmedSchema.includes("diagram"),
|
|
69916
|
-
trimmedSchema.includes("flowchart"),
|
|
69917
|
-
trimmedSchema.includes("sequence"),
|
|
69918
|
-
trimmedSchema.includes("gantt"),
|
|
69919
|
-
trimmedSchema.includes("pie chart"),
|
|
69920
|
-
trimmedSchema.includes("state diagram"),
|
|
69921
|
-
trimmedSchema.includes("class diagram"),
|
|
69922
|
-
trimmedSchema.includes("entity relationship"),
|
|
69923
|
-
trimmedSchema.includes("user journey"),
|
|
69924
|
-
trimmedSchema.includes("git graph"),
|
|
69925
|
-
trimmedSchema.includes("requirement diagram"),
|
|
69926
|
-
trimmedSchema.includes("c4 context")
|
|
69927
|
-
];
|
|
69928
|
-
return mermaidIndicators.some((indicator) => indicator);
|
|
69929
|
-
}
|
|
69930
69877
|
function extractMermaidFromJson(response) {
|
|
69931
69878
|
if (!response || typeof response !== "string") {
|
|
69932
69879
|
return { diagrams: [], jsonPaths: [], parsedJson: null };
|
|
@@ -70058,28 +70005,6 @@ ${modifiedJsonString}
|
|
|
70058
70005
|
}
|
|
70059
70006
|
return modifiedJsonString;
|
|
70060
70007
|
}
|
|
70061
|
-
function replaceMermaidDiagramsInMarkdown(originalResponse, correctedDiagrams) {
|
|
70062
|
-
if (!originalResponse || typeof originalResponse !== "string") {
|
|
70063
|
-
return originalResponse;
|
|
70064
|
-
}
|
|
70065
|
-
if (!correctedDiagrams || correctedDiagrams.length === 0) {
|
|
70066
|
-
return originalResponse;
|
|
70067
|
-
}
|
|
70068
|
-
const hasJsonDiagrams = correctedDiagrams.some((d) => d.isInJson);
|
|
70069
|
-
if (hasJsonDiagrams) {
|
|
70070
|
-
return replaceMermaidDiagramsInJson(originalResponse, correctedDiagrams);
|
|
70071
|
-
}
|
|
70072
|
-
let modifiedResponse = originalResponse;
|
|
70073
|
-
const sortedDiagrams = [...correctedDiagrams].sort((a, b) => b.startIndex - a.startIndex);
|
|
70074
|
-
for (const diagram of sortedDiagrams) {
|
|
70075
|
-
const attributesStr = diagram.attributes ? ` ${diagram.attributes}` : "";
|
|
70076
|
-
const newCodeBlock = `\`\`\`mermaid${attributesStr}
|
|
70077
|
-
${diagram.content}
|
|
70078
|
-
\`\`\``;
|
|
70079
|
-
modifiedResponse = modifiedResponse.slice(0, diagram.startIndex) + newCodeBlock + modifiedResponse.slice(diagram.endIndex);
|
|
70080
|
-
}
|
|
70081
|
-
return modifiedResponse;
|
|
70082
|
-
}
|
|
70083
70008
|
function replaceSingleMermaidDiagramInResponse(response, originalDiagram, newContent) {
|
|
70084
70009
|
if (!originalDiagram) {
|
|
70085
70010
|
return response;
|
|
@@ -70164,45 +70089,6 @@ async function validateMermaidResponse(response) {
|
|
|
70164
70089
|
errors: errors.length > 0 ? errors : void 0
|
|
70165
70090
|
};
|
|
70166
70091
|
}
|
|
70167
|
-
function createMermaidCorrectionPrompt(invalidResponse, schema, errors, diagrams) {
|
|
70168
|
-
let prompt = `Your previous response contains invalid Mermaid diagrams that cannot be parsed. Here's what you returned:
|
|
70169
|
-
|
|
70170
|
-
${invalidResponse}
|
|
70171
|
-
|
|
70172
|
-
Validation Errors:`;
|
|
70173
|
-
errors.forEach((error, index) => {
|
|
70174
|
-
prompt += `
|
|
70175
|
-
${index + 1}. ${error}`;
|
|
70176
|
-
});
|
|
70177
|
-
if (diagrams && diagrams.length > 0) {
|
|
70178
|
-
prompt += `
|
|
70179
|
-
|
|
70180
|
-
Diagram Details:`;
|
|
70181
|
-
diagrams.forEach((diagramResult, index) => {
|
|
70182
|
-
if (!diagramResult.isValid) {
|
|
70183
|
-
prompt += `
|
|
70184
|
-
|
|
70185
|
-
Diagram ${index + 1}:`;
|
|
70186
|
-
const diagramContent = diagramResult.content || diagramResult.diagram || "";
|
|
70187
|
-
prompt += `
|
|
70188
|
-
- Content: ${diagramContent.substring(0, 100)}${diagramContent.length > 100 ? "..." : ""}`;
|
|
70189
|
-
prompt += `
|
|
70190
|
-
- Error: ${diagramResult.error}`;
|
|
70191
|
-
if (diagramResult.detailedError && diagramResult.detailedError !== diagramResult.error) {
|
|
70192
|
-
prompt += `
|
|
70193
|
-
- Details: ${diagramResult.detailedError}`;
|
|
70194
|
-
}
|
|
70195
|
-
}
|
|
70196
|
-
});
|
|
70197
|
-
}
|
|
70198
|
-
prompt += `
|
|
70199
|
-
|
|
70200
|
-
Please correct your response to include valid Mermaid diagrams that match this schema:
|
|
70201
|
-
${schema}
|
|
70202
|
-
|
|
70203
|
-
Ensure all Mermaid diagrams are properly formatted within \`\`\`mermaid code blocks and follow correct Mermaid syntax.`;
|
|
70204
|
-
return prompt;
|
|
70205
|
-
}
|
|
70206
70092
|
async function tryMaidAutoFix(diagramContent, options = {}) {
|
|
70207
70093
|
const { debug = false } = options;
|
|
70208
70094
|
try {
|
|
@@ -70512,7 +70398,7 @@ async function validateAndFixMermaidResponse(response, options = {}) {
|
|
|
70512
70398
|
};
|
|
70513
70399
|
}
|
|
70514
70400
|
}
|
|
70515
|
-
var import_ajv, HTML_ENTITY_MAP, sessionIdCounter,
|
|
70401
|
+
var import_ajv, HTML_ENTITY_MAP, sessionIdCounter, MermaidFixingAgent;
|
|
70516
70402
|
var init_schemaUtils = __esm({
|
|
70517
70403
|
"src/agent/schemaUtils.js"() {
|
|
70518
70404
|
"use strict";
|
|
@@ -70530,172 +70416,6 @@ var init_schemaUtils = __esm({
|
|
|
70530
70416
|
" ": " "
|
|
70531
70417
|
};
|
|
70532
70418
|
sessionIdCounter = 0;
|
|
70533
|
-
JsonFixingAgent = class {
|
|
70534
|
-
constructor(options = {}) {
|
|
70535
|
-
this.ProbeAgent = null;
|
|
70536
|
-
this.options = {
|
|
70537
|
-
sessionId: options.sessionId || `json-fixer-${Date.now()}-${sessionIdCounter++}`,
|
|
70538
|
-
path: options.path || process.cwd(),
|
|
70539
|
-
provider: options.provider,
|
|
70540
|
-
model: options.model,
|
|
70541
|
-
debug: options.debug,
|
|
70542
|
-
tracer: options.tracer,
|
|
70543
|
-
// Set to false since we're only fixing JSON syntax, not implementing code
|
|
70544
|
-
allowEdit: false
|
|
70545
|
-
};
|
|
70546
|
-
}
|
|
70547
|
-
/**
|
|
70548
|
-
* Get the specialized prompt for JSON fixing
|
|
70549
|
-
*/
|
|
70550
|
-
getJsonFixingPrompt() {
|
|
70551
|
-
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.
|
|
70552
|
-
|
|
70553
|
-
CORE RESPONSIBILITIES:
|
|
70554
|
-
- Analyze JSON for syntax errors and structural issues
|
|
70555
|
-
- Fix syntax errors while maintaining the original data's semantic meaning
|
|
70556
|
-
- Ensure JSON follows proper RFC 8259 specification
|
|
70557
|
-
- Handle all JSON structures: objects, arrays, primitives, nested structures
|
|
70558
|
-
|
|
70559
|
-
JSON SYNTAX RULES:
|
|
70560
|
-
1. **Property names**: Must be enclosed in double quotes
|
|
70561
|
-
2. **String values**: Must use double quotes (not single quotes)
|
|
70562
|
-
3. **Numbers**: Can be integers or decimals, no quotes needed
|
|
70563
|
-
4. **Booleans**: true or false (lowercase, no quotes)
|
|
70564
|
-
5. **Null**: null (lowercase, no quotes)
|
|
70565
|
-
6. **Arrays**: Comma-separated values in square brackets [...]
|
|
70566
|
-
7. **Objects**: Comma-separated key-value pairs in curly braces {...}
|
|
70567
|
-
8. **No trailing commas**: Last item in array/object must not have a trailing comma
|
|
70568
|
-
9. **Escape sequences**: Special characters must be escaped (\\n, \\t, \\", \\\\, etc.)
|
|
70569
|
-
|
|
70570
|
-
COMMON ERRORS TO FIX:
|
|
70571
|
-
1. **Unquoted property names**: {name: "value"} \u2192 {"name": "value"}
|
|
70572
|
-
2. **Single quotes**: {'key': 'value'} \u2192 {"key": "value"}
|
|
70573
|
-
3. **Trailing commas**: {"a": 1,} \u2192 {"a": 1}
|
|
70574
|
-
4. **Unquoted strings**: {key: value} \u2192 {"key": "value"}
|
|
70575
|
-
5. **Missing commas**: {"a": 1 "b": 2} \u2192 {"a": 1, "b": 2}
|
|
70576
|
-
6. **Extra commas**: {"a": 1,, "b": 2} \u2192 {"a": 1, "b": 2}
|
|
70577
|
-
7. **Unclosed brackets/braces**: {"key": "value" \u2192 {"key": "value"}
|
|
70578
|
-
8. **Invalid escape sequences**: Fix or remove
|
|
70579
|
-
9. **Comments**: Remove // or /* */ comments (not allowed in JSON)
|
|
70580
|
-
10. **Undefined values**: Replace undefined with null
|
|
70581
|
-
|
|
70582
|
-
FIXING METHODOLOGY:
|
|
70583
|
-
1. **Identify the error location** from the error message
|
|
70584
|
-
2. **Analyze the context** around the error
|
|
70585
|
-
3. **Apply the appropriate fix** based on JSON syntax rules
|
|
70586
|
-
4. **Preserve data intent** - never change the meaning of the data
|
|
70587
|
-
5. **Validate the result** - ensure it's parseable JSON
|
|
70588
|
-
|
|
70589
|
-
CRITICAL RULES:
|
|
70590
|
-
- ALWAYS output only the corrected JSON
|
|
70591
|
-
- NEVER add explanations, comments, or additional text
|
|
70592
|
-
- NEVER wrap in markdown code blocks (no \`\`\`json)
|
|
70593
|
-
- PRESERVE the original data structure and values
|
|
70594
|
-
- FIX only syntax errors, don't modify the data itself
|
|
70595
|
-
- ENSURE the output is valid, parseable JSON
|
|
70596
|
-
|
|
70597
|
-
When presented with broken JSON, analyze it thoroughly and provide the corrected version that maintains the original intent while fixing all syntax issues.`;
|
|
70598
|
-
}
|
|
70599
|
-
/**
|
|
70600
|
-
* Initialize the ProbeAgent if not already done
|
|
70601
|
-
*/
|
|
70602
|
-
async initializeAgent() {
|
|
70603
|
-
if (!this.ProbeAgent) {
|
|
70604
|
-
const { ProbeAgent: ProbeAgent2 } = await Promise.resolve().then(() => (init_ProbeAgent(), ProbeAgent_exports));
|
|
70605
|
-
this.ProbeAgent = ProbeAgent2;
|
|
70606
|
-
}
|
|
70607
|
-
if (!this.agent) {
|
|
70608
|
-
this.agent = new this.ProbeAgent({
|
|
70609
|
-
sessionId: this.options.sessionId,
|
|
70610
|
-
customPrompt: this.getJsonFixingPrompt(),
|
|
70611
|
-
path: this.options.path,
|
|
70612
|
-
provider: this.options.provider,
|
|
70613
|
-
model: this.options.model,
|
|
70614
|
-
debug: this.options.debug,
|
|
70615
|
-
tracer: this.options.tracer,
|
|
70616
|
-
allowEdit: this.options.allowEdit,
|
|
70617
|
-
maxIterations: 5,
|
|
70618
|
-
// Allow multiple iterations for JSON fixing
|
|
70619
|
-
disableJsonValidation: true
|
|
70620
|
-
// CRITICAL: Disable JSON validation in nested agent to prevent infinite recursion
|
|
70621
|
-
});
|
|
70622
|
-
}
|
|
70623
|
-
return this.agent;
|
|
70624
|
-
}
|
|
70625
|
-
/**
|
|
70626
|
-
* Fix invalid JSON using the specialized agent
|
|
70627
|
-
* @param {string} invalidJson - The broken JSON string
|
|
70628
|
-
* @param {string} schema - The original schema for context
|
|
70629
|
-
* @param {Object} validationResult - Validation result with error details
|
|
70630
|
-
* @param {number} attemptNumber - Current attempt number (for logging)
|
|
70631
|
-
* @returns {Promise<string>} - The corrected JSON
|
|
70632
|
-
*/
|
|
70633
|
-
async fixJson(invalidJson, schema, validationResult, attemptNumber = 1) {
|
|
70634
|
-
await this.initializeAgent();
|
|
70635
|
-
let errorContext = validationResult.error;
|
|
70636
|
-
if (validationResult.enhancedError) {
|
|
70637
|
-
errorContext = validationResult.enhancedError;
|
|
70638
|
-
}
|
|
70639
|
-
let schemaErrorDetails = "";
|
|
70640
|
-
if (validationResult.errorSummary) {
|
|
70641
|
-
schemaErrorDetails = `
|
|
70642
|
-
|
|
70643
|
-
Schema Validation Errors:
|
|
70644
|
-
${validationResult.errorSummary}`;
|
|
70645
|
-
} else if (validationResult.schemaErrors && validationResult.schemaErrors.length > 0) {
|
|
70646
|
-
const errors = validationResult.schemaErrors.map((err) => {
|
|
70647
|
-
const path9 = err.instancePath || "(root)";
|
|
70648
|
-
return ` ${path9}: ${err.message}`;
|
|
70649
|
-
}).join("\n");
|
|
70650
|
-
schemaErrorDetails = `
|
|
70651
|
-
|
|
70652
|
-
Schema Validation Errors:
|
|
70653
|
-
${errors}`;
|
|
70654
|
-
}
|
|
70655
|
-
const prompt = `Fix the following invalid JSON.
|
|
70656
|
-
|
|
70657
|
-
Error: ${errorContext}${schemaErrorDetails}
|
|
70658
|
-
|
|
70659
|
-
Invalid JSON:
|
|
70660
|
-
${invalidJson}
|
|
70661
|
-
|
|
70662
|
-
Expected schema structure:
|
|
70663
|
-
${schema}
|
|
70664
|
-
|
|
70665
|
-
${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.`;
|
|
70666
|
-
try {
|
|
70667
|
-
if (this.options.debug) {
|
|
70668
|
-
console.log(`[DEBUG] JSON fixing: Attempt ${attemptNumber} to fix JSON with separate agent`);
|
|
70669
|
-
}
|
|
70670
|
-
const result = await this.agent.answer(prompt, []);
|
|
70671
|
-
const cleaned = cleanSchemaResponse(result);
|
|
70672
|
-
if (this.options.debug) {
|
|
70673
|
-
console.log(`[DEBUG] JSON fixing: Agent returned ${cleaned.length} chars`);
|
|
70674
|
-
}
|
|
70675
|
-
return cleaned;
|
|
70676
|
-
} catch (error) {
|
|
70677
|
-
if (this.options.debug) {
|
|
70678
|
-
console.error(`[DEBUG] JSON fixing failed: ${error.message}`);
|
|
70679
|
-
}
|
|
70680
|
-
throw new Error(`Failed to fix JSON: ${error.message}`);
|
|
70681
|
-
}
|
|
70682
|
-
}
|
|
70683
|
-
/**
|
|
70684
|
-
* Get token usage information from the specialized agent
|
|
70685
|
-
* @returns {Object} - Token usage statistics
|
|
70686
|
-
*/
|
|
70687
|
-
getTokenUsage() {
|
|
70688
|
-
return this.agent ? this.agent.getTokenUsage() : null;
|
|
70689
|
-
}
|
|
70690
|
-
/**
|
|
70691
|
-
* Cancel any ongoing operations
|
|
70692
|
-
*/
|
|
70693
|
-
cancel() {
|
|
70694
|
-
if (this.agent) {
|
|
70695
|
-
this.agent.cancel();
|
|
70696
|
-
}
|
|
70697
|
-
}
|
|
70698
|
-
};
|
|
70699
70419
|
MermaidFixingAgent = class {
|
|
70700
70420
|
constructor(options = {}) {
|
|
70701
70421
|
this.ProbeAgent = null;
|
|
@@ -70939,7 +70659,7 @@ When reviewing code:
|
|
|
70939
70659
|
"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.`,
|
|
70940
70660
|
"engineer": `You are a senior engineer focused on software architecture and design.
|
|
70941
70661
|
Before jumping on the task you first analyse the user request in detail, and try to provide an elegant and concise solution.
|
|
70942
|
-
If the solution is clear, you can jump to implementation right away. If not, ask the user a clarification question
|
|
70662
|
+
If the solution is clear, you can jump to implementation right away. If not, ask the user a clarification question with the required details.
|
|
70943
70663
|
|
|
70944
70664
|
# Tone and Style
|
|
70945
70665
|
- Be concise and direct. Explain your approach briefly before implementing, then let the code speak for itself.
|
|
@@ -70962,7 +70682,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
70962
70682
|
When the request has **multiple distinct goals** (e.g. "Fix bug A AND add feature B"), use the task tool to track them:
|
|
70963
70683
|
- Call the task tool with action="create" and a tasks array. Each task must have an "id" field.
|
|
70964
70684
|
- Update task status to "in_progress" when starting and "completed" when done.
|
|
70965
|
-
- All tasks must be completed or cancelled before
|
|
70685
|
+
- All tasks must be completed or cancelled before providing your final answer.
|
|
70966
70686
|
- Stay flexible \u2014 add, remove, or reorganize tasks as your understanding changes.
|
|
70967
70687
|
|
|
70968
70688
|
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.
|
|
@@ -80219,9 +79939,15 @@ function messageContainsCompletion(msg) {
|
|
|
80219
79939
|
}
|
|
80220
79940
|
if (Array.isArray(msg.content)) {
|
|
80221
79941
|
if (msg.content.some((p) => p.type === "tool-call" && p.toolName === "attempt_completion")) return true;
|
|
79942
|
+
const hasToolCalls = msg.content.some((p) => p.type === "tool-call");
|
|
79943
|
+
const hasText = msg.content.some((p) => p.type === "text" && p.text?.trim());
|
|
79944
|
+
if (!hasToolCalls && hasText) return true;
|
|
80222
79945
|
}
|
|
80223
79946
|
const text = typeof msg.content === "string" ? msg.content : "";
|
|
80224
|
-
|
|
79947
|
+
if (text.includes("attempt_completion")) return true;
|
|
79948
|
+
const hasNoToolCalls = !Array.isArray(msg.toolInvocations) && !Array.isArray(msg.tool_calls);
|
|
79949
|
+
if (hasNoToolCalls && text.trim().length > 0) return true;
|
|
79950
|
+
return false;
|
|
80225
79951
|
}
|
|
80226
79952
|
function identifyMessageSegments(messages) {
|
|
80227
79953
|
const segments = [];
|
|
@@ -81988,7 +81714,7 @@ import { createAnthropic as createAnthropic2 } from "@ai-sdk/anthropic";
|
|
|
81988
81714
|
import { createOpenAI as createOpenAI2 } from "@ai-sdk/openai";
|
|
81989
81715
|
import { createGoogleGenerativeAI as createGoogleGenerativeAI2 } from "@ai-sdk/google";
|
|
81990
81716
|
import { createAmazonBedrock as createAmazonBedrock2 } from "@ai-sdk/amazon-bedrock";
|
|
81991
|
-
import { streamText as streamText2, tool as tool5, stepCountIs, jsonSchema } from "ai";
|
|
81717
|
+
import { streamText as streamText2, tool as tool5, stepCountIs, jsonSchema, Output } from "ai";
|
|
81992
81718
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
81993
81719
|
import { EventEmitter as EventEmitter5 } from "events";
|
|
81994
81720
|
import { existsSync as existsSync7 } from "fs";
|
|
@@ -82002,8 +81728,8 @@ function debugTruncate(s, limit = 200) {
|
|
|
82002
81728
|
function debugLogToolResults(toolResults) {
|
|
82003
81729
|
if (!toolResults || toolResults.length === 0) return;
|
|
82004
81730
|
for (const tr of toolResults) {
|
|
82005
|
-
const argsStr = JSON.stringify(tr.args
|
|
82006
|
-
const resultStr = typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result
|
|
81731
|
+
const argsStr = tr.args != null ? JSON.stringify(tr.args) : "<no args>";
|
|
81732
|
+
const resultStr = tr.result != null ? typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result) : "<no result>";
|
|
82007
81733
|
console.log(`[DEBUG] tool: ${tr.toolName} | args: ${debugTruncate(argsStr)} | result: ${debugTruncate(resultStr)}`);
|
|
82008
81734
|
}
|
|
82009
81735
|
}
|
|
@@ -82099,7 +81825,7 @@ var init_ProbeAgent = __esm({
|
|
|
82099
81825
|
* @param {Array<Object>} [options.fallback.providers] - List of provider configurations for custom fallback
|
|
82100
81826
|
* @param {boolean} [options.fallback.stopOnSuccess=true] - Stop on first success
|
|
82101
81827
|
* @param {number} [options.fallback.maxTotalAttempts=10] - Maximum total attempts across all providers
|
|
82102
|
-
* @param {string} [options.completionPrompt] - Custom prompt to run after
|
|
81828
|
+
* @param {string} [options.completionPrompt] - Custom prompt to run after completion for validation/review (runs before mermaid/JSON validation)
|
|
82103
81829
|
* @param {number} [options.maxOutputTokens] - Maximum tokens for tool output before truncation (default: 20000, can also be set via PROBE_MAX_OUTPUT_TOKENS env var)
|
|
82104
81830
|
* @param {number} [options.requestTimeout] - Timeout in ms for AI requests (default: 120000 or REQUEST_TIMEOUT env var). Used to abort hung requests.
|
|
82105
81831
|
* @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.
|
|
@@ -83251,12 +82977,11 @@ var init_ProbeAgent = __esm({
|
|
|
83251
82977
|
* - Delegate tool param injection
|
|
83252
82978
|
*
|
|
83253
82979
|
* @param {Object} options - Options from the answer() call
|
|
83254
|
-
* @param {Function} onComplete - Callback when attempt_completion is called (receives result string)
|
|
83255
82980
|
* @param {Object} context - Execution context { maxIterations, currentMessages }
|
|
83256
82981
|
* @returns {Object} Tools object for streamText()
|
|
83257
82982
|
* @private
|
|
83258
82983
|
*/
|
|
83259
|
-
_buildNativeTools(options,
|
|
82984
|
+
_buildNativeTools(options, context = {}) {
|
|
83260
82985
|
const { maxIterations = 30 } = context;
|
|
83261
82986
|
const nativeTools = {};
|
|
83262
82987
|
const isToolAllowed = (toolName) => this.allowedTools.isEnabled(toolName);
|
|
@@ -83406,16 +83131,6 @@ var init_ProbeAgent = __esm({
|
|
|
83406
83131
|
});
|
|
83407
83132
|
};
|
|
83408
83133
|
if (options._disableTools) {
|
|
83409
|
-
nativeTools.attempt_completion = tool5({
|
|
83410
|
-
description: "Signal task completion and provide the final result to the user",
|
|
83411
|
-
inputSchema: external_exports.object({
|
|
83412
|
-
result: external_exports.string().describe("The final result to present to the user")
|
|
83413
|
-
}),
|
|
83414
|
-
execute: async ({ result }) => {
|
|
83415
|
-
onComplete(result);
|
|
83416
|
-
return result;
|
|
83417
|
-
}
|
|
83418
|
-
});
|
|
83419
83134
|
return nativeTools;
|
|
83420
83135
|
}
|
|
83421
83136
|
for (const [toolName, toolImpl] of Object.entries(this.toolImplementations)) {
|
|
@@ -83426,28 +83141,6 @@ var init_ProbeAgent = __esm({
|
|
|
83426
83141
|
nativeTools[toolName] = wrapTool(toolName, schema, description, toolImpl.execute);
|
|
83427
83142
|
}
|
|
83428
83143
|
}
|
|
83429
|
-
nativeTools.attempt_completion = tool5({
|
|
83430
|
-
description: "Signal task completion and provide the final result to the user",
|
|
83431
|
-
inputSchema: external_exports.object({
|
|
83432
|
-
result: external_exports.string().describe("The final result to present to the user")
|
|
83433
|
-
}),
|
|
83434
|
-
execute: async ({ result }) => {
|
|
83435
|
-
if (this.enableTasks && this.taskManager && this.taskManager.hasIncompleteTasks()) {
|
|
83436
|
-
const incompleteTasks = this.taskManager.getIncompleteTasks();
|
|
83437
|
-
const highIterationCount = (context.currentIteration || 0) > maxIterations * 0.7;
|
|
83438
|
-
if (!highIterationCount) {
|
|
83439
|
-
const taskSummary = this.taskManager.getTaskSummary();
|
|
83440
|
-
const blockedMessage = createTaskCompletionBlockedMessage(taskSummary);
|
|
83441
|
-
if (this.debug) {
|
|
83442
|
-
console.log("[DEBUG] Task checkpoint: Blocking completion due to incomplete tasks");
|
|
83443
|
-
}
|
|
83444
|
-
return blockedMessage;
|
|
83445
|
-
}
|
|
83446
|
-
}
|
|
83447
|
-
onComplete(result);
|
|
83448
|
-
return result;
|
|
83449
|
-
}
|
|
83450
|
-
});
|
|
83451
83144
|
if (this.mcpBridge && !options._disableTools) {
|
|
83452
83145
|
const mcpTools = this.mcpBridge.getVercelTools(this._filterMcpTools(this.mcpBridge.getToolNames()));
|
|
83453
83146
|
for (const [name, mcpTool] of Object.entries(mcpTools)) {
|
|
@@ -84331,7 +84024,7 @@ Follow these instructions carefully:
|
|
|
84331
84024
|
2. Use the available tools step-by-step to fulfill the request.
|
|
84332
84025
|
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."}
|
|
84333
84026
|
4. Ensure to get really deep and understand the full picture before answering.
|
|
84334
|
-
5. Once the task is fully completed,
|
|
84027
|
+
5. Once the task is fully completed, provide your final answer directly as text.
|
|
84335
84028
|
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."}
|
|
84336
84029
|
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 ? `
|
|
84337
84030
|
7. When modifying files, choose the appropriate tool:
|
|
@@ -84509,7 +84202,7 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84509
84202
|
});
|
|
84510
84203
|
const systemMessage = await this.getSystemMessage();
|
|
84511
84204
|
let userMessage = { role: "user", content: message.trim() };
|
|
84512
|
-
if (options.schema && !options._schemaFormatted) {
|
|
84205
|
+
if (options.schema && !options._schemaFormatted && !options._disableTools) {
|
|
84513
84206
|
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
84514
84207
|
userMessage.content = message.trim() + schemaInstructions;
|
|
84515
84208
|
}
|
|
@@ -84542,7 +84235,6 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84542
84235
|
];
|
|
84543
84236
|
}
|
|
84544
84237
|
let currentIteration = 0;
|
|
84545
|
-
let completionAttempted = false;
|
|
84546
84238
|
let finalResult = "I was unable to complete your request due to reaching the maximum number of tool iterations.";
|
|
84547
84239
|
const baseMaxIterations = options._maxIterationsOverride || this.maxIterations || MAX_TOOL_ITERATIONS;
|
|
84548
84240
|
const maxIterations = options._maxIterationsOverride ? baseMaxIterations : options.schema ? baseMaxIterations + 4 : baseMaxIterations;
|
|
@@ -84658,12 +84350,8 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84658
84350
|
console.log(`[DEBUG] Schema provided, using extended iteration limit: ${maxIterations} (base: ${baseMaxIterations})`);
|
|
84659
84351
|
}
|
|
84660
84352
|
}
|
|
84661
|
-
let completionResult = null;
|
|
84662
84353
|
const toolContext = { maxIterations, currentIteration: 0, currentMessages };
|
|
84663
|
-
const tools2 = this._buildNativeTools(options,
|
|
84664
|
-
completionResult = result;
|
|
84665
|
-
completionAttempted = true;
|
|
84666
|
-
}, toolContext);
|
|
84354
|
+
const tools2 = this._buildNativeTools(options, toolContext);
|
|
84667
84355
|
if (this.debug) {
|
|
84668
84356
|
const toolNames = Object.keys(tools2);
|
|
84669
84357
|
console.log(`[DEBUG] Agent tools registered (${toolNames.length}): ${toolNames.join(", ")}`);
|
|
@@ -84677,6 +84365,8 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84677
84365
|
maxResponseTokens = 32e3;
|
|
84678
84366
|
}
|
|
84679
84367
|
}
|
|
84368
|
+
let completionPromptInjected = false;
|
|
84369
|
+
let preCompletionResult = null;
|
|
84680
84370
|
let compactionAttempted = false;
|
|
84681
84371
|
while (true) {
|
|
84682
84372
|
try {
|
|
@@ -84685,19 +84375,103 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84685
84375
|
model: this.provider ? this.provider(this.model) : this.model,
|
|
84686
84376
|
messages: messagesForAI,
|
|
84687
84377
|
tools: tools2,
|
|
84688
|
-
stopWhen:
|
|
84378
|
+
stopWhen: ({ steps }) => {
|
|
84379
|
+
if (steps.length >= maxIterations) return true;
|
|
84380
|
+
const lastStep = steps[steps.length - 1];
|
|
84381
|
+
const modelWantsToStop = lastStep?.finishReason === "stop" && (!lastStep?.toolCalls || lastStep.toolCalls.length === 0);
|
|
84382
|
+
if (modelWantsToStop) {
|
|
84383
|
+
if (this.enableTasks && this.taskManager?.hasIncompleteTasks()) {
|
|
84384
|
+
const highIterationCount = steps.length > maxIterations * 0.7;
|
|
84385
|
+
if (!highIterationCount) return false;
|
|
84386
|
+
}
|
|
84387
|
+
if (this.completionPrompt && !options._completionPromptProcessed && !completionPromptInjected) {
|
|
84388
|
+
preCompletionResult = lastStep.text || null;
|
|
84389
|
+
return false;
|
|
84390
|
+
}
|
|
84391
|
+
}
|
|
84392
|
+
let trailingNoTool = 0;
|
|
84393
|
+
for (let i = steps.length - 1; i >= 0; i--) {
|
|
84394
|
+
if (!steps[i].toolCalls?.length) trailingNoTool++;
|
|
84395
|
+
else break;
|
|
84396
|
+
}
|
|
84397
|
+
if (trailingNoTool >= 5) return true;
|
|
84398
|
+
if (trailingNoTool >= 3) {
|
|
84399
|
+
const recentTexts = steps.slice(-3).map((s) => s.text);
|
|
84400
|
+
if (recentTexts.every((t) => t && t === recentTexts[0])) return true;
|
|
84401
|
+
if (recentTexts.every((t) => detectStuckResponse(t))) return true;
|
|
84402
|
+
}
|
|
84403
|
+
return false;
|
|
84404
|
+
},
|
|
84405
|
+
prepareStep: ({ steps, stepNumber }) => {
|
|
84406
|
+
if (stepNumber === maxIterations - 1) {
|
|
84407
|
+
return {
|
|
84408
|
+
toolChoice: "none"
|
|
84409
|
+
};
|
|
84410
|
+
}
|
|
84411
|
+
const lastStep = steps[steps.length - 1];
|
|
84412
|
+
const modelJustStopped = lastStep?.finishReason === "stop" && (!lastStep?.toolCalls || lastStep.toolCalls.length === 0);
|
|
84413
|
+
if (modelJustStopped) {
|
|
84414
|
+
if (this.enableTasks && this.taskManager?.hasIncompleteTasks()) {
|
|
84415
|
+
const taskSummary = this.taskManager.getTaskSummary();
|
|
84416
|
+
const blockedMessage = createTaskCompletionBlockedMessage(taskSummary);
|
|
84417
|
+
return {
|
|
84418
|
+
userMessage: blockedMessage
|
|
84419
|
+
};
|
|
84420
|
+
}
|
|
84421
|
+
if (this.completionPrompt && !options._completionPromptProcessed && !completionPromptInjected) {
|
|
84422
|
+
completionPromptInjected = true;
|
|
84423
|
+
const resultToReview = lastStep.text || preCompletionResult || "";
|
|
84424
|
+
if (this.debug) {
|
|
84425
|
+
console.log("[DEBUG] Injecting completion prompt into main loop via prepareStep...");
|
|
84426
|
+
}
|
|
84427
|
+
if (this.tracer) {
|
|
84428
|
+
this.tracer.recordEvent("completion_prompt.started", {
|
|
84429
|
+
"completion_prompt.original_result_length": resultToReview.length
|
|
84430
|
+
});
|
|
84431
|
+
}
|
|
84432
|
+
const completionPromptMessage = `${this.completionPrompt}
|
|
84433
|
+
|
|
84434
|
+
Here is the result to review:
|
|
84435
|
+
<result>
|
|
84436
|
+
${resultToReview}
|
|
84437
|
+
</result>
|
|
84438
|
+
|
|
84439
|
+
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).`;
|
|
84440
|
+
return {
|
|
84441
|
+
userMessage: completionPromptMessage
|
|
84442
|
+
};
|
|
84443
|
+
}
|
|
84444
|
+
}
|
|
84445
|
+
return void 0;
|
|
84446
|
+
},
|
|
84689
84447
|
maxTokens: maxResponseTokens,
|
|
84690
84448
|
temperature: 0.3,
|
|
84691
|
-
onStepFinish: (
|
|
84449
|
+
onStepFinish: (stepResult) => {
|
|
84450
|
+
const { toolResults, toolCalls, text, reasoningText, finishReason, usage } = stepResult;
|
|
84692
84451
|
currentIteration++;
|
|
84693
84452
|
toolContext.currentIteration = currentIteration;
|
|
84694
84453
|
if (this.tracer) {
|
|
84695
|
-
|
|
84454
|
+
const stepEvent = {
|
|
84696
84455
|
"iteration": currentIteration,
|
|
84697
84456
|
"max_iterations": maxIterations,
|
|
84698
84457
|
"finish_reason": finishReason,
|
|
84699
84458
|
"has_tool_calls": !!(toolResults && toolResults.length > 0)
|
|
84700
|
-
}
|
|
84459
|
+
};
|
|
84460
|
+
if (text) {
|
|
84461
|
+
stepEvent["ai.text"] = text.substring(0, 1e4);
|
|
84462
|
+
stepEvent["ai.text.length"] = text.length;
|
|
84463
|
+
}
|
|
84464
|
+
if (reasoningText) {
|
|
84465
|
+
stepEvent["ai.reasoning"] = reasoningText.substring(0, 1e4);
|
|
84466
|
+
stepEvent["ai.reasoning.length"] = reasoningText.length;
|
|
84467
|
+
}
|
|
84468
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
84469
|
+
stepEvent["ai.tool_calls"] = toolCalls.map((tc) => ({
|
|
84470
|
+
name: tc.toolName,
|
|
84471
|
+
args: JSON.stringify(tc.args || {}).substring(0, 2e3)
|
|
84472
|
+
}));
|
|
84473
|
+
}
|
|
84474
|
+
this.tracer.addEvent("iteration.step", stepEvent);
|
|
84701
84475
|
}
|
|
84702
84476
|
if (usage) {
|
|
84703
84477
|
this.tokenCounter.recordUsage(usage);
|
|
@@ -84707,10 +84481,32 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84707
84481
|
}
|
|
84708
84482
|
if (this.debug) {
|
|
84709
84483
|
console.log(`[DEBUG] Step ${currentIteration}/${maxIterations} finished (reason: ${finishReason}, tools: ${toolResults?.length || 0})`);
|
|
84484
|
+
if (text) {
|
|
84485
|
+
console.log(`[DEBUG] model text: ${debugTruncate(text)}`);
|
|
84486
|
+
}
|
|
84487
|
+
if (reasoningText) {
|
|
84488
|
+
console.log(`[DEBUG] reasoning: ${debugTruncate(reasoningText)}`);
|
|
84489
|
+
}
|
|
84710
84490
|
debugLogToolResults(toolResults);
|
|
84711
84491
|
}
|
|
84712
84492
|
}
|
|
84713
84493
|
};
|
|
84494
|
+
const hasActiveTools = Object.keys(tools2).length > 0;
|
|
84495
|
+
if (options.schema && !hasActiveTools) {
|
|
84496
|
+
try {
|
|
84497
|
+
const parsedSchema = typeof options.schema === "string" ? JSON.parse(options.schema) : options.schema;
|
|
84498
|
+
if (isJsonSchema(options.schema)) {
|
|
84499
|
+
streamOptions.output = Output.object({ schema: jsonSchema(parsedSchema) });
|
|
84500
|
+
if (this.debug) {
|
|
84501
|
+
console.log(`[DEBUG] Native JSON schema output enabled (no active tools)`);
|
|
84502
|
+
}
|
|
84503
|
+
}
|
|
84504
|
+
} catch (e) {
|
|
84505
|
+
if (this.debug) {
|
|
84506
|
+
console.log(`[DEBUG] Failed to set native JSON schema output: ${e.message}`);
|
|
84507
|
+
}
|
|
84508
|
+
}
|
|
84509
|
+
}
|
|
84714
84510
|
const providerOpts = this._buildThinkingProviderOptions(maxResponseTokens);
|
|
84715
84511
|
if (providerOpts) {
|
|
84716
84512
|
streamOptions.providerOptions = providerOpts;
|
|
@@ -84720,7 +84516,7 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84720
84516
|
const finalText = await result.text;
|
|
84721
84517
|
if (this.debug) {
|
|
84722
84518
|
const steps = await result.steps;
|
|
84723
|
-
console.log(`[DEBUG] streamText completed: ${steps?.length || 0} steps, finalText=${finalText?.length || 0} chars
|
|
84519
|
+
console.log(`[DEBUG] streamText completed: ${steps?.length || 0} steps, finalText=${finalText?.length || 0} chars`);
|
|
84724
84520
|
}
|
|
84725
84521
|
const usage = await result.usage;
|
|
84726
84522
|
if (usage) {
|
|
@@ -84744,18 +84540,24 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84744
84540
|
} else {
|
|
84745
84541
|
aiResult = await executeAIRequest();
|
|
84746
84542
|
}
|
|
84747
|
-
if (
|
|
84748
|
-
|
|
84749
|
-
|
|
84750
|
-
|
|
84751
|
-
|
|
84752
|
-
|
|
84753
|
-
|
|
84543
|
+
if (options.schema && streamOptions.output) {
|
|
84544
|
+
try {
|
|
84545
|
+
const outputObject = await aiResult.result.output;
|
|
84546
|
+
if (outputObject) {
|
|
84547
|
+
finalResult = JSON.stringify(outputObject);
|
|
84548
|
+
} else if (aiResult.finalText) {
|
|
84549
|
+
finalResult = aiResult.finalText;
|
|
84550
|
+
}
|
|
84551
|
+
} catch (e) {
|
|
84552
|
+
if (this.debug) {
|
|
84553
|
+
console.log(`[DEBUG] Native JSON output failed, falling back to text: ${e.message}`);
|
|
84554
|
+
}
|
|
84555
|
+
if (aiResult.finalText) {
|
|
84556
|
+
finalResult = aiResult.finalText;
|
|
84754
84557
|
}
|
|
84755
84558
|
}
|
|
84756
84559
|
} else if (aiResult.finalText) {
|
|
84757
84560
|
finalResult = aiResult.finalText;
|
|
84758
|
-
completionAttempted = true;
|
|
84759
84561
|
}
|
|
84760
84562
|
const resultMessages = await aiResult.result.response?.messages;
|
|
84761
84563
|
if (resultMessages) {
|
|
@@ -84763,6 +84565,75 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84763
84565
|
currentMessages.push(msg);
|
|
84764
84566
|
}
|
|
84765
84567
|
}
|
|
84568
|
+
if (this.completionPrompt && !options._completionPromptProcessed && !completionPromptInjected && finalResult) {
|
|
84569
|
+
completionPromptInjected = true;
|
|
84570
|
+
preCompletionResult = finalResult;
|
|
84571
|
+
if (this.debug) {
|
|
84572
|
+
console.log("[DEBUG] Injecting completion prompt as post-streamText follow-up pass...");
|
|
84573
|
+
}
|
|
84574
|
+
if (this.tracer) {
|
|
84575
|
+
this.tracer.recordEvent("completion_prompt.started", {
|
|
84576
|
+
"completion_prompt.original_result_length": finalResult.length
|
|
84577
|
+
});
|
|
84578
|
+
}
|
|
84579
|
+
const completionPromptMessage = `${this.completionPrompt}
|
|
84580
|
+
|
|
84581
|
+
Here is the result to review:
|
|
84582
|
+
<result>
|
|
84583
|
+
${finalResult}
|
|
84584
|
+
</result>
|
|
84585
|
+
|
|
84586
|
+
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).`;
|
|
84587
|
+
currentMessages.push({ role: "user", content: completionPromptMessage });
|
|
84588
|
+
const completionMaxIterations = 5;
|
|
84589
|
+
const completionStreamOptions = {
|
|
84590
|
+
model: this.provider ? this.provider(this.model) : this.model,
|
|
84591
|
+
messages: this.prepareMessagesWithImages(currentMessages),
|
|
84592
|
+
tools: tools2,
|
|
84593
|
+
stopWhen: stepCountIs(completionMaxIterations),
|
|
84594
|
+
maxTokens: maxResponseTokens,
|
|
84595
|
+
temperature: 0.3,
|
|
84596
|
+
onStepFinish: ({ toolResults, text, finishReason, usage }) => {
|
|
84597
|
+
if (usage) {
|
|
84598
|
+
this.tokenCounter.recordUsage(usage);
|
|
84599
|
+
}
|
|
84600
|
+
if (options.onStream && text) {
|
|
84601
|
+
options.onStream(text);
|
|
84602
|
+
}
|
|
84603
|
+
if (this.debug) {
|
|
84604
|
+
console.log(`[DEBUG] Completion prompt step finished (reason: ${finishReason}, tools: ${toolResults?.length || 0})`);
|
|
84605
|
+
}
|
|
84606
|
+
}
|
|
84607
|
+
};
|
|
84608
|
+
const providerOpts2 = this._buildThinkingProviderOptions(maxResponseTokens);
|
|
84609
|
+
if (providerOpts2) {
|
|
84610
|
+
completionStreamOptions.providerOptions = providerOpts2;
|
|
84611
|
+
}
|
|
84612
|
+
try {
|
|
84613
|
+
const cpResult = await this.streamTextWithRetryAndFallback(completionStreamOptions);
|
|
84614
|
+
const cpFinalText = await cpResult.text;
|
|
84615
|
+
const cpUsage = await cpResult.usage;
|
|
84616
|
+
if (cpUsage) {
|
|
84617
|
+
this.tokenCounter.recordUsage(cpUsage, cpResult.experimental_providerMetadata);
|
|
84618
|
+
}
|
|
84619
|
+
const cpMessages = await cpResult.response?.messages;
|
|
84620
|
+
if (cpMessages) {
|
|
84621
|
+
for (const msg of cpMessages) {
|
|
84622
|
+
currentMessages.push(msg);
|
|
84623
|
+
}
|
|
84624
|
+
}
|
|
84625
|
+
if (cpFinalText && cpFinalText.trim().length > 0) {
|
|
84626
|
+
finalResult = cpFinalText;
|
|
84627
|
+
}
|
|
84628
|
+
if (this.debug) {
|
|
84629
|
+
console.log(`[DEBUG] Completion prompt follow-up produced ${cpFinalText?.length || 0} chars (using ${cpFinalText && cpFinalText.trim().length > 0 ? "updated" : "original"} result)`);
|
|
84630
|
+
}
|
|
84631
|
+
} catch (cpError) {
|
|
84632
|
+
if (this.debug) {
|
|
84633
|
+
console.log(`[DEBUG] Completion prompt follow-up failed: ${cpError.message}, keeping original result`);
|
|
84634
|
+
}
|
|
84635
|
+
}
|
|
84636
|
+
}
|
|
84766
84637
|
break;
|
|
84767
84638
|
} catch (error) {
|
|
84768
84639
|
if (!compactionAttempted && handleContextLimitError) {
|
|
@@ -84792,17 +84663,13 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84792
84663
|
continue;
|
|
84793
84664
|
}
|
|
84794
84665
|
}
|
|
84795
|
-
if (completionResult) {
|
|
84796
|
-
finalResult = completionResult;
|
|
84797
|
-
break;
|
|
84798
|
-
}
|
|
84799
84666
|
console.error(`Error during streamText:`, error);
|
|
84800
84667
|
finalResult = `Error: Failed to get response from AI model. ${error.message}`;
|
|
84801
84668
|
throw new Error(finalResult);
|
|
84802
84669
|
}
|
|
84803
84670
|
}
|
|
84804
|
-
if (currentIteration >= maxIterations
|
|
84805
|
-
console.warn(`[WARN] Max tool iterations (${maxIterations}) reached for session ${this.sessionId}
|
|
84671
|
+
if (currentIteration >= maxIterations) {
|
|
84672
|
+
console.warn(`[WARN] Max tool iterations (${maxIterations}) reached for session ${this.sessionId}.`);
|
|
84806
84673
|
}
|
|
84807
84674
|
this.history = currentMessages.map((msg) => ({ ...msg }));
|
|
84808
84675
|
if (this.history.length > MAX_HISTORY_MESSAGES) {
|
|
@@ -84825,279 +84692,17 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
84825
84692
|
} catch (error) {
|
|
84826
84693
|
console.error(`[ERROR] Failed to save messages to storage:`, error);
|
|
84827
84694
|
}
|
|
84828
|
-
if (
|
|
84829
|
-
|
|
84830
|
-
|
|
84831
|
-
|
|
84832
|
-
|
|
84833
|
-
const originalResult = finalResult;
|
|
84834
|
-
if (this.tracer) {
|
|
84835
|
-
this.tracer.recordEvent("completion_prompt.started", {
|
|
84836
|
-
"completion_prompt.original_result_length": finalResult?.length || 0
|
|
84837
|
-
});
|
|
84838
|
-
}
|
|
84839
|
-
const completionPromptMessage = `${this.completionPrompt}
|
|
84840
|
-
|
|
84841
|
-
Here is the result to review:
|
|
84842
|
-
<result>
|
|
84843
|
-
${finalResult}
|
|
84844
|
-
</result>
|
|
84845
|
-
|
|
84846
|
-
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.`;
|
|
84847
|
-
currentMessages.push({ role: "user", content: completionPromptMessage });
|
|
84848
|
-
completionResult = null;
|
|
84849
|
-
completionAttempted = false;
|
|
84850
|
-
const completionMaxIterations = 5;
|
|
84851
|
-
const completionStreamOptions = {
|
|
84852
|
-
model: this.provider ? this.provider(this.model) : this.model,
|
|
84853
|
-
messages: this.prepareMessagesWithImages(currentMessages),
|
|
84854
|
-
tools: tools2,
|
|
84855
|
-
stopWhen: stepCountIs(completionMaxIterations),
|
|
84856
|
-
maxTokens: maxResponseTokens,
|
|
84857
|
-
temperature: 0.3,
|
|
84858
|
-
onStepFinish: ({ toolResults, text, finishReason, usage }) => {
|
|
84859
|
-
if (usage) {
|
|
84860
|
-
this.tokenCounter.recordUsage(usage);
|
|
84861
|
-
}
|
|
84862
|
-
if (options.onStream && text) {
|
|
84863
|
-
options.onStream(text);
|
|
84864
|
-
}
|
|
84865
|
-
if (this.debug) {
|
|
84866
|
-
console.log(`[DEBUG] Completion prompt step finished (reason: ${finishReason}, tools: ${toolResults?.length || 0})`);
|
|
84867
|
-
debugLogToolResults(toolResults);
|
|
84868
|
-
}
|
|
84869
|
-
}
|
|
84870
|
-
};
|
|
84871
|
-
const providerOpts = this._buildThinkingProviderOptions(maxResponseTokens);
|
|
84872
|
-
if (providerOpts) {
|
|
84873
|
-
completionStreamOptions.providerOptions = providerOpts;
|
|
84874
|
-
}
|
|
84875
|
-
const cpResult = await this.streamTextWithRetryAndFallback(completionStreamOptions);
|
|
84876
|
-
const cpFinalText = await cpResult.text;
|
|
84877
|
-
const cpUsage = await cpResult.usage;
|
|
84878
|
-
if (cpUsage) {
|
|
84879
|
-
this.tokenCounter.recordUsage(cpUsage, cpResult.experimental_providerMetadata);
|
|
84880
|
-
}
|
|
84881
|
-
const cpMessages = await cpResult.response?.messages;
|
|
84882
|
-
if (cpMessages) {
|
|
84883
|
-
for (const msg of cpMessages) {
|
|
84884
|
-
currentMessages.push(msg);
|
|
84885
|
-
}
|
|
84886
|
-
}
|
|
84887
|
-
if (completionResult) {
|
|
84888
|
-
finalResult = completionResult;
|
|
84889
|
-
completionAttempted = true;
|
|
84890
|
-
} else if (cpFinalText && cpFinalText.trim().length > 0) {
|
|
84891
|
-
finalResult = cpFinalText;
|
|
84892
|
-
completionAttempted = true;
|
|
84893
|
-
} else {
|
|
84894
|
-
finalResult = originalResult;
|
|
84895
|
-
completionAttempted = true;
|
|
84896
|
-
if (this.debug) {
|
|
84897
|
-
console.log("[DEBUG] Completion prompt returned empty result, keeping original.");
|
|
84898
|
-
}
|
|
84899
|
-
}
|
|
84900
|
-
if (this.debug) {
|
|
84901
|
-
console.log(`[DEBUG] Completion prompt finished. Final result length: ${finalResult?.length || 0}`);
|
|
84902
|
-
}
|
|
84903
|
-
if (this.tracer) {
|
|
84904
|
-
this.tracer.recordEvent("completion_prompt.completed", {
|
|
84905
|
-
"completion_prompt.final_result_length": finalResult?.length || 0,
|
|
84906
|
-
"completion_prompt.used_original": finalResult === originalResult
|
|
84907
|
-
});
|
|
84908
|
-
}
|
|
84909
|
-
} catch (error) {
|
|
84910
|
-
console.error("[ERROR] Completion prompt failed:", error);
|
|
84911
|
-
if (this.tracer) {
|
|
84912
|
-
this.tracer.recordEvent("completion_prompt.error", {
|
|
84913
|
-
"completion_prompt.error": error.message
|
|
84914
|
-
});
|
|
84915
|
-
}
|
|
84916
|
-
}
|
|
84695
|
+
if (completionPromptInjected && this.tracer) {
|
|
84696
|
+
this.tracer.recordEvent("completion_prompt.completed", {
|
|
84697
|
+
"completion_prompt.final_result_length": finalResult?.length || 0,
|
|
84698
|
+
"completion_prompt.used_original": preCompletionResult && finalResult === preCompletionResult
|
|
84699
|
+
});
|
|
84917
84700
|
}
|
|
84918
|
-
|
|
84919
|
-
if (options.schema && !options._schemaFormatted && !completionAttempted && !reachedMaxIterations) {
|
|
84920
|
-
if (this.debug) {
|
|
84921
|
-
console.log("[DEBUG] Schema provided, applying automatic formatting...");
|
|
84922
|
-
}
|
|
84923
|
-
try {
|
|
84924
|
-
const schemaPrompt = `CRITICAL: You MUST respond with ONLY valid JSON DATA that conforms to this schema structure. DO NOT return the schema definition itself.
|
|
84925
|
-
|
|
84926
|
-
Schema to follow (this is just the structure - provide ACTUAL DATA):
|
|
84927
|
-
${options.schema}
|
|
84928
|
-
|
|
84929
|
-
REQUIREMENTS:
|
|
84930
|
-
- Return ONLY the JSON object/array with REAL DATA that matches the schema structure
|
|
84931
|
-
- DO NOT return the schema definition itself (no "$schema", "$id", "type", "properties", etc.)
|
|
84932
|
-
- NO additional text, explanations, or markdown formatting
|
|
84933
|
-
- NO code blocks or backticks
|
|
84934
|
-
- The JSON must be parseable by JSON.parse()
|
|
84935
|
-
- Fill in actual values that make sense based on your previous response content
|
|
84936
|
-
|
|
84937
|
-
EXAMPLE:
|
|
84938
|
-
If schema defines {type: "object", properties: {name: {type: "string"}, age: {type: "number"}}}
|
|
84939
|
-
Return: {"name": "John Doe", "age": 25}
|
|
84940
|
-
NOT: {"type": "object", "properties": {"name": {"type": "string"}}}
|
|
84941
|
-
|
|
84942
|
-
Convert your previous response content into actual JSON data that follows this schema structure.`;
|
|
84943
|
-
finalResult = await this.answer(schemaPrompt, [], {
|
|
84944
|
-
...options,
|
|
84945
|
-
_schemaFormatted: true,
|
|
84946
|
-
_completionPromptProcessed: true
|
|
84947
|
-
// Prevent cascading completion prompts in retry calls
|
|
84948
|
-
});
|
|
84949
|
-
if (!this.disableMermaidValidation) {
|
|
84950
|
-
try {
|
|
84951
|
-
if (this.debug) {
|
|
84952
|
-
console.log(`[DEBUG] Mermaid validation: Starting enhanced mermaid validation...`);
|
|
84953
|
-
}
|
|
84954
|
-
if (this.tracer) {
|
|
84955
|
-
this.tracer.recordMermaidValidationEvent("schema_processing_started", {
|
|
84956
|
-
"mermaid_validation.context": "schema_processing",
|
|
84957
|
-
"mermaid_validation.response_length": finalResult.length
|
|
84958
|
-
});
|
|
84959
|
-
}
|
|
84960
|
-
const mermaidValidation = await validateAndFixMermaidResponse(finalResult, {
|
|
84961
|
-
debug: this.debug,
|
|
84962
|
-
path: this.workspaceRoot || this.allowedFolders[0],
|
|
84963
|
-
provider: this.clientApiProvider,
|
|
84964
|
-
model: this.model,
|
|
84965
|
-
tracer: this.tracer
|
|
84966
|
-
});
|
|
84967
|
-
if (mermaidValidation.wasFixed) {
|
|
84968
|
-
finalResult = mermaidValidation.fixedResponse;
|
|
84969
|
-
if (this.debug) {
|
|
84970
|
-
console.log(`[DEBUG] Mermaid validation: Diagrams successfully fixed`);
|
|
84971
|
-
if (mermaidValidation.performanceMetrics) {
|
|
84972
|
-
const metrics = mermaidValidation.performanceMetrics;
|
|
84973
|
-
console.log(`[DEBUG] Mermaid validation: Performance - total: ${metrics.totalTimeMs}ms, AI fixing: ${metrics.aiFixingTimeMs}ms`);
|
|
84974
|
-
console.log(`[DEBUG] Mermaid validation: Results - ${metrics.diagramsFixed}/${metrics.diagramsProcessed} diagrams fixed`);
|
|
84975
|
-
}
|
|
84976
|
-
if (mermaidValidation.fixingResults) {
|
|
84977
|
-
mermaidValidation.fixingResults.forEach((fixResult, index) => {
|
|
84978
|
-
if (fixResult.wasFixed) {
|
|
84979
|
-
const method = fixResult.fixedWithHtmlDecoding ? "HTML entity decoding" : "AI correction";
|
|
84980
|
-
const time = fixResult.aiFixingTimeMs ? ` in ${fixResult.aiFixingTimeMs}ms` : "";
|
|
84981
|
-
console.log(`[DEBUG] Mermaid validation: Fixed diagram ${fixResult.diagramIndex + 1} with ${method}${time}`);
|
|
84982
|
-
console.log(`[DEBUG] Mermaid validation: Original error: ${fixResult.originalError}`);
|
|
84983
|
-
} else {
|
|
84984
|
-
console.log(`[DEBUG] Mermaid validation: Failed to fix diagram ${fixResult.diagramIndex + 1}: ${fixResult.fixingError}`);
|
|
84985
|
-
}
|
|
84986
|
-
});
|
|
84987
|
-
}
|
|
84988
|
-
}
|
|
84989
|
-
} else if (this.debug) {
|
|
84990
|
-
console.log(`[DEBUG] Mermaid validation: No fixes needed or fixes unsuccessful`);
|
|
84991
|
-
if (mermaidValidation.diagrams?.length > 0) {
|
|
84992
|
-
console.log(`[DEBUG] Mermaid validation: Found ${mermaidValidation.diagrams.length} diagrams, all valid: ${mermaidValidation.isValid}`);
|
|
84993
|
-
}
|
|
84994
|
-
}
|
|
84995
|
-
} catch (error) {
|
|
84996
|
-
if (this.debug) {
|
|
84997
|
-
console.log(`[DEBUG] Mermaid validation: Process failed with error: ${error.message}`);
|
|
84998
|
-
console.log(`[DEBUG] Mermaid validation: Stack trace: ${error.stack}`);
|
|
84999
|
-
}
|
|
85000
|
-
}
|
|
85001
|
-
} else if (this.debug) {
|
|
85002
|
-
console.log(`[DEBUG] Mermaid validation: Skipped due to disableMermaidValidation option`);
|
|
85003
|
-
}
|
|
85004
|
-
finalResult = cleanSchemaResponse(finalResult);
|
|
85005
|
-
if (isJsonSchema(options.schema)) {
|
|
85006
|
-
if (this.debug) {
|
|
85007
|
-
console.log(`[DEBUG] JSON validation: Starting validation process for schema response`);
|
|
85008
|
-
console.log(`[DEBUG] JSON validation: Cleaned response length: ${finalResult.length} chars`);
|
|
85009
|
-
}
|
|
85010
|
-
if (this.tracer) {
|
|
85011
|
-
this.tracer.recordJsonValidationEvent("started", {
|
|
85012
|
-
"json_validation.response_length": finalResult.length,
|
|
85013
|
-
"json_validation.schema_type": "JSON"
|
|
85014
|
-
});
|
|
85015
|
-
}
|
|
85016
|
-
let validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
85017
|
-
let retryCount = 0;
|
|
85018
|
-
const maxRetries = 3;
|
|
85019
|
-
if (validation.isValid && isJsonSchemaDefinition(finalResult, { debug: this.debug })) {
|
|
85020
|
-
if (this.debug) {
|
|
85021
|
-
console.log(`[DEBUG] JSON validation: Response is a JSON schema definition instead of data, needs correction...`);
|
|
85022
|
-
}
|
|
85023
|
-
validation = {
|
|
85024
|
-
isValid: false,
|
|
85025
|
-
error: "Response is a JSON schema definition instead of actual data",
|
|
85026
|
-
enhancedError: "Response is a JSON schema definition instead of actual data. Please return data that conforms to the schema, not the schema itself."
|
|
85027
|
-
};
|
|
85028
|
-
}
|
|
85029
|
-
if (!validation.isValid) {
|
|
85030
|
-
if (this.debug) {
|
|
85031
|
-
console.log(`[DEBUG] JSON validation: Starting separate JsonFixingAgent session...`);
|
|
85032
|
-
}
|
|
85033
|
-
const { JsonFixingAgent: JsonFixingAgent2 } = await Promise.resolve().then(() => (init_schemaUtils(), schemaUtils_exports));
|
|
85034
|
-
const jsonFixer = new JsonFixingAgent2({
|
|
85035
|
-
path: this.workspaceRoot || this.allowedFolders[0],
|
|
85036
|
-
provider: this.clientApiProvider,
|
|
85037
|
-
model: this.model,
|
|
85038
|
-
debug: this.debug,
|
|
85039
|
-
tracer: this.tracer
|
|
85040
|
-
});
|
|
85041
|
-
let currentResult = finalResult;
|
|
85042
|
-
let currentValidation = validation;
|
|
85043
|
-
while (!currentValidation.isValid && retryCount < maxRetries) {
|
|
85044
|
-
if (this.debug) {
|
|
85045
|
-
console.log(`[DEBUG] JSON validation: Validation failed (attempt ${retryCount + 1}/${maxRetries}):`, currentValidation.error);
|
|
85046
|
-
console.log(`[DEBUG] JSON validation: Invalid response sample: ${currentResult.substring(0, 300)}${currentResult.length > 300 ? "..." : ""}`);
|
|
85047
|
-
}
|
|
85048
|
-
try {
|
|
85049
|
-
currentResult = await jsonFixer.fixJson(
|
|
85050
|
-
currentResult,
|
|
85051
|
-
options.schema,
|
|
85052
|
-
currentValidation,
|
|
85053
|
-
retryCount + 1
|
|
85054
|
-
);
|
|
85055
|
-
currentValidation = validateJsonResponse(currentResult, { debug: this.debug, schema: options.schema });
|
|
85056
|
-
retryCount++;
|
|
85057
|
-
if (this.debug) {
|
|
85058
|
-
if (!currentValidation.isValid && retryCount < maxRetries) {
|
|
85059
|
-
console.log(`[DEBUG] JSON validation: Still invalid after correction ${retryCount}, retrying...`);
|
|
85060
|
-
console.log(`[DEBUG] JSON validation: Corrected response sample: ${currentResult.substring(0, 300)}${currentResult.length > 300 ? "..." : ""}`);
|
|
85061
|
-
} else if (currentValidation.isValid) {
|
|
85062
|
-
console.log(`[DEBUG] JSON validation: Successfully corrected after ${retryCount} attempts with JsonFixingAgent`);
|
|
85063
|
-
}
|
|
85064
|
-
}
|
|
85065
|
-
} catch (error) {
|
|
85066
|
-
if (this.debug) {
|
|
85067
|
-
console.error(`[DEBUG] JSON validation: JsonFixingAgent error on attempt ${retryCount + 1}:`, error.message);
|
|
85068
|
-
}
|
|
85069
|
-
break;
|
|
85070
|
-
}
|
|
85071
|
-
}
|
|
85072
|
-
finalResult = currentResult;
|
|
85073
|
-
validation = currentValidation;
|
|
85074
|
-
if (!validation.isValid && this.debug) {
|
|
85075
|
-
console.log(`[DEBUG] JSON validation: Still invalid after ${maxRetries} correction attempts with JsonFixingAgent:`, validation.error);
|
|
85076
|
-
console.log(`[DEBUG] JSON validation: Final invalid response: ${finalResult.substring(0, 500)}${finalResult.length > 500 ? "..." : ""}`);
|
|
85077
|
-
} else if (validation.isValid && this.debug) {
|
|
85078
|
-
console.log(`[DEBUG] JSON validation: Final validation successful`);
|
|
85079
|
-
}
|
|
85080
|
-
}
|
|
85081
|
-
if (this.tracer) {
|
|
85082
|
-
this.tracer.recordJsonValidationEvent("completed", {
|
|
85083
|
-
"json_validation.success": validation.isValid,
|
|
85084
|
-
"json_validation.retry_count": retryCount,
|
|
85085
|
-
"json_validation.max_retries": maxRetries,
|
|
85086
|
-
"json_validation.final_response_length": finalResult.length,
|
|
85087
|
-
"json_validation.error": validation.isValid ? null : validation.error
|
|
85088
|
-
});
|
|
85089
|
-
}
|
|
85090
|
-
}
|
|
85091
|
-
} catch (error) {
|
|
85092
|
-
console.error("[ERROR] Schema formatting failed:", error);
|
|
85093
|
-
}
|
|
85094
|
-
} else if (reachedMaxIterations && options.schema && this.debug) {
|
|
85095
|
-
console.log("[DEBUG] Skipping schema formatting due to max iterations reached without completion");
|
|
85096
|
-
} else if (completionAttempted && options.schema && !options._schemaFormatted && !options._skipValidation) {
|
|
84701
|
+
if (options.schema && !options._schemaFormatted && !options._skipValidation) {
|
|
85097
84702
|
try {
|
|
85098
84703
|
if (!this.disableMermaidValidation) {
|
|
85099
84704
|
if (this.debug) {
|
|
85100
|
-
console.log(`[DEBUG] Mermaid validation: Validating
|
|
84705
|
+
console.log(`[DEBUG] Mermaid validation: Validating result BEFORE schema cleaning...`);
|
|
85101
84706
|
}
|
|
85102
84707
|
const mermaidValidation = await validateAndFixMermaidResponse(finalResult, {
|
|
85103
84708
|
debug: this.debug,
|
|
@@ -85109,55 +84714,51 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
85109
84714
|
if (mermaidValidation.wasFixed) {
|
|
85110
84715
|
finalResult = mermaidValidation.fixedResponse;
|
|
85111
84716
|
if (this.debug) {
|
|
85112
|
-
console.log(`[DEBUG] Mermaid validation:
|
|
84717
|
+
console.log(`[DEBUG] Mermaid validation: Diagrams fixed`);
|
|
85113
84718
|
if (mermaidValidation.performanceMetrics) {
|
|
85114
84719
|
console.log(`[DEBUG] Mermaid validation: Fixed in ${mermaidValidation.performanceMetrics.totalTimeMs}ms`);
|
|
85115
84720
|
}
|
|
85116
84721
|
}
|
|
85117
84722
|
} else if (this.debug) {
|
|
85118
|
-
console.log(`[DEBUG] Mermaid validation:
|
|
84723
|
+
console.log(`[DEBUG] Mermaid validation: Completed (no fixes needed)`);
|
|
85119
84724
|
}
|
|
85120
84725
|
} else if (this.debug) {
|
|
85121
|
-
console.log(`[DEBUG] Mermaid validation: Skipped
|
|
84726
|
+
console.log(`[DEBUG] Mermaid validation: Skipped due to disableMermaidValidation option`);
|
|
85122
84727
|
}
|
|
85123
84728
|
finalResult = cleanSchemaResponse(finalResult);
|
|
85124
84729
|
if (isJsonSchema(options.schema)) {
|
|
85125
84730
|
if (this.debug) {
|
|
85126
|
-
console.log(`[DEBUG] JSON validation: Starting validation process
|
|
84731
|
+
console.log(`[DEBUG] JSON validation: Starting validation process`);
|
|
85127
84732
|
console.log(`[DEBUG] JSON validation: Response length: ${finalResult.length} chars`);
|
|
85128
84733
|
}
|
|
85129
84734
|
if (this.tracer) {
|
|
85130
|
-
this.tracer.recordJsonValidationEvent("
|
|
84735
|
+
this.tracer.recordJsonValidationEvent("started", {
|
|
85131
84736
|
"json_validation.response_length": finalResult.length,
|
|
85132
|
-
"json_validation.schema_type": "JSON"
|
|
85133
|
-
"json_validation.context": "attempt_completion"
|
|
84737
|
+
"json_validation.schema_type": "JSON"
|
|
85134
84738
|
});
|
|
85135
84739
|
}
|
|
85136
|
-
let validation = validateJsonResponse(finalResult, { debug: this.debug });
|
|
84740
|
+
let validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
85137
84741
|
let retryCount = 0;
|
|
85138
84742
|
const maxRetries = 3;
|
|
85139
84743
|
if (validation.isValid && isJsonSchemaDefinition(finalResult, { debug: this.debug })) {
|
|
85140
84744
|
if (this.debug) {
|
|
85141
|
-
console.log(`[DEBUG] JSON validation:
|
|
84745
|
+
console.log(`[DEBUG] JSON validation: Response is a JSON schema definition instead of data, correcting...`);
|
|
85142
84746
|
}
|
|
85143
84747
|
const schemaDefinitionPrompt = createSchemaDefinitionCorrectionPrompt(
|
|
85144
84748
|
finalResult,
|
|
85145
84749
|
options.schema,
|
|
85146
84750
|
0
|
|
85147
84751
|
);
|
|
85148
|
-
const { schema: _unusedSchema1, ...schemaDefCorrectionOptions } = options;
|
|
85149
84752
|
finalResult = await this.answer(schemaDefinitionPrompt, [], {
|
|
85150
|
-
...
|
|
84753
|
+
...options,
|
|
85151
84754
|
_schemaFormatted: true,
|
|
85152
84755
|
_skipValidation: true,
|
|
85153
|
-
|
|
84756
|
+
_disableTools: true,
|
|
85154
84757
|
_completionPromptProcessed: true,
|
|
85155
|
-
// Prevent cascading completion prompts in retry calls
|
|
85156
84758
|
_maxIterationsOverride: 3
|
|
85157
|
-
// Correction should complete in 1-2 iterations (issue #447)
|
|
85158
84759
|
});
|
|
85159
84760
|
finalResult = cleanSchemaResponse(finalResult);
|
|
85160
|
-
validation = validateJsonResponse(finalResult);
|
|
84761
|
+
validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
85161
84762
|
retryCount = 1;
|
|
85162
84763
|
}
|
|
85163
84764
|
if (!validation.isValid) {
|
|
@@ -85167,20 +84768,16 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
85167
84768
|
console.log(`[DEBUG] JSON validation: Auto-wrapped plain text for simple schema`);
|
|
85168
84769
|
}
|
|
85169
84770
|
finalResult = autoWrapped;
|
|
85170
|
-
validation = validateJsonResponse(finalResult, { debug: this.debug });
|
|
84771
|
+
validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
85171
84772
|
}
|
|
85172
84773
|
}
|
|
85173
84774
|
while (!validation.isValid && retryCount < maxRetries) {
|
|
85174
84775
|
if (this.debug) {
|
|
85175
|
-
console.log(`[DEBUG] JSON validation:
|
|
85176
|
-
console.log(`[DEBUG] JSON validation: Invalid response sample: ${finalResult.substring(0, 300)}${finalResult.length > 300 ? "..." : ""}`);
|
|
84776
|
+
console.log(`[DEBUG] JSON validation: Validation failed (attempt ${retryCount + 1}/${maxRetries}):`, validation.error);
|
|
85177
84777
|
}
|
|
85178
84778
|
let correctionPrompt;
|
|
85179
84779
|
try {
|
|
85180
84780
|
if (isJsonSchemaDefinition(finalResult, { debug: this.debug })) {
|
|
85181
|
-
if (this.debug) {
|
|
85182
|
-
console.log(`[DEBUG] JSON validation: attempt_completion response is still a schema definition, using specialized correction`);
|
|
85183
|
-
}
|
|
85184
84781
|
correctionPrompt = createSchemaDefinitionCorrectionPrompt(
|
|
85185
84782
|
finalResult,
|
|
85186
84783
|
options.schema,
|
|
@@ -85202,47 +84799,43 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
85202
84799
|
retryCount
|
|
85203
84800
|
);
|
|
85204
84801
|
}
|
|
85205
|
-
const { schema: _unusedSchema2, ...correctionOptions } = options;
|
|
85206
84802
|
finalResult = await this.answer(correctionPrompt, [], {
|
|
85207
|
-
...
|
|
84803
|
+
...options,
|
|
85208
84804
|
_schemaFormatted: true,
|
|
85209
84805
|
_skipValidation: true,
|
|
85210
|
-
// Skip validation in recursive correction calls to prevent loops
|
|
85211
84806
|
_disableTools: true,
|
|
85212
|
-
// Only allow attempt_completion - prevent AI from using search/query tools
|
|
85213
84807
|
_completionPromptProcessed: true,
|
|
85214
|
-
// Prevent cascading completion prompts in retry calls
|
|
85215
84808
|
_maxIterationsOverride: 3
|
|
85216
|
-
// Correction should complete in 1-2 iterations (issue #447)
|
|
85217
84809
|
});
|
|
85218
84810
|
finalResult = cleanSchemaResponse(finalResult);
|
|
85219
|
-
validation = validateJsonResponse(finalResult, { debug: this.debug });
|
|
84811
|
+
validation = validateJsonResponse(finalResult, { debug: this.debug, schema: options.schema });
|
|
85220
84812
|
retryCount++;
|
|
85221
84813
|
if (this.debug) {
|
|
85222
84814
|
if (validation.isValid) {
|
|
85223
|
-
console.log(`[DEBUG] JSON validation:
|
|
84815
|
+
console.log(`[DEBUG] JSON validation: Correction successful on attempt ${retryCount}`);
|
|
85224
84816
|
} else {
|
|
85225
|
-
console.log(`[DEBUG] JSON validation:
|
|
84817
|
+
console.log(`[DEBUG] JSON validation: Correction failed on attempt ${retryCount}: ${validation.error}`);
|
|
85226
84818
|
}
|
|
85227
84819
|
}
|
|
85228
84820
|
}
|
|
85229
84821
|
if (this.tracer) {
|
|
85230
|
-
this.tracer.recordJsonValidationEvent("
|
|
84822
|
+
this.tracer.recordJsonValidationEvent("completed", {
|
|
85231
84823
|
"json_validation.success": validation.isValid,
|
|
85232
84824
|
"json_validation.retry_count": retryCount,
|
|
85233
|
-
"json_validation.
|
|
84825
|
+
"json_validation.max_retries": maxRetries,
|
|
84826
|
+
"json_validation.final_response_length": finalResult.length,
|
|
84827
|
+
"json_validation.error": validation.isValid ? null : validation.error
|
|
85234
84828
|
});
|
|
85235
84829
|
}
|
|
85236
84830
|
if (!validation.isValid && this.debug) {
|
|
85237
|
-
console.log(`[DEBUG] JSON validation:
|
|
85238
|
-
console.log(`[DEBUG] JSON validation: Final attempt_completion response: ${finalResult.substring(0, 500)}${finalResult.length > 500 ? "..." : ""}`);
|
|
84831
|
+
console.log(`[DEBUG] JSON validation: Failed after ${maxRetries} attempts: ${validation.error}`);
|
|
85239
84832
|
} else if (validation.isValid && this.debug) {
|
|
85240
|
-
console.log(`[DEBUG] JSON validation:
|
|
84833
|
+
console.log(`[DEBUG] JSON validation: Final validation successful`);
|
|
85241
84834
|
}
|
|
85242
84835
|
}
|
|
85243
84836
|
} catch (error) {
|
|
85244
84837
|
if (this.debug) {
|
|
85245
|
-
console.log(`[DEBUG]
|
|
84838
|
+
console.log(`[DEBUG] Schema validation/cleanup failed: ${error.message}`);
|
|
85246
84839
|
}
|
|
85247
84840
|
}
|
|
85248
84841
|
}
|
|
@@ -86418,7 +86011,9 @@ function parseArgs() {
|
|
|
86418
86011
|
disableDefaultBashAllow: false,
|
|
86419
86012
|
disableDefaultBashDeny: false,
|
|
86420
86013
|
// Native thinking/reasoning effort
|
|
86421
|
-
thinkingEffort: null
|
|
86014
|
+
thinkingEffort: null,
|
|
86015
|
+
// Completion prompt for post-completion validation/review
|
|
86016
|
+
completionPrompt: null
|
|
86422
86017
|
};
|
|
86423
86018
|
for (let i = 0; i < args.length; i++) {
|
|
86424
86019
|
const arg = args[i];
|
|
@@ -86452,6 +86047,8 @@ function parseArgs() {
|
|
|
86452
86047
|
config.architectureFileName = args[++i];
|
|
86453
86048
|
} else if (arg === "--schema" && i + 1 < args.length) {
|
|
86454
86049
|
config.schema = args[++i];
|
|
86050
|
+
} else if (arg === "--completion-prompt" && i + 1 < args.length) {
|
|
86051
|
+
config.completionPrompt = args[++i];
|
|
86455
86052
|
} else if (arg === "--provider" && i + 1 < args.length) {
|
|
86456
86053
|
config.provider = args[++i];
|
|
86457
86054
|
} else if (arg === "--model" && i + 1 < args.length) {
|
|
@@ -86538,6 +86135,7 @@ Options:
|
|
|
86538
86135
|
--system-prompt <text|file> Custom system prompt (text or file path)
|
|
86539
86136
|
--architecture-file <name> Architecture context filename in repo root (defaults to AGENTS.md with CLAUDE.md fallback; ARCHITECTURE.md is always included when present)
|
|
86540
86137
|
--schema <schema|file> Output schema (JSON, XML, any format - text or file path)
|
|
86138
|
+
--completion-prompt <text> Post-completion review prompt (validates/enriches the answer)
|
|
86541
86139
|
--provider <name> Force AI provider: anthropic, openai, google
|
|
86542
86140
|
--model <name> Override model name
|
|
86543
86141
|
--allow-edit Enable code modification capabilities (edit + create tools)
|
|
@@ -87040,7 +86638,8 @@ async function main() {
|
|
|
87040
86638
|
enableTasks: config.enableTasks,
|
|
87041
86639
|
thinkingEffort: config.thinkingEffort,
|
|
87042
86640
|
searchDelegateProvider: config.searchDelegateProvider,
|
|
87043
|
-
searchDelegateModel: config.searchDelegateModel
|
|
86641
|
+
searchDelegateModel: config.searchDelegateModel,
|
|
86642
|
+
completionPrompt: config.completionPrompt
|
|
87044
86643
|
};
|
|
87045
86644
|
const agent = new ProbeAgent(agentConfig2);
|
|
87046
86645
|
await agent.initialize();
|