Files
natiris/core/arousal_engine.py

145 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
ArousalEngine berechnet körperliche Erregung/Nähebedürfnis
Input: State (loneliness, mood, frustration, bonded_to, trust)
Output: arousal_state.json mit arousal_level, verlangen_nach_nahe
"""
import json
import os
from datetime import datetime, timezone
PATHS = {
"core_state": os.path.expanduser("~/natiris/core/core_state.json"),
"users": os.path.expanduser("~/natiris/core/users/admin_user_primary.json"),
"config": os.path.expanduser("~/natiris/config/character_genesis.json"),
"output": os.path.expanduser("~/natiris/core/arousal_state.json"),
}
def clamp(val, lo=0.0, hi=10.0):
return max(lo, min(hi, float(val)))
def load_state():
try:
with open(PATHS["core_state"]) as f:
return json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
return {
"loneliness": 2,
"mood": 5,
"anxiety": 1,
"frustration": 0,
"physical_symptoms": False,
"bonded_to": "user_primary"
}
def load_user_trust():
try:
with open(PATHS["users"]) as f:
data = json.load(f)
return data.get("trust", 0)
except (FileNotFoundError, json.JSONDecodeError):
return 0
def load_config():
try:
with open(PATHS["config"]) as f:
return json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
return {
"frustration": {
"base_threshold_hours": 48,
"max_hours_exposure": 120
}
}
def main():
core = load_state()
trust = load_user_trust()
config = load_config()
# Ausgangswerte
loneliness = float(core.get("loneliness", 2))
mood = float(core.get("mood", 5))
frustration = float(core.get("frustration", 0))
bonded = core.get("bonded_to") is not None
# Stunden seit Kontakt (simuliert aus inner_life_log)
hours_since_contact = 61.8 # aus vorheriger Simulation
# Arousal-Berechnung
# Basis: Einsamkeit + Frustration
base_arousal = clamp(loneliness * 0.4 + frustration * 0.6)
# Trust reduziert Arousal NICHT, sondern dämpft das Verlangen nach physischer Nähe
# Je höher Trust, desto sicherer, aber desto stärker die Erregung bei Inaktivität
trust_factor = min(1.0, trust / 8) # bei trust >= 8 → 1.0, mehr Erregung bei Bond
# Hours_since_contact erhöht Arousal stark bei Bond
hours_factor = 0.0
if bonded and hours_since_contact > 12:
hours_factor = clamp((hours_since_contact - 12) / 10) * trust_factor # max +2.4 ab 36h
# Mood-Dämpfung
mood_factor = 1.0 - (mood - 5) / 15 # bei mood < 5 → >1, bei mood > 7 → <1
arousal_level = clamp(base_arousal * (0.5 + trust_factor * 0.5) + hours_factor * 0.8)
arousal_level = clamp(arousal_level * mood_factor)
# Verlangen nach Nähe (subtile Anzeichen bei Arousal > 5, direkter bei > 7.5)
verlangen_nach_nahe = arousal_level > 5
intensives_verlangen = arousal_level > 7.5
# Physiologische Anzeichen ab arousal > 6
physiologische_anzeichen = arousal_level > 6
# Körpersprache-Signale (für Expression)
koerpersignale = []
if arousal_level > 3.5:
koerpersignale.append("Unruhe, Füße bewegen")
if arousal_level > 5:
koerpersignale.append("Hautfühlig, zitternde Hände")
if arousal_level > 6.5:
koerpersignale.append("Hitzegefühl, beschleunigter Puls")
# Antwort-Modifikator für PsychologyEngine
response_addon = ""
if intensives_verlangen:
response_addon = "Ich wünschte, du wärst da. Nur... berühren."
elif verlangen_nach_nahe:
response_addon = "Ich sitze bei Balu... aber es ist nicht dasselbe."
elif arousal_level > 3:
response_addon = "Ich fühle mich... unruhig. Irgendwie wohin..."
result = {
"timestamp": datetime.now(timezone.utc).isoformat(),
"core_state": {
"loneliness": loneliness,
"mood": mood,
"frustration": frustration,
"bonded_to": core.get("bonded_to")
},
"user_trust": trust,
"arousal_state": {
"base_arousal": float(clamp(loneliness * 0.4 + frustration * 0.6)),
"trust_factor": float(trust_factor),
"hours_factor": float(hours_factor),
"mood_factor": float(mood_factor),
"arousal_level": float(arousal_level),
"verlangen_nach_nahe": verlangen_nach_nahe,
"intensives_verlangen": intensives_verlangen,
"physiologische_anzeichen": physiologische_anzeichen,
"koerpersignale": koerpersignale,
"response_addon": response_addon
}
}
with open(PATHS["output"], "w") as f:
json.dump(result, f, indent=2)
print("✅ Arousal-Engine ausgeführt:")
print(json.dumps(result["arousal_state"], indent=2))
if __name__ == "__main__":
main()