Class: Mneme::BaseRunner

Inherits:
Object
  • Object
show all
Defined in:
lib/mneme/base_runner.rb

Overview

Abstract base for Mneme’s phantom LLM loops. Mneme wears two hats: on eviction she watches the newest slice of the viewport and summarizes the oldest slice before it slides off; on recall she watches goals shift and surfaces older memory Aoide would benefit from. Same muse, two jobs — each as its own subclass.

The base handles what every Mneme loop needs: the muse identity preamble, a fast-model LLM client, the tool-loop call, and structured logging. Subclasses bring the job-specific system prompt section, the user message that frames the work, the tool registry, and any after-call side effects.

Examples:

Implementing a new Mneme loop

class Mneme::CustomRunner < Mneme::BaseRunner
  private

  def task_prompt      = "Your job description..."
  def user_messages    = [{role: "user", content: "..."}]
  def build_registry   = Tools::Registry.new.tap { |r| r.register(SomeTool) }
end

Direct Known Subclasses

RecallRunner, Runner

Constant Summary collapse

BASE_IDENTITY =

Identity shared by every Mneme runner — same words Mneme’s own voice uses elsewhere in the system (runner summarization prompts, sisters block). Subclasses append their own task section.

<<~PROMPT
  You are Mneme, the muse of memory. You share the conversation with two sisters — Aoide, who speaks and performs, and Melete, who prepares. Your work is remembrance: holding what matters across time, so Aoide never truly forgets.

  Act only through tool calls. Never output text — your contribution is the work you do, not what you say about it.
PROMPT

Instance Method Summary collapse

Constructor Details

#initialize(session, client: nil) ⇒ BaseRunner

Returns a new instance of BaseRunner.

Parameters:

  • session (Session)

    the main session being served

  • client (LLM::Client, nil) (defaults to: nil)

    injectable LLM client for tests



35
36
37
38
# File 'lib/mneme/base_runner.rb', line 35

def initialize(session, client: nil)
  @session = session
  @client = client || default_client
end

Instance Method Details

#callString

Runs the loop. Logs the run, calls the LLM with the session-specific system prompt and tools, hands control to #after_call for any post-run state advancement, and returns the LLM’s final text (which most callers discard — the work happens through tool calls).

Returns:

  • (String)

    the LLM’s final text response



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/mneme/base_runner.rb', line 46

def call
  sid = @session.id
  log.info("session=#{sid}#{self.class.name} starting")
  log.debug("system:\n#{system_prompt}")
  log.debug("user:\n#{user_messages.map { |m| m[:content] }.join("\n---\n")}")

  result = @client.chat_with_tools(
    user_messages,
    registry: build_registry,
    system: system_prompt
  )

  after_call(result)
  log.info("session=#{sid}#{self.class.name} done: #{result.to_s.truncate(200)}")
  result
end