@probelabs/probe 0.6.0-rc162 → 0.6.0-rc163
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/agent/ProbeAgent.js +12 -12
- package/build/agent/index.js +66 -10
- package/build/agent/schemaUtils.js +74 -0
- package/cjs/agent/ProbeAgent.cjs +66 -10
- package/cjs/index.cjs +66 -10
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +12 -12
- package/src/agent/schemaUtils.js +74 -0
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
isJsonSchema,
|
|
49
49
|
validateJsonResponse,
|
|
50
50
|
createJsonCorrectionPrompt,
|
|
51
|
+
generateSchemaInstructions,
|
|
51
52
|
isJsonSchemaDefinition,
|
|
52
53
|
createSchemaDefinitionCorrectionPrompt,
|
|
53
54
|
validateAndFixMermaidResponse
|
|
@@ -1455,11 +1456,18 @@ When troubleshooting:
|
|
|
1455
1456
|
|
|
1456
1457
|
// Create user message with optional image support
|
|
1457
1458
|
let userMessage = { role: 'user', content: message.trim() };
|
|
1458
|
-
|
|
1459
|
+
|
|
1460
|
+
// If schema is provided, prepend JSON format requirement to user message
|
|
1461
|
+
if (options.schema && !options._schemaFormatted) {
|
|
1462
|
+
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
1463
|
+
userMessage.content = message.trim() + schemaInstructions;
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1459
1466
|
// If images are provided, use multi-modal message format
|
|
1460
1467
|
if (images && images.length > 0) {
|
|
1468
|
+
const textContent = userMessage.content;
|
|
1461
1469
|
userMessage.content = [
|
|
1462
|
-
{ type: 'text', text:
|
|
1470
|
+
{ type: 'text', text: textContent },
|
|
1463
1471
|
...images.map(image => ({
|
|
1464
1472
|
type: 'image',
|
|
1465
1473
|
image: image
|
|
@@ -2004,7 +2012,7 @@ When troubleshooting:
|
|
|
2004
2012
|
// Build appropriate reminder message based on whether schema is provided
|
|
2005
2013
|
let reminderContent;
|
|
2006
2014
|
if (options.schema) { // Apply for ANY schema, not just JSON schemas
|
|
2007
|
-
// When schema is provided,
|
|
2015
|
+
// When schema is provided, use the same instructions as initial message
|
|
2008
2016
|
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.
|
|
2009
2017
|
|
|
2010
2018
|
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
@@ -2012,15 +2020,7 @@ Remember: Use proper XML format with BOTH opening and closing tags:
|
|
|
2012
2020
|
<tool_name>
|
|
2013
2021
|
<parameter>value</parameter>
|
|
2014
2022
|
</tool_name>
|
|
2015
|
-
|
|
2016
|
-
IMPORTANT: A schema was provided for the final output format.
|
|
2017
|
-
|
|
2018
|
-
You MUST use attempt_completion to provide your answer:
|
|
2019
|
-
<attempt_completion>
|
|
2020
|
-
[Your complete answer here - provide in natural language, it will be automatically formatted to match the schema]
|
|
2021
|
-
</attempt_completion>
|
|
2022
|
-
|
|
2023
|
-
Your response will be automatically formatted to JSON. You can provide your answer in natural language or as JSON - either will work.`;
|
|
2023
|
+
` + generateSchemaInstructions(options.schema, { debug: this.debug }).trim();
|
|
2024
2024
|
} else {
|
|
2025
2025
|
// Standard reminder without schema
|
|
2026
2026
|
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.
|
package/build/agent/index.js
CHANGED
|
@@ -54264,6 +54264,8 @@ __export(schemaUtils_exports, {
|
|
|
54264
54264
|
createSchemaDefinitionCorrectionPrompt: () => createSchemaDefinitionCorrectionPrompt,
|
|
54265
54265
|
decodeHtmlEntities: () => decodeHtmlEntities,
|
|
54266
54266
|
extractMermaidFromMarkdown: () => extractMermaidFromMarkdown,
|
|
54267
|
+
generateExampleFromSchema: () => generateExampleFromSchema,
|
|
54268
|
+
generateSchemaInstructions: () => generateSchemaInstructions,
|
|
54267
54269
|
isJsonSchema: () => isJsonSchema,
|
|
54268
54270
|
isJsonSchemaDefinition: () => isJsonSchemaDefinition,
|
|
54269
54271
|
isMermaidSchema: () => isMermaidSchema,
|
|
@@ -54276,6 +54278,63 @@ __export(schemaUtils_exports, {
|
|
|
54276
54278
|
validateMermaidResponse: () => validateMermaidResponse,
|
|
54277
54279
|
validateXmlResponse: () => validateXmlResponse
|
|
54278
54280
|
});
|
|
54281
|
+
function generateExampleFromSchema(schema, options = {}) {
|
|
54282
|
+
const { debug = false } = options;
|
|
54283
|
+
try {
|
|
54284
|
+
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
54285
|
+
if (parsedSchema.type !== "object" || !parsedSchema.properties) {
|
|
54286
|
+
return null;
|
|
54287
|
+
}
|
|
54288
|
+
const exampleObj = {};
|
|
54289
|
+
for (const [key, value] of Object.entries(parsedSchema.properties)) {
|
|
54290
|
+
if (value.type === "boolean") {
|
|
54291
|
+
exampleObj[key] = false;
|
|
54292
|
+
} else if (value.type === "number") {
|
|
54293
|
+
exampleObj[key] = 0;
|
|
54294
|
+
} else if (value.type === "string") {
|
|
54295
|
+
exampleObj[key] = value.description || "your answer here";
|
|
54296
|
+
} else if (value.type === "array") {
|
|
54297
|
+
exampleObj[key] = [];
|
|
54298
|
+
} else {
|
|
54299
|
+
exampleObj[key] = {};
|
|
54300
|
+
}
|
|
54301
|
+
}
|
|
54302
|
+
return exampleObj;
|
|
54303
|
+
} catch (e) {
|
|
54304
|
+
if (debug) {
|
|
54305
|
+
console.error("[DEBUG] generateExampleFromSchema: Failed to parse schema:", e.message);
|
|
54306
|
+
}
|
|
54307
|
+
return null;
|
|
54308
|
+
}
|
|
54309
|
+
}
|
|
54310
|
+
function generateSchemaInstructions(schema, options = {}) {
|
|
54311
|
+
const { debug = false } = options;
|
|
54312
|
+
let instructions = "\n\nIMPORTANT: When you provide your final answer using attempt_completion, you MUST format it as valid JSON matching this schema:\n\n";
|
|
54313
|
+
try {
|
|
54314
|
+
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
54315
|
+
instructions += `${JSON.stringify(parsedSchema, null, 2)}
|
|
54316
|
+
|
|
54317
|
+
`;
|
|
54318
|
+
const exampleObj = generateExampleFromSchema(parsedSchema, { debug });
|
|
54319
|
+
if (exampleObj) {
|
|
54320
|
+
instructions += `Example:
|
|
54321
|
+
<attempt_completion>
|
|
54322
|
+
${JSON.stringify(exampleObj, null, 2)}
|
|
54323
|
+
</attempt_completion>
|
|
54324
|
+
|
|
54325
|
+
`;
|
|
54326
|
+
}
|
|
54327
|
+
} catch (e) {
|
|
54328
|
+
if (debug) {
|
|
54329
|
+
console.error("[DEBUG] generateSchemaInstructions: Failed to parse schema:", e.message);
|
|
54330
|
+
}
|
|
54331
|
+
instructions += `${schema}
|
|
54332
|
+
|
|
54333
|
+
`;
|
|
54334
|
+
}
|
|
54335
|
+
instructions += "Your response inside attempt_completion must be ONLY valid JSON - no plain text, no explanations, no markdown.";
|
|
54336
|
+
return instructions;
|
|
54337
|
+
}
|
|
54279
54338
|
function enforceNoAdditionalProperties(schema) {
|
|
54280
54339
|
if (!schema || typeof schema !== "object") {
|
|
54281
54340
|
return schema;
|
|
@@ -58305,9 +58364,14 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
58305
58364
|
});
|
|
58306
58365
|
const systemMessage = await this.getSystemMessage();
|
|
58307
58366
|
let userMessage = { role: "user", content: message.trim() };
|
|
58367
|
+
if (options.schema && !options._schemaFormatted) {
|
|
58368
|
+
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
58369
|
+
userMessage.content = message.trim() + schemaInstructions;
|
|
58370
|
+
}
|
|
58308
58371
|
if (images && images.length > 0) {
|
|
58372
|
+
const textContent = userMessage.content;
|
|
58309
58373
|
userMessage.content = [
|
|
58310
|
-
{ type: "text", text:
|
|
58374
|
+
{ type: "text", text: textContent },
|
|
58311
58375
|
...images.map((image) => ({
|
|
58312
58376
|
type: "image",
|
|
58313
58377
|
image
|
|
@@ -58736,15 +58800,7 @@ Remember: Use proper XML format with BOTH opening and closing tags:
|
|
|
58736
58800
|
<tool_name>
|
|
58737
58801
|
<parameter>value</parameter>
|
|
58738
58802
|
</tool_name>
|
|
58739
|
-
|
|
58740
|
-
IMPORTANT: A schema was provided for the final output format.
|
|
58741
|
-
|
|
58742
|
-
You MUST use attempt_completion to provide your answer:
|
|
58743
|
-
<attempt_completion>
|
|
58744
|
-
[Your complete answer here - provide in natural language, it will be automatically formatted to match the schema]
|
|
58745
|
-
</attempt_completion>
|
|
58746
|
-
|
|
58747
|
-
Your response will be automatically formatted to JSON. You can provide your answer in natural language or as JSON - either will work.`;
|
|
58803
|
+
` + generateSchemaInstructions(options.schema, { debug: this.debug }).trim();
|
|
58748
58804
|
} else {
|
|
58749
58805
|
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.
|
|
58750
58806
|
|
|
@@ -7,6 +7,80 @@ import { createMessagePreview } from '../tools/common.js';
|
|
|
7
7
|
import { validate, fixText, extractMermaidBlocks } from '@probelabs/maid';
|
|
8
8
|
import Ajv from 'ajv';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Generate an example JSON object from a JSON schema
|
|
12
|
+
* @param {Object|string} schema - JSON schema object or string
|
|
13
|
+
* @param {Object} options - Options for generation
|
|
14
|
+
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
15
|
+
* @returns {Object|null} - Example object, or null if schema cannot be processed
|
|
16
|
+
*/
|
|
17
|
+
export function generateExampleFromSchema(schema, options = {}) {
|
|
18
|
+
const { debug = false } = options;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const parsedSchema = typeof schema === 'string' ? JSON.parse(schema) : schema;
|
|
22
|
+
|
|
23
|
+
if (parsedSchema.type !== 'object' || !parsedSchema.properties) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const exampleObj = {};
|
|
28
|
+
for (const [key, value] of Object.entries(parsedSchema.properties)) {
|
|
29
|
+
if (value.type === 'boolean') {
|
|
30
|
+
exampleObj[key] = false;
|
|
31
|
+
} else if (value.type === 'number') {
|
|
32
|
+
exampleObj[key] = 0;
|
|
33
|
+
} else if (value.type === 'string') {
|
|
34
|
+
exampleObj[key] = value.description || 'your answer here';
|
|
35
|
+
} else if (value.type === 'array') {
|
|
36
|
+
exampleObj[key] = [];
|
|
37
|
+
} else {
|
|
38
|
+
exampleObj[key] = {};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return exampleObj;
|
|
43
|
+
} catch (e) {
|
|
44
|
+
if (debug) {
|
|
45
|
+
console.error('[DEBUG] generateExampleFromSchema: Failed to parse schema:', e.message);
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Generate schema instructions for AI to follow
|
|
53
|
+
* @param {Object|string} schema - JSON schema object or string
|
|
54
|
+
* @param {Object} options - Options for generation
|
|
55
|
+
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
56
|
+
* @returns {string} - Formatted schema instructions
|
|
57
|
+
*/
|
|
58
|
+
export function generateSchemaInstructions(schema, options = {}) {
|
|
59
|
+
const { debug = false } = options;
|
|
60
|
+
|
|
61
|
+
let instructions = '\n\nIMPORTANT: When you provide your final answer using attempt_completion, you MUST format it as valid JSON matching this schema:\n\n';
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const parsedSchema = typeof schema === 'string' ? JSON.parse(schema) : schema;
|
|
65
|
+
instructions += `${JSON.stringify(parsedSchema, null, 2)}\n\n`;
|
|
66
|
+
|
|
67
|
+
// Generate example using helper function
|
|
68
|
+
const exampleObj = generateExampleFromSchema(parsedSchema, { debug });
|
|
69
|
+
if (exampleObj) {
|
|
70
|
+
instructions += `Example:\n<attempt_completion>\n${JSON.stringify(exampleObj, null, 2)}\n</attempt_completion>\n\n`;
|
|
71
|
+
}
|
|
72
|
+
} catch (e) {
|
|
73
|
+
if (debug) {
|
|
74
|
+
console.error('[DEBUG] generateSchemaInstructions: Failed to parse schema:', e.message);
|
|
75
|
+
}
|
|
76
|
+
instructions += `${schema}\n\n`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
instructions += 'Your response inside attempt_completion must be ONLY valid JSON - no plain text, no explanations, no markdown.';
|
|
80
|
+
|
|
81
|
+
return instructions;
|
|
82
|
+
}
|
|
83
|
+
|
|
10
84
|
/**
|
|
11
85
|
* Recursively apply additionalProperties: false to all object schemas
|
|
12
86
|
* This ensures strict validation at all nesting levels
|
package/cjs/agent/ProbeAgent.cjs
CHANGED
|
@@ -79944,6 +79944,8 @@ __export(schemaUtils_exports, {
|
|
|
79944
79944
|
createSchemaDefinitionCorrectionPrompt: () => createSchemaDefinitionCorrectionPrompt,
|
|
79945
79945
|
decodeHtmlEntities: () => decodeHtmlEntities,
|
|
79946
79946
|
extractMermaidFromMarkdown: () => extractMermaidFromMarkdown,
|
|
79947
|
+
generateExampleFromSchema: () => generateExampleFromSchema,
|
|
79948
|
+
generateSchemaInstructions: () => generateSchemaInstructions,
|
|
79947
79949
|
isJsonSchema: () => isJsonSchema,
|
|
79948
79950
|
isJsonSchemaDefinition: () => isJsonSchemaDefinition,
|
|
79949
79951
|
isMermaidSchema: () => isMermaidSchema,
|
|
@@ -79956,6 +79958,63 @@ __export(schemaUtils_exports, {
|
|
|
79956
79958
|
validateMermaidResponse: () => validateMermaidResponse,
|
|
79957
79959
|
validateXmlResponse: () => validateXmlResponse
|
|
79958
79960
|
});
|
|
79961
|
+
function generateExampleFromSchema(schema, options = {}) {
|
|
79962
|
+
const { debug = false } = options;
|
|
79963
|
+
try {
|
|
79964
|
+
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
79965
|
+
if (parsedSchema.type !== "object" || !parsedSchema.properties) {
|
|
79966
|
+
return null;
|
|
79967
|
+
}
|
|
79968
|
+
const exampleObj = {};
|
|
79969
|
+
for (const [key, value] of Object.entries(parsedSchema.properties)) {
|
|
79970
|
+
if (value.type === "boolean") {
|
|
79971
|
+
exampleObj[key] = false;
|
|
79972
|
+
} else if (value.type === "number") {
|
|
79973
|
+
exampleObj[key] = 0;
|
|
79974
|
+
} else if (value.type === "string") {
|
|
79975
|
+
exampleObj[key] = value.description || "your answer here";
|
|
79976
|
+
} else if (value.type === "array") {
|
|
79977
|
+
exampleObj[key] = [];
|
|
79978
|
+
} else {
|
|
79979
|
+
exampleObj[key] = {};
|
|
79980
|
+
}
|
|
79981
|
+
}
|
|
79982
|
+
return exampleObj;
|
|
79983
|
+
} catch (e3) {
|
|
79984
|
+
if (debug) {
|
|
79985
|
+
console.error("[DEBUG] generateExampleFromSchema: Failed to parse schema:", e3.message);
|
|
79986
|
+
}
|
|
79987
|
+
return null;
|
|
79988
|
+
}
|
|
79989
|
+
}
|
|
79990
|
+
function generateSchemaInstructions(schema, options = {}) {
|
|
79991
|
+
const { debug = false } = options;
|
|
79992
|
+
let instructions = "\n\nIMPORTANT: When you provide your final answer using attempt_completion, you MUST format it as valid JSON matching this schema:\n\n";
|
|
79993
|
+
try {
|
|
79994
|
+
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
79995
|
+
instructions += `${JSON.stringify(parsedSchema, null, 2)}
|
|
79996
|
+
|
|
79997
|
+
`;
|
|
79998
|
+
const exampleObj = generateExampleFromSchema(parsedSchema, { debug });
|
|
79999
|
+
if (exampleObj) {
|
|
80000
|
+
instructions += `Example:
|
|
80001
|
+
<attempt_completion>
|
|
80002
|
+
${JSON.stringify(exampleObj, null, 2)}
|
|
80003
|
+
</attempt_completion>
|
|
80004
|
+
|
|
80005
|
+
`;
|
|
80006
|
+
}
|
|
80007
|
+
} catch (e3) {
|
|
80008
|
+
if (debug) {
|
|
80009
|
+
console.error("[DEBUG] generateSchemaInstructions: Failed to parse schema:", e3.message);
|
|
80010
|
+
}
|
|
80011
|
+
instructions += `${schema}
|
|
80012
|
+
|
|
80013
|
+
`;
|
|
80014
|
+
}
|
|
80015
|
+
instructions += "Your response inside attempt_completion must be ONLY valid JSON - no plain text, no explanations, no markdown.";
|
|
80016
|
+
return instructions;
|
|
80017
|
+
}
|
|
79959
80018
|
function enforceNoAdditionalProperties(schema) {
|
|
79960
80019
|
if (!schema || typeof schema !== "object") {
|
|
79961
80020
|
return schema;
|
|
@@ -83985,9 +84044,14 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
83985
84044
|
});
|
|
83986
84045
|
const systemMessage = await this.getSystemMessage();
|
|
83987
84046
|
let userMessage = { role: "user", content: message.trim() };
|
|
84047
|
+
if (options.schema && !options._schemaFormatted) {
|
|
84048
|
+
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
84049
|
+
userMessage.content = message.trim() + schemaInstructions;
|
|
84050
|
+
}
|
|
83988
84051
|
if (images && images.length > 0) {
|
|
84052
|
+
const textContent = userMessage.content;
|
|
83989
84053
|
userMessage.content = [
|
|
83990
|
-
{ type: "text", text:
|
|
84054
|
+
{ type: "text", text: textContent },
|
|
83991
84055
|
...images.map((image) => ({
|
|
83992
84056
|
type: "image",
|
|
83993
84057
|
image
|
|
@@ -84416,15 +84480,7 @@ Remember: Use proper XML format with BOTH opening and closing tags:
|
|
|
84416
84480
|
<tool_name>
|
|
84417
84481
|
<parameter>value</parameter>
|
|
84418
84482
|
</tool_name>
|
|
84419
|
-
|
|
84420
|
-
IMPORTANT: A schema was provided for the final output format.
|
|
84421
|
-
|
|
84422
|
-
You MUST use attempt_completion to provide your answer:
|
|
84423
|
-
<attempt_completion>
|
|
84424
|
-
[Your complete answer here - provide in natural language, it will be automatically formatted to match the schema]
|
|
84425
|
-
</attempt_completion>
|
|
84426
|
-
|
|
84427
|
-
Your response will be automatically formatted to JSON. You can provide your answer in natural language or as JSON - either will work.`;
|
|
84483
|
+
` + generateSchemaInstructions(options.schema, { debug: this.debug }).trim();
|
|
84428
84484
|
} else {
|
|
84429
84485
|
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.
|
|
84430
84486
|
|
package/cjs/index.cjs
CHANGED
|
@@ -77686,6 +77686,8 @@ __export(schemaUtils_exports, {
|
|
|
77686
77686
|
createSchemaDefinitionCorrectionPrompt: () => createSchemaDefinitionCorrectionPrompt,
|
|
77687
77687
|
decodeHtmlEntities: () => decodeHtmlEntities,
|
|
77688
77688
|
extractMermaidFromMarkdown: () => extractMermaidFromMarkdown,
|
|
77689
|
+
generateExampleFromSchema: () => generateExampleFromSchema,
|
|
77690
|
+
generateSchemaInstructions: () => generateSchemaInstructions,
|
|
77689
77691
|
isJsonSchema: () => isJsonSchema,
|
|
77690
77692
|
isJsonSchemaDefinition: () => isJsonSchemaDefinition,
|
|
77691
77693
|
isMermaidSchema: () => isMermaidSchema,
|
|
@@ -77698,6 +77700,63 @@ __export(schemaUtils_exports, {
|
|
|
77698
77700
|
validateMermaidResponse: () => validateMermaidResponse,
|
|
77699
77701
|
validateXmlResponse: () => validateXmlResponse
|
|
77700
77702
|
});
|
|
77703
|
+
function generateExampleFromSchema(schema, options = {}) {
|
|
77704
|
+
const { debug = false } = options;
|
|
77705
|
+
try {
|
|
77706
|
+
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
77707
|
+
if (parsedSchema.type !== "object" || !parsedSchema.properties) {
|
|
77708
|
+
return null;
|
|
77709
|
+
}
|
|
77710
|
+
const exampleObj = {};
|
|
77711
|
+
for (const [key, value] of Object.entries(parsedSchema.properties)) {
|
|
77712
|
+
if (value.type === "boolean") {
|
|
77713
|
+
exampleObj[key] = false;
|
|
77714
|
+
} else if (value.type === "number") {
|
|
77715
|
+
exampleObj[key] = 0;
|
|
77716
|
+
} else if (value.type === "string") {
|
|
77717
|
+
exampleObj[key] = value.description || "your answer here";
|
|
77718
|
+
} else if (value.type === "array") {
|
|
77719
|
+
exampleObj[key] = [];
|
|
77720
|
+
} else {
|
|
77721
|
+
exampleObj[key] = {};
|
|
77722
|
+
}
|
|
77723
|
+
}
|
|
77724
|
+
return exampleObj;
|
|
77725
|
+
} catch (e3) {
|
|
77726
|
+
if (debug) {
|
|
77727
|
+
console.error("[DEBUG] generateExampleFromSchema: Failed to parse schema:", e3.message);
|
|
77728
|
+
}
|
|
77729
|
+
return null;
|
|
77730
|
+
}
|
|
77731
|
+
}
|
|
77732
|
+
function generateSchemaInstructions(schema, options = {}) {
|
|
77733
|
+
const { debug = false } = options;
|
|
77734
|
+
let instructions = "\n\nIMPORTANT: When you provide your final answer using attempt_completion, you MUST format it as valid JSON matching this schema:\n\n";
|
|
77735
|
+
try {
|
|
77736
|
+
const parsedSchema = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
77737
|
+
instructions += `${JSON.stringify(parsedSchema, null, 2)}
|
|
77738
|
+
|
|
77739
|
+
`;
|
|
77740
|
+
const exampleObj = generateExampleFromSchema(parsedSchema, { debug });
|
|
77741
|
+
if (exampleObj) {
|
|
77742
|
+
instructions += `Example:
|
|
77743
|
+
<attempt_completion>
|
|
77744
|
+
${JSON.stringify(exampleObj, null, 2)}
|
|
77745
|
+
</attempt_completion>
|
|
77746
|
+
|
|
77747
|
+
`;
|
|
77748
|
+
}
|
|
77749
|
+
} catch (e3) {
|
|
77750
|
+
if (debug) {
|
|
77751
|
+
console.error("[DEBUG] generateSchemaInstructions: Failed to parse schema:", e3.message);
|
|
77752
|
+
}
|
|
77753
|
+
instructions += `${schema}
|
|
77754
|
+
|
|
77755
|
+
`;
|
|
77756
|
+
}
|
|
77757
|
+
instructions += "Your response inside attempt_completion must be ONLY valid JSON - no plain text, no explanations, no markdown.";
|
|
77758
|
+
return instructions;
|
|
77759
|
+
}
|
|
77701
77760
|
function enforceNoAdditionalProperties(schema) {
|
|
77702
77761
|
if (!schema || typeof schema !== "object") {
|
|
77703
77762
|
return schema;
|
|
@@ -81727,9 +81786,14 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
81727
81786
|
});
|
|
81728
81787
|
const systemMessage = await this.getSystemMessage();
|
|
81729
81788
|
let userMessage = { role: "user", content: message.trim() };
|
|
81789
|
+
if (options.schema && !options._schemaFormatted) {
|
|
81790
|
+
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
81791
|
+
userMessage.content = message.trim() + schemaInstructions;
|
|
81792
|
+
}
|
|
81730
81793
|
if (images && images.length > 0) {
|
|
81794
|
+
const textContent = userMessage.content;
|
|
81731
81795
|
userMessage.content = [
|
|
81732
|
-
{ type: "text", text:
|
|
81796
|
+
{ type: "text", text: textContent },
|
|
81733
81797
|
...images.map((image) => ({
|
|
81734
81798
|
type: "image",
|
|
81735
81799
|
image
|
|
@@ -82158,15 +82222,7 @@ Remember: Use proper XML format with BOTH opening and closing tags:
|
|
|
82158
82222
|
<tool_name>
|
|
82159
82223
|
<parameter>value</parameter>
|
|
82160
82224
|
</tool_name>
|
|
82161
|
-
|
|
82162
|
-
IMPORTANT: A schema was provided for the final output format.
|
|
82163
|
-
|
|
82164
|
-
You MUST use attempt_completion to provide your answer:
|
|
82165
|
-
<attempt_completion>
|
|
82166
|
-
[Your complete answer here - provide in natural language, it will be automatically formatted to match the schema]
|
|
82167
|
-
</attempt_completion>
|
|
82168
|
-
|
|
82169
|
-
Your response will be automatically formatted to JSON. You can provide your answer in natural language or as JSON - either will work.`;
|
|
82225
|
+
` + generateSchemaInstructions(options.schema, { debug: this.debug }).trim();
|
|
82170
82226
|
} else {
|
|
82171
82227
|
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.
|
|
82172
82228
|
|
package/package.json
CHANGED
package/src/agent/ProbeAgent.js
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
isJsonSchema,
|
|
49
49
|
validateJsonResponse,
|
|
50
50
|
createJsonCorrectionPrompt,
|
|
51
|
+
generateSchemaInstructions,
|
|
51
52
|
isJsonSchemaDefinition,
|
|
52
53
|
createSchemaDefinitionCorrectionPrompt,
|
|
53
54
|
validateAndFixMermaidResponse
|
|
@@ -1455,11 +1456,18 @@ When troubleshooting:
|
|
|
1455
1456
|
|
|
1456
1457
|
// Create user message with optional image support
|
|
1457
1458
|
let userMessage = { role: 'user', content: message.trim() };
|
|
1458
|
-
|
|
1459
|
+
|
|
1460
|
+
// If schema is provided, prepend JSON format requirement to user message
|
|
1461
|
+
if (options.schema && !options._schemaFormatted) {
|
|
1462
|
+
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
1463
|
+
userMessage.content = message.trim() + schemaInstructions;
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1459
1466
|
// If images are provided, use multi-modal message format
|
|
1460
1467
|
if (images && images.length > 0) {
|
|
1468
|
+
const textContent = userMessage.content;
|
|
1461
1469
|
userMessage.content = [
|
|
1462
|
-
{ type: 'text', text:
|
|
1470
|
+
{ type: 'text', text: textContent },
|
|
1463
1471
|
...images.map(image => ({
|
|
1464
1472
|
type: 'image',
|
|
1465
1473
|
image: image
|
|
@@ -2004,7 +2012,7 @@ When troubleshooting:
|
|
|
2004
2012
|
// Build appropriate reminder message based on whether schema is provided
|
|
2005
2013
|
let reminderContent;
|
|
2006
2014
|
if (options.schema) { // Apply for ANY schema, not just JSON schemas
|
|
2007
|
-
// When schema is provided,
|
|
2015
|
+
// When schema is provided, use the same instructions as initial message
|
|
2008
2016
|
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.
|
|
2009
2017
|
|
|
2010
2018
|
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
@@ -2012,15 +2020,7 @@ Remember: Use proper XML format with BOTH opening and closing tags:
|
|
|
2012
2020
|
<tool_name>
|
|
2013
2021
|
<parameter>value</parameter>
|
|
2014
2022
|
</tool_name>
|
|
2015
|
-
|
|
2016
|
-
IMPORTANT: A schema was provided for the final output format.
|
|
2017
|
-
|
|
2018
|
-
You MUST use attempt_completion to provide your answer:
|
|
2019
|
-
<attempt_completion>
|
|
2020
|
-
[Your complete answer here - provide in natural language, it will be automatically formatted to match the schema]
|
|
2021
|
-
</attempt_completion>
|
|
2022
|
-
|
|
2023
|
-
Your response will be automatically formatted to JSON. You can provide your answer in natural language or as JSON - either will work.`;
|
|
2023
|
+
` + generateSchemaInstructions(options.schema, { debug: this.debug }).trim();
|
|
2024
2024
|
} else {
|
|
2025
2025
|
// Standard reminder without schema
|
|
2026
2026
|
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.
|
package/src/agent/schemaUtils.js
CHANGED
|
@@ -7,6 +7,80 @@ import { createMessagePreview } from '../tools/common.js';
|
|
|
7
7
|
import { validate, fixText, extractMermaidBlocks } from '@probelabs/maid';
|
|
8
8
|
import Ajv from 'ajv';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Generate an example JSON object from a JSON schema
|
|
12
|
+
* @param {Object|string} schema - JSON schema object or string
|
|
13
|
+
* @param {Object} options - Options for generation
|
|
14
|
+
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
15
|
+
* @returns {Object|null} - Example object, or null if schema cannot be processed
|
|
16
|
+
*/
|
|
17
|
+
export function generateExampleFromSchema(schema, options = {}) {
|
|
18
|
+
const { debug = false } = options;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const parsedSchema = typeof schema === 'string' ? JSON.parse(schema) : schema;
|
|
22
|
+
|
|
23
|
+
if (parsedSchema.type !== 'object' || !parsedSchema.properties) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const exampleObj = {};
|
|
28
|
+
for (const [key, value] of Object.entries(parsedSchema.properties)) {
|
|
29
|
+
if (value.type === 'boolean') {
|
|
30
|
+
exampleObj[key] = false;
|
|
31
|
+
} else if (value.type === 'number') {
|
|
32
|
+
exampleObj[key] = 0;
|
|
33
|
+
} else if (value.type === 'string') {
|
|
34
|
+
exampleObj[key] = value.description || 'your answer here';
|
|
35
|
+
} else if (value.type === 'array') {
|
|
36
|
+
exampleObj[key] = [];
|
|
37
|
+
} else {
|
|
38
|
+
exampleObj[key] = {};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return exampleObj;
|
|
43
|
+
} catch (e) {
|
|
44
|
+
if (debug) {
|
|
45
|
+
console.error('[DEBUG] generateExampleFromSchema: Failed to parse schema:', e.message);
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Generate schema instructions for AI to follow
|
|
53
|
+
* @param {Object|string} schema - JSON schema object or string
|
|
54
|
+
* @param {Object} options - Options for generation
|
|
55
|
+
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
56
|
+
* @returns {string} - Formatted schema instructions
|
|
57
|
+
*/
|
|
58
|
+
export function generateSchemaInstructions(schema, options = {}) {
|
|
59
|
+
const { debug = false } = options;
|
|
60
|
+
|
|
61
|
+
let instructions = '\n\nIMPORTANT: When you provide your final answer using attempt_completion, you MUST format it as valid JSON matching this schema:\n\n';
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const parsedSchema = typeof schema === 'string' ? JSON.parse(schema) : schema;
|
|
65
|
+
instructions += `${JSON.stringify(parsedSchema, null, 2)}\n\n`;
|
|
66
|
+
|
|
67
|
+
// Generate example using helper function
|
|
68
|
+
const exampleObj = generateExampleFromSchema(parsedSchema, { debug });
|
|
69
|
+
if (exampleObj) {
|
|
70
|
+
instructions += `Example:\n<attempt_completion>\n${JSON.stringify(exampleObj, null, 2)}\n</attempt_completion>\n\n`;
|
|
71
|
+
}
|
|
72
|
+
} catch (e) {
|
|
73
|
+
if (debug) {
|
|
74
|
+
console.error('[DEBUG] generateSchemaInstructions: Failed to parse schema:', e.message);
|
|
75
|
+
}
|
|
76
|
+
instructions += `${schema}\n\n`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
instructions += 'Your response inside attempt_completion must be ONLY valid JSON - no plain text, no explanations, no markdown.';
|
|
80
|
+
|
|
81
|
+
return instructions;
|
|
82
|
+
}
|
|
83
|
+
|
|
10
84
|
/**
|
|
11
85
|
* Recursively apply additionalProperties: false to all object schemas
|
|
12
86
|
* This ensures strict validation at all nesting levels
|