Spaces:
Sleeping
Sleeping
| """Tests for the ScriptedClient opponent.""" | |
| from server.contract_fixtures import get_fixture | |
| from server.private_briefs import generate_client_brief | |
| from server.scripted_client import ScriptedClient | |
| def test_responds_to_offer(): | |
| fixture = get_fixture("simple_saas") | |
| cbrief = generate_client_brief(fixture) | |
| sc = ScriptedClient(cbrief, fixture, strategy="balanced", seed=1) | |
| vendor_action = { | |
| "action_type": "make_offer", | |
| "agent_role": "vendor", | |
| "proposed_terms": { | |
| "annual_price": 90000, | |
| "payment_net_days": 35, | |
| "contract_length_months": 30, | |
| "support_tier": "basic", | |
| }, | |
| } | |
| resp = sc.respond(vendor_action, [], turn=1) | |
| assert isinstance(resp, dict) | |
| assert resp.get("agent_role") == "client" | |
| assert resp.get("action_type") in ( | |
| "counter_offer", | |
| "accept_offer", | |
| "walk_away", | |
| "make_offer", | |
| ) | |
| def test_walks_away_on_dealbreaker(): | |
| fixture = get_fixture("gdpr_dpa") | |
| cbrief = generate_client_brief(fixture) | |
| sc = ScriptedClient(cbrief, fixture, strategy="balanced", seed=2) | |
| # Client dealbreaker: breach_notification_hours > 72 | |
| vendor_action = { | |
| "action_type": "make_offer", | |
| "agent_role": "vendor", | |
| "proposed_terms": { | |
| "data_retention_months": 24, | |
| "breach_notification_hours": 96, # past client's dealbreaker | |
| "audit_frequency": "annual", | |
| "subprocessor_approval": "notice_only", | |
| "liability_cap_multiple": 1.0, | |
| "indemnification_scope": "limited", | |
| }, | |
| } | |
| resp = sc.respond(vendor_action, [], turn=1) | |
| assert resp["action_type"] == "walk_away" | |
| def test_concedes_in_late_game(): | |
| fixture = get_fixture("simple_saas") | |
| cbrief = generate_client_brief(fixture) | |
| sc = ScriptedClient(cbrief, fixture, strategy="conciliatory", seed=3) | |
| # Late-game, vendor offers terms that are at least acceptable | |
| vendor_action = { | |
| "action_type": "counter_offer", | |
| "agent_role": "vendor", | |
| "proposed_terms": { | |
| "annual_price": 70000, | |
| "payment_net_days": 65, | |
| "contract_length_months": 18, | |
| "support_tier": "premium", | |
| }, | |
| } | |
| resp = sc.respond( | |
| vendor_action, | |
| [{"agent_role": "vendor", "proposed_terms": vendor_action["proposed_terms"]}], | |
| turn=fixture["max_turns"] - 1, | |
| ) | |
| assert resp["action_type"] in ("accept_offer", "counter_offer", "walk_away") | |
| def test_strategies_are_distinguishable(): | |
| fixture = get_fixture("simple_saas") | |
| cbrief = generate_client_brief(fixture) | |
| aggressive = ScriptedClient(cbrief, fixture, strategy="aggressive", seed=4) | |
| conciliatory = ScriptedClient(cbrief, fixture, strategy="conciliatory", seed=4) | |
| # Conciliatory accepts at lower utility than aggressive | |
| assert conciliatory._accept_threshold < aggressive._accept_threshold | |