diff --git a/src/core/assistant-message/parseAssistantMessage.ts b/src/core/assistant-message/parseAssistantMessage.ts index 57238911e9..fc3dc18fef 100644 --- a/src/core/assistant-message/parseAssistantMessage.ts +++ b/src/core/assistant-message/parseAssistantMessage.ts @@ -12,6 +12,7 @@ export function parseAssistantMessage(assistantMessage: string): AssistantMessag let currentToolUseStartIndex = 0 let currentParamName: ToolParamName | undefined = undefined let currentParamValueStartIndex = 0 + let parameterNestingDepth = 0 let accumulator = "" let inFunctionCalls = false @@ -22,15 +23,28 @@ export function parseAssistantMessage(assistantMessage: string): AssistantMessag // Inside function_calls block, handle parameters (check this FIRST to avoid nested tag issues) if (currentToolUse && currentParamName) { const currentParamValue = accumulator.slice(currentParamValueStartIndex) + + // Check for nested opening tags within param value + if (currentParamValue.endsWith('= paramOpenPattern.length - 1 && + assistantMessage.startsWith(paramOpenPattern, currentCharIndex - paramOpenPattern.length + 1) + ) { + parameterNestingDepth++ + } + + // Check for closing tag const paramCloseTag = "" if ( currentCharIndex >= paramCloseTag.length - 1 && assistantMessage.startsWith(paramCloseTag, currentCharIndex - paramCloseTag.length + 1) ) { - // Found the closing tag for the parameter + if (parameterNestingDepth > 0) { + // This is a nested closing tag, decrement depth and continue + parameterNestingDepth-- + continue + } + // This is the actual closing tag for our parameter const value = assistantMessage.slice( currentParamValueStart, currentCharIndex - paramCloseTag.length + 1, @@ -69,6 +85,7 @@ export function parseAssistantMessageV2(assistantMessage: string): AssistantMess currentToolUse.params[currentParamName] = currentParamName === "content" ? value.replace(/^\n/, "").replace(/\n$/, "") : value.trim() currentParamName = undefined + parameterNestingDepth = 0 } else { continue // Still inside param value } @@ -159,6 +176,7 @@ export function parseAssistantMessageV2(assistantMessage: string): AssistantMess if (toolParamNames.includes(paramName as ToolParamName)) { currentParamName = paramName as ToolParamName currentParamValueStart = currentCharIndex + 1 + parameterNestingDepth = 0 } continue }