user_limbic_mirror

User Limbic Mirror v2 — per-user relational modeling with conflict detection.

Tracks each user’s inferred emotional state via a 20-node shadow vector, maintaining separate game and genuine context layers. Detects inter-user conflict and triggers equidistance mechanics to prevent recency/loudness bias.

Architecture: - Per-user keying: {channel_id}:{user_id} composite keys - Dual vectors: genuine_vector (long-term relationship) and game_vector

(KoTH / roleplay context, doesn’t pollute genuine)

  • Relational baselines: slow-updating snapshots of “how Star normally is with this person,” stored in Redis for persistence across sessions

  • Conflict detection: when 2+ high-trust users have opposing emotional bids, sets conflict_detected flag and triggers equidistance rules

class user_limbic_mirror.ContextMode(*values)[source]

Bases: Enum

ContextMode (inherits from Enum).

GENUINE = 'genuine'
GAME = 'game'
AMBIGUOUS = 'ambiguous'
class user_limbic_mirror.TurnRecord(timestamp, user_msg_len, star_reply_len, sentiment, deltas, context_mode, dominant_signals)[source]

Bases: object

Single turn record for rolling-window analysis.

Parameters:
timestamp: float
user_msg_len: int
star_reply_len: int
sentiment: float
deltas: Dict[str, float]
context_mode: ContextMode
dominant_signals: List[str]
class user_limbic_mirror.UserProfile(user_id, channel_id, genuine_vector=<factory>, game_vector=<factory>, relational_baseline=<factory>, history=<factory>, timestamps=<factory>, prev_message='', context_mode=ContextMode.GENUINE, total_turns=0, last_active=0.0)[source]

Bases: object

Complete per-user state, keyed by {channel}:{user}.

Parameters:
user_id: str
channel_id: str
genuine_vector: Dict[str, float]
game_vector: Dict[str, float]
relational_baseline: Dict[str, float]
history: deque
timestamps: deque
prev_message: str = ''
context_mode: ContextMode = 'genuine'
total_turns: int = 0
last_active: float = 0.0
class user_limbic_mirror.ChannelConflictState(detected=False, parties=<factory>, severity=0.0, started_at=0.0, description='')[source]

Bases: object

Tracks inter-user conflict within a channel.

Parameters:
detected: bool = False
parties: List[str]
severity: float = 0.0
started_at: float = 0.0
description: str = ''
class user_limbic_mirror.UserLimbicMirror(redis_client=None)[source]

Bases: object

Per-user relational model with conflict detection and game/genuine split.

Maintains separate shadow vectors per user per channel, detects inter-user conflict, and applies equidistance mechanics to prevent Star from siding with whoever is loudest.

__init__(redis_client=None)[source]

Initialize the instance.

Parameters:

redis_client – Redis connection client.

Return type:

None

set_game_mode(channel_id, active=True)[source]

Mark a channel as having active KoTH / game context.

Return type:

None

Parameters:
check_mimetic_pull(user_msg, star_desire_text)[source]

Check mimetic pull.

Parameters:
  • user_msg (str) – The user msg value.

  • star_desire_text (str) – The star desire text value.

Returns:

The result.

Return type:

float

analyze(channel_id, user_id, user_msg, star_reply='', star_desire_text='', context_mode=None)[source]

Analyze a user message and update their shadow vector.

Parameters:
  • channel_id (str)

  • user_id (str)

  • user_msg (str)

  • star_reply (str)

  • star_desire_text (str)

  • context_mode (Optional[ContextMode])

  • updates. (Returns the active shadow vector (genuine or game) after)

Return type:

Dict[str, float]

get_vector(channel_id, user_id, layer='genuine')[source]

Return a copy of user’s shadow vector (genuine or game).

Return type:

Dict[str, float]

Parameters:
get_conflict_state(channel_id)[source]

Return current conflict state for a channel.

Return type:

ChannelConflictState

Parameters:

channel_id (str)

get_read_summary(channel_id, user_id)[source]

Generate natural-language summary of user state for prompt injection.

Return type:

str

Parameters:
  • channel_id (str)

  • user_id (str)

get_channel_summary(channel_id)[source]

Return a summary of all users and conflict state in a channel.

Return type:

Dict[str, Any]

Parameters:

channel_id (str)

async inject_resonance(user_id, deltas, reason='', ttl_seconds=86400)[source]

Write resonance deltas to a global per-user key in Redis.

These deltas merge into the user’s shadow vector during analyze(), modulating how Star perceives and responds to this user across ALL channels. Spells decay after ttl_seconds.

Parameters:
  • user_id (str) – Target user’s Discord ID.

  • deltas (Dict[str, float]) – Node deltas to inject, e.g. {“U_TRUST”: 0.3, “U_INTIMACY”: 0.2}.

  • reason (str) – Why the resonance was cast (for logging / read summary).

  • ttl_seconds (int) – Time-to-live in seconds. Default 86400 (24h).

Return type:

bool

async load_resonance(user_id)[source]

Load global resonance state for a user.

Return type:

Dict[str, Any]

Returns:

  • dict with keys (deltas (Dict[str, float]), cast_at (float), reason (str))

  • Empty dict if no active resonance.

Parameters:

user_id (str)

async save_baseline(channel_id, user_id)[source]

Persist relational baseline to Redis for cross-session persistence.

Return type:

None

Parameters:
  • channel_id (str)

  • user_id (str)

async load_baseline(channel_id, user_id)[source]

Load relational baseline from Redis.

Return type:

None

Parameters:
  • channel_id (str)

  • user_id (str)