You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
mirosociety/backend/tests/test_life_context.py

394 lines
13 KiB

from app.models.agent import (
AgentPersona, Personality, LifeState, FamilyMember,
FormativeEvent, LifePressure,
)
from app.services.life_context import (
compute_domain_level,
compute_need_priority,
compute_action_bias,
find_relevant_echoes,
build_life_prompt_block,
)
def _make_agent(**life_overrides) -> AgentPersona:
ls_kwargs = dict(
childhood_summary="Grew up in a small village.",
formative_events=[],
family=[],
)
ls_kwargs.update(life_overrides)
return AgentPersona(
id=1, name="Ada", role="Worker", age=30,
personality=Personality(), background="test",
life_state=LifeState(**ls_kwargs),
)
def _make_agent_no_life() -> AgentPersona:
return AgentPersona(
id=2, name="Ghost", role="Wanderer", age=25,
personality=Personality(), background="none",
)
# ──────────────────────────────────────────────
# compute_domain_level
# ──────────────────────────────────────────────
def test_domain_level_desperate():
result = compute_domain_level("finances", 0.1)
assert "desperate" in result
assert "survival" in result.lower()
def test_domain_level_struggling():
result = compute_domain_level("health", 0.25)
assert "struggling" in result
def test_domain_level_tight():
result = compute_domain_level("career", 0.45)
assert "tight but managing" in result
def test_domain_level_stable():
result = compute_domain_level("finances", 0.6)
assert "stable" in result
def test_domain_level_comfortable():
result = compute_domain_level("health", 0.75)
assert "comfortable" in result
def test_domain_level_thriving():
result = compute_domain_level("career", 0.95)
assert "thriving" in result
def test_domain_level_boundary_020():
assert "desperate" in compute_domain_level("finances", 0.19)
assert "struggling" in compute_domain_level("finances", 0.20)
def test_domain_level_unknown_domain():
result = compute_domain_level("unknown", 0.1)
assert result == "desperate"
# ──────────────────────────────────────────────
# compute_need_priority
# ──────────────────────────────────────────────
def test_need_priority_no_life_state():
agent = _make_agent_no_life()
assert compute_need_priority(agent, 10) == ""
def test_need_priority_urgent_pressure():
agent = _make_agent(pressures=[
LifePressure(domain="finances", description="Eviction", severity=0.8, deadline_day=11, created_day=1),
])
result = compute_need_priority(agent, 10)
assert "SURVIVAL MODE" in result
assert "Eviction" in result
def test_need_priority_pressure_not_urgent_when_far():
agent = _make_agent(pressures=[
LifePressure(domain="finances", description="Rent", severity=0.9, deadline_day=20, created_day=1),
])
result = compute_need_priority(agent, 10)
assert "SURVIVAL MODE" not in result
def test_need_priority_pressure_not_urgent_low_severity():
agent = _make_agent(pressures=[
LifePressure(domain="finances", description="Rent", severity=0.4, deadline_day=11, created_day=1),
])
result = compute_need_priority(agent, 10)
assert "SURVIVAL MODE" not in result
def test_need_priority_basic_needs_finances():
agent = _make_agent(finances=0.15)
assert compute_need_priority(agent, 10) == "Your basic needs are threatened"
def test_need_priority_basic_needs_health():
agent = _make_agent(health=0.1)
assert compute_need_priority(agent, 10) == "Your basic needs are threatened"
def test_need_priority_family_dependency():
agent = _make_agent(
finances=0.35,
family=[
FamilyMember(name="Rosa", relation="daughter", age=5, dependency=0.8),
],
)
result = compute_need_priority(agent, 10)
assert "depending on you" in result
assert "Rosa" in result
def test_need_priority_career_stagnating():
agent = _make_agent(career=0.25)
assert compute_need_priority(agent, 10) == "Your career is stagnating"
def test_need_priority_all_high():
agent = _make_agent(finances=0.8, career=0.8, health=0.9)
assert "legacy" in compute_need_priority(agent, 10).lower()
def test_need_priority_default():
agent = _make_agent(finances=0.5, career=0.5, health=0.5)
assert compute_need_priority(agent, 10) == "Life is manageable but not easy"
# ──────────────────────────────────────────────
# compute_action_bias
# ──────────────────────────────────────────────
def test_action_bias_no_life_state():
agent = _make_agent_no_life()
assert compute_action_bias(agent, 10) == {}
def test_action_bias_financial_desperation():
agent = _make_agent(finances=0.1)
biases = compute_action_bias(agent, 10)
assert "TRADE" in biases
assert "NEED resources" in biases["TRADE"]
assert "BUILD" in biases
assert "afford" in biases["BUILD"]
def test_action_bias_financial_desperation_with_dependents():
agent = _make_agent(
finances=0.1,
family=[FamilyMember(name="Tom", relation="son", age=3, dependency=0.9)],
)
biases = compute_action_bias(agent, 10)
assert "family" in biases["DEFECT"].lower()
def test_action_bias_health_crisis():
agent = _make_agent(health=0.15)
biases = compute_action_bias(agent, 10)
assert "energy" in biases["BUILD"].lower()
assert "exhausted" in biases["PROTEST"].lower()
assert "conserving" in biases["OBSERVE"].lower()
def test_action_bias_high_dependency():
agent = _make_agent(
family=[
FamilyMember(name="A", relation="child", age=3, dependency=0.6),
FamilyMember(name="B", relation="child", age=5, dependency=0.6),
],
)
biases = compute_action_bias(agent, 10)
assert "DEFECT" in biases
assert "safe" in biases["DEFECT"].lower()
assert "PROTEST" in biases
assert "counting on you" in biases["PROTEST"].lower()
def test_action_bias_career_pressure():
agent = _make_agent(career=0.2)
biases = compute_action_bias(agent, 10)
assert "COMPLY" in biases
assert "reliable" in biases["COMPLY"]
def test_action_bias_imminent_deadline():
agent = _make_agent(pressures=[
LifePressure(domain="finances", description="Debt payment", severity=0.7, deadline_day=11, created_day=1),
])
biases = compute_action_bias(agent, 10)
assert "DO_NOTHING" in biases
assert "URGENT" in biases["DO_NOTHING"]
assert "OBSERVE" in biases
assert "deadline" in biases["OBSERVE"].lower()
def test_action_bias_thriving():
agent = _make_agent(finances=0.85, career=0.8, health=0.9)
biases = compute_action_bias(agent, 10)
assert "PROPOSE_RULE" in biases
assert "standing" in biases["PROPOSE_RULE"].lower()
assert "BUILD" in biases
assert "FORM_GROUP" in biases
def test_action_bias_empty_when_middle():
agent = _make_agent(finances=0.5, career=0.5, health=0.5)
biases = compute_action_bias(agent, 10)
assert biases == {}
# ──────────────────────────────────────────────
# find_relevant_echoes
# ──────────────────────────────────────────────
def test_echoes_no_life_state():
agent = _make_agent_no_life()
assert find_relevant_echoes(agent, "new rule imposed") == []
def test_echoes_no_formative_events():
agent = _make_agent()
assert find_relevant_echoes(agent, "new rule imposed") == []
def test_echoes_authority_match():
agent = _make_agent(formative_events=[
FormativeEvent(
age_at_event=10,
description="Father was a strict law enforcer",
lasting_effect="Reflexive obedience to authority",
),
])
echoes = find_relevant_echoes(agent, "A new rule has been proposed by the leader")
assert len(echoes) == 1
assert "Echo from your past" in echoes[0]
assert "Father" in echoes[0]
def test_echoes_scarcity_match():
agent = _make_agent(formative_events=[
FormativeEvent(
age_at_event=8,
description="Village faced a food crisis",
lasting_effect="Hoards resources compulsively",
),
])
echoes = find_relevant_echoes(agent, "There is a resource shortage in the market")
assert len(echoes) >= 1
assert "crisis" in echoes[0].lower() or "Hoards" in echoes[0]
def test_echoes_no_match():
agent = _make_agent(formative_events=[
FormativeEvent(
age_at_event=12,
description="Won a swimming contest",
lasting_effect="Loves competition",
),
])
assert find_relevant_echoes(agent, "The weather is nice today") == []
def test_echoes_max_two():
agent = _make_agent(formative_events=[
FormativeEvent(age_at_event=5, description="Saw a leader fall", lasting_effect="Distrusts order"),
FormativeEvent(age_at_event=8, description="New rule destroyed home", lasting_effect="Hates authority"),
FormativeEvent(age_at_event=12, description="Order restored peace", lasting_effect="Believes in law"),
])
echoes = find_relevant_echoes(agent, "The leader proposed a new rule")
assert len(echoes) <= 2
def test_echoes_trust_match():
agent = _make_agent(formative_events=[
FormativeEvent(
age_at_event=15,
description="Best friend betrayed a promise",
lasting_effect="Slow to trust",
),
])
echoes = find_relevant_echoes(agent, "Can you trust this person?")
assert len(echoes) == 1
# ──────────────────────────────────────────────
# build_life_prompt_block
# ──────────────────────────────────────────────
def test_prompt_block_no_life_state():
agent = _make_agent_no_life()
assert build_life_prompt_block(agent, 10, "context") == ""
def test_prompt_block_contains_sections():
agent = _make_agent()
block = build_life_prompt_block(agent, 10, "context")
assert "YOUR LIFE RIGHT NOW" in block
assert "YOUR HISTORY" in block
def test_prompt_block_domain_levels():
agent = _make_agent(finances=0.1, career=0.9, health=0.5)
block = build_life_prompt_block(agent, 10, "context")
assert "desperate" in block
assert "thriving" in block
assert "stable" in block.lower()
def test_prompt_block_family_listed():
agent = _make_agent(family=[
FamilyMember(name="Ella", relation="daughter", age=7, dependency=0.5),
])
block = build_life_prompt_block(agent, 10, "context")
assert "Ella" in block
assert "daughter" in block
def test_prompt_block_pressures_listed():
agent = _make_agent(pressures=[
LifePressure(domain="health", description="Surgery needed", severity=0.9, deadline_day=15, created_day=1),
])
block = build_life_prompt_block(agent, 10, "context")
assert "Surgery needed" in block
assert "severity 0.9" in block
assert "deadline: day 15" in block
def test_prompt_block_childhood():
agent = _make_agent()
block = build_life_prompt_block(agent, 10, "context")
assert "Grew up in a small village." in block
def test_prompt_block_formative_events():
agent = _make_agent(formative_events=[
FormativeEvent(age_at_event=7, description="Lost a parent", lasting_effect="Fear of abandonment"),
])
block = build_life_prompt_block(agent, 10, "context")
assert "Age 7" in block
assert "Lost a parent" in block
def test_prompt_block_echoes_included():
agent = _make_agent(formative_events=[
FormativeEvent(
age_at_event=10,
description="Saw a leader betray the group",
lasting_effect="Distrusts leaders",
),
])
block = build_life_prompt_block(agent, 10, "A new leader has proposed a rule")
assert "Echo from your past" in block
def test_prompt_block_all_domains_low():
agent = _make_agent(
finances=0.05, career=0.1, health=0.08,
family=[FamilyMember(name="Kid", relation="child", age=2, dependency=0.9)],
pressures=[
LifePressure(domain="finances", description="Debt", severity=0.9, deadline_day=11, created_day=1),
],
)
block = build_life_prompt_block(agent, 10, "context")
assert "SURVIVAL MODE" in block
assert "desperate" in block
def test_prompt_block_all_domains_high():
agent = _make_agent(finances=0.9, career=0.85, health=0.95)
block = build_life_prompt_block(agent, 10, "context")
assert "thriving" in block
assert "legacy" in block.lower()