World Model
The World Model is a structured, continuously-updated representation of real-world state. It aggregates data from conversations, background monitoring, and scheduled jobs to maintain an accurate picture of entities that matter to the user.
Architecture
Sources:
├── conversation text → temporal_extract()
├── dream_prefetch → price APIs
├── perception_job → real-time price monitoring
└── world_model_job → periodic state synthesis
↓ (all write to world_timeline table)
world_timeline
┌──────────────────────────────────────┐
│ entity | value | timestamp | source │
│ BTC | 67663 | 2026-03-09 | conv │
│ ETH | 1950 | 2026-03-09 | dream │
└──────────────────────────────────────┘
↓ (WorldModelUpdateJob aggregates)
entity_states
┌─────────────────────────────────────────────────┐
│ entity | current_value | trend | change_pct │
│ BTC | $67,663 | stable | -0.99% │
│ ETH | $1,950 | stable | -1.68% │
└─────────────────────────────────────────────────┘
world_timeline Table
Stores every observed value for every entity:
| Column | Type | Description |
|---|---|---|
entity | string | Entity name (BTC, ETH, user_state) |
value | string | Observed value |
observation_type | string | price, mention, state |
source | string | conversation, dream_prefetch, perception_job |
timestamp | timestamp | When observed |
entity_states Table
Aggregated current state per entity:
| Column | Type | Description |
|---|---|---|
entity | string | Entity name |
current_value | string | Most recent value |
trend | string | rising, falling, stable, unknown |
change_pct | float | Percentage change from previous |
updated_at | timestamp | Last update time |
WorldModelUpdateJob (every 15 min)
The WorldModelUpdateJob (src/scheduler/world_model_job.py):
- Reads recent
world_timelineentries - Groups by entity
- Calculates trend (rising/falling/stable) based on direction of change
- Calculates
change_pctvs the previous observation - Upserts into
entity_states
Data Sources
Conversation Extraction
The temporal_extract() function (src/memory/temporal.py) runs after every message:
# Matches: "BTC is at $67,000" → entity=BTC, value=$67,000
_PRICE_PATTERNS = [
r"(\b[A-Z]{2,5}\b)\s+(?:is\s+)?(?:at\s+)?\$?([\d,]+(?:\.\d+)?)",
...
]
Contamination guards prevent extraction from garbage text (error messages, JSON artifacts, partial sentences).
Dream Prefetch
Dream Mode pre-fetches current prices for crypto assets found in the Knowledge Graph:
- Calls price APIs (CoinGecko, Coinbase)
- Stores results as
source=dream_prefetchinworld_timeline
Background Perception
BackgroundPerceptionJob monitors tracked assets every 15 minutes:
- Checks Coinbase/CoinGecko APIs
- Stores as
source=perception_job - Triggers alerts on >4% movement
Context Injection
The World Model is not directly injected into the system prompt (the Temporal Insights block covers this). However, it feeds the temporal reasoning system which generates the [TEMPORAL INSIGHTS] block.
Query the world model:
# Current entity states
docker exec agent-postgres psql -U agent -d agent \
-c "SELECT entity, current_value, trend, change_pct FROM entity_states;"
# Historical timeline for BTC
docker exec agent-postgres psql -U agent -d agent \
-c "SELECT value, source, timestamp FROM world_timeline WHERE entity='BTC' ORDER BY timestamp DESC LIMIT 20;"
Trend Detection
Trend is calculated as:
- rising: latest value > average of previous 3 values by more than 1%
- falling: latest value < average of previous 3 values by more than 1%
- stable: change within ±1%
- unknown: insufficient data
Known Limitation
The user_state entity occasionally captures raw conversation fragments instead of structured state. This is a cosmetic issue — the contamination guards prevent most false positives, but complex text can slip through. The value is informational only and does not affect agent behavior.