Class: Looped::Agent

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/looped/agent.rb

Constant Summary collapse

DEFAULT_MODEL =
'openai/gpt-4o-mini'
DEFAULT_MAX_ITERATIONS =
10

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model: nil, max_iterations: DEFAULT_MAX_ITERATIONS, judge_model: nil) ⇒ Agent

Returns a new instance of Agent.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/looped/agent.rb', line 27

def initialize(model: nil, max_iterations: DEFAULT_MAX_ITERATIONS, judge_model: nil)
  @model_id = T.let(model || ENV.fetch('LOOPED_MODEL', DEFAULT_MODEL), String)
  @max_iterations = T.let(max_iterations, Integer)
  @memory = T.let(Memory.new, Memory)
  @state = T.let(State.new, State)
  @judge = T.let(Judge.new(model: judge_model), Judge)
  @instructions_mtime = T.let(nil, T.nilable(String))

  # Build the ReAct agent with tools
  @react = T.let(build_react_agent, DSPy::ReAct)

  # Load any existing instructions
  maybe_reload_instructions
end

Instance Attribute Details

#instructions_mtimeObject (readonly)

Returns the value of attribute instructions_mtime.



24
25
26
# File 'lib/looped/agent.rb', line 24

def instructions_mtime
  @instructions_mtime
end

#judgeObject (readonly)

Returns the value of attribute judge.



21
22
23
# File 'lib/looped/agent.rb', line 21

def judge
  @judge
end

#memoryObject (readonly)

Returns the value of attribute memory.



15
16
17
# File 'lib/looped/agent.rb', line 15

def memory
  @memory
end

#reactObject (readonly)

Returns the value of attribute react.



12
13
14
# File 'lib/looped/agent.rb', line 12

def react
  @react
end

#stateObject (readonly)

Returns the value of attribute state.



18
19
20
# File 'lib/looped/agent.rb', line 18

def state
  @state
end

Instance Method Details

#reload_instructionsObject



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/looped/agent.rb', line 72

def reload_instructions
  instructions = @state.load_instructions
  return unless instructions

  # Create a new react agent with the updated instructions
  thought_instruction = instructions.thought_generator
  observation_instruction = instructions.observation_processor

  if thought_instruction || observation_instruction
    @react = build_react_agent(
      thought_instruction: thought_instruction,
      observation_instruction: observation_instruction
    )

    # Track mtime for hot-reload detection
    @instructions_mtime = instructions.updated_at
  end
end

#run(task:, context: '') ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/looped/agent.rb', line 43

def run(task:, context: '')
  # Check for instruction hot-reload
  maybe_reload_instructions

  # Clear memory for new task
  @memory.clear

  # Execute the agent
  result = execute_task(task: task, context: context)

  # Judge the result
  judgment = @judge.evaluate(task: task, solution: result[:solution])

  # Create training result
  training_result = Types::TrainingResult.new(
    task: task,
    solution: result[:solution],
    score: judgment.score,
    feedback: @judge.to_feedback(judgment),
    timestamp: Time.now.utc.iso8601
  )

  # Persist for GEPA optimization
  @state.append_training_result(training_result)

  training_result
end