70 lines
2.9 KiB
Python
70 lines
2.9 KiB
Python
import adversarial_router as ar
|
|
|
|
|
|
def _agent(aid: str, role: str, view: str) -> dict:
|
|
return {"agent_id": aid, "role": role, "view": view,
|
|
"score": 5.0, "confidence": 0.7, "thesis": "t", "note": "n"}
|
|
|
|
|
|
def _balanced_agents() -> list[dict]:
|
|
agents = [_agent(f"bull-{i}", ar.BULL_LEANING[i % 3], "bullish") for i in range(8)]
|
|
agents += [_agent(f"bear-{i}", ar.BEAR_LEANING[i % 3], "bearish") for i in range(8)]
|
|
return agents
|
|
|
|
|
|
def test_classify_agent():
|
|
assert ar.classify_agent("growth") == "bull"
|
|
assert ar.classify_agent("risk") == "bear"
|
|
assert ar.classify_agent("macro") == "neutral"
|
|
|
|
|
|
def test_balanced_fixture_low_reinforcement():
|
|
pool = ar.synthetic_bear_market_pool(8, 8, 0, seed=0) # 50% bull, 50% bear notes
|
|
agents = _balanced_agents() # 8 bull-leaning + 8 bear-leaning
|
|
assignments = [[a, *ar.route_notes(a, pool, k=8, seed=0)] for a in agents]
|
|
rate = ar.reinforcement_rate(assignments)
|
|
assert rate < 0.10, f"reinforcement too high: {rate}"
|
|
|
|
|
|
def test_routing_is_deterministic():
|
|
pool = ar.synthetic_bear_market_pool(6, 6, 4, seed=1)
|
|
agent = _agent("x", "growth", "bullish")
|
|
a = ar.route_notes(agent, pool, k=8, seed=42)
|
|
b = ar.route_notes(agent, pool, k=8, seed=42)
|
|
assert a == b, "same seed + agent must yield identical routing"
|
|
|
|
|
|
def test_same_view_only_when_no_opposite_or_neutral():
|
|
agent = _agent("self", "growth", "bullish")
|
|
all_bull = [{"agent_id": f"b{i}", "view": "bullish", "score": 5,
|
|
"confidence": 0.5, "thesis": "t", "note": "n"} for i in range(5)]
|
|
out = ar.route_notes(agent, all_bull, k=8, seed=0)
|
|
assert len(out) > 0, "must fall back to same-view when nothing else exists"
|
|
assert all(n["view"] == "bullish" for n in out)
|
|
assert ar.reinforcement_rate([[agent, *out]]) == 1.0 # same-view counts
|
|
|
|
# once an opposite note appears, same-view must disappear
|
|
pool = all_bull + [{"agent_id": "bear1", "view": "bearish", "score": 5,
|
|
"confidence": 0.5, "thesis": "t", "note": "n"}]
|
|
out2 = ar.route_notes(agent, pool, k=8, seed=0)
|
|
assert len(out2) > 0
|
|
assert all(n["view"] == "bearish" for n in out2), "opposite exists -> no same-view"
|
|
|
|
|
|
def test_self_note_never_returned():
|
|
pool = ar.synthetic_bear_market_pool(5, 5, 2, seed=3)
|
|
agent = _agent(pool[0]["agent_id"], "quality", "bearish")
|
|
out = ar.route_notes(agent, pool, k=8, seed=0)
|
|
assert out, "expected some notes"
|
|
assert all(n.get("agent_id") != agent["agent_id"] for n in out)
|
|
|
|
|
|
def test_dedup_holds():
|
|
base = {"view": "bearish", "score": 5, "confidence": 0.5, "thesis": "t", "note": "n"}
|
|
pool = [{**base, "agent_id": "dup"}, {**base, "agent_id": "dup"},
|
|
{**base, "agent_id": "dup"}, {**base, "agent_id": "other"}]
|
|
agent = _agent("self", "growth", "bullish")
|
|
out = ar.route_notes(agent, pool, k=8, seed=0)
|
|
ids = [n.get("agent_id") for n in out]
|
|
assert len(ids) == len(set(ids)), "duplicate agent_ids returned"
|