Skip to main content

Understanding Cortex Predictions

The Cortex API provides predictive capabilities for state transitions in AveniECA. Given a current state (or sequence of states), Cortex predicts the most likely next states based on historical patterns.

NextStateRequest Parameters

The NextStateRequest model controls how predictions are generated:
from avenieca.api.model import NextStateRequest

nsr = NextStateRequest(
    module_id="aggregate001",
    recall=20,
    range=20,
    n=1,
    status="e",
    current_state=None,
    previous_state=None,
    store_response=False,
    store_sequence=False
)

Parameter Details

module_id
str
required
The module ID to generate predictions for. Must match existing ESS/aggregates.
recall
int
default:2
Number of historical sequences to recall when making predictions. Higher values consider more historical context but may be slower.
range
int
default:2
Range parameter for sequence matching. Controls how broadly to search for similar historical patterns.
n
int
default:1
Number of next states to predict. Returns the top N most likely next states.
status
str
Filter sequences by status code (e.g., “e” for ended, “n” for new, “sk” for skipped). Only considers sequences with this status.
current_state
int
ESS ID representing the current state. If not provided, Cortex uses the most recent state.
previous_state
List[int]
List of ESS IDs representing the sequence history leading to current state. Provides additional context for predictions.
store_response
bool
default:false
Whether to store the prediction response in the database for later retrieval.
store_sequence
bool
default:false
Whether to create a new sequence record from this prediction.

Making Predictions

There are two prediction endpoints: predictions() for human-readable output and predictions_raw() for raw numerical data.

Basic Prediction Example

import os
from avenieca.api.model import Config, NextStateRequest
from avenieca.api.eca import ECA

config = Config(
    uri="http://localhost:2580/v1",
    username=os.getenv("USERNAME"),
    password=os.getenv("PASSWORD")
)
eca = ECA(config)

# Request prediction
nsr = NextStateRequest(
    module_id="aggregate001",
    recall=20,
    range=20,
    n=1,
    status="e"
)

res, status = eca.cortex.predictions(data=nsr)

if status == 200:
    print("Current state:")
    for twin in res.current_state:
        print(f"  {twin.module_id}: {twin.state}")
    
    print("\nPredicted next states:")
    for i, twins in enumerate(res.next_state, 1):
        print(f"\nPrediction {i}:")
        for twin in twins.list:
            print(f"  {twin.module_id}: {twin.state}")

Interpreting predictions vs predictions_raw

predictions() - Human-Readable Format

The predictions() method returns a NextStateResponse with states mapped to their original embedding inputs (if defined):
res, status = eca.cortex.predictions(data=nsr)

# NextStateResponse structure:
# - current_state: List[Twin]
# - next_state: List[Twins]

# Each Twin contains:
# - aggregate_id: int
# - ess_id: int
# - module_id: str
# - state: str (mapped from embedding input)

for twin in res.current_state:
    print(f"Module: {twin.module_id}")
    print(f"ESS ID: {twin.ess_id}")
    print(f"State: {twin.state}")  # Human-readable if embedding exists

predictions_raw() - Raw Numerical Format

The predictions_raw() method returns a NextStateResponseRaw with raw numerical state vectors:
res, status = eca.cortex.predictions_raw(data=nsr)

# NextStateResponseRaw structure:
# - current_state: List[TwinRaw]
# - next_state: List[TwinsRaw]

# Each TwinRaw contains:
# - aggregate_id: int
# - ess_id: int
# - module_id: str
# - state: List[float] (raw numerical vector)

for twin_raw in res.current_state:
    print(f"Module: {twin_raw.module_id}")
    print(f"ESS ID: {twin_raw.ess_id}")
    print(f"State vector: {twin_raw.state}")  # Always numerical
When to use each:
  • predictions(): Use when you have embedding inputs and want human-readable state descriptions (e.g., “high temperature” instead of [28.5])
  • predictions_raw(): Use when you need the actual numerical state vectors for further computation or analysis

Advanced Prediction Patterns

Multi-Step Predictions

Predict multiple future states by requesting n > 1:
nsr = NextStateRequest(
    module_id="aggregate001",
    recall=30,
    range=30,
    n=5,  # Get top 5 most likely next states
    status="e"
)

res, status = eca.cortex.predictions(data=nsr)

for i, twins in enumerate(res.next_state, 1):
    print(f"\nPrediction {i} (ranked by likelihood):")
    for twin in twins.list:
        print(f"  {twin.module_id}: {twin.state}")

Context-Aware Predictions

Provide sequence history for more accurate predictions:
# Get recent sequence
seq_res, seq_status = eca.sequence.get_one(
    module_id="aggregate001",
    db_id=4
)

# Get ESS from sequence to build history
history_res, hist_status = eca.ess.get_one_sequence(
    module_id="aggregate001",
    sequence_id=4
)

# Use sequence context in prediction
nsr = NextStateRequest(
    module_id="aggregate001",
    recall=20,
    range=20,
    n=3,
    current_state=history_res.id,  # Explicit current state
    previous_state=[12, 15, 18],    # Historical ESS IDs
    status="e"
)

res, status = eca.cortex.predictions(data=nsr)

Storing Predictions for Analysis

Store predictions and sequences for later retrieval:
nsr = NextStateRequest(
    module_id="aggregate001",
    recall=20,
    range=20,
    n=1,
    status="e",
    store_response=True,   # Save prediction to responses table
    store_sequence=True    # Create sequence record
)

res, status = eca.cortex.predictions(data=nsr)

# Later, retrieve stored responses
responses, resp_status = eca.response.get_all()
for response in responses:
    print(f"Prediction stored at {response.created_at}")

Aggregate Predictions

When predicting aggregates, each component module is predicted:
nsr = NextStateRequest(
    module_id="aggregate001",  # Aggregate of multiple modules
    recall=25,
    range=25,
    n=2,
    status="e"
)

res, status = eca.cortex.predictions(data=nsr)

# Current aggregate state
print("Current state components:")
for twin in res.current_state:
    print(f"  {twin.module_id} (ESS {twin.ess_id}): {twin.state}")

# Predicted aggregate states
for i, twins in enumerate(res.next_state, 1):
    print(f"\nPrediction {i}:")
    for twin in twins.list:
        # Each twin represents one component of the aggregate
        print(f"  {twin.module_id}: {twin.state}")
        print(f"    Aggregate ID: {twin.aggregate_id}")
        print(f"    ESS ID: {twin.ess_id}")

Error Handling

Handle prediction errors gracefully:
from avenieca.api.model import Error

res, status = eca.cortex.predictions(data=nsr)

if isinstance(res, Error):
    print("Prediction failed:")
    for error in res.errors:
        print(f"  - {error}")
elif status != 200:
    print(f"Request failed with status {status}")
else:
    # Process successful predictions
    print(f"Got {len(res.next_state)} predictions")

Performance Considerations

Tuning recall and range: Higher values provide more context but increase computation time. Start with lower values (10-20) and increase if predictions aren’t accurate enough.
Sequence status filtering: Using status filters can significantly speed up predictions by limiting the search space to relevant sequences only.

Next Steps

Aggregates

Learn how to create multi-module aggregates for richer predictions

Best Practices

Production patterns for prediction systems

Build docs developers (and LLMs) love