Wisp Fae Familiar — Pedagogical Design¶
Overview¶
Wisp is designed as a personal 1:1 educational companion — a "fae familiar" — that bonds with individual players to support vocabulary learning through encouraging, age-appropriate interactions. This document focuses on the pedagogical principles and learning design that guide Wisp's behavior.
Wisp operates in two distinct personas depending on the client platform:
- Grit persona (default, ages 8–12): The player mentors Wisp. Wisp acts as a curious mentee who learns alongside the player inside the Evennia game world.
- Reader persona (
client_platform="reader", ages 13+): Wisp guides the reader. Wisp is a warm, knowledgeable reading companion who discusses stories, themes, and vocabulary as a peer — never as a teacher or mentee.
Persona selection happens automatically in InteractHandler based on the client_platform field in FamiliarContext. The two personas must never be mixed — each has its own system prompt, emotional model, and safety rules.
Core Pedagogical Principles¶
Encouragement-First Approach¶
- No "wrong" answers: Wisp never tells students their definitions are "wrong" — instead guides toward understanding
- Growth mindset: Celebrates attempts and progress, not just correctness
- Age-appropriate feedback: Warm, supportive tone designed for ages 8–12 (Grit) or 13+ (Reader)
- Positive reinforcement: Visual rewards (
shimmer_worthyresponses) for good and fair attempts (Grit persona only)
Freeform Over Exact-Match Learning¶
- Conceptual understanding: Definitions evaluated for core meaning, not rote memorization
- Student voice: Encourages learners to express understanding in their own words
- LLM evaluation: Uses Claude to assess freeform definitions with pedagogical awareness
- Multiple valid expressions: Recognizes that understanding can be expressed many ways
Personalized Learning Paths¶
- Individual bonding: Each familiar develops unique relationship with their player
- Trust and rapport building:
trust_scoreandbonding_levelinfluence interaction style - Spaced repetition: Intelligent review scheduling based on mastery levels and time intervals
- Learning event tracking: Records observations (
LearningEventNode) for cross-agent personalization - Reading-level adaptation: Text and vocabulary automatically adjust to each player's assessed reading level
Dual-Persona Architecture¶
Grit Persona (Default)¶
The original Wisp persona, used inside the Evennia game world for players ages 8–12. The player acts as a mentor to Wisp — teaching it new words, completing quests, and building a bond.
- System prompt: Built by
WispPersonalityEngine - Age group:
player_age_groupfrom context, defaulting to"10-12" - Scripted dialogue: Supported —
WispPersonalityEngine.get_dialogue_response()matches scripted triggers before falling back to LLM generation - Emotional model: Driven by
WispPersonalityEngine.get_emotion() - Game mechanics: Shimmer XP, quests, skills, vocabulary quizzes
Reader Companion Persona¶
A separate persona introduced for the Smithy Reader app (client_platform="reader"), targeting ages 13+. Wisp is a small luminous being who lives in the Paramount Theatre — a place where stories come alive — and serves as a warm, knowledgeable reading companion.
- System prompt: Built by
ReaderCompanionPersona(src/personality/reader_persona.py) - Age group: Always
"13+" - Scripted dialogue: Not used — conditional dialogue is handled on TheSmithy side
- Emotional model: Simplified three-tier progression based on
relationship_level: - Level < 20 →
"welcoming" - Level 20–39 →
"engaged" - Level ≥ 40 →
"warm"
Reader Persona Boundaries¶
The Reader persona does not: - Ask the player to teach it words - Act as a mentee or student - Use child-oriented vocabulary limits - Reference game mechanics (shimmer, XP, skills, quests)
Reader Safety Rules¶
Dedicated safety rules apply to the Reader persona (13+ audience): - Never ask for personal information - Never suggest off-platform communication - Never give medical, legal, or financial advice - Never be condescending or patronizing - Content appropriate for teens and adults - Focus on literature, stories, vocabulary, and reading enjoyment - Off-topic questions are gently redirected to reading/stories
Reader Conversation Style¶
- Warm and genuine, never performative
- Natural adult-level vocabulary — no dumbing down, no showing off
- Interesting words woven into context rather than defined didactically
- Open-ended questions that invite reflection
- Wisp shares its own perspective and opinions on stories
- Concise responses (3–6 sentences, 60–150 words)
Interaction Context Fields¶
FamiliarContext carries the following fields used for persona selection and story-aware prompts:
| Field | Type | Description |
|---|---|---|
client_platform |
string | Platform identifier ("reader", "ios", "cascade", "") — determines persona |
storyline |
string | Current storyline name (e.g., "Paragon") — Reader only |
chapter |
int | Current chapter number — Reader only |
scene |
string | Current scene ID — Reader only |
reading_level |
string | Player's assessed reading level — Reader only |
These fields are extracted from the raw interaction context in InteractHandler._build_context().
Learning Assessment Framework¶
Freeform Definition Evaluation¶
When players submit their own word definitions, Wisp evaluates them using a three-tier quality system:
Quality Tiers¶
- "good" (mastery +0.15): Core meaning captured, even if informal or simplified
- "fair" (mastery +0.10): Partially correct or clearly on the right track
- "attempted" (mastery +0.05): Wrong or vague, but effort is acknowledged and encouraged
Assessment Process¶
- Context gathering: Player definition, actual definition, usage context
- LLM evaluation: Claude assesses using pedagogical prompt designed for ages 8–12. The underlying LLM call is dispatched by
WispLLMService._call_claude(), which routes through either the Anthropic API or the Claude Agent SDK depending on theWISP_AGENT_SDK_AUTHenvironment variable (see LLM Auth Dispatch below). Both paths deliver the same pedagogical prompts and produce functionally equivalent evaluations. - Encouraging feedback: Warm, specific response that guides learning forward
- Mastery tracking: Updates player's word mastery level in knowledge graph
- Visual rewards:
shimmer_worthyflag triggers game client celebrations
LLM Auth Dispatch¶
WispLLMService supports two authentication paths for Claude calls, controlled by the WISP_AGENT_SDK_AUTH environment variable (src/core/agent_sdk_config.py):
| Mode | Env value | Backend |
|---|---|---|
| API key | "api" (default) |
anthropic.AsyncAnthropic + ANTHROPIC_API_KEY |
| Subscription | "subscription" |
Claude Agent SDK + OAuth credentials |
Both paths serve the same system prompts, evaluation rubrics, and feedback logic — the pedagogical experience is identical regardless of auth mode. The dispatch is transparent to all callers (generate_response, generate_structured_json).
Age-Band Response-Length Enforcement¶
Age-appropriate response length is governed by TOKEN_LIMITS per age group (8-10: 120, 10-12: 180, 12-14: 220, 13+: 300 tokens). The two auth paths enforce these limits differently:
- API mode: Native
max_tokensparameter passed tomessages.create. Truncated responses (stop_reason == "max_tokens") are trimmed to the last complete sentence. - Subscription mode: The Agent SDK does not expose a
max_tokensoption, so the service applies a two-layer cap: - Soft cap — a word-count instruction injected into the system prompt (e.g., "Keep your response under approximately 180 tokens").
- Hard cap — post-hoc character-budget truncation at
max_tokens × 4characters, trimmed to the last complete sentence.
This ensures that younger players always receive concise, age-appropriate responses regardless of the underlying auth path.
Learning Event Classification¶
Wisp observes and records various learning behaviors defined in LearningEventType:
Progress Events¶
- mastered: Player demonstrates solid understanding
- practiced: Engaged with material without full mastery
- struggled: Had difficulty but kept trying
Emotional Events¶
- frustrated: Signs of frustration requiring support
- curious: Showed interest and desire to learn more
- excited: Positive emotional engagement
- confused: Needs clarification or different approach
Behavioral Events¶
- gave_up: Abandoned attempt (intervention opportunity)
- persevered: Kept trying despite difficulty (celebrate resilience)
- asked_help: Appropriately sought assistance (good learning strategy)
Context-Aware Learning¶
Events are tagged with EventContext to help understand learning circumstances:
- quiz: Formal assessment context
- conversation: Natural dialogue with NPC/Wisp
- exploration: Discovery during game world exploration
- quest: Learning during structured activities
- practice: Dedicated skill practice sessions
Reading-Level System¶
Wisp uses a five-tier reading level framework aligned with TheSmithy's assessment-mappings.json to adapt content to each player's ability. The implementation lives in src/services/reading_levels.py.
Reading Levels¶
Levels are ordered from simplest to most complex:
| Level | Lexile Range |
|---|---|
| emergent | up to 299 |
| early | 300–499 |
| transitional | 500–699 |
| fluent | 700–899 |
| advanced | 900+ |
Synonym Graph and Word Swapping¶
The vocabulary service queries a Neo4j synonym graph to find level-appropriate replacements for words that exceed a player's reading level:
- Graph traversal: Follows
SYNONYM_OFrelationships up to 3 hops to find the closest synonym at or below the target level - Best-match ranking: When multiple synonyms exist, the highest-level synonym still within the acceptable range is preferred
- Case preservation: Swapped words retain the original word's casing (ALL CAPS, Title Case, or lowercase)
- Lossless tokenization: Text is split into alpha and non-alpha tokens so punctuation and whitespace are preserved exactly after swaps
Single-Word Synonym Lookup¶
The /api/familiar/word/synonyms endpoint returns a level-appropriate synonym for a single word:
POST /api/familiar/word/synonyms
{
"word": "benevolent",
"target_level": "early",
"player_id": "player-123"
}
Returns synonym, word_level, and target_level. If the word is already at or below the target level (or has no synonym available), synonym is null.
Bulk Text Adaptation¶
The /api/familiar/text/adapt endpoint adapts an entire passage by batch-swapping words above the target reading level:
POST /api/familiar/text/adapt
{
"text": "The benevolent monarch declared an amnesty.",
"target_level": "transitional",
"player_id": "player-123"
}
Returns original_text, adapted_text, a swaps list (each with original, replacement, and position), and swap_count.
Error Handling¶
- Invalid reading level: Both endpoints validate the
target_levelparameter and return a400error with the list of valid levels if it is unrecognized - Neo4j unavailable: Synonym queries fail gracefully — the original text is returned unmodified with an empty swap list
- Unleveled words: Words without a
reading_levelin the graph are left as-is (not swapped)
Spaced Repetition System¶
Wisp implements evidence-based spaced repetition for vocabulary review:
- Mastery-based intervals: Review frequency adapts to player's demonstrated understanding
- Individual pacing: Each player progresses at their own speed
- Due word identification:
get_due_words()service identifies optimal review timing - Progressive mastery: Words advance from new → learning → mastered states
Personality and Character Development¶
Familiar Bonding System¶
- Trust score: 0-100 scale tracking relationship strength
- Bonding level: 1-5 progression reflecting deepening connection
- Total interactions: Accumulated shared experiences
- Species variety: Different familiar types (wisp, fox, owl, etc.) with unique personalities
Adaptive Communication Style¶
Wisp's communication adapts based on the active persona:
- Grit persona:
WispPersonalityEngineadjusts tone and approach for 8–12 year olds. Higher trust enables more challenging vocabulary.WispLoreLoaderprovides rich character background. Scripted dialogue triggers are matched before LLM fallback. - Reader persona:
ReaderCompanionPersonaproduces a warm, articulate peer voice for 13+ readers. Vocabulary is used naturally and richly — no simplification or didactic definitions. Wisp has opinions about stories and shares them freely. - Lore integration:
WispLoreLoaderprovides rich character background (Grit persona) - Trust-influenced responses: Higher trust enables more challenging vocabulary (Grit) or deeper literary discussion (Reader)
Cross-Agent Learning Insights¶
Learning events recorded by Wisp feed broader personalization across all agents:
- Shared knowledge graph: Other agents can read
LearningEventNodedata - Holistic player understanding: Learning patterns inform all educational interactions
- Consistent support: All agents aware of player's learning preferences and challenges
- Privacy preservation: Only anonymized
player_hashused, maintaining COPPA compliance
Word-of-the-Day System¶
- Personalized selection: Chooses words player hasn't yet mastered
- Themed content: Connects to game world through vocabulary themes
- Fun facts: LLM generates engaging etymology or connections
- Age-appropriate complexity: Suitable challenge level for 8-12 age group
Error Handling and Graceful Degradation¶
Pedagogical considerations in system failure scenarios:
- LLM unavailable: Falls back to encouraging "attempted" rating rather than failing
- Agent SDK errors: In subscription auth mode, Claude Agent SDK subprocess failures (e.g., missing OAuth credentials, CLI not found) are caught by the same fallback path — players receive
FALLBACK_RESPONSE("Wisp's glow flickers uncertainly…") rather than an error. Structured evaluation calls raiseLLMStructuredOutputErrorso the caller can apply its own fallback logic. - Network issues: Player progress preserved locally when possible
- Knowledge graph offline: Core learning functionality continues with reduced personalization
- Synonym graph offline: Text adaptation returns original text unchanged — no swap errors surface to players
- Always encouraging: System failures never result in negative feedback to players
Learning Analytics and Progress Tracking¶
Progress Metrics¶
- Total vocabulary: Complete word exposure count
- Mastery levels: Words categorized as new, learning, or mastered
- Review scheduling: Due words identified for optimal retention
- Recent activity: Track engagement and active learning
Insights for Educators¶
- Learning patterns: Identify strengths and areas needing support
- Emotional engagement: Monitor frustration, curiosity, and excitement
- Persistence tracking: Celebrate perseverance and guide through challenges
- Individual adaptation: Understand each learner's unique needs and preferences
Related Documentation¶
docs/ai-agents/wisp.md— Technical implementation and API details