File size: 3,466 Bytes
2e818da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import pytest

from app.schemas.commit_adaptation import CommitAdaptationReview
from app.services.agent_control import AgentControlService


def test_manual_profile_override_beats_inferred_profile(tmp_path):
    service = AgentControlService(root=str(tmp_path))

    service.update_profile("p1", scope="student", text="Student prefers proofs first.", source="inferred")
    service.update_profile("p1", scope="student", text="Student wants mechanisms before examples.", source="manual")
    service.update_profile("p1", scope="student", text="Student prefers analogy first.", source="inferred")

    profile = service.get_profile("p1")

    assert profile["student"]["manual_text"] == "Student wants mechanisms before examples."
    assert profile["student"]["inferred_text"] == "Student prefers analogy first."
    preview = service.preview("p1", agent_id="tutor")
    layer_names = [layer["name"] for layer in preview["layers"]]
    assert "Base Contract" in layer_names
    assert "Student Profile" in layer_names
    assert "Student wants mechanisms before examples." in preview["composed_prompt"]
    assert "Student prefers analogy first." not in preview["composed_prompt"]


def test_skill_update_reset_and_evolution_history(tmp_path):
    service = AgentControlService(root=str(tmp_path))

    service.update_skill("p1", "tutor", "Start with formal mechanism.")
    service.record_evolution("p1", "persona_update", "Persona engine updated from Commit.", {"source": "commit"})

    assert service.get_skills("p1")["skills"]["tutor"]["manual_text"] == "Start with formal mechanism."
    assert service.get_evolution("p1")[0]["message"] == "Persona engine updated from Commit."

    service.reset("p1", scope="skills")

    assert service.get_skills("p1")["skills"]["tutor"]["manual_text"] == ""


class _FakeCerebrasClient:
    def __init__(self, review: CommitAdaptationReview):
        self._review = review
        self.calls = []

    def structured_complete(self, messages, output_model, **kwargs):
        self.calls.append((messages, output_model))
        return self._review


@pytest.mark.asyncio
async def test_review_commit_with_llm_returns_structured_review(tmp_path):
    expected = CommitAdaptationReview(memory_proposals=[], inferred_persona_text="Be concise.")
    fake_client = _FakeCerebrasClient(expected)
    service = AgentControlService(root=str(tmp_path), client=fake_client)

    review = await service.review_commit_with_llm(
        project_id="project-a",
        interactions_text="Student: Do not give me the complete code.",
        current_profile="No prior profile.",
        current_persona="",
        manual_persona="",
    )

    assert review == expected
    assert fake_client.calls
    assert fake_client.calls[0][1] is CommitAdaptationReview


def test_get_effective_text_prefers_manual_over_inferred(tmp_path):
    service = AgentControlService(root=str(tmp_path))
    service.update_skill("project-a", "tutor", "Inferred: adapt pacing.", source="inferred")
    service.update_skill("project-a", "tutor", "Manual: always use analogies.", source="manual")

    assert service.get_effective_text(project_id="project-a", agent_id="tutor") == "Manual: always use analogies."


def test_get_effective_text_falls_back_to_default(tmp_path):
    service = AgentControlService(root=str(tmp_path))
    text = service.get_effective_text(project_id="project-a", agent_id="tutor")
    assert text  # DEFAULT_AGENT_SKILLS["tutor"]