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 event (‘mneme_boundary_event_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 event to the boundary of what it just summarized, so the cycle repeats as more events accumulate.
Constant Summary collapse
- TOOLS =
[ Tools::SaveSnapshot, Tools::AttachEventsToGoals, Tools::EverythingOk ].freeze
- SYSTEM_PROMPT =
<<~PROMPT You are Mneme, the memory department of an AI agent named Anima. Your job is to create concise summaries of conversation context that is about to leave the agent's context window. You MUST ONLY communicate through tool calls — NEVER output text. ────────────────────────────── WHAT YOU SEE ────────────────────────────── A compressed viewport with three zones: - EVICTION ZONE: Events about to leave the viewport. Summarize these. - MIDDLE ZONE: Events still visible but aging. Note key context. - RECENT ZONE: Fresh events. Use for continuity with the summary. Events are prefixed with `event N` (their database ID). Tool calls are compressed to `[N tools called]` — the mechanical work is not important, only the conversation flow. ────────────────────────────── YOUR TASK ────────────────────────────── 1. Read the eviction zone carefully. 2. If it contains meaningful conversation (decisions, goals, context): Call save_snapshot with a concise summary. 3. If any events in the eviction zone are too important to summarize (exact user instructions, critical corrections, key decisions), pin them to active goals with attach_events_to_goals. Pinned events survive eviction intact — use this sparingly for events where the exact wording matters. 4. If it contains only mechanical activity with no conversation: Call everything_ok. You may call BOTH save_snapshot AND attach_events_to_goals in one turn when the zone has a mix of summarizable and pin-worthy events. Write summaries that capture: - What was discussed and decided - Why decisions were made - Active goals and their progress - Key context the agent would need later Do NOT include: - Tool call details (which files were read, commands run) - Mechanical execution steps - Verbatim quotes (paraphrase instead) Always finish with at least one tool call: save_snapshot, attach_events_to_goals, or everything_ok. You may combine save_snapshot with attach_events_to_goals. PROMPT
Instance Method Summary collapse
-
#call ⇒ String?
Runs the Mneme loop: builds compressed viewport, calls LLM, executes snapshot tool, then advances the terminal event 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.
77 78 79 80 81 82 83 84 |
# File 'lib/mneme/runner.rb', line 77 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 event pointer.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/mneme/runner.rb', line 91 def call = compressed_text = .render sid = @session.id if compressed_text.empty? log.debug("session=#{sid} — no events for Mneme, skipping") return end = (compressed_text) system = SYSTEM_PROMPT log.info("session=#{sid} — running Mneme (#{.events.size} events)") 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 |