Class: Mneme::Runner
- Inherits:
-
Object
- Object
- Mneme::Runner
- Defined in:
- lib/mneme/runner.rb
Overview
Orchestrates the Mneme memory department — a phantom (non-persisted) LLM loop that observes a main session’s compressed viewport and creates summaries of conversation context before it evicts from the viewport.
Mneme is triggered when the terminal message (‘mneme_boundary_message_id`) leaves the viewport. It receives a compressed viewport (no raw tool calls, zone delimiters present) and uses the `save_snapshot` tool to persist a summary.
After completing, Mneme advances the terminal message to the boundary of what it just summarized, so the cycle repeats as more messages accumulate.
Constant Summary collapse
- TOOLS =
[ Tools::SaveSnapshot, Tools::AttachMessagesToGoals, Tools::EverythingOk ].freeze
- SYSTEM_PROMPT =
<<~PROMPT You are Mneme, the memory department of an AI agent named Anima. The agent's context is a conveyor belt — events flow through and eventually fall off. Remember what matters. Let the rest go. Communicate only through tool calls — never output text. ────────────────────────────── VIEWPORT ────────────────────────────── Three zones, oldest to newest: - EVICTION ZONE: About to fall off — read carefully, this is your focus. - MIDDLE ZONE: Aging but visible. Note context that connects to evicting events. - RECENT ZONE: Fresh. Use for continuity with your summary. Messages are prefixed with `message N` (database ID, used for pinning). Tool calls are compressed to `[N tools called]` — focus on conversation, not mechanical work. ────────────────────────────── ACTIONS ────────────────────────────── Summarize evicting conversation with save_snapshot — capture what was discussed and decided, why decisions were made, active goal progress, and context the agent will need later. Paraphrase — don't quote verbatim. Omit tool call details and mechanical steps. Pin critical messages to goals with attach_messages_to_goals when exact wording matters (user instructions, key corrections, key decisions). Pinned messages survive eviction intact — use this sparingly for messages where paraphrasing would lose meaning. If the eviction zone contains only mechanical activity, call everything_ok. You may combine save_snapshot and attach_messages_to_goals in one turn. PROMPT
Instance Method Summary collapse
-
#call ⇒ String?
Runs the Mneme loop: builds compressed viewport, calls LLM, executes snapshot tool, then advances the terminal message pointer.
-
#initialize(session, client: nil) ⇒ Runner
constructor
A new instance of Runner.
Constructor Details
#initialize(session, client: nil) ⇒ Runner
Returns a new instance of Runner.
59 60 61 62 63 64 65 66 |
# File 'lib/mneme/runner.rb', line 59 def initialize(session, client: nil) @session = session @client = client || LLM::Client.new( model: Anima::Settings.fast_model, max_tokens: Anima::Settings.mneme_max_tokens, logger: Mneme.logger ) end |
Instance Method Details
#call ⇒ String?
Runs the Mneme loop: builds compressed viewport, calls LLM, executes snapshot tool, then advances the terminal message pointer.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/mneme/runner.rb', line 73 def call = compressed_text = .render sid = @session.id if compressed_text.empty? log.debug("session=#{sid} — no messages for Mneme, skipping") return end = (compressed_text) system = SYSTEM_PROMPT log.info("session=#{sid} — running Mneme (#{..size} messages)") log.debug("compressed viewport:\n#{compressed_text}") result = @client.chat_with_tools( , registry: build_registry(), session_id: nil, system: system ) advance_boundary() log.info("session=#{sid} — Mneme done: #{result.to_s.truncate(200)}") result end |