DEPRECATION NOTICE
This implementation plan has been completed. The checkboxes below were not updated during implementation and do not reflect current status. Please refer to the actual codebase for the current implementation state. Key implemented features include:
- DialogueComponent (
packages/maid-stdlib/src/maid_stdlib/components/dialogue.py)- ConversationManager (
packages/maid-engine/src/maid_engine/ai/conversation.py)- PromptBuilder (
packages/maid-engine/src/maid_engine/ai/prompts.py)- RateLimiter (
packages/maid-engine/src/maid_engine/ai/rate_limiter.py)- NPCDialogueSystem (
packages/maid-classic-rpg/src/maid_classic_rpg/systems/npc/dialogue.py)- Dialogue Commands (
packages/maid-classic-rpg/src/maid_classic_rpg/commands/)
AI Integration Completion - Implementation Plan¶
Summary¶
This plan implements MAID's AI-powered NPC dialogue system, transforming the existing AI framework (providers, context builders, streaming) into a functional end-to-end dialogue system. The goal is feature parity with Evennia's LLMNPC while leveraging MAID's superior infrastructure (multi-provider support, streaming, ECS architecture).
Key Deliverables:
- Working talk <npc> <message> command with AI-generated responses
- Context-aware NPC conversations (world state, location, player info)
- Conversation memory within sessions
- Multi-provider support (Anthropic, OpenAI, Ollama)
- Rate limiting and safety guardrails
Tasks¶
Phase 1: Core Infrastructure¶
1.1 DialogueComponent (maid-stdlib)¶
File: packages/maid-stdlib/src/maid_stdlib/components/dialogue.py
- [x] Create
DialogueComponentclass extendingComponent - [x] AI config fields:
ai_enabled,provider_name,model_name - [x] Personality fields:
personality,speaking_style,knowledge_domains,secret_knowledge - [x] Role fields:
npc_role,faction - [x] Behavioral constraints:
will_discuss,wont_discuss - [x] Response settings:
max_response_tokens,temperature - [x] Fallback dialogue:
greeting,farewell,fallback_response - [x] Rate limiting:
cooldown_seconds,last_response_time - [x] Add Pydantic validation rules (token range 50-500, temperature 0.0-1.0)
- [x] Write unit tests for component (
test_dialogue_component.py) - [x] Export from
maid_stdlib/components/__init__.py
1.2 ConversationManager (maid-engine)¶
File: packages/maid-engine/src/maid_engine/ai/conversation.py
- [x] Create
ConversationMessagedataclass - [x] Fields:
role,content,timestamp,metadata - [x] Create
Conversationdataclass - [x] Fields:
player_id,npc_id,messages,started_at,last_activity,context_data - [x] Method:
add_message(role, content) - [x] Method:
get_recent_messages(count=10) - [x] Method:
to_conversation_context(...) - [x] Method:
is_stale(timeout_minutes=30) - [x] Create
ConversationManagerclass - [x] Method:
get_or_create(player_id, npc_id) - [x] Method:
get(player_id, npc_id) - [x] Method:
end_conversation(player_id, npc_id) - [x] Method:
cleanup_stale() - [x] Method:
get_player_conversations(player_id) - [x] Write unit tests (
test_conversation_manager.py) - Depends on: None
1.3 PromptBuilder (maid-engine)¶
File: packages/maid-engine/src/maid_engine/ai/prompts.py
- [x] Create
NPCPromptConfigdataclass - [x] Context toggles:
include_world_context,include_location_context,include_player_context - [x] Safety flags:
enforce_character,block_meta_discussion,block_harmful_content - [x] Limit:
max_context_tokens,allowed_actions - [x] Create
PromptBuilderclass - [x] Define
SYSTEM_TEMPLATEwith personality, role, guidelines, restrictions - [x] Define
WORLD_CONTEXT_TEMPLATE(time, weather, events) - [x] Define
LOCATION_CONTEXT_TEMPLATE(room, exits, characters) - [x] Define
PLAYER_CONTEXT_TEMPLATE(name, level, race, class, reputation) - [x] Method:
build_system_prompt(...)- assembles full system prompt - [x] Method:
build_messages(...)- builds message list for API call - [x] Method:
build_for_npc(...)- convenience wrapper using DialogueComponent - [x] Add hardcoded safety guardrails in system prompt
- [x] Write unit tests (
test_prompt_builder.py) - Depends on: 1.2 ConversationManager (for ConversationContext integration)
Phase 2: System Integration¶
2.1 NPCDialogueSystem (maid-classic-rpg)¶
File: packages/maid-classic-rpg/src/maid_classic_rpg/systems/npc/dialogue.py
- [x] Create
NPCDialogueSystemclass extendingSystem - [x] Set
priority = 50 - [x] Initialize
ConversationManagerin constructor - [x] Initialize
PromptBuilderin constructor - [x] Implement lifecycle methods
- [x]
startup()- subscribe to events if needed - [x]
shutdown()- cancel pending responses, cleanup - [x]
update(delta)- periodic cleanup of stale conversations - [x] Implement
process_dialogue(player_entity, npc_entity, message, session) - [x] Get DialogueComponent from NPC entity
- [x] Check if AI is enabled, return fallback if not
- [x] Check cooldown, return waiting message if on cooldown
- [x] Get/create conversation via ConversationManager
- [x] Build all contexts (World, Location, Entity, Conversation)
- [x] Build messages via PromptBuilder
- [x] Get LLM provider from registry (support per-NPC override)
- [x] Stream response to player session
- [x] Record messages in conversation history
- [x] Update cooldown timestamp
- [x] Handle errors with fallback response
- [x] Implement
find_npc_in_room(room_id, keyword)for NPC lookup - [x] Implement helper methods:
_get_dialogue_component(),_get_entity_name(),_build_location_context(),_check_cooldown() - [x] Write unit tests with MockProvider (
test_npc_dialogue_system.py) - Depends on: 1.1 DialogueComponent, 1.2 ConversationManager, 1.3 PromptBuilder
2.2 Register System in ContentPack¶
File: packages/maid-classic-rpg/src/maid_classic_rpg/pack.py
- [x] Import
NPCDialogueSystem - [x] Add to
get_systems()method inClassicRPGContentPack - [x] Verify initialization order (must come after component registration)
- Depends on: 2.1 NPCDialogueSystem
Phase 3: Command Implementation¶
3.1 Talk Command¶
File: packages/maid-classic-rpg/src/maid_classic_rpg/commands/handlers/dialogue.py (new file)
- [x] Create
dialogue.pycommand handler file - [x] Implement
cmd_talkcommand - [x] Parse target NPC keyword and message from input
- [x] Handle missing target: "Talk to whom?"
- [x] Handle missing message: "What do you want to say?"
- [x] Get character's current room
- [x] Get player entity from world
- [x] Get NPCDialogueSystem from world systems
- [x] Find NPC in room by keyword
- [x] Handle NPC not found: "You don't see '{keyword}' here to talk to."
- [x] Call
dialogue_system.process_dialogue() - [x] Register command with category
SOCIAL, aliases["tell"] - [x] Write integration tests
- Depends on: 2.1 NPCDialogueSystem
3.2 Ask Command¶
File: packages/maid-classic-rpg/src/maid_classic_rpg/commands/handlers/dialogue.py
- [x] Implement
cmd_askcommand - [x] Parse "npc about topic" format
- [x] Validate " about " separator exists
- [x] Reformat topic as question: "What can you tell me about {topic}?"
- [x] Delegate to
cmd_talklogic - [x] Register command with category
SOCIAL - [x] Write tests
- Depends on: 3.1 Talk Command
3.3 Conversation Management Commands¶
File: packages/maid-classic-rpg/src/maid_classic_rpg/commands/handlers/dialogue.py
- [x] Implement
cmd_conversationscommand - [x] Get player's active conversations from ConversationManager
- [x] Display NPC names and message counts
- [x] Handle empty list: "You have no active conversations."
- [x] Implement
cmd_endconversationcommand - [x] Parse target NPC keyword
- [x] Find NPC in room
- [x] End conversation via ConversationManager
- [x] Display NPC's farewell message
- [x] Register commands with appropriate categories
- [x] Write tests
- Depends on: 3.1 Talk Command
3.4 Register Commands in ContentPack¶
File: packages/maid-classic-rpg/src/maid_classic_rpg/pack.py
- [x] Import dialogue command handlers
- [x] Add to
register_commands()method - Depends on: 3.1, 3.2, 3.3
Phase 4: Configuration & Safety¶
4.1 AIDialogueSettings¶
File: packages/maid-engine/src/maid_engine/config/settings.py
- [x] Create
AIDialogueSettingsclass extendingBaseSettings - [x]
enabled: bool = True - [x]
default_provider: str = "anthropic" - [x]
default_model: str | None = None - [x]
default_max_tokens: int = 150 - [x]
default_temperature: float = 0.7 - [x]
global_rate_limit_rpm: int = 60 - [x]
per_player_rate_limit_rpm: int = 10 - [x]
per_npc_cooldown_seconds: float = 2.0 - [x]
daily_token_budget: int | None = None - [x]
per_player_daily_budget: int | None = 5000 - [x]
include_world_context: bool = True - [x]
include_location_context: bool = True - [x]
include_player_context: bool = True - [x]
max_conversation_history: int = 10 - [x]
conversation_timeout_minutes: int = 30 - [x]
content_filtering: bool = True - [x]
log_conversations: bool = False - [x] Set
env_prefix = "MAID_AI_DIALOGUE_" - [x] Add to main Settings class
- [x] Write validation tests
- Depends on: None
4.2 RateLimiter¶
File: packages/maid-engine/src/maid_engine/ai/rate_limiter.py (new file)
- [x] Create
RateLimitStatedataclass - [x]
request_times: list[float] - [x]
tokens_used_today: int = 0 - [x]
day_start: float = 0.0 - [x] Create
RateLimiterclass - [x] Constructor params:
global_rpm,per_player_rpm,daily_token_budget,per_player_daily_budget - [x] Method:
check_rate_limit(player_id)→tuple[bool, str]- [x] Check global RPM limit
- [x] Check per-player RPM limit
- [x] Check global daily token budget
- [x] Check per-player daily token budget
- [x] Return appropriate rejection messages
- [x] Method:
record_request(player_id, tokens_used) - [x] Write unit tests (
test_rate_limiter.py) - Depends on: None
4.3 Integrate Rate Limiting into NPCDialogueSystem¶
File: packages/maid-classic-rpg/src/maid_classic_rpg/systems/npc/dialogue.py
- [x] Import
RateLimiter - [x] Initialize
RateLimiterfromAIDialogueSettingsin constructor - [x] Add rate limit check before processing dialogue
- [x] Record request after successful response
- [x] Handle rate limit rejection with user-friendly message
- Depends on: 4.1 AIDialogueSettings, 4.2 RateLimiter
4.4 Content Filtering (Optional Enhancement)¶
File: packages/maid-engine/src/maid_engine/ai/safety.py (new file)
- [x] Create
ContentFilterclass (optional/future) - [x] Method:
check_input(message)- validate player input - [x] Method:
check_output(response)- validate AI response - [x] Integrate into NPCDialogueSystem if enabled in settings
- Depends on: 4.1 AIDialogueSettings
Phase 5: Testing & Polish¶
5.1 Create Test NPCs¶
Directory: packages/maid-classic-rpg/data/npcs/ or test fixtures
- [x] Create bartender NPC configuration
- [x] Personality: gruff but kind-hearted
- [x] Knowledge: local gossip, drinks, travelers' tales
- [x] Create town guard NPC configuration
- [x] Personality: dutiful, formal
- [x] Knowledge: town laws, local crimes
- [x] Restrictions: won't discuss bribes
- [x] Create mysterious merchant NPC configuration
- [x] Personality: flowery, hints at secrets
- [x] Knowledge: rare items, distant lands
- [x] Higher temperature (0.9) for variety
- [x] Document NPC configuration format in examples
- Depends on: 1.1 DialogueComponent
5.2 End-to-End Tests¶
File: packages/maid-classic-rpg/tests/test_dialogue_e2e.py
- [x] Test
talk bartender hellofull flow with MockProvider - [x] Test
ask guard about troublereformatting - [x] Test multiple exchanges maintain conversation context
- [x] Test conversation timeout resets history
- [x] Test different NPC personalities respond differently
- [x] Test rate limiting prevents rapid requests
- [x] Test fallback when AI provider unavailable
- [x] Test streaming response format (quotes, NPC name)
- Depends on: 3.1 Talk Command, 5.1 Test NPCs
5.3 Manual Provider Testing¶
- [x] Test with Anthropic provider (Claude)
- [x] Test with OpenAI provider (GPT-4)
- [x] Test with Ollama provider (local models)
- [x] Verify streaming works correctly for each
- [x] Document any provider-specific quirks
- Depends on: 5.2 E2E Tests
5.4 Documentation¶
- [x] Update main README with AI dialogue feature
- [x] Create NPC creation guide (
docs/guides/npc_dialogue.md) - [x] DialogueComponent field explanations
- [x] Personality design tips
- [x] Example configurations
- [x] Document configuration options in settings guide
- [x] Add prompt engineering tips for NPC personalities
- [x] Update CLAUDE.md if needed
- Depends on: 5.3 Manual Testing
File Location Summary¶
| Component | Package | Path |
|---|---|---|
| DialogueComponent | maid-stdlib | src/maid_stdlib/components/dialogue.py |
| ConversationManager | maid-engine | src/maid_engine/ai/conversation.py |
| PromptBuilder | maid-engine | src/maid_engine/ai/prompts.py |
| RateLimiter | maid-engine | src/maid_engine/ai/rate_limiter.py |
| AIDialogueSettings | maid-engine | src/maid_engine/config/settings.py |
| NPCDialogueSystem | maid-classic-rpg | src/maid_classic_rpg/systems/npc/dialogue.py |
| Talk/Ask Commands | maid-classic-rpg | src/maid_classic_rpg/commands/handlers/dialogue.py |
Acceptance Criteria¶
Must Have (MVP)¶
- [x]
talk bartender helloproduces AI-generated response - [x] Response displays as:
{NPC Name} says, "{response}" - [x] Response streams incrementally to player
- [x] Conversation history maintained within session
- [x] Works with all three providers (Anthropic, OpenAI, Ollama)
- [x] Rate limiting prevents abuse
- [x] Fallback response when AI unavailable
- [x] NPCs stay in character (no meta-discussion)
Should Have¶
- [x]
ask npc about topiccommand - [x]
conversationscommand to list active chats - [x]
endconversationcommand to end a chat - [x] Per-NPC provider/model override
- [x] Configurable conversation timeout
Nice to Have (Post-MVP)¶
- [ ] Emotion/mood system affecting responses
- [ ] Memory persistence across sessions
- [ ] Action triggers from dialogue (quest starts, item gives)
- [ ] NPC-to-NPC background conversations