Table of Contents
- Architecture: Context System
- Overview
- 1. Context Types
- 2. Prompt Components
- 1000-Point ID Scheme
- Pluggable Component Allocation
- PromptComponent Structure
- Component Assembly Order
- 3. Three-Layer Execution Pattern
- Restrictive Composition Principle
- Layer 1: Static Configuration
- Layer 2: Context Configuration
- Layer 3: LLM Assessment
- Context Signal Adjustments
- ExecutionPattern Result
- Composition Example
- 4. Context Component Sets
- 5. Component Overrides
- Key Files
Architecture: Context System
Layer 2 - Context Types, Prompt Components, and Execution Pattern Composition
Overview
The context system determines what information the LLM receives and how it can act. It consists of three components:
- prompt_contexts.py (713 lines) - 7 context types with execution settings
- prompt_components.py (303 lines) - Component ID scheme and ordering
1. Context Types
The LLM is called in 7 distinct contexts, each with specific components and execution behavior.
Context Type Summary
| Context | Purpose | Components | Tools | Max Iterations |
|---|---|---|---|---|
tick_event |
Process pending event | Full (9) | All | 5 |
tick_autonomous |
Goal-driven behavior | Full (9) | All | 5 |
reflection |
Self-analysis | 3 | journal only | 3 |
reflection_cont |
After reflection tool | 2 | journal only | 2 |
sleep_consolidate |
Memory consolidation | 2 | memory + journal | 10 |
goal_decompose |
Break down goals | 3 | None | 1 |
pre_compaction |
Fact extraction | 4 | journal only | 5 |
ContextConfig Structure
@dataclass
class ContextConfig:
# Identity
context_type: str # e.g., "tick_event"
name: str # Human-readable name
description: str # What this context is for
# Component configuration
enabled_components: list[int] # Component IDs to include
component_overrides: dict # Per-component customizations
tool_filter: list[str] | None # Allowed tools (None = all)
token_budget: int | None # Max tokens (None = default)
# Execution settings (Layer 2 of 3-layer system)
execution_mode: str # single_action | react_loop | plan_execute
max_iterations: int # Max tool calls
allowed_tool_categories: list[str] | None # ToolCategory filter
terminal_ends_loop: bool # TERMINAL tools end loop
dangerous_requires_confirm: bool # Confirm before DANGEROUS
allows_multi_tool: bool # Allow ReAct loop
allows_sub_agents: bool # Allow delegation
Context-Specific Tool Filters
# Reflection-only tools
REFLECTION_TOOLS = ["noop", "add_journal_entry", "review_journal"]
# Sleep mode tools
SLEEP_TOOLS = ["noop", "add_journal_entry", "review_journal",
"recall_memories", "store_memory"]
# Pre-compaction extraction tools
PRE_COMPACTION_TOOLS = ["noop", "add_journal_entry", "update_entity_observation"]
2. Prompt Components
Components are building blocks of the LLM context window, ordered by ID.
1000-Point ID Scheme
Static components use IDs at 1000-point increments, leaving 999 slots for pluggable components:
ID Component Description
───── ───────────────────── ─────────────────────────────────────
0 system_prompt Core LLM instructions
1000 character_context User/assistant persona, session memory
1500 entity_context O-Mem entity profiles and working memory
2000 semantic_memories Retrieved facts from Mem0
3000 context_buffer Ambient room messages
4000 goals Active goals with hierarchy
5000 conversation_history Recent chat (token-budgeted)
6000 pending_event Current event from queue
7000 tool_result Previous tool execution result
Pluggable Component Allocation
# Pluggable IDs fit between static IDs
after_static_id = 1000 # character_context
pluggable_id = 1001 # First slot after character_context
# Range: (1001, 1999) available for custom components
# 999 slots per static component pair
PromptComponent Structure
@dataclass
class PromptComponent:
id: int # Ordered position (0, 1000, 2000...)
key: str # Unique identifier ("system_prompt")
name: str # Display name
description: str # What this provides
content: str # Template (may have {placeholders})
is_static: bool # True for built-in
enabled: bool # Include in assembly
role: str # "system" | "user" | "assistant" | "tool" | "mixed"
Component Assembly Order
Components are assembled in ID order:
0 System Prompt → Sets behavior and capabilities
1000 Character Context → Persona and session state
1500 Entity Context → Active relationships (O-Mem)
2000 Semantic Memories → Long-term facts (Mem0)
3000 Context Buffer → Environmental awareness
4000 Goals → Task hierarchy
5000 Conversation History → Recent exchanges
6000 Pending Event → What triggered this tick
7000 Tool Result → Previous action outcome
3. Three-Layer Execution Pattern
Execution behavior is composed from three layers with restrictive semantics.
Restrictive Composition Principle
Layer 1 (Static Config) ⊇ Layer 2 (Context Config) ⊇ Layer 3 (LLM Assessment)
Each layer can only restrict, never expand, what the previous layer allows.
Layer 1: Static Configuration
Hard limits from AssistantScript.db.execution_config:
db.execution_config = {
"multi_action_enabled": True, # Master switch for ReAct
"max_iterations_per_tick": 5, # Absolute maximum (1-10)
"task_assessment_enabled": False, # Enable LLM complexity analysis
"sub_agents_enabled": False, # Enable delegation
"sub_agent_budget": 3, # Max concurrent sub-agents
}
Layer 2: Context Configuration
Context-specific restrictions from ContextConfig:
| Setting | tick_event | reflection | sleep_consolidate | goal_decompose |
|---|---|---|---|---|
| execution_mode | react_loop | react_loop | react_loop | single_action |
| max_iterations | 5 | 3 | 10 | 1 |
| allows_multi_tool | True | True | True | False |
| allows_sub_agents | True | False | False | False |
Layer 3: LLM Assessment
Advisory runtime adjustments (can only restrict):
llm_assessment = {
"recommended_iterations": 3, # Suggest fewer iterations
"recommended_mode": "single_action", # Downgrade from react_loop
"recommend_confirm_dangerous": True, # Request confirmation
"context_signals": {
"token_pressure": "high", # Reduce iterations at 60%+
"recent_errors": 2, # Consecutive failures
"event_class": "communication", # Force single_action
"goal_urgency": "low",
}
}
Context Signal Adjustments
The select_execution_pattern() function applies runtime restrictions:
| Signal | Condition | Effect |
|---|---|---|
| token_pressure = "critical" | 80%+ usage | Force single_action |
| token_pressure = "high" | 60%+ usage | Max 2 iterations |
| recent_errors >= 3 | Consecutive failures | Force single_action + confirm dangerous |
| recent_errors >= 2 | Multiple failures | Max 2 iterations |
| event_class = "communication" | User message | Force single_action |
| event_class = "building" | World modification | Confirm dangerous |
ExecutionPattern Result
The composed result with debugging info:
@dataclass
class ExecutionPattern:
mode: str # Effective mode
max_iterations: int # Effective limit
allowed_categories: list[str] | None # Category filter
terminal_ends_loop: bool # TERMINAL behavior
dangerous_requires_confirm: bool # DANGEROUS behavior
multi_tool_enabled: bool # ReAct allowed
sub_agents_enabled: bool # Delegation allowed
source_layers: dict # Debug: which layer set each value
Composition Example
static_config = {"multi_action_enabled": True, "max_iterations_per_tick": 5}
context_config = get_context_config("reflection") # max_iterations=3
pattern = select_execution_pattern(static_config, context_config)
# Result:
# pattern.mode = "react_loop"
# pattern.max_iterations = 3 # Context restricted from 5
# pattern.source_layers = {
# "mode": "context",
# "max_iterations": "context",
# "multi_tool_enabled": "allowed"
# }
4. Context Component Sets
Each context type enables specific components.
Full Component Set (tick_event, tick_autonomous)
_FULL_COMPONENTS = [
COMPONENT_SYSTEM_PROMPT, # 0
COMPONENT_CHARACTER_CONTEXT, # 1000
COMPONENT_ENTITY_CONTEXT, # 1500
COMPONENT_SEMANTIC_MEMORIES, # 2000
COMPONENT_CONTEXT_BUFFER, # 3000
COMPONENT_GOALS, # 4000
COMPONENT_CONVERSATION_HISTORY, # 5000
COMPONENT_PENDING_EVENT, # 6000
COMPONENT_TOOL_RESULT, # 7000
]
Minimal Sets
| Context | Components | Purpose |
|---|---|---|
| reflection | system_prompt, pending_event, tool_result | Focused self-analysis |
| reflection_cont | system_prompt, tool_result | Process reflection tool output |
| sleep_consolidate | system_prompt, semantic_memories | Memory consolidation |
| goal_decompose | system_prompt, goals, pending_event | Goal breakdown |
| pre_compaction | system_prompt, conversation_history, pending_event, tool_result | Full history for fact extraction |
5. Component Overrides
Contexts can customize component content:
CONTEXT_REFLECTION: ContextConfig(
component_overrides={
"system_prompt": {
"content": """You are an AI assistant performing periodic self-reflection.
Review your recent performance and journal entries. Consider:
1. What patterns am I observing in my work?
2. What strategies are working well?
3. What mistakes am I repeating?
4. What should I do differently?
Use the journal tools to record your insights.""",
},
},
)
Override Resolution
def get_component_content_override(self, component_key: str) -> Optional[str]:
"""Get content override for a component, if any."""
override = self.component_overrides.get(component_key, {})
if isinstance(override, dict):
return override.get("content")
return None
Key Files
| File | Lines | Purpose |
|---|---|---|
prompt_contexts.py |
59-143 | ContextConfig dataclass |
prompt_contexts.py |
221-398 | DEFAULT_CONTEXT_CONFIGS (7 types) |
prompt_contexts.py |
541-713 | select_execution_pattern() |
prompt_components.py |
32-86 | PromptComponent dataclass |
prompt_components.py |
91-173 | STATIC_COMPONENTS (9 components) |
See also: Architecture-Overview | Architecture-Core-Engine | Architecture-Memory-and-Sleep