@probelabs/probe 0.6.0-rc238 → 0.6.0-rc240

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.
Files changed (33) hide show
  1. package/bin/binaries/probe-v0.6.0-rc240-aarch64-apple-darwin.tar.gz +0 -0
  2. package/bin/binaries/probe-v0.6.0-rc240-aarch64-unknown-linux-musl.tar.gz +0 -0
  3. package/bin/binaries/probe-v0.6.0-rc240-x86_64-apple-darwin.tar.gz +0 -0
  4. package/bin/binaries/{probe-v0.6.0-rc238-x86_64-pc-windows-msvc.zip → probe-v0.6.0-rc240-x86_64-pc-windows-msvc.zip} +0 -0
  5. package/bin/binaries/probe-v0.6.0-rc240-x86_64-unknown-linux-musl.tar.gz +0 -0
  6. package/build/agent/ProbeAgent.js +20 -2
  7. package/build/agent/dsl/runtime.js +3 -16
  8. package/build/agent/dsl/validator.js +5 -4
  9. package/build/agent/index.js +127 -24
  10. package/build/agent/probeTool.js +9 -0
  11. package/build/agent/schemaUtils.js +34 -10
  12. package/build/agent/tools.js +9 -0
  13. package/build/index.js +5 -1
  14. package/build/tools/common.js +6 -0
  15. package/build/tools/executePlan.js +100 -2
  16. package/build/tools/index.js +3 -2
  17. package/cjs/agent/ProbeAgent.cjs +127 -24
  18. package/cjs/index.cjs +136 -24
  19. package/package.json +1 -1
  20. package/src/agent/ProbeAgent.js +20 -2
  21. package/src/agent/dsl/runtime.js +3 -16
  22. package/src/agent/dsl/validator.js +5 -4
  23. package/src/agent/probeTool.js +9 -0
  24. package/src/agent/schemaUtils.js +34 -10
  25. package/src/agent/tools.js +9 -0
  26. package/src/index.js +5 -1
  27. package/src/tools/common.js +6 -0
  28. package/src/tools/executePlan.js +100 -2
  29. package/src/tools/index.js +3 -2
  30. package/bin/binaries/probe-v0.6.0-rc238-aarch64-apple-darwin.tar.gz +0 -0
  31. package/bin/binaries/probe-v0.6.0-rc238-aarch64-unknown-linux-musl.tar.gz +0 -0
  32. package/bin/binaries/probe-v0.6.0-rc238-x86_64-apple-darwin.tar.gz +0 -0
  33. package/bin/binaries/probe-v0.6.0-rc238-x86_64-unknown-linux-musl.tar.gz +0 -0
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { tool } from 'ai';
9
- import { executePlanSchema, parseAndResolvePaths } from './common.js';
9
+ import { executePlanSchema, cleanupExecutePlanSchema, parseAndResolvePaths } from './common.js';
10
10
  import { createDSLRuntime } from '../agent/dsl/runtime.js';
11
11
  import { search } from '../search.js';
12
12
  import { query } from '../query.js';
@@ -347,7 +347,16 @@ RULES REMINDER:
347
347
  });
348
348
  }
349
349
 
350
- // All retries exhausted
350
+ // All retries exhausted — auto-cleanup output buffer to prevent stale data
351
+ if (outputBuffer && outputBuffer.items && outputBuffer.items.length > 0) {
352
+ const clearedChars = outputBuffer.items.reduce((sum, item) => sum + item.length, 0);
353
+ outputBuffer.items = [];
354
+ planSpan?.addEvent?.('dsl.auto_cleanup', {
355
+ 'cleanup.chars_cleared': clearedChars,
356
+ 'cleanup.reason': 'all_retries_exhausted',
357
+ });
358
+ }
359
+
351
360
  finalOutput = `Plan execution failed after ${maxRetries} retries.\n\nLast error: ${lastError}`;
