@probelabs/probe 0.6.0-rc284 → 0.6.0-rc285
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/binaries/{probe-v0.6.0-rc284-aarch64-apple-darwin.tar.gz → probe-v0.6.0-rc285-aarch64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/probe-v0.6.0-rc285-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc285-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc285-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc285-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.d.ts +1 -1
- package/build/agent/ProbeAgent.js +333 -486
- package/build/agent/contextCompactor.js +17 -10
- package/build/agent/index.js +301 -702
- package/build/agent/schemaUtils.js +10 -11
- package/build/agent/shared/prompts.js +2 -2
- package/build/agent/tasks/taskTool.js +3 -3
- package/build/agent/tools.js +0 -2
- package/build/index.js +0 -2
- package/build/tools/analyzeAll.js +4 -4
- package/build/tools/common.js +55 -55
- package/build/tools/index.js +0 -1
- package/build/tools/vercel.js +3 -3
- package/cjs/agent/ProbeAgent.cjs +292 -758
- package/cjs/index.cjs +293 -814
- package/package.json +1 -1
- package/src/agent/ProbeAgent.d.ts +1 -1
- package/src/agent/ProbeAgent.js +333 -486
- package/src/agent/contextCompactor.js +17 -10
- package/src/agent/index.js +8 -2
- package/src/agent/schemaUtils.js +10 -11
- package/src/agent/shared/prompts.js +2 -2
- package/src/agent/tasks/taskTool.js +3 -3
- package/src/agent/tools.js +0 -2
- package/src/index.js +0 -2
- package/src/tools/analyzeAll.js +4 -4
- package/src/tools/common.js +55 -55
- package/src/tools/index.js +0 -1
- package/src/tools/vercel.js +3 -3
- package/bin/binaries/probe-v0.6.0-rc284-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc284-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc284-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc284-x86_64-unknown-linux-musl.tar.gz +0 -0
|
@@ -58,7 +58,7 @@ export function generateExampleFromSchema(schema, options = {}) {
|
|
|
58
58
|
export function generateSchemaInstructions(schema, options = {}) {
|
|
59
59
|
const { debug = false } = options;
|
|
60
60
|
|
|
61
|
-
let instructions = '\n\nIMPORTANT: When you provide your final answer
|
|
61
|
+
let instructions = '\n\nIMPORTANT: When you provide your final answer, you MUST format it as valid JSON matching this schema:\n\n';
|
|
62
62
|
|
|
63
63
|
try {
|
|
64
64
|
const parsedSchema = typeof schema === 'string' ? JSON.parse(schema) : schema;
|
|
@@ -70,7 +70,7 @@ export function generateSchemaInstructions(schema, options = {}) {
|
|
|
70
70
|
instructions += `${schema}\n\n`;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
instructions += 'Your response
|
|
73
|
+
instructions += 'Your final response must be ONLY valid JSON - no plain text, no explanations, no markdown.\n\nIMPORTANT: First complete the requested analysis/task thoroughly, then provide your final answer in the JSON format above.';
|
|
74
74
|
|
|
75
75
|
return instructions;
|
|
76
76
|
}
|
|
@@ -1167,22 +1167,22 @@ export function createJsonCorrectionPrompt(invalidResponse, schema, errorOrValid
|
|
|
1167
1167
|
}
|
|
1168
1168
|
|
|
1169
1169
|
// Create increasingly stronger prompts based on retry attempt
|
|
1170
|
-
// These prompts
|
|
1170
|
+
// These prompts instruct the AI to respond with valid JSON
|
|
1171
1171
|
const strengthLevels = [
|
|
1172
1172
|
{
|
|
1173
1173
|
prefix: "CRITICAL JSON ERROR:",
|
|
1174
|
-
instruction: "You MUST fix this and respond
|
|
1175
|
-
emphasis: "
|
|
1174
|
+
instruction: "You MUST fix this and respond with ONLY valid JSON.",
|
|
1175
|
+
emphasis: "Respond with ONLY the corrected JSON. No explanatory text, no markdown, no code blocks."
|
|
1176
1176
|
},
|
|
1177
1177
|
{
|
|
1178
1178
|
prefix: "URGENT - JSON PARSING FAILED:",
|
|
1179
|
-
instruction: "This is your second chance.
|
|
1180
|
-
emphasis: "ABSOLUTELY NO explanatory text or formatting.
|
|
1179
|
+
instruction: "This is your second chance. Respond with valid JSON that can be parsed by JSON.parse().",
|
|
1180
|
+
emphasis: "ABSOLUTELY NO explanatory text or formatting. Respond with ONLY raw JSON."
|
|
1181
1181
|
},
|
|
1182
1182
|
{
|
|
1183
1183
|
prefix: "FINAL ATTEMPT - CRITICAL JSON ERROR:",
|
|
1184
|
-
instruction: "This is the final retry. You MUST
|
|
1185
|
-
emphasis: "CORRECT:
|
|
1184
|
+
instruction: "This is the final retry. You MUST respond with ONLY raw JSON.",
|
|
1185
|
+
emphasis: "CORRECT: {\"key\": \"value\"}\nWRONG: Here is the JSON: {\"key\": \"value\"}\nWRONG: ```json{\"key\": \"value\"}```"
|
|
1186
1186
|
}
|
|
1187
1187
|
];
|
|
1188
1188
|
|
|
@@ -2081,8 +2081,7 @@ Provide only the corrected Mermaid diagram within a mermaid code block. Do not a
|
|
|
2081
2081
|
|
|
2082
2082
|
try {
|
|
2083
2083
|
// Don't pass schema to avoid infinite loop where AI returns raw mermaid code
|
|
2084
|
-
// instead of
|
|
2085
|
-
// to return only mermaid code blocks.
|
|
2084
|
+
// instead of JSON. The custom prompt already instructs to return only mermaid code blocks.
|
|
2086
2085
|
const result = await this.agent.answer(prompt, []);
|
|
2087
2086
|
|
|
2088
2087
|
// Extract the mermaid code from the response
|
|
@@ -61,7 +61,7 @@ When reviewing code:
|
|
|
61
61
|
|
|
62
62
|
'engineer': `You are a senior engineer focused on software architecture and design.
|
|
63
63
|
Before jumping on the task you first analyse the user request in detail, and try to provide an elegant and concise solution.
|
|
64
|
-
If the solution is clear, you can jump to implementation right away. If not, ask the user a clarification question
|
|
64
|
+
If the solution is clear, you can jump to implementation right away. If not, ask the user a clarification question with the required details.
|
|
65
65
|
|
|
66
66
|
# Tone and Style
|
|
67
67
|
- Be concise and direct. Explain your approach briefly before implementing, then let the code speak for itself.
|
|
@@ -84,7 +84,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
84
84
|
When the request has **multiple distinct goals** (e.g. "Fix bug A AND add feature B"), use the task tool to track them:
|
|
85
85
|
- Call the task tool with action="create" and a tasks array. Each task must have an "id" field.
|
|
86
86
|
- Update task status to "in_progress" when starting and "completed" when done.
|
|
87
|
-
- All tasks must be completed or cancelled before
|
|
87
|
+
- All tasks must be completed or cancelled before providing your final answer.
|
|
88
88
|
- Stay flexible — add, remove, or reorganize tasks as your understanding changes.
|
|
89
89
|
|
|
90
90
|
Do NOT create tasks for single-goal requests, even complex ones. Multiple internal steps for one goal (search, read, analyze, implement) do not need tasks.
|
|
@@ -69,13 +69,13 @@ Tasks = logical units of work, not files or steps.
|
|
|
69
69
|
|
|
70
70
|
1. **Plan**: Call task tool with action="create" and a tasks array up front
|
|
71
71
|
2. **Execute**: Update status to "in_progress" / "completed" as you work. Add, split, or cancel tasks as you learn more.
|
|
72
|
-
3. **Finish**: All tasks must be "completed" or "cancelled" before
|
|
72
|
+
3. **Finish**: All tasks must be "completed" or "cancelled" before providing your final answer.
|
|
73
73
|
|
|
74
74
|
## Rules
|
|
75
75
|
|
|
76
76
|
- Dependencies are enforced: a task cannot start until its dependencies are completed
|
|
77
77
|
- Circular dependencies are rejected
|
|
78
|
-
-
|
|
78
|
+
- Completion is blocked while tasks remain unresolved
|
|
79
79
|
`;
|
|
80
80
|
|
|
81
81
|
/**
|
|
@@ -101,7 +101,7 @@ For each pending/in_progress task, either:
|
|
|
101
101
|
- Complete it: call task tool with action="complete", id="task-X"
|
|
102
102
|
- Cancel it: call task tool with action="update", id="task-X", status="cancelled"
|
|
103
103
|
|
|
104
|
-
After all tasks are resolved,
|
|
104
|
+
After all tasks are resolved, provide your final answer.`;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
/**
|
package/build/agent/tools.js
CHANGED
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
createTool,
|
|
13
13
|
multiEditTool,
|
|
14
14
|
DEFAULT_SYSTEM_MESSAGE,
|
|
15
|
-
attemptCompletionSchema,
|
|
16
15
|
searchSchema,
|
|
17
16
|
querySchema,
|
|
18
17
|
extractSchema,
|
|
@@ -107,7 +106,6 @@ export {
|
|
|
107
106
|
editSchema,
|
|
108
107
|
createSchema,
|
|
109
108
|
multiEditSchema,
|
|
110
|
-
attemptCompletionSchema,
|
|
111
109
|
listFilesSchema,
|
|
112
110
|
searchFilesSchema,
|
|
113
111
|
readImageSchema,
|
package/build/index.js
CHANGED
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
analyzeAllSchema,
|
|
29
29
|
executePlanSchema,
|
|
30
30
|
cleanupExecutePlanSchema,
|
|
31
|
-
attemptCompletionSchema,
|
|
32
31
|
bashSchema,
|
|
33
32
|
listFilesSchema,
|
|
34
33
|
searchFilesSchema,
|
|
@@ -105,7 +104,6 @@ export {
|
|
|
105
104
|
analyzeAllSchema,
|
|
106
105
|
executePlanSchema,
|
|
107
106
|
cleanupExecutePlanSchema,
|
|
108
|
-
attemptCompletionSchema,
|
|
109
107
|
bashSchema,
|
|
110
108
|
editSchema,
|
|
111
109
|
createSchema,
|
|
@@ -176,7 +176,7 @@ Instructions:
|
|
|
176
176
|
- Format as a structured list if multiple items found
|
|
177
177
|
- If nothing relevant is found in this chunk, respond with "No relevant items found in this chunk."
|
|
178
178
|
- Do NOT summarize the code - extract the specific information requested
|
|
179
|
-
- When done,
|
|
179
|
+
- When done, provide your final answer directly.`;
|
|
180
180
|
|
|
181
181
|
try {
|
|
182
182
|
const result = await delegate({
|
|
@@ -269,7 +269,7 @@ async function aggregateResults(chunkResults, aggregation, extractionPrompt, opt
|
|
|
269
269
|
.map(r => `--- Chunk ${r.chunk.id} ---\n${stripResultTags(r.result)}`)
|
|
270
270
|
.join('\n\n');
|
|
271
271
|
|
|
272
|
-
const completionNote = `\n\nWhen done,
|
|
272
|
+
const completionNote = `\n\nWhen done, provide your final answer directly.`;
|
|
273
273
|
|
|
274
274
|
const aggregationPrompts = {
|
|
275
275
|
summarize: `Synthesize these analyses into a comprehensive summary. Combine related findings, remove redundancy, and present a coherent overview.
|
|
@@ -378,7 +378,7 @@ For example, if looking for customer data:
|
|
|
378
378
|
STEP 3: CREATE THE FINAL PLAN
|
|
379
379
|
Based on your experiments, output the BEST search strategy.
|
|
380
380
|
|
|
381
|
-
|
|
381
|
+
Provide your answer in this EXACT format:
|
|
382
382
|
|
|
383
383
|
SEARCH_QUERY: <the query that WORKED in your experiments - use OR for multiple terms>
|
|
384
384
|
AGGREGATION: <summarize | list_unique | count | group_by>
|
|
@@ -458,7 +458,7 @@ Your answer should:
|
|
|
458
458
|
|
|
459
459
|
Format your response as a well-structured document that fully answers: "${question}"
|
|
460
460
|
|
|
461
|
-
When done,
|
|
461
|
+
When done, provide your final answer directly.`;
|
|
462
462
|
|
|
463
463
|
try {
|
|
464
464
|
const result = await delegate({
|
package/build/tools/common.js
CHANGED
|
@@ -85,64 +85,14 @@ export const cleanupExecutePlanSchema = z.object({
|
|
|
85
85
|
clearSessionStore: z.boolean().optional().default(false).describe('Clear the session store (persisted data across execute_plan calls)')
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
//
|
|
88
|
+
// Legacy: attemptCompletionSchema kept as no-op for backward compatibility of external imports
|
|
89
|
+
// The attempt_completion tool has been removed — the model now completes naturally via text.
|
|
89
90
|
export const attemptCompletionSchema = {
|
|
90
|
-
// Custom validation that requires result parameter but allows direct XML response
|
|
91
91
|
safeParse: (params) => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return {
|
|
95
|
-
success: false,
|
|
96
|
-
error: {
|
|
97
|
-
issues: [{
|
|
98
|
-
code: 'invalid_type',
|
|
99
|
-
expected: 'object',
|
|
100
|
-
received: typeof params,
|
|
101
|
-
path: [],
|
|
102
|
-
message: 'Expected object'
|
|
103
|
-
}]
|
|
104
|
-
}
|
|
105
|
-
};
|
|
92
|
+
if (!params || typeof params !== 'object' || typeof params.result !== 'string') {
|
|
93
|
+
return { success: false, error: { issues: [{ code: 'invalid_type', path: ['result'], message: 'Deprecated' }] } };
|
|
106
94
|
}
|
|
107
|
-
|
|
108
|
-
// Validate that result parameter exists and is a string
|
|
109
|
-
if (!('result' in params)) {
|
|
110
|
-
return {
|
|
111
|
-
success: false,
|
|
112
|
-
error: {
|
|
113
|
-
issues: [{
|
|
114
|
-
code: 'invalid_type',
|
|
115
|
-
expected: 'string',
|
|
116
|
-
received: 'undefined',
|
|
117
|
-
path: ['result'],
|
|
118
|
-
message: 'Required'
|
|
119
|
-
}]
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (typeof params.result !== 'string') {
|
|
125
|
-
return {
|
|
126
|
-
success: false,
|
|
127
|
-
error: {
|
|
128
|
-
issues: [{
|
|
129
|
-
code: 'invalid_type',
|
|
130
|
-
expected: 'string',
|
|
131
|
-
received: typeof params.result,
|
|
132
|
-
path: ['result'],
|
|
133
|
-
message: 'Expected string'
|
|
134
|
-
}]
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Filter out command parameter if present (legacy compatibility)
|
|
140
|
-
const filteredData = { result: params.result };
|
|
141
|
-
|
|
142
|
-
return {
|
|
143
|
-
success: true,
|
|
144
|
-
data: filteredData
|
|
145
|
-
};
|
|
95
|
+
return { success: true, data: { result: params.result } };
|
|
146
96
|
}
|
|
147
97
|
};
|
|
148
98
|
|
|
@@ -188,6 +138,56 @@ export function createMessagePreview(message, charsPerSide = 200) {
|
|
|
188
138
|
}
|
|
189
139
|
|
|
190
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Detect if a response indicates the agent is stuck in a loop or unable to proceed.
|
|
143
|
+
*
|
|
144
|
+
* @param {string} response - The agent's text response
|
|
145
|
+
* @returns {boolean} - True if the response indicates a stuck state
|
|
146
|
+
*/
|
|
147
|
+
export function detectStuckResponse(response) {
|
|
148
|
+
if (!response || typeof response !== 'string') {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const stuckPatterns = [
|
|
153
|
+
/\bi\s+cannot\s+proceed\b/i,
|
|
154
|
+
/\bi\s+can['']t\s+(?:proceed|continue|move\s+forward)\b/i,
|
|
155
|
+
/\bunable\s+to\s+(?:proceed|continue|complete)\b/i,
|
|
156
|
+
/\bblocked\b.*\b(?:proceed|continue)\b/i,
|
|
157
|
+
/\bneed\s+(?:the|an?)\s+\w+(?:\s+\w+)?\s+to\s+(?:proceed|continue)\b/i,
|
|
158
|
+
/\brequire[sd]?\s+(?:the|an?)\s+\w+\b.*\bto\s+(?:proceed|continue)\b/i,
|
|
159
|
+
/\bmissing\s+(?:required|necessary|essential)\b/i,
|
|
160
|
+
/\bdeadlock\b/i,
|
|
161
|
+
/\bwe\s+are\s+in\s+a\s+loop\b/i,
|
|
162
|
+
/\bstuck\s+in\s+a\s+loop\b/i,
|
|
163
|
+
/\bi\s+(?:have|['']ve)\s+(?:explained|stated|mentioned)\s+(?:this|the\s+situation|it)\s+(?:multiple|several)\s+times\b/i,
|
|
164
|
+
/\bi\s+(?:cannot|can['']t|could\s+not|couldn['']t)\s+(?:find|locate|get|retrieve|obtain)\s+(?:the|this|that|an?)\b/i,
|
|
165
|
+
/\bno\s+way\s+to\s+(?:find|get|obtain|retrieve)\b/i,
|
|
166
|
+
/\bi\s+(?:have|['']ve)\s+exhausted\s+(?:all|my)\s+(?:available\s+)?(?:options|methods|approaches)\b/i,
|
|
167
|
+
/\bneither\s+of\s+these\s+methods\b/i,
|
|
168
|
+
];
|
|
169
|
+
|
|
170
|
+
for (const pattern of stuckPatterns) {
|
|
171
|
+
if (pattern.test(response)) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Check if two responses both indicate a stuck state.
|
|
181
|
+
*
|
|
182
|
+
* @param {string} response1 - First response
|
|
183
|
+
* @param {string} response2 - Second response
|
|
184
|
+
* @returns {boolean} - True if both responses indicate a stuck state
|
|
185
|
+
*/
|
|
186
|
+
export function areBothStuckResponses(response1, response2) {
|
|
187
|
+
return detectStuckResponse(response1) && detectStuckResponse(response2);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
191
|
/**
|
|
192
192
|
* Parse targets string into array of file specifications
|
|
193
193
|
* Handles both space-separated and comma-separated targets for extract tool
|
package/build/tools/index.js
CHANGED
package/build/tools/vercel.js
CHANGED
|
@@ -396,7 +396,7 @@ export const searchTool = (options = {}) => {
|
|
|
396
396
|
if (debug) {
|
|
397
397
|
console.error(`[DEDUP] Blocked duplicate search: "${searchQuery}" (path: "${searchPath}")`);
|
|
398
398
|
}
|
|
399
|
-
return 'DUPLICATE SEARCH BLOCKED: You already searched for this exact query. Changing the path does NOT give different results — probe searches recursively. Do NOT repeat the same search. Try a genuinely different keyword, use extract to examine results you already found, or
|
|
399
|
+
return 'DUPLICATE SEARCH BLOCKED: You already searched for this exact query. Changing the path does NOT give different results — probe searches recursively. Do NOT repeat the same search. Try a genuinely different keyword, use extract to examine results you already found, or provide your final answer if you have enough information.';
|
|
400
400
|
}
|
|
401
401
|
previousSearches.add(searchKey);
|
|
402
402
|
paginationCounts.set(searchKey, 0);
|
|
@@ -408,7 +408,7 @@ export const searchTool = (options = {}) => {
|
|
|
408
408
|
if (debug) {
|
|
409
409
|
console.error(`[DEDUP] Blocked excessive pagination (page ${pageCount}/${MAX_PAGES_PER_QUERY}): "${searchQuery}" in "${searchPath}"`);
|
|
410
410
|
}
|
|
411
|
-
return `PAGINATION LIMIT REACHED: You have already retrieved ${MAX_PAGES_PER_QUERY} pages of results for this query. You have enough results — use extract to examine specific files, or
|
|
411
|
+
return `PAGINATION LIMIT REACHED: You have already retrieved ${MAX_PAGES_PER_QUERY} pages of results for this query. You have enough results — use extract to examine specific files, or provide your final answer with your findings.`;
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
414
|
try {
|
|
@@ -450,7 +450,7 @@ export const searchTool = (options = {}) => {
|
|
|
450
450
|
bashConfig: null,
|
|
451
451
|
architectureFileName: options.architectureFileName || null,
|
|
452
452
|
promptType: 'code-searcher',
|
|
453
|
-
allowedTools: ['search', 'extract', 'listFiles'
|
|
453
|
+
allowedTools: ['search', 'extract', 'listFiles'],
|
|
454
454
|
searchDelegate: false,
|
|
455
455
|
schema: CODE_SEARCH_SCHEMA,
|
|
456
456
|
parentAbortSignal: options.parentAbortSignal || null
|