from central.app.ai.cache_policy import CONFLICT, NEEDS_REVALIDATION, VALID, cache_key, classify_knowledge_freshness from central.app.ai.provider import BudgetGuard def test_cache_key_changes_for_each_input_dimension(): base = ("input", "candidates", "model", "prompt", {"ncm": "n1", "tipi": "t1"}) key = cache_key(*base) assert key != cache_key("changed", *base[1:]) assert key != cache_key(base[0], "changed", *base[2:]) assert key != cache_key(base[0], base[1], "changed", *base[3:]) assert key != cache_key(base[0], base[1], base[2], "changed", base[4]) assert key != cache_key(*base[:4], {"ncm": "n2", "tipi": "t1"}) assert key == cache_key(*base) def test_dataset_freshness_is_fail_closed(): assert classify_knowledge_freshness({"ncm": "v1"}, {"ncm": "v1"}) == VALID assert classify_knowledge_freshness({"ncm": "v1"}, {"ncm": "v2"}) == CONFLICT assert classify_knowledge_freshness({"ncm": "v1"}, {"ncm": "v1", "tipi": "v2"}) == NEEDS_REVALIDATION assert classify_knowledge_freshness({}, {"ncm": "v1"}) == NEEDS_REVALIDATION def test_budget_blocks_before_call_and_actual_usage_cannot_exceed_limit(): guard = BudgetGuard(1.0, 1.0, 2.0) assert guard.authorize(guard.estimate(600_000, 300_000)) is False assert guard.authorize(guard.estimate(100_000, 50_000)) is True assert guard.authorize_usage(100_000, 50_000, prior_cost_usd=0.9) is False def test_unknown_cost_requires_explicit_limited_run(): guard = BudgetGuard(5.0, None, None) assert guard.authorize_usage(1000, 100) is False assert guard.authorize_usage(1000, 100, allow_unknown_cost=True) is True