352
361
  planSpan?.setAttributes?.({
353
362
  'dsl.result': 'all_retries_exhausted',
@@ -358,6 +367,11 @@ RULES REMINDER:
358
367
  planSpan?.end?.();
359
368
  return finalOutput;
360
369
  } catch (e) {
370
+ // Auto-cleanup output buffer on exception to prevent stale data
371
+ if (outputBuffer && outputBuffer.items && outputBuffer.items.length > 0) {
372
+ outputBuffer.items = [];
373
+ }
374
+
361
375
  planSpan?.setStatus?.('ERROR');
362
376
  planSpan?.addEvent?.('exception', {
363
377
  'exception.message': e.message,
@@ -808,3 +822,87 @@ output(table);
808
822
  return "Generated table with " + results.length + " items.";
809
823
  \`\`\``;
810
824
  }
825
+
826
+ /**
827
+ * Create the cleanup_execute_plan tool for the Vercel AI SDK.
828
+ *
829
+ * Cleans up output buffer and optionally session store from previous
830
+ * failed or interrupted execute_plan calls.
831
+ *
832
+ * @param {Object} options
833
+ * @param {Object} [options.outputBuffer] - Output buffer to clear
834
+ * @param {Object} [options.sessionStore] - Session store to clear
835
+ * @param {Object} [options.tracer] - OTEL tracer for tracing
836
+ * @returns {Object} Vercel AI SDK tool
837
+ */
838
+ export function createCleanupExecutePlanTool(options) {
839
+ const { outputBuffer, sessionStore, tracer } = options;
840
+
841
+ return tool({
842
+ description: 'Clean up output buffer and session store from previous execute_plan calls. ' +
843
+ 'Use this when a previous execute_plan failed and left stale data, or before starting a fresh analysis.',
844
+ parameters: cleanupExecutePlanSchema,
845
+ execute: async ({ clearOutputBuffer = true, clearSessionStore = false }) => {
846
+ const span = tracer?.createToolSpan?.('cleanup_execute_plan', {
847
+ 'cleanup.clear_output_buffer': clearOutputBuffer,
848
+ 'cleanup.clear_session_store': clearSessionStore,
849
+ }) || null;
850
+
851
+ const results = [];
852
+
853
+ try {
854
+ if (clearOutputBuffer && outputBuffer) {
855
+ const itemCount = outputBuffer.items?.length || 0;
856
+ const charCount = outputBuffer.items?.reduce((sum, item) => sum + item.length, 0) || 0;
857
+ outputBuffer.items = [];
858
+ results.push(`Output buffer cleared (${itemCount} items, ${charCount} chars)`);
859
+ }
860
+
861
+ if (clearSessionStore && sessionStore) {
862
+ const keyCount = Object.keys(sessionStore).length;
863
+ for (const key of Object.keys(sessionStore)) {
864
+ delete sessionStore[key];
865
+ }
866
+ results.push(`Session store cleared (${keyCount} keys)`);
867
+ }
868
+
869
+ const output = results.length > 0
870
+ ? `Cleanup complete:\n- ${results.join('\n- ')}`
871
+ : 'Nothing to clean up';
872
+
873
+ span?.setAttributes?.({
874
+ 'cleanup.result': output,
875
+ 'cleanup.success': true,
876
+ });
877
+ span?.setStatus?.('OK');
878
+ span?.end?.();
879
+
880
+ return output;
881
+ } catch (e) {
882
+ span?.setStatus?.('ERROR');
883
+ span?.addEvent?.('exception', { 'exception.message': e.message });
884
+ span?.end?.();
885
+ return `Cleanup failed: ${e.message}`;
886
+ }
887
+ },
888
+ });
889
+ }
890
+
891
+ /**
892
+ * XML tool definition for cleanup_execute_plan.
893
+ *
894
+ * @returns {string} Tool definition text
895
+ */
896
+ export function getCleanupExecutePlanToolDefinition() {
897
+ return `## cleanup_execute_plan
898
+ Description: Clean up output buffer and session store from previous execute_plan calls. Use when a previous execute_plan failed and left stale data, or before starting a fresh analysis.
899
+
900
+ Parameters:
901
+ - clearOutputBuffer: (optional, default: true) Clear the output buffer from previous execute_plan calls
902
+ - clearSessionStore: (optional, default: false) Clear the session store (persisted data across execute_plan calls)
903
+
904
+ Example:
905
+ <cleanup_execute_plan>
906
+ <clearOutputBuffer>true</clearOutputBuffer>
907
+ </cleanup_execute_plan>`;
908
+ }
@@ -11,8 +11,8 @@ export { editTool, createTool } from './edit.js';
11
11
  // Export LangChain tools
12
12
  export { createSearchTool, createQueryTool, createExtractTool } from './langchain.js';
13
13
 
14
- // Export execute_plan tool
15
- export { createExecutePlanTool, getExecutePlanToolDefinition } from './executePlan.js';
14
+ // Export execute_plan and cleanup_execute_plan tools
15
+ export { createExecutePlanTool, getExecutePlanToolDefinition, createCleanupExecutePlanTool, getCleanupExecutePlanToolDefinition } from './executePlan.js';
16
16
 
17
17
  // Export common schemas and utilities
18
18
  export {
@@ -22,6 +22,7 @@ export {
22
22
  delegateSchema,
23
23
  bashSchema,
24
24
  executePlanSchema,
25
+ cleanupExecutePlanSchema,
25
26
  delegateDescription,
26
27
  delegateToolDefinition,
27
28
  bashDescription,
@@ -39352,7 +39352,7 @@ function resolveTargetPath(target, cwd) {
39352
39352
  }
39353
39353
  return filePart + suffix;
39354
39354
  }
39355
- var import_path6, searchSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, bashSchema, analyzeAllSchema, executePlanSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, analyzeAllToolDefinition, bashToolDefinition, googleSearchToolDefinition, urlContextToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription, DEFAULT_VALID_TOOLS;
39355
+ var import_path6, searchSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, analyzeAllToolDefinition, bashToolDefinition, googleSearchToolDefinition, urlContextToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription, DEFAULT_VALID_TOOLS;
39356
39356
  var init_common2 = __esm({
39357
39357
  "src/tools/common.js"() {
39358
39358
  "use strict";
@@ -39401,6 +39401,10 @@ var init_common2 = __esm({
39401
39401
  code: external_exports.string().min(1).describe("JavaScript DSL code to execute. All function calls look synchronous \u2014 do NOT use async/await. Use map(items, fn) for batch operations. Use LLM(instruction, data) for AI processing."),
39402
39402
  description: external_exports.string().optional().describe("Human-readable description of what this plan does, for logging.")
39403
39403
  });
39404
+ cleanupExecutePlanSchema = external_exports.object({
39405
+ clearOutputBuffer: external_exports.boolean().optional().default(true).describe("Clear the output buffer from previous execute_plan calls"),
39406
+ clearSessionStore: external_exports.boolean().optional().default(false).describe("Clear the session store (persisted data across execute_plan calls)")
39407
+ });
39404
39408
  attemptCompletionSchema = {
39405
39409
  // Custom validation that requires result parameter but allows direct XML response
39406
39410
  safeParse: (params) => {
@@ -39748,6 +39752,7 @@ Capabilities:
39748
39752
  "delegate",
39749
39753
  "analyze_all",
39750
39754
  "execute_plan",
39755
+ "cleanup_execute_plan",
39751
39756
  "listSkills",
39752
39757
  "useSkill",
39753
39758
  "listFiles",
@@ -50948,9 +50953,6 @@ function validateDSL(code) {
50948
50953
  if (node.type === "FunctionExpression" && node.generator) {
50949
50954
  errors.push(`Generator functions are not allowed at position ${node.start}`);
50950
50955
  }
50951
- if (node.type === "Literal" && node.regex) {
50952
- errors.push(`Regex literals are not supported at position ${node.start}. Use String methods like indexOf(), includes(), startsWith() instead.`);
50953
- }
50954
50956
  if (node.type === "Identifier" && BLOCKED_IDENTIFIERS.has(node.name)) {
50955
50957
  errors.push(`Blocked identifier: '${node.name}' at position ${node.start}`);
50956
50958
  }
@@ -50989,18 +50991,23 @@ var init_validator = __esm({
50989
50991
  "BlockStatement",
50990
50992
  "VariableDeclaration",
50991
50993
  "VariableDeclarator",
50994
+ "FunctionDeclaration",
50992
50995
  "ArrowFunctionExpression",
50993
50996
  "FunctionExpression",
50994
50997
  "CallExpression",
50998
+ "NewExpression",
50995
50999
  "MemberExpression",
50996
51000
  "Identifier",
50997
51001
  "Literal",
50998
51002
  "TemplateLiteral",
50999
51003
  "TemplateElement",
51004
+ "TaggedTemplateExpression",
51000
51005
  "ArrayExpression",
51001
51006
  "ObjectExpression",
51002
51007
  "SpreadElement",
51003
51008
  "IfStatement",
51009
+ "SwitchStatement",
51010
+ "SwitchCase",
51004
51011
  "ConditionalExpression",
51005
51012
  "ForOfStatement",
51006
51013
  "ForInStatement",
@@ -51462,7 +51469,6 @@ function createDSLRuntime(options) {
51462
51469
  mcpTools = {},
51463
51470
  llmCall,
51464
51471
  mapConcurrency = 3,
51465
- timeoutMs = 12e4,
51466
51472
  maxLoopIterations = 5e3,
51467
51473
  tracer = null,
51468
51474
  sessionStore = {},
@@ -51517,7 +51523,6 @@ ${validation.errors.join("\n")}`,
51517
51523
  };
51518
51524
  }
51519
51525
  tracer?.addEvent?.("dsl.phase.execute_start", {
51520
- "dsl.timeout_ms": timeoutMs,
51521
51526
  "dsl.max_loop_iterations": maxLoopIterations
51522
51527
  });
51523
51528
  try {
@@ -51545,18 +51550,10 @@ ${validation.errors.join("\n")}`,
51545
51550
  escapedError = reason;
51546
51551
  };
51547
51552
  process.on("unhandledRejection", rejectionHandler);
51548
- let timeoutHandle;
51549
- const executionPromise = exec6().run();
51550
- const timeoutPromise = new Promise((_, reject2) => {
51551
- timeoutHandle = setTimeout(() => {
51552
- reject2(new Error(`Execution timed out after ${Math.round(timeoutMs / 1e3)}s. Script took too long \u2014 reduce the amount of work (fewer items, smaller data) or increase timeout.`));
51553
- }, timeoutMs);
51554
- });
51555
51553
  let result;
51556
51554
  try {
51557
- result = await Promise.race([executionPromise, timeoutPromise]);
51555
+ result = await exec6().run();
51558
51556
  } finally {
51559
- clearTimeout(timeoutHandle);
51560
51557
  setTimeout(() => {
51561
51558
  process.removeListener("unhandledRejection", rejectionHandler);
51562
51559
  }, 500);
@@ -58542,6 +58539,14 @@ Logs: ${result.logs.join(" | ")}` : "";
58542
58539
  "dsl.error": lastError.substring(0, 1e3)
58543
58540
  });
58544
58541
  }
58542
+ if (outputBuffer && outputBuffer.items && outputBuffer.items.length > 0) {
58543
+ const clearedChars = outputBuffer.items.reduce((sum, item) => sum + item.length, 0);
58544
+ outputBuffer.items = [];
58545
+ planSpan?.addEvent?.("dsl.auto_cleanup", {
58546
+ "cleanup.chars_cleared": clearedChars,
58547
+ "cleanup.reason": "all_retries_exhausted"
58548
+ });
58549
+ }
58545
58550
  finalOutput = `Plan execution failed after ${maxRetries} retries.
58546
58551
 
58547
58552
  Last error: ${lastError}`;
@@ -58554,6 +58559,9 @@ Last error: ${lastError}`;
58554
58559
  planSpan?.end?.();
58555
58560
  return finalOutput;
58556
58561
  } catch (e5) {
58562
+ if (outputBuffer && outputBuffer.items && outputBuffer.items.length > 0) {
58563
+ outputBuffer.items = [];
58564
+ }
58557
58565
  planSpan?.setStatus?.("ERROR");
58558
58566
  planSpan?.addEvent?.("exception", {
58559
58567
  "exception.message": e5.message,
@@ -58997,6 +59005,62 @@ output(table);
58997
59005
  return "Generated table with " + results.length + " items.";
58998
59006
  \`\`\``;
58999
59007
  }
59008
+ function createCleanupExecutePlanTool(options) {
59009
+ const { outputBuffer, sessionStore, tracer } = options;
59010
+ return (0, import_ai4.tool)({
59011
+ description: "Clean up output buffer and session store from previous execute_plan calls. Use this when a previous execute_plan failed and left stale data, or before starting a fresh analysis.",
59012
+ parameters: cleanupExecutePlanSchema,
59013
+ execute: async ({ clearOutputBuffer = true, clearSessionStore = false }) => {
59014
+ const span = tracer?.createToolSpan?.("cleanup_execute_plan", {
59015
+ "cleanup.clear_output_buffer": clearOutputBuffer,
59016
+ "cleanup.clear_session_store": clearSessionStore
59017
+ }) || null;
59018
+ const results = [];
59019
+ try {
59020
+ if (clearOutputBuffer && outputBuffer) {
59021
+ const itemCount = outputBuffer.items?.length || 0;
59022
+ const charCount = outputBuffer.items?.reduce((sum, item) => sum + item.length, 0) || 0;
59023
+ outputBuffer.items = [];
59024
+ results.push(`Output buffer cleared (${itemCount} items, ${charCount} chars)`);
59025
+ }
59026
+ if (clearSessionStore && sessionStore) {
59027
+ const keyCount = Object.keys(sessionStore).length;
59028
+ for (const key of Object.keys(sessionStore)) {
59029
+ delete sessionStore[key];
59030
+ }
59031
+ results.push(`Session store cleared (${keyCount} keys)`);
59032
+ }
59033
+ const output = results.length > 0 ? `Cleanup complete:
59034
+ - ${results.join("\n- ")}` : "Nothing to clean up";
59035
+ span?.setAttributes?.({
59036
+ "cleanup.result": output,
59037
+ "cleanup.success": true
59038
+ });
59039
+ span?.setStatus?.("OK");
59040
+ span?.end?.();
59041
+ return output;
59042
+ } catch (e5) {
59043
+ span?.setStatus?.("ERROR");
59044
+ span?.addEvent?.("exception", { "exception.message": e5.message });
59045
+ span?.end?.();
59046
+ return `Cleanup failed: ${e5.message}`;
59047
+ }
59048
+ }
59049
+ });
59050
+ }
59051
+ function getCleanupExecutePlanToolDefinition() {
59052
+ return `## cleanup_execute_plan
59053
+ Description: Clean up output buffer and session store from previous execute_plan calls. Use when a previous execute_plan failed and left stale data, or before starting a fresh analysis.
59054
+
59055
+ Parameters:
59056
+ - clearOutputBuffer: (optional, default: true) Clear the output buffer from previous execute_plan calls
59057
+ - clearSessionStore: (optional, default: false) Clear the session store (persisted data across execute_plan calls)
59058
+
59059
+ Example:
59060
+ <cleanup_execute_plan>
59061
+ <clearOutputBuffer>true</clearOutputBuffer>
59062
+ </cleanup_execute_plan>`;
59063
+ }
59000
59064
  var import_ai4;
59001
59065
  var init_executePlan = __esm({
59002
59066
  "src/tools/executePlan.js"() {
@@ -59352,6 +59416,13 @@ function createWrappedTools(baseTools) {
59352
59416
  baseTools.executePlanTool.execute
59353
59417
  );
59354
59418
  }
59419
+ if (baseTools.cleanupExecutePlanTool) {
59420
+ wrappedTools.cleanupExecutePlanToolInstance = wrapToolWithEmitter(
59421
+ baseTools.cleanupExecutePlanTool,
59422
+ "cleanup_execute_plan",
59423
+ baseTools.cleanupExecutePlanTool.execute
59424
+ );
59425
+ }
59355
59426
  if (baseTools.bashTool) {
59356
59427
  wrappedTools.bashToolInstance = wrapToolWithEmitter(
59357
59428
  baseTools.bashTool,
@@ -60268,6 +60339,9 @@ function createTools(configOptions) {
60268
60339
  }
60269
60340
  if (configOptions.enableExecutePlan && isToolAllowed("execute_plan")) {
60270
60341
  tools2.executePlanTool = createExecutePlanTool(configOptions);
60342
+ if (isToolAllowed("cleanup_execute_plan")) {
60343
+ tools2.cleanupExecutePlanTool = createCleanupExecutePlanTool(configOptions);
60344
+ }
60271
60345
  } else if (isToolAllowed("analyze_all")) {
60272
60346
  tools2.analyzeAllTool = analyzeAllTool(configOptions);
60273
60347
  }
@@ -97681,15 +97755,31 @@ function isSimpleTextWrapperSchema(schema) {
97681
97755
  return null;
97682
97756
  }
97683
97757
  const trimmed = schema.trim();
97684
- const simplePatterns = [
97685
- /^\{\s*["']?(\w+)["']?\s*:\s*["']?string["']?\s*\}$/i,
97686
- /^\{\s*["']?type["']?\s*:\s*["']?object["']?\s*,\s*["']?properties["']?\s*:\s*\{\s*["']?(\w+)["']?\s*:\s*\{\s*["']?type["']?\s*:\s*["']?string["']?\s*\}\s*\}\s*\}$/i
97687
- ];
97688
- for (const pattern of simplePatterns) {
97689
- const match2 = trimmed.match(pattern);
97690
- if (match2) {
97691
- return { fieldName: match2[1] };
97758
+ try {
97759
+ const parsed = JSON.parse(trimmed);
97760
+ if (typeof parsed !== "object" || parsed === null) {
97761
+ } else {
97762
+ const keys2 = Object.keys(parsed);
97763
+ if (keys2.length === 1 && parsed[keys2[0]] === "string") {
97764
+ return { fieldName: keys2[0] };
97765
+ }
97766
+ if (parsed.type === "object" && parsed.properties) {
97767
+ const propKeys = Object.keys(parsed.properties);
97768
+ if (propKeys.length === 1) {
97769
+ const prop = parsed.properties[propKeys[0]];
97770
+ if (prop && prop.type === "string") {
97771
+ return { fieldName: propKeys[0] };
97772
+ }
97773
+ }
97774
+ }
97775
+ return null;
97692
97776
  }
97777
+ } catch {
97778
+ }
97779
+ const simplePattern = /^\{\s*["']?(\w+)["']?\s*:\s*["']?string["']?\s*\}$/i;
97780
+ const match2 = trimmed.match(simplePattern);
97781
+ if (match2) {
97782
+ return { fieldName: match2[1] };
97693
97783
  }
97694
97784
  return null;
97695
97785
  }
@@ -110551,6 +110641,9 @@ var init_ProbeAgent = __esm({
110551
110641
  }
110552
110642
  if (this.enableExecutePlan && wrappedTools.executePlanToolInstance && isToolAllowed("execute_plan")) {
110553
110643
  this.toolImplementations.execute_plan = wrappedTools.executePlanToolInstance;
110644
+ if (wrappedTools.cleanupExecutePlanToolInstance && isToolAllowed("cleanup_execute_plan")) {
110645
+ this.toolImplementations.cleanup_execute_plan = wrappedTools.cleanupExecutePlanToolInstance;
110646
+ }
110554
110647
  } else if (wrappedTools.analyzeAllToolInstance && isToolAllowed("analyze_all")) {
110555
110648
  this.toolImplementations.analyze_all = wrappedTools.analyzeAllToolInstance;
110556
110649
  }
@@ -111924,6 +112017,10 @@ Workspace: ${this.allowedFolders.join(", ")}`;
111924
112017
  if (this.enableBash && isToolAllowed("bash")) dslFunctions.push("bash");
111925
112018
  toolDefinitions += `${getExecutePlanToolDefinition(dslFunctions)}
111926
112019
  `;
112020
+ if (isToolAllowed("cleanup_execute_plan")) {
112021
+ toolDefinitions += `${getCleanupExecutePlanToolDefinition()}
112022
+ `;
112023
+ }
111927
112024
  } else if (isToolAllowed("analyze_all")) {
111928
112025
  toolDefinitions += `${analyzeAllToolDefinition}
111929
112026
  `;
@@ -111999,6 +112096,9 @@ The configuration is loaded from src/config.js lines 15-25 which contains the da
111999
112096
  }
112000
112097
  if (this.enableExecutePlan && isToolAllowed("execute_plan")) {
112001
112098
  availableToolsList += '- execute_plan: Execute a DSL program to orchestrate tool calls. ALWAYS use this for: questions containing "all"/"every"/"comprehensive"/"complete inventory", multi-topic analysis, open-ended discovery questions, or any task requiring full codebase coverage.\n';
112099
+ if (isToolAllowed("cleanup_execute_plan")) {
112100
+ availableToolsList += "- cleanup_execute_plan: Clean up output buffer and session store from previous execute_plan calls.\n";
112101
+ }
112002
112102
  } else if (isToolAllowed("analyze_all")) {
112003
112103
  availableToolsList += "- analyze_all: Process ALL data matching a query using map-reduce (for aggregate questions needing 100% coverage).\n";
112004
112104
  }
@@ -112225,7 +112325,7 @@ You are working with a workspace. Available paths: ${workspaceDesc}
112225
112325
  }
112226
112326
  try {
112227
112327
  const oldHistoryLength = this.history.length;
112228
- if (this._outputBuffer) {
112328
+ if (this._outputBuffer && !options?._schemaFormatted) {
112229
112329
  this._outputBuffer.items = [];
112230
112330
  }
112231
112331
  if (this.enableTasks) {
@@ -112585,6 +112685,9 @@ You are working with a workspace. Available paths: ${workspaceDesc}
112585
112685
  }
112586
112686
  if (this.enableExecutePlan && this.allowedTools.isEnabled("execute_plan")) {
112587
112687
  validTools.push("execute_plan");
112688
+ if (this.allowedTools.isEnabled("cleanup_execute_plan")) {
112689
+ validTools.push("cleanup_execute_plan");
112690
+ }
112588
112691
  } else if (this.allowedTools.isEnabled("analyze_all")) {
112589
112692
  validTools.push("analyze_all");
112590
112693
  }