Prompt System
Last Updated: 2025-01-16
Primary Source: docs/project_status.md, docs/PROMPT_SYSTEM_ARCHITECTURE.md
Service File: backend/src/services/prompt.service.ts, backend/src/services/promptComposition.service.ts
Overview
The Prompt System manages AI instructions and behavior through dynamic prompt templates stored in the database. It supports protocol-based prompts, template composition, and flexible prompt engineering.
Architecture
Prompt System Flow
Prompt Sources
1. Database Prompt Templates (Primary)
Table: prompt_templates
Loader: backend/src/services/prompt.service.ts → getPromptTemplate(name)
Process:
- Fetches
PromptTemplatewhere{ name, is_active: true } - In-memory cached per process
- Falls back to JSON if name exists there
Key Templates:
npc_tool_call_v2- Main tool-call promptnpc_spoken_response_v1- Post-tool spoken responsebase_tool_call_v1- Base template for compositiondirector_classification_v1- Director classificationnpc_personality_layer_v1- Personality layer
2. Local JSON Fallback (Minimal)
File: backend/src/config/prompts.json
Purpose: Boot fallback for critical templates
Contains:
director_classification_v1npc_personality_layer_v1
Note: Not enough for full tool calling - database templates required.
3. Protocol Definitions
Table: protocols.definition
Format: Can be string (full prompt) or object (reference-based)
String-based (Current):
- Full prompt template embedded in protocol definition
- Tool allow-list and JSON output rules duplicated per protocol
- Used as-is (no composition)
Reference-based (Target):
{
"base": "base_tool_call_v1",
"overrides": {
"rules": "...",
"toolDefinitions": "..."
}
}4. Inline Prompts (Hardcoded)
Location: Service files
Examples:
asoAnalyzeLayer.service.ts- Incoming analysis promptasoAnalyzeLayer.service.ts- Outgoing filter prompt
Purpose: Specialized prompts that don't need template management
Prompt Composition
Composition Service
File: backend/src/services/promptComposition.service.ts
Function: composePromptTemplate(protocol, options)
Process:
- Load base template from
prompt_templates - Inject
placeholder - Append protocol-specific rules
- Apply placeholder overrides
- Fill variables (persona, emotions, memory, etc.)
Template Variables
Common Variables:
- NPC/ASO information- Active persona- Current emotional state- Relevant memories- Inventory summary- Active quests- Available tools- User message- File attachments context
Tool Calling Modes
1. Legacy JSON-Block Tool Calling (Current Default)
Format: Model outputs fenced JSON block:
{
"tool": "<tool name or null>",
"arguments": { },
"spokenResponse": "<string>"
}Parsing:
- Service:
backend/src/services/llmToolGateway.service.ts - Function:
parseLlmToolOutput()
Execution:
- Service:
backend/src/services/toolExecutor.service.ts - Function:
executeTool()
Final Response:
- Uses
npc_spoken_response_v1template - Generates spoken response after tool execution
2. Provider-Native Tool Calling (Optional)
Feature Flag: USE_PROVIDER_NATIVE_TOOLS=true|false
Process:
- Send OpenAI-compatible
toolsarray to One-API - Model returns
tool_callsin response - Execute tools
- Send tool outputs back to model
- Model generates final response
Service: backend/src/services/nativeToolCalling.service.ts
Benefits:
- Eliminates JSON-block formatting constraints
- Better output quality
- Standard tool calling format
Prompt Selection Flow
In handleNpcConversationTurn
Process:
Prefer protocol base template (routing protocol)
- Route protocol via
protocolRouter.service.ts - If merged with workflow protocol, use base routing protocol
- Attempt
composePromptTemplate(baseProtocol)
- Route protocol via
Fallback to legacy DB template
getPromptTemplate('npc_tool_call_v2')
Important: If protocol's promptTemplate is a string, it's used as-is and may contain legacy tool names.
Analyze Layer Prompts
Incoming Analysis
Service: backend/src/services/asoAnalyzeLayer.service.ts
Function: analyzeIncomingInteraction(userInput)
Purpose: Analyze user intent, topic, and capability needed
Output: JSON analysis
{
"intent": "...",
"topic": "...",
"capabilityNeeded": "...",
"confidence": 0.0,
"reason": "..."
}Outgoing Filter
Function: filterOutgoingResponse(rawResponse, context)
Purpose: Refine response style/personality for Discord
Note: Can materially change tone, so must align with protocol.
Protocol-Based Prompts
Protocol Prompt Integration
Process:
- Protocol routing determines protocol
- Protocol definition contains
promptTemplate - If string: use as-is
- If object: compose with base template
- Inject protocol-specific rules
- Fill variables
Protocol-Specific Rules
Each protocol adds its own rules:
- PRIVATE_PROTOCOL: Intimate, emotional tone
- TECH_PROTOCOL: Technical, no emotional language
- NEUTRAL_PROTOCOL: Brief, neutral tone
- SYSTEM_PROTOCOL: System-aware, meta-observer
- PUBLIC_PROTOCOL: Professional, friendly, appropriate boundaries
Data Flow
API Endpoints
Prompt Management
GET /api/admin/prompts- List all promptsGET /api/admin/prompts/:name- Get prompt templatePOST /api/admin/prompts- Create prompt templatePUT /api/admin/prompts/:name- Update prompt templatePOST /api/admin/prompts/preview- Preview filled prompt
Source Files
Primary Sources:
backend/src/services/prompt.service.ts- Template loadingbackend/src/services/promptComposition.service.ts- Template compositionbackend/src/services/protocolRouter.service.ts- Protocol routingdocs/PROMPT_SYSTEM_ARCHITECTURE.md- Complete prompt system guide
Related Files:
backend/src/services/asoAnalyzeLayer.service.ts- Analyze layer promptsbackend/src/services/aso.service.ts- Prompt usage in ASO
Related Documentation
- Protocol Routing - Protocol assignment and routing
- Tool System - Tool execution and command parsing
- 06-ARCHITECTURE/Data-Flow.md - Prompt usage in data flows
- 00-OVERVIEW.md - Complete system overview