f6d3d758aa
---ci--- phase: 4 milestone: v0.2 status: complete ---/ci--- REQ-2-007/008 complete. Lab streams scenario-driven in-flow feedback over mock telemetry; Assessor returns pydantic-validated rubric scores via 4-layer defense. Endpoints /v1/lab/feedback + /v1/assessment/ evaluate. D-021-aligned corpora both sides. 110/110 tests, ruff + tsc green, lockfile integrity restored.
43 lines
1.6 KiB
Python
43 lines
1.6 KiB
Python
"""Lab agent tests — scenario-driven streaming feedback (REQ-2-007)."""
|
|
|
|
from ai_service.agents.lab import LabAgent
|
|
from ai_service.config import Settings
|
|
from ai_service.corpus.learner_context import get_learner_context
|
|
from ai_service.corpus.telemetry import get_lab_scenario, summarize_scenario
|
|
from ai_service.llm.mock import MockProvider
|
|
|
|
|
|
def make_lab() -> LabAgent:
|
|
return LabAgent(MockProvider(), Settings(provider="mock"))
|
|
|
|
|
|
def test_system_prompt_names_lab_persona():
|
|
prompt = make_lab().system_prompt(get_learner_context())
|
|
assert "Lab" in prompt
|
|
assert "Alex Rivera" in prompt
|
|
assert "telemetry" in prompt.lower()
|
|
|
|
|
|
async def test_stream_feedback_mentions_scenario_events():
|
|
"""Mock-scripted: feedback text derives from scenario timeline input —
|
|
distinct scenarios produce distinct (deterministic) replies."""
|
|
lab = make_lab()
|
|
ctx = get_learner_context()
|
|
strong = get_lab_scenario("lab-scenario-strong")
|
|
struggling = get_lab_scenario("lab-scenario-struggling")
|
|
|
|
strong_reply = "".join([t async for t in lab.stream_feedback(strong, ctx)])
|
|
struggling_reply = "".join([t async for t in lab.stream_feedback(struggling, ctx)])
|
|
assert strong_reply
|
|
assert strong_reply != struggling_reply # scenario-driven, not canned
|
|
|
|
|
|
def test_build_evaluation_messages_carry_timeline():
|
|
lab = make_lab()
|
|
scenario = get_lab_scenario("lab-scenario-flagged")
|
|
timeline = summarize_scenario(scenario)
|
|
messages = lab.build_messages(None, timeline, get_learner_context())
|
|
assert messages[0].role == "system"
|
|
assert "paste" in messages[-1].content
|
|
assert "2,400 chars" in messages[-1].content
|