This commit is contained in:
AI Christianson 2025-03-07 19:56:40 -05:00 committed by Will
parent 1272e80800
commit 26ecc05de8
7 changed files with 207 additions and 3 deletions

View File

@ -620,6 +620,8 @@ class CiaynAgent:
self.chat_history.append(HumanMessage(content=base_prompt))
full_history = self._trim_chat_history(initial_messages, self.chat_history)
response = self.model.invoke([self.sys_message] + full_history)
print("RESPONSE")
print(response.content)
# Check if the response is empty or doesn't contain a valid tool call
if not response.content or not response.content.strip():

View File

@ -165,6 +165,15 @@ models_params = {
"latency_coefficient": DEFAULT_BASE_LATENCY,
},
},
"openai-compatible": {
"qwen-qwq-32b": {
"token_limit": 130000,
"think_tag": True,
"supports_temperature": True,
"latency_coefficient": DEFAULT_BASE_LATENCY,
"max_tokens": 64000,
}
},
"azure_openai": {
"gpt-3.5-turbo-0125": {
"token_limit": 16385,

View File

@ -1,3 +1,3 @@
from .processing import truncate_output
from .processing import truncate_output, extract_think_tag
__all__ = ["truncate_output"]
__all__ = ["truncate_output", "extract_think_tag"]

View File

@ -1,4 +1,5 @@
from typing import Optional
from typing import Optional, Tuple
import re
def truncate_output(output: str, max_lines: Optional[int] = 5000) -> str:
@ -41,3 +42,29 @@ def truncate_output(output: str, max_lines: Optional[int] = 5000) -> str:
# Combine message with remaining lines
return truncation_msg + "".join(truncated_lines)
def extract_think_tag(text: str) -> Tuple[Optional[str], str]:
"""Extract content from the first <think>...</think> tag at the start of a string.
Args:
text: Input string that may contain think tags
Returns:
A tuple containing:
- The extracted content from the first think tag (None if no tag found)
- The remaining string after the first think tag (or the original string if no tag found)
"""
# Pattern to match think tags at the start of the string
pattern = r'^\s*<think>(.*?)</think>'
match = re.search(pattern, text, re.DOTALL)
if match:
think_content = match.group(1)
# Get the index where the think tag ends
end_index = match.end()
# Extract the remaining text
remaining_text = text[end_index:]
return think_content, remaining_text
else:
return None, text

View File

@ -0,0 +1,63 @@
<think>
Okay, the user wants me to write a "hello world" program in C++. Let me think about the steps needed.
First, since it's a new project, there are no existing files. So I need to create a main C++ file. The standard entry point for C++ is a main.cpp or something similar. Let's name it main.cpp.
The code for "Hello World" in C++ typically includes the iostream header and uses std::cout. So the code would be:
#include <iostream>
using namespace std;
int main() {
cout << "Hello, world!" << endl;
return 0;
}
Wait, but maybe I should check if there's a standard way. Alternatively, sometimes people use std::cout directly instead of the using directive. Maybe the better practice is to avoid the using namespace std; for clarity, so perhaps rewrite it as:
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
Hmm, but the user said to keep it simple. The first version is simpler for a beginner example. But maybe the second is better for standards. Let me think. Since the user said "keep it simple", the first version is okay, but I should make sure that the code compiles.
Next, the user is in a new project directory, so I need to create the main.cpp file. The function to use is request_task_implementation, which takes a task spec. The task spec should be a markdown detailing the steps. Wait, looking back at the available functions, the request_task_implementation function requires a task specification in markdown. So I need to structure that.
The task spec should describe creating the main.cpp file with the code. So the task_spec would be something like "Create a C++ file named main.cpp with the Hello World program. The program should include iostream, use std::cout to output 'Hello, world!' and end with a return 0; statement in main()".
Wait, but the user might prefer the using namespace std; to simplify. Let me check again. Since it's a simple example, using the using namespace is acceptable for brevity. So the code would be:
#include <iostream>
using namespace std;
int main() {
cout << "Hello, world!" << endl;
return 0;
}
Yes, that's standard. Now, to implement this, the correct function to use is request_task_implementation with that code. So the tool call would be to request_task_implementation with the task spec as a markdown string.
Alternatively, maybe I should first check if there's any existing files, but since it's a new project with 0 files, listing directories might be redundant. The efficiency guidelines say to avoid listing empty directories. So instead, proceed directly to creating the file.
Therefore, the correct tool call here is to call request_task_implementation with the task specification to create main.cpp with the code.
</think>
request_task_implementation('''Create a C++ source file named main.cpp containing a standard "Hello World" program.
Steps:
1. Create file main.cpp
2. Add the following content:
#include <iostream>
using namespace std;
int main() {
cout << "Hello, world!" << endl;
return 0;
}
Acceptance Criteria:
- The program compiles without errors using g++ main.cpp -o hello
- Running ./hello outputs exactly "Hello, world!" followed by a newline
''')

View File

@ -0,0 +1 @@
# This file makes the directory a Python package.

View File

@ -0,0 +1,102 @@
import os
import pytest
from ra_aid.text.processing import extract_think_tag
def test_basic_extraction():
"""Test basic extraction of think tag content."""
content = "<think>This is a test</think>Remaining content"
expected_extracted = "This is a test"
expected_remaining = "Remaining content"
extracted, remaining = extract_think_tag(content)
assert extracted == expected_extracted
assert remaining == expected_remaining
def test_multiline_extraction():
"""Test extraction of multiline think tag content."""
content = "<think>Line 1\nLine 2\nLine 3</think>Remaining content"
expected_extracted = "Line 1\nLine 2\nLine 3"
expected_remaining = "Remaining content"
extracted, remaining = extract_think_tag(content)
assert extracted == expected_extracted
assert remaining == expected_remaining
def test_multiple_think_tags():
"""Test that only the first think tag is extracted."""
content = "<think>First tag</think>Middle<think>Second tag</think>End"
expected_extracted = "First tag"
expected_remaining = "Middle<think>Second tag</think>End"
extracted, remaining = extract_think_tag(content)
assert extracted == expected_extracted
assert remaining == expected_remaining
def test_no_think_tag():
"""Test behavior when no think tag is present."""
content = "This is a string without a think tag"
extracted, remaining = extract_think_tag(content)
assert extracted is None
assert remaining == content
def test_empty_think_tag():
"""Test extraction of an empty think tag."""
content = "<think></think>Remaining content"
expected_extracted = ""
expected_remaining = "Remaining content"
extracted, remaining = extract_think_tag(content)
assert extracted == expected_extracted
assert remaining == expected_remaining
def test_whitespace_handling():
"""Test whitespace handling in think tag extraction."""
content = "<think> \n Content with whitespace \n </think>Remaining content"
expected_extracted = " \n Content with whitespace \n "
expected_remaining = "Remaining content"
extracted, remaining = extract_think_tag(content)
assert extracted == expected_extracted
assert remaining == expected_remaining
def test_tag_not_at_start():
"""Test behavior when think tag is not at the start of the string."""
content = "Some content before <think>Think content</think>Remaining content"
extracted, remaining = extract_think_tag(content)
assert extracted is None
assert remaining == content
def test_sample_data():
"""Test extraction using sample data from tests/data/think-tag/sample_1.txt."""
# Get the absolute path to the sample file
current_dir = os.path.dirname(os.path.abspath(__file__))
sample_file_path = os.path.join(current_dir, '..', '..', 'data', 'think-tag', 'sample_1.txt')
# Read the sample data
with open(sample_file_path, 'r', encoding='utf-8') as f:
sample_data = f.read()
# Extract the think tag
extracted, remaining = extract_think_tag(sample_data)
# Check that extraction worked
assert extracted is not None
assert "Okay, the user wants me to write a" in extracted
assert "return 0;" in extracted
# Check that we got the think tag content without the tags
assert not extracted.startswith("<think>")
assert not extracted.endswith("</think>")
# Check that the remaining content doesn't contain the think tag
assert "<think>" not in remaining
assert "</think>" not in remaining