mirror of
https://github.com/Aider-AI/aider.git
synced 2025-05-31 01:35:00 +00:00
refactor: Extract reasoning tag handling to separate module
This commit is contained in:
parent
d9551b3106
commit
e7f16f07f7
2 changed files with 72 additions and 43 deletions
|
@ -30,16 +30,16 @@ from aider.llm import litellm
|
|||
from aider.models import RETRY_TIMEOUT
|
||||
from aider.repo import ANY_GIT_ERROR, GitRepo
|
||||
from aider.repomap import RepoMap
|
||||
from aider.reasoning_tags import (
|
||||
REASONING_TAG, REASONING_START, REASONING_END,
|
||||
replace_reasoning_tags, format_reasoning_content, detect_reasoning_tag
|
||||
)
|
||||
from aider.run_cmd import run_cmd
|
||||
from aider.utils import format_content, format_messages, format_tokens, is_image_file
|
||||
|
||||
from ..dump import dump # noqa: F401
|
||||
from .chat_chunks import ChatChunks
|
||||
|
||||
REASONING_TAG = "thinking-content-" + "7bbeb8e1441453ad999a0bbba8a46d4b"
|
||||
REASONING_START = "> Thinking ..."
|
||||
REASONING_END = "> ... done thinking.\n\n------"
|
||||
|
||||
|
||||
class UnknownEditFormat(ValueError):
|
||||
def __init__(self, edit_format, valid_formats):
|
||||
|
@ -1697,39 +1697,7 @@ class Coder:
|
|||
if args:
|
||||
self.io.ai_output(json.dumps(args, indent=4))
|
||||
|
||||
def replace_reasoning_tags(self, text):
|
||||
"""
|
||||
Replace opening and closing reasoning tags with standard formatting.
|
||||
Ensures exactly one blank line before START and END markers.
|
||||
|
||||
Args:
|
||||
text (str): The text containing the tags
|
||||
|
||||
Returns:
|
||||
str: Text with reasoning tags replaced with standard format
|
||||
"""
|
||||
if not text:
|
||||
return text
|
||||
|
||||
# Helper function to ensure exactly one blank line before replacement
|
||||
def ensure_one_blank_line(match):
|
||||
content_before = match.string[: match.start()].rstrip()
|
||||
# If we're not at the start of the text, add exactly one blank line
|
||||
if content_before:
|
||||
return f"{content_before}\n\n{match.group(1)}"
|
||||
# If we're at the start, don't add extra newlines
|
||||
return match.group(1)
|
||||
|
||||
# Replace opening tag with proper spacing
|
||||
text = re.sub(f"\\s*<{self.reasoning_tag_name}>\\s*", f"\n{REASONING_START}\n\n", text)
|
||||
|
||||
# Replace closing tag with proper spacing
|
||||
text = re.sub(f"\\s*</{self.reasoning_tag_name}>\\s*", f"\n\n{REASONING_END}\n\n", text)
|
||||
|
||||
# Clean up any excessive newlines (more than 2 consecutive)
|
||||
text = re.sub(r"\n{3,}", "\n\n", text)
|
||||
|
||||
return text
|
||||
# Moved to aider/reasoning_tags.py
|
||||
|
||||
def show_send_output(self, completion):
|
||||
if self.verbose:
|
||||
|
@ -1774,12 +1742,7 @@ class Coder:
|
|||
show_resp = self.render_incremental_response(True)
|
||||
|
||||
if reasoning_content:
|
||||
formatted_reasoning = (
|
||||
f"<{self.reasoning_tag_name}>\n\n"
|
||||
+ reasoning_content
|
||||
+ f"\n\n</{self.reasoning_tag_name}>"
|
||||
)
|
||||
formatted_reasoning = self.replace_reasoning_tags(formatted_reasoning) + "\n\n"
|
||||
formatted_reasoning = format_reasoning_content(reasoning_content, self.reasoning_tag_name) + "\n\n"
|
||||
show_resp = formatted_reasoning + show_resp
|
||||
|
||||
self.io.assistant_output(show_resp, pretty=self.show_pretty())
|
||||
|
|
66
aider/reasoning_tags.py
Normal file
66
aider/reasoning_tags.py
Normal file
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
|
||||
# Standard tag identifier
|
||||
REASONING_TAG = "thinking-content-" + "7bbeb8e1441453ad999a0bbba8a46d4b"
|
||||
# Output formatting
|
||||
REASONING_START = "> Thinking ..."
|
||||
REASONING_END = "> ... done thinking.\n\n------"
|
||||
|
||||
def replace_reasoning_tags(text, tag_name):
|
||||
"""
|
||||
Replace opening and closing reasoning tags with standard formatting.
|
||||
Ensures exactly one blank line before START and END markers.
|
||||
|
||||
Args:
|
||||
text (str): The text containing the tags
|
||||
tag_name (str): The name of the tag to replace
|
||||
|
||||
Returns:
|
||||
str: Text with reasoning tags replaced with standard format
|
||||
"""
|
||||
if not text:
|
||||
return text
|
||||
|
||||
# Replace opening tag with proper spacing
|
||||
text = re.sub(f"\\s*<{tag_name}>\\s*", f"\n{REASONING_START}\n\n", text)
|
||||
|
||||
# Replace closing tag with proper spacing
|
||||
text = re.sub(f"\\s*</{tag_name}>\\s*", f"\n\n{REASONING_END}\n\n", text)
|
||||
|
||||
# Clean up any excessive newlines (more than 2 consecutive)
|
||||
text = re.sub(r"\n{3,}", "\n\n", text)
|
||||
|
||||
return text
|
||||
|
||||
def format_reasoning_content(reasoning_content, tag_name):
|
||||
"""
|
||||
Format reasoning content with appropriate tags.
|
||||
|
||||
Args:
|
||||
reasoning_content (str): The content to format
|
||||
tag_name (str): The tag name to use
|
||||
|
||||
Returns:
|
||||
str: Formatted reasoning content with tags
|
||||
"""
|
||||
if not reasoning_content:
|
||||
return ""
|
||||
|
||||
formatted = f"<{tag_name}>\n\n{reasoning_content}\n\n</{tag_name}>"
|
||||
return replace_reasoning_tags(formatted, tag_name)
|
||||
|
||||
def detect_reasoning_tag(text, tag_name):
|
||||
"""
|
||||
Detect if text contains reasoning tags.
|
||||
|
||||
Args:
|
||||
text (str): The text to check
|
||||
tag_name (str): The tag name to look for
|
||||
|
||||
Returns:
|
||||
bool: True if text contains reasoning tags
|
||||
"""
|
||||
opening_pattern = f"<{tag_name}>"
|
||||
return opening_pattern in text
|
Loading…
Add table
Add a link
Reference in a new issue