Class: Foobara::Agent
- Inherits:
-
CommandConnector
- Object
- CommandConnector
- Foobara::Agent
- Defined in:
- foobara-agent-0.0.5/src/foobara/agent/accomplish_goal.rb,
foobara-agent-0.0.5/src/foobara/agent.rb,
foobara-agent-0.0.5/src/foobara/agent/give_up.rb,
foobara-agent-0.0.5/src/foobara/agent/list_types.rb,
foobara-agent-0.0.5/src/foobara/agent/describe_type.rb,
foobara-agent-0.0.5/src/foobara/agent/list_commands.rb,
foobara-agent-0.0.5/src/foobara/agent/types/context.rb,
foobara-agent-0.0.5/src/foobara/agent/describe_command.rb,
foobara-agent-0.0.5/src/foobara/agent/determine_next_command.rb,
foobara-agent-0.0.5/src/foobara/agent/types/command_log_entry.rb,
foobara-agent-0.0.5/src/foobara/agent/concerns/subclass_cacheable.rb,
foobara-agent-0.0.5/src/foobara/agent/determine_inputs_for_next_command.rb,
foobara-agent-0.0.5/src/foobara/agent/determine_next_command_name_and_inputs.rb,
foobara-agent-0.0.5/src/foobara/agent/connector/set_command_connector_inputs_transformer.rb,
foobara-agent-0.0.5/src/foobara/agent/notify_user_that_current_goal_has_been_accomplished.rb,
foobara-agent-0.0.5/lib/foobara/agent.rb
Overview
TODO: should agent maybe be a command connector? It feels a bit more like a command connector.
Defined Under Namespace
Modules: Concerns Classes: AccomplishGoal, CommandLogEntry, Context, DescribeCommand, DescribeType, DetermineInputsForNextCommand, DetermineNextCommand, DetermineNextCommandNameAndInputs, GiveUp, ListCommands, ListTypes, NotifyUserThatCurrentGoalHasBeenAccomplished, SetCommandConnectorInputsTransformer
Constant Summary collapse
- StateMachine =
Foobara::StateMachine.for( [:initialized, :idle, :error, :failure] => { kill: :killed, accomplish_goal: :accomplishing_goal }, accomplishing_goal: { goal_accomplished: :idle, goal_errored: :error, goal_failed: :failure, kill: :killed } )
Instance Attribute Summary collapse
-
#agent_commands_connected ⇒ Object
Returns the value of attribute agent_commands_connected.
-
#agent_name ⇒ Object
Returns the value of attribute agent_name.
-
#context ⇒ Object
Returns the value of attribute context.
-
#current_accomplish_goal_command ⇒ Object
Returns the value of attribute current_accomplish_goal_command.
-
#llm_model ⇒ Object
Returns the value of attribute llm_model.
-
#result_type ⇒ Object
Returns the value of attribute result_type.
Attributes inherited from CommandConnector
#authenticator, #capture_unknown_error, #command_registry
Class Method Summary collapse
Instance Method Summary collapse
- #accomplish_goal(goal, result_type: nil, choose_next_command_and_next_inputs_separately: nil, maximum_call_count: nil) ⇒ Object
- #agent_commands_connected? ⇒ Boolean
- #build_initial_context ⇒ Object
- #connect_agent_commands(final_result_type: nil, agent_name: nil) ⇒ Object
- #give_up(reason) ⇒ Object
-
#initialize(context: nil, agent_name: nil, command_classes: nil, llm_model: nil, result_type: nil, current_accomplish_goal_command: nil, **opts) ⇒ Agent
constructor
A new instance of Agent.
- #kill! ⇒ Object
- #killed? ⇒ Boolean
- #mark_mission_accomplished(final_result, message_to_user) ⇒ Object
- #run(*args) ⇒ Object
- #state_machine ⇒ Object
Methods inherited from CommandConnector
#all_exposed_commands, #all_exposed_type_names, allowed_rules_to_register, authenticator_registry, #build_command_instance, #build_request, #build_response, #connect, #connect_delayed, #delayed_connections, #desugarize_connect_args, #determine_command_class, find_builtin_command_class, #find_builtin_command_class, #foobara_manifest, #foobara_manifest_in_current_namespace, #lookup_command, #mutate_response, #normalize_manifest, #patch_up_broken_parents_for_errors_with_missing_command_parents, #process_delayed_connections, register_allowed_rule, register_authenticator, #request_to_command_class, #request_to_command_inputs, #request_to_command_instance, #request_to_response, #run_command, #run_request, #serialize_response_body, #set_response_body, #set_response_status, to_authenticator, #transform_command_class, #type_from_name
Constructor Details
#initialize(context: nil, agent_name: nil, command_classes: nil, llm_model: nil, result_type: nil, current_accomplish_goal_command: nil, **opts) ⇒ 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 48 49 50 51 52 53 54 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 23 def initialize( context: nil, agent_name: nil, command_classes: nil, llm_model: nil, result_type: nil, current_accomplish_goal_command: nil, **opts ) # TODO: shouldn't have to pass command_log here since it has a default, debug that self.context = context self.agent_name = agent_name if agent_name self.llm_model = llm_model self.result_type = result_type self.current_accomplish_goal_command = current_accomplish_goal_command unless opts.key?(:default_serializers) opts = opts.merge(default_serializers: [ Foobara::CommandConnectors::Serializers::ErrorsSerializer, Foobara::CommandConnectors::Serializers::AtomicSerializer ]) end super(**opts) build_initial_context # TODO: push this convenience method up into base class? command_classes&.each do |command_class| connect(command_class) end end |
Instance Attribute Details
#agent_commands_connected ⇒ Object
Returns the value of attribute agent_commands_connected.
16 17 18 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 16 def agent_commands_connected @agent_commands_connected end |
#agent_name ⇒ Object
Returns the value of attribute agent_name.
16 17 18 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 16 def agent_name @agent_name end |
#context ⇒ Object
Returns the value of attribute context.
16 17 18 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 16 def context @context end |
#current_accomplish_goal_command ⇒ Object
Returns the value of attribute current_accomplish_goal_command.
16 17 18 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 16 def current_accomplish_goal_command @current_accomplish_goal_command end |
#llm_model ⇒ Object
Returns the value of attribute llm_model.
16 17 18 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 16 def llm_model @llm_model end |
#result_type ⇒ Object
Returns the value of attribute result_type.
16 17 18 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 16 def result_type @result_type end |
Class Method Details
.reset_all ⇒ Object
12 13 14 15 16 17 18 19 20 21 |
# File 'foobara-agent-0.0.5/lib/foobara/agent.rb', line 12 def reset_all [ DetermineInputsForNextCommand, DetermineNextCommand, NotifyUserThatCurrentGoalHasBeenAccomplished ].each do |command_class| command_class.clear_subclass_cache Util.descendants(command_class).each(&:clear_subclass_cache) end end |
Instance Method Details
#accomplish_goal(goal, result_type: nil, choose_next_command_and_next_inputs_separately: nil, maximum_call_count: nil) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 80 def accomplish_goal( goal, result_type: nil, choose_next_command_and_next_inputs_separately: nil, maximum_call_count: nil ) if result_type && self.result_type != result_type if self.result_type # :nocov: raise ArgumentError, "You can only specify a result type once" # :nocov: elsif agent_commands_connected? # :nocov: raise ArgumentError, "You can't specify a result type this late in the process" # :nocov: else self.result_type = result_type end end state_machine.perform_transition!(:accomplish_goal) begin inputs = { goal:, final_result_type: self.result_type, current_context: context, existing_command_connector: self } if agent_name inputs[:agent_name] = agent_name end if llm_model inputs[:llm_model] = llm_model end unless choose_next_command_and_next_inputs_separately.nil? inputs[:choose_next_command_and_next_inputs_separately] = choose_next_command_and_next_inputs_separately end unless maximum_call_count.nil? inputs[:maximum_command_calls] = maximum_call_count end self.current_accomplish_goal_command = AccomplishGoal.new(inputs) current_accomplish_goal_command.run.tap do |outcome| if outcome.success? state_machine.perform_transition!(:goal_accomplished) else state_machine.perform_transition!(:goal_errored) end end rescue # :nocov: state_machine.perform_transition!(:goal_failed) raise # :nocov: end end |
#agent_commands_connected? ⇒ Boolean
158 159 160 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 158 def agent_commands_connected? agent_commands_connected end |
#build_initial_context ⇒ Object
143 144 145 146 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 143 def build_initial_context # TODO: shouldn't have to pass command_log here since it has a default, debug that self.context ||= Context.new(command_log: []) end |
#connect_agent_commands(final_result_type: nil, agent_name: nil) ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 162 def connect_agent_commands(final_result_type: nil, agent_name: nil) command_classes = [ DescribeCommand, DescribeType, GiveUp, ListCommands, ListTypes ] command_classes << if final_result_type NotifyUserThatCurrentGoalHasBeenAccomplished.for( result_type: final_result_type, agent_id: agent_name ) else NotifyUserThatCurrentGoalHasBeenAccomplished end set_command_connector_transformer = SetCommandConnectorInputsTransformer.for(self) command_classes.each do |command_class| connect(command_class, inputs: set_command_connector_transformer) end self.agent_commands_connected = true end |
#give_up(reason) ⇒ Object
154 155 156 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 154 def give_up(reason) current_accomplish_goal_command.give_up!(reason) end |
#kill! ⇒ Object
72 73 74 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 72 def kill! state_machine.perform_transition!(:kill) end |
#killed? ⇒ Boolean
76 77 78 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 76 def killed? state_machine.current_state == :killed end |
#mark_mission_accomplished(final_result, message_to_user) ⇒ Object
148 149 150 151 152 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 148 def mark_mission_accomplished(final_result, ) # TODO: this is a pretty awkward way to communicate between commands hmmm... # maybe see if there's a less hacky way to pull this off. current_accomplish_goal_command.mission_accomplished!(final_result, ) end |
#run(*args) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 56 def run(*args, **) if args.first.is_a?(::String) accomplish_goal(*args, **) else unless agent_commands_connected? connect_agent_commands end super end end |
#state_machine ⇒ Object
68 69 70 |
# File 'foobara-agent-0.0.5/src/foobara/agent.rb', line 68 def state_machine @state_machine ||= StateMachine.new end |