Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion packages/dbgpt-core/src/dbgpt/agent/util/react_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from dataclasses import dataclass
from typing import Any, List, Optional

from dbgpt.vis.tags.vis_thinking import VisThinking


@dataclass
class ReActStep:
Expand Down Expand Up @@ -61,6 +63,37 @@ def __init__(
self.action_input_prefix_escaped = re.escape(action_input_prefix)
self.observation_prefix_escaped = re.escape(observation_prefix)

def _strip_leading_vis_thinking_block(self, text: str) -> str:
"""Remove the leading vis-thinking wrapper produced by VisThinking."""
if not text:
return text

stripped = text.lstrip()
fence = "`" * 6
opening = f"{fence}{VisThinking.vis_tag()}"
if not stripped.startswith(opening):
return text

lines = stripped.splitlines()
if len(lines) < 3 or lines[0].strip() != opening:
return text

closing_index = None
for idx in range(1, len(lines)):
if lines[idx].strip() == fence:
trailing_content = "\n".join(lines[idx + 1 :]).lstrip()
if not trailing_content or trailing_content.startswith(
self.thought_prefix
):
closing_index = idx
break

if closing_index is None:
return text

stripped_content = "\n".join(lines[closing_index + 1 :]).lstrip()
return stripped_content

def parse(self, text: str) -> List[ReActStep]:
"""
Parse the ReAct format output text into structured steps.
Expand All @@ -76,7 +109,7 @@ def parse(self, text: str) -> List[ReActStep]:
steps = []

# Remove any leading/trailing whitespace
text = text.strip()
text = self._strip_leading_vis_thinking_block(text).strip()

# Find all instances of the thought prefix
thought_matches = list(re.finditer(rf"{self.thought_prefix_escaped}\s*", text))
Expand Down
Loading