Class: Ragents::Agent
- Inherits:
-
Object
- Object
- Ragents::Agent
- Defined in:
- lib/ragents/agent.rb
Overview
Base class for AI agents. Agents can run in isolated Ractors for concurrent execution.
Class Attribute Summary collapse
-
.defined_system_prompt ⇒ Object
readonly
Returns the value of attribute defined_system_prompt.
-
.defined_tools ⇒ Object
readonly
Returns the value of attribute defined_tools.
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#provider ⇒ Object
readonly
Returns the value of attribute provider.
-
#tools ⇒ Object
readonly
Returns the value of attribute tools.
Class Method Summary collapse
-
.resolved_system_prompt ⇒ Object
Get resolved system prompt.
-
.run_async(provider:, context: nil, input: nil, **options) ⇒ Ractor
Run the agent in a Ractor for isolated concurrent execution.
-
.run_in_ractor(provider:, context: nil, input: nil, **options) ⇒ Object
Execute in Ractor and wait for result Uses Ruby 4.x Ractor#value (replaces deprecated #take).
-
.system_prompt(prompt = nil, &block) ⇒ Object
DSL: Define the system prompt for this agent.
-
.tool(name, &block) ⇒ Object
DSL: Define a tool for this agent.
-
.tools ⇒ Object
Get all inherited tools.
Instance Method Summary collapse
-
#generate ⇒ Response
Run a single generation (does not auto-execute tools).
-
#initialize(provider:, context: nil, tools: nil, **options) ⇒ Agent
constructor
A new instance of Agent.
-
#last_response ⇒ Object
Get the last response content.
-
#run(input: nil) ⇒ Context
Run the agent to completion (handles tool calls automatically).
-
#say(content) ⇒ self
Add a user message and return self for chaining.
Constructor Details
#initialize(provider:, context: nil, tools: nil, **options) ⇒ Agent
Returns a new instance of Agent.
60 61 62 63 64 65 66 67 68 |
# File 'lib/ragents/agent.rb', line 60 def initialize(provider:, context: nil, tools: nil, **) @provider = provider @context = context || Context.new @tools = tools || self.class.tools @options = @max_iterations = .fetch(:max_iterations, 10) setup_initial_context! end |
Class Attribute Details
.defined_system_prompt ⇒ Object (readonly)
Returns the value of attribute defined_system_prompt.
24 25 26 |
# File 'lib/ragents/agent.rb', line 24 def defined_system_prompt @defined_system_prompt end |
.defined_tools ⇒ Object (readonly)
Returns the value of attribute defined_tools.
24 25 26 |
# File 'lib/ragents/agent.rb', line 24 def defined_tools @defined_tools end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
58 59 60 |
# File 'lib/ragents/agent.rb', line 58 def context @context end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
58 59 60 |
# File 'lib/ragents/agent.rb', line 58 def @options end |
#provider ⇒ Object (readonly)
Returns the value of attribute provider.
58 59 60 |
# File 'lib/ragents/agent.rb', line 58 def provider @provider end |
#tools ⇒ Object (readonly)
Returns the value of attribute tools.
58 59 60 |
# File 'lib/ragents/agent.rb', line 58 def tools @tools end |
Class Method Details
.resolved_system_prompt ⇒ Object
Get resolved system prompt
52 53 54 55 |
# File 'lib/ragents/agent.rb', line 52 def resolved_system_prompt prompt = defined_system_prompt prompt.is_a?(Proc) ? prompt.call : prompt end |
.run_async(provider:, context: nil, input: nil, **options) ⇒ Ractor
Run the agent in a Ractor for isolated concurrent execution
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/ragents/agent.rb', line 118 def self.run_async(provider:, context: nil, input: nil, **) # Prepare Ractor-shareable data agent_class = self frozen_context = context&.freeze || Context.new.freeze Ractor.new(agent_class, provider, frozen_context, input, ) do |klass, prov, ctx, inp, opts| agent = klass.new(provider: prov, context: ctx, **opts) agent.run(input: inp) end end |
.run_in_ractor(provider:, context: nil, input: nil, **options) ⇒ Object
Execute in Ractor and wait for result Uses Ruby 4.x Ractor#value (replaces deprecated #take)
131 132 133 134 |
# File 'lib/ragents/agent.rb', line 131 def self.run_in_ractor(provider:, context: nil, input: nil, **) ractor = run_async(provider: provider, context: context, input: input, **) ractor.value end |
.system_prompt(prompt = nil, &block) ⇒ Object
DSL: Define the system prompt for this agent
27 28 29 |
# File 'lib/ragents/agent.rb', line 27 def system_prompt(prompt = nil, &block) @defined_system_prompt = block_given? ? block : prompt end |
.tool(name, &block) ⇒ Object
DSL: Define a tool for this agent
32 33 34 35 |
# File 'lib/ragents/agent.rb', line 32 def tool(name, &block) @defined_tools ||= ToolRegistry.new @defined_tools.register(name, &block) end |
.tools ⇒ Object
Get all inherited tools
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/ragents/agent.rb', line 38 def tools registry = ToolRegistry.new # Collect tools from ancestors (inheritance chain) ancestors.reverse.each do |klass| next unless klass.respond_to?(:defined_tools) && klass.defined_tools klass.defined_tools.each { |t| registry.register(t.name, t) } end registry end |
Instance Method Details
#generate ⇒ Response
Run a single generation (does not auto-execute tools)
94 95 96 97 98 99 100 |
# File 'lib/ragents/agent.rb', line 94 def generate @provider.generate( messages: @context.to_a, tools: @tools, **@options ) end |
#last_response ⇒ Object
Get the last response content
111 112 113 |
# File 'lib/ragents/agent.rb', line 111 def last_response @context.&.content end |
#run(input: nil) ⇒ Context
Run the agent to completion (handles tool calls automatically)
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/ragents/agent.rb', line 73 def run(input: nil) add_user_input!(input) if input iterations = 0 loop do iterations += 1 raise MaxIterationsError, "Exceeded #{@max_iterations} iterations" if iterations > @max_iterations response = generate @context = @context.(response.) break unless response.has_tool_calls? execute_tool_calls(response.tool_calls) end @context end |