diff --git a/ra_aid/models_params.py b/ra_aid/models_params.py
index 8c3652f..b4aa9af 100644
--- a/ra_aid/models_params.py
+++ b/ra_aid/models_params.py
@@ -171,7 +171,7 @@ models_params = {
"supports_think_tag": True,
"supports_temperature": True,
"latency_coefficient": DEFAULT_BASE_LATENCY,
- "max_tokens": 64000,
+ "max_tokens": 130000,
}
},
"azure_openai": {
diff --git a/ra_aid/tools/expert.py b/ra_aid/tools/expert.py
index aaf1044..f5be3c6 100644
--- a/ra_aid/tools/expert.py
+++ b/ra_aid/tools/expert.py
@@ -18,6 +18,8 @@ from ..llm import initialize_expert_llm
from ..model_formatters import format_key_facts_dict
from ..model_formatters.key_snippets_formatter import format_key_snippets_dict
from ..model_formatters.research_notes_formatter import format_research_notes_dict
+from ..models_params import models_params
+from ..text import extract_think_tag
console = Console()
_model = None
@@ -231,10 +233,38 @@ def ask_expert(question: str) -> str:
# Get the content from the response
content = response.content
+ logger.debug(f"Expert response content type: {type(content).__name__}")
+
+ # Check if model supports think tags
+ config_repo = get_config_repository()
+ provider = config_repo.get("expert_provider") or config_repo.get("provider")
+ model_name = config_repo.get("expert_model") or config_repo.get("model")
+ model_config = models_params.get(provider, {}).get(model_name, {})
+ supports_think_tag = model_config.get("supports_think_tag", False)
+ supports_thinking = model_config.get("supports_thinking", False)
+
+ logger.debug(f"Expert model: {provider}/{model_name}")
+ logger.debug(f"Model supports think tag: {supports_think_tag}")
+ logger.debug(f"Model supports thinking: {supports_thinking}")
# Handle thinking mode responses (content is a list) or regular responses (content is a string)
try:
- if isinstance(content, list):
+ # Case 1: Check for think tags if the model supports them
+ if (supports_think_tag or supports_thinking) and isinstance(content, str):
+ logger.debug("Checking for think tags in expert response")
+ think_content, remaining_text = extract_think_tag(content)
+ if think_content:
+ logger.debug(f"Found think tag content ({len(think_content)} chars)")
+ console.print(
+ Panel(Markdown(think_content), title="💠Thoughts", border_style="yellow")
+ )
+ content = remaining_text
+ else:
+ logger.debug("No think tag content found in expert response")
+
+ # Case 2: Handle structured thinking (content is a list of dictionaries)
+ elif isinstance(content, list):
+ logger.debug("Expert response content is a list, processing structured thinking")
# Extract thinking content and response text from structured response
thinking_content = None
response_text = None
@@ -245,12 +275,15 @@ def ask_expert(question: str) -> str:
# Extract thinking content
if item.get('type') == 'thinking' and 'thinking' in item:
thinking_content = item['thinking']
+ logger.debug("Found structured thinking content")
# Extract response text
elif item.get('type') == 'text' and 'text' in item:
response_text = item['text']
+ logger.debug("Found structured response text")
# Display thinking content in a separate panel if available
if thinking_content:
+ logger.debug(f"Displaying structured thinking content ({len(thinking_content)} chars)")
console.print(
Panel(Markdown(thinking_content), title="Expert Thinking", border_style="yellow")
)
@@ -260,6 +293,7 @@ def ask_expert(question: str) -> str:
content = response_text
else:
# Fallback: join list items if structured extraction failed
+ logger.debug("No structured response text found, joining list items")
content = "\n".join(str(item) for item in content)
except Exception as e:
diff --git a/tests/ra_aid/tools/test_expert_think_tag.py b/tests/ra_aid/tools/test_expert_think_tag.py
new file mode 100644
index 0000000..d37587e
--- /dev/null
+++ b/tests/ra_aid/tools/test_expert_think_tag.py
@@ -0,0 +1,155 @@
+"""Test the think tag functionality in the expert tool."""
+
+import pytest
+from unittest.mock import patch, MagicMock
+
+from ra_aid.text.processing import extract_think_tag
+
+
+def test_extract_think_tag_basic():
+ """Test basic functionality of extract_think_tag."""
+ # Test basic think tag extraction
+ text = "This is thinking contentThis is the response"
+ think_content, remaining_text = extract_think_tag(text)
+
+ assert think_content == "This is thinking content"
+ assert remaining_text == "This is the response"
+
+
+def test_extract_think_tag_multiline():
+ """Test extract_think_tag with multiline content."""
+ text = "Line 1\nLine 2\nLine 3This is the response"
+ think_content, remaining_text = extract_think_tag(text)
+
+ assert think_content == "Line 1\nLine 2\nLine 3"
+ assert remaining_text == "This is the response"
+
+
+def test_extract_think_tag_no_tag():
+ """Test extract_think_tag when no tag is present."""
+ text = "This is just regular text with no think tag"
+ think_content, remaining_text = extract_think_tag(text)
+
+ assert think_content is None
+ assert remaining_text == text
+
+
+def test_expert_think_tag_handling():
+ """Test the logic that would be used in the expert tool for think tag handling."""
+ # Mimic the implementation from expert.py
+ def process_expert_response(text, supports_think_tag=False):
+ """Simulate the expert tool's think tag handling."""
+ if supports_think_tag:
+ think_content, remaining_text = extract_think_tag(text)
+ if think_content:
+ # In the real implementation, this would display the thoughts
+ thoughts_displayed = True
+ return thoughts_displayed, think_content, remaining_text
+
+ # No think content extracted
+ return False, None, text
+
+ # Test with think tag and support enabled
+ thoughts_displayed, think_content, response = process_expert_response(
+ "Here's my reasoningFinal answer",
+ supports_think_tag=True
+ )
+ assert thoughts_displayed
+ assert think_content == "Here's my reasoning"
+ assert response == "Final answer"
+
+ # Test with think tag but support disabled
+ thoughts_displayed, think_content, response = process_expert_response(
+ "Here's my reasoningFinal answer",
+ supports_think_tag=False
+ )
+ assert not thoughts_displayed
+ assert think_content is None
+ assert response == "Here's my reasoningFinal answer"
+
+ # Test with no think tag
+ thoughts_displayed, think_content, response = process_expert_response(
+ "Just a regular response",
+ supports_think_tag=True
+ )
+ assert not thoughts_displayed
+ assert think_content is None
+ assert response == "Just a regular response"
+
+
+def test_expert_think_tag_with_supports_thinking():
+ """Test handling of the supports_thinking parameter."""
+ # Mimic the implementation from expert.py
+ def process_expert_response(text, supports_think_tag=False, supports_thinking=False):
+ """Simulate the expert tool's think tag handling with both parameters."""
+ if supports_think_tag or supports_thinking:
+ think_content, remaining_text = extract_think_tag(text)
+ if think_content:
+ # In the real implementation, this would display the thoughts
+ thoughts_displayed = True
+ return thoughts_displayed, think_content, remaining_text
+
+ # No think content extracted
+ return False, None, text
+
+ # Test with supports_thinking=True
+ thoughts_displayed, think_content, response = process_expert_response(
+ "Thinking with alternate parameterFinal answer",
+ supports_think_tag=False,
+ supports_thinking=True
+ )
+ assert thoughts_displayed
+ assert think_content == "Thinking with alternate parameter"
+ assert response == "Final answer"
+
+
+def test_expert_think_tag_combined_flags():
+ """Test that either flag (supports_think_tag or supports_thinking) enables extraction."""
+ # Mimic the implementation from expert.py
+ def process_expert_response(text, supports_think_tag=False, supports_thinking=False):
+ """Simulate the expert tool's think tag handling with both parameters."""
+ if supports_think_tag or supports_thinking:
+ think_content, remaining_text = extract_think_tag(text)
+ if think_content:
+ return think_content, remaining_text
+ return None, text
+
+ test_input = "Some thoughtsResponse text"
+
+ # Test with both flags False
+ think_content, response = process_expert_response(
+ test_input,
+ supports_think_tag=False,
+ supports_thinking=False
+ )
+ assert think_content is None
+ assert response == test_input
+
+ # Test with supports_think_tag=True
+ think_content, response = process_expert_response(
+ test_input,
+ supports_think_tag=True,
+ supports_thinking=False
+ )
+ assert think_content == "Some thoughts"
+ assert response == "Response text"
+
+ # Test with supports_thinking=True
+ think_content, response = process_expert_response(
+ test_input,
+ supports_think_tag=False,
+ supports_thinking=True
+ )
+ assert think_content == "Some thoughts"
+ assert response == "Response text"
+
+ # Test with both flags True
+ think_content, response = process_expert_response(
+ test_input,
+ supports_think_tag=True,
+ supports_thinking=True
+ )
+ assert think_content == "Some thoughts"
+ assert response == "Response text"
+
+