Spaces:
Sleeping
Sleeping
| """Expectation quality loop pure control plane (no LLM).""" | |
| from __future__ import annotations | |
| from agents.world_class_advisor import evaluate_application | |
| from core.generation.expectation_loop import ( | |
| is_regulation_ready, | |
| run_advisor_expectation_loop, | |
| run_expectation_loop, | |
| ) | |
| BRIEF = { | |
| "key_rules": ["Wnioskodawca musi posiadać status MŚP", "Projekt musi spełniać zasadę DNSH"], | |
| "required_sections": ["Opis projektu", "Budżet"], | |
| "required_attachments": [], | |
| "attention_points": ["Sprawdź DNSH / wpływ środowiskowy w opisie projektu."], | |
| "usable": True, | |
| } | |
| def test_is_regulation_ready_false_for_structure_only(): | |
| assert ( | |
| is_regulation_ready( | |
| { | |
| "passed": True, | |
| "score": 95, | |
| "regulation_grounded_pass": False, | |
| "blockers": [], | |
| "grounding_mode": "structure_only", | |
| } | |
| ) | |
| is False | |
| ) | |
| def test_loop_stops_when_ready(): | |
| sections = { | |
| "Opis projektu": ( | |
| "Projekt MŚP z DNSH i pełnym opisem innowacji. " * 10 | |
| ), | |
| "Budżet": ( | |
| "Budżet z wkładem własnym i kosztami kwalifikowalnymi. " * 10 | |
| ), | |
| } | |
| def evaluate(state): | |
| return evaluate_application( | |
| sections=state.get("generated_sections") or {}, | |
| brief=BRIEF, | |
| grounding_mode="regulation", | |
| ) | |
| result = run_expectation_loop( | |
| evaluate=evaluate, | |
| apply_fixes=None, | |
| initial_state={"generated_sections": sections}, | |
| max_iterations=3, | |
| min_score=70, | |
| ) | |
| assert result.ready is True | |
| assert result.stop_reason == "ready" | |
| assert result.regulation_grounded_pass is True | |
| assert result.iterations >= 1 | |
| assert not result.remaining_blockers | |
| def test_loop_max_iter_with_blockers(): | |
| weak = {"Opis projektu": "za mało"} | |
| def evaluate(state): | |
| return evaluate_application( | |
| sections=state.get("generated_sections") or {}, | |
| brief=BRIEF, | |
| grounding_mode="regulation", | |
| ) | |
| def fix(state, report): | |
| # Improves slightly but not enough to cover Budżet | |
| gen = dict(state.get("generated_sections") or {}) | |
| gen["Opis projektu"] = (gen.get("Opis projektu") or "") + " dodatek MŚP DNSH " * 5 | |
| state = dict(state) | |
| state["generated_sections"] = gen | |
| state["fixed_sections"] = ["Opis projektu"] | |
| return state | |
| result = run_expectation_loop( | |
| evaluate=evaluate, | |
| apply_fixes=fix, | |
| initial_state={"generated_sections": weak}, | |
| max_iterations=2, | |
| min_score=70, | |
| ) | |
| assert result.ready is False | |
| assert result.stop_reason == "max_iter" | |
| assert result.iterations == 2 | |
| assert result.remaining_blockers | |
| assert result.regulation_grounded_pass is False | |
| def test_loop_structure_only_never_ready(): | |
| sections = { | |
| "Opis projektu": "x" * 250, | |
| "Budżet": "y" * 250, | |
| } | |
| def evaluate(state): | |
| return evaluate_application( | |
| sections=state.get("generated_sections") or {}, | |
| brief=BRIEF, | |
| grounding_mode="structure_only", | |
| ) | |
| result = run_expectation_loop( | |
| evaluate=evaluate, | |
| apply_fixes=lambda s, r: s, | |
| initial_state={ | |
| "generated_sections": sections, | |
| "external_context": {"grounding_mode": "structure_only"}, | |
| "grounding_mode": "structure_only", | |
| }, | |
| max_iterations=2, | |
| ) | |
| assert result.ready is False | |
| assert result.regulation_grounded_pass is False | |
| assert result.stop_reason in ("max_iter", "blocked_grounding") | |
| def test_quality_expectation_step_wired_for_production(): | |
| """Production helper run_quality_expectation_step drives real advisor + fix path.""" | |
| from core.generation.quality_loop import run_quality_expectation_step | |
| state = { | |
| "sections_plan": [ | |
| {"title": "Opis projektu", "type": "desc"}, | |
| {"title": "Budżet", "type": "budget"}, | |
| ], | |
| "generated_sections": { | |
| "Opis projektu": "Pełny opis projektu MŚP z DNSH i celami. " * 8, | |
| "Budżet": "Budżet z wkładem własnym 30% i kosztami kwalifikowalnymi. " * 8, | |
| }, | |
| "external_context": { | |
| "grounding_mode": "regulation", | |
| "advisor_brief": BRIEF, | |
| "required_sections": BRIEF["required_sections"], | |
| "key_rules": BRIEF["key_rules"], | |
| }, | |
| } | |
| out = run_quality_expectation_step(state, source="holistic", min_score=70) | |
| assert "advisor_before" in out | |
| assert "regulation_ready" in out | |
| assert out["stop_reason"] in ("ready", "needs_retry") | |
| # Strong content with brief signals should be ready without needing rewrite | |
| assert out["regulation_ready"] is True | |
| assert out["stop_reason"] == "ready" | |
| def test_soft_pass_gate_requires_regulation_grounded_pass_semantics(): | |
| """Mirror generator gate: usable brief → only regulation_grounded_pass is ready.""" | |
| from core.generation.expectation_loop import is_regulation_ready | |
| fluff_rep = evaluate_application( | |
| sections={ | |
| "Opis projektu": "Projekt innowacyjny z bogatym doświadczeniem zespołu. " * 20, | |
| "Budżet": "Budżet obejmuje koszty osobowe i sprzęt w pełnym zakresie. " * 20, | |
| }, | |
| brief=BRIEF, | |
| grounding_mode="regulation", | |
| ) | |
| assert fluff_rep.regulation_grounded_pass is False | |
| assert is_regulation_ready(fluff_rep) is False | |
| def test_run_advisor_expectation_loop_improves_to_ready(): | |
| state = { | |
| "generated_sections": { | |
| "Opis projektu": "krótki start", | |
| }, | |
| "external_context": { | |
| "grounding_mode": "regulation", | |
| "advisor_brief": BRIEF, | |
| "required_sections": BRIEF["required_sections"], | |
| }, | |
| } | |
| def pure_fix(st, report): | |
| # Simulate targeted rewrite filling required sections | |
| st = dict(st) | |
| st["generated_sections"] = { | |
| "Opis projektu": ( | |
| "Pełny opis projektu MŚP z DNSH, innowacją i celami programu. " * 8 | |
| ), | |
| "Budżet": ( | |
| "Szczegółowy budżet, wkład własny 30%, koszty kwalifikowalne. " * 8 | |
| ), | |
| } | |
| st["fixed_sections"] = ["Opis projektu", "Budżet"] | |
| return st | |
| result = run_advisor_expectation_loop( | |
| state, | |
| max_iterations=3, | |
| min_score=70, | |
| apply_fixes=pure_fix, | |
| ) | |
| assert result.ready is True | |
| assert result.stop_reason == "ready" | |
| assert result.regulation_grounded_pass is True | |