viva_emotion

VIVA Emotion - Core emotional engine

The “cartilage of sanity” - type-safe emotional processing

Architecture

Stimulus ──▶ PAD State ──▶ Dynamics ──▶ Emotion
                │              │
                └── evolve ────┘

Example

import viva_emotion
import viva_emotion/pad
import viva_emotion/stimulus
import viva_emotion/emotion

let state = viva_emotion.new()
let state = viva_emotion.feel(state, stimulus.Success, 1.0)
let #(state, _jumped) = viva_emotion.tick(state, 0.1)
let classified = viva_emotion.classify(state)
// classified.emotion == emotion.Joy

Types

Emotional state with full configuration

pub type EmotionalState {
  EmotionalState(
    pad: pad.Pad,
    config: dynamics.DynamicsConfig,
    classification: emotion.ClassificationConfig,
    stimulus_weights: dict.Dict(stimulus.Stimulus, pad.Pad),
    tick_count: Int,
  )
}

Constructors

Full state including long-term mood

pub type EmotionalStateWithMood {
  EmotionalStateWithMood(
    emotion: EmotionalState,
    mood: mood.Mood,
  )
}

Constructors

Values

pub fn bounce_mood(
  state: EmotionalStateWithMood,
  decay: Float,
) -> EmotionalStateWithMood

Apply Big Bounce to mood (partial continuity across death)

pub fn classify(
  state: EmotionalState,
) -> emotion.ClassifiedEmotion

Classify current emotional state using personality-specific thresholds

pub fn emotional_coherence(
  state: EmotionalState,
  need: pad.Pad,
  past: pad.Pad,
) -> Float

Get emotional coherence (how aligned are sources)

pub fn feel(
  state: EmotionalState,
  stim: stimulus.Stimulus,
  intensity: Float,
) -> EmotionalState

Apply a stimulus to the emotional state Uses personality-specific stimulus weights if configured

pub fn fuse(
  state: EmotionalState,
  need: pad.Pad,
  past: pad.Pad,
  context: fusion.FusionContext,
) -> EmotionalState

Fuse need-based, past-based, and personality PAD into single state

Uses adaptive weights based on context (arousal, confidence, novelty)

pub fn fuse_explicit(
  state: EmotionalState,
  need: pad.Pad,
  past: pad.Pad,
  weights: fusion.FusionWeights,
) -> EmotionalState

Fuse with explicit weights (bypass adaptive calculation)

pub fn fuse_simple(
  state: EmotionalState,
  need: pad.Pad,
) -> EmotionalState

Simple fusion with just need (no memory retrieval)

pub fn fusion_weights(
  context: fusion.FusionContext,
) -> fusion.FusionWeights

Calculate fusion weights for current context

pub fn get_mood(state: EmotionalStateWithMood) -> pad.Pad

Get current mood state

pub fn get_pad(state: EmotionalState) -> pad.Pad

Get current PAD values

pub fn has_emotional_conflict(
  state: EmotionalState,
  need: pad.Pad,
  past: pad.Pad,
) -> Bool

Check if there’s emotional conflict between sources

pub fn is_distressed(state: EmotionalState) -> Bool

Check if emotion is in “danger zone” (high arousal, low pleasure)

pub fn is_stable(state: EmotionalState) -> Bool

Check if emotion is stable (low arousal, near baseline)

pub fn mood_activation(state: EmotionalStateWithMood) -> Float

Get mood activation (arousal component)

pub fn mood_is_negative(state: EmotionalStateWithMood) -> Bool

Check if mood is negative

pub fn mood_is_positive(state: EmotionalStateWithMood) -> Bool

Check if mood is positive

pub fn mood_valence(state: EmotionalStateWithMood) -> Float

Get mood valence (simplified positive/negative measure)

pub fn new() -> EmotionalState

Create a new emotional state with default config

pub fn new_with_mood() -> EmotionalStateWithMood

Create state with mood tracking

pub fn tick(
  state: EmotionalState,
  dt: Float,
) -> #(EmotionalState, Bool)

Evolve the emotional state by one time step (deterministic) Returns updated state and whether a cusp catastrophe occurred

pub fn tick_with_noise(
  state: EmotionalState,
  dt: Float,
  noise: pad.Pad,
) -> #(EmotionalState, Bool)

Evolve with injected noise (stochastic O-U process)

noise: PAD where each component should be ~ N(0,1) for correct Euler-Maruyama discretization. Values outside [-1,1] are valid.

Use pad.neutral() for deterministic behavior (testing/replay)

pub fn update_mood(
  state: EmotionalStateWithMood,
) -> EmotionalStateWithMood

Update mood with current emotion

pub fn with_full_config(
  baseline: pad.Pad,
  dynamics_config: dynamics.DynamicsConfig,
  classification_config: emotion.ClassificationConfig,
  weights: dict.Dict(stimulus.Stimulus, pad.Pad),
) -> EmotionalState

Create fully customized emotional state

pub fn with_personality(baseline: pad.Pad) -> EmotionalState

Create emotional state with custom baseline (personality)

pub fn with_personality_and_mood(
  baseline: pad.Pad,
) -> EmotionalStateWithMood

Create with personality and mood

Search Document