Skip to main content

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:

ColumnTypeDescription
entitystringEntity name (BTC, ETH, user_state)
valuestringObserved value
observation_typestringprice, mention, state
sourcestringconversation, dream_prefetch, perception_job
timestamptimestampWhen observed

entity_states Table

Aggregated current state per entity:

ColumnTypeDescription
entitystringEntity name
current_valuestringMost recent value
trendstringrising, falling, stable, unknown
change_pctfloatPercentage change from previous
updated_attimestampLast update time

WorldModelUpdateJob (every 15 min)

The WorldModelUpdateJob (src/scheduler/world_model_job.py):

  1. Reads recent world_timeline entries
  2. Groups by entity
  3. Calculates trend (rising/falling/stable) based on direction of change
  4. Calculates change_pct vs the previous observation
  5. 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_prefetch in world_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.