foobara-agent 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7288308d62332addbe98233f7652d718b16f496b02a632426c418642959c5aa4
4
- data.tar.gz: 2da140d10bf62e8858de3d5f77c732a0295a4179dfa22e3ddb2c3becf7421029
3
+ metadata.gz: fc0affa9f2a80a45d94dbcde1ad4ba5f173d0e3aa91076d91147058e5e1c6829
4
+ data.tar.gz: 40f0e2ed19b6e95a0b325e54eb624b15d3cde7eeda9cfe325626bee5a347f001
5
5
  SHA512:
6
- metadata.gz: 830b3932828ccb30587c64214425f7b4eea862f5deec5c6a9a8d2a8d80733720b66e0d73f936444d91f5dffa6b7f27d8736638c000e17d2caa37cbff477fe6d2
7
- data.tar.gz: cd9e89b6dc3dc81f2bd71ed5d6269f7dc8268d950bb120508c8295d1b89b64cd345d79fec8aa2f85cba0945e534e5fc62305ca070f78490f5c3f0303bf72f011
6
+ metadata.gz: 716dbb353942408388d6a8e28f87c54911f44d067f398d8c224bbed7e926adc63eae816cea9d40f5acd7ccab478421319c542d2d28e9451996775fcd6ec5f9e7
7
+ data.tar.gz: 0e80baab41484b2843ddbbe49a1a9412cce157ed43758af7f621f8dc7c99d94d02e0767b92cbe069d5396373e561ee03da4b510e94cb1ddcc86b738b413d203c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ ## [0.0.4] - 2025-05-30
2
+
3
+ - Refactor agent to be a command connector
4
+
5
+ ## [0.0.3] - 2025-05-30
6
+
7
+ - Increase the retries, attempt to improve command descriptions,
8
+ and attempt to improve the information stored in the context/command log
9
+ - Add some safeguards around changing the result type too late in the process
10
+ - Add an agent state machine and a kill! method
11
+
12
+ ## [0.0.2] - 2025-05-27
13
+
14
+ - Add maximum_call_count option
15
+ - Try getting the command and inputs together to reduce calls
16
+ - Tweaks to algorithms and improvements to what is stored in context/command_log
17
+
1
18
  ## [0.0.1] - 2025-05-21
2
19
 
3
20
  - Initial release
data/lib/foobara/agent.rb CHANGED
@@ -3,7 +3,7 @@ require "foobara/ai"
3
3
  require "foobara/command_connectors"
4
4
 
5
5
  module Foobara
6
- class Agent
6
+ class Agent < CommandConnector
7
7
  foobara_domain!
8
8
 
9
9
  foobara_depends_on Foobara::Ai::AnswerBot
@@ -2,7 +2,7 @@ require_relative "list_commands"
2
2
 
3
3
  module Foobara
4
4
  # TODO: should agent maybe be a command connector? It feels a bit more like a command connector.
5
- class Agent
5
+ class Agent < CommandConnector
6
6
  class AccomplishGoal < Foobara::Command
7
7
  possible_error :gave_up, context: { reason: :string }, message: "Gave up."
8
8
  possible_error :too_many_command_calls,
@@ -62,7 +62,8 @@ module Foobara
62
62
  connect_agent_commands
63
63
  end
64
64
 
65
- until mission_accomplished or given_up or timed_out
65
+ until mission_accomplished or given_up
66
+ check_if_too_many_calls
66
67
  if choose_next_command_and_next_inputs_separately?
67
68
  determine_next_command_then_inputs_separately
68
69
  else
@@ -71,7 +72,6 @@ module Foobara
71
72
 
72
73
  run_next_command
73
74
  log_last_command_outcome
74
- check_if_too_many_calls
75
75
  end
76
76
 
77
77
  if given_up
@@ -115,19 +115,17 @@ module Foobara
115
115
  @command_connector ||= existing_command_connector
116
116
  end
117
117
 
118
+ # Do we really want to support calling AccomplishGoal outside the context of an Agent?
119
+ # If not, just delete this awkward coupling
118
120
  def build_command_connector
