cascade_engine

NCM Cascade Engine — Multi-turn neurochemical event sequences.

╔═══════════════════════════════════════════════════════════════════════════════╗ ║ 🌀 CASCADE ENGINE ║ ╠═══════════════════════════════════════════════════════════════════════════════╣ ║ Loads cascade definitions from ncm_cascades.yaml ║ ║ Checks triggers against current NCM vector + active emotions ║ ║ Advances active cascades one stage-tick per turn ║ ║ Handles interrupts (abort / pause / skip_to_stage / trigger_cascade) ║ ║ Applies synergy bonuses when cascades co-activate ║ ║ Persists state in Redis: ncm:cascades:{channel_id} ║ ╠═══════════════════════════════════════════════════════════════════════════════╣ ║ Called during exhale() after metabolic decay, stimulus delta ║ ║ stacking, and antagonist suppression. ║ ╚═══════════════════════════════════════════════════════════════════════════════╝

class cascade_engine.CascadeState[source]

Bases: object

Per-channel cascade bookkeeping, serializable to and from Redis.

Holds everything the engine needs to advance a channel’s cascades across turns: the currently active cascades and their stage progress, per-cascade cooldowns, a rolling history of trigger/abort/complete events, rolling windows of recent node values, delta counts and emotion sets used for sustained-condition checks, and the habituation fire_counts / last_fired_turn used for tolerance and recovery. Instances are loaded and persisted by CascadeEngine._load_state() and CascadeEngine._save_state() under the ncm:cascades:{channel_id} Redis key, round-tripping through to_dict() and from_dict().

__init__()[source]

Initialize an empty cascade state with no active cascades.

Sets up all tracking containers to their empty defaults so a fresh channel starts with nothing active, no cooldowns, and zeroed rolling windows. Touches no external state; called by from_dict() and by CascadeEngine._load_state() when Redis holds no prior state.

to_dict()[source]

Convert to dict representation.

Returns:

Result dictionary.

Return type:

dict

classmethod from_dict(d)[source]

Construct from dict data.

Parameters:

d (dict) – The d value.

Returns:

The result.

Return type:

CascadeState

class cascade_engine.CascadeEngine(redis_client=None, variant_cache=None)[source]

Bases: object

Drives multi-turn neurochemical cascades for the limbic system.

Owns the per-channel cascade lifecycle: each turn it loads CascadeState from Redis, checks interrupts on active cascades, advances their stages and accumulates stage deltas, applies synergy bonuses and the meta-systems (habituation/tolerance, sensitization, GABA polarity inversion), evaluates triggers for new cascades, and persists state back to Redis under ncm:cascades:{channel_id}. Cascade definitions and meta configs are loaded once via _load_cascade_defs() and _load_meta_configs(); stage cue text is humanized through an optional CueVariantCache, and the returned delta vector feeds back into the NCM state. Instantiated once by limbic_system.coordinator.LimbicCoordinator (its cascade_engine attribute), which calls tick() and get_active_cascades() from exhale() each turn.

Parameters:

variant_cache (CueVariantCache | None)

__init__(redis_client=None, variant_cache=None)[source]

Initialize the instance.

Parameters:
  • redis_client – Redis connection client.

  • variant_cache (CueVariantCache | None) – The variant cache value.

async tick(channel_id, vector, active_emotions, delta_count=0)[source]

Execute one turn of cascade processing.

Called during exhale(). Returns combined delta vector from all active cascade stages this turn.

Parameters:
  • channel_id (str) – The channel being processed.

  • vector (Dict[str, float]) – Current NCM state vector (post-emotion-deltas).

  • active_emotions (Set[str]) – Emotions that fired this turn.

  • delta_count (int) – Number of emotion deltas applied this turn.

Returns:

Combined delta vector from cascade processing this turn.

Return type:

Dict[str, float]

async get_active_cascades(channel_id)[source]

Summarize a channel’s in-flight cascades for prompt-context injection.

Loads the channel’s CascadeState (read-only; it does not advance anything) and, for each active cascade, resolves the current stage name and a humanized cue line through _pick() (the variant cache), plus how many turns it has run and whether it is paused. The coordinator’s exhale() calls this right after tick() and forwards the non-paused cues into the limbic context so active cascades can color the bot’s reply.

Parameters:

channel_id (str) – Channel whose active cascades are summarized.

Return type:

Dict[str, Dict[str, Any]]

Returns:

Mapping of cascade id to a dict with stage, turn, cue, and paused (empty when nothing is active).

async force_trigger(channel_id, cascade_id, strain_gradient=None)[source]

Manually trigger a cascade (e.g. from a tool call).

Parameters:
  • channel_id (str) – Target channel.

  • cascade_id (str) – Cascade to trigger.

  • strain_gradient (float | None) – Optional sativa/indica gradient (0.0-1.0) for ENDOCANNABINOID_DRIFT bipolar interpolation.

Return type:

bool