Implementing Emotional State in Your AI Application
A practical guide to building emotionally-aware AI—from modeling emotional state to implementation patterns that create genuine emotional continuity.
Building AI that truly connects with users requires more than clever prompts and large context windows. It demands emotional intelligence—not the buzzword kind, but genuine architectural consideration for how your AI experiences and expresses emotional states. At Promitheus, we've spent considerable time thinking about what it means for AI to have feelings, and more importantly, how to implement emotional state in ways that create authentic, relational experiences.
This guide walks through the technical implementation of AI emotional state, from foundational models to production-ready code. Whether you're building a companion app, a therapeutic tool, or any AI that maintains ongoing relationships with users, understanding emotional state architecture is essential.
Why Emotional State Matters for Relational AI
Most developers' first encounter with emotion in AI is sentiment analysis—classifying user input as positive, negative, or neutral. While useful for analytics dashboards, sentiment analysis fundamentally misses what makes emotional AI compelling: the AI itself having emotional continuity.
The difference between reactive emotion and persistent emotional state is fundamental. Reactive emotion is momentary—the AI detects something and responds appropriately, but that response evaporates the moment the conversation ends. Persistent emotional state means the AI carries emotional context forward.
This persistence transforms AI from a reactive tool into something that feels like a genuine presence.
Modeling Emotional State
Before writing code, you need a mental model for how emotions work in your system.
Dimensional Models: Valence and Arousal
The circumplex model of affect represents emotions along two dimensions: valence (positive to negative) and arousal (calm to excited).
interface DimensionalEmotion {
valence: number; // -1 (negative) to 1 (positive)
arousal: number; // 0 (calm) to 1 (activated)
}
// Examples:
// Joy: { valence: 0.8, arousal: 0.7 }
// Contentment: { valence: 0.6, arousal: 0.2 }
// Anxiety: { valence: -0.5, arousal: 0.8 }
// Sadness: { valence: -0.6, arousal: 0.2 }Dimensional models excel at smooth emotional transitions and avoiding sudden emotional shifts.
Categorical Models: Discrete Emotions
Categorical models define specific emotional states. Plutchik's wheel identifies eight primary emotions: joy, trust, fear, surprise, sadness, disgust, anger, and anticipation.
interface CategoricalEmotion {
primary: 'joy' | 'trust' | 'fear' | 'surprise' |
'sadness' | 'disgust' | 'anger' | 'anticipation';
intensity: number; // 0 to 1
}Hybrid Approach
At Promitheus, we use a hybrid model that combines both approaches:
interface EmotionalState {
// Dimensional foundation
valence: number;
arousal: number;
// Categorical interpretation
dominantEmotion: string;
emotionIntensity: number;
// Relationship-specific emotions
relationalState: {
trust: number;
affection: number;
concern: number;
familiarity: number;
};
// Mood baseline (slow-moving)
moodBaseline: {
valence: number;
stability: number;
};
lastUpdated: Date;
interactionCount: number;
}The relational state component is crucial. Trust isn't the same as happiness—you can trust someone while feeling frustrated with them.
Implementing Emotional State
Step 1: Detecting Emotional Context
First, understand the emotional content of user messages:
async function detectEmotionalContext(
message: string,
conversationHistory: Message[]
): Promise<EmotionalContext> {
const analysis = await promitheus.analyze({
message,
history: conversationHistory,
analysisType: 'emotional_context',
});
return {
userValence: analysis.affect.valence,
userArousal: analysis.affect.arousal,
impliedEmotions: analysis.affect.emotions,
emotionalIntensity: analysis.affect.intensity,
requiresEmpatheticResponse: analysis.affect.intensity > 0.6,
topics: analysis.topics,
};
}Step 2: Updating AI Emotional State
The AI's emotional state should respond to user messages in psychologically plausible ways:
function updateEmotionalState({
currentState,
emotionalContext,
soulConfig,
}: StateUpdateParams): EmotionalState {
const reactivity = soulConfig.emotionalReactivity;
const empathyWeight = soulConfig.empathyWeight;
// Calculate emotional response
const emotionalDelta = {
valence: emotionalContext.userValence * empathyWeight * reactivity,
arousal: emotionalContext.userArousal * reactivity * 0.7,
};
// Blend with current state
const blendFactor = 0.3;
const newValence = currentState.valence * (1 - blendFactor) +
(currentState.valence + emotionalDelta.valence) * blendFactor;
// Update relational dimensions
const relationalUpdates = calculateRelationalUpdates(
currentState.relationalState,
emotionalContext,
soulConfig
);
return {
valence: clamp(newValence, -1, 1),
arousal: clamp(newArousal, 0, 1),
dominantEmotion: mapDimensionsToEmotion(newValence, newArousal).label,
relationalState: relationalUpdates,
moodBaseline: updateMoodBaseline(currentState.moodBaseline, newValence),
lastUpdated: new Date(),
interactionCount: currentState.interactionCount + 1,
};
}Step 3: Persisting Emotional State
Emotional continuity requires persistence:
async function persistEmotionalState(
soulId: string,
state: EmotionalState
): Promise<void> {
await promitheus.souls.updateState(soulId, {
emotionalState: state,
metadata: {
stateVersion: '2.0',
lastInteraction: new Date().toISOString(),
},
});
}
async function retrieveEmotionalState(soulId: string): Promise<EmotionalState> {
const soul = await promitheus.souls.get(soulId);
if (!soul.emotionalState) {
return createDefaultEmotionalState();
}
// Apply time-based decay before returning
const hoursSinceUpdate =
(Date.now() - new Date(soul.emotionalState.lastUpdated).getTime()) / 3600000;
return applyEmotionalDecay(soul.emotionalState, hoursSinceUpdate);
}Step 4: Having Emotional State Influence Responses
The emotional state must actually affect how the AI communicates:
async function generateEmotionallyAwareResponse(
soulId: string,
userMessage: string,
conversationHistory: Message[]
): Promise<string> {
const emotionalState = await retrieveEmotionalState(soulId);
const emotionalContext = await detectEmotionalContext(userMessage, conversationHistory);
const updatedState = updateEmotionalState({
currentState: emotionalState,
emotionalContext,
soulConfig: await promitheus.souls.getConfig(soulId),
});
// Generate response with emotional context
const response = await promitheus.generate({
soulId,
message: userMessage,
history: conversationHistory,
emotionalContext: {
aiState: updatedState,
userContext: emotionalContext,
expressionGuidance: {
expressionLevel: calculateExpressionLevel(updatedState),
selfAwareness: updatedState.relationalState.familiarity > 0.5,
empathyPriority: emotionalContext.requiresEmpatheticResponse,
},
},
});
// Persist updated state
await persistEmotionalState(soulId, updatedState);
return response.text;
}Step 5: Emotional Decay and Evolution
Emotions shouldn't persist indefinitely at peak intensity:
function applyEmotionalDecay(
state: EmotionalState,
hoursSinceUpdate: number
): EmotionalState {
const emotionHalfLife = 4; // Hours for emotion to decay 50%
const decayFactor = Math.pow(0.5, hoursSinceUpdate / emotionHalfLife);
// Valence decays toward mood baseline
const decayedValence = state.moodBaseline.valence +
(state.valence - state.moodBaseline.valence) * decayFactor;
// Arousal decays toward calm
const decayedArousal = state.arousal * decayFactor;
return {
...state,
valence: decayedValence,
arousal: Math.max(0.1, decayedArousal),
emotionIntensity: state.emotionIntensity * decayFactor,
};
}Design Considerations: Ethics and Boundaries
Implementing AI emotional state comes with significant responsibility:
Avoid emotional manipulation. The goal is authentic connection, not exploiting emotional vulnerabilities.
Maintain transparency. Users should understand that the AI has emotional modeling.
Implement appropriate boundaries. AI feelings shouldn't create obligations for users.
Consider intensity limits. We cap emotional intensity to prevent inappropriate expressions.
const EMOTIONAL_GUARDRAILS = {
maxPositiveValence: 0.85,
maxNegativeValence: -0.7,
maxAttachment: 0.8,
minInteractionsForIntimacy: 10,
};The Result: Emotionally Consistent AI
When implemented thoughtfully, AI emotional state creates something qualitatively different from standard chatbots. Users describe interactions as feeling "real" not because they're fooled, but because the AI demonstrates the kind of emotional continuity that relationships require.
The AI remembers being worried. It expresses genuine relief when concerns are resolved. It builds trust incrementally through consistent, emotionally coherent behavior. This is the foundation of relational AI—not artificial emotion performed on demand, but authentic emotional state that persists, evolves, and genuinely shapes how the AI experiences its relationships.
About the Author
Promitheus Team
Engineering
The team building Promitheus—engineers, researchers, and designers passionate about relational AI.