Class: Llmemory::Actions::Reason

Inherits:
Object
  • Object
show all
Defined in:
lib/llmemory/actions/reason.rb

Overview

CoALA’s “reasoning” action: read working memory, call the LLM, write the result back to working memory. Unlike retrieval (long-term -> working) or learning (working -> long-term), reasoning reads from and writes to working memory, producing new information for the current decision.

It is a small, composable primitive — agents can chain reason -> retrieve -> reason — and deliberately does NOT touch long-term memory.

Llmemory::Actions::Reason.call(
  working_memory: wm,
  template: "Given goals {{goals}}, what is the next step?",
  into: :intermediate_reasoning
)

‘template` is either a String (with {slot} placeholders filled from working memory) or a callable that receives the WorkingMemory and returns the prompt. `parse` optionally transforms the raw LLM output before it is stored. `into` is the slot to write to (nil to reason without writing). Returns the parsed result.

Constant Summary collapse

DEFAULT_SLOT =
:intermediate_reasoning

Class Method Summary collapse

Class Method Details

.call(working_memory:, template:, into: DEFAULT_SLOT, parse: nil, llm: nil) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/llmemory/actions/reason.rb', line 27

def self.call(working_memory:, template:, into: DEFAULT_SLOT, parse: nil, llm: nil)
  client = llm || Llmemory::LLM.client
  prompt = render(template, working_memory)
  output = client.invoke(prompt).to_s
  result = parse ? parse.call(output) : output
  working_memory.set(into, result) unless into.nil?
  result
end

.interpolate(text, slots) ⇒ Object



41
42
43
44
45
46
# File 'lib/llmemory/actions/reason.rb', line 41

def self.interpolate(text, slots)
  text.gsub(/\{\{(\w+)\}\}/) do
    key = Regexp.last_match(1).to_sym
    slots.key?(key) ? slots[key].to_s : ""
  end
end

.render(template, working_memory) ⇒ Object



36
37
38
39
# File 'lib/llmemory/actions/reason.rb', line 36

def self.render(template, working_memory)
  return template.call(working_memory).to_s if template.respond_to?(:call)
  interpolate(template.to_s, working_memory.to_h)
end