flavor_memory

Flavor Memory — Per-channel gustatory history in Redis.

Tracks which flavors a user has referenced, how often, and when. Provides familiarity bonuses: more mentions → stronger OXT/MOR on re-encounter.

async flavor_memory.record_flavor(redis_client, channel_id, flavor_name)[source]

Log a flavor reference for a channel.

Each entry: {"flavor": name, "count": N, "first_ts": ts, "last_ts": ts}. Maintains a running history of the last _MAX_HISTORY unique flavors.

Return type:

None

Parameters:
  • redis_client (Any)

  • channel_id (str)

  • flavor_name (str)

async flavor_memory.get_flavor_affinity(redis_client, channel_id, flavor_name)[source]

Get familiarity bonus for a specific flavor in this channel.

Returns a multiplier: 1.0 for unknown, up to ~1.5 for very familiar. The bonus follows a log curve: rapid early gain, diminishing returns.

Used as a multiplier on OXT and MOR deltas during Phase 4 NCM computation.

Return type:

float

Parameters:
  • redis_client (Any)

  • channel_id (str)

  • flavor_name (str)

async flavor_memory.get_history(redis_client, channel_id)[source]

Return the full per-channel flavor history list.

Reads the JSON-encoded history array from the single Redis string keyed by ncm:flavor_history:<channel_id> (built via _make_key()) and decodes it. Each element is a record like {"flavor": NAME, "count": N, "first_ts": ts, "last_ts": ts} as written by record_flavor(). This is a read-only accessor: it never mutates or sorts the stored data, and any decode/connection error is swallowed and reported as an empty history so callers degrade gracefully.

Called by get_top_flavors() within this module; no external callers were found via grep, so it otherwise serves as a public read helper for the flavor subsystem.

Parameters:
  • redis_client (Any) – An async Redis client, or None to short-circuit to an empty list (e.g. when Redis is unavailable).

  • channel_id (str) – Discord/Matrix channel identifier whose history to load.

Returns:

The decoded history records, newest-first as last persisted, or an empty list when absent or on any error.

Return type:

List[Dict[str, Any]]

async flavor_memory.get_top_flavors(redis_client, channel_id, n=5)[source]

Return the channel’s most-referenced flavor names, highest count first.

Loads the channel’s history via get_history(), sorts a local copy by the per-flavor count field in descending order, and returns just the canonical flavor names (upper-cased, underscore-joined) of the top n entries. Useful for surfacing a channel’s recurring gustatory preferences, e.g. to seed prompt context or summaries. Pure read path: the underlying Redis data is not modified.

No external callers were found via grep, so this acts as a public convenience accessor over get_history().

Parameters:
  • redis_client (Any) – An async Redis client, or None (yields an empty list via get_history()).

  • channel_id (str) – Discord/Matrix channel identifier whose top flavors to fetch.

  • n (int) – Maximum number of flavor names to return (default 5).

Returns:

Up to n flavor names ordered by descending reference count.

Return type:

List[str]