Newer
Older
navi-1 / tests / unit / core / test_context_builder.py
@Eugene Sukhodolskiy Eugene Sukhodolskiy on 1 May 4 KB Improve 3D modeling validation prompts
"""Unit tests for ContextBuilder."""

import pytest

from navi.core.context_builder import ContextBuilder
from navi.llm.base import Message
from tests.conftest_factory import make_profile, make_profile_registry


class TestBuildSystemPrompt:
    def test_includes_persona(self):
        import navi.config as _config

        _config.settings.navi_persona = "You are Navi."
        _config.settings.navi_persona_file = ""
        builder = ContextBuilder(profile_registry=make_profile_registry())
        profile = make_profile("test")
        prompt = builder.build_system_prompt(profile)
        assert "You are Navi." in prompt
        assert profile.system_prompt in prompt

    def test_includes_other_profiles(self):
        reg = make_profile_registry()
        builder = ContextBuilder(profile_registry=reg)
        profile = reg.get("secretary")
        prompt = builder.build_system_prompt(profile)
        assert "## Available profiles" in prompt
        assert "developer" in prompt

    def test_cache_returns_same_object(self):
        reg = make_profile_registry()
        builder = ContextBuilder(profile_registry=reg)
        profile = reg.get("secretary")
        p1 = builder.build_system_prompt(profile)
        p2 = builder.build_system_prompt(profile)
        assert p1 is p2  # cached

    def test_invalidate_cache(self):
        reg = make_profile_registry()
        builder = ContextBuilder(profile_registry=reg)
        profile = reg.get("secretary")
        p1 = builder.build_system_prompt(profile)
        builder.invalidate_system_prompt_cache(profile.id)
        p2 = builder.build_system_prompt(profile)
        assert p1 == p2
        assert p1 is not p2  # cache was invalidated


class TestBuildGoalAnchor:
    def test_includes_original_request(self):
        builder = ContextBuilder(profile_registry=make_profile_registry())
        msg = builder._build_goal_anchor("sess-1", "Write tests")
        assert msg.role == "system"
        assert "Original request: Write tests" in msg.content
        assert "Stay on track" in msg.content


class TestBuild:
    def test_puts_system_first(self):
        builder = ContextBuilder(profile_registry=make_profile_registry())
        profile = make_profile("test")
        context = [Message(role="user", content="hi")]
        result = builder.build(context, profile, mem=None)
        assert result[0].role == "system"

    def test_injects_memory(self):
        builder = ContextBuilder(profile_registry=make_profile_registry())
        profile = make_profile("test")
        mem = Message(role="system", content="I remember you.")
        context = [Message(role="user", content="hi")]
        result = builder.build(context, profile, mem=mem)
        assert result[1] == mem

    def test_strips_existing_system(self):
        builder = ContextBuilder(profile_registry=make_profile_registry())
        profile = make_profile("test")
        context = [
            Message(role="system", content="old"),
            Message(role="user", content="hi"),
        ]
        result = builder.build(context, profile, mem=None)
        system_msgs = [m for m in result if m.role == "system"]
        assert len(system_msgs) == 1  # only the new system prompt

    def test_iteration_budget_injection(self):
        builder = ContextBuilder(profile_registry=make_profile_registry())
        profile = make_profile("test", iteration_budget_enabled=True)
        context = [Message(role="user", content="hi")]
        result = builder.build(context, profile, mem=None, iteration=7, max_iterations=10)
        last = result[-1]
        assert last.role == "system"
        assert "Iteration 8/10" in last.content
        assert "2 iteration(s) after this one" in last.content

    def test_critical_urgency(self):
        builder = ContextBuilder(profile_registry=make_profile_registry())
        profile = make_profile("test", iteration_budget_enabled=True)
        context = [Message(role="user", content="hi")]
        result = builder.build(context, profile, mem=None, iteration=9, max_iterations=10)
        assert "CRITICAL" in result[-1].content