foobara-agent 0.0.9 → 0.0.11
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 +10 -0
- data/lib/foobara/agent.rb +1 -2
- data/src/foobara/agent/accomplish_goal.rb +40 -170
- data/src/foobara/agent/concerns/subclass_cacheable.rb +2 -0
- data/src/foobara/agent/determine_next_command_name_and_inputs.rb +1 -1
- data/src/foobara/agent/notify_user_that_current_goal_has_been_accomplished.rb +53 -17
- data/src/foobara/agent.rb +1 -6
- metadata +1 -3
- data/src/foobara/agent/determine_inputs_for_next_command.rb +0 -33
- data/src/foobara/agent/determine_next_command.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e0f6302247bbcc56ed93f61ec3a5d39e5041029e03b20cadea2d1dd0ebd04b6
|
4
|
+
data.tar.gz: baca677e1ea555bcdc908fd2b37dc2d8b016df9888f8f7a69c8cff73774756b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 350feb6d9058009889a342a5dcc4f44befed8a25be71ebc7673bf75b7ceb1f95adcec3a52d2eb53ba9301d0ef2312919a4496a53f2146423dd36c17b122856af
|
7
|
+
data.tar.gz: a91ec6608bc3001f06d3c17562321d2c1a52a537372347593293d57d9d6312126f5116853c8b32b649d7c65a050bbb67bd03b2dbc50247cdc7260013b6d8f3ec
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## [0.0.11] - 2025-07-01
|
2
|
+
|
3
|
+
- Fix some bugs with result type/value mismatches
|
4
|
+
- Eliminate ability to select command and inputs separately
|
5
|
+
|
6
|
+
## [0.0.10] - 2025-06-30
|
7
|
+
|
8
|
+
- Allow more retries
|
9
|
+
- Eliminate ability to select command and inputs separately
|
10
|
+
|
1
11
|
## [0.0.9] - 2025-06-28
|
2
12
|
|
3
13
|
- Relocate some common Determine* behavior into a DetermineBase
|
data/lib/foobara/agent.rb
CHANGED
@@ -11,7 +11,6 @@ module Foobara
|
|
11
11
|
class << self
|
12
12
|
def reset_all
|
13
13
|
[
|
14
|
-
DetermineInputsForNextCommand,
|
15
14
|
NotifyUserThatCurrentGoalHasBeenAccomplished
|
16
15
|
].each do |command_class|
|
17
16
|
command_class.clear_subclass_cache
|
@@ -23,4 +22,4 @@ module Foobara
|
|
23
22
|
end
|
24
23
|
|
25
24
|
Foobara::Util.require_directory "#{__dir__}/../../src"
|
26
|
-
Foobara
|
25
|
+
Foobara.project "agent", project_path: "#{__dir__}/../../"
|
@@ -29,12 +29,6 @@ module Foobara
|
|
29
29
|
one_of: Foobara::Ai::AnswerBot::Types::ModelEnum,
|
30
30
|
default: "claude-3-7-sonnet-20250219",
|
31
31
|
description: "The model to use for the LLM"
|
32
|
-
choose_next_command_and_next_inputs_separately :boolean,
|
33
|
-
default: false,
|
34
|
-
description:
|
35
|
-
"By default, asks for next command and inputs together. " \
|
36
|
-
"You can experiment with getting the separately " \
|
37
|
-
"with this flag if you wish."
|
38
32
|
max_llm_calls_per_minute :integer, :allow_nil
|
39
33
|
end
|
40
34
|
|
@@ -56,15 +50,10 @@ module Foobara
|
|
56
50
|
|
57
51
|
throttle_llm_calls_if_necessary
|
58
52
|
|
59
|
-
|
60
|
-
determine_next_command_then_inputs_separately
|
61
|
-
else
|
62
|
-
determine_next_command_and_inputs
|
63
|
-
end
|
64
|
-
|
53
|
+
determine_next_command_and_inputs
|
65
54
|
run_next_command
|
55
|
+
|
66
56
|
log_last_command_outcome
|
67
|
-
compact_command_log
|
68
57
|
end
|
69
58
|
|
70
59
|
if given_up
|
@@ -138,7 +127,24 @@ module Foobara
|
|
138
127
|
# :nocov:
|
139
128
|
end
|
140
129
|
|
141
|
-
def determine_next_command_and_inputs(retries =
|
130
|
+
def determine_next_command_and_inputs(retries = 3, error_outcome = nil)
|
131
|
+
if retries == 0
|
132
|
+
# TODO: test this path by irreparably breaking the needed commands
|
133
|
+
# :nocov:
|
134
|
+
self.next_command_name = GiveUp.full_command_name
|
135
|
+
self.next_command_inputs = {
|
136
|
+
message_to_user: "While trying to choose the next command and inputs, " \
|
137
|
+
"I've ran into an error several times that I couldn't figure out how to get past. " \
|
138
|
+
"The last error looked like this:\n#{error_outcome.errors_hash}"
|
139
|
+
}
|
140
|
+
self.next_command_raw_inputs = next_command_inputs
|
141
|
+
|
142
|
+
return
|
143
|
+
# :nocov:
|
144
|
+
end
|
145
|
+
|
146
|
+
compact_command_log
|
147
|
+
|
142
148
|
inputs_for_determine = {
|
143
149
|
context:,
|
144
150
|
llm_model:
|
@@ -156,7 +162,7 @@ module Foobara
|
|
156
162
|
end
|
157
163
|
|
158
164
|
if outcome.success?
|
159
|
-
self.next_command_name = outcome.result[:
|
165
|
+
self.next_command_name = outcome.result[:command]
|
160
166
|
self.next_command_inputs = outcome.result[:inputs]
|
161
167
|
self.next_command_raw_inputs = next_command_inputs
|
162
168
|
|
@@ -176,7 +182,8 @@ module Foobara
|
|
176
182
|
)
|
177
183
|
|
178
184
|
simulate_describe_command
|
179
|
-
|
185
|
+
|
186
|
+
determine_next_command_and_inputs(retries - 1, outcome)
|
180
187
|
end
|
181
188
|
else
|
182
189
|
self.next_command_inputs = {}
|
@@ -190,11 +197,7 @@ module Foobara
|
|
190
197
|
result: nil
|
191
198
|
)
|
192
199
|
|
193
|
-
|
194
|
-
determine_next_command_and_inputs(retries - 1)
|
195
|
-
else
|
196
|
-
determine_next_command_then_inputs_separately
|
197
|
-
end
|
200
|
+
determine_next_command_and_inputs(retries - 1, outcome)
|
198
201
|
end
|
199
202
|
else
|
200
203
|
log_command_outcome(
|
@@ -204,23 +207,7 @@ module Foobara
|
|
204
207
|
result: outcome.result || determine_command.raw_result
|
205
208
|
)
|
206
209
|
|
207
|
-
|
208
|
-
determine_next_command_and_inputs(retries - 1)
|
209
|
-
else
|
210
|
-
determine_next_command_then_inputs_separately
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def determine_next_command_then_inputs_separately
|
216
|
-
determine_next_command_name
|
217
|
-
|
218
|
-
if command_described?
|
219
|
-
fetch_next_command_class
|
220
|
-
determine_next_command_inputs
|
221
|
-
else
|
222
|
-
choose_describe_command_instead
|
223
|
-
fetch_next_command_class
|
210
|
+
determine_next_command_and_inputs(retries - 1, outcome)
|
224
211
|
end
|
225
212
|
end
|
226
213
|
|
@@ -259,74 +246,6 @@ module Foobara
|
|
259
246
|
@command_name_type ||= Agent.foobara_type_from_declaration(:string, one_of: all_command_classes)
|
260
247
|
end
|
261
248
|
|
262
|
-
def determine_next_command_name(retries = 2)
|
263
|
-
self.next_command_name = if delayed_command_name
|
264
|
-
name = delayed_command_name
|
265
|
-
self.delayed_command_name = nil
|
266
|
-
name
|
267
|
-
else
|
268
|
-
inputs = { context: }
|
269
|
-
if llm_model
|
270
|
-
inputs[:llm_model] = llm_model
|
271
|
-
end
|
272
|
-
|
273
|
-
command = DetermineNextCommand.new(inputs)
|
274
|
-
outcome = begin
|
275
|
-
record_llm_call_timestamp
|
276
|
-
command.run
|
277
|
-
rescue CommandPatternImplementation::Concerns::Result::CouldNotProcessResult => e
|
278
|
-
# :nocov:
|
279
|
-
Outcome.errors(e.errors)
|
280
|
-
# :nocov:
|
281
|
-
end
|
282
|
-
|
283
|
-
if outcome.success?
|
284
|
-
self.next_command_name = outcome.result
|
285
|
-
|
286
|
-
outcome = validate_next_command_name
|
287
|
-
|
288
|
-
unless outcome.success?
|
289
|
-
# TODO: figure out a way to hit this path in the test suite or delete it
|
290
|
-
# :nocov:
|
291
|
-
log_command_outcome(
|
292
|
-
command:,
|
293
|
-
inputs: command.inputs.except(:context),
|
294
|
-
outcome:,
|
295
|
-
result: outcome.result || command.raw_result
|
296
|
-
)
|
297
|
-
|
298
|
-
if retries > 0
|
299
|
-
return determine_next_command_name(retries - 1)
|
300
|
-
end
|
301
|
-
# :nocov:
|
302
|
-
end
|
303
|
-
else
|
304
|
-
# TODO: either figure out a way to hit this path in the test suite or delete it
|
305
|
-
# :nocov:
|
306
|
-
log_command_outcome(
|
307
|
-
command:,
|
308
|
-
inputs: command.inputs&.except(:context),
|
309
|
-
outcome:,
|
310
|
-
result: outcome.result || command.raw_result
|
311
|
-
)
|
312
|
-
|
313
|
-
if retries > 0
|
314
|
-
return determine_next_command_name(retries - 1)
|
315
|
-
end
|
316
|
-
# :nocov:
|
317
|
-
end
|
318
|
-
|
319
|
-
outcome.raise!
|
320
|
-
outcome.result
|
321
|
-
end
|
322
|
-
end
|
323
|
-
|
324
|
-
def choose_describe_command_instead
|
325
|
-
self.delayed_command_name = next_command_name
|
326
|
-
self.next_command_inputs = { command_name: next_command_name }
|
327
|
-
self.next_command_name = DescribeCommand.full_command_name
|
328
|
-
end
|
329
|
-
|
330
249
|
def all_command_classes
|
331
250
|
@all_command_classes ||= run_subcommand!(ListCommands, command_connector: agent).values.flatten
|
332
251
|
end
|
@@ -335,58 +254,11 @@ module Foobara
|
|
335
254
|
self.next_command_class = agent.transformed_command_from_name(next_command_name)
|
336
255
|
end
|
337
256
|
|
338
|
-
def determine_next_command_inputs(retries = 2)
|
339
|
-
self.next_command_inputs = if next_command_has_inputs?
|
340
|
-
command_class = command_class_for_determine_inputs_for_next_command
|
341
|
-
|
342
|
-
inputs = { context: }
|
343
|
-
if llm_model
|
344
|
-
inputs[:llm_model] = llm_model
|
345
|
-
end
|
346
|
-
|
347
|
-
command = command_class.new(inputs)
|
348
|
-
outcome = begin
|
349
|
-
record_llm_call_timestamp
|
350
|
-
command.run
|
351
|
-
rescue CommandPatternImplementation::Concerns::Result::CouldNotProcessResult => e
|
352
|
-
# :nocov:
|
353
|
-
Outcome.errors(e.errors)
|
354
|
-
# :nocov:
|
355
|
-
end
|
356
|
-
|
357
|
-
unless outcome.success?
|
358
|
-
# TODO: either figure out a way to hit this path in the test suite or delete it
|
359
|
-
# :nocov:
|
360
|
-
log_command_outcome(
|
361
|
-
command_name: next_command_name,
|
362
|
-
inputs: command.raw_result,
|
363
|
-
outcome:
|
364
|
-
)
|
365
|
-
|
366
|
-
simulate_describe_command
|
367
|
-
|
368
|
-
if retries > 0
|
369
|
-
return determine_next_command_inputs(retries - 1)
|
370
|
-
end
|
371
|
-
# :nocov:
|
372
|
-
end
|
373
|
-
|
374
|
-
outcome.raise!
|
375
|
-
outcome.result
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
257
|
def next_command_has_inputs?
|
380
258
|
type = next_command_class.inputs_type
|
381
259
|
type && !empty_attributes?(type)
|
382
260
|
end
|
383
261
|
|
384
|
-
def command_class_for_determine_inputs_for_next_command
|
385
|
-
DetermineInputsForNextCommand.for(
|
386
|
-
command_class: next_command_class, agent_id: agent_name
|
387
|
-
)
|
388
|
-
end
|
389
|
-
|
390
262
|
def run_next_command
|
391
263
|
if verbose?
|
392
264
|
args = if next_command_inputs.nil? || next_command_inputs.empty?
|
@@ -402,6 +274,7 @@ module Foobara
|
|
402
274
|
# :nocov:
|
403
275
|
end
|
404
276
|
end
|
277
|
+
|
405
278
|
(io_out || $stdout).puts "#{next_command_name}.run#{args}"
|
406
279
|
end
|
407
280
|
|
@@ -431,8 +304,8 @@ module Foobara
|
|
431
304
|
def compact_command_log
|
432
305
|
# Rules:
|
433
306
|
# Delete errors for any command that has succeeded since
|
434
|
-
# Delete all but the last DescribeCommand call
|
435
|
-
describe_command_call_indexes =
|
307
|
+
# Delete all but the last DescribeCommand call for a given
|
308
|
+
describe_command_call_indexes = {}
|
436
309
|
commands = {}
|
437
310
|
|
438
311
|
describe_command_name = DescribeCommand.full_command_name
|
@@ -440,7 +313,12 @@ module Foobara
|
|
440
313
|
command_name = command_log_entry.command_name
|
441
314
|
|
442
315
|
if command_name == describe_command_name
|
443
|
-
|
316
|
+
described_command = command_log_entry.inputs[:command_name]
|
317
|
+
|
318
|
+
if command_log_entry.outcome[:success]
|
319
|
+
describe_command_call_indexes[described_command] ||= []
|
320
|
+
describe_command_call_indexes[described_command] << index
|
321
|
+
end
|
444
322
|
end
|
445
323
|
|
446
324
|
commands[command_name] ||= [[], []]
|
@@ -448,7 +326,11 @@ module Foobara
|
|
448
326
|
commands[command_name][bucket_index] << index
|
449
327
|
end
|
450
328
|
|
451
|
-
indexes_to_delete =
|
329
|
+
indexes_to_delete = []
|
330
|
+
|
331
|
+
describe_command_call_indexes.each_value do |indexes|
|
332
|
+
indexes_to_delete += indexes[0..-2]
|
333
|
+
end
|
452
334
|
|
453
335
|
commands.each_value do |(success_indexes, failure_indexes)|
|
454
336
|
last_success = success_indexes.last
|
@@ -548,10 +430,6 @@ module Foobara
|
|
548
430
|
}
|
549
431
|
end
|
550
432
|
|
551
|
-
def command_described?
|
552
|
-
described_commands.include?(next_command_name)
|
553
|
-
end
|
554
|
-
|
555
433
|
def described_commands
|
556
434
|
@described_commands ||= Set.new
|
557
435
|
end
|
@@ -560,14 +438,6 @@ module Foobara
|
|
560
438
|
type.extends_type?(BuiltinTypes[:attributes]) && type.element_types.empty?
|
561
439
|
end
|
562
440
|
|
563
|
-
def choose_next_command_and_next_inputs_separately?
|
564
|
-
choose_next_command_and_next_inputs_separately
|
565
|
-
end
|
566
|
-
|
567
|
-
def agent_name
|
568
|
-
agent.agent_name
|
569
|
-
end
|
570
|
-
|
571
441
|
def verbose?
|
572
442
|
verbose
|
573
443
|
end
|
@@ -596,7 +466,7 @@ module Foobara
|
|
596
466
|
first_to_expire = calls.first
|
597
467
|
|
598
468
|
if first_to_expire
|
599
|
-
(first_to_expire + SECONDS_PER_MINUTE) - Time.now
|
469
|
+
[0, (first_to_expire + SECONDS_PER_MINUTE) - Time.now].max
|
600
470
|
else
|
601
471
|
# TODO: figure out how to test this code path
|
602
472
|
# :nocov:
|
@@ -4,7 +4,7 @@ module Foobara
|
|
4
4
|
extend Concerns::SubclassCacheable
|
5
5
|
|
6
6
|
class << self
|
7
|
-
attr_accessor :command_class
|
7
|
+
attr_accessor :command_class, :returns_message_to_user, :returns_result_data, :result_is_attributes
|
8
8
|
|
9
9
|
def for(agent_id: nil, result_type: nil, include_message_to_user_in_result: true)
|
10
10
|
agent_id ||= "Anon#{SecureRandom.hex(2)}"
|
@@ -19,24 +19,36 @@ module Foobara
|
|
19
19
|
"The user might issue a new goal."
|
20
20
|
|
21
21
|
if result_type
|
22
|
+
klass.returns_result_data = true
|
23
|
+
|
24
|
+
# TODO: fix this... agent backed command sets these via its own result type.
|
25
|
+
# check if message_to_user is already here and also search/fix result_data to be result for consistency.
|
22
26
|
if include_message_to_user_in_result
|
23
|
-
klass.
|
24
|
-
result result_type, :required
|
25
|
-
message_to_user :string, :required, "Message to the user about what was done"
|
26
|
-
end
|
27
|
+
klass.returns_message_to_user = true
|
27
28
|
|
28
29
|
klass.result do
|
29
30
|
result result_type, :required
|
30
31
|
message_to_user :string, :required, "Message to the user about what was done"
|
31
32
|
end
|
32
33
|
|
34
|
+
klass.add_inputs klass.result_type
|
35
|
+
|
33
36
|
klass.description "Notifies the user that the current goal has been accomplished and returns a final " \
|
34
37
|
"result formatted according to the " \
|
35
38
|
"result schema and a message to the user. " \
|
36
39
|
"The user might issue a new goal."
|
37
40
|
else
|
38
|
-
|
39
|
-
|
41
|
+
unless result_type.is_a?(Types::Type)
|
42
|
+
result_type = Domain.current.foobara_type_from_declaration(result_type)
|
43
|
+
end
|
44
|
+
|
45
|
+
if result_type.extends?(BuiltinTypes[:attributes])
|
46
|
+
klass.result_is_attributes = true
|
47
|
+
klass.add_inputs result_type
|
48
|
+
else
|
49
|
+
klass.add_inputs do
|
50
|
+
result result_type, :required
|
51
|
+
end
|
40
52
|
end
|
41
53
|
|
42
54
|
klass.result result_type
|
@@ -47,6 +59,8 @@ module Foobara
|
|
47
59
|
"The user might issue a new goal."
|
48
60
|
end
|
49
61
|
elsif include_message_to_user_in_result
|
62
|
+
klass.returns_message_to_user = true
|
63
|
+
|
50
64
|
klass.add_inputs do
|
51
65
|
message_to_user :string, :required, "Message to the user about what was done"
|
52
66
|
end
|
@@ -79,24 +93,46 @@ module Foobara
|
|
79
93
|
end
|
80
94
|
|
81
95
|
def execute
|
96
|
+
build_result
|
82
97
|
mark_mission_accomplished
|
83
98
|
|
84
|
-
|
99
|
+
built_result
|
85
100
|
end
|
86
101
|
|
102
|
+
attr_accessor :built_result
|
103
|
+
|
87
104
|
def mark_mission_accomplished
|
88
|
-
|
105
|
+
result, message_to_user = if returns_message_to_user?
|
106
|
+
[built_result[:result], built_result[:message_to_user]]
|
107
|
+
elsif returns_result_data?
|
108
|
+
[built_result, nil]
|
109
|
+
end
|
110
|
+
|
111
|
+
command_connector.mark_mission_accomplished(result, message_to_user)
|
89
112
|
end
|
90
113
|
|
91
|
-
def
|
92
|
-
|
93
|
-
|
114
|
+
def build_result
|
115
|
+
self.built_result = if returns_message_to_user?
|
116
|
+
inputs.slice(:result, :message_to_user)
|
117
|
+
elsif returns_result_data?
|
118
|
+
if result_is_attributes?
|
119
|
+
inputs.slice(*self.class.result_type.element_types.keys)
|
120
|
+
else
|
121
|
+
inputs[:result]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
94
125
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
126
|
+
def returns_message_to_user?
|
127
|
+
self.class.returns_message_to_user
|
128
|
+
end
|
129
|
+
|
130
|
+
def returns_result_data?
|
131
|
+
self.class.returns_result_data
|
132
|
+
end
|
133
|
+
|
134
|
+
def result_is_attributes?
|
135
|
+
self.class.result_is_attributes
|
100
136
|
end
|
101
137
|
end
|
102
138
|
end
|
data/src/foobara/agent.rb
CHANGED
@@ -41,7 +41,7 @@ module Foobara
|
|
41
41
|
# TODO: shouldn't have to pass command_log here since it has a default, debug that
|
42
42
|
self.context = context
|
43
43
|
self.agent_name = agent_name || "Anon#{SecureRandom.hex(2)}"
|
44
|
-
self.llm_model = llm_model
|
44
|
+
self.llm_model = llm_model || "claude-opus-4-20250514"
|
45
45
|
self.result_type = result_type
|
46
46
|
self.include_message_to_user_in_result = include_message_to_user_in_result
|
47
47
|
self.verbose = verbose
|
@@ -114,7 +114,6 @@ module Foobara
|
|
114
114
|
def accomplish_goal(
|
115
115
|
goal,
|
116
116
|
result_type: nil,
|
117
|
-
choose_next_command_and_next_inputs_separately: nil,
|
118
117
|
maximum_call_count: nil,
|
119
118
|
llm_model: nil
|
120
119
|
)
|
@@ -154,10 +153,6 @@ module Foobara
|
|
154
153
|
inputs[:llm_model] = llm_model
|
155
154
|
end
|
156
155
|
|
157
|
-
unless choose_next_command_and_next_inputs_separately.nil?
|
158
|
-
inputs[:choose_next_command_and_next_inputs_separately] = choose_next_command_and_next_inputs_separately
|
159
|
-
end
|
160
|
-
|
161
156
|
unless maximum_call_count.nil?
|
162
157
|
inputs[:maximum_command_calls] = maximum_call_count
|
163
158
|
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.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miles Georgi
|
@@ -55,8 +55,6 @@ files:
|
|
55
55
|
- src/foobara/agent/describe_command.rb
|
56
56
|
- src/foobara/agent/describe_type.rb
|
57
57
|
- src/foobara/agent/determine_base.rb
|
58
|
-
- src/foobara/agent/determine_inputs_for_next_command.rb
|
59
|
-
- src/foobara/agent/determine_next_command.rb
|
60
58
|
- src/foobara/agent/determine_next_command_name_and_inputs.rb
|
61
59
|
- src/foobara/agent/give_up.rb
|
62
60
|
- src/foobara/agent/list_commands.rb
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module Foobara
|
2
|
-
class Agent < CommandConnector
|
3
|
-
class DetermineInputsForNextCommand < DetermineBase
|
4
|
-
extend Concerns::SubclassCacheable
|
5
|
-
|
6
|
-
class << self
|
7
|
-
def for(command_class:, agent_id:)
|
8
|
-
cached_subclass([command_class.full_command_name, agent_id]) do
|
9
|
-
command_short_name = Util.non_full_name(command_class.command_name)
|
10
|
-
class_name = "Foobara::Agent::#{agent_id}::DetermineInputsForNext#{command_short_name}Command"
|
11
|
-
klass = Util.make_class_p(class_name, self)
|
12
|
-
|
13
|
-
klass.description "Returns the inputs for " \
|
14
|
-
"the next #{command_class.full_command_name} command to run."
|
15
|
-
|
16
|
-
if command_class.inputs_type.nil? || command_class.inputs_type.element_types.empty?
|
17
|
-
# :nocov:
|
18
|
-
raise ArgumentError, "command #{command_class.full_command_name} has no inputs"
|
19
|
-
# :nocov:
|
20
|
-
end
|
21
|
-
|
22
|
-
transformer = CommandConnectors::Transformers::EntityToPrimaryKeyInputsTransformer.new(
|
23
|
-
to: command_class.inputs_type
|
24
|
-
)
|
25
|
-
klass.result transformer.from_type
|
26
|
-
|
27
|
-
klass
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Foobara
|
2
|
-
class Agent < CommandConnector
|
3
|
-
class DetermineNextCommand < DetermineBase
|
4
|
-
description "Returns the name of the next command to run given the progress " \
|
5
|
-
"towards accomplishing the current goal. " \
|
6
|
-
"If the goal has been accomplished it will choose the " \
|
7
|
-
"NotifyUserThatCurrentGoalHasBeenAccomplished command."
|
8
|
-
|
9
|
-
result :string,
|
10
|
-
description: "Name of the next command to run"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|