Class: Rixie::Agent

Inherits:
Object
  • Object
show all
Defined in:
lib/rixie/agent.rb,
lib/rixie/agent/plan.rb,
lib/rixie/agent/re_act.rb,
lib/rixie/agent/compressor.rb

Defined Under Namespace

Classes: Compressor, Plan, ReAct, ThinkResult, Thought

Constant Summary collapse

DEFAULT_MAX_STEPS =
10

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instructions:, llm_client:, tools: [], max_steps: nil, parallel_tool_calls: false) ⇒ Agent

Returns a new instance of Agent.



16
17
18
19
20
21
22
23
# File 'lib/rixie/agent.rb', line 16

def initialize(instructions:, llm_client:, tools: [], max_steps: nil, parallel_tool_calls: false)
  @instructions = instructions
  @tools = tools
  @max_steps = max_steps || DEFAULT_MAX_STEPS
  @parallel_tool_calls = parallel_tool_calls
  @tool_executor = ToolExecutor.new(tools: tools)
  @llm_client = llm_client
end

Instance Attribute Details

#instructionsObject (readonly)

Returns the value of attribute instructions.



14
15
16
# File 'lib/rixie/agent.rb', line 14

def instructions
  @instructions
end

#llm_clientObject (readonly)

Returns the value of attribute llm_client.



14
15
16
# File 'lib/rixie/agent.rb', line 14

def llm_client
  @llm_client
end

#parallel_tool_callsObject (readonly)

Returns the value of attribute parallel_tool_calls.



14
15
16
# File 'lib/rixie/agent.rb', line 14

def parallel_tool_calls
  @parallel_tool_calls
end

#toolsObject (readonly)

Returns the value of attribute tools.



14
15
16
# File 'lib/rixie/agent.rb', line 14

def tools
  @tools
end

Instance Method Details

#think(messages:, listener:) ⇒ Object



35
36
37
38
39
40
41
42
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
70
71
72
73
# File 'lib/rixie/agent.rb', line 35

def think(messages:, listener:)
  thoughts = []
  tool_call_count = 0
  step_count = 0

  loop do
    step_count += 1
    listener.emit(Event::LlmCallStart.new(step_count: step_count))
    thought = llm_call(messages:) { |event| listener.emit(event) }

    if thought.tool_call?
      raise MaxStepsExceededError, "Max steps (#{@max_steps}) exceeded" if tool_call_count >= @max_steps
      tool_call_count += 1
      results = call_thought_tools(
        on_start: ->(tc) { listener.emit(Event::ToolCallStart.new(tool_call: tc)) },
        thought: thought,
        on_end: ->(tc, result) { listener.emit(Event::ToolCallEnd.new(tool_call: tc, result: result)) },
        parallel: @parallel_tool_calls
      )

      listener.emit(Event::ToolCallsCompleted.new(tool_calls: thought.tool_calls, tool_results: results))

      thought = record_thought(thoughts, thought, results)
      append_thought_messages(messages, thought)

      if @tool_executor.return_direct?(thought.tool_calls)
        listener.emit(Event::Finished.new(content: nil))
        return ThinkResult.new(content: nil, thoughts: thoughts)
      end
    elsif thought.finish?
      thoughts << thought
      listener.emit(Event::ThoughtCompleted.new(thought: thought))
      listener.emit(Event::Finished.new(content: thought.content))
      return ThinkResult.new(content: thought.content, thoughts: thoughts)
    else
      raise Rixie::AgentError, "Unknown thought type: #{thought.type.inspect}"
    end
  end
end

#with_llm_client(llm_client) ⇒ Object



25
26
27
28
29
30
31
32
33
# File 'lib/rixie/agent.rb', line 25

def with_llm_client(llm_client)
  Agent.new(
    instructions: @instructions,
    tools: @tools,
    max_steps: @max_steps,
    llm_client: llm_client,
    parallel_tool_calls: @parallel_tool_calls
  )
end