Class: RCrewAI::Agent
- Inherits:
-
Object
- Object
- RCrewAI::Agent
- Includes:
- AgentAugmentations, HumanInteractionExtensions
- Defined in:
- lib/rcrewai/agent.rb
Defined Under Namespace
Classes: CLI
Instance Attribute Summary collapse
-
#allow_delegation ⇒ Object
Returns the value of attribute allow_delegation.
-
#backstory ⇒ Object
readonly
Returns the value of attribute backstory.
-
#crew_knowledge ⇒ Object
writeonly
Set by the crew so agents see shared knowledge in addition to their own.
-
#goal ⇒ Object
readonly
Returns the value of attribute goal.
-
#knowledge ⇒ Object
readonly
Returns the value of attribute knowledge.
-
#llm_client ⇒ Object
readonly
Returns the value of attribute llm_client.
-
#manager ⇒ Object
Returns the value of attribute manager.
-
#max_execution_time ⇒ Object
Returns the value of attribute max_execution_time.
-
#max_iterations ⇒ Object
Returns the value of attribute max_iterations.
-
#memory ⇒ Object
readonly
Returns the value of attribute memory.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#rate_limiter ⇒ Object
readonly
Returns the value of attribute rate_limiter.
-
#role ⇒ Object
readonly
Returns the value of attribute role.
-
#subordinates ⇒ Object
readonly
Returns the value of attribute subordinates.
-
#tools ⇒ Object
readonly
Returns the value of attribute tools.
-
#verbose ⇒ Object
Returns the value of attribute verbose.
Instance Method Summary collapse
- #add_subordinate(agent) ⇒ Object
- #available_tools_description ⇒ Object
- #delegate_task(task, target_agent) ⇒ Object
- #disable_human_input ⇒ Object
-
#enable_human_input(**options) ⇒ Object
Human input methods (public).
- #execute_delegated_task(task, delegation_instructions, manager_agent) ⇒ Object
- #execute_task(task, stream: nil, **opts) ⇒ Object
- #human_input_enabled? ⇒ Boolean
-
#initialize(name:, role:, goal:, backstory: nil, tools: [], **options) ⇒ Agent
constructor
A new instance of Agent.
-
#is_manager? ⇒ Boolean
Manager-specific methods.
- #require_approval_for_tools? ⇒ Boolean
- #use_tool(tool_name, **params) ⇒ Object
Methods included from AgentAugmentations
#fit_context, #reasoning?, #respect_context_window?
Methods included from HumanInteractionExtensions
#confirm_with_human, #get_human_feedback, #request_human_approval, #request_human_choice, #request_human_input, #request_human_review
Constructor Details
#initialize(name:, role:, goal:, backstory: nil, tools: [], **options) ⇒ Agent
Returns a new instance of Agent.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/rcrewai/agent.rb', line 23 def initialize(name:, role:, goal:, backstory: nil, tools: [], **) @name = name @role = role @goal = goal @backstory = backstory @tools = tools @verbose = .fetch(:verbose, false) @allow_delegation = .fetch(:allow_delegation, false) @manager = .fetch(:manager, false) # New manager flag @max_iterations = .fetch(:max_iterations, 10) @max_execution_time = .fetch(:max_execution_time, 300) # 5 minutes @human_input_enabled = .fetch(:human_input, false) @require_approval_for_tools = .fetch(:require_approval_for_tools, false) @require_approval_for_final_answer = .fetch(:require_approval_for_final_answer, false) @logger = Logger.new($stdout) @logger.level = verbose ? Logger::DEBUG : Logger::INFO @reasoning = .fetch(:reasoning, false) @max_reasoning_attempts = .fetch(:max_reasoning_attempts, 3) @respect_context_window = .fetch(:respect_context_window, false) @memory = build_memory([:memory]) @rate_limiter = [:max_rpm] ? RateLimiter.new(max_rpm: [:max_rpm]) : nil @llm_client = wrap_with_rate_limiter(build_llm_client([:llm])) @knowledge = build_knowledge([:knowledge], [:knowledge_sources]) @subordinates = [] # For manager agents end |
Instance Attribute Details
#allow_delegation ⇒ Object
Returns the value of attribute allow_delegation.
19 20 21 |
# File 'lib/rcrewai/agent.rb', line 19 def allow_delegation @allow_delegation end |
#backstory ⇒ Object (readonly)
Returns the value of attribute backstory.
18 19 20 |
# File 'lib/rcrewai/agent.rb', line 18 def backstory @backstory end |
#crew_knowledge=(value) ⇒ Object (writeonly)
Set by the crew so agents see shared knowledge in addition to their own.
21 22 23 |
# File 'lib/rcrewai/agent.rb', line 21 def crew_knowledge=(value) @crew_knowledge = value end |
#goal ⇒ Object (readonly)
Returns the value of attribute goal.
18 19 20 |
# File 'lib/rcrewai/agent.rb', line 18 def goal @goal end |
#knowledge ⇒ Object (readonly)
Returns the value of attribute knowledge.
18 19 20 |
# File 'lib/rcrewai/agent.rb', line 18 def knowledge @knowledge end |
#llm_client ⇒ Object (readonly)
Returns the value of attribute llm_client.
18 19 20 |
# File 'lib/rcrewai/agent.rb', line 18 def llm_client @llm_client end |
#manager ⇒ Object
Returns the value of attribute manager.
19 20 21 |
# File 'lib/rcrewai/agent.rb', line 19 def manager @manager end |
#max_execution_time ⇒ Object
Returns the value of attribute max_execution_time.
19 20 21 |
# File 'lib/rcrewai/agent.rb', line 19 def max_execution_time @max_execution_time end |
#max_iterations ⇒ Object
Returns the value of attribute max_iterations.
19 20 21 |
# File 'lib/rcrewai/agent.rb', line 19 def max_iterations @max_iterations end |
#memory ⇒ Object (readonly)
Returns the value of attribute memory.
18 19 20 |
# File 'lib/rcrewai/agent.rb', line 18 def memory @memory end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
18 19 20 |
# File 'lib/rcrewai/agent.rb', line 18 def name @name end |
#rate_limiter ⇒ Object (readonly)
Returns the value of attribute rate_limiter.
18 19 20 |
# File 'lib/rcrewai/agent.rb', line 18 def rate_limiter @rate_limiter end |
#role ⇒ Object (readonly)
Returns the value of attribute role.
18 19 20 |
# File 'lib/rcrewai/agent.rb', line 18 def role @role end |
#subordinates ⇒ Object (readonly)
Returns the value of attribute subordinates.
140 141 142 |
# File 'lib/rcrewai/agent.rb', line 140 def subordinates @subordinates end |
#tools ⇒ Object (readonly)
Returns the value of attribute tools.
18 19 20 |
# File 'lib/rcrewai/agent.rb', line 18 def tools @tools end |
#verbose ⇒ Object
Returns the value of attribute verbose.
19 20 21 |
# File 'lib/rcrewai/agent.rb', line 19 def verbose @verbose end |
Instance Method Details
#add_subordinate(agent) ⇒ Object
134 135 136 137 138 |
# File 'lib/rcrewai/agent.rb', line 134 def add_subordinate(agent) return unless is_manager? @subordinates << agent unless @subordinates.include?(agent) end |
#available_tools_description ⇒ Object
89 90 91 92 93 94 95 |
# File 'lib/rcrewai/agent.rb', line 89 def available_tools_description return 'No tools available.' if tools.empty? tools.map do |tool| "- #{tool.name}: #{tool.description}" end.join("\n") end |
#delegate_task(task, target_agent) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/rcrewai/agent.rb', line 142 def delegate_task(task, target_agent) return unless is_manager? return unless @subordinates.include?(target_agent) || allow_delegation @logger.info "Manager #{name} delegating task '#{task.name}' to #{target_agent.name}" # Create delegation context delegation_prompt = build_delegation_prompt(task, target_agent) # Use LLM to create proper delegation response = llm_client.chat( messages: [{ role: 'user', content: delegation_prompt }], temperature: 0.2, max_tokens: 1000 ) delegation_instructions = response[:content] @logger.debug "Delegation instructions: #{delegation_instructions}" # Execute delegated task target_agent.execute_delegated_task(task, delegation_instructions, self) end |
#disable_human_input ⇒ Object
198 199 200 201 202 203 |
# File 'lib/rcrewai/agent.rb', line 198 def disable_human_input @human_input_enabled = false @require_approval_for_tools = false @require_approval_for_final_answer = false @logger.info "Human input disabled for agent #{name}" end |
#enable_human_input(**options) ⇒ Object
Human input methods (public)
191 192 193 194 195 196 |
# File 'lib/rcrewai/agent.rb', line 191 def enable_human_input(**) @human_input_enabled = true @require_approval_for_tools = .fetch(:require_approval_for_tools, false) @require_approval_for_final_answer = .fetch(:require_approval_for_final_answer, false) @logger.info "Human input enabled for agent #{name}" end |
#execute_delegated_task(task, delegation_instructions, manager_agent) ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/rcrewai/agent.rb', line 165 def execute_delegated_task(task, delegation_instructions, manager_agent) @logger.info "Receiving delegation from manager #{manager_agent.name}" @logger.debug "Delegation instructions: #{delegation_instructions}" # Store delegation context in task original_description = task.description enhanced_description = "#{original_description}\n\nDelegation Instructions from #{manager_agent.name}:\n#{delegation_instructions}" # Temporarily modify task task.instance_variable_set(:@description, enhanced_description) task.instance_variable_set(:@manager, manager_agent) begin result = execute_task(task) # Report back to manager report_to_manager(task, result, manager_agent) result ensure # Restore original task description task.instance_variable_set(:@description, original_description) end end |
#execute_task(task, stream: nil, **opts) ⇒ Object
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 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rcrewai/agent.rb', line 49 def execute_task(task, stream: nil, **opts) @logger.info "Agent #{name} starting task: #{task.name}" start_time = Time.now begin = (task) sink = stream || ->(_) {} reasoning = reasoning? ? run_reasoning_pass(task) : nil = inject_reasoning(, reasoning) if reasoning runner_class = pick_runner_class @logger.info "[rcrewai] agent=#{name} runner=#{runner_class.name.split('::').last}" runner = runner_class.new( agent: self, llm: @llm_client, tools: @tools, max_iterations: opts.fetch(:max_iterations, max_iterations), event_sink: sink ) runner_result = runner.run(messages: ) execution_time = Time.now - start_time @logger.info "Task completed in #{execution_time.round(2)}s" result_string = runner_result[:content].to_s memory.add_execution(task, result_string, execution_time) task.result = result_string build_task_result(task, runner_result, reasoning: reasoning) rescue StandardError => e @logger.error "Task execution failed: #{e.}" task.result = "Task failed: #{e.}" raise AgentError, "Agent #{name} failed to execute task: #{e.}" end end |
#human_input_enabled? ⇒ Boolean
205 206 207 |
# File 'lib/rcrewai/agent.rb', line 205 def human_input_enabled? @human_input_enabled end |
#is_manager? ⇒ Boolean
Manager-specific methods
130 131 132 |
# File 'lib/rcrewai/agent.rb', line 130 def is_manager? @manager end |
#require_approval_for_tools? ⇒ Boolean
85 86 87 |
# File 'lib/rcrewai/agent.rb', line 85 def require_approval_for_tools? @require_approval_for_tools && @human_input_enabled end |
#use_tool(tool_name, **params) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/rcrewai/agent.rb', line 97 def use_tool(tool_name, **params) tool = tools.find { |t| t.name == tool_name || t.class.name.split('::').last.downcase == tool_name.downcase } raise ToolNotFoundError, "Tool '#{tool_name}' not found" unless tool # Request human approval for tool usage if required if @require_approval_for_tools && @human_input_enabled approval_result = request_tool_approval(tool_name, params) unless approval_result[:approved] @logger.info "Tool usage rejected by human: #{tool_name}" return "Tool usage was rejected by human reviewer: #{approval_result[:reason]}" end end @logger.debug "Using tool: #{tool_name} with params: #{params}" begin result = tool.execute(**params) # Store tool usage in memory memory.add_tool_usage(tool_name, params, result) result rescue StandardError => e @logger.error "Tool execution failed: #{e.}" # Offer human intervention if tool fails and human input is enabled raise e unless @human_input_enabled handle_tool_failure(tool_name, params, e) end end |