121 lines
4.7 KiB
Python
121 lines
4.7 KiB
Python
import pytest
|
|
|
|
from tests.rag.asserts_intent_router import (
|
|
assert_domain_layer_prefixes,
|
|
assert_domains,
|
|
assert_file_only_scope,
|
|
assert_has_file_path,
|
|
assert_intent,
|
|
assert_no_symbol_keyword,
|
|
assert_no_symbol_leakage_from_paths,
|
|
assert_spans_valid,
|
|
assert_sub_intent,
|
|
assert_test_policy,
|
|
)
|
|
from tests.rag.intent_router_testkit import run_sequence
|
|
|
|
pytestmark = pytest.mark.intent_router
|
|
|
|
|
|
def test_invariant_code_file_path_with_canonical_key_term() -> None:
|
|
result = run_sequence(["Уточни по файлу app/core/config.py"])[0]
|
|
|
|
assert_intent(result, "CODE_QA")
|
|
assert_has_file_path(result, "app/core/config.py")
|
|
assert_file_only_scope(result, "app/core/config.py")
|
|
key_terms = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "KEY_TERM"]
|
|
assert "файл" in key_terms
|
|
assert "файлу" not in key_terms
|
|
assert_spans_valid(result)
|
|
assert_domain_layer_prefixes(result)
|
|
|
|
|
|
def test_invariant_open_file_for_specified_file_phrase_uses_narrow_layers() -> None:
|
|
result = run_sequence(["Уточни по файлу app/core/config.py"])[0]
|
|
|
|
assert_intent(result, "CODE_QA")
|
|
assert_sub_intent(result, "OPEN_FILE")
|
|
assert_file_only_scope(result, "app/core/config.py")
|
|
layer_ids = [item.layer_id for item in result.retrieval_spec.layer_queries]
|
|
assert layer_ids == ["C0_SOURCE_CHUNKS"]
|
|
assert result.evidence_policy.require_flow is False
|
|
|
|
|
|
def test_invariant_inline_code_span_routes_to_code_and_extracts_symbol() -> None:
|
|
result = run_sequence(["Уточни по коду `def build(x): return x`"])[0]
|
|
|
|
assert_intent(result, "CODE_QA")
|
|
assert_spans_valid(result)
|
|
assert_no_symbol_keyword(result)
|
|
symbols = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "SYMBOL"]
|
|
key_terms = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "KEY_TERM"]
|
|
assert "build" in symbols
|
|
assert "def" in key_terms
|
|
|
|
|
|
def test_invariant_docs_cyrillic_path_with_quotes() -> None:
|
|
result = run_sequence(["Что сказано в «docs/архитектура.md»?"])[0]
|
|
|
|
assert_intent(result, "DOCS_QA")
|
|
assert_sub_intent(result, "EXPLAIN")
|
|
assert_domains(result, ["DOCS"])
|
|
assert "docs/архитектура.md" in result.query_plan.normalized
|
|
assert_has_file_path(result, "docs/архитектура.md")
|
|
assert any(anchor.type == "DOC_REF" for anchor in result.query_plan.anchors)
|
|
assert result.retrieval_spec.filters.doc_kinds == []
|
|
assert_spans_valid(result)
|
|
assert_domain_layer_prefixes(result)
|
|
|
|
|
|
def test_invariant_file_check_phrase_not_project_misc() -> None:
|
|
result = run_sequence(["Проверь app/modules/rag/explain/intent_builder.py и объясни"])[0]
|
|
|
|
assert_intent(result, "CODE_QA")
|
|
assert_domains(result, ["CODE"])
|
|
assert_no_symbol_leakage_from_paths(result)
|
|
assert_domain_layer_prefixes(result)
|
|
|
|
|
|
def test_invariant_tests_include_routing() -> None:
|
|
result = run_sequence(["Где тесты на ConfigManager?"])[0]
|
|
|
|
assert_intent(result, "CODE_QA")
|
|
assert_test_policy(result, "INCLUDE")
|
|
symbols = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "SYMBOL"]
|
|
key_terms = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "KEY_TERM"]
|
|
assert "ConfigManager" in symbols
|
|
assert "тест" in key_terms
|
|
|
|
|
|
def test_invariant_keyword_hints_and_expansions_for_function_identifier() -> None:
|
|
result = run_sequence(["Теперь объясни функцию load_config"])[0]
|
|
|
|
assert_intent(result, "CODE_QA")
|
|
assert "load_config" in result.query_plan.keyword_hints
|
|
assert "функция" not in result.query_plan.keyword_hints
|
|
assert "def" not in result.query_plan.expansions
|
|
|
|
|
|
def test_invariant_open_file_sub_intent_uses_narrow_retrieval_profile() -> None:
|
|
result = run_sequence(["Открой файл app/core/config.py"])[0]
|
|
|
|
assert_intent(result, "CODE_QA")
|
|
assert_sub_intent(result, "OPEN_FILE")
|
|
assert_file_only_scope(result, "app/core/config.py")
|
|
layer_ids = [item.layer_id for item in result.retrieval_spec.layer_queries]
|
|
assert "C0_SOURCE_CHUNKS" in layer_ids
|
|
assert "C1_SYMBOL_CATALOG" not in layer_ids
|
|
assert "C2_DEPENDENCY_GRAPH" not in layer_ids
|
|
assert "C3_ENTRYPOINTS" not in layer_ids
|
|
assert result.evidence_policy.require_flow is False
|
|
|
|
|
|
def test_invariant_docs_question_routes_to_docs() -> None:
|
|
result = run_sequence(["Что сказано в документации?"])[0]
|
|
|
|
assert_intent(result, "DOCS_QA")
|
|
assert_domains(result, ["DOCS"])
|
|
assert_domain_layer_prefixes(result)
|
|
assert result.query_plan.keyword_hints
|
|
assert any(item in result.query_plan.expansions for item in result.query_plan.keyword_hints)
|