foobara-agent 0.0.3 → 0.0.5
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 +8 -0
- data/lib/foobara/agent.rb +1 -1
- data/src/foobara/agent/accomplish_goal.rb +12 -8
- data/src/foobara/agent/concerns/subclass_cacheable.rb +1 -1
- data/src/foobara/agent/connector/set_command_connector_inputs_transformer.rb +1 -1
- data/src/foobara/agent/describe_command.rb +2 -2
- data/src/foobara/agent/describe_type.rb +1 -1
- data/src/foobara/agent/determine_inputs_for_next_command.rb +1 -1
- data/src/foobara/agent/determine_next_command.rb +1 -1
- data/src/foobara/agent/determine_next_command_name_and_inputs.rb +1 -1
- data/src/foobara/agent/give_up.rb +1 -1
- data/src/foobara/agent/list_commands.rb +1 -1
- data/src/foobara/agent/list_types.rb +1 -1
- data/src/foobara/agent/notify_user_that_current_goal_has_been_accomplished.rb +2 -1
- data/src/foobara/agent/types/command_log_entry.rb +1 -1
- data/src/foobara/agent/types/context.rb +1 -1
- data/src/foobara/agent.rb +75 -20
- metadata +1 -2
- data/src/foobara/agent/connector/connector.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88347fd73d897f4a3f05eb2dcec999c5afddcec625cecc79a44a1a803394b352
|
4
|
+
data.tar.gz: '016936d6acc4e2497aa8e8853d058653d201d3d7d5c2c77090128b728f8833fe'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5672d6bd7930969b566d6dce04314062116593cd2df5c06d718916d83938deb91af64765a85752f7b5c8119d0fce32a56099907b252da636f0408fb3109bf38c
|
7
|
+
data.tar.gz: 71b2c350e024aca9d86c1f5f2bfd3d83726784ab028c6d7b6e0010a88512c1a06351cfbb298478fc1e5f6b5126367e9bca5d417040b9d493153fe7d142b20faa
|
data/CHANGELOG.md
CHANGED
data/lib/foobara/agent.rb
CHANGED
@@ -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,
|
@@ -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 ||=
|
120
|
-
|
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.
|
128
|
+
command_connector.current_accomplish_goal_command = self
|
131
129
|
end
|
132
130
|
|
133
131
|
def connect_agent_commands
|
@@ -160,7 +158,9 @@ module Foobara
|
|
160
158
|
outcome = begin
|
161
159
|
determine_command.run
|
162
160
|
rescue CommandPatternImplementation::Concerns::Result::CouldNotProcessResult => e
|
161
|
+
# :nocov:
|
163
162
|
Outcome.errors(e.errors)
|
163
|
+
# :nocov:
|
164
164
|
end
|
165
165
|
|
166
166
|
if outcome.success?
|
@@ -286,7 +286,9 @@ module Foobara
|
|
286
286
|
outcome = begin
|
287
287
|
command.run
|
288
288
|
rescue CommandPatternImplementation::Concerns::Result::CouldNotProcessResult => e
|
289
|
+
# :nocov:
|
289
290
|
Outcome.errors(e.errors)
|
291
|
+
# :nocov:
|
290
292
|
end
|
291
293
|
|
292
294
|
if outcome.success?
|
@@ -345,7 +347,9 @@ module Foobara
|
|
345
347
|
outcome = begin
|
346
348
|
command.run
|
347
349
|
rescue CommandPatternImplementation::Concerns::Result::CouldNotProcessResult => e
|
350
|
+
# :nocov:
|
348
351
|
Outcome.errors(e.errors)
|
352
|
+
# :nocov:
|
349
353
|
end
|
350
354
|
|
351
355
|
if outcome.success?
|
@@ -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.
|
55
|
+
command_connector.current_accomplish_goal_command.described_commands << command_class.full_command_name
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -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 DetermineNextCommandNameAndInputs < Foobara::LlmBackedCommand
|
6
6
|
description "Accepts the current goal, which might already be accomplished, and context of the work " \
|
7
7
|
"so far and returns the inputs for " \
|
@@ -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
|
|
data/src/foobara/agent.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Foobara
|
2
|
-
class Agent
|
2
|
+
class Agent < CommandConnector
|
3
3
|
StateMachine = Foobara::StateMachine.for(
|
4
4
|
[:initialized, :idle, :error, :failure] => {
|
5
5
|
kill: :killed,
|
@@ -14,32 +14,54 @@ module Foobara
|
|
14
14
|
)
|
15
15
|
|
16
16
|
attr_accessor :context,
|
17
|
-
:agent_command_connector,
|
18
17
|
:agent_name,
|
19
18
|
:llm_model,
|
20
19
|
:current_accomplish_goal_command,
|
21
|
-
:result_type
|
20
|
+
:result_type,
|
21
|
+
:agent_commands_connected
|
22
22
|
|
23
23
|
def initialize(
|
24
24
|
context: nil,
|
25
25
|
agent_name: nil,
|
26
26
|
command_classes: nil,
|
27
|
-
agent_command_connector: nil,
|
28
27
|
llm_model: nil,
|
29
|
-
result_type: nil
|
28
|
+
result_type: nil,
|
29
|
+
current_accomplish_goal_command: nil,
|
30
|
+
**opts
|
30
31
|
)
|
31
32
|
# TODO: shouldn't have to pass command_log here since it has a default, debug that
|
32
33
|
self.context = context
|
33
|
-
self.agent_command_connector = agent_command_connector
|
34
34
|
self.agent_name = agent_name if agent_name
|
35
35
|
self.llm_model = llm_model
|
36
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)
|
37
47
|
|
38
48
|
build_initial_context
|
39
|
-
build_agent_command_connector
|
40
49
|
|
50
|
+
# TODO: push this convenience method up into base class?
|
41
51
|
command_classes&.each do |command_class|
|
42
|
-
|
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
|
43
65
|
end
|
44
66
|
end
|
45
67
|
|
@@ -66,7 +88,7 @@ module Foobara
|
|
66
88
|
# :nocov:
|
67
89
|
raise ArgumentError, "You can only specify a result type once"
|
68
90
|
# :nocov:
|
69
|
-
elsif
|
91
|
+
elsif agent_commands_connected?
|
70
92
|
# :nocov:
|
71
93
|
raise ArgumentError, "You can't specify a result type this late in the process"
|
72
94
|
# :nocov:
|
@@ -82,10 +104,13 @@ module Foobara
|
|
82
104
|
goal:,
|
83
105
|
final_result_type: self.result_type,
|
84
106
|
current_context: context,
|
85
|
-
existing_command_connector:
|
86
|
-
agent_name:
|
107
|
+
existing_command_connector: self
|
87
108
|
}
|
88
109
|
|
110
|
+
if agent_name
|
111
|
+
inputs[:agent_name] = agent_name
|
112
|
+
end
|
113
|
+
|
89
114
|
if llm_model
|
90
115
|
inputs[:llm_model] = llm_model
|
91
116
|
end
|
@@ -120,15 +145,45 @@ module Foobara
|
|
120
145
|
self.context ||= Context.new(command_log: [])
|
121
146
|
end
|
122
147
|
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
148
|
+
def mark_mission_accomplished(final_result, message_to_user)
|
149
|
+
# TODO: this is a pretty awkward way to communicate between commands hmmm...
|
150
|
+
# maybe see if there's a less hacky way to pull this off.
|
151
|
+
current_accomplish_goal_command.mission_accomplished!(final_result, message_to_user)
|
152
|
+
end
|
153
|
+
|
154
|
+
def give_up(reason)
|
155
|
+
current_accomplish_goal_command.give_up!(reason)
|
156
|
+
end
|
157
|
+
|
158
|
+
def agent_commands_connected?
|
159
|
+
agent_commands_connected
|
160
|
+
end
|
161
|
+
|
162
|
+
def connect_agent_commands(final_result_type: nil, agent_name: nil)
|
163
|
+
command_classes = [
|
164
|
+
DescribeCommand,
|
165
|
+
DescribeType,
|
166
|
+
GiveUp,
|
167
|
+
ListCommands,
|
168
|
+
ListTypes
|
169
|
+
]
|
170
|
+
|
171
|
+
command_classes << if final_result_type
|
172
|
+
NotifyUserThatCurrentGoalHasBeenAccomplished.for(
|
173
|
+
result_type: final_result_type,
|
174
|
+
agent_id: agent_name
|
175
|
+
)
|
176
|
+
else
|
177
|
+
NotifyUserThatCurrentGoalHasBeenAccomplished
|
178
|
+
end
|
179
|
+
|
180
|
+
set_command_connector_transformer = SetCommandConnectorInputsTransformer.for(self)
|
181
|
+
|
182
|
+
command_classes.each do |command_class|
|
183
|
+
connect(command_class, inputs: set_command_connector_transformer)
|
184
|
+
end
|
185
|
+
|
186
|
+
self.agent_commands_connected = true
|
132
187
|
end
|
133
188
|
end
|
134
189
|
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.5
|
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
|