Spaces:
Running
Running
Download tests/test_model_reply_passthrough.py from Deign86/mathpulse-api-v3test: direct link, hf CLI and curl.
- Browser
- Download file 3.37 kB
-
https://huggingface.co/spaces/Deign86/mathpulse-api-v3test/resolve/main/tests/test_model_reply_passthrough.py
- Command line
-
hf download hf://spaces/Deign86/mathpulse-api-v3test/tests/test_model_reply_passthrough.py
-
curl -L -o test_model_reply_passthrough.py https://huggingface.co/spaces/Deign86/mathpulse-api-v3test/resolve/main/tests/test_model_reply_passthrough.py
3.37 kB
| """Model replies reach their callers whole. | |
| call_hf_chat used to pass every non-streaming reply through a repetition stripper written for small models that | |
| looped. It took ordinary Markdown paragraphs for repeats and deleted them: a tutor reply came back as its last | |
| paragraph, a first-turn chat came back empty, and pretty-printed quiz JSON stopped parsing. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import os | |
| import sys | |
| import pytest | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) | |
| import main | |
| TUTOR_PARAGRAPHS = [ | |
| "Great question! Finding the domain of a rational function comes down to one idea.", | |
| "**Step 1:** Look at the denominator, because division by zero is undefined for every real number.", | |
| "**Step 2:** Set the denominator equal to zero and solve, so you know which x-values to exclude.", | |
| "What value of x makes x - 2 equal to zero?", | |
| "Once you find that value, think about what it means for the domain. Give it a try and tell me what you get!", | |
| ] | |
| TUTOR_REPLY = "\n\n".join(TUTOR_PARAGRAPHS) | |
| QUIZ_REPLY = json.dumps( | |
| [ | |
| { | |
| "questionType": "multiple_choice", | |
| "question": f"What is the domain of f(x) = 1/(x - {number})?", | |
| "options": [f"A) x != {number}", "B) all real numbers", "C) x > 0", "D) x < 0"], | |
| "correctAnswer": "A", | |
| "bloomLevel": "understand", | |
| "difficulty": "medium", | |
| "topic": "Domain and Range of Functions", | |
| "points": 1, | |
| "explanation": f"Division by zero is undefined, so x cannot equal {number}.", | |
| } | |
| for number in range(1, 11) | |
| ], | |
| indent=2, | |
| ) | |
| class ReplyingInferenceClient: | |
| """The inference client's contract: a request in, the model's reply text out.""" | |
| def __init__(self, reply: str) -> None: | |
| self.reply = reply | |
| def generate_from_messages(self, _request: object) -> str: | |
| return self.reply | |
| def serve_model_reply(monkeypatch: pytest.MonkeyPatch, reply: str) -> None: | |
| client = ReplyingInferenceClient(reply) | |
| monkeypatch.setattr(main, "get_inference_client", lambda: client) | |
| def test_call_hf_chat_returns_the_reply_unchanged(monkeypatch: pytest.MonkeyPatch, reply: str) -> None: | |
| serve_model_reply(monkeypatch, reply) | |
| assert main.call_hf_chat([{"role": "user", "content": "Help me"}], task_type="chat") == reply | |
| async def test_a_first_turn_chat_reply_reaches_the_student_whole(monkeypatch: pytest.MonkeyPatch) -> None: | |
| monkeypatch.setattr(main, "HAS_MEMORY_SERVICE", False) | |
| monkeypatch.setattr(main, "HAS_FIREBASE_ADMIN", False) | |
| monkeypatch.setattr(main, "retrieve_curriculum_context", lambda **_: []) | |
| monkeypatch.setattr(main, "retrieve_chat_context", lambda _message: "") | |
| async def route_intent(_message: str) -> dict[str, object]: | |
| return {"choice": "conceptual_confusion", "confidence": 0.91} | |
| monkeypatch.setattr(main, "route_student_intent", route_intent) | |
| serve_model_reply(monkeypatch, TUTOR_REPLY) | |
| response = await main.chat_tutor( | |
| main.ChatRequest(message="How do I find the domain of f(x) = (x + 1)/(x - 2)?") | |
| ) | |
| for paragraph in TUTOR_PARAGRAPHS: | |
| assert paragraph in response.response | |