@probelabs/probe 0.6.0-rc162 → 0.6.0-rc164
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 -26
- package/build/agent/index.js +57 -22
- package/build/agent/schemaUtils.js +68 -0
- package/cjs/agent/ProbeAgent.cjs +57 -22
- package/cjs/index.cjs +57 -22
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +12 -26
- package/src/agent/schemaUtils.js +68 -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
|
|
@@ -2001,29 +2009,8 @@ When troubleshooting:
|
|
|
2001
2009
|
// Add assistant response and ask for tool usage
|
|
2002
2010
|
currentMessages.push({ role: 'assistant', content: assistantResponseContent });
|
|
2003
2011
|
|
|
2004
|
-
//
|
|
2005
|
-
|
|
2006
|
-
if (options.schema) { // Apply for ANY schema, not just JSON schemas
|
|
2007
|
-
// When schema is provided, AI must use attempt_completion to trigger schema formatting
|
|
2008
|
-
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
|
-
|
|
2010
|
-
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
2011
|
-
|
|
2012
|
-
<tool_name>
|
|
2013
|
-
<parameter>value</parameter>
|
|
2014
|
-
</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.`;
|
|
2024
|
-
} else {
|
|
2025
|
-
// Standard reminder without schema
|
|
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.
|
|
2012
|
+
// Standard reminder - schema was already provided in initial message
|
|
2013
|
+
const 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.
|
|
2027
2014
|
|
|
2028
2015
|
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
2029
2016
|
|
|
@@ -2035,7 +2022,6 @@ Or for quick completion if your previous response was already correct and comple
|
|
|
2035
2022
|
<attempt_complete>
|
|
2036
2023
|
|
|
2037
2024
|
IMPORTANT: When using <attempt_complete>, this must be the ONLY content in your response. No additional text, explanations, or other content should be included. This tag signals to reuse your previous response as the final answer.`;
|
|
2038
|
-
}
|
|
2039
2025
|
|
|
2040
2026
|
currentMessages.push({
|
|
2041
2027
|
role: 'user',
|
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,54 @@ __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
|
+
} catch (e) {
|
|
54319
|
+
if (debug) {
|
|
54320
|
+
console.error("[DEBUG] generateSchemaInstructions: Failed to parse schema:", e.message);
|
|
54321
|
+
}
|
|
54322
|
+
instructions += `${schema}
|
|
54323
|
+
|
|
54324
|
+
`;
|
|
54325
|
+
}
|
|
54326
|
+
instructions += "Your response inside attempt_completion 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.";
|
|
54327
|
+
return instructions;
|
|
54328
|
+
}
|
|
54279
54329
|
function enforceNoAdditionalProperties(schema) {
|
|
54280
54330
|
if (!schema || typeof schema !== "object") {
|
|
54281
54331
|
return schema;
|
|
@@ -58305,9 +58355,14 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
58305
58355
|
});
|
|
58306
58356
|
const systemMessage = await this.getSystemMessage();
|
|
58307
58357
|
let userMessage = { role: "user", content: message.trim() };
|
|
58358
|
+
if (options.schema && !options._schemaFormatted) {
|
|
58359
|
+
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
58360
|
+
userMessage.content = message.trim() + schemaInstructions;
|
|
58361
|
+
}
|
|
58308
58362
|
if (images && images.length > 0) {
|
|
58363
|
+
const textContent = userMessage.content;
|
|
58309
58364
|
userMessage.content = [
|
|
58310
|
-
{ type: "text", text:
|
|
58365
|
+
{ type: "text", text: textContent },
|
|
58311
58366
|
...images.map((image) => ({
|
|
58312
58367
|
type: "image",
|
|
58313
58368
|
image
|
|
@@ -58727,26 +58782,7 @@ Error: Unknown tool '${toolName}'. Available tools: ${allAvailableTools.join(",
|
|
|
58727
58782
|
break;
|
|
58728
58783
|
}
|
|
58729
58784
|
currentMessages.push({ role: "assistant", content: assistantResponseContent });
|
|
58730
|
-
|
|
58731
|
-
if (options.schema) {
|
|
58732
|
-
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.
|
|
58733
|
-
|
|
58734
|
-
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
58735
|
-
|
|
58736
|
-
<tool_name>
|
|
58737
|
-
<parameter>value</parameter>
|
|
58738
|
-
</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.`;
|
|
58748
|
-
} else {
|
|
58749
|
-
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.
|
|
58785
|
+
const 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
58786
|
|
|
58751
58787
|
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
58752
58788
|
|
|
@@ -58758,7 +58794,6 @@ Or for quick completion if your previous response was already correct and comple
|
|
|
58758
58794
|
<attempt_complete>
|
|
58759
58795
|
|
|
58760
58796
|
IMPORTANT: When using <attempt_complete>, this must be the ONLY content in your response. No additional text, explanations, or other content should be included. This tag signals to reuse your previous response as the final answer.`;
|
|
58761
|
-
}
|
|
58762
58797
|
currentMessages.push({
|
|
58763
58798
|
role: "user",
|
|
58764
58799
|
content: reminderContent
|
|
@@ -7,6 +7,74 @@ 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
|
+
} catch (e) {
|
|
67
|
+
if (debug) {
|
|
68
|
+
console.error('[DEBUG] generateSchemaInstructions: Failed to parse schema:', e.message);
|
|
69
|
+
}
|
|
70
|
+
instructions += `${schema}\n\n`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
instructions += 'Your response inside attempt_completion 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.';
|
|
74
|
+
|
|
75
|
+
return instructions;
|
|
76
|
+
}
|
|
77
|
+
|
|
10
78
|
/**
|
|
11
79
|
* Recursively apply additionalProperties: false to all object schemas
|
|
12
80
|
* 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,54 @@ __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
|
+
} catch (e3) {
|
|
79999
|
+
if (debug) {
|
|
80000
|
+
console.error("[DEBUG] generateSchemaInstructions: Failed to parse schema:", e3.message);
|
|
80001
|
+
}
|
|
80002
|
+
instructions += `${schema}
|
|
80003
|
+
|
|
80004
|
+
`;
|
|
80005
|
+
}
|
|
80006
|
+
instructions += "Your response inside attempt_completion 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.";
|
|
80007
|
+
return instructions;
|
|
80008
|
+
}
|
|
79959
80009
|
function enforceNoAdditionalProperties(schema) {
|
|
79960
80010
|
if (!schema || typeof schema !== "object") {
|
|
79961
80011
|
return schema;
|
|
@@ -83985,9 +84035,14 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
83985
84035
|
});
|
|
83986
84036
|
const systemMessage = await this.getSystemMessage();
|
|
83987
84037
|
let userMessage = { role: "user", content: message.trim() };
|
|
84038
|
+
if (options.schema && !options._schemaFormatted) {
|
|
84039
|
+
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
84040
|
+
userMessage.content = message.trim() + schemaInstructions;
|
|
84041
|
+
}
|
|
83988
84042
|
if (images && images.length > 0) {
|
|
84043
|
+
const textContent = userMessage.content;
|
|
83989
84044
|
userMessage.content = [
|
|
83990
|
-
{ type: "text", text:
|
|
84045
|
+
{ type: "text", text: textContent },
|
|
83991
84046
|
...images.map((image) => ({
|
|
83992
84047
|
type: "image",
|
|
83993
84048
|
image
|
|
@@ -84407,26 +84462,7 @@ Error: Unknown tool '${toolName}'. Available tools: ${allAvailableTools.join(",
|
|
|
84407
84462
|
break;
|
|
84408
84463
|
}
|
|
84409
84464
|
currentMessages.push({ role: "assistant", content: assistantResponseContent });
|
|
84410
|
-
|
|
84411
|
-
if (options.schema) {
|
|
84412
|
-
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.
|
|
84413
|
-
|
|
84414
|
-
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
84415
|
-
|
|
84416
|
-
<tool_name>
|
|
84417
|
-
<parameter>value</parameter>
|
|
84418
|
-
</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.`;
|
|
84428
|
-
} else {
|
|
84429
|
-
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.
|
|
84465
|
+
const 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
84466
|
|
|
84431
84467
|
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
84432
84468
|
|
|
@@ -84438,7 +84474,6 @@ Or for quick completion if your previous response was already correct and comple
|
|
|
84438
84474
|
<attempt_complete>
|
|
84439
84475
|
|
|
84440
84476
|
IMPORTANT: When using <attempt_complete>, this must be the ONLY content in your response. No additional text, explanations, or other content should be included. This tag signals to reuse your previous response as the final answer.`;
|
|
84441
|
-
}
|
|
84442
84477
|
currentMessages.push({
|
|
84443
84478
|
role: "user",
|
|
84444
84479
|
content: reminderContent
|
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,54 @@ __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
|
+
} catch (e3) {
|
|
77741
|
+
if (debug) {
|
|
77742
|
+
console.error("[DEBUG] generateSchemaInstructions: Failed to parse schema:", e3.message);
|
|
77743
|
+
}
|
|
77744
|
+
instructions += `${schema}
|
|
77745
|
+
|
|
77746
|
+
`;
|
|
77747
|
+
}
|
|
77748
|
+
instructions += "Your response inside attempt_completion 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.";
|
|
77749
|
+
return instructions;
|
|
77750
|
+
}
|
|
77701
77751
|
function enforceNoAdditionalProperties(schema) {
|
|
77702
77752
|
if (!schema || typeof schema !== "object") {
|
|
77703
77753
|
return schema;
|
|
@@ -81727,9 +81777,14 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
81727
81777
|
});
|
|
81728
81778
|
const systemMessage = await this.getSystemMessage();
|
|
81729
81779
|
let userMessage = { role: "user", content: message.trim() };
|
|
81780
|
+
if (options.schema && !options._schemaFormatted) {
|
|
81781
|
+
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
81782
|
+
userMessage.content = message.trim() + schemaInstructions;
|
|
81783
|
+
}
|
|
81730
81784
|
if (images && images.length > 0) {
|
|
81785
|
+
const textContent = userMessage.content;
|
|
81731
81786
|
userMessage.content = [
|
|
81732
|
-
{ type: "text", text:
|
|
81787
|
+
{ type: "text", text: textContent },
|
|
81733
81788
|
...images.map((image) => ({
|
|
81734
81789
|
type: "image",
|
|
81735
81790
|
image
|
|
@@ -82149,26 +82204,7 @@ Error: Unknown tool '${toolName}'. Available tools: ${allAvailableTools.join(",
|
|
|
82149
82204
|
break;
|
|
82150
82205
|
}
|
|
82151
82206
|
currentMessages.push({ role: "assistant", content: assistantResponseContent });
|
|
82152
|
-
|
|
82153
|
-
if (options.schema) {
|
|
82154
|
-
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.
|
|
82155
|
-
|
|
82156
|
-
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
82157
|
-
|
|
82158
|
-
<tool_name>
|
|
82159
|
-
<parameter>value</parameter>
|
|
82160
|
-
</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.`;
|
|
82170
|
-
} else {
|
|
82171
|
-
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.
|
|
82207
|
+
const 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
82208
|
|
|
82173
82209
|
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
82174
82210
|
|
|
@@ -82180,7 +82216,6 @@ Or for quick completion if your previous response was already correct and comple
|
|
|
82180
82216
|
<attempt_complete>
|
|
82181
82217
|
|
|
82182
82218
|
IMPORTANT: When using <attempt_complete>, this must be the ONLY content in your response. No additional text, explanations, or other content should be included. This tag signals to reuse your previous response as the final answer.`;
|
|
82183
|
-
}
|
|
82184
82219
|
currentMessages.push({
|
|
82185
82220
|
role: "user",
|
|
82186
82221
|
content: reminderContent
|
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
|
|
@@ -2001,29 +2009,8 @@ When troubleshooting:
|
|
|
2001
2009
|
// Add assistant response and ask for tool usage
|
|
2002
2010
|
currentMessages.push({ role: 'assistant', content: assistantResponseContent });
|
|
2003
2011
|
|
|
2004
|
-
//
|
|
2005
|
-
|
|
2006
|
-
if (options.schema) { // Apply for ANY schema, not just JSON schemas
|
|
2007
|
-
// When schema is provided, AI must use attempt_completion to trigger schema formatting
|
|
2008
|
-
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
|
-
|
|
2010
|
-
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
2011
|
-
|
|
2012
|
-
<tool_name>
|
|
2013
|
-
<parameter>value</parameter>
|
|
2014
|
-
</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.`;
|
|
2024
|
-
} else {
|
|
2025
|
-
// Standard reminder without schema
|
|
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.
|
|
2012
|
+
// Standard reminder - schema was already provided in initial message
|
|
2013
|
+
const 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.
|
|
2027
2014
|
|
|
2028
2015
|
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
2029
2016
|
|
|
@@ -2035,7 +2022,6 @@ Or for quick completion if your previous response was already correct and comple
|
|
|
2035
2022
|
<attempt_complete>
|
|
2036
2023
|
|
|
2037
2024
|
IMPORTANT: When using <attempt_complete>, this must be the ONLY content in your response. No additional text, explanations, or other content should be included. This tag signals to reuse your previous response as the final answer.`;
|
|
2038
|
-
}
|
|
2039
2025
|
|
|
2040
2026
|
currentMessages.push({
|
|
2041
2027
|
role: 'user',
|
package/src/agent/schemaUtils.js
CHANGED
|
@@ -7,6 +7,74 @@ 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
|
+
} catch (e) {
|
|
67
|
+
if (debug) {
|
|
68
|
+
console.error('[DEBUG] generateSchemaInstructions: Failed to parse schema:', e.message);
|
|
69
|
+
}
|
|
70
|
+
instructions += `${schema}\n\n`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
instructions += 'Your response inside attempt_completion 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.';
|
|
74
|
+
|
|
75
|
+
return instructions;
|
|
76
|
+
}
|
|
77
|
+
|
|
10
78
|
/**
|
|
11
79
|
* Recursively apply additionalProperties: false to all object schemas
|
|
12
80
|
* This ensures strict validation at all nesting levels
|