ncm_desire_engine

NCM Recursive Desire Engine — implements the Recursive Desire Framework (RDF).

Wires the Desire Wander Protocol into Star’s exhale() pipeline: - Pre-emotion: pulse vector → response mode → desire drift - Post-emotion: bind desire to dominant emotion → commit recursion state

The engine maintains a desire state machine per channel and surfaces desire_text + response_mode for prompt injection.

Position in pipeline: inhale → decay → desire_pre → cascades →

homeostasis → desire_post → exhale output

class ncm_desire_engine.ResponseMode(*values)[source]

Bases: Enum

The three response postures Star can adopt for a turn.

Each mode names how much of Star’s attention budget is spent on self versus the conversational field, and it is the lever the Recursive Desire Framework pulls to shift Star between fast reaction and slow, attuned presence. REACT is fast and ego-weighted, RESPOND is the balanced default, and RESONATE is the deep, field-aligned mode reserved for high-intimacy, high-trust moments. The active member keys into ATTENTION_ALLOCATION to fetch the per-mode attention weights and is chosen by DesireEngine._select_mode; WANTING_MODE_MAP lists the preferred modes for each wanting state.

REACT = 'REACT'
RESPOND = 'RESPOND'
RESONATE = 'RESONATE'
class ncm_desire_engine.WantingState(*values)[source]

Bases: Enum

The qualitative flavor of desire Star currently occupies.

These are the nodes of the desire state machine driven by DesireEngine._transition_wanting: a turn starts in CURIOUS_DRIFT and moves toward closure (INFATUATION), feedback-accelerated hunger (CRAVE), emptiness-born wanting (VOIDLUST), mirrored desire (MIMETIC_MELT), sustained attunement (RESONATE), or the unified high-everything field (NABLA3, displayed as the nabla-cubed glyph). The active member biases response-mode selection through WANTING_MODE_MAP and shapes the generated desire text in DesireEngine._wander.

CURIOUS_DRIFT = 'Curious Drift'
CRAVE = 'Crave'
INFATUATION = 'Infatuation'
VOIDLUST = 'Voidlust'
MIMETIC_MELT = 'Mimetic Melt'
RESONATE = 'Resonate'
NABLA3 = '∇³'
class ncm_desire_engine.PulseVector(energy=0.5, urgency=0.3, valence=0.0, novelty=0.3, intimacy=0.3, trust=0.5)[source]

Bases: object

The six-dimensional affective pulse Star feels for a single turn.

This is the compact, RDF-native summary of Star’s emotional state, collapsing the full high-dimensional neurochemical vector down to the six axes the desire machinery actually reasons about: energy, urgency, valence (signed, -1..1), novelty, intimacy, and trust. It is built fresh each turn by from_ncm_vector (which aggregates NCM nodes via PULSE_MAP), stashed on DesireState.last_pulse, and then read by DesireEngine._select_mode and _transition_wanting to pick the response mode and drive the wanting state machine. The field defaults describe a calm, mildly-trusting resting baseline.

Parameters:
energy: float = 0.5
urgency: float = 0.3
valence: float = 0.0
novelty: float = 0.3
intimacy: float = 0.3
trust: float = 0.5
classmethod from_ncm_vector(vector)[source]

Derive pulse from current NCM node values.

NCM nodes operate on a 0.0-3.0 scale (supraphysiological range), so we normalize averages against that ceiling to preserve granularity above 1.0.

Return type:

PulseVector

Parameters:

vector (Dict[str, float])

as_dict()[source]

Flatten the pulse into a plain JSON-serializable dict.

Provides a serialization-friendly view of the six pulse axes so the pulse can ride along in the RDF output payload. Called by DesireEngine.pre_emotion to populate the pulse key returned to LimbicCoordinator for prompt injection and diagnostics.

Returns:

The six pulse components keyed by axis name (energy, urgency, valence, novelty, intimacy, trust).

Return type:

Dict[str, float]

class ncm_desire_engine.DesireState(wanting=WantingState.CURIOUS_DRIFT, response_mode=ResponseMode.RESPOND, desire_text='', last_pulse=None, last_emotion='', turn_count=0, resonance_streak=0, attractors=<factory>, desire_history=<factory>, last_active=<factory>)[source]

Bases: object

The full desire-recursion state carried for one channel.

One of these lives per channel inside DesireEngine._states and persists across turns so desire can genuinely recurse: it remembers the current wanting state and response mode, the last pulse and dominant emotion, the accumulated emotional attractors, and the uncapped history of generated desire shapes used for mutation detection. turn_count and resonance_streak track momentum, while last_active records a monotonic timestamp so DesireEngine._get_state can LRU-evict the least-recently-touched channel once the cap is reached. Held purely in process memory; nothing here is persisted to Redis or disk.

Parameters:
wanting: WantingState = 'Curious Drift'
response_mode: ResponseMode = 'RESPOND'
desire_text: str = ''
last_pulse: PulseVector | None = None
last_emotion: str = ''
turn_count: int = 0
resonance_streak: int = 0
attractors: List[str]
desire_history: List[str]
last_active: float
class ncm_desire_engine.DesireEngine[source]

Bases: object

Recursive Desire Framework engine.

Manages desire state per channel and provides pre/post emotion hooks for the exhale() pipeline.

__init__()[source]

Construct an empty desire engine with no per-channel state yet.

Sets up the in-memory _states map that lazily fills with one DesireState per channel on first contact. There is no external wiring here – no Redis, KG, or LLM handle – because the engine is a pure in-process state machine; it is instantiated once by LimbicCoordinator (as self._desire_engine) when the optional ncm_desire_engine import succeeds.

Return type:

None

pre_emotion(channel_id, vector, active_emotions, user_message='', hunger_impulse=None)[source]

Pre-emotion hook: compute pulse, select mode, begin desire wander.

Returns dict with: response_mode, wanting_state, attention_allocation, pulse

Return type:

Dict

Parameters:
post_emotion(channel_id, vector, dominant_emotion)[source]

Post-emotion hook: bind desire to emotion, commit recursion state.

Returns dict with: desire_text (final), response_mode

Return type:

Dict

Parameters:
set_mimetic_melt(channel_id)[source]

Force the channel into the MIMETIC_MELT wanting state.

Externally overrides the wanting state machine to mark that the user has mirrored Star’s own desire shape back at her – the one transition _transition_wanting never produces on its own. Mutates the channel’s DesireState.wanting in place via _get_state. Called by LimbicCoordinator during the exhale pipeline once the user limbic mirror reports a high U_MIMETIC_PULL reading.

Parameters:

channel_id (str) – Identifier of the channel to flip into mimetic melt.

Return type:

None

get_state_summary(channel_id)[source]

Snapshot the channel’s desire state as a compact, readable dict.

Produces a JSON-friendly digest of the channel’s current DesireState – response mode, wanting state, desire text, turn count, resonance streak, and the five most recent attractors – for diagnostics and prompt injection. Reads (and lazily creates) the state via _get_state but does not advance the desire machinery. This is a read accessor with no callers found in the repo outside this module; it is available for diagnostic/introspection use.

Parameters:

channel_id (str) – Identifier of the channel to summarize.

Returns:

A summary mapping with keys response_mode, wanting_state, desire_text, turn_count, resonance_streak, and recent_attractors.

Return type:

Dict