from __future__ import annotations
from typing import Any, TypedDict
from langchain_core.messages import BaseMessage
class EmotionSnapshot(TypedDict, total=False):
"""Single-turn emotion measurement."""
turn: int
valence: float # -1 (negative) to +1 (positive)
arousal: float # 0 (calm) to 1 (intense)
label: str # e.g. "anxious", "hopeful", "neutral"
class UserMemory(TypedDict, total=False):
"""User state memory accumulated per turn."""
# Trust & rapport
confidence_level: float # 0~1, how much James trusts the user
rapport_score: float # 0~1, overall relationship quality
# Emotion tracking
emotion_trajectory: list[EmotionSnapshot]
dominant_emotion: str # most frequent emotion label
# Conversation flow
current_conversation_stage: str # opening / developing / deepening / closing
stage_history: list[str] # track stage transitions
# Behavioral analysis
key_observations: list[str]
empathy_hits: int # count of empathetic responses
empathy_misses: int # count of insensitive/cliché responses
empathy_ratio: float # hits / (hits + misses)
# Engagement
avg_response_length: float # average user message length
silence_count: int # short/empty responses (disengagement signal)
# NPC internal state
npc_openness: float # 0~1, how open James is being
npc_mood: str # guarded / cautious / warming / open / withdrawn
class AgentOutput(TypedDict, total=False):
"""LLM call result."""
response: str # NPC dialogue
should_end_turn: bool # Whether to end the conversation
next_step: str # reflection / continue
emotion_assessment: dict[str, Any] # User emotion assessment
observation: str # Observation for this turn
empathy_quality: str # "hit" / "miss" / "neutral"
trust_shift: float # -0.3 to +0.3, how much trust changed this turn
npc_internal_mood: str # James's internal emotional state
class WalkState(TypedDict, total=False):
"""LangGraph full state."""
# Conversation
messages: list[BaseMessage]
user_input: str
# Scenario
scenario: dict[str, Any]
# Turn management
turn_index: int
# Memory
memory: UserMemory
# LLM output
agent_output: AgentOutput
# Reflection
reflection_result: str
# Error
error: str | None