Class: Mneme::Tools::SurfaceMemory

Inherits:
Tools::Base show all
Defined in:
lib/mneme/tools/surface_memory.rb

Overview

Surfaces a past message into Aoide’s next turn as a ‘from_mneme` phantom tool pair. Called by Mneme’s recall loop when a search hit or a viewed message clears her relevance bar.

The persisted PendingMessage carries the original message_id in its source_name (and through promotion ends up inside tool_input.message_id of the phantom pair), so the same memory isn’t re-surfaced on later cycles — Mneme::Search already excludes Aoide’s viewport, and once a recall promotes it lives there.

The muse explains why she’s surfacing this memory. The reason is logged but not shown to Aoide — keeping the surfaced content itself clean of meta-commentary.

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Tools::Base

prompt_guidelines, prompt_snippet, schema, truncation_threshold

Constructor Details

#initialize(main_session:) ⇒ SurfaceMemory

Returns a new instance of SurfaceMemory.

Parameters:

  • main_session (Session)

    the session receiving the recall



35
36
37
# File 'lib/mneme/tools/surface_memory.rb', line 35

def initialize(main_session:, **)
  @main_session = main_session
end

Class Method Details

.descriptionObject



21
# File 'lib/mneme/tools/surface_memory.rb', line 21

def self.description = "Surface a memory into Aoide's next turn. Use when a specific past message is genuinely useful for what she's working on now. Pass the message_id and a short reason — one sentence explaining why she needs this *now*."

.input_schemaObject



23
24
25
26
27
28
29
30
31
32
# File 'lib/mneme/tools/surface_memory.rb', line 23

def self.input_schema
  {
    type: "object",
    properties: {
      message_id: {type: "integer"},
      why: {type: "string", description: "One-sentence justification — kept for logs, not shown to Aoide."}
    },
    required: %w[message_id why]
  }
end

.tool_nameObject



19
# File 'lib/mneme/tools/surface_memory.rb', line 19

def self.tool_name = "surface_memory"

Instance Method Details

#execute(input) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/mneme/tools/surface_memory.rb', line 39

def execute(input)
  message_id = input["message_id"].to_i
  why = input["why"].to_s.strip

  message = Message.find_by(id: message_id)
  return {error: "Message #{message_id} not found"} unless message
  return {error: "Reason cannot be blank"} if why.empty?

  content = render_snippet(message)

  @main_session.pending_messages.create!(
    content: content,
    source_type: "recall",
    source_name: message_id.to_s,
    message_type: "from_mneme"
  )

  Mneme.logger.info("session=#{@main_session.id} — surfaced message #{message_id}: #{why}")

  "Surfaced message #{message_id}."
end