119
- self.command_connector ||= Connector.new(
120
- accomplish_goal_command: self,
121
- default_serializers: [
122
- Foobara::CommandConnectors::Serializers::ErrorsSerializer,
123
- Foobara::CommandConnectors::Serializers::AtomicSerializer
124
- ],
121
+ self.command_connector ||= Agent.new(
122
+ current_accomplish_goal_command: self,
125
123
  llm_model:
126
124
  )
127
125
  end
128
126
 
129
127
  def set_accomplished_goal_command
130
- command_connector.accomplish_goal_command = self
128
+ command_connector.current_accomplish_goal_command = self
131
129
  end
132
130
 
133
131
  def connect_agent_commands
@@ -140,7 +138,7 @@ module Foobara
140
138
  end
141
139
  end
142
140
 
143
- def determine_next_command_and_inputs(retries = 1)
141
+ def determine_next_command_and_inputs(retries = 2)
144
142
  if context.command_log.empty?
145
143
  self.next_command_name = ListCommands.full_command_name
146
144
  self.next_command_inputs = nil
@@ -157,7 +155,13 @@ module Foobara
157
155
 
158
156
  determine_command = DetermineNextCommandNameAndInputs.new(inputs_for_determine)
159
157
 
160
- outcome = determine_command.run
158
+ outcome = begin
159
+ determine_command.run
160
+ rescue CommandPatternImplementation::Concerns::Result::CouldNotProcessResult => e
161
+ # :nocov:
162
+ Outcome.errors(e.errors)
163
+ # :nocov:
164
+ end
161
165
 
162
166
  if outcome.success?
163
167
  self.next_command_name = outcome.result[:command_name]
@@ -182,7 +186,8 @@ module Foobara
182
186
  log_command_outcome(
183
187
  command: determine_command,
184
188
  inputs: determine_command.inputs.except(:context),
185
- outcome:
189
+ outcome:,
190
+ result: outcome.result || determine_command.raw_result
186
191
  )
187
192
 
188
193
  determine_next_command_inputs
@@ -194,7 +199,8 @@ module Foobara
194
199
  log_command_outcome(
195
200
  command: determine_command,
196
201
  inputs: determine_command.inputs&.except(:context),
197
- outcome:
202
+ outcome:,
203
+ result: outcome.result || determine_command.raw_result
198
204
  )
199
205
 
200
206
  if retries > 0
@@ -207,7 +213,8 @@ module Foobara
207
213
  log_command_outcome(
208
214
  command_name: determine_command.class.full_command_name,
209
215
  inputs: determine_command.inputs&.except(:context),
210
- outcome:
216
+ outcome:,
217
+ result: outcome.result || determine_command.raw_result
211
218
  )
212
219
 
213
220
  if retries > 0
@@ -258,7 +265,7 @@ module Foobara
258
265
  @command_name_type ||= Agent.foobara_type_from_declaration(:string, one_of: all_command_classes)
259
266
  end
260
267
 
261
- def determine_next_command_name(retries = 1)
268
+ def determine_next_command_name(retries = 2)
262
269
  self.next_command_name = if context.command_log.empty?
263
270
  ListCommands.full_command_name
264
271
  elsif delayed_command_name
@@ -276,13 +283,20 @@ module Foobara
276
283
  end
277
284
 
278
285
  command = command_class.new(inputs)
279
- outcome = command.run
286
+ outcome = begin
287
+ command.run
288
+ rescue CommandPatternImplementation::Concerns::Result::CouldNotProcessResult => e
289
+ # :nocov:
290
+ Outcome.errors(e.errors)
291
+ # :nocov:
292
+ end
280
293
 
281
294
  if outcome.success?
282
295
  if log_successful_determine_command_and_inputs_outcomes?
283
296
  log_command_outcome(
284
297
  command:,
285
- inputs: command.inputs.except(:context)
298
+ inputs: command.inputs.except(:context),
299
+ outcome:
286
300
  )
287
301
  end
288
302
  else
@@ -290,7 +304,9 @@ module Foobara
290
304
  # :nocov:
291
305
  log_command_outcome(
292
306
  command:,
293
- inputs: command.inputs.except(:context)
307
+ inputs: command.inputs.except(:context),
308
+ outcome:,
309
+ result: outcome.result || command.raw_result
294
310
  )
295
311
 
296
312
  if retries > 0
@@ -318,7 +334,7 @@ module Foobara
318
334
  self.next_command_class = command_connector.transformed_command_from_name(next_command_name)
319
335
  end
320
336
 
321
- def determine_next_command_inputs(retries = 1)
337
+ def determine_next_command_inputs(retries = 2)
322
338
  self.next_command_inputs = if next_command_has_inputs?
323
339
  command_class = command_class_for_determine_inputs_for_next_command
324
340
 
@@ -328,13 +344,20 @@ module Foobara
328
344
  end
329
345
 
330
346
  command = command_class.new(inputs)
331
- outcome = command.run
347
+ outcome = begin
348
+ command.run
349
+ rescue CommandPatternImplementation::Concerns::Result::CouldNotProcessResult => e
350
+ # :nocov:
351
+ Outcome.errors(e.errors)
352
+ # :nocov:
353
+ end
332
354
 
333
355
  if outcome.success?
334
356
  if log_successful_determine_command_and_inputs_outcomes?
335
357
  log_command_outcome(
336
358
  command:,
337
- inputs: command.inputs.except(:context)
359
+ inputs: command.inputs.except(:context),
360
+ outcome:
338
361
  )
339
362
  end
340
363
  else
@@ -342,7 +365,9 @@ module Foobara
342
365
  # :nocov:
343
366
  log_command_outcome(
344
367
  command:,
345
- inputs: command.inputs.except(:context)
368
+ inputs: command.inputs.except(:context),
369
+ outcome:,
370
+ result: outcome.result || command.raw_result
346
371
  )
347
372
  if retries > 0
348
373
  return determine_next_command_inputs(retries - 1)
@@ -409,11 +434,13 @@ module Foobara
409
434
  outcome_hash[:errors_hash] = outcome.errors_hash
410
435
  end
411
436
 
412
- context.command_log << CommandLogEntry.new(
437
+ log_entry = CommandLogEntry.new(
413
438
  command_name:,
414
439
  inputs:,
415
440
  outcome: outcome_hash
416
441
  )
442
+
443
+ context.command_log << log_entry
417
444
  end
418
445
 
419
446
  # TODO: these are awkwardly called from outside. Come up with a better solution.
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  module Concerns
4
4
  # There's nothing really subclass-specific about this concern, maybe rename it...
5
5
  module SubclassCacheable
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  class SetCommandConnectorInputsTransformer < TypeDeclarations::TypedTransformer
4
4
  class << self
5
5
  attr_accessor :command_connector
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  class DescribeCommand < Foobara::Command
4
4
  inputs do
5
5
  command_connector :duck, :required, "Connector to find relevant command in"
@@ -52,7 +52,7 @@ module Foobara
52
52
  end
53
53
 
54
54
  def mark_command_as_described
55
- command_connector.accomplish_goal_command.described_commands << command_class.full_command_name
55
+ command_connector.current_accomplish_goal_command.described_commands << command_class.full_command_name
56
56
  end
57
57
  end
58
58
  end
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  class DescribeType < Foobara::Command
4
4
  inputs do
5
5
  command_connector :duck, :required, "Connector to find relevant type in"
@@ -1,7 +1,7 @@
1
1
  require "foobara/llm_backed_command"
2
2
 
3
3
  module Foobara
4
- class Agent
4
+ class Agent < CommandConnector
5
5
  class DetermineInputsForNextCommand < Foobara::LlmBackedCommand
6
6
  extend Concerns::SubclassCacheable
7
7
 
@@ -17,7 +17,7 @@ module Foobara
17
17
  "accomplishing the goal."
18
18
 
19
19
  klass.inputs do
20
- goal :string, :required, "What do you want the agent to attempt to accomplish?"
20
+ goal :string, :required, "The current (possibly already accomplished) goal"
21
21
  context Context, :required, "Context of the progress towards the goal so far"
22
22
  llm_model :string,
23
23
  one_of: Foobara::Ai::AnswerBot::Types::ModelEnum,
@@ -1,7 +1,7 @@
1
1
  require "foobara/llm_backed_command"
2
2
 
3
3
  module Foobara
4
- class Agent
4
+ class Agent < CommandConnector
5
5
  class DetermineNextCommand < Foobara::LlmBackedCommand
6
6
  extend Concerns::SubclassCacheable
7
7
 
@@ -12,8 +12,17 @@ module Foobara
12
12
  command_name = "Foobara::Agent::#{agent_id}::DetermineNextCommand"
13
13
  klass = Util.make_class_p(command_name, self)
14
14
 
15
+ klass.description "Accepts the current goal, which might already be accomplished, " \
16
+ "and context of the work " \
17
+ "so far and returns the name of " \
18
+ "the next command to run to make progress towards " \
19
+ "accomplishing the goal. If the goal has already been accomplished then choose the " \
20
+ "NotifyUserThatCurrentGoalHasBeenAccomplished command."
21
+
15
22
  klass.inputs do
16
- goal :string, :required, "What do you want the agent to attempt to accomplish?"
23
+ goal :string, :required, "The current goal to accomplish. If the goal has already been accomplished " \
24
+ "by the previous command runs then choose " \
25
+ "NotifyUserThatCurrentGoalHasBeenAccomplished to stop the loop."
17
26
  context Context, :required, "Context of progress so far"
18
27
  llm_model :string,
19
28
  one_of: Foobara::Ai::AnswerBot::Types::ModelEnum,
@@ -1,14 +1,18 @@
1
1
  require "foobara/llm_backed_command"
2
2
 
3
3
  module Foobara
4
- class Agent
4
+ class Agent < CommandConnector
5
5
  class DetermineNextCommandNameAndInputs < Foobara::LlmBackedCommand
6
- description "Accepts a goal and context of the work so far and returns the inputs for " \
6
+ description "Accepts the current goal, which might already be accomplished, and context of the work " \
7
+ "so far and returns the inputs for " \
7
8
  "the next command to run to make progress towards " \
8
- "accomplishing the goal."
9
+ "accomplishing the goal. If the goal has already been accomplished then choose the " \
10
+ "NotifyUserThatCurrentGoalHasBeenAccomplished command."
9
11
 
10
12
  inputs do
11
- goal :string, :required, "What do you want the agent to attempt to accomplish?"
13
+ goal :string, :required, "The current goal to accomplish. If the goal has already been accomplished " \
14
+ "by the previous command runs then choose " \
15
+ "NotifyUserThatCurrentGoalHasBeenAccomplished to stop the loop."
12
16
  context Context, :required, "Context of the progress towards the goal so far"
13
17
  command_class_names [:string], :required
14
18
  llm_model :string,
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  class GiveUp < Foobara::Command
4
4
  inputs do
5
5
  command_connector CommandConnector, :required, "Connector to end"
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  class ListCommands < Foobara::Command
4
4
  inputs do
5
5
  command_connector :duck, :required, "Connector to end"
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  class ListTypes < Foobara::Command
4
4
  inputs do
5
5
  command_connector :duck, :required, "Connector to fetch types from"
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  class NotifyUserThatCurrentGoalHasBeenAccomplished < Foobara::Command
4
4
  extend Concerns::SubclassCacheable
5
5
 
@@ -71,6 +71,7 @@ module Foobara
71
71
  data = if result_type
72
72
  inputs[:result_data]
73
73
  end
74
+
74
75
  command_connector.mark_mission_accomplished(data, message_to_user)
75
76
  end
76
77
 
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  class CommandLogEntry < Foobara::Model
4
4
  attributes do
5
5
  command_name :string, :required, "Name of the command that was run"
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- class Agent
2
+ class Agent < CommandConnector
3
3
  class Context < Foobara::Model
4
4
  attributes do
5
5
  # TODO: why doesn't this default of [] work as expected on newly created models?
data/src/foobara/agent.rb CHANGED
@@ -1,56 +1,140 @@
1
1
  module Foobara
2
- class Agent
3
- attr_accessor :context, :agent_command_connector, :agent_name, :llm_model
2
+ class Agent < CommandConnector
3
+ StateMachine = Foobara::StateMachine.for(
4
+ [:initialized, :idle, :error, :failure] => {
5
+ kill: :killed,
6
+ accomplish_goal: :accomplishing_goal
7
+ },
8
+ accomplishing_goal: {
9
+ goal_accomplished: :idle,
10
+ goal_errored: :error,
11
+ goal_failed: :failure,
12
+ kill: :killed
13
+ }
14
+ )
15
+
16
+ attr_accessor :context,
17
+ :agent_name,
18
+ :llm_model,
19
+ :current_accomplish_goal_command,
20
+ :result_type,
21
+ :agent_commands_connected
4
22
 
5
23
  def initialize(
6
24
  context: nil,
7
25
  agent_name: nil,
8
26
  command_classes: nil,
9
- agent_command_connector: nil,
10
- llm_model: nil
27
+ llm_model: nil,
28
+ result_type: nil,
29
+ current_accomplish_goal_command: nil,
30
+ **opts
11
31
  )
12
32
  # TODO: shouldn't have to pass command_log here since it has a default, debug that
13
33
  self.context = context
14
- self.agent_command_connector = agent_command_connector
15
34
  self.agent_name = agent_name if agent_name
16
35
  self.llm_model = llm_model
36
+ self.result_type = result_type
37
+ self.current_accomplish_goal_command = current_accomplish_goal_command
38
+
39
+ unless opts.key?(:default_serializers)
40
+ opts = opts.merge(default_serializers: [
41
+ Foobara::CommandConnectors::Serializers::ErrorsSerializer,
42
+ Foobara::CommandConnectors::Serializers::AtomicSerializer
43
+ ])
44
+ end
45
+
46
+ super(**opts)
17
47
 
18
48
  build_initial_context
19
- build_agent_command_connector
20
49
 
50
+ # TODO: push this convenience method up into base class?
21
51
  command_classes&.each do |command_class|
22
- self.agent_command_connector.connect(command_class)
52
+ connect(command_class)
53
+ end
54
+ end
55
+
56
+ def run(*args, **)
57
+ if args.first.is_a?(::String)
58
+ accomplish_goal(*args, **)
59
+ else
60
+ unless agent_commands_connected?
61
+ connect_agent_commands
62
+ end
63
+
64
+ super
23
65
  end
24
66
  end
25
67
 
68
+ def state_machine
69
+ @state_machine ||= StateMachine.new
70
+ end
71
+
72
+ def kill!
73
+ state_machine.perform_transition!(:kill)
74
+ end
75
+
76
+ def killed?
77
+ state_machine.current_state == :killed
78
+ end
79
+
26
80
  def accomplish_goal(
27
81
  goal,
28
82
  result_type: nil,
29
83
  choose_next_command_and_next_inputs_separately: nil,
30
84
  maximum_call_count: nil
31
85
  )
32
- inputs = {
33
- goal:,
34
- final_result_type: result_type,
35
- current_context: context,
36
- existing_command_connector: agent_command_connector,
37
- agent_name:
86
+ if result_type && self.result_type != result_type
87
+ if self.result_type
88
+ # :nocov:
89
+ raise ArgumentError, "You can only specify a result type once"
90
+ # :nocov:
91
+ elsif agent_commands_connected?
92
+ # :nocov:
93
+ raise ArgumentError, "You can't specify a result type this late in the process"
94
+ # :nocov:
95
+ else
96
+ self.result_type = result_type
97
+ end
98
+ end
38
99
 
39
- }
100
+ state_machine.perform_transition!(:accomplish_goal)
40
101
 
41
- if llm_model
42
- inputs[:llm_model] = llm_model
43
- end
102
+ begin
103
+ inputs = {
104
+ goal:,
105
+ final_result_type: self.result_type,
106
+ current_context: context,
107
+ existing_command_connector: self,
108
+ agent_name:
109
+ }
44
110
 
45
- unless choose_next_command_and_next_inputs_separately.nil?
46
- inputs[:choose_next_command_and_next_inputs_separately] = choose_next_command_and_next_inputs_separately
47
- end
111
+ if llm_model
112
+ inputs[:llm_model] = llm_model
113
+ end
48
114
 
49
- unless maximum_call_count.nil?
50
- inputs[:maximum_command_calls] = maximum_call_count
51
- end
115
+ unless choose_next_command_and_next_inputs_separately.nil?
116
+ inputs[:choose_next_command_and_next_inputs_separately] = choose_next_command_and_next_inputs_separately
117
+ end
118
+
119
+ unless maximum_call_count.nil?
120
+ inputs[:maximum_command_calls] = maximum_call_count
121
+ end
52
122
 
53
- AccomplishGoal.run(inputs)
123
+ self.current_accomplish_goal_command = AccomplishGoal.new(inputs)
124
+
125
+ current_accomplish_goal_command.run.tap do |outcome|
126
+ if outcome.success?
127
+ state_machine.perform_transition!(:goal_accomplished)
128
+ else
129
+ state_machine.perform_transition!(:goal_errored)
130
+ end
131
+ end
132
+ rescue
133
+ # :nocov:
134
+ state_machine.perform_transition!(:goal_failed)
135
+ raise
136
+ # :nocov:
137
+ end
54
138
  end
55
139
 
56
140
  def build_initial_context
@@ -58,15 +142,45 @@ module Foobara
58
142
  self.context ||= Context.new(command_log: [])
59
143
  end
60
144
 
61
- def build_agent_command_connector
62
- self.agent_command_connector ||= Connector.new(
63
- accomplish_goal_command: self,
64
- llm_model:,
65
- default_serializers: [
66
- Foobara::CommandConnectors::Serializers::ErrorsSerializer,
67
- Foobara::CommandConnectors::Serializers::AtomicSerializer
68
- ]
69
- )
145
+ def mark_mission_accomplished(final_result, message_to_user)
146
+ # TODO: this is a pretty awkward way to communicate between commands hmmm...
147
+ # maybe see if there's a less hacky way to pull this off.
148
+ current_accomplish_goal_command.mission_accomplished!(final_result, message_to_user)
149
+ end
150
+
151
+ def give_up(reason)
152
+ current_accomplish_goal_command.give_up!(reason)
153
+ end
154
+
155
+ def agent_commands_connected?
156
+ agent_commands_connected
157
+ end
158
+
159
+ def connect_agent_commands(final_result_type: nil, agent_name: nil)
160
+ command_classes = [
161
+ DescribeCommand,
162
+ DescribeType,
163
+ GiveUp,
164
+ ListCommands,
165
+ ListTypes
166
+ ]
167
+
168
+ command_classes << if final_result_type
169
+ NotifyUserThatCurrentGoalHasBeenAccomplished.for(
170
+ result_type: final_result_type,
171
+ agent_id: agent_name
172
+ )
173
+ else
174
+ NotifyUserThatCurrentGoalHasBeenAccomplished
175
+ end
176
+
177
+ set_command_connector_transformer = SetCommandConnectorInputsTransformer.for(self)
178
+
179
+ command_classes.each do |command_class|
180
+ connect(command_class, inputs: set_command_connector_transformer)
181
+ end
182
+
183
+ self.agent_commands_connected = true
70
184
  end
71
185
  end
72
186
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foobara-agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
@@ -51,7 +51,6 @@ files:
51
51
  - src/foobara/agent.rb
52
52
  - src/foobara/agent/accomplish_goal.rb
53
53
  - src/foobara/agent/concerns/subclass_cacheable.rb
54
- - src/foobara/agent/connector/connector.rb
55
54
  - src/foobara/agent/connector/set_command_connector_inputs_transformer.rb
56
55
  - src/foobara/agent/describe_command.rb
57
56
  - src/foobara/agent/describe_type.rb
@@ -1,59 +0,0 @@
1
- require "foobara/command_connectors"
2
-
3
- module Foobara
4
- class Agent
5
- class Connector < Foobara::CommandConnector
6
- attr_accessor :accomplish_goal_command, :agent_commands_connected, :llm_model
7
-
8
- def initialize(*, accomplish_goal_command:, llm_model: nil, **)
9
- self.accomplish_goal_command = accomplish_goal_command
10
- self.llm_model = llm_model
11
-
12
- super(*, **)
13
- end
14
-
15
- def mark_mission_accomplished(final_result, message_to_user)
16
- # TODO: this is a pretty awkward way to communicate between commands hmmm...
17
- # maybe see if there's a less hacky way to pull this off.
18
- accomplish_goal_command.mission_accomplished!(final_result, message_to_user)
19
- end
20
-
21
- def give_up(reason)
22
- accomplish_goal_command.give_up!(reason)
23
- end
24
-
25
- def agent_commands_connected?
26
- agent_commands_connected
27
- end
28
-
29
- def connect_agent_commands(final_result_type: nil, agent_name: nil)
30
- command_classes = [
31
- DescribeCommand,
32
- DescribeType,
33
- GiveUp,
34
- ListCommands,
35
- ListTypes
36
- ]
37
-
38
- command_classes << if final_result_type
39
- NotifyUserThatCurrentGoalHasBeenAccomplished.for(
40
- result_type: final_result_type,
41
- agent_id: agent_name
42
- )
43
- else
44
- NotifyUserThatCurrentGoalHasBeenAccomplished
45
- end
46
-
47
- command_classes.each do |command_class|
48
- connect(command_class, inputs: set_command_connector_transformer)
49
- end
50
-
51
- self.agent_commands_connected = true
52
- end
53
-
54
- def set_command_connector_transformer
55
- @set_command_connector_transformer ||= SetCommandConnectorInputsTransformer.for(self)
56
- end
57
- end
58
- end
59
- end