LifeStack / intake /simperson.py
Soham Banerjee
deploy: pure lifestack with partitioned wisdom pool
77da5ce
import random
import json
import math
from dataclasses import dataclass, field, asdict
@dataclass
class SimPerson:
openness: float = field(default_factory=lambda: random.uniform(0, 1))
conscientiousness: float = field(default_factory=lambda: random.uniform(0, 1))
extraversion: float = field(default_factory=lambda: random.uniform(0, 1))
agreeableness: float = field(default_factory=lambda: random.uniform(0, 1))
neuroticism: float = field(default_factory=lambda: random.uniform(0, 1))
name: str = "Anonymous"
def respond_to_action(self, action_type: str, resource_cost: dict, current_stress: float) -> float:
"""
Determines how likely the person is to successfully 'uptake' an action.
Uptake determines effectiveness of metric changes.
"""
uptake = 0.70
# Stress interaction
stress_penalty = 0.0
if current_stress > 70:
stress_penalty = 0.20
# Personality amplification of stress
if self.neuroticism > 0.7:
stress_penalty *= 1.3
uptake -= stress_penalty
# Personality-Action alignment
if action_type == 'communicate' and self.agreeableness > 0.6:
uptake += 0.15
if action_type == 'structured_plan' and self.conscientiousness > 0.7:
uptake += 0.10
if action_type == 'delegate' and self.neuroticism > 0.7:
uptake -= 0.10
if action_type == 'rest' and self.extraversion < 0.4:
uptake += 0.10
return max(0.1, min(1.0, uptake))
def drift(self, timestep: int) -> dict:
"""Personality shifts slightly over time, occasionally triggering events."""
if timestep % 5 != 0 or timestep == 0:
return {}
traits = ['openness', 'conscientiousness', 'extraversion', 'agreeableness', 'neuroticism']
trait = random.choice(traits)
change = random.choice([0.05, -0.05])
current = getattr(self, trait)
setattr(self, trait, max(0.0, min(1.0, current + change)))
trait_to_metric = {
'openness': 'career.growth_trajectory',
'conscientiousness': 'time.admin_overhead',
'extraversion': 'relationships.social',
'agreeableness': 'relationships.romantic',
'neuroticism': 'mental_wellbeing.stress_level'
}
metric = trait_to_metric[trait]
# neuroticism up → stress up (bad); conscientiousness up → overhead down (good);
# openness/extraversion/agreeableness up → their metric up (good).
if trait == 'neuroticism':
delta = 6 if change > 0 else -4
elif trait == 'conscientiousness':
delta = -3 if change > 0 else 7 # more conscientious = less admin overhead
else:
delta = 5 if change > 0 else -5 # trait up → metric up
return {
'metric': metric,
'delta': delta,
'reason': f'Internal personality shift in {trait} impacting {metric.split(".")[1]}.'
}
def get_personality_hint(self) -> str:
"""Returns a human-readable summary of the person's personality and tendencies."""
traits = []
if self.openness > 0.7: traits.append("intellectually curious")
elif self.openness < 0.3: traits.append("grounded in tradition")
if self.conscientiousness > 0.7: traits.append("highly organized")
elif self.conscientiousness < 0.3: traits.append("spontaneous/relaxed")
if self.extraversion > 0.7: traits.append("energetic/social")
elif self.extraversion < 0.3: traits.append("reserved/introspective")
if self.agreeableness > 0.7: traits.append("deeply cooperative")
elif self.agreeableness < 0.3: traits.append("skeptical/competitive")
if self.neuroticism > 0.7: traits.append("anxious/sensitive")
elif self.neuroticism < 0.3: traits.append("emotionally resilient")
trait_str = ", ".join(traits) if traits else "balanced"
# Strategy hints
strategies = []
if self.conscientiousness > 0.7: strategies.append("structured plans")
if self.agreeableness > 0.6: strategies.append("open communication")
if self.extraversion < 0.4: strategies.append("quiet rest")
hint = f"{self.name} is {trait_str}."
if strategies:
hint += f" Responds best to {', '.join(strategies)}."
if self.neuroticism > 0.7:
hint += " Caution: Heavily impacted by high stress."
return hint
def generate_and_save_profiles():
"""Generates 5 diverse profiles as requested."""
profiles_data = [
{
"name": "Alex (High-Stress Executive)",
"openness": 0.4, "conscientiousness": 0.9, "extraversion": 0.7,
"agreeableness": 0.25, "neuroticism": 0.8
},
{
"name": "Chloe (Laid-Back Creative)",
"openness": 0.9, "conscientiousness": 0.2, "extraversion": 0.5,
"agreeableness": 0.7, "neuroticism": 0.15
},
{
"name": "Sam (Anxious Introvert)",
"openness": 0.5, "conscientiousness": 0.6, "extraversion": 0.1,
"agreeableness": 0.65, "neuroticism": 0.9
},
{
"name": "Maya (Balanced Family Person)",
"openness": 0.5, "conscientiousness": 0.7, "extraversion": 0.5,
"agreeableness": 0.95, "neuroticism": 0.3
},
{
"name": "Leo (Ambitious Student)",
"openness": 0.85, "conscientiousness": 0.8, "extraversion": 0.4,
"agreeableness": 0.4, "neuroticism": 0.55
}
]
import os
data_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "data", "simperson_profiles.json")
with open(data_path, 'w') as f:
json.dump(profiles_data, f, indent=4)
print(f"Saved 5 diverse profiles to {data_path}")
def main():
# 1. Setup
generate_and_save_profiles()
# 2. Create 3 test instances
test_people = [
SimPerson(name="Alex (Executive)", openness=0.4, conscientiousness=0.9, extraversion=0.7, agreeableness=0.25, neuroticism=0.8),
SimPerson(name="Chloe (Creative)", openness=0.9, conscientiousness=0.2, extraversion=0.5, agreeableness=0.7, neuroticism=0.15),
SimPerson(name="Sam (Introvert)", openness=0.5, conscientiousness=0.6, extraversion=0.1, agreeableness=0.65, neuroticism=0.9)
]
actions = ['communicate', 'structured_plan', 'delegate', 'rest']
stress_levels = [30.0, 80.0]
print("\n--- PERSONALITY ANALYSIS ---")
for person in test_people:
print(f"\n[{person.name}]")
print(f"Hint: {person.get_personality_hint()}")
print(f"{'Action':20} | {'Low Stress (30)':15} | {'High Stress (80)':15}")
print("-" * 55)
for action in actions:
uptake_low = person.respond_to_action(action, {}, 30.0)
uptake_high = person.respond_to_action(action, {}, 80.0)
print(f"{action:20} | {uptake_low:15.2f} | {uptake_high:15.2f}")
if __name__ == "__main__":
main()