Introduce Socratic tutor turn counting logic to force wrap-up after 2 hints and add corresponding tests
Browse files- backend/main.py +11 -4
- backend/test_sentiment.py +30 -1
backend/main.py
CHANGED
|
@@ -127,10 +127,17 @@ def run_flow_b(message: str, api_key: str, history: Optional[List[ChatMessage]]
|
|
| 127 |
generation_config={"response_mime_type": "application/json"}
|
| 128 |
)
|
| 129 |
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
|
| 135 |
tone_instruction = (
|
| 136 |
"JSON: {\"s\":\"sentiment\",\"r\":\"reply\"}\n"
|
|
|
|
| 127 |
generation_config={"response_mime_type": "application/json"}
|
| 128 |
)
|
| 129 |
|
| 130 |
+
num_user_turns = sum(1 for m in history if m.role == "user") if history else 0
|
| 131 |
+
if num_user_turns >= 2:
|
| 132 |
+
custom_system = (
|
| 133 |
+
"Socratic tutor: You have already given multiple hints. Do not ask any more Socratic questions. "
|
| 134 |
+
"Provide the final direct answer/solution to the initial question immediately now, and ask: 'Do you want to learn something else?'"
|
| 135 |
+
)
|
| 136 |
+
else:
|
| 137 |
+
custom_system = (
|
| 138 |
+
"Socratic tutor: guide with clear, substantial hints. Continue unless close. "
|
| 139 |
+
"If close: give solution to the initial question & ask: 'Do you want to learn something else?'"
|
| 140 |
+
)
|
| 141 |
|
| 142 |
tone_instruction = (
|
| 143 |
"JSON: {\"s\":\"sentiment\",\"r\":\"reply\"}\n"
|
backend/test_sentiment.py
CHANGED
|
@@ -5,7 +5,7 @@ from unittest.mock import MagicMock, patch
|
|
| 5 |
# Add current directory to path for imports
|
| 6 |
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
| 7 |
|
| 8 |
-
from main import run_flow_b
|
| 9 |
|
| 10 |
def test_run_flow_b_parsing():
|
| 11 |
print("Testing run_flow_b parsing and extraction logic...")
|
|
@@ -30,5 +30,34 @@ def test_run_flow_b_parsing():
|
|
| 30 |
|
| 31 |
print("Mocked run_flow_b test passed!")
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
if __name__ == "__main__":
|
| 34 |
test_run_flow_b_parsing()
|
|
|
|
|
|
| 5 |
# Add current directory to path for imports
|
| 6 |
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
| 7 |
|
| 8 |
+
from main import run_flow_b, ChatMessage
|
| 9 |
|
| 10 |
def test_run_flow_b_parsing():
|
| 11 |
print("Testing run_flow_b parsing and extraction logic...")
|
|
|
|
| 30 |
|
| 31 |
print("Mocked run_flow_b test passed!")
|
| 32 |
|
| 33 |
+
def test_run_flow_b_force_wrap_up():
|
| 34 |
+
print("Testing force wrap-up system prompt switch...")
|
| 35 |
+
|
| 36 |
+
mock_response = MagicMock()
|
| 37 |
+
mock_response.content = '{"s": "neutral", "r": "The answer is 4. Do you want to learn something else?"}'
|
| 38 |
+
|
| 39 |
+
with patch("main.ChatGoogleGenerativeAI") as MockLLM:
|
| 40 |
+
mock_llm_instance = MagicMock()
|
| 41 |
+
mock_llm_instance.invoke.return_value = mock_response
|
| 42 |
+
MockLLM.return_value = mock_llm_instance
|
| 43 |
+
|
| 44 |
+
history = [
|
| 45 |
+
ChatMessage(role="user", content="What is 2x = 4?"),
|
| 46 |
+
ChatMessage(role="assistant", content="What do you think?"),
|
| 47 |
+
ChatMessage(role="user", content="I don't know"),
|
| 48 |
+
ChatMessage(role="assistant", content="Try dividing both sides by 2.")
|
| 49 |
+
]
|
| 50 |
+
|
| 51 |
+
state, reply, context, est_in, est_out = run_flow_b(
|
| 52 |
+
message="Still confused.",
|
| 53 |
+
api_key="fake-api-key",
|
| 54 |
+
history=history
|
| 55 |
+
)
|
| 56 |
+
|
| 57 |
+
# Verify that the force wrap-up system prompt was selected
|
| 58 |
+
assert "do not ask any more socratic questions" in context.lower()
|
| 59 |
+
print("Mocked force wrap-up test passed!")
|
| 60 |
+
|
| 61 |
if __name__ == "__main__":
|
| 62 |
test_run_flow_b_parsing()
|
| 63 |
+
test_run_flow_b_force_wrap_up()
|