foobara-agent 0.0.5 → 0.0.7
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 +4 -4
- data/CHANGELOG.md +13 -0
- data/src/foobara/agent/accomplish_goal.rb +64 -77
- data/src/foobara/agent/notify_user_that_current_goal_has_been_accomplished.rb +48 -34
- data/src/foobara/agent.rb +71 -21
- metadata +2 -3
- data/src/foobara/agent/list_types.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 968399c2d338c8f069712d0ad9437b928fe48bc7356e88fd86b9ff6fb7ae235f
|
4
|
+
data.tar.gz: 8483b856faf2f559985550cc631764121797f88963c0baf428b7f16646bd8b59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79be2912847cb407d1ad65166313c8b799b981a2b0da6f8c8e3f8132049c1eb67ec56a9307fdf887f8e659299883f0da4517762abc885fdf8b69949f869f54de
|
7
|
+
data.tar.gz: 169c02a8070d5feb4d307b41ff757294ca5a2e3b810ac0766cece386a357db2cf85075ae9ecb1f5ee2e0b1ec92c855eb202ee4166102a88341b8e5b4268eeb92
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## [0.0.7] - 2025-06-23
|
2
|
+
|
3
|
+
-
|
4
|
+
|
5
|
+
## [0.0.6] - 2025-06-19
|
6
|
+
|
7
|
+
- Do not run next command with pre-cast inputs
|
8
|
+
- Make result_data and message_to_user required (probably unwise for message_to_user?)
|
9
|
+
- Simulate ListCommands and DescribeCommand being at start
|
10
|
+
- Add a verbose flag for debugging help
|
11
|
+
- Give each AccomplishGoal its own command call count
|
12
|
+
- Convert entities to their aggregates as input and primary keys as output
|
13
|
+
|
1
14
|
## [0.0.5] - 2025-05-30
|
2
15
|
|
3
16
|
- Don't require agents to have a name
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative "list_commands"
|
2
2
|
|
3
3
|
module Foobara
|
4
|
-
# TODO: should agent maybe be a command connector? It feels a bit more like a command connector.
|
5
4
|
class Agent < CommandConnector
|
6
5
|
class AccomplishGoal < Foobara::Command
|
7
6
|
possible_error :gave_up, context: { reason: :string }, message: "Gave up."
|
@@ -9,13 +8,14 @@ module Foobara
|
|
9
8
|
context: { maximum_command_calls: :integer }
|
10
9
|
|
11
10
|
inputs do
|
12
|
-
agent_name :string, "Name of the agent"
|
13
11
|
goal :string, :required, "What do you want the agent to attempt to accomplish?"
|
14
12
|
# TODO: we should be able to specify a subclass as a type
|
15
|
-
command_classes [Class], "Commands that can be ran to accomplish the goal"
|
16
13
|
final_result_type :duck, "Specifies how the result of the goal is to be structured"
|
17
|
-
|
18
|
-
|
14
|
+
include_message_to_user_in_result :boolean, default: true
|
15
|
+
verbose :boolean, default: false
|
16
|
+
io_out :duck
|
17
|
+
io_err :duck
|
18
|
+
agent Agent, :required
|
19
19
|
current_context Context, :allow_nil, "The current context of the agent"
|
20
20
|
maximum_command_calls :integer,
|
21
21
|
:allow_nil,
|
@@ -42,7 +42,7 @@ module Foobara
|
|
42
42
|
end
|
43
43
|
|
44
44
|
result do
|
45
|
-
message_to_user :string, :
|
45
|
+
message_to_user :string, :allow_nil, "Message to the user about successfully accomplishing the goal"
|
46
46
|
result_data :duck, "Optional result data to return to the user if final_result_type was given"
|
47
47
|
end
|
48
48
|
|
@@ -51,19 +51,13 @@ module Foobara
|
|
51
51
|
def execute
|
52
52
|
build_initial_context_if_necessary
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
else
|
57
|
-
build_command_connector
|
58
|
-
connect_user_provided_commands
|
59
|
-
end
|
60
|
-
|
61
|
-
unless agent_commands_connected?
|
62
|
-
connect_agent_commands
|
63
|
-
end
|
54
|
+
simulate_list_commands_run
|
55
|
+
simulate_describe_command_run_for_all_commands
|
64
56
|
|
65
57
|
until mission_accomplished or given_up
|
58
|
+
increment_command_calls
|
66
59
|
check_if_too_many_calls
|
60
|
+
|
67
61
|
if choose_next_command_and_next_inputs_separately?
|
68
62
|
determine_next_command_then_inputs_separately
|
69
63
|
else
|
@@ -81,71 +75,43 @@ module Foobara
|
|
81
75
|
build_result
|
82
76
|
end
|
83
77
|
|
84
|
-
def agent_commands_connected?
|
85
|
-
command_connector.agent_commands_connected?
|
86
|
-
end
|
87
|
-
|
88
|
-
def validate
|
89
|
-
validate_either_command_classes_or_connector_given
|
90
|
-
end
|
91
|
-
|
92
|
-
def validate_either_command_classes_or_connector_given
|
93
|
-
# TODO: implement this!
|
94
|
-
end
|
95
|
-
|
96
78
|
attr_accessor :context, :next_command_name, :next_command_inputs, :mission_accomplished, :given_up,
|
97
79
|
:next_command_class, :next_command, :command_outcome, :timed_out,
|
98
|
-
:final_result, :final_message, :command_response, :delayed_command_name
|
99
|
-
|
100
|
-
|
101
|
-
def agent_name
|
102
|
-
@agent_name ||= inputs[:agent_name] || "Anon#{SecureRandom.hex(2)}"
|
103
|
-
end
|
80
|
+
:final_result, :final_message, :command_response, :delayed_command_name,
|
81
|
+
:command_calls
|
104
82
|
|
105
83
|
def build_initial_context_if_necessary
|
106
84
|
# TODO: shouldn't have to pass command_log here since it has a default, debug that
|
107
85
|
self.context = current_context || Context.new(command_log: [])
|
108
86
|
end
|
109
87
|
|
110
|
-
def
|
111
|
-
|
112
|
-
end
|
88
|
+
def simulate_list_commands_run
|
89
|
+
return unless context.command_log.empty?
|
113
90
|
|
114
|
-
|
115
|
-
|
116
|
-
|
91
|
+
self.next_command_name = ListCommands.full_command_name
|
92
|
+
self.next_command_inputs = nil
|
93
|
+
fetch_next_command_class
|
117
94
|
|
118
|
-
|
119
|
-
|
120
|
-
def build_command_connector
|
121
|
-
self.command_connector ||= Agent.new(
|
122
|
-
current_accomplish_goal_command: self,
|
123
|
-
llm_model:
|
124
|
-
)
|
95
|
+
run_next_command
|
96
|
+
log_last_command_outcome
|
125
97
|
end
|
126
98
|
|
127
|
-
def
|
128
|
-
|
129
|
-
end
|
99
|
+
def simulate_describe_command_run_for_all_commands
|
100
|
+
return if context.command_log.size > 1
|
130
101
|
|
131
|
-
|
132
|
-
|
133
|
-
|
102
|
+
ListCommands.run!(command_connector: agent)[:user_provided_commands].each do |full_command_name|
|
103
|
+
next if described_commands.include?(full_command_name)
|
104
|
+
|
105
|
+
self.next_command_name = DescribeCommand.full_command_name
|
106
|
+
self.next_command_inputs = { command_name: full_command_name }
|
107
|
+
fetch_next_command_class
|
134
108
|
|
135
|
-
|
136
|
-
|
137
|
-
command_connector.connect(command_class)
|
109
|
+
run_next_command
|
110
|
+
log_last_command_outcome
|
138
111
|
end
|
139
112
|
end
|
140
113
|
|
141
114
|
def determine_next_command_and_inputs(retries = 2)
|
142
|
-
if context.command_log.empty?
|
143
|
-
self.next_command_name = ListCommands.full_command_name
|
144
|
-
self.next_command_inputs = nil
|
145
|
-
fetch_next_command_class
|
146
|
-
return
|
147
|
-
end
|
148
|
-
|
149
115
|
inputs_for_determine = {
|
150
116
|
goal:,
|
151
117
|
context:,
|
@@ -250,15 +216,9 @@ module Foobara
|
|
250
216
|
def validate_next_command_inputs
|
251
217
|
inputs_type = next_command_class.inputs_type
|
252
218
|
|
253
|
-
|
219
|
+
NestedTransactionable.with_needed_transactions_for_type(inputs_type) do
|
254
220
|
inputs_type.process_value(next_command_inputs)
|
255
221
|
end
|
256
|
-
|
257
|
-
if outcome.success?
|
258
|
-
self.next_command_inputs = outcome.result
|
259
|
-
end
|
260
|
-
|
261
|
-
outcome
|
262
222
|
end
|
263
223
|
|
264
224
|
def command_name_type
|
@@ -266,9 +226,7 @@ module Foobara
|
|
266
226
|
end
|
267
227
|
|
268
228
|
def determine_next_command_name(retries = 2)
|
269
|
-
self.next_command_name = if
|
270
|
-
ListCommands.full_command_name
|
271
|
-
elsif delayed_command_name
|
229
|
+
self.next_command_name = if delayed_command_name
|
272
230
|
name = delayed_command_name
|
273
231
|
self.delayed_command_name = nil
|
274
232
|
name
|
@@ -327,11 +285,11 @@ module Foobara
|
|
327
285
|
end
|
328
286
|
|
329
287
|
def all_command_classes
|
330
|
-
@all_command_classes ||= run_subcommand!(ListCommands, command_connector:).values.flatten
|
288
|
+
@all_command_classes ||= run_subcommand!(ListCommands, command_connector: agent).values.flatten
|
331
289
|
end
|
332
290
|
|
333
291
|
def fetch_next_command_class
|
334
|
-
self.next_command_class =
|
292
|
+
self.next_command_class = agent.transformed_command_from_name(next_command_name)
|
335
293
|
end
|
336
294
|
|
337
295
|
def determine_next_command_inputs(retries = 2)
|
@@ -392,21 +350,42 @@ module Foobara
|
|
392
350
|
end
|
393
351
|
|
394
352
|
def run_next_command
|
395
|
-
|
353
|
+
if verbose?
|
354
|
+
(io_out || $stdout).puts "Running #{next_command_name} with #{next_command_inputs}"
|
355
|
+
end
|
356
|
+
|
357
|
+
self.command_response = agent.run(
|
396
358
|
full_command_name: next_command_name,
|
397
359
|
inputs: next_command_inputs,
|
398
360
|
action: "run"
|
399
361
|
)
|
400
362
|
|
401
363
|
self.command_outcome = command_response.outcome
|
364
|
+
|
365
|
+
if verbose?
|
366
|
+
if command_outcome.success?
|
367
|
+
(io_out || $stdout).puts "Command #{command_response.command.class.full_command_name} succeeded"
|
368
|
+
else
|
369
|
+
# :nocov:
|
370
|
+
(io_err || $stderr).puts(
|
371
|
+
"Command #{command_response.command.class.full_command_name} failed #{command_outcome.errors_hash}"
|
372
|
+
)
|
373
|
+
# :nocov:
|
374
|
+
end
|
375
|
+
end
|
402
376
|
end
|
403
377
|
|
404
378
|
def log_last_command_outcome
|
405
379
|
log_command_outcome(command: command_response.command)
|
406
380
|
end
|
407
381
|
|
382
|
+
def increment_command_calls
|
383
|
+
self.command_calls ||= -1
|
384
|
+
self.command_calls += 1
|
385
|
+
end
|
386
|
+
|
408
387
|
def check_if_too_many_calls
|
409
|
-
if
|
388
|
+
if command_calls > maximum_command_calls
|
410
389
|
add_runtime_error(
|
411
390
|
:too_many_command_calls,
|
412
391
|
"Too many command calls. " \
|
@@ -485,6 +464,14 @@ module Foobara
|
|
485
464
|
def choose_next_command_and_next_inputs_separately?
|
486
465
|
choose_next_command_and_next_inputs_separately
|
487
466
|
end
|
467
|
+
|
468
|
+
def agent_name
|
469
|
+
agent.agent_name
|
470
|
+
end
|
471
|
+
|
472
|
+
def verbose?
|
473
|
+
verbose
|
474
|
+
end
|
488
475
|
end
|
489
476
|
end
|
490
477
|
end
|
@@ -6,8 +6,10 @@ module Foobara
|
|
6
6
|
class << self
|
7
7
|
attr_accessor :command_class
|
8
8
|
|
9
|
-
def for(result_type
|
10
|
-
|
9
|
+
def for(agent_id: nil, result_type: nil, include_message_to_user_in_result: true)
|
10
|
+
agent_id ||= "Anon#{SecureRandom.hex(2)}"
|
11
|
+
|
12
|
+
cached_subclass([result_type, agent_id, include_message_to_user_in_result]) do
|
11
13
|
command_name = "Foobara::Agent::#{agent_id}::NotifyUserThatCurrentGoalHasBeenAccomplished"
|
12
14
|
klass = Util.make_class_p(command_name, self)
|
13
15
|
|
@@ -16,32 +18,50 @@ module Foobara
|
|
16
18
|
"result schema and an optional message to the user. " \
|
17
19
|
"The user might issue a new goal."
|
18
20
|
|
19
|
-
inputs do
|
20
|
-
command_connector CommandConnector, :required, "Connector to notify user through"
|
21
|
-
message_to_user :string, "Optional message to the user"
|
22
|
-
end
|
23
|
-
|
24
21
|
if result_type
|
25
|
-
|
26
|
-
|
22
|
+
if include_message_to_user_in_result
|
23
|
+
klass.add_inputs do
|
24
|
+
result result_type, :required
|
25
|
+
message_to_user :string, :required, "Message to the user about what was done"
|
26
|
+
end
|
27
|
+
|
28
|
+
klass.result do
|
29
|
+
result result_type, :required
|
30
|
+
message_to_user :string, :required, "Message to the user about what was done"
|
31
|
+
end
|
32
|
+
|
33
|
+
klass.description "Notifies the user that the current goal has been accomplished and returns a final " \
|
34
|
+
"result formatted according to the " \
|
35
|
+
"result schema and a message to the user. " \
|
36
|
+
"The user might issue a new goal."
|
37
|
+
else
|
38
|
+
klass.add_inputs do
|
39
|
+
result result_type, :required
|
40
|
+
end
|
41
|
+
|
42
|
+
klass.result result_type
|
43
|
+
|
44
|
+
klass.description "Notifies the user that the current goal has been accomplished and returns a final " \
|
45
|
+
"result formatted according to the " \
|
46
|
+
"result schema. " \
|
47
|
+
"The user might issue a new goal."
|
48
|
+
end
|
49
|
+
elsif include_message_to_user_in_result
|
50
|
+
klass.add_inputs do
|
51
|
+
message_to_user :string, :required, "Message to the user about what was done"
|
27
52
|
end
|
28
53
|
|
29
54
|
klass.result do
|
30
|
-
message_to_user :string
|
31
|
-
result_data result_type
|
55
|
+
message_to_user :string, :required, "Message to the user about what was done"
|
32
56
|
end
|
33
|
-
klass.description "Notifies the user that the current goal has been accomplished and returns a final " \
|
34
|
-
"result formatted according to the " \
|
35
|
-
"result schema if relevant and an optional message to the user. " \
|
36
|
-
"The user might issue a new goal."
|
37
57
|
|
58
|
+
klass.description "Notifies the user that the current goal has been accomplished and results in a " \
|
59
|
+
"message to the user. " \
|
60
|
+
"The user might issue a new goal."
|
38
61
|
else
|
39
|
-
#
|
62
|
+
# This should be unreachable actually
|
40
63
|
# :nocov:
|
41
|
-
klass.description "Notifies the user that the current goal has been accomplished
|
42
|
-
"returns a final " \
|
43
|
-
"result formatted according to the " \
|
44
|
-
"result schema and an optional message to the user. " \
|
64
|
+
klass.description "Notifies the user that the current goal has been accomplished. " \
|
45
65
|
"The user might issue a new goal."
|
46
66
|
# :nocov:
|
47
67
|
end
|
@@ -55,10 +75,7 @@ module Foobara
|
|
55
75
|
"result schema if relevant and an optional message to the user."
|
56
76
|
|
57
77
|
inputs do
|
58
|
-
|
59
|
-
command_connector :duck, :required, "Connector to end"
|
60
|
-
message_to_user :string, "Optional message to the user"
|
61
|
-
result_data :duck, "The final result of the work if relevant/expected"
|
78
|
+
command_connector CommandConnector, :required, "Connector to notify user through"
|
62
79
|
end
|
63
80
|
|
64
81
|
def execute
|
@@ -68,21 +85,18 @@ module Foobara
|
|
68
85
|
end
|
69
86
|
|
70
87
|
def mark_mission_accomplished
|
71
|
-
|
72
|
-
inputs[:result_data]
|
73
|
-
end
|
74
|
-
|
75
|
-
command_connector.mark_mission_accomplished(data, message_to_user)
|
88
|
+
command_connector.mark_mission_accomplished(inputs[:result], inputs[:message_to_user])
|
76
89
|
end
|
77
90
|
|
78
91
|
def parsed_result
|
79
|
-
|
92
|
+
inputs_type = self.class.inputs_type
|
93
|
+
element_types = inputs_type.element_types
|
80
94
|
|
81
|
-
if
|
82
|
-
|
95
|
+
if element_types.key?(:message_to_user)
|
96
|
+
inputs.slice(:result, :message_to_user)
|
97
|
+
elsif element_types.key?(:result)
|
98
|
+
inputs[:result]
|
83
99
|
end
|
84
|
-
|
85
|
-
h
|
86
100
|
end
|
87
101
|
end
|
88
102
|
end
|
data/src/foobara/agent.rb
CHANGED
@@ -18,7 +18,11 @@ module Foobara
|
|
18
18
|
:llm_model,
|
19
19
|
:current_accomplish_goal_command,
|
20
20
|
:result_type,
|
21
|
-
:
|
21
|
+
:include_message_to_user_in_result,
|
22
|
+
:agent_commands_connected,
|
23
|
+
:verbose,
|
24
|
+
:io_out,
|
25
|
+
:io_err
|
22
26
|
|
23
27
|
def initialize(
|
24
28
|
context: nil,
|
@@ -26,25 +30,34 @@ module Foobara
|
|
26
30
|
command_classes: nil,
|
27
31
|
llm_model: nil,
|
28
32
|
result_type: nil,
|
29
|
-
|
33
|
+
include_message_to_user_in_result: true,
|
34
|
+
verbose: false,
|
35
|
+
io_out: nil,
|
36
|
+
io_err: nil,
|
30
37
|
**opts
|
31
38
|
)
|
32
39
|
# TODO: shouldn't have to pass command_log here since it has a default, debug that
|
33
40
|
self.context = context
|
34
|
-
self.agent_name = agent_name
|
41
|
+
self.agent_name = agent_name || "Anon#{SecureRandom.hex(2)}"
|
35
42
|
self.llm_model = llm_model
|
36
43
|
self.result_type = result_type
|
37
|
-
self.
|
44
|
+
self.include_message_to_user_in_result = include_message_to_user_in_result
|
45
|
+
self.verbose = verbose
|
46
|
+
self.io_out = io_out
|
47
|
+
self.io_err = io_err
|
38
48
|
|
39
49
|
unless opts.key?(:default_serializers)
|
40
50
|
opts = opts.merge(default_serializers: [
|
41
51
|
Foobara::CommandConnectors::Serializers::ErrorsSerializer,
|
42
|
-
Foobara::CommandConnectors::Serializers::
|
52
|
+
Foobara::CommandConnectors::Serializers::AggregateSerializer
|
43
53
|
])
|
44
54
|
end
|
45
55
|
|
46
56
|
super(**opts)
|
47
57
|
|
58
|
+
# TODO: this should work now, switch to this approach
|
59
|
+
# add_default_inputs_transformer EntityToPrimaryKeyInputsTransformer
|
60
|
+
|
48
61
|
build_initial_context
|
49
62
|
|
50
63
|
# TODO: push this convenience method up into base class?
|
@@ -53,6 +66,20 @@ module Foobara
|
|
53
66
|
end
|
54
67
|
end
|
55
68
|
|
69
|
+
def connect(*args, **opts)
|
70
|
+
args, opts = desugarize_connect_args(args, opts)
|
71
|
+
|
72
|
+
inputs_transformers = opts[:inputs_transformers] || []
|
73
|
+
inputs_transformers = Util.array(inputs_transformers)
|
74
|
+
inputs_transformers << CommandConnectors::Transformers::EntityToPrimaryKeyInputsTransformer
|
75
|
+
|
76
|
+
unless opts.key?(:aggregate_entities)
|
77
|
+
opts = opts.merge(aggregate_entities: true)
|
78
|
+
end
|
79
|
+
|
80
|
+
super(*args, **opts.merge(inputs_transformers:))
|
81
|
+
end
|
82
|
+
|
56
83
|
def run(*args, **)
|
57
84
|
if args.first.is_a?(::String)
|
58
85
|
accomplish_goal(*args, **)
|
@@ -81,7 +108,8 @@ module Foobara
|
|
81
108
|
goal,
|
82
109
|
result_type: nil,
|
83
110
|
choose_next_command_and_next_inputs_separately: nil,
|
84
|
-
maximum_call_count: nil
|
111
|
+
maximum_call_count: nil,
|
112
|
+
llm_model: nil
|
85
113
|
)
|
86
114
|
if result_type && self.result_type != result_type
|
87
115
|
if self.result_type
|
@@ -97,6 +125,10 @@ module Foobara
|
|
97
125
|
end
|
98
126
|
end
|
99
127
|
|
128
|
+
unless agent_commands_connected?
|
129
|
+
connect_agent_commands
|
130
|
+
end
|
131
|
+
|
100
132
|
state_machine.perform_transition!(:accomplish_goal)
|
101
133
|
|
102
134
|
begin
|
@@ -104,12 +136,10 @@ module Foobara
|
|
104
136
|
goal:,
|
105
137
|
final_result_type: self.result_type,
|
106
138
|
current_context: context,
|
107
|
-
|
139
|
+
agent: self
|
108
140
|
}
|
109
141
|
|
110
|
-
|
111
|
-
inputs[:agent_name] = agent_name
|
112
|
-
end
|
142
|
+
llm_model ||= self.llm_model
|
113
143
|
|
114
144
|
if llm_model
|
115
145
|
inputs[:llm_model] = llm_model
|
@@ -123,14 +153,32 @@ module Foobara
|
|
123
153
|
inputs[:maximum_command_calls] = maximum_call_count
|
124
154
|
end
|
125
155
|
|
156
|
+
if verbose
|
157
|
+
inputs[:verbose] = verbose
|
158
|
+
end
|
159
|
+
|
160
|
+
if io_out
|
161
|
+
inputs[:io_out] = io_out
|
162
|
+
end
|
163
|
+
|
164
|
+
if io_err
|
165
|
+
inputs[:io_err] = io_err
|
166
|
+
end
|
167
|
+
|
168
|
+
if include_message_to_user_in_result || include_message_to_user_in_result == false
|
169
|
+
inputs[:include_message_to_user_in_result] = include_message_to_user_in_result
|
170
|
+
end
|
171
|
+
|
126
172
|
self.current_accomplish_goal_command = AccomplishGoal.new(inputs)
|
127
173
|
|
128
174
|
current_accomplish_goal_command.run.tap do |outcome|
|
129
|
-
if outcome.success?
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
175
|
+
transition = if outcome.success?
|
176
|
+
:goal_accomplished
|
177
|
+
else
|
178
|
+
:goal_errored
|
179
|
+
end
|
180
|
+
|
181
|
+
state_machine.perform_transition!(transition)
|
134
182
|
end
|
135
183
|
rescue
|
136
184
|
# :nocov:
|
@@ -159,19 +207,21 @@ module Foobara
|
|
159
207
|
agent_commands_connected
|
160
208
|
end
|
161
209
|
|
162
|
-
def connect_agent_commands
|
210
|
+
def connect_agent_commands
|
163
211
|
command_classes = [
|
164
212
|
DescribeCommand,
|
165
213
|
DescribeType,
|
166
214
|
GiveUp,
|
167
|
-
ListCommands
|
168
|
-
ListTypes
|
215
|
+
ListCommands
|
169
216
|
]
|
170
217
|
|
171
|
-
command_classes << if
|
218
|
+
command_classes << if result_type || include_message_to_user_in_result
|
219
|
+
# TODO: Support changing the final result type when the goal changes
|
172
220
|
NotifyUserThatCurrentGoalHasBeenAccomplished.for(
|
173
|
-
result_type
|
174
|
-
agent_id: agent_name
|
221
|
+
result_type:,
|
222
|
+
agent_id: agent_name,
|
223
|
+
# TODO: Support changing this flag when the goal changes
|
224
|
+
include_message_to_user_in_result:
|
175
225
|
)
|
176
226
|
else
|
177
227
|
NotifyUserThatCurrentGoalHasBeenAccomplished
|
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.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miles Georgi
|
@@ -59,7 +59,6 @@ files:
|
|
59
59
|
- src/foobara/agent/determine_next_command_name_and_inputs.rb
|
60
60
|
- src/foobara/agent/give_up.rb
|
61
61
|
- src/foobara/agent/list_commands.rb
|
62
|
-
- src/foobara/agent/list_types.rb
|
63
62
|
- src/foobara/agent/notify_user_that_current_goal_has_been_accomplished.rb
|
64
63
|
- src/foobara/agent/types/command_log_entry.rb
|
65
64
|
- src/foobara/agent/types/context.rb
|
@@ -85,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
84
|
- !ruby/object:Gem::Version
|
86
85
|
version: '0'
|
87
86
|
requirements: []
|
88
|
-
rubygems_version: 3.6.
|
87
|
+
rubygems_version: 3.6.9
|
89
88
|
specification_version: 4
|
90
89
|
summary: An agent that uses whatever Foobara commands you wish to accomplish goals
|
91
90
|
of your choosing!
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Foobara
|
2
|
-
class Agent < CommandConnector
|
3
|
-
class ListTypes < Foobara::Command
|
4
|
-
inputs do
|
5
|
-
command_connector :duck, :required, "Connector to fetch types from"
|
6
|
-
end
|
7
|
-
|
8
|
-
result [:string]
|
9
|
-
|
10
|
-
def execute
|
11
|
-
construct_type_list
|
12
|
-
|
13
|
-
type_list
|
14
|
-
end
|
15
|
-
|
16
|
-
attr_accessor :type_list
|
17
|
-
|
18
|
-
def construct_type_list
|
19
|
-
self.type_list = command_connector.all_exposed_type_names
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|