Messages
Throughout the code you’ll be working with the Message interface. We create Message objects when a user or LLM sends a message.
Basic Structure
Section titled “Basic Structure”Every message has at least these core properties:
created: Timestamp when the message was createdrole: Either “user” or “assistant”content: The text content of the messagelevel: (optional) A number indicating which level this message was created ininput: The original prompt that triggered this response (only for assistant messages)
For complete type definitions, check the ./web/src/lib/messages.js file.
Message Flow Diagram
Section titled “Message Flow Diagram”┌─────────────┐ ┌───────────────┐ ┌─────────────────┐│ User Input │────▶│ ask() Function│────▶│ AI API (Claude) │└─────────────┘ └───────────────┘ └─────────────────┘ │ │ │ │ ▼ ▼┌─────────────┐ ┌───────────────┐ ┌─────────────────┐│ UI Display │◀────│ Memory System │◀────│ Message Object │└─────────────┘ └───────────────┘ └─────────────────┘ │ │ (optional delay) ▼ ┌─────────────────┐ │ Pending Queue │ │ (deliverAt) │ └─────────────────┘Message Content and JSON Structure
Section titled “Message Content and JSON Structure”When possible, AI responses are parsed into structured data in the contentJson property, which can include whatever the prompt requested. The structure is flexible and determined by the system prompt instructions given to the AI. Common examples include:
reply: The main response textinnerMonologue: The AI’s thought process (visible whenshowThoughtsis enabled)mood: Emotional state indicator (e.g., “happy”, “confused”, “surprised”)
For example, a response might contain:
contentJson: { reply: "I found the hidden key!", innerMonologue: "The user asked where the key is. Based on the game context, it's under the red carpet.", mood: "excited"}Creating and Processing Messages
Section titled “Creating and Processing Messages”The primary flow for AI text generation:
<MessageForm>component →/?/askform action →ask()function- Alternative: Direct API calls to
/api/chat(used in some levels)
Both routes through the core ask() function in /lib/server/ask.js.
Message Scheduling
Section titled “Message Scheduling”For delayed message delivery (humanization), use memory.scheduleMessage():
// Immediate delivery (delay = 0)memory.scheduleMessage(message, 0)
// Delayed delivery (5 seconds)memory.scheduleMessage(message, 5000)
// System messages with delaymemory.scheduleMessage(systemMessage, 3000, 'systemMessages')The pending queue automatically processes messages when their deliverAt time is reached, ensuring delivery survives page navigation and refresh.
The ask() Function
Section titled “The ask() Function”The core function powering message generation accepts these parameters:
ask(userPrompt, systemPrompt, messageContext, settings, level, traceType)userPrompt: The user’s input textsystemPrompt: An optional system prompt to guide the AImessageContext: An optional list of previousMessageobjects (conversation history)settings: Configuration options for the AI including model selectionlevel: The level number (optional)traceType: Type of trace to be added to the message (optional)
Understanding Context
Section titled “Understanding Context”By default, AI messages are NOT given any context or knowledge. You must provide:
systemPrompt: Character instructions (e.g., frompromptSystemChat()orpromptHumanChat())messageContext: Previous conversation history
Technical Implementation
Section titled “Technical Implementation”Behind the scenes, the ask() function performs these operations:
-
Message Formatting: Messages are transformed to be compatible with the Anthropic API format, which requires:
- Messages must alternate between ‘user’ and ‘assistant’ roles
- The first message must be from a ‘user’
- Empty messages are filtered out
-
API Interaction: The function makes a request to Claude with the formatted messages.
-
Response Processing:
- It extracts the text content from the API response
- It attempts to parse JSON from the response into
contentJson - It calculates usage statistics and costs
-
Storage: The resulting message is returned and stored in:
memory.messages: Human NPC conversations (context: ‘human’)memory.systemMessages: System NPC conversations (context: ‘system’)memory.pendingMessages: Messages scheduled for delayed delivery (automatically processed into the above arrays when theirdeliverAttime is reached)
Additional Resources
Section titled “Additional Resources”For complete type definitions, check the ./web/src/lib/messages.js file.