@probelabs/probe 0.6.0-rc131 → 0.6.0-rc132
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/agent/ProbeAgent.d.ts +1 -1
- package/build/agent/ProbeAgent.js +188 -93
- package/build/agent/index.js +444 -77
- package/build/agent/schemaUtils.js +260 -11
- package/cjs/agent/ProbeAgent.cjs +770 -289
- package/cjs/index.cjs +770 -289
- package/package.json +1 -1
- package/src/agent/ProbeAgent.d.ts +1 -1
- package/src/agent/ProbeAgent.js +188 -93
- package/src/agent/schemaUtils.js +260 -11
package/build/agent/index.js
CHANGED
|
@@ -46421,6 +46421,28 @@ var init_out = __esm({
|
|
|
46421
46421
|
});
|
|
46422
46422
|
|
|
46423
46423
|
// src/agent/schemaUtils.js
|
|
46424
|
+
var schemaUtils_exports = {};
|
|
46425
|
+
__export(schemaUtils_exports, {
|
|
46426
|
+
JsonFixingAgent: () => JsonFixingAgent,
|
|
46427
|
+
MermaidFixingAgent: () => MermaidFixingAgent,
|
|
46428
|
+
cleanSchemaResponse: () => cleanSchemaResponse,
|
|
46429
|
+
createJsonCorrectionPrompt: () => createJsonCorrectionPrompt,
|
|
46430
|
+
createMermaidCorrectionPrompt: () => createMermaidCorrectionPrompt,
|
|
46431
|
+
createSchemaDefinitionCorrectionPrompt: () => createSchemaDefinitionCorrectionPrompt,
|
|
46432
|
+
decodeHtmlEntities: () => decodeHtmlEntities,
|
|
46433
|
+
extractMermaidFromMarkdown: () => extractMermaidFromMarkdown,
|
|
46434
|
+
isJsonSchema: () => isJsonSchema,
|
|
46435
|
+
isJsonSchemaDefinition: () => isJsonSchemaDefinition,
|
|
46436
|
+
isMermaidSchema: () => isMermaidSchema,
|
|
46437
|
+
processSchemaResponse: () => processSchemaResponse,
|
|
46438
|
+
replaceMermaidDiagramsInMarkdown: () => replaceMermaidDiagramsInMarkdown,
|
|
46439
|
+
tryMaidAutoFix: () => tryMaidAutoFix,
|
|
46440
|
+
validateAndFixMermaidResponse: () => validateAndFixMermaidResponse,
|
|
46441
|
+
validateJsonResponse: () => validateJsonResponse,
|
|
46442
|
+
validateMermaidDiagram: () => validateMermaidDiagram,
|
|
46443
|
+
validateMermaidResponse: () => validateMermaidResponse,
|
|
46444
|
+
validateXmlResponse: () => validateXmlResponse
|
|
46445
|
+
});
|
|
46424
46446
|
function decodeHtmlEntities(text) {
|
|
46425
46447
|
if (!text || typeof text !== "string") {
|
|
46426
46448
|
return text;
|
|
@@ -46509,9 +46531,49 @@ function validateJsonResponse(response, options = {}) {
|
|
|
46509
46531
|
}
|
|
46510
46532
|
return { isValid: true, parsed };
|
|
46511
46533
|
} catch (error) {
|
|
46534
|
+
const positionMatch = error.message.match(/position (\d+)/);
|
|
46535
|
+
let errorPosition = positionMatch ? parseInt(positionMatch[1], 10) : null;
|
|
46536
|
+
if (errorPosition === null) {
|
|
46537
|
+
const tokenMatch = error.message.match(/Unexpected token '(.)', /);
|
|
46538
|
+
if (tokenMatch && tokenMatch[1]) {
|
|
46539
|
+
const problematicToken = tokenMatch[1];
|
|
46540
|
+
errorPosition = response.indexOf(problematicToken);
|
|
46541
|
+
}
|
|
46542
|
+
}
|
|
46543
|
+
let enhancedError = error.message;
|
|
46544
|
+
let errorContext = null;
|
|
46545
|
+
if (errorPosition !== null && errorPosition >= 0 && response && response.length > 0) {
|
|
46546
|
+
const contextRadius = 50;
|
|
46547
|
+
const startPos = Math.max(0, errorPosition - contextRadius);
|
|
46548
|
+
const endPos = Math.min(response.length, errorPosition + contextRadius);
|
|
46549
|
+
const beforeError = response.substring(startPos, errorPosition);
|
|
46550
|
+
const atError = response[errorPosition] || "";
|
|
46551
|
+
const afterError = response.substring(errorPosition + 1, endPos);
|
|
46552
|
+
const snippet = beforeError + atError + afterError;
|
|
46553
|
+
const pointerOffset = beforeError.length;
|
|
46554
|
+
const pointer = " ".repeat(pointerOffset) + "^";
|
|
46555
|
+
errorContext = {
|
|
46556
|
+
position: errorPosition,
|
|
46557
|
+
snippet,
|
|
46558
|
+
pointer,
|
|
46559
|
+
beforeError,
|
|
46560
|
+
atError,
|
|
46561
|
+
afterError
|
|
46562
|
+
};
|
|
46563
|
+
enhancedError = `${error.message}
|
|
46564
|
+
|
|
46565
|
+
Error location (position ${errorPosition}):
|
|
46566
|
+
${snippet}
|
|
46567
|
+
${pointer} here`;
|
|
46568
|
+
}
|
|
46512
46569
|
if (debug) {
|
|
46513
46570
|
console.log(`[DEBUG] JSON validation: Parse failed with error: ${error.message}`);
|
|
46514
|
-
console.log(`[DEBUG] JSON validation: Error at position: ${
|
|
46571
|
+
console.log(`[DEBUG] JSON validation: Error at position: ${errorPosition !== null ? errorPosition : "unknown"}`);
|
|
46572
|
+
if (errorContext) {
|
|
46573
|
+
console.log(`[DEBUG] JSON validation: Error context:
|
|
46574
|
+
${errorContext.snippet}
|
|
46575
|
+
${errorContext.pointer}`);
|
|
46576
|
+
}
|
|
46515
46577
|
if (error.message.includes("Unexpected token")) {
|
|
46516
46578
|
console.log(`[DEBUG] JSON validation: Likely syntax error - unexpected character`);
|
|
46517
46579
|
} else if (error.message.includes("Unexpected end")) {
|
|
@@ -46520,7 +46582,12 @@ function validateJsonResponse(response, options = {}) {
|
|
|
46520
46582
|
console.log(`[DEBUG] JSON validation: Likely unquoted property names`);
|
|
46521
46583
|
}
|
|
46522
46584
|
}
|
|
46523
|
-
return {
|
|
46585
|
+
return {
|
|
46586
|
+
isValid: false,
|
|
46587
|
+
error: error.message,
|
|
46588
|
+
enhancedError,
|
|
46589
|
+
errorContext
|
|
46590
|
+
};
|
|
46524
46591
|
}
|
|
46525
46592
|
}
|
|
46526
46593
|
function validateXmlResponse(response) {
|
|
@@ -46640,7 +46707,16 @@ function isJsonSchemaDefinition(jsonString, options = {}) {
|
|
|
46640
46707
|
return false;
|
|
46641
46708
|
}
|
|
46642
46709
|
}
|
|
46643
|
-
function createJsonCorrectionPrompt(invalidResponse, schema,
|
|
46710
|
+
function createJsonCorrectionPrompt(invalidResponse, schema, errorOrValidation, retryCount = 0) {
|
|
46711
|
+
let errorMessage;
|
|
46712
|
+
let enhancedError;
|
|
46713
|
+
if (typeof errorOrValidation === "object" && errorOrValidation !== null) {
|
|
46714
|
+
errorMessage = errorOrValidation.error;
|
|
46715
|
+
enhancedError = errorOrValidation.enhancedError || errorMessage;
|
|
46716
|
+
} else {
|
|
46717
|
+
errorMessage = errorOrValidation;
|
|
46718
|
+
enhancedError = errorMessage;
|
|
46719
|
+
}
|
|
46644
46720
|
const strengthLevels = [
|
|
46645
46721
|
{
|
|
46646
46722
|
prefix: "CRITICAL JSON ERROR:",
|
|
@@ -46664,7 +46740,7 @@ function createJsonCorrectionPrompt(invalidResponse, schema, error, retryCount =
|
|
|
46664
46740
|
|
|
46665
46741
|
${invalidResponse.substring(0, 500)}${invalidResponse.length > 500 ? "..." : ""}
|
|
46666
46742
|
|
|
46667
|
-
Error: ${
|
|
46743
|
+
Error: ${enhancedError}
|
|
46668
46744
|
|
|
46669
46745
|
${currentLevel.instruction}
|
|
46670
46746
|
|
|
@@ -46709,6 +46785,28 @@ ${currentLevel.example}
|
|
|
46709
46785
|
Return ONLY the JSON data object/array that follows the schema structure. NO schema definitions, NO explanations, NO markdown formatting.`;
|
|
46710
46786
|
return prompt;
|
|
46711
46787
|
}
|
|
46788
|
+
function isMermaidSchema(schema) {
|
|
46789
|
+
if (!schema || typeof schema !== "string") {
|
|
46790
|
+
return false;
|
|
46791
|
+
}
|
|
46792
|
+
const trimmedSchema = schema.trim().toLowerCase();
|
|
46793
|
+
const mermaidIndicators = [
|
|
46794
|
+
trimmedSchema.includes("mermaid"),
|
|
46795
|
+
trimmedSchema.includes("diagram"),
|
|
46796
|
+
trimmedSchema.includes("flowchart"),
|
|
46797
|
+
trimmedSchema.includes("sequence"),
|
|
46798
|
+
trimmedSchema.includes("gantt"),
|
|
46799
|
+
trimmedSchema.includes("pie chart"),
|
|
46800
|
+
trimmedSchema.includes("state diagram"),
|
|
46801
|
+
trimmedSchema.includes("class diagram"),
|
|
46802
|
+
trimmedSchema.includes("entity relationship"),
|
|
46803
|
+
trimmedSchema.includes("user journey"),
|
|
46804
|
+
trimmedSchema.includes("git graph"),
|
|
46805
|
+
trimmedSchema.includes("requirement diagram"),
|
|
46806
|
+
trimmedSchema.includes("c4 context")
|
|
46807
|
+
];
|
|
46808
|
+
return mermaidIndicators.some((indicator) => indicator);
|
|
46809
|
+
}
|
|
46712
46810
|
function extractMermaidFromMarkdown(response) {
|
|
46713
46811
|
if (!response || typeof response !== "string") {
|
|
46714
46812
|
return { diagrams: [], cleanedResponse: response };
|
|
@@ -46729,6 +46827,24 @@ function extractMermaidFromMarkdown(response) {
|
|
|
46729
46827
|
}
|
|
46730
46828
|
return { diagrams, cleanedResponse: response };
|
|
46731
46829
|
}
|
|
46830
|
+
function replaceMermaidDiagramsInMarkdown(originalResponse, correctedDiagrams) {
|
|
46831
|
+
if (!originalResponse || typeof originalResponse !== "string") {
|
|
46832
|
+
return originalResponse;
|
|
46833
|
+
}
|
|
46834
|
+
if (!correctedDiagrams || correctedDiagrams.length === 0) {
|
|
46835
|
+
return originalResponse;
|
|
46836
|
+
}
|
|
46837
|
+
let modifiedResponse = originalResponse;
|
|
46838
|
+
const sortedDiagrams = [...correctedDiagrams].sort((a, b) => b.startIndex - a.startIndex);
|
|
46839
|
+
for (const diagram of sortedDiagrams) {
|
|
46840
|
+
const attributesStr = diagram.attributes ? ` ${diagram.attributes}` : "";
|
|
46841
|
+
const newCodeBlock = `\`\`\`mermaid${attributesStr}
|
|
46842
|
+
${diagram.content}
|
|
46843
|
+
\`\`\``;
|
|
46844
|
+
modifiedResponse = modifiedResponse.slice(0, diagram.startIndex) + newCodeBlock + modifiedResponse.slice(diagram.endIndex);
|
|
46845
|
+
}
|
|
46846
|
+
return modifiedResponse;
|
|
46847
|
+
}
|
|
46732
46848
|
async function validateMermaidDiagram(diagram) {
|
|
46733
46849
|
if (!diagram || typeof diagram !== "string") {
|
|
46734
46850
|
return { isValid: false, error: "Empty or invalid diagram input" };
|
|
@@ -46795,6 +46911,45 @@ async function validateMermaidResponse(response) {
|
|
|
46795
46911
|
errors: errors.length > 0 ? errors : void 0
|
|
46796
46912
|
};
|
|
46797
46913
|
}
|
|
46914
|
+
function createMermaidCorrectionPrompt(invalidResponse, schema, errors, diagrams) {
|
|
46915
|
+
let prompt = `Your previous response contains invalid Mermaid diagrams that cannot be parsed. Here's what you returned:
|
|
46916
|
+
|
|
46917
|
+
${invalidResponse}
|
|
46918
|
+
|
|
46919
|
+
Validation Errors:`;
|
|
46920
|
+
errors.forEach((error, index) => {
|
|
46921
|
+
prompt += `
|
|
46922
|
+
${index + 1}. ${error}`;
|
|
46923
|
+
});
|
|
46924
|
+
if (diagrams && diagrams.length > 0) {
|
|
46925
|
+
prompt += `
|
|
46926
|
+
|
|
46927
|
+
Diagram Details:`;
|
|
46928
|
+
diagrams.forEach((diagramResult, index) => {
|
|
46929
|
+
if (!diagramResult.isValid) {
|
|
46930
|
+
prompt += `
|
|
46931
|
+
|
|
46932
|
+
Diagram ${index + 1}:`;
|
|
46933
|
+
const diagramContent = diagramResult.content || diagramResult.diagram || "";
|
|
46934
|
+
prompt += `
|
|
46935
|
+
- Content: ${diagramContent.substring(0, 100)}${diagramContent.length > 100 ? "..." : ""}`;
|
|
46936
|
+
prompt += `
|
|
46937
|
+
- Error: ${diagramResult.error}`;
|
|
46938
|
+
if (diagramResult.detailedError && diagramResult.detailedError !== diagramResult.error) {
|
|
46939
|
+
prompt += `
|
|
46940
|
+
- Details: ${diagramResult.detailedError}`;
|
|
46941
|
+
}
|
|
46942
|
+
}
|
|
46943
|
+
});
|
|
46944
|
+
}
|
|
46945
|
+
prompt += `
|
|
46946
|
+
|
|
46947
|
+
Please correct your response to include valid Mermaid diagrams that match this schema:
|
|
46948
|
+
${schema}
|
|
46949
|
+
|
|
46950
|
+
Ensure all Mermaid diagrams are properly formatted within \`\`\`mermaid code blocks and follow correct Mermaid syntax.`;
|
|
46951
|
+
return prompt;
|
|
46952
|
+
}
|
|
46798
46953
|
async function tryMaidAutoFix(diagramContent, options = {}) {
|
|
46799
46954
|
const { debug = false } = options;
|
|
46800
46955
|
try {
|
|
@@ -47104,7 +47259,7 @@ ${fixedContent}
|
|
|
47104
47259
|
};
|
|
47105
47260
|
}
|
|
47106
47261
|
}
|
|
47107
|
-
var HTML_ENTITY_MAP, MermaidFixingAgent;
|
|
47262
|
+
var HTML_ENTITY_MAP, JsonFixingAgent, MermaidFixingAgent;
|
|
47108
47263
|
var init_schemaUtils = __esm({
|
|
47109
47264
|
"src/agent/schemaUtils.js"() {
|
|
47110
47265
|
"use strict";
|
|
@@ -47120,6 +47275,156 @@ var init_schemaUtils = __esm({
|
|
|
47120
47275
|
// Also handle XML/HTML5 apostrophe entity
|
|
47121
47276
|
" ": " "
|
|
47122
47277
|
};
|
|
47278
|
+
JsonFixingAgent = class {
|
|
47279
|
+
constructor(options = {}) {
|
|
47280
|
+
this.ProbeAgent = null;
|
|
47281
|
+
this.options = {
|
|
47282
|
+
sessionId: options.sessionId || `json-fixer-${Date.now()}`,
|
|
47283
|
+
path: options.path || process.cwd(),
|
|
47284
|
+
provider: options.provider,
|
|
47285
|
+
model: options.model,
|
|
47286
|
+
debug: options.debug,
|
|
47287
|
+
tracer: options.tracer,
|
|
47288
|
+
// Set to false since we're only fixing JSON syntax, not implementing code
|
|
47289
|
+
allowEdit: false
|
|
47290
|
+
};
|
|
47291
|
+
}
|
|
47292
|
+
/**
|
|
47293
|
+
* Get the specialized prompt for JSON fixing
|
|
47294
|
+
*/
|
|
47295
|
+
getJsonFixingPrompt() {
|
|
47296
|
+
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.
|
|
47297
|
+
|
|
47298
|
+
CORE RESPONSIBILITIES:
|
|
47299
|
+
- Analyze JSON for syntax errors and structural issues
|
|
47300
|
+
- Fix syntax errors while maintaining the original data's semantic meaning
|
|
47301
|
+
- Ensure JSON follows proper RFC 8259 specification
|
|
47302
|
+
- Handle all JSON structures: objects, arrays, primitives, nested structures
|
|
47303
|
+
|
|
47304
|
+
JSON SYNTAX RULES:
|
|
47305
|
+
1. **Property names**: Must be enclosed in double quotes
|
|
47306
|
+
2. **String values**: Must use double quotes (not single quotes)
|
|
47307
|
+
3. **Numbers**: Can be integers or decimals, no quotes needed
|
|
47308
|
+
4. **Booleans**: true or false (lowercase, no quotes)
|
|
47309
|
+
5. **Null**: null (lowercase, no quotes)
|
|
47310
|
+
6. **Arrays**: Comma-separated values in square brackets [...]
|
|
47311
|
+
7. **Objects**: Comma-separated key-value pairs in curly braces {...}
|
|
47312
|
+
8. **No trailing commas**: Last item in array/object must not have a trailing comma
|
|
47313
|
+
9. **Escape sequences**: Special characters must be escaped (\\n, \\t, \\", \\\\, etc.)
|
|
47314
|
+
|
|
47315
|
+
COMMON ERRORS TO FIX:
|
|
47316
|
+
1. **Unquoted property names**: {name: "value"} \u2192 {"name": "value"}
|
|
47317
|
+
2. **Single quotes**: {'key': 'value'} \u2192 {"key": "value"}
|
|
47318
|
+
3. **Trailing commas**: {"a": 1,} \u2192 {"a": 1}
|
|
47319
|
+
4. **Unquoted strings**: {key: value} \u2192 {"key": "value"}
|
|
47320
|
+
5. **Missing commas**: {"a": 1 "b": 2} \u2192 {"a": 1, "b": 2}
|
|
47321
|
+
6. **Extra commas**: {"a": 1,, "b": 2} \u2192 {"a": 1, "b": 2}
|
|
47322
|
+
7. **Unclosed brackets/braces**: {"key": "value" \u2192 {"key": "value"}
|
|
47323
|
+
8. **Invalid escape sequences**: Fix or remove
|
|
47324
|
+
9. **Comments**: Remove // or /* */ comments (not allowed in JSON)
|
|
47325
|
+
10. **Undefined values**: Replace undefined with null
|
|
47326
|
+
|
|
47327
|
+
FIXING METHODOLOGY:
|
|
47328
|
+
1. **Identify the error location** from the error message
|
|
47329
|
+
2. **Analyze the context** around the error
|
|
47330
|
+
3. **Apply the appropriate fix** based on JSON syntax rules
|
|
47331
|
+
4. **Preserve data intent** - never change the meaning of the data
|
|
47332
|
+
5. **Validate the result** - ensure it's parseable JSON
|
|
47333
|
+
|
|
47334
|
+
CRITICAL RULES:
|
|
47335
|
+
- ALWAYS output only the corrected JSON
|
|
47336
|
+
- NEVER add explanations, comments, or additional text
|
|
47337
|
+
- NEVER wrap in markdown code blocks (no \`\`\`json)
|
|
47338
|
+
- PRESERVE the original data structure and values
|
|
47339
|
+
- FIX only syntax errors, don't modify the data itself
|
|
47340
|
+
- ENSURE the output is valid, parseable JSON
|
|
47341
|
+
|
|
47342
|
+
When presented with broken JSON, analyze it thoroughly and provide the corrected version that maintains the original intent while fixing all syntax issues.`;
|
|
47343
|
+
}
|
|
47344
|
+
/**
|
|
47345
|
+
* Initialize the ProbeAgent if not already done
|
|
47346
|
+
*/
|
|
47347
|
+
async initializeAgent() {
|
|
47348
|
+
if (!this.ProbeAgent) {
|
|
47349
|
+
const { ProbeAgent: ProbeAgent2 } = await Promise.resolve().then(() => (init_ProbeAgent(), ProbeAgent_exports));
|
|
47350
|
+
this.ProbeAgent = ProbeAgent2;
|
|
47351
|
+
}
|
|
47352
|
+
if (!this.agent) {
|
|
47353
|
+
this.agent = new this.ProbeAgent({
|
|
47354
|
+
sessionId: this.options.sessionId,
|
|
47355
|
+
customPrompt: this.getJsonFixingPrompt(),
|
|
47356
|
+
path: this.options.path,
|
|
47357
|
+
provider: this.options.provider,
|
|
47358
|
+
model: this.options.model,
|
|
47359
|
+
debug: this.options.debug,
|
|
47360
|
+
tracer: this.options.tracer,
|
|
47361
|
+
allowEdit: this.options.allowEdit,
|
|
47362
|
+
maxIterations: 5,
|
|
47363
|
+
// Allow multiple iterations for JSON fixing
|
|
47364
|
+
disableJsonValidation: true
|
|
47365
|
+
// CRITICAL: Disable JSON validation in nested agent to prevent infinite recursion
|
|
47366
|
+
});
|
|
47367
|
+
}
|
|
47368
|
+
return this.agent;
|
|
47369
|
+
}
|
|
47370
|
+
/**
|
|
47371
|
+
* Fix invalid JSON using the specialized agent
|
|
47372
|
+
* @param {string} invalidJson - The broken JSON string
|
|
47373
|
+
* @param {string} schema - The original schema for context
|
|
47374
|
+
* @param {Object} validationResult - Validation result with error details
|
|
47375
|
+
* @param {number} attemptNumber - Current attempt number (for logging)
|
|
47376
|
+
* @returns {Promise<string>} - The corrected JSON
|
|
47377
|
+
*/
|
|
47378
|
+
async fixJson(invalidJson, schema, validationResult, attemptNumber = 1) {
|
|
47379
|
+
await this.initializeAgent();
|
|
47380
|
+
let errorContext = validationResult.error;
|
|
47381
|
+
if (validationResult.enhancedError) {
|
|
47382
|
+
errorContext = validationResult.enhancedError;
|
|
47383
|
+
}
|
|
47384
|
+
const prompt = `Fix the following invalid JSON.
|
|
47385
|
+
|
|
47386
|
+
Error: ${errorContext}
|
|
47387
|
+
|
|
47388
|
+
Invalid JSON:
|
|
47389
|
+
${invalidJson}
|
|
47390
|
+
|
|
47391
|
+
Expected schema structure:
|
|
47392
|
+
${schema}
|
|
47393
|
+
|
|
47394
|
+
Provide only the corrected JSON without any markdown formatting or explanations.`;
|
|
47395
|
+
try {
|
|
47396
|
+
if (this.options.debug) {
|
|
47397
|
+
console.log(`[DEBUG] JSON fixing: Attempt ${attemptNumber} to fix JSON with separate agent`);
|
|
47398
|
+
}
|
|
47399
|
+
const result = await this.agent.answer(prompt, []);
|
|
47400
|
+
const cleaned = cleanSchemaResponse(result);
|
|
47401
|
+
if (this.options.debug) {
|
|
47402
|
+
console.log(`[DEBUG] JSON fixing: Agent returned ${cleaned.length} chars`);
|
|
47403
|
+
}
|
|
47404
|
+
return cleaned;
|
|
47405
|
+
} catch (error) {
|
|
47406
|
+
if (this.options.debug) {
|
|
47407
|
+
console.error(`[DEBUG] JSON fixing failed: ${error.message}`);
|
|
47408
|
+
}
|
|
47409
|
+
throw new Error(`Failed to fix JSON: ${error.message}`);
|
|
47410
|
+
}
|
|
47411
|
+
}
|
|
47412
|
+
/**
|
|
47413
|
+
* Get token usage information from the specialized agent
|
|
47414
|
+
* @returns {Object} - Token usage statistics
|
|
47415
|
+
*/
|
|
47416
|
+
getTokenUsage() {
|
|
47417
|
+
return this.agent ? this.agent.getTokenUsage() : null;
|
|
47418
|
+
}
|
|
47419
|
+
/**
|
|
47420
|
+
* Cancel any ongoing operations
|
|
47421
|
+
*/
|
|
47422
|
+
cancel() {
|
|
47423
|
+
if (this.agent) {
|
|
47424
|
+
this.agent.cancel();
|
|
47425
|
+
}
|
|
47426
|
+
}
|
|
47427
|
+
};
|
|
47123
47428
|
MermaidFixingAgent = class {
|
|
47124
47429
|
constructor(options = {}) {
|
|
47125
47430
|
this.ProbeAgent = null;
|
|
@@ -48112,6 +48417,7 @@ var init_ProbeAgent = __esm({
|
|
|
48112
48417
|
* @param {number} [options.maxResponseTokens] - Maximum tokens for AI responses
|
|
48113
48418
|
* @param {number} [options.maxIterations] - Maximum tool iterations (overrides MAX_TOOL_ITERATIONS env var)
|
|
48114
48419
|
* @param {boolean} [options.disableMermaidValidation=false] - Disable automatic mermaid diagram validation and fixing
|
|
48420
|
+
* @param {boolean} [options.disableJsonValidation=false] - Disable automatic JSON validation and fixing (prevents infinite recursion in JsonFixingAgent)
|
|
48115
48421
|
* @param {boolean} [options.enableMcp=false] - Enable MCP tool integration
|
|
48116
48422
|
* @param {string} [options.mcpConfigPath] - Path to MCP configuration file
|
|
48117
48423
|
* @param {Object} [options.mcpConfig] - MCP configuration object (overrides mcpConfigPath)
|
|
@@ -48131,6 +48437,7 @@ var init_ProbeAgent = __esm({
|
|
|
48131
48437
|
this.maxResponseTokens = options.maxResponseTokens || parseInt(process.env.MAX_RESPONSE_TOKENS || "0", 10) || null;
|
|
48132
48438
|
this.maxIterations = options.maxIterations || null;
|
|
48133
48439
|
this.disableMermaidValidation = !!options.disableMermaidValidation;
|
|
48440
|
+
this.disableJsonValidation = !!options.disableJsonValidation;
|
|
48134
48441
|
this.storageAdapter = options.storageAdapter || new InMemoryStorageAdapter();
|
|
48135
48442
|
this.hooks = new HookManager();
|
|
48136
48443
|
if (options.hooks) {
|
|
@@ -49345,15 +49652,16 @@ Remember: Use proper XML format with BOTH opening and closing tags:
|
|
|
49345
49652
|
<parameter>value</parameter>
|
|
49346
49653
|
</tool_name>
|
|
49347
49654
|
|
|
49348
|
-
IMPORTANT: A schema was provided
|
|
49349
|
-
Use attempt_completion with your response directly inside the tags:
|
|
49655
|
+
IMPORTANT: A schema was provided for the final output format. You have two options:
|
|
49350
49656
|
|
|
49657
|
+
Option 1 - Use attempt_completion with your complete answer:
|
|
49351
49658
|
<attempt_completion>
|
|
49352
|
-
[Your
|
|
49659
|
+
[Your complete answer here - will be automatically formatted to match the schema]
|
|
49353
49660
|
</attempt_completion>
|
|
49354
49661
|
|
|
49355
|
-
|
|
49356
|
-
|
|
49662
|
+
Option 2 - Provide a natural response without any tool, and it will be automatically formatted.
|
|
49663
|
+
|
|
49664
|
+
Do NOT try to format your response as JSON yourself - this will be done automatically.`;
|
|
49357
49665
|
} else {
|
|
49358
49666
|
reminderContent = `Please use one of the available tools to help answer the question, or use attempt_completion if you have enough information to provide a final answer.
|
|
49359
49667
|
|
|
@@ -49500,6 +49808,10 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
49500
49808
|
console.log(`[DEBUG] JSON validation: Starting validation process for schema response`);
|
|
49501
49809
|
console.log(`[DEBUG] JSON validation: Response length: ${finalResult.length} chars`);
|
|
49502
49810
|
}
|
|
49811
|
+
finalResult = cleanSchemaResponse(finalResult);
|
|
49812
|
+
if (this.debug) {
|
|
49813
|
+
console.log(`[DEBUG] JSON validation: After cleaning, length: ${finalResult.length} chars`);
|
|
49814
|
+
}
|
|
49503
49815
|
if (this.tracer) {
|
|
49504
49816
|
this.tracer.recordJsonValidationEvent("started", {
|
|
49505
49817
|
"json_validation.response_length": finalResult.length,
|
|
@@ -49511,75 +49823,66 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
49511
49823
|
const maxRetries = 3;
|
|
49512
49824
|
if (validation.isValid && isJsonSchemaDefinition(finalResult, { debug: this.debug })) {
|
|
49513
49825
|
if (this.debug) {
|
|
49514
|
-
console.log(`[DEBUG] JSON validation: Response is a JSON schema definition instead of data,
|
|
49826
|
+
console.log(`[DEBUG] JSON validation: Response is a JSON schema definition instead of data, needs correction...`);
|
|
49515
49827
|
}
|
|
49516
|
-
|
|
49517
|
-
|
|
49518
|
-
|
|
49519
|
-
|
|
49520
|
-
|
|
49521
|
-
finalResult = await this.answer(schemaDefinitionPrompt, [], {
|
|
49522
|
-
...options,
|
|
49523
|
-
_schemaFormatted: true
|
|
49524
|
-
});
|
|
49525
|
-
finalResult = cleanSchemaResponse(finalResult);
|
|
49526
|
-
validation = validateJsonResponse(finalResult);
|
|
49527
|
-
retryCount = 1;
|
|
49828
|
+
validation = {
|
|
49829
|
+
isValid: false,
|
|
49830
|
+
error: "Response is a JSON schema definition instead of actual data",
|
|
49831
|
+
enhancedError: "Response is a JSON schema definition instead of actual data. Please return data that conforms to the schema, not the schema itself."
|
|
49832
|
+
};
|
|
49528
49833
|
}
|
|
49529
|
-
|
|
49834
|
+
if (!validation.isValid) {
|
|
49530
49835
|
if (this.debug) {
|
|
49531
|
-
console.log(`[DEBUG] JSON validation:
|
|
49532
|
-
console.log(`[DEBUG] JSON validation: Invalid response sample: ${finalResult.substring(0, 300)}${finalResult.length > 300 ? "..." : ""}`);
|
|
49836
|
+
console.log(`[DEBUG] JSON validation: Starting separate JsonFixingAgent session...`);
|
|
49533
49837
|
}
|
|
49534
|
-
|
|
49535
|
-
|
|
49536
|
-
|
|
49537
|
-
|
|
49538
|
-
|
|
49539
|
-
|
|
49540
|
-
|
|
49541
|
-
|
|
49542
|
-
|
|
49543
|
-
|
|
49544
|
-
|
|
49545
|
-
|
|
49546
|
-
|
|
49547
|
-
|
|
49838
|
+
const { JsonFixingAgent: JsonFixingAgent2 } = await Promise.resolve().then(() => (init_schemaUtils(), schemaUtils_exports));
|
|
49839
|
+
const jsonFixer = new JsonFixingAgent2({
|
|
49840
|
+
path: this.allowedFolders[0],
|
|
49841
|
+
provider: this.clientApiProvider,
|
|
49842
|
+
model: this.model,
|
|
49843
|
+
debug: this.debug,
|
|
49844
|
+
tracer: this.tracer
|
|
49845
|
+
});
|
|
49846
|
+
let currentResult = finalResult;
|
|
49847
|
+
let currentValidation = validation;
|
|
49848
|
+
while (!currentValidation.isValid && retryCount < maxRetries) {
|
|
49849
|
+
if (this.debug) {
|
|
49850
|
+
console.log(`[DEBUG] JSON validation: Validation failed (attempt ${retryCount + 1}/${maxRetries}):`, currentValidation.error);
|
|
49851
|
+
console.log(`[DEBUG] JSON validation: Invalid response sample: ${currentResult.substring(0, 300)}${currentResult.length > 300 ? "..." : ""}`);
|
|
49852
|
+
}
|
|
49853
|
+
try {
|
|
49854
|
+
currentResult = await jsonFixer.fixJson(
|
|
49855
|
+
currentResult,
|
|
49548
49856
|
options.schema,
|
|
49549
|
-
|
|
49550
|
-
retryCount
|
|
49857
|
+
currentValidation,
|
|
49858
|
+
retryCount + 1
|
|
49551
49859
|
);
|
|
49860
|
+
currentValidation = validateJsonResponse(currentResult, { debug: this.debug });
|
|
49861
|
+
retryCount++;
|
|
49862
|
+
if (this.debug) {
|
|
49863
|
+
if (!currentValidation.isValid && retryCount < maxRetries) {
|
|
49864
|
+
console.log(`[DEBUG] JSON validation: Still invalid after correction ${retryCount}, retrying...`);
|
|
49865
|
+
console.log(`[DEBUG] JSON validation: Corrected response sample: ${currentResult.substring(0, 300)}${currentResult.length > 300 ? "..." : ""}`);
|
|
49866
|
+
} else if (currentValidation.isValid) {
|
|
49867
|
+
console.log(`[DEBUG] JSON validation: Successfully corrected after ${retryCount} attempts with JsonFixingAgent`);
|
|
49868
|
+
}
|
|
49869
|
+
}
|
|
49870
|
+
} catch (error) {
|
|
49871
|
+
if (this.debug) {
|
|
49872
|
+
console.error(`[DEBUG] JSON validation: JsonFixingAgent error on attempt ${retryCount + 1}:`, error.message);
|
|
49873
|
+
}
|
|
49874
|
+
break;
|
|
49552
49875
|
}
|
|
49553
|
-
} catch (error) {
|
|
49554
|
-
correctionPrompt = createJsonCorrectionPrompt(
|
|
49555
|
-
finalResult,
|
|
49556
|
-
options.schema,
|
|
49557
|
-
validation.error,
|
|
49558
|
-
retryCount
|
|
49559
|
-
);
|
|
49560
49876
|
}
|
|
49561
|
-
finalResult =
|
|
49562
|
-
|
|
49563
|
-
|
|
49564
|
-
|
|
49565
|
-
|
|
49566
|
-
|
|
49567
|
-
|
|
49568
|
-
if (this.debug) {
|
|
49569
|
-
if (!validation.isValid && retryCount < maxRetries) {
|
|
49570
|
-
console.log(`[DEBUG] JSON validation: Still invalid after correction ${retryCount}, retrying...`);
|
|
49571
|
-
console.log(`[DEBUG] JSON validation: Corrected response sample: ${finalResult.substring(0, 300)}${finalResult.length > 300 ? "..." : ""}`);
|
|
49572
|
-
} else if (validation.isValid) {
|
|
49573
|
-
console.log(`[DEBUG] JSON validation: Successfully corrected after ${retryCount} attempts`);
|
|
49574
|
-
}
|
|
49877
|
+
finalResult = currentResult;
|
|
49878
|
+
validation = currentValidation;
|
|
49879
|
+
if (!validation.isValid && this.debug) {
|
|
49880
|
+
console.log(`[DEBUG] JSON validation: Still invalid after ${maxRetries} correction attempts with JsonFixingAgent:`, validation.error);
|
|
49881
|
+
console.log(`[DEBUG] JSON validation: Final invalid response: ${finalResult.substring(0, 500)}${finalResult.length > 500 ? "..." : ""}`);
|
|
49882
|
+
} else if (validation.isValid && this.debug) {
|
|
49883
|
+
console.log(`[DEBUG] JSON validation: Final validation successful`);
|
|
49575
49884
|
}
|
|
49576
49885
|
}
|
|
49577
|
-
if (!validation.isValid && this.debug) {
|
|
49578
|
-
console.log(`[DEBUG] JSON validation: Still invalid after ${maxRetries} correction attempts:`, validation.error);
|
|
49579
|
-
console.log(`[DEBUG] JSON validation: Final invalid response: ${finalResult.substring(0, 500)}${finalResult.length > 500 ? "..." : ""}`);
|
|
49580
|
-
} else if (validation.isValid && this.debug) {
|
|
49581
|
-
console.log(`[DEBUG] JSON validation: Final validation successful`);
|
|
49582
|
-
}
|
|
49583
49886
|
if (this.tracer) {
|
|
49584
49887
|
this.tracer.recordJsonValidationEvent("completed", {
|
|
49585
49888
|
"json_validation.success": validation.isValid,
|
|
@@ -49827,6 +50130,7 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
49827
50130
|
maxResponseTokens: this.maxResponseTokens,
|
|
49828
50131
|
maxIterations: this.maxIterations,
|
|
49829
50132
|
disableMermaidValidation: this.disableMermaidValidation,
|
|
50133
|
+
disableJsonValidation: this.disableJsonValidation,
|
|
49830
50134
|
enableMcp: !!this.mcpBridge,
|
|
49831
50135
|
mcpConfig: this.mcpConfig,
|
|
49832
50136
|
enableBash: this.enableBash,
|
|
@@ -49845,11 +50149,44 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
49845
50149
|
}
|
|
49846
50150
|
/**
|
|
49847
50151
|
* Internal method to strip internal/temporary messages from history
|
|
49848
|
-
*
|
|
49849
|
-
*
|
|
50152
|
+
* Strategy: Find the FIRST schema-related message and truncate everything from that point onwards.
|
|
50153
|
+
* This ensures that all schema formatting iterations (IMPORTANT, CRITICAL, corrections, etc.) are removed.
|
|
50154
|
+
* Keeps: system message, user messages, assistant responses, tool results up to the first schema message
|
|
49850
50155
|
* @private
|
|
49851
50156
|
*/
|
|
49852
50157
|
_stripInternalMessages(history, keepSystemMessage = true) {
|
|
50158
|
+
let firstSchemaMessageIndex = -1;
|
|
50159
|
+
for (let i = 0; i < history.length; i++) {
|
|
50160
|
+
const message = history[i];
|
|
50161
|
+
if (message.role === "system") {
|
|
50162
|
+
continue;
|
|
50163
|
+
}
|
|
50164
|
+
if (this._isSchemaMessage(message)) {
|
|
50165
|
+
firstSchemaMessageIndex = i;
|
|
50166
|
+
if (this.debug) {
|
|
50167
|
+
console.log(`[DEBUG] Found first schema message at index ${i}, truncating from here`);
|
|
50168
|
+
}
|
|
50169
|
+
break;
|
|
50170
|
+
}
|
|
50171
|
+
}
|
|
50172
|
+
if (firstSchemaMessageIndex === -1) {
|
|
50173
|
+
return this._stripNonSchemaInternalMessages(history, keepSystemMessage);
|
|
50174
|
+
}
|
|
50175
|
+
const truncated = history.slice(0, firstSchemaMessageIndex);
|
|
50176
|
+
const filtered = this._stripNonSchemaInternalMessages(truncated, keepSystemMessage);
|
|
50177
|
+
if (this.debug) {
|
|
50178
|
+
const removedCount = history.length - filtered.length;
|
|
50179
|
+
console.log(`[DEBUG] Truncated at schema message (index ${firstSchemaMessageIndex}) and filtered non-schema internal messages`);
|
|
50180
|
+
console.log(`[DEBUG] Removed ${removedCount} messages total (${history.length} \u2192 ${filtered.length})`);
|
|
50181
|
+
}
|
|
50182
|
+
return filtered;
|
|
50183
|
+
}
|
|
50184
|
+
/**
|
|
50185
|
+
* Strip non-schema internal messages (mermaid fixes, tool reminders, etc.) individually
|
|
50186
|
+
* Used when no schema messages are present in history
|
|
50187
|
+
* @private
|
|
50188
|
+
*/
|
|
50189
|
+
_stripNonSchemaInternalMessages(history, keepSystemMessage = true) {
|
|
49853
50190
|
const filtered = [];
|
|
49854
50191
|
for (let i = 0; i < history.length; i++) {
|
|
49855
50192
|
const message = history[i];
|
|
@@ -49861,9 +50198,9 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
49861
50198
|
}
|
|
49862
50199
|
continue;
|
|
49863
50200
|
}
|
|
49864
|
-
if (this.
|
|
50201
|
+
if (this._isNonSchemaInternalMessage(message)) {
|
|
49865
50202
|
if (this.debug) {
|
|
49866
|
-
console.log(`[DEBUG] Stripping internal message at index ${i}: ${message.role}`);
|
|
50203
|
+
console.log(`[DEBUG] Stripping non-schema internal message at index ${i}: ${message.role}`);
|
|
49867
50204
|
}
|
|
49868
50205
|
continue;
|
|
49869
50206
|
}
|
|
@@ -49872,20 +50209,50 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
49872
50209
|
return filtered;
|
|
49873
50210
|
}
|
|
49874
50211
|
/**
|
|
49875
|
-
*
|
|
50212
|
+
* Check if a message is schema-related (IMPORTANT, CRITICAL, etc.)
|
|
49876
50213
|
* @private
|
|
49877
50214
|
*/
|
|
49878
|
-
|
|
50215
|
+
_isSchemaMessage(message) {
|
|
49879
50216
|
if (message.role !== "user") {
|
|
49880
50217
|
return false;
|
|
49881
50218
|
}
|
|
49882
50219
|
if (!message.content) {
|
|
49883
50220
|
return false;
|
|
49884
50221
|
}
|
|
49885
|
-
|
|
49886
|
-
|
|
50222
|
+
let content;
|
|
50223
|
+
try {
|
|
50224
|
+
content = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
|
|
50225
|
+
} catch (error) {
|
|
50226
|
+
if (this.debug) {
|
|
50227
|
+
console.log(`[DEBUG] Could not stringify message content in _isSchemaMessage: ${error.message}`);
|
|
50228
|
+
}
|
|
50229
|
+
return false;
|
|
50230
|
+
}
|
|
50231
|
+
if (content.includes("IMPORTANT: A schema was provided") || content.includes("You MUST respond with data that matches this schema") || content.includes("Your response must conform to this schema:") || content.includes("CRITICAL: You MUST respond with ONLY valid JSON DATA") || content.includes("Schema to follow (this is just the structure")) {
|
|
49887
50232
|
return true;
|
|
49888
50233
|
}
|
|
50234
|
+
return false;
|
|
50235
|
+
}
|
|
50236
|
+
/**
|
|
50237
|
+
* Check if a message is a non-schema internal message (mermaid, tool reminders, JSON corrections)
|
|
50238
|
+
* @private
|
|
50239
|
+
*/
|
|
50240
|
+
_isNonSchemaInternalMessage(message) {
|
|
50241
|
+
if (message.role !== "user") {
|
|
50242
|
+
return false;
|
|
50243
|
+
}
|
|
50244
|
+
if (!message.content) {
|
|
50245
|
+
return false;
|
|
50246
|
+
}
|
|
50247
|
+
let content;
|
|
50248
|
+
try {
|
|
50249
|
+
content = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
|
|
50250
|
+
} catch (error) {
|
|
50251
|
+
if (this.debug) {
|
|
50252
|
+
console.log(`[DEBUG] Could not stringify message content in _isNonSchemaInternalMessage: ${error.message}`);
|
|
50253
|
+
}
|
|
50254
|
+
return false;
|
|
50255
|
+
}
|
|
49889
50256
|
if (content.includes("Please use one of the available tools") && content.includes("or use attempt_completion") && content.includes("Remember: Use proper XML format")) {
|
|
49890
50257
|
return true;
|
|
49891
50258
|
}
|