1 Architecture Context System
blightbow edited this page 2025-12-07 00:46:48 +00:00

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