@probelabs/probe 0.6.0-rc240 → 0.6.0-rc242

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.
@@ -16,8 +16,42 @@ import { glob } from 'glob';
16
16
 
17
17
  export { executePlanSchema };
18
18
 
19
+ /**
20
+ * Decode common HTML entities that LLMs sometimes produce when generating code.
21
+ * This handles entities like &amp;&amp; → &&, &lt;= → <=, etc.
22
+ */
23
+ function decodeHtmlEntities(str) {
24
+ const entities = {
25
+ '&amp;': '&',
26
+ '&lt;': '<',
27
+ '&gt;': '>',
28
+ '&quot;': '"',
29
+ '&apos;': "'",
30
+ '&#39;': "'",
31
+ '&#x27;': "'",
32
+ };
33
+
34
+ // Replace named/common entities
35
+ let result = str.replace(/&(?:amp|lt|gt|quot|apos|#39|#x27);/gi, (match) => {
36
+ return entities[match.toLowerCase()] || match;
37
+ });
38
+
39
+ // Handle numeric entities (decimal): &#60; → <
40
+ result = result.replace(/&#(\d+);/g, (match, dec) => {
41
+ return String.fromCharCode(parseInt(dec, 10));
42
+ });
43
+
44
+ // Handle numeric entities (hex): &#x3C; → <
45
+ result = result.replace(/&#x([0-9a-f]+);/gi, (match, hex) => {
46
+ return String.fromCharCode(parseInt(hex, 16));
47
+ });
48
+
49
+ return result;
50
+ }
51
+
19
52
  /**
20
53
  * Strip markdown fences and XML tags that LLMs sometimes wrap code in.
54
+ * Also decodes HTML entities that may appear in XML-extracted code.
21
55
  */
22
56
  function stripCodeWrapping(code) {
23
57
  let s = String(code || '');
@@ -25,6 +59,8 @@ function stripCodeWrapping(code) {
25
59
  s = s.replace(/^```(?:javascript|js)?\n?/gm, '').replace(/```$/gm, '');
26
60
  // Strip XML-style tags: <execute_plan>, </execute_plan>, <code>, </code>
27
61
  s = s.replace(/<\/?(?:execute_plan|code)>/g, '');
62
+ // Decode HTML entities (e.g., &amp;&amp; → &&, &lt;= → <=)
63
+ s = decodeHtmlEntities(s);
28
64
  return s.trim();
29
65
  }
30
66
 
@@ -384,6 +420,51 @@ RULES REMINDER:
384
420
  });
385
421
  }
386
422
 
423
+ // Delimiters for raw output passthrough - prevents LLM from processing/hallucinating large structured output
424
+ export const RAW_OUTPUT_START = '<<<RAW_OUTPUT>>>';
425
+ export const RAW_OUTPUT_END = '<<<END_RAW_OUTPUT>>>';
426
+
427
+ /**
428
+ * Extract raw output blocks from tool result content and pass them through to the output buffer.
429
+ * This prevents parent LLMs from processing/hallucinating large structured output.
430
+ *
431
+ * @param {string} content - The tool result content
432
+ * @param {Object} [outputBuffer] - The output buffer to append extracted content to
433
+ * @returns {{ cleanedContent: string, extractedBlocks: string[] }} - Content with blocks removed and extracted blocks
434
+ */
435
+ export function extractRawOutputBlocks(content, outputBuffer = null) {
436
+ if (typeof content !== 'string') {
437
+ return { cleanedContent: content, extractedBlocks: [] };
438
+ }
439
+
440
+ const extractedBlocks = [];
441
+ const regex = new RegExp(`${RAW_OUTPUT_START}\\n([\\s\\S]*?)\\n${RAW_OUTPUT_END}`, 'g');
442
+
443
+ let cleanedContent = content;
444
+ let match;
445
+
446
+ // Extract all blocks
447
+ while ((match = regex.exec(content)) !== null) {
448
+ extractedBlocks.push(match[1]);
449
+ }
450
+
451
+ // Remove the blocks and any following instruction line from content
452
+ cleanedContent = content
453
+ .replace(new RegExp(`${RAW_OUTPUT_START}\\n[\\s\\S]*?\\n${RAW_OUTPUT_END}`, 'g'), '')
454
+ .replace(/\n\n\[The above raw output \(\d+ chars\) will be passed directly to the final response\. Do NOT repeat, summarize, or modify it\.\]/g, '')
455
+ .trim();
456
+
457
+ // If output buffer provided, append extracted content
458
+ if (outputBuffer && extractedBlocks.length > 0) {
459
+ for (const block of extractedBlocks) {
460
+ outputBuffer.items = outputBuffer.items || [];
461
+ outputBuffer.items.push(block);
462
+ }
463
+ }
464
+
465
+ return { cleanedContent, extractedBlocks };
466
+ }
467
+
387
468
  function formatSuccess(result, description, attempt, outputBuffer) {
388
469
  let output = '';
389
470
 
@@ -416,10 +497,12 @@ function formatSuccess(result, description, attempt, outputBuffer) {
416
497
  }
417
498
  }
418
499
 
419
- // If output buffer has content, tell the LLM the data was written to direct output
500
+ // If output buffer has content, wrap it in delimiters for passthrough
501
+ // This prevents parent LLMs from processing/hallucinating the raw data
420
502
  if (outputBuffer && outputBuffer.items && outputBuffer.items.length > 0) {
421
- const totalChars = outputBuffer.items.reduce((sum, item) => sum + item.length, 0);
422
- output += `\n\n[Output buffer: ${totalChars} chars written via output(). This content will be appended directly to your response. Do NOT repeat or summarize it.]`;
503
+ const rawContent = outputBuffer.items.join('\n');
504
+ output += `\n\n${RAW_OUTPUT_START}\n${rawContent}\n${RAW_OUTPUT_END}`;
505
+ output += `\n\n[The above raw output (${rawContent.length} chars) will be passed directly to the final response. Do NOT repeat, summarize, or modify it.]`;
423
506
  }
424
507
 
425
508
  return output;
@@ -6314,7 +6314,9 @@ var init_HttpBindingProtocol = __esm({
6314
6314
  if (bytes.byteLength > 0) {
6315
6315
  const dataFromBody = await deserializer.read(ns, bytes);
6316
6316
  for (const member2 of nonHttpBindingMembers) {
6317
- dataObject[member2] = dataFromBody[member2];
6317
+ if (dataFromBody[member2] != null) {
6318
+ dataObject[member2] = dataFromBody[member2];
6319
+ }
6318
6320
  }
6319
6321
  }
6320
6322
  } else if (nonHttpBindingMembers.discardResponseBody) {
@@ -50930,6 +50932,50 @@ var init_walk = __esm({
50930
50932
  });
50931
50933
 
50932
50934
  // src/agent/dsl/validator.js
50935
+ function offsetToLineColumn(code, offset2) {
50936
+ const lines = code.split("\n");
50937
+ let pos = 0;
50938
+ for (let i5 = 0; i5 < lines.length; i5++) {
50939
+ const lineLength = lines[i5].length + 1;
50940
+ if (pos + lineLength > offset2) {
50941
+ return { line: i5 + 1, column: offset2 - pos + 1 };
50942
+ }
50943
+ pos += lineLength;
50944
+ }
50945
+ return { line: lines.length, column: 1 };
50946
+ }
50947
+ function generateErrorSnippet(code, line, column, contextLines = 2) {
50948
+ const lines = code.split("\n");
50949
+ const startLine = Math.max(0, line - 1 - contextLines);
50950
+ const endLine = Math.min(lines.length, line + contextLines);
50951
+ const snippetLines = [];
50952
+ const lineNumWidth = String(endLine).length;
50953
+ for (let i5 = startLine; i5 < endLine; i5++) {
50954
+ const lineNum = String(i5 + 1).padStart(lineNumWidth, " ");
50955
+ const marker15 = i5 + 1 === line ? ">" : " ";
50956
+ snippetLines.push(`${marker15} ${lineNum} | ${lines[i5]}`);
50957
+ if (i5 + 1 === line) {
50958
+ const padding = " ".repeat(lineNumWidth + 4);
50959
+ const arrow = " ".repeat(Math.max(0, column - 1)) + "^";
50960
+ snippetLines.push(`${padding}${arrow}`);
50961
+ }
50962
+ }
50963
+ return snippetLines.join("\n");
50964
+ }
50965
+ function formatErrorWithSnippet(message, code, offset2 = -1, line = 0, column = 0) {
50966
+ if (offset2 >= 0) {
50967
+ const loc = offsetToLineColumn(code, offset2);
50968
+ line = loc.line;
50969
+ column = loc.column;
50970
+ }
50971
+ if (line <= 0) {
50972
+ return message;
50973
+ }
50974
+ const snippet = generateErrorSnippet(code, line, column);
50975
+ return `${message}
50976
+
50977
+ ${snippet}`;
50978
+ }
50933
50979
  function validateDSL(code) {
50934
50980
  const errors = [];
50935
50981
  let ast;
@@ -50937,40 +50983,54 @@ function validateDSL(code) {
50937
50983
  ast = parse3(code, {
50938
50984
  ecmaVersion: 2022,
50939
50985
  sourceType: "script",
50940
- allowReturnOutsideFunction: true
50986
+ allowReturnOutsideFunction: true,
50987
+ locations: true
50988
+ // Enable location tracking for better error messages
50941
50989
  });
50942
50990
  } catch (e5) {
50943
- return { valid: false, errors: [`Syntax error: ${e5.message}`] };
50991
+ const line = e5.loc?.line || 0;
50992
+ const column = e5.loc?.column ? e5.loc.column + 1 : 0;
50993
+ const formattedError = formatErrorWithSnippet(
50994
+ `Syntax error: ${e5.message}`,
50995
+ code,
50996
+ -1,
50997
+ line,
50998
+ column
50999
+ );
51000
+ return { valid: false, errors: [formattedError] };
50944
51001
  }
51002
+ const addError = (message, position) => {
51003
+ errors.push(formatErrorWithSnippet(message, code, position));
51004
+ };
50945
51005
  full(ast, (node) => {
50946
51006
  if (!ALLOWED_NODE_TYPES.has(node.type)) {
50947
- errors.push(`Blocked node type: ${node.type} at position ${node.start}`);
51007
+ addError(`Blocked node type: ${node.type}`, node.start);
50948
51008
  return;
50949
51009
  }
50950
51010
  if ((node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") && node.async) {
50951
- errors.push(`Async functions are not allowed at position ${node.start}. Write synchronous code \u2014 the runtime handles async.`);
51011
+ addError(`Async functions are not allowed. Write synchronous code \u2014 the runtime handles async.`, node.start);
50952
51012
  }
50953
51013
  if (node.type === "FunctionExpression" && node.generator) {
50954
- errors.push(`Generator functions are not allowed at position ${node.start}`);
51014
+ addError(`Generator functions are not allowed`, node.start);
50955
51015
  }
50956
51016
  if (node.type === "Identifier" && BLOCKED_IDENTIFIERS.has(node.name)) {
50957
- errors.push(`Blocked identifier: '${node.name}' at position ${node.start}`);
51017
+ addError(`Blocked identifier: '${node.name}'`, node.start);
50958
51018
  }
50959
51019
  if (node.type === "MemberExpression" && !node.computed) {
50960
51020
  if (node.property.type === "Identifier" && BLOCKED_PROPERTIES.has(node.property.name)) {
50961
- errors.push(`Blocked property access: '.${node.property.name}' at position ${node.property.start}`);
51021
+ addError(`Blocked property access: '.${node.property.name}'`, node.property.start);
50962
51022
  }
50963
51023
  }
50964
51024
  if (node.type === "MemberExpression" && node.computed) {
50965
51025
  if (node.property.type === "Literal" && typeof node.property.value === "string") {
50966
51026
  if (BLOCKED_PROPERTIES.has(node.property.value) || BLOCKED_IDENTIFIERS.has(node.property.value)) {
50967
- errors.push(`Blocked computed property access: '["${node.property.value}"]' at position ${node.property.start}`);
51027
+ addError(`Blocked computed property access: '["${node.property.value}"]'`, node.property.start);
50968
51028
  }
50969
51029
  }
50970
51030
  }
50971
51031
  if (node.type === "VariableDeclarator" && node.id.type === "Identifier") {
50972
51032
  if (BLOCKED_IDENTIFIERS.has(node.id.name)) {
50973
- errors.push(`Cannot declare variable with blocked name: '${node.id.name}' at position ${node.id.start}`);
51033
+ addError(`Cannot declare variable with blocked name: '${node.id.name}'`, node.id.start);
50974
51034
  }
50975
51035
  }
50976
51036
  });
@@ -51294,7 +51354,16 @@ function generateSandboxGlobals(options) {
51294
51354
  }
51295
51355
  if (llmCall) {
51296
51356
  const rawLLM = async (instruction, data3, opts = {}) => {
51297
- return llmCall(instruction, data3, opts);
51357
+ const result = await llmCall(instruction, data3, opts);
51358
+ if (opts.schema && typeof result === "string") {
51359
+ try {
51360
+ return JSON.parse(result);
51361
+ } catch (e5) {
51362
+ logFn?.("[LLM] Warning: schema provided but result is not valid JSON");
51363
+ return result;
51364
+ }
51365
+ }
51366
+ return result;
51298
51367
  };
51299
51368
  globals.LLM = traceToolCall("LLM", rawLLM, tracer, logFn);
51300
51369
  }
@@ -51351,6 +51420,54 @@ function generateSandboxGlobals(options) {
51351
51420
  }
51352
51421
  return chunks;
51353
51422
  };
51423
+ globals.chunkByKey = (data3, keyFn, maxTokens = 2e4) => {
51424
+ const CHARS_PER_TOKEN3 = 4;
51425
+ const maxChars = maxTokens * CHARS_PER_TOKEN3;
51426
+ const text = typeof data3 === "string" ? data3 : JSON.stringify(data3);
51427
+ const blockRegex = /^File: ([^\n]+)/gm;
51428
+ const markers = [];
51429
+ let match2;
51430
+ while ((match2 = blockRegex.exec(text)) !== null) {
51431
+ markers.push({ index: match2.index, file: match2[1].trim() });
51432
+ }
51433
+ if (markers.length === 0) {
51434
+ return globals.chunk(data3, maxTokens);
51435
+ }
51436
+ const chunks = [];
51437
+ let currentChunk = "";
51438
+ let currentSize = 0;
51439
+ let keysInChunk = /* @__PURE__ */ new Set();
51440
+ for (let i5 = 0; i5 < markers.length; i5++) {
51441
+ const start = markers[i5].index;
51442
+ const end = i5 + 1 < markers.length ? markers[i5 + 1].index : text.length;
51443
+ const block = text.slice(start, end).trim();
51444
+ const file = markers[i5].file;
51445
+ const key = typeof keyFn === "function" ? keyFn(file) : file;
51446
+ const blockSize = block.length + 2;
51447
+ const wouldOverflow = currentSize + blockSize > maxChars;
51448
+ const keyAlreadyInChunk = keysInChunk.has(key);
51449
+ if (!keyAlreadyInChunk && wouldOverflow && currentChunk) {
51450
+ chunks.push(currentChunk.trim());
51451
+ currentChunk = "";
51452
+ currentSize = 0;
51453
+ keysInChunk = /* @__PURE__ */ new Set();
51454
+ }
51455
+ if (currentChunk) currentChunk += "\n\n";
51456
+ currentChunk += block;
51457
+ currentSize += blockSize;
51458
+ keysInChunk.add(key);
51459
+ }
51460
+ if (currentChunk.trim()) {
51461
+ chunks.push(currentChunk.trim());
51462
+ }
51463
+ return chunks.length > 0 ? chunks : [""];
51464
+ };
51465
+ globals.extractPaths = (searchResults) => {
51466
+ const text = typeof searchResults === "string" ? searchResults : JSON.stringify(searchResults);
51467
+ const matches = text.match(/^File: ([^\n]+)/gm) || [];
51468
+ const paths = matches.map((m5) => m5.replace("File: ", "").trim());
51469
+ return [...new Set(paths)];
51470
+ };
51354
51471
  globals.log = (message) => {
51355
51472
  if (globals._logs) globals._logs.push(String(message));
51356
51473
  };
@@ -58284,10 +58401,32 @@ var init_esm5 = __esm({
58284
58401
  });
58285
58402
 
58286
58403
  // src/tools/executePlan.js
58404
+ function decodeHtmlEntities(str) {
58405
+ const entities = {
58406
+ "&amp;": "&",
58407
+ "&lt;": "<",
58408
+ "&gt;": ">",
58409
+ "&quot;": '"',
58410
+ "&apos;": "'",
58411
+ "&#39;": "'",
58412
+ "&#x27;": "'"
58413
+ };
58414
+ let result = str.replace(/&(?:amp|lt|gt|quot|apos|#39|#x27);/gi, (match2) => {
58415
+ return entities[match2.toLowerCase()] || match2;
58416
+ });
58417
+ result = result.replace(/&#(\d+);/g, (match2, dec) => {
58418
+ return String.fromCharCode(parseInt(dec, 10));
58419
+ });
58420
+ result = result.replace(/&#x([0-9a-f]+);/gi, (match2, hex) => {
58421
+ return String.fromCharCode(parseInt(hex, 16));
58422
+ });
58423
+ return result;
58424
+ }
58287
58425
  function stripCodeWrapping(code) {
58288
58426
  let s5 = String(code || "");
58289
58427
  s5 = s5.replace(/^```(?:javascript|js)?\n?/gm, "").replace(/```$/gm, "");
58290
58428
  s5 = s5.replace(/<\/?(?:execute_plan|code)>/g, "");
58429
+ s5 = decodeHtmlEntities(s5);
58291
58430
  return s5.trim();
58292
58431
  }
58293
58432
  function buildToolImplementations(configOptions) {
@@ -58573,6 +58712,26 @@ Last error: ${lastError}`;
58573
58712
  }
58574
58713
  });
58575
58714
  }
58715
+ function extractRawOutputBlocks(content, outputBuffer = null) {
58716
+ if (typeof content !== "string") {
58717
+ return { cleanedContent: content, extractedBlocks: [] };
58718
+ }
58719
+ const extractedBlocks = [];
58720
+ const regex = new RegExp(`${RAW_OUTPUT_START}\\n([\\s\\S]*?)\\n${RAW_OUTPUT_END}`, "g");
58721
+ let cleanedContent = content;
58722
+ let match2;
58723
+ while ((match2 = regex.exec(content)) !== null) {
58724
+ extractedBlocks.push(match2[1]);
58725
+ }
58726
+ cleanedContent = content.replace(new RegExp(`${RAW_OUTPUT_START}\\n[\\s\\S]*?\\n${RAW_OUTPUT_END}`, "g"), "").replace(/\n\n\[The above raw output \(\d+ chars\) will be passed directly to the final response\. Do NOT repeat, summarize, or modify it\.\]/g, "").trim();
58727
+ if (outputBuffer && extractedBlocks.length > 0) {
58728
+ for (const block of extractedBlocks) {
58729
+ outputBuffer.items = outputBuffer.items || [];
58730
+ outputBuffer.items.push(block);
58731
+ }
58732
+ }
58733
+ return { cleanedContent, extractedBlocks };
58734
+ }
58576
58735
  function formatSuccess(result, description, attempt, outputBuffer) {
58577
58736
  let output = "";
58578
58737
  if (description) {
@@ -58609,10 +58768,15 @@ ${JSON.stringify(resultValue, null, 2)}`;
58609
58768
  }
58610
58769
  }
58611
58770
  if (outputBuffer && outputBuffer.items && outputBuffer.items.length > 0) {
58612
- const totalChars = outputBuffer.items.reduce((sum, item) => sum + item.length, 0);
58771
+ const rawContent = outputBuffer.items.join("\n");
58613
58772
  output += `
58614
58773
 
58615
- [Output buffer: ${totalChars} chars written via output(). This content will be appended directly to your response. Do NOT repeat or summarize it.]`;
58774
+ ${RAW_OUTPUT_START}
58775
+ ${rawContent}
58776
+ ${RAW_OUTPUT_END}`;
58777
+ output += `
58778
+
58779
+ [The above raw output (${rawContent.length} chars) will be passed directly to the final response. Do NOT repeat, summarize, or modify it.]`;
58616
58780
  }
58617
58781
  return output;
58618
58782
  }
@@ -59061,7 +59225,7 @@ Example:
59061
59225
  <clearOutputBuffer>true</clearOutputBuffer>
59062
59226
  </cleanup_execute_plan>`;
59063
59227
  }
59064
- var import_ai4;
59228
+ var import_ai4, RAW_OUTPUT_START, RAW_OUTPUT_END;
59065
59229
  var init_executePlan = __esm({
59066
59230
  "src/tools/executePlan.js"() {
59067
59231
  "use strict";
@@ -59073,6 +59237,8 @@ var init_executePlan = __esm({
59073
59237
  init_extract();
59074
59238
  init_delegate();
59075
59239
  init_esm5();
59240
+ RAW_OUTPUT_START = "<<<RAW_OUTPUT>>>";
59241
+ RAW_OUTPUT_END = "<<<END_RAW_OUTPUT>>>";
59076
59242
  }
59077
59243
  });
59078
59244
 
@@ -97220,7 +97386,7 @@ __export(schemaUtils_exports, {
97220
97386
  createJsonCorrectionPrompt: () => createJsonCorrectionPrompt,
97221
97387
  createMermaidCorrectionPrompt: () => createMermaidCorrectionPrompt,
97222
97388
  createSchemaDefinitionCorrectionPrompt: () => createSchemaDefinitionCorrectionPrompt,
97223
- decodeHtmlEntities: () => decodeHtmlEntities,
97389
+ decodeHtmlEntities: () => decodeHtmlEntities2,
97224
97390
  extractMermaidFromJson: () => extractMermaidFromJson,
97225
97391
  extractMermaidFromMarkdown: () => extractMermaidFromMarkdown,
97226
97392
  generateExampleFromSchema: () => generateExampleFromSchema,
@@ -97325,7 +97491,7 @@ function enforceNoAdditionalProperties(schema) {
97325
97491
  applyRecursively(cloned);
97326
97492
  return cloned;
97327
97493
  }
97328
- function decodeHtmlEntities(text) {
97494
+ function decodeHtmlEntities2(text) {
97329
97495
  if (!text || typeof text !== "string") {
97330
97496
  return text;
97331
97497
  }
@@ -98768,7 +98934,7 @@ When presented with a broken Mermaid diagram, analyze it thoroughly and provide
98768
98934
  * @returns {Promise<string>} - The corrected Mermaid diagram
98769
98935
  */
98770
98936
  async fixMermaidDiagram(diagramContent, originalErrors = [], diagramInfo = {}) {
98771
- const decodedContent = decodeHtmlEntities(diagramContent);
98937
+ const decodedContent = decodeHtmlEntities2(diagramContent);
98772
98938
  if (decodedContent !== diagramContent) {
98773
98939
  try {
98774
98940
  const quickValidation = await validateMermaidDiagram(decodedContent);
@@ -110083,6 +110249,7 @@ var init_ProbeAgent = __esm({
110083
110249
  init_path_validation();
110084
110250
  init_outputTruncator();
110085
110251
  init_delegate();
110252
+ init_executePlan();
110086
110253
  init_tasks();
110087
110254
  import_dotenv2.default.config();
110088
110255
  ENGINE_ACTIVITY_TIMEOUT_DEFAULT = 18e4;
@@ -112814,6 +112981,15 @@ You are working with a workspace. Available paths: ${workspaceDesc}
112814
112981
  }
112815
112982
  const executionResult = await this.mcpBridge.mcpTools[toolName].execute(params);
112816
112983
  let toolResultContent = typeof executionResult === "string" ? executionResult : JSON.stringify(executionResult, null, 2);
112984
+ if (this._outputBuffer) {
112985
+ const { cleanedContent, extractedBlocks } = extractRawOutputBlocks(toolResultContent, this._outputBuffer);
112986
+ if (extractedBlocks.length > 0) {
112987
+ toolResultContent = cleanedContent;
112988
+ if (this.debug) {
112989
+ console.log(`[DEBUG] Extracted ${extractedBlocks.length} raw output blocks (${extractedBlocks.reduce((sum, b5) => sum + b5.length, 0)} chars) to output buffer`);
112990
+ }
112991
+ }
112992
+ }
112817
112993
  try {
112818
112994
  const truncateResult = await truncateIfNeeded(toolResultContent, this.tokenCounter, this.sessionId, this.maxOutputTokens);
112819
112995
  if (truncateResult.truncated) {
@@ -113020,6 +113196,15 @@ ${errorXml}
113020
113196
  const wsPrefix = this.workspaceRoot.endsWith(import_path17.sep) ? this.workspaceRoot : this.workspaceRoot + import_path17.sep;
113021
113197
  toolResultContent = toolResultContent.split(wsPrefix).join("");
113022
113198
  }
113199
+ if (this._outputBuffer) {
113200
+ const { cleanedContent, extractedBlocks } = extractRawOutputBlocks(toolResultContent, this._outputBuffer);
113201
+ if (extractedBlocks.length > 0) {
113202
+ toolResultContent = cleanedContent;
113203
+ if (this.debug) {
113204
+ console.log(`[DEBUG] Extracted ${extractedBlocks.length} raw output blocks (${extractedBlocks.reduce((sum, b5) => sum + b5.length, 0)} chars) to output buffer`);
113205
+ }
113206
+ }
113207
+ }
113023
113208
  try {
113024
113209
  const truncateResult = await truncateIfNeeded(toolResultContent, this.tokenCounter, this.sessionId, this.maxOutputTokens);
113025
113210
  if (truncateResult.truncated